Microtonality for SF2Player (#6580)

Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>
This commit is contained in:
Lost Robot
2023-01-01 02:28:30 -08:00
committed by GitHub
parent 6c7d2da9c4
commit 2f2ba41f28
4 changed files with 59 additions and 11 deletions

View File

@@ -495,7 +495,7 @@ ENDIF()
# check for Fluidsynth
IF(WANT_SF2)
find_package(FluidSynth 1.0.7)
find_package(FluidSynth 1.1.0)
if(FluidSynth_FOUND)
SET(LMMS_HAVE_FLUIDSYNTH TRUE)
SET(STATUS_FLUIDSYNTH "OK")

View File

@@ -224,6 +224,11 @@ public:
return &m_mixerChannelModel;
}
BoolModel* useMasterPitchModel()
{
return &m_useMasterPitchModel;
}
void setPreviewMode( const bool );
bool isPreviewMode() const

View File

@@ -181,6 +181,15 @@ Sf2Instrument::Sf2Instrument( InstrumentTrack * _instrument_track ) :
connect( &m_chorusLevel, SIGNAL( dataChanged() ), this, SLOT( updateChorus() ) );
connect( &m_chorusSpeed, SIGNAL( dataChanged() ), this, SLOT( updateChorus() ) );
connect( &m_chorusDepth, SIGNAL( dataChanged() ), this, SLOT( updateChorus() ) );
// Microtuning
connect(Engine::getSong(), &Song::scaleListChanged, this, &Sf2Instrument::updateTuning);
connect(Engine::getSong(), &Song::keymapListChanged, this, &Sf2Instrument::updateTuning);
connect(instrumentTrack()->microtuner()->enabledModel(), &Model::dataChanged, this, &Sf2Instrument::updateTuning, Qt::DirectConnection);
connect(instrumentTrack()->microtuner()->scaleModel(), &Model::dataChanged, this, &Sf2Instrument::updateTuning, Qt::DirectConnection);
connect(instrumentTrack()->microtuner()->keymapModel(), &Model::dataChanged, this, &Sf2Instrument::updateTuning, Qt::DirectConnection);
connect(instrumentTrack()->microtuner()->keyRangeImportModel(), &Model::dataChanged, this, &Sf2Instrument::updateTuning, Qt::DirectConnection);
connect(instrumentTrack()->baseNoteModel(), &Model::dataChanged, this, &Sf2Instrument::updateTuning, Qt::DirectConnection);
auto iph = new InstrumentPlayHandle(this, _instrument_track);
Engine::audioEngine()->addPlayHandle( iph );
@@ -537,6 +546,38 @@ void Sf2Instrument::updateChorus()
void Sf2Instrument::updateTuning()
{
if (instrumentTrack()->microtuner()->enabledModel()->value())
{
auto centArray = std::array<double, 128>{};
double lowestHz = pow(2., -69. / 12.) * 440.;// Frequency of MIDI note 0, which is approximately 8.175798916 Hz
for (int i = 0; i < 128; ++i)
{
// Get desired Hz of note
double noteHz = instrumentTrack()->microtuner()->keyToFreq(i, DefaultBaseKey);
// Convert Hz to cents
centArray[i] = noteHz == 0. ? 0. : 1200. * log2(noteHz / lowestHz);
}
fluid_synth_activate_key_tuning(m_synth, 0, 0, "", centArray.data(), true);
for (int chan = 0; chan < 16; chan++)
{
fluid_synth_activate_tuning(m_synth, chan, 0, 0, true);
}
}
else
{
fluid_synth_activate_key_tuning(m_synth, 0, 0, "", nullptr, true);
for (int chan = 0; chan < 16; chan++)
{
fluid_synth_activate_tuning(m_synth, chan, 0, 0, true);
}
}
}
void Sf2Instrument::reloadSynth()
{
double tempRate;
@@ -604,6 +645,7 @@ void Sf2Instrument::reloadSynth()
updateReverbOn();
updateChorusOn();
updateGain();
updateTuning();
// Reset last MIDI pitch properties, which will be set to the correct values
// upon playing the next note
@@ -622,18 +664,19 @@ void Sf2Instrument::playNote( NotePlayHandle * _n, sampleFrame * )
}
const f_cnt_t tfp = _n->totalFramesPlayed();
int masterPitch = instrumentTrack()->useMasterPitchModel()->value() ? Engine::getSong()->masterPitch() : 0;
int baseNote = instrumentTrack()->baseNoteModel()->value();
int midiNote = _n->midiKey() - baseNote + DefaultBaseKey + masterPitch;
if( tfp == 0 )
// out of range?
if (midiNote < 0 || midiNote >= 128)
{
const float LOG440 = 2.643452676f;
return;
}
int midiNote = (int)floor( 12.0 * ( log2( _n->unpitchedFrequency() ) - LOG440 ) - 4.0 );
// out of range?
if( midiNote <= 0 || midiNote >= 128 )
{
return;
}
if (tfp == 0)
{
const int baseVelocity = instrumentTrack()->midiPort()->baseVelocity();
auto pluginData = new Sf2PluginData;

View File

@@ -111,7 +111,7 @@ public slots:
void updateChorusOn();
void updateChorus();
void updateGain();
void updateTuning();
private:
static QMutex s_fontsMutex;