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