xref: /aosp_15_r20/frameworks/base/media/jni/JetPlayer.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2008 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*d57664e9SAndroid Build Coastguard Worker #define LOG_TAG "JetPlayer-C"
19*d57664e9SAndroid Build Coastguard Worker 
20*d57664e9SAndroid Build Coastguard Worker #include <utils/Log.h>
21*d57664e9SAndroid Build Coastguard Worker #include "JetPlayer.h"
22*d57664e9SAndroid Build Coastguard Worker 
23*d57664e9SAndroid Build Coastguard Worker 
24*d57664e9SAndroid Build Coastguard Worker namespace android
25*d57664e9SAndroid Build Coastguard Worker {
26*d57664e9SAndroid Build Coastguard Worker 
27*d57664e9SAndroid Build Coastguard Worker static const int MIX_NUM_BUFFERS = 4;
28*d57664e9SAndroid Build Coastguard Worker static const S_EAS_LIB_CONFIG* pLibConfig = NULL;
29*d57664e9SAndroid Build Coastguard Worker 
30*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
JetPlayer(void * javaJetPlayer,int maxTracks,int trackBufferSize)31*d57664e9SAndroid Build Coastguard Worker JetPlayer::JetPlayer(void *javaJetPlayer, int maxTracks, int trackBufferSize) :
32*d57664e9SAndroid Build Coastguard Worker         mEventCallback(NULL),
33*d57664e9SAndroid Build Coastguard Worker         mJavaJetPlayerRef(javaJetPlayer),
34*d57664e9SAndroid Build Coastguard Worker         mTid(-1),
35*d57664e9SAndroid Build Coastguard Worker         mRender(false),
36*d57664e9SAndroid Build Coastguard Worker         mPaused(false),
37*d57664e9SAndroid Build Coastguard Worker         mMaxTracks(maxTracks),
38*d57664e9SAndroid Build Coastguard Worker         mEasData(NULL),
39*d57664e9SAndroid Build Coastguard Worker         mIoWrapper(NULL),
40*d57664e9SAndroid Build Coastguard Worker         mTrackBufferSize(trackBufferSize)
41*d57664e9SAndroid Build Coastguard Worker {
42*d57664e9SAndroid Build Coastguard Worker     ALOGV("JetPlayer constructor");
43*d57664e9SAndroid Build Coastguard Worker     mPreviousJetStatus.currentUserID = -1;
44*d57664e9SAndroid Build Coastguard Worker     mPreviousJetStatus.segmentRepeatCount = -1;
45*d57664e9SAndroid Build Coastguard Worker     mPreviousJetStatus.numQueuedSegments = -1;
46*d57664e9SAndroid Build Coastguard Worker     mPreviousJetStatus.paused = true;
47*d57664e9SAndroid Build Coastguard Worker }
48*d57664e9SAndroid Build Coastguard Worker 
49*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
~JetPlayer()50*d57664e9SAndroid Build Coastguard Worker JetPlayer::~JetPlayer()
51*d57664e9SAndroid Build Coastguard Worker {
52*d57664e9SAndroid Build Coastguard Worker     ALOGV("~JetPlayer");
53*d57664e9SAndroid Build Coastguard Worker     release();
54*d57664e9SAndroid Build Coastguard Worker }
55*d57664e9SAndroid Build Coastguard Worker 
56*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
init()57*d57664e9SAndroid Build Coastguard Worker int JetPlayer::init()
58*d57664e9SAndroid Build Coastguard Worker {
59*d57664e9SAndroid Build Coastguard Worker     //Mutex::Autolock lock(&mMutex);
60*d57664e9SAndroid Build Coastguard Worker 
61*d57664e9SAndroid Build Coastguard Worker     EAS_RESULT result;
62*d57664e9SAndroid Build Coastguard Worker 
63*d57664e9SAndroid Build Coastguard Worker     // retrieve the EAS library settings
64*d57664e9SAndroid Build Coastguard Worker     if (pLibConfig == NULL)
65*d57664e9SAndroid Build Coastguard Worker         pLibConfig = EAS_Config();
66*d57664e9SAndroid Build Coastguard Worker     if (pLibConfig == NULL) {
67*d57664e9SAndroid Build Coastguard Worker         ALOGE("JetPlayer::init(): EAS library configuration could not be retrieved, aborting.");
68*d57664e9SAndroid Build Coastguard Worker         return EAS_FAILURE;
69*d57664e9SAndroid Build Coastguard Worker     }
70*d57664e9SAndroid Build Coastguard Worker 
71*d57664e9SAndroid Build Coastguard Worker     // init the EAS library
72*d57664e9SAndroid Build Coastguard Worker     result = EAS_Init(&mEasData);
73*d57664e9SAndroid Build Coastguard Worker     if (result != EAS_SUCCESS) {
74*d57664e9SAndroid Build Coastguard Worker         ALOGE("JetPlayer::init(): Error initializing Sonivox EAS library, aborting.");
75*d57664e9SAndroid Build Coastguard Worker         mState = EAS_STATE_ERROR;
76*d57664e9SAndroid Build Coastguard Worker         return result;
77*d57664e9SAndroid Build Coastguard Worker     }
78*d57664e9SAndroid Build Coastguard Worker     // init the JET library with the default app event controller range
79*d57664e9SAndroid Build Coastguard Worker     result = JET_Init(mEasData, NULL, sizeof(S_JET_CONFIG));
80*d57664e9SAndroid Build Coastguard Worker     if (result != EAS_SUCCESS) {
81*d57664e9SAndroid Build Coastguard Worker         ALOGE("JetPlayer::init(): Error initializing JET library, aborting.");
82*d57664e9SAndroid Build Coastguard Worker         mState = EAS_STATE_ERROR;
83*d57664e9SAndroid Build Coastguard Worker         return result;
84*d57664e9SAndroid Build Coastguard Worker     }
85*d57664e9SAndroid Build Coastguard Worker 
86*d57664e9SAndroid Build Coastguard Worker     // create the output AudioTrack
87*d57664e9SAndroid Build Coastguard Worker     mAudioTrack = new AudioTrack();
88*d57664e9SAndroid Build Coastguard Worker     status_t status = mAudioTrack->set(AUDIO_STREAM_MUSIC,  //TODO parameterize this
89*d57664e9SAndroid Build Coastguard Worker             pLibConfig->sampleRate,
90*d57664e9SAndroid Build Coastguard Worker             AUDIO_FORMAT_PCM_16_BIT,
91*d57664e9SAndroid Build Coastguard Worker             audio_channel_out_mask_from_count(pLibConfig->numChannels),
92*d57664e9SAndroid Build Coastguard Worker             (size_t) mTrackBufferSize,
93*d57664e9SAndroid Build Coastguard Worker             AUDIO_OUTPUT_FLAG_NONE);
94*d57664e9SAndroid Build Coastguard Worker     if (status != OK) {
95*d57664e9SAndroid Build Coastguard Worker         ALOGE("JetPlayer::init(): Error initializing JET library; AudioTrack error %d", status);
96*d57664e9SAndroid Build Coastguard Worker         mAudioTrack.clear();
97*d57664e9SAndroid Build Coastguard Worker         mState = EAS_STATE_ERROR;
98*d57664e9SAndroid Build Coastguard Worker         return EAS_FAILURE;
99*d57664e9SAndroid Build Coastguard Worker     }
100*d57664e9SAndroid Build Coastguard Worker 
101*d57664e9SAndroid Build Coastguard Worker     // create render and playback thread
102*d57664e9SAndroid Build Coastguard Worker     {
103*d57664e9SAndroid Build Coastguard Worker         Mutex::Autolock l(mMutex);
104*d57664e9SAndroid Build Coastguard Worker         ALOGV("JetPlayer::init(): trying to start render thread");
105*d57664e9SAndroid Build Coastguard Worker         mThread = new JetPlayerThread(this);
106*d57664e9SAndroid Build Coastguard Worker         mThread->run("jetRenderThread", ANDROID_PRIORITY_AUDIO);
107*d57664e9SAndroid Build Coastguard Worker         mCondition.wait(mMutex);
108*d57664e9SAndroid Build Coastguard Worker     }
109*d57664e9SAndroid Build Coastguard Worker     if (mTid > 0) {
110*d57664e9SAndroid Build Coastguard Worker         // render thread started, we're ready
111*d57664e9SAndroid Build Coastguard Worker         ALOGV("JetPlayer::init(): render thread(%d) successfully started.", mTid);
112*d57664e9SAndroid Build Coastguard Worker         mState = EAS_STATE_READY;
113*d57664e9SAndroid Build Coastguard Worker     } else {
114*d57664e9SAndroid Build Coastguard Worker         ALOGE("JetPlayer::init(): failed to start render thread.");
115*d57664e9SAndroid Build Coastguard Worker         mState = EAS_STATE_ERROR;
116*d57664e9SAndroid Build Coastguard Worker         return EAS_FAILURE;
117*d57664e9SAndroid Build Coastguard Worker     }
118*d57664e9SAndroid Build Coastguard Worker 
119*d57664e9SAndroid Build Coastguard Worker     return EAS_SUCCESS;
120*d57664e9SAndroid Build Coastguard Worker }
121*d57664e9SAndroid Build Coastguard Worker 
setEventCallback(jetevent_callback eventCallback)122*d57664e9SAndroid Build Coastguard Worker void JetPlayer::setEventCallback(jetevent_callback eventCallback)
123*d57664e9SAndroid Build Coastguard Worker {
124*d57664e9SAndroid Build Coastguard Worker     Mutex::Autolock l(mMutex);
125*d57664e9SAndroid Build Coastguard Worker     mEventCallback = eventCallback;
126*d57664e9SAndroid Build Coastguard Worker }
127*d57664e9SAndroid Build Coastguard Worker 
128*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
release()129*d57664e9SAndroid Build Coastguard Worker int JetPlayer::release()
130*d57664e9SAndroid Build Coastguard Worker {
131*d57664e9SAndroid Build Coastguard Worker     ALOGV("JetPlayer::release()");
132*d57664e9SAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
133*d57664e9SAndroid Build Coastguard Worker     mPaused = true;
134*d57664e9SAndroid Build Coastguard Worker     mRender = false;
135*d57664e9SAndroid Build Coastguard Worker     if (mEasData) {
136*d57664e9SAndroid Build Coastguard Worker         JET_Pause(mEasData);
137*d57664e9SAndroid Build Coastguard Worker         JET_CloseFile(mEasData);
138*d57664e9SAndroid Build Coastguard Worker         JET_Shutdown(mEasData);
139*d57664e9SAndroid Build Coastguard Worker         EAS_Shutdown(mEasData);
140*d57664e9SAndroid Build Coastguard Worker     }
141*d57664e9SAndroid Build Coastguard Worker     delete mIoWrapper;
142*d57664e9SAndroid Build Coastguard Worker     mIoWrapper = NULL;
143*d57664e9SAndroid Build Coastguard Worker     if (mAudioTrack != 0) {
144*d57664e9SAndroid Build Coastguard Worker         mAudioTrack->stop();
145*d57664e9SAndroid Build Coastguard Worker         mAudioTrack->flush();
146*d57664e9SAndroid Build Coastguard Worker         mAudioTrack.clear();
147*d57664e9SAndroid Build Coastguard Worker     }
148*d57664e9SAndroid Build Coastguard Worker     if (mAudioBuffer) {
149*d57664e9SAndroid Build Coastguard Worker         delete mAudioBuffer;
150*d57664e9SAndroid Build Coastguard Worker         mAudioBuffer = NULL;
151*d57664e9SAndroid Build Coastguard Worker     }
152*d57664e9SAndroid Build Coastguard Worker     mEasData = NULL;
153*d57664e9SAndroid Build Coastguard Worker 
154*d57664e9SAndroid Build Coastguard Worker     return EAS_SUCCESS;
155*d57664e9SAndroid Build Coastguard Worker }
156*d57664e9SAndroid Build Coastguard Worker 
157*d57664e9SAndroid Build Coastguard Worker 
158*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
render()159*d57664e9SAndroid Build Coastguard Worker int JetPlayer::render() {
160*d57664e9SAndroid Build Coastguard Worker     EAS_RESULT result = EAS_FAILURE;
161*d57664e9SAndroid Build Coastguard Worker     EAS_I32 count;
162*d57664e9SAndroid Build Coastguard Worker     int temp;
163*d57664e9SAndroid Build Coastguard Worker     bool audioStarted = false;
164*d57664e9SAndroid Build Coastguard Worker 
165*d57664e9SAndroid Build Coastguard Worker     ALOGV("JetPlayer::render(): entering");
166*d57664e9SAndroid Build Coastguard Worker 
167*d57664e9SAndroid Build Coastguard Worker     // allocate render buffer
168*d57664e9SAndroid Build Coastguard Worker     mAudioBuffer =
169*d57664e9SAndroid Build Coastguard Worker         new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * MIX_NUM_BUFFERS];
170*d57664e9SAndroid Build Coastguard Worker 
171*d57664e9SAndroid Build Coastguard Worker     // signal main thread that we started
172*d57664e9SAndroid Build Coastguard Worker     {
173*d57664e9SAndroid Build Coastguard Worker         Mutex::Autolock l(mMutex);
174*d57664e9SAndroid Build Coastguard Worker         mTid = gettid();
175*d57664e9SAndroid Build Coastguard Worker         ALOGV("JetPlayer::render(): render thread(%d) signal", mTid);
176*d57664e9SAndroid Build Coastguard Worker         mCondition.signal();
177*d57664e9SAndroid Build Coastguard Worker     }
178*d57664e9SAndroid Build Coastguard Worker 
179*d57664e9SAndroid Build Coastguard Worker     while (1) {
180*d57664e9SAndroid Build Coastguard Worker 
181*d57664e9SAndroid Build Coastguard Worker         mMutex.lock(); // [[[[[[[[ LOCK ---------------------------------------
182*d57664e9SAndroid Build Coastguard Worker 
183*d57664e9SAndroid Build Coastguard Worker         if (mEasData == NULL) {
184*d57664e9SAndroid Build Coastguard Worker             mMutex.unlock();
185*d57664e9SAndroid Build Coastguard Worker             ALOGV("JetPlayer::render(): NULL EAS data, exiting render.");
186*d57664e9SAndroid Build Coastguard Worker             goto threadExit;
187*d57664e9SAndroid Build Coastguard Worker         }
188*d57664e9SAndroid Build Coastguard Worker 
189*d57664e9SAndroid Build Coastguard Worker         // nothing to render, wait for client thread to wake us up
190*d57664e9SAndroid Build Coastguard Worker         while (!mRender)
191*d57664e9SAndroid Build Coastguard Worker         {
192*d57664e9SAndroid Build Coastguard Worker             ALOGV("JetPlayer::render(): signal wait");
193*d57664e9SAndroid Build Coastguard Worker             if (audioStarted) {
194*d57664e9SAndroid Build Coastguard Worker                 mAudioTrack->pause();
195*d57664e9SAndroid Build Coastguard Worker                 // we have to restart the playback once we start rendering again
196*d57664e9SAndroid Build Coastguard Worker                 audioStarted = false;
197*d57664e9SAndroid Build Coastguard Worker             }
198*d57664e9SAndroid Build Coastguard Worker             mCondition.wait(mMutex);
199*d57664e9SAndroid Build Coastguard Worker             ALOGV("JetPlayer::render(): signal rx'd");
200*d57664e9SAndroid Build Coastguard Worker         }
201*d57664e9SAndroid Build Coastguard Worker 
202*d57664e9SAndroid Build Coastguard Worker         // render midi data into the input buffer
203*d57664e9SAndroid Build Coastguard Worker         int num_output = 0;
204*d57664e9SAndroid Build Coastguard Worker         EAS_PCM* p = mAudioBuffer;
205*d57664e9SAndroid Build Coastguard Worker         for (int i = 0; i < MIX_NUM_BUFFERS; i++) {
206*d57664e9SAndroid Build Coastguard Worker             result = EAS_Render(mEasData, p, pLibConfig->mixBufferSize, &count);
207*d57664e9SAndroid Build Coastguard Worker             if (result != EAS_SUCCESS) {
208*d57664e9SAndroid Build Coastguard Worker                 ALOGE("JetPlayer::render(): EAS_Render returned error %ld", result);
209*d57664e9SAndroid Build Coastguard Worker             }
210*d57664e9SAndroid Build Coastguard Worker             p += count * pLibConfig->numChannels;
211*d57664e9SAndroid Build Coastguard Worker             num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM);
212*d57664e9SAndroid Build Coastguard Worker 
213*d57664e9SAndroid Build Coastguard Worker             // send events that were generated (if any) to the event callback
214*d57664e9SAndroid Build Coastguard Worker             fireEventsFromJetQueue();
215*d57664e9SAndroid Build Coastguard Worker         }
216*d57664e9SAndroid Build Coastguard Worker 
217*d57664e9SAndroid Build Coastguard Worker         // update playback state
218*d57664e9SAndroid Build Coastguard Worker         //ALOGV("JetPlayer::render(): updating state");
219*d57664e9SAndroid Build Coastguard Worker         JET_Status(mEasData, &mJetStatus);
220*d57664e9SAndroid Build Coastguard Worker         fireUpdateOnStatusChange();
221*d57664e9SAndroid Build Coastguard Worker         mPaused = mJetStatus.paused;
222*d57664e9SAndroid Build Coastguard Worker 
223*d57664e9SAndroid Build Coastguard Worker         mMutex.unlock(); // UNLOCK ]]]]]]]] -----------------------------------
224*d57664e9SAndroid Build Coastguard Worker 
225*d57664e9SAndroid Build Coastguard Worker         // check audio output track
226*d57664e9SAndroid Build Coastguard Worker         if (mAudioTrack == NULL) {
227*d57664e9SAndroid Build Coastguard Worker             ALOGE("JetPlayer::render(): output AudioTrack was not created");
228*d57664e9SAndroid Build Coastguard Worker             goto threadExit;
229*d57664e9SAndroid Build Coastguard Worker         }
230*d57664e9SAndroid Build Coastguard Worker 
231*d57664e9SAndroid Build Coastguard Worker         // Write data to the audio hardware
232*d57664e9SAndroid Build Coastguard Worker         //ALOGV("JetPlayer::render(): writing to audio output");
233*d57664e9SAndroid Build Coastguard Worker         if ((temp = mAudioTrack->write(mAudioBuffer, num_output)) < 0) {
234*d57664e9SAndroid Build Coastguard Worker             ALOGE("JetPlayer::render(): Error in writing:%d",temp);
235*d57664e9SAndroid Build Coastguard Worker             return temp;
236*d57664e9SAndroid Build Coastguard Worker         }
237*d57664e9SAndroid Build Coastguard Worker 
238*d57664e9SAndroid Build Coastguard Worker         // start audio output if necessary
239*d57664e9SAndroid Build Coastguard Worker         if (!audioStarted) {
240*d57664e9SAndroid Build Coastguard Worker             ALOGV("JetPlayer::render(): starting audio playback");
241*d57664e9SAndroid Build Coastguard Worker             mAudioTrack->start();
242*d57664e9SAndroid Build Coastguard Worker             audioStarted = true;
243*d57664e9SAndroid Build Coastguard Worker         }
244*d57664e9SAndroid Build Coastguard Worker 
245*d57664e9SAndroid Build Coastguard Worker     }//while (1)
246*d57664e9SAndroid Build Coastguard Worker 
247*d57664e9SAndroid Build Coastguard Worker threadExit:
248*d57664e9SAndroid Build Coastguard Worker     if (mAudioTrack != NULL) {
249*d57664e9SAndroid Build Coastguard Worker         mAudioTrack->stop();
250*d57664e9SAndroid Build Coastguard Worker         mAudioTrack->flush();
251*d57664e9SAndroid Build Coastguard Worker     }
252*d57664e9SAndroid Build Coastguard Worker     delete [] mAudioBuffer;
253*d57664e9SAndroid Build Coastguard Worker     mAudioBuffer = NULL;
254*d57664e9SAndroid Build Coastguard Worker     mMutex.lock();
255*d57664e9SAndroid Build Coastguard Worker     mTid = -1;
256*d57664e9SAndroid Build Coastguard Worker     mCondition.signal();
257*d57664e9SAndroid Build Coastguard Worker     mMutex.unlock();
258*d57664e9SAndroid Build Coastguard Worker     return result;
259*d57664e9SAndroid Build Coastguard Worker }
260*d57664e9SAndroid Build Coastguard Worker 
261*d57664e9SAndroid Build Coastguard Worker 
262*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
263*d57664e9SAndroid Build Coastguard Worker // fire up an update if any of the status fields has changed
264*d57664e9SAndroid Build Coastguard Worker // precondition: mMutex locked
fireUpdateOnStatusChange()265*d57664e9SAndroid Build Coastguard Worker void JetPlayer::fireUpdateOnStatusChange()
266*d57664e9SAndroid Build Coastguard Worker {
267*d57664e9SAndroid Build Coastguard Worker     if ( (mJetStatus.currentUserID      != mPreviousJetStatus.currentUserID)
268*d57664e9SAndroid Build Coastguard Worker        ||(mJetStatus.segmentRepeatCount != mPreviousJetStatus.segmentRepeatCount) ) {
269*d57664e9SAndroid Build Coastguard Worker         if (mEventCallback)  {
270*d57664e9SAndroid Build Coastguard Worker             mEventCallback(
271*d57664e9SAndroid Build Coastguard Worker                 JetPlayer::JET_USERID_UPDATE,
272*d57664e9SAndroid Build Coastguard Worker                 mJetStatus.currentUserID,
273*d57664e9SAndroid Build Coastguard Worker                 mJetStatus.segmentRepeatCount,
274*d57664e9SAndroid Build Coastguard Worker                 mJavaJetPlayerRef);
275*d57664e9SAndroid Build Coastguard Worker         }
276*d57664e9SAndroid Build Coastguard Worker         mPreviousJetStatus.currentUserID      = mJetStatus.currentUserID;
277*d57664e9SAndroid Build Coastguard Worker         mPreviousJetStatus.segmentRepeatCount = mJetStatus.segmentRepeatCount;
278*d57664e9SAndroid Build Coastguard Worker     }
279*d57664e9SAndroid Build Coastguard Worker 
280*d57664e9SAndroid Build Coastguard Worker     if (mJetStatus.numQueuedSegments != mPreviousJetStatus.numQueuedSegments) {
281*d57664e9SAndroid Build Coastguard Worker         if (mEventCallback)  {
282*d57664e9SAndroid Build Coastguard Worker             mEventCallback(
283*d57664e9SAndroid Build Coastguard Worker                 JetPlayer::JET_NUMQUEUEDSEGMENT_UPDATE,
284*d57664e9SAndroid Build Coastguard Worker                 mJetStatus.numQueuedSegments,
285*d57664e9SAndroid Build Coastguard Worker                 -1,
286*d57664e9SAndroid Build Coastguard Worker                 mJavaJetPlayerRef);
287*d57664e9SAndroid Build Coastguard Worker         }
288*d57664e9SAndroid Build Coastguard Worker         mPreviousJetStatus.numQueuedSegments  = mJetStatus.numQueuedSegments;
289*d57664e9SAndroid Build Coastguard Worker     }
290*d57664e9SAndroid Build Coastguard Worker 
291*d57664e9SAndroid Build Coastguard Worker     if (mJetStatus.paused != mPreviousJetStatus.paused) {
292*d57664e9SAndroid Build Coastguard Worker         if (mEventCallback)  {
293*d57664e9SAndroid Build Coastguard Worker             mEventCallback(JetPlayer::JET_PAUSE_UPDATE,
294*d57664e9SAndroid Build Coastguard Worker                 mJetStatus.paused,
295*d57664e9SAndroid Build Coastguard Worker                 -1,
296*d57664e9SAndroid Build Coastguard Worker                 mJavaJetPlayerRef);
297*d57664e9SAndroid Build Coastguard Worker         }
298*d57664e9SAndroid Build Coastguard Worker         mPreviousJetStatus.paused = mJetStatus.paused;
299*d57664e9SAndroid Build Coastguard Worker     }
300*d57664e9SAndroid Build Coastguard Worker 
301*d57664e9SAndroid Build Coastguard Worker }
302*d57664e9SAndroid Build Coastguard Worker 
303*d57664e9SAndroid Build Coastguard Worker 
304*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
305*d57664e9SAndroid Build Coastguard Worker // fire up all the JET events in the JET engine queue (until the queue is empty)
306*d57664e9SAndroid Build Coastguard Worker // precondition: mMutex locked
fireEventsFromJetQueue()307*d57664e9SAndroid Build Coastguard Worker void JetPlayer::fireEventsFromJetQueue()
308*d57664e9SAndroid Build Coastguard Worker {
309*d57664e9SAndroid Build Coastguard Worker     if (!mEventCallback) {
310*d57664e9SAndroid Build Coastguard Worker         // no callback, just empty the event queue
311*d57664e9SAndroid Build Coastguard Worker         while (JET_GetEvent(mEasData, NULL, NULL)) { }
312*d57664e9SAndroid Build Coastguard Worker         return;
313*d57664e9SAndroid Build Coastguard Worker     }
314*d57664e9SAndroid Build Coastguard Worker 
315*d57664e9SAndroid Build Coastguard Worker     EAS_U32 rawEvent;
316*d57664e9SAndroid Build Coastguard Worker     while (JET_GetEvent(mEasData, &rawEvent, NULL)) {
317*d57664e9SAndroid Build Coastguard Worker         mEventCallback(
318*d57664e9SAndroid Build Coastguard Worker             JetPlayer::JET_EVENT,
319*d57664e9SAndroid Build Coastguard Worker             rawEvent,
320*d57664e9SAndroid Build Coastguard Worker             -1,
321*d57664e9SAndroid Build Coastguard Worker             mJavaJetPlayerRef);
322*d57664e9SAndroid Build Coastguard Worker     }
323*d57664e9SAndroid Build Coastguard Worker }
324*d57664e9SAndroid Build Coastguard Worker 
325*d57664e9SAndroid Build Coastguard Worker 
326*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
loadFromFile(const char * path)327*d57664e9SAndroid Build Coastguard Worker int JetPlayer::loadFromFile(const char* path)
328*d57664e9SAndroid Build Coastguard Worker {
329*d57664e9SAndroid Build Coastguard Worker     ALOGV("JetPlayer::loadFromFile(): path=%s", path);
330*d57664e9SAndroid Build Coastguard Worker 
331*d57664e9SAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
332*d57664e9SAndroid Build Coastguard Worker 
333*d57664e9SAndroid Build Coastguard Worker     delete mIoWrapper;
334*d57664e9SAndroid Build Coastguard Worker     mIoWrapper = new MidiIoWrapper(path);
335*d57664e9SAndroid Build Coastguard Worker 
336*d57664e9SAndroid Build Coastguard Worker     EAS_RESULT result = JET_OpenFile(mEasData, mIoWrapper->getLocator());
337*d57664e9SAndroid Build Coastguard Worker     if (result != EAS_SUCCESS)
338*d57664e9SAndroid Build Coastguard Worker         mState = EAS_STATE_ERROR;
339*d57664e9SAndroid Build Coastguard Worker     else
340*d57664e9SAndroid Build Coastguard Worker         mState = EAS_STATE_OPEN;
341*d57664e9SAndroid Build Coastguard Worker     return( result );
342*d57664e9SAndroid Build Coastguard Worker }
343*d57664e9SAndroid Build Coastguard Worker 
344*d57664e9SAndroid Build Coastguard Worker 
345*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
loadFromFD(const int fd,const long long offset,const long long length)346*d57664e9SAndroid Build Coastguard Worker int JetPlayer::loadFromFD(const int fd, const long long offset, const long long length)
347*d57664e9SAndroid Build Coastguard Worker {
348*d57664e9SAndroid Build Coastguard Worker     ALOGV("JetPlayer::loadFromFD(): fd=%d offset=%lld length=%lld", fd, offset, length);
349*d57664e9SAndroid Build Coastguard Worker 
350*d57664e9SAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
351*d57664e9SAndroid Build Coastguard Worker 
352*d57664e9SAndroid Build Coastguard Worker     delete mIoWrapper;
353*d57664e9SAndroid Build Coastguard Worker     mIoWrapper = new MidiIoWrapper(fd, offset, length);
354*d57664e9SAndroid Build Coastguard Worker 
355*d57664e9SAndroid Build Coastguard Worker     EAS_RESULT result = JET_OpenFile(mEasData, mIoWrapper->getLocator());
356*d57664e9SAndroid Build Coastguard Worker     if (result != EAS_SUCCESS)
357*d57664e9SAndroid Build Coastguard Worker         mState = EAS_STATE_ERROR;
358*d57664e9SAndroid Build Coastguard Worker     else
359*d57664e9SAndroid Build Coastguard Worker         mState = EAS_STATE_OPEN;
360*d57664e9SAndroid Build Coastguard Worker     return( result );
361*d57664e9SAndroid Build Coastguard Worker }
362*d57664e9SAndroid Build Coastguard Worker 
363*d57664e9SAndroid Build Coastguard Worker 
364*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
closeFile()365*d57664e9SAndroid Build Coastguard Worker int JetPlayer::closeFile()
366*d57664e9SAndroid Build Coastguard Worker {
367*d57664e9SAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
368*d57664e9SAndroid Build Coastguard Worker     return JET_CloseFile(mEasData);
369*d57664e9SAndroid Build Coastguard Worker }
370*d57664e9SAndroid Build Coastguard Worker 
371*d57664e9SAndroid Build Coastguard Worker 
372*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
play()373*d57664e9SAndroid Build Coastguard Worker int JetPlayer::play()
374*d57664e9SAndroid Build Coastguard Worker {
375*d57664e9SAndroid Build Coastguard Worker     ALOGV("JetPlayer::play(): entering");
376*d57664e9SAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
377*d57664e9SAndroid Build Coastguard Worker 
378*d57664e9SAndroid Build Coastguard Worker     EAS_RESULT result = JET_Play(mEasData);
379*d57664e9SAndroid Build Coastguard Worker 
380*d57664e9SAndroid Build Coastguard Worker     mPaused = false;
381*d57664e9SAndroid Build Coastguard Worker     mRender = true;
382*d57664e9SAndroid Build Coastguard Worker 
383*d57664e9SAndroid Build Coastguard Worker     JET_Status(mEasData, &mJetStatus);
384*d57664e9SAndroid Build Coastguard Worker     this->dumpJetStatus(&mJetStatus);
385*d57664e9SAndroid Build Coastguard Worker 
386*d57664e9SAndroid Build Coastguard Worker     fireUpdateOnStatusChange();
387*d57664e9SAndroid Build Coastguard Worker 
388*d57664e9SAndroid Build Coastguard Worker     // wake up render thread
389*d57664e9SAndroid Build Coastguard Worker     ALOGV("JetPlayer::play(): wakeup render thread");
390*d57664e9SAndroid Build Coastguard Worker     mCondition.signal();
391*d57664e9SAndroid Build Coastguard Worker 
392*d57664e9SAndroid Build Coastguard Worker     return result;
393*d57664e9SAndroid Build Coastguard Worker }
394*d57664e9SAndroid Build Coastguard Worker 
395*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
pause()396*d57664e9SAndroid Build Coastguard Worker int JetPlayer::pause()
397*d57664e9SAndroid Build Coastguard Worker {
398*d57664e9SAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
399*d57664e9SAndroid Build Coastguard Worker     mPaused = true;
400*d57664e9SAndroid Build Coastguard Worker     EAS_RESULT result = JET_Pause(mEasData);
401*d57664e9SAndroid Build Coastguard Worker 
402*d57664e9SAndroid Build Coastguard Worker     mRender = false;
403*d57664e9SAndroid Build Coastguard Worker 
404*d57664e9SAndroid Build Coastguard Worker     JET_Status(mEasData, &mJetStatus);
405*d57664e9SAndroid Build Coastguard Worker     this->dumpJetStatus(&mJetStatus);
406*d57664e9SAndroid Build Coastguard Worker     fireUpdateOnStatusChange();
407*d57664e9SAndroid Build Coastguard Worker 
408*d57664e9SAndroid Build Coastguard Worker 
409*d57664e9SAndroid Build Coastguard Worker     return result;
410*d57664e9SAndroid Build Coastguard Worker }
411*d57664e9SAndroid Build Coastguard Worker 
412*d57664e9SAndroid Build Coastguard Worker 
413*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
queueSegment(int segmentNum,int libNum,int repeatCount,int transpose,EAS_U32 muteFlags,EAS_U8 userID)414*d57664e9SAndroid Build Coastguard Worker int JetPlayer::queueSegment(int segmentNum, int libNum, int repeatCount, int transpose,
415*d57664e9SAndroid Build Coastguard Worker         EAS_U32 muteFlags, EAS_U8 userID)
416*d57664e9SAndroid Build Coastguard Worker {
417*d57664e9SAndroid Build Coastguard Worker     ALOGV("JetPlayer::queueSegment segmentNum=%d, libNum=%d, repeatCount=%d, transpose=%d",
418*d57664e9SAndroid Build Coastguard Worker         segmentNum, libNum, repeatCount, transpose);
419*d57664e9SAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
420*d57664e9SAndroid Build Coastguard Worker     return JET_QueueSegment(mEasData, segmentNum, libNum, repeatCount, transpose, muteFlags,
421*d57664e9SAndroid Build Coastguard Worker             userID);
422*d57664e9SAndroid Build Coastguard Worker }
423*d57664e9SAndroid Build Coastguard Worker 
424*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
setMuteFlags(EAS_U32 muteFlags,bool sync)425*d57664e9SAndroid Build Coastguard Worker int JetPlayer::setMuteFlags(EAS_U32 muteFlags, bool sync)
426*d57664e9SAndroid Build Coastguard Worker {
427*d57664e9SAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
428*d57664e9SAndroid Build Coastguard Worker     return JET_SetMuteFlags(mEasData, muteFlags, sync);
429*d57664e9SAndroid Build Coastguard Worker }
430*d57664e9SAndroid Build Coastguard Worker 
431*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
setMuteFlag(int trackNum,bool muteFlag,bool sync)432*d57664e9SAndroid Build Coastguard Worker int JetPlayer::setMuteFlag(int trackNum, bool muteFlag, bool sync)
433*d57664e9SAndroid Build Coastguard Worker {
434*d57664e9SAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
435*d57664e9SAndroid Build Coastguard Worker     return JET_SetMuteFlag(mEasData, trackNum, muteFlag, sync);
436*d57664e9SAndroid Build Coastguard Worker }
437*d57664e9SAndroid Build Coastguard Worker 
438*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
triggerClip(int clipId)439*d57664e9SAndroid Build Coastguard Worker int JetPlayer::triggerClip(int clipId)
440*d57664e9SAndroid Build Coastguard Worker {
441*d57664e9SAndroid Build Coastguard Worker     ALOGV("JetPlayer::triggerClip clipId=%d", clipId);
442*d57664e9SAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
443*d57664e9SAndroid Build Coastguard Worker     return JET_TriggerClip(mEasData, clipId);
444*d57664e9SAndroid Build Coastguard Worker }
445*d57664e9SAndroid Build Coastguard Worker 
446*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
clearQueue()447*d57664e9SAndroid Build Coastguard Worker int JetPlayer::clearQueue()
448*d57664e9SAndroid Build Coastguard Worker {
449*d57664e9SAndroid Build Coastguard Worker     ALOGV("JetPlayer::clearQueue");
450*d57664e9SAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
451*d57664e9SAndroid Build Coastguard Worker     return JET_Clear_Queue(mEasData);
452*d57664e9SAndroid Build Coastguard Worker }
453*d57664e9SAndroid Build Coastguard Worker 
454*d57664e9SAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------
dump()455*d57664e9SAndroid Build Coastguard Worker void JetPlayer::dump()
456*d57664e9SAndroid Build Coastguard Worker {
457*d57664e9SAndroid Build Coastguard Worker }
458*d57664e9SAndroid Build Coastguard Worker 
dumpJetStatus(S_JET_STATUS * pJetStatus)459*d57664e9SAndroid Build Coastguard Worker void JetPlayer::dumpJetStatus(S_JET_STATUS* pJetStatus)
460*d57664e9SAndroid Build Coastguard Worker {
461*d57664e9SAndroid Build Coastguard Worker     if (pJetStatus!=NULL)
462*d57664e9SAndroid Build Coastguard Worker         ALOGV(">> current JET player status: userID=%d segmentRepeatCount=%d numQueuedSegments=%d "
463*d57664e9SAndroid Build Coastguard Worker                 "paused=%d",
464*d57664e9SAndroid Build Coastguard Worker                 pJetStatus->currentUserID, pJetStatus->segmentRepeatCount,
465*d57664e9SAndroid Build Coastguard Worker                 pJetStatus->numQueuedSegments, pJetStatus->paused);
466*d57664e9SAndroid Build Coastguard Worker     else
467*d57664e9SAndroid Build Coastguard Worker         ALOGE(">> JET player status is NULL");
468*d57664e9SAndroid Build Coastguard Worker }
469*d57664e9SAndroid Build Coastguard Worker 
470*d57664e9SAndroid Build Coastguard Worker 
471*d57664e9SAndroid Build Coastguard Worker } // end namespace android
472