1 /*---------------------------------------------------------------------------*
2 Project: THP Player
3 File: THPAudioDecode.c
4
5 Copyright (C)2002-2006 Nintendo All Rights Reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: THPAudioDecode.c,v $
14 Revision 1.1 02/03/2006 10:01:27 aka
15 Imported from Dolphin tree.
16
17
18 3 03/11/25 11:24 Dante
19 Japanese to English translation of comments and text strings
20
21 2 03/09/16 15:42:00 Suzuki
22 changed DECODE_BUFFER_NUM to DECODE_AUDIO_BUFFER_NUM.
23
24 1 02/05/14 11:28a Suzuki
25 Initial check-in.
26
27 $NoKeywords: $
28
29 *---------------------------------------------------------------------------*/
30
31 #include <revolution.h>
32
33 #include "THPPlayerStrmAX.h"
34 #include "THPAudioDecode.h"
35 #include "THPRead.h"
36
37 /*---------------------------------------------------------------------------*
38 External Function
39 *---------------------------------------------------------------------------*/
40
41 extern void PrepareReady(BOOL flag);
42
43 /*---------------------------------------------------------------------------*
44 Static Function
45 *---------------------------------------------------------------------------*/
46
47 static void *AudioDecoder(void *ptr);
48 static void *AudioDecoderForOnMemory(void *ptr);
49 static void AudioDecode(THPReadBuffer *readBuffer);
50
51 /*---------------------------------------------------------------------------*
52 Global Variable
53 *---------------------------------------------------------------------------*/
54
55 extern THPPlayer ActivePlayer;
56
57 /*---------------------------------------------------------------------------*
58 Static Variable
59 *---------------------------------------------------------------------------*/
60
61 static s32 AudioDecodeThreadCreated = 0;
62 static OSThread AudioDecodeThread;
63 static u8 AudioDecodeThreadStack[4*1024];
64 static OSMessageQueue FreeAudioBufferQueue;
65 static OSMessageQueue DecodedAudioBufferQueue;
66 static OSMessage FreeAudioBufferMessage[DECODE_AUDIO_BUFFER_NUM];
67 static OSMessage DecodedAudioBufferMessage[DECODE_AUDIO_BUFFER_NUM];
68
69 /*---------------------------------------------------------------------------*
70 Name: CreateAudioDecodeThread
71
72 Description: Creation of audio decode thread
73
74 Arguments: priority thread priority
75 ptr Pointer to memory where the start data of movie
76 is with OnMemory playback.
77
78 Return Values: If creation of thread succeeds, returns TRUE. If creation fails, returns FALSE.
79 *---------------------------------------------------------------------------*/
80
CreateAudioDecodeThread(OSPriority priority,u8 * ptr)81 BOOL CreateAudioDecodeThread(OSPriority priority, u8 *ptr)
82 {
83 if (ptr)
84 {
85 if (OSCreateThread(&AudioDecodeThread,
86 AudioDecoderForOnMemory,
87 ptr,
88 AudioDecodeThreadStack + sizeof(AudioDecodeThreadStack),
89 sizeof(AudioDecodeThreadStack),
90 priority,
91 OS_THREAD_ATTR_DETACH) == FALSE)
92 {
93 #ifdef _DEBUG
94 OSReport("Can't create audio decode thread\n");
95 #endif
96 return FALSE;
97 }
98 }
99 else
100 {
101 if (OSCreateThread(&AudioDecodeThread,
102 AudioDecoder,
103 NULL,
104 AudioDecodeThreadStack + sizeof(AudioDecodeThreadStack),
105 sizeof(AudioDecodeThreadStack),
106 priority,
107 OS_THREAD_ATTR_DETACH) == FALSE)
108 {
109 #ifdef _DEBUG
110 OSReport("Can't create audio decode thread\n");
111 #endif
112 return FALSE;
113 }
114 }
115
116 OSInitMessageQueue(&FreeAudioBufferQueue,
117 FreeAudioBufferMessage,
118 DECODE_AUDIO_BUFFER_NUM);
119
120 OSInitMessageQueue(&DecodedAudioBufferQueue,
121 DecodedAudioBufferMessage,
122 DECODE_AUDIO_BUFFER_NUM);
123
124 AudioDecodeThreadCreated = 1;
125
126 return TRUE;
127 }
128
129 /*---------------------------------------------------------------------------*
130 Name: AudioDecodeThreadStart
131
132 Description: Start of audio decode thread.
133
134 Arguments: None
135
136 Return Values: None
137 *---------------------------------------------------------------------------*/
138
AudioDecodeThreadStart(void)139 void AudioDecodeThreadStart(void)
140 {
141 if (AudioDecodeThreadCreated)
142 {
143 OSResumeThread(&AudioDecodeThread);
144 }
145
146 return;
147 }
148
149 /*---------------------------------------------------------------------------*
150 Name: AudioDecodeThreadCancel
151
152 Description: Cancel audio decode thread
153
154 Arguments: None
155
156 Returns: None
157 *---------------------------------------------------------------------------*/
158
AudioDecodeThreadCancel(void)159 void AudioDecodeThreadCancel(void)
160 {
161 if (AudioDecodeThreadCreated)
162 {
163 OSCancelThread(&AudioDecodeThread);
164
165 AudioDecodeThreadCreated = 0;
166 }
167
168 return;
169 }
170
171 /*---------------------------------------------------------------------------*
172 Name: AudioDecoder
173
174 Description: Audio decoder for streaming playback
175
176 Arguments: None
177
178 Returns: None
179 *---------------------------------------------------------------------------*/
180
AudioDecoder(void * ptr)181 static void *AudioDecoder(void *ptr)
182 {
183 #pragma unused(ptr)
184 THPReadBuffer *readBuffer;
185 s32 frameNumber, count;
186
187 count = 0;
188
189 while(1)
190 {
191 readBuffer = PopReadedBuffer();
192
193 AudioDecode(readBuffer);
194
195 if (count < 2)
196 {
197 if (!(ActivePlayer.playFlag & THP_PLAY_LOOP))
198 {
199 frameNumber = (s32)(readBuffer->frameNumber + ActivePlayer.initReadFrame);
200
201 if (frameNumber == ActivePlayer.header.numFrames - 1)
202 {
203 PrepareReady(TRUE);
204 }
205 }
206 }
207
208 if (count == 2)
209 {
210 PrepareReady(TRUE);
211 }
212
213 PushReadedBuffer2(readBuffer);
214
215 count++;
216 }
217
218 return NULL;
219 }
220
221 /*---------------------------------------------------------------------------*
222 Name: AudioDecoderForOnMemory
223
224 Description: Audio decoder for OnMemory playback.
225
226 Arguments: None
227
228 Returns: None
229 *---------------------------------------------------------------------------*/
230
AudioDecoderForOnMemory(void * ptr)231 static void *AudioDecoderForOnMemory(void *ptr)
232 {
233 THPReadBuffer readBuffer;
234 s32 tmp, size, readFrame, frameNumber;
235
236 size = ActivePlayer.initReadSize;
237 readBuffer.ptr = (u8 *)ptr;
238 readFrame = 0;
239
240 while(1)
241 {
242 readBuffer.frameNumber = readFrame;
243
244 AudioDecode(&readBuffer);
245
246 frameNumber = (s32)((readFrame + ActivePlayer.initReadFrame)
247 % ActivePlayer.header.numFrames);
248
249 // Check end of THP movie data
250 if (frameNumber == ActivePlayer.header.numFrames - 1)
251 {
252 // If loop playback, at beginning of movie data
253 if (ActivePlayer.playFlag & THP_PLAY_LOOP)
254 {
255 size = *(s32 *)(readBuffer.ptr);
256 readBuffer.ptr = ActivePlayer.movieData;
257 }
258 // Stop decode if one-shot playback
259 else
260 {
261 if (readFrame < 2)
262 {
263 PrepareReady(TRUE);
264 }
265 OSSuspendThread(&AudioDecodeThread);
266 }
267 }
268 // Move next frame pointer if not end
269 else
270 {
271 tmp = *(s32 *)(readBuffer.ptr);
272 readBuffer.ptr += size;
273 size = tmp;
274 }
275
276 if (readFrame == 2)
277 {
278 PrepareReady(TRUE);
279 }
280
281 readFrame++;
282 }
283
284 return NULL;
285 }
286
287 /*---------------------------------------------------------------------------*
288 Name: AudioDecode
289
290 Description: Decoding of THP audio data.
291
292 Arguments: readBuffer Pointer to buffer where THP frame stored.
293
294 Returns: None
295 *---------------------------------------------------------------------------*/
296
AudioDecode(THPReadBuffer * readBuffer)297 static void AudioDecode(THPReadBuffer *readBuffer)
298 {
299 THPAudioBuffer *audioBuffer;
300 u32 i, sample;
301 u32 *compSizePtr;
302 u8 *ptr;
303
304 compSizePtr = (u32 *)(readBuffer->ptr + 8);
305 ptr = readBuffer->ptr + ActivePlayer.compInfo.numComponents * 4 + 8;
306
307 audioBuffer = PopFreeAudioBuffer();
308
309 for (i = 0 ; i < ActivePlayer.compInfo.numComponents ; i++)
310 {
311 switch (ActivePlayer.compInfo.frameComp[i])
312 {
313 case THP_AUDIO_COMP:
314 sample = THPAudioDecode(audioBuffer->buffer,
315 ptr + (*compSizePtr) * ActivePlayer.curAudioTrack,
316 THP_AUDIO_INTERLEAVE);
317 audioBuffer->validSample = sample;
318 audioBuffer->curPtr = audioBuffer->buffer;
319 PushDecodedAudioBuffer(audioBuffer);
320 return;
321 default:
322 ptr += *compSizePtr;
323 compSizePtr++;
324 }
325 }
326
327 return;
328 }
329
330 /*---------------------------------------------------------------------------*
331 Name: PopFreeAudioBuffer
332
333 Description: Acquire audio buffers not used.
334
335 Arguments: None
336
337 Returns: Pointer for audio buffers not used.
338 *---------------------------------------------------------------------------*/
339
PopFreeAudioBuffer()340 void *PopFreeAudioBuffer()
341 {
342 OSMessage msg;
343
344 OSReceiveMessage(&FreeAudioBufferQueue, &msg, OS_MESSAGE_BLOCK);
345
346 return msg;
347 }
348
349 /*---------------------------------------------------------------------------*
350 Name: PushFreeAudioBuffer
351
352 Description: Free THP audio data finished playing back.
353
354 Arguments: buffer Pointer for THP audio data finished playing back.
355
356 Returns: None
357 *---------------------------------------------------------------------------*/
358
PushFreeAudioBuffer(void * buffer)359 void PushFreeAudioBuffer(void *buffer)
360 {
361 OSSendMessage(&FreeAudioBufferQueue, buffer, OS_MESSAGE_NOBLOCK);
362
363 return;
364 }
365
366 /*---------------------------------------------------------------------------*
367 Name: PopDecodedAudioBuffer
368
369 Description: Acquire decoded THP audio data.
370
371 Arguments: Block until can get decoded THP audio data
372 if flag OS_MESSAGE_BLOCK. Do not block if
373 OS_MESSAGE_NOBLOCK.
374
375 Returns: If successful, return audio buffer pointer.
376 If unsuccessful, NULL is returned.
377 *---------------------------------------------------------------------------*/
378
PopDecodedAudioBuffer(s32 flag)379 void *PopDecodedAudioBuffer(s32 flag)
380 {
381 OSMessage msg;
382
383 if (OSReceiveMessage(&DecodedAudioBufferQueue, &msg, flag) == TRUE)
384 {
385 return msg;
386 }
387 else
388 {
389 return NULL;
390 }
391 }
392
393 /*---------------------------------------------------------------------------*
394 Name: PushDecodedAudioBuffer
395
396 Description: Push THP audio that has finished decoding into queue
397
398 Arguments: buffer Pointer for decoded THP audio data.
399
400 Returns: None
401 *---------------------------------------------------------------------------*/
402
PushDecodedAudioBuffer(void * buffer)403 void PushDecodedAudioBuffer(void *buffer)
404 {
405 OSSendMessage(&DecodedAudioBufferQueue, buffer, OS_MESSAGE_BLOCK);
406
407 return;
408 }
409
410
411
412