// FMOD Sound Interface // for the Build Engine // by Jonathon Fowler (jonof@edgenetwk.com) #include "fmod.h" #include "fmod_errors.h" #ifndef F_CALLBACKAPI #define FMOD_PRE370 #define F_CALLBACKAPI _cdecl #endif // some Linux people may need this if GCC can't find FSOUND_Stream_Open // #define FMOD_PRE370 #include "osd.h" #include "compat.h" #include "cache1d.h" #define NUMCHANNELS 16 #define MAXWAVES 256 static int fmod_inited = 0; static int musicstat = 0; // general sample playback static int numwaves; static FSOUND_SAMPLE * samples[MAXWAVES]; static char instname[MAXWAVES][16]; static int channels[NUMCHANNELS]; void loadwaves(void); static unsigned int F_CALLBACKAPI f_open(const char *name) { return kopen4load((char *)name, 0) + 1; } static void F_CALLBACKAPI f_close(unsigned int handle) { kclose(handle - 1); } static int F_CALLBACKAPI f_read(void *buffer, int size, unsigned int handle) { return kread(handle - 1, buffer, size); } static int F_CALLBACKAPI f_seek(unsigned int handle, int pos, signed char mode) { return klseek(handle - 1, pos, mode); } static int F_CALLBACKAPI f_tell(unsigned int handle) { return ktell(handle - 1); } void initsb(char dadigistat, char damusistat, long dasamplerate, char danumspeakers, char dabytespersample, char daintspersec, char daquality) { char *s; int i,j; if (fmod_inited) return; fmod_inited = 0; if (dasamplerate < 6000) dasamplerate = 6000; else if (dasamplerate > 48000) dasamplerate = 48000; musicstat = damusistat; printOSD("Initialising FMOD...\n"); printOSD(" Linked version: %.02f\n", FMOD_VERSION); printOSD(" DLL version: %.02f\n", FSOUND_GetVersion()); if (FSOUND_GetVersion() < FMOD_VERSION) { printOSD(" ... Failure: FMOD DLL too old! Sound disabled.\n"); return; } printOSD(" Samplerate: %d hz\n", dasamplerate); //FSOUND_SetOutput(FSOUND_OUTPUT_ASIO); if (FSOUND_Init(dasamplerate, NUMCHANNELS, 0)) { printOSD(" ... Success\n"); fmod_inited = 1; } else { printOSD(" ... Failure: %s\n", FMOD_ErrorString(FSOUND_GetError())); } switch (FSOUND_GetOutput()) { case FSOUND_OUTPUT_NOSOUND: s = "No Sound"; break; case FSOUND_OUTPUT_WINMM: s = "WINMM"; break; case FSOUND_OUTPUT_DSOUND: s = "DirectSound"; break; case FSOUND_OUTPUT_OSS: s = "OSS"; break; case FSOUND_OUTPUT_ESD: s = "ESound"; break; case FSOUND_OUTPUT_ALSA: s = "ALSA"; break; case FSOUND_OUTPUT_ASIO: s = "ASIO"; break; default: s = "Other"; break; } printOSD("Using FMOD \"%s\" output driver\n", s); FSOUND_File_SetCallbacks( (FSOUND_OPENCALLBACK)f_open, (FSOUND_CLOSECALLBACK)f_close, (FSOUND_READCALLBACK)f_read, (FSOUND_SEEKCALLBACK)f_seek, (FSOUND_TELLCALLBACK)f_tell); //FSOUND_SetMemorySystem(fmod_cache, fmod_cachelen, NULL, NULL, NULL); loadwaves(); for (i=0; i=0;wavnum--) { bad = 0; i = 0; while ((dafilename[i] > 0) && (i < 16)) { ch1 = dafilename[i]; if ((ch1 >= 97) && (ch1 <= 123)) ch1 -= 32; ch2 = instname[wavnum][i]; if ((ch2 >= 97) && (ch2 <= 123)) ch2 -= 32; if (ch1 != ch2) {bad = 1; break;} i++; } if (bad != 0) continue; for (i=0; i oldestpos) { oldest = i; oldestpos = FSOUND_GetCurrentPosition(channels[i]); } } if (free < 0) { FSOUND_StopSound(channels[oldest]); free = oldest; } chan = FSOUND_PlaySoundEx(FSOUND_FREE, samples[wavnum], NULL, 1); if (chan == -1) return; FSOUND_SetFrequency(chan, dafreq*11025/4096); FSOUND_SetVolume(chan, davol); FSOUND_SetPaused(chan, 0); channels[free] = chan; return; } } void wsay(char *dafilename, long dafreq, long volume1, long volume2) { unsigned char ch1, ch2; long i, j, bad, free=-1, oldest=0; unsigned int oldestpos=0; int chan; if (fmod_inited == 0) return; i = numwaves-1; do { bad = 0; j = 0; while ((dafilename[j] > 0) && (j < 16)) { ch1 = dafilename[j]; if ((ch1 >= 97) && (ch1 <= 123)) ch1 -= 32; ch2 = instname[i][j]; if ((ch2 >= 97) && (ch2 <= 123)) ch2 -= 32; if (ch1 != ch2) {bad = 1; break;} j++; } if (bad == 0) { for (j=0; j oldestpos) { oldest = j; oldestpos = FSOUND_GetCurrentPosition(channels[j]); } } if (free < 0) { FSOUND_StopSound(channels[oldest]); free = oldest; } chan = FSOUND_PlaySoundEx(FSOUND_FREE, samples[i], NULL, 1); if (chan == -1) return; FSOUND_SetFrequency(chan, dafreq*11025/4096); FSOUND_SetVolume(chan, (volume1*volume2)>>1); // set pan FSOUND_SetPaused(chan, 0); channels[free] = chan; return; } i--; } while (i >= 0); } void loadwaves(void) { long fil, dawaversionum, i, tmp; long wavleng[MAXWAVES], repstart[MAXWAVES], repleng[MAXWAVES], finetune[MAXWAVES]; char *p; fil = kopen4load("WAVES.KWV", 0); if (fil != -1) { kread(fil, &dawaversionum, 4); dawaversionum = B_LITTLE32(dawaversionum); if (dawaversionum != 0) { kclose(fil); return; } kread(fil, &numwaves, 4); numwaves = B_LITTLE32(numwaves); for (i=0; i