blob: 62beadabddcb5d5f88c3f345ca15725350efdcd8 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
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
34namespace android {
35
36// ----------------------------------------------------------------------------
37
38static char const * const kAudioDeviceName = "/dev/eac";
39
40// ----------------------------------------------------------------------------
41
42AudioHardwareGeneric::AudioHardwareGeneric()
43 : mOutput(0), mInput(0), mFd(-1), mMicMute(false)
44{
45 mFd = ::open(kAudioDeviceName, O_RDWR);
46}
47
48AudioHardwareGeneric::~AudioHardwareGeneric()
49{
50 if (mFd >= 0) ::close(mFd);
51 delete mOutput;
52 delete mInput;
53}
54
55status_t AudioHardwareGeneric::initCheck()
56{
57 if (mFd >= 0) {
58 if (::access(kAudioDeviceName, O_RDWR) == NO_ERROR)
59 return NO_ERROR;
60 }
61 return NO_INIT;
62}
63
64AudioStreamOut* AudioHardwareGeneric::openOutputStream(
65 int format, int channelCount, uint32_t sampleRate, status_t *status)
66{
67 AutoMutex lock(mLock);
68
69 // only one output stream allowed
70 if (mOutput) {
71 if (status) {
72 *status = INVALID_OPERATION;
73 }
74 return 0;
75 }
76
77 // create new output stream
78 AudioStreamOutGeneric* out = new AudioStreamOutGeneric();
79 status_t lStatus = out->set(this, mFd, format, channelCount, sampleRate);
80 if (status) {
81 *status = lStatus;
82 }
83 if (lStatus == NO_ERROR) {
84 mOutput = out;
85 } else {
86 delete out;
87 }
88 return mOutput;
89}
90
91void AudioHardwareGeneric::closeOutputStream(AudioStreamOutGeneric* out) {
92 if (out == mOutput) mOutput = 0;
93}
94
95AudioStreamIn* AudioHardwareGeneric::openInputStream(
96 int format, int channelCount, uint32_t sampleRate, status_t *status,
97 AudioSystem::audio_in_acoustics acoustics)
98{
99 AutoMutex lock(mLock);
100
101 // only one input stream allowed
102 if (mInput) {
103 if (status) {
104 *status = INVALID_OPERATION;
105 }
106 return 0;
107 }
108
109 // create new output stream
110 AudioStreamInGeneric* in = new AudioStreamInGeneric();
111 status_t lStatus = in->set(this, mFd, format, channelCount, sampleRate, acoustics);
112 if (status) {
113 *status = lStatus;
114 }
115 if (lStatus == NO_ERROR) {
116 mInput = in;
117 } else {
118 delete in;
119 }
120 return mInput;
121}
122
123void AudioHardwareGeneric::closeInputStream(AudioStreamInGeneric* in) {
124 if (in == mInput) mInput = 0;
125}
126
127status_t AudioHardwareGeneric::setVoiceVolume(float v)
128{
129 // Implement: set voice volume
130 return NO_ERROR;
131}
132
133status_t AudioHardwareGeneric::setMasterVolume(float v)
134{
135 // Implement: set master volume
136 // return error - software mixer will handle it
137 return INVALID_OPERATION;
138}
139
140status_t AudioHardwareGeneric::setMicMute(bool state)
141{
142 mMicMute = state;
143 return NO_ERROR;
144}
145
146status_t AudioHardwareGeneric::getMicMute(bool* state)
147{
148 *state = mMicMute;
149 return NO_ERROR;
150}
151
152status_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args)
153{
154 const size_t SIZE = 256;
155 char buffer[SIZE];
156 String8 result;
157 result.append("AudioHardwareGeneric::dumpInternals\n");
158 snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n", mFd, mMicMute? "true": "false");
159 result.append(buffer);
160 ::write(fd, result.string(), result.size());
161 return NO_ERROR;
162}
163
164status_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args)
165{
166 dumpInternals(fd, args);
167 if (mInput) {
168 mInput->dump(fd, args);
169 }
170 if (mOutput) {
171 mOutput->dump(fd, args);
172 }
173 return NO_ERROR;
174}
175
176// ----------------------------------------------------------------------------
177
178status_t AudioStreamOutGeneric::set(
179 AudioHardwareGeneric *hw,
180 int fd,
181 int format,
182 int channels,
183 uint32_t rate)
184{
185 // fix up defaults
186 if (format == 0) format = AudioSystem::PCM_16_BIT;
187 if (channels == 0) channels = channelCount();
188 if (rate == 0) rate = sampleRate();
189
190 // check values
191 if ((format != AudioSystem::PCM_16_BIT) ||
192 (channels != channelCount()) ||
193 (rate != sampleRate()))
194 return BAD_VALUE;
195
196 mAudioHardware = hw;
197 mFd = fd;
198 return NO_ERROR;
199}
200
201AudioStreamOutGeneric::~AudioStreamOutGeneric()
202{
203 if (mAudioHardware)
204 mAudioHardware->closeOutputStream(this);
205}
206
207ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
208{
209 Mutex::Autolock _l(mLock);
210 return ssize_t(::write(mFd, buffer, bytes));
211}
212
213status_t AudioStreamOutGeneric::standby()
214{
215 // Implement: audio hardware to standby mode
216 return NO_ERROR;
217}
218
219status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
220{
221 const size_t SIZE = 256;
222 char buffer[SIZE];
223 String8 result;
224 snprintf(buffer, SIZE, "AudioStreamOutGeneric::dump\n");
225 result.append(buffer);
226 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
227 result.append(buffer);
228 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
229 result.append(buffer);
230 snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
231 result.append(buffer);
232 snprintf(buffer, SIZE, "\tformat: %d\n", format());
233 result.append(buffer);
234 snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
235 result.append(buffer);
236 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
237 result.append(buffer);
238 ::write(fd, result.string(), result.size());
239 return NO_ERROR;
240}
241
242// ----------------------------------------------------------------------------
243
244// record functions
245status_t AudioStreamInGeneric::set(
246 AudioHardwareGeneric *hw,
247 int fd,
248 int format,
249 int channels,
250 uint32_t rate,
251 AudioSystem::audio_in_acoustics acoustics)
252{
253 // FIXME: remove logging
254 LOGD("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, format, channels, rate);
255 // check values
256 if ((format != AudioSystem::PCM_16_BIT) ||
257 (channels != channelCount()) ||
258 (rate != sampleRate())) {
259 LOGE("Error opening input channel");
260 return BAD_VALUE;
261 }
262
263 mAudioHardware = hw;
264 mFd = fd;
265 return NO_ERROR;
266}
267
268AudioStreamInGeneric::~AudioStreamInGeneric()
269{
270 // FIXME: remove logging
271 LOGD("AudioStreamInGeneric destructor");
272 if (mAudioHardware)
273 mAudioHardware->closeInputStream(this);
274}
275
276ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
277{
278 // FIXME: remove logging
279 LOGD("AudioStreamInGeneric::read(%p, %d) from fd %d", buffer, bytes, mFd);
280 AutoMutex lock(mLock);
281 if (mFd < 0) {
282 LOGE("Attempt to read from unopened device");
283 return NO_INIT;
284 }
285 return ::read(mFd, buffer, bytes);
286}
287
288status_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args)
289{
290 const size_t SIZE = 256;
291 char buffer[SIZE];
292 String8 result;
293 snprintf(buffer, SIZE, "AudioStreamInGeneric::dump\n");
294 result.append(buffer);
295 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
296 result.append(buffer);
297 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
298 result.append(buffer);
299 snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
300 result.append(buffer);
301 snprintf(buffer, SIZE, "\tformat: %d\n", format());
302 result.append(buffer);
303 snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
304 result.append(buffer);
305 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
306 result.append(buffer);
307 ::write(fd, result.string(), result.size());
308 return NO_ERROR;
309}
310
311// ----------------------------------------------------------------------------
312
313}; // namespace android