1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "audio_hw_yukawa"
18 //#define LOG_NDEBUG 0
19
20 #include <errno.h>
21 #include <inttypes.h>
22 #include <malloc.h>
23 #include <pthread.h>
24 #include <stdint.h>
25 #include <stdlib.h>
26 #include <sys/time.h>
27 #include <unistd.h>
28
29 #include <log/log.h>
30 #include <cutils/str_parms.h>
31 #include <cutils/properties.h>
32
33 #include <hardware/hardware.h>
34 #include <system/audio.h>
35 #include <hardware/audio.h>
36
37 #include <audio_effects/effect_aec.h>
38 #include <audio_route/audio_route.h>
39 #include <audio_utils/clock.h>
40 #include <audio_utils/echo_reference.h>
41 #include <audio_utils/resampler.h>
42 #include <hardware/audio_alsaops.h>
43 #include <hardware/audio_effect.h>
44 #include <sound/asound.h>
45 #include <tinyalsa/asoundlib.h>
46
47 #include <sys/ioctl.h>
48
49 #include "audio_aec.h"
50 #include "audio_hw.h"
51
52 static int adev_get_mic_mute(const struct audio_hw_device* dev, bool* state);
53 static int adev_get_microphones(const struct audio_hw_device* dev,
54 struct audio_microphone_characteristic_t* mic_array,
55 size_t* mic_count);
56 static size_t out_get_buffer_size(const struct audio_stream* stream);
57
get_audio_output_port(audio_devices_t devices)58 static int get_audio_output_port(audio_devices_t devices) {
59 /* Prefer HDMI, default to internal speaker */
60 int port = PORT_INTERNAL_SPEAKER;
61 if (devices & AUDIO_DEVICE_OUT_HDMI) {
62 port = PORT_HDMI;
63 }
64
65 return port;
66 }
67
timestamp_adjust(struct timespec * ts,ssize_t frames,uint32_t sampling_rate)68 static void timestamp_adjust(struct timespec* ts, ssize_t frames, uint32_t sampling_rate) {
69 /* This function assumes the adjustment (in nsec) is less than the max value of long,
70 * which for 32-bit long this is 2^31 * 1e-9 seconds, slightly over 2 seconds.
71 * For 64-bit long it is 9e+9 seconds. */
72 long adj_nsec = (frames / (float) sampling_rate) * 1E9L;
73 ts->tv_nsec += adj_nsec;
74 while (ts->tv_nsec > 1E9L) {
75 ts->tv_sec++;
76 ts->tv_nsec -= 1E9L;
77 }
78 if (ts->tv_nsec < 0) {
79 ts->tv_sec--;
80 ts->tv_nsec += 1E9L;
81 }
82 }
83
84 /* Helper function to get PCM hardware timestamp.
85 * Only the field 'timestamp' of argument 'ts' is updated. */
get_pcm_timestamp(struct pcm * pcm,uint32_t sample_rate,struct aec_info * info,bool isOutput)86 static int get_pcm_timestamp(struct pcm* pcm, uint32_t sample_rate, struct aec_info* info,
87 bool isOutput) {
88 int ret = 0;
89 if (pcm_get_htimestamp(pcm, &info->available, &info->timestamp) < 0) {
90 ALOGE("Error getting PCM timestamp!");
91 info->timestamp.tv_sec = 0;
92 info->timestamp.tv_nsec = 0;
93 return -EINVAL;
94 }
95 ssize_t frames;
96 if (isOutput) {
97 frames = pcm_get_buffer_size(pcm) - info->available;
98 } else {
99 frames = -info->available; /* rewind timestamp */
100 }
101 timestamp_adjust(&info->timestamp, frames, sample_rate);
102 return ret;
103 }
104
read_filter_from_file(const char * filename,int16_t * filter,int max_length)105 static int read_filter_from_file(const char* filename, int16_t* filter, int max_length) {
106 FILE* fp = fopen(filename, "r");
107 if (fp == NULL) {
108 ALOGI("%s: File %s not found.", __func__, filename);
109 return 0;
110 }
111 int num_taps = 0;
112 char* line = NULL;
113 size_t len = 0;
114 while (!feof(fp)) {
115 size_t size = getline(&line, &len, fp);
116 if ((line[0] == '#') || (size < 2)) {
117 continue;
118 }
119 int n = sscanf(line, "%" SCNd16 "\n", &filter[num_taps++]);
120 if (n < 1) {
121 ALOGE("Could not find coefficient %d! Exiting...", num_taps - 1);
122 return 0;
123 }
124 ALOGV("Coeff %d : %" PRId16, num_taps, filter[num_taps - 1]);
125 if (num_taps == max_length) {
126 ALOGI("%s: max tap length %d reached.", __func__, max_length);
127 break;
128 }
129 }
130 free(line);
131 fclose(fp);
132 return num_taps;
133 }
134
out_set_eq(struct alsa_stream_out * out)135 static void out_set_eq(struct alsa_stream_out* out) {
136 out->speaker_eq = NULL;
137 int16_t* speaker_eq_coeffs = (int16_t*)calloc(SPEAKER_MAX_EQ_LENGTH, sizeof(int16_t));
138 if (speaker_eq_coeffs == NULL) {
139 ALOGE("%s: Failed to allocate speaker EQ", __func__);
140 return;
141 }
142 int num_taps = read_filter_from_file(SPEAKER_EQ_FILE, speaker_eq_coeffs, SPEAKER_MAX_EQ_LENGTH);
143 if (num_taps == 0) {
144 ALOGI("%s: Empty filter file or 0 taps set.", __func__);
145 free(speaker_eq_coeffs);
146 return;
147 }
148 out->speaker_eq = fir_init(
149 out->config.channels, FIR_SINGLE_FILTER, num_taps,
150 out_get_buffer_size(&out->stream.common) / out->config.channels / sizeof(int16_t),
151 speaker_eq_coeffs);
152 free(speaker_eq_coeffs);
153 }
154
155 /* must be called with hw device and output stream mutexes locked */
start_output_stream(struct alsa_stream_out * out)156 static int start_output_stream(struct alsa_stream_out *out)
157 {
158 struct alsa_audio_device *adev = out->dev;
159
160 /* default to low power: will be corrected in out_write if necessary before first write to
161 * tinyalsa.
162 */
163 out->write_threshold = PLAYBACK_PERIOD_COUNT * PLAYBACK_PERIOD_SIZE;
164 out->config.start_threshold = PLAYBACK_PERIOD_START_THRESHOLD * PLAYBACK_PERIOD_SIZE;
165 out->config.avail_min = PLAYBACK_PERIOD_SIZE;
166 out->unavailable = true;
167 unsigned int pcm_retry_count = PCM_OPEN_RETRIES;
168 int out_port = get_audio_output_port(out->devices);
169
170 while (1) {
171 out->pcm = pcm_open(CARD_OUT, out_port, PCM_OUT | PCM_MONOTONIC, &out->config);
172 if ((out->pcm != NULL) && pcm_is_ready(out->pcm)) {
173 break;
174 } else {
175 ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm));
176 if (out->pcm != NULL) {
177 pcm_close(out->pcm);
178 out->pcm = NULL;
179 }
180 if (--pcm_retry_count == 0) {
181 ALOGE("Failed to open pcm_out after %d tries", PCM_OPEN_RETRIES);
182 return -ENODEV;
183 }
184 usleep(PCM_OPEN_WAIT_TIME_MS * 1000);
185 }
186 }
187 out->unavailable = false;
188 adev->active_output = out;
189 return 0;
190 }
191
out_get_sample_rate(const struct audio_stream * stream)192 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
193 {
194 struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
195 return out->config.rate;
196 }
197
out_set_sample_rate(struct audio_stream * stream,uint32_t rate)198 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
199 {
200 ALOGV("out_set_sample_rate: %d", 0);
201 return -ENOSYS;
202 }
203
out_get_buffer_size(const struct audio_stream * stream)204 static size_t out_get_buffer_size(const struct audio_stream *stream)
205 {
206 ALOGV("out_get_buffer_size: %d", 4096);
207
208 /* return the closest majoring multiple of 16 frames, as
209 * audioflinger expects audio buffers to be a multiple of 16 frames */
210 size_t size = PLAYBACK_PERIOD_SIZE;
211 size = ((size + 15) / 16) * 16;
212 return size * audio_stream_out_frame_size((struct audio_stream_out *)stream);
213 }
214
out_get_channels(const struct audio_stream * stream)215 static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
216 {
217 ALOGV("out_get_channels");
218 struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
219 return audio_channel_out_mask_from_count(out->config.channels);
220 }
221
out_get_format(const struct audio_stream * stream)222 static audio_format_t out_get_format(const struct audio_stream *stream)
223 {
224 ALOGV("out_get_format");
225 struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
226 return audio_format_from_pcm_format(out->config.format);
227 }
228
out_set_format(struct audio_stream * stream,audio_format_t format)229 static int out_set_format(struct audio_stream *stream, audio_format_t format)
230 {
231 ALOGV("out_set_format: %d",format);
232 return -ENOSYS;
233 }
234
do_output_standby(struct alsa_stream_out * out)235 static int do_output_standby(struct alsa_stream_out *out)
236 {
237 struct alsa_audio_device *adev = out->dev;
238
239 fir_reset(out->speaker_eq);
240
241 if (!out->standby) {
242 pcm_close(out->pcm);
243 out->pcm = NULL;
244 adev->active_output = NULL;
245 out->standby = 1;
246 }
247 aec_set_spk_running(adev->aec, false);
248 return 0;
249 }
250
out_standby(struct audio_stream * stream)251 static int out_standby(struct audio_stream *stream)
252 {
253 ALOGV("out_standby");
254 struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
255 int status;
256
257 pthread_mutex_lock(&out->dev->lock);
258 pthread_mutex_lock(&out->lock);
259 status = do_output_standby(out);
260 pthread_mutex_unlock(&out->lock);
261 pthread_mutex_unlock(&out->dev->lock);
262 return status;
263 }
264
out_dump(const struct audio_stream * stream,int fd)265 static int out_dump(const struct audio_stream *stream, int fd)
266 {
267 ALOGV("out_dump");
268 return 0;
269 }
270
out_set_parameters(struct audio_stream * stream,const char * kvpairs)271 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
272 {
273 ALOGV("out_set_parameters");
274 struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
275 struct alsa_audio_device *adev = out->dev;
276 struct str_parms *parms;
277 char value[32];
278 int ret, val = 0;
279
280 parms = str_parms_create_str(kvpairs);
281
282 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
283 if (ret >= 0) {
284 val = atoi(value);
285 pthread_mutex_lock(&adev->lock);
286 pthread_mutex_lock(&out->lock);
287 if (((out->devices & AUDIO_DEVICE_OUT_ALL) != val) && (val != 0)) {
288 out->devices &= ~AUDIO_DEVICE_OUT_ALL;
289 out->devices |= val;
290 }
291 pthread_mutex_unlock(&out->lock);
292 pthread_mutex_unlock(&adev->lock);
293 }
294
295 str_parms_destroy(parms);
296 return 0;
297 }
298
out_get_parameters(const struct audio_stream * stream,const char * keys)299 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
300 {
301 ALOGV("out_get_parameters");
302 return strdup("");
303 }
304
out_get_latency(const struct audio_stream_out * stream)305 static uint32_t out_get_latency(const struct audio_stream_out *stream)
306 {
307 ALOGV("out_get_latency");
308 struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
309 return (PLAYBACK_PERIOD_SIZE * PLAYBACK_PERIOD_COUNT * 1000) / out->config.rate;
310 }
311
out_set_volume(struct audio_stream_out * stream,float left,float right)312 static int out_set_volume(struct audio_stream_out *stream, float left,
313 float right)
314 {
315 ALOGV("out_set_volume: Left:%f Right:%f", left, right);
316 return -ENOSYS;
317 }
318
out_write(struct audio_stream_out * stream,const void * buffer,size_t bytes)319 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
320 size_t bytes)
321 {
322 int ret;
323 struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
324 struct alsa_audio_device *adev = out->dev;
325 size_t frame_size = audio_stream_out_frame_size(stream);
326 size_t out_frames = bytes / frame_size;
327
328 ALOGV("%s: devices: %d, bytes %zu", __func__, out->devices, bytes);
329
330 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
331 * on the output stream mutex - e.g. executing select_mode() while holding the hw device
332 * mutex
333 */
334 pthread_mutex_lock(&adev->lock);
335 pthread_mutex_lock(&out->lock);
336 if (out->standby) {
337 ret = start_output_stream(out);
338 if (ret != 0) {
339 pthread_mutex_unlock(&adev->lock);
340 goto exit;
341 }
342 out->standby = 0;
343 aec_set_spk_running(adev->aec, true);
344 }
345
346 pthread_mutex_unlock(&adev->lock);
347
348 if (out->speaker_eq != NULL) {
349 fir_process_interleaved(out->speaker_eq, (int16_t*)buffer, (int16_t*)buffer, out_frames);
350 }
351
352 ret = pcm_write(out->pcm, buffer, out_frames * frame_size);
353 if (ret == 0) {
354 out->frames_written += out_frames;
355
356 struct aec_info info;
357 get_pcm_timestamp(out->pcm, out->config.rate, &info, true /*isOutput*/);
358 out->timestamp = info.timestamp;
359 info.bytes = out_frames * frame_size;
360 int aec_ret = write_to_reference_fifo(adev->aec, (void *)buffer, &info);
361 if (aec_ret) {
362 ALOGE("AEC: Write to speaker loopback FIFO failed!");
363 }
364 }
365
366 exit:
367 pthread_mutex_unlock(&out->lock);
368
369 if (ret != 0) {
370 usleep((int64_t)bytes * 1000000 / audio_stream_out_frame_size(stream) /
371 out_get_sample_rate(&stream->common));
372 }
373
374 return bytes;
375 }
376
out_get_render_position(const struct audio_stream_out * stream,uint32_t * dsp_frames)377 static int out_get_render_position(const struct audio_stream_out *stream,
378 uint32_t *dsp_frames)
379 {
380 ALOGV("out_get_render_position: dsp_frames: %p", dsp_frames);
381 return -ENOSYS;
382 }
383
out_get_presentation_position(const struct audio_stream_out * stream,uint64_t * frames,struct timespec * timestamp)384 static int out_get_presentation_position(const struct audio_stream_out *stream,
385 uint64_t *frames, struct timespec *timestamp)
386 {
387 if (stream == NULL || frames == NULL || timestamp == NULL) {
388 return -EINVAL;
389 }
390 struct alsa_stream_out* out = (struct alsa_stream_out*)stream;
391
392 *frames = out->frames_written;
393 *timestamp = out->timestamp;
394 ALOGV("%s: frames: %" PRIu64 ", timestamp (nsec): %" PRIu64, __func__, *frames,
395 audio_utils_ns_from_timespec(timestamp));
396
397 return 0;
398 }
399
400
out_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)401 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
402 {
403 ALOGV("out_add_audio_effect: %p", effect);
404 return 0;
405 }
406
out_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)407 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
408 {
409 ALOGV("out_remove_audio_effect: %p", effect);
410 return 0;
411 }
412
out_get_next_write_timestamp(const struct audio_stream_out * stream,int64_t * timestamp)413 static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
414 int64_t *timestamp)
415 {
416 *timestamp = 0;
417 ALOGV("out_get_next_write_timestamp: %ld", (long int)(*timestamp));
418 return -ENOSYS;
419 }
420
421 /** audio_stream_in implementation **/
422
423 /* must be called with hw device and input stream mutexes locked */
start_input_stream(struct alsa_stream_in * in)424 static int start_input_stream(struct alsa_stream_in *in)
425 {
426 struct alsa_audio_device *adev = in->dev;
427 in->unavailable = true;
428 unsigned int pcm_retry_count = PCM_OPEN_RETRIES;
429
430 while (1) {
431 in->pcm = pcm_open(CARD_IN, PORT_BUILTIN_MIC, PCM_IN | PCM_MONOTONIC, &in->config);
432 if ((in->pcm != NULL) && pcm_is_ready(in->pcm)) {
433 break;
434 } else {
435 ALOGE("cannot open pcm_in driver: %s", pcm_get_error(in->pcm));
436 if (in->pcm != NULL) {
437 pcm_close(in->pcm);
438 in->pcm = NULL;
439 }
440 if (--pcm_retry_count == 0) {
441 ALOGE("Failed to open pcm_in after %d tries", PCM_OPEN_RETRIES);
442 return -ENODEV;
443 }
444 usleep(PCM_OPEN_WAIT_TIME_MS * 1000);
445 }
446 }
447 in->unavailable = false;
448 adev->active_input = in;
449 return 0;
450 }
451
get_mic_characteristics(struct audio_microphone_characteristic_t * mic_data,size_t * mic_count)452 static void get_mic_characteristics(struct audio_microphone_characteristic_t* mic_data,
453 size_t* mic_count) {
454 *mic_count = 1;
455 memset(mic_data, 0, sizeof(struct audio_microphone_characteristic_t));
456 strlcpy(mic_data->device_id, "builtin_mic", AUDIO_MICROPHONE_ID_MAX_LEN - 1);
457 strlcpy(mic_data->address, "top", AUDIO_DEVICE_MAX_ADDRESS_LEN - 1);
458 memset(mic_data->channel_mapping, AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED,
459 sizeof(mic_data->channel_mapping));
460 mic_data->device = AUDIO_DEVICE_IN_BUILTIN_MIC;
461 mic_data->sensitivity = -37.0;
462 mic_data->max_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
463 mic_data->min_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
464 mic_data->orientation.x = 0.0f;
465 mic_data->orientation.y = 0.0f;
466 mic_data->orientation.z = 0.0f;
467 mic_data->geometric_location.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
468 mic_data->geometric_location.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
469 mic_data->geometric_location.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
470 }
471
in_get_sample_rate(const struct audio_stream * stream)472 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
473 {
474 struct alsa_stream_in *in = (struct alsa_stream_in *)stream;
475 return in->config.rate;
476 }
477
in_set_sample_rate(struct audio_stream * stream,uint32_t rate)478 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
479 {
480 ALOGV("in_set_sample_rate: %d", rate);
481 return -ENOSYS;
482 }
483
get_input_buffer_size(size_t frames,audio_format_t format,audio_channel_mask_t channel_mask)484 static size_t get_input_buffer_size(size_t frames, audio_format_t format,
485 audio_channel_mask_t channel_mask) {
486 /* return the closest majoring multiple of 16 frames, as
487 * audioflinger expects audio buffers to be a multiple of 16 frames */
488 frames = ((frames + 15) / 16) * 16;
489 size_t bytes_per_frame = audio_channel_count_from_in_mask(channel_mask) *
490 audio_bytes_per_sample(format);
491 size_t buffer_size = frames * bytes_per_frame;
492 return buffer_size;
493 }
494
in_get_channels(const struct audio_stream * stream)495 static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
496 {
497 struct alsa_stream_in *in = (struct alsa_stream_in *)stream;
498 ALOGV("in_get_channels: %d", in->config.channels);
499 return audio_channel_in_mask_from_count(in->config.channels);
500 }
501
in_get_format(const struct audio_stream * stream)502 static audio_format_t in_get_format(const struct audio_stream *stream)
503 {
504 struct alsa_stream_in *in = (struct alsa_stream_in *)stream;
505 ALOGV("in_get_format: %d", in->config.format);
506 return audio_format_from_pcm_format(in->config.format);
507 }
508
in_set_format(struct audio_stream * stream,audio_format_t format)509 static int in_set_format(struct audio_stream *stream, audio_format_t format)
510 {
511 return -ENOSYS;
512 }
513
in_get_buffer_size(const struct audio_stream * stream)514 static size_t in_get_buffer_size(const struct audio_stream *stream)
515 {
516 struct alsa_stream_in* in = (struct alsa_stream_in*)stream;
517 size_t frames = CAPTURE_PERIOD_SIZE;
518 if (in->source == AUDIO_SOURCE_ECHO_REFERENCE) {
519 frames = CAPTURE_PERIOD_SIZE * PLAYBACK_CODEC_SAMPLING_RATE / CAPTURE_CODEC_SAMPLING_RATE;
520 }
521
522 size_t buffer_size =
523 get_input_buffer_size(frames, stream->get_format(stream), stream->get_channels(stream));
524 ALOGV("in_get_buffer_size: %zu", buffer_size);
525 return buffer_size;
526 }
527
in_get_active_microphones(const struct audio_stream_in * stream,struct audio_microphone_characteristic_t * mic_array,size_t * mic_count)528 static int in_get_active_microphones(const struct audio_stream_in* stream,
529 struct audio_microphone_characteristic_t* mic_array,
530 size_t* mic_count) {
531 ALOGV("in_get_active_microphones");
532 if ((mic_array == NULL) || (mic_count == NULL)) {
533 return -EINVAL;
534 }
535 struct alsa_stream_in* in = (struct alsa_stream_in*)stream;
536 struct audio_hw_device* dev = (struct audio_hw_device*)in->dev;
537 bool mic_muted = false;
538 adev_get_mic_mute(dev, &mic_muted);
539 if ((in->source == AUDIO_SOURCE_ECHO_REFERENCE) || mic_muted) {
540 *mic_count = 0;
541 return 0;
542 }
543 adev_get_microphones(dev, mic_array, mic_count);
544 return 0;
545 }
546
do_input_standby(struct alsa_stream_in * in)547 static int do_input_standby(struct alsa_stream_in *in)
548 {
549 struct alsa_audio_device *adev = in->dev;
550
551 if (!in->standby) {
552 pcm_close(in->pcm);
553 in->pcm = NULL;
554 adev->active_input = NULL;
555 in->standby = true;
556 }
557 return 0;
558 }
559
in_standby(struct audio_stream * stream)560 static int in_standby(struct audio_stream *stream)
561 {
562 struct alsa_stream_in *in = (struct alsa_stream_in *)stream;
563 int status;
564
565 pthread_mutex_lock(&in->lock);
566 pthread_mutex_lock(&in->dev->lock);
567 status = do_input_standby(in);
568 pthread_mutex_unlock(&in->dev->lock);
569 pthread_mutex_unlock(&in->lock);
570 return status;
571 }
572
in_dump(const struct audio_stream * stream,int fd)573 static int in_dump(const struct audio_stream *stream, int fd)
574 {
575 struct alsa_stream_in* in = (struct alsa_stream_in*)stream;
576 if (in->source == AUDIO_SOURCE_ECHO_REFERENCE) {
577 return 0;
578 }
579
580 struct audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT];
581 size_t mic_count;
582
583 get_mic_characteristics(mic_array, &mic_count);
584
585 dprintf(fd, " Microphone count: %zd\n", mic_count);
586 size_t idx;
587 for (idx = 0; idx < mic_count; idx++) {
588 dprintf(fd, " Microphone: %zd\n", idx);
589 dprintf(fd, " Address: %s\n", mic_array[idx].address);
590 dprintf(fd, " Device: %d\n", mic_array[idx].device);
591 dprintf(fd, " Sensitivity (dB): %.2f\n", mic_array[idx].sensitivity);
592 }
593
594 return 0;
595 }
596
in_set_parameters(struct audio_stream * stream,const char * kvpairs)597 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
598 {
599 return 0;
600 }
601
in_get_parameters(const struct audio_stream * stream,const char * keys)602 static char * in_get_parameters(const struct audio_stream *stream,
603 const char *keys)
604 {
605 return strdup("");
606 }
607
in_set_gain(struct audio_stream_in * stream,float gain)608 static int in_set_gain(struct audio_stream_in *stream, float gain)
609 {
610 return 0;
611 }
612
in_read(struct audio_stream_in * stream,void * buffer,size_t bytes)613 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
614 size_t bytes)
615 {
616 int ret;
617 struct alsa_stream_in *in = (struct alsa_stream_in *)stream;
618 struct alsa_audio_device *adev = in->dev;
619 size_t frame_size = audio_stream_in_frame_size(stream);
620 size_t in_frames = bytes / frame_size;
621
622 ALOGV("in_read: stream: %d, bytes %zu", in->source, bytes);
623
624 /* Special handling for Echo Reference: simply get the reference from FIFO.
625 * The format and sample rate should be specified by arguments to adev_open_input_stream. */
626 if (in->source == AUDIO_SOURCE_ECHO_REFERENCE) {
627 struct aec_info info;
628 info.bytes = bytes;
629
630 const uint64_t time_increment_nsec = (uint64_t)bytes * NANOS_PER_SECOND /
631 audio_stream_in_frame_size(stream) /
632 in_get_sample_rate(&stream->common);
633 if (!aec_get_spk_running(adev->aec)) {
634 if (in->timestamp_nsec == 0) {
635 struct timespec now;
636 clock_gettime(CLOCK_MONOTONIC, &now);
637 const uint64_t timestamp_nsec = audio_utils_ns_from_timespec(&now);
638 in->timestamp_nsec = timestamp_nsec;
639 } else {
640 in->timestamp_nsec += time_increment_nsec;
641 }
642 memset(buffer, 0, bytes);
643 const uint64_t time_increment_usec = time_increment_nsec / 1000;
644 usleep(time_increment_usec);
645 } else {
646 int ref_ret = get_reference_samples(adev->aec, buffer, &info);
647 if ((ref_ret) || (info.timestamp_usec == 0)) {
648 memset(buffer, 0, bytes);
649 in->timestamp_nsec += time_increment_nsec;
650 } else {
651 in->timestamp_nsec = 1000 * info.timestamp_usec;
652 }
653 }
654 in->frames_read += in_frames;
655
656 #if DEBUG_AEC
657 FILE* fp_ref = fopen("/data/local/traces/aec_ref.pcm", "a+");
658 if (fp_ref) {
659 fwrite((char*)buffer, 1, bytes, fp_ref);
660 fclose(fp_ref);
661 } else {
662 ALOGE("AEC debug: Could not open file aec_ref.pcm!");
663 }
664 FILE* fp_ref_ts = fopen("/data/local/traces/aec_ref_timestamps.txt", "a+");
665 if (fp_ref_ts) {
666 fprintf(fp_ref_ts, "%" PRIu64 "\n", in->timestamp_nsec);
667 fclose(fp_ref_ts);
668 } else {
669 ALOGE("AEC debug: Could not open file aec_ref_timestamps.txt!");
670 }
671 #endif
672 return info.bytes;
673 }
674
675 /* Microphone input stream read */
676
677 /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
678 * on the input stream mutex - e.g. executing select_mode() while holding the hw device
679 * mutex
680 */
681 pthread_mutex_lock(&in->lock);
682 pthread_mutex_lock(&adev->lock);
683 if (in->standby) {
684 ret = start_input_stream(in);
685 if (ret != 0) {
686 pthread_mutex_unlock(&adev->lock);
687 ALOGE("start_input_stream failed with code %d", ret);
688 goto exit;
689 }
690 in->standby = false;
691 }
692
693 pthread_mutex_unlock(&adev->lock);
694
695 ret = pcm_read(in->pcm, buffer, in_frames * frame_size);
696 struct aec_info info;
697 get_pcm_timestamp(in->pcm, in->config.rate, &info, false /*isOutput*/);
698 if (ret == 0) {
699 in->frames_read += in_frames;
700 in->timestamp_nsec = audio_utils_ns_from_timespec(&info.timestamp);
701 }
702 else {
703 ALOGE("pcm_read failed with code %d", ret);
704 }
705
706 exit:
707 pthread_mutex_unlock(&in->lock);
708
709 bool mic_muted = false;
710 adev_get_mic_mute((struct audio_hw_device*)adev, &mic_muted);
711 if (mic_muted) {
712 memset(buffer, 0, bytes);
713 }
714
715 if (ret != 0) {
716 usleep((int64_t)bytes * 1000000 / audio_stream_in_frame_size(stream) /
717 in_get_sample_rate(&stream->common));
718 } else {
719 /* Process AEC if available */
720 /* TODO move to a separate thread */
721 if (!mic_muted) {
722 info.bytes = bytes;
723 int aec_ret = process_aec(adev->aec, buffer, &info);
724 if (aec_ret) {
725 ALOGE("process_aec returned error code %d", aec_ret);
726 }
727 }
728 }
729
730 #if DEBUG_AEC && !defined(AEC_HAL)
731 FILE* fp_in = fopen("/data/local/traces/aec_in.pcm", "a+");
732 if (fp_in) {
733 fwrite((char*)buffer, 1, bytes, fp_in);
734 fclose(fp_in);
735 } else {
736 ALOGE("AEC debug: Could not open file aec_in.pcm!");
737 }
738 FILE* fp_mic_ts = fopen("/data/local/traces/aec_in_timestamps.txt", "a+");
739 if (fp_mic_ts) {
740 fprintf(fp_mic_ts, "%" PRIu64 "\n", in->timestamp_nsec);
741 fclose(fp_mic_ts);
742 } else {
743 ALOGE("AEC debug: Could not open file aec_in_timestamps.txt!");
744 }
745 #endif
746
747 return bytes;
748 }
749
in_get_capture_position(const struct audio_stream_in * stream,int64_t * frames,int64_t * time)750 static int in_get_capture_position(const struct audio_stream_in* stream, int64_t* frames,
751 int64_t* time) {
752 if (stream == NULL || frames == NULL || time == NULL) {
753 return -EINVAL;
754 }
755 struct alsa_stream_in* in = (struct alsa_stream_in*)stream;
756
757 *frames = in->frames_read;
758 *time = in->timestamp_nsec;
759 ALOGV("%s: source: %d, timestamp (nsec): %" PRIu64, __func__, in->source, *time);
760
761 return 0;
762 }
763
in_get_input_frames_lost(struct audio_stream_in * stream)764 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
765 {
766 return 0;
767 }
768
in_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)769 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
770 {
771 return 0;
772 }
773
in_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)774 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
775 {
776 return 0;
777 }
778
adev_open_output_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,audio_output_flags_t flags,struct audio_config * config,struct audio_stream_out ** stream_out,const char * address __unused)779 static int adev_open_output_stream(struct audio_hw_device *dev,
780 audio_io_handle_t handle,
781 audio_devices_t devices,
782 audio_output_flags_t flags,
783 struct audio_config *config,
784 struct audio_stream_out **stream_out,
785 const char *address __unused)
786 {
787 ALOGV("adev_open_output_stream...");
788
789 struct alsa_audio_device *ladev = (struct alsa_audio_device *)dev;
790 struct alsa_stream_out *out;
791 struct pcm_params *params;
792 int ret = 0;
793
794 int out_port = get_audio_output_port(devices);
795
796 params = pcm_params_get(CARD_OUT, out_port, PCM_OUT);
797 if (!params)
798 return -ENOSYS;
799
800 out = (struct alsa_stream_out *)calloc(1, sizeof(struct alsa_stream_out));
801 if (!out)
802 return -ENOMEM;
803
804 out->stream.common.get_sample_rate = out_get_sample_rate;
805 out->stream.common.set_sample_rate = out_set_sample_rate;
806 out->stream.common.get_buffer_size = out_get_buffer_size;
807 out->stream.common.get_channels = out_get_channels;
808 out->stream.common.get_format = out_get_format;
809 out->stream.common.set_format = out_set_format;
810 out->stream.common.standby = out_standby;
811 out->stream.common.dump = out_dump;
812 out->stream.common.set_parameters = out_set_parameters;
813 out->stream.common.get_parameters = out_get_parameters;
814 out->stream.common.add_audio_effect = out_add_audio_effect;
815 out->stream.common.remove_audio_effect = out_remove_audio_effect;
816 out->stream.get_latency = out_get_latency;
817 out->stream.set_volume = out_set_volume;
818 out->stream.write = out_write;
819 out->stream.get_render_position = out_get_render_position;
820 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
821 out->stream.get_presentation_position = out_get_presentation_position;
822
823 out->config.channels = CHANNEL_STEREO;
824 out->config.rate = PLAYBACK_CODEC_SAMPLING_RATE;
825 out->config.format = PCM_FORMAT_S16_LE;
826 out->config.period_size = PLAYBACK_PERIOD_SIZE;
827 out->config.period_count = PLAYBACK_PERIOD_COUNT;
828
829 if (out->config.rate != config->sample_rate ||
830 audio_channel_count_from_out_mask(config->channel_mask) != CHANNEL_STEREO ||
831 out->config.format != pcm_format_from_audio_format(config->format) ) {
832 config->sample_rate = out->config.rate;
833 config->format = audio_format_from_pcm_format(out->config.format);
834 config->channel_mask = audio_channel_out_mask_from_count(CHANNEL_STEREO);
835 ret = -EINVAL;
836 }
837
838 ALOGI("adev_open_output_stream selects channels=%d rate=%d format=%d, devices=%d",
839 out->config.channels, out->config.rate, out->config.format, devices);
840
841 out->dev = ladev;
842 out->standby = 1;
843 out->unavailable = false;
844 out->devices = devices;
845
846 config->format = out_get_format(&out->stream.common);
847 config->channel_mask = out_get_channels(&out->stream.common);
848 config->sample_rate = out_get_sample_rate(&out->stream.common);
849
850 *stream_out = &out->stream;
851
852 out->speaker_eq = NULL;
853 if (out_port == PORT_INTERNAL_SPEAKER) {
854 out_set_eq(out);
855 if (out->speaker_eq == NULL) {
856 ALOGE("%s: Failed to initialize speaker EQ", __func__);
857 }
858 }
859
860 /* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger. */
861 ret = 0;
862
863 if (ret == 0) {
864 int aec_ret = init_aec_reference_config(ladev->aec, out);
865 if (aec_ret) {
866 ALOGE("AEC: Speaker config init failed!");
867 return -EINVAL;
868 }
869 }
870
871 return ret;
872 }
873
adev_close_output_stream(struct audio_hw_device * dev,struct audio_stream_out * stream)874 static void adev_close_output_stream(struct audio_hw_device *dev,
875 struct audio_stream_out *stream)
876 {
877 ALOGV("adev_close_output_stream...");
878 struct alsa_audio_device *adev = (struct alsa_audio_device *)dev;
879 destroy_aec_reference_config(adev->aec);
880 struct alsa_stream_out* out = (struct alsa_stream_out*)stream;
881 fir_release(out->speaker_eq);
882 free(stream);
883 }
884
adev_set_parameters(struct audio_hw_device * dev,const char * kvpairs)885 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
886 {
887 ALOGV("adev_set_parameters");
888 return -ENOSYS;
889 }
890
adev_get_parameters(const struct audio_hw_device * dev,const char * keys)891 static char * adev_get_parameters(const struct audio_hw_device *dev,
892 const char *keys)
893 {
894 ALOGV("adev_get_parameters");
895 return strdup("");
896 }
897
adev_get_microphones(const struct audio_hw_device * dev,struct audio_microphone_characteristic_t * mic_array,size_t * mic_count)898 static int adev_get_microphones(const struct audio_hw_device* dev,
899 struct audio_microphone_characteristic_t* mic_array,
900 size_t* mic_count) {
901 ALOGV("adev_get_microphones");
902 if ((mic_array == NULL) || (mic_count == NULL)) {
903 return -EINVAL;
904 }
905 get_mic_characteristics(mic_array, mic_count);
906 return 0;
907 }
908
adev_init_check(const struct audio_hw_device * dev)909 static int adev_init_check(const struct audio_hw_device *dev)
910 {
911 ALOGV("adev_init_check");
912 return 0;
913 }
914
adev_set_voice_volume(struct audio_hw_device * dev,float volume)915 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
916 {
917 ALOGV("adev_set_voice_volume: %f", volume);
918 return -ENOSYS;
919 }
920
adev_set_master_volume(struct audio_hw_device * dev,float volume)921 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
922 {
923 ALOGV("adev_set_master_volume: %f", volume);
924 return -ENOSYS;
925 }
926
adev_get_master_volume(struct audio_hw_device * dev,float * volume)927 static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
928 {
929 ALOGV("adev_get_master_volume: %f", *volume);
930 return -ENOSYS;
931 }
932
adev_set_master_mute(struct audio_hw_device * dev,bool muted)933 static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
934 {
935 ALOGV("adev_set_master_mute: %d", muted);
936 return -ENOSYS;
937 }
938
adev_get_master_mute(struct audio_hw_device * dev,bool * muted)939 static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
940 {
941 ALOGV("adev_get_master_mute: %d", *muted);
942 return -ENOSYS;
943 }
944
adev_set_mode(struct audio_hw_device * dev,audio_mode_t mode)945 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
946 {
947 ALOGV("adev_set_mode: %d", mode);
948 return 0;
949 }
950
adev_set_mic_mute(struct audio_hw_device * dev,bool state)951 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
952 {
953 ALOGV("adev_set_mic_mute: %d",state);
954 struct alsa_audio_device *adev = (struct alsa_audio_device *)dev;
955 pthread_mutex_lock(&adev->lock);
956 adev->mic_mute = state;
957 pthread_mutex_unlock(&adev->lock);
958 return 0;
959 }
960
adev_get_mic_mute(const struct audio_hw_device * dev,bool * state)961 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
962 {
963 ALOGV("adev_get_mic_mute");
964 struct alsa_audio_device *adev = (struct alsa_audio_device *)dev;
965 pthread_mutex_lock(&adev->lock);
966 *state = adev->mic_mute;
967 pthread_mutex_unlock(&adev->lock);
968 return 0;
969 }
970
adev_get_input_buffer_size(const struct audio_hw_device * dev,const struct audio_config * config)971 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
972 const struct audio_config *config)
973 {
974 size_t buffer_size =
975 get_input_buffer_size(CAPTURE_PERIOD_SIZE, config->format, config->channel_mask);
976 ALOGV("adev_get_input_buffer_size: %zu", buffer_size);
977 return buffer_size;
978 }
979
adev_open_input_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,struct audio_config * config,struct audio_stream_in ** stream_in,audio_input_flags_t flags __unused,const char * address __unused,audio_source_t source)980 static int adev_open_input_stream(struct audio_hw_device* dev, audio_io_handle_t handle,
981 audio_devices_t devices, struct audio_config* config,
982 struct audio_stream_in** stream_in,
983 audio_input_flags_t flags __unused, const char* address __unused,
984 audio_source_t source) {
985 ALOGV("adev_open_input_stream...");
986
987 struct alsa_audio_device *ladev = (struct alsa_audio_device *)dev;
988 struct alsa_stream_in *in;
989 struct pcm_params *params;
990 int ret = 0;
991
992 params = pcm_params_get(CARD_IN, PORT_BUILTIN_MIC, PCM_IN);
993 if (!params)
994 return -ENOSYS;
995
996 in = (struct alsa_stream_in *)calloc(1, sizeof(struct alsa_stream_in));
997 if (!in)
998 return -ENOMEM;
999
1000 in->stream.common.get_sample_rate = in_get_sample_rate;
1001 in->stream.common.set_sample_rate = in_set_sample_rate;
1002 in->stream.common.get_buffer_size = in_get_buffer_size;
1003 in->stream.common.get_channels = in_get_channels;
1004 in->stream.common.get_format = in_get_format;
1005 in->stream.common.set_format = in_set_format;
1006 in->stream.common.standby = in_standby;
1007 in->stream.common.dump = in_dump;
1008 in->stream.common.set_parameters = in_set_parameters;
1009 in->stream.common.get_parameters = in_get_parameters;
1010 in->stream.common.add_audio_effect = in_add_audio_effect;
1011 in->stream.common.remove_audio_effect = in_remove_audio_effect;
1012 in->stream.set_gain = in_set_gain;
1013 in->stream.read = in_read;
1014 in->stream.get_input_frames_lost = in_get_input_frames_lost;
1015 in->stream.get_capture_position = in_get_capture_position;
1016 in->stream.get_active_microphones = in_get_active_microphones;
1017
1018 in->config.channels = CHANNEL_STEREO;
1019 if (source == AUDIO_SOURCE_ECHO_REFERENCE) {
1020 in->config.rate = PLAYBACK_CODEC_SAMPLING_RATE;
1021 } else {
1022 in->config.rate = CAPTURE_CODEC_SAMPLING_RATE;
1023 }
1024 in->config.format = PCM_FORMAT_S32_LE;
1025 in->config.period_size = CAPTURE_PERIOD_SIZE;
1026 in->config.period_count = CAPTURE_PERIOD_COUNT;
1027
1028 if (in->config.rate != config->sample_rate ||
1029 audio_channel_count_from_in_mask(config->channel_mask) != CHANNEL_STEREO ||
1030 in->config.format != pcm_format_from_audio_format(config->format) ) {
1031 ret = -EINVAL;
1032 }
1033
1034 ALOGI("adev_open_input_stream selects channels=%d rate=%d format=%d source=%d",
1035 in->config.channels, in->config.rate, in->config.format, source);
1036
1037 in->dev = ladev;
1038 in->standby = true;
1039 in->unavailable = false;
1040 in->source = source;
1041 in->devices = devices;
1042
1043 config->format = in_get_format(&in->stream.common);
1044 config->channel_mask = in_get_channels(&in->stream.common);
1045 config->sample_rate = in_get_sample_rate(&in->stream.common);
1046
1047 /* If AEC is in the app, only configure based on ECHO_REFERENCE spec.
1048 * If AEC is in the HAL, configure using the given mic stream. */
1049 bool aecInput = true;
1050 #if !defined(AEC_HAL)
1051 aecInput = (in->source == AUDIO_SOURCE_ECHO_REFERENCE);
1052 #endif
1053
1054 if ((ret == 0) && aecInput) {
1055 int aec_ret = init_aec_mic_config(ladev->aec, in);
1056 if (aec_ret) {
1057 ALOGE("AEC: Mic config init failed!");
1058 return -EINVAL;
1059 }
1060 }
1061
1062 if (ret) {
1063 free(in);
1064 } else {
1065 *stream_in = &in->stream;
1066 }
1067
1068 #if DEBUG_AEC
1069 remove("/data/local/traces/aec_ref.pcm");
1070 remove("/data/local/traces/aec_in.pcm");
1071 remove("/data/local/traces/aec_ref_timestamps.txt");
1072 remove("/data/local/traces/aec_in_timestamps.txt");
1073 #endif
1074 return ret;
1075 }
1076
adev_close_input_stream(struct audio_hw_device * dev,struct audio_stream_in * stream)1077 static void adev_close_input_stream(struct audio_hw_device *dev,
1078 struct audio_stream_in *stream)
1079 {
1080 ALOGV("adev_close_input_stream...");
1081 struct alsa_audio_device *adev = (struct alsa_audio_device *)dev;
1082 destroy_aec_mic_config(adev->aec);
1083 free(stream);
1084 return;
1085 }
1086
adev_dump(const audio_hw_device_t * device,int fd)1087 static int adev_dump(const audio_hw_device_t *device, int fd)
1088 {
1089 ALOGV("adev_dump");
1090 return 0;
1091 }
1092
adev_close(hw_device_t * device)1093 static int adev_close(hw_device_t *device)
1094 {
1095 ALOGV("adev_close");
1096
1097 struct alsa_audio_device *adev = (struct alsa_audio_device *)device;
1098 release_aec(adev->aec);
1099 free(device);
1100 return 0;
1101 }
1102
adev_open(const hw_module_t * module,const char * name,hw_device_t ** device)1103 static int adev_open(const hw_module_t* module, const char* name,
1104 hw_device_t** device)
1105 {
1106 struct alsa_audio_device *adev;
1107
1108 ALOGV("adev_open: %s", name);
1109
1110 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
1111 return -EINVAL;
1112
1113 adev = calloc(1, sizeof(struct alsa_audio_device));
1114 if (!adev)
1115 return -ENOMEM;
1116
1117 adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
1118 adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
1119 adev->hw_device.common.module = (struct hw_module_t *) module;
1120 adev->hw_device.common.close = adev_close;
1121 adev->hw_device.init_check = adev_init_check;
1122 adev->hw_device.set_voice_volume = adev_set_voice_volume;
1123 adev->hw_device.set_master_volume = adev_set_master_volume;
1124 adev->hw_device.get_master_volume = adev_get_master_volume;
1125 adev->hw_device.set_master_mute = adev_set_master_mute;
1126 adev->hw_device.get_master_mute = adev_get_master_mute;
1127 adev->hw_device.set_mode = adev_set_mode;
1128 adev->hw_device.set_mic_mute = adev_set_mic_mute;
1129 adev->hw_device.get_mic_mute = adev_get_mic_mute;
1130 adev->hw_device.set_parameters = adev_set_parameters;
1131 adev->hw_device.get_parameters = adev_get_parameters;
1132 adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
1133 adev->hw_device.open_output_stream = adev_open_output_stream;
1134 adev->hw_device.close_output_stream = adev_close_output_stream;
1135 adev->hw_device.open_input_stream = adev_open_input_stream;
1136 adev->hw_device.close_input_stream = adev_close_input_stream;
1137 adev->hw_device.dump = adev_dump;
1138 adev->hw_device.get_microphones = adev_get_microphones;
1139
1140 *device = &adev->hw_device.common;
1141
1142 adev->mixer = mixer_open(CARD_OUT);
1143
1144 if (!adev->mixer) {
1145 ALOGE("Unable to open the mixer, aborting.");
1146 return -EINVAL;
1147 }
1148
1149 adev->audio_route = audio_route_init(CARD_OUT, MIXER_XML_PATH);
1150 if (!adev->audio_route) {
1151 ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
1152 return -EINVAL;
1153 }
1154
1155 pthread_mutex_lock(&adev->lock);
1156 if (init_aec(CAPTURE_CODEC_SAMPLING_RATE, NUM_AEC_REFERENCE_CHANNELS,
1157 CHANNEL_STEREO, &adev->aec)) {
1158 pthread_mutex_unlock(&adev->lock);
1159 return -EINVAL;
1160 }
1161 pthread_mutex_unlock(&adev->lock);
1162
1163 return 0;
1164 }
1165
1166 static struct hw_module_methods_t hal_module_methods = {
1167 .open = adev_open,
1168 };
1169
1170 struct audio_module HAL_MODULE_INFO_SYM = {
1171 .common = {
1172 .tag = HARDWARE_MODULE_TAG,
1173 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
1174 .hal_api_version = HARDWARE_HAL_API_VERSION,
1175 .id = AUDIO_HARDWARE_MODULE_ID,
1176 .name = "Yukawa audio HW HAL",
1177 .author = "The Android Open Source Project",
1178 .methods = &hal_module_methods,
1179 },
1180 };
1181