selcal/src/synth.cpp

108 lines
3.1 KiB
C++

#include "synth.h"
#include <stdexcept>
Synth::Synth() {
try {
settings = new_fluid_settings();
if (settings == nullptr) {
throw new std::runtime_error("Unable to create fluid settings");
}
synth = new_fluid_synth(settings);
if (synth == nullptr) {
throw new std::runtime_error("Unable to create fluid synth");
}
adriver = new_fluid_audio_driver(settings, synth);
if (adriver == nullptr) {
throw new std::runtime_error("Unable to create audio driver");
}
}
catch (std::runtime_error& e) {
// Do a mem-safe cleanup and rethrow.
// TODO JMT: Do these handle receiving nullptr for deletes?
delete_fluid_audio_driver(adriver);
delete_fluid_synth(synth);
delete_fluid_settings(settings);
throw;
}
}
Synth::~Synth() {
// TODO JMT: Do I need to manually clear all of the soundfonts and programs I have handles for?
delete_fluid_audio_driver(adriver);
delete_fluid_synth(synth);
delete_fluid_settings(settings);
}
bool Synth::loadSoundfont(const std::string& filepath) {
int soundfontId = fluid_synth_sfload(synth, filepath.c_str(), 1);
if(soundfontId == FLUID_FAILED) {
return false;
}
fluid_sfont_t* soundfontHandle = fluid_synth_get_sfont_by_id(synth, soundfontId);
const std::string soundfontName{fluid_sfont_get_name(soundfontHandle)};
Synth::Soundfont soundfont{soundfontName, soundfontId};
soundfonts.push_back(soundfont);
fluid_preset_t* preset = nullptr;
fluid_sfont_iteration_start(soundfontHandle);
while ((preset = fluid_sfont_iteration_next(soundfontHandle)) != nullptr) {
const std::string presetName{fluid_preset_get_name(preset)};
const int bankNumber = fluid_preset_get_banknum(preset);
const int programNumber = fluid_preset_get_num(preset);
Synth::Program program {presetName, soundfontId, bankNumber, programNumber};
programs.push_back(program);
}
return true;
}
bool Synth::loadProgram(const Program& program) {
// TODO JMT: fix this
fluid_synth_program_select(synth, 0, program.soundfontId, program.bankNumber, program.programNumber);
fluid_synth_program_select(synth, 1, program.soundfontId, program.bankNumber, program.programNumber);
return true;
}
bool Synth::setTuning(const std::array<double, NUM_MIDI_NOTES>& pitches) {
int result = fluid_synth_activate_key_tuning(
synth,
0, 0,
"default",
pitches.data(),
1
);
if (result == FLUID_OK) {
result = fluid_synth_activate_tuning(synth, 0, 0, 0, 1);
result = fluid_synth_activate_tuning(synth, 1, 0, 0, 1);
}
return result == FLUID_OK;
}
bool Synth::resetTuning() {
int result = fluid_synth_activate_key_tuning(
synth,
0, 0,
"default",
nullptr,
1
);
return result == FLUID_OK;
}
const std::vector<Synth::Program>& Synth::getPrograms() const {
return programs;
}
fluid_synth_t* Synth::getSynth() {
return synth;
}