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