Skip to content

Commit

Permalink
Added global output panning
Browse files Browse the repository at this point in the history
  • Loading branch information
schellingb committed Oct 21, 2017
1 parent 2aa0769 commit 7f29067
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions tsf.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,13 @@ enum TSFOutputMode
// Setup the parameters for the voice render methods
// outputmode: if mono or stereo and how stereo channel data is ordered
// samplerate: the number of samples per second (output frequency)
// globalgaindb: volume gain in decibels (>0 means higher, <0 means lower)
TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float globalgaindb CPP_DEFAULT0);
// global_gain_db: volume gain in decibels (>0 means higher, <0 means lower)
TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float global_gain_db CPP_DEFAULT0);

// Adjust global panning values. Mono output will apply the average of both.
// pan_factor_left: volume gain factor for the left channel
// pan_factor_right: volume gain factor for the right channel
TSFDEF void tsf_set_panning(tsf* f, float pan_factor_left, float pan_factor_right);

// Start playing a note
// preset_index: preset index >= 0 and < tsf_get_presetcount()
Expand Down Expand Up @@ -236,7 +241,7 @@ struct tsf

float outSampleRate;
enum TSFOutputMode outputmode;
float globalGainDB;
float globalGainDB, globalPanFactorLeft, globalPanFactorRight;

float* outputSamples;
int outputSampleSize;
Expand Down Expand Up @@ -899,7 +904,7 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i
if (dynamicPitchRatio) pitchRatio = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch;
else pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0;

if (dynamicGain) noteGain = 0, tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f;
if (dynamicGain) tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f;
else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0;

while (numSamples)
Expand Down Expand Up @@ -934,7 +939,7 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i
switch (f->outputmode)
{
case TSF_STEREO_INTERLEAVED:
gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight;
gainLeft = gainMono * f->globalPanFactorLeft * v->panFactorLeft, gainRight = gainMono * f->globalPanFactorRight * v->panFactorRight;
while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
{
unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
Expand All @@ -955,7 +960,7 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i
break;

case TSF_STEREO_UNWEAVED:
gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight;
gainLeft = gainMono * f->globalPanFactorLeft * v->panFactorLeft, gainRight = gainMono * f->globalPanFactorRight * v->panFactorRight;
while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
{
unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
Expand All @@ -976,6 +981,7 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i
break;

case TSF_MONO:
gainMono *= (f->globalPanFactorLeft + f->globalPanFactorRight) * .5f;
while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
{
unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
Expand Down Expand Up @@ -1080,6 +1086,7 @@ TSFDEF tsf* tsf_load(struct tsf_stream* stream)
res->fontSamples = fontSamples;
res->fontSampleCount = fontSampleCount;
res->outSampleRate = 44100.0f;
res->globalPanFactorLeft = res->globalPanFactorRight = 1.0f;
fontSamples = TSF_NULL; //don't free below
tsf_load_presets(res, &hydra);
}
Expand Down Expand Up @@ -1128,11 +1135,17 @@ TSFDEF const char* tsf_bank_get_presetname(const tsf* f, int bank, int preset_nu
return tsf_get_presetname(f, tsf_get_presetindex(f, bank, preset_number));
}

TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float globalgaindb)
TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float global_gain_db)
{
f->outSampleRate = (float)(samplerate >= 1 ? samplerate : 44100.0f);
f->outputmode = outputmode;
f->globalGainDB = globalgaindb;
f->globalGainDB = global_gain_db;
}

TSFDEF void tsf_set_panning(tsf* f, float pan_factor_left, float pan_factor_right)
{
f->globalPanFactorLeft = pan_factor_left;
f->globalPanFactorRight = pan_factor_right;
}

TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel)
Expand All @@ -1141,7 +1154,7 @@ TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel)
TSF_BOOL haveGroupedNotesPlaying = TSF_FALSE;
struct tsf_voice *v, *vEnd; struct tsf_region *region, *regionEnd;

if (preset_index < 0 || preset_index >= f->presetNum) return;
if (preset_index < 0 || preset_index >= f->presetNum || midiVelocity <= 0) return;

// Are any grouped notes playing? (Needed for group stopping) Also stop any voices still playing this note.
for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++)
Expand Down

0 comments on commit 7f29067

Please sign in to comment.