Skip to content

Commit

Permalink
fix(DmSynth,tsf): alter TSF to allow for weighing mixed PCM
Browse files Browse the repository at this point in the history
This patch drastically improves the volume issues we're having with some soundtracks, though it does not fully solve it.
  • Loading branch information
lmichaelis committed Apr 29, 2024
1 parent d0dbd49 commit 565af6b
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 16 deletions.
8 changes: 4 additions & 4 deletions src/Synth.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ void DmSynth_sendBandUpdate(DmSynth* slf, DmBand* band) {
float pan = (ins->flags & DmInstrument_PAN) ? (float) ins->pan / DmInt_MIDI_MAX : DmInt_PAN_CENTER;
float vol = (ins->flags & DmInstrument_VOLUME) ? (float) ins->volume / DmInt_MIDI_MAX : DmInt_VOLUME_MAX;

tsf_set_volume(t, 1.0f);

bool res = tsf_channel_set_pan(t, 0, pan);
if (!res) {
Dm_report(DmLogLevel_ERROR, "DmSynth: tsf_channel_set_pan encountered an error.");
Expand Down Expand Up @@ -241,12 +243,10 @@ size_t DmSynth_render(DmSynth* slf, void* buf, size_t len, DmRenderOptions fmt)
tsf_set_output(slf->channels[i].synth, TSF_MONO, 44100, 0);
}

tsf_set_volume(slf->channels[i].synth, slf->channels[i].volume);

if (fmt & DmRender_FLOAT) {
tsf_render_float(slf->channels[i].synth, buf, (int) len / channels, true);
tsf_render_float(slf->channels[i].synth, buf, (int) len / channels, true, slf->channels[i].volume);
} else {
tsf_render_short(slf->channels[i].synth, buf, (int) len / channels, true);
tsf_render_short(slf->channels[i].synth, buf, (int) len / channels, true, slf->channels[i].volume);
}
}

Expand Down
24 changes: 12 additions & 12 deletions vendor/TinySoundFont/tsf.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ TSFDEF int tsf_active_voice_count(tsf* f);
// buffer: target buffer of size samples * output_channels * sizeof(type)
// samples: number of samples to render
// flag_mixing: if 0 clear the buffer first, otherwise mix into existing data
TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing CPP_DEFAULT0);
TSFDEF void tsf_render_float(tsf* f, float* buffer, int samples, int flag_mixing CPP_DEFAULT0);
TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing, float factor);
TSFDEF void tsf_render_float(tsf* f, float* buffer, int samples, int flag_mixing, float factor);

// Higher level channel based functions, set up channel parameters
// channel: channel number
Expand Down Expand Up @@ -1172,7 +1172,7 @@ static void tsf_voice_calcpitchratio(struct tsf_voice* v, float pitchShift, floa
v->pitchOutputFactor = v->region->sample_rate / (tsf_timecents2Secsd(v->region->pitch_keycenter * 100.0) * outSampleRate);
}

static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, int numSamples)
static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, int numSamples, float factor)
{
struct tsf_region* region = v->region;
float* input = f->fontSamples;
Expand Down Expand Up @@ -1252,8 +1252,8 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i
// Low-pass filter.
if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);

*outL++ += val * gainLeft;
*outL++ += val * gainRight;
*outL++ += val * gainLeft * factor;
*outL++ += val * gainRight * factor;

// Next sample.
tmpSourceSamplePosition += pitchRatio;
Expand All @@ -1273,8 +1273,8 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i
// Low-pass filter.
if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);

*outL++ += val * gainLeft;
*outR++ += val * gainRight;
*outL++ += val * gainLeft * factor;
*outR++ += val * gainRight * factor;

// Next sample.
tmpSourceSamplePosition += pitchRatio;
Expand All @@ -1293,7 +1293,7 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i
// Low-pass filter.
if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);

*outL++ += val * gainMono;
*outL++ += val * gainMono * factor;

// Next sample.
tmpSourceSamplePosition += pitchRatio;
Expand Down Expand Up @@ -1661,7 +1661,7 @@ TSFDEF int tsf_active_voice_count(tsf* f)
return count;
}

TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing)
TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing, float factor)
{
float outputSamples[TSF_RENDER_SHORTBUFFERBLOCK];
int channels = (f->outputmode == TSF_MONO ? 1 : 2), maxChannelSamples = TSF_RENDER_SHORTBUFFERBLOCK / channels;
Expand All @@ -1670,7 +1670,7 @@ TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing
int channelSamples = (samples > maxChannelSamples ? maxChannelSamples : samples);
short* bufferEnd = buffer + channelSamples * channels;
float *floatSamples = outputSamples;
tsf_render_float(f, floatSamples, channelSamples, TSF_FALSE);
tsf_render_float(f, floatSamples, channelSamples, TSF_FALSE, factor);
samples -= channelSamples;

if (flag_mixing)
Expand All @@ -1689,13 +1689,13 @@ TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing
}
}

TSFDEF void tsf_render_float(tsf* f, float* buffer, int samples, int flag_mixing)
TSFDEF void tsf_render_float(tsf* f, float* buffer, int samples, int flag_mixing, float factor)
{
struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
if (!flag_mixing) TSF_MEMSET(buffer, 0, (f->outputmode == TSF_MONO ? 1 : 2) * sizeof(float) * samples);
for (; v != vEnd; v++)
if (v->playingPreset != -1)
tsf_voice_render(f, v, buffer, samples);
tsf_voice_render(f, v, buffer, samples, factor);
}

static void tsf_channel_setup_voice(tsf* f, struct tsf_voice* v)
Expand Down

0 comments on commit 565af6b

Please sign in to comment.