OSDN Git Service

bff4534ce8f1548b3cff8bc1b3cb76133f93a1fa
[android-x86/hardware-alsa_sound.git] / AudioHardwareALSA.cpp
1 /* AudioHardwareALSA.cpp
2  **
3  ** Copyright 2008-2010 Wind River Systems
4  **
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
8  **
9  **     http://www.apache.org/licenses/LICENSE-2.0
10  **
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.
16  */
17
18 #include <errno.h>
19 #include <stdarg.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <dlfcn.h>
25
26 #define LOG_TAG "AudioHardwareALSA"
27 #include <utils/Log.h>
28 #include <utils/String8.h>
29
30 #include <cutils/properties.h>
31 #include <media/AudioRecord.h>
32 #include <hardware_legacy/power.h>
33
34 #include "AudioHardwareALSA.h"
35
36 extern "C"
37 {
38     //
39     // Function for dlsym() to look up for creating a new AudioHardwareInterface.
40     //
41     android::AudioHardwareInterface *createAudioHardware(void) {
42         return android::AudioHardwareALSA::create();
43     }
44 }         // extern "C"
45
46 namespace android
47 {
48
49 // ----------------------------------------------------------------------------
50
51 static void ALSAErrorHandler(const char *file,
52                              int line,
53                              const char *function,
54                              int err,
55                              const char *fmt,
56                              ...)
57 {
58     char buf[BUFSIZ];
59     va_list arg;
60     int l;
61
62     va_start(arg, fmt);
63     l = snprintf(buf, BUFSIZ, "%s:%i:(%s) ", file, line, function);
64     vsnprintf(buf + l, BUFSIZ - l, fmt, arg);
65     buf[BUFSIZ-1] = '\0';
66     LOG(LOG_ERROR, "ALSALib", buf);
67     va_end(arg);
68 }
69
70 AudioHardwareInterface *AudioHardwareALSA::create() {
71     return new AudioHardwareALSA();
72 }
73
74 AudioHardwareALSA::AudioHardwareALSA() :
75     mALSADevice(0),
76     mAcousticDevice(0)
77 {
78     snd_lib_error_set_handler(&ALSAErrorHandler);
79     mMixer = new ALSAMixer;
80
81     hw_module_t *module;
82     int err = hw_get_module(ALSA_HARDWARE_MODULE_ID,
83             (hw_module_t const**)&module);
84
85     if (err == 0) {
86         hw_device_t* device;
87         err = module->methods->open(module, ALSA_HARDWARE_NAME, &device);
88         if (err == 0) {
89             mALSADevice = (alsa_device_t *)device;
90             mALSADevice->init(mALSADevice, mDeviceList);
91         } else
92             LOGE("ALSA Module could not be opened!!!");
93     } else
94         LOGE("ALSA Module not found!!!");
95
96     err = hw_get_module(ACOUSTICS_HARDWARE_MODULE_ID,
97             (hw_module_t const**)&module);
98
99     if (err == 0) {
100         hw_device_t* device;
101         err = module->methods->open(module, ACOUSTICS_HARDWARE_NAME, &device);
102         if (err == 0)
103             mAcousticDevice = (acoustic_device_t *)device;
104         else
105             LOGE("Acoustics Module not found.");
106     }
107 }
108
109 AudioHardwareALSA::~AudioHardwareALSA()
110 {
111     if (mMixer) delete mMixer;
112     if (mALSADevice)
113         mALSADevice->common.close(&mALSADevice->common);
114     if (mAcousticDevice)
115         mAcousticDevice->common.close(&mAcousticDevice->common);
116 }
117
118 status_t AudioHardwareALSA::initCheck()
119 {
120     if (!mALSADevice)
121         return NO_INIT;
122
123     if (!mMixer || !mMixer->isValid())
124         LOGW("ALSA Mixer is not valid. AudioFlinger will do software volume control.");
125
126     return NO_ERROR;
127 }
128
129 status_t AudioHardwareALSA::setVoiceVolume(float volume)
130 {
131     // The voice volume is used by the VOICE_CALL audio stream.
132     if (mMixer)
133         return mMixer->setVolume(AudioSystem::DEVICE_OUT_EARPIECE, volume, volume);
134     else
135         return INVALID_OPERATION;
136 }
137
138 status_t AudioHardwareALSA::setMasterVolume(float volume)
139 {
140     if (mMixer)
141         return mMixer->setMasterVolume(volume);
142     else
143         return INVALID_OPERATION;
144 }
145
146 status_t AudioHardwareALSA::setMode(int mode)
147 {
148     status_t status = NO_ERROR;
149
150     if (mode != mMode) {
151         status = AudioHardwareBase::setMode(mode);
152
153         if (status == NO_ERROR) {
154             // take care of mode change.
155             for(ALSAHandleList::iterator it = mDeviceList.begin();
156                 it != mDeviceList.end(); ++it) {
157                 status = mALSADevice->route(&(*it), it->curDev, mode);
158                 if (status != NO_ERROR)
159                     break;
160             }
161         }
162     }
163
164     return status;
165 }
166
167 AudioStreamOut *
168 AudioHardwareALSA::openOutputStream(uint32_t devices,
169                                     int *format,
170                                     uint32_t *channels,
171                                     uint32_t *sampleRate,
172                                     status_t *status)
173 {
174     AutoMutex lock(mLock);
175
176     LOGD("openOutputStream called for devices: 0x%08x", devices);
177
178     status_t err = BAD_VALUE;
179     AudioStreamOutALSA *out = 0;
180
181     if (devices & (devices - 1)) {
182         if (status) *status = err;
183         LOGD("openOutputStream called with bad devices");
184         return out;
185     }
186
187     // Find the appropriate alsa device
188     for(ALSAHandleList::iterator it = mDeviceList.begin();
189         it != mDeviceList.end(); ++it)
190         if (it->devices & devices) {
191             err = mALSADevice->open(&(*it), devices, mode());
192             if (err) break;
193             out = new AudioStreamOutALSA(this, &(*it));
194             err = out->set(format, channels, sampleRate);
195             break;
196         }
197
198     if (status) *status = err;
199     return out;
200 }
201
202 void
203 AudioHardwareALSA::closeOutputStream(AudioStreamOut* out)
204 {
205     AutoMutex lock(mLock);
206     delete out;
207 }
208
209 AudioStreamIn *
210 AudioHardwareALSA::openInputStream(uint32_t devices,
211                                    int *format,
212                                    uint32_t *channels,
213                                    uint32_t *sampleRate,
214                                    status_t *status,
215                                    AudioSystem::audio_in_acoustics acoustics)
216 {
217     AutoMutex lock(mLock);
218
219     status_t err = BAD_VALUE;
220     AudioStreamInALSA *in = 0;
221
222     if (devices & (devices - 1)) {
223         if (status) *status = err;
224         return in;
225     }
226
227     // Find the appropriate alsa device
228     for(ALSAHandleList::iterator it = mDeviceList.begin();
229         it != mDeviceList.end(); ++it)
230         if (it->devices & devices) {
231             err = mALSADevice->open(&(*it), devices, mode());
232             if (err) break;
233             in = new AudioStreamInALSA(this, &(*it), acoustics);
234             err = in->set(format, channels, sampleRate);
235             break;
236         }
237
238     if (status) *status = err;
239     return in;
240 }
241
242 void
243 AudioHardwareALSA::closeInputStream(AudioStreamIn* in)
244 {
245     AutoMutex lock(mLock);
246     delete in;
247 }
248
249 status_t AudioHardwareALSA::setMicMute(bool state)
250 {
251     if (mMixer)
252         return mMixer->setCaptureMuteState(AudioSystem::DEVICE_OUT_EARPIECE, state);
253
254     return NO_INIT;
255 }
256
257 status_t AudioHardwareALSA::getMicMute(bool *state)
258 {
259     if (mMixer)
260         return mMixer->getCaptureMuteState(AudioSystem::DEVICE_OUT_EARPIECE, state);
261
262     return NO_ERROR;
263 }
264
265 status_t AudioHardwareALSA::dump(int fd, const Vector<String16>& args)
266 {
267     return NO_ERROR;
268 }
269
270 }       // namespace android