114 lines
3.5 KiB
C++
114 lines
3.5 KiB
C++
#include "synth.h"
|
|
#include "code.h"
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <magic_enum.hpp>
|
|
#include "midi.h"
|
|
|
|
#include <thread>
|
|
#include <chrono>
|
|
|
|
int main(int argc, char** argv) {
|
|
|
|
SELCAL::Code code{argv[1]};
|
|
|
|
for (auto& group : code.getGroups()) {
|
|
std::cout
|
|
<< magic_enum::enum_name(group[0]) << " + "
|
|
<< magic_enum::enum_name(group[1])
|
|
<< std::endl;
|
|
}
|
|
|
|
|
|
Synth synth;
|
|
synth.loadSoundfont("../soundfonts/square-equaltemperament.sf2");
|
|
//synth.loadSoundfont("../soundfonts/TimGM6mb.sf2");
|
|
synth.loadSoundfont("../soundfonts/GU-1.471.sf2");
|
|
|
|
/*
|
|
for(int i = 1; i < argc; ++i) {
|
|
synth.loadSoundfont(argv[i]);
|
|
}
|
|
*/
|
|
|
|
for (const Synth::Program& program : synth.getPrograms()) {
|
|
std::cout << program.name << " " << program.soundfontId
|
|
<< ":(" << program.bankNumber << ", " << program.programNumber << ")"
|
|
<< std::endl;
|
|
|
|
if (program.name == "Night Vision") {
|
|
std::cout << "Loading program!" << std::endl;
|
|
synth.loadProgram(program);
|
|
}
|
|
}
|
|
|
|
std::map<SELCAL::Key, double> keyFrequencies = {
|
|
{SELCAL::Key::KEY_1, 680.0},
|
|
{SELCAL::Key::KEY_2, 754.2},
|
|
{SELCAL::Key::KEY_3, 836.6},
|
|
{SELCAL::Key::KEY_4, 927.9},
|
|
{SELCAL::Key::KEY_5, 1029.2},
|
|
{SELCAL::Key::KEY_6, 1141.6},
|
|
{SELCAL::Key::KEY_7, 1266.2},
|
|
{SELCAL::Key::KEY_8, 1404.4},
|
|
{SELCAL::Key::KEY_9, 1557.8},
|
|
{SELCAL::Key::KEY_A, 312.6},
|
|
{SELCAL::Key::KEY_B, 346.7},
|
|
{SELCAL::Key::KEY_C, 384.6},
|
|
{SELCAL::Key::KEY_D, 426.6},
|
|
{SELCAL::Key::KEY_E, 473.2},
|
|
{SELCAL::Key::KEY_F, 524.8},
|
|
{SELCAL::Key::KEY_G, 582.1},
|
|
{SELCAL::Key::KEY_H, 645.7},
|
|
{SELCAL::Key::KEY_J, 716.1},
|
|
{SELCAL::Key::KEY_K, 794.3},
|
|
{SELCAL::Key::KEY_L, 881.0},
|
|
{SELCAL::Key::KEY_M, 977.2},
|
|
{SELCAL::Key::KEY_P, 1083.9},
|
|
{SELCAL::Key::KEY_Q, 1202.3},
|
|
{SELCAL::Key::KEY_R, 1333.5},
|
|
{SELCAL::Key::KEY_S, 1479.1},
|
|
{SELCAL::Key::KEY_T, 329.2},
|
|
{SELCAL::Key::KEY_U, 365.2},
|
|
{SELCAL::Key::KEY_V, 405.0},
|
|
{SELCAL::Key::KEY_W, 449.3},
|
|
{SELCAL::Key::KEY_X, 498.3},
|
|
{SELCAL::Key::KEY_Y, 552.7},
|
|
{SELCAL::Key::KEY_Z, 613.1},
|
|
};
|
|
|
|
std::array<double, NUM_MIDI_NOTES> tunings;
|
|
tunings.fill(0);
|
|
|
|
|
|
for (auto pair : keyFrequencies) {
|
|
// fluidsynth wants tunings in MIDI cents, which effectively means MIDI key * 100.
|
|
// As we only care about the SELCAL 32 tones, only tune those specific keys. We don't
|
|
// need to tune the full 128-key keyboard.
|
|
constexpr double MIDI_CENT_SCALE = 100.0;
|
|
const int keyIndex = static_cast<int>(pair.first);
|
|
tunings[keyIndex] = frequencyToMidi(pair.second) * MIDI_CENT_SCALE;
|
|
}
|
|
|
|
fluid_synth_t* raw_synth = synth.getSynth();
|
|
constexpr int ALL_CHANNELS = -1;
|
|
bool success;
|
|
using namespace std::chrono_literals;
|
|
|
|
|
|
success = synth.setTuning(tunings);
|
|
std::cout << "Set tuning: " << (success ? "success" : "failed") << std::endl;
|
|
|
|
for (auto& group : code.getGroups()) {
|
|
fluid_synth_noteon(raw_synth, 0, static_cast<int>(group[0]), 127);
|
|
fluid_synth_noteon(raw_synth, 1, static_cast<int>(group[1]), 127);
|
|
std::this_thread::sleep_for(1s);
|
|
|
|
// Silence between tone groups
|
|
fluid_synth_all_notes_off(raw_synth, ALL_CHANNELS);
|
|
std::this_thread::sleep_for(200ms);
|
|
}
|
|
|
|
std::this_thread::sleep_for(500ms);
|
|
}
|