AudioHardware: Dispatch setParameters to input and output
[tinyalsa-audio.git] / AudioHardware.cpp
1 /*
2  * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
3  * 
4  * This is based on TinyHardware:
5  * Copyright 2011 Wolfson Microelectronics plc
6  *
7  * This is based on Nexus S AudioHardware implementation:
8  * Copyright 2010, The Android Open-Source Project
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *     http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  */
22
23 #define LOG_TAG "AudioHardware"
24
25 #include "tinyalsa/asoundlib.h"
26
27 #include "AudioHardware.h"
28 #include "AudioStreamOut.h"
29 #include "AudioStreamIn.h"
30 #include "AudioRILInterface.h"
31
32 namespace android {
33
34 AudioHardware::AudioHardware() :
35         mInit(false),
36         mOutput(NULL),
37         mInput(NULL),
38         mRILInterface(NULL),
39         mInDevices(0),
40         mOutDevices(0),
41         mMode(AudioSystem::MODE_NORMAL),
42         mVoiceVolume(0),
43         mMicMute(false)
44 {
45         LOGD("AudioHardware()");
46
47         mInit = true;
48         mRILInterface = new TinyALSAAudioRILInterface();
49 }
50
51 AudioHardware::~AudioHardware()
52 {
53         LOGD("~AudioHardware()");
54
55         mInit = false;
56         closeOutputStream((AudioStreamOut *) mOutput);
57         closeInputStream((AudioStreamIn *) mInput);
58 }
59
60 status_t AudioHardware::initCheck()
61 {
62         LOGD("initCheck()");
63
64         return mInit ? NO_ERROR : NO_INIT;
65 }
66
67 status_t AudioHardware::setVoiceVolume(float volume)
68 {
69         LOGD("setVoiceVolume(%f)", volume);
70
71         mVoiceVolume = volume;
72
73         if(mOutput && mOutput->mMixer)
74                 mOutput->mMixer->setVoiceVolume(volume);
75
76         if(mRILInterface)
77                 mRILInterface->setVoiceVolume(volume);
78
79         return NO_ERROR;
80 }
81
82 status_t AudioHardware::getVoiceVolume(float *volume)
83 {
84         LOGD("getVoiceVolume()");
85
86         if(volume != NULL)
87                 *volume = mVoiceVolume;
88
89         return NO_ERROR;
90 }
91
92 status_t AudioHardware::setMasterVolume(float volume)
93 {
94         LOGD("setMasterVolume(%f)", volume);
95
96         return BAD_VALUE;
97 }
98
99 status_t AudioHardware::setMode(int mode)
100 {
101         LOGD("setMode(%d)", mode);
102
103         mMode = mode;
104
105         if(mode == AudioSystem::MODE_IN_CALL || mode == AudioSystem::MODE_IN_COMMUNICATION)
106                 setVoiceVolume(mVoiceVolume);
107
108         if(mRILInterface)
109                 mRILInterface->setMode(mode);
110
111         return NO_ERROR;
112 }
113
114 status_t AudioHardware::getMode(int *mode)
115 {
116         LOGD("getMode()");
117
118         if(mode != NULL)
119                 *mode = mMode;
120
121         return NO_ERROR;
122 }
123
124 status_t AudioHardware::setMicMute(bool state)
125 {
126         LOGD("setMicMute(%d)", state);
127
128         mMicMute = state;
129
130         if(mOutput && mOutput->mMixer)
131                 mOutput->mMixer->setMicMute(state);
132
133         if(mRILInterface)
134                 mRILInterface->setMicMute(state);
135
136         return NO_ERROR;
137 }
138
139 status_t AudioHardware::getMicMute(bool *state)
140 {
141         LOGD("getMicMute()");
142
143         if(state != NULL)
144                 *state = mMicMute;
145
146         return NO_ERROR;
147 }
148
149 status_t AudioHardware::setParameters(const String8& keyValuePairs)
150 {
151         AudioParameter param = AudioParameter(keyValuePairs);
152         String8 key = String8(AudioParameter::keyRouting);
153         int device;
154
155         LOGD("setParameters(%s)",
156                 keyValuePairs.string());
157
158         if(param.getInt(key, device) == NO_ERROR) {
159                 if(AudioSystem::isOutputDevice((AudioSystem::audio_devices) device) && mOutput) {
160                         return mOutput->setParameters(keyValuePairs);
161                 } else if(AudioSystem::isInputDevice((AudioSystem::audio_devices) device) && mInput) {
162                         return mInput->setParameters(keyValuePairs);
163                 }
164         }
165
166         return NO_ERROR;
167 }
168
169 String8 AudioHardware::getParameters(const String8& keys)
170 {
171         LOGD("getParameters()");
172
173         AudioParameter request = AudioParameter(keys);
174         AudioParameter reply = AudioParameter();
175
176         return reply.toString();
177 }
178
179 size_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
180 {
181         LOGD("getInputBufferSize(%d, %d, %d)", sampleRate, format, channelCount);
182
183         if(!mInput) {
184                 LOGE("Input wasn't initialized yet!");
185                 return 0;
186         }
187
188         return mInput->bufferSize();
189 }
190
191 AudioStreamOut* AudioHardware::openOutputStream(
192         uint32_t devices, int *format, uint32_t *channels,
193         uint32_t *sampleRate, status_t *status)
194 {
195         status_t set_status;
196
197         AutoMutex lock(mLock);
198
199         LOGD("openOutputStream()");
200
201         // Check for valid input source
202         if(!AudioSystem::isOutputDevice((AudioSystem::audio_devices) devices)) {
203                 LOGE("openOutputStream() failed: invalid device");
204                 return NULL;
205         }
206
207         if(mOutput) {
208                 *status = INVALID_OPERATION;
209
210                 LOGE("openOutputStream() failed: there is already an active outputStream!");
211                 return NULL;
212         }
213
214         TinyALSAAudioStreamOut *output = new TinyALSAAudioStreamOut();
215
216         set_status = output->set(this, devices, format, channels, sampleRate);
217
218         *status = set_status;
219
220         if(set_status != NO_ERROR) {
221                 delete output;
222                 return NULL;
223         }
224
225         mOutput = output;
226
227         return output;
228 }
229
230 AudioStreamIn* AudioHardware::openInputStream(
231         uint32_t devices, int *format, uint32_t *channels,
232         uint32_t *sampleRate, status_t *status,
233         AudioSystem::audio_in_acoustics acoustic_flags)
234 {
235         status_t set_status;
236
237         AutoMutex lock(mLock);
238
239         LOGD("openInputStream()");
240
241         // Check for valid input source
242         if(!AudioSystem::isInputDevice((AudioSystem::audio_devices) devices)) {
243                 LOGE("openInputStream() failed: invalid device");
244                 return NULL;
245         }
246
247         if(mInput) {
248                 *status = INVALID_OPERATION;
249
250                 LOGE("openInputStream() failed: there is already an active inputStream!");
251                 return NULL;
252         }
253
254         TinyALSAAudioStreamIn *input = new TinyALSAAudioStreamIn();
255
256         set_status = input->set(this, devices, format, channels, sampleRate,
257                 acoustic_flags);
258
259         *status = set_status;
260
261         if(set_status != NO_ERROR) {
262                 delete input;
263                 return NULL;
264         }
265
266         mInput = input;
267
268         return input;
269 }
270
271 void AudioHardware::closeOutputStream(AudioStreamOut* out)
272 {
273         LOGD("closeOutputStream()");
274
275         if(mOutput && mOutput == out) {
276                 delete mOutput;
277                 mOutput = NULL;
278         }
279 }
280
281 void AudioHardware::closeInputStream(AudioStreamIn* in)
282 {
283         LOGD("closeInputStream()");
284
285         if(mInput && mInput == in) {
286                 delete mInput;
287                 mInput = NULL;
288         }
289 }
290
291 status_t AudioHardware::dump(int fd, const Vector<String16>& args)
292 {
293         LOGD("dump()");
294
295         return NO_ERROR;
296 }
297
298 // Main function called to return AudioHardware object
299 extern "C" AudioHardwareInterface* createAudioHardware(void)
300 {
301         return new AudioHardware();
302 }
303
304 }; // namespace android