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 37namespace android_audio_legacy { 38 39// ---------------------------------------------------------------------------- 40 41static char const * const kAudioDeviceName = "/dev/eac"; 42 43// ---------------------------------------------------------------------------- 44 45AudioHardwareGeneric::AudioHardwareGeneric() 46 : mOutput(0), mInput(0), mFd(-1), mMicMute(false) 47{ 48 mFd = ::open(kAudioDeviceName, O_RDWR); 49} 50 51AudioHardwareGeneric::~AudioHardwareGeneric() 52{ 53 if (mFd >= 0) ::close(mFd); 54 closeOutputStream((AudioStreamOut *)mOutput); 55 closeInputStream((AudioStreamIn *)mInput); 56} 57 58status_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 67AudioStreamOut* 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 94void AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) { 95 if (mOutput && out == mOutput) { 96 delete mOutput; 97 mOutput = 0; 98 } 99} 100 101AudioStreamIn* 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 134void AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) { 135 if (mInput && in == mInput) { 136 delete mInput; 137 mInput = 0; 138 } 139} 140 141status_t AudioHardwareGeneric::setVoiceVolume(float v) 142{ 143 // Implement: set voice volume 144 return NO_ERROR; 145} 146 147status_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 154status_t AudioHardwareGeneric::setMicMute(bool state) 155{ 156 mMicMute = state; 157 return NO_ERROR; 158} 159 160status_t AudioHardwareGeneric::getMicMute(bool* state) 161{ 162 *state = mMicMute; 163 return NO_ERROR; 164} 165 166status_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 178status_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 192status_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 229AudioStreamOutGeneric::~AudioStreamOutGeneric() 230{ 231} 232 233ssize_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 239status_t AudioStreamOutGeneric::standby() 240{ 241 // Implement: audio hardware to standby mode 242 return NO_ERROR; 243} 244 245status_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 270status_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 289String8 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 303status_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames) 304{ 305 return INVALID_OPERATION; 306} 307 308// ---------------------------------------------------------------------------- 309 310// record functions 311status_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 339AudioStreamInGeneric::~AudioStreamInGeneric() 340{ 341} 342 343ssize_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 353status_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 378status_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 397String8 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