mirror of https://github.com/arendst/Tasmota.git
only disable midi for esp32 no code update
Disable since esp32 compiler bug
This commit is contained in:
parent
5a204aea48
commit
fa7e0f938e
|
@ -200,6 +200,7 @@ TSFDEF void tsf_channel_set_bank(tsf* f, int channel, int bank);
|
||||||
TSFDEF int tsf_channel_set_bank_preset(tsf* f, int channel, int bank, int preset_number);
|
TSFDEF int tsf_channel_set_bank_preset(tsf* f, int channel, int bank, int preset_number);
|
||||||
TSFDEF void tsf_channel_set_pan(tsf* f, int channel, float pan);
|
TSFDEF void tsf_channel_set_pan(tsf* f, int channel, float pan);
|
||||||
TSFDEF void tsf_channel_set_volume(tsf* f, int channel, float volume);
|
TSFDEF void tsf_channel_set_volume(tsf* f, int channel, float volume);
|
||||||
|
TSFDEF void tsf_channel_set_volume_to_one(tsf* f, int channel); // solves a Compiler bug!! TODO: refactor after compiler fix!!
|
||||||
TSFDEF void tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel);
|
TSFDEF void tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel);
|
||||||
TSFDEF void tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range);
|
TSFDEF void tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range);
|
||||||
TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning);
|
TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning);
|
||||||
|
@ -612,11 +613,11 @@ struct tsf_voice
|
||||||
{
|
{
|
||||||
int playingPreset, playingKey, playingChannel;
|
int playingPreset, playingKey, playingChannel;
|
||||||
struct tsf_region* region;
|
struct tsf_region* region;
|
||||||
double pitchRatio;
|
double pitchInputTimecents, pitchOutputFactor;
|
||||||
double sourceSamplePosition;
|
double sourceSamplePosition;
|
||||||
fixed32p32 sourceSamplePositionF32P32, loopStartF32P32, loopEndF32P32, loopSizeF32P32, pitchRatioF32P32;
|
fixed32p32 sourceSamplePositionF32P32;
|
||||||
float noteGain, panFactorLeft, panFactorRight;
|
float noteGainDB, panFactorLeft, panFactorRight;
|
||||||
int playIndex, loopStart, loopEnd;
|
unsigned int playIndex, loopStart, loopEnd;
|
||||||
struct tsf_voice_envelope ampenv, modenv;
|
struct tsf_voice_envelope ampenv, modenv;
|
||||||
struct tsf_voice_lowpass lowpass;
|
struct tsf_voice_lowpass lowpass;
|
||||||
struct tsf_voice_lfo modlfo, viblfo;
|
struct tsf_voice_lfo modlfo, viblfo;
|
||||||
|
@ -635,14 +636,6 @@ struct tsf_channels
|
||||||
int channelNum, activeChannel;
|
int channelNum, activeChannel;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Math properties of tsf_timecents2Secs* (tc2s):
|
|
||||||
// # tc2s(a + b) = tc2s(a) * tc2s(b)
|
|
||||||
// # tc2s(a - b) = tc2s(a) / tc2s(b)
|
|
||||||
// # 1 / tc2s(a) = tc2s(-a)
|
|
||||||
// # The same applies to tsf_cents2Hertz and tsf_decibelsToGain
|
|
||||||
// Path properties of tsf_decibelsToGain (db2g) and tsf_gainToDecibels (g2db)
|
|
||||||
// # db2g(g2db(a)) = a
|
|
||||||
// # g2db(db2g(a)) = a
|
|
||||||
static double tsf_timecents2Secsd(double timecents) { return TSF_POW(2.0, timecents / 1200.0); }
|
static double tsf_timecents2Secsd(double timecents) { return TSF_POW(2.0, timecents / 1200.0); }
|
||||||
static float tsf_timecents2Secsf(float timecents) { return TSF_POWF(2.0f, timecents / 1200.0f); }
|
static float tsf_timecents2Secsf(float timecents) { return TSF_POWF(2.0f, timecents / 1200.0f); }
|
||||||
static float tsf_cents2Hertz(float cents) { return 8.176f * TSF_POWF(2.0f, cents / 1200.0f); }
|
static float tsf_cents2Hertz(float cents) { return 8.176f * TSF_POWF(2.0f, cents / 1200.0f); }
|
||||||
|
@ -1238,7 +1231,6 @@ static void tsf_voice_end(struct tsf_voice* v, float outSampleRate)
|
||||||
{
|
{
|
||||||
// Continue playing, but stop looping.
|
// Continue playing, but stop looping.
|
||||||
v->loopEnd = v->loopStart;
|
v->loopEnd = v->loopStart;
|
||||||
v->loopSizeF32P32 = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1251,9 +1243,10 @@ static void tsf_voice_endquick(struct tsf_voice* v, float outSampleRate)
|
||||||
static void tsf_voice_calcpitchratio(struct tsf_voice* v, float pitchShift, float outSampleRate)
|
static void tsf_voice_calcpitchratio(struct tsf_voice* v, float pitchShift, float outSampleRate)
|
||||||
{
|
{
|
||||||
double note = v->playingKey + v->region->transpose + v->region->tune / 100.0;
|
double note = v->playingKey + v->region->transpose + v->region->tune / 100.0;
|
||||||
double adjustedPitch = (note - v->region->pitch_keycenter) * v->region->pitch_keytrack;
|
double adjustedPitch = v->region->pitch_keycenter + (note - v->region->pitch_keycenter) * (v->region->pitch_keytrack / 100.0);
|
||||||
if (pitchShift) adjustedPitch += adjustedPitch * 100.0f;
|
if (pitchShift) adjustedPitch += pitchShift;
|
||||||
v->pitchRatio = v->region->sample_rate * tsf_timecents2Secsd(adjustedPitch) / outSampleRate;
|
v->pitchInputTimecents = adjustedPitch * 100.0;
|
||||||
|
v->pitchOutputFactor = v->region->sample_rate / (tsf_timecents2Secsd(v->region->pitch_keycenter * 100.0) * outSampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
short tsf_read_short_cached(tsf *f, int pos)
|
short tsf_read_short_cached(tsf *f, int pos)
|
||||||
|
@ -1321,10 +1314,10 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i
|
||||||
else tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0;
|
else tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0;
|
||||||
|
|
||||||
if (dynamicPitchRatio) pitchRatio = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch;
|
if (dynamicPitchRatio) pitchRatio = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch;
|
||||||
else pitchRatio = v->pitchRatio, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0;
|
else pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0;
|
||||||
|
|
||||||
if (dynamicGain) tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f;
|
if (dynamicGain) tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f;
|
||||||
else noteGain = v->noteGain, tmpModLfoToVolume = 0;
|
else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0;
|
||||||
|
|
||||||
while (numSamples)
|
while (numSamples)
|
||||||
{
|
{
|
||||||
|
@ -1341,10 +1334,10 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dynamicPitchRatio)
|
if (dynamicPitchRatio)
|
||||||
pitchRatio = v->pitchRatio * tsf_timecents2Secsd(v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch);
|
pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents + (v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch)) * v->pitchOutputFactor;
|
||||||
|
|
||||||
if (dynamicGain)
|
if (dynamicGain)
|
||||||
noteGain = v->noteGain * tsf_decibelsToGain(v->modlfo.level * tmpModLfoToVolume);
|
noteGain = tsf_decibelsToGain(v->noteGainDB + (v->modlfo.level * tmpModLfoToVolume));
|
||||||
|
|
||||||
gainMono = noteGain * v->ampenv.level;
|
gainMono = noteGain * v->ampenv.level;
|
||||||
|
|
||||||
|
@ -1453,22 +1446,39 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff
|
||||||
TSF_BOOL updateModEnv = (region->modEnvToPitch || region->modEnvToFilterFc);
|
TSF_BOOL updateModEnv = (region->modEnvToPitch || region->modEnvToFilterFc);
|
||||||
TSF_BOOL updateModLFO = (v->modlfo.delta && (region->modLfoToPitch || region->modLfoToFilterFc || region->modLfoToVolume));
|
TSF_BOOL updateModLFO = (v->modlfo.delta && (region->modLfoToPitch || region->modLfoToFilterFc || region->modLfoToVolume));
|
||||||
TSF_BOOL updateVibLFO = (v->viblfo.delta && (region->vibLfoToPitch));
|
TSF_BOOL updateVibLFO = (v->viblfo.delta && (region->vibLfoToPitch));
|
||||||
TSF_BOOL isLooping = (v->loopSizeF32P32 > 0);
|
TSF_BOOL isLooping = (v->loopStart < v->loopEnd);
|
||||||
fixed32p32 tmpSampleEndF32P32 = (fixed32p32)(region->end) << 32;
|
unsigned int tmpLoopStart = v->loopStart, tmpLoopEnd = v->loopEnd;
|
||||||
|
//double tmpSampleEndDbl = (double)v->sampleEnd, tmpLoopEndDbl = (double)tmpLoopEnd + 1.0;
|
||||||
|
//double tmpSourceSamplePosition = v->sourceSamplePosition;
|
||||||
|
fixed32p32 tmpSampleEndF32P32 = ((fixed32p32)(region->end)) << 32;
|
||||||
|
fixed32p32 tmpLoopEndF32P32 = ((fixed32p32)(tmpLoopEnd + 1)) << 32;
|
||||||
fixed32p32 tmpSourceSamplePositionF32P32 = v->sourceSamplePositionF32P32;
|
fixed32p32 tmpSourceSamplePositionF32P32 = v->sourceSamplePositionF32P32;
|
||||||
|
struct tsf_voice_lowpass tmpLowpass = v->lowpass;
|
||||||
|
|
||||||
|
TSF_BOOL dynamicLowpass = (region->modLfoToFilterFc || region->modEnvToFilterFc);
|
||||||
|
float tmpSampleRate = f->outSampleRate, tmpInitialFilterFc, tmpModLfoToFilterFc, tmpModEnvToFilterFc;
|
||||||
|
|
||||||
TSF_BOOL dynamicPitchRatio = (region->modLfoToPitch || region->modEnvToPitch || region->vibLfoToPitch);
|
TSF_BOOL dynamicPitchRatio = (region->modLfoToPitch || region->modEnvToPitch || region->vibLfoToPitch);
|
||||||
fixed32p32 pitchRatioF32P32, tmpPitchRatioF32P32;
|
//double pitchRatio;
|
||||||
|
fixed32p32 pitchRatioF32P32;
|
||||||
float tmpModLfoToPitch, tmpVibLfoToPitch, tmpModEnvToPitch;
|
float tmpModLfoToPitch, tmpVibLfoToPitch, tmpModEnvToPitch;
|
||||||
|
|
||||||
TSF_BOOL dynamicGain = (region->modLfoToVolume != 0);
|
TSF_BOOL dynamicGain = (region->modLfoToVolume != 0);
|
||||||
float noteGain, tmpNoteGain, tmpModLfoToVolume;
|
float noteGain, tmpModLfoToVolume;
|
||||||
|
|
||||||
if (dynamicPitchRatio) tmpPitchRatioF32P32 = v->pitchRatioF32P32, pitchRatioF32P32 = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch;
|
if (dynamicLowpass) tmpInitialFilterFc = (float)region->initialFilterFc, tmpModLfoToFilterFc = (float)region->modLfoToFilterFc, tmpModEnvToFilterFc = (float)region->modEnvToFilterFc;
|
||||||
else pitchRatioF32P32 = v->pitchRatioF32P32, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0;
|
else tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0;
|
||||||
|
|
||||||
if (dynamicGain) noteGain = 0, tmpNoteGain = v->noteGain, tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f;
|
if (dynamicPitchRatio) pitchRatioF32P32 = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch;
|
||||||
else noteGain = v->noteGain, tmpModLfoToVolume = 0;
|
else {
|
||||||
|
double pr = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor;
|
||||||
|
fixed32p32 adj = 1LL<<32;
|
||||||
|
pr *= adj;
|
||||||
|
pitchRatioF32P32 = (int64_t)pr, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamicGain) noteGain = 0, tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f;
|
||||||
|
else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0;
|
||||||
|
|
||||||
while (numSamples)
|
while (numSamples)
|
||||||
{
|
{
|
||||||
|
@ -1476,17 +1486,19 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff
|
||||||
int blockSamples = (numSamples > TSF_RENDER_EFFECTSAMPLEBLOCK ? TSF_RENDER_EFFECTSAMPLEBLOCK : numSamples);
|
int blockSamples = (numSamples > TSF_RENDER_EFFECTSAMPLEBLOCK ? TSF_RENDER_EFFECTSAMPLEBLOCK : numSamples);
|
||||||
numSamples -= blockSamples;
|
numSamples -= blockSamples;
|
||||||
|
|
||||||
if (dynamicPitchRatio) {
|
if (dynamicLowpass)
|
||||||
if (v->modlfo.level || v->viblfo.level || v->modenv.level)
|
{
|
||||||
pitchRatioF32P32 = tmpPitchRatioF32P32 * tsf_timecents2Secsd(v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch);
|
float fres = tmpInitialFilterFc + v->modlfo.level * tmpModLfoToFilterFc + v->modenv.level * tmpModEnvToFilterFc;
|
||||||
else
|
tmpLowpass.active = (fres <= 13500.0f);
|
||||||
pitchRatioF32P32 = tmpPitchRatioF32P32; // If all levels are 0, just bypass conversion function
|
if (tmpLowpass.active) tsf_voice_lowpass_setup(&tmpLowpass, tsf_cents2Hertz(fres) / tmpSampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dynamicGain) {
|
if (dynamicPitchRatio) {
|
||||||
if (v->modlfo.level) noteGain = tmpNoteGain * tsf_decibelsToGain(v->modlfo.level * tmpModLfoToVolume);
|
pitchRatioF32P32 = tsf_timecents2Secsd(v->pitchInputTimecents + (v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch)) * v->pitchOutputFactor * (1LL<<32);
|
||||||
else noteGain = tmpNoteGain; // If level is 0, just bypass conversion function
|
}
|
||||||
}
|
|
||||||
|
if (dynamicGain)
|
||||||
|
noteGain = tsf_decibelsToGain(v->noteGainDB + (v->modlfo.level * tmpModLfoToVolume));
|
||||||
|
|
||||||
gainMono = noteGain * v->ampenv.level;
|
gainMono = noteGain * v->ampenv.level;
|
||||||
short gainMonoFP = gainMono * 32767;
|
short gainMonoFP = gainMono * 32767;
|
||||||
|
@ -1499,7 +1511,7 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff
|
||||||
if (updateModLFO) tsf_voice_lfo_process(&v->modlfo, blockSamples);
|
if (updateModLFO) tsf_voice_lfo_process(&v->modlfo, blockSamples);
|
||||||
if (updateVibLFO) tsf_voice_lfo_process(&v->viblfo, blockSamples);
|
if (updateVibLFO) tsf_voice_lfo_process(&v->viblfo, blockSamples);
|
||||||
|
|
||||||
while (blockSamples--)
|
while (blockSamples-- && tmpSourceSamplePositionF32P32 < tmpSampleEndF32P32)
|
||||||
{
|
{
|
||||||
unsigned int pos = (unsigned int)(tmpSourceSamplePositionF32P32>>32);
|
unsigned int pos = (unsigned int)(tmpSourceSamplePositionF32P32>>32);
|
||||||
if (pos == 0xffffffff) pos = 0;
|
if (pos == 0xffffffff) pos = 0;
|
||||||
|
@ -1511,14 +1523,8 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff
|
||||||
|
|
||||||
// Next sample.
|
// Next sample.
|
||||||
tmpSourceSamplePositionF32P32 += pitchRatioF32P32;
|
tmpSourceSamplePositionF32P32 += pitchRatioF32P32;
|
||||||
|
if (tmpSourceSamplePositionF32P32 >= tmpLoopEndF32P32 && isLooping)
|
||||||
if (tmpSourceSamplePositionF32P32 >= v->loopEndF32P32)
|
tmpSourceSamplePositionF32P32 -= (tmpLoopEndF32P32 - tmpLoopStart + (1LL<<32));
|
||||||
{
|
|
||||||
if (isLooping)
|
|
||||||
tmpSourceSamplePositionF32P32 -= v->loopSizeF32P32;
|
|
||||||
else if (tmpSourceSamplePositionF32P32 >= tmpSampleEndF32P32)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmpSourceSamplePositionF32P32 >= tmpSampleEndF32P32 || v->ampenv.segment == TSF_SEGMENT_DONE)
|
if (tmpSourceSamplePositionF32P32 >= tmpSampleEndF32P32 || v->ampenv.segment == TSF_SEGMENT_DONE)
|
||||||
|
@ -1529,6 +1535,7 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff
|
||||||
}
|
}
|
||||||
|
|
||||||
v->sourceSamplePositionF32P32 = tmpSourceSamplePositionF32P32;
|
v->sourceSamplePositionF32P32 = tmpSourceSamplePositionF32P32;
|
||||||
|
if (tmpLowpass.active || dynamicLowpass) v->lowpass = tmpLowpass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1723,14 +1730,13 @@ TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel)
|
||||||
}
|
}
|
||||||
voice = &f->voices[f->voiceNum - 4];
|
voice = &f->voices[f->voiceNum - 4];
|
||||||
voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1;
|
voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1;
|
||||||
voice[1].playIndex = voice[2].playIndex = voice[3].playIndex = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
voice->region = region;
|
voice->region = region;
|
||||||
voice->playingPreset = preset_index;
|
voice->playingPreset = preset_index;
|
||||||
voice->playingKey = key;
|
voice->playingKey = key;
|
||||||
voice->playIndex = voicePlayIndex;
|
voice->playIndex = voicePlayIndex;
|
||||||
voice->noteGain = vel * tsf_decibelsToGain(f->globalGainDB - region->attenuation);
|
voice->noteGainDB = f->globalGainDB - region->attenuation - tsf_gainToDecibels(1.0f / vel);
|
||||||
|
|
||||||
if (f->channels)
|
if (f->channels)
|
||||||
{
|
{
|
||||||
|
@ -1746,6 +1752,7 @@ TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel)
|
||||||
|
|
||||||
// Offset/end.
|
// Offset/end.
|
||||||
voice->sourceSamplePosition = region->offset;
|
voice->sourceSamplePosition = region->offset;
|
||||||
|
voice->sourceSamplePositionF32P32 = ((int64_t)region->offset)<< 32;
|
||||||
|
|
||||||
// Loop.
|
// Loop.
|
||||||
doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end);
|
doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end);
|
||||||
|
@ -1770,86 +1777,6 @@ TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the generated playing index that can be used to identify all voices related to this note.
|
|
||||||
*/
|
|
||||||
TSFDEF int tsf_note_on_fast(tsf* f, int preset_index, int key, float vel)
|
|
||||||
{
|
|
||||||
if (preset_index < 0 || preset_index >= f->presetNum) return -1;
|
|
||||||
if (!vel) { tsf_note_off(f, preset_index, key); return -1; }
|
|
||||||
if (f->presets[preset_index].regions == NULL) tsf_load_preset(f, f->hydra, preset_index);
|
|
||||||
|
|
||||||
short midiVelocity = (short)(vel * 127);
|
|
||||||
struct tsf_region *region, *regionEnd;
|
|
||||||
|
|
||||||
// Play all matching regions.
|
|
||||||
int voicePlayIndex = f->voicePlayIndex++;
|
|
||||||
for (region = f->presets[preset_index].regions, regionEnd = region + f->presets[preset_index].regionNum; region != regionEnd; region++)
|
|
||||||
{
|
|
||||||
if (key < region->lokey || key > region->hikey || midiVelocity < region->lovel || midiVelocity > region->hivel) continue;
|
|
||||||
|
|
||||||
struct tsf_voice *voice, *v, *vEnd; TSF_BOOL doLoop;
|
|
||||||
voice = TSF_NULL, v = f->voices, vEnd = v + f->voiceNum;
|
|
||||||
if (region->group)
|
|
||||||
{
|
|
||||||
for (; v != vEnd; v++)
|
|
||||||
if (v->playingPreset == preset_index && v->region->group == region->group) tsf_voice_endquick(v, f->outSampleRate);
|
|
||||||
else if (v->playingPreset == -1 && !voice) voice = v;
|
|
||||||
}
|
|
||||||
else for (; v != vEnd; v++) if (v->playingPreset == -1) { voice = v; break; }
|
|
||||||
|
|
||||||
if (!voice)
|
|
||||||
{
|
|
||||||
f->voiceNum += 4;
|
|
||||||
struct tsf_voice *saveVoice = f->voices;
|
|
||||||
f->voices = (struct tsf_voice*)TSF_REALLOC(f->voices, f->voiceNum * sizeof(struct tsf_voice));
|
|
||||||
if (!f->voices) {
|
|
||||||
f->voices = saveVoice;
|
|
||||||
printf("OOM, no room for new voice. Ignoring note_on\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
voice = &f->voices[f->voiceNum - 4];
|
|
||||||
voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1;
|
|
||||||
voice[1].playIndex = voice[2].playIndex = voice[3].playIndex = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
voice->region = region;
|
|
||||||
voice->playingPreset = preset_index;
|
|
||||||
voice->playingKey = key;
|
|
||||||
voice->playIndex = voicePlayIndex;
|
|
||||||
voice->noteGain = vel * tsf_decibelsToGain(f->globalGainDB - region->attenuation);
|
|
||||||
|
|
||||||
if (f->channels)
|
|
||||||
{
|
|
||||||
f->channels->setupVoice(f, voice);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tsf_voice_calcpitchratio(voice, 0, f->outSampleRate);
|
|
||||||
voice->pitchRatioF32P32 = voice->pitchRatio * (1LL << 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset/end.
|
|
||||||
voice->sourceSamplePositionF32P32 = ((int64_t)region->offset)<< 32;
|
|
||||||
|
|
||||||
// Loop.
|
|
||||||
doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end);
|
|
||||||
voice->loopStartF32P32 = doLoop ? ((int64_t)region->loop_start + 1) << 32 : 0;
|
|
||||||
voice->loopEndF32P32 = doLoop ? ((int64_t)region->loop_end + 1) << 32 : 0;
|
|
||||||
voice->loopSizeF32P32 = doLoop ? voice->loopEndF32P32 - voice->loopStartF32P32 + (1LL << 32) : 0;
|
|
||||||
|
|
||||||
// Setup envelopes.
|
|
||||||
tsf_voice_envelope_setup(&voice->ampenv, ®ion->ampenv, key, midiVelocity, TSF_TRUE, f->outSampleRate);
|
|
||||||
tsf_voice_envelope_setup(&voice->modenv, ®ion->modenv, key, midiVelocity, TSF_FALSE, f->outSampleRate);
|
|
||||||
|
|
||||||
// Setup LFO filters.
|
|
||||||
tsf_voice_lfo_setup(&voice->modlfo, region->delayModLFO, region->freqModLFO, f->outSampleRate);
|
|
||||||
tsf_voice_lfo_setup(&voice->viblfo, region->delayVibLFO, region->freqVibLFO, f->outSampleRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return voicePlayIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
TSFDEF int tsf_bank_note_on(tsf* f, int bank, int preset_number, int key, float vel)
|
TSFDEF int tsf_bank_note_on(tsf* f, int bank, int preset_number, int key, float vel)
|
||||||
{
|
{
|
||||||
int preset_index = tsf_get_presetindex(f, bank, preset_number);
|
int preset_index = tsf_get_presetindex(f, bank, preset_number);
|
||||||
|
@ -1878,19 +1805,6 @@ TSFDEF void tsf_note_off(tsf* f, int preset_index, int key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops all voices with the given playing index. If no key provided or if -1, fallbacks to tsf_note_off
|
|
||||||
*/
|
|
||||||
TSFDEF void tsf_note_off_fast(tsf* f, int preset_index, int key, int playIndex = -1)
|
|
||||||
{
|
|
||||||
if (playIndex < 0)
|
|
||||||
tsf_note_off(f, preset_index, key);
|
|
||||||
else
|
|
||||||
for (struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; v != vEnd; v++)
|
|
||||||
if (v->playIndex == playIndex && v->playingPreset == preset_index && v->playingKey == key && v->ampenv.segment < TSF_SEGMENT_RELEASE)
|
|
||||||
tsf_voice_end(v, f->outSampleRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
TSFDEF int tsf_bank_note_off(tsf* f, int bank, int preset_number, int key)
|
TSFDEF int tsf_bank_note_off(tsf* f, int bank, int preset_number, int key)
|
||||||
{
|
{
|
||||||
int preset_index = tsf_get_presetindex(f, bank, preset_number);
|
int preset_index = tsf_get_presetindex(f, bank, preset_number);
|
||||||
|
@ -1970,7 +1884,7 @@ static void tsf_channel_setup_voice(tsf* f, struct tsf_voice* v)
|
||||||
struct tsf_channel* c = &f->channels->channels[f->channels->activeChannel];
|
struct tsf_channel* c = &f->channels->channels[f->channels->activeChannel];
|
||||||
float newpan = v->region->pan + c->panOffset;
|
float newpan = v->region->pan + c->panOffset;
|
||||||
v->playingChannel = f->channels->activeChannel;
|
v->playingChannel = f->channels->activeChannel;
|
||||||
v->noteGain *= tsf_decibelsToGain(c->gainDB);
|
v->noteGainDB += c->gainDB;
|
||||||
tsf_voice_calcpitchratio(v, (c->pitchWheel == 8192 ? c->tuning : ((c->pitchWheel / 16383.0f * c->pitchRange * 2.0f) - c->pitchRange + c->tuning)), f->outSampleRate);
|
tsf_voice_calcpitchratio(v, (c->pitchWheel == 8192 ? c->tuning : ((c->pitchWheel / 16383.0f * c->pitchRange * 2.0f) - c->pitchRange + c->tuning)), f->outSampleRate);
|
||||||
if (newpan <= -0.5f) { v->panFactorLeft = 1.0f; v->panFactorRight = 0.0f; }
|
if (newpan <= -0.5f) { v->panFactorLeft = 1.0f; v->panFactorRight = 0.0f; }
|
||||||
else if (newpan >= 0.5f) { v->panFactorLeft = 0.0f; v->panFactorRight = 1.0f; }
|
else if (newpan >= 0.5f) { v->panFactorLeft = 0.0f; v->panFactorRight = 1.0f; }
|
||||||
|
@ -2080,7 +1994,7 @@ TSFDEF void tsf_channel_set_volume(tsf* f, int channel, float volume)
|
||||||
if (gainDBChange == 0) return;
|
if (gainDBChange == 0) return;
|
||||||
for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++)
|
for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++)
|
||||||
if (v->playingChannel == channel && v->playingPreset != -1)
|
if (v->playingChannel == channel && v->playingPreset != -1)
|
||||||
v->noteGain *= tsf_decibelsToGain(gainDBChange);
|
v->noteGainDB += gainDBChange;
|
||||||
c->gainDB = gainDB;
|
c->gainDB = gainDB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2151,6 +2065,10 @@ TSFDEF void tsf_channel_sounds_off_all(tsf* f, int channel)
|
||||||
tsf_voice_endquick(v, f->outSampleRate);
|
tsf_voice_endquick(v, f->outSampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TSFDEF void tsf_channel_set_volume_to_one(tsf* f, int channel){
|
||||||
|
tsf_channel_set_volume(f, channel, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int control_value)
|
TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int control_value)
|
||||||
{
|
{
|
||||||
struct tsf_channel* c = tsf_channel_init(f, channel);
|
struct tsf_channel* c = tsf_channel_init(f, channel);
|
||||||
|
@ -2176,7 +2094,7 @@ TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int co
|
||||||
c->midiVolume = c->midiExpression = 16383;
|
c->midiVolume = c->midiExpression = 16383;
|
||||||
c->midiPan = 8192;
|
c->midiPan = 8192;
|
||||||
c->bank = 0;
|
c->bank = 0;
|
||||||
tsf_channel_set_volume(f, channel, 1.0f);
|
tsf_channel_set_volume_to_one(f, channel);
|
||||||
tsf_channel_set_pan(f, channel, 0.5f);
|
tsf_channel_set_pan(f, channel, 0.5f);
|
||||||
tsf_channel_set_pitchrange(f, channel, 2.0f);
|
tsf_channel_set_pitchrange(f, channel, 2.0f);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue