summaryrefslogtreecommitdiff
path: root/AudioHardwareInterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'AudioHardwareInterface.cpp')
-rw-r--r--AudioHardwareInterface.cpp240
1 files changed, 240 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