summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiaopeng Yang <xiaopeng.yang@windriver.com>2008-11-19 16:33:20 +0800
committerXiaopeng Yang <xiaopeng.yang@windriver.com>2008-11-19 16:33:20 +0800
commit48e8b3bac91275743bd62d01e4d1e7a30396dad4 (patch)
tree84d0c2d3fb6db54a1e6c4897cca9cede6957fc12
downloadalsa_sound-48e8b3bac91275743bd62d01e4d1e7a30396dad4.tar.gz
Template files from frameworks/base/libs/audioflinger
-rw-r--r--AudioHardwareInterface.cpp240
-rw-r--r--AudioHardwareStub.cpp175
-rw-r--r--AudioHardwareStub.h95
3 files changed, 510 insertions, 0 deletions
diff --git a/AudioHardwareInterface.cpp b/AudioHardwareInterface.cpp
new file mode 100644
index 0000000..7387b3d
--- /dev/null
+++ b/AudioHardwareInterface.cpp
@@ -0,0 +1,240 @@
+/*
+**
+** 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 "
+};
+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 and setting environement
+ // "audioflinger.dump = 1". The output file is "tmp/FlingerOut.pcm". Pause are not recorded
+ // in the file.
+
+ // read dump mode
+ property_get("audioflinger.dump", value, "0");
+ switch(value[0]) {
+ case '1':
+ LOGV("Dump mode");
+ hw = new AudioDumpInterface(hw); // replace interface
+ return hw;
+ break;
+ case '0':
+ default:
+ LOGV("No Dump mode");
+ return hw;
+ break;
+ }
+#endif
+ return hw;
+}
+
+AudioStreamOut::~AudioStreamOut()
+{
+}
+
+AudioStreamIn::~AudioStreamIn() {}
+
+AudioHardwareInterface::AudioHardwareInterface()
+{
+ // 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 AudioHardwareInterface::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 AudioHardwareInterface::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 AudioHardwareInterface::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 AudioHardwareInterface::getMode(int* mode)
+{
+ // Implement: set audio routing
+ *mode = mMode;
+ return NO_ERROR;
+}
+
+status_t AudioHardwareInterface::setParameter(const char* key, const char* value)
+{
+ // default implementation is to ignore
+ return NO_ERROR;
+}
+
+status_t AudioHardwareInterface::dumpState(int fd, const Vector<String16>& args)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+ snprintf(buffer, SIZE, "AudioHardwareInterface::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
diff --git a/AudioHardwareStub.cpp b/AudioHardwareStub.cpp
new file mode 100644
index 0000000..0046db8
--- /dev/null
+++ b/AudioHardwareStub.cpp
@@ -0,0 +1,175 @@
+/* //device/servers/AudioFlinger/AudioHardwareStub.cpp
+**
+** 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 <stdint.h>
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <utils/String8.h>
+
+#include "AudioHardwareStub.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+AudioHardwareStub::AudioHardwareStub() : mMicMute(false)
+{
+}
+
+AudioHardwareStub::~AudioHardwareStub()
+{
+}
+
+status_t AudioHardwareStub::initCheck()
+{
+ return NO_ERROR;
+}
+
+status_t AudioHardwareStub::standby()
+{
+ return NO_ERROR;
+}
+
+AudioStreamOut* AudioHardwareStub::openOutputStream(
+ int format, int channelCount, uint32_t sampleRate)
+{
+ AudioStreamOutStub* out = new AudioStreamOutStub();
+ if (out->set(format, channelCount, sampleRate) == NO_ERROR)
+ return out;
+ delete out;
+ return 0;
+}
+
+AudioStreamIn* AudioHardwareStub::openInputStream(
+ int format, int channelCount, uint32_t sampleRate)
+{
+ AudioStreamInStub* in = new AudioStreamInStub();
+ if (in->set(format, channelCount, sampleRate) == NO_ERROR)
+ return in;
+ delete in;
+ return 0;
+}
+
+status_t AudioHardwareStub::setVoiceVolume(float volume)
+{
+ return NO_ERROR;
+}
+
+status_t AudioHardwareStub::setMasterVolume(float volume)
+{
+ return NO_ERROR;
+}
+
+status_t AudioHardwareStub::dumpInternals(int fd, const Vector<String16>& args)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+ result.append("AudioHardwareStub::dumpInternals\n");
+ snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false");
+ result.append(buffer);
+ ::write(fd, result.string(), result.size());
+ return NO_ERROR;
+}
+
+status_t AudioHardwareStub::dump(int fd, const Vector<String16>& args)
+{
+ dumpInternals(fd, args);
+ return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+status_t AudioStreamOutStub::set(int format, int channels, uint32_t rate)
+{
+ // fix up defaults
+ if (format == 0) format = AudioSystem::PCM_16_BIT;
+ if (channels == 0) channels = channelCount();
+ if (rate == 0) rate = sampleRate();
+
+ if ((format == AudioSystem::PCM_16_BIT) &&
+ (channels == channelCount()) &&
+ (rate == sampleRate()))
+ return NO_ERROR;
+ return BAD_VALUE;
+}
+
+ssize_t AudioStreamOutStub::write(const void* buffer, size_t bytes)
+{
+ // fake timing for audio output
+ usleep(bytes * 1000000 / sizeof(int16_t) / channelCount() / sampleRate());
+ return bytes;
+}
+
+status_t AudioStreamOutStub::dump(int fd, const Vector<String16>& args)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+ snprintf(buffer, SIZE, "AudioStreamOutStub::dump\n");
+ snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
+ snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
+ snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
+ snprintf(buffer, SIZE, "\tformat: %d\n", format());
+ result.append(buffer);
+ ::write(fd, result.string(), result.size());
+ return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+status_t AudioStreamInStub::set(int format, int channels, uint32_t rate)
+{
+ if ((format == AudioSystem::PCM_16_BIT) &&
+ (channels == channelCount()) &&
+ (rate == sampleRate()))
+ return NO_ERROR;
+ return BAD_VALUE;
+}
+
+ssize_t AudioStreamInStub::read(void* buffer, ssize_t bytes)
+{
+ // fake timing for audio input
+ usleep(bytes * 1000000 / sizeof(int16_t) / channelCount() / sampleRate());
+ memset(buffer, 0, bytes);
+ return bytes;
+}
+
+status_t AudioStreamInStub::dump(int fd, const Vector<String16>& args)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+ snprintf(buffer, SIZE, "AudioStreamInStub::dump\n");
+ result.append(buffer);
+ snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
+ result.append(buffer);
+ snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
+ result.append(buffer);
+ snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
+ result.append(buffer);
+ snprintf(buffer, SIZE, "\tformat: %d\n", format());
+ result.append(buffer);
+ ::write(fd, result.string(), result.size());
+ return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/AudioHardwareStub.h b/AudioHardwareStub.h
new file mode 100644
index 0000000..1a61552
--- /dev/null
+++ b/AudioHardwareStub.h
@@ -0,0 +1,95 @@
+/* //device/servers/AudioFlinger/AudioHardwareStub.h
+**
+** 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.
+*/
+
+#ifndef ANDROID_AUDIO_HARDWARE_STUB_H
+#define ANDROID_AUDIO_HARDWARE_STUB_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <hardware/AudioHardwareInterface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class AudioStreamOutStub : public AudioStreamOut {
+public:
+ virtual status_t set(int format, int channelCount, uint32_t sampleRate);
+ virtual uint32_t sampleRate() const { return 44100; }
+ virtual size_t bufferSize() const { return 4096; }
+ virtual int channelCount() const { return 2; }
+ virtual int format() const { return AudioSystem::PCM_16_BIT; }
+ virtual status_t setVolume(float volume) { return NO_ERROR; }
+ virtual ssize_t write(const void* buffer, size_t bytes);
+ virtual status_t dump(int fd, const Vector<String16>& args);
+};
+
+class AudioStreamInStub : public AudioStreamIn {
+public:
+ virtual status_t set(int format, int channelCount, uint32_t sampleRate);
+ virtual uint32_t sampleRate() const { return 8000; }
+ virtual size_t bufferSize() const { return 320; }
+ virtual int channelCount() const { return 1; }
+ virtual int format() const { return AudioSystem::PCM_16_BIT; }
+ virtual status_t setGain(float gain) { return NO_ERROR; }
+ virtual ssize_t read(void* buffer, ssize_t bytes);
+ virtual status_t dump(int fd, const Vector<String16>& args);
+};
+
+class AudioHardwareStub : public AudioHardwareInterface
+{
+public:
+ AudioHardwareStub();
+ virtual ~AudioHardwareStub();
+ virtual status_t initCheck();
+ virtual status_t standby();
+ virtual status_t setVoiceVolume(float volume);
+ virtual status_t setMasterVolume(float volume);
+
+ // mic mute
+ virtual status_t setMicMute(bool state) { mMicMute = state; return NO_ERROR; }
+ virtual status_t getMicMute(bool* state) { *state = mMicMute ; return NO_ERROR; }
+
+ virtual status_t setParameter(const char* key, const char* value)
+ { return NO_ERROR; }
+
+ // create I/O streams
+ virtual AudioStreamOut* openOutputStream(
+ int format=0,
+ int channelCount=0,
+ uint32_t sampleRate=0);
+
+ virtual AudioStreamIn* openInputStream(
+ int format,
+ int channelCount,
+ uint32_t sampleRate);
+
+protected:
+ virtual status_t doRouting() { return NO_ERROR; }
+ virtual status_t dump(int fd, const Vector<String16>& args);
+
+ bool mMicMute;
+private:
+ status_t dumpInternals(int fd, const Vector<String16>& args);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_HARDWARE_STUB_H