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