diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 5574dbfd5..04d5e59a4 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,10 @@ +April 16, 2008 +- Updated fmod_wrap.h for FMOD 4.14. +- Set note velocity back to using a linear sounding volume curve, although + it's now used to scale channel volume and expression, so recompute_amp() + is still only doing one volume curve lookup. +- Fixed: TimidityMIDIDevice caused a crash at the end of a non-looping song. + April 16, 2008 (Changes by Graf Zahl) - Made translation support for multipatch textures operational. @@ -9,7 +16,7 @@ April 15, 2008 this sounds closer to TiMidity++, although I don't believe it's correct MIDI behavior. Also changed expression so that it scales the channel volume before going through the curve. -- Reworked load_instrument to be less opaque. +- Reworked load_instrument() to be less opaque. - Went through the TiMidity code and removed pretty much all of the SDL_mixer extensions. The only exception would be kill_others(), which I reworked into a kill_key_group() function, which should be useful for DLS diff --git a/src/oplsynth/fmopl.cpp b/src/oplsynth/fmopl.cpp index f367e81c9..99e7794e5 100644 --- a/src/oplsynth/fmopl.cpp +++ b/src/oplsynth/fmopl.cpp @@ -215,7 +215,7 @@ typedef struct fm_opl_f { UINT32 eg_cnt; /* global envelope generator counter */ UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/72 */ UINT32 eg_timer_add; /* step of eg_timer */ - UINT32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */ + UINT32 eg_timer_overflow; /* envelope generator timer overflows every 1 sample (on real chip) */ UINT32 fn_tab[1024]; /* fnumber->increment counter */ diff --git a/src/sound/fmod_wrap.h b/src/sound/fmod_wrap.h index 7bda4bbbd..1c7592df3 100644 --- a/src/sound/fmod_wrap.h +++ b/src/sound/fmod_wrap.h @@ -18,6 +18,7 @@ struct FMOD_CHANNELGROUP {}; struct FMOD_SOUNDGROUP {}; struct FMOD_REVERB {}; struct FMOD_DSP {}; +struct FMOD_DSPCONNECTION {}; struct FMOD_POLYGON {}; struct FMOD_GEOMETRY {}; struct FMOD_SYNCPOINT {}; @@ -39,6 +40,7 @@ namespace FMOD class SoundGroup; class Reverb; class DSP; + class DSPConnection; class Geometry; /* @@ -159,7 +161,7 @@ namespace FMOD // System level DSP access. FMOD_RESULT getDSPHead (DSP **dsp) { return FMOD_System_GetDSPHead(this, (FMOD_DSP **)dsp); } - FMOD_RESULT addDSP (DSP *dsp) { return FMOD_System_AddDSP(this, (FMOD_DSP *)dsp); } + FMOD_RESULT addDSP (DSP *dsp, DSPConnection **connection) { return FMOD_System_AddDSP(this, (FMOD_DSP *)dsp, (FMOD_DSPCONNECTION**)dsp); } FMOD_RESULT lockDSP () { return FMOD_System_LockDSP(this); } FMOD_RESULT unlockDSP () { return FMOD_System_UnlockDSP(this); } @@ -277,8 +279,8 @@ namespace FMOD FMOD_RESULT getFrequency (float *frequency) { return FMOD_Channel_GetFrequency(this, frequency); } FMOD_RESULT setPan (float pan) { return FMOD_Channel_SetPan(this, pan); } FMOD_RESULT getPan (float *pan) { return FMOD_Channel_GetPan(this, pan); } - FMOD_RESULT setDelay (unsigned int startdelay, unsigned int enddelay) { return FMOD_Channel_SetDelay(this, startdelay, enddelay); } - FMOD_RESULT getDelay (unsigned int *startdelay, unsigned int *enddelay) { return FMOD_Channel_GetDelay(this, startdelay, enddelay); } + FMOD_RESULT setDelay (FMOD_DELAYTYPE delaytype, unsigned int delayhi, unsigned int delaylo) { return FMOD_Channel_SetDelay(this, delaytype, delaylo, delayhi); } + FMOD_RESULT getDelay (FMOD_DELAYTYPE delaytype, unsigned int *delayhi, unsigned int *delaylo) { return FMOD_Channel_GetDelay(this, delaytype, delaylo, delayhi); } FMOD_RESULT setSpeakerMix (float frontleft, float frontright, float center, float lfe, float backleft, float backright, float sideleft, float sideright) { return FMOD_Channel_SetSpeakerMix(this, frontleft, frontright, center, lfe, backleft, backright, sideleft, sideright); } FMOD_RESULT getSpeakerMix (float *frontleft, float *frontright, float *center, float *lfe, float *backleft, float *backright, float *sideleft, float *sideright) { return FMOD_Channel_GetSpeakerMix(this, frontleft, frontright, center, lfe, backleft, backright, sideleft, sideright); } FMOD_RESULT setSpeakerLevels (FMOD_SPEAKER speaker, float *levels, int numlevels) { return FMOD_Channel_SetSpeakerLevels(this, speaker, levels, numlevels); } @@ -320,7 +322,7 @@ namespace FMOD // DSP functionality only for channels playing sounds created with FMOD_SOFTWARE. FMOD_RESULT getDSPHead (DSP **dsp) { return FMOD_Channel_GetDSPHead(this, (FMOD_DSP **)dsp); } - FMOD_RESULT addDSP (DSP *dsp) { return FMOD_Channel_AddDSP(this, (FMOD_DSP *)dsp); } + FMOD_RESULT addDSP (DSP *dsp, DSPConnection **connection) { return FMOD_Channel_AddDSP(this, (FMOD_DSP *)dsp, (FMOD_DSPCONNECTION **)connection); } // Information only functions. FMOD_RESULT isPlaying (bool *isplaying) { FMOD_BOOL b; FMOD_RESULT res = FMOD_Channel_IsPlaying(this, &b); *isplaying = b; return res; } @@ -387,7 +389,7 @@ namespace FMOD // DSP functionality only for channel groups playing sounds created with FMOD_SOFTWARE. FMOD_RESULT getDSPHead (DSP **dsp) { return FMOD_ChannelGroup_GetDSPHead(this, (FMOD_DSP **)dsp); } - FMOD_RESULT addDSP (DSP *dsp) { return FMOD_ChannelGroup_AddDSP(this, (FMOD_DSP *)dsp); } + FMOD_RESULT addDSP (DSP *dsp, DSPConnection **connection) { return FMOD_ChannelGroup_AddDSP(this, (FMOD_DSP *)dsp, (FMOD_DSPCONNECTION **)connection); } // Information only functions. FMOD_RESULT getName (char *name, int namelen) { return FMOD_ChannelGroup_GetName(this, name, namelen); } @@ -452,22 +454,14 @@ namespace FMOD FMOD_RESULT getSystemObject (System **system) { return FMOD_DSP_GetSystemObject(this, (FMOD_SYSTEM **)system); } // Connection / disconnection / input and output enumeration. - FMOD_RESULT addInput (DSP *target) { return FMOD_DSP_AddInput(this, target); } + FMOD_RESULT addInput (DSP *target, DSPConnection **connection) { return FMOD_DSP_AddInput(this, target, (FMOD_DSPCONNECTION **)connection); } FMOD_RESULT disconnectFrom (DSP *target) { return FMOD_DSP_DisconnectFrom(this, target); } FMOD_RESULT disconnectAll (bool inputs, bool outputs) { return FMOD_DSP_DisconnectAll(this, inputs, outputs); } FMOD_RESULT remove () { return FMOD_DSP_Remove(this); } FMOD_RESULT getNumInputs (int *numinputs) { return FMOD_DSP_GetNumInputs(this, numinputs); } FMOD_RESULT getNumOutputs (int *numoutputs) { return FMOD_DSP_GetNumOutputs(this, numoutputs); } - FMOD_RESULT getInput (int index, DSP **input) { return FMOD_DSP_GetInput(this, index, (FMOD_DSP **)input); } - FMOD_RESULT getOutput (int index, DSP **output) { return FMOD_DSP_GetOutput(this, index, (FMOD_DSP **)output); } - FMOD_RESULT setInputMix (int index, float volume) { return FMOD_DSP_SetInputMix(this, index, volume); } - FMOD_RESULT getInputMix (int index, float *volume) { return FMOD_DSP_GetInputMix(this, index, volume); } - FMOD_RESULT setInputLevels (int index, FMOD_SPEAKER speaker, float *levels, int numlevels) { return FMOD_DSP_SetInputLevels(this, index, speaker, levels, numlevels); } - FMOD_RESULT getInputLevels (int index, FMOD_SPEAKER speaker, float *levels, int numlevels) { return FMOD_DSP_GetInputLevels(this, index, speaker, levels, numlevels); } - FMOD_RESULT setOutputMix (int index, float volume) { return FMOD_DSP_SetOutputMix(this, index, volume); } - FMOD_RESULT getOutputMix (int index, float *volume) { return FMOD_DSP_GetOutputMix(this, index, volume); } - FMOD_RESULT setOutputLevels (int index, FMOD_SPEAKER speaker, float *levels, int numlevels) { return FMOD_DSP_SetOutputLevels(this, index, speaker, levels, numlevels); } - FMOD_RESULT getOutputLevels (int index, FMOD_SPEAKER speaker, float *levels, int numlevels) { return FMOD_DSP_GetOutputLevels(this, index, speaker, levels, numlevels); } + FMOD_RESULT getInput (int index, DSP **input, DSPConnection **inputconnection) { return FMOD_DSP_GetInput(this, index, (FMOD_DSP **)input, (FMOD_DSPCONNECTION **)inputconnection); } + FMOD_RESULT getOutput (int index, DSP **output, DSPConnection **outputconnection) { return FMOD_DSP_GetOutput(this, index, (FMOD_DSP **)output, (FMOD_DSPCONNECTION **)outputconnection); } // DSP unit control. FMOD_RESULT setActive (bool active) { return FMOD_DSP_SetActive(this, active); } @@ -488,13 +482,38 @@ namespace FMOD FMOD_RESULT getType (FMOD_DSP_TYPE *type) { return FMOD_DSP_GetType(this, type); } FMOD_RESULT setDefaults (float frequency, float volume, float pan, int priority) { return FMOD_DSP_SetDefaults(this, frequency, volume, pan, priority); } FMOD_RESULT getDefaults (float *frequency, float *volume, float *pan, int *priority) { return FMOD_DSP_GetDefaults(this, frequency, volume, pan, priority) ;} - + // Userdata set/get. FMOD_RESULT setUserData (void *userdata) { return FMOD_DSP_SetUserData(this, userdata); } FMOD_RESULT getUserData (void **userdata) { return FMOD_DSP_GetUserData(this, userdata); } }; + /* + 'DSPConnection' API + */ + class DSPConnection : FMOD_DSPCONNECTION + { + private: + + DSPConnection(); /* Constructor made private so user cannot statically instance a DSPConnection class. + Appropriate DSPConnection creation or retrieval function must be used. */ + + public: + + FMOD_RESULT F_API getInput (DSP **input) { return FMOD_DSPConnection_GetInput(this, (FMOD_DSP **)input); } + FMOD_RESULT F_API getOutput (DSP **output) { return FMOD_DSPConnection_GetOutput(this, (FMOD_DSP **)output); } + FMOD_RESULT F_API setMix (float volume) { return FMOD_DSPConnection_SetMix(this, volume); } + FMOD_RESULT F_API getMix (float *volume) { return FMOD_DSPConnection_GetMix(this, volume); } + FMOD_RESULT F_API setLevels (FMOD_SPEAKER speaker, float *levels, int numlevels) { return FMOD_DSPConnection_SetLevels(this, speaker, levels, numlevels); } + FMOD_RESULT F_API getLevels (FMOD_SPEAKER speaker, float *levels, int numlevels) { return FMOD_DSPConnection_GetLevels(this, speaker, levels, numlevels); } + + // Userdata set/get. + FMOD_RESULT F_API setUserData (void *userdata) { return FMOD_DSPConnection_SetUserData(this, userdata); } + FMOD_RESULT F_API getUserData (void **userdata) { return FMOD_DSPConnection_GetUserData(this, userdata); } + }; + + /* 'Geometry' API */ diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index e1a1c1fe6..ebdd7b4cb 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -262,7 +262,7 @@ static const char *Enum_NameForNum(const FEnumList *list, int num) //========================================================================== // -// The container for a FSOUND_STREAM. +// The container for a streaming FMOD::Sound, for playing music. // //========================================================================== @@ -270,15 +270,15 @@ class FMODStreamCapsule : public SoundStream { public: FMODStreamCapsule(FMOD::Sound *stream, FMODSoundRenderer *owner) - : Owner(owner), Stream(NULL), Channel(NULL), DSP(NULL), - UserData(NULL), Callback(NULL) + : Owner(owner), Stream(NULL), Channel(NULL), + UserData(NULL), Callback(NULL), Ended(false) { SetStream(stream); } FMODStreamCapsule(void *udata, SoundStreamCallback callback, FMODSoundRenderer *owner) - : Owner(owner), Stream(NULL), Channel(NULL), DSP(NULL), - UserData(udata), Callback(callback) + : Owner(owner), Stream(NULL), Channel(NULL), + UserData(udata), Callback(callback), Ended(false) {} ~FMODStreamCapsule() @@ -333,11 +333,6 @@ public: Channel->stop(); Channel = NULL; } - if (DSP != NULL) - { - DSP->release(); - DSP = NULL; - } } bool SetPaused(bool paused) @@ -411,20 +406,16 @@ public: FMODStreamCapsule *self; result = ((FMOD::Sound *)sound)->getUserData((void **)&self); - if (result != FMOD_OK || self == NULL || self->Callback == NULL) - { - return FMOD_ERR_INVALID_PARAM; - } - if (self->Callback(self, data, datalen, self->UserData)) + if (result != FMOD_OK || self == NULL || self->Callback == NULL || self->Ended) { + // Contrary to the docs, this return value is completely ignored. return FMOD_OK; } - else + if (!self->Callback(self, data, datalen, self->UserData)) { - self->Channel->stop(); - // Contrary to the docs, this return value is completely ignored. - return FMOD_ERR_INVALID_PARAM; + self->Ended = true; } + return FMOD_OK; } static FMOD_RESULT F_CALLBACK PCMSetPosCallback(FMOD_SOUND *sound, int subsound, unsigned int position, FMOD_TIMEUNIT postype) @@ -438,9 +429,9 @@ private: FMODSoundRenderer *Owner; FMOD::Sound *Stream; FMOD::Channel *Channel; - FMOD::DSP *DSP; void *UserData; SoundStreamCallback Callback; + bool Ended; }; //========================================================================== diff --git a/src/sound/music_midistream.cpp b/src/sound/music_midistream.cpp index 3f9d454df..98b36a5ef 100644 --- a/src/sound/music_midistream.cpp +++ b/src/sound/music_midistream.cpp @@ -655,11 +655,11 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, DWORD max_time) { InitialPlayback = false; // Send the full master volume SysEx message. - events[0] = 0; // dwDeltaTime - events[1] = 0; // dwStreamID - events[2] = (MEVT_LONGMSG << 24) | 8; // dwEvent - events[3] = 0x047f7ff0; // dwParms[0] - events[4] = 0xf77f7f01; // dwParms[1] + events[0] = 0; // dwDeltaTime + events[1] = 0; // dwStreamID + events[2] = (MEVT_LONGMSG << 24) | 8; // dwEvent + events[3] = MAKE_ID(0xf0,0x7f,0x7f,0x04); // dwParms[0] + events[4] = MAKE_ID(0x01,0x7f,0x7f,0xf7); // dwParms[1] events += 5; DoInitialSetup(); } diff --git a/src/sound/music_timidity_mididevice.cpp b/src/sound/music_timidity_mididevice.cpp index abaf3b44a..b138abdf9 100644 --- a/src/sound/music_timidity_mididevice.cpp +++ b/src/sound/music_timidity_mididevice.cpp @@ -484,7 +484,7 @@ bool TimidityMIDIDevice::ServiceStream (void *buff, int numbytes) memset(buff, 0, numbytes); CritSec.Enter(); - while (numsamples > 0) + while (Events != NULL && numsamples > 0) { double ticky = NextTickIn; int tick_in = int(NextTickIn); diff --git a/src/textures/bitmap.h b/src/textures/bitmap.h index 98a950d83..ad42152c2 100644 --- a/src/textures/bitmap.h +++ b/src/textures/bitmap.h @@ -285,4 +285,4 @@ struct bCopy -#endif \ No newline at end of file +#endif diff --git a/src/timidity/playmidi.cpp b/src/timidity/playmidi.cpp index 9a2a2139c..9f261a9e7 100644 --- a/src/timidity/playmidi.cpp +++ b/src/timidity/playmidi.cpp @@ -173,8 +173,8 @@ void Renderer::recompute_amp(Voice *v) int panning = v->panning; double vol = channel[chan].volume / 16383.f; double expr = channel[chan].expression / 16383.f; - double vel = /*calc_vol*/(v->velocity / 127.f); - double tempamp = vel * calc_vol(vol * expr) * v->sample->volume; + double vel = v->velocity / 127.f; + double tempamp = calc_vol(vol * expr * vel) * v->sample->volume; if (panning >= 0x1DBB && panning < 0x2244) { diff --git a/tools/updaterevision/updaterevision.vcproj b/tools/updaterevision/updaterevision.vcproj index f39914dca..202c9d042 100644 --- a/tools/updaterevision/updaterevision.vcproj +++ b/tools/updaterevision/updaterevision.vcproj @@ -1,7 +1,7 @@ + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - -