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