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