diff --git a/media/libmediaplayerservice/MidiFile.cpp b/media/libmediaplayerservice/MidiFile.cpp
new file mode 100644
index 0000000..d03caa5
--- /dev/null
+++ b/media/libmediaplayerservice/MidiFile.cpp
@@ -0,0 +1,558 @@
+/* MidiFile.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_NDEBUG 0
+#define LOG_TAG "MidiFile"
+#include "utils/Log.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sched.h>
+#include <utils/threads.h>
+#include <libsonivox/eas_reverb.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "MidiFile.h"
+
+#ifdef HAVE_GETTID
+static pid_t myTid() { return gettid(); }
+#else
+static pid_t myTid() { return getpid(); }
+#endif
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+// The midi engine buffers are a bit small (128 frames), so we batch them up
+static const int NUM_BUFFERS = 4;
+
+// TODO: Determine appropriate return codes
+static status_t ERROR_NOT_OPEN = -1;
+static status_t ERROR_OPEN_FAILED = -2;
+static status_t ERROR_EAS_FAILURE = -3;
+static status_t ERROR_ALLOCATE_FAILED = -4;
+
+static const S_EAS_LIB_CONFIG* pLibConfig = NULL;
+
+MidiFile::MidiFile() :
+    mEasData(NULL), mEasHandle(NULL), mAudioBuffer(NULL),
+    mPlayTime(-1), mDuration(-1), mState(EAS_STATE_ERROR),
+    mStreamType(AudioSystem::MUSIC), mLoop(false), mExit(false),
+    mPaused(false), mRender(false), mTid(-1)
+{
+    LOGV("constructor");
+
+    mFileLocator.path = NULL;
+    mFileLocator.fd = -1;
+    mFileLocator.offset = 0;
+    mFileLocator.length = 0;
+
+    // get the library configuration and do sanity check
+    if (pLibConfig == NULL)
+        pLibConfig = EAS_Config();
+    if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) {
+        LOGE("EAS library/header mismatch");
+        goto Failed;
+    }
+
+    // initialize EAS library
+    if (EAS_Init(&mEasData) != EAS_SUCCESS) {
+        LOGE("EAS_Init failed");
+        goto Failed;
+    }
+
+    // select reverb preset and enable
+    EAS_SetParameter(mEasData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_PRESET, EAS_PARAM_REVERB_CHAMBER);
+    EAS_SetParameter(mEasData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_BYPASS, EAS_FALSE);
+
+    // create playback thread
+    {
+        Mutex::Autolock l(mMutex);
+        createThreadEtc(renderThread, this, "midithread");
+        mCondition.wait(mMutex);
+        LOGV("thread started");
+    }
+
+    // indicate success
+    if (mTid > 0) {
+        LOGV(" render thread(%d) started", mTid);
+        mState = EAS_STATE_READY;
+    }
+
+Failed:
+    return;
+}
+
+status_t MidiFile::initCheck()
+{
+    if (mState == EAS_STATE_ERROR) return ERROR_EAS_FAILURE;
+    return NO_ERROR;
+}
+
+MidiFile::~MidiFile() {
+    LOGV("MidiFile destructor");
+    release();
+}
+
+status_t MidiFile::setDataSource(const char* path)
+{
+    LOGV("MidiFile::setDataSource url=%s", path);
+    Mutex::Autolock lock(mMutex);
+
+    // file still open?
+    if (mEasHandle) {
+        reset_nosync();
+    }
+
+    // open file and set paused state
+    mFileLocator.path = strdup(path);
+    mFileLocator.fd = -1;
+    mFileLocator.offset = 0;
+    mFileLocator.length = 0;
+    EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle);
+    if (result == EAS_SUCCESS) {
+        updateState();
+    }
+
+    if (result != EAS_SUCCESS) {
+        LOGE("EAS_OpenFile failed: [%d]", (int)result);
+        mState = EAS_STATE_ERROR;
+        return ERROR_OPEN_FAILED;
+    }
+
+    mState = EAS_STATE_OPEN;
+    mPlayTime = 0;
+    return NO_ERROR;
+}
+
+status_t MidiFile::setDataSource(int fd, int64_t offset, int64_t length)
+{
+    LOGV("MidiFile::setDataSource fd=%d", fd);
+    Mutex::Autolock lock(mMutex);
+
+    // file still open?
+    if (mEasHandle) {
+        reset_nosync();
+    }
+
+    // open file and set paused state
+    mFileLocator.fd = dup(fd);
+    mFileLocator.offset = offset;
+    mFileLocator.length = length;
+    EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle);
+    updateState();
+
+    if (result != EAS_SUCCESS) {
+        LOGE("EAS_OpenFile failed: [%d]", (int)result);
+        mState = EAS_STATE_ERROR;
+        return ERROR_OPEN_FAILED;
+    }
+
+    mState = EAS_STATE_OPEN;
+    mPlayTime = 0;
+    return NO_ERROR;
+}
+
+status_t MidiFile::prepare()
+{
+    LOGV("MidiFile::prepare");
+    Mutex::Autolock lock(mMutex);
+    if (!mEasHandle) {
+        return ERROR_NOT_OPEN;
+    }
+    EAS_RESULT result;
+    if ((result = EAS_Prepare(mEasData, mEasHandle)) != EAS_SUCCESS) {
+        LOGE("EAS_Prepare failed: [%ld]", result);
+        return ERROR_EAS_FAILURE;
+    }
+    updateState();
+    return NO_ERROR;
+}
+
+status_t MidiFile::prepareAsync()
+{
+    LOGV("MidiFile::prepareAsync");
+    status_t ret = prepare();
+
+    // don't hold lock during callback
+    if (ret == NO_ERROR) {
+        sendEvent(MEDIA_PREPARED);
+    } else {
+        sendEvent(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ret);
+    }
+    return ret;
+}
+
+status_t MidiFile::start()
+{
+    LOGV("MidiFile::start");
+    Mutex::Autolock lock(mMutex);
+    if (!mEasHandle) {
+        return ERROR_NOT_OPEN;
+    }
+
+    // resuming after pause?
+    if (mPaused) {
+        if (EAS_Resume(mEasData, mEasHandle) != EAS_SUCCESS) {
+            return ERROR_EAS_FAILURE;
+        }
+        mPaused = false;
+        updateState();
+    }
+
+    mRender = true;
+
+    // wake up render thread
+    LOGV("  wakeup render thread");
+    mCondition.signal();
+    return NO_ERROR;
+}
+
+status_t MidiFile::stop()
+{
+    LOGV("MidiFile::stop");
+    Mutex::Autolock lock(mMutex);
+    if (!mEasHandle) {
+        return ERROR_NOT_OPEN;
+    }
+    if (!mPaused && (mState != EAS_STATE_STOPPED)) {
+        EAS_RESULT result = EAS_Pause(mEasData, mEasHandle);
+        if (result != EAS_SUCCESS) {
+            LOGE("EAS_Pause returned error %ld", result);
+            return ERROR_EAS_FAILURE;
+        }
+    }
+    mPaused = false;
+    return NO_ERROR;
+}
+
+status_t MidiFile::seekTo(int position)
+{
+    LOGV("MidiFile::seekTo %d", position);
+    // hold lock during EAS calls
+    {
+        Mutex::Autolock lock(mMutex);
+        if (!mEasHandle) {
+            return ERROR_NOT_OPEN;
+        }
+        EAS_RESULT result;
+        if ((result = EAS_Locate(mEasData, mEasHandle, position, false))
+                != EAS_SUCCESS)
+        {
+            LOGE("EAS_Locate returned %ld", result);
+            return ERROR_EAS_FAILURE;
+        }
+        EAS_GetLocation(mEasData, mEasHandle, &mPlayTime);
+    }
+    sendEvent(MEDIA_SEEK_COMPLETE);
+    return NO_ERROR;
+}
+
+status_t MidiFile::pause()
+{
+    LOGV("MidiFile::pause");
+    Mutex::Autolock lock(mMutex);
+    if (!mEasHandle) {
+        return ERROR_NOT_OPEN;
+    }
+    if ((mState == EAS_STATE_PAUSING) || (mState == EAS_STATE_PAUSED)) return NO_ERROR;
+    if (EAS_Pause(mEasData, mEasHandle) != EAS_SUCCESS) {
+        return ERROR_EAS_FAILURE;
+    }
+    mPaused = true;
+    return NO_ERROR;
+}
+
+bool MidiFile::isPlaying()
+{
+    LOGV("MidiFile::isPlaying, mState=%d", int(mState));
+    if (!mEasHandle || mPaused) return false;
+    return (mState == EAS_STATE_PLAY);
+}
+
+status_t MidiFile::getCurrentPosition(int* position)
+{
+    LOGV("MidiFile::getCurrentPosition");
+    if (!mEasHandle) {
+        LOGE("getCurrentPosition(): file not open");
+        return ERROR_NOT_OPEN;
+    }
+    if (mPlayTime < 0) {
+        LOGE("getCurrentPosition(): mPlayTime = %ld", mPlayTime);
+        return ERROR_EAS_FAILURE;
+    }
+    *position = mPlayTime;
+    return NO_ERROR;
+}
+
+status_t MidiFile::getDuration(int* duration)
+{
+
+    LOGV("MidiFile::getDuration");
+    {
+        Mutex::Autolock lock(mMutex);
+        if (!mEasHandle) return ERROR_NOT_OPEN;
+        *duration = mDuration;
+    }
+
+    // if no duration cached, get the duration
+    // don't need a lock here because we spin up a new engine
+    if (*duration < 0) {
+        EAS_I32 temp;
+        EAS_DATA_HANDLE easData = NULL;
+        EAS_HANDLE easHandle = NULL;
+        EAS_RESULT result = EAS_Init(&easData);
+        if (result == EAS_SUCCESS) {
+            result = EAS_OpenFile(easData, &mFileLocator, &easHandle);
+        }
+        if (result == EAS_SUCCESS) {
+            result = EAS_Prepare(easData, easHandle);
+        }
+        if (result == EAS_SUCCESS) {
+            result = EAS_ParseMetaData(easData, easHandle, &temp);
+        }
+        if (easHandle) {
+            EAS_CloseFile(easData, easHandle);
+        }
+        if (easData) {
+            EAS_Shutdown(easData);
+        }
+
+        if (result != EAS_SUCCESS) {
+            return ERROR_EAS_FAILURE;
+        }
+
+        // cache successful result
+        mDuration = *duration = int(temp);
+    }
+
+    return NO_ERROR;
+}
+
+status_t MidiFile::release()
+{
+    LOGV("MidiFile::release");
+    Mutex::Autolock l(mMutex);
+    reset_nosync();
+
+    // wait for render thread to exit
+    mExit = true;
+    mCondition.signal();
+
+    // wait for thread to exit
+    if (mAudioBuffer) {
+        mCondition.wait(mMutex);
+    }
+
+    // release resources
+    if (mEasData) {
+        EAS_Shutdown(mEasData);
+        mEasData = NULL;
+    }
+    return NO_ERROR;
+}
+
+status_t MidiFile::reset()
+{
+    LOGV("MidiFile::reset");
+    Mutex::Autolock lock(mMutex);
+    return reset_nosync();
+}
+
+// call only with mutex held
+status_t MidiFile::reset_nosync()
+{
+    LOGV("MidiFile::reset_nosync");
+    // close file
+    if (mEasHandle) {
+        EAS_CloseFile(mEasData, mEasHandle);
+        mEasHandle = NULL;
+    }
+    if (mFileLocator.path) {
+        free((void*)mFileLocator.path);
+        mFileLocator.path = NULL;
+    }
+    if (mFileLocator.fd >= 0) {
+        close(mFileLocator.fd);
+    }
+    mFileLocator.fd = -1;
+    mFileLocator.offset = 0;
+    mFileLocator.length = 0;
+
+    mPlayTime = -1;
+    mDuration = -1;
+    mLoop = false;
+    mPaused = false;
+    mRender = false;
+    return NO_ERROR;
+}
+
+status_t MidiFile::setLooping(int loop)
+{
+    LOGV("MidiFile::setLooping");
+    Mutex::Autolock lock(mMutex);
+    if (!mEasHandle) {
+        return ERROR_NOT_OPEN;
+    }
+    loop = loop ? -1 : 0;
+    if (EAS_SetRepeat(mEasData, mEasHandle, loop) != EAS_SUCCESS) {
+        return ERROR_EAS_FAILURE;
+    }
+    return NO_ERROR;
+}
+
+status_t MidiFile::createOutputTrack() {
+    if (mAudioSink->open(pLibConfig->sampleRate, pLibConfig->numChannels, AudioSystem::PCM_16_BIT, 2) != NO_ERROR) {
+        LOGE("mAudioSink open failed");
+        return ERROR_OPEN_FAILED;
+    }
+    return NO_ERROR;
+}
+
+int MidiFile::renderThread(void* p) {
+
+    return ((MidiFile*)p)->render();
+}
+
+int MidiFile::render() {
+    EAS_RESULT result = EAS_FAILURE;
+    EAS_I32 count;
+    int temp;
+    bool audioStarted = false;
+
+    LOGV("MidiFile::render");
+
+    // allocate render buffer
+    mAudioBuffer = new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * NUM_BUFFERS];
+    if (!mAudioBuffer) {
+        LOGE("mAudioBuffer allocate failed");
+        goto threadExit;
+    }
+
+    // signal main thread that we started
+    {
+        Mutex::Autolock l(mMutex);
+        mTid = myTid();
+        LOGV("render thread(%d) signal", mTid);
+        mCondition.signal();
+    }
+
+    while (1) {
+        mMutex.lock();
+
+        // nothing to render, wait for client thread to wake us up
+        while (!mRender && !mExit)
+        {
+            LOGV("MidiFile::render - signal wait");
+            mCondition.wait(mMutex);
+            LOGV("MidiFile::render - signal rx'd");
+        }
+        if (mExit) {
+            mMutex.unlock();
+            break;
+        }
+
+        // render midi data into the input buffer
+        //LOGV("MidiFile::render - rendering audio");
+        int num_output = 0;
+        EAS_PCM* p = mAudioBuffer;
+        for (int i = 0; i < NUM_BUFFERS; i++) {
+            result = EAS_Render(mEasData, p, pLibConfig->mixBufferSize, &count);
+            if (result != EAS_SUCCESS) {
+                LOGE("EAS_Render returned %ld", result);
+            }
+            p += count * pLibConfig->numChannels;
+            num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM);
+        }
+
+        // update playback state and position
+        // LOGV("MidiFile::render - updating state");
+        EAS_GetLocation(mEasData, mEasHandle, &mPlayTime);
+        EAS_State(mEasData, mEasHandle, &mState);
+        mMutex.unlock();
+
+        // create audio output track if necessary
+        if (!mAudioSink->ready()) {
+            LOGV("MidiFile::render - create output track");
+            if (createOutputTrack() != NO_ERROR)
+                goto threadExit;
+        }
+
+        // Write data to the audio hardware
+        // LOGV("MidiFile::render - writing to audio output");
+        if ((temp = mAudioSink->write(mAudioBuffer, num_output)) < 0) {
+            LOGE("Error in writing:%d",temp);
+            return temp;
+        }
+
+        // start audio output if necessary
+        if (!audioStarted) {
+            //LOGV("MidiFile::render - starting audio");
+            mAudioSink->start();
+            audioStarted = true;
+        }
+
+        // still playing?
+        if ((mState == EAS_STATE_STOPPED) || (mState == EAS_STATE_ERROR) ||
+                (mState == EAS_STATE_PAUSED))
+        {
+            switch(mState) {
+            case EAS_STATE_STOPPED:
+            {
+                LOGV("MidiFile::render - stopped");
+                sendEvent(MEDIA_PLAYBACK_COMPLETE);
+                break;
+            }
+            case EAS_STATE_ERROR:
+            {
+                LOGE("MidiFile::render - error");
+                sendEvent(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN);
+                break;
+            }
+            case EAS_STATE_PAUSED:
+                LOGV("MidiFile::render - paused");
+                break;
+            default:
+                break;
+            }
+            mAudioSink->stop();
+            audioStarted = false;
+            mRender = false;
+        }
+    }
+
+threadExit:
+    mAudioSink.clear();
+    if (mAudioBuffer) {
+        delete [] mAudioBuffer;
+        mAudioBuffer = NULL;
+    }
+    mMutex.lock();
+    mTid = -1;
+    mCondition.signal();
+    mMutex.unlock();
+    return result;
+}
+
+} // end namespace android
