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