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 34namespace android_audio_legacy { 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 closeOutputStream((AudioStreamOut *)mOutput); 52 closeInputStream((AudioStreamIn *)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 64AudioStreamOut* 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 91void AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) { 92 if (mOutput && out == mOutput) { 93 delete mOutput; 94 mOutput = 0; 95 } 96} 97 98AudioStreamIn* 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 131void AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) { 132 if (mInput && in == mInput) { 133 delete mInput; 134 mInput = 0; 135 } 136} 137 138status_t AudioHardwareGeneric::setVoiceVolume(float v) 139{ 140 // Implement: set voice volume 141 return NO_ERROR; 142} 143 144status_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 151status_t AudioHardwareGeneric::setMicMute(bool state) 152{ 153 mMicMute = state; 154 return NO_ERROR; 155} 156 157status_t AudioHardwareGeneric::getMicMute(bool* state) 158{ 159 *state = mMicMute; 160 return NO_ERROR; 161} 162 163status_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 175status_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 189status_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 226AudioStreamOutGeneric::~AudioStreamOutGeneric() 227{ 228} 229 230ssize_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 236status_t AudioStreamOutGeneric::standby() 237{ 238 // Implement: audio hardware to standby mode 239 return NO_ERROR; 240} 241 242status_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 267status_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 286String8 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 300status_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames) 301{ 302 return INVALID_OPERATION; 303} 304 305// ---------------------------------------------------------------------------- 306 307// record functions 308status_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 336AudioStreamInGeneric::~AudioStreamInGeneric() 337{ 338} 339 340ssize_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 350status_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 375status_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 394String8 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 410extern "C" AudioHardwareInterface* createAudioHardware(void) { 411 return new AudioHardwareGeneric(); 412} 413 414}; // namespace android 415