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