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(¶ms, &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