AudioHardwareGeneric.cpp revision f01215993dda68b6b52111d754bd0c7c2d5bcfa3
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
35namespace android {
36
37// ----------------------------------------------------------------------------
38
39static char const * const kAudioDeviceName = "/dev/eac";
40
41// ----------------------------------------------------------------------------
42
43AudioHardwareGeneric::AudioHardwareGeneric()
44    : mOutput(0), mInput(0),  mFd(-1), mMicMute(false)
45{
46    mFd = ::open(kAudioDeviceName, O_RDWR);
47}
48
49AudioHardwareGeneric::~AudioHardwareGeneric()
50{
51    if (mFd >= 0) ::close(mFd);
52    closeOutputStream((AudioStreamOut *)mOutput);
53    closeInputStream((AudioStreamIn *)mInput);
54}
55
56status_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
65AudioStreamOut* 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
92void AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) {
93    if (mOutput && out == mOutput) {
94        delete mOutput;
95        mOutput = 0;
96    }
97}
98
99AudioStreamIn* 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
132void AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) {
133    if (mInput && in == mInput) {
134        delete mInput;
135        mInput = 0;
136    }
137}
138
139status_t AudioHardwareGeneric::setVoiceVolume(float v)
140{
141    // Implement: set voice volume
142    return NO_ERROR;
143}
144
145status_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
152status_t AudioHardwareGeneric::setMicMute(bool state)
153{
154    mMicMute = state;
155    return NO_ERROR;
156}
157
158status_t AudioHardwareGeneric::getMicMute(bool* state)
159{
160    *state = mMicMute;
161    return NO_ERROR;
162}
163
164status_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
176status_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
190status_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
227AudioStreamOutGeneric::~AudioStreamOutGeneric()
228{
229}
230
231ssize_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
237status_t AudioStreamOutGeneric::standby()
238{
239    // Implement: audio hardware to standby mode
240    return NO_ERROR;
241}
242
243status_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
268status_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
287String8 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
301status_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames)
302{
303    return INVALID_OPERATION;
304}
305
306// ----------------------------------------------------------------------------
307
308// record functions
309status_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
337AudioStreamInGeneric::~AudioStreamInGeneric()
338{
339}
340
341ssize_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
351status_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
376status_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
395String8 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
411}; // namespace android
412