AudioHardwareInterface.cpp revision ef02827d4c3b9c0601eddc9c348fc2ea866420a2
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 <cutils/properties.h> 19#include <string.h> 20#include <unistd.h> 21 22#define LOG_TAG "AudioHardwareInterface" 23#include <utils/Log.h> 24#include <utils/String8.h> 25 26#include "AudioHardwareStub.h" 27#include "AudioHardwareGeneric.h" 28 29//#define DUMP_FLINGER_OUT // if defined allows recording samples in a file 30#ifdef DUMP_FLINGER_OUT 31#include "AudioDumpInterface.h" 32#endif 33 34 35// change to 1 to log routing calls 36#define LOG_ROUTING_CALLS 0 37 38namespace android { 39 40#if LOG_ROUTING_CALLS 41static const char* routingModeStrings[] = 42{ 43 "OUT OF RANGE", 44 "INVALID", 45 "CURRENT", 46 "NORMAL", 47 "RINGTONE", 48 "IN_CALL" 49}; 50 51static const char* routeStrings[] = 52{ 53 "EARPIECE ", 54 "SPEAKER ", 55 "BLUETOOTH ", 56 "HEADSET ", 57 "BLUETOOTH_A2DP " 58}; 59static const char* routeNone = "NONE"; 60 61static const char* displayMode(int mode) 62{ 63 if ((mode < -2) || (mode > 2)) 64 return routingModeStrings[0]; 65 return routingModeStrings[mode+3]; 66} 67 68static const char* displayRoutes(uint32_t routes) 69{ 70 static char routeStr[80]; 71 if (routes == 0) 72 return routeNone; 73 routeStr[0] = 0; 74 int bitMask = 1; 75 for (int i = 0; i < 4; ++i, bitMask <<= 1) { 76 if (routes & bitMask) { 77 strcat(routeStr, routeStrings[i]); 78 } 79 } 80 routeStr[strlen(routeStr)-1] = 0; 81 return routeStr; 82} 83#endif 84 85// ---------------------------------------------------------------------------- 86 87AudioHardwareInterface* AudioHardwareInterface::create() 88{ 89 /* 90 * FIXME: This code needs to instantiate the correct audio device 91 * interface. For now - we use compile-time switches. 92 */ 93 AudioHardwareInterface* hw = 0; 94 char value[PROPERTY_VALUE_MAX]; 95 96#ifdef GENERIC_AUDIO 97 hw = new AudioHardwareGeneric(); 98#else 99 // if running in emulation - use the emulator driver 100 if (property_get("ro.kernel.qemu", value, 0)) { 101 LOGD("Running in emulation - using generic audio driver"); 102 hw = new AudioHardwareGeneric(); 103 } 104 else { 105 LOGV("Creating Vendor Specific AudioHardware"); 106 hw = createAudioHardware(); 107 } 108#endif 109 if (hw->initCheck() != NO_ERROR) { 110 LOGW("Using stubbed audio hardware. No sound will be produced."); 111 delete hw; 112 hw = new AudioHardwareStub(); 113 } 114 115#ifdef DUMP_FLINGER_OUT 116 // This code adds a record of buffers in a file to write calls made by AudioFlinger. 117 // It replaces the current AudioHardwareInterface object by an intermediate one which 118 // will record buffers in a file (after sending them to hardware) for testing purpose. 119 // This feature is enabled by defining symbol DUMP_FLINGER_OUT. 120 // The output file is FLINGER_DUMP_NAME. Pause are not recorded in the file. 121 122 hw = new AudioDumpInterface(hw); // replace interface 123#endif 124 return hw; 125} 126 127AudioStreamOut::~AudioStreamOut() 128{ 129} 130 131AudioStreamIn::~AudioStreamIn() {} 132 133AudioHardwareBase::AudioHardwareBase() 134{ 135 // force a routing update on initialization 136 memset(&mRoutes, 0, sizeof(mRoutes)); 137 mMode = 0; 138} 139 140// generics for audio routing - the real work is done in doRouting 141status_t AudioHardwareBase::setRouting(int mode, uint32_t routes) 142{ 143#if LOG_ROUTING_CALLS 144 LOGD("setRouting: mode=%s, routes=[%s]", displayMode(mode), displayRoutes(routes)); 145#endif 146 if (mode == AudioSystem::MODE_CURRENT) 147 mode = mMode; 148 if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) 149 return BAD_VALUE; 150 uint32_t old = mRoutes[mode]; 151 mRoutes[mode] = routes; 152 if ((mode != mMode) || (old == routes)) 153 return NO_ERROR; 154#if LOG_ROUTING_CALLS 155 const char* oldRouteStr = strdup(displayRoutes(old)); 156 LOGD("doRouting: mode=%s, old route=[%s], new route=[%s]", 157 displayMode(mode), oldRouteStr, displayRoutes(routes)); 158 delete oldRouteStr; 159#endif 160 return doRouting(); 161} 162 163status_t AudioHardwareBase::getRouting(int mode, uint32_t* routes) 164{ 165 if (mode == AudioSystem::MODE_CURRENT) 166 mode = mMode; 167 if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) 168 return BAD_VALUE; 169 *routes = mRoutes[mode]; 170#if LOG_ROUTING_CALLS 171 LOGD("getRouting: mode=%s, routes=[%s]", 172 displayMode(mode), displayRoutes(*routes)); 173#endif 174 return NO_ERROR; 175} 176 177status_t AudioHardwareBase::setMode(int mode) 178{ 179#if LOG_ROUTING_CALLS 180 LOGD("setMode(%s)", displayMode(mode)); 181#endif 182 if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) 183 return BAD_VALUE; 184 if (mMode == mode) 185 return NO_ERROR; 186#if LOG_ROUTING_CALLS 187 LOGD("doRouting: old mode=%s, new mode=%s route=[%s]", 188 displayMode(mMode), displayMode(mode), displayRoutes(mRoutes[mode])); 189#endif 190 mMode = mode; 191 return doRouting(); 192} 193 194status_t AudioHardwareBase::getMode(int* mode) 195{ 196 // Implement: set audio routing 197 *mode = mMode; 198 return NO_ERROR; 199} 200 201status_t AudioHardwareBase::setParameter(const char* key, const char* value) 202{ 203 // default implementation is to ignore 204 return NO_ERROR; 205} 206 207 208// default implementation 209size_t AudioHardwareBase::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 210{ 211 if (sampleRate != 8000) { 212 LOGW("getInputBufferSize bad sampling rate: %d", sampleRate); 213 return 0; 214 } 215 if (format != AudioSystem::PCM_16_BIT) { 216 LOGW("getInputBufferSize bad format: %d", format); 217 return 0; 218 } 219 if (channelCount != 1) { 220 LOGW("getInputBufferSize bad channel count: %d", channelCount); 221 return 0; 222 } 223 224 return 320; 225} 226 227status_t AudioHardwareBase::dumpState(int fd, const Vector<String16>& args) 228{ 229 const size_t SIZE = 256; 230 char buffer[SIZE]; 231 String8 result; 232 snprintf(buffer, SIZE, "AudioHardwareBase::dumpState\n"); 233 result.append(buffer); 234 snprintf(buffer, SIZE, "\tmMode: %d\n", mMode); 235 result.append(buffer); 236 for (int i = 0, n = AudioSystem::NUM_MODES; i < n; ++i) { 237 snprintf(buffer, SIZE, "\tmRoutes[%d]: %d\n", i, mRoutes[i]); 238 result.append(buffer); 239 } 240 ::write(fd, result.string(), result.size()); 241 dump(fd, args); // Dump the state of the concrete child. 242 return NO_ERROR; 243} 244 245// ---------------------------------------------------------------------------- 246 247}; // namespace android 248