From 08b9e2d113213c37506a416bc95a36789bcab4ca Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Tue, 16 Dec 2014 12:46:34 -0800 Subject: Use callbacks for Midi I/O Instead of having the Sonivox engine directly open the file and use stdio to read from it, use caller-provided callbacks. Change-Id: I4d775c8458c48c591a15794c4517e006dcf034e1 --- include/media/JetPlayer.h | 5 +- include/media/MidiIoWrapper.h | 46 +++++++++++++ media/libmedia/Android.mk | 1 + media/libmedia/JetPlayer.cpp | 26 ++------ media/libmedia/MidiIoWrapper.cpp | 76 ++++++++++++++++++++++ media/libmediaplayerservice/MediaPlayerFactory.cpp | 11 ++-- media/libmediaplayerservice/MidiFile.cpp | 31 ++------- media/libmediaplayerservice/MidiFile.h | 4 +- media/libstagefright/StagefrightMediaScanner.cpp | 9 +-- 9 files changed, 145 insertions(+), 64 deletions(-) create mode 100644 include/media/MidiIoWrapper.h create mode 100644 media/libmedia/MidiIoWrapper.cpp diff --git a/include/media/JetPlayer.h b/include/media/JetPlayer.h index 388f767..63d1980 100644 --- a/include/media/JetPlayer.h +++ b/include/media/JetPlayer.h @@ -22,6 +22,7 @@ #include #include #include +#include namespace android { @@ -86,15 +87,13 @@ private: int mMaxTracks; // max number of MIDI tracks, usually 32 EAS_DATA_HANDLE mEasData; - EAS_FILE_LOCATOR mEasJetFileLoc; + sp mIoWrapper; EAS_PCM* mAudioBuffer;// EAS renders the MIDI data into this buffer, sp mAudioTrack; // and we play it in this audio track int mTrackBufferSize; S_JET_STATUS mJetStatus; S_JET_STATUS mPreviousJetStatus; - char mJetFilePath[PATH_MAX]; - class JetPlayerThread : public Thread { public: JetPlayerThread(JetPlayer *player) : mPlayer(player) { diff --git a/include/media/MidiIoWrapper.h b/include/media/MidiIoWrapper.h new file mode 100644 index 0000000..caf1d75 --- /dev/null +++ b/include/media/MidiIoWrapper.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MIDI_IO_WRAPPER_H_ +#define MIDI_IO_WRAPPER_H_ + +#include + +namespace android { + +class MidiIoWrapper : public RefBase { +public: + MidiIoWrapper(const char *path); + MidiIoWrapper(int fd, off64_t offset, int64_t size); + + ~MidiIoWrapper(); + + int readAt(void *buffer, int offset, int size); + int size(); + + EAS_FILE_LOCATOR getLocator(); + +private: + int mFd; + off64_t mBase; + int64_t mLength; + EAS_FILE mEasFile; +}; + + +} // namespace android + +#endif // MIDI_IO_WRAPPER_H_ diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index bcec9c9..c58a503 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -42,6 +42,7 @@ LOCAL_SRC_FILES:= \ mediarecorder.cpp \ IMediaMetadataRetriever.cpp \ mediametadataretriever.cpp \ + MidiIoWrapper.cpp \ ToneGenerator.cpp \ JetPlayer.cpp \ IOMX.cpp \ diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp index f0f1832..721d8d7 100644 --- a/media/libmedia/JetPlayer.cpp +++ b/media/libmedia/JetPlayer.cpp @@ -36,7 +36,6 @@ JetPlayer::JetPlayer(void *javaJetPlayer, int maxTracks, int trackBufferSize) : mPaused(false), mMaxTracks(maxTracks), mEasData(NULL), - mEasJetFileLoc(NULL), mTrackBufferSize(trackBufferSize) { ALOGV("JetPlayer constructor"); @@ -133,10 +132,7 @@ int JetPlayer::release() JET_Shutdown(mEasData); EAS_Shutdown(mEasData); } - if (mEasJetFileLoc) { - free(mEasJetFileLoc); - mEasJetFileLoc = NULL; - } + mIoWrapper.clear(); if (mAudioTrack != 0) { mAudioTrack->stop(); mAudioTrack->flush(); @@ -327,16 +323,9 @@ int JetPlayer::loadFromFile(const char* path) Mutex::Autolock lock(mMutex); - mEasJetFileLoc = (EAS_FILE_LOCATOR) malloc(sizeof(EAS_FILE)); - strncpy(mJetFilePath, path, sizeof(mJetFilePath)); - mJetFilePath[sizeof(mJetFilePath) - 1] = '\0'; - mEasJetFileLoc->path = mJetFilePath; - - mEasJetFileLoc->fd = 0; - mEasJetFileLoc->length = 0; - mEasJetFileLoc->offset = 0; + mIoWrapper = new MidiIoWrapper(path); - EAS_RESULT result = JET_OpenFile(mEasData, mEasJetFileLoc); + EAS_RESULT result = JET_OpenFile(mEasData, mIoWrapper->getLocator()); if (result != EAS_SUCCESS) mState = EAS_STATE_ERROR; else @@ -352,13 +341,9 @@ int JetPlayer::loadFromFD(const int fd, const long long offset, const long long Mutex::Autolock lock(mMutex); - mEasJetFileLoc = (EAS_FILE_LOCATOR) malloc(sizeof(EAS_FILE)); - mEasJetFileLoc->fd = fd; - mEasJetFileLoc->offset = offset; - mEasJetFileLoc->length = length; - mEasJetFileLoc->path = NULL; + mIoWrapper = new MidiIoWrapper(fd, offset, length); - EAS_RESULT result = JET_OpenFile(mEasData, mEasJetFileLoc); + EAS_RESULT result = JET_OpenFile(mEasData, mIoWrapper->getLocator()); if (result != EAS_SUCCESS) mState = EAS_STATE_ERROR; else @@ -459,7 +444,6 @@ int JetPlayer::clearQueue() //------------------------------------------------------------------------------------------------- void JetPlayer::dump() { - ALOGE("JetPlayer dump: JET file=%s", mEasJetFileLoc->path); } void JetPlayer::dumpJetStatus(S_JET_STATUS* pJetStatus) diff --git a/media/libmedia/MidiIoWrapper.cpp b/media/libmedia/MidiIoWrapper.cpp new file mode 100644 index 0000000..ef931d2 --- /dev/null +++ b/media/libmedia/MidiIoWrapper.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "MidiIoWrapper" +#include +#include + +#include +#include + +#include "media/MidiIoWrapper.h" + +static int readAt(void *handle, void *buffer, int pos, int size) { + return ((android::MidiIoWrapper*)handle)->readAt(buffer, pos, size); +} +static int size(void *handle) { + return ((android::MidiIoWrapper*)handle)->size(); +} + +namespace android { + +MidiIoWrapper::MidiIoWrapper(const char *path) { + ALOGV("MidiIoWrapper(%s)", path); + mFd = open(path, O_RDONLY | O_LARGEFILE); + mBase = 0; + mLength = lseek(mFd, 0, SEEK_END); +} + +MidiIoWrapper::MidiIoWrapper(int fd, off64_t offset, int64_t size) { + ALOGV("MidiIoWrapper(fd=%d)", fd); + mFd = dup(fd); + mBase = offset; + mLength = size; +} + +MidiIoWrapper::~MidiIoWrapper() { + ALOGV("~MidiIoWrapper"); + close(mFd); +} + +int MidiIoWrapper::readAt(void *buffer, int offset, int size) { + ALOGV("readAt(%p, %d, %d)", buffer, offset, size); + lseek(mFd, mBase + offset, SEEK_SET); + if (offset + size > mLength) { + size = mLength - offset; + } + return read(mFd, buffer, size); +} + +int MidiIoWrapper::size() { + ALOGV("size() = %d", mLength); + return mLength; +} + +EAS_FILE_LOCATOR MidiIoWrapper::getLocator() { + mEasFile.handle = this; + mEasFile.readAt = ::readAt; + mEasFile.size = ::size; + return &mEasFile; +} + +} // namespace android diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp index aeefb4c..c689470 100644 --- a/media/libmediaplayerservice/MediaPlayerFactory.cpp +++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp @@ -15,11 +15,13 @@ ** limitations under the License. */ +//#define LOG_NDEBUG 0 #define LOG_TAG "MediaPlayerFactory" #include #include #include +#include #include #include #include @@ -308,7 +310,6 @@ class SonivoxPlayerFactory : public MediaPlayerFactory::IFactory { } } } - return 0.0; } @@ -324,14 +325,10 @@ class SonivoxPlayerFactory : public MediaPlayerFactory::IFactory { // Some kind of MIDI? EAS_DATA_HANDLE easdata; + sp wrapper = new MidiIoWrapper(fd, offset, length); if (EAS_Init(&easdata) == EAS_SUCCESS) { - EAS_FILE locator; - locator.path = NULL; - locator.fd = fd; - locator.offset = offset; - locator.length = length; EAS_HANDLE eashandle; - if (EAS_OpenFile(easdata, &locator, &eashandle) == EAS_SUCCESS) { + if (EAS_OpenFile(easdata, wrapper->getLocator(), &eashandle) == EAS_SUCCESS) { EAS_CloseFile(easdata, eashandle); EAS_Shutdown(easdata); return kOurScore; diff --git a/media/libmediaplayerservice/MidiFile.cpp b/media/libmediaplayerservice/MidiFile.cpp index 749ef96..205d44f 100644 --- a/media/libmediaplayerservice/MidiFile.cpp +++ b/media/libmediaplayerservice/MidiFile.cpp @@ -60,11 +60,6 @@ MidiFile::MidiFile() : { ALOGV("constructor"); - mFileLocator.path = NULL; - mFileLocator.fd = -1; - mFileLocator.offset = 0; - mFileLocator.length = 0; - // get the library configuration and do sanity check if (pLibConfig == NULL) pLibConfig = EAS_Config(); @@ -126,11 +121,8 @@ status_t MidiFile::setDataSource( } // open file and set paused state - mFileLocator.path = strdup(path); - mFileLocator.fd = -1; - mFileLocator.offset = 0; - mFileLocator.length = 0; - EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle); + mIoWrapper = new MidiIoWrapper(path); + EAS_RESULT result = EAS_OpenFile(mEasData, mIoWrapper->getLocator(), &mEasHandle); if (result == EAS_SUCCESS) { updateState(); } @@ -157,10 +149,8 @@ status_t MidiFile::setDataSource(int fd, int64_t offset, int64_t length) } // open file and set paused state - mFileLocator.fd = dup(fd); - mFileLocator.offset = offset; - mFileLocator.length = length; - EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle); + mIoWrapper = new MidiIoWrapper(fd, offset, length); + EAS_RESULT result = EAS_OpenFile(mEasData, mIoWrapper->getLocator(), &mEasHandle); updateState(); if (result != EAS_SUCCESS) { @@ -329,7 +319,7 @@ status_t MidiFile::getDuration(int* duration) EAS_HANDLE easHandle = NULL; EAS_RESULT result = EAS_Init(&easData); if (result == EAS_SUCCESS) { - result = EAS_OpenFile(easData, &mFileLocator, &easHandle); + result = EAS_OpenFile(easData, mIoWrapper->getLocator(), &easHandle); } if (result == EAS_SUCCESS) { result = EAS_Prepare(easData, easHandle); @@ -395,17 +385,8 @@ status_t MidiFile::reset_nosync() EAS_CloseFile(mEasData, mEasHandle); mEasHandle = NULL; } - if (mFileLocator.path) { - free((void*)mFileLocator.path); - mFileLocator.path = NULL; - } - if (mFileLocator.fd >= 0) { - close(mFileLocator.fd); - } - mFileLocator.fd = -1; - mFileLocator.offset = 0; - mFileLocator.length = 0; + mIoWrapper.clear(); mPlayTime = -1; mDuration = -1; mLoop = false; diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h index 82e4e88..48a42aa 100644 --- a/media/libmediaplayerservice/MidiFile.h +++ b/media/libmediaplayerservice/MidiFile.h @@ -20,6 +20,7 @@ #include #include +#include namespace android { @@ -63,7 +64,6 @@ public: return INVALID_OPERATION; } - private: status_t createOutputTrack(); status_t reset_nosync(); @@ -78,7 +78,7 @@ private: EAS_I32 mPlayTime; EAS_I32 mDuration; EAS_STATE mState; - EAS_FILE mFileLocator; + sp mIoWrapper; audio_stream_type_t mStreamType; bool mLoop; volatile bool mExit; diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp index 4449d57..6ded3a7 100644 --- a/media/libstagefright/StagefrightMediaScanner.cpp +++ b/media/libstagefright/StagefrightMediaScanner.cpp @@ -26,6 +26,7 @@ #include #include +#include #include // Sonivox includes @@ -71,13 +72,9 @@ static MediaScanResult HandleMIDI( EAS_DATA_HANDLE easData = NULL; EAS_HANDLE easHandle = NULL; EAS_RESULT result = EAS_Init(&easData); + MidiIoWrapper wrapper(filename); 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); + result = EAS_OpenFile(easData, wrapper.getLocator(), &easHandle); } if (result == EAS_SUCCESS) { result = EAS_Prepare(easData, easHandle); -- cgit v1.1