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