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 34 namespace android_audio_legacy { 35 36 // ---------------------------------------------------------------------------- 37 38 static char const * const kAudioDeviceName = "/dev/eac"; 39 40 // ---------------------------------------------------------------------------- 41 42 AudioHardwareGeneric::AudioHardwareGeneric() 43 : mOutput(0), mInput(0), mFd(-1), mMicMute(false) 44 { 45 mFd = ::open(kAudioDeviceName, O_RDWR); 46 } 47 48 AudioHardwareGeneric::~AudioHardwareGeneric() 49 { 50 if (mFd >= 0) ::close(mFd); 51 closeOutputStream((AudioStreamOut *)mOutput); 52 closeInputStream((AudioStreamIn *)mInput); 53 } 54 55 status_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 64 AudioStreamOut* AudioHardwareGeneric::openOutputStream( 65 uint32_t devices, int *format, uint32_t *channels, 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, devices, format, channels, 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 91 void AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) { 92 if (mOutput && out == mOutput) { 93 delete mOutput; 94 mOutput = 0; 95 } 96 } 97 98 AudioStreamIn* AudioHardwareGeneric::openInputStream( 99 uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, 100 status_t *status, AudioSystem::audio_in_acoustics acoustics) 101 { 102 // check for valid input source 103 if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) { 104 return 0; 105 } 106 107 AutoMutex lock(mLock); 108 109 // only one input stream allowed 110 if (mInput) { 111 if (status) { 112 *status = INVALID_OPERATION; 113 } 114 return 0; 115 } 116 117 // create new output stream 118 AudioStreamInGeneric* in = new AudioStreamInGeneric(); 119 status_t lStatus = in->set(this, mFd, devices, format, channels, sampleRate, acoustics); 120 if (status) { 121 *status = lStatus; 122 } 123 if (lStatus == NO_ERROR) { 124 mInput = in; 125 } else { 126 delete in; 127 } 128 return mInput; 129 } 130 131 void AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) { 132 if (mInput && in == mInput) { 133 delete mInput; 134 mInput = 0; 135 } 136 } 137 138 status_t AudioHardwareGeneric::setVoiceVolume(float v) 139 { 140 // Implement: set voice volume 141 return NO_ERROR; 142 } 143 144 status_t AudioHardwareGeneric::setMasterVolume(float v) 145 { 146 // Implement: set master volume 147 // return error - software mixer will handle it 148 return INVALID_OPERATION; 149 } 150 151 status_t AudioHardwareGeneric::setMicMute(bool state) 152 { 153 mMicMute = state; 154 return NO_ERROR; 155 } 156 157 status_t AudioHardwareGeneric::getMicMute(bool* state) 158 { 159 *state = mMicMute; 160 return NO_ERROR; 161 } 162 163 status_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args) 164 { 165 const size_t SIZE = 256; 166 char buffer[SIZE]; 167 String8 result; 168 result.append("AudioHardwareGeneric::dumpInternals\n"); 169 snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n", mFd, mMicMute? "true": "false"); 170 result.append(buffer); 171 ::write(fd, result.string(), result.size()); 172 return NO_ERROR; 173 } 174 175 status_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args) 176 { 177 dumpInternals(fd, args); 178 if (mInput) { 179 mInput->dump(fd, args); 180 } 181 if (mOutput) { 182 mOutput->dump(fd, args); 183 } 184 return NO_ERROR; 185 } 186 187 // ---------------------------------------------------------------------------- 188 189 status_t AudioStreamOutGeneric::set( 190 AudioHardwareGeneric *hw, 191 int fd, 192 uint32_t devices, 193 int *pFormat, 194 uint32_t *pChannels, 195 uint32_t *pRate) 196 { 197 int lFormat = pFormat ? *pFormat : 0; 198 uint32_t lChannels = pChannels ? *pChannels : 0; 199 uint32_t lRate = pRate ? *pRate : 0; 200 201 // fix up defaults 202 if (lFormat == 0) lFormat = format(); 203 if (lChannels == 0) lChannels = channels(); 204 if (lRate == 0) lRate = sampleRate(); 205 206 // check values 207 if ((lFormat != format()) || 208 (lChannels != channels()) || 209 (lRate != sampleRate())) { 210 if (pFormat) *pFormat = format(); 211 if (pChannels) *pChannels = channels(); 212 if (pRate) *pRate = sampleRate(); 213 return BAD_VALUE; 214 } 215 216 if (pFormat) *pFormat = lFormat; 217 if (pChannels) *pChannels = lChannels; 218 if (pRate) *pRate = lRate; 219 220 mAudioHardware = hw; 221 mFd = fd; 222 mDevice = devices; 223 return NO_ERROR; 224 } 225 226 AudioStreamOutGeneric::~AudioStreamOutGeneric() 227 { 228 } 229 230 ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes) 231 { 232 Mutex::Autolock _l(mLock); 233 return ssize_t(::write(mFd, buffer, bytes)); 234 } 235 236 status_t AudioStreamOutGeneric::standby() 237 { 238 // Implement: audio hardware to standby mode 239 return NO_ERROR; 240 } 241 242 status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args) 243 { 244 const size_t SIZE = 256; 245 char buffer[SIZE]; 246 String8 result; 247 snprintf(buffer, SIZE, "AudioStreamOutGeneric::dump\n"); 248 result.append(buffer); 249 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 250 result.append(buffer); 251 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 252 result.append(buffer); 253 snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 254 result.append(buffer); 255 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 256 result.append(buffer); 257 snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice); 258 result.append(buffer); 259 snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware); 260 result.append(buffer); 261 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 262 result.append(buffer); 263 ::write(fd, result.string(), result.size()); 264 return NO_ERROR; 265 } 266 267 status_t AudioStreamOutGeneric::setParameters(const String8& keyValuePairs) 268 { 269 AudioParameter param = AudioParameter(keyValuePairs); 270 String8 key = String8(AudioParameter::keyRouting); 271 status_t status = NO_ERROR; 272 int device; 273 ALOGV("setParameters() %s", keyValuePairs.string()); 274 275 if (param.getInt(key, device) == NO_ERROR) { 276 mDevice = device; 277 param.remove(key); 278 } 279 280 if (param.size()) { 281 status = BAD_VALUE; 282 } 283 return status; 284 } 285 286 String8 AudioStreamOutGeneric::getParameters(const String8& keys) 287 { 288 AudioParameter param = AudioParameter(keys); 289 String8 value; 290 String8 key = String8(AudioParameter::keyRouting); 291 292 if (param.get(key, value) == NO_ERROR) { 293 param.addInt(key, (int)mDevice); 294 } 295 296 ALOGV("getParameters() %s", param.toString().string()); 297 return param.toString(); 298 } 299 300 status_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames) 301 { 302 return INVALID_OPERATION; 303 } 304 305 // ---------------------------------------------------------------------------- 306 307 // record functions 308 status_t AudioStreamInGeneric::set( 309 AudioHardwareGeneric *hw, 310 int fd, 311 uint32_t devices, 312 int *pFormat, 313 uint32_t *pChannels, 314 uint32_t *pRate, 315 AudioSystem::audio_in_acoustics acoustics) 316 { 317 if (pFormat == 0 || pChannels == 0 || pRate == 0) return BAD_VALUE; 318 ALOGV("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, *pFormat, *pChannels, *pRate); 319 // check values 320 if ((*pFormat != format()) || 321 (*pChannels != channels()) || 322 (*pRate != sampleRate())) { 323 ALOGE("Error opening input channel"); 324 *pFormat = format(); 325 *pChannels = channels(); 326 *pRate = sampleRate(); 327 return BAD_VALUE; 328 } 329 330 mAudioHardware = hw; 331 mFd = fd; 332 mDevice = devices; 333 return NO_ERROR; 334 } 335 336 AudioStreamInGeneric::~AudioStreamInGeneric() 337 { 338 } 339 340 ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes) 341 { 342 AutoMutex lock(mLock); 343 if (mFd < 0) { 344 ALOGE("Attempt to read from unopened device"); 345 return NO_INIT; 346 } 347 return ::read(mFd, buffer, bytes); 348 } 349 350 status_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args) 351 { 352 const size_t SIZE = 256; 353 char buffer[SIZE]; 354 String8 result; 355 snprintf(buffer, SIZE, "AudioStreamInGeneric::dump\n"); 356 result.append(buffer); 357 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 358 result.append(buffer); 359 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 360 result.append(buffer); 361 snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 362 result.append(buffer); 363 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 364 result.append(buffer); 365 snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice); 366 result.append(buffer); 367 snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware); 368 result.append(buffer); 369 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 370 result.append(buffer); 371 ::write(fd, result.string(), result.size()); 372 return NO_ERROR; 373 } 374 375 status_t AudioStreamInGeneric::setParameters(const String8& keyValuePairs) 376 { 377 AudioParameter param = AudioParameter(keyValuePairs); 378 String8 key = String8(AudioParameter::keyRouting); 379 status_t status = NO_ERROR; 380 int device; 381 ALOGV("setParameters() %s", keyValuePairs.string()); 382 383 if (param.getInt(key, device) == NO_ERROR) { 384 mDevice = device; 385 param.remove(key); 386 } 387 388 if (param.size()) { 389 status = BAD_VALUE; 390 } 391 return status; 392 } 393 394 String8 AudioStreamInGeneric::getParameters(const String8& keys) 395 { 396 AudioParameter param = AudioParameter(keys); 397 String8 value; 398 String8 key = String8(AudioParameter::keyRouting); 399 400 if (param.get(key, value) == NO_ERROR) { 401 param.addInt(key, (int)mDevice); 402 } 403 404 ALOGV("getParameters() %s", param.toString().string()); 405 return param.toString(); 406 } 407 408 // ---------------------------------------------------------------------------- 409 410 extern "C" AudioHardwareInterface* createAudioHardware(void) { 411 return new AudioHardwareGeneric(); 412 } 413 414 }; // namespace android 415