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 35namespace android { 36 37// ---------------------------------------------------------------------------- 38 39static char const * const kAudioDeviceName = "/dev/eac"; 40 41// ---------------------------------------------------------------------------- 42 43AudioHardwareGeneric::AudioHardwareGeneric() 44 : mOutput(0), mInput(0), mFd(-1), mMicMute(false) 45{ 46 mFd = ::open(kAudioDeviceName, O_RDWR); 47} 48 49AudioHardwareGeneric::~AudioHardwareGeneric() 50{ 51 if (mFd >= 0) ::close(mFd); 52 closeOutputStream((AudioStreamOut *)mOutput); 53 closeInputStream((AudioStreamIn *)mInput); 54} 55 56status_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 65AudioStreamOut* 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 92void AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) { 93 if (mOutput && out == mOutput) { 94 delete mOutput; 95 mOutput = 0; 96 } 97} 98 99AudioStreamIn* 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 132void AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) { 133 if (mInput && in == mInput) { 134 delete mInput; 135 mInput = 0; 136 } 137} 138 139status_t AudioHardwareGeneric::setVoiceVolume(float v) 140{ 141 // Implement: set voice volume 142 return NO_ERROR; 143} 144 145status_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 152status_t AudioHardwareGeneric::setMicMute(bool state) 153{ 154 mMicMute = state; 155 return NO_ERROR; 156} 157 158status_t AudioHardwareGeneric::getMicMute(bool* state) 159{ 160 *state = mMicMute; 161 return NO_ERROR; 162} 163 164status_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 176status_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 190status_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 227AudioStreamOutGeneric::~AudioStreamOutGeneric() 228{ 229} 230 231ssize_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 237status_t AudioStreamOutGeneric::standby() 238{ 239 // Implement: audio hardware to standby mode 240 return NO_ERROR; 241} 242 243status_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 268status_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 287String8 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// ---------------------------------------------------------------------------- 302 303// record functions 304status_t AudioStreamInGeneric::set( 305 AudioHardwareGeneric *hw, 306 int fd, 307 uint32_t devices, 308 int *pFormat, 309 uint32_t *pChannels, 310 uint32_t *pRate, 311 AudioSystem::audio_in_acoustics acoustics) 312{ 313 // FIXME: remove logging 314 if (pFormat == 0 || pChannels == 0 || pRate == 0) return BAD_VALUE; 315 LOGD("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, *pFormat, *pChannels, *pRate); 316 // check values 317 if ((*pFormat != format()) || 318 (*pChannels != channels()) || 319 (*pRate != sampleRate())) { 320 LOGE("Error opening input channel"); 321 *pFormat = format(); 322 *pChannels = channels(); 323 *pRate = sampleRate(); 324 return BAD_VALUE; 325 } 326 327 mAudioHardware = hw; 328 mFd = fd; 329 mDevice = devices; 330 return NO_ERROR; 331} 332 333AudioStreamInGeneric::~AudioStreamInGeneric() 334{ 335 // FIXME: remove logging 336 LOGD("AudioStreamInGeneric destructor"); 337} 338 339ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes) 340{ 341 // FIXME: remove logging 342 LOGD("AudioStreamInGeneric::read(%p, %d) from fd %d", buffer, (int)bytes, mFd); 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 351status_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 376status_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 395String8 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}; // namespace android 412