summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'audio/primary/audio_hw.c')
-rw-r--r--audio/primary/audio_hw.c1770
1 files changed, 1770 insertions, 0 deletions
diff --git a/audio/primary/audio_hw.c b/audio/primary/audio_hw.c
new file mode 100644
index 0000000..95f0f06
--- /dev/null
+++ b/audio/primary/audio_hw.c
@@ -0,0 +1,1770 @@
1/*
2 * Copyright (C) 2013 Texas Instruments
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_primary"
18//#define LOG_NDEBUG 0
19//#define VERY_VERBOSE_LOGGING
20#ifdef VERY_VERBOSE_LOGGING
21#define ALOGVV ALOGV
22#else
23#define ALOGVV(a...) do { } while(0)
24#endif
25
26#include <errno.h>
27#include <stdint.h>
28#include <stdlib.h>
29#include <sys/time.h>
30
31#include <cutils/log.h>
32#include <cutils/str_parms.h>
33#include <cutils/properties.h>
34
35#include <audio_utils/resampler.h>
36#include <audio_route/audio_route.h>
37#include <system/audio.h>
38#include <hardware/hardware.h>
39#include <hardware/audio.h>
40#include <hardware/audio_effect.h>
41
42#include <tinyalsa/asoundlib.h>
43
44#define UNUSED(x) (void)(x)
45
46/* yet another definition of ARRAY_SIZE macro) */
47#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
48
49/*
50 * additional space in resampler buffer allowing for extra samples to be returned
51 * by speex resampler when sample rates ratio is not an integer
52 */
53#define RESAMPLER_HEADROOM_FRAMES 10
54
55/* buffer_remix: functor for doing in-place buffer manipulations.
56 *
57 * NB. When remix_func is called, the memory at `buf` must be at least
58 * as large as frames * sample_size * MAX(in_chans, out_chans).
59 */
60struct buffer_remix {
61 void (*remix_func)(struct buffer_remix *data, void *buf, size_t frames);
62 size_t sample_size; /* size of one audio sample, in bytes */
63 size_t in_chans; /* number of input channels */
64 size_t out_chans; /* number of output channels */
65};
66
67struct j6_voice_stream {
68 struct j6_audio_device *dev;
69 struct pcm *pcm_in;
70 struct pcm *pcm_out;
71 struct pcm_config in_config;
72 struct pcm_config out_config;
73 struct resampler_itfe *resampler;
74 struct resampler_buffer_provider buf_provider;
75 struct buffer_remix *remix;
76 pthread_t thread;
77 int16_t *in_buffer;
78 int16_t *out_buffer;
79 size_t in_frames;
80 size_t out_frames;
81 size_t in_frame_size;
82 size_t out_frame_size;
83 char *name;
84};
85
86struct j6_voice {
87 struct j6_voice_stream ul;
88 struct j6_voice_stream dl;
89};
90
91struct j6_audio_device {
92 struct audio_hw_device device;
93 struct j6_stream_in *in;
94 struct j6_stream_out *out;
95 struct j6_voice voice;
96 struct audio_route *route;
97 audio_devices_t in_device;
98 audio_devices_t out_device;
99 pthread_mutex_t lock;
100 unsigned int card;
101 unsigned int in_port;
102 unsigned int out_port;
103 unsigned int bt_card;
104 unsigned int bt_port;
105 bool mic_mute;
106 bool in_call;
107 audio_mode_t mode;
108};
109
110struct j6_stream_in {
111 struct audio_stream_in stream;
112 struct j6_audio_device *dev;
113 struct pcm_config config;
114 struct pcm *pcm;
115 struct buffer_remix *remix; /* adapt hw chan count to client */
116 struct resampler_itfe *resampler;
117 struct resampler_buffer_provider buf_provider;
118 int16_t *buffer;
119 size_t frames_in;
120 size_t hw_frame_size;
121 unsigned int requested_rate;
122 unsigned int requested_channels;
123 int read_status;
124 pthread_mutex_t lock;
125 bool standby;
126};
127
128struct j6_stream_out {
129 struct audio_stream_out stream;
130 struct j6_audio_device *dev;
131 struct pcm_config config;
132 struct pcm *pcm;
133 struct timespec last;
134 pthread_mutex_t lock;
135 bool standby;
136 int64_t written; /* total frames written, not cleared when entering standby */
137};
138
139
140static const char *supported_media_cards[] = {
141 "dra7evm",
142 "VayuEVM",
143 "DRA7xxEVM",
144};
145
146static const char *supported_bt_cards[] = {
147 "DRA7xxWiLink",
148};
149
150#define SUPPORTED_IN_DEVICES (AUDIO_DEVICE_IN_BUILTIN_MIC | \
151 AUDIO_DEVICE_IN_WIRED_HEADSET | \
152 AUDIO_DEVICE_IN_DEFAULT)
153#define SUPPORTED_OUT_DEVICES (AUDIO_DEVICE_OUT_SPEAKER | \
154 AUDIO_DEVICE_OUT_WIRED_HEADSET | \
155 AUDIO_DEVICE_OUT_WIRED_HEADPHONE | \
156 AUDIO_DEVICE_OUT_DEFAULT)
157
158#define CAPTURE_SAMPLE_RATE 44100
159#define CAPTURE_PERIOD_SIZE 256
160#define CAPTURE_PERIOD_COUNT 4
161#define CAPTURE_BUFFER_SIZE (CAPTURE_PERIOD_SIZE * CAPTURE_PERIOD_COUNT)
162
163#define PLAYBACK_SAMPLE_RATE 44100
164#define PLAYBACK_PERIOD_SIZE 256
165#define PLAYBACK_PERIOD_COUNT 4
166#define PLAYBACK_BUFFER_SIZE (PLAYBACK_PERIOD_SIZE * PLAYBACK_PERIOD_COUNT)
167
168#define BT_SAMPLE_RATE 8000
169#define BT_PERIOD_SIZE 80
170#define BT_PERIOD_COUNT 4
171#define BT_BUFFER_SIZE (BT_PERIOD_SIZE * BT_PERIOD_COUNT)
172
173struct pcm_config pcm_config_capture = {
174 .channels = 2,
175 .rate = CAPTURE_SAMPLE_RATE,
176 .format = PCM_FORMAT_S16_LE,
177 .period_size = CAPTURE_PERIOD_SIZE,
178 .period_count = CAPTURE_PERIOD_COUNT,
179 .start_threshold = 1,
180 .stop_threshold = CAPTURE_BUFFER_SIZE,
181};
182
183struct pcm_config pcm_config_playback = {
184 .channels = 2,
185 .rate = PLAYBACK_SAMPLE_RATE,
186 .format = PCM_FORMAT_S16_LE,
187 .period_size = PLAYBACK_PERIOD_SIZE,
188 .period_count = PLAYBACK_PERIOD_COUNT,
189 .start_threshold = PLAYBACK_BUFFER_SIZE / 2,
190 .stop_threshold = PLAYBACK_BUFFER_SIZE,
191 .avail_min = PLAYBACK_PERIOD_SIZE,
192};
193
194struct pcm_config pcm_config_bt_in = {
195 .channels = 1,
196 .rate = BT_SAMPLE_RATE,
197 .format = PCM_FORMAT_S16_LE,
198 .period_size = BT_PERIOD_SIZE,
199 .period_count = BT_PERIOD_COUNT,
200};
201
202struct pcm_config pcm_config_bt_out = {
203 .channels = 1,
204 .rate = BT_SAMPLE_RATE,
205 .format = PCM_FORMAT_S16_LE,
206 .period_size = BT_PERIOD_SIZE,
207 .period_count = BT_PERIOD_COUNT,
208};
209
210static void do_out_standby(struct j6_stream_out *out);
211
212/* must be called with device lock held */
213static void select_input_device(struct j6_audio_device *adev)
214{
215 if (adev->in_device & ~SUPPORTED_IN_DEVICES)
216 ALOGW("select_input_device() device not supported, will use default device");
217}
218
219/* must be called with device lock held */
220static void select_output_device(struct j6_audio_device *adev)
221{
222 if (adev->out_device & ~SUPPORTED_OUT_DEVICES)
223 ALOGW("select_output_device() device(s) not supported, will use default devices");
224}
225
226static size_t get_input_buffer_size(uint32_t sample_rate, int format, int channel_count)
227{
228 size_t size;
229
230 /*
231 * take resampling into account and return the closest majoring
232 * multiple of 16 frames, as audioflinger expects audio buffers to
233 * be a multiple of 16 frames
234 */
235 size = (pcm_config_capture.period_size * sample_rate) / pcm_config_capture.rate;
236 size = ((size + 15) / 16) * 16;
237
238 return size * channel_count * audio_bytes_per_sample(format);
239}
240
241/*
242 * Implementation of buffer_remix::remix_func that removes
243 * channels in place without doing any other processing. The
244 * extra channels are truncated.
245 */
246static void remove_channels_from_buf(struct buffer_remix *data, void *buf, size_t frames)
247{
248 size_t samp_size, in_frame, out_frame;
249 size_t N, c;
250 char *s, *d;
251
252 ALOGVV("remove_channels_from_buf() remix=%p buf=%p frames=%u",
253 data, buf, frames);
254
255 if (frames == 0)
256 return;
257
258 samp_size = data->sample_size;
259 in_frame = data->in_chans * samp_size;
260 out_frame = data->out_chans * samp_size;
261
262 if (out_frame >= in_frame) {
263 ALOGE("BUG: remove_channels_from_buf() can not add channels to a buffer.\n");
264 return;
265 }
266
267 N = frames - 1;
268 d = (char*)buf + out_frame;
269 s = (char*)buf + in_frame;
270
271 /* take the first several channels and truncate the rest */
272 while (N--) {
273 for (c = 0; c < out_frame; ++c)
274 d[c] = s[c];
275 d += out_frame;
276 s += in_frame;
277 }
278}
279
280static int setup_stereo_to_mono_input_remix(struct j6_stream_in *in)
281{
282 ALOGV("setup_stereo_to_mono_input_remix() stream=%p", in);
283
284 struct buffer_remix *br = (struct buffer_remix *)calloc(1, sizeof(struct buffer_remix));
285 if (!br)
286 return -ENOMEM;
287
288 br->remix_func = remove_channels_from_buf;
289 br->sample_size = sizeof(int16_t);
290 br->in_chans = 2;
291 br->out_chans = 1;
292 in->remix = br;
293
294 return 0;
295}
296
297/*
298 * Implementation of buffer_remix::remix_func that duplicates the first
299 * channel into the rest of channels in the frame without doing any other
300 * processing
301 */
302static void duplicate_channels_from_mono(struct buffer_remix *data, void *buf, size_t frames)
303{
304 int samp_size, in_frame, out_frame;
305 int N, c;
306 char *s, *d;
307
308 ALOGVV("duplicate_channels_from_mono() remix=%p buf=%p frames=%u",
309 data, buf, frames);
310
311 if (frames == 0)
312 return;
313
314 samp_size = data->sample_size;
315 in_frame = data->in_chans * samp_size;
316 out_frame = data->out_chans * samp_size;
317
318 if (in_frame >= out_frame) {
319 ALOGE("BUG: duplicate_channels_from_mono() can not drop channels\n");
320 return;
321 }
322
323 N = frames - 1;
324 d = (char*)buf + N * out_frame;
325 s = (char*)buf + N * in_frame;
326
327 /* duplicate first channel into the rest of channels in the frame */
328 while (N-- >= 0) {
329 for (c = 0; c < out_frame; ++c)
330 d[c] = s[c % in_frame];
331 d -= out_frame;
332 s -= in_frame;
333 }
334}
335
336static int setup_voice_remix(struct j6_voice_stream *stream)
337{
338 ALOGVV("setup_voice_mono_to_stereo_input_remix() %s stream", stream->name);
339
340 struct buffer_remix *br = (struct buffer_remix *)calloc(1, sizeof(struct buffer_remix));
341 if (!br)
342 return -ENOMEM;
343
344 br->remix_func = duplicate_channels_from_mono;
345 br->sample_size = sizeof(int16_t);
346 br->in_chans = stream->in_config.channels;
347 br->out_chans = stream->out_config.channels;
348
349 if (br->in_chans == 1)
350 br->remix_func = duplicate_channels_from_mono;
351 else if (br->out_chans == 1)
352 br->remix_func = remove_channels_from_buf;
353 else
354 return -ENOTSUP;
355
356 stream->remix = br;
357
358 return 0;
359}
360
361static int voice_get_next_buffer(struct resampler_buffer_provider *buffer_provider,
362 struct resampler_buffer* buffer)
363{
364 struct j6_voice_stream *stream;
365 int ret;
366
367 if (buffer_provider == NULL || buffer == NULL) {
368 ALOGE("voice_get_next_buffer() invalid buffer/provider");
369 return -EINVAL;
370 }
371
372 stream = (struct j6_voice_stream *)((char *)buffer_provider -
373 offsetof(struct j6_voice_stream, buf_provider));
374
375 if (stream->pcm_in == NULL) {
376 buffer->raw = NULL;
377 buffer->frame_count = 0;
378 return -ENODEV;
379 }
380
381 if (buffer->frame_count > stream->in_frames) {
382 ALOGW("voice_get_next_buffer() %s unexpected frame count %u, "
383 "buffer was allocated for %u frames",
384 stream->name, buffer->frame_count, stream->in_frames);
385 buffer->frame_count = stream->in_frames;
386 }
387
388 ret = pcm_read(stream->pcm_in, stream->in_buffer,
389 buffer->frame_count * stream->in_frame_size);
390 if (ret) {
391 ALOGE("voice_get_next_buffer() failed to read %s: %s",
392 stream->name, pcm_get_error(stream->pcm_in));
393 buffer->raw = NULL;
394 buffer->frame_count = 0;
395 return ret;
396 }
397
398 buffer->i16 = stream->in_buffer;
399
400 return ret;
401}
402
403static void voice_release_buffer(struct resampler_buffer_provider *buffer_provider,
404 struct resampler_buffer* buffer)
405{
406 UNUSED(buffer_provider);
407 UNUSED(buffer);
408}
409
410static void *voice_thread_func(void *arg)
411{
412 struct j6_voice_stream *stream = (struct j6_voice_stream *)arg;
413 struct j6_audio_device *adev = stream->dev;
414 size_t frames = stream->out_frames;
415 uint32_t periods = 0;
416 uint32_t avail;
417 bool in_steady = false;
418 bool out_steady = false;
419 int ret = 0;
420
421 pcm_start(stream->pcm_in);
422
423 memset(stream->out_buffer, 0, stream->out_frames * stream->out_frame_size);
424
425 while (adev->in_call) {
426 if (out_steady) {
427 if (in_steady) {
428 stream->resampler->resample_from_provider(stream->resampler,
429 stream->out_buffer,
430 &frames);
431 } else {
432 avail = pcm_avail_update(stream->pcm_in);
433 if (avail > 0) {
434 in_steady = true;
435 continue;
436 }
437 }
438 } else if (++periods == stream->out_config.period_count) {
439 out_steady = true;
440 }
441
442 if (stream->remix)
443 stream->remix->remix_func(stream->remix, stream->out_buffer, frames);
444
445 ret = pcm_write(stream->pcm_out, stream->out_buffer,
446 frames * stream->out_frame_size);
447 if (ret) {
448 ALOGE("voice_thread_func() failed to write %s: %s",
449 stream->name, pcm_get_error(stream->pcm_out));
450 usleep((frames * 1000000) / stream->out_config.rate);
451 }
452 }
453
454 return (void*)ret;
455}
456
457static void voice_stream_exit(struct j6_voice_stream *stream)
458{
459 if (stream->resampler) {
460 release_resampler(stream->resampler);
461 stream->resampler = NULL;
462 }
463
464 if (stream->pcm_out) {
465 pcm_close(stream->pcm_out);
466 stream->pcm_out = NULL;
467 }
468
469 if (stream->pcm_in) {
470 pcm_close(stream->pcm_in);
471 stream->pcm_in = NULL;
472 }
473
474 if (stream->in_buffer) {
475 free(stream->in_buffer);
476 stream->in_buffer = NULL;
477 stream->in_frames = 0;
478 }
479
480 if (stream->out_buffer) {
481 free(stream->out_buffer);
482 stream->out_buffer = NULL;
483 stream->out_frames = 0;
484 }
485
486 if (stream->remix) {
487 free(stream->remix);
488 stream->remix = NULL;
489 }
490
491 if (stream->name) {
492 free(stream->name);
493 stream->name = NULL;
494 }
495}
496
497static int voice_stream_init(struct j6_voice_stream *stream,
498 unsigned int in_card,
499 unsigned int in_port,
500 unsigned int out_card,
501 unsigned int out_port)
502{
503 struct j6_audio_device *adev = stream->dev;
504 int frames;
505 int ret;
506
507 stream->buf_provider.get_next_buffer = voice_get_next_buffer;
508 stream->buf_provider.release_buffer = voice_release_buffer;
509 ret = create_resampler(stream->in_config.rate,
510 stream->out_config.rate,
511 stream->in_config.channels,
512 RESAMPLER_QUALITY_DEFAULT,
513 &stream->buf_provider,
514 &stream->resampler);
515 if (ret) {
516 ALOGE("voice_stream_init() failed to create %s resampler %d", stream->name, ret);
517 return ret;
518 }
519
520 stream->pcm_in = pcm_open(in_card, in_port,
521 PCM_IN | PCM_MONOTONIC,
522 &stream->in_config);
523 stream->pcm_out = pcm_open(out_card, out_port,
524 PCM_OUT | PCM_MONOTONIC,
525 &stream->out_config);
526
527 if (!pcm_is_ready(stream->pcm_in) || !pcm_is_ready(stream->pcm_out)) {
528 ALOGE("voice_stream_init() failed to open pcm %s devices", stream->name);
529 voice_stream_exit(stream);
530 return -ENODEV;
531 }
532
533 /*
534 * Choose the largest frame size since mono-to-stereo and
535 * stereo-to-mono conversion happens in place
536 */
537 stream->in_frame_size = pcm_frames_to_bytes(stream->pcm_in, 1);
538 stream->out_frame_size = pcm_frames_to_bytes(stream->pcm_out, 1);
539 frames = (stream->in_frame_size > stream->out_frame_size) ?
540 stream->in_frame_size : stream->out_frame_size;
541
542 /* out_buffer will store the resampled data */
543 stream->out_frames = stream->out_config.period_size;
544 stream->out_buffer = malloc(stream->out_frames * frames);
545
546 /* in_buffer will store the frames recorded from the PCM device */
547 stream->in_frames = (stream->out_frames * stream->in_config.rate) / stream->out_config.rate +
548 RESAMPLER_HEADROOM_FRAMES;
549 stream->in_buffer = malloc(stream->in_frames * frames);
550
551 if (!stream->in_buffer || !stream->out_buffer) {
552 ALOGE("voice_stream_init() failed to allocate %s buffers", stream->name);
553 voice_stream_exit(stream);
554 return -ENOMEM;
555 }
556
557 ret = setup_voice_remix(stream);
558 if (ret) {
559 ALOGE("voice_stream_init() failed to setup remix %d", ret);
560 voice_stream_exit(stream);
561 }
562
563 return ret;
564}
565
566static int enter_voice_call(struct j6_audio_device *adev)
567{
568 struct j6_voice *voice = &adev->voice;
569 int ret;
570
571 ALOGI("enter_voice_call() entering bluetooth voice call");
572
573 /* Let the primary output switch to a dummy sink */
574 if (adev->out)
575 do_out_standby(adev->out);
576
577 /* Uplink: Mic (44.1kHz) -> BT (8kHz) */
578 voice->ul.name = strdup("UL");
579 voice->ul.in_config = pcm_config_capture;
580 voice->ul.out_config = pcm_config_bt_out;
581 voice->ul.dev = adev;
582 ret = voice_stream_init(&voice->ul, adev->card, adev->in_port,
583 adev->bt_card, adev->bt_port);
584 if (ret) {
585 ALOGE("enter_voice_call() failed to init uplink %d", ret);
586 return ret;
587 }
588
589 /* Downlink: BT (8kHz) -> HP/Spk (44.1kHz) */
590 voice->dl.name = strdup("DL");
591 voice->dl.in_config = pcm_config_bt_in;
592 voice->dl.out_config = pcm_config_playback;
593 voice->dl.dev = adev;
594 ret = voice_stream_init(&voice->dl, adev->bt_card, adev->bt_port,
595 adev->card, adev->out_port);
596 if (ret) {
597 ALOGE("enter_voice_call() failed to init downlink %d", ret);
598 goto err_dl_init;
599 }
600
601 adev->in_call = true;
602
603 /* Create uplink thread: Mic -> BT */
604 ret = pthread_create(&voice->ul.thread, NULL, voice_thread_func, &voice->ul);
605 if (ret) {
606 ALOGE("enter_voice_call() failed to create uplink thread %d", ret);
607 adev->in_call = false;
608 goto err_ul_thread;
609 }
610
611 /* Create downlink thread: BT -> HP/Spk */
612 ret = pthread_create(&voice->dl.thread, NULL, voice_thread_func, &voice->dl);
613 if (ret) {
614 ALOGE("enter_voice_call() failed to create downlink thread %d", ret);
615 adev->in_call = false;
616 goto err_dl_thread;
617 }
618
619 return 0;
620
621 err_dl_thread:
622 pthread_join(voice->ul.thread, NULL);
623 err_ul_thread:
624 voice_stream_exit(&voice->ul);
625 err_dl_init:
626 voice_stream_exit(&voice->dl);
627
628 return ret;
629}
630
631static void leave_voice_call(struct j6_audio_device *adev)
632{
633 struct j6_voice *voice = &adev->voice;
634 struct j6_voice_stream *ul = &voice->ul;
635 struct j6_voice_stream *dl = &voice->dl;
636 void *ret;
637
638 ALOGI("leave_voice_call() leaving bluetooth voice call");
639
640 adev->in_call = false;
641
642 if (ul->pcm_out)
643 pcm_stop(ul->pcm_out);
644 if (dl->pcm_in)
645 pcm_stop(dl->pcm_in);
646
647 pthread_join(voice->dl.thread, &ret);
648 pthread_join(voice->ul.thread, &ret);
649
650 voice_stream_exit(&voice->dl);
651 voice_stream_exit(&voice->ul);
652
653 /* Let the primary output switch back to its ALSA PCM device */
654 if (adev->out)
655 do_out_standby(adev->out);
656}
657
658static uint32_t time_diff(struct timespec t1, struct timespec t0)
659{
660 struct timespec temp;
661
662 if ((t1.tv_nsec - t0.tv_nsec) < 0) {
663 temp.tv_sec = t1.tv_sec - t0.tv_sec-1;
664 temp.tv_nsec = 1000000000UL + t1.tv_nsec - t0.tv_nsec;
665 } else {
666 temp.tv_sec = t1.tv_sec - t0.tv_sec;
667 temp.tv_nsec = t1.tv_nsec - t0.tv_nsec;
668 }
669
670 return (temp.tv_sec * 1000000UL + temp.tv_nsec / 1000);
671}
672
673/* audio HAL functions */
674
675static uint32_t out_get_sample_rate(const struct audio_stream *stream)
676{
677 uint32_t rate = PLAYBACK_SAMPLE_RATE;
678
679 UNUSED(stream);
680 ALOGVV("out_get_sample_rate() stream=%p rate=%u", stream, rate);
681
682 return rate;
683}
684
685static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
686{
687 UNUSED(stream);
688 UNUSED(rate);
689 ALOGVV("out_set_sample_rate() stream=%p rate=%u", stream, rate);
690
691 return 0;
692}
693
694static size_t out_get_buffer_size(const struct audio_stream *stream)
695{
696 const struct audio_stream_out *s = (const struct audio_stream_out *)stream;
697 uint32_t frames = ((PLAYBACK_PERIOD_SIZE + 15) / 16) * 16;
698 size_t bytes = frames * audio_stream_out_frame_size(s);
699
700 ALOGVV("out_get_buffer_size() stream=%p frames=%u bytes=%u", stream, frames, bytes);
701
702 return bytes;
703}
704
705static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
706{
707 audio_channel_mask_t channels = AUDIO_CHANNEL_OUT_STEREO;
708
709 UNUSED(stream);
710 ALOGVV("out_get_channels() stream=%p channels=%u", stream, popcount(channels));
711
712 return channels;
713}
714
715static audio_format_t out_get_format(const struct audio_stream *stream)
716{
717 audio_format_t format = AUDIO_FORMAT_PCM_16_BIT;
718
719 UNUSED(stream);
720 ALOGVV("out_set_format() stream=%p format=0x%08x (%u bits/sample)",
721 stream, format, audio_bytes_per_sample(format) << 3);
722
723 return format;
724}
725
726static int out_set_format(struct audio_stream *stream, audio_format_t format)
727{
728 UNUSED(stream);
729 ALOGVV("out_set_format() stream=%p format=0x%08x (%u bits/sample)",
730 stream, format, audio_bytes_per_sample(format) << 3);
731
732 if (format != AUDIO_FORMAT_PCM_16_BIT) {
733 return -ENOSYS;
734 } else {
735 return 0;
736 }
737}
738
739/* must be called with locks held */
740static void do_out_standby(struct j6_stream_out *out)
741{
742 struct j6_audio_device *adev = out->dev;
743
744 if (!out->standby) {
745 if (adev->mode != AUDIO_MODE_IN_CALL) {
746 ALOGI("do_out_standby() close card %u port %u", adev->card, adev->out_port);
747 pcm_close(out->pcm);
748 out->pcm = NULL;
749 } else {
750 ALOGI("do_out_standby() close dummy card");
751 }
752 out->standby = true;
753 }
754}
755
756static int out_standby(struct audio_stream *stream)
757{
758 struct j6_stream_out *out = (struct j6_stream_out *)(stream);
759 struct j6_audio_device *adev = out->dev;
760
761 ALOGV("out_standby() stream=%p", out);
762 pthread_mutex_lock(&adev->lock);
763 pthread_mutex_lock(&out->lock);
764 do_out_standby(out);
765 pthread_mutex_unlock(&out->lock);
766 pthread_mutex_unlock(&adev->lock);
767
768 return 0;
769}
770
771static int out_dump(const struct audio_stream *stream, int fd)
772{
773 UNUSED(stream);
774 UNUSED(fd);
775
776 return 0;
777}
778
779static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
780{
781 struct j6_stream_out *out = (struct j6_stream_out *)(stream);
782 struct j6_audio_device *adev = out->dev;
783 struct str_parms *parms;
784 char value[32];
785 int ret;
786 uint32_t val = 0;
787
788 ALOGV("out_set_parameters() stream=%p parameter='%s'", out, kvpairs);
789
790 parms = str_parms_create_str(kvpairs);
791
792 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
793 if (ret >= 0) {
794 val = atoi(value);
795 pthread_mutex_lock(&adev->lock);
796 pthread_mutex_lock(&out->lock);
797 if (val != 0) {
798 if ((adev->out_device & AUDIO_DEVICE_OUT_ALL) != val)
799 do_out_standby(out);
800
801 /* set the active output device */
802 adev->out_device = val;
803 select_output_device(adev);
804 }
805 pthread_mutex_unlock(&out->lock);
806 pthread_mutex_unlock(&adev->lock);
807 }
808
809 return 0;
810}
811
812static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
813{
814 UNUSED(stream);
815 UNUSED(keys);
816
817 return strdup("");
818}
819
820static uint32_t out_get_latency(const struct audio_stream_out *stream)
821{
822 const struct j6_stream_out *out = (const struct j6_stream_out *)(stream);
823 uint32_t frames = PLAYBACK_BUFFER_SIZE;
824 uint32_t latency = (frames * 1000) / PLAYBACK_SAMPLE_RATE;
825
826 ALOGVV("out_get_latency() stream=%p latency=%u msecs", out, latency);
827
828 return latency;
829}
830
831static int out_set_volume(struct audio_stream_out *stream, float left,
832 float right)
833{
834 UNUSED(stream);
835 UNUSED(left);
836 UNUSED(right);
837
838 return -ENOSYS;
839}
840
841static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
842 size_t bytes)
843{
844 const struct audio_stream_out *s = (const struct audio_stream_out *)stream;
845 struct j6_stream_out *out = (struct j6_stream_out *)(stream);
846 struct j6_audio_device *adev = out->dev;
847 struct timespec now;
848 const size_t frame_size = audio_stream_out_frame_size(s);
849 const size_t frames = bytes / frame_size;
850 uint32_t rate = out->config.rate;
851 uint32_t write_usecs = frames * 1000000 / rate;
852 uint32_t diff_usecs;
853 int ret = 0;
854
855 ALOGVV("out_write() stream=%p buffer=%p size=%u/%u time=%u usecs",
856 out, buffer, frames, rate, write_usecs);
857
858 pthread_mutex_lock(&adev->lock);
859 pthread_mutex_lock(&out->lock);
860
861 if (out->standby) {
862 if (!adev->in_call) {
863 select_output_device(adev);
864
865 ALOGI("out_write() open card %u port %u", adev->card, adev->out_port);
866 out->pcm = pcm_open(adev->card, adev->out_port,
867 PCM_OUT | PCM_MONOTONIC,
868 &out->config);
869 if (!pcm_is_ready(out->pcm)) {
870 ALOGE("out_write() failed to open pcm out: %s", pcm_get_error(out->pcm));
871 pcm_close(out->pcm);
872 out->pcm = NULL;
873 ret = -ENODEV;
874 }
875 } else {
876 ALOGI("out_write() open dummy port");
877 clock_gettime(CLOCK_REALTIME, &out->last);
878 }
879
880 if (ret) {
881 usleep(write_usecs); /* limits the rate of error messages */
882 pthread_mutex_unlock(&out->lock);
883 pthread_mutex_unlock(&adev->lock);
884 return ret;
885 }
886
887 out->standby = false;
888 }
889
890 pthread_mutex_unlock(&adev->lock);
891
892 if (!adev->in_call) {
893 ret = pcm_write(out->pcm, buffer, bytes);
894 if (ret) {
895 ALOGE("out_write() failed to write audio data %d", ret);
896 usleep(write_usecs); /* limits the rate of error messages */
897 }
898 } else {
899 clock_gettime(CLOCK_REALTIME, &now);
900 diff_usecs = time_diff(now, out->last);
901 if (write_usecs > diff_usecs)
902 usleep(write_usecs - diff_usecs);
903
904 clock_gettime(CLOCK_REALTIME, &out->last);
905 }
906
907 out->written += frames;
908
909 pthread_mutex_unlock(&out->lock);
910
911 return bytes;
912}
913
914static int out_get_render_position(const struct audio_stream_out *stream,
915 uint32_t *dsp_frames)
916{
917 UNUSED(stream);
918 UNUSED(dsp_frames);
919
920 return -EINVAL;
921}
922
923static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
924{
925 UNUSED(stream);
926 UNUSED(effect);
927
928 return 0;
929}
930
931static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
932{
933 UNUSED(stream);
934 UNUSED(effect);
935
936 return 0;
937}
938
939static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
940 int64_t *timestamp)
941{
942 UNUSED(stream);
943 UNUSED(timestamp);
944
945 return -EINVAL;
946}
947
948static int out_get_presentation_position(const struct audio_stream_out *stream,
949 uint64_t *frames, struct timespec *timestamp)
950{
951 struct j6_stream_out *out = (struct j6_stream_out *)(stream);
952 struct j6_audio_device *adev = out->dev;
953 int64_t signed_frames = -1;
954 size_t avail;
955 int ret = -1;
956
957 pthread_mutex_lock(&out->lock);
958
959 if (!adev->in_call) {
960 if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
961 signed_frames = out->written - pcm_get_buffer_size(out->pcm) + avail;
962 }
963 } else {
964 clock_gettime(CLOCK_MONOTONIC, timestamp);
965 signed_frames = out->written +
966 (time_diff(*timestamp, out->last) * out->config.rate) / 1000000;
967 }
968
969 /* It would be unusual for this value to be negative, but check just in case ... */
970 if (signed_frames >= 0) {
971 *frames = signed_frames;
972 ret = 0;
973 }
974
975 pthread_mutex_unlock(&out->lock);
976
977 return ret;
978}
979
980/** audio_stream_in implementation **/
981static uint32_t in_get_sample_rate(const struct audio_stream *stream)
982{
983 const struct j6_stream_in *in = (const struct j6_stream_in *)(stream);
984
985 ALOGVV("in_get_sample_rate() stream=%p rate=%u", stream, in->requested_rate);
986
987 return in->requested_rate;
988}
989
990static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
991{
992 ALOGV("in_set_sample_rate() stream=%p rate=%u", stream, rate);
993
994 return 0;
995}
996
997static size_t in_get_buffer_size(const struct audio_stream *stream)
998{
999 const struct j6_stream_in *in = (const struct j6_stream_in *)(stream);
1000
1001 size_t bytes = get_input_buffer_size(in->requested_rate,
1002 AUDIO_FORMAT_PCM_16_BIT,
1003 in->requested_channels);
1004
1005 ALOGVV("in_get_buffer_size() stream=%p bytes=%u", in, bytes);
1006
1007 return bytes;
1008}
1009
1010static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
1011{
1012 const struct j6_stream_in *in = (const struct j6_stream_in *)(stream);
1013 audio_channel_mask_t channels = audio_channel_in_mask_from_count(in->requested_channels);
1014
1015 ALOGVV("in_get_channels() stream=%p channels=%u", in, in->requested_channels);
1016
1017 return channels;
1018}
1019
1020static audio_format_t in_get_format(const struct audio_stream *stream)
1021{
1022 audio_format_t format = AUDIO_FORMAT_PCM_16_BIT;
1023
1024 UNUSED(stream);
1025 ALOGVV("in_set_format() stream=%p format=0x%08x (%u bits/sample)",
1026 stream, format, audio_bytes_per_sample(format) << 3);
1027
1028 return format;
1029}
1030
1031static int in_set_format(struct audio_stream *stream, audio_format_t format)
1032{
1033 UNUSED(stream);
1034 ALOGV("in_set_format() stream=%p format=0x%08x (%u bits/sample)",
1035 stream, format, audio_bytes_per_sample(format) << 3);
1036
1037 if (format != AUDIO_FORMAT_PCM_16_BIT) {
1038 return -ENOSYS;
1039 } else {
1040 return 0;
1041 }
1042}
1043
1044/* must be called with locks held */
1045static void do_in_standby(struct j6_stream_in *in)
1046{
1047 struct j6_audio_device *adev = in->dev;
1048
1049 if (!in->standby) {
1050 ALOGI("do_in_standby() close card %u port %u", adev->card, adev->out_port);
1051 pcm_close(in->pcm);
1052 in->pcm = NULL;
1053 in->standby = true;
1054 }
1055}
1056
1057static int in_standby(struct audio_stream *stream)
1058{
1059 struct j6_stream_in *in = (struct j6_stream_in *)(stream);
1060 struct j6_audio_device *adev = in->dev;
1061
1062 ALOGV("in_standby() stream=%p", in);
1063 pthread_mutex_lock(&adev->lock);
1064 pthread_mutex_lock(&in->lock);
1065 do_in_standby(in);
1066 pthread_mutex_unlock(&in->lock);
1067 pthread_mutex_unlock(&adev->lock);
1068
1069 return 0;
1070}
1071
1072static int in_dump(const struct audio_stream *stream, int fd)
1073{
1074 UNUSED(stream);
1075 UNUSED(fd);
1076
1077 return 0;
1078}
1079
1080static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
1081{
1082 struct j6_stream_in *in = (struct j6_stream_in *)(stream);
1083 struct j6_audio_device *adev = in->dev;
1084 struct str_parms *parms;
1085 char value[32];
1086 int ret;
1087 uint32_t val = 0;
1088
1089 ALOGV("in_set_parameters() stream=%p parameter='%s'", stream, kvpairs);
1090
1091 parms = str_parms_create_str(kvpairs);
1092
1093 /* Nothing to do for AUDIO_PARAMETER_STREAM_INPUT_SOURCE, so it's ignored */
1094
1095 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
1096 if (ret >= 0) {
1097 val = atoi(value);
1098 pthread_mutex_lock(&adev->lock);
1099 pthread_mutex_lock(&in->lock);
1100 if (val != 0) {
1101 if ((adev->in_device & AUDIO_DEVICE_IN_ALL) != val)
1102 do_in_standby(in);
1103
1104 /* set the active input device */
1105 adev->in_device = val;
1106 select_input_device(adev);
1107 }
1108 pthread_mutex_unlock(&in->lock);
1109 pthread_mutex_unlock(&adev->lock);
1110 }
1111
1112 return 0;
1113}
1114
1115static char * in_get_parameters(const struct audio_stream *stream,
1116 const char *keys)
1117{
1118 UNUSED(stream);
1119 UNUSED(keys);
1120
1121 return strdup("");
1122}
1123
1124static int in_set_gain(struct audio_stream_in *stream, float gain)
1125{
1126 UNUSED(stream);
1127 UNUSED(gain);
1128
1129 return 0;
1130}
1131
1132static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1133 struct resampler_buffer* buffer)
1134{
1135 struct j6_stream_in *in;
1136 struct buffer_remix *remix;
1137
1138 if (buffer_provider == NULL || buffer == NULL)
1139 return -EINVAL;
1140
1141 in = (struct j6_stream_in *)((char *)buffer_provider -
1142 offsetof(struct j6_stream_in, buf_provider));
1143
1144 if (in->pcm == NULL) {
1145 buffer->raw = NULL;
1146 buffer->frame_count = 0;
1147 in->read_status = -ENODEV;
1148 return -ENODEV;
1149 }
1150
1151 if (in->frames_in == 0) {
1152 in->read_status = pcm_read(in->pcm,
1153 (void*)in->buffer,
1154 buffer->frame_count * in->hw_frame_size);
1155 if (in->read_status != 0) {
1156 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
1157 buffer->raw = NULL;
1158 buffer->frame_count = 0;
1159 return in->read_status;
1160 }
1161 in->frames_in = buffer->frame_count;
1162
1163 remix = in->remix;
1164 if (remix)
1165 remix->remix_func(remix, in->buffer, in->frames_in);
1166 }
1167
1168 buffer->frame_count = (buffer->frame_count > in->frames_in) ?
1169 in->frames_in : buffer->frame_count;
1170 buffer->i16 = in->buffer;
1171
1172 return in->read_status;
1173}
1174
1175static void release_buffer(struct resampler_buffer_provider *buffer_provider,
1176 struct resampler_buffer* buffer)
1177{
1178 struct j6_stream_in *in;
1179
1180 if (buffer_provider == NULL || buffer == NULL)
1181 return;
1182
1183 in = (struct j6_stream_in *)((char *)buffer_provider -
1184 offsetof(struct j6_stream_in, buf_provider));
1185
1186 in->frames_in -= buffer->frame_count;
1187}
1188
1189/*
1190 * read_frames() reads frames from kernel driver, down samples to capture rate
1191 * if necessary and output the number of frames requested to the buffer specified
1192 */
1193static ssize_t read_frames(struct j6_stream_in *in, void *buffer, ssize_t frames)
1194{
1195 const struct audio_stream_in *s = (const struct audio_stream_in *)in;
1196 ssize_t frames_wr = 0;
1197 size_t frame_size;
1198
1199 ALOGVV("read_frames() stream=%p frames=%u", in, frames);
1200
1201 if (in->remix)
1202 frame_size = audio_stream_in_frame_size(s);
1203 else
1204 frame_size = in->hw_frame_size;
1205
1206 while (frames_wr < frames) {
1207 size_t frames_rd = frames - frames_wr;
1208
1209 if (in->resampler) {
1210 in->resampler->resample_from_provider(in->resampler,
1211 (int16_t *)((char *)buffer + frames_wr * frame_size),
1212 &frames_rd);
1213 } else {
1214 struct resampler_buffer buf = {
1215 { raw : NULL, },
1216 frame_count : frames_rd,
1217 };
1218 get_next_buffer(&in->buf_provider, &buf);
1219 if (buf.raw) {
1220 memcpy((char *)buffer + frames_wr * frame_size,
1221 buf.raw,
1222 buf.frame_count * frame_size);
1223 frames_rd = buf.frame_count;
1224 }
1225 release_buffer(&in->buf_provider, &buf);
1226 }
1227
1228 /* in->read_status is updated by getNextBuffer() also called by
1229 * in->resampler->resample_from_provider() */
1230 if (in->read_status != 0)
1231 return in->read_status;
1232
1233 frames_wr += frames_rd;
1234 }
1235
1236 return frames_wr;
1237}
1238
1239static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
1240 size_t bytes)
1241{
1242 const struct audio_stream_in *s = (const struct audio_stream_in *)stream;
1243 struct j6_stream_in *in = (struct j6_stream_in *)(stream);
1244 struct j6_audio_device *adev = in->dev;
1245 const size_t frame_size = audio_stream_in_frame_size(stream);
1246 const size_t frames = bytes / frame_size;
1247 uint32_t rate = in_get_sample_rate(&stream->common);
1248 uint32_t read_usecs = frames * 1000000 / rate;
1249 int ret;
1250
1251 ALOGVV("in_read() stream=%p buffer=%p size=%u/%u time=%u usecs",
1252 stream, buffer, frames, rate, read_usecs);
1253
1254 pthread_mutex_lock(&adev->lock);
1255 pthread_mutex_lock(&in->lock);
1256
1257 if (in->standby) {
1258 select_input_device(adev);
1259
1260 ALOGI("in_read() open card %u port %u", adev->card, adev->in_port);
1261 in->pcm = pcm_open(adev->card, adev->in_port,
1262 PCM_IN | PCM_MONOTONIC,
1263 &in->config);
1264 if (!pcm_is_ready(in->pcm)) {
1265 ALOGE("in_read() failed to open pcm in: %s", pcm_get_error(in->pcm));
1266 pcm_close(in->pcm);
1267 in->pcm = NULL;
1268 usleep(read_usecs); /* limits the rate of error messages */
1269 pthread_mutex_unlock(&in->lock);
1270 pthread_mutex_unlock(&adev->lock);
1271 return -ENODEV;
1272 }
1273
1274 /* if no supported sample rate is available, use the resampler */
1275 if (in->resampler) {
1276 in->resampler->reset(in->resampler);
1277 in->frames_in = 0;
1278 }
1279
1280 in->standby = false;
1281 }
1282
1283 pthread_mutex_unlock(&adev->lock);
1284
1285 if (in->resampler || in->remix)
1286 ret = read_frames(in, buffer, frames);
1287 else
1288 ret = pcm_read(in->pcm, buffer, bytes);
1289
1290 if (ret < 0) {
1291 ALOGE("in_read() failed to read audio data %d", ret);
1292 usleep(read_usecs); /* limits the rate of error messages */
1293 memset(buffer, 0, bytes);
1294 } else if (adev->mic_mute) {
1295 memset(buffer, 0, bytes);
1296 }
1297
1298 pthread_mutex_unlock(&in->lock);
1299
1300 return bytes;
1301}
1302
1303static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
1304{
1305 UNUSED(stream);
1306 ALOGVV("in_get_input_frames_lost() stream=%p frames=%u", stream, 0);
1307
1308 return 0;
1309}
1310
1311static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1312{
1313 UNUSED(stream);
1314 UNUSED(effect);
1315
1316 return 0;
1317}
1318
1319static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1320{
1321 UNUSED(stream);
1322 UNUSED(effect);
1323
1324 return 0;
1325}
1326
1327static int adev_open_output_stream(struct audio_hw_device *dev,
1328 audio_io_handle_t handle,
1329 audio_devices_t devices,
1330 audio_output_flags_t flags,
1331 struct audio_config *config,
1332 struct audio_stream_out **stream_out,
1333 const char *address)
1334{
1335 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
1336 struct j6_stream_out *out;
1337
1338 UNUSED(handle);
1339 UNUSED(devices);
1340 UNUSED(address);
1341
1342 out = (struct j6_stream_out *)calloc(1, sizeof(struct j6_stream_out));
1343 if (!out)
1344 return -ENOMEM;
1345
1346 ALOGV("adev_open_output_stream() stream=%p rate=%u channels=%u "
1347 "format=0x%08x flags=0x%08x",
1348 out, config->sample_rate, popcount(config->channel_mask),
1349 config->format, flags);
1350
1351 pthread_mutex_init(&out->lock, NULL);
1352
1353 out->stream.common.get_sample_rate = out_get_sample_rate;
1354 out->stream.common.set_sample_rate = out_set_sample_rate;
1355 out->stream.common.get_buffer_size = out_get_buffer_size;
1356 out->stream.common.get_channels = out_get_channels;
1357 out->stream.common.get_format = out_get_format;
1358 out->stream.common.set_format = out_set_format;
1359 out->stream.common.standby = out_standby;
1360 out->stream.common.dump = out_dump;
1361 out->stream.common.set_parameters = out_set_parameters;
1362 out->stream.common.get_parameters = out_get_parameters;
1363 out->stream.common.add_audio_effect = out_add_audio_effect;
1364 out->stream.common.remove_audio_effect = out_remove_audio_effect;
1365 out->stream.get_latency = out_get_latency;
1366 out->stream.set_volume = out_set_volume;
1367 out->stream.write = out_write;
1368 out->stream.get_render_position = out_get_render_position;
1369 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
1370 out->stream.get_presentation_position = out_get_presentation_position;
1371
1372 out->dev = adev;
1373 out->standby = true;
1374 out->config = pcm_config_playback;
1375 out->written = 0;
1376 adev->out = out;
1377
1378 config->format = out_get_format(&out->stream.common);
1379 config->channel_mask = out_get_channels(&out->stream.common);
1380 config->sample_rate = out_get_sample_rate(&out->stream.common);
1381
1382 *stream_out = &out->stream;
1383
1384 return 0;
1385}
1386
1387static void adev_close_output_stream(struct audio_hw_device *dev,
1388 struct audio_stream_out *stream)
1389{
1390 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
1391 struct j6_stream_out *out = (struct j6_stream_out *)(stream);
1392
1393 ALOGV("adev_close_output_stream() stream=%p", out);
1394
1395 out_standby(&stream->common);
1396 out->dev = NULL;
1397 adev->out = NULL;
1398
1399 free(stream);
1400}
1401
1402static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
1403{
1404 UNUSED(dev);
1405 UNUSED(kvpairs);
1406
1407 return -ENOSYS;
1408}
1409
1410static char * adev_get_parameters(const struct audio_hw_device *dev,
1411 const char *keys)
1412{
1413 UNUSED(dev);
1414 UNUSED(keys);
1415
1416 return strdup("");;
1417}
1418
1419static int adev_init_check(const struct audio_hw_device *dev)
1420{
1421 UNUSED(dev);
1422
1423 return 0;
1424}
1425
1426static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
1427{
1428 UNUSED(dev);
1429 UNUSED(volume);
1430
1431 return -ENOSYS;
1432}
1433
1434static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
1435{
1436 UNUSED(dev);
1437 UNUSED(volume);
1438
1439 return -ENOSYS;
1440}
1441
1442static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
1443{
1444 UNUSED(dev);
1445 UNUSED(volume);
1446
1447 return -ENOSYS;
1448}
1449
1450static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
1451{
1452 UNUSED(dev);
1453 UNUSED(muted);
1454
1455 return -ENOSYS;
1456}
1457
1458static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
1459{
1460 UNUSED(dev);
1461 UNUSED(muted);
1462
1463 return -ENOSYS;
1464}
1465
1466static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
1467{
1468 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
1469 struct j6_stream_out *out = adev->out;
1470 int ret = 0;
1471
1472 ALOGV("adev_set_mode() mode=0x%08x", mode);
1473
1474 pthread_mutex_lock(&adev->lock);
1475 pthread_mutex_lock(&out->lock);
1476
1477 if (adev->mode == mode) {
1478 ALOGV("adev_set_mode() already in mode=0x%08x", mode);
1479 goto out;
1480 }
1481
1482 if (mode == AUDIO_MODE_IN_CALL) {
1483 ret = enter_voice_call(adev);
1484 if (ret) {
1485 ALOGE("adev_set_mode() failed to initialize voice call %d", ret);
1486 goto out;
1487 }
1488 } else if (adev->mode == AUDIO_MODE_IN_CALL) {
1489 leave_voice_call(adev);
1490 }
1491
1492 adev->mode = mode;
1493
1494out:
1495 pthread_mutex_unlock(&out->lock);
1496 pthread_mutex_unlock(&adev->lock);
1497
1498 return ret;
1499}
1500
1501static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
1502{
1503 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
1504
1505 ALOGV("adev_set_mic_mute() state=%s", state ? "mute" : "unmute");
1506 adev->mic_mute = state;
1507
1508 return 0;
1509}
1510
1511static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
1512{
1513 const struct j6_audio_device *adev = (const struct j6_audio_device *)dev;
1514
1515 *state = adev->mic_mute;
1516 ALOGV("adev_get_mic_mute() state=%s", *state ? "mute" : "unmute");
1517
1518 return 0;
1519}
1520
1521static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
1522 const struct audio_config *config)
1523{
1524 UNUSED(dev);
1525
1526 size_t bytes = get_input_buffer_size(config->sample_rate,
1527 config->format,
1528 popcount(config->channel_mask));
1529
1530 ALOGVV("adev_in_get_buffer_size() bytes=%u", bytes);
1531
1532 return bytes;
1533}
1534
1535static int adev_open_input_stream(struct audio_hw_device *dev,
1536 audio_io_handle_t handle,
1537 audio_devices_t devices,
1538 struct audio_config *config,
1539 struct audio_stream_in **stream_in,
1540 audio_input_flags_t flags,
1541 const char *address,
1542 audio_source_t source)
1543{
1544 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
1545 struct j6_stream_in *in;
1546 int buffer_size;
1547 int ret;
1548
1549 UNUSED(handle);
1550 UNUSED(devices);
1551 UNUSED(flags);
1552 UNUSED(address);
1553 UNUSED(source);
1554
1555 in = (struct j6_stream_in *)calloc(1, sizeof(struct j6_stream_in));
1556 if (!in)
1557 return -ENOMEM;
1558
1559 ALOGV("adev_open_input_stream() stream=%p rate=%u channels=%u format=0x%08x",
1560 in, config->sample_rate, popcount(config->channel_mask), config->format);
1561
1562 pthread_mutex_init(&in->lock, NULL);
1563
1564 in->stream.common.get_sample_rate = in_get_sample_rate;
1565 in->stream.common.set_sample_rate = in_set_sample_rate;
1566 in->stream.common.get_buffer_size = in_get_buffer_size;
1567 in->stream.common.get_channels = in_get_channels;
1568 in->stream.common.get_format = in_get_format;
1569 in->stream.common.set_format = in_set_format;
1570 in->stream.common.standby = in_standby;
1571 in->stream.common.dump = in_dump;
1572 in->stream.common.set_parameters = in_set_parameters;
1573 in->stream.common.get_parameters = in_get_parameters;
1574 in->stream.common.add_audio_effect = in_add_audio_effect;
1575 in->stream.common.remove_audio_effect = in_remove_audio_effect;
1576 in->stream.set_gain = in_set_gain;
1577 in->stream.read = in_read;
1578 in->stream.get_input_frames_lost = in_get_input_frames_lost;
1579
1580 in->dev = adev;
1581 in->standby = true;
1582 in->config = pcm_config_capture;
1583 in->requested_rate = config->sample_rate;
1584 in->requested_channels = popcount(config->channel_mask);
1585 in->hw_frame_size = in->config.channels * sizeof(int16_t);
1586 in->remix = NULL;
1587 in->resampler = NULL;
1588 in->buffer = NULL;
1589 adev->in = in;
1590
1591 /* in-place stereo-to-mono remix since capture stream is stereo */
1592 if (in->requested_channels == 1) {
1593 ALOGV("adev_open_input_stream() stereo-to-mono remix needed");
1594 ret = setup_stereo_to_mono_input_remix(in);
1595 if (ret) {
1596 ALOGE("adev_open_input_stream() failed to setup remix %d", ret);
1597 goto err1;
1598 }
1599 }
1600
1601 if (in->requested_rate != in->config.rate) {
1602 ALOGV("adev_open_input_stream() resample needed, req=%uHz got=%uHz",
1603 in->requested_rate, in->config.rate);
1604
1605 in->buf_provider.get_next_buffer = get_next_buffer;
1606 in->buf_provider.release_buffer = release_buffer;
1607 ret = create_resampler(in->config.rate,
1608 in->requested_rate,
1609 in->requested_channels,
1610 RESAMPLER_QUALITY_DEFAULT,
1611 &in->buf_provider,
1612 &in->resampler);
1613 if (ret) {
1614 ALOGE("adev_open_input_stream() failed to create resampler %d", ret);
1615 goto err2;
1616 }
1617 }
1618
1619 /*
1620 * buffer size needs to be enough to allow stereo-to-mono remix
1621 * and resample if needed
1622 */
1623 if (in->resampler || in->remix) {
1624 buffer_size = in->config.period_size * in->hw_frame_size;
1625 if (in->resampler)
1626 buffer_size *= 2;
1627 if (in->remix)
1628 buffer_size *= 2;
1629
1630 in->buffer = malloc(buffer_size);
1631 if (!in->buffer) {
1632 ret = -ENOMEM;
1633 goto err3;
1634 }
1635 }
1636
1637 *stream_in = &in->stream;
1638
1639 return 0;
1640
1641 err3:
1642 release_resampler(in->resampler);
1643 err2:
1644 free(in->remix);
1645 err1:
1646 free(in);
1647 return ret;
1648}
1649
1650static void adev_close_input_stream(struct audio_hw_device *dev,
1651 struct audio_stream_in *stream)
1652{
1653 struct j6_audio_device *adev = (struct j6_audio_device *)dev;
1654 struct j6_stream_in *in = (struct j6_stream_in *)(stream);
1655
1656 ALOGV("adev_close_input_stream() stream=%p", stream);
1657
1658 in_standby(&stream->common);
1659
1660 if (in->resampler)
1661 release_resampler(in->resampler);
1662
1663 if (in->remix)
1664 free(in->remix);
1665
1666 free(in->buffer);
1667 free(in);
1668 adev->in = NULL;
1669}
1670
1671static int adev_dump(const audio_hw_device_t *device, int fd)
1672{
1673 UNUSED(device);
1674 UNUSED(fd);
1675
1676 return 0;
1677}
1678
1679static int adev_close(hw_device_t *device)
1680{
1681 struct j6_audio_device *adev = (struct j6_audio_device *)device;
1682
1683 ALOGI("adev_close()");
1684
1685 audio_route_free(adev->route);
1686 free(device);
1687
1688 return 0;
1689}
1690
1691static int adev_open(const hw_module_t* module, const char* name,
1692 hw_device_t** device)
1693{
1694 struct j6_audio_device *adev;
1695
1696 ALOGI("adev_open() %s", name);
1697
1698 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
1699 return -EINVAL;
1700
1701 adev = (struct j6_audio_device*)calloc(1, sizeof(struct j6_audio_device));
1702 if (!adev)
1703 return -ENOMEM;
1704
1705 pthread_mutex_init(&adev->lock, NULL);
1706
1707 adev->device.common.tag = HARDWARE_DEVICE_TAG;
1708 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
1709 adev->device.common.module = (struct hw_module_t *) module;
1710 adev->device.common.close = adev_close;
1711
1712 adev->device.init_check = adev_init_check;
1713 adev->device.set_voice_volume = adev_set_voice_volume;
1714 adev->device.set_master_volume = adev_set_master_volume;
1715 adev->device.get_master_volume = adev_get_master_volume;
1716 adev->device.set_master_mute = adev_set_master_mute;
1717 adev->device.get_master_mute = adev_get_master_mute;
1718 adev->device.set_mode = adev_set_mode;
1719 adev->device.set_mic_mute = adev_set_mic_mute;
1720 adev->device.get_mic_mute = adev_get_mic_mute;
1721 adev->device.set_parameters = adev_set_parameters;
1722 adev->device.get_parameters = adev_get_parameters;
1723 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
1724 adev->device.open_output_stream = adev_open_output_stream;
1725 adev->device.close_output_stream = adev_close_output_stream;
1726 adev->device.open_input_stream = adev_open_input_stream;
1727 adev->device.close_input_stream = adev_close_input_stream;
1728 adev->device.dump = adev_dump;
1729
1730 adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC;
1731 adev->out_device = AUDIO_DEVICE_OUT_SPEAKER;
1732 adev->card = 0;
1733 adev->in_port = 0;
1734 adev->out_port = 0;
1735 ALOGI("Media card is hw:%d\n", adev->card);
1736 adev->bt_card=2;
1737 adev->bt_port = 0;
1738 ALOGI("Bluetooth SCO card is hw:%d\n", adev->bt_card);
1739
1740 adev->mic_mute = false;
1741 adev->in_call = false;
1742 adev->mode = AUDIO_MODE_NORMAL;
1743
1744 adev->route = audio_route_init(adev->card, NULL);
1745 if (!adev->route) {
1746 ALOGE("Unable to initialize audio routes");
1747 free(adev);
1748 return -EINVAL;
1749 }
1750
1751 *device = &adev->device.common;
1752
1753 return 0;
1754}
1755
1756static struct hw_module_methods_t hal_module_methods = {
1757 .open = adev_open,
1758};
1759
1760struct audio_module HAL_MODULE_INFO_SYM = {
1761 .common = {
1762 .tag = HARDWARE_MODULE_TAG,
1763 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
1764 .hal_api_version = HARDWARE_HAL_API_VERSION,
1765 .id = AUDIO_HARDWARE_MODULE_ID,
1766 .name = "Jacinto6 Audio HAL",
1767 .author = "Texas Instruments Inc.",
1768 .methods = &hal_module_methods,
1769 },
1770};