ref: a298ba47b2d18c23b1ed9f9b222959295f040968
parent: 1bfb3616300b913f931d510fc9d7d33b850c9ce3
author: Bernhard Schelling <schellingb@gmail.com>
date: Sat Apr 7 12:28:55 EDT 2018
- Fixed pitch range handling of midi control - Fixed initial attenuation of instruments
--- a/examples/example3.c
+++ b/examples/example3.c
@@ -94,8 +94,8 @@
//Initialize preset on special 10th MIDI channel to use percussion sound bank (128) if available
tsf_channel_set_bank_preset(g_TinySoundFont, 9, 128, 0);
- // Set the SoundFont rendering output mode with -18 db volume gain
- tsf_set_output(g_TinySoundFont, TSF_STEREO_INTERLEAVED, OutputAudioSpec.freq, -18.0f);
+ // Set the SoundFont rendering output mode
+ tsf_set_output(g_TinySoundFont, TSF_STEREO_INTERLEAVED, OutputAudioSpec.freq, 0.0f);
// Request the desired audio output format
if (SDL_OpenAudio(&OutputAudioSpec, TSF_NULL) < 0)
--- a/tsf.h
+++ b/tsf.h
@@ -166,8 +166,8 @@
// pan: stereo panning value from 0.0 (left) to 1.0 (right) (default 0.5 center)
// volume: linear volume scale factor (default 1.0 full)
// pitch_wheel: pitch wheel position 0 to 16383 (default 8192 unpitched)
-// pitch_range: range of the pitch wheel in semitones (default 2.0)
-// tuning: tuning of all playing voices in semitones (default 0.0 standard (A440) tuning)
+// pitch_range: range of the pitch wheel in semitones (default 2.0, total +/- 2 semitones)
+// tuning: tuning of all playing voices in semitones (default 0.0, standard (A440) tuning)
// (set_preset_number and set_bank_preset return 0 if preset does not exist, otherwise 1)
TSFDEF void tsf_channel_set_presetindex(tsf* f, int channel, int preset_index);
TSFDEF int tsf_channel_set_presetnumber(tsf* f, int channel, int preset_number, int flag_mididrums CPP_DEFAULT0);
@@ -195,9 +195,11 @@
TSFDEF int tsf_channel_get_preset_index(tsf* f, int channel);
TSFDEF int tsf_channel_get_preset_bank(tsf* f, int channel);
TSFDEF int tsf_channel_get_preset_number(tsf* f, int channel);
-TSFDEF int tsf_channel_get_pitchwheel(tsf* f, int channel);
TSFDEF float tsf_channel_get_pan(tsf* f, int channel);
TSFDEF float tsf_channel_get_volume(tsf* f, int channel);
+TSFDEF int tsf_channel_get_pitchwheel(tsf* f, int channel);
+TSFDEF float tsf_channel_get_pitchrange(tsf* f, int channel);
+TSFDEF float tsf_channel_get_tuning(tsf* f, int channel);
#ifdef __cplusplus
# undef CPP_DEFAULT0
@@ -376,7 +378,7 @@
unsigned char lokey, hikey, lovel, hivel;
unsigned int group, offset, end, loop_start, loop_end;
int transpose, tune, pitch_keycenter, pitch_keytrack;
- float volume, pan;
+ float attenuation, pan;
struct tsf_envelope ampenv, modenv;
int initialFilterQ, initialFilterFc;
int modEnvToPitch, modEnvToFilterFc, modLfoToFilterFc, modLfoToVolume;
@@ -515,7 +517,7 @@
case KeyRange: region->lokey = amount->range.lo; region->hikey = amount->range.hi; break;
case VelRange: region->lovel = amount->range.lo; region->hivel = amount->range.hi; break;
case StartloopAddrsCoarseOffset: region->loop_start += amount->shortAmount * 32768; break;
- case InitialAttenuation: region->volume += amount->shortAmount / 100.0f; break;
+ case InitialAttenuation: region->attenuation += amount->shortAmount * 0.1f; break;
case EndloopAddrsCoarseOffset: region->loop_end += amount->shortAmount * 32768; break;
case CoarseTune: region->transpose += amount->shortAmount; break;
case FineTune: region->tune += amount->shortAmount; break;
@@ -649,7 +651,7 @@
zoneRegion.transpose += presetRegion.transpose;
zoneRegion.tune += presetRegion.tune;
zoneRegion.pitch_keytrack += presetRegion.pitch_keytrack;
- zoneRegion.volume += presetRegion.volume;
+ zoneRegion.attenuation += presetRegion.attenuation;
zoneRegion.pan += presetRegion.pan;
zoneRegion.ampenv.delay += presetRegion.ampenv.delay;
zoneRegion.ampenv.attack += presetRegion.ampenv.attack;
@@ -1256,7 +1258,7 @@
voice->playingPreset = preset_index;
voice->playingKey = key;
voice->playIndex = voicePlayIndex;
- voice->noteGainDB = f->globalGainDB - region->volume - tsf_gainToDecibels(1.0f / vel);
+ voice->noteGainDB = f->globalGainDB - region->attenuation - tsf_gainToDecibels(1.0f / vel);
if (f->channels)
{
@@ -1465,30 +1467,7 @@
c->bank = bank;
return 1;
}
-TSFDEF void tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel)
-{
- struct tsf_channel *c = tsf_channel_init(f, channel);
- if (c->pitchWheel == pitch_wheel) return;
- c->pitchWheel = pitch_wheel;
- tsf_channel_applypitch(f, channel, c);
-}
-TSFDEF void tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range)
-{
- struct tsf_channel *c = tsf_channel_init(f, channel);
- if (c->pitchRange == pitch_range) return;
- c->pitchRange = pitch_range;
- if (c->pitchWheel != 8192) tsf_channel_applypitch(f, channel, c);
-}
-
-TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning)
-{
- struct tsf_channel *c = tsf_channel_init(f, channel);
- if (c->tuning == tuning) return;
- c->tuning = tuning;
- tsf_channel_applypitch(f, channel, c);
-}
-
TSFDEF void tsf_channel_set_pan(tsf* f, int channel, float pan)
{
struct tsf_voice *v, *vEnd;
@@ -1515,6 +1494,30 @@
c->gainDB = gainDB;
}
+TSFDEF void tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel)
+{
+ struct tsf_channel *c = tsf_channel_init(f, channel);
+ if (c->pitchWheel == pitch_wheel) return;
+ c->pitchWheel = pitch_wheel;
+ tsf_channel_applypitch(f, channel, c);
+}
+
+TSFDEF void tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range)
+{
+ struct tsf_channel *c = tsf_channel_init(f, channel);
+ if (c->pitchRange == pitch_range) return;
+ c->pitchRange = pitch_range;
+ if (c->pitchWheel != 8192) tsf_channel_applypitch(f, channel, c);
+}
+
+TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning)
+{
+ struct tsf_channel *c = tsf_channel_init(f, channel);
+ if (c->tuning == tuning) return;
+ c->tuning = tuning;
+ tsf_channel_applypitch(f, channel, c);
+}
+
TSFDEF void tsf_channel_note_on(tsf* f, int channel, int key, float vel)
{
if (!f->channels || channel >= f->channels->channelNum) return;
@@ -1597,7 +1600,7 @@
tsf_channel_set_pan(f, channel, c->midiPan / 16383.0f);
return;
TCMC_SET_DATA:
- if (c->midiRPN == 0) tsf_channel_set_pitchrange(f, channel, (c->midiData >> 8) + 0.01f * (c->midiData & 0x7F));
+ if (c->midiRPN == 0) tsf_channel_set_pitchrange(f, channel, (c->midiData >> 7) + 0.01f * (c->midiData & 0x7F));
else if (c->midiRPN == 1) tsf_channel_set_tuning(f, channel, (int)c->tuning + ((float)c->midiData - 8192.0f) / 8192.0f); //fine tune
else if (c->midiRPN == 2 && controller == 6) tsf_channel_set_tuning(f, channel, ((float)control_value - 64.0f) + (c->tuning - (int)c->tuning)); //coarse tune
return;
@@ -1618,19 +1621,29 @@
return (f->channels && channel < f->channels->channelNum ? f->presets[f->channels->channels[channel].presetIndex].preset : 0);
}
+TSFDEF float tsf_channel_get_pan(tsf* f, int channel)
+{
+ return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].panOffset - 0.5f : 0.5f);
+}
+
+TSFDEF float tsf_channel_get_volume(tsf* f, int channel)
+{
+ return (f->channels && channel < f->channels->channelNum ? tsf_decibelsToGain(f->channels->channels[channel].gainDB) : 1.0f);
+}
+
TSFDEF int tsf_channel_get_pitchwheel(tsf* f, int channel)
{
return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].pitchWheel : 8192);
}
-TSFDEF float tsf_channel_get_pan(tsf* f, int channel)
+TSFDEF float tsf_channel_get_pitchrange(tsf* f, int channel)
{
- return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].panOffset - 0.5f : 0.5f);
+ return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].pitchRange : 2.0f);
}
-TSFDEF float tsf_channel_get_volume(tsf* f, int channel)
+TSFDEF float tsf_channel_get_tuning(tsf* f, int channel)
{
- return (f->channels && channel < f->channels->channelNum ? tsf_decibelsToGain(f->channels->channels[channel].gainDB) : 1.0f);
+ return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].tuning : 0.0f);
}
#ifdef __cplusplus