MidiFile.cpp revision fce7a473248381cc83a01855f92581077d3c9ee2
189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/* MidiFile.cpp 289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** 389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Copyright 2007, The Android Open Source Project 489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** 589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** you may not use this file except in compliance with the License. 789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** You may obtain a copy of the License at 889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** 989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** 1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** See the License for the specific language governing permissions and 1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** limitations under the License. 1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project*/ 1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//#define LOG_NDEBUG 0 1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LOG_TAG "MidiFile" 2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "utils/Log.h" 2189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <stdio.h> 2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <assert.h> 2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <limits.h> 2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <unistd.h> 2689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <fcntl.h> 2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sched.h> 2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/threads.h> 2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <libsonivox/eas_reverb.h> 3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/types.h> 3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/stat.h> 3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 33fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <hardware/audio.h> 34fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 3589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "MidiFile.h" 3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#ifdef HAVE_GETTID 3889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic pid_t myTid() { return gettid(); } 3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#else 4089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic pid_t myTid() { return getpid(); } 4189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#endif 4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ---------------------------------------------------------------------------- 4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android { 4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ---------------------------------------------------------------------------- 4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// The midi engine buffers are a bit small (128 frames), so we batch them up 5089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic const int NUM_BUFFERS = 4; 5189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 5289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// TODO: Determine appropriate return codes 5389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic status_t ERROR_NOT_OPEN = -1; 5489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic status_t ERROR_OPEN_FAILED = -2; 5589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic status_t ERROR_EAS_FAILURE = -3; 5689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic status_t ERROR_ALLOCATE_FAILED = -4; 5789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 5889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic const S_EAS_LIB_CONFIG* pLibConfig = NULL; 5989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMidiFile::MidiFile() : 6189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mEasData(NULL), mEasHandle(NULL), mAudioBuffer(NULL), 6289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mPlayTime(-1), mDuration(-1), mState(EAS_STATE_ERROR), 63fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mStreamType(AUDIO_STREAM_MUSIC), mLoop(false), mExit(false), 6489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mPaused(false), mRender(false), mTid(-1) 6589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 6689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("constructor"); 6789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.path = NULL; 6989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.fd = -1; 7089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.offset = 0; 7189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.length = 0; 7289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // get the library configuration and do sanity check 7489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (pLibConfig == NULL) 7589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project pLibConfig = EAS_Config(); 7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) { 7789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("EAS library/header mismatch"); 7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto Failed; 7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // initialize EAS library 8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (EAS_Init(&mEasData) != EAS_SUCCESS) { 8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("EAS_Init failed"); 8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto Failed; 8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // select reverb preset and enable 8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_SetParameter(mEasData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_PRESET, EAS_PARAM_REVERB_CHAMBER); 8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_SetParameter(mEasData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_BYPASS, EAS_FALSE); 9089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // create playback thread 9289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project { 9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock l(mMutex); 94577ba8a1ae29cd2ca3b6103ae51530111d3e9b22Dave Sparks createThreadEtc(renderThread, this, "midithread", ANDROID_PRIORITY_AUDIO); 9589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCondition.wait(mMutex); 9689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("thread started"); 9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 9889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 9989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // indicate success 10089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mTid > 0) { 10189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV(" render thread(%d) started", mTid); 10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = EAS_STATE_READY; 10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectFailed: 10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return; 10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 10889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::initCheck() 11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mState == EAS_STATE_ERROR) return ERROR_EAS_FAILURE; 11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 11389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMidiFile::~MidiFile() { 11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile destructor"); 11789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project release(); 11889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1202db8455d8f4468a637109d31f319ce02d9d743ecAndreas Huberstatus_t MidiFile::setDataSource( 1212db8455d8f4468a637109d31f319ce02d9d743ecAndreas Huber const char* path, const KeyedVector<String8, String8> *) { 12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::setDataSource url=%s", path); 12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(mMutex); 12489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 12589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // file still open? 12689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mEasHandle) { 12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project reset_nosync(); 12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // open file and set paused state 13189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.path = strdup(path); 13289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.fd = -1; 13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.offset = 0; 13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.length = 0; 13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle); 13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (result == EAS_SUCCESS) { 13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project updateState(); 13889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (result != EAS_SUCCESS) { 14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("EAS_OpenFile failed: [%d]", (int)result); 14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = EAS_STATE_ERROR; 14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_OPEN_FAILED; 14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 14689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = EAS_STATE_OPEN; 14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mPlayTime = 0; 14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 14989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 15089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 15189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::setDataSource(int fd, int64_t offset, int64_t length) 15289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::setDataSource fd=%d", fd); 15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(mMutex); 15589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // file still open? 15789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mEasHandle) { 15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project reset_nosync(); 15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 16089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // open file and set paused state 16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.fd = dup(fd); 16389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.offset = offset; 16489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.length = length; 16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle); 16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project updateState(); 16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 16889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (result != EAS_SUCCESS) { 16989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("EAS_OpenFile failed: [%d]", (int)result); 17089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = EAS_STATE_ERROR; 17189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_OPEN_FAILED; 17289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 17389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 17489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = EAS_STATE_OPEN; 17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mPlayTime = 0; 17689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 17889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 17989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::prepare() 18089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 18189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::prepare"); 18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(mMutex); 18389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mEasHandle) { 18489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_NOT_OPEN; 18589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 18689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_RESULT result; 18789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if ((result = EAS_Prepare(mEasData, mEasHandle)) != EAS_SUCCESS) { 18889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("EAS_Prepare failed: [%ld]", result); 18989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_EAS_FAILURE; 19089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 19189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project updateState(); 19289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 19389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 19489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::prepareAsync() 19689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::prepareAsync"); 19889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t ret = prepare(); 19989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // don't hold lock during callback 20189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (ret == NO_ERROR) { 20289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sendEvent(MEDIA_PREPARED); 20389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 20489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sendEvent(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ret); 20589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ret; 20789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 20889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 20989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::start() 21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::start"); 21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(mMutex); 21389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mEasHandle) { 21489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_NOT_OPEN; 21589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 21689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 21789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // resuming after pause? 21889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mPaused) { 21989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (EAS_Resume(mEasData, mEasHandle) != EAS_SUCCESS) { 22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_EAS_FAILURE; 22189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mPaused = false; 22389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project updateState(); 22489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 22689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRender = true; 22789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 22889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // wake up render thread 22989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV(" wakeup render thread"); 23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCondition.signal(); 23189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 23289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 23389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::stop() 23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 23689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::stop"); 23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(mMutex); 23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mEasHandle) { 23989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_NOT_OPEN; 24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mPaused && (mState != EAS_STATE_STOPPED)) { 24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_RESULT result = EAS_Pause(mEasData, mEasHandle); 24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (result != EAS_SUCCESS) { 24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("EAS_Pause returned error %ld", result); 24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_EAS_FAILURE; 24689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mPaused = false; 24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::seekTo(int position) 25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::seekTo %d", position); 25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // hold lock during EAS calls 25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project { 25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(mMutex); 25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mEasHandle) { 25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_NOT_OPEN; 26089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 26189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_RESULT result; 26289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if ((result = EAS_Locate(mEasData, mEasHandle, position, false)) 26389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project != EAS_SUCCESS) 26489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project { 26589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("EAS_Locate returned %ld", result); 26689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_EAS_FAILURE; 26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 26889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_GetLocation(mEasData, mEasHandle, &mPlayTime); 26989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 27089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sendEvent(MEDIA_SEEK_COMPLETE); 27189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 27289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::pause() 27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 27689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::pause"); 27789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(mMutex); 27889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mEasHandle) { 27989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_NOT_OPEN; 28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if ((mState == EAS_STATE_PAUSING) || (mState == EAS_STATE_PAUSED)) return NO_ERROR; 28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (EAS_Pause(mEasData, mEasHandle) != EAS_SUCCESS) { 28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_EAS_FAILURE; 28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mPaused = true; 28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 28789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 28889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 28989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool MidiFile::isPlaying() 29089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 29189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::isPlaying, mState=%d", int(mState)); 29289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mEasHandle || mPaused) return false; 29389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return (mState == EAS_STATE_PLAY); 29489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 29589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 29689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::getCurrentPosition(int* position) 29789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 29889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::getCurrentPosition"); 29989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mEasHandle) { 30089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("getCurrentPosition(): file not open"); 30189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_NOT_OPEN; 30289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 30389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mPlayTime < 0) { 30489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("getCurrentPosition(): mPlayTime = %ld", mPlayTime); 30589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_EAS_FAILURE; 30689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 30789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *position = mPlayTime; 30889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 30989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 31089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 31189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::getDuration(int* duration) 31289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 31389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 31489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::getDuration"); 31589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project { 31689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(mMutex); 31789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mEasHandle) return ERROR_NOT_OPEN; 31889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *duration = mDuration; 31989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 32089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 32189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // if no duration cached, get the duration 32289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // don't need a lock here because we spin up a new engine 32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (*duration < 0) { 32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_I32 temp; 32589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_DATA_HANDLE easData = NULL; 32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_HANDLE easHandle = NULL; 32789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_RESULT result = EAS_Init(&easData); 32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (result == EAS_SUCCESS) { 32989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = EAS_OpenFile(easData, &mFileLocator, &easHandle); 33089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 33189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (result == EAS_SUCCESS) { 33289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = EAS_Prepare(easData, easHandle); 33389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 33489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (result == EAS_SUCCESS) { 33589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = EAS_ParseMetaData(easData, easHandle, &temp); 33689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 33789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (easHandle) { 33889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_CloseFile(easData, easHandle); 33989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 34089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (easData) { 34189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_Shutdown(easData); 34289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 34389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 34489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (result != EAS_SUCCESS) { 34589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_EAS_FAILURE; 34689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 34789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // cache successful result 34989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mDuration = *duration = int(temp); 35089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 35189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 35289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 35389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 35489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 35589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::release() 35689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 35789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::release"); 35889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock l(mMutex); 35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project reset_nosync(); 36089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // wait for render thread to exit 36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mExit = true; 36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCondition.signal(); 36489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // wait for thread to exit 36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mAudioBuffer) { 36789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCondition.wait(mMutex); 36889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 36989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // release resources 37189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mEasData) { 37289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_Shutdown(mEasData); 37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mEasData = NULL; 37489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 37689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::reset() 37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::reset"); 38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(mMutex); 38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return reset_nosync(); 38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// call only with mutex held 38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::reset_nosync() 38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 38889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::reset_nosync"); 38989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // close file 39089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mEasHandle) { 39189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_CloseFile(mEasData, mEasHandle); 39289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mEasHandle = NULL; 39389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 39489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mFileLocator.path) { 39589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project free((void*)mFileLocator.path); 39689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.path = NULL; 39789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 39889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mFileLocator.fd >= 0) { 39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project close(mFileLocator.fd); 40089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 40189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.fd = -1; 40289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.offset = 0; 40389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFileLocator.length = 0; 40489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mPlayTime = -1; 40689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mDuration = -1; 40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mLoop = false; 40889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mPaused = false; 40989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRender = false; 41089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 41189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 41289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::setLooping(int loop) 41489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::setLooping"); 41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(mMutex); 41789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mEasHandle) { 41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_NOT_OPEN; 41989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 42089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project loop = loop ? -1 : 0; 42189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (EAS_SetRepeat(mEasData, mEasHandle, loop) != EAS_SUCCESS) { 42289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_EAS_FAILURE; 42389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 42489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 42589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 42689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 42789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MidiFile::createOutputTrack() { 428fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mAudioSink->open(pLibConfig->sampleRate, pLibConfig->numChannels, AUDIO_FORMAT_PCM_16_BIT, 2) != NO_ERROR) { 42989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("mAudioSink open failed"); 43089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ERROR_OPEN_FAILED; 43189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 43289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 43389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 43489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 43589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint MidiFile::renderThread(void* p) { 43689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 43789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ((MidiFile*)p)->render(); 43889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 43989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 44089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint MidiFile::render() { 44189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_RESULT result = EAS_FAILURE; 44289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_I32 count; 44389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int temp; 44489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project bool audioStarted = false; 44589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 44689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::render"); 44789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 44889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // allocate render buffer 44989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioBuffer = new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * NUM_BUFFERS]; 45089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mAudioBuffer) { 45189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("mAudioBuffer allocate failed"); 45289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto threadExit; 45389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 45489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 45589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // signal main thread that we started 45689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project { 45789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock l(mMutex); 45889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mTid = myTid(); 45989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("render thread(%d) signal", mTid); 46089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCondition.signal(); 46189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 46289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 46389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (1) { 46489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMutex.lock(); 46589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 46689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // nothing to render, wait for client thread to wake us up 46789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (!mRender && !mExit) 46889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project { 46989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::render - signal wait"); 47089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCondition.wait(mMutex); 47189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::render - signal rx'd"); 47289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 47389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mExit) { 47489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMutex.unlock(); 47589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 47689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 47789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 47889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // render midi data into the input buffer 47989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project //LOGV("MidiFile::render - rendering audio"); 48089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int num_output = 0; 48189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_PCM* p = mAudioBuffer; 48289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project for (int i = 0; i < NUM_BUFFERS; i++) { 48389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = EAS_Render(mEasData, p, pLibConfig->mixBufferSize, &count); 48489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (result != EAS_SUCCESS) { 48589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("EAS_Render returned %ld", result); 48689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 48789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project p += count * pLibConfig->numChannels; 48889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM); 48989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 49089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 49189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // update playback state and position 49289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // LOGV("MidiFile::render - updating state"); 49389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_GetLocation(mEasData, mEasHandle, &mPlayTime); 49489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project EAS_State(mEasData, mEasHandle, &mState); 49589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMutex.unlock(); 49689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 49789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // create audio output track if necessary 49889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mAudioSink->ready()) { 49989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::render - create output track"); 50089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (createOutputTrack() != NO_ERROR) 50189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto threadExit; 50289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 50389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 50489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Write data to the audio hardware 50589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // LOGV("MidiFile::render - writing to audio output"); 50689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if ((temp = mAudioSink->write(mAudioBuffer, num_output)) < 0) { 50789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Error in writing:%d",temp); 50889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return temp; 50989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 51089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 51189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // start audio output if necessary 51289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!audioStarted) { 51389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project //LOGV("MidiFile::render - starting audio"); 51489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioSink->start(); 51589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioStarted = true; 51689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 51789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 51889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // still playing? 51989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if ((mState == EAS_STATE_STOPPED) || (mState == EAS_STATE_ERROR) || 52089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project (mState == EAS_STATE_PAUSED)) 52189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project { 52289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project switch(mState) { 52389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case EAS_STATE_STOPPED: 52489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project { 52589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::render - stopped"); 52689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sendEvent(MEDIA_PLAYBACK_COMPLETE); 52789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 52889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 52989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case EAS_STATE_ERROR: 53089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project { 53189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("MidiFile::render - error"); 53289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sendEvent(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN); 53389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 53489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 53589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case EAS_STATE_PAUSED: 53689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("MidiFile::render - paused"); 53789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 53889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project default: 53989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 54089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 54189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioSink->stop(); 54289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioStarted = false; 54389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRender = false; 54489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 54589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 54689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 54789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectthreadExit: 54889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioSink.clear(); 54989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mAudioBuffer) { 55089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project delete [] mAudioBuffer; 55189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioBuffer = NULL; 55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 55389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMutex.lock(); 55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mTid = -1; 55589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCondition.signal(); 55689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMutex.unlock(); 55789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return result; 55889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 55989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} // end namespace android 561