diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:31:44 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:31:44 -0800 |
commit | 9066cfe9886ac131c34d59ed0e2d287b0e3c0087 (patch) | |
tree | d88beb88001f2482911e3d28e43833b50e4b4e97 /libs/audioflinger/AudioHardwareInterface.cpp | |
parent | d83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (diff) | |
download | frameworks_base-9066cfe9886ac131c34d59ed0e2d287b0e3c0087.zip frameworks_base-9066cfe9886ac131c34d59ed0e2d287b0e3c0087.tar.gz frameworks_base-9066cfe9886ac131c34d59ed0e2d287b0e3c0087.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'libs/audioflinger/AudioHardwareInterface.cpp')
-rw-r--r-- | libs/audioflinger/AudioHardwareInterface.cpp | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/libs/audioflinger/AudioHardwareInterface.cpp b/libs/audioflinger/AudioHardwareInterface.cpp new file mode 100644 index 0000000..ac76a19 --- /dev/null +++ b/libs/audioflinger/AudioHardwareInterface.cpp @@ -0,0 +1,247 @@ +/* +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#include <cutils/properties.h> +#include <string.h> +#include <unistd.h> + +#define LOG_TAG "AudioHardwareInterface" +#include <utils/Log.h> +#include <utils/String8.h> + +#include "AudioHardwareStub.h" +#include "AudioHardwareGeneric.h" + +//#define DUMP_FLINGER_OUT // if defined allows recording samples in a file +#ifdef DUMP_FLINGER_OUT +#include "AudioDumpInterface.h" +#endif + + +// change to 1 to log routing calls +#define LOG_ROUTING_CALLS 0 + +namespace android { + +#if LOG_ROUTING_CALLS +static const char* routingModeStrings[] = +{ + "OUT OF RANGE", + "INVALID", + "CURRENT", + "NORMAL", + "RINGTONE", + "IN_CALL" +}; + +static const char* routeStrings[] = +{ + "EARPIECE ", + "SPEAKER ", + "BLUETOOTH ", + "HEADSET " + "BLUETOOTH_A2DP " +}; +static const char* routeNone = "NONE"; + +static const char* displayMode(int mode) +{ + if ((mode < -2) || (mode > 2)) + return routingModeStrings[0]; + return routingModeStrings[mode+3]; +} + +static const char* displayRoutes(uint32_t routes) +{ + static char routeStr[80]; + if (routes == 0) + return routeNone; + routeStr[0] = 0; + int bitMask = 1; + for (int i = 0; i < 4; ++i, bitMask <<= 1) { + if (routes & bitMask) { + strcat(routeStr, routeStrings[i]); + } + } + routeStr[strlen(routeStr)-1] = 0; + return routeStr; +} +#endif + +// ---------------------------------------------------------------------------- + +AudioHardwareInterface* AudioHardwareInterface::create() +{ + /* + * FIXME: This code needs to instantiate the correct audio device + * interface. For now - we use compile-time switches. + */ + AudioHardwareInterface* hw = 0; + char value[PROPERTY_VALUE_MAX]; + +#ifdef GENERIC_AUDIO + hw = new AudioHardwareGeneric(); +#else + // if running in emulation - use the emulator driver + if (property_get("ro.kernel.qemu", value, 0)) { + LOGD("Running in emulation - using generic audio driver"); + hw = new AudioHardwareGeneric(); + } + else { + LOGV("Creating Vendor Specific AudioHardware"); + hw = createAudioHardware(); + } +#endif + if (hw->initCheck() != NO_ERROR) { + LOGW("Using stubbed audio hardware. No sound will be produced."); + delete hw; + hw = new AudioHardwareStub(); + } + +#ifdef DUMP_FLINGER_OUT + // This code adds a record of buffers in a file to write calls made by AudioFlinger. + // It replaces the current AudioHardwareInterface object by an intermediate one which + // will record buffers in a file (after sending them to hardware) for testing purpose. + // This feature is enabled by defining symbol DUMP_FLINGER_OUT. + // The output file is FLINGER_DUMP_NAME. Pause are not recorded in the file. + + hw = new AudioDumpInterface(hw); // replace interface +#endif + return hw; +} + +AudioStreamOut::~AudioStreamOut() +{ +} + +AudioStreamIn::~AudioStreamIn() {} + +AudioHardwareBase::AudioHardwareBase() +{ + // force a routing update on initialization + memset(&mRoutes, 0, sizeof(mRoutes)); + mMode = 0; +} + +// generics for audio routing - the real work is done in doRouting +status_t AudioHardwareBase::setRouting(int mode, uint32_t routes) +{ +#if LOG_ROUTING_CALLS + LOGD("setRouting: mode=%s, routes=[%s]", displayMode(mode), displayRoutes(routes)); +#endif + if (mode == AudioSystem::MODE_CURRENT) + mode = mMode; + if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) + return BAD_VALUE; + uint32_t old = mRoutes[mode]; + mRoutes[mode] = routes; + if ((mode != mMode) || (old == routes)) + return NO_ERROR; +#if LOG_ROUTING_CALLS + const char* oldRouteStr = strdup(displayRoutes(old)); + LOGD("doRouting: mode=%s, old route=[%s], new route=[%s]", + displayMode(mode), oldRouteStr, displayRoutes(routes)); + delete oldRouteStr; +#endif + return doRouting(); +} + +status_t AudioHardwareBase::getRouting(int mode, uint32_t* routes) +{ + if (mode == AudioSystem::MODE_CURRENT) + mode = mMode; + if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) + return BAD_VALUE; + *routes = mRoutes[mode]; +#if LOG_ROUTING_CALLS + LOGD("getRouting: mode=%s, routes=[%s]", + displayMode(mode), displayRoutes(*routes)); +#endif + return NO_ERROR; +} + +status_t AudioHardwareBase::setMode(int mode) +{ +#if LOG_ROUTING_CALLS + LOGD("setMode(%s)", displayMode(mode)); +#endif + if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) + return BAD_VALUE; + if (mMode == mode) + return NO_ERROR; +#if LOG_ROUTING_CALLS + LOGD("doRouting: old mode=%s, new mode=%s route=[%s]", + displayMode(mMode), displayMode(mode), displayRoutes(mRoutes[mode])); +#endif + mMode = mode; + return doRouting(); +} + +status_t AudioHardwareBase::getMode(int* mode) +{ + // Implement: set audio routing + *mode = mMode; + return NO_ERROR; +} + +status_t AudioHardwareBase::setParameter(const char* key, const char* value) +{ + // default implementation is to ignore + return NO_ERROR; +} + + +// default implementation +size_t AudioHardwareBase::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) +{ + if (sampleRate != 8000) { + LOGW("getInputBufferSize bad sampling rate: %d", sampleRate); + return 0; + } + if (format != AudioSystem::PCM_16_BIT) { + LOGW("getInputBufferSize bad format: %d", format); + return 0; + } + if (channelCount != 1) { + LOGW("getInputBufferSize bad channel count: %d", channelCount); + return 0; + } + + return 320; +} + +status_t AudioHardwareBase::dumpState(int fd, const Vector<String16>& args) +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + snprintf(buffer, SIZE, "AudioHardwareBase::dumpState\n"); + result.append(buffer); + snprintf(buffer, SIZE, "\tmMode: %d\n", mMode); + result.append(buffer); + for (int i = 0, n = AudioSystem::NUM_MODES; i < n; ++i) { + snprintf(buffer, SIZE, "\tmRoutes[%d]: %d\n", i, mRoutes[i]); + result.append(buffer); + } + ::write(fd, result.string(), result.size()); + dump(fd, args); // Dump the state of the concrete child. + return NO_ERROR; +} + +// ---------------------------------------------------------------------------- + +}; // namespace android |