diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
new file mode 100644
index 0000000..eb00f8c
--- /dev/null
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2008 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 <math.h>
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "A2dpAudioInterface"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include "A2dpAudioInterface.h"
+#include "audio/liba2dp.h"
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+A2dpAudioInterface::A2dpAudioInterface() :
+    mOutput(0)
+{
+}
+
+A2dpAudioInterface::~A2dpAudioInterface()
+{
+    delete mOutput;
+}
+
+status_t A2dpAudioInterface::initCheck()
+{
+    return 0;
+}
+
+AudioStreamOut* A2dpAudioInterface::openOutputStream(
+        int format, int channelCount, uint32_t sampleRate, status_t *status)
+{
+    LOGD("A2dpAudioInterface::openOutputStream %d, %d, %d\n", format, channelCount, sampleRate);
+    Mutex::Autolock lock(mLock);
+    status_t err = 0;
+
+    // only one output stream allowed
+    if (mOutput) {
+        if (status)
+            *status = -1;
+        return NULL;
+    }
+
+    // create new output stream
+    A2dpAudioStreamOut* out = new A2dpAudioStreamOut();
+    if ((err = out->set(format, channelCount, sampleRate)) == NO_ERROR) {
+        mOutput = out;
+    } else {
+        delete out;
+    }
+    
+    if (status)
+        *status = err;
+    return mOutput;
+}
+
+AudioStreamIn* A2dpAudioInterface::openInputStream(
+        int format, int channelCount, uint32_t sampleRate, status_t *status,
+        AudioSystem::audio_in_acoustics acoustics)
+{
+    if (status)
+        *status = -1;
+    return NULL;
+}
+
+status_t A2dpAudioInterface::setMicMute(bool state)
+{
+    return 0;
+}
+
+status_t A2dpAudioInterface::getMicMute(bool* state)
+{
+    return 0;
+}
+
+status_t A2dpAudioInterface::setParameter(const char *key, const char *value)
+{
+    LOGD("setParameter %s,%s\n", key, value);
+    
+    if (!key || !value)
+        return -EINVAL;
+    
+    if (strcmp(key, "a2dp_sink_address") == 0) {        
+        return mOutput->setAddress(value);
+    }
+    if (strcmp(key, "bluetooth_enabled") == 0 &&
+        strcmp(value, "false") == 0) {
+        return mOutput->close();
+    }
+
+    return 0;
+}
+
+status_t A2dpAudioInterface::setVoiceVolume(float v)
+{
+    return 0;
+}
+
+status_t A2dpAudioInterface::setMasterVolume(float v)
+{
+    return 0;
+}
+
+status_t A2dpAudioInterface::doRouting()
+{
+    return 0;
+}
+
+status_t A2dpAudioInterface::dump(int fd, const Vector<String16>& args)
+{
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() :
+    mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL)
+{
+    // use any address by default
+    strncpy(mA2dpAddress, "00:00:00:00:00:00", sizeof(mA2dpAddress));
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::set(
+        int format, int channels, uint32_t rate)
+{
+    LOGD("A2dpAudioStreamOut::set %d, %d, %d\n", format, channels, rate);
+
+    // fix up defaults
+    if (format == 0) format = AudioSystem::PCM_16_BIT;
+    if (channels == 0) channels = channelCount();
+    if (rate == 0) rate = sampleRate();
+
+    // check values
+    if ((format != AudioSystem::PCM_16_BIT) ||
+            (channels != channelCount()) ||
+            (rate != sampleRate()))
+        return BAD_VALUE;
+
+    return NO_ERROR;
+}
+
+A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
+{
+    close();
+}
+
+ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
+{    
+    status_t status = NO_INIT;
+    size_t remaining = bytes;
+
+    if (!mData) {
+        status = a2dp_init(44100, 2, &mData);
+        if (status < 0) {
+            LOGE("a2dp_init failed err: %d\n", status);
+            mData = NULL;
+            goto Error;
+        }
+        a2dp_set_sink(mData, mA2dpAddress);
+    }
+    
+    while (remaining > 0) {
+        status = a2dp_write(mData, buffer, remaining);
+        if (status <= 0) {
+            LOGE("a2dp_write failed err: %d\n", status);
+            goto Error;
+        }
+        remaining -= status;
+        buffer = ((char *)buffer) + status;
+    }
+
+    mStandby = false;
+    
+    return bytes;
+
+Error:
+    // Simulate audio output timing in case of error
+    usleep(bytes * 1000000 / frameSize() / sampleRate());
+
+    return status;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
+{
+    int result = 0;
+
+    if (!mStandby) {
+        result = a2dp_stop(mData);
+        if (result == 0)
+            mStandby = true;
+    }
+
+    return result;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::setAddress(const char* address)
+{
+    if (strlen(address) < sizeof(mA2dpAddress))
+        return -EINVAL;
+
+    if (strcmp(address, mA2dpAddress)) {
+        strcpy(mA2dpAddress, address);
+        if (mData)
+            a2dp_set_sink(mData, mA2dpAddress);
+    }
+    
+    return NO_ERROR;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::close()
+{
+    if (mData) {
+        a2dp_cleanup(mData);
+        mData = NULL;
+    }
+    return NO_ERROR;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::dump(int fd, const Vector<String16>& args)
+{
+    return NO_ERROR;
+}
+
+
+}; // namespace android
diff --git a/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
new file mode 100644
index 0000000..a56e8a0
--- /dev/null
+++ b/libs/audioflinger/A2dpAudioInterface.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008 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 A2DP_AUDIO_HARDWARE_H
+#define A2DP_AUDIO_HARDWARE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+
+#include <hardware_legacy/AudioHardwareBase.h>
+
+
+namespace android {
+
+class A2dpAudioInterface : public AudioHardwareBase
+{
+    class A2dpAudioStreamOut;
+
+public:
+                        A2dpAudioInterface();
+    virtual             ~A2dpAudioInterface();
+    virtual status_t    initCheck();
+
+    virtual status_t    setVoiceVolume(float volume);
+    virtual status_t    setMasterVolume(float volume);
+
+    // mic mute
+    virtual status_t    setMicMute(bool state);
+    virtual status_t    getMicMute(bool* state);
+
+    // Temporary interface, do not use
+    // TODO: Replace with a more generic key:value get/set mechanism
+    virtual status_t    setParameter(const char *key, const char *value);
+
+    // create I/O streams
+    virtual AudioStreamOut* openOutputStream(
+                                int format=0,
+                                int channelCount=0,
+                                uint32_t sampleRate=0,
+                                status_t *status=0);
+
+    virtual AudioStreamIn* openInputStream(
+                                int format,
+                                int channelCount,
+                                uint32_t sampleRate,
+                                status_t *status,
+                                AudioSystem::audio_in_acoustics acoustics);
+
+protected:
+    virtual status_t    doRouting();
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+private:
+    class A2dpAudioStreamOut : public AudioStreamOut {
+    public:
+                            A2dpAudioStreamOut();
+        virtual             ~A2dpAudioStreamOut();
+                status_t    set(int format,
+                                int channelCount,
+                                uint32_t sampleRate);
+        virtual uint32_t    sampleRate() const { return 44100; }
+        // SBC codec wants a multiple of 512
+        virtual size_t      bufferSize() const { return 512 * 20; }
+        virtual int         channelCount() const { return 2; }
+        virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+        virtual uint32_t    latency() const { return ((1000*bufferSize())/frameSize())/sampleRate() + 200; }
+        virtual status_t    setVolume(float volume) { return INVALID_OPERATION; }
+        virtual ssize_t     write(const void* buffer, size_t bytes);
+                status_t    standby();
+                status_t    close();
+        virtual status_t    dump(int fd, const Vector<String16>& args);
+
+    private:
+        friend class A2dpAudioInterface;
+        status_t            setAddress(const char* address);
+
+    private:
+                int         mFd;
+                bool        mStandby;
+                int         mStartCount;
+                int         mRetryCount;
+                char        mA2dpAddress[20];
+                void*       mData;
+    };
+
+    Mutex                   mLock;
+    A2dpAudioStreamOut*     mOutput;
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // A2DP_AUDIO_HARDWARE_H
diff --git a/libs/audioflinger/Android.mk b/libs/audioflinger/Android.mk
new file mode 100644
index 0000000..50d516b
--- /dev/null
+++ b/libs/audioflinger/Android.mk
@@ -0,0 +1,56 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    AudioHardwareGeneric.cpp \
+    AudioHardwareStub.cpp \
+    AudioDumpInterface.cpp \
+    AudioHardwareInterface.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    libmedia \
+    libhardware_legacy
+
+ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
+  LOCAL_CFLAGS += -DGENERIC_AUDIO
+endif
+
+LOCAL_MODULE:= libaudiointerface
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=               \
+    AudioFlinger.cpp            \
+    AudioMixer.cpp.arm          \
+    AudioResampler.cpp.arm      \
+    AudioResamplerSinc.cpp.arm  \
+    AudioResamplerCubic.cpp.arm
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    libmedia \
+    libhardware_legacy
+
+ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
+  LOCAL_STATIC_LIBRARIES += libaudiointerface
+else
+  LOCAL_SHARED_LIBRARIES += libaudio
+endif
+
+LOCAL_MODULE:= libaudioflinger
+
+ifeq ($(BOARD_HAVE_BLUETOOTH),true)
+  LOCAL_SRC_FILES += A2dpAudioInterface.cpp
+  LOCAL_SHARED_LIBRARIES += liba2dp
+  LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
+  LOCAL_C_INCLUDES += $(call include-path-for, bluez-libs)
+  LOCAL_C_INCLUDES += $(call include-path-for, bluez-utils)
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/audioflinger/AudioBufferProvider.h b/libs/audioflinger/AudioBufferProvider.h
new file mode 100644
index 0000000..1a467c7
--- /dev/null
+++ b/libs/audioflinger/AudioBufferProvider.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 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_BUFFER_PROVIDER_H
+#define ANDROID_AUDIO_BUFFER_PROVIDER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class AudioBufferProvider
+{
+public:
+
+    struct Buffer {
+        union {
+            void*       raw;
+            short*      i16;
+            int8_t*     i8;
+        };
+        size_t frameCount;
+    };
+    
+    virtual status_t getNextBuffer(Buffer* buffer) = 0;
+    virtual void releaseBuffer(Buffer* buffer) = 0;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_AUDIO_BUFFER_PROVIDER_H
diff --git a/libs/audioflinger/AudioDumpInterface.cpp b/libs/audioflinger/AudioDumpInterface.cpp
new file mode 100644
index 0000000..b4940cb
--- /dev/null
+++ b/libs/audioflinger/AudioDumpInterface.cpp
@@ -0,0 +1,117 @@
+/* //device/servers/AudioFlinger/AudioDumpInterface.cpp
+**
+** Copyright 2008, 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.
+*/
+
+#define LOG_TAG "AudioFlingerDump"
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Log.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "AudioDumpInterface.h"
+
+namespace android {
+
+bool gFirst = true;       // true if first write after a standby
+
+// ----------------------------------------------------------------------------
+
+AudioDumpInterface::AudioDumpInterface(AudioHardwareInterface* hw)
+{
+    if(hw == 0) {
+        LOGE("Dump construct hw = 0");
+    }
+    mFinalInterface = hw;
+    mStreamOut = 0;
+}
+
+
+AudioDumpInterface::~AudioDumpInterface()
+{
+    if(mFinalInterface) delete mFinalInterface;
+    if(mStreamOut) delete mStreamOut;
+}
+
+
+AudioStreamOut* AudioDumpInterface::openOutputStream(
+        int format, int channelCount, uint32_t sampleRate, status_t *status)
+{
+    AudioStreamOut* outFinal = mFinalInterface->openOutputStream(format, channelCount, sampleRate, status);
+
+    if(outFinal) {
+        mStreamOut =  new AudioStreamOutDump(outFinal);
+        return mStreamOut;
+    } else {
+        LOGE("Dump outFinal=0");
+        return 0;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+AudioStreamOutDump::AudioStreamOutDump( AudioStreamOut* finalStream)
+{
+    mFinalStream = finalStream;
+    mOutFile = 0;
+}
+
+
+AudioStreamOutDump::~AudioStreamOutDump()
+{
+    Close();
+    delete mFinalStream;
+}
+
+ssize_t AudioStreamOutDump::write(const void* buffer, size_t bytes)
+{
+    ssize_t ret;
+
+    ret = mFinalStream->write(buffer, bytes);
+    if(!mOutFile && gFirst) {
+        gFirst = false;
+        // check if dump file exist
+        mOutFile = fopen(FLINGER_DUMP_NAME, "r");
+        if(mOutFile) {
+            fclose(mOutFile);
+            mOutFile = fopen(FLINGER_DUMP_NAME, "ab");
+        }
+    }
+    if (mOutFile) {
+        fwrite(buffer, bytes, 1, mOutFile);
+    }
+    return ret;
+}
+
+status_t AudioStreamOutDump::standby()
+{
+    Close();
+    gFirst = true;
+    return mFinalStream->standby();
+}
+
+
+void AudioStreamOutDump::Close(void)
+{
+    if(mOutFile) {
+        fclose(mOutFile);
+        mOutFile = 0;
+    }
+}
+
+}; // namespace android
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
new file mode 100644
index 0000000..9a94102
--- /dev/null
+++ b/libs/audioflinger/AudioDumpInterface.h
@@ -0,0 +1,97 @@
+/* //device/servers/AudioFlinger/AudioDumpInterface.h
+**
+** Copyright 2008, 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_DUMP_INTERFACE_H
+#define ANDROID_AUDIO_DUMP_INTERFACE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <hardware_legacy/AudioHardwareBase.h>
+
+namespace android {
+
+#define FLINGER_DUMP_NAME "/data/FlingerOut.pcm" // name of file used for dump
+
+class AudioStreamOutDump : public AudioStreamOut {
+public:
+                        AudioStreamOutDump( AudioStreamOut* FinalStream);
+                        ~AudioStreamOutDump();
+                        virtual ssize_t     write(const void* buffer, size_t bytes);
+
+    virtual uint32_t    sampleRate() const { return mFinalStream->sampleRate(); }
+    virtual size_t      bufferSize() const { return mFinalStream->bufferSize(); }
+    virtual int         channelCount() const { return mFinalStream->channelCount(); }
+    virtual int         format() const { return mFinalStream->format(); }
+    virtual uint32_t    latency() const { return mFinalStream->latency(); }
+    virtual status_t    setVolume(float volume)
+                            { return mFinalStream->setVolume(volume); }
+    virtual status_t    standby();
+    virtual status_t    dump(int fd, const Vector<String16>& args) { return mFinalStream->dump(fd, args); }
+    void                Close(void);
+
+private:
+    AudioStreamOut      *mFinalStream;
+    FILE                *mOutFile;     // output file
+};
+
+
+class AudioDumpInterface : public AudioHardwareBase
+{
+
+public:
+                        AudioDumpInterface(AudioHardwareInterface* hw);
+    virtual AudioStreamOut* openOutputStream(
+                                int format=0,
+                                int channelCount=0,
+                                uint32_t sampleRate=0,
+                                status_t *status=0);
+    virtual             ~AudioDumpInterface();
+
+    virtual status_t    initCheck()
+                            {return mFinalInterface->initCheck();}
+    virtual status_t    setVoiceVolume(float volume)
+                            {return mFinalInterface->setVoiceVolume(volume);}
+    virtual status_t    setMasterVolume(float volume)
+                            {return mFinalInterface->setMasterVolume(volume);}
+
+    // mic mute
+    virtual status_t    setMicMute(bool state)
+                            {return mFinalInterface->setMicMute(state);}
+    virtual status_t    getMicMute(bool* state)
+                            {return mFinalInterface->getMicMute(state);}
+
+    virtual status_t    setParameter(const char* key, const char* value)
+                            {return mFinalInterface->setParameter(key, value);}
+
+    virtual AudioStreamIn* openInputStream( int format, int channelCount, uint32_t sampleRate, status_t *status,
+                                            AudioSystem::audio_in_acoustics acoustics)
+                            {return mFinalInterface->openInputStream( format, channelCount, sampleRate, status, acoustics);}
+
+    virtual status_t    dump(int fd, const Vector<String16>& args) { return mFinalInterface->dumpState(fd, args); }
+
+protected:
+    virtual status_t    doRouting() {return mFinalInterface->setRouting(mMode, mRoutes[mMode]);}
+
+    AudioHardwareInterface  *mFinalInterface;
+    AudioStreamOutDump      *mStreamOut;
+
+};
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_DUMP_INTERFACE_H
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
new file mode 100644
index 0000000..92c40e9
--- /dev/null
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -0,0 +1,2474 @@
+/* //device/include/server/AudioFlinger/AudioFlinger.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.
+*/
+
+
+#define LOG_TAG "AudioFlinger"
+//#define LOG_NDEBUG 0
+
+#include <math.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <utils/IServiceManager.h>
+#include <utils/Log.h>
+#include <utils/Parcel.h>
+#include <utils/IPCThreadState.h>
+#include <utils/String16.h>
+#include <utils/threads.h>
+
+#include <cutils/properties.h>
+
+#include <media/AudioTrack.h>
+#include <media/AudioRecord.h>
+
+#include <private/media/AudioTrackShared.h>
+
+#include <hardware_legacy/AudioHardwareInterface.h>
+
+#include "AudioMixer.h"
+#include "AudioFlinger.h"
+
+#ifdef WITH_A2DP
+#include "A2dpAudioInterface.h"
+#endif
+
+// ----------------------------------------------------------------------------
+// the sim build doesn't have gettid
+
+#ifndef HAVE_GETTID
+# define gettid getpid
+#endif
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
+static const unsigned long kBufferRecoveryInUsecs = 2000;
+static const unsigned long kMaxBufferRecoveryInUsecs = 20000;
+static const float MAX_GAIN = 4096.0f;
+
+// retry counts for buffer fill timeout
+// 50 * ~20msecs = 1 second
+static const int8_t kMaxTrackRetries = 50;
+static const int8_t kMaxTrackStartupRetries = 50;
+
+static const int kStartSleepTime = 30000;
+static const int kStopSleepTime = 30000;
+
+// Maximum number of pending buffers allocated by OutputTrack::write()
+static const uint8_t kMaxOutputTrackBuffers = 5;
+
+
+#define AUDIOFLINGER_SECURITY_ENABLED 1
+
+// ----------------------------------------------------------------------------
+
+static bool recordingAllowed() {
+#ifndef HAVE_ANDROID_OS
+    return true;
+#endif
+#if AUDIOFLINGER_SECURITY_ENABLED
+    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
+    bool ok = checkCallingPermission(String16("android.permission.RECORD_AUDIO"));
+    if (!ok) LOGE("Request requires android.permission.RECORD_AUDIO");
+    return ok;
+#else
+    if (!checkCallingPermission(String16("android.permission.RECORD_AUDIO")))
+        LOGW("WARNING: Need to add android.permission.RECORD_AUDIO to manifest");
+    return true;
+#endif
+}
+
+static bool settingsAllowed() {
+#ifndef HAVE_ANDROID_OS
+    return true;
+#endif
+#if AUDIOFLINGER_SECURITY_ENABLED
+    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
+    bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
+    if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
+    return ok;
+#else
+    if (!checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")))
+        LOGW("WARNING: Need to add android.permission.MODIFY_AUDIO_SETTINGS to manifest");
+    return true;
+#endif
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::AudioFlinger()
+    : BnAudioFlinger(),
+        mAudioHardware(0), mA2dpAudioInterface(0),
+        mA2dpEnabled(false), mA2dpEnabledReq(false),
+        mForcedSpeakerCount(0), mForcedRoute(0), mRouteRestoreTime(0), mMusicMuteSaved(false)
+{
+    mHardwareStatus = AUDIO_HW_IDLE;
+    mAudioHardware = AudioHardwareInterface::create();
+    mHardwareStatus = AUDIO_HW_INIT;
+    if (mAudioHardware->initCheck() == NO_ERROR) {
+        // open 16-bit output stream for s/w mixer
+        mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
+        status_t status;
+        AudioStreamOut *hwOutput = mAudioHardware->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
+        mHardwareStatus = AUDIO_HW_IDLE;
+        if (hwOutput) {
+            mHardwareMixerThread = new MixerThread(this, hwOutput, AudioSystem::AUDIO_OUTPUT_HARDWARE);
+        } else {
+            LOGE("Failed to initialize hardware output stream, status: %d", status);
+        }
+        
+#ifdef WITH_A2DP
+        // Create A2DP interface
+        mA2dpAudioInterface = new A2dpAudioInterface();
+        AudioStreamOut *a2dpOutput = mA2dpAudioInterface->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
+        if (a2dpOutput) {
+            mA2dpMixerThread = new MixerThread(this, a2dpOutput, AudioSystem::AUDIO_OUTPUT_A2DP);
+            if (hwOutput) {  
+                uint32_t frameCount = ((a2dpOutput->bufferSize()/a2dpOutput->frameSize()) * hwOutput->sampleRate()) / a2dpOutput->sampleRate();
+                MixerThread::OutputTrack *a2dpOutTrack = new MixerThread::OutputTrack(mA2dpMixerThread,
+                                                            hwOutput->sampleRate(),
+                                                            AudioSystem::PCM_16_BIT,
+                                                            hwOutput->channelCount(),
+                                                            frameCount);
+                mHardwareMixerThread->setOuputTrack(a2dpOutTrack);                
+            }
+        } else {
+            LOGE("Failed to initialize A2DP output stream, status: %d", status);
+        }
+#endif
+ 
+        // FIXME - this should come from settings
+        setRouting(AudioSystem::MODE_NORMAL, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
+        setRouting(AudioSystem::MODE_RINGTONE, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
+        setRouting(AudioSystem::MODE_IN_CALL, AudioSystem::ROUTE_EARPIECE, AudioSystem::ROUTE_ALL);
+        setMode(AudioSystem::MODE_NORMAL);
+
+        setMasterVolume(1.0f);
+        setMasterMute(false);
+
+        // Start record thread
+        mAudioRecordThread = new AudioRecordThread(mAudioHardware);
+        if (mAudioRecordThread != 0) {
+            mAudioRecordThread->run("AudioRecordThread", PRIORITY_URGENT_AUDIO);            
+        }
+     } else {
+        LOGE("Couldn't even initialize the stubbed audio hardware!");
+    }
+}
+
+AudioFlinger::~AudioFlinger()
+{
+    if (mAudioRecordThread != 0) {
+        mAudioRecordThread->exit();
+        mAudioRecordThread.clear();        
+    }
+    mHardwareMixerThread.clear();
+    delete mAudioHardware;
+    // deleting mA2dpAudioInterface also deletes mA2dpOutput;
+#ifdef WITH_A2DP
+    mA2dpMixerThread.clear();
+    delete mA2dpAudioInterface;
+#endif
+}
+
+
+#ifdef WITH_A2DP
+void AudioFlinger::setA2dpEnabled(bool enable)
+{
+    LOGV_IF(enable, "set output to A2DP\n");
+    LOGV_IF(!enable, "set output to hardware audio\n");
+
+    mA2dpEnabledReq = enable;
+    mA2dpMixerThread->wakeUp();
+}
+#endif // WITH_A2DP
+
+bool AudioFlinger::streamForcedToSpeaker(int streamType)
+{
+    // NOTE that streams listed here must not be routed to A2DP by default:
+    // AudioSystem::routedToA2dpOutput(streamType) == false
+    return (streamType == AudioSystem::RING ||
+            streamType == AudioSystem::ALARM ||
+            streamType == AudioSystem::NOTIFICATION);
+}
+
+status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    result.append("Clients:\n");
+    for (size_t i = 0; i < mClients.size(); ++i) {
+        wp<Client> wClient = mClients.valueAt(i);
+        if (wClient != 0) {
+            sp<Client> client = wClient.promote();
+            if (client != 0) {
+                snprintf(buffer, SIZE, "  pid: %d\n", client->pid());
+                result.append(buffer);
+            }
+        }
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+
+status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "Hardware status: %d\n", mHardwareStatus);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "Permission Denial: "
+            "can't dump AudioFlinger from pid=%d, uid=%d\n",
+            IPCThreadState::self()->getCallingPid(),
+            IPCThreadState::self()->getCallingUid());
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
+{
+    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+        dumpPermissionDenial(fd, args);
+    } else {
+        AutoMutex lock(&mLock);
+
+        dumpClients(fd, args);
+        dumpInternals(fd, args);
+        mHardwareMixerThread->dump(fd, args);
+#ifdef WITH_A2DP
+        mA2dpMixerThread->dump(fd, args);
+#endif
+
+        // dump record client
+        if (mAudioRecordThread != 0) mAudioRecordThread->dump(fd, args);
+
+        if (mAudioHardware) {
+            mAudioHardware->dumpState(fd, args);
+        }
+    }
+    return NO_ERROR;
+}
+
+// IAudioFlinger interface
+
+
+sp<IAudioTrack> AudioFlinger::createTrack(
+        pid_t pid,
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int frameCount,
+        uint32_t flags,
+        const sp<IMemory>& sharedBuffer,
+        status_t *status)
+{
+    sp<MixerThread::Track> track;
+    sp<TrackHandle> trackHandle;
+    sp<Client> client;
+    wp<Client> wclient;
+    status_t lStatus;
+
+    if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
+        LOGE("invalid stream type");
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
+    {
+        Mutex::Autolock _l(mLock);
+
+        wclient = mClients.valueFor(pid);
+
+        if (wclient != NULL) {
+            client = wclient.promote();
+        } else {
+            client = new Client(this, pid);
+            mClients.add(pid, client);
+        }
+#ifdef WITH_A2DP
+        if (isA2dpEnabled() && AudioSystem::routedToA2dpOutput(streamType)) {
+            track = mA2dpMixerThread->createTrack(client, streamType, sampleRate, format,
+                    channelCount, frameCount, sharedBuffer, &lStatus);            
+        } else 
+#endif
+        {
+            track = mHardwareMixerThread->createTrack(client, streamType, sampleRate, format,
+                    channelCount, frameCount, sharedBuffer, &lStatus);            
+        }
+        if (track != NULL) {
+            trackHandle = new TrackHandle(track);
+            lStatus = NO_ERROR;            
+        }
+    }
+
+Exit:
+    if(status) {
+        *status = lStatus;
+    }
+    return trackHandle;
+}
+
+uint32_t AudioFlinger::sampleRate(int output) const
+{
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->sampleRate();
+     }
+#endif
+     return mHardwareMixerThread->sampleRate();
+}
+
+int AudioFlinger::channelCount(int output) const
+{
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->channelCount();
+     }
+#endif
+     return mHardwareMixerThread->channelCount();
+}
+
+int AudioFlinger::format(int output) const
+{
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->format();
+     }
+#endif
+     return mHardwareMixerThread->format();
+}
+
+size_t AudioFlinger::frameCount(int output) const
+{
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->frameCount();
+     }
+#endif
+     return mHardwareMixerThread->frameCount();
+}
+
+uint32_t AudioFlinger::latency(int output) const
+{
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->latency();
+     }
+#endif
+     return mHardwareMixerThread->latency();
+}
+
+status_t AudioFlinger::setMasterVolume(float value)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    // when hw supports master volume, don't scale in sw mixer
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+    if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
+        value = 1.0f;
+    }
+    mHardwareStatus = AUDIO_HW_IDLE;
+    mHardwareMixerThread->setMasterVolume(value);
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setMasterVolume(value);
+#endif
+    
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
+{
+    status_t err = NO_ERROR;
+
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    if ((mode < AudioSystem::MODE_CURRENT) || (mode >= AudioSystem::NUM_MODES)) {
+        LOGW("Illegal value: setRouting(%d, %u, %u)", mode, routes, mask);
+        return BAD_VALUE;
+    }
+
+#ifdef WITH_A2DP
+    LOGD("setRouting %d %d %d, tid %d, calling tid %d\n", mode, routes, mask, gettid(), IPCThreadState::self()->getCallingPid());
+    if (mode == AudioSystem::MODE_NORMAL && 
+            (mask & AudioSystem::ROUTE_BLUETOOTH_A2DP)) {
+        AutoMutex lock(&mLock);
+
+        bool enableA2dp = false;
+        if (routes & AudioSystem::ROUTE_BLUETOOTH_A2DP) {
+            enableA2dp = true;
+        }
+        setA2dpEnabled(enableA2dp);
+        LOGV("setOutput done\n");
+    }
+#endif
+
+    // do nothing if only A2DP routing is affected
+    mask &= ~AudioSystem::ROUTE_BLUETOOTH_A2DP;
+    if (mask) {
+        AutoMutex lock(mHardwareLock);
+        mHardwareStatus = AUDIO_HW_GET_ROUTING;
+        uint32_t r;
+        err = mAudioHardware->getRouting(mode, &r);
+        if (err == NO_ERROR) {
+            r = (r & ~mask) | (routes & mask);
+            if (mode == AudioSystem::MODE_NORMAL || 
+                (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
+                mSavedRoute = r;
+                r |= mForcedRoute;
+                LOGV("setRouting mSavedRoute %08x mForcedRoute %08x\n", mSavedRoute, mForcedRoute);
+            }
+            mHardwareStatus = AUDIO_HW_SET_ROUTING;
+            err = mAudioHardware->setRouting(mode, r);
+        }
+        mHardwareStatus = AUDIO_HW_IDLE;
+    }
+    return err;
+}
+
+uint32_t AudioFlinger::getRouting(int mode) const
+{
+    uint32_t routes = 0;
+    if ((mode >= AudioSystem::MODE_CURRENT) && (mode < AudioSystem::NUM_MODES)) {
+        if (mode == AudioSystem::MODE_NORMAL || 
+            (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
+            routes = mSavedRoute;                
+        } else {
+            mHardwareStatus = AUDIO_HW_GET_ROUTING;
+            mAudioHardware->getRouting(mode, &routes);
+            mHardwareStatus = AUDIO_HW_IDLE;
+        }
+    } else {
+        LOGW("Illegal value: getRouting(%d)", mode);
+    }
+    return routes;
+}
+
+status_t AudioFlinger::setMode(int mode)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
+        LOGW("Illegal value: setMode(%d)", mode);
+        return BAD_VALUE;
+    }
+
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_HW_SET_MODE;
+    status_t ret = mAudioHardware->setMode(mode);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return ret;
+}
+
+int AudioFlinger::getMode() const
+{
+    int mode = AudioSystem::MODE_INVALID;
+    mHardwareStatus = AUDIO_HW_SET_MODE;
+    mAudioHardware->getMode(&mode);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return mode;
+}
+
+status_t AudioFlinger::setMicMute(bool state)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
+    status_t ret = mAudioHardware->setMicMute(state);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return ret;
+}
+
+bool AudioFlinger::getMicMute() const
+{
+    bool state = AudioSystem::MODE_INVALID;
+    mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
+    mAudioHardware->getMicMute(&state);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return state;
+}
+
+status_t AudioFlinger::setMasterMute(bool muted)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    mHardwareMixerThread->setMasterMute(muted);
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setMasterMute(muted);
+#endif
+    return NO_ERROR;
+}
+
+float AudioFlinger::masterVolume() const
+{
+    return mHardwareMixerThread->masterVolume();
+}
+
+bool AudioFlinger::masterMute() const
+{
+    return mHardwareMixerThread->masterMute();
+}
+
+status_t AudioFlinger::setStreamVolume(int stream, float value)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
+        return BAD_VALUE;
+    }
+
+    mHardwareMixerThread->setStreamVolume(stream, value);
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setStreamVolume(stream, value);
+#endif
+
+    status_t ret = NO_ERROR;
+    if (stream == AudioSystem::VOICE_CALL ||
+        stream == AudioSystem::BLUETOOTH_SCO) {
+        
+        if (stream == AudioSystem::VOICE_CALL) {
+            value = (float)AudioSystem::logToLinear(value)/100.0f;
+        } else { // (type == AudioSystem::BLUETOOTH_SCO)
+            value = 1.0f;
+        }
+
+        AutoMutex lock(mHardwareLock);
+        mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
+        ret = mAudioHardware->setVoiceVolume(value);
+        mHardwareStatus = AUDIO_HW_IDLE;
+    }
+
+    return ret;
+}
+
+status_t AudioFlinger::setStreamMute(int stream, bool muted)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
+        return BAD_VALUE;
+    }
+    
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setStreamMute(stream, muted);
+#endif
+    if (stream == AudioSystem::MUSIC) 
+    {
+        AutoMutex lock(&mHardwareLock);
+        if (mForcedRoute != 0)
+            mMusicMuteSaved = muted;
+        else
+            mHardwareMixerThread->setStreamMute(stream, muted);
+    } else {
+        mHardwareMixerThread->setStreamMute(stream, muted);
+    }
+
+    
+
+    return NO_ERROR;
+}
+
+float AudioFlinger::streamVolume(int stream) const
+{
+    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
+        return 0.0f;
+    }
+    return mHardwareMixerThread->streamVolume(stream);
+}
+
+bool AudioFlinger::streamMute(int stream) const
+{
+    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
+        return true;
+    }
+    
+    if (stream == AudioSystem::MUSIC && mForcedRoute != 0) 
+    {
+        return mMusicMuteSaved;
+    }
+    return mHardwareMixerThread->streamMute(stream);
+}
+
+bool AudioFlinger::isMusicActive() const
+{
+ #ifdef WITH_A2DP
+     if (isA2dpEnabled()) {
+         return mA2dpMixerThread->isMusicActive();
+     }
+ #endif
+    return mHardwareMixerThread->isMusicActive();
+}
+
+status_t AudioFlinger::setParameter(const char* key, const char* value)
+{
+    status_t result, result2;
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_SET_PARAMETER;
+    
+    LOGV("setParameter() key %s, value %s, tid %d, calling tid %d", key, value, gettid(), IPCThreadState::self()->getCallingPid());
+    result = mAudioHardware->setParameter(key, value);
+    if (mA2dpAudioInterface) {
+        result2 = mA2dpAudioInterface->setParameter(key, value);
+        if (result2)
+            result = result2;
+    }
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return result;
+}
+
+size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
+{
+    return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
+}
+
+void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
+{
+    
+    LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mLock);
+
+    sp<IBinder> binder = client->asBinder();
+    if (mNotificationClients.indexOf(binder) < 0) {
+        LOGV("Adding notification client %p", binder.get());
+        binder->linkToDeath(this);
+        mNotificationClients.add(binder);
+        client->a2dpEnabledChanged(isA2dpEnabled());
+    }
+}
+
+void AudioFlinger::binderDied(const wp<IBinder>& who) {
+    
+    LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mLock);
+
+    IBinder *binder = who.unsafe_get();
+
+    if (binder != NULL) {
+        int index = mNotificationClients.indexOf(binder);
+        if (index >= 0) {
+            LOGV("Removing notification client %p", binder);
+            mNotificationClients.removeAt(index);
+        }
+    }
+}
+
+void AudioFlinger::handleOutputSwitch()
+{
+    if (mA2dpEnabled != mA2dpEnabledReq)
+    {
+        Mutex::Autolock _l(mLock);
+
+        if (mA2dpEnabled != mA2dpEnabledReq)
+        {
+            mA2dpEnabled = mA2dpEnabledReq;
+            SortedVector < sp<MixerThread::Track> > tracks;
+            SortedVector < wp<MixerThread::Track> > activeTracks;
+            
+            // We hold mA2dpMixerThread mLock already 
+            Mutex::Autolock _l(mHardwareMixerThread->mLock);
+            
+            // Transfer tracks playing on MUSIC stream from one mixer to the other
+            if (mA2dpEnabled) {
+                mHardwareMixerThread->getTracks(tracks, activeTracks);
+                mA2dpMixerThread->putTracks(tracks, activeTracks);
+            } else {
+                mA2dpMixerThread->getTracks(tracks, activeTracks);
+                mHardwareMixerThread->putTracks(tracks, activeTracks);
+            }            
+            
+            // Notify AudioSystem of the A2DP activation/deactivation
+            size_t size = mNotificationClients.size();
+            for (size_t i = 0; i < size; i++) {
+                sp<IBinder> binder = mNotificationClients.itemAt(i).promote();
+                if (binder != NULL) {
+                    LOGV("Notifying output change to client %p", binder.get());
+                    sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
+                    client->a2dpEnabledChanged(mA2dpEnabled);
+                }
+            }
+
+            mHardwareMixerThread->wakeUp();
+        }
+    }
+}
+
+void AudioFlinger::removeClient(pid_t pid)
+{
+    LOGV("removeClient() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mLock);
+    mClients.removeItem(pid);
+}
+
+void AudioFlinger::wakeUp()
+{
+    mHardwareMixerThread->wakeUp();
+#ifdef WITH_A2DP
+    mA2dpMixerThread->wakeUp();
+#endif // WITH_A2DP
+}
+
+bool AudioFlinger::isA2dpEnabled() const
+{
+    return mA2dpEnabledReq;
+}
+
+void AudioFlinger::handleForcedSpeakerRoute(int command)
+{
+    switch(command) {
+    case ACTIVE_TRACK_ADDED:
+        {
+            AutoMutex lock(mHardwareLock);
+            if (mForcedSpeakerCount++ == 0) {
+                mRouteRestoreTime = 0;
+                mMusicMuteSaved = mHardwareMixerThread->streamMute(AudioSystem::MUSIC);
+                if (mForcedRoute == 0 && !(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
+                    LOGV("Route forced to Speaker ON %08x", mSavedRoute | AudioSystem::ROUTE_SPEAKER);
+                    mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, true);
+                    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+                    mAudioHardware->setMasterVolume(0);
+                    usleep(mHardwareMixerThread->latency()*1000);
+                    mHardwareStatus = AUDIO_HW_SET_ROUTING;
+                    mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute | AudioSystem::ROUTE_SPEAKER);
+                    mHardwareStatus = AUDIO_HW_IDLE;
+                    // delay track start so that audio hardware has time to siwtch routes
+                    usleep(kStartSleepTime);
+                    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+                    mAudioHardware->setMasterVolume(mHardwareMixerThread->masterVolume());
+                    mHardwareStatus = AUDIO_HW_IDLE;
+                }
+                mForcedRoute = AudioSystem::ROUTE_SPEAKER;
+            }
+            LOGV("mForcedSpeakerCount incremented to %d", mForcedSpeakerCount);
+        }
+        break;
+    case ACTIVE_TRACK_REMOVED:
+        {
+            AutoMutex lock(mHardwareLock);
+            if (mForcedSpeakerCount > 0){
+                if (--mForcedSpeakerCount == 0) {
+                    mRouteRestoreTime = systemTime() + milliseconds(kStopSleepTime/1000);
+                }
+                LOGV("mForcedSpeakerCount decremented to %d", mForcedSpeakerCount);            
+            } else {
+                LOGE("mForcedSpeakerCount is already zero");            
+            }            
+        }
+        break;
+    case CHECK_ROUTE_RESTORE_TIME:
+    case FORCE_ROUTE_RESTORE:
+        if (mRouteRestoreTime) {
+            AutoMutex lock(mHardwareLock);
+            if (mRouteRestoreTime && 
+               (systemTime() > mRouteRestoreTime || command == FORCE_ROUTE_RESTORE)) {
+                mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, mMusicMuteSaved);
+                mForcedRoute = 0;
+                if (!(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
+                    mHardwareStatus = AUDIO_HW_SET_ROUTING;
+                    mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute);
+                    mHardwareStatus = AUDIO_HW_IDLE;
+                    LOGV("Route forced to Speaker OFF %08x", mSavedRoute);
+                }
+                mRouteRestoreTime = 0;
+            }
+        }
+        break;
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType)
+    :   Thread(false),
+        mAudioFlinger(audioFlinger), mAudioMixer(0), mOutput(output), mOutputType(outputType), 
+        mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
+        mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
+        mInWrite(false)
+{
+    mSampleRate = output->sampleRate();
+    mChannelCount = output->channelCount();
+
+    // FIXME - Current mixer implementation only supports stereo output
+    if (mChannelCount == 1) {
+        LOGE("Invalid audio hardware channel count");
+    }
+
+    mFormat = output->format();
+    mFrameCount = output->bufferSize() / output->channelCount() / sizeof(int16_t);
+    mAudioMixer = new AudioMixer(mFrameCount, output->sampleRate());
+
+    // FIXME - Current mixer implementation only supports stereo output: Always
+    // Allocate a stereo buffer even if HW output is mono.
+    mMixBuffer = new int16_t[mFrameCount * 2];
+    memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
+}
+
+AudioFlinger::MixerThread::~MixerThread()
+{
+    delete [] mMixBuffer;
+    delete mAudioMixer;
+}
+
+status_t AudioFlinger::MixerThread::dump(int fd, const Vector<String16>& args)
+{
+    dumpInternals(fd, args);
+    dumpTracks(fd, args);
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::MixerThread::dumpTracks(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "Output %d mixer thread tracks\n", mOutputType);
+    result.append(buffer);
+    result.append("   Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
+    for (size_t i = 0; i < mTracks.size(); ++i) {
+        wp<Track> wTrack = mTracks[i];
+        if (wTrack != 0) {
+            sp<Track> track = wTrack.promote();
+            if (track != 0) {
+                track->dump(buffer, SIZE);
+                result.append(buffer);
+            }
+        }
+    }
+
+    snprintf(buffer, SIZE, "Output %d mixer thread active tracks\n", mOutputType);
+    result.append(buffer);
+    result.append("   Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
+    for (size_t i = 0; i < mActiveTracks.size(); ++i) {
+        wp<Track> wTrack = mTracks[i];
+        if (wTrack != 0) {
+            sp<Track> track = wTrack.promote();
+            if (track != 0) {
+                track->dump(buffer, SIZE);
+                result.append(buffer);
+            }
+        }
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "Output %d mixer thread internals\n", mOutputType);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
+    result.append(buffer);
+    snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "standby: %d\n", mStandby);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+// Thread virtuals
+bool AudioFlinger::MixerThread::threadLoop()
+{
+    unsigned long sleepTime = kBufferRecoveryInUsecs;
+    int16_t* curBuf = mMixBuffer;
+    Vector< sp<Track> > tracksToRemove;
+    size_t enabledTracks = 0;
+    nsecs_t standbyTime = systemTime();   
+    size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
+    nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;
+
+#ifdef WITH_A2DP
+    bool outputTrackActive = false;
+#endif
+
+    do {
+        enabledTracks = 0;
+        { // scope for the mLock
+        
+            Mutex::Autolock _l(mLock);
+
+#ifdef WITH_A2DP
+            if (mOutputType == AudioSystem::AUDIO_OUTPUT_A2DP) {
+                mAudioFlinger->handleOutputSwitch();
+            }
+            if (mOutputTrack != NULL && !mAudioFlinger->isA2dpEnabled()) {
+                if (outputTrackActive) {
+                    mOutputTrack->stop();
+                    outputTrackActive = false;
+                }
+            }
+#endif
+
+            const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
+
+            // put audio hardware into standby after short delay
+            if UNLIKELY(!activeTracks.size() && systemTime() > standbyTime) {
+                // wait until we have something to do...
+                LOGV("Audio hardware entering standby, output %d\n", mOutputType);
+//                mAudioFlinger->mHardwareStatus = AUDIO_HW_STANDBY;
+                if (!mStandby) {
+                    mOutput->standby();
+                    mStandby = true;
+                }
+                
+#ifdef WITH_A2DP
+                if (outputTrackActive) {
+                    mOutputTrack->stop();
+                    outputTrackActive = false;
+                }
+#endif
+                if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
+                    mAudioFlinger->handleForcedSpeakerRoute(FORCE_ROUTE_RESTORE);
+                }                
+//                mHardwareStatus = AUDIO_HW_IDLE;
+                // we're about to wait, flush the binder command buffer
+                IPCThreadState::self()->flushCommands();
+                mWaitWorkCV.wait(mLock);
+                LOGV("Audio hardware exiting standby, output %d\n", mOutputType);
+                
+                if (mMasterMute == false) {
+                    char value[PROPERTY_VALUE_MAX];
+                    property_get("ro.audio.silent", value, "0");
+                    if (atoi(value)) {
+                        LOGD("Silence is golden");
+                        setMasterMute(true);
+                    }                    
+                }
+                
+                standbyTime = systemTime() + kStandbyTimeInNsecs;
+                continue;
+            }
+
+            // Forced route to speaker is handled by hardware mixer thread
+            if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
+                mAudioFlinger->handleForcedSpeakerRoute(CHECK_ROUTE_RESTORE_TIME);
+            }
+
+            // find out which tracks need to be processed
+            size_t count = activeTracks.size();
+            for (size_t i=0 ; i<count ; i++) {
+                sp<Track> t = activeTracks[i].promote();
+                if (t == 0) continue;
+
+                Track* const track = t.get();
+                audio_track_cblk_t* cblk = track->cblk();
+
+                // The first time a track is added we wait
+                // for all its buffers to be filled before processing it
+                mAudioMixer->setActiveTrack(track->name());
+                if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
+                        !track->isPaused())
+                {
+                    //LOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
+
+                    // compute volume for this track
+                    int16_t left, right;
+                    if (track->isMuted() || mMasterMute || track->isPausing()) {
+                        left = right = 0;
+                        if (track->isPausing()) {
+                            LOGV("paused(%d)", track->name());
+                            track->setPaused();
+                        }
+                    } else {
+                        float typeVolume = mStreamTypes[track->type()].volume;
+                        float v = mMasterVolume * typeVolume;
+                        float v_clamped = v * cblk->volume[0];
+                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
+                        left = int16_t(v_clamped);
+                        v_clamped = v * cblk->volume[1];
+                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
+                        right = int16_t(v_clamped);
+                    }
+
+                    // XXX: these things DON'T need to be done each time
+                    mAudioMixer->setBufferProvider(track);
+                    mAudioMixer->enable(AudioMixer::MIXING);
+
+                    int param;
+                    if ( track->mFillingUpStatus == Track::FS_FILLED) {
+                        // no ramp for the first volume setting
+                        track->mFillingUpStatus = Track::FS_ACTIVE;
+                        if (track->mState == TrackBase::RESUMING) {
+                            track->mState = TrackBase::ACTIVE;
+                            param = AudioMixer::RAMP_VOLUME;
+                        } else {
+                            param = AudioMixer::VOLUME;
+                        }
+                    } else {
+                        param = AudioMixer::RAMP_VOLUME;
+                    }
+                    mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
+                    mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
+                    mAudioMixer->setParameter(
+                        AudioMixer::TRACK,
+                        AudioMixer::FORMAT, track->format());
+                    mAudioMixer->setParameter(
+                        AudioMixer::TRACK,
+                        AudioMixer::CHANNEL_COUNT, track->channelCount());
+                    mAudioMixer->setParameter(
+                        AudioMixer::RESAMPLE,
+                        AudioMixer::SAMPLE_RATE,
+                        int(cblk->sampleRate));
+
+                    // reset retry count
+                    track->mRetryCount = kMaxTrackRetries;
+                    enabledTracks++;
+                } else {
+                    //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
+                    if (track->isStopped()) {
+                        track->reset();
+                    }
+                    if (track->isTerminated() || track->isStopped() || track->isPaused()) {
+                        // We have consumed all the buffers of this track.
+                        // Remove it from the list of active tracks.
+                        LOGV("remove(%d) from active list", track->name());
+                        tracksToRemove.add(track);
+                    } else {
+                        // No buffers for this track. Give it a few chances to
+                        // fill a buffer, then remove it from active list.
+                        if (--(track->mRetryCount) <= 0) {
+                            LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
+                            tracksToRemove.add(track);
+                        }
+                    }
+                    // LOGV("disable(%d)", track->name());
+                    mAudioMixer->disable(AudioMixer::MIXING);
+                }
+            }
+
+            // remove all the tracks that need to be...
+            count = tracksToRemove.size();
+            if (UNLIKELY(count)) {
+                for (size_t i=0 ; i<count ; i++) {
+                    const sp<Track>& track = tracksToRemove[i];
+                    removeActiveTrack(track);
+                    if (track->isTerminated()) {
+                        mTracks.remove(track);
+                        deleteTrackName(track->mName);
+                    }
+                }
+            }  
+       }
+        
+        if (LIKELY(enabledTracks)) {
+            // mix buffers...
+            mAudioMixer->process(curBuf);
+
+#ifdef WITH_A2DP
+            if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
+                if (!outputTrackActive) {
+                    LOGV("starting output track in mixer for output %d", mOutputType);
+                    mOutputTrack->start();
+                    outputTrackActive = true;
+                }
+                mOutputTrack->write(curBuf, mFrameCount);
+            }
+#endif
+
+            // output audio to hardware
+            mLastWriteTime = systemTime();
+            mInWrite = true;
+            mOutput->write(curBuf, mixBufferSize);
+            mNumWrites++;
+            mInWrite = false;
+            mStandby = false;
+            nsecs_t temp = systemTime();
+            standbyTime = temp + kStandbyTimeInNsecs;
+            nsecs_t delta = temp - mLastWriteTime;
+            if (delta > maxPeriod) {
+                LOGW("write blocked for %llu msecs", ns2ms(delta));
+                mNumDelayedWrites++;
+            }
+            sleepTime = kBufferRecoveryInUsecs;
+        } else {         
+#ifdef WITH_A2DP
+            if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
+                if (outputTrackActive) {
+                    mOutputTrack->write(curBuf, 0);
+                    if (mOutputTrack->bufferQueueEmpty()) {
+                        mOutputTrack->stop();
+                        outputTrackActive = false;
+                    } else {
+                        standbyTime = systemTime() + kStandbyTimeInNsecs;
+                    }
+                }
+            }
+#endif
+            // There was nothing to mix this round, which means all
+            // active tracks were late. Sleep a little bit to give
+            // them another chance. If we're too late, the audio
+            // hardware will zero-fill for us.
+            //LOGV("no buffers - usleep(%lu)", sleepTime);
+            usleep(sleepTime);
+            if (sleepTime < kMaxBufferRecoveryInUsecs) {
+                sleepTime += kBufferRecoveryInUsecs;
+            }
+        }
+
+        // finally let go of all our tracks, without the lock held
+        // since we can't guarantee the destructors won't acquire that
+        // same lock.
+        tracksToRemove.clear();
+    } while (true);
+
+    return false;
+}
+
+status_t AudioFlinger::MixerThread::readyToRun()
+{
+    if (mSampleRate == 0) {
+        LOGE("No working audio driver found.");
+        return NO_INIT;
+    }
+    LOGI("AudioFlinger's thread ready to run for output %d", mOutputType);
+    return NO_ERROR;
+}
+
+void AudioFlinger::MixerThread::onFirstRef()
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+
+    snprintf(buffer, SIZE, "Mixer Thread for output %d", mOutputType);
+
+    run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
+}
+
+
+sp<AudioFlinger::MixerThread::Track>  AudioFlinger::MixerThread::createTrack(
+        const sp<AudioFlinger::Client>& client,
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int frameCount,
+        const sp<IMemory>& sharedBuffer,
+        status_t *status)
+{
+    sp<Track> track;
+    status_t lStatus;
+    
+    // Resampler implementation limits input sampling rate to 2 x output sampling rate.
+    if (sampleRate > MAX_SAMPLE_RATE || sampleRate > mSampleRate*2) {
+        LOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
+    {
+        Mutex::Autolock _l(mLock);
+
+        if (mSampleRate == 0) {
+            LOGE("Audio driver not initialized.");
+            lStatus = NO_INIT;
+            goto Exit;
+        }
+
+        track = new Track(this, client, streamType, sampleRate, format,
+                channelCount, frameCount, sharedBuffer);
+        if (track->getCblk() == NULL) {
+            track.clear();
+            lStatus = NO_MEMORY;
+            goto Exit;
+        }
+        mTracks.add(track);
+        lStatus = NO_ERROR;
+    }
+
+Exit:
+    if(status) {
+        *status = lStatus;
+    }
+    return track;
+}
+
+void AudioFlinger::MixerThread::getTracks(
+        SortedVector < sp<Track> >& tracks,
+        SortedVector < wp<Track> >& activeTracks)
+{
+    size_t size = mTracks.size();
+    LOGV ("MixerThread::getTracks() for output %d, mTracks.size %d, mActiveTracks.size %d", mOutputType,  mTracks.size(), mActiveTracks.size());
+    for (size_t i = 0; i < size; i++) {
+        sp<Track> t = mTracks[i];
+        if (AudioSystem::routedToA2dpOutput(t->mStreamType)) {
+            tracks.add(t);
+            int j = mActiveTracks.indexOf(t);
+            if (j >= 0) {
+                t = mActiveTracks[j].promote();
+                if (t != NULL) {
+                    activeTracks.add(t);                                    
+                }                            
+            }
+        }
+    }
+
+    size = activeTracks.size();
+    for (size_t i = 0; i < size; i++) {
+        removeActiveTrack(activeTracks[i]);
+    }
+    
+    size = tracks.size();
+    for (size_t i = 0; i < size; i++) {
+        sp<Track> t = tracks[i];
+        mTracks.remove(t);
+        deleteTrackName(t->name());
+    }
+}
+
+void AudioFlinger::MixerThread::putTracks(
+        SortedVector < sp<Track> >& tracks,
+        SortedVector < wp<Track> >& activeTracks)
+{
+
+    LOGV ("MixerThread::putTracks() for output %d, tracks.size %d, activeTracks.size %d", mOutputType,  tracks.size(), activeTracks.size());
+
+    size_t size = tracks.size();
+    for (size_t i = 0; i < size ; i++) {
+        sp<Track> t = tracks[i];
+        int name = getTrackName();
+
+        if (name < 0) return;
+        
+        t->mName = name;
+        t->mMixerThread = this;
+        mTracks.add(t);
+
+        int j = activeTracks.indexOf(t);
+        if (j >= 0) {
+            addActiveTrack(t);
+        }            
+    }
+}
+
+uint32_t AudioFlinger::MixerThread::sampleRate() const
+{
+    return mSampleRate;
+}
+
+int AudioFlinger::MixerThread::channelCount() const
+{
+    return mChannelCount;
+}
+
+int AudioFlinger::MixerThread::format() const
+{
+    return mFormat;
+}
+
+size_t AudioFlinger::MixerThread::frameCount() const
+{
+    return mFrameCount;
+}
+
+uint32_t AudioFlinger::MixerThread::latency() const
+{
+    if (mOutput) {
+        return mOutput->latency();
+    }
+    else {
+        return 0;
+    }
+}
+
+status_t AudioFlinger::MixerThread::setMasterVolume(float value)
+{
+    mMasterVolume = value;
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::MixerThread::setMasterMute(bool muted)
+{
+    mMasterMute = muted;
+    return NO_ERROR;
+}
+
+float AudioFlinger::MixerThread::masterVolume() const
+{
+    return mMasterVolume;
+}
+
+bool AudioFlinger::MixerThread::masterMute() const
+{
+    return mMasterMute;
+}
+
+status_t AudioFlinger::MixerThread::setStreamVolume(int stream, float value)
+{
+    mStreamTypes[stream].volume = value;
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::MixerThread::setStreamMute(int stream, bool muted)
+{
+    mStreamTypes[stream].mute = muted;
+    return NO_ERROR;
+}
+
+float AudioFlinger::MixerThread::streamVolume(int stream) const
+{
+    return mStreamTypes[stream].volume;
+}
+
+bool AudioFlinger::MixerThread::streamMute(int stream) const
+{
+    return mStreamTypes[stream].mute;
+}
+
+bool AudioFlinger::MixerThread::isMusicActive() const
+{
+    size_t count = mActiveTracks.size();
+    for (size_t i = 0 ; i < count ; ++i) {
+        sp<Track> t = mActiveTracks[i].promote();
+        if (t == 0) continue;
+        Track* const track = t.get();
+        if (t->mStreamType == AudioSystem::MUSIC)
+            return true;
+    }
+    return false;
+}
+
+status_t AudioFlinger::MixerThread::addTrack(const sp<Track>& track)
+{
+    status_t status = ALREADY_EXISTS;
+    Mutex::Autolock _l(mLock);
+
+    // here the track could be either new, or restarted
+    // in both cases "unstop" the track
+    if (track->isPaused()) {
+        track->mState = TrackBase::RESUMING;
+        LOGV("PAUSED => RESUMING (%d)", track->name());
+    } else {
+        track->mState = TrackBase::ACTIVE;
+        LOGV("? => ACTIVE (%d)", track->name());
+    }
+    // set retry count for buffer fill
+    track->mRetryCount = kMaxTrackStartupRetries;
+    if (mActiveTracks.indexOf(track) < 0) {
+        // the track is newly added, make sure it fills up all its
+        // buffers before playing. This is to ensure the client will
+        // effectively get the latency it requested.
+        track->mFillingUpStatus = Track::FS_FILLING;
+        track->mResetDone = false;
+        addActiveTrack(track);
+        status = NO_ERROR;
+    }
+    
+    LOGV("mWaitWorkCV.broadcast");
+    mWaitWorkCV.broadcast();
+
+    return status;
+}
+
+void AudioFlinger::MixerThread::removeTrack(wp<Track> track, int name)
+{
+    Mutex::Autolock _l(mLock);
+    sp<Track> t = track.promote();
+    if (t!=NULL && (t->mState <= TrackBase::STOPPED)) {
+        remove_track_l(track, name);
+    }
+}
+
+void AudioFlinger::MixerThread::remove_track_l(wp<Track> track, int name)
+{
+    sp<Track> t = track.promote();
+    if (t!=NULL) {
+        t->reset();
+    }
+    deleteTrackName(name);
+    removeActiveTrack(track);
+    mWaitWorkCV.broadcast();
+}
+
+void AudioFlinger::MixerThread::destroyTrack(const sp<Track>& track)
+{
+    // NOTE: We're acquiring a strong reference on the track before
+    // acquiring the lock, this is to make sure removing it from
+    // mTracks won't cause the destructor to be called while the lock is
+    // held (note that technically, 'track' could be a reference to an item
+    // in mTracks, which is why we need to do this).
+    sp<Track> keep(track);
+    Mutex::Autolock _l(mLock);
+    track->mState = TrackBase::TERMINATED;
+    if (mActiveTracks.indexOf(track) < 0) {
+        LOGV("remove track (%d) and delete from mixer", track->name());
+        mTracks.remove(track);
+        deleteTrackName(keep->name());
+    }
+}
+
+
+void AudioFlinger::MixerThread::addActiveTrack(const wp<Track>& t)
+{
+    mActiveTracks.add(t);
+
+    // Force routing to speaker for certain stream types
+    // The forced routing to speaker is managed by hardware mixer
+    if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
+        sp<Track> track = t.promote();
+        if (track == NULL) return;
+   
+        if (streamForcedToSpeaker(track->type())) {
+            mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_ADDED);
+        }        
+    }
+}
+
+void AudioFlinger::MixerThread::removeActiveTrack(const wp<Track>& t)
+{
+    mActiveTracks.remove(t);
+
+    // Force routing to speaker for certain stream types
+    // The forced routing to speaker is managed by hardware mixer
+    if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
+        sp<Track> track = t.promote();
+        if (track == NULL) return;
+
+        if (streamForcedToSpeaker(track->type())) {
+            mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_REMOVED);
+        }
+    }
+}
+
+int AudioFlinger::MixerThread::getTrackName()
+{
+    return mAudioMixer->getTrackName();
+}
+
+void AudioFlinger::MixerThread::deleteTrackName(int name)
+{
+    mAudioMixer->deleteTrackName(name);
+}
+
+size_t AudioFlinger::MixerThread::getOutputFrameCount() 
+{
+    return mOutput->bufferSize() / mOutput->channelCount() / sizeof(int16_t);
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::TrackBase::TrackBase(
+            const sp<MixerThread>& mixerThread,
+            const sp<Client>& client,
+            int streamType,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount,
+            uint32_t flags,
+            const sp<IMemory>& sharedBuffer)
+    :   RefBase(),
+        mMixerThread(mixerThread),
+        mClient(client),
+        mStreamType(streamType),
+        mFrameCount(0),
+        mState(IDLE),
+        mClientTid(-1),
+        mFormat(format),
+        mFlags(flags & ~SYSTEM_FLAGS_MASK)
+{
+    mName = mixerThread->getTrackName();
+    LOGV("TrackBase contructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
+    if (mName < 0) {
+        LOGE("no more track names availlable");
+        return;
+    }
+
+    LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
+
+    // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
+   size_t size = sizeof(audio_track_cblk_t);
+   size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
+   if (sharedBuffer == 0) {
+       size += bufferSize;
+   }
+
+   if (client != NULL) {
+        mCblkMemory = client->heap()->allocate(size);
+        if (mCblkMemory != 0) {
+            mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
+            if (mCblk) { // construct the shared structure in-place.
+                new(mCblk) audio_track_cblk_t();
+                // clear all buffers
+                mCblk->frameCount = frameCount;
+                mCblk->sampleRate = sampleRate;
+                mCblk->channels = channelCount;
+                if (sharedBuffer == 0) {
+                    mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
+                    memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
+                    // Force underrun condition to avoid false underrun callback until first data is
+                    // written to buffer
+                    mCblk->flowControlFlag = 1;
+                } else {
+                    mBuffer = sharedBuffer->pointer();
+                }
+                mBufferEnd = (uint8_t *)mBuffer + bufferSize;
+            }
+        } else {
+            LOGE("not enough memory for AudioTrack size=%u", size);
+            client->heap()->dump("AudioTrack");
+            return;
+        }
+   } else {
+       mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
+       if (mCblk) { // construct the shared structure in-place.
+           new(mCblk) audio_track_cblk_t();
+           // clear all buffers
+           mCblk->frameCount = frameCount;
+           mCblk->sampleRate = sampleRate;
+           mCblk->channels = channelCount;
+           mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
+           memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
+           // Force underrun condition to avoid false underrun callback until first data is
+           // written to buffer
+           mCblk->flowControlFlag = 1;
+           mBufferEnd = (uint8_t *)mBuffer + bufferSize;
+       }
+   }
+}
+
+AudioFlinger::MixerThread::TrackBase::~TrackBase()
+{
+    if (mCblk) {
+        mCblk->~audio_track_cblk_t();   // destroy our shared-structure.        
+    }
+    mCblkMemory.clear();            // and free the shared memory
+    mClient.clear();
+}
+
+void AudioFlinger::MixerThread::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    buffer->raw = 0;
+    mFrameCount = buffer->frameCount;
+    step();
+    buffer->frameCount = 0;
+}
+
+bool AudioFlinger::MixerThread::TrackBase::step() {
+    bool result;
+    audio_track_cblk_t* cblk = this->cblk();
+
+    result = cblk->stepServer(mFrameCount);
+    if (!result) {
+        LOGV("stepServer failed acquiring cblk mutex");
+        mFlags |= STEPSERVER_FAILED;
+    }
+    return result;
+}
+
+void AudioFlinger::MixerThread::TrackBase::reset() {
+    audio_track_cblk_t* cblk = this->cblk();
+
+    cblk->user = 0;
+    cblk->server = 0;
+    cblk->userBase = 0;
+    cblk->serverBase = 0;
+    mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
+    LOGV("TrackBase::reset");
+}
+
+sp<IMemory> AudioFlinger::MixerThread::TrackBase::getCblk() const
+{
+    return mCblkMemory;
+}
+
+int AudioFlinger::MixerThread::TrackBase::sampleRate() const {
+    return mCblk->sampleRate;
+}
+
+int AudioFlinger::MixerThread::TrackBase::channelCount() const {
+    return mCblk->channels;
+}
+
+void* AudioFlinger::MixerThread::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
+    audio_track_cblk_t* cblk = this->cblk();
+    int16_t *bufferStart = (int16_t *)mBuffer + (offset-cblk->serverBase)*cblk->channels;
+    int16_t *bufferEnd = bufferStart + frames * cblk->channels;
+
+    // Check validity of returned pointer in case the track control block would have been corrupted.
+    if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd) {
+        LOGW("TrackBase::getBuffer buffer out of range:\n    start: %p, end %p , mBuffer %p mBufferEnd %p\n    \
+                server %d, serverBase %d, user %d, userBase %d",
+                bufferStart, bufferEnd, mBuffer, mBufferEnd,
+                cblk->server, cblk->serverBase, cblk->user, cblk->userBase);
+        return 0;
+    }
+
+    return bufferStart;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::Track::Track(
+            const sp<MixerThread>& mixerThread,
+            const sp<Client>& client,
+            int streamType,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount,
+            const sp<IMemory>& sharedBuffer)
+    :   TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, 0, sharedBuffer)
+{
+    mVolume[0] = 1.0f;
+    mVolume[1] = 1.0f;
+    mMute = false;
+    mSharedBuffer = sharedBuffer;
+}
+
+AudioFlinger::MixerThread::Track::~Track()
+{
+    wp<Track> weak(this); // never create a strong ref from the dtor
+    mState = TERMINATED;
+    mMixerThread->removeTrack(weak, mName);
+}
+
+void AudioFlinger::MixerThread::Track::destroy()
+{
+    mMixerThread->destroyTrack(this);
+}
+
+void AudioFlinger::MixerThread::Track::dump(char* buffer, size_t size)
+{
+    snprintf(buffer, size, "  %5d %5d %3u %3u %3u %3u %1d %1d %1d %5u %5u %5u %04x %04x\n",
+            mName - AudioMixer::TRACK0,
+            (mClient == NULL) ? getpid() : mClient->pid(),
+            mStreamType,
+            mFormat,
+            mCblk->channels,
+            mFrameCount,
+            mState,
+            mMute,
+            mFillingUpStatus,
+            mCblk->sampleRate,
+            mCblk->volume[0],
+            mCblk->volume[1],
+            mCblk->server,
+            mCblk->user);
+}
+
+status_t AudioFlinger::MixerThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+{
+     audio_track_cblk_t* cblk = this->cblk();
+     uint32_t framesReady;
+     uint32_t framesReq = buffer->frameCount;
+
+     // Check if last stepServer failed, try to step now
+     if (mFlags & TrackBase::STEPSERVER_FAILED) {
+         if (!step())  goto getNextBuffer_exit;
+         LOGV("stepServer recovered");
+         mFlags &= ~TrackBase::STEPSERVER_FAILED;
+     }
+
+     framesReady = cblk->framesReady();
+
+     if (LIKELY(framesReady)) {
+        uint32_t s = cblk->server;
+        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
+
+        bufferEnd = (cblk->loopEnd < bufferEnd) ? cblk->loopEnd : bufferEnd;
+        if (framesReq > framesReady) {
+            framesReq = framesReady;
+        }
+        if (s + framesReq > bufferEnd) {
+            framesReq = bufferEnd - s;
+        }
+
+         buffer->raw = getBuffer(s, framesReq);
+         if (buffer->raw == 0) goto getNextBuffer_exit;
+
+         buffer->frameCount = framesReq;
+        return NO_ERROR;
+     }
+
+getNextBuffer_exit:
+     buffer->raw = 0;
+     buffer->frameCount = 0;
+     return NOT_ENOUGH_DATA;
+}
+
+bool AudioFlinger::MixerThread::Track::isReady() const {
+    if (mFillingUpStatus != FS_FILLING) return true;
+
+    if (mCblk->framesReady() >= mCblk->frameCount ||
+        mCblk->forceReady) {
+        mFillingUpStatus = FS_FILLED;
+        mCblk->forceReady = 0;
+        LOGV("Track::isReady() track %d for output %d", mName, mMixerThread->mOutputType);
+        return true;
+    }
+    return false;
+}
+
+status_t AudioFlinger::MixerThread::Track::start()
+{
+    LOGV("start(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
+    mMixerThread->addTrack(this);
+    return NO_ERROR;
+}
+
+void AudioFlinger::MixerThread::Track::stop()
+{
+    LOGV("stop(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
+    Mutex::Autolock _l(mMixerThread->mLock);
+    if (mState > STOPPED) {
+        mState = STOPPED;
+        // If the track is not active (PAUSED and buffers full), flush buffers
+        if (mMixerThread->mActiveTracks.indexOf(this) < 0) {
+            reset();
+        }
+        LOGV("(> STOPPED) => STOPPED (%d)", mName);
+    }
+}
+
+void AudioFlinger::MixerThread::Track::pause()
+{
+    LOGV("pause(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mMixerThread->mLock);
+    if (mState == ACTIVE || mState == RESUMING) {
+        mState = PAUSING;
+        LOGV("ACTIVE/RESUMING => PAUSING (%d)", mName);
+    }
+}
+
+void AudioFlinger::MixerThread::Track::flush()
+{
+    LOGV("flush(%d)", mName);
+    Mutex::Autolock _l(mMixerThread->mLock);
+    if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
+        return;
+    }
+    // No point remaining in PAUSED state after a flush => go to
+    // STOPPED state
+    mState = STOPPED;
+
+    // NOTE: reset() will reset cblk->user and cblk->server with
+    // the risk that at the same time, the AudioMixer is trying to read
+    // data. In this case, getNextBuffer() would return a NULL pointer
+    // as audio buffer => the AudioMixer code MUST always test that pointer
+    // returned by getNextBuffer() is not NULL!
+    reset();
+}
+
+void AudioFlinger::MixerThread::Track::reset()
+{
+    // Do not reset twice to avoid discarding data written just after a flush and before
+    // the audioflinger thread detects the track is stopped.
+    if (!mResetDone) {
+        TrackBase::reset();
+        // Force underrun condition to avoid false underrun callback until first data is
+        // written to buffer
+        mCblk->flowControlFlag = 1;
+        mCblk->forceReady = 0;
+        mFillingUpStatus = FS_FILLING;        
+        mResetDone = true;
+    }
+}
+
+void AudioFlinger::MixerThread::Track::mute(bool muted)
+{
+    mMute = muted;
+}
+
+void AudioFlinger::MixerThread::Track::setVolume(float left, float right)
+{
+    mVolume[0] = left;
+    mVolume[1] = right;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::RecordTrack::RecordTrack(
+            const sp<MixerThread>& mixerThread,
+            const sp<Client>& client,
+            int streamType,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount,
+            uint32_t flags)
+    :   TrackBase(mixerThread, client, streamType, sampleRate, format,
+                  channelCount, frameCount, flags, 0),
+        mOverflow(false)
+{
+}
+
+AudioFlinger::MixerThread::RecordTrack::~RecordTrack()
+{
+    mMixerThread->deleteTrackName(mName);
+}
+
+status_t AudioFlinger::MixerThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    audio_track_cblk_t* cblk = this->cblk();
+    uint32_t framesAvail;
+    uint32_t framesReq = buffer->frameCount;
+
+     // Check if last stepServer failed, try to step now
+    if (mFlags & TrackBase::STEPSERVER_FAILED) {
+        if (!step()) goto getNextBuffer_exit;
+        LOGV("stepServer recovered");
+        mFlags &= ~TrackBase::STEPSERVER_FAILED;
+    }
+
+    framesAvail = cblk->framesAvailable_l();
+
+    if (LIKELY(framesAvail)) {
+        uint32_t s = cblk->server;
+        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
+
+        if (framesReq > framesAvail) {
+            framesReq = framesAvail;
+        }
+        if (s + framesReq > bufferEnd) {
+            framesReq = bufferEnd - s;
+        }
+
+        buffer->raw = getBuffer(s, framesReq);
+        if (buffer->raw == 0) goto getNextBuffer_exit;
+
+        buffer->frameCount = framesReq;
+        return NO_ERROR;
+    }
+
+getNextBuffer_exit:
+    buffer->raw = 0;
+    buffer->frameCount = 0;
+    return NOT_ENOUGH_DATA;
+}
+
+status_t AudioFlinger::MixerThread::RecordTrack::start()
+{
+    return mMixerThread->mAudioFlinger->startRecord(this);
+}
+
+void AudioFlinger::MixerThread::RecordTrack::stop()
+{
+    mMixerThread->mAudioFlinger->stopRecord(this);
+    TrackBase::reset();
+    // Force overerrun condition to avoid false overrun callback until first data is
+    // read from buffer
+    mCblk->flowControlFlag = 1;
+}
+
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::OutputTrack::OutputTrack(
+            const sp<MixerThread>& mixerThread,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount)
+    :   Track(mixerThread, NULL, AudioSystem::SYSTEM, sampleRate, format, channelCount, frameCount, NULL),
+    mOutputMixerThread(mixerThread)
+{
+                
+    mCblk->out = 1;
+    mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
+    mCblk->volume[0] = mCblk->volume[1] = 0x1000;
+    mOutBuffer.frameCount = 0;
+    mCblk->bufferTimeoutMs = 10;
+    
+    LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p", 
+            mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd);
+    
+}
+
+AudioFlinger::MixerThread::OutputTrack::~OutputTrack()
+{
+    stop();
+}
+
+status_t AudioFlinger::MixerThread::OutputTrack::start()
+{
+    status_t status = Track::start();
+    
+    mRetryCount = 127;
+    return status;
+}
+
+void AudioFlinger::MixerThread::OutputTrack::stop()
+{
+    Track::stop();
+    clearBufferQueue();
+    mOutBuffer.frameCount = 0;
+}
+
+void AudioFlinger::MixerThread::OutputTrack::write(int16_t* data, uint32_t frames)
+{
+    Buffer *pInBuffer;
+    Buffer inBuffer;
+    uint32_t channels = mCblk->channels;
+        
+    inBuffer.frameCount = frames;
+    inBuffer.i16 = data;
+    
+    if (mCblk->user == 0) {
+        if (mOutputMixerThread->isMusicActive()) {
+            mCblk->forceReady = 1;
+            LOGV("OutputTrack::start() force ready");
+        } else if (mCblk->frameCount > frames){
+            if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
+                uint32_t startFrames = (mCblk->frameCount - frames);
+                LOGV("OutputTrack::start() write %d frames", startFrames);
+                pInBuffer = new Buffer;
+                pInBuffer->mBuffer = new int16_t[startFrames * channels];
+                pInBuffer->frameCount = startFrames;
+                pInBuffer->i16 = pInBuffer->mBuffer;
+                memset(pInBuffer->raw, 0, startFrames * channels * sizeof(int16_t));
+                mBufferQueue.add(pInBuffer);                
+            } else {
+                LOGW ("OutputTrack::write() no more buffers");
+            }
+        }        
+    }
+
+    while (1) { 
+        // First write pending buffers, then new data
+        if (mBufferQueue.size()) {
+            pInBuffer = mBufferQueue.itemAt(0);
+        } else {
+            pInBuffer = &inBuffer;
+        }
+ 
+        if (pInBuffer->frameCount == 0) {
+            break;
+        }
+        
+        if (mOutBuffer.frameCount == 0) {
+            mOutBuffer.frameCount = pInBuffer->frameCount;
+            if (obtainBuffer(&mOutBuffer) == (status_t)AudioTrack::NO_MORE_BUFFERS) {
+                break;
+            }
+        }
+            
+        uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : pInBuffer->frameCount;
+        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channels * sizeof(int16_t));
+        mCblk->stepUser(outFrames);
+        pInBuffer->frameCount -= outFrames;
+        pInBuffer->i16 += outFrames * channels;
+        mOutBuffer.frameCount -= outFrames;
+        mOutBuffer.i16 += outFrames * channels;            
+        
+        if (pInBuffer->frameCount == 0) {
+            if (mBufferQueue.size()) {
+                mBufferQueue.removeAt(0);
+                delete [] pInBuffer->mBuffer;
+                delete pInBuffer;
+            } else {
+                break;
+            }
+        }
+    }
+ 
+    // If we could not write all frames, allocate a buffer and queue it for next time.
+    if (inBuffer.frameCount) {
+        if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
+            pInBuffer = new Buffer;
+            pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channels];
+            pInBuffer->frameCount = inBuffer.frameCount;
+            pInBuffer->i16 = pInBuffer->mBuffer;
+            memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channels * sizeof(int16_t));
+            mBufferQueue.add(pInBuffer);
+        } else {
+            LOGW("OutputTrack::write() no more buffers");
+        }
+    }
+    
+    // Calling write() with a 0 length buffer, means that no more data will be written:
+    // If no more buffers are pending, fill output track buffer to make sure it is started 
+    // by output mixer.
+    if (frames == 0 && mBufferQueue.size() == 0 && mCblk->user < mCblk->frameCount) {
+        frames = mCblk->frameCount - mCblk->user;
+        pInBuffer = new Buffer;
+        pInBuffer->mBuffer = new int16_t[frames * channels];
+        pInBuffer->frameCount = frames;
+        pInBuffer->i16 = pInBuffer->mBuffer;
+        memset(pInBuffer->raw, 0, frames * channels * sizeof(int16_t));
+        mBufferQueue.add(pInBuffer);
+    }
+
+}
+
+status_t AudioFlinger::MixerThread::OutputTrack::obtainBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    int active;
+    int timeout = 0;
+    status_t result;
+    audio_track_cblk_t* cblk = mCblk;
+    uint32_t framesReq = buffer->frameCount;
+
+    LOGV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
+    buffer->frameCount  = 0;
+    
+    uint32_t framesAvail = cblk->framesAvailable();
+
+    if (framesAvail == 0) {
+        return AudioTrack::NO_MORE_BUFFERS;
+    }
+
+    if (framesReq > framesAvail) {
+        framesReq = framesAvail;
+    }
+
+    uint32_t u = cblk->user;
+    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
+
+    if (u + framesReq > bufferEnd) {
+        framesReq = bufferEnd - u;
+    }
+
+    buffer->frameCount  = framesReq;
+    buffer->raw         = (void *)cblk->buffer(u);
+    return NO_ERROR;
+}
+
+
+void AudioFlinger::MixerThread::OutputTrack::clearBufferQueue()
+{
+    size_t size = mBufferQueue.size();
+    Buffer *pBuffer;
+    
+    for (size_t i = 0; i < size; i++) {
+        pBuffer = mBufferQueue.itemAt(i);
+        delete [] pBuffer->mBuffer;
+        delete pBuffer;
+    }
+    mBufferQueue.clear();
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
+    :   RefBase(),
+        mAudioFlinger(audioFlinger),
+        mMemoryDealer(new MemoryDealer(1024*1024)),
+        mPid(pid)
+{
+    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
+}
+
+AudioFlinger::Client::~Client()
+{
+    mAudioFlinger->removeClient(mPid);
+}
+
+const sp<MemoryDealer>& AudioFlinger::Client::heap() const
+{
+    return mMemoryDealer;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::MixerThread::Track>& track)
+    : BnAudioTrack(),
+      mTrack(track)
+{
+}
+
+AudioFlinger::TrackHandle::~TrackHandle() {
+    // just stop the track on deletion, associated resources
+    // will be freed from the main thread once all pending buffers have
+    // been played. Unless it's not in the active track list, in which
+    // case we free everything now...
+    mTrack->destroy();
+}
+
+status_t AudioFlinger::TrackHandle::start() {
+    return mTrack->start();
+}
+
+void AudioFlinger::TrackHandle::stop() {
+    mTrack->stop();
+}
+
+void AudioFlinger::TrackHandle::flush() {
+    mTrack->flush();
+}
+
+void AudioFlinger::TrackHandle::mute(bool e) {
+    mTrack->mute(e);
+}
+
+void AudioFlinger::TrackHandle::pause() {
+    mTrack->pause();
+}
+
+void AudioFlinger::TrackHandle::setVolume(float left, float right) {
+    mTrack->setVolume(left, right);
+}
+
+sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
+    return mTrack->getCblk();
+}
+
+status_t AudioFlinger::TrackHandle::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    return BnAudioTrack::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+
+sp<IAudioRecord> AudioFlinger::openRecord(
+        pid_t pid,
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int frameCount,
+        uint32_t flags,
+        status_t *status)
+{
+    sp<AudioRecordThread> thread;
+    sp<MixerThread::RecordTrack> recordTrack;
+    sp<RecordHandle> recordHandle;
+    sp<Client> client;
+    wp<Client> wclient;
+    AudioStreamIn* input = 0;
+    int inFrameCount;
+    size_t inputBufferSize;
+    status_t lStatus;
+
+    // check calling permissions
+    if (!recordingAllowed()) {
+        lStatus = PERMISSION_DENIED;
+        goto Exit;
+    }
+
+    if (uint32_t(streamType) >= AudioRecord::NUM_STREAM_TYPES) {
+        LOGE("invalid stream type");
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
+    if (sampleRate > MAX_SAMPLE_RATE) {
+        LOGE("Sample rate out of range");
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
+    if (mAudioRecordThread == 0) {
+        LOGE("Audio record thread not started");
+        lStatus = NO_INIT;
+        goto Exit;
+    }
+
+
+    // Check that audio input stream accepts requested audio parameters 
+    inputBufferSize = mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
+    if (inputBufferSize == 0) {
+        lStatus = BAD_VALUE;
+        LOGE("Bad audio input parameters: sampling rate %u, format %d, channels %d",  sampleRate, format, channelCount);
+        goto Exit;
+    }
+
+    // add client to list
+    {
+        Mutex::Autolock _l(mLock);
+        wclient = mClients.valueFor(pid);
+        if (wclient != NULL) {
+            client = wclient.promote();
+        } else {
+            client = new Client(this, pid);
+            mClients.add(pid, client);
+        }
+    }
+
+    // frameCount must be a multiple of input buffer size
+    inFrameCount = inputBufferSize/channelCount/sizeof(short);
+    frameCount = ((frameCount - 1)/inFrameCount + 1) * inFrameCount;
+
+    // create new record track and pass to record thread
+    recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, streamType, sampleRate,
+                                               format, channelCount, frameCount, flags);
+    if (recordTrack->getCblk() == NULL) {
+        recordTrack.clear();
+        lStatus = NO_MEMORY;
+        goto Exit;
+    }
+
+    // return to handle to client
+    recordHandle = new RecordHandle(recordTrack);
+    lStatus = NO_ERROR;
+
+Exit:
+    if (status) {
+        *status = lStatus;
+    }
+    return recordHandle;
+}
+
+status_t AudioFlinger::startRecord(MixerThread::RecordTrack* recordTrack) {
+    if (mAudioRecordThread != 0) {
+        return mAudioRecordThread->start(recordTrack);        
+    }
+    return NO_INIT;
+}
+
+void AudioFlinger::stopRecord(MixerThread::RecordTrack* recordTrack) {
+    if (mAudioRecordThread != 0) {
+        mAudioRecordThread->stop(recordTrack);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::MixerThread::RecordTrack>& recordTrack)
+    : BnAudioRecord(),
+    mRecordTrack(recordTrack)
+{
+}
+
+AudioFlinger::RecordHandle::~RecordHandle() {
+    stop();
+}
+
+status_t AudioFlinger::RecordHandle::start() {
+    LOGV("RecordHandle::start()");
+    return mRecordTrack->start();
+}
+
+void AudioFlinger::RecordHandle::stop() {
+    LOGV("RecordHandle::stop()");
+    mRecordTrack->stop();
+}
+
+sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
+    return mRecordTrack->getCblk();
+}
+
+status_t AudioFlinger::RecordHandle::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    return BnAudioRecord::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::AudioRecordThread::AudioRecordThread(AudioHardwareInterface* audioHardware) :
+    mAudioHardware(audioHardware),
+    mActive(false)
+{
+}
+
+AudioFlinger::AudioRecordThread::~AudioRecordThread()
+{
+}
+
+bool AudioFlinger::AudioRecordThread::threadLoop()
+{
+    LOGV("AudioRecordThread: start record loop");
+    AudioBufferProvider::Buffer buffer;
+    int inBufferSize = 0;
+    int inFrameCount = 0;
+    AudioStreamIn* input = 0;
+
+    mActive = 0;
+    
+    // start recording
+    while (!exitPending()) {
+        if (!mActive) {
+            mLock.lock();
+            if (!mActive && !exitPending()) {
+                LOGV("AudioRecordThread: loop stopping");
+                if (input) {
+                    delete input;
+                    input = 0;
+                }
+                mRecordTrack.clear();
+                mStopped.signal();
+
+                mWaitWorkCV.wait(mLock);
+               
+                LOGV("AudioRecordThread: loop starting");
+                if (mRecordTrack != 0) {
+                    input = mAudioHardware->openInputStream(mRecordTrack->format(), 
+                                    mRecordTrack->channelCount(), 
+                                    mRecordTrack->sampleRate(), 
+                                    &mStartStatus,
+                                    (AudioSystem::audio_in_acoustics)(mRecordTrack->mFlags >> 16));
+                    if (input != 0) {
+                        inBufferSize = input->bufferSize();
+                        inFrameCount = inBufferSize/input->frameSize();                        
+                    }
+                } else {
+                    mStartStatus = NO_INIT;
+                }
+                if (mStartStatus !=NO_ERROR) {
+                    LOGW("record start failed, status %d", mStartStatus);
+                    mActive = false;
+                    mRecordTrack.clear();                    
+                }
+                mWaitWorkCV.signal();
+            }
+            mLock.unlock();
+        } else if (mRecordTrack != 0) {
+
+            buffer.frameCount = inFrameCount;
+            if (LIKELY(mRecordTrack->getNextBuffer(&buffer) == NO_ERROR)) {
+                LOGV("AudioRecordThread read: %d frames", buffer.frameCount);
+                ssize_t bytesRead = input->read(buffer.raw, inBufferSize);
+                if (bytesRead < 0) {
+                    LOGE("Error reading audio input");
+                    sleep(1);
+                }
+                mRecordTrack->releaseBuffer(&buffer);
+                mRecordTrack->overflow();
+            }
+
+            // client isn't retrieving buffers fast enough
+            else {
+                if (!mRecordTrack->setOverflow())
+                    LOGW("AudioRecordThread: buffer overflow");
+                // Release the processor for a while before asking for a new buffer.
+                // This will give the application more chance to read from the buffer and
+                // clear the overflow.
+                usleep(5000);
+            }
+        }
+    }
+
+
+    if (input) {
+        delete input;
+    }
+    mRecordTrack.clear();
+    
+    return false;
+}
+
+status_t AudioFlinger::AudioRecordThread::start(MixerThread::RecordTrack* recordTrack)
+{
+    LOGV("AudioRecordThread::start");
+    AutoMutex lock(&mLock);
+    mActive = true;
+    // If starting the active track, just reset mActive in case a stop
+    // was pending and exit
+    if (recordTrack == mRecordTrack.get()) return NO_ERROR;
+
+    if (mRecordTrack != 0) return -EBUSY;
+
+    mRecordTrack = recordTrack;
+
+    // signal thread to start
+    LOGV("Signal record thread");
+    mWaitWorkCV.signal();
+    mWaitWorkCV.wait(mLock);
+    LOGV("Record started, status %d", mStartStatus);
+    return mStartStatus;
+}
+
+void AudioFlinger::AudioRecordThread::stop(MixerThread::RecordTrack* recordTrack) {
+    LOGV("AudioRecordThread::stop");
+    AutoMutex lock(&mLock);
+    if (mActive && (recordTrack == mRecordTrack.get())) {
+        mActive = false;
+        mStopped.wait(mLock);
+    }
+}
+
+void AudioFlinger::AudioRecordThread::exit()
+{
+    LOGV("AudioRecordThread::exit");
+    {
+        AutoMutex lock(&mLock);
+        requestExit();
+        mWaitWorkCV.signal();
+    }
+    requestExitAndWait();
+}
+
+status_t AudioFlinger::AudioRecordThread::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    pid_t pid = 0;
+
+    if (mRecordTrack != 0 && mRecordTrack->mClient != 0) {
+        snprintf(buffer, SIZE, "Record client pid: %d\n", mRecordTrack->mClient->pid());
+        result.append(buffer);
+    } else {
+        result.append("No record client\n");
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    return BnAudioFlinger::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+void AudioFlinger::instantiate() {
+    defaultServiceManager()->addService(
+            String16("media.audio_flinger"), new AudioFlinger());
+}
+
+}; // namespace android
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
new file mode 100644
index 0000000..77f064b
--- /dev/null
+++ b/libs/audioflinger/AudioFlinger.h
@@ -0,0 +1,637 @@
+/* //device/include/server/AudioFlinger/AudioFlinger.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_FLINGER_H
+#define ANDROID_AUDIO_FLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <media/IAudioFlinger.h>
+#include <media/IAudioFlingerClient.h>
+#include <media/IAudioTrack.h>
+#include <media/IAudioRecord.h>
+#include <media/AudioTrack.h>
+
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <utils/MemoryDealer.h>
+#include <utils/KeyedVector.h>
+#include <utils/SortedVector.h>
+#include <utils/Vector.h>
+
+#include <hardware_legacy/AudioHardwareInterface.h>
+
+#include "AudioBufferProvider.h"
+
+namespace android {
+
+class audio_track_cblk_t;
+class AudioMixer;
+class AudioBuffer;
+
+
+// ----------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+
+// ----------------------------------------------------------------------------
+
+static const nsecs_t kStandbyTimeInNsecs = seconds(3);
+
+class AudioFlinger : public BnAudioFlinger, public IBinder::DeathRecipient 
+{
+public:
+    static void instantiate();
+
+    virtual     status_t    dump(int fd, const Vector<String16>& args);
+
+    // IAudioFlinger interface
+    virtual sp<IAudioTrack> createTrack(
+                                pid_t pid,
+                                int streamType,
+                                uint32_t sampleRate,
+                                int format,
+                                int channelCount,
+                                int frameCount,
+                                uint32_t flags,
+                                const sp<IMemory>& sharedBuffer,
+                                status_t *status);
+
+    virtual     uint32_t    sampleRate(int output) const;
+    virtual     int         channelCount(int output) const;
+    virtual     int         format(int output) const;
+    virtual     size_t      frameCount(int output) const;
+    virtual     uint32_t    latency(int output) const;
+
+    virtual     status_t    setMasterVolume(float value);
+    virtual     status_t    setMasterMute(bool muted);
+
+    virtual     float       masterVolume() const;
+    virtual     bool        masterMute() const;
+
+    virtual     status_t    setStreamVolume(int stream, float value);
+    virtual     status_t    setStreamMute(int stream, bool muted);
+
+    virtual     float       streamVolume(int stream) const;
+    virtual     bool        streamMute(int stream) const;
+
+    virtual     status_t    setRouting(int mode, uint32_t routes, uint32_t mask);
+    virtual     uint32_t    getRouting(int mode) const;
+
+    virtual     status_t    setMode(int mode);
+    virtual     int         getMode() const;
+
+    virtual     status_t    setMicMute(bool state);
+    virtual     bool        getMicMute() const;
+
+    virtual     bool        isMusicActive() const;
+
+    virtual     bool        isA2dpEnabled() const;
+
+    virtual     status_t    setParameter(const char* key, const char* value);
+
+    virtual     void        registerClient(const sp<IAudioFlingerClient>& client);
+    
+    virtual     size_t      getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
+    
+    virtual     void        wakeUp();
+    
+    // IBinder::DeathRecipient
+    virtual     void        binderDied(const wp<IBinder>& who);
+
+    enum hardware_call_state {
+        AUDIO_HW_IDLE = 0,
+        AUDIO_HW_INIT,
+        AUDIO_HW_OUTPUT_OPEN,
+        AUDIO_HW_OUTPUT_CLOSE,
+        AUDIO_HW_INPUT_OPEN,
+        AUDIO_HW_INPUT_CLOSE,
+        AUDIO_HW_STANDBY,
+        AUDIO_HW_SET_MASTER_VOLUME,
+        AUDIO_HW_GET_ROUTING,
+        AUDIO_HW_SET_ROUTING,
+        AUDIO_HW_GET_MODE,
+        AUDIO_HW_SET_MODE,
+        AUDIO_HW_GET_MIC_MUTE,
+        AUDIO_HW_SET_MIC_MUTE,
+        AUDIO_SET_VOICE_VOLUME,
+        AUDIO_SET_PARAMETER,
+    };
+
+    // record interface
+    virtual sp<IAudioRecord> openRecord(
+                                pid_t pid,
+                                int streamType,
+                                uint32_t sampleRate,
+                                int format,
+                                int channelCount,
+                                int frameCount,
+                                uint32_t flags,
+                                status_t *status);
+
+    virtual     status_t    onTransact(
+                                uint32_t code,
+                                const Parcel& data,
+                                Parcel* reply,
+                                uint32_t flags);
+
+private:
+                            AudioFlinger();
+    virtual                 ~AudioFlinger();
+    
+    void                    setOutput(int outputType);
+    void                    doSetOutput(int outputType);
+
+#ifdef WITH_A2DP
+    void                    setA2dpEnabled(bool enable);
+#endif
+    static bool             streamForcedToSpeaker(int streamType);
+    
+    // Management of forced route to speaker for certain track types.
+    enum force_speaker_command {
+        ACTIVE_TRACK_ADDED = 0,
+        ACTIVE_TRACK_REMOVED,
+        CHECK_ROUTE_RESTORE_TIME,
+        FORCE_ROUTE_RESTORE
+    };
+    void                    handleForcedSpeakerRoute(int command);
+
+    // Internal dump utilites.
+    status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
+    status_t dumpClients(int fd, const Vector<String16>& args);
+    status_t dumpInternals(int fd, const Vector<String16>& args);
+
+    // --- Client ---
+    class Client : public RefBase {
+    public:
+                            Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
+        virtual             ~Client();
+        const sp<MemoryDealer>&     heap() const;
+        pid_t               pid() const { return mPid; }
+    private:
+                            Client(const Client&);
+                            Client& operator = (const Client&);
+        sp<AudioFlinger>    mAudioFlinger;
+        sp<MemoryDealer>    mMemoryDealer;
+        pid_t               mPid;
+    };
+
+
+    class TrackHandle;
+    class RecordHandle;
+    class AudioRecordThread;
+
+    
+    // --- MixerThread ---
+    class MixerThread : public Thread {
+    public:
+        
+        // --- Track ---
+
+        // base for record and playback
+        class TrackBase : public AudioBufferProvider, public RefBase {
+
+        public:
+            enum track_state {
+                IDLE,
+                TERMINATED,
+                STOPPED,
+                RESUMING,
+                ACTIVE,
+                PAUSING,
+                PAUSED
+            };
+
+            enum track_flags {
+                STEPSERVER_FAILED = 0x01, //  StepServer could not acquire cblk->lock mutex
+                SYSTEM_FLAGS_MASK = 0x0000ffffUL,
+                // The upper 16 bits are used for track-specific flags.
+            };
+
+                                TrackBase(const sp<MixerThread>& mixerThread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        uint32_t flags,
+                                        const sp<IMemory>& sharedBuffer);
+                                ~TrackBase();
+
+            virtual status_t    start() = 0;
+            virtual void        stop() = 0;
+                    sp<IMemory> getCblk() const;
+
+        protected:
+            friend class MixerThread;
+            friend class RecordHandle;
+            friend class AudioRecordThread;
+
+                                TrackBase(const TrackBase&);
+                                TrackBase& operator = (const TrackBase&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
+            virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+
+            audio_track_cblk_t* cblk() const {
+                return mCblk;
+            }
+
+            int type() const {
+                return mStreamType;
+            }
+
+            int format() const {
+                return mFormat;
+            }
+
+            int channelCount() const ;
+
+            int sampleRate() const;
+
+            void* getBuffer(uint32_t offset, uint32_t frames) const;
+
+            int name() const {
+                return mName;
+            }
+
+            bool isStopped() const {
+                return mState == STOPPED;
+            }
+
+            bool isTerminated() const {
+                return mState == TERMINATED;
+            }
+
+            bool step();
+            void reset();
+
+            sp<MixerThread>     mMixerThread;
+            sp<Client>          mClient;
+            sp<IMemory>         mCblkMemory;
+            audio_track_cblk_t* mCblk;
+            int                 mStreamType;
+            void*               mBuffer;
+            void*               mBufferEnd;
+            uint32_t            mFrameCount;
+            int                 mName;
+            // we don't really need a lock for these
+            int                 mState;
+            int                 mClientTid;
+            uint8_t             mFormat;
+            uint32_t            mFlags;
+        };
+
+        // playback track
+        class Track : public TrackBase {
+        public:
+                                Track(  const sp<MixerThread>& mixerThread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        const sp<IMemory>& sharedBuffer);
+                                ~Track();
+
+                    void        dump(char* buffer, size_t size);
+            virtual status_t    start();
+            virtual void        stop();
+                    void        pause();
+
+                    void        flush();
+                    void        destroy();
+                    void        mute(bool);
+                    void        setVolume(float left, float right);
+
+        protected:
+            friend class MixerThread;
+            friend class AudioFlinger;
+            friend class AudioFlinger::TrackHandle;
+
+                                Track(const Track&);
+                                Track& operator = (const Track&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+
+            bool isMuted() const {
+                return (mMute || mMixerThread->mStreamTypes[mStreamType].mute);
+            }
+
+            bool isPausing() const {
+                return mState == PAUSING;
+            }
+
+            bool isPaused() const {
+                return mState == PAUSED;
+            }
+
+            bool isReady() const;
+
+            void setPaused() { mState = PAUSED; }
+            void reset();
+
+            // we don't really need a lock for these
+            float               mVolume[2];
+            volatile bool       mMute;
+            // FILLED state is used for suppressing volume ramp at begin of playing
+            enum {FS_FILLING, FS_FILLED, FS_ACTIVE};
+            mutable uint8_t     mFillingUpStatus;
+            int8_t              mRetryCount;
+            sp<IMemory>         mSharedBuffer;
+            bool                mResetDone;
+        };  // end of Track
+
+        // record track
+        class RecordTrack : public TrackBase {
+        public:
+                                RecordTrack(const sp<MixerThread>& mixerThread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        uint32_t flags);
+                                ~RecordTrack();
+
+            virtual status_t    start();
+            virtual void        stop();
+
+                    bool        overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; }
+                    bool        setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
+
+        private:
+            friend class AudioFlinger;
+            friend class AudioFlinger::RecordHandle;
+            friend class AudioFlinger::AudioRecordThread;
+            friend class MixerThread;
+
+                                RecordTrack(const Track&);
+                                RecordTrack& operator = (const Track&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+
+            bool                mOverflow;
+        };
+
+        // playback track
+        class OutputTrack : public Track {
+        public:
+            
+            class Buffer: public AudioBufferProvider::Buffer {
+            public:
+                int16_t *mBuffer;
+            };
+            
+                                OutputTrack(  const sp<MixerThread>& mixerThread,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount);
+                                ~OutputTrack();
+
+            virtual status_t    start();
+            virtual void        stop();
+                    void        write(int16_t* data, uint32_t frames);
+                    bool        bufferQueueEmpty() { return (mBufferQueue.size() == 0) ? true : false; }
+
+        private:
+
+            status_t            obtainBuffer(AudioBufferProvider::Buffer* buffer);
+            void                clearBufferQueue();
+            
+            sp<MixerThread>             mOutputMixerThread;
+            Vector < Buffer* >          mBufferQueue;
+            AudioBufferProvider::Buffer mOutBuffer;
+            uint32_t                    mFramesWritten;
+            
+         };  // end of OutputTrack
+
+        MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType);
+        virtual             ~MixerThread();
+
+        virtual     status_t    dump(int fd, const Vector<String16>& args);
+
+        // Thread virtuals
+        virtual     bool        threadLoop();
+        virtual     status_t    readyToRun();
+        virtual     void        onFirstRef();
+
+        virtual     uint32_t    sampleRate() const;
+        virtual     int         channelCount() const;
+        virtual     int         format() const;
+        virtual     size_t      frameCount() const;
+        virtual     uint32_t    latency() const;
+
+        virtual     status_t    setMasterVolume(float value);
+        virtual     status_t    setMasterMute(bool muted);
+
+        virtual     float       masterVolume() const;
+        virtual     bool        masterMute() const;
+
+        virtual     status_t    setStreamVolume(int stream, float value);
+        virtual     status_t    setStreamMute(int stream, bool muted);
+
+        virtual     float       streamVolume(int stream) const;
+        virtual     bool        streamMute(int stream) const;
+
+                    bool        isMusicActive() const;
+        
+                    
+        sp<Track> createTrack(
+                                    const sp<AudioFlinger::Client>& client,
+                                    int streamType,
+                                    uint32_t sampleRate,
+                                    int format,
+                                    int channelCount,
+                                    int frameCount,
+                                    const sp<IMemory>& sharedBuffer,
+                                    status_t *status);
+
+                    void        wakeUp() { mWaitWorkCV.broadcast(); }
+                    
+                    void        getTracks(SortedVector < sp<Track> >& tracks,
+                                          SortedVector < wp<Track> >& activeTracks);
+                    void        putTracks(SortedVector < sp<Track> >& tracks,
+                                          SortedVector < wp<Track> >& activeTracks);
+                    void        setOuputTrack(OutputTrack *track) { mOutputTrack = track; }
+                    
+        struct  stream_type_t {
+            stream_type_t()
+                :   volume(1.0f),
+                    mute(false)
+            {
+            }
+            float       volume;
+            bool        mute;
+        };
+
+    private:
+
+
+        friend class AudioFlinger;
+        friend class Track;
+        friend class TrackBase;
+        friend class RecordTrack;
+        
+        MixerThread(const Client&);
+        MixerThread& operator = (const MixerThread&);
+  
+        status_t    addTrack(const sp<Track>& track);
+        void        removeTrack(wp<Track> track, int name);
+        void        remove_track_l(wp<Track> track, int name);
+        void        destroyTrack(const sp<Track>& track);
+        int         getTrackName();
+        void        deleteTrackName(int name);
+        void        addActiveTrack(const wp<Track>& t);
+        void        removeActiveTrack(const wp<Track>& t);
+        size_t      getOutputFrameCount();
+
+        status_t    dumpInternals(int fd, const Vector<String16>& args);
+        status_t    dumpTracks(int fd, const Vector<String16>& args);
+        
+        sp<AudioFlinger>                mAudioFlinger;       
+        mutable     Mutex               mLock;
+        mutable     Condition           mWaitWorkCV;
+        SortedVector< wp<Track> >       mActiveTracks;
+        SortedVector< sp<Track> >       mTracks;
+        stream_type_t                   mStreamTypes[AudioSystem::NUM_STREAM_TYPES];
+        AudioMixer*                     mAudioMixer;
+        AudioStreamOut*                 mOutput;
+        int                             mOutputType;
+        uint32_t                        mSampleRate;
+        size_t                          mFrameCount;
+        int                             mChannelCount;
+        int                             mFormat;
+        int16_t*                        mMixBuffer;
+        float                           mMasterVolume;
+        bool                            mMasterMute;
+        nsecs_t                         mLastWriteTime;
+        int                             mNumWrites;
+        int                             mNumDelayedWrites;
+        bool                            mStandby;
+        bool                            mInWrite;
+        sp <OutputTrack>                mOutputTrack;
+    };
+
+    
+    friend class AudioBuffer;
+
+    class TrackHandle : public android::BnAudioTrack {
+    public:
+                            TrackHandle(const sp<MixerThread::Track>& track);
+        virtual             ~TrackHandle();
+        virtual status_t    start();
+        virtual void        stop();
+        virtual void        flush();
+        virtual void        mute(bool);
+        virtual void        pause();
+        virtual void        setVolume(float left, float right);
+        virtual sp<IMemory> getCblk() const;
+        virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+    private:
+        sp<MixerThread::Track> mTrack;
+    };
+
+    friend class Client;
+    friend class MixerThread::Track;
+
+
+                void        removeClient(pid_t pid);
+
+
+
+    class RecordHandle : public android::BnAudioRecord {
+    public:
+        RecordHandle(const sp<MixerThread::RecordTrack>& recordTrack);
+        virtual             ~RecordHandle();
+        virtual status_t    start();
+        virtual void        stop();
+        virtual sp<IMemory> getCblk() const;
+        virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+    private:
+        sp<MixerThread::RecordTrack> mRecordTrack;
+    };
+
+    // record thread
+    class AudioRecordThread : public Thread
+    {
+    public:
+        AudioRecordThread(AudioHardwareInterface* audioHardware);
+        virtual             ~AudioRecordThread();
+        virtual bool        threadLoop();
+        virtual status_t    readyToRun() { return NO_ERROR; }
+        virtual void        onFirstRef() {}
+
+                status_t    start(MixerThread::RecordTrack* recordTrack);
+                void        stop(MixerThread::RecordTrack* recordTrack);
+                void        exit();
+                status_t    dump(int fd, const Vector<String16>& args);
+
+    private:
+                AudioRecordThread();
+                AudioHardwareInterface              *mAudioHardware;
+                sp<MixerThread::RecordTrack>        mRecordTrack;
+                Mutex                               mLock;
+                Condition                           mWaitWorkCV;
+                Condition                           mStopped;
+                volatile bool                       mActive;
+                status_t                            mStartStatus;
+    };
+
+    friend class AudioRecordThread;
+    friend class MixerThread;
+
+                status_t    startRecord(MixerThread::RecordTrack* recordTrack);
+                void        stopRecord(MixerThread::RecordTrack* recordTrack);
+                
+                void        handleOutputSwitch();
+
+    mutable     Mutex                                       mHardwareLock;
+    mutable     Mutex                                       mLock;
+                DefaultKeyedVector< pid_t, wp<Client> >     mClients;
+
+                sp<MixerThread>                     mA2dpMixerThread;
+                sp<MixerThread>                     mHardwareMixerThread;
+                AudioHardwareInterface*             mAudioHardware;
+                AudioHardwareInterface*             mA2dpAudioInterface;
+                sp<AudioRecordThread>               mAudioRecordThread;
+                bool                                mA2dpEnabled;
+                bool                                mA2dpEnabledReq;
+    mutable     int                                 mHardwareStatus;
+                SortedVector< wp<IBinder> >         mNotificationClients;
+                int                                 mForcedSpeakerCount;
+                uint32_t                            mSavedRoute;
+                uint32_t                            mForcedRoute;
+                nsecs_t                             mRouteRestoreTime;
+                bool                                mMusicMuteSaved;
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_FLINGER_H
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
new file mode 100644
index 0000000..62beada
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareGeneric.cpp
@@ -0,0 +1,313 @@
+/*
+**
+** 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 <stdio.h>
+#include <unistd.h>
+#include <sched.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#define LOG_TAG "AudioHardware"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include "AudioHardwareGeneric.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static char const * const kAudioDeviceName = "/dev/eac";
+
+// ----------------------------------------------------------------------------
+
+AudioHardwareGeneric::AudioHardwareGeneric()
+    : mOutput(0), mInput(0),  mFd(-1), mMicMute(false)
+{
+    mFd = ::open(kAudioDeviceName, O_RDWR);
+}
+
+AudioHardwareGeneric::~AudioHardwareGeneric()
+{
+    if (mFd >= 0) ::close(mFd);
+    delete mOutput;
+    delete mInput;
+}
+
+status_t AudioHardwareGeneric::initCheck()
+{
+    if (mFd >= 0) {
+        if (::access(kAudioDeviceName, O_RDWR) == NO_ERROR)
+            return NO_ERROR;
+    }
+    return NO_INIT;
+}
+
+AudioStreamOut* AudioHardwareGeneric::openOutputStream(
+        int format, int channelCount, uint32_t sampleRate, status_t *status)
+{
+    AutoMutex lock(mLock);
+
+    // only one output stream allowed
+    if (mOutput) {
+        if (status) {
+            *status = INVALID_OPERATION;
+        }
+        return 0;
+    }
+
+    // create new output stream
+    AudioStreamOutGeneric* out = new AudioStreamOutGeneric();
+    status_t lStatus = out->set(this, mFd, format, channelCount, sampleRate);
+    if (status) {
+        *status = lStatus;
+    }
+    if (lStatus == NO_ERROR) {
+        mOutput = out;
+    } else {
+        delete out;
+    }
+    return mOutput;
+}
+
+void AudioHardwareGeneric::closeOutputStream(AudioStreamOutGeneric* out) {
+    if (out == mOutput) mOutput = 0;
+}
+
+AudioStreamIn* AudioHardwareGeneric::openInputStream(
+        int format, int channelCount, uint32_t sampleRate, status_t *status,
+        AudioSystem::audio_in_acoustics acoustics)
+{
+    AutoMutex lock(mLock);
+
+    // only one input stream allowed
+    if (mInput) {
+        if (status) {
+            *status = INVALID_OPERATION;
+        }
+        return 0;
+    }
+
+    // create new output stream
+    AudioStreamInGeneric* in = new AudioStreamInGeneric();
+    status_t lStatus = in->set(this, mFd, format, channelCount, sampleRate, acoustics);
+    if (status) {
+        *status = lStatus;
+    }
+    if (lStatus == NO_ERROR) {
+        mInput = in;
+    } else {
+        delete in;
+    }
+    return mInput;
+}
+
+void AudioHardwareGeneric::closeInputStream(AudioStreamInGeneric* in) {
+    if (in == mInput) mInput = 0;
+}
+
+status_t AudioHardwareGeneric::setVoiceVolume(float v)
+{
+    // Implement: set voice volume
+    return NO_ERROR;
+}
+
+status_t AudioHardwareGeneric::setMasterVolume(float v)
+{
+    // Implement: set master volume
+    // return error - software mixer will handle it
+    return INVALID_OPERATION;
+}
+
+status_t AudioHardwareGeneric::setMicMute(bool state)
+{
+    mMicMute = state;
+    return NO_ERROR;
+}
+
+status_t AudioHardwareGeneric::getMicMute(bool* state)
+{
+    *state = mMicMute;
+    return NO_ERROR;
+}
+
+status_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    result.append("AudioHardwareGeneric::dumpInternals\n");
+    snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n",  mFd, mMicMute? "true": "false");
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args)
+{
+    dumpInternals(fd, args);
+    if (mInput) {
+        mInput->dump(fd, args);
+    }
+    if (mOutput) {
+        mOutput->dump(fd, args);
+    }
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+status_t AudioStreamOutGeneric::set(
+        AudioHardwareGeneric *hw,
+        int fd,
+        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();
+
+    // check values
+    if ((format != AudioSystem::PCM_16_BIT) ||
+            (channels != channelCount()) ||
+            (rate != sampleRate()))
+        return BAD_VALUE;
+
+    mAudioHardware = hw;
+    mFd = fd;
+    return NO_ERROR;
+}
+
+AudioStreamOutGeneric::~AudioStreamOutGeneric()
+{
+    if (mAudioHardware)
+        mAudioHardware->closeOutputStream(this);
+}
+
+ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
+{
+    Mutex::Autolock _l(mLock);
+    return ssize_t(::write(mFd, buffer, bytes));
+}
+
+status_t AudioStreamOutGeneric::standby()
+{
+    // Implement: audio hardware to standby mode
+    return NO_ERROR;
+}
+
+status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioStreamOutGeneric::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);
+    snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+// record functions
+status_t AudioStreamInGeneric::set(
+        AudioHardwareGeneric *hw,
+        int fd,
+        int format,
+        int channels,
+        uint32_t rate,
+        AudioSystem::audio_in_acoustics acoustics)
+{
+    // FIXME: remove logging
+    LOGD("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, format, channels, rate);
+    // check values
+    if ((format != AudioSystem::PCM_16_BIT) ||
+            (channels != channelCount()) ||
+            (rate != sampleRate())) {
+        LOGE("Error opening input channel");
+        return BAD_VALUE;
+    }
+
+    mAudioHardware = hw;
+    mFd = fd;
+    return NO_ERROR;
+}
+
+AudioStreamInGeneric::~AudioStreamInGeneric()
+{
+    // FIXME: remove logging
+    LOGD("AudioStreamInGeneric destructor");
+    if (mAudioHardware)
+        mAudioHardware->closeInputStream(this);
+}
+
+ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
+{
+    // FIXME: remove logging
+    LOGD("AudioStreamInGeneric::read(%p, %d) from fd %d", buffer, bytes, mFd);
+    AutoMutex lock(mLock);
+    if (mFd < 0) {
+        LOGE("Attempt to read from unopened device");
+        return NO_INIT;
+    }
+    return ::read(mFd, buffer, bytes);
+}
+
+status_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioStreamInGeneric::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);
+    snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
new file mode 100644
index 0000000..c949aa1
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareGeneric.h
@@ -0,0 +1,141 @@
+/*
+**
+** 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_GENERIC_H
+#define ANDROID_AUDIO_HARDWARE_GENERIC_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+
+#include <hardware_legacy/AudioHardwareBase.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class AudioHardwareGeneric;
+
+class AudioStreamOutGeneric : public AudioStreamOut {
+public:
+                        AudioStreamOutGeneric() : mAudioHardware(0), mFd(-1) {}
+    virtual             ~AudioStreamOutGeneric();
+
+    virtual status_t    set(
+            AudioHardwareGeneric *hw,
+            int mFd,
+            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 uint32_t    latency() const { return 20; }
+    virtual status_t    setVolume(float volume) { return INVALID_OPERATION; }
+    virtual ssize_t     write(const void* buffer, size_t bytes);
+    virtual status_t    standby();
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+private:
+    AudioHardwareGeneric *mAudioHardware;
+    Mutex   mLock;
+    int     mFd;
+};
+
+class AudioStreamInGeneric : public AudioStreamIn {
+public:
+                        AudioStreamInGeneric() : mAudioHardware(0), mFd(-1) {}
+    virtual             ~AudioStreamInGeneric();
+
+    virtual status_t    set(
+            AudioHardwareGeneric *hw,
+            int mFd,
+            int format,
+            int channelCount,
+            uint32_t sampleRate,
+            AudioSystem::audio_in_acoustics acoustics);
+
+    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 INVALID_OPERATION; }
+    virtual ssize_t     read(void* buffer, ssize_t bytes);
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+    virtual status_t    standby() { return NO_ERROR; }
+
+private:
+    AudioHardwareGeneric *mAudioHardware;
+    Mutex   mLock;
+    int     mFd;
+};
+
+
+class AudioHardwareGeneric : public AudioHardwareBase
+{
+public:
+                        AudioHardwareGeneric();
+    virtual             ~AudioHardwareGeneric();
+    virtual status_t    initCheck();
+    virtual status_t    setVoiceVolume(float volume);
+    virtual status_t    setMasterVolume(float volume);
+
+    // mic mute
+    virtual status_t    setMicMute(bool state);
+    virtual status_t    getMicMute(bool* state);
+
+    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,
+            status_t *status=0);
+
+    virtual AudioStreamIn* openInputStream(
+            int format,
+            int channelCount,
+            uint32_t sampleRate,
+            status_t *status,
+            AudioSystem::audio_in_acoustics acoustics);
+
+            void            closeOutputStream(AudioStreamOutGeneric* out);
+            void            closeInputStream(AudioStreamInGeneric* in);
+protected:
+    virtual status_t        doRouting() { return NO_ERROR; }
+    virtual status_t        dump(int fd, const Vector<String16>& args);
+
+private:
+    status_t                dumpInternals(int fd, const Vector<String16>& args);
+
+    Mutex                   mLock;
+    AudioStreamOutGeneric   *mOutput;
+    AudioStreamInGeneric    *mInput;
+    int                     mFd;
+    bool                    mMicMute;
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_HARDWARE_GENERIC_H
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
diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
new file mode 100644
index 0000000..b13cb1c
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareStub.cpp
@@ -0,0 +1,185 @@
+/* //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;
+}
+
+AudioStreamOut* AudioHardwareStub::openOutputStream(
+        int format, int channelCount, uint32_t sampleRate, status_t *status)
+{
+    AudioStreamOutStub* out = new AudioStreamOutStub();
+    status_t lStatus = out->set(format, channelCount, sampleRate);
+    if (status) {
+        *status = lStatus;
+    }
+    if (lStatus == NO_ERROR)
+        return out;
+    delete out;
+    return 0;
+}
+
+AudioStreamIn* AudioHardwareStub::openInputStream(
+        int format, int channelCount, uint32_t sampleRate,
+        status_t *status, AudioSystem::audio_in_acoustics acoustics)
+{
+    AudioStreamInStub* in = new AudioStreamInStub();
+    status_t lStatus = in->set(format, channelCount, sampleRate, acoustics);
+    if (status) {
+        *status = lStatus;
+    }
+    if (lStatus == 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::standby()
+{
+    return NO_ERROR;
+}
+
+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,
+				AudioSystem::audio_in_acoustics acoustics)
+{
+    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/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
new file mode 100644
index 0000000..d406424
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareStub.h
@@ -0,0 +1,100 @@
+/* //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_legacy/AudioHardwareBase.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 uint32_t    latency() const { return 0; }
+    virtual status_t    setVolume(float volume) { return NO_ERROR; }
+    virtual ssize_t     write(const void* buffer, size_t bytes);
+    virtual status_t    standby();
+    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, AudioSystem::audio_in_acoustics acoustics);
+    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);
+    virtual status_t    standby() { return NO_ERROR; }
+};
+
+class AudioHardwareStub : public  AudioHardwareBase
+{
+public:
+                        AudioHardwareStub();
+    virtual             ~AudioHardwareStub();
+    virtual status_t    initCheck();
+    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,
+                                status_t *status=0);
+
+    virtual AudioStreamIn* openInputStream(
+                                int format,
+                                int channelCount,
+                                uint32_t sampleRate,
+                                status_t *status,
+				AudioSystem::audio_in_acoustics acoustics);
+
+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
diff --git a/libs/audioflinger/AudioMixer.cpp b/libs/audioflinger/AudioMixer.cpp
new file mode 100644
index 0000000..b03467f
--- /dev/null
+++ b/libs/audioflinger/AudioMixer.cpp
@@ -0,0 +1,913 @@
+/* //device/include/server/AudioFlinger/AudioMixer.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.
+*/
+
+#define LOG_TAG "AudioMixer"
+
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include "AudioMixer.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+static inline int16_t clamp16(int32_t sample)
+{
+    if ((sample>>15) ^ (sample>>31))
+        sample = 0x7FFF ^ (sample>>31);
+    return sample;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate)
+    :   mActiveTrack(0), mTrackNames(0), mSampleRate(sampleRate)
+{
+    mState.enabledTracks= 0;
+    mState.needsChanged = 0;
+    mState.frameCount   = frameCount;
+    mState.outputTemp   = 0;
+    mState.resampleTemp = 0;
+    mState.hook         = process__nop;
+    track_t* t = mState.tracks;
+    for (int i=0 ; i<32 ; i++) {
+        t->needs = 0;
+        t->volume[0] = UNITY_GAIN;
+        t->volume[1] = UNITY_GAIN;
+        t->volumeInc[0] = 0;
+        t->volumeInc[1] = 0;
+        t->channelCount = 2;
+        t->enabled = 0;
+        t->format = 16;
+        t->buffer.raw = 0;
+        t->bufferProvider = 0;
+        t->hook = 0;
+        t->resampler = 0;
+        t->sampleRate = mSampleRate;
+        t->in = 0;
+        t++;
+    }
+}
+
+ AudioMixer::~AudioMixer()
+ {
+     track_t* t = mState.tracks;
+     for (int i=0 ; i<32 ; i++) {
+         delete t->resampler;
+         t++;
+     }
+     delete [] mState.outputTemp;
+     delete [] mState.resampleTemp;
+ }
+
+ int AudioMixer::getTrackName()
+ {
+    uint32_t names = mTrackNames;
+    uint32_t mask = 1;
+    int n = 0;
+    while (names & mask) {
+        mask <<= 1;
+        n++;
+    }
+    if (mask) {
+        LOGV("add track (%d)", n);
+        mTrackNames |= mask;
+        return TRACK0 + n;
+    }
+    return -1;
+ }
+
+ void AudioMixer::invalidateState(uint32_t mask)
+ {
+    if (mask) {
+        mState.needsChanged |= mask;
+        mState.hook = process__validate;
+    }
+ }
+
+ void AudioMixer::deleteTrackName(int name)
+ {
+    name -= TRACK0;
+    if (uint32_t(name) < MAX_NUM_TRACKS) {
+        LOGV("deleteTrackName(%d)", name);
+        track_t& track(mState.tracks[ name ]);
+        if (track.enabled != 0) {
+            track.enabled = 0;
+            invalidateState(1<<name);
+        }
+        if (track.resampler) {
+            // delete  the resampler
+            delete track.resampler;
+            track.resampler = 0;
+            track.sampleRate = mSampleRate;
+            invalidateState(1<<name);
+        }
+        track.volumeInc[0] = 0;
+        track.volumeInc[1] = 0;
+        mTrackNames &= ~(1<<name);
+    }
+ }
+
+status_t AudioMixer::enable(int name)
+{
+    switch (name) {
+        case MIXING: {
+            if (mState.tracks[ mActiveTrack ].enabled != 1) {
+                mState.tracks[ mActiveTrack ].enabled = 1;
+                LOGV("enable(%d)", mActiveTrack);
+                invalidateState(1<<mActiveTrack);
+            }
+        } break;
+        default:
+            return NAME_NOT_FOUND;
+    }
+    return NO_ERROR;
+}
+
+status_t AudioMixer::disable(int name)
+{
+    switch (name) {
+        case MIXING: {
+            if (mState.tracks[ mActiveTrack ].enabled != 0) {
+                mState.tracks[ mActiveTrack ].enabled = 0;
+                LOGV("disable(%d)", mActiveTrack);
+                invalidateState(1<<mActiveTrack);
+            }
+        } break;
+        default:
+            return NAME_NOT_FOUND;
+    }
+    return NO_ERROR;
+}
+
+status_t AudioMixer::setActiveTrack(int track)
+{
+    if (uint32_t(track-TRACK0) >= MAX_NUM_TRACKS) {
+        return BAD_VALUE;
+    }
+    mActiveTrack = track - TRACK0;
+    return NO_ERROR;
+}
+
+status_t AudioMixer::setParameter(int target, int name, int value)
+{
+    switch (target) {
+    case TRACK:
+        if (name == CHANNEL_COUNT) {
+            if ((uint32_t(value) <= MAX_NUM_CHANNELS) && (value)) {
+                if (mState.tracks[ mActiveTrack ].channelCount != value) {
+                    mState.tracks[ mActiveTrack ].channelCount = value;
+                    LOGV("setParameter(TRACK, CHANNEL_COUNT, %d)", value);
+                    invalidateState(1<<mActiveTrack);
+                }
+                return NO_ERROR;
+            }
+        }
+        break;
+    case RESAMPLE:
+        if (name == SAMPLE_RATE) {
+            if (value > 0) {
+                track_t& track = mState.tracks[ mActiveTrack ];
+                if (track.setResampler(uint32_t(value), mSampleRate)) {
+                    LOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
+                            uint32_t(value));
+                    invalidateState(1<<mActiveTrack);
+                }
+                return NO_ERROR;
+            }
+        }
+        break;
+    case RAMP_VOLUME:
+    case VOLUME:
+        if ((uint32_t(name-VOLUME0) < MAX_NUM_CHANNELS)) {
+            track_t& track = mState.tracks[ mActiveTrack ];
+            if (track.volume[name-VOLUME0] != value) {
+                track.prevVolume[name-VOLUME0] = track.volume[name-VOLUME0] << 16;
+                track.volume[name-VOLUME0] = value;
+                if (target == VOLUME) {
+                    track.prevVolume[name-VOLUME0] = value << 16;
+                    track.volumeInc[name-VOLUME0] = 0;
+                } else {
+                    int32_t d = (value<<16) - track.prevVolume[name-VOLUME0];
+                    int32_t volInc = d / int32_t(mState.frameCount);
+                    track.volumeInc[name-VOLUME0] = volInc;
+                    if (volInc == 0) {
+                        track.prevVolume[name-VOLUME0] = value << 16;
+                    }
+                }
+                invalidateState(1<<mActiveTrack);
+            }
+            return NO_ERROR;
+        }
+        break;
+    }
+    return BAD_VALUE;
+}
+
+bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
+{
+    if (value!=devSampleRate || resampler) {
+        if (sampleRate != value) {
+            sampleRate = value;
+            if (resampler == 0) {
+                resampler = AudioResampler::create(
+                        format, channelCount, devSampleRate);
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+bool AudioMixer::track_t::doesResample() const
+{
+    return resampler != 0;
+}
+
+inline
+void AudioMixer::track_t::adjustVolumeRamp()
+{
+    for (int i=0 ; i<2 ; i++) {
+        if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
+            ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
+            volumeInc[i] = 0;
+            prevVolume[i] = volume[i]<<16;
+        }
+    }
+}
+
+
+status_t AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
+{
+    mState.tracks[ mActiveTrack ].bufferProvider = buffer;
+    return NO_ERROR;
+}
+
+
+
+void AudioMixer::process(void* output)
+{
+    mState.hook(&mState, output);
+}
+
+
+void AudioMixer::process__validate(state_t* state, void* output)
+{
+    LOGW_IF(!state->needsChanged,
+        "in process__validate() but nothing's invalid");
+
+    uint32_t changed = state->needsChanged;
+    state->needsChanged = 0; // clear the validation flag
+
+    // recompute which tracks are enabled / disabled
+    uint32_t enabled = 0;
+    uint32_t disabled = 0;
+    while (changed) {
+        const int i = 31 - __builtin_clz(changed);
+        const uint32_t mask = 1<<i;
+        changed &= ~mask;
+        track_t& t = state->tracks[i];
+        (t.enabled ? enabled : disabled) |= mask;
+    }
+    state->enabledTracks &= ~disabled;
+    state->enabledTracks |=  enabled;
+
+    // compute everything we need...
+    int countActiveTracks = 0;
+    int all16BitsStereoNoResample = 1;
+    int resampling = 0;
+    int volumeRamp = 0;
+    uint32_t en = state->enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+
+        countActiveTracks++;
+        track_t& t = state->tracks[i];
+        uint32_t n = 0;
+        n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
+        n |= NEEDS_FORMAT_16;
+        n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
+       
+        if (t.volumeInc[0]|t.volumeInc[1]) {
+            volumeRamp = 1;
+        } else if (!t.doesResample() && t.volumeRL == 0) {
+            n |= NEEDS_MUTE_ENABLED;
+        }
+        t.needs = n;
+
+        if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
+            t.hook = track__nop;
+        } else {
+            if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
+                all16BitsStereoNoResample = 0;
+                resampling = 1;
+                t.hook = track__genericResample;
+            } else {
+                if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
+                    t.hook = track__16BitsMono;
+                    all16BitsStereoNoResample = 0;
+                }
+                if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
+                    t.hook = track__16BitsStereo;
+                }
+            }
+        }
+    }
+
+    // select the processing hooks
+    state->hook = process__nop;
+    if (countActiveTracks) {
+        if (resampling) {
+            if (!state->outputTemp) {
+                state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
+            }
+            if (!state->resampleTemp) {
+                state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
+            }
+            state->hook = process__genericResampling;
+        } else {
+            if (state->outputTemp) {
+                delete [] state->outputTemp;
+                state->outputTemp = 0;
+            }
+            if (state->resampleTemp) {
+                delete [] state->resampleTemp;
+                state->resampleTemp = 0;
+            }
+            state->hook = process__genericNoResampling;
+            if (all16BitsStereoNoResample && !volumeRamp) {
+                if (countActiveTracks == 1) {
+                    state->hook = process__OneTrack16BitsStereoNoResampling;
+                }
+            }
+        }
+    }
+
+    LOGV("mixer configuration change: %d activeTracks (%08x) "
+        "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
+        countActiveTracks, state->enabledTracks,
+        all16BitsStereoNoResample, resampling, volumeRamp);
+
+   state->hook(state, output);
+
+   // Now that the volume ramp has been done, set optimal state and
+   // track hooks for subsequent mixer process
+   if (countActiveTracks) {
+       int allMuted = 1;
+       uint32_t en = state->enabledTracks;
+       while (en) {
+           const int i = 31 - __builtin_clz(en);
+           en &= ~(1<<i);
+           track_t& t = state->tracks[i];
+           if (!t.doesResample() && t.volumeRL == 0)
+           {
+               t.needs |= NEEDS_MUTE_ENABLED;
+               t.hook = track__nop;
+           } else {
+               allMuted = 0;
+           }
+       }
+       if (allMuted) {
+           state->hook = process__nop;
+       } else if (!resampling && all16BitsStereoNoResample) {
+           if (countActiveTracks == 1) {
+              state->hook = process__OneTrack16BitsStereoNoResampling;
+           }
+       }
+   }
+}
+
+static inline
+int32_t mulAdd(int16_t in, int16_t v, int32_t a)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    asm( "smlabb %[out], %[in], %[v], %[a] \n"
+         : [out]"=r"(out)
+         : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
+         : );
+    return out;
+#else
+    return a + in * int32_t(v);
+#endif
+}
+
+static inline
+int32_t mul(int16_t in, int16_t v)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    asm( "smulbb %[out], %[in], %[v] \n"
+         : [out]"=r"(out)
+         : [in]"%r"(in), [v]"r"(v)
+         : );
+    return out;
+#else
+    return in * int32_t(v);
+#endif
+}
+
+static inline
+int32_t mulAddRL(int left, uint32_t inRL, uint32_t vRL, int32_t a)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    if (left) {
+        asm( "smlabb %[out], %[inRL], %[vRL], %[a] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a)
+             : );
+    } else {
+        asm( "smlatt %[out], %[inRL], %[vRL], %[a] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a)
+             : );
+    }
+    return out;
+#else
+    if (left) {
+        return a + int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF);
+    } else {
+        return a + int16_t(inRL>>16) * int16_t(vRL>>16);
+    }
+#endif
+}
+
+static inline
+int32_t mulRL(int left, uint32_t inRL, uint32_t vRL)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    if (left) {
+        asm( "smulbb %[out], %[inRL], %[vRL] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [vRL]"r"(vRL)
+             : );
+    } else {
+        asm( "smultt %[out], %[inRL], %[vRL] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [vRL]"r"(vRL)
+             : );
+    }
+    return out;
+#else
+    if (left) {
+        return int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF);
+    } else {
+        return int16_t(inRL>>16) * int16_t(vRL>>16);
+    }
+#endif
+}
+
+
+void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp)
+{
+    t->resampler->setSampleRate(t->sampleRate);
+
+    // ramp gain - resample to temp buffer and scale/mix in 2nd step
+    if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
+        t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
+        memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
+        t->resampler->resample(temp, outFrameCount, t->bufferProvider);
+        volumeRampStereo(t, out, outFrameCount, temp);
+    }
+
+    // constant gain
+    else {
+        t->resampler->setVolume(t->volume[0], t->volume[1]);
+        t->resampler->resample(out, outFrameCount, t->bufferProvider);
+    }
+}
+
+void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp)
+{
+}
+
+void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
+{
+    int32_t vl = t->prevVolume[0];
+    int32_t vr = t->prevVolume[1];
+    const int32_t vlInc = t->volumeInc[0];
+    const int32_t vrInc = t->volumeInc[1];
+
+    //LOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+    //        t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
+    //       (vl + vlInc*frameCount)/65536.0f, frameCount);
+   
+    // ramp volume
+    do {
+        *out++ += (vl >> 16) * (*temp++ >> 12);
+        *out++ += (vr >> 16) * (*temp++ >> 12);
+        vl += vlInc;
+        vr += vrInc;
+    } while (--frameCount);
+
+    t->prevVolume[0] = vl;
+    t->prevVolume[1] = vr;
+    t->adjustVolumeRamp();
+}
+
+void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
+{
+    int16_t const *in = static_cast<int16_t const *>(t->in);
+
+    // ramp gain
+    if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
+        int32_t vl = t->prevVolume[0];
+        int32_t vr = t->prevVolume[1];
+        const int32_t vlInc = t->volumeInc[0];
+        const int32_t vrInc = t->volumeInc[1];
+
+        // LOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+        //        t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
+        //        (vl + vlInc*frameCount)/65536.0f, frameCount);
+
+        do {
+            *out++ += (vl >> 16) * (int32_t) *in++;
+            *out++ += (vr >> 16) * (int32_t) *in++;
+            vl += vlInc;
+            vr += vrInc;
+        } while (--frameCount);
+       
+        t->prevVolume[0] = vl;
+        t->prevVolume[1] = vr;
+        t->adjustVolumeRamp();
+    }
+
+    // constant gain
+    else {
+        const uint32_t vrl = t->volumeRL;
+        do {
+            uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
+            in += 2;
+            out[0] = mulAddRL(1, rl, vrl, out[0]);
+            out[1] = mulAddRL(0, rl, vrl, out[1]);
+            out += 2;
+        } while (--frameCount);
+    }
+    t->in = in;
+}
+
+void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
+{
+    int16_t const *in = static_cast<int16_t const *>(t->in);
+
+    // ramp gain
+    if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
+        int32_t vl = t->prevVolume[0];
+        int32_t vr = t->prevVolume[1];
+        const int32_t vlInc = t->volumeInc[0];
+        const int32_t vrInc = t->volumeInc[1];
+
+        // LOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+        //         t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
+        //         (vl + vlInc*frameCount)/65536.0f, frameCount);
+
+        do {
+            int32_t l = *in++;
+            *out++ += (vl >> 16) * l;
+            *out++ += (vr >> 16) * l;
+            vl += vlInc;
+            vr += vrInc;
+        } while (--frameCount);
+       
+        t->prevVolume[0] = vl;
+        t->prevVolume[1] = vr;
+        t->adjustVolumeRamp();
+    }
+    // constant gain
+    else {
+        const int16_t vl = t->volume[0];
+        const int16_t vr = t->volume[1];
+        do {
+            int16_t l = *in++;
+            out[0] = mulAdd(l, vl, out[0]);
+            out[1] = mulAdd(l, vr, out[1]);
+            out += 2;
+        } while (--frameCount);
+    }
+    t->in = in;
+}
+
+inline
+void AudioMixer::ditherAndClamp(int32_t* out, int32_t const *sums, size_t c)
+{
+    for (size_t i=0 ; i<c ; i++) {
+        int32_t l = *sums++;
+        int32_t r = *sums++;
+        int32_t nl = l >> 12;
+        int32_t nr = r >> 12;
+        l = clamp16(nl);
+        r = clamp16(nr);
+        *out++ = (r<<16) | (l & 0xFFFF);
+    }
+}
+
+// no-op case
+void AudioMixer::process__nop(state_t* state, void* output)
+{
+    // this assumes output 16 bits stereo, no resampling
+    memset(output, 0, state->frameCount*4);
+    uint32_t en = state->enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+        track_t& t = state->tracks[i];
+        size_t outFrames = state->frameCount;
+        while (outFrames) {
+            t.buffer.frameCount = outFrames;
+            t.bufferProvider->getNextBuffer(&t.buffer);
+            if (!t.buffer.raw) break;
+            outFrames -= t.buffer.frameCount;
+            t.bufferProvider->releaseBuffer(&t.buffer);
+        }
+    }
+}
+
+// generic code without resampling
+void AudioMixer::process__genericNoResampling(state_t* state, void* output)
+{
+    int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
+
+    // acquire each track's buffer
+    uint32_t enabledTracks = state->enabledTracks;
+    uint32_t en = enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+        track_t& t = state->tracks[i];
+        t.buffer.frameCount = state->frameCount;
+        t.bufferProvider->getNextBuffer(&t.buffer);
+        t.frameCount = t.buffer.frameCount;
+        t.in = t.buffer.raw;
+        // t.in == NULL can happen if the track was flushed just after having
+        // been enabled for mixing.
+        if (t.in == NULL)
+            enabledTracks &= ~(1<<i);
+    }
+
+    // this assumes output 16 bits stereo, no resampling
+    int32_t* out = static_cast<int32_t*>(output);
+    size_t numFrames = state->frameCount;
+    do {
+        memset(outTemp, 0, sizeof(outTemp));
+
+        en = enabledTracks;
+        while (en) {
+            const int i = 31 - __builtin_clz(en);
+            en &= ~(1<<i);
+            track_t& t = state->tracks[i];
+            size_t outFrames = BLOCKSIZE;
+           
+            while (outFrames) {
+                size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
+                if (inFrames) {
+                    (t.hook)(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp);
+                    t.frameCount -= inFrames;
+                    outFrames -= inFrames;
+                }
+                if (t.frameCount == 0 && outFrames) {
+                    t.bufferProvider->releaseBuffer(&t.buffer);
+                    t.buffer.frameCount = numFrames - (BLOCKSIZE - outFrames);
+                    t.bufferProvider->getNextBuffer(&t.buffer);
+                    t.in = t.buffer.raw;
+                    if (t.in == NULL) {
+                        enabledTracks &= ~(1<<i);
+                        break;
+                    }
+                    t.frameCount = t.buffer.frameCount;
+                 }
+            }
+        }
+
+        ditherAndClamp(out, outTemp, BLOCKSIZE);
+        out += BLOCKSIZE;
+        numFrames -= BLOCKSIZE;
+    } while (numFrames);
+
+
+    // release each track's buffer
+    en = enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+        track_t& t = state->tracks[i];
+        t.bufferProvider->releaseBuffer(&t.buffer);
+    }
+}
+
+// generic code with resampling
+void AudioMixer::process__genericResampling(state_t* state, void* output)
+{
+    int32_t* const outTemp = state->outputTemp;
+    const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
+    memset(outTemp, 0, size);
+
+    int32_t* out = static_cast<int32_t*>(output);
+    size_t numFrames = state->frameCount;
+
+    uint32_t en = state->enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+        track_t& t = state->tracks[i];
+
+        // this is a little goofy, on the resampling case we don't
+        // acquire/release the buffers because it's done by
+        // the resampler.
+        if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
+            (t.hook)(&t, outTemp, numFrames, state->resampleTemp);
+        } else {
+
+            size_t outFrames = numFrames;
+           
+            while (outFrames) {
+                t.buffer.frameCount = outFrames;
+                t.bufferProvider->getNextBuffer(&t.buffer);
+                t.in = t.buffer.raw;
+                // t.in == NULL can happen if the track was flushed just after having
+                // been enabled for mixing.
+                if (t.in == NULL) break;
+
+                (t.hook)(&t, outTemp + (numFrames-outFrames)*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp);
+                outFrames -= t.buffer.frameCount;
+                t.bufferProvider->releaseBuffer(&t.buffer);
+            }
+        }
+    }
+
+    ditherAndClamp(out, outTemp, numFrames);
+}
+
+// one track, 16 bits stereo without resampling is the most common case
+void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state, void* output)
+{
+    const int i = 31 - __builtin_clz(state->enabledTracks);
+    const track_t& t = state->tracks[i];
+
+    AudioBufferProvider::Buffer& b(t.buffer);
+   
+    int32_t* out = static_cast<int32_t*>(output);
+    size_t numFrames = state->frameCount;
+  
+    const int16_t vl = t.volume[0];
+    const int16_t vr = t.volume[1];
+    const uint32_t vrl = t.volumeRL;
+    while (numFrames) {
+        b.frameCount = numFrames;
+        t.bufferProvider->getNextBuffer(&b);
+        int16_t const *in = b.i16;
+
+        // in == NULL can happen if the track was flushed just after having
+        // been enabled for mixing.
+        if (in == NULL) {
+            memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
+            return;
+        }
+        size_t outFrames = b.frameCount;
+       
+        if (UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
+            // volume is boosted, so we might need to clamp even though
+            // we process only one track.
+            do {
+                uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
+                in += 2;
+                int32_t l = mulRL(1, rl, vrl) >> 12;
+                int32_t r = mulRL(0, rl, vrl) >> 12;
+                // clamping...
+                l = clamp16(l);
+                r = clamp16(r);
+                *out++ = (r<<16) | (l & 0xFFFF);
+            } while (--outFrames);
+        } else {
+            do {
+                uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
+                in += 2;
+                int32_t l = mulRL(1, rl, vrl) >> 12;
+                int32_t r = mulRL(0, rl, vrl) >> 12;
+                *out++ = (r<<16) | (l & 0xFFFF);
+            } while (--outFrames);
+        }
+        numFrames -= b.frameCount;
+        t.bufferProvider->releaseBuffer(&b);
+    }
+}
+
+// 2 tracks is also a common case
+void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state, void* output)
+{
+    int i;
+    uint32_t en = state->enabledTracks;
+
+    i = 31 - __builtin_clz(en);
+    const track_t& t0 = state->tracks[i];
+    AudioBufferProvider::Buffer& b0(t0.buffer);
+
+    en &= ~(1<<i);
+    i = 31 - __builtin_clz(en);
+    const track_t& t1 = state->tracks[i];
+    AudioBufferProvider::Buffer& b1(t1.buffer);
+   
+    int16_t const *in0;
+    const int16_t vl0 = t0.volume[0];
+    const int16_t vr0 = t0.volume[1];
+    size_t frameCount0 = 0;
+  
+    int16_t const *in1;
+    const int16_t vl1 = t1.volume[0];
+    const int16_t vr1 = t1.volume[1];
+    size_t frameCount1 = 0;
+   
+    int32_t* out = static_cast<int32_t*>(output);
+    size_t numFrames = state->frameCount;
+    int16_t const *buff = NULL;
+
+  
+    while (numFrames) {
+   
+        if (frameCount0 == 0) {
+            b0.frameCount = numFrames;
+            t0.bufferProvider->getNextBuffer(&b0);
+            if (b0.i16 == NULL) {
+                if (buff == NULL) {
+                    buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
+                }
+                in0 = buff;
+                b0.frameCount = numFrames;
+            } else {
+                in0 = b0.i16;
+            }
+            frameCount0 = b0.frameCount;
+        }
+        if (frameCount1 == 0) {
+            b1.frameCount = numFrames;
+            t1.bufferProvider->getNextBuffer(&b1);
+            if (b1.i16 == NULL) {
+                if (buff == NULL) {
+                    buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
+                }
+                in1 = buff;
+                b1.frameCount = numFrames;
+               } else {
+                in1 = b1.i16;
+            }
+            frameCount1 = b1.frameCount;
+        }
+       
+        size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
+
+        numFrames -= outFrames;
+        frameCount0 -= outFrames;
+        frameCount1 -= outFrames;
+       
+        do {
+            int32_t l0 = *in0++;
+            int32_t r0 = *in0++;
+            l0 = mul(l0, vl0);
+            r0 = mul(r0, vr0);
+            int32_t l = *in1++;
+            int32_t r = *in1++;
+            l = mulAdd(l, vl1, l0) >> 12;
+            r = mulAdd(r, vr1, r0) >> 12;
+            // clamping...
+            l = clamp16(l);
+            r = clamp16(r);
+            *out++ = (r<<16) | (l & 0xFFFF);
+        } while (--outFrames);
+       
+        if (frameCount0 == 0) {
+            t0.bufferProvider->releaseBuffer(&b0);
+        }
+        if (frameCount1 == 0) {
+            t1.bufferProvider->releaseBuffer(&b1);
+        }
+    }   
+       
+    if (buff != NULL) {
+        delete [] buff;       
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/libs/audioflinger/AudioMixer.h b/libs/audioflinger/AudioMixer.h
new file mode 100644
index 0000000..72ca28a
--- /dev/null
+++ b/libs/audioflinger/AudioMixer.h
@@ -0,0 +1,192 @@
+/* //device/include/server/AudioFlinger/AudioMixer.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_MIXER_H
+#define ANDROID_AUDIO_MIXER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "AudioBufferProvider.h"
+#include "AudioResampler.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ----------------------------------------------------------------------------
+
+class AudioMixer
+{
+public:
+                            AudioMixer(size_t frameCount, uint32_t sampleRate);
+
+                            ~AudioMixer();
+
+    static const uint32_t MAX_NUM_TRACKS = 32;
+    static const uint32_t MAX_NUM_CHANNELS = 2;
+
+    static const uint16_t UNITY_GAIN = 0x1000;
+
+    enum { // names
+
+        // track units (32 units)
+        TRACK0          = 0x1000,
+
+        // enable/disable
+        MIXING          = 0x2000,
+
+        // setParameter targets
+        TRACK           = 0x3000,
+        RESAMPLE        = 0x3001,
+        RAMP_VOLUME     = 0x3002, // ramp to new volume
+        VOLUME          = 0x3003, // don't ramp
+
+        // set Parameter names
+        // for target TRACK
+        CHANNEL_COUNT   = 0x4000,
+        FORMAT          = 0x4001,
+        // for TARGET RESAMPLE
+        SAMPLE_RATE     = 0x4100,
+        // for TARGET VOLUME (8 channels max)
+        VOLUME0         = 0x4200,
+        VOLUME1         = 0x4201,
+    };
+
+
+    int         getTrackName();
+    void        deleteTrackName(int name);
+
+    status_t    enable(int name);
+    status_t    disable(int name);
+
+    status_t    setActiveTrack(int track);
+    status_t    setParameter(int target, int name, int value);
+
+    status_t    setBufferProvider(AudioBufferProvider* bufferProvider);
+    void        process(void* output);
+
+    uint32_t    trackNames() const { return mTrackNames; }
+
+private:
+
+    enum {
+        NEEDS_CHANNEL_COUNT__MASK   = 0x00000003,
+        NEEDS_FORMAT__MASK          = 0x000000F0,
+        NEEDS_MUTE__MASK            = 0x00000100,
+        NEEDS_RESAMPLE__MASK        = 0x00001000,
+    };
+
+    enum {
+        NEEDS_CHANNEL_1             = 0x00000000,
+        NEEDS_CHANNEL_2             = 0x00000001,
+
+        NEEDS_FORMAT_16             = 0x00000010,
+
+        NEEDS_MUTE_DISABLED         = 0x00000000,
+        NEEDS_MUTE_ENABLED          = 0x00000100,
+
+        NEEDS_RESAMPLE_DISABLED     = 0x00000000,
+        NEEDS_RESAMPLE_ENABLED      = 0x00001000,
+    };
+
+    static inline int32_t applyVolume(int32_t in, int32_t v) {
+        return in * v;
+    }
+
+
+    struct state_t;
+
+    typedef void (*mix_t)(state_t* state, void* output);
+
+    static const int BLOCKSIZE = 16; // 4 cache lines
+
+    struct track_t {
+        uint32_t    needs;
+
+        union {
+        int16_t     volume[2];      // [0]3.12 fixed point
+        int32_t     volumeRL;
+        };
+
+        int32_t     prevVolume[2];
+
+        int32_t     volumeInc[2];
+
+        uint16_t    frameCount;
+
+        uint8_t     channelCount : 4;
+        uint8_t     enabled      : 1;
+        uint8_t     reserved0    : 3;
+        uint8_t     format;
+
+        AudioBufferProvider*                bufferProvider;
+        mutable AudioBufferProvider::Buffer buffer;
+
+        void (*hook)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp);
+        void const* in;             // current location in buffer
+
+        AudioResampler*     resampler;
+        uint32_t            sampleRate;
+
+        bool        setResampler(uint32_t sampleRate, uint32_t devSampleRate);
+        bool        doesResample() const;
+        void        adjustVolumeRamp();
+    };
+
+    // pad to 32-bytes to fill cache line
+    struct state_t {
+        uint32_t        enabledTracks;
+        uint32_t        needsChanged;
+        size_t          frameCount;
+        mix_t           hook;
+        int32_t         *outputTemp;
+        int32_t         *resampleTemp;
+        int32_t         reserved[2];
+        track_t         tracks[32]; __attribute__((aligned(32)));
+    };
+
+    int             mActiveTrack;
+    uint32_t        mTrackNames;
+    const uint32_t  mSampleRate;
+
+    state_t         mState __attribute__((aligned(32)));
+
+    void invalidateState(uint32_t mask);
+
+    static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
+    static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
+    static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp);
+    static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
+    static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
+    static void ditherAndClamp(int32_t* out, int32_t const *sums, size_t c);
+
+    static void process__validate(state_t* state, void* output);
+    static void process__nop(state_t* state, void* output);
+    static void process__genericNoResampling(state_t* state, void* output);
+    static void process__genericResampling(state_t* state, void* output);
+    static void process__OneTrack16BitsStereoNoResampling(state_t* state, void* output);
+    static void process__TwoTracks16BitsStereoNoResampling(state_t* state, void* output);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_AUDIO_MIXER_H
diff --git a/libs/audioflinger/AudioResampler.cpp b/libs/audioflinger/AudioResampler.cpp
new file mode 100644
index 0000000..5dabacb
--- /dev/null
+++ b/libs/audioflinger/AudioResampler.cpp
@@ -0,0 +1,595 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#define LOG_TAG "AudioResampler"
+//#define LOG_NDEBUG 0
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include "AudioResampler.h"
+#include "AudioResamplerSinc.h"
+#include "AudioResamplerCubic.h"
+
+namespace android {
+
+#ifdef __ARM_ARCH_5E__  // optimized asm option
+    #define ASM_ARM_RESAMP1 // enable asm optimisation for ResamplerOrder1
+#endif // __ARM_ARCH_5E__
+// ----------------------------------------------------------------------------
+
+class AudioResamplerOrder1 : public AudioResampler {
+public:
+    AudioResamplerOrder1(int bitDepth, int inChannelCount, int32_t sampleRate) :
+        AudioResampler(bitDepth, inChannelCount, sampleRate), mX0L(0), mX0R(0) {
+    }
+    virtual void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+private:
+    // number of bits used in interpolation multiply - 15 bits avoids overflow
+    static const int kNumInterpBits = 15;
+
+    // bits to shift the phase fraction down to avoid overflow
+    static const int kPreInterpShift = kNumPhaseBits - kNumInterpBits;
+
+    void init() {}
+    void resampleMono16(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+    void resampleStereo16(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
+    void AsmMono16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
+            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
+            uint32_t &phaseFraction, uint32_t phaseIncrement);
+    void AsmStereo16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
+            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
+            uint32_t &phaseFraction, uint32_t phaseIncrement);
+#endif  // ASM_ARM_RESAMP1
+
+    static inline int32_t Interp(int32_t x0, int32_t x1, uint32_t f) {
+        return x0 + (((x1 - x0) * (int32_t)(f >> kPreInterpShift)) >> kNumInterpBits);
+    }
+    static inline void Advance(size_t* index, uint32_t* frac, uint32_t inc) {
+        *frac += inc;
+        *index += (size_t)(*frac >> kNumPhaseBits);
+        *frac &= kPhaseMask;
+    }
+    int mX0L;
+    int mX0R;
+};
+
+// ----------------------------------------------------------------------------
+AudioResampler* AudioResampler::create(int bitDepth, int inChannelCount,
+        int32_t sampleRate, int quality) {
+
+    // can only create low quality resample now
+    AudioResampler* resampler;
+
+    char value[PROPERTY_VALUE_MAX];
+    if (property_get("af.resampler.quality", value, 0)) {
+        quality = atoi(value);
+        LOGD("forcing AudioResampler quality to %d", quality);
+    }
+
+    if (quality == DEFAULT)
+        quality = LOW_QUALITY;
+
+    switch (quality) {
+    default:
+    case LOW_QUALITY:
+        LOGV("Create linear Resampler");
+        resampler = new AudioResamplerOrder1(bitDepth, inChannelCount, sampleRate);
+        break;
+    case MED_QUALITY:
+        LOGV("Create cubic Resampler");
+        resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate);
+        break;
+    case HIGH_QUALITY:
+        LOGV("Create sinc Resampler");
+        resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate);
+        break;
+    }
+
+    // initialize resampler
+    resampler->init();
+    return resampler;
+}
+
+AudioResampler::AudioResampler(int bitDepth, int inChannelCount,
+        int32_t sampleRate) :
+    mBitDepth(bitDepth), mChannelCount(inChannelCount),
+            mSampleRate(sampleRate), mInSampleRate(sampleRate), mInputIndex(0),
+            mPhaseFraction(0) {
+    // sanity check on format
+    if ((bitDepth != 16) ||(inChannelCount < 1) || (inChannelCount > 2)) {
+        LOGE("Unsupported sample format, %d bits, %d channels", bitDepth,
+                inChannelCount);
+        // LOG_ASSERT(0);
+    }
+
+    // initialize common members
+    mVolume[0] = mVolume[1] = 0;
+    mBuffer.frameCount = 0;
+
+    // save format for quick lookup
+    if (inChannelCount == 1) {
+        mFormat = MONO_16_BIT;
+    } else {
+        mFormat = STEREO_16_BIT;
+    }
+}
+
+AudioResampler::~AudioResampler() {
+}
+
+void AudioResampler::setSampleRate(int32_t inSampleRate) {
+    mInSampleRate = inSampleRate;
+    mPhaseIncrement = (uint32_t)((kPhaseMultiplier * inSampleRate) / mSampleRate);
+}
+
+void AudioResampler::setVolume(int16_t left, int16_t right) {
+    // TODO: Implement anti-zipper filter
+    mVolume[0] = left;
+    mVolume[1] = right;
+}
+
+// ----------------------------------------------------------------------------
+
+void AudioResamplerOrder1::resample(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    // should never happen, but we overflow if it does
+    // LOG_ASSERT(outFrameCount < 32767);
+
+    // select the appropriate resampler
+    switch (mChannelCount) {
+    case 1:
+        resampleMono16(out, outFrameCount, provider);
+        break;
+    case 2:
+        resampleStereo16(out, outFrameCount, provider);
+        break;
+    }
+}
+
+void AudioResamplerOrder1::resampleStereo16(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    int32_t vl = mVolume[0];
+    int32_t vr = mVolume[1];
+
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    // LOGE("starting resample %d frames, inputIndex=%d, phaseFraction=%d, phaseIncrement=%d\n",
+    //      outFrameCount, inputIndex, phaseFraction, phaseIncrement);
+
+    while (outputIndex < outputSampleCount) {
+
+        // buffer is empty, fetch a new one
+        while (mBuffer.frameCount == 0) {
+            mBuffer.frameCount = inFrameCount;
+            provider->getNextBuffer(&mBuffer);
+            if (mBuffer.raw == NULL) {
+                goto resampleStereo16_exit;
+            }
+
+            // LOGE("New buffer fetched: %d frames\n", mBuffer.frameCount);
+            if (mBuffer.frameCount > inputIndex) break;
+
+            inputIndex -= mBuffer.frameCount;
+            mX0L = mBuffer.i16[mBuffer.frameCount*2-2];
+            mX0R = mBuffer.i16[mBuffer.frameCount*2-1];
+            provider->releaseBuffer(&mBuffer);
+             // mBuffer.frameCount == 0 now so we reload a new buffer
+        }
+
+        int16_t *in = mBuffer.i16;
+
+        // handle boundary case
+        while (inputIndex == 0) {
+            // LOGE("boundary case\n");
+            out[outputIndex++] += vl * Interp(mX0L, in[0], phaseFraction);
+            out[outputIndex++] += vr * Interp(mX0R, in[1], phaseFraction);
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+            if (outputIndex == outputSampleCount)
+                break;
+        }
+
+        // process input samples
+        // LOGE("general case\n");
+
+#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
+        if (inputIndex + 2 < mBuffer.frameCount) {
+            int32_t* maxOutPt;
+            int32_t maxInIdx;
+
+            maxOutPt = out + (outputSampleCount - 2);   // 2 because 2 frames per loop
+            maxInIdx = mBuffer.frameCount - 2;
+            AsmStereo16Loop(in, maxOutPt, maxInIdx, outputIndex, out, inputIndex, vl, vr,
+                    phaseFraction, phaseIncrement);
+        }
+#endif  // ASM_ARM_RESAMP1
+
+        while (outputIndex < outputSampleCount && inputIndex < mBuffer.frameCount) {
+            out[outputIndex++] += vl * Interp(in[inputIndex*2-2],
+                    in[inputIndex*2], phaseFraction);
+            out[outputIndex++] += vr * Interp(in[inputIndex*2-1],
+                    in[inputIndex*2+1], phaseFraction);
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+        }
+
+        // LOGE("loop done - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+        // if done with buffer, save samples
+        if (inputIndex >= mBuffer.frameCount) {
+            inputIndex -= mBuffer.frameCount;
+
+            // LOGE("buffer done, new input index %d", inputIndex);
+
+            mX0L = mBuffer.i16[mBuffer.frameCount*2-2];
+            mX0R = mBuffer.i16[mBuffer.frameCount*2-1];
+            provider->releaseBuffer(&mBuffer);
+
+            // verify that the releaseBuffer resets the buffer frameCount
+            // LOG_ASSERT(mBuffer.frameCount == 0);
+        }
+    }
+
+    // LOGE("output buffer full - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+resampleStereo16_exit:
+    // save state
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+void AudioResamplerOrder1::resampleMono16(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    int32_t vl = mVolume[0];
+    int32_t vr = mVolume[1];
+
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    // LOGE("starting resample %d frames, inputIndex=%d, phaseFraction=%d, phaseIncrement=%d\n",
+    //      outFrameCount, inputIndex, phaseFraction, phaseIncrement);
+    while (outputIndex < outputSampleCount) {
+        // buffer is empty, fetch a new one
+        while (mBuffer.frameCount == 0) {
+            mBuffer.frameCount = inFrameCount;
+            provider->getNextBuffer(&mBuffer);
+            if (mBuffer.raw == NULL) {
+                mInputIndex = inputIndex;
+                mPhaseFraction = phaseFraction;
+                goto resampleMono16_exit;
+            }
+            // LOGE("New buffer fetched: %d frames\n", mBuffer.frameCount);
+            if (mBuffer.frameCount >  inputIndex) break;
+
+            inputIndex -= mBuffer.frameCount;
+            mX0L = mBuffer.i16[mBuffer.frameCount-1];
+            provider->releaseBuffer(&mBuffer);
+            // mBuffer.frameCount == 0 now so we reload a new buffer
+        }
+        int16_t *in = mBuffer.i16;
+
+        // handle boundary case
+        while (inputIndex == 0) {
+            // LOGE("boundary case\n");
+            int32_t sample = Interp(mX0L, in[0], phaseFraction);
+            out[outputIndex++] += vl * sample;
+            out[outputIndex++] += vr * sample;
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+            if (outputIndex == outputSampleCount)
+                break;
+        }
+
+        // process input samples
+        // LOGE("general case\n");
+
+#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
+        if (inputIndex + 2 < mBuffer.frameCount) {
+            int32_t* maxOutPt;
+            int32_t maxInIdx;
+
+            maxOutPt = out + (outputSampleCount - 2);
+            maxInIdx = (int32_t)mBuffer.frameCount - 2;
+                AsmMono16Loop(in, maxOutPt, maxInIdx, outputIndex, out, inputIndex, vl, vr,
+                        phaseFraction, phaseIncrement);
+        }
+#endif  // ASM_ARM_RESAMP1
+
+        while (outputIndex < outputSampleCount && inputIndex < mBuffer.frameCount) {
+            int32_t sample = Interp(in[inputIndex-1], in[inputIndex],
+                    phaseFraction);
+            out[outputIndex++] += vl * sample;
+            out[outputIndex++] += vr * sample;
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+        }
+
+
+        // LOGE("loop done - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+        // if done with buffer, save samples
+        if (inputIndex >= mBuffer.frameCount) {
+            inputIndex -= mBuffer.frameCount;
+
+            // LOGE("buffer done, new input index %d", inputIndex);
+
+            mX0L = mBuffer.i16[mBuffer.frameCount-1];
+            provider->releaseBuffer(&mBuffer);
+
+            // verify that the releaseBuffer resets the buffer frameCount
+            // LOG_ASSERT(mBuffer.frameCount == 0);
+        }
+    }
+
+    // LOGE("output buffer full - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+resampleMono16_exit:
+    // save state
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
+
+/*******************************************************************
+*
+*   AsmMono16Loop
+*   asm optimized monotonic loop version; one loop is 2 frames
+*   Input:
+*       in : pointer on input samples
+*       maxOutPt : pointer on first not filled
+*       maxInIdx : index on first not used
+*       outputIndex : pointer on current output index
+*       out : pointer on output buffer
+*       inputIndex : pointer on current input index
+*       vl, vr : left and right gain
+*       phaseFraction : pointer on current phase fraction
+*       phaseIncrement
+*   Ouput:
+*       outputIndex :
+*       out : updated buffer
+*       inputIndex : index of next to use
+*       phaseFraction : phase fraction for next interpolation
+*
+*******************************************************************/
+void AudioResamplerOrder1::AsmMono16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
+            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
+            uint32_t &phaseFraction, uint32_t phaseIncrement)
+{
+#define MO_PARAM5   "36"        // offset of parameter 5 (outputIndex)
+
+    asm(
+        "stmfd  sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
+        // get parameters
+        "   ldr r6, [sp, #" MO_PARAM5 " + 20]\n"    // &phaseFraction
+        "   ldr r6, [r6]\n"                         // phaseFraction
+        "   ldr r7, [sp, #" MO_PARAM5 " + 8]\n"     // &inputIndex
+        "   ldr r7, [r7]\n"                         // inputIndex
+        "   ldr r8, [sp, #" MO_PARAM5 " + 4]\n"     // out
+        "   ldr r0, [sp, #" MO_PARAM5 " + 0]\n"     // &outputIndex
+        "   ldr r0, [r0]\n"                         // outputIndex
+        "   add r8, r0, asl #2\n"                   // curOut
+        "   ldr r9, [sp, #" MO_PARAM5 " + 24]\n"    // phaseIncrement
+        "   ldr r10, [sp, #" MO_PARAM5 " + 12]\n"   // vl
+        "   ldr r11, [sp, #" MO_PARAM5 " + 16]\n"   // vr
+
+        // r0 pin, x0, Samp
+
+        // r1 in
+        // r2 maxOutPt
+        // r3 maxInIdx
+
+        // r4 x1, i1, i3, Out1
+        // r5 out0
+
+        // r6 frac
+        // r7 inputIndex
+        // r8 curOut
+
+        // r9 inc
+        // r10 vl
+        // r11 vr
+
+        // r12
+        // r13 sp
+        // r14
+
+        // the following loop works on 2 frames
+
+        ".Y4L01:\n"
+        "   cmp r8, r2\n"                   // curOut - maxCurOut
+        "   bcs .Y4L02\n"
+
+#define MO_ONE_FRAME \
+    "   add r0, r1, r7, asl #1\n"       /* in + inputIndex */\
+    "   ldrsh r4, [r0]\n"               /* in[inputIndex] */\
+    "   ldr r5, [r8]\n"                 /* out[outputIndex] */\
+    "   ldrsh r0, [r0, #-2]\n"          /* in[inputIndex-1] */\
+    "   bic r6, r6, #0xC0000000\n"      /* phaseFraction & ... */\
+    "   sub r4, r4, r0\n"               /* in[inputIndex] - in[inputIndex-1] */\
+    "   mov r4, r4, lsl #2\n"           /* <<2 */\
+    "   smulwt r4, r4, r6\n"            /* (x1-x0)*.. */\
+    "   add r6, r6, r9\n"               /* phaseFraction + phaseIncrement */\
+    "   add r0, r0, r4\n"               /* x0 - (..) */\
+    "   mla r5, r0, r10, r5\n"          /* vl*interp + out[] */\
+    "   ldr r4, [r8, #4]\n"             /* out[outputIndex+1] */\
+    "   str r5, [r8], #4\n"             /* out[outputIndex++] = ... */\
+    "   mla r4, r0, r11, r4\n"          /* vr*interp + out[] */\
+    "   add r7, r7, r6, lsr #30\n"      /* inputIndex + phaseFraction>>30 */\
+    "   str r4, [r8], #4\n"             /* out[outputIndex++] = ... */
+
+        MO_ONE_FRAME    // frame 1
+        MO_ONE_FRAME    // frame 2
+
+        "   cmp r7, r3\n"                   // inputIndex - maxInIdx
+        "   bcc .Y4L01\n"
+        ".Y4L02:\n"
+
+        "   bic r6, r6, #0xC0000000\n"             // phaseFraction & ...
+        // save modified values
+        "   ldr r0, [sp, #" MO_PARAM5 " + 20]\n"    // &phaseFraction
+        "   str r6, [r0]\n"                         // phaseFraction
+        "   ldr r0, [sp, #" MO_PARAM5 " + 8]\n"     // &inputIndex
+        "   str r7, [r0]\n"                         // inputIndex
+        "   ldr r0, [sp, #" MO_PARAM5 " + 4]\n"     // out
+        "   sub r8, r0\n"                           // curOut - out
+        "   asr r8, #2\n"                           // new outputIndex
+        "   ldr r0, [sp, #" MO_PARAM5 " + 0]\n"     // &outputIndex
+        "   str r8, [r0]\n"                         // save outputIndex
+
+        "   ldmfd   sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc}\n"
+    );
+}
+
+/*******************************************************************
+*
+*   AsmStereo16Loop
+*   asm optimized stereo loop version; one loop is 2 frames
+*   Input:
+*       in : pointer on input samples
+*       maxOutPt : pointer on first not filled
+*       maxInIdx : index on first not used
+*       outputIndex : pointer on current output index
+*       out : pointer on output buffer
+*       inputIndex : pointer on current input index
+*       vl, vr : left and right gain
+*       phaseFraction : pointer on current phase fraction
+*       phaseIncrement
+*   Ouput:
+*       outputIndex :
+*       out : updated buffer
+*       inputIndex : index of next to use
+*       phaseFraction : phase fraction for next interpolation
+*
+*******************************************************************/
+void AudioResamplerOrder1::AsmStereo16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
+            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
+            uint32_t &phaseFraction, uint32_t phaseIncrement)
+{
+#define ST_PARAM5    "40"     // offset of parameter 5 (outputIndex)
+    asm(
+        "stmfd  sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}\n"
+        // get parameters
+        "   ldr r6, [sp, #" ST_PARAM5 " + 20]\n"    // &phaseFraction
+        "   ldr r6, [r6]\n"                         // phaseFraction
+        "   ldr r7, [sp, #" ST_PARAM5 " + 8]\n"     // &inputIndex
+        "   ldr r7, [r7]\n"                         // inputIndex
+        "   ldr r8, [sp, #" ST_PARAM5 " + 4]\n"     // out
+        "   ldr r0, [sp, #" ST_PARAM5 " + 0]\n"     // &outputIndex
+        "   ldr r0, [r0]\n"                         // outputIndex
+        "   add r8, r0, asl #2\n"                   // curOut
+        "   ldr r9, [sp, #" ST_PARAM5 " + 24]\n"    // phaseIncrement
+        "   ldr r10, [sp, #" ST_PARAM5 " + 12]\n"   // vl
+        "   ldr r11, [sp, #" ST_PARAM5 " + 16]\n"   // vr
+
+        // r0 pin, x0, Samp
+
+        // r1 in
+        // r2 maxOutPt
+        // r3 maxInIdx
+
+        // r4 x1, i1, i3, out1
+        // r5 out0
+
+        // r6 frac
+        // r7 inputIndex
+        // r8 curOut
+
+        // r9 inc
+        // r10 vl
+        // r11 vr
+
+        // r12 temporary
+        // r13 sp
+        // r14
+
+        ".Y5L01:\n"
+        "   cmp r8, r2\n"                   // curOut - maxCurOut
+        "   bcs .Y5L02\n"
+
+#define ST_ONE_FRAME \
+    "   bic r6, r6, #0xC0000000\n"      /* phaseFraction & ... */\
+\
+    "   add r0, r1, r7, asl #2\n"       /* in + 2*inputIndex */\
+\
+    "   ldrsh r4, [r0]\n"               /* in[2*inputIndex] */\
+    "   ldr r5, [r8]\n"                 /* out[outputIndex] */\
+    "   ldrsh r12, [r0, #-4]\n"         /* in[2*inputIndex-2] */\
+    "   sub r4, r4, r12\n"              /* in[2*InputIndex] - in[2*InputIndex-2] */\
+    "   mov r4, r4, lsl #2\n"           /* <<2 */\
+    "   smulwt r4, r4, r6\n"            /* (x1-x0)*.. */\
+    "   add r12, r12, r4\n"             /* x0 - (..) */\
+    "   mla r5, r12, r10, r5\n"         /* vl*interp + out[] */\
+    "   ldr r4, [r8, #4]\n"             /* out[outputIndex+1] */\
+    "   str r5, [r8], #4\n"             /* out[outputIndex++] = ... */\
+\
+    "   ldrsh r12, [r0, #+2]\n"         /* in[2*inputIndex+1] */\
+    "   ldrsh r0, [r0, #-2]\n"          /* in[2*inputIndex-1] */\
+    "   sub r12, r12, r0\n"             /* in[2*InputIndex] - in[2*InputIndex-2] */\
+    "   mov r12, r12, lsl #2\n"         /* <<2 */\
+    "   smulwt r12, r12, r6\n"          /* (x1-x0)*.. */\
+    "   add r12, r0, r12\n"             /* x0 - (..) */\
+    "   mla r4, r12, r11, r4\n"         /* vr*interp + out[] */\
+    "   str r4, [r8], #4\n"             /* out[outputIndex++] = ... */\
+\
+    "   add r6, r6, r9\n"               /* phaseFraction + phaseIncrement */\
+    "   add r7, r7, r6, lsr #30\n"      /* inputIndex + phaseFraction>>30 */
+
+    ST_ONE_FRAME    // frame 1
+    ST_ONE_FRAME    // frame 1
+
+        "   cmp r7, r3\n"                       // inputIndex - maxInIdx
+        "   bcc .Y5L01\n"
+        ".Y5L02:\n"
+
+        "   bic r6, r6, #0xC0000000\n"              // phaseFraction & ...
+        // save modified values
+        "   ldr r0, [sp, #" ST_PARAM5 " + 20]\n"    // &phaseFraction
+        "   str r6, [r0]\n"                         // phaseFraction
+        "   ldr r0, [sp, #" ST_PARAM5 " + 8]\n"     // &inputIndex
+        "   str r7, [r0]\n"                         // inputIndex
+        "   ldr r0, [sp, #" ST_PARAM5 " + 4]\n"     // out
+        "   sub r8, r0\n"                           // curOut - out
+        "   asr r8, #2\n"                           // new outputIndex
+        "   ldr r0, [sp, #" ST_PARAM5 " + 0]\n"     // &outputIndex
+        "   str r8, [r0]\n"                         // save outputIndex
+
+        "   ldmfd   sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc}\n"
+    );
+}
+
+#endif  // ASM_ARM_RESAMP1
+
+
+// ----------------------------------------------------------------------------
+}
+; // namespace android
+
diff --git a/libs/audioflinger/AudioResampler.h b/libs/audioflinger/AudioResampler.h
new file mode 100644
index 0000000..39656c0
--- /dev/null
+++ b/libs/audioflinger/AudioResampler.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 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_RESAMPLER_H
+#define ANDROID_AUDIO_RESAMPLER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "AudioBufferProvider.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class AudioResampler {
+public:
+    // Determines quality of SRC.
+    //  LOW_QUALITY: linear interpolator (1st order)
+    //  MED_QUALITY: cubic interpolator (3rd order)
+    //  HIGH_QUALITY: fixed multi-tap FIR (e.g. 48KHz->44.1KHz)
+    // NOTE: high quality SRC will only be supported for
+    // certain fixed rate conversions. Sample rate cannot be
+    // changed dynamically. 
+    enum src_quality {
+        DEFAULT=0,
+        LOW_QUALITY=1,
+        MED_QUALITY=2,
+        HIGH_QUALITY=3
+    };
+
+    static AudioResampler* create(int bitDepth, int inChannelCount,
+            int32_t sampleRate, int quality=DEFAULT);
+
+    virtual ~AudioResampler();
+
+    virtual void init() = 0;
+    virtual void setSampleRate(int32_t inSampleRate);
+    virtual void setVolume(int16_t left, int16_t right);
+
+    virtual void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider) = 0;
+
+protected:
+    // number of bits for phase fraction - 30 bits allows nearly 2x downsampling
+    static const int kNumPhaseBits = 30;
+
+    // phase mask for fraction
+    static const uint32_t kPhaseMask = (1LU<<kNumPhaseBits)-1;
+
+    // multiplier to calculate fixed point phase increment
+    static const double kPhaseMultiplier = 1L << kNumPhaseBits;
+
+    enum format {MONO_16_BIT, STEREO_16_BIT};
+    AudioResampler(int bitDepth, int inChannelCount, int32_t sampleRate);
+
+    // prevent copying
+    AudioResampler(const AudioResampler&);
+    AudioResampler& operator=(const AudioResampler&);
+
+    int32_t mBitDepth;
+    int32_t mChannelCount;
+    int32_t mSampleRate;
+    int32_t mInSampleRate;
+    AudioBufferProvider::Buffer mBuffer;
+    union {
+    	int16_t mVolume[2];
+    	uint32_t mVolumeRL;
+    };
+    int16_t mTargetVolume[2];
+    format mFormat;
+    size_t mInputIndex;
+    int32_t mPhaseIncrement;
+    uint32_t mPhaseFraction;
+};
+
+// ----------------------------------------------------------------------------
+}
+; // namespace android
+
+#endif // ANDROID_AUDIO_RESAMPLER_H
diff --git a/libs/audioflinger/AudioResamplerCubic.cpp b/libs/audioflinger/AudioResamplerCubic.cpp
new file mode 100644
index 0000000..1d247bd
--- /dev/null
+++ b/libs/audioflinger/AudioResamplerCubic.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 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 <string.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+
+#include "AudioResampler.h"
+#include "AudioResamplerCubic.h"
+
+#define LOG_TAG "AudioSRC"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+void AudioResamplerCubic::init() {
+    memset(&left, 0, sizeof(state));
+    memset(&right, 0, sizeof(state));
+}
+
+void AudioResamplerCubic::resample(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    // should never happen, but we overflow if it does
+    // LOG_ASSERT(outFrameCount < 32767);
+
+    // select the appropriate resampler
+    switch (mChannelCount) {
+    case 1:
+        resampleMono16(out, outFrameCount, provider);
+        break;
+    case 2:
+        resampleStereo16(out, outFrameCount, provider);
+        break;
+    }
+}
+
+void AudioResamplerCubic::resampleStereo16(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    int32_t vl = mVolume[0];
+    int32_t vr = mVolume[1];
+
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    // fetch first buffer
+    if (mBuffer.frameCount == 0) {
+        mBuffer.frameCount = inFrameCount;
+        provider->getNextBuffer(&mBuffer);
+        if (mBuffer.raw == NULL)
+            return;
+        // LOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount);
+    }
+    int16_t *in = mBuffer.i16;
+
+    while (outputIndex < outputSampleCount) {
+        int32_t sample;
+        int32_t x;
+
+        // calculate output sample
+        x = phaseFraction >> kPreInterpShift;
+        out[outputIndex++] += vl * interp(&left, x);
+        out[outputIndex++] += vr * interp(&right, x);
+        // out[outputIndex++] += vr * in[inputIndex*2];
+
+        // increment phase
+        phaseFraction += phaseIncrement;
+        uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits);
+        phaseFraction &= kPhaseMask;
+
+        // time to fetch another sample
+        while (indexIncrement--) {
+
+            inputIndex++;
+            if (inputIndex == mBuffer.frameCount) {
+                inputIndex = 0;
+                provider->releaseBuffer(&mBuffer);
+                mBuffer.frameCount = inFrameCount;
+                provider->getNextBuffer(&mBuffer);
+                if (mBuffer.raw == NULL)
+                    goto save_state;  // ugly, but efficient
+                in = mBuffer.i16;
+                // LOGW("New buffer: offset=%p, frames=%d\n", mBuffer.raw, mBuffer.frameCount);
+            }
+
+            // advance sample state
+            advance(&left, in[inputIndex*2]);
+            advance(&right, in[inputIndex*2+1]);
+        }
+    }
+
+save_state:
+    // LOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction);
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+void AudioResamplerCubic::resampleMono16(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    int32_t vl = mVolume[0];
+    int32_t vr = mVolume[1];
+
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    // fetch first buffer
+    if (mBuffer.frameCount == 0) {
+        mBuffer.frameCount = inFrameCount;
+        provider->getNextBuffer(&mBuffer);
+        if (mBuffer.raw == NULL)
+            return;
+        // LOGW("New buffer: offset=%p, frames=%d\n", mBuffer.raw, mBuffer.frameCount);
+    }
+    int16_t *in = mBuffer.i16;
+
+    while (outputIndex < outputSampleCount) {
+        int32_t sample;
+        int32_t x;
+
+        // calculate output sample
+        x = phaseFraction >> kPreInterpShift;
+        sample = interp(&left, x);
+        out[outputIndex++] += vl * sample;
+        out[outputIndex++] += vr * sample;
+
+        // increment phase
+        phaseFraction += phaseIncrement;
+        uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits);
+        phaseFraction &= kPhaseMask;
+
+        // time to fetch another sample
+        while (indexIncrement--) {
+
+            inputIndex++;
+            if (inputIndex == mBuffer.frameCount) {
+                inputIndex = 0;
+                provider->releaseBuffer(&mBuffer);
+                mBuffer.frameCount = inFrameCount;
+                provider->getNextBuffer(&mBuffer);
+                if (mBuffer.raw == NULL)
+                    goto save_state;  // ugly, but efficient
+                // LOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount);
+                in = mBuffer.i16;
+            }
+
+            // advance sample state
+            advance(&left, in[inputIndex]);
+        }
+    }
+
+save_state:
+    // LOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction);
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+// ----------------------------------------------------------------------------
+}
+; // namespace android
+
diff --git a/libs/audioflinger/AudioResamplerCubic.h b/libs/audioflinger/AudioResamplerCubic.h
new file mode 100644
index 0000000..b72b62a
--- /dev/null
+++ b/libs/audioflinger/AudioResamplerCubic.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 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_RESAMPLER_CUBIC_H
+#define ANDROID_AUDIO_RESAMPLER_CUBIC_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+
+#include "AudioResampler.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class AudioResamplerCubic : public AudioResampler {
+public:
+    AudioResamplerCubic(int bitDepth, int inChannelCount, int32_t sampleRate) :
+        AudioResampler(bitDepth, inChannelCount, sampleRate) {
+    }
+    virtual void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+private:
+    // number of bits used in interpolation multiply - 14 bits avoids overflow
+    static const int kNumInterpBits = 14;
+
+    // bits to shift the phase fraction down to avoid overflow
+    static const int kPreInterpShift = kNumPhaseBits - kNumInterpBits;
+    typedef struct {
+        int32_t a, b, c, y0, y1, y2, y3;
+    } state;
+    void init();
+    void resampleMono16(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+    void resampleStereo16(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+    static inline int32_t interp(state* p, int32_t x) {
+        return (((((p->a * x >> 14) + p->b) * x >> 14) + p->c) * x >> 14) + p->y1;
+    }
+    static inline void advance(state* p, int16_t in) {
+        p->y0 = p->y1;
+        p->y1 = p->y2;
+        p->y2 = p->y3;
+        p->y3 = in;
+        p->a = (3 * (p->y1 - p->y2) - p->y0 + p->y3) >> 1;            
+        p->b = (p->y2 << 1) + p->y0 - (((5 * p->y1 + p->y3)) >> 1);
+        p->c = (p->y2 - p->y0) >> 1;
+    }
+    state left, right;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif /*ANDROID_AUDIO_RESAMPLER_CUBIC_H*/
diff --git a/libs/audioflinger/AudioResamplerSinc.cpp b/libs/audioflinger/AudioResamplerSinc.cpp
new file mode 100644
index 0000000..9e5e254
--- /dev/null
+++ b/libs/audioflinger/AudioResamplerSinc.cpp
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 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 <string.h>
+#include "AudioResamplerSinc.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+
+/*
+ * These coeficients are computed with the "fir" utility found in
+ * tools/resampler_tools
+ * TODO: A good optimization would be to transpose this matrix, to take
+ * better advantage of the data-cache.
+ */
+const int32_t AudioResamplerSinc::mFirCoefsUp[] = {
+        0x7fffffff, 0x7f15d078, 0x7c5e0da6, 0x77ecd867, 0x71e2e251, 0x6a6c304a, 0x61be7269, 0x58170412, 0x4db8ab05, 0x42e92ea6, 0x37eee214, 0x2d0e3bb1, 0x22879366, 0x18951e95, 0x0f693d0d, 0x072d2621,
+        0x00000000, 0xf9f66655, 0xf51a5fd7, 0xf16bbd84, 0xeee0d9ac, 0xed67a922, 0xece70de6, 0xed405897, 0xee50e505, 0xeff3be30, 0xf203370f, 0xf45a6741, 0xf6d67d53, 0xf957db66, 0xfbc2f647, 0xfe00f2b9,
+        0x00000000, 0x01b37218, 0x0313a0c6, 0x041d930d, 0x04d28057, 0x053731b0, 0x05534dff, 0x05309bfd, 0x04da440d, 0x045c1aee, 0x03c1fcdd, 0x03173ef5, 0x02663ae8, 0x01b7f736, 0x0113ec79, 0x007fe6a9,
+        0x00000000, 0xff96b229, 0xff44f99f, 0xff0a86be, 0xfee5f803, 0xfed518fd, 0xfed521fd, 0xfee2f4fd, 0xfefb54f8, 0xff1b159b, 0xff3f4203, 0xff6539e0, 0xff8ac502, 0xffae1ddd, 0xffcdf3f9, 0xffe96798,
+        0x00000000, 0x00119de6, 0x001e6b7e, 0x0026cb7a, 0x002b4830, 0x002c83d6, 0x002b2a82, 0x0027e67a, 0x002356f9, 0x001e098e, 0x001875e4, 0x0012fbbe, 0x000de2d1, 0x00095c10, 0x00058414, 0x00026636,
+        0x00000000, 0xfffe44a9, 0xfffd206d, 0xfffc7b7f, 0xfffc3c8f, 0xfffc4ac2, 0xfffc8f2b, 0xfffcf5c4, 0xfffd6df3, 0xfffdeab2, 0xfffe6275, 0xfffececf, 0xffff2c07, 0xffff788c, 0xffffb471, 0xffffe0f2,
+        0x00000000, 0x000013e6, 0x00001f03, 0x00002396, 0x00002399, 0x000020b6, 0x00001c3c, 0x00001722, 0x00001216, 0x00000d81, 0x0000099c, 0x0000067c, 0x00000419, 0x0000025f, 0x00000131, 0x00000070,
+        0x00000000, 0xffffffc7, 0xffffffb3, 0xffffffb3, 0xffffffbe, 0xffffffcd, 0xffffffdb, 0xffffffe7, 0xfffffff0, 0xfffffff7, 0xfffffffb, 0xfffffffe, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
+        0x00000000 // this one is needed for lerping the last coefficient
+};
+
+/*
+ * These coefficients are optimized for 48KHz -> 44.1KHz (stop-band at 22.050KHz)
+ * It's possible to use the above coefficient for any down-sampling
+ * at the expense of a slower processing loop (we can interpolate
+ * these coefficient from the above by "Stretching" them in time).
+ */
+const int32_t AudioResamplerSinc::mFirCoefsDown[] = {
+        0x7fffffff, 0x7f55e46d, 0x7d5b4c60, 0x7a1b4b98, 0x75a7fb14, 0x7019f0bd, 0x698f875a, 0x622bfd59, 0x5a167256, 0x5178cc54, 0x487e8e6c, 0x3f53aae8, 0x36235ad4, 0x2d17047b, 0x245539ab, 0x1c00d540,
+        0x14383e57, 0x0d14d5ca, 0x06aa910b, 0x0107c38b, 0xfc351654, 0xf835abae, 0xf5076b45, 0xf2a37202, 0xf0fe9faa, 0xf00a3bbd, 0xefb4aa81, 0xefea2b05, 0xf0959716, 0xf1a11e83, 0xf2f6f7a0, 0xf481fff4,
+        0xf62e48ce, 0xf7e98ca5, 0xf9a38b4c, 0xfb4e4bfa, 0xfcde456f, 0xfe4a6d30, 0xff8c2fdf, 0x009f5555, 0x0181d393, 0x0233940f, 0x02b62f06, 0x030ca07d, 0x033afa62, 0x03461725, 0x03334f83, 0x030835fa,
+        0x02ca59cc, 0x027f12d1, 0x022b570d, 0x01d39a49, 0x017bb78f, 0x0126e414, 0x00d7aaaf, 0x008feec7, 0x0050f584, 0x001b73e3, 0xffefa063, 0xffcd46ed, 0xffb3ddcd, 0xffa29aaa, 0xff988691, 0xff949066,
+        0xff959d24, 0xff9a959e, 0xffa27195, 0xffac4011, 0xffb72d2b, 0xffc28569, 0xffcdb706, 0xffd85171, 0xffe20364, 0xffea97e9, 0xfff1f2b2, 0xfff80c06, 0xfffcec92, 0x0000a955, 0x00035fd8, 0x000532cf,
+        0x00064735, 0x0006c1f9, 0x0006c62d, 0x000673ba, 0x0005e68f, 0x00053630, 0x000475a3, 0x0003b397, 0x0002fac1, 0x00025257, 0x0001be9e, 0x0001417a, 0x0000dafd, 0x000089eb, 0x00004c28, 0x00001f1d,
+        0x00000000, 0xffffec10, 0xffffe0be, 0xffffdbc5, 0xffffdb39, 0xffffdd8b, 0xffffe182, 0xffffe638, 0xffffeb0a, 0xffffef8f, 0xfffff38b, 0xfffff6e3, 0xfffff993, 0xfffffba6, 0xfffffd30, 0xfffffe4a,
+        0xffffff09, 0xffffff85, 0xffffffd1, 0xfffffffb, 0x0000000f, 0x00000016, 0x00000015, 0x00000012, 0x0000000d, 0x00000009, 0x00000006, 0x00000003, 0x00000002, 0x00000001, 0x00000000, 0x00000000,
+        0x00000000 // this one is needed for lerping the last coefficient
+};
+
+// ----------------------------------------------------------------------------
+
+static inline
+int32_t mulRL(int left, int32_t in, uint32_t vRL)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    if (left) {
+        asm( "smultb %[out], %[in], %[vRL] \n"
+             : [out]"=r"(out)
+             : [in]"%r"(in), [vRL]"r"(vRL)
+             : );
+    } else {
+        asm( "smultt %[out], %[in], %[vRL] \n"
+             : [out]"=r"(out)
+             : [in]"%r"(in), [vRL]"r"(vRL)
+             : );
+    }
+    return out;
+#else
+    if (left) {
+        return int16_t(in>>16) * int16_t(vRL&0xFFFF);
+    } else {
+        return int16_t(in>>16) * int16_t(vRL>>16);
+    }
+#endif
+}
+
+static inline
+int32_t mulAdd(int16_t in, int32_t v, int32_t a)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    asm( "smlawb %[out], %[v], %[in], %[a] \n"
+         : [out]"=r"(out)
+         : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
+         : );
+    return out;
+#else
+    return a + in * (v>>16);
+    // improved precision
+    // return a + in * (v>>16) + ((in * (v & 0xffff)) >> 16);
+#endif
+}
+
+static inline
+int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    if (left) {
+        asm( "smlawb %[out], %[v], %[inRL], %[a] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
+             : );
+    } else {
+        asm( "smlawt %[out], %[v], %[inRL], %[a] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
+             : );
+    }
+    return out;
+#else
+    if (left) {
+        return a + (int16_t(inRL&0xFFFF) * (v>>16));
+        //improved precision
+        // return a + (int16_t(inRL&0xFFFF) * (v>>16)) + ((int16_t(inRL&0xFFFF) * (v & 0xffff)) >> 16);
+    } else {
+        return a + (int16_t(inRL>>16) * (v>>16));
+    }
+#endif
+}
+
+// ----------------------------------------------------------------------------
+
+AudioResamplerSinc::AudioResamplerSinc(int bitDepth,
+        int inChannelCount, int32_t sampleRate)
+    : AudioResampler(bitDepth, inChannelCount, sampleRate),
+    mState(0)
+{
+    /*
+     * Layout of the state buffer for 32 tap:
+     *
+     * "present" sample            beginning of 2nd buffer
+     *                 v                v
+     *  0              01               2              23              3
+     *  0              F0               0              F0              F
+     * [pppppppppppppppInnnnnnnnnnnnnnnnpppppppppppppppInnnnnnnnnnnnnnnn]
+     *                 ^               ^ head
+     *
+     * p = past samples, convoluted with the (p)ositive side of sinc()
+     * n = future samples, convoluted with the (n)egative side of sinc()
+     * r = extra space for implementing the ring buffer
+     *
+     */
+
+    const size_t numCoefs = 2*halfNumCoefs;
+    const size_t stateSize = numCoefs * inChannelCount * 2;
+    mState = new int16_t[stateSize];
+    memset(mState, 0, sizeof(int16_t)*stateSize);
+    mImpulse = mState + (halfNumCoefs-1)*inChannelCount;
+    mRingFull = mImpulse + (numCoefs+1)*inChannelCount;
+}
+
+AudioResamplerSinc::~AudioResamplerSinc()
+{
+    delete [] mState;
+}
+
+void AudioResamplerSinc::init() {
+}
+
+void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider)
+{
+    mFirCoefs = (mInSampleRate <= mSampleRate) ? mFirCoefsUp : mFirCoefsDown;
+
+    // select the appropriate resampler
+    switch (mChannelCount) {
+    case 1:
+        resample<1>(out, outFrameCount, provider);
+        break;
+    case 2:
+        resample<2>(out, outFrameCount, provider);
+        break;
+    }
+}
+
+
+template<int CHANNELS>
+void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider)
+{
+    int16_t* impulse = mImpulse;
+    uint32_t vRL = mVolumeRL;
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    AudioBufferProvider::Buffer& buffer(mBuffer);
+    while (outputIndex < outputSampleCount) {
+        // buffer is empty, fetch a new one
+        while (buffer.frameCount == 0) {
+            buffer.frameCount = inFrameCount;
+            provider->getNextBuffer(&buffer);
+            if (buffer.raw == NULL) {
+                goto resample_exit;
+            }
+            const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
+            if (phaseIndex == 1) {
+                // read one frame
+                read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
+            } else if (phaseIndex == 2) {
+                // read 2 frames
+                read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
+                inputIndex++;
+                if (inputIndex >= mBuffer.frameCount) {
+                    inputIndex -= mBuffer.frameCount;
+                    provider->releaseBuffer(&buffer);
+                } else {
+                    read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
+                }
+           }
+        }
+        int16_t *in = buffer.i16;
+        const size_t frameCount = buffer.frameCount;
+
+        // Always read-in the first samples from the input buffer
+        int16_t* head = impulse + halfNumCoefs*CHANNELS;
+        head[0] = in[inputIndex*CHANNELS + 0];
+        if (CHANNELS == 2)
+            head[1] = in[inputIndex*CHANNELS + 1];
+
+        // handle boundary case
+        int32_t l, r;
+        while (outputIndex < outputSampleCount) {
+            filterCoefficient<CHANNELS>(l, r, phaseFraction, impulse);
+            out[outputIndex++] += 2 * mulRL(1, l, vRL);
+            out[outputIndex++] += 2 * mulRL(0, r, vRL);
+
+            phaseFraction += phaseIncrement;
+            const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
+            if (phaseIndex == 1) {
+                inputIndex++;
+                if (inputIndex >= frameCount)
+                    break;  // need a new buffer
+                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
+            } else if(phaseIndex == 2) {    // maximum value
+                inputIndex++;
+                if (inputIndex >= frameCount)
+                    break;  // 0 frame available, 2 frames needed
+                // read first frame
+                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
+                inputIndex++;
+                if (inputIndex >= frameCount)
+                    break;  // 0 frame available, 1 frame needed
+                // read second frame
+                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
+            }
+        }
+
+        // if done with buffer, save samples
+        if (inputIndex >= frameCount) {
+            inputIndex -= frameCount;
+            provider->releaseBuffer(&buffer);
+        }
+    }
+
+resample_exit:
+    mImpulse = impulse;
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+template<int CHANNELS>
+/***
+* read()
+*
+* This function reads only one frame from input buffer and writes it in
+* state buffer
+*
+**/
+void AudioResamplerSinc::read(
+        int16_t*& impulse, uint32_t& phaseFraction,
+        int16_t const* in, size_t inputIndex)
+{
+    const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
+    impulse += CHANNELS;
+    phaseFraction -= 1LU<<kNumPhaseBits;
+    if (impulse >= mRingFull) {
+        const size_t stateSize = (halfNumCoefs*2)*CHANNELS;
+        memcpy(mState, mState+stateSize, sizeof(int16_t)*stateSize);
+        impulse -= stateSize;
+    }
+    int16_t* head = impulse + halfNumCoefs*CHANNELS;
+    head[0] = in[inputIndex*CHANNELS + 0];
+    if (CHANNELS == 2)
+        head[1] = in[inputIndex*CHANNELS + 1];
+}
+
+template<int CHANNELS>
+void AudioResamplerSinc::filterCoefficient(
+        int32_t& l, int32_t& r, uint32_t phase, int16_t const *samples)
+{
+    // compute the index of the coefficient on the positive side and
+    // negative side
+    uint32_t indexP = (phase & cMask) >> cShift;
+    uint16_t lerpP  = (phase & pMask) >> pShift;
+    uint32_t indexN = (-phase & cMask) >> cShift;
+    uint16_t lerpN  = (-phase & pMask) >> pShift;
+    if ((indexP == 0) && (lerpP == 0)) {
+        indexN = cMask >> cShift;
+        lerpN = pMask >> pShift;
+    }
+
+    l = 0;
+    r = 0;
+    int32_t const* coefs = mFirCoefs;
+    int16_t const *sP = samples;
+    int16_t const *sN = samples+CHANNELS;
+    for (unsigned int i=0 ; i<halfNumCoefs/4 ; i++) {
+        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
+        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
+        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
+        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
+        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
+        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
+        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
+        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
+        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
+        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
+        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
+        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
+    }
+}
+
+template<int CHANNELS>
+void AudioResamplerSinc::interpolate(
+        int32_t& l, int32_t& r,
+        int32_t const* coefs, int16_t lerp, int16_t const* samples)
+{
+    int32_t c0 = coefs[0];
+    int32_t c1 = coefs[1];
+    int32_t sinc = mulAdd(lerp, (c1-c0)<<1, c0);
+    if (CHANNELS == 2) {
+        uint32_t rl = *reinterpret_cast<uint32_t const*>(samples);
+        l = mulAddRL(1, rl, sinc, l);
+        r = mulAddRL(0, rl, sinc, r);
+    } else {
+        r = l = mulAdd(samples[0], sinc, l);
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/libs/audioflinger/AudioResamplerSinc.h b/libs/audioflinger/AudioResamplerSinc.h
new file mode 100644
index 0000000..e6cb90b
--- /dev/null
+++ b/libs/audioflinger/AudioResamplerSinc.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 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_RESAMPLER_SINC_H
+#define ANDROID_AUDIO_RESAMPLER_SINC_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+
+#include "AudioResampler.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class AudioResamplerSinc : public AudioResampler {
+public:
+    AudioResamplerSinc(int bitDepth, int inChannelCount, int32_t sampleRate);
+
+    ~AudioResamplerSinc();
+
+    virtual void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+private:
+    void init();
+
+    template<int CHANNELS>
+    void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+
+    template<int CHANNELS>
+    inline void filterCoefficient(
+            int32_t& l, int32_t& r, uint32_t phase, int16_t const *samples);
+
+    template<int CHANNELS>
+    inline void interpolate(
+            int32_t& l, int32_t& r,
+            int32_t const* coefs, int16_t lerp, int16_t const* samples);
+
+    template<int CHANNELS>
+    inline void read(int16_t*& impulse, uint32_t& phaseFraction,
+            int16_t const* in, size_t inputIndex);
+
+    int16_t *mState;
+    int16_t *mImpulse;
+    int16_t *mRingFull;
+
+    int32_t const * mFirCoefs;
+    static const int32_t mFirCoefsDown[];
+    static const int32_t mFirCoefsUp[];
+
+    // ----------------------------------------------------------------------------
+    static const int32_t RESAMPLE_FIR_NUM_COEF       = 8;
+    static const int32_t RESAMPLE_FIR_LERP_INT_BITS  = 4;
+
+    // we have 16 coefs samples per zero-crossing
+    static const int coefsBits = RESAMPLE_FIR_LERP_INT_BITS;        // 4
+    static const int cShift = kNumPhaseBits - coefsBits;            // 26
+    static const uint32_t cMask  = ((1<<coefsBits)-1) << cShift;    // 0xf<<26 = 3c00 0000
+
+    // and we use 15 bits to interpolate between these samples
+    // this cannot change because the mul below rely on it.
+    static const int pLerpBits = 15;
+    static const int pShift = kNumPhaseBits - coefsBits - pLerpBits;    // 11
+    static const uint32_t pMask  = ((1<<pLerpBits)-1) << pShift;    // 0x7fff << 11
+
+    // number of zero-crossing on each side
+    static const unsigned int halfNumCoefs = RESAMPLE_FIR_NUM_COEF;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif /*ANDROID_AUDIO_RESAMPLER_SINC_H*/
