19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* MidiFile.cpp 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2007, The Android Open Source Project 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License. 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License. 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define LOG_NDEBUG 0 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "MidiFile" 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/Log.h" 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <assert.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <limits.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sched.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/threads.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <libsonivox/eas_reverb.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MidiFile.h" 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_GETTID 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic pid_t myTid() { return gettid(); } 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic pid_t myTid() { return getpid(); } 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// The midi engine buffers are a bit small (128 frames), so we batch them up 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const int NUM_BUFFERS = 4; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// TODO: Determine appropriate return codes 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic status_t ERROR_NOT_OPEN = -1; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic status_t ERROR_OPEN_FAILED = -2; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic status_t ERROR_EAS_FAILURE = -3; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic status_t ERROR_ALLOCATE_FAILED = -4; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const S_EAS_LIB_CONFIG* pLibConfig = NULL; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectMidiFile::MidiFile() : 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEasData(NULL), mEasHandle(NULL), mAudioBuffer(NULL), 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayTime(-1), mDuration(-1), mState(EAS_STATE_ERROR), 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStreamType(AudioSystem::MUSIC), mLoop(false), mExit(false), 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPaused(false), mRender(false), mTid(-1) 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("constructor"); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.path = NULL; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.fd = -1; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.offset = 0; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.length = 0; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // get the library configuration and do sanity check 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pLibConfig == NULL) 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pLibConfig = EAS_Config(); 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) { 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("EAS library/header mismatch"); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto Failed; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // initialize EAS library 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (EAS_Init(&mEasData) != EAS_SUCCESS) { 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("EAS_Init failed"); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto Failed; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // select reverb preset and enable 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_SetParameter(mEasData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_PRESET, EAS_PARAM_REVERB_CHAMBER); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_SetParameter(mEasData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_BYPASS, EAS_FALSE); 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // create playback thread 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock l(mMutex); 92c082769b673f0ac57f39c44cffce4d756e48e140Dave Sparks createThreadEtc(renderThread, this, "midithread", ANDROID_PRIORITY_AUDIO); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCondition.wait(mMutex); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("thread started"); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // indicate success 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTid > 0) { 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV(" render thread(%d) started", mTid); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = EAS_STATE_READY; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectFailed: 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::initCheck() 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState == EAS_STATE_ERROR) return ERROR_EAS_FAILURE; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectMidiFile::~MidiFile() { 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile destructor"); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project release(); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::setDataSource(const char* path) 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::setDataSource url=%s", path); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(mMutex); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // file still open? 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEasHandle) { 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reset_nosync(); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // open file and set paused state 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.path = strdup(path); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.fd = -1; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.offset = 0; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.length = 0; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == EAS_SUCCESS) { 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateState(); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != EAS_SUCCESS) { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("EAS_OpenFile failed: [%d]", (int)result); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = EAS_STATE_ERROR; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_OPEN_FAILED; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = EAS_STATE_OPEN; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayTime = 0; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::setDataSource(int fd, int64_t offset, int64_t length) 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::setDataSource fd=%d", fd); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(mMutex); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // file still open? 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEasHandle) { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reset_nosync(); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // open file and set paused state 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.fd = dup(fd); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.offset = offset; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.length = length; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateState(); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != EAS_SUCCESS) { 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("EAS_OpenFile failed: [%d]", (int)result); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = EAS_STATE_ERROR; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_OPEN_FAILED; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = EAS_STATE_OPEN; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayTime = 0; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::prepare() 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::prepare"); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(mMutex); 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEasHandle) { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_NOT_OPEN; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_RESULT result; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result = EAS_Prepare(mEasData, mEasHandle)) != EAS_SUCCESS) { 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("EAS_Prepare failed: [%ld]", result); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_EAS_FAILURE; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateState(); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::prepareAsync() 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::prepareAsync"); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t ret = prepare(); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't hold lock during callback 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret == NO_ERROR) { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendEvent(MEDIA_PREPARED); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendEvent(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ret); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::start() 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::start"); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(mMutex); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEasHandle) { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_NOT_OPEN; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // resuming after pause? 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPaused) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (EAS_Resume(mEasData, mEasHandle) != EAS_SUCCESS) { 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_EAS_FAILURE; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPaused = false; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateState(); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRender = true; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // wake up render thread 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV(" wakeup render thread"); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCondition.signal(); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::stop() 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::stop"); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(mMutex); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEasHandle) { 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_NOT_OPEN; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mPaused && (mState != EAS_STATE_STOPPED)) { 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_RESULT result = EAS_Pause(mEasData, mEasHandle); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != EAS_SUCCESS) { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("EAS_Pause returned error %ld", result); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_EAS_FAILURE; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPaused = false; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::seekTo(int position) 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::seekTo %d", position); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // hold lock during EAS calls 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(mMutex); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEasHandle) { 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_NOT_OPEN; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_RESULT result; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result = EAS_Locate(mEasData, mEasHandle, position, false)) 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != EAS_SUCCESS) 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("EAS_Locate returned %ld", result); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_EAS_FAILURE; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_GetLocation(mEasData, mEasHandle, &mPlayTime); 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendEvent(MEDIA_SEEK_COMPLETE); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::pause() 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::pause"); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(mMutex); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEasHandle) { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_NOT_OPEN; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mState == EAS_STATE_PAUSING) || (mState == EAS_STATE_PAUSED)) return NO_ERROR; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (EAS_Pause(mEasData, mEasHandle) != EAS_SUCCESS) { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_EAS_FAILURE; 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPaused = true; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool MidiFile::isPlaying() 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::isPlaying, mState=%d", int(mState)); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEasHandle || mPaused) return false; 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mState == EAS_STATE_PLAY); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::getCurrentPosition(int* position) 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::getCurrentPosition"); 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEasHandle) { 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("getCurrentPosition(): file not open"); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_NOT_OPEN; 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPlayTime < 0) { 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("getCurrentPosition(): mPlayTime = %ld", mPlayTime); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_EAS_FAILURE; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *position = mPlayTime; 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::getDuration(int* duration) 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::getDuration"); 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(mMutex); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEasHandle) return ERROR_NOT_OPEN; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *duration = mDuration; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if no duration cached, get the duration 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't need a lock here because we spin up a new engine 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*duration < 0) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_I32 temp; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_DATA_HANDLE easData = NULL; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_HANDLE easHandle = NULL; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_RESULT result = EAS_Init(&easData); 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == EAS_SUCCESS) { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = EAS_OpenFile(easData, &mFileLocator, &easHandle); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == EAS_SUCCESS) { 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = EAS_Prepare(easData, easHandle); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == EAS_SUCCESS) { 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = EAS_ParseMetaData(easData, easHandle, &temp); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (easHandle) { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_CloseFile(easData, easHandle); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (easData) { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_Shutdown(easData); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != EAS_SUCCESS) { 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_EAS_FAILURE; 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cache successful result 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDuration = *duration = int(temp); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::release() 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::release"); 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock l(mMutex); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reset_nosync(); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // wait for render thread to exit 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExit = true; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCondition.signal(); 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // wait for thread to exit 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAudioBuffer) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCondition.wait(mMutex); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // release resources 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEasData) { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_Shutdown(mEasData); 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEasData = NULL; 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::reset() 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::reset"); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(mMutex); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return reset_nosync(); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// call only with mutex held 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::reset_nosync() 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::reset_nosync"); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // close file 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEasHandle) { 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_CloseFile(mEasData, mEasHandle); 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEasHandle = NULL; 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileLocator.path) { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free((void*)mFileLocator.path); 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.path = NULL; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileLocator.fd >= 0) { 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(mFileLocator.fd); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.fd = -1; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.offset = 0; 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileLocator.length = 0; 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayTime = -1; 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDuration = -1; 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLoop = false; 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPaused = false; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRender = false; 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::setLooping(int loop) 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::setLooping"); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(mMutex); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEasHandle) { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_NOT_OPEN; 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loop = loop ? -1 : 0; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (EAS_SetRepeat(mEasData, mEasHandle, loop) != EAS_SUCCESS) { 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_EAS_FAILURE; 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MidiFile::createOutputTrack() { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAudioSink->open(pLibConfig->sampleRate, pLibConfig->numChannels, AudioSystem::PCM_16_BIT, 2) != NO_ERROR) { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("mAudioSink open failed"); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_OPEN_FAILED; 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint MidiFile::renderThread(void* p) { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((MidiFile*)p)->render(); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint MidiFile::render() { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_RESULT result = EAS_FAILURE; 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_I32 count; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int temp; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool audioStarted = false; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::render"); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // allocate render buffer 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAudioBuffer = new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * NUM_BUFFERS]; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mAudioBuffer) { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("mAudioBuffer allocate failed"); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto threadExit; 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // signal main thread that we started 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock l(mMutex); 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTid = myTid(); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("render thread(%d) signal", mTid); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCondition.signal(); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (1) { 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutex.lock(); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // nothing to render, wait for client thread to wake us up 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (!mRender && !mExit) 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::render - signal wait"); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCondition.wait(mMutex); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::render - signal rx'd"); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExit) { 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutex.unlock(); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // render midi data into the input buffer 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //LOGV("MidiFile::render - rendering audio"); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num_output = 0; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_PCM* p = mAudioBuffer; 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < NUM_BUFFERS; i++) { 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = EAS_Render(mEasData, p, pLibConfig->mixBufferSize, &count); 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != EAS_SUCCESS) { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("EAS_Render returned %ld", result); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p += count * pLibConfig->numChannels; 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM); 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // update playback state and position 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // LOGV("MidiFile::render - updating state"); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_GetLocation(mEasData, mEasHandle, &mPlayTime); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EAS_State(mEasData, mEasHandle, &mState); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutex.unlock(); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // create audio output track if necessary 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mAudioSink->ready()) { 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::render - create output track"); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (createOutputTrack() != NO_ERROR) 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto threadExit; 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Write data to the audio hardware 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // LOGV("MidiFile::render - writing to audio output"); 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((temp = mAudioSink->write(mAudioBuffer, num_output)) < 0) { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Error in writing:%d",temp); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return temp; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // start audio output if necessary 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!audioStarted) { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //LOGV("MidiFile::render - starting audio"); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAudioSink->start(); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioStarted = true; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // still playing? 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mState == EAS_STATE_STOPPED) || (mState == EAS_STATE_ERROR) || 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mState == EAS_STATE_PAUSED)) 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(mState) { 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case EAS_STATE_STOPPED: 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::render - stopped"); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendEvent(MEDIA_PLAYBACK_COMPLETE); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case EAS_STATE_ERROR: 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("MidiFile::render - error"); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendEvent(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case EAS_STATE_PAUSED: 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("MidiFile::render - paused"); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAudioSink->stop(); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioStarted = false; 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRender = false; 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectthreadExit: 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAudioSink.clear(); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAudioBuffer) { 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete [] mAudioBuffer; 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAudioBuffer = NULL; 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutex.lock(); 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTid = -1; 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCondition.signal(); 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutex.unlock(); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // end namespace android 559