1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/DEMOLib
3   File:     DEMOWave.c
4 
5   Copyright 2007-2008 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   $Date:: 2008-10-02#$
14   $Rev: 8827 $
15   $Author: yosizaki $
16  *---------------------------------------------------------------------------*/
17 #ifdef SDK_TWL
18 #include <twl.h>
19 #else
20 #include <nitro.h>
21 #endif
22 #include "DEMOWave.h"
23 
24 #define MAKE_FOURCC(cc1, cc2, cc3, cc4) (u32)((cc1) | (cc2 << 8) | (cc3 << 16) | (cc4 << 24))
25 
26 #define FOURCC_RIFF MAKE_FOURCC('R', 'I', 'F', 'F')
27 #define FOURCC_WAVE MAKE_FOURCC('W', 'A', 'V', 'E')
28 #define FOURCC_fmt  MAKE_FOURCC('f', 'm', 't', ' ')
29 #define FOURCC_data MAKE_FOURCC('d', 'a', 't', 'a')
30 
31 #define L_CHANNEL 4
32 #define R_CHANNEL 5
33 #define ALARM_NUM 0
34 #define STREAM_THREAD_PRIO 12
35 #define THREAD_STACK_SIZE 1024
36 #define STRM_BUF_PAGESIZE 1024*32
37 #define STRM_BUF_SIZE STRM_BUF_PAGESIZE*2
38 
39 // WAV format header
40 typedef struct WaveFormat
41 {
42     u16     format;
43     u16     channels;
44     s32     sampleRate;
45     u32     dataRate;
46     u16     blockAlign;
47     u16     bitPerSample;
48 }
49 WaveFormat;
50 
51 // Stream object
52 typedef struct StreamInfo
53 {
54     FSFile  file;
55     WaveFormat format;
56     u32     beginPos;
57     s32     dataSize;
58     BOOL    isPlay;
59 }
60 StreamInfo;
61 
62 static BOOL ReadWaveFormat(StreamInfo * strm);
63 static void CloseWave(void);
64 
65 static StreamInfo StrmInfo;
66 
67 /*---------------------------------------------------------------------------*
68   Name:         DEMOReadWave
69 
70   Description:  Initializes wave data.
71 
72   Arguments:    dst: Buffer in which to get waveform data
73                 filename:   Name of the streaming playback file
74 
75   Returns:      Returns the waveform data size
76  *---------------------------------------------------------------------------*/
DEMOReadWave(char * dst,const char * filename)77 int DEMOReadWave(char* dst, const char *filename)
78 {
79     int readSize;
80 
81     StreamInfo * strm = &StrmInfo;
82 
83     // File scanning
84     if (FS_IsFile(&strm->file))
85     {
86         (void)FS_CloseFile(&strm->file);
87     }
88     if (!FS_OpenFileEx(&strm->file, filename, FS_FILEMODE_R))
89     {
90         OS_Panic("Error: failed to open file %s\n", filename);
91     }
92     if (!ReadWaveFormat(strm))
93     {
94         OS_Panic("Error: failed to read wavefile\n");
95     }
96 
97     // seek to the sound data
98     (void)FS_SeekFile(&strm->file, (s32)strm->beginPos, FS_SEEK_SET);
99 
100     readSize = FS_ReadFile(&strm->file,
101                            dst, strm->dataSize);
102     if (readSize == -1)
103     {
104         OS_Panic("read file end\n");
105     }
106 
107     CloseWave();
108 
109     return readSize;
110 }
111 
112 /*---------------------------------------------------------------------------*
113   Name:         CloseWave
114 
115   Description:  Closes wave data
116 
117   Arguments:    strm:   Stream object
118 
119   Returns:      None
120  *---------------------------------------------------------------------------*/
CloseWave(void)121 static void CloseWave(void)
122 {
123     StreamInfo * strm = &StrmInfo;
124     if (FS_IsFile(&strm->file))
125     {
126         (void)FS_CloseFile(&strm->file);
127     }
128 }
129 
130 /*---------------------------------------------------------------------------*
131   Name:         ReadWaveFormat
132 
133   Description:  Gets the data size and first position of a data string, and the WAVE format data header
134 
135   Arguments:    strm:   Stream object
136 
137   Returns:      If readout is successful: TRUE; if failed: FALSE
138  *---------------------------------------------------------------------------*/
ReadWaveFormat(StreamInfo * strm)139 static BOOL ReadWaveFormat(StreamInfo * strm)
140 {
141     u32     tag;
142     s32     size;
143     BOOL    fFmt = FALSE, fData = FALSE;
144 
145     (void)FS_SeekFileToBegin(&strm->file);
146 
147     (void)FS_ReadFile(&strm->file, &tag, 4);
148     if (tag != FOURCC_RIFF)
149         return FALSE;
150 
151     (void)FS_ReadFile(&strm->file, &size, 4);
152 
153     (void)FS_ReadFile(&strm->file, &tag, 4);
154     if (tag != FOURCC_WAVE)
155         return FALSE;
156 
157     while (size > 0)
158     {
159         s32     chunkSize;
160         if (FS_ReadFile(&strm->file, &tag, 4) == -1)
161         {
162             return FALSE;
163         }
164         if (FS_ReadFile(&strm->file, &chunkSize, 4) == -1)
165         {
166             return FALSE;
167         }
168 
169         switch (tag)
170         {
171         case FOURCC_fmt:
172             if (FS_ReadFile(&strm->file, (u8 *)&strm->format, chunkSize) == -1)
173             {
174                 return FALSE;
175             }
176             fFmt = TRUE;
177             break;
178         case FOURCC_data:
179             strm->beginPos = FS_GetFilePosition(&strm->file);
180             strm->dataSize = chunkSize;
181             (void)FS_SeekFile(&strm->file, chunkSize, FS_SEEK_CUR);
182             fData = TRUE;
183             break;
184         default:
185             (void)FS_SeekFile(&strm->file, chunkSize, FS_SEEK_CUR);
186             break;
187         }
188         if (fFmt && fData)
189         {
190             return TRUE;               // Forces end if fmt and data have finished being read
191         }
192 
193         size -= chunkSize;
194     }
195 
196     if (size != 0)
197         return FALSE;
198     return TRUE;
199 }
200