1 /*--------------------------------------------------------------------------*
2 Project: Revolution Audio sound file converter
3 File: sound.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: sound.c,v $
14 Revision 1.2 02/09/2006 06:26:26 aka
15 Changed copyright.
16
17
18 *--------------------------------------------------------------------------*/
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include "soundconv.h"
23
24
25 /*--------------------------------------------------------------------------*
26 export from soundfile.dll
27 *--------------------------------------------------------------------------*/
28 typedef int (*FUNCTION1)(char *path, SOUNDINFO *soundinfo);
29 typedef int (*FUNCTION2)(char *path, SOUNDINFO *soundinfo, void *dest);
30
31 extern FUNCTION1 getSoundInfo;
32 extern FUNCTION2 getSoundSamples;
33
34 /*--------------------------------------------------------------------------*
35 export from dsptool.dll
36 *--------------------------------------------------------------------------*/
37 typedef int (*FUNCTION3)(int);
38 extern FUNCTION3 getBytesForAdpcmBuffer;
39 extern FUNCTION3 getBytesForAdpcmSamples;
40
41
42 /*--------------------------------------------------------------------------*
43 globals for each sound instance
44 *--------------------------------------------------------------------------*/
45 SOUNDINFO soundinfo;
46
47 static u8 soundFile[1024];
48 static u8 soundIdString[1024];
49 static u32 soundSampleRate;
50 static u32 soundFormat;
51 static u32 soundLoopStart;
52 static u32 soundLoopEnd;
53 static u32 soundMix;
54 static u32 soundDefaultFormat;
55
56
57 /*--------------------------------------------------------------------------*
58 set default output format
59 *--------------------------------------------------------------------------*/
soundSetDefaultFormat(u32 format)60 void soundSetDefaultFormat(u32 format)
61 {
62 soundDefaultFormat = format;
63 }
64
65
66 /*--------------------------------------------------------------------------*
67 set sound file
68 *--------------------------------------------------------------------------*/
soundSetSoundFile(char * ch)69 void soundSetSoundFile(char *ch)
70 {
71 strcpy(soundFile, ch);
72 }
73
74
75 /*--------------------------------------------------------------------------*
76 set id string
77 *--------------------------------------------------------------------------*/
soundSetIdString(char * ch)78 void soundSetIdString(char *ch)
79 {
80 strcpy(soundIdString, ch);
81 }
82
83
84 /*--------------------------------------------------------------------------*
85 set sample rate
86 *--------------------------------------------------------------------------*/
soundSetSampleRate(u32 i)87 void soundSetSampleRate(u32 i)
88 {
89 soundSampleRate = i;
90 }
91
92
93 /*--------------------------------------------------------------------------*
94 set format
95 *--------------------------------------------------------------------------*/
soundSetFormat(u32 i)96 void soundSetFormat(u32 i)
97 {
98 soundFormat = i;
99 }
100
101
102 /*--------------------------------------------------------------------------*
103 set loop start
104 *--------------------------------------------------------------------------*/
soundSetLoopStart(u32 i)105 void soundSetLoopStart(u32 i)
106 {
107 soundLoopStart = i;
108 }
109
110
111 /*--------------------------------------------------------------------------*
112 set loop end
113 *--------------------------------------------------------------------------*/
soundSetLoopEnd(u32 i)114 void soundSetLoopEnd(u32 i)
115 {
116 soundLoopEnd = i;
117 }
118
119
120 /*--------------------------------------------------------------------------*
121 set mix
122 *--------------------------------------------------------------------------*/
soundSetMix(u32 i)123 void soundSetMix(u32 i)
124 {
125 soundMix = i;
126 }
127
128
129 /*--------------------------------------------------------------------------*
130 set sound params to default
131 *--------------------------------------------------------------------------*/
soundInitParams(void)132 void soundInitParams(void)
133 {
134 soundFile[0] = 0;
135 soundIdString[0] = 0;
136 soundSampleRate = SOUND_DATA_NO_USER_INPUT;
137 soundFormat = SOUND_DATA_NO_USER_INPUT;
138 soundLoopStart = SOUND_DATA_NO_USER_INPUT;
139 soundLoopEnd = SOUND_DATA_NO_USER_INPUT;
140 soundMix = SOUND_DATA_NO_USER_INPUT;
141 }
142
143
144 /*--------------------------------------------------------------------------*
145 get sound buffer
146 *--------------------------------------------------------------------------*/
soundGetBuffer(void)147 void *soundGetBuffer(void)
148 {
149 void *p, *ptemp;
150
151 if (soundinfo.bufferLength == 0)
152 return NULL;
153
154 if (ptemp = malloc(soundinfo.bufferLength))
155 {
156 getSoundSamples(soundFile, &soundinfo, ptemp);
157
158 if (soundinfo.channels == 1)
159 return ptemp;
160
161 // stereo
162 if (p = malloc(soundinfo.bufferLength / 2))
163 {
164 switch (soundMix)
165 {
166 case SOUND_STEREO_COMBINE:
167
168 if (soundinfo.bitsPerSample == 8)
169 soundStereoCombine8Bit(p, ptemp, soundinfo.samples);
170
171 if (soundinfo.bitsPerSample == 16)
172 soundStereoCombine16Bit(p, ptemp, soundinfo.samples);
173
174 break;
175
176 case SOUND_STEREO_LEFT:
177
178 if (soundinfo.bitsPerSample == 8)
179 soundStereoLeft8Bit(p, ptemp, soundinfo.samples);
180
181 if (soundinfo.bitsPerSample == 16)
182 soundStereoLeft16Bit(p, ptemp, soundinfo.samples);
183
184 break;
185
186 case SOUND_STEREO_RIGHT:
187
188 if (soundinfo.bitsPerSample == 8)
189 soundStereoRight8Bit(p, ptemp, soundinfo.samples);
190
191 if (soundinfo.bitsPerSample == 16)
192 soundStereoRight16Bit(p, ptemp, soundinfo.samples);
193
194 break;
195 }
196
197 free(ptemp);
198
199 return p;
200 }
201 }
202
203 return NULL;
204 }
205
206
207 /*--------------------------------------------------------------------------*
208 pack 8bit source samples
209 *--------------------------------------------------------------------------*/
soundPack8BitSource(char * source)210 void soundPack8BitSource(char *source)
211 {
212 switch (soundFormat)
213 {
214 case SOUND_FORMAT_ADPCM:
215
216 {
217 int bytes;
218 void *p;
219 ADPCMINFO adpcminfo;
220
221 memset(&adpcminfo, 0, sizeof(ADPCMINFO));
222
223 bytes = getBytesForAdpcmBuffer(soundinfo.samples);
224
225 if (p = malloc(bytes))
226 {
227 if (soundLoopEnd)
228 soundConvert8BitToAdpcmLoop(
229 p,
230 source,
231 &adpcminfo,
232 soundinfo.samples,
233 soundLoopStart
234 );
235 else
236 soundConvert8BitToAdpcm(
237 p,
238 source,
239 &adpcminfo,
240 soundinfo.samples
241 );
242
243 // pack the data
244 soundOutputAddEntry(
245 soundFormat,
246 getBytesForAdpcmSamples(soundinfo.samples),
247 p,
248 soundinfo.samples,
249 soundSampleRate,
250 soundLoopStart,
251 soundLoopEnd,
252 &adpcminfo,
253 soundIdString
254 );
255
256 free(p);
257 }
258 }
259
260 break;
261
262 case SOUND_FORMAT_PCM8:
263
264 soundOutputAddEntry(
265 soundFormat,
266 soundinfo.samples,
267 source,
268 soundinfo.samples,
269 soundSampleRate,
270 soundLoopStart,
271 soundLoopEnd,
272 NULL,
273 soundIdString
274 );
275
276 break;
277
278 case SOUND_FORMAT_PCM16:
279
280 {
281 int bytes;
282 void *p;
283
284 bytes = soundinfo.samples * 2;
285
286 if (p = malloc(bytes))
287 {
288 soundConvert8to16Bit(p, source, soundinfo.samples);
289
290 // pack the data
291 soundOutputAddEntry(
292 soundFormat,
293 soundinfo.samples * 2,
294 p,
295 soundinfo.samples,
296 soundSampleRate,
297 soundLoopStart,
298 soundLoopEnd,
299 NULL,
300 soundIdString
301 );
302
303 free(p);
304 }
305 }
306
307 break;
308 }
309 }
310
311
312 /*--------------------------------------------------------------------------*
313 pack 16bit source samples
314 *--------------------------------------------------------------------------*/
soundPack16BitSource(short * source)315 void soundPack16BitSource(short *source)
316 {
317 switch (soundFormat)
318 {
319 case SOUND_FORMAT_ADPCM:
320
321 {
322 int bytes;
323 void *p;
324 ADPCMINFO adpcminfo;
325
326 memset(&adpcminfo, 0, sizeof(ADPCMINFO));
327
328 bytes = getBytesForAdpcmBuffer(soundinfo.samples);
329
330 if (p = malloc(bytes))
331 {
332 if (soundLoopEnd)
333 soundConvert16BitToAdpcmLoop(
334 p,
335 source,
336 &adpcminfo,
337 soundinfo.samples,
338 soundLoopStart
339 );
340 else
341 soundConvert16BitToAdpcm(
342 p,
343 source,
344 &adpcminfo,
345 soundinfo.samples
346 );
347
348 soundOutputAddEntry(
349 soundFormat,
350 getBytesForAdpcmSamples(soundinfo.samples),
351 p,
352 soundinfo.samples,
353 soundSampleRate,
354 soundLoopStart,
355 soundLoopEnd,
356 &adpcminfo,
357 soundIdString
358 );
359
360 free(p);
361 }
362 }
363
364 break;
365
366 case SOUND_FORMAT_PCM8:
367
368 {
369 int bytes;
370 void *p;
371
372 bytes = soundinfo.samples;
373
374 if (p = malloc(bytes))
375 {
376 soundConvert16to8Bit(p, source, soundinfo.samples);
377
378 // pack the data
379 soundOutputAddEntry(
380 soundFormat,
381 bytes,
382 p,
383 soundinfo.samples,
384 soundSampleRate,
385 soundLoopStart,
386 soundLoopEnd,
387 NULL,
388 soundIdString
389 );
390
391 free(p);
392 }
393 }
394
395 break;
396
397 case SOUND_FORMAT_PCM16:
398
399 // no need to convert just pack the data
400 soundOutputAddEntry(
401 soundFormat,
402 soundinfo.samples * 2,
403 source,
404 soundinfo.samples,
405 soundSampleRate,
406 soundLoopStart,
407 soundLoopEnd,
408 NULL,
409 soundIdString
410 );
411
412 break;
413 }
414 }
415
416
417 /*--------------------------------------------------------------------------*
418 print sound
419 *--------------------------------------------------------------------------*/
soundPrintSound(void)420 int soundPrintSound(void)
421 {
422 int status;
423
424 status = getSoundInfo(soundFile, &soundinfo);
425
426 if (status == STATUS_SUCCESS)
427 {
428 if ((soundinfo.bitsPerSample != 8) && (soundinfo.bitsPerSample != 16))
429 {
430 printf("%cWarning, %s is not 8bit or 16bit, data not encoded!\n", 7, soundFile);
431 }
432 else if ((soundinfo.channels != 1) && (soundinfo.channels != 2))
433 {
434 printf("%cWarning, %s is not mono or stereo, data not encoded!\n", 7, soundFile);
435 }
436 else
437 {
438 void *p;
439
440 // use defaults if script didn't specify setting
441 if (soundSampleRate == SOUND_DATA_NO_USER_INPUT)
442 soundSampleRate = soundinfo.sampleRate;
443
444 if (soundFormat == SOUND_DATA_NO_USER_INPUT)
445 soundFormat = soundDefaultFormat;
446
447 if (soundLoopStart == SOUND_DATA_NO_USER_INPUT)
448 soundLoopStart = soundinfo.loopStart;
449
450 if (soundLoopEnd == SOUND_DATA_NO_USER_INPUT)
451 if (soundinfo.loopEnd)
452 soundLoopEnd = soundinfo.loopEnd - 1; // AIFF has 1 based loopend
453 else
454 soundLoopEnd = 0;
455
456 if (soundMix == SOUND_DATA_NO_USER_INPUT)
457 soundMix = SOUND_STEREO_COMBINE;
458
459 if (p = soundGetBuffer())
460 {
461 switch (soundinfo.bitsPerSample)
462 {
463 case 8:
464
465 soundPack8BitSource(p);
466
467 break;
468
469 case 16:
470
471 soundPack16BitSource(p);
472
473 break;
474 }
475
476 free(p);
477 }
478 }
479 }
480 else
481 {
482 printf("%cWarning, cannot convert %s!\n", 7, soundFile);
483 }
484
485 return status;
486 }
487