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