static MediaScanResult HandleMIDI( const char *filename, MediaScannerClient *client) { // get the library configuration and do sanity check const S_EAS_LIB_CONFIG* pLibConfig = EAS_Config(); if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) { LOGE("EAS library/header mismatch\n"); return MEDIA_SCAN_RESULT_ERROR; } EAS_I32 temp; // spin up a new EAS engine EAS_DATA_HANDLE easData = NULL; EAS_HANDLE easHandle = NULL; EAS_RESULT result = EAS_Init(&easData); if (result == EAS_SUCCESS) { EAS_FILE file; file.path = filename; file.fd = 0; file.offset = 0; file.length = 0; result = EAS_OpenFile(easData, &file, &easHandle); } if (result == EAS_SUCCESS) { result = EAS_Prepare(easData, easHandle); } if (result == EAS_SUCCESS) { result = EAS_ParseMetaData(easData, easHandle, &temp); } if (easHandle) { EAS_CloseFile(easData, easHandle); } if (easData) { EAS_Shutdown(easData); } if (result != EAS_SUCCESS) { #ifndef ANDROID_DEFAULT_CODE client->setMimeType("bad mime type"); #endif // ANDROID_DEFAULT_CODE return MEDIA_SCAN_RESULT_SKIPPED; } char buffer[20]; sprintf(buffer, "%ld", temp); status_t status = client->addStringTag("duration", buffer); if (status != OK) { return MEDIA_SCAN_RESULT_ERROR; } #ifndef ANDROID_DEFAULT_CODE status_t status_res = client->addStringTag("isAccurateDuration", "1"); if (status_res) { return MEDIA_SCAN_RESULT_ERROR; } #endif // ANDROID_DEFAULT_CODE return MEDIA_SCAN_RESULT_OK; }
status_t MidiFile::prepare() { ALOGV("MidiFile::prepare"); Mutex::Autolock lock(mMutex); if (!mEasHandle) { return ERROR_NOT_OPEN; } EAS_RESULT result; if ((result = EAS_Prepare(mEasData, mEasHandle)) != EAS_SUCCESS) { ALOGE("EAS_Prepare failed: [%ld]", result); return ERROR_EAS_FAILURE; } updateState(); return NO_ERROR; }
static status_t HandleMIDI( const char *filename, MediaScannerClient *client) { // get the library configuration and do sanity check const S_EAS_LIB_CONFIG* pLibConfig = EAS_Config(); if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) { LOGE("EAS library/header mismatch\n"); return UNKNOWN_ERROR; } EAS_I32 temp; // spin up a new EAS engine EAS_DATA_HANDLE easData = NULL; EAS_HANDLE easHandle = NULL; EAS_RESULT result = EAS_Init(&easData); if (result == EAS_SUCCESS) { EAS_FILE file; file.path = filename; file.fd = 0; file.offset = 0; file.length = 0; result = EAS_OpenFile(easData, &file, &easHandle); } if (result == EAS_SUCCESS) { result = EAS_Prepare(easData, easHandle); } if (result == EAS_SUCCESS) { result = EAS_ParseMetaData(easData, easHandle, &temp); } if (easHandle) { EAS_CloseFile(easData, easHandle); } if (easData) { EAS_Shutdown(easData); } if (result != EAS_SUCCESS) { return UNKNOWN_ERROR; } char buffer[20]; sprintf(buffer, "%ld", temp); if (!client->addStringTag("duration", buffer)) return UNKNOWN_ERROR; return OK; }
status_t MidiFile::getDuration(int* duration) { ALOGV("MidiFile::getDuration"); { Mutex::Autolock lock(mMutex); if (!mEasHandle) return ERROR_NOT_OPEN; *duration = mDuration; } // if no duration cached, get the duration // don't need a lock here because we spin up a new engine if (*duration < 0) { EAS_I32 temp; EAS_DATA_HANDLE easData = NULL; EAS_HANDLE easHandle = NULL; EAS_RESULT result = EAS_Init(&easData); if (result == EAS_SUCCESS) { result = EAS_OpenFile(easData, &mFileLocator, &easHandle); } if (result == EAS_SUCCESS) { result = EAS_Prepare(easData, easHandle); } if (result == EAS_SUCCESS) { result = EAS_ParseMetaData(easData, easHandle, &temp); } if (easHandle) { EAS_CloseFile(easData, easHandle); } if (easData) { EAS_Shutdown(easData); } if (result != EAS_SUCCESS) { return ERROR_EAS_FAILURE; } // cache successful result mDuration = *duration = int(temp); } return NO_ERROR; }
MidiEngine::MidiEngine(const sp<DataSource> &dataSource, const sp<MetaData> &fileMetadata, const sp<MetaData> &trackMetadata) : mGroup(NULL), mEasData(NULL), mEasHandle(NULL), mEasConfig(NULL), mIsInitialized(false) { mIoWrapper = new MidiIoWrapper(dataSource); // spin up a new EAS engine EAS_I32 temp; EAS_RESULT result = EAS_Init(&mEasData); if (result == EAS_SUCCESS) { result = EAS_OpenFile(mEasData, mIoWrapper->getLocator(), &mEasHandle); } if (result == EAS_SUCCESS) { result = EAS_Prepare(mEasData, mEasHandle); } if (result == EAS_SUCCESS) { result = EAS_ParseMetaData(mEasData, mEasHandle, &temp); } if (result != EAS_SUCCESS) { return; } if (fileMetadata != NULL) { fileMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MIDI); } if (trackMetadata != NULL) { trackMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); trackMetadata->setInt64(kKeyDuration, 1000ll * temp); // milli->micro mEasConfig = EAS_Config(); trackMetadata->setInt32(kKeySampleRate, mEasConfig->sampleRate); trackMetadata->setInt32(kKeyChannelCount, mEasConfig->numChannels); } mIsInitialized = true; }
// play MIDI_RESULT MIDI_PlayFile(char *path, MIDI_HANDLE *handle) { EAS_RESULT result; // fill in file struct file.path = path; file.fd = 0; // lock pthread_mutex_lock(&mutex); // open file if ((result = EAS_OpenFile(pEASData, &file, handle)) != EAS_SUCCESS) { // unlock pthread_mutex_unlock(&mutex); return result; } // unlock pthread_mutex_unlock(&mutex); // lock pthread_mutex_lock(&mutex); // prepare if ((result = EAS_Prepare(pEASData, *handle)) != EAS_SUCCESS) { // unlock pthread_mutex_unlock(&mutex); return result; } // unlock pthread_mutex_unlock(&mutex); return MIDI_SUCCESS; }
static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize) { EAS_HANDLE handle; EAS_RESULT result, reportResult; EAS_I32 count; EAS_STATE state; EAS_I32 playTime; char waveFilename[256]; WAVE_FILE *wFile; EAS_INT i; EAS_PCM *p; EAS_FILE file; /* determine the name of the output file */ wFile = NULL; if (outputFile == NULL) { StrCopy(waveFilename, filename, sizeof(waveFilename)); if (!ChangeFileExt(waveFilename, "wav", sizeof(waveFilename))) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error in output filename %s\n", waveFilename); */ } return EAS_FAILURE; } outputFile = waveFilename; } /* call EAS library to open file */ file.path = filename; file.fd = 0; if ((reportResult = EAS_OpenFile(easData, &file, &handle)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_OpenFile returned %ld\n", reportResult); */ } return reportResult; } /* prepare to play the file */ if ((result = EAS_Prepare(easData, handle)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Prepare returned %ld\n", result); */ } reportResult = result; } /* get play length */ if ((result = EAS_ParseMetaData(easData, handle, &playTime)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_ParseMetaData returned %ld\n", result); */ } return result; } EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0xe624f4d9, 0x00000005 , playTime / 1000, playTime % 1000); if (reportResult == EAS_SUCCESS) { /* create the output file */ wFile = WaveFileCreate(outputFile, pLibConfig->numChannels, pLibConfig->sampleRate, sizeof(EAS_PCM) * 8); if (!wFile) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to create output file %s\n", waveFilename); */ } reportResult = EAS_FAILURE; } } /* rendering loop */ while (reportResult == EAS_SUCCESS) { /* we may render several buffers here to fill one host buffer */ for (i = 0, p = buffer; i < NUM_BUFFERS; i++, p+= pLibConfig->mixBufferSize * pLibConfig->numChannels) { /* get the current time */ if ((result = EAS_GetLocation(easData, handle, &playTime)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_GetLocation returned %d\n",result); */ } if (reportResult == EAS_SUCCESS) reportResult = result; break; } { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Parser time: %d.%03d\n", playTime / 1000, playTime % 1000); */ } /* render a buffer of audio */ if ((result = EAS_Render(easData, p, pLibConfig->mixBufferSize, &count)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Render returned %d\n",result); */ } if (reportResult == EAS_SUCCESS) reportResult = result; } } if (result == EAS_SUCCESS) { /* write it to the wave file */ if (WaveFileWrite(wFile, buffer, bufferSize) != bufferSize) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "WaveFileWrite failed\n"); */ } reportResult = EAS_FAILURE; } } if (reportResult == EAS_SUCCESS) { /* check stream state */ if ((result = EAS_State(easData, handle, &state)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_State returned %d\n", result); */ } reportResult = result; } /* is playback complete */ if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR)) break; } } /* close the output file */ if (wFile) { if (!WaveFileClose(wFile)) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error closing wave file %s\n", waveFilename); */ } if (reportResult == EAS_SUCCESS) result = EAS_FAILURE; } } /* close the input file */ if ((result = EAS_CloseFile(easData,handle)) != EAS_SUCCESS) { { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Close returned %ld\n", result); */ } if (reportResult == EAS_SUCCESS) result = EAS_FAILURE; } return reportResult; } /* end PlayFile */