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/AudioHw.cpp
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/AudioHw.cpp')
-rw-r--r--audio/multizone/AudioHw.cpp873
1 files changed, 873 insertions, 0 deletions
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 */