• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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