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