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 43 AudioHardwareGeneric::AudioHardwareGeneric() 44 : mOutput(0), mInput(0), mFd(-1), mMicMute(false) 45 { 46 mFd = ::open(kAudioDeviceName, O_RDWR); 47 } 48 49 AudioHardwareGeneric::~AudioHardwareGeneric() 50 { 51 if (mFd >= 0) ::close(mFd); 52 closeOutputStream((AudioStreamOut *)mOutput); 53 closeInputStream((AudioStreamIn *)mInput); 54 } 55 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 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 92 void AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) { 93 if (mOutput && out == mOutput) { 94 delete mOutput; 95 mOutput = 0; 96 } 97 } 98 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 132 void AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) { 133 if (mInput && in == mInput) { 134 delete mInput; 135 mInput = 0; 136 } 137 } 138 139 status_t AudioHardwareGeneric::setVoiceVolume(float v) 140 { 141 // Implement: set voice volume 142 return NO_ERROR; 143 } 144 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 152 status_t AudioHardwareGeneric::setMicMute(bool state) 153 { 154 mMicMute = state; 155 return NO_ERROR; 156 } 157 158 status_t AudioHardwareGeneric::getMicMute(bool* state) 159 { 160 *state = mMicMute; 161 return NO_ERROR; 162 } 163 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 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 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 227 AudioStreamOutGeneric::~AudioStreamOutGeneric() 228 { 229 } 230 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 237 status_t AudioStreamOutGeneric::standby() 238 { 239 // Implement: audio hardware to standby mode 240 return NO_ERROR; 241 } 242 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 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 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 301 status_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames) 302 { 303 return INVALID_OPERATION; 304 } 305 306 // ---------------------------------------------------------------------------- 307 308 // record functions 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 337 AudioStreamInGeneric::~AudioStreamInGeneric() 338 { 339 } 340 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 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 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 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 411 extern "C" AudioHardwareInterface* createAudioHardware(void) { 412 return new AudioHardwareGeneric(); 413 } 414 415 }; // namespace android 416