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