1 /*--------------------------------------------------------------------------*
2 Project: Revolution SOUNDFILE dynamic link library
3 File: soundfile.c
4
5 Copyright (C)1998-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: soundfile.c,v $
14 Revision 1.3 2007/11/30 04:19:32 iwai_yuma
15 Related to Visual Studio 2005
16
17 Revision 1.3 2007/11/22 21:57:56 iwai
18 Replaced unsecure function to secure one.
19
20 Revision 1.2 2006/02/09 06:51:39 aka
21 Changed copyright.
22
23
24 *--------------------------------------------------------------------------*/
25 #include <windows.h>
26 #include <stdio.h>
27 #include "Types.h"
28 #include "soundfile.h"
29 #include "endian.h"
30 #include "aifffile.h"
31 #include "Wavfile.h"
32
33
34 #define SOUND_FILE_WAVE 0
35 #define SOUND_FILE_AIFF 1
36
37
38 /*--------------------------------------------------------------------------*
39 *--------------------------------------------------------------------------*/
getAiffInfo(char * path,SOUNDINFO * soundinfo,void * buffer)40 int getAiffInfo(char *path, SOUNDINFO *soundinfo, void *buffer)
41 {
42 FILE *file;
43 AIFFINFO aiffinfo;
44 errno_t err;
45
46 if( ( err = fopen_s( &file, path, "rb" ) ) != 0 )
47 // if (!(file = fopen(path, "rb")))
48 return SOUND_FILE_FOPEN_ERROR;
49
50 aiffReadHeader(&aiffinfo, file);
51
52 soundinfo->channels = aiffGetChannels(&aiffinfo);
53 soundinfo->bitsPerSample = aiffGetBitsPerSample(&aiffinfo);
54 soundinfo->sampleRate = aiffGetSampleRate(&aiffinfo);
55 soundinfo->samples = aiffGetSamples(&aiffinfo);
56 soundinfo->loopStart = aiffGetLoopStart(&aiffinfo);
57 soundinfo->loopEnd = aiffGetLoopEnd(&aiffinfo);
58 soundinfo->bufferLength = 0;
59
60 switch (soundinfo->bitsPerSample)
61 {
62 case 8:
63
64 soundinfo->bufferLength = soundinfo->samples * soundinfo->channels;
65
66 break;
67
68 case 16:
69
70 soundinfo->bufferLength = soundinfo->samples * soundinfo->channels * 2;
71
72 break;
73 }
74
75 if (buffer)
76 {
77 fread(buffer, soundinfo->bufferLength, 1, file);
78
79 if (soundinfo->bitsPerSample == 16)
80 reverse_buffer_16(buffer, soundinfo->bufferLength / 2);
81 }
82
83 fclose(file);
84
85 return SOUND_FILE_SUCCESS;
86 }
87
88
89 /*--------------------------------------------------------------------------*
90 *--------------------------------------------------------------------------*/
getWaveInfo(char * path,SOUNDINFO * soundinfo,void * buffer)91 int getWaveInfo(char *path, SOUNDINFO *soundinfo, void *buffer)
92 {
93 FILE *file;
94 WAVECHUNK wavechunk;
95 errno_t err;
96
97 if( ( err = fopen_s( &file, path, "rb" ) ) != 0 )
98 // if (!(file = fopen(path, "rb")))
99 return SOUND_FILE_FOPEN_ERROR;
100
101 wavReadHeader(&wavechunk, file);
102
103 soundinfo->channels = wavGetChannels(&wavechunk);
104 soundinfo->bitsPerSample = wavGetBitsPerSample(&wavechunk);
105 soundinfo->sampleRate = wavGetSampleRate(&wavechunk);
106 soundinfo->samples = wavGetSamples(&wavechunk);
107 soundinfo->loopStart = 0;
108 soundinfo->loopEnd = 0;
109
110 soundinfo->bufferLength = 0;
111
112 switch (soundinfo->bitsPerSample)
113 {
114 case 8:
115
116 soundinfo->bufferLength = soundinfo->samples * soundinfo->channels;
117
118 break;
119
120 case 16:
121
122 soundinfo->bufferLength = soundinfo->samples * soundinfo->channels * 2;
123
124 break;
125 }
126
127 if (buffer)
128 {
129 fread(buffer, soundinfo->bufferLength, 1, file);
130
131 if (soundinfo->bitsPerSample == 8)
132 {
133 int i;
134 char *p;
135
136 p = buffer;
137
138 for (i = 0; i < soundinfo->bufferLength; i++)
139 {
140 *p = *p + 0x79;
141 p++;
142 }
143 }
144 }
145
146 fclose(file);
147
148 return SOUND_FILE_SUCCESS;
149 }
150
151
152 /*--------------------------------------------------------------------------*
153 *--------------------------------------------------------------------------*/
getFileType(char * path,SOUNDINFO * soundinfo)154 int getFileType(char *path, SOUNDINFO *soundinfo)
155 {
156 FILE *file;
157 u32 data, result;
158 errno_t err;
159
160 if( ( err = fopen_s( &file, path, "rb" ) ) != 0 )
161 // if (!(file = fopen(path, "rb")))
162 return SOUND_FILE_FOPEN_ERROR;
163 else
164 result = SOUND_FILE_FORMAT_ERROR;
165
166 fread(&data, 1, sizeof(u32), file);
167
168 switch (data)
169 {
170 case CHUNK_FORM:
171
172 fread(&data, 1, sizeof(u32), file);
173 fread(&data, 1, sizeof(u32), file);
174
175 if (data == CHUNK_AIFF)
176 result = SOUND_FILE_AIFF;
177
178 break;
179
180 case CHUNK_RIFF:
181
182 fread(&data, 1, sizeof(u32), file);
183 fread(&data, 1, sizeof(u32), file);
184
185 if (data == CHUNK_WAVE)
186 result = SOUND_FILE_WAVE;
187
188 break;
189 }
190
191 fclose(file);
192
193 return result;
194 }
195
196
197 /*--------------------------------------------------------------------------*
198 *--------------------------------------------------------------------------*/
getSoundInfo(char * path,SOUNDINFO * soundinfo)199 int getSoundInfo(char *path, SOUNDINFO *soundinfo)
200 {
201 u32 result = getFileType(path, soundinfo);
202
203 switch (result)
204 {
205 case SOUND_FILE_AIFF:
206
207 result = getAiffInfo(path, soundinfo, NULL);
208
209 break;
210
211 case SOUND_FILE_WAVE:
212
213 result = getWaveInfo(path, soundinfo, NULL);
214
215 break;
216 }
217
218 return result;
219 }
220
221
222 /*--------------------------------------------------------------------------*
223 *--------------------------------------------------------------------------*/
getSoundSamples(char * path,SOUNDINFO * soundinfo,void * dest)224 int getSoundSamples(char *path, SOUNDINFO *soundinfo, void *dest)
225 {
226 u32 result = getFileType(path, soundinfo);
227
228 switch (result)
229 {
230 case SOUND_FILE_AIFF:
231
232 result = getAiffInfo(path, soundinfo, dest);
233
234 break;
235
236 case SOUND_FILE_WAVE:
237
238 result = getWaveInfo(path, soundinfo, dest);
239
240 break;
241 }
242
243 return result;
244 }
245
246
247 /*--------------------------------------------------------------------------*
248 *--------------------------------------------------------------------------*/
writeWaveFile(char * path,SOUNDINFO * info,void * samples)249 int writeWaveFile(char *path, SOUNDINFO *info, void *samples)
250 {
251 WAVECHUNK wavechunk;
252 FILE *file;
253 errno_t err;
254
255 if( ( err = fopen_s( &file, path, "rb" ) ) != 0 )
256 // if (!(file = fopen(path, "wb")))
257 return SOUND_FILE_FOPEN_ERROR;
258
259 wavCreateHeader(
260 &wavechunk,
261 info->samples,
262 info->channels,
263 info->bitsPerSample,
264 info->sampleRate
265 );
266
267 wavWriteHeader(
268 &wavechunk,
269 file
270 );
271
272 fwrite(samples, info->bufferLength, sizeof(char), file);
273
274 fclose(file);
275
276 return SOUND_FILE_SUCCESS;
277 }
278
279
280 /*--------------------------------------------------------------------------*
281 *--------------------------------------------------------------------------*/
writeAiffFile(char * path,SOUNDINFO * info,void * samples)282 int writeAiffFile(char *path, SOUNDINFO *info, void *samples)
283 {
284 AIFFINFO aiffinfo;
285 FILE *file;
286 errno_t err;
287
288 if( ( err = fopen_s( &file, path, "rb" ) ) != 0 )
289 // if (!(file = fopen(path, "wb")))
290 return SOUND_FILE_FOPEN_ERROR;
291
292 aiffCreateHeader(
293 &aiffinfo,
294 info->channels,
295 info->samples,
296 info->bitsPerSample,
297 info->sampleRate
298 );
299
300 aiffWriteHeader(
301 &aiffinfo,
302 file,
303 info->loopStart,
304 info->loopEnd,
305 info->bitsPerSample,
306 info->samples,
307 info->channels
308 );
309
310 if (info->bitsPerSample == 16)
311 reverse_buffer_16(samples, info->bufferLength / 2);
312
313 fwrite(samples, info->bufferLength, sizeof(char), file);
314
315 if (info->loopEnd)
316 {
317 aiffCreateMark(&aiffinfo, info->loopStart, info->loopEnd);
318 aiffWriteMark(&aiffinfo, file);
319 }
320
321 fclose(file);
322
323 return SOUND_FILE_SUCCESS;
324 }
325