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