/*--------------------------------------------------------------------------* Project: Revolution Audio sound file converter File: sound.c Copyright (C)1998-2006 Nintendo All Rights Reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Log: sound.c,v $ Revision 1.2 02/09/2006 06:26:26 aka Changed copyright. *--------------------------------------------------------------------------*/ #include #include #include #include "soundconv.h" /*--------------------------------------------------------------------------* export from soundfile.dll *--------------------------------------------------------------------------*/ typedef int (*FUNCTION1)(char *path, SOUNDINFO *soundinfo); typedef int (*FUNCTION2)(char *path, SOUNDINFO *soundinfo, void *dest); extern FUNCTION1 getSoundInfo; extern FUNCTION2 getSoundSamples; /*--------------------------------------------------------------------------* export from dsptool.dll *--------------------------------------------------------------------------*/ typedef int (*FUNCTION3)(int); extern FUNCTION3 getBytesForAdpcmBuffer; extern FUNCTION3 getBytesForAdpcmSamples; /*--------------------------------------------------------------------------* globals for each sound instance *--------------------------------------------------------------------------*/ SOUNDINFO soundinfo; static u8 soundFile[1024]; static u8 soundIdString[1024]; static u32 soundSampleRate; static u32 soundFormat; static u32 soundLoopStart; static u32 soundLoopEnd; static u32 soundMix; static u32 soundDefaultFormat; /*--------------------------------------------------------------------------* set default output format *--------------------------------------------------------------------------*/ void soundSetDefaultFormat(u32 format) { soundDefaultFormat = format; } /*--------------------------------------------------------------------------* set sound file *--------------------------------------------------------------------------*/ void soundSetSoundFile(char *ch) { strcpy(soundFile, ch); } /*--------------------------------------------------------------------------* set id string *--------------------------------------------------------------------------*/ void soundSetIdString(char *ch) { strcpy(soundIdString, ch); } /*--------------------------------------------------------------------------* set sample rate *--------------------------------------------------------------------------*/ void soundSetSampleRate(u32 i) { soundSampleRate = i; } /*--------------------------------------------------------------------------* set format *--------------------------------------------------------------------------*/ void soundSetFormat(u32 i) { soundFormat = i; } /*--------------------------------------------------------------------------* set loop start *--------------------------------------------------------------------------*/ void soundSetLoopStart(u32 i) { soundLoopStart = i; } /*--------------------------------------------------------------------------* set loop end *--------------------------------------------------------------------------*/ void soundSetLoopEnd(u32 i) { soundLoopEnd = i; } /*--------------------------------------------------------------------------* set mix *--------------------------------------------------------------------------*/ void soundSetMix(u32 i) { soundMix = i; } /*--------------------------------------------------------------------------* set sound params to default *--------------------------------------------------------------------------*/ void soundInitParams(void) { soundFile[0] = 0; soundIdString[0] = 0; soundSampleRate = SOUND_DATA_NO_USER_INPUT; soundFormat = SOUND_DATA_NO_USER_INPUT; soundLoopStart = SOUND_DATA_NO_USER_INPUT; soundLoopEnd = SOUND_DATA_NO_USER_INPUT; soundMix = SOUND_DATA_NO_USER_INPUT; } /*--------------------------------------------------------------------------* get sound buffer *--------------------------------------------------------------------------*/ void *soundGetBuffer(void) { void *p, *ptemp; if (soundinfo.bufferLength == 0) return NULL; if (ptemp = malloc(soundinfo.bufferLength)) { getSoundSamples(soundFile, &soundinfo, ptemp); if (soundinfo.channels == 1) return ptemp; // stereo if (p = malloc(soundinfo.bufferLength / 2)) { switch (soundMix) { case SOUND_STEREO_COMBINE: if (soundinfo.bitsPerSample == 8) soundStereoCombine8Bit(p, ptemp, soundinfo.samples); if (soundinfo.bitsPerSample == 16) soundStereoCombine16Bit(p, ptemp, soundinfo.samples); break; case SOUND_STEREO_LEFT: if (soundinfo.bitsPerSample == 8) soundStereoLeft8Bit(p, ptemp, soundinfo.samples); if (soundinfo.bitsPerSample == 16) soundStereoLeft16Bit(p, ptemp, soundinfo.samples); break; case SOUND_STEREO_RIGHT: if (soundinfo.bitsPerSample == 8) soundStereoRight8Bit(p, ptemp, soundinfo.samples); if (soundinfo.bitsPerSample == 16) soundStereoRight16Bit(p, ptemp, soundinfo.samples); break; } free(ptemp); return p; } } return NULL; } /*--------------------------------------------------------------------------* pack 8bit source samples *--------------------------------------------------------------------------*/ void soundPack8BitSource(char *source) { switch (soundFormat) { case SOUND_FORMAT_ADPCM: { int bytes; void *p; ADPCMINFO adpcminfo; memset(&adpcminfo, 0, sizeof(ADPCMINFO)); bytes = getBytesForAdpcmBuffer(soundinfo.samples); if (p = malloc(bytes)) { if (soundLoopEnd) soundConvert8BitToAdpcmLoop( p, source, &adpcminfo, soundinfo.samples, soundLoopStart ); else soundConvert8BitToAdpcm( p, source, &adpcminfo, soundinfo.samples ); // pack the data soundOutputAddEntry( soundFormat, getBytesForAdpcmSamples(soundinfo.samples), p, soundinfo.samples, soundSampleRate, soundLoopStart, soundLoopEnd, &adpcminfo, soundIdString ); free(p); } } break; case SOUND_FORMAT_PCM8: soundOutputAddEntry( soundFormat, soundinfo.samples, source, soundinfo.samples, soundSampleRate, soundLoopStart, soundLoopEnd, NULL, soundIdString ); break; case SOUND_FORMAT_PCM16: { int bytes; void *p; bytes = soundinfo.samples * 2; if (p = malloc(bytes)) { soundConvert8to16Bit(p, source, soundinfo.samples); // pack the data soundOutputAddEntry( soundFormat, soundinfo.samples * 2, p, soundinfo.samples, soundSampleRate, soundLoopStart, soundLoopEnd, NULL, soundIdString ); free(p); } } break; } } /*--------------------------------------------------------------------------* pack 16bit source samples *--------------------------------------------------------------------------*/ void soundPack16BitSource(short *source) { switch (soundFormat) { case SOUND_FORMAT_ADPCM: { int bytes; void *p; ADPCMINFO adpcminfo; memset(&adpcminfo, 0, sizeof(ADPCMINFO)); bytes = getBytesForAdpcmBuffer(soundinfo.samples); if (p = malloc(bytes)) { if (soundLoopEnd) soundConvert16BitToAdpcmLoop( p, source, &adpcminfo, soundinfo.samples, soundLoopStart ); else soundConvert16BitToAdpcm( p, source, &adpcminfo, soundinfo.samples ); soundOutputAddEntry( soundFormat, getBytesForAdpcmSamples(soundinfo.samples), p, soundinfo.samples, soundSampleRate, soundLoopStart, soundLoopEnd, &adpcminfo, soundIdString ); free(p); } } break; case SOUND_FORMAT_PCM8: { int bytes; void *p; bytes = soundinfo.samples; if (p = malloc(bytes)) { soundConvert16to8Bit(p, source, soundinfo.samples); // pack the data soundOutputAddEntry( soundFormat, bytes, p, soundinfo.samples, soundSampleRate, soundLoopStart, soundLoopEnd, NULL, soundIdString ); free(p); } } break; case SOUND_FORMAT_PCM16: // no need to convert just pack the data soundOutputAddEntry( soundFormat, soundinfo.samples * 2, source, soundinfo.samples, soundSampleRate, soundLoopStart, soundLoopEnd, NULL, soundIdString ); break; } } /*--------------------------------------------------------------------------* print sound *--------------------------------------------------------------------------*/ int soundPrintSound(void) { int status; status = getSoundInfo(soundFile, &soundinfo); if (status == STATUS_SUCCESS) { if ((soundinfo.bitsPerSample != 8) && (soundinfo.bitsPerSample != 16)) { printf("%cWarning, %s is not 8bit or 16bit, data not encoded!\n", 7, soundFile); } else if ((soundinfo.channels != 1) && (soundinfo.channels != 2)) { printf("%cWarning, %s is not mono or stereo, data not encoded!\n", 7, soundFile); } else { void *p; // use defaults if script didn't specify setting if (soundSampleRate == SOUND_DATA_NO_USER_INPUT) soundSampleRate = soundinfo.sampleRate; if (soundFormat == SOUND_DATA_NO_USER_INPUT) soundFormat = soundDefaultFormat; if (soundLoopStart == SOUND_DATA_NO_USER_INPUT) soundLoopStart = soundinfo.loopStart; if (soundLoopEnd == SOUND_DATA_NO_USER_INPUT) if (soundinfo.loopEnd) soundLoopEnd = soundinfo.loopEnd - 1; // AIFF has 1 based loopend else soundLoopEnd = 0; if (soundMix == SOUND_DATA_NO_USER_INPUT) soundMix = SOUND_STEREO_COMBINE; if (p = soundGetBuffer()) { switch (soundinfo.bitsPerSample) { case 8: soundPack8BitSource(p); break; case 16: soundPack16BitSource(p); break; } free(p); } } } else { printf("%cWarning, cannot convert %s!\n", 7, soundFile); } return status; }