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