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