summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngela Stegmaier2013-10-21 14:16:11 -0500
committerMisael Lopez Cruz2013-11-01 01:47:04 -0500
commit5e8c7ea0515d571d711a9a1e7903313d6b481a3b (patch)
tree1899b1972cec8274c2a1833b2a0ea8a325bc5b86 /audio/multizone
parentd6147ac6f4a3eafaef23f81213c9a4511cda1f73 (diff)
downloaddevice-ti-jacinto6evm-5e8c7ea0515d571d711a9a1e7903313d6b481a3b.tar.gz
device-ti-jacinto6evm-5e8c7ea0515d571d711a9a1e7903313d6b481a3b.tar.xz
device-ti-jacinto6evm-5e8c7ea0515d571d711a9a1e7903313d6b481a3b.zip
audio: multizone: Add initial implementation
Add the multizone AudioHAL support to jacinto6evm. The multizone audio is built if the multizone flag is set, otherwise the legacy AudioHAL is built. Change-Id: Ib0b401f963cd9327caeb73623bba163fe8129870 Signed-off-by: Angela Stegmaier <a0866189@ti.com> Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
Diffstat (limited to 'audio/multizone')
-rw-r--r--audio/multizone/Android.mk60
-rw-r--r--audio/multizone/AudioHw.cpp873
-rw-r--r--audio/multizone/AudioHw.h209
-rw-r--r--audio/multizone/audio_hw.cpp562
-rw-r--r--audio/multizone/audio_policy.conf116
-rw-r--r--audio/multizone/dra7evm_paths.xml110
6 files changed, 1930 insertions, 0 deletions
diff --git a/audio/multizone/Android.mk b/audio/multizone/Android.mk
new file mode 100644
index 0000000..46ec26a
--- /dev/null
+++ b/audio/multizone/Android.mk
@@ -0,0 +1,60 @@
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
17include $(CLEAR_VARS)
18LOCAL_MODULE := audio_policy.conf
19LOCAL_MODULE_TAGS := optional
20LOCAL_MODULE_CLASS := ETC
21LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
22LOCAL_SRC_FILES := $(LOCAL_MODULE)
23include $(BUILD_PREBUILT)
24
25include $(CLEAR_VARS)
26LOCAL_MODULE := dra7evm_paths.xml
27LOCAL_MODULE_TAGS := optional
28LOCAL_MODULE_CLASS := ETC
29LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
30LOCAL_SRC_FILES := $(LOCAL_MODULE)
31include $(BUILD_PREBUILT)
32
33include $(CLEAR_VARS)
34
35LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
36
37LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
38
39LOCAL_SRC_FILES := \
40 AudioHw.cpp \
41 audio_hw.cpp
42
43LOCAL_C_INCLUDES += \
44 system/media/audio_utils/include \
45 system/media/audio_effects/include \
46 device/ti/common-open/audio/utils/include
47
48LOCAL_SHARED_LIBRARIES := \
49 liblog \
50 libtiaudioutils \
51 libutils
52
53LOCAL_SHARED_LIBRARIES += libstlport
54include external/stlport/libstlport.mk
55
56LOCAL_STATIC_LIBRARIES := libmedia_helper
57
58LOCAL_MODULE_TAGS := optional
59
60include $(BUILD_SHARED_LIBRARY)
diff --git a/audio/multizone/AudioHw.cpp b/audio/multizone/AudioHw.cpp
new file mode 100644
index 0000000..78caf77
--- /dev/null
+++ b/audio/multizone/AudioHw.cpp
@@ -0,0 +1,873 @@
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 "AudioHw"
18// #define LOG_NDEBUG 0
19// #define VERY_VERBOSE_LOGGING
20#ifdef VERY_VERBOSE_LOGGING
21#define ALOGVV ALOGV
22#else
23#define ALOGVV(...) do { } while(0)
24#endif
25
26#include <cutils/log.h>
27
28#include <media/AudioParameter.h>
29
30#include <AudioHw.h>
31
32namespace android {
33
34AudioStreamOut::AudioStreamOut(AudioHwDevice *hwDev,
35 PcmWriter *writer,
36 const PcmParams &params,
37 const SlotMap &map,
38 audio_devices_t devices)
39 : mHwDev(hwDev), mWriter(writer),
40 mParams(params), mDevices(devices), mStandby(true)
41{
42 if (mWriter)
43 mStream = new AdaptedOutStream(params, map);
44}
45
46int AudioStreamOut::initCheck() const
47{
48 int ret = 0;
49
50 if (!mHwDev) {
51 ALOGE("AudioStreamOut: initCheck() invalid AudioHwDevice");
52 ret = -ENODEV;
53 }
54 else if (!mWriter || !mWriter->initCheck()) {
55 ALOGE("AudioStreamOut: initCheck() invalid PCM writer");
56 ret = -ENODEV;
57 }
58 else if (mStream == NULL || !mStream->initCheck()) {
59 ALOGE("AudioStreamOut: initCheck() invalid Out Stream");
60 ret = -ENODEV;
61 }
62
63 ALOGV("AudioStreamOut: init check %d", ret);
64
65 return ret;
66}
67
68uint32_t AudioStreamOut::getSampleRate() const
69{
70 uint32_t rate = mParams.sampleRate;
71
72 ALOGVV("AudioStreamOut: getSampleRate() %u Hz", rate);
73
74 return rate;
75}
76
77int AudioStreamOut::setSampleRate(uint32_t rate)
78{
79 ALOGV("AudioStreamOut: setSampleRate() %u Hz", rate);
80
81 return 0;
82}
83
84size_t AudioStreamOut::getBufferSize() const
85{
86 size_t size;
87
88 /* Take resampling ratio into account and align to the nearest
89 * 16 frames as required by the AudioFlinger */
90 size = (mParams.frameCount * mParams.sampleRate) / mWriter->getParams().sampleRate;
91 size = ((size + 15) & ~15) * mParams.frameSize();
92
93 ALOGVV("AudioStreamOut: getBufferSize() %u bytes", size);
94
95 return size;
96}
97
98audio_channel_mask_t AudioStreamOut::getChannels() const
99{
100 uint32_t channels = mParams.channels;
101
102 ALOGVV("AudioStreamOut: getChannels() %u channels", channels);
103
104 return audio_channel_out_mask_from_count(channels);
105}
106
107audio_format_t AudioStreamOut::getFormat() const
108{
109 uint32_t sampleBits = mParams.sampleBits;
110
111 ALOGVV("AudioStreamOut: getFormat() %u bits/sample", sampleBits);
112
113 switch (sampleBits) {
114 case 8:
115 return AUDIO_FORMAT_PCM_8_BIT;
116 case 24:
117 return AUDIO_FORMAT_PCM_8_24_BIT;
118 case 32:
119 return AUDIO_FORMAT_PCM_32_BIT;
120 case 16:
121 default:
122 return AUDIO_FORMAT_PCM_16_BIT;
123 }
124}
125
126int AudioStreamOut::setFormat(audio_format_t format)
127{
128 ALOGV("AudioStreamOut: setFormat() %u bits/sample",
129 audio_bytes_per_sample(format) * 8);
130
131 return 0;
132}
133
134int AudioStreamOut::standby()
135{
136 ALOGV("AudioStreamOut: standby()");
137
138 AutoMutex lock(mLock);
139
140 if (!mStandby) {
141 mStream->stop();
142 mWriter->unregisterStream(mStream);
143 mHwDev->mMixer.setPath(mDevices, false);
144 mStandby = true;
145 }
146
147 return 0;
148}
149
150int AudioStreamOut::dump(int fd) const
151{
152 ALOGV("AudioStreamOut: dump()");
153 return 0;
154}
155
156audio_devices_t AudioStreamOut::getDevice() const
157{
158 ALOGV("AudioStreamOut: getDevice()");
159 return mDevices;
160}
161
162int AudioStreamOut::setParameters(const char *kv_pairs)
163{
164 ALOGV("AudioStreamOut: setParameters() '%s'", kv_pairs ? kv_pairs : "");
165
166 int ret;
167
168 AudioParameter parms = AudioParameter(String8(kv_pairs));
169 String8 key = String8(AudioParameter::keyRouting);
170 int device;
171
172 if ((ret = parms.getInt(key, device)) == NO_ERROR) {
173 if ((mDevices & AUDIO_DEVICE_OUT_ALL) != (unsigned int)device) {
174 standby();
175 }
176 if (device & ~(mHwDev->getSupportedDevices())) {
177 ALOGW("AudioStreamOut: setParameters() device(s) not supported, "
178 "will use default devices");
179 }
180 else
181 mDevices = device;
182 }
183
184 return ret;
185}
186
187char *AudioStreamOut::getParameters(const char *keys) const
188{
189 ALOGV("AudioStreamOut::getParameters()");
190 return NULL;
191}
192
193int AudioStreamOut::addAudioEffect(effect_handle_t effect) const
194{
195 ALOGV("AudioStreamOut: addAudioEffects()");
196 return 0;
197}
198
199int AudioStreamOut::removeAudioEffect(effect_handle_t effect) const
200{
201 ALOGV("AudioStreamOut: removeAudioEffects()");
202 return 0;
203}
204
205uint32_t AudioStreamOut::getLatency() const
206{
207 uint32_t latency = (1000 * getBufferSize()) / mWriter->getParams().sampleRate;
208
209 ALOGVV("AudioStreamOut: getLatency() %u ms", latency);
210
211 return latency;
212}
213
214int AudioStreamOut::setVolume(float left, float right)
215{
216 ALOGV("AudioStreamOut: setVolume() left=%.4f right=%.4f", left, right);
217 return -ENOSYS;
218}
219
220ssize_t AudioStreamOut::write(const void* buffer, size_t bytes)
221{
222 uint32_t frames = mParams.bytesToFrames(bytes);
223 int ret = 0;
224 uint32_t usecs = (frames * 1000000) / mParams.sampleRate;
225
226 ALOGVV("AudioStreamOut: write %u frames (%u bytes) buffer %p",
227 frames, bytes, buffer);
228
229 AutoMutex lock(mLock);
230
231 if (mStandby) {
232 mHwDev->mMixer.setPath(mDevices, true);
233 ret = mWriter->registerStream(mStream);
234 if (ret) {
235 ALOGE("AudioStreamOut: failed to register stream %d", ret);
236 return ret;
237 }
238 ret = mStream->start();
239 if (ret) {
240 ALOGE("AudioStreamOut: failed to start stream %d", ret);
241 mWriter->unregisterStream(mStream);
242 usleep(usecs); /* limits the rate of error messages */
243 return ret;
244 }
245
246 mStandby = false;
247 }
248
249 ret = mStream->write(buffer, frames);
250 if (ret < 0) {
251 ALOGE("AudioStreamOut: failed to write data %d", ret);
252 usleep(usecs);
253 } else {
254 ALOGW_IF(ret != (int)frames,
255 "AudioStreamOut: wrote only %d out of %d requested frames",
256 ret, frames);
257 bytes = mParams.framesToBytes(ret);
258 }
259
260 return bytes;
261}
262
263int AudioStreamOut::getRenderPosition(uint32_t *dsp_frames) const
264{
265 ALOGV("AudioStreamOut: getRenderPosition()");
266
267 return -EINVAL;
268}
269
270int AudioStreamOut::getNextWriteTimestamp(int64_t *timestamp) const
271{
272 ALOGVV("AudioStreamOut: getNextWriteTimestamp()");
273
274 return -EINVAL;
275}
276
277/* ---------------------------------------------------------------------------------------- */
278
279AudioStreamIn::AudioStreamIn(AudioHwDevice *hwDev,
280 PcmReader *reader,
281 const PcmParams &params,
282 const SlotMap &map,
283 audio_devices_t devices)
284 : mHwDev(hwDev), mReader(reader), mParams(params), mDevices(devices),
285 mSource(AUDIO_SOURCE_DEFAULT), mStandby(true)
286{
287 if (mReader)
288 mStream = new AdaptedInStream(params, map);
289}
290
291int AudioStreamIn::initCheck() const
292{
293 int ret = 0;
294
295 if (!mHwDev) {
296 ALOGE("AudioStreamIn: initCheck() invalid AudioHwDevice");
297 ret = -ENODEV;
298 }
299 else if (!mReader || !mReader->initCheck()) {
300 ALOGE("AudioStreamIn: initCheck() invalid PCM reader");
301 ret = -ENODEV;
302 }
303 else if (mStream == NULL || !mStream->initCheck()) {
304 ALOGE("AudioStreamIn: initCheck() invalid In Stream");
305 ret = -ENODEV;
306 }
307
308 ALOGV("AudioStreamIn: init check %d", ret);
309
310 return ret;
311}
312
313uint32_t AudioStreamIn::getSampleRate() const
314{
315 ALOGV("AudioStreamIn: getSampleRate()");
316
317 uint32_t rate = mParams.sampleRate;
318
319 return rate;
320}
321
322int AudioStreamIn::setSampleRate(uint32_t rate)
323{
324 ALOGV("AudioStreamIn: setSampleRate() %u Hz", rate);
325
326 return 0;
327}
328
329size_t AudioStreamIn::getBufferSize() const
330{
331 size_t size;
332
333 /* Take resampling ratio into account and align to the nearest
334 * 16 frames as required by the AudioFlinger */
335 size = (mParams.frameCount * mParams.sampleRate) / mReader->getParams().sampleRate;
336 size = ((size + 15) & ~15) * mParams.frameSize();
337
338 ALOGVV("AudioStreamIn: getBufferSize() %u bytes", size);
339
340 return size;
341}
342
343audio_channel_mask_t AudioStreamIn::getChannels() const
344{
345 ALOGV("AudioStreamIn: getChannels()");
346
347 return audio_channel_in_mask_from_count(mParams.channels);
348}
349
350audio_format_t AudioStreamIn::getFormat() const
351{
352 ALOGV("AudioStreamIn: getFormat()");
353
354 return AUDIO_FORMAT_PCM_16_BIT;
355}
356
357int AudioStreamIn::setFormat(audio_format_t format)
358{
359 ALOGV("AudioStreamIn: setFormat()");
360
361 return 0;
362}
363
364int AudioStreamIn::standby()
365{
366 ALOGV("AudioStreamIn: standby()");
367
368 AutoMutex lock(mLock);
369
370 if (!mStandby) {
371 mStream->stop();
372 mReader->unregisterStream(mStream);
373 mHwDev->mMixer.setPath(mDevices, false);
374 mStandby = true;
375 }
376
377 return 0;
378}
379
380int AudioStreamIn::dump(int fd) const
381{
382 ALOGV("AudioStreamIn: dump()");
383
384 return 0;
385}
386
387audio_devices_t AudioStreamIn::getDevice() const
388{
389 ALOGV("AudioStreamIn: getDevice()");
390
391 return mDevices;
392}
393
394int AudioStreamIn::setParameters(const char *kv_pairs)
395{
396 ALOGV("AudioStreamIn: setParameters() '%s'", kv_pairs ? kv_pairs : "");
397
398 int ret;
399
400 AudioParameter parms = AudioParameter(String8(kv_pairs));
401 String8 source_key = String8(AudioParameter::keyInputSource);
402 String8 device_key = String8(AudioParameter::keyRouting);
403 int source, device;
404
405 if ((ret = parms.getInt(source_key, source)) == NO_ERROR) {
406 /* no audio source uses 0 */
407 if ((mSource != (unsigned int)source) &&
408 (source != 0) &&
409 (source < AUDIO_SOURCE_CNT)) {
410 ALOGV("AudioStreamIn: setParameters() source changed [%d]->[%d]",
411 mSource, source);
412 mSource = (audio_source_t)source;
413 /* Nothing to do for AUDIO_PARAMETER_STREAM_INPUT_SOURCE, so only
414 * record the source and continue */
415 }
416 }
417
418 if ((ret = parms.getInt(device_key, device)) == NO_ERROR) {
419 if ((mDevices & AUDIO_DEVICE_IN_ALL) != (unsigned int)device) {
420 standby();
421 }
422 if (device & ~(mHwDev->getSupportedDevices())) {
423 ALOGW("AudioStreamIn: setParameters() device(s) not supported, "
424 "will use default devices");
425 }
426 else {
427 mDevices = device;
428 ALOGV("AudioStreamIn: setParameters() device set to [0x%x]",
429 mDevices);
430 }
431 }
432
433 return 0;
434}
435
436char *AudioStreamIn::getParameters(const char *keys) const
437{
438 ALOGV("AudioStreamIn: getParameters()");
439
440 return NULL;
441}
442
443int AudioStreamIn::addAudioEffect(effect_handle_t effect) const
444{
445 ALOGV("AudioStreamIn: addAudioEffect()");
446
447 return 0;
448}
449
450int AudioStreamIn::removeAudioEffect(effect_handle_t effect) const
451{
452 ALOGV("AudioStreamIn: removeAudioEffect()");
453
454 return 0;
455}
456
457int AudioStreamIn::setGain(float gain)
458{
459 ALOGV("AudioStreamIn: setGain()");
460
461 return 0;
462}
463
464ssize_t AudioStreamIn::read(void* buffer, size_t bytes)
465{
466 uint32_t frames = mParams.bytesToFrames(bytes);
467 int ret = 0;
468 uint32_t usecs = (frames * 1000000) / mParams.sampleRate;
469
470 ALOGVV("AudioStreamIn: read %u frames (%u bytes) buffer %p",
471 frames, bytes, buffer);
472
473 AutoMutex lock(mLock);
474
475 if (mStandby) {
476 mHwDev->mMixer.setPath(mDevices, true);
477 ret = mReader->registerStream(mStream);
478 if (ret) {
479 ALOGE("AudioStreamIn: failed to register Dest %d", ret);
480 return ret;
481 }
482 ret = mStream->start();
483 if (ret) {
484 ALOGE("AudioStreamIn: failed to start stream %d", ret);
485 mReader->unregisterStream(mStream);
486 usleep(usecs); /* limits the rate of error messages */
487 return ret;
488 }
489
490 mStandby = false;
491 }
492
493 ret = mStream->read(buffer, frames);
494 if (ret < 0) {
495 ALOGE("AudioStreamIn: failed to read data %d", ret);
496 uint32_t usecs = (frames * 1000000) / mParams.sampleRate;
497 usleep(usecs);
498 bytes = ret;
499 } else {
500 ALOGW_IF(ret != (int)frames,
501 "AudioStreamIn: read only %d out of %d requested frames",
502 ret, frames);
503 bytes = mParams.framesToBytes(ret);
504 if (mHwDev->mMicMute)
505 memset(buffer, 0, bytes);
506 }
507
508 return bytes;
509}
510
511uint32_t AudioStreamIn::getInputFramesLost()
512{
513 ALOGVV("AudioStreamIn: getInputFrameLost()");
514
515 return 0;
516}
517
518/* ---------------------------------------------------------------------------------------- */
519
520AudioHwDevice::AudioHwDevice(uint32_t card)
521 : mCardId(card), mMixer(mCardId), mMicMute(false)
522{
523 ALOGI("AudioHwDevice: create hw device for card hw:%u", card);
524
525 /* Mixer for dra7evm and input/output ports for JAMR3 PCM device */
526 for (uint32_t i = 0; i < kNumPorts; i++) {
527 ALSAInPort *inPort = new ALSAInPort(mCardId, i);
528 mInPorts.push_back(inPort);
529
530 ALSAOutPort *outPort = new ALSAOutPort(mCardId, i);
531 mOutPorts.push_back(outPort);
532 }
533
534 /* PCM parameters for the port associated with on-board audio:
535 * 2 channels, 16-bits/sample, 44.1kHz, buffer of 882 frames (capture) */
536 PcmParams params0(kCPUNumChannels, kSampleSize, kSampleRate, kCaptureFrameCount);
537 PcmReader *reader = new PcmReader(mInPorts[kCPUPortId], params0);
538 mReaders.push_back(reader);
539 /* 2 channels, 16-bits/sample, 44.1kHz, buffer of 1024 frames (playback) */
540 params0.frameCount = kPlaybackFrameCount;
541 PcmWriter *writer = new PcmWriter(mOutPorts[kCPUPortId], params0);
542 mWriters.push_back(writer);
543
544 /* PCM parameters for the port associated with JAMR3 audio:
545 * 8 channels, 16-bits/sample, 44.1kHz, buffer of 882 frames (capture) */
546 PcmParams params1(kJAMR3NumChannels, kSampleSize, kSampleRate, kCaptureFrameCount);
547 reader = new PcmReader(mInPorts[kJAMR3PortId], params1);
548 mReaders.push_back(reader);
549 /* 8 channels, 16-bits/sample, 44.1kHz, buffer of 1024 frames (playback) */
550 params1.frameCount = kPlaybackFrameCount;
551 writer = new PcmWriter(mOutPorts[kJAMR3PortId], params1);
552 mWriters.push_back(writer);
553
554 mMixer.initRoutes();
555}
556
557AudioHwDevice::~AudioHwDevice()
558{
559 ALOGI("AudioHwDevice: destroy hw device for card hw:%u", mCardId);
560
561 for (WriterVect::const_iterator i = mWriters.begin(); i != mWriters.end(); ++i) {
562 delete (*i);
563 }
564 for (ReaderVect::const_iterator i = mReaders.begin(); i != mReaders.end(); ++i) {
565 delete (*i);
566 }
567 for (OutPortVect::iterator i = mOutPorts.begin(); i != mOutPorts.end(); ++i) {
568 delete (*i);
569 }
570 for (InPortVect::iterator i = mInPorts.begin(); i != mInPorts.end(); ++i) {
571 delete (*i);
572 }
573}
574
575uint32_t AudioHwDevice::getSupportedDevices() const
576{
577 uint32_t devices;
578
579 devices = AUDIO_DEVICE_IN_BUILTIN_MIC |
580 AUDIO_DEVICE_IN_BACK_MIC |
581 AUDIO_DEVICE_IN_VOICE_CALL |
582 AUDIO_DEVICE_OUT_SPEAKER |
583 AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
584 AUDIO_DEVICE_OUT_WIRED_HEADSET |
585 AUDIO_DEVICE_OUT_WIRED_HEADPHONE2;
586 ALOGV("AudioHwDevice: supported devices 0x%08x", devices);
587
588 return devices;
589}
590
591int AudioHwDevice::initCheck() const
592{
593 if (!mMixer.initCheck()) {
594 ALOGE("AudioHwDevice: ALSA mixer init failed");
595 return -ENODEV;
596 }
597
598 for (ReaderVect::const_iterator i = mReaders.begin(); i != mReaders.end(); ++i) {
599 if (!((*i)->initCheck())) {
600 ALOGE("AudioHwDevice: PCM reader initCheck failed");
601 return -ENODEV;
602 }
603 }
604 for (WriterVect::const_iterator i = mWriters.begin(); i != mWriters.end(); ++i) {
605 if (!((*i)->initCheck())) {
606 ALOGE("AudioHwDevice: PCM writer init failed");
607 return -ENODEV;
608 }
609 }
610
611 return 0;
612}
613
614int AudioHwDevice::setVoiceVolume(float volume)
615{
616 ALOGV("AudioHwDevice: setVoiceVolume() vol=%.4f", volume);
617 return -ENOSYS;
618}
619
620int AudioHwDevice::setMasterVolume(float volume)
621{
622 ALOGV("AudioHwDevice: setMasterVolume() vol=%.4f", volume);
623 return -ENOSYS;
624}
625
626const char *AudioHwDevice::getModeName(audio_mode_t mode) const
627{
628 switch (mode) {
629 case AUDIO_MODE_CURRENT:
630 return "CURRENT";
631 case AUDIO_MODE_NORMAL:
632 return "NORMAL";
633 case AUDIO_MODE_RINGTONE:
634 return "RINGTONE";
635 case AUDIO_MODE_IN_CALL:
636 return "IN_CALL";
637 case AUDIO_MODE_IN_COMMUNICATION:
638 return "COMMUNICATION";
639 default:
640 return "INVALID";
641 }
642}
643
644int AudioHwDevice::setMode(audio_mode_t mode)
645{
646 ALOGV("AudioHwDevice: setMode() %s", getModeName(mode));
647
648 return 0;
649}
650
651int AudioHwDevice::setMicMute(bool state)
652{
653 ALOGV("AudioHwDevice: setMicMute() %s", state ? "mute" : "unmute");
654
655 mMicMute = state;
656
657 return 0;
658}
659
660int AudioHwDevice::getMicMute(bool *state) const
661{
662 ALOGV("AudioHwDevice: getMicMute()");
663
664 *state = mMicMute;
665
666 return 0;
667}
668
669int AudioHwDevice::setParameters(const char *kv_pairs)
670{
671 ALOGV("AudioHwDevice: setParameters() '%s'", kv_pairs ? kv_pairs : "");
672
673 return 0;
674}
675
676char *AudioHwDevice::getParameters(const char *keys) const
677{
678 ALOGV("AudioHwDevice: getParameters()");
679
680 return NULL;
681}
682
683size_t AudioHwDevice::getInputBufferSize(const struct audio_config *config) const
684{
685 ALOGV("AudioHwDevice: getInputBufferSize()");
686
687 size_t size;
688
689 /* Take resampling ratio into account and align to the nearest
690 * 16 frames as required by the AudioFlinger */
691 /* Use port 0 for the calculation, since values for both ports are the same */
692 uint32_t frames = mReaders[kCPUPortId]->getParams().frameCount;
693 uint32_t rate = mReaders[kCPUPortId]->getParams().sampleRate;
694
695 size = (frames * config->sample_rate) / rate;
696 size = ((size + 15) & ~15) * mReaders[kCPUPortId]->getParams().frameSize();
697
698 ALOGV("AudioHwDevice: getInputBufferSize() %d bytes", size);
699
700 return size;
701}
702
703int AudioHwDevice::dump(int fd) const
704{
705 ALOGV("AudioHwDevice: dump()");
706
707 return 0;
708}
709
710int AudioHwDevice::setMasterMute(bool mute)
711{
712 ALOGV("AudioHwDevice: setMasterMute() %s", mute ? "mute" : "unmute");
713 return -ENOSYS;
714}
715
716AudioStreamIn* AudioHwDevice::openInputStream(audio_io_handle_t handle,
717 audio_devices_t devices,
718 struct audio_config *config)
719{
720 uint32_t port = 0;
721 uint32_t channels = popcount(config->channel_mask);
722
723 ALOGV("AudioHwDevice: openInputStream()");
724
725 uint32_t srcMask, dstMask;
726 switch (devices) {
727 case AUDIO_DEVICE_IN_BUILTIN_MIC:
728 case AUDIO_DEVICE_IN_VOICE_CALL:
729 if (channels == 1) {
730 /* Mic is in slots 0&1 (mask = 0x03) on port 0, but AF wants
731 * only mono so take only one channel here */
732 srcMask = 0x01;
733 dstMask = 0x01;
734 }
735 else {
736 srcMask = 0x03;
737 dstMask = 0x03;
738 }
739 port = 0;
740 break;
741 case AUDIO_DEVICE_IN_BACK_MIC:
742 if (channels == 1) {
743 srcMask = 0x08;
744 dstMask = 0x01;
745 }
746 else {
747 ALOGE("AudioHwDevice: device 0x%08x only supports 1 channel",
748 devices);
749 return NULL;
750 }
751 port = 1;
752 break;
753 default:
754 ALOGE("AudioHwDevice: device 0x%08x is not supported", devices);
755 return NULL;
756 }
757
758 SlotMap slotMap(srcMask, dstMask);
759
760 /* Set the parameters for the internal input stream. Don't change the
761 * parameters for capture. The resampler is used if needed. */
762 PcmParams params(*config, mReaders[port]->getParams().frameCount);
763
764 sp<AudioStreamIn> in = new AudioStreamIn(this, mReaders[port], params,
765 slotMap, devices);
766 if ((in == NULL) || in->initCheck()) {
767 ALOGE("AudioHwDevice: failed to open input stream on port hw:%u,%u",
768 mCardId, port);
769 return NULL;
770 }
771
772 mInStreams.insert(in);
773
774 return in.get();
775}
776
777void AudioHwDevice::closeInputStream(AudioStreamIn *in)
778{
779 ALOGV("AudioHwDevice: closeInputStream()");
780
781 if (mInStreams.find(in) == mInStreams.end()) {
782 ALOGW("AudioHwDevice: input stream %p is not open", in);
783 return;
784 }
785
786 mInStreams.erase(in);
787
788 in = NULL;
789}
790
791AudioStreamOut* AudioHwDevice::openOutputStream(audio_io_handle_t handle,
792 audio_devices_t devices,
793 audio_output_flags_t flags,
794 struct audio_config *config)
795{
796 uint32_t port = 0;
797 PcmParams params;
798
799 ALOGV("AudioHwDevice: openOutputStream()");
800
801 uint32_t destMask;
802 switch (devices) {
803 case AUDIO_DEVICE_OUT_SPEAKER:
804 port = 0;
805 destMask = 0x03;
806 break;
807 case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
808 case AUDIO_DEVICE_OUT_WIRED_HEADSET:
809 port = 1;
810 destMask = 0x0c;
811 break;
812 case AUDIO_DEVICE_OUT_WIRED_HEADPHONE2:
813 port = 1;
814 destMask = 0x30;
815 break;
816 default:
817 ALOGE("AudioHwDevice: device 0x%08x is not supported", devices);
818 return NULL;
819 }
820
821 SlotMap slotMap(0x03, destMask);
822 if (!slotMap.isValid()) {
823 ALOGE("AudioHwDevice: failed to create slot map");
824 return NULL;
825 }
826
827 /* Set the parameters for the internal output stream */
828 params.frameCount = mWriters[port]->getParams().frameCount;
829 params.sampleRate = config->sample_rate; /* Use stream's resampler if needed */
830 params.sampleBits = 16; /* 16-bits/sample */
831 params.channels = 2; /* Listening zones are stereo */
832
833 /* Update audio config with granted parameters */
834 if (popcount(config->channel_mask) != (int)params.channels) {
835 ALOGV("AudioHwDevice: updating audio config channel mask [0x%x]->[0x%x]",
836 config->channel_mask,
837 audio_channel_out_mask_from_count(params.channels));
838 }
839 config->channel_mask = audio_channel_out_mask_from_count(params.channels);
840 if (config->format != AUDIO_FORMAT_PCM_16_BIT) {
841 ALOGV("AudioHwDevice: updating audio config format [0x%x]->[0x%x]",
842 config->format, AUDIO_FORMAT_PCM_16_BIT);
843 }
844 config->format = AUDIO_FORMAT_PCM_16_BIT;
845
846 sp<AudioStreamOut> out = new AudioStreamOut(this, mWriters[port], params,
847 slotMap, devices);
848 if ((out == NULL) || out->initCheck()) {
849 ALOGE("AudioHwDevice: failed to open output stream on port hw:%u,%u",
850 mCardId, port);
851 return NULL;
852 }
853
854 mOutStreams.insert(out);
855
856 return out.get();
857}
858
859void AudioHwDevice::closeOutputStream(AudioStreamOut *out)
860{
861 ALOGV("AudioHwDevice: closeOutputStream()");
862
863 if (mOutStreams.find(out) == mOutStreams.end()) {
864 ALOGW("AudioHwDevice: output stream %p is not open", out);
865 return;
866 }
867
868 mOutStreams.erase(out);
869
870 out = NULL;
871}
872
873}; /* namespace android */
diff --git a/audio/multizone/AudioHw.h b/audio/multizone/AudioHw.h
new file mode 100644
index 0000000..2a5e296
--- /dev/null
+++ b/audio/multizone/AudioHw.h
@@ -0,0 +1,209 @@
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#ifndef _AUDIO_HW_H_
18#define _AUDIO_HW_H_
19
20#include <vector>
21
22#include <system/audio.h>
23#include <hardware/audio_effect.h>
24
25#include <tiaudioutils/Pcm.h>
26#include <tiaudioutils/ALSAPcm.h>
27#include <tiaudioutils/ALSAMixer.h>
28#include <tiaudioutils/MumStream.h>
29#include <tiaudioutils/Stream.h>
30#include <tiaudioutils/Base.h>
31
32namespace android {
33
34using namespace tiaudioutils;
35using std::vector;
36
37class AudioHwDevice;
38
39class AudioStream {
40 public:
41 virtual ~AudioStream() {}
42 virtual uint32_t getSampleRate() const = 0;
43 virtual int setSampleRate(uint32_t rate) = 0;
44 virtual size_t getBufferSize() const = 0;
45 virtual audio_channel_mask_t getChannels() const = 0;
46 virtual audio_format_t getFormat() const = 0;
47 virtual int setFormat(audio_format_t format) = 0;
48 virtual int standby() = 0;
49 virtual int dump(int fd) const = 0;
50 virtual audio_devices_t getDevice() const = 0;
51 virtual int setDevice(audio_devices_t device) { return 0; } /* unused */
52 virtual int setParameters(const char *kv_pairs) = 0;
53 virtual char *getParameters(const char *keys) const = 0;
54 virtual int addAudioEffect(effect_handle_t effect) const = 0;
55 virtual int removeAudioEffect(effect_handle_t effect) const = 0;
56
57 // FIXME not used
58 static const uint32_t kDefaultSampleRate = 44100;
59 static const uint32_t kDefaultBufferSize = 4096;
60};
61
62class AudioStreamOut : public RefBase, public AudioStream {
63 public:
64 AudioStreamOut(AudioHwDevice *hwDev,
65 PcmWriter *writer,
66 const PcmParams &params,
67 const SlotMap &map,
68 audio_devices_t devices);
69 virtual ~AudioStreamOut() {};
70 int initCheck() const;
71
72 /* From AudioStream */
73 virtual uint32_t getSampleRate() const;
74 virtual int setSampleRate(uint32_t rate);
75 virtual size_t getBufferSize() const;
76 virtual audio_channel_mask_t getChannels() const;
77 virtual audio_format_t getFormat() const;
78 virtual int setFormat(audio_format_t format);
79 virtual int standby();
80 virtual int dump(int fd) const;
81 virtual audio_devices_t getDevice() const;
82 virtual int setParameters(const char *kv_pairs);
83 virtual char *getParameters(const char *keys) const;
84 virtual int addAudioEffect(effect_handle_t effect) const;
85 virtual int removeAudioEffect(effect_handle_t effect) const;
86
87 /* AudioStreamOut specific */
88 uint32_t getLatency() const;
89 int setVolume(float left, float right);
90 ssize_t write(const void* buffer, size_t bytes);
91 int getRenderPosition(uint32_t *dsp_frames) const;
92 int getNextWriteTimestamp(int64_t *timestamp) const;
93
94 protected:
95 AudioHwDevice *mHwDev;
96 PcmWriter *mWriter;
97 PcmParams mParams;
98 audio_devices_t mDevices;
99 sp<OutStream> mStream;
100 bool mStandby;
101 Mutex mLock;
102};
103
104class AudioStreamIn : public RefBase, public AudioStream {
105 public:
106 AudioStreamIn(AudioHwDevice *hwDev,
107 PcmReader *reader,
108 const PcmParams &params,
109 const SlotMap &map,
110 audio_devices_t devices);
111 virtual ~AudioStreamIn() {};
112 int initCheck() const;
113
114 /* From AudioStream */
115 virtual uint32_t getSampleRate() const;
116 virtual int setSampleRate(uint32_t rate);
117 virtual size_t getBufferSize() const;
118 virtual audio_channel_mask_t getChannels() const;
119 virtual audio_format_t getFormat() const;
120 virtual int setFormat(audio_format_t format);
121 virtual int standby();
122 virtual int dump(int fd) const;
123 virtual audio_devices_t getDevice() const;
124 virtual int setParameters(const char *kv_pairs);
125 virtual char *getParameters(const char *keys) const;
126 virtual int addAudioEffect(effect_handle_t effect) const;
127 virtual int removeAudioEffect(effect_handle_t effect) const;
128
129 /* AudioStreamIn specific */
130 int setGain(float gain);
131 ssize_t read(void* buffer, size_t bytes);
132 uint32_t getInputFramesLost();
133
134 protected:
135 AudioHwDevice *mHwDev;
136 PcmReader *mReader;
137 PcmParams mParams;
138 audio_devices_t mDevices;
139 audio_source_t mSource;
140 sp<InStream> mStream;
141 bool mStandby;
142 Mutex mLock;
143};
144
145class AudioHwDevice {
146 public:
147 AudioHwDevice(uint32_t card);
148 virtual ~AudioHwDevice();
149
150 uint32_t getSupportedDevices() const;
151 int initCheck() const;
152 int setVoiceVolume(float volume);
153 int setMasterVolume(float volume);
154 int setMode(audio_mode_t mode);
155 int setMicMute(bool state);
156 int getMicMute(bool *state) const;
157 int setParameters(const char *kv_pairs);
158 char *getParameters(const char *keys) const;
159 size_t getInputBufferSize(const struct audio_config *config) const;
160 int dump(int fd) const;
161 int setMasterMute(bool mute);
162 AudioStreamIn* openInputStream(audio_io_handle_t handle,
163 audio_devices_t devices,
164 struct audio_config *config);
165 void closeInputStream(AudioStreamIn *in);
166 AudioStreamOut* openOutputStream(audio_io_handle_t handle,
167 audio_devices_t devices,
168 audio_output_flags_t flags,
169 struct audio_config *config);
170 void closeOutputStream(AudioStreamOut *out);
171
172 friend class AudioStreamIn;
173 friend class AudioStreamOut;
174
175 static const uint32_t kNumPorts = 2;
176 static const uint32_t kCPUPortId = 0;
177 static const uint32_t kJAMR3PortId = 1;
178 static const uint32_t kCPUNumChannels = 2;
179 static const uint32_t kJAMR3NumChannels = 8;
180
181 static const uint32_t kSampleRate = 44100;
182 static const uint32_t kSampleSize = 16;
183 static const uint32_t kCaptureFrameCount = 882;
184 static const uint32_t kPlaybackFrameCount = 1024;
185
186 protected:
187 typedef set< sp<AudioStreamIn> > StreamInSet;
188 typedef set< sp<AudioStreamOut> > StreamOutSet;
189 typedef vector<ALSAInPort*> InPortVect;
190 typedef vector<ALSAOutPort*> OutPortVect;
191 typedef vector<PcmReader*> ReaderVect;
192 typedef vector<PcmWriter*> WriterVect;
193
194 const char *getModeName(audio_mode_t mode) const;
195
196 uint32_t mCardId;
197 ALSAMixer mMixer;
198 InPortVect mInPorts;
199 OutPortVect mOutPorts;
200 ReaderVect mReaders;
201 WriterVect mWriters;
202 StreamInSet mInStreams;
203 StreamOutSet mOutStreams;
204 bool mMicMute;
205};
206
207}; // namespace android
208
209#endif /* _AUDIO_HW_H_ */
diff --git a/audio/multizone/audio_hw.cpp b/audio/multizone/audio_hw.cpp
new file mode 100644
index 0000000..3e429c4
--- /dev/null
+++ b/audio/multizone/audio_hw.cpp
@@ -0,0 +1,562 @@
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
20#include <errno.h>
21#include <stdint.h>
22#include <stdlib.h>
23#include <sys/time.h>
24
25#include <cutils/log.h>
26#include <cutils/str_parms.h>
27#include <cutils/properties.h>
28
29#include <system/audio.h>
30#include <hardware/hardware.h>
31#include <hardware/audio.h>
32#include <hardware/audio_effect.h>
33
34#include <AudioHw.h>
35
36extern "C" {
37
38namespace android {
39
40struct mz_audio_device {
41 struct audio_hw_device device;
42 AudioHwDevice *hwDev;
43};
44
45struct mz_stream_in {
46 struct audio_stream_in stream;
47 AudioStreamIn *streamIn;
48};
49
50struct mz_stream_out {
51 struct audio_stream_out stream;
52 AudioStreamOut *streamOut;
53};
54
55static inline AudioHwDevice *toAudioHwDev(struct audio_hw_device *dev)
56{
57 return reinterpret_cast<struct mz_audio_device *>(dev)->hwDev;
58}
59
60static inline const AudioHwDevice *tocAudioHwDev(const struct audio_hw_device *dev)
61{
62 return reinterpret_cast<const struct mz_audio_device *>(dev)->hwDev;
63}
64
65static inline AudioStreamIn *toStreamIn(struct audio_stream_in *in)
66{
67 return reinterpret_cast<struct mz_stream_in *>(in)->streamIn;
68}
69
70static inline const AudioStreamIn *tocStreamIn(const struct audio_stream_in *in)
71{
72 return reinterpret_cast<const struct mz_stream_in *>(in)->streamIn;
73}
74
75static inline AudioStreamOut *toStreamOut(struct audio_stream_out *out)
76{
77 return reinterpret_cast<struct mz_stream_out *>(out)->streamOut;
78}
79
80static inline const AudioStreamOut *tocStreamOut(const struct audio_stream_out *out)
81{
82 return reinterpret_cast<const struct mz_stream_out *>(out)->streamOut;
83}
84
85/* audio HAL functions */
86
87/* audio_stream_out implementation */
88
89static uint32_t out_get_sample_rate(const struct audio_stream *stream)
90{
91 const AudioStreamOut *out = tocStreamOut((audio_stream_out *)stream);
92 return out->getSampleRate();
93}
94
95static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
96{
97 AudioStreamOut *out = toStreamOut((audio_stream_out *)stream);
98 return out->setSampleRate(rate);
99}
100
101static size_t out_get_buffer_size(const struct audio_stream *stream)
102{
103 const AudioStreamOut *out = tocStreamOut((audio_stream_out *)stream);
104 return out->getBufferSize();
105}
106
107static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
108{
109 const AudioStreamOut *out = tocStreamOut((audio_stream_out *)stream);
110 return out->getChannels();
111}
112
113static audio_format_t out_get_format(const struct audio_stream *stream)
114{
115 const AudioStreamOut *out = tocStreamOut((audio_stream_out *)stream);
116 return out->getFormat();
117}
118
119static int out_set_format(struct audio_stream *stream, audio_format_t format)
120{
121 AudioStreamOut *out = toStreamOut((audio_stream_out *)stream);
122 return out->setFormat(format);
123}
124
125static int out_standby(struct audio_stream *stream)
126{
127 AudioStreamOut *out = toStreamOut((audio_stream_out *)stream);
128 return out->standby();
129}
130
131static int out_dump(const struct audio_stream *stream, int fd)
132{
133 const AudioStreamOut *out = tocStreamOut((audio_stream_out *)stream);
134 return out->dump(fd);
135}
136
137static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
138{
139 AudioStreamOut *out = toStreamOut((audio_stream_out *)stream);
140 return out->setParameters(kvpairs);
141}
142
143static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
144{
145 const AudioStreamOut *out = tocStreamOut((audio_stream_out *)stream);
146 return out->getParameters(keys);
147}
148
149static uint32_t out_get_latency(const struct audio_stream_out *stream)
150{
151 const AudioStreamOut *out = tocStreamOut((audio_stream_out *)stream);
152 return out->getLatency();
153}
154
155static int out_set_volume(struct audio_stream_out *stream, float left,
156 float right)
157{
158 AudioStreamOut *out = toStreamOut((audio_stream_out *)stream);
159 return out->setVolume(left, right);
160}
161
162static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
163 size_t bytes)
164{
165 AudioStreamOut *out = toStreamOut((audio_stream_out *)stream);
166 return out->write(buffer, bytes);
167}
168
169static int out_get_render_position(const struct audio_stream_out *stream,
170 uint32_t *dsp_frames)
171{
172 const AudioStreamOut *out = tocStreamOut((audio_stream_out *)stream);
173 return out->getRenderPosition(dsp_frames);
174}
175
176static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
177{
178 const AudioStreamOut *out = tocStreamOut((audio_stream_out *)stream);
179 return out->addAudioEffect(effect);
180}
181
182static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
183{
184 const AudioStreamOut *out = tocStreamOut((audio_stream_out *)stream);
185 return out->removeAudioEffect(effect);
186}
187
188static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
189 int64_t *timestamp)
190{
191 const AudioStreamOut *out = tocStreamOut((audio_stream_out *)stream);
192 return out->getNextWriteTimestamp(timestamp);
193}
194
195/* audio_stream_in implementation */
196
197static uint32_t in_get_sample_rate(const struct audio_stream *stream)
198{
199 const AudioStreamIn *in = tocStreamIn((audio_stream_in *)stream);
200 return in->getSampleRate();
201}
202
203static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
204{
205 AudioStreamIn *in = toStreamIn((audio_stream_in *)stream);
206 return in->setSampleRate(rate);
207}
208
209static size_t in_get_buffer_size(const struct audio_stream *stream)
210{
211 const AudioStreamIn *in = tocStreamIn((audio_stream_in *)stream);
212 return in->getBufferSize();
213}
214
215static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
216{
217 const AudioStreamIn *in = tocStreamIn((audio_stream_in *)stream);
218 return in->getChannels();
219}
220
221static audio_format_t in_get_format(const struct audio_stream *stream)
222{
223 const AudioStreamIn *in = tocStreamIn((audio_stream_in *)stream);
224 return in->getFormat();
225}
226
227static int in_set_format(struct audio_stream *stream, audio_format_t format)
228{
229 AudioStreamIn *in = toStreamIn((audio_stream_in *)stream);
230 return in->setFormat(format);
231}
232
233static int in_standby(struct audio_stream *stream)
234{
235 AudioStreamIn *in = toStreamIn((audio_stream_in *)stream);
236 return in->standby();
237}
238
239static int in_dump(const struct audio_stream *stream, int fd)
240{
241 const AudioStreamIn *in = tocStreamIn((audio_stream_in *)stream);
242 return in->dump(fd);
243}
244
245static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
246{
247 AudioStreamIn *in = toStreamIn((audio_stream_in *)stream);
248 return in->setParameters(kvpairs);
249}
250
251static char * in_get_parameters(const struct audio_stream *stream,
252 const char *keys)
253{
254 const AudioStreamIn *in = tocStreamIn((audio_stream_in *)stream);
255 return in->getParameters(keys);
256}
257
258static int in_set_gain(struct audio_stream_in *stream, float gain)
259{
260 AudioStreamIn *in = toStreamIn(stream);
261 return in->setGain(gain);
262}
263
264static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t bytes)
265{
266 AudioStreamIn *in = toStreamIn(stream);
267 return in->read(buffer, bytes);
268}
269
270static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
271{
272 AudioStreamIn *in = toStreamIn(stream);
273 return in->getInputFramesLost();
274}
275
276static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
277{
278 const AudioStreamIn *in = tocStreamIn((audio_stream_in *)stream);
279 return in->addAudioEffect(effect);
280}
281
282static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
283{
284 const AudioStreamIn *in = tocStreamIn((audio_stream_in *)stream);
285 return in->removeAudioEffect(effect);
286}
287
288/* audio_hw_device implementation */
289
290static int adev_open_output_stream(struct audio_hw_device *dev,
291 audio_io_handle_t handle,
292 audio_devices_t devices,
293 audio_output_flags_t flags,
294 struct audio_config *config,
295 struct audio_stream_out **stream_out)
296{
297 AudioHwDevice *hwDev = toAudioHwDev(dev);
298 struct mz_stream_out *out;
299
300 out = (struct mz_stream_out *)malloc(sizeof(*out));
301 if (!out)
302 return -ENOMEM;
303
304 ALOGV("adev_open_output_stream() stream %p, %u Hz, %u channels, "
305 "%u bits/sample, flags 0x%08x",
306 out, config->sample_rate, popcount(config->channel_mask),
307 audio_bytes_per_sample(config->format) * 8, flags);
308
309 out->stream.common.get_sample_rate = out_get_sample_rate;
310 out->stream.common.set_sample_rate = out_set_sample_rate;
311 out->stream.common.get_buffer_size = out_get_buffer_size;
312 out->stream.common.get_channels = out_get_channels;
313 out->stream.common.get_format = out_get_format;
314 out->stream.common.set_format = out_set_format;
315 out->stream.common.standby = out_standby;
316 out->stream.common.dump = out_dump;
317 out->stream.common.set_parameters = out_set_parameters;
318 out->stream.common.get_parameters = out_get_parameters;
319 out->stream.common.add_audio_effect = out_add_audio_effect;
320 out->stream.common.remove_audio_effect = out_remove_audio_effect;
321 out->stream.get_latency = out_get_latency;
322 out->stream.set_volume = out_set_volume;
323 out->stream.write = out_write;
324 out->stream.get_render_position = out_get_render_position;
325 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
326
327 out->streamOut = hwDev->openOutputStream(handle, devices, flags, config);
328 if (!out->streamOut) {
329 ALOGE("adev_open_output_stream() failed to open stream");
330 free(out);
331 return -ENODEV;
332 }
333
334 *stream_out = &out->stream;
335
336 return 0;
337}
338
339static void adev_close_output_stream(struct audio_hw_device *dev,
340 struct audio_stream_out *stream)
341{
342 AudioHwDevice *hwDev = toAudioHwDev(dev);
343 AudioStreamOut *out = toStreamOut(stream);
344
345 ALOGV("adev_close_output_stream() stream %p", stream);
346
347 out_standby(&stream->common);
348
349 /* closeOutputStream() also deletes the out object */
350 hwDev->closeOutputStream(out);
351
352 free(stream);
353}
354
355static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
356{
357 AudioHwDevice *hwDev = toAudioHwDev(dev);
358 return hwDev->setParameters(kvpairs);
359}
360
361static char *adev_get_parameters(const struct audio_hw_device *dev,
362 const char *keys)
363{
364 const AudioHwDevice *hwDev = tocAudioHwDev(dev);
365 return hwDev->getParameters(keys);
366}
367
368static int adev_init_check(const struct audio_hw_device *dev)
369{
370 const AudioHwDevice *hwDev = tocAudioHwDev(dev);
371 return hwDev->initCheck();
372}
373
374static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
375{
376 AudioHwDevice *hwDev = toAudioHwDev(dev);
377 return hwDev->setVoiceVolume(volume);
378}
379
380static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
381{
382 AudioHwDevice *hwDev = toAudioHwDev(dev);
383 return hwDev->setMasterVolume(volume);
384}
385
386static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
387{
388 AudioHwDevice *hwDev = toAudioHwDev(dev);
389 return hwDev->setMasterMute(muted);
390}
391
392static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
393{
394 AudioHwDevice *hwDev = toAudioHwDev(dev);
395 return hwDev->setMode(mode);
396}
397
398static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
399{
400 AudioHwDevice *hwDev = toAudioHwDev(dev);
401 return hwDev->setMicMute(state);
402}
403
404static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
405{
406 const AudioHwDevice *hwDev = tocAudioHwDev(dev);
407 return hwDev->getMicMute(state);
408}
409
410static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
411 const struct audio_config *config)
412{
413 const AudioHwDevice *hwDev = tocAudioHwDev(dev);
414 return hwDev->getInputBufferSize(config);
415}
416
417static int adev_open_input_stream(struct audio_hw_device *dev,
418 audio_io_handle_t handle,
419 audio_devices_t devices,
420 struct audio_config *config,
421 struct audio_stream_in **stream_in)
422{
423 AudioHwDevice *hwDev = toAudioHwDev(dev);
424 struct mz_stream_in *in;
425 int ret;
426
427 in = (struct mz_stream_in *)malloc(sizeof(*in));
428 if (!in)
429 return -ENOMEM;
430
431 ALOGV("adev_open_input_stream() stream %p, %u Hz, %u channels, "
432 "%u bits/sample",
433 in, config->sample_rate, popcount(config->channel_mask),
434 audio_bytes_per_sample(config->format) * 8);
435
436 in->stream.common.get_sample_rate = in_get_sample_rate;
437 in->stream.common.set_sample_rate = in_set_sample_rate;
438 in->stream.common.get_buffer_size = in_get_buffer_size;
439 in->stream.common.get_channels = in_get_channels;
440 in->stream.common.get_format = in_get_format;
441 in->stream.common.set_format = in_set_format;
442 in->stream.common.standby = in_standby;
443 in->stream.common.dump = in_dump;
444 in->stream.common.set_parameters = in_set_parameters;
445 in->stream.common.get_parameters = in_get_parameters;
446 in->stream.common.add_audio_effect = in_add_audio_effect;
447 in->stream.common.remove_audio_effect = in_remove_audio_effect;
448 in->stream.set_gain = in_set_gain;
449 in->stream.read = in_read;
450 in->stream.get_input_frames_lost = in_get_input_frames_lost;
451
452 in->streamIn = hwDev->openInputStream(handle, devices, config);
453 if (!in->streamIn) {
454 ALOGE("adev_open_input_stream() failed to open stream");
455 free(in);
456 return -ENODEV;
457 }
458
459 *stream_in = &in->stream;
460
461 return 0;
462}
463
464static void adev_close_input_stream(struct audio_hw_device *dev,
465 struct audio_stream_in *stream)
466{
467 AudioHwDevice *hwDev = toAudioHwDev(dev);
468 AudioStreamIn *in = toStreamIn(stream);
469
470 ALOGV("adev_close_input_stream() stream %p", stream);
471
472 in_standby(&stream->common);
473
474 /* closeInputStream() also deletes the in object */
475 hwDev->closeInputStream(in);
476
477 free(stream);
478}
479
480static int adev_dump(const audio_hw_device_t *device, int fd)
481{
482 return 0;
483}
484
485static uint32_t adev_get_supported_devices(const struct audio_hw_device *dev)
486{
487 const AudioHwDevice *hwDev = tocAudioHwDev(dev);
488 return hwDev->getSupportedDevices();
489}
490
491static int adev_close(hw_device_t *device)
492{
493 ALOGI("adev_close()");
494
495 free(device);
496
497 return 0;
498}
499
500static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device)
501{
502 struct mz_audio_device *adev;
503
504 ALOGI("adev_open() %s", name);
505
506 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
507 return -EINVAL;
508
509 adev = (struct mz_audio_device*)calloc(1, sizeof(*adev));
510 if (!adev)
511 return -ENOMEM;
512
513 adev->device.common.tag = HARDWARE_DEVICE_TAG;
514 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
515 adev->device.common.module = (struct hw_module_t *) module;
516 adev->device.common.close = adev_close;
517
518 adev->device.get_supported_devices = adev_get_supported_devices;
519 adev->device.init_check = adev_init_check;
520 adev->device.set_voice_volume = adev_set_voice_volume;
521 adev->device.set_master_volume = adev_set_master_volume;
522 adev->device.set_master_mute = adev_set_master_mute;
523 adev->device.set_mode = adev_set_mode;
524 adev->device.set_mic_mute = adev_set_mic_mute;
525 adev->device.get_mic_mute = adev_get_mic_mute;
526 adev->device.set_parameters = adev_set_parameters;
527 adev->device.get_parameters = adev_get_parameters;
528 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
529 adev->device.open_output_stream = adev_open_output_stream;
530 adev->device.close_output_stream = adev_close_output_stream;
531 adev->device.open_input_stream = adev_open_input_stream;
532 adev->device.close_input_stream = adev_close_input_stream;
533 adev->device.dump = adev_dump;
534
535 adev->hwDev = new AudioHwDevice(0);
536
537 *device = &adev->device.common;
538
539 return 0;
540}
541
542static struct hw_module_methods_t hal_module_methods = {
543 /* open */ adev_open,
544};
545
546struct audio_module HAL_MODULE_INFO_SYM = {
547 /* common */ {
548 /* tag*/ HARDWARE_MODULE_TAG,
549 /* module_api_version */AUDIO_MODULE_API_VERSION_0_1,
550 /* hal_api_version */ HARDWARE_HAL_API_VERSION,
551 /* id */ AUDIO_HARDWARE_MODULE_ID,
552 /* name */ "Jacinto6 Multizone Audio HAL",
553 /* author */ "Texas Instruments Inc.",
554 /* methods */ &hal_module_methods,
555 /* dso */ NULL,
556 /* reserved */ {0},
557 },
558};
559
560} /* namespace android */
561
562} /* extern "C" */
diff --git a/audio/multizone/audio_policy.conf b/audio/multizone/audio_policy.conf
new file mode 100644
index 0000000..2f4eb19
--- /dev/null
+++ b/audio/multizone/audio_policy.conf
@@ -0,0 +1,116 @@
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|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_WIRED_HEADPHONE2
7 default_output_device AUDIO_DEVICE_OUT_SPEAKER
8 attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC
9}
10
11# Zone affinity section: lists the output devices allowed per listening zone. Devices are
12# designated by a string that corresponds to the enum in audio.h. Multiple devices can be
13# concatenated by use of "|" without space or "\n".
14
15zone_affinity {
16 CABIN AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_ALL_A2DP|AUDIO_DEVICE_IN_REMOTE_SUBMIX
17 BACKSEAT1 AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_A2DP|AUDIO_DEVICE_IN_REMOTE_SUBMIX
18 BACKSEAT2 AUDIO_DEVICE_OUT_WIRED_HEADPHONE2|AUDIO_DEVICE_OUT_ALL_A2DP|AUDIO_DEVICE_IN_REMOTE_SUBMIX
19}
20
21# audio hardware module section: contains descriptors for all audio hw modules present on the
22# device. Each hw module node is named after the corresponding hw module library base name.
23# For instance, "primary" corresponds to audio.primary.<device>.so.
24# The "primary" module is mandatory and must include at least one output with
25# AUDIO_OUTPUT_FLAG_PRIMARY flag.
26# Each module descriptor contains one or more output profile descriptors and zero or more
27# input profile descriptors. Each profile lists all the parameters supported by a given output
28# or input stream category.
29# The "channel_masks", "formats", "devices" and "flags" are specified using strings corresponding
30# to enums in audio.h and audio_policy.h. They are concatenated by use of "|" without space or "\n".
31
32audio_hw_modules {
33 primary {
34 outputs {
35 primary {
36 sampling_rates 44100
37 channel_masks AUDIO_CHANNEL_OUT_STEREO
38 formats AUDIO_FORMAT_PCM_16_BIT
39 devices AUDIO_DEVICE_OUT_SPEAKER
40 flags AUDIO_OUTPUT_FLAG_PRIMARY
41 }
42 hp1 {
43 sampling_rates 44100
44 channel_masks AUDIO_CHANNEL_OUT_STEREO
45 formats AUDIO_FORMAT_PCM_16_BIT
46 devices AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE
47 }
48 hp2 {
49 sampling_rates 44100
50 channel_masks AUDIO_CHANNEL_OUT_STEREO
51 formats AUDIO_FORMAT_PCM_16_BIT
52 devices AUDIO_DEVICE_OUT_WIRED_HEADPHONE2
53 }
54 }
55 inputs {
56 primary {
57 sampling_rates 8000|11025|16000|22050|32000|44100|48000
58 channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO
59 formats AUDIO_FORMAT_PCM_16_BIT
60 devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_VOICE_CALL
61 }
62 }
63 }
64 hdmi {
65 outputs {
66 stereo {
67 sampling_rates 44100|48000
68 channel_masks AUDIO_CHANNEL_OUT_STEREO
69 formats AUDIO_FORMAT_PCM_16_BIT
70 devices AUDIO_DEVICE_OUT_AUX_DIGITAL
71 }
72 multichannel {
73 sampling_rates 44100|48000
74 channel_masks dynamic
75 formats AUDIO_FORMAT_PCM_16_BIT
76 devices AUDIO_DEVICE_OUT_AUX_DIGITAL
77 flags AUDIO_OUTPUT_FLAG_DIRECT
78 }
79 }
80 }
81 a2dp {
82 outputs {
83 a2dp {
84 sampling_rates 44100
85 channel_masks AUDIO_CHANNEL_OUT_STEREO
86 formats AUDIO_FORMAT_PCM_16_BIT
87 devices AUDIO_DEVICE_OUT_ALL_A2DP
88 }
89 }
90 }
91 r_submix {
92 outputs {
93 r_submix {
94 sampling_rates 44100|48000
95 channel_masks AUDIO_CHANNEL_OUT_STEREO
96 formats AUDIO_FORMAT_PCM_16_BIT
97 devices AUDIO_DEVICE_OUT_REMOTE_SUBMIX
98 }
99 multichannel {
100 sampling_rates 44100|48000
101 channel_masks AUDIO_CHANNEL_OUT_5POINT1
102 formats AUDIO_FORMAT_PCM_16_BIT
103 devices AUDIO_DEVICE_OUT_REMOTE_SUBMIX
104 flags AUDIO_OUTPUT_FLAG_DIRECT
105 }
106 }
107 inputs {
108 r_submix {
109 sampling_rates 44100|48000
110 channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_5POINT1EMUL
111 formats AUDIO_FORMAT_PCM_16_BIT
112 devices AUDIO_DEVICE_IN_REMOTE_SUBMIX
113 }
114 }
115 }
116}
diff --git a/audio/multizone/dra7evm_paths.xml b/audio/multizone/dra7evm_paths.xml
new file mode 100644
index 0000000..a64ea4c
--- /dev/null
+++ b/audio/multizone/dra7evm_paths.xml
@@ -0,0 +1,110 @@
1<mixer>
2
3<!-- Card default routes -->
4
5<!-- Capture: Mic -->
6<ctl name="Left PGA Mixer Mic3L Switch" value="1" />
7<ctl name="Right PGA Mixer Mic3R Switch" value="1" />
8<ctl name="PGA Capture Switch" value="1" />
9<ctl name="PGA Capture Volume" value="24" />
10<ctl name="Left Line1L Mux" value="single-ended" />
11<ctl name="Right Line1L Mux" value="single-ended" />
12<ctl name="Left Line1R Mux" value="single-ended" />
13<ctl name="Right Line1R Mux" value="single-ended" />
14
15<!-- Playback: Line-Out and Headphone -->
16<ctl name="Left DAC Mux" value="DAC_L1" />
17<ctl name="Right DAC Mux" value="DAC_R1" />
18<ctl name="PCM Playback Volume" value="127" />
19
20<ctl name="Left HP Mixer DACL1 Switch" value="1" />
21<ctl name="Right HP Mixer DACR1 Switch" value="1" />
22<ctl name="HP Playback Switch" value="1" />
23<ctl name="HP DAC Playback Volume" value="118" />
24<ctl name="Output Driver Power-On time" value="200ms" />
25
26<ctl name="Left Line Mixer DACL1 Switch" value="1" />
27<ctl name="Right Line Mixer DACR1 Switch" value="1" />
28<ctl name="Line Playback Switch" value="1" />
29<ctl name="Line DAC Playback Volume" value="118" />
30
31<!-- JAMR3 board, codec-A input: Line-In -->
32<ctl name="J3A Left PGA Mixer Line1L Switch" value="1" />
33<ctl name="J3A Right PGA Mixer Line1R Switch" value="1" />
34<ctl name="J3A PGA Capture Switch" value="0" />
35<ctl name="J3A PGA Capture Volume" value="0" />
36<ctl name="J3A Left Line1L Mux" value="differential" />
37<ctl name="J3A Right Line1L Mux" value="differential" />
38<ctl name="J3A Left Line1R Mux" value="differential" />
39<ctl name="J3A Right Line1R Mux" value="differential" />
40
41<!-- JAMR3 board, codec-B input: Mic -->
42<ctl name="J3B Left PGA Mixer Line1L Switch" value="1" />
43<ctl name="J3B Right PGA Mixer Line1R Switch" value="1" />
44<ctl name="J3B PGA Capture Switch" value="0" />
45<ctl name="J3B PGA Capture Volume" value="0" />
46<ctl name="J3B Left Line1L Mux" value="differential" />
47<ctl name="J3B Right Line1L Mux" value="differential" />
48<ctl name="J3B Left Line1R Mux" value="differential" />
49<ctl name="J3B Right Line1R Mux" value="differential" />
50
51<!-- JAMR3 board, codec-A output: Line-Out -->
52<ctl name="J3A Left DAC Mux" value="DAC_L1" />
53<ctl name="J3A Right DAC Mux" value="DAC_R1" />
54<ctl name="J3A Left Line Mixer DACL1 Switch" value="1" />
55<ctl name="J3A Right Line Mixer DACR1 Switch" value="1" />
56<ctl name="J3A Line DAC Playback Volume" value="0" />
57<ctl name="J3A Line Playback Switch" value="1" />
58<ctl name="J3A PCM Playback Volume" value="127" />
59
60<!-- JAMR3 board, codec-B Output: Line-Out -->
61<ctl name="J3B Left DAC Mux" value="DAC_L1" />
62<ctl name="J3B Right DAC Mux" value="DAC_R1" />
63<ctl name="J3B Left Line Mixer DACL1 Switch" value="1" />
64<ctl name="J3B Right Line Mixer DACR1 Switch" value="1" />
65<ctl name="J3B Line DAC Playback Volume" value="0" />
66<ctl name="J3B Line Playback Switch" value="1" />
67<ctl name="J3B PCM Playback Volume" value="127" />
68
69<!-- JAMR3 board, codec-C Output: Line-Out -->
70<ctl name="J3C Left DAC Mux" value="DAC_L1" />
71<ctl name="J3C Right DAC Mux" value="DAC_R1" />
72<ctl name="J3C Left Line Mixer DACL1 Switch" value="1" />
73<ctl name="J3C Right Line Mixer DACR1 Switch" value="1" />
74<ctl name="J3C Line DAC Playback Volume" value="0" />
75<ctl name="J3C Line Playback Switch" value="1" />
76<ctl name="J3C PCM Playback Volume" value="127" />
77
78<!-- Device specific routes -->
79
80<!-- JAMR3 codec A input: Line-In -->
81<path name="AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET">
82<ctl name="J3A PGA Capture Switch" value="1" />
83</path>
84
85<!-- On-board input: Stereo mic -->
86<path name="AUDIO_DEVICE_IN_BUILTIN_MIC">
87<ctl name="PGA Capture Switch" value="1" />
88</path>
89
90<!-- JAMR3 codec B input: Mono mic right -->
91<path name="AUDIO_DEVICE_IN_BACK_MIC">
92<ctl name="J3B PGA Capture Switch" id="1" value="1" />
93</path>
94
95<!-- On-board output: Line-Out -->
96<path name="AUDIO_DEVICE_OUT_SPEAKER">
97<ctl name="Line DAC Playback Volume" value="118" />
98</path>
99
100<!-- JAMR3 codec B output: Line-Out -->
101<path name="AUDIO_DEVICE_OUT_WIRED_HEADPHONE">
102<ctl name="J3B Line DAC Playback Volume" value="118" />
103</path>
104
105<!-- JAMR3 codec C output: Line-Out -->
106<path name="AUDIO_DEVICE_OUT_WIRED_HEADPHONE2">
107<ctl name="J3C Line DAC Playback Volume" value="118" />
108</path>
109
110</mixer>