blob: a97c0bcb9ae7ba589a04128bf177b20461411494 [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"
Dave Sparksa5a11d42009-05-19 14:38:46 -070033#include <media/AudioRecord.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080034
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 delete mOutput;
53 delete 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 int format, int channelCount, 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, format, channelCount, 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(AudioStreamOutGeneric* out) {
93 if (out == mOutput) mOutput = 0;
94}
95
96AudioStreamIn* AudioHardwareGeneric::openInputStream(
Dave Sparksa5a11d42009-05-19 14:38:46 -070097 int inputSource, int format, int channelCount, uint32_t sampleRate,
98 status_t *status, AudioSystem::audio_in_acoustics acoustics)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080099{
Dave Sparksa5a11d42009-05-19 14:38:46 -0700100 // check for valid input source
101 if ((inputSource != AudioRecord::DEFAULT_INPUT) &&
102 (inputSource != AudioRecord::MIC_INPUT)) {
103 return 0;
104 }
105
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800106 AutoMutex lock(mLock);
107
108 // only one input stream allowed
109 if (mInput) {
110 if (status) {
111 *status = INVALID_OPERATION;
112 }
113 return 0;
114 }
115
116 // create new output stream
117 AudioStreamInGeneric* in = new AudioStreamInGeneric();
118 status_t lStatus = in->set(this, mFd, format, channelCount, sampleRate, acoustics);
119 if (status) {
120 *status = lStatus;
121 }
122 if (lStatus == NO_ERROR) {
123 mInput = in;
124 } else {
125 delete in;
126 }
127 return mInput;
128}
129
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800130void AudioHardwareGeneric::closeInputStream(AudioStreamInGeneric* in) {
131 if (in == mInput) mInput = 0;
132}
133
134status_t AudioHardwareGeneric::setVoiceVolume(float v)
135{
136 // Implement: set voice volume
137 return NO_ERROR;
138}
139
140status_t AudioHardwareGeneric::setMasterVolume(float v)
141{
142 // Implement: set master volume
143 // return error - software mixer will handle it
144 return INVALID_OPERATION;
145}
146
147status_t AudioHardwareGeneric::setMicMute(bool state)
148{
149 mMicMute = state;
150 return NO_ERROR;
151}
152
153status_t AudioHardwareGeneric::getMicMute(bool* state)
154{
155 *state = mMicMute;
156 return NO_ERROR;
157}
158
159status_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args)
160{
161 const size_t SIZE = 256;
162 char buffer[SIZE];
163 String8 result;
164 result.append("AudioHardwareGeneric::dumpInternals\n");
165 snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n", mFd, mMicMute? "true": "false");
166 result.append(buffer);
167 ::write(fd, result.string(), result.size());
168 return NO_ERROR;
169}
170
171status_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args)
172{
173 dumpInternals(fd, args);
174 if (mInput) {
175 mInput->dump(fd, args);
176 }
177 if (mOutput) {
178 mOutput->dump(fd, args);
179 }
180 return NO_ERROR;
181}
182
183// ----------------------------------------------------------------------------
184
185status_t AudioStreamOutGeneric::set(
186 AudioHardwareGeneric *hw,
187 int fd,
188 int format,
189 int channels,
190 uint32_t rate)
191{
192 // fix up defaults
193 if (format == 0) format = AudioSystem::PCM_16_BIT;
194 if (channels == 0) channels = channelCount();
195 if (rate == 0) rate = sampleRate();
196
197 // check values
198 if ((format != AudioSystem::PCM_16_BIT) ||
199 (channels != channelCount()) ||
200 (rate != sampleRate()))
201 return BAD_VALUE;
202
203 mAudioHardware = hw;
204 mFd = fd;
205 return NO_ERROR;
206}
207
208AudioStreamOutGeneric::~AudioStreamOutGeneric()
209{
210 if (mAudioHardware)
211 mAudioHardware->closeOutputStream(this);
212}
213
214ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
215{
216 Mutex::Autolock _l(mLock);
217 return ssize_t(::write(mFd, buffer, bytes));
218}
219
220status_t AudioStreamOutGeneric::standby()
221{
222 // Implement: audio hardware to standby mode
223 return NO_ERROR;
224}
225
226status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
227{
228 const size_t SIZE = 256;
229 char buffer[SIZE];
230 String8 result;
231 snprintf(buffer, SIZE, "AudioStreamOutGeneric::dump\n");
232 result.append(buffer);
233 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
234 result.append(buffer);
235 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
236 result.append(buffer);
237 snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
238 result.append(buffer);
239 snprintf(buffer, SIZE, "\tformat: %d\n", format());
240 result.append(buffer);
241 snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
242 result.append(buffer);
243 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
244 result.append(buffer);
245 ::write(fd, result.string(), result.size());
246 return NO_ERROR;
247}
248
249// ----------------------------------------------------------------------------
250
251// record functions
252status_t AudioStreamInGeneric::set(
253 AudioHardwareGeneric *hw,
254 int fd,
255 int format,
256 int channels,
257 uint32_t rate,
258 AudioSystem::audio_in_acoustics acoustics)
259{
260 // FIXME: remove logging
261 LOGD("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, format, channels, rate);
262 // check values
263 if ((format != AudioSystem::PCM_16_BIT) ||
264 (channels != channelCount()) ||
265 (rate != sampleRate())) {
266 LOGE("Error opening input channel");
267 return BAD_VALUE;
268 }
269
270 mAudioHardware = hw;
271 mFd = fd;
272 return NO_ERROR;
273}
274
275AudioStreamInGeneric::~AudioStreamInGeneric()
276{
277 // FIXME: remove logging
278 LOGD("AudioStreamInGeneric destructor");
279 if (mAudioHardware)
280 mAudioHardware->closeInputStream(this);
281}
282
283ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
284{
285 // FIXME: remove logging
286 LOGD("AudioStreamInGeneric::read(%p, %d) from fd %d", buffer, bytes, mFd);
287 AutoMutex lock(mLock);
288 if (mFd < 0) {
289 LOGE("Attempt to read from unopened device");
290 return NO_INIT;
291 }
292 return ::read(mFd, buffer, bytes);
293}
294
295status_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args)
296{
297 const size_t SIZE = 256;
298 char buffer[SIZE];
299 String8 result;
300 snprintf(buffer, SIZE, "AudioStreamInGeneric::dump\n");
301 result.append(buffer);
302 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
303 result.append(buffer);
304 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
305 result.append(buffer);
306 snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
307 result.append(buffer);
308 snprintf(buffer, SIZE, "\tformat: %d\n", format());
309 result.append(buffer);
310 snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
311 result.append(buffer);
312 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
313 result.append(buffer);
314 ::write(fd, result.string(), result.size());
315 return NO_ERROR;
316}
317
318// ----------------------------------------------------------------------------
319
320}; // namespace android