1 /*
2 **
3 ** Copyright 2007, The Android Open Source Project
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 <stdint.h>
19 #include <sys/types.h>
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <sched.h>
25 #include <fcntl.h>
26 #include <sys/ioctl.h>
27
28 #define LOG_TAG "AudioHardware"
29 #include <utils/Log.h>
30 #include <utils/String8.h>
31
32 #include "AudioHardwareGeneric.h"
33 #include <media/AudioRecord.h>
34
35 namespace android_audio_legacy {
36
37 // ----------------------------------------------------------------------------
38
39 static char const * const kAudioDeviceName = "/dev/eac";
40
41 // ----------------------------------------------------------------------------
42
AudioHardwareGeneric()43 AudioHardwareGeneric::AudioHardwareGeneric()
44 : mOutput(0), mInput(0), mFd(-1), mMicMute(false)
45 {
46 mFd = ::open(kAudioDeviceName, O_RDWR);
47 }
48
~AudioHardwareGeneric()49 AudioHardwareGeneric::~AudioHardwareGeneric()
50 {
51 if (mFd >= 0) ::close(mFd);
52 closeOutputStream((AudioStreamOut *)mOutput);
53 closeInputStream((AudioStreamIn *)mInput);
54 }
55
initCheck()56 status_t AudioHardwareGeneric::initCheck()
57 {
58 if (mFd >= 0) {
59 if (::access(kAudioDeviceName, O_RDWR) == NO_ERROR)
60 return NO_ERROR;
61 }
62 return NO_INIT;
63 }
64
openOutputStream(uint32_t devices,int * format,uint32_t * channels,uint32_t * sampleRate,status_t * status)65 AudioStreamOut* AudioHardwareGeneric::openOutputStream(
66 uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
67 {
68 AutoMutex lock(mLock);
69
70 // only one output stream allowed
71 if (mOutput) {
72 if (status) {
73 *status = INVALID_OPERATION;
74 }
75 return 0;
76 }
77
78 // create new output stream
79 AudioStreamOutGeneric* out = new AudioStreamOutGeneric();
80 status_t lStatus = out->set(this, mFd, devices, format, channels, sampleRate);
81 if (status) {
82 *status = lStatus;
83 }
84 if (lStatus == NO_ERROR) {
85 mOutput = out;
86 } else {
87 delete out;
88 }
89 return mOutput;
90 }
91
closeOutputStream(AudioStreamOut * out)92 void AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) {
93 if (mOutput && out == mOutput) {
94 delete mOutput;
95 mOutput = 0;
96 }
97 }
98
openInputStream(uint32_t devices,int * format,uint32_t * channels,uint32_t * sampleRate,status_t * status,AudioSystem::audio_in_acoustics acoustics)99 AudioStreamIn* AudioHardwareGeneric::openInputStream(
100 uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate,
101 status_t *status, AudioSystem::audio_in_acoustics acoustics)
102 {
103 // check for valid input source
104 if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
105 return 0;
106 }
107
108 AutoMutex lock(mLock);
109
110 // only one input stream allowed
111 if (mInput) {
112 if (status) {
113 *status = INVALID_OPERATION;
114 }
115 return 0;
116 }
117
118 // create new output stream
119 AudioStreamInGeneric* in = new AudioStreamInGeneric();
120 status_t lStatus = in->set(this, mFd, devices, format, channels, sampleRate, acoustics);
121 if (status) {
122 *status = lStatus;
123 }
124 if (lStatus == NO_ERROR) {
125 mInput = in;
126 } else {
127 delete in;
128 }
129 return mInput;
130 }
131
closeInputStream(AudioStreamIn * in)132 void AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) {
133 if (mInput && in == mInput) {
134 delete mInput;
135 mInput = 0;
136 }
137 }
138
setVoiceVolume(float v)139 status_t AudioHardwareGeneric::setVoiceVolume(float v)
140 {
141 // Implement: set voice volume
142 return NO_ERROR;
143 }
144
setMasterVolume(float v)145 status_t AudioHardwareGeneric::setMasterVolume(float v)
146 {
147 // Implement: set master volume
148 // return error - software mixer will handle it
149 return INVALID_OPERATION;
150 }
151
setMicMute(bool state)152 status_t AudioHardwareGeneric::setMicMute(bool state)
153 {
154 mMicMute = state;
155 return NO_ERROR;
156 }
157
getMicMute(bool * state)158 status_t AudioHardwareGeneric::getMicMute(bool* state)
159 {
160 *state = mMicMute;
161 return NO_ERROR;
162 }
163
dumpInternals(int fd,const Vector<String16> & args)164 status_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args)
165 {
166 const size_t SIZE = 256;
167 char buffer[SIZE];
168 String8 result;
169 result.append("AudioHardwareGeneric::dumpInternals\n");
170 snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n", mFd, mMicMute? "true": "false");
171 result.append(buffer);
172 ::write(fd, result.string(), result.size());
173 return NO_ERROR;
174 }
175
dump(int fd,const Vector<String16> & args)176 status_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args)
177 {
178 dumpInternals(fd, args);
179 if (mInput) {
180 mInput->dump(fd, args);
181 }
182 if (mOutput) {
183 mOutput->dump(fd, args);
184 }
185 return NO_ERROR;
186 }
187
188 // ----------------------------------------------------------------------------
189
set(AudioHardwareGeneric * hw,int fd,uint32_t devices,int * pFormat,uint32_t * pChannels,uint32_t * pRate)190 status_t AudioStreamOutGeneric::set(
191 AudioHardwareGeneric *hw,
192 int fd,
193 uint32_t devices,
194 int *pFormat,
195 uint32_t *pChannels,
196 uint32_t *pRate)
197 {
198 int lFormat = pFormat ? *pFormat : 0;
199 uint32_t lChannels = pChannels ? *pChannels : 0;
200 uint32_t lRate = pRate ? *pRate : 0;
201
202 // fix up defaults
203 if (lFormat == 0) lFormat = format();
204 if (lChannels == 0) lChannels = channels();
205 if (lRate == 0) lRate = sampleRate();
206
207 // check values
208 if ((lFormat != format()) ||
209 (lChannels != channels()) ||
210 (lRate != sampleRate())) {
211 if (pFormat) *pFormat = format();
212 if (pChannels) *pChannels = channels();
213 if (pRate) *pRate = sampleRate();
214 return BAD_VALUE;
215 }
216
217 if (pFormat) *pFormat = lFormat;
218 if (pChannels) *pChannels = lChannels;
219 if (pRate) *pRate = lRate;
220
221 mAudioHardware = hw;
222 mFd = fd;
223 mDevice = devices;
224 return NO_ERROR;
225 }
226
~AudioStreamOutGeneric()227 AudioStreamOutGeneric::~AudioStreamOutGeneric()
228 {
229 }
230
write(const void * buffer,size_t bytes)231 ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
232 {
233 Mutex::Autolock _l(mLock);
234 return ssize_t(::write(mFd, buffer, bytes));
235 }
236
standby()237 status_t AudioStreamOutGeneric::standby()
238 {
239 // Implement: audio hardware to standby mode
240 return NO_ERROR;
241 }
242
dump(int fd,const Vector<String16> & args)243 status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
244 {
245 const size_t SIZE = 256;
246 char buffer[SIZE];
247 String8 result;
248 snprintf(buffer, SIZE, "AudioStreamOutGeneric::dump\n");
249 result.append(buffer);
250 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
251 result.append(buffer);
252 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
253 result.append(buffer);
254 snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
255 result.append(buffer);
256 snprintf(buffer, SIZE, "\tformat: %d\n", format());
257 result.append(buffer);
258 snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
259 result.append(buffer);
260 snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
261 result.append(buffer);
262 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
263 result.append(buffer);
264 ::write(fd, result.string(), result.size());
265 return NO_ERROR;
266 }
267
setParameters(const String8 & keyValuePairs)268 status_t AudioStreamOutGeneric::setParameters(const String8& keyValuePairs)
269 {
270 AudioParameter param = AudioParameter(keyValuePairs);
271 String8 key = String8(AudioParameter::keyRouting);
272 status_t status = NO_ERROR;
273 int device;
274 LOGV("setParameters() %s", keyValuePairs.string());
275
276 if (param.getInt(key, device) == NO_ERROR) {
277 mDevice = device;
278 param.remove(key);
279 }
280
281 if (param.size()) {
282 status = BAD_VALUE;
283 }
284 return status;
285 }
286
getParameters(const String8 & keys)287 String8 AudioStreamOutGeneric::getParameters(const String8& keys)
288 {
289 AudioParameter param = AudioParameter(keys);
290 String8 value;
291 String8 key = String8(AudioParameter::keyRouting);
292
293 if (param.get(key, value) == NO_ERROR) {
294 param.addInt(key, (int)mDevice);
295 }
296
297 LOGV("getParameters() %s", param.toString().string());
298 return param.toString();
299 }
300
getRenderPosition(uint32_t * dspFrames)301 status_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames)
302 {
303 return INVALID_OPERATION;
304 }
305
306 // ----------------------------------------------------------------------------
307
308 // record functions
set(AudioHardwareGeneric * hw,int fd,uint32_t devices,int * pFormat,uint32_t * pChannels,uint32_t * pRate,AudioSystem::audio_in_acoustics acoustics)309 status_t AudioStreamInGeneric::set(
310 AudioHardwareGeneric *hw,
311 int fd,
312 uint32_t devices,
313 int *pFormat,
314 uint32_t *pChannels,
315 uint32_t *pRate,
316 AudioSystem::audio_in_acoustics acoustics)
317 {
318 if (pFormat == 0 || pChannels == 0 || pRate == 0) return BAD_VALUE;
319 LOGV("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, *pFormat, *pChannels, *pRate);
320 // check values
321 if ((*pFormat != format()) ||
322 (*pChannels != channels()) ||
323 (*pRate != sampleRate())) {
324 LOGE("Error opening input channel");
325 *pFormat = format();
326 *pChannels = channels();
327 *pRate = sampleRate();
328 return BAD_VALUE;
329 }
330
331 mAudioHardware = hw;
332 mFd = fd;
333 mDevice = devices;
334 return NO_ERROR;
335 }
336
~AudioStreamInGeneric()337 AudioStreamInGeneric::~AudioStreamInGeneric()
338 {
339 }
340
read(void * buffer,ssize_t bytes)341 ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
342 {
343 AutoMutex lock(mLock);
344 if (mFd < 0) {
345 LOGE("Attempt to read from unopened device");
346 return NO_INIT;
347 }
348 return ::read(mFd, buffer, bytes);
349 }
350
dump(int fd,const Vector<String16> & args)351 status_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args)
352 {
353 const size_t SIZE = 256;
354 char buffer[SIZE];
355 String8 result;
356 snprintf(buffer, SIZE, "AudioStreamInGeneric::dump\n");
357 result.append(buffer);
358 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
359 result.append(buffer);
360 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
361 result.append(buffer);
362 snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
363 result.append(buffer);
364 snprintf(buffer, SIZE, "\tformat: %d\n", format());
365 result.append(buffer);
366 snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
367 result.append(buffer);
368 snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
369 result.append(buffer);
370 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
371 result.append(buffer);
372 ::write(fd, result.string(), result.size());
373 return NO_ERROR;
374 }
375
setParameters(const String8 & keyValuePairs)376 status_t AudioStreamInGeneric::setParameters(const String8& keyValuePairs)
377 {
378 AudioParameter param = AudioParameter(keyValuePairs);
379 String8 key = String8(AudioParameter::keyRouting);
380 status_t status = NO_ERROR;
381 int device;
382 LOGV("setParameters() %s", keyValuePairs.string());
383
384 if (param.getInt(key, device) == NO_ERROR) {
385 mDevice = device;
386 param.remove(key);
387 }
388
389 if (param.size()) {
390 status = BAD_VALUE;
391 }
392 return status;
393 }
394
getParameters(const String8 & keys)395 String8 AudioStreamInGeneric::getParameters(const String8& keys)
396 {
397 AudioParameter param = AudioParameter(keys);
398 String8 value;
399 String8 key = String8(AudioParameter::keyRouting);
400
401 if (param.get(key, value) == NO_ERROR) {
402 param.addInt(key, (int)mDevice);
403 }
404
405 LOGV("getParameters() %s", param.toString().string());
406 return param.toString();
407 }
408
409 // ----------------------------------------------------------------------------
410
createAudioHardware(void)411 extern "C" AudioHardwareInterface* createAudioHardware(void) {
412 return new AudioHardwareGeneric();
413 }
414
415 }; // namespace android
416