mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-31 05:40:44 +00:00
- Added dynamic recentering for the OPL synth. The chip has four basic
waveforms, and three of them are non-negative. This can cause a tendency for the resulting output waveform to go into very high ranges depending on the timbres used, and Heretic's exemplify this problem. - Reduced the OPL volume level slightly. - Fixed: The waveform view from snd_drawoutput was upside-down. SVN r949 (trunk)
This commit is contained in:
parent
bc5f49dd49
commit
de85314234
5 changed files with 82 additions and 3 deletions
|
@ -1,4 +1,10 @@
|
||||||
April 28, 2008
|
April 28, 2008
|
||||||
|
- Added dynamic recentering for the OPL synth. The chip has four basic
|
||||||
|
waveforms, and three of them are non-negative. This can cause a tendency
|
||||||
|
for the resulting output waveform to go into very high ranges depending on
|
||||||
|
the timbres used, and Heretic's exemplify this problem.
|
||||||
|
- Reduced the OPL volume level slightly.
|
||||||
|
- Fixed: The waveform view from snd_drawoutput was upside-down.
|
||||||
- Various fixes for compiling working 64-bit binaries with Visual C++. The
|
- Various fixes for compiling working 64-bit binaries with Visual C++. The
|
||||||
number of changes was pleasantly small, and a cursory check seems to show
|
number of changes was pleasantly small, and a cursory check seems to show
|
||||||
everything working alright.
|
everything working alright.
|
||||||
|
|
|
@ -1638,7 +1638,7 @@ static bool CalcVoice (FM_OPL *OPL, int voice, float *buffer, int length)
|
||||||
output[0] += tl_tab[p];
|
output[0] += tl_tab[p];
|
||||||
}
|
}
|
||||||
// [RH] Convert to floating point.
|
// [RH] Convert to floating point.
|
||||||
buffer[i] += float(output[0]) / 7168.f;
|
buffer[i] += float(output[0]) / 10240;
|
||||||
}
|
}
|
||||||
|
|
||||||
// advance
|
// advance
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "opl_mus_player.h"
|
#include "opl_mus_player.h"
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
|
@ -21,6 +22,7 @@ OPLmusicBlock::OPLmusicBlock()
|
||||||
{
|
{
|
||||||
scoredata = NULL;
|
scoredata = NULL;
|
||||||
NextTickIn = 0;
|
NextTickIn = 0;
|
||||||
|
LastOffset = 0;
|
||||||
TwoChips = !opl_onechip;
|
TwoChips = !opl_onechip;
|
||||||
Looping = false;
|
Looping = false;
|
||||||
io = NULL;
|
io = NULL;
|
||||||
|
@ -47,6 +49,7 @@ void OPLmusicBlock::Restart()
|
||||||
OPLplayMusic (127);
|
OPLplayMusic (127);
|
||||||
MLtime = 0;
|
MLtime = 0;
|
||||||
playingcount = 0;
|
playingcount = 0;
|
||||||
|
LastOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
OPLmusicFile::OPLmusicFile (FILE *file, char *musiccache, int len)
|
OPLmusicFile::OPLmusicFile (FILE *file, char *musiccache, int len)
|
||||||
|
@ -209,6 +212,7 @@ bool OPLmusicBlock::ServiceStream (void *buff, int numbytes)
|
||||||
{
|
{
|
||||||
YM3812UpdateOne (1, samples1, samplesleft);
|
YM3812UpdateOne (1, samples1, samplesleft);
|
||||||
}
|
}
|
||||||
|
OffsetSamples(samples1, samplesleft);
|
||||||
assert(NextTickIn == ticky);
|
assert(NextTickIn == ticky);
|
||||||
NextTickIn -= samplesleft;
|
NextTickIn -= samplesleft;
|
||||||
assert (NextTickIn >= 0);
|
assert (NextTickIn >= 0);
|
||||||
|
@ -231,6 +235,7 @@ bool OPLmusicBlock::ServiceStream (void *buff, int numbytes)
|
||||||
{
|
{
|
||||||
YM3812UpdateOne (1, samples1, numsamples);
|
YM3812UpdateOne (1, samples1, numsamples);
|
||||||
}
|
}
|
||||||
|
OffsetSamples(samples1, numsamples);
|
||||||
}
|
}
|
||||||
res = false;
|
res = false;
|
||||||
break;
|
break;
|
||||||
|
@ -256,6 +261,72 @@ bool OPLmusicBlock::ServiceStream (void *buff, int numbytes)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OPLmusicBlock::OffsetSamples(float *buff, int count)
|
||||||
|
{
|
||||||
|
// Three out of four of the OPL waveforms are non-negative. Depending on
|
||||||
|
// timbre selection, this can cause the output waveform to tend toward
|
||||||
|
// very large positive values. Heretic's music is particularly bad for
|
||||||
|
// this. This function attempts to compensate by offseting the sample
|
||||||
|
// data back to around the [-1.0, 1.0] range.
|
||||||
|
|
||||||
|
double max = -1e10, min = 1e10, offset, step;
|
||||||
|
int i, ramp;
|
||||||
|
|
||||||
|
// Find max and min values for this segment of the waveform.
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
if (buff[i] > max)
|
||||||
|
{
|
||||||
|
max = buff[i];
|
||||||
|
}
|
||||||
|
if (buff[i] < min)
|
||||||
|
{
|
||||||
|
min = buff[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Don't slide if we don't have to, because doing so introduces noise.
|
||||||
|
// However, if the amplitude is low, we do want to slide so that when
|
||||||
|
// the song ends, the wave will be around 0 and not click when the song
|
||||||
|
// starts over.
|
||||||
|
if (min - LastOffset > -0.5 && max - LastOffset < 0.5 && max - min > 0.5)
|
||||||
|
{
|
||||||
|
offset = LastOffset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offset = (max + min) / 2;
|
||||||
|
// If the new offset is close to 0, make it 0 to avoid making another
|
||||||
|
// full loop through the sample data.
|
||||||
|
if (fabs(offset) < 1/256.0)
|
||||||
|
{
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Ramp the offset change so there aren't any abrupt clicks in the output.
|
||||||
|
// If the ramp is too short, it can sound scratchy. cblood2.mid is
|
||||||
|
// particularly unforgiving of short ramps.
|
||||||
|
ramp = MIN(512, count);
|
||||||
|
step = (offset - LastOffset) / 512;
|
||||||
|
offset = LastOffset;
|
||||||
|
i = 0;
|
||||||
|
if (step != 0)
|
||||||
|
{
|
||||||
|
for (; i < ramp; ++i)
|
||||||
|
{
|
||||||
|
buff[i] = float(buff[i] - offset);
|
||||||
|
offset += step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (offset != 0)
|
||||||
|
{
|
||||||
|
for (; i < count; ++i)
|
||||||
|
{
|
||||||
|
buff[i] = float(buff[i] - offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LastOffset = float(offset);
|
||||||
|
}
|
||||||
|
|
||||||
int OPLmusicFile::PlayTick ()
|
int OPLmusicFile::PlayTick ()
|
||||||
{
|
{
|
||||||
BYTE reg, data;
|
BYTE reg, data;
|
||||||
|
|
|
@ -15,11 +15,13 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int PlayTick() = 0;
|
virtual int PlayTick() = 0;
|
||||||
|
void OffsetSamples(float *buff, int count);
|
||||||
|
|
||||||
double NextTickIn;
|
double NextTickIn;
|
||||||
double SamplesPerTick;
|
double SamplesPerTick;
|
||||||
bool TwoChips;
|
bool TwoChips;
|
||||||
bool Looping;
|
bool Looping;
|
||||||
|
double LastOffset;
|
||||||
|
|
||||||
FCriticalSection ChipAccess;
|
FCriticalSection ChipAccess;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1970,11 +1970,11 @@ void FMODSoundRenderer::DrawWave(float *wavearray, int x, int y, int width, int
|
||||||
if (screen->Accel2D)
|
if (screen->Accel2D)
|
||||||
{ // Drawing this with lines is super-slow without hardware acceleration, at least with
|
{ // Drawing this with lines is super-slow without hardware acceleration, at least with
|
||||||
// the debug build.
|
// the debug build.
|
||||||
float lasty = wavearray[0] * scale + mid;
|
float lasty = mid - wavearray[0] * scale;
|
||||||
float newy;
|
float newy;
|
||||||
for (i = 1; i < width; ++i)
|
for (i = 1; i < width; ++i)
|
||||||
{
|
{
|
||||||
newy = wavearray[i] * scale + mid;
|
newy = mid - wavearray[i] * scale;
|
||||||
screen->DrawLine(x + i - 1, int(lasty), x + i, int(newy), -1, MAKEARGB(255,255,248,248));
|
screen->DrawLine(x + i - 1, int(lasty), x + i, int(newy), -1, MAKEARGB(255,255,248,248));
|
||||||
lasty = newy;
|
lasty = newy;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue