1 /* AudioStreamOutALSA.cpp
3 ** Copyright 2008-2009 Wind River Systems
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
9 ** http://www.apache.org/licenses/LICENSE-2.0
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
26 #define LOG_TAG "AudioHardwareALSA"
27 #include <utils/Log.h>
28 #include <utils/String8.h>
30 #include <cutils/properties.h>
31 #include <media/AudioRecord.h>
32 #include <hardware_legacy/power.h>
34 #include "AudioHardwareALSA.h"
36 #ifndef ALSA_DEFAULT_SAMPLE_RATE
37 #define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
43 // ----------------------------------------------------------------------------
45 static const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE;
47 // ----------------------------------------------------------------------------
49 AudioStreamOutALSA::AudioStreamOutALSA(AudioHardwareALSA *parent, alsa_handle_t *handle) :
50 ALSAStreamOps(parent, handle),
55 AudioStreamOutALSA::~AudioStreamOutALSA()
60 uint32_t AudioStreamOutALSA::channels() const
62 int c = ALSAStreamOps::channels();
66 status_t AudioStreamOutALSA::setVolume(float left, float right)
68 return mixer()->setVolume (mHandle->curDev, left, right);
71 ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes)
73 AutoMutex lock(mLock);
76 acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock");
80 acoustic_device_t *aDev = acoustics();
82 // For output, we will pass the data on to the acoustics module, but the actual
83 // data is expected to be sent to the audio device directly as well.
84 if (aDev && aDev->write)
85 aDev->write(aDev, buffer, bytes);
92 n = snd_pcm_writei(mHandle->handle,
93 (char *)buffer + sent,
94 snd_pcm_bytes_to_frames(mHandle->handle, bytes - sent));
96 // Somehow the stream is in a bad state. The driver probably
97 // has a bug and snd_pcm_recover() doesn't seem to handle this.
98 mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode);
100 if (aDev && aDev->recover) aDev->recover(aDev, n);
103 if (mHandle->handle) {
104 // snd_pcm_recover() will return 0 if successful in recovering from
105 // an error, or -errno if the error was unrecoverable.
106 n = snd_pcm_recover(mHandle->handle, n, 1);
108 if (aDev && aDev->recover) aDev->recover(aDev, n);
110 if (n) return static_cast<ssize_t>(n);
115 sent += static_cast<ssize_t>(snd_pcm_frames_to_bytes(mHandle->handle, n));
118 } while (mHandle->handle && sent < bytes);
123 status_t AudioStreamOutALSA::dump(int fd, const Vector<String16>& args)
128 status_t AudioStreamOutALSA::open(int mode)
130 AutoMutex lock(mLock);
132 return ALSAStreamOps::open(mode);
135 status_t AudioStreamOutALSA::close()
137 AutoMutex lock(mLock);
139 snd_pcm_drain (mHandle->handle);
140 ALSAStreamOps::close();
143 release_wake_lock ("AudioOutLock");
150 status_t AudioStreamOutALSA::standby()
152 AutoMutex lock(mLock);
154 snd_pcm_drain (mHandle->handle);
157 release_wake_lock ("AudioOutLock");
166 #define USEC_TO_MSEC(x) ((x + 999) / 1000)
168 uint32_t AudioStreamOutALSA::latency() const
170 // Android wants latency in milliseconds.
171 return USEC_TO_MSEC (mHandle->latency);
174 // return the number of audio frames written by the audio dsp to DAC since
175 // the output has exited standby
176 status_t AudioStreamOutALSA::getRenderPosition(uint32_t *dspFrames)
178 *dspFrames = mFrameCount;
182 } // namespace android