Something went wrong. Try again.
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071// Boot firmware 5.0.0.2084, send MIDI, and record three seconds of mono PCM.#include "targets/main.hpp"#include "control/panel.hpp"#include <algorithm>#include <array>#include <fstream>#include <iostream>#include <iterator>#include <stdexcept>#include <vector>
int main(int argc, char **argv) { try { if (argc != 3) throw std::runtime_error("usage: record firmware.bin output.wav"); std::ifstream input(argv[1], std::ios::binary); if (!input) throw std::runtime_error("cannot open firmware"); std::vector<char> bytes{std::istreambuf_iterator<char>(input), {}};
auto main = mf::Main::create(std::as_bytes(std::span(bytes))); main->boot();
uint8_t sequence = 0; auto parameter = [&](uint16_t id, uint16_t raw) { const auto command = "synth param " + std::to_string(id) + " " + std::to_string(raw); std::vector<uint8_t> sysex{0xf0, 0, 0x20, 0x6b, 7, 1, sequence++, static_cast<uint8_t>(command.size()), 0x53}; sysex.insert(sysex.end(), command.begin(), command.end()); sysex.push_back(0xf7); main->midi().send(sysex); // Deliver each edit before the next one; discard the settling audio. auto result = main->audio().advance(480, nullptr); if (!result) throw std::runtime_error(result.error().message); }; parameter(0x0000, mf::panel::Param::encode(22, 2)); // SuperWave parameter(0x0001, 0); // saw waveform parameter(0x0003, 9000); // moderate detune parameter(0x0005, 24000); // detuned-copy level parameter(0x0601, 1500); // short attack parameter(0x0602, 15000); // decay/release tail parameter(0x0603, 24000); // sustain // std::ofstream wav(argv[2], std::ios::binary); wav.exceptions(std::ios::failbit | std::ios::badbit); auto le = [&](uint32_t value, unsigned count) { for (unsigned i = 0; i < count; ++i) wav.put(static_cast<char>(value >> (8 * i))); }; constexpr uint32_t rate = 48000, frames = rate * 3; wav.write("RIFF", 4); le(36 + frames * 2, 4); wav.write("WAVEfmt ", 8); le(16, 4); le(1, 2); le(1, 2); le(rate, 4); le(rate * 2, 4); le(2, 2); le(16, 2); wav.write("data", 4); le(frames * 2, 4);
const std::array<uint8_t, 3> on{0x90, 60, 100}, off{0x80, 60, 0};
main->midi().send(on);
std::array<float, 480> block{}; for (uint32_t pos = 0; pos < frames; pos += block.size()) { if (pos == rate * 2) main->midi().send(off);
auto result = main->audio().advance(block.size(), block.data()); if (!result) throw std::runtime_error(result.error().message); for (float sample : block) le(static_cast<uint16_t>(static_cast<int16_t>(std::clamp(sample, -1.f, 1.f) * 32767)), 2); } wav.close(); } catch (const std::exception &e) { std::cerr << e.what() << '\n'; return 1; }}