diff --git a/docs/rh-log.txt b/docs/rh-log.txt
index 5574dbfd52..04d5e59a47 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 f367e81c95..99e7794e54 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 7bda4bbbd4..1c7592df3d 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 e1a1c1fe62..ebdd7b4cb1 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 3f9d454dfb..98b36a5efc 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 abaf3b44a9..b138abdf91 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 98a950d83e..ad42152c2b 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 9a2a2139c5..9f261a9e72 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 f39914dcac..202c9d042b 100644
--- a/tools/updaterevision/updaterevision.vcproj
+++ b/tools/updaterevision/updaterevision.vcproj
@@ -1,7 +1,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-