A bunch of WIP stuff needing cleaning

This commit is contained in:
Jono Targett 2024-05-25 19:59:41 +09:30
parent 5d18b8636c
commit ec52422955
8 changed files with 75 additions and 5 deletions

View File

@ -8,6 +8,7 @@ add_subdirectory(external/magic_enum)
add_subdirectory(external/argparse)
add_subdirectory(external/log4cxx)
file(GLOB_RECURSE sources src/*.cpp src/*.h)
file(GLOB_RECURSE data resources/*)

8
scripts/raw-to-wav.sh Executable file
View File

@ -0,0 +1,8 @@
#! /bin/sh
set -eux
input_file="$1"
output_file="$2"
sox -r 44100 -e signed-integer -b 16 -c 1 ${input_file} ${output_file}

View File

@ -1,6 +1,6 @@
#! /usr/bin/env python3
from tones import SQUARE_WAVE
from tones import SQUARE_WAVE, SINE_WAVE
from tones.mixer import Mixer
import csv
import math
@ -14,7 +14,8 @@ def frequency_to_midi(frequency):
f = 440 * 2 ^ (n - 69)/12
'''
note = 12 * (math.log(frequency/220)/math.log(2)) + 57
return round(note)
#return round(note)
return note
tones = {}
with open('tones.csv', newline='') as csvfile:
@ -26,6 +27,27 @@ for tone in tones:
print(f"{tone} is MIDI #{frequency_to_midi(tones[tone])}")
mixer = Mixer(44100, 1)
mixer.create_track(0, SQUARE_WAVE)
mixer.create_track(0, SINE_WAVE)
mixer.add_tone(0, frequency=tones[tone], duration=1.0)
mixer.write_wav(f'samples/{tone}.wav')
mixer.write_wav(f'samples/{tone}.wav')
mixer = Mixer(44100, 1)
mixer.create_track(0, SQUARE_WAVE)
mixer.add_tone(0, frequency=440, duration=1.0)
mixer.write_wav(f'samples/MIDI-69-square.wav')
mixer = Mixer(44100, 1)
mixer.create_track(0, SINE_WAVE)
mixer.add_tone(0, frequency=440, duration=1.0)
mixer.write_wav(f'samples/MIDI-69-sine.wav')
mixer = Mixer(44100, 1)
mixer.create_track(0, SQUARE_WAVE)
mixer.add_tone(0, frequency=261.6256, duration=1.0)
mixer.write_wav(f'samples/MIDI-60-square.wav')
mixer = Mixer(44100, 1)
mixer.create_track(0, SINE_WAVE)
mixer.add_tone(0, frequency=261.6256, duration=1.0)
mixer.write_wav(f'samples/MIDI-60-sine.wav')

View File

@ -14,6 +14,14 @@ with open('tones.csv', newline='') as csvfile:
for row in reader:
tones[row['designator']] = float(row['frequency'])
'''
def freq_of_key(midi_key):
return 440.0 * (2 ** ((midi_key - 69)/12))
tones = {}
for c in range(65, 90):
tones[c] = freq_of_key(c)
'''
# Shamelessly lifted from
# https://scipy.github.io/old-wiki/pages/Cookbook/ButterworthBandpass
@ -98,6 +106,14 @@ if __name__ == '__main__':
line = plot.plot(correlation, pen=pg.mkPen(color=color), fillLevel=0.1, name=tone)
legend.addItem(line, tone)
y_max = max(line.getData()[1]) # Maximum y-value
x_max = line.getData()[0][np.argmax(line.getData()[1])] # Corresponding x-coordinate
label = pg.TextItem(html=f'<div style="text-align: center"><span style="color: #FFFFFF; font-size: 12pt;">{line.opts["name"]}</span></div>', anchor=(0.5, 0.5))
plot.addItem(label)
label.setPos(x_max, y_max)
label.setZValue(100) # Ensure label is above other items
plot.setLabel('left', 'Signal Correlation')
plot.setLabel('bottom', 'Time (samples)')
plot.showGrid(x=True, y=True)

BIN
soundfonts/basic.sf2 Normal file

Binary file not shown.

Binary file not shown.

View File

@ -92,6 +92,7 @@ int main(int argc, char** argv) {
Synth synth;
auto tunings = getSelcalTunings();
if (!synth.setTuning(tunings)) {
LOG4CXX_ERROR(logger, "Failed to set SELCAL tuning on synth");
@ -127,7 +128,10 @@ int main(int argc, char** argv) {
SELCAL::Code code{parser.get<std::string>("code")};
for (auto& group : code.getGroups()) {
int midi = static_cast<int>(group[0]);
std::cout << "Playing MIDI " << midi << std::endl;
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(std::chrono::duration<double>(toneDuration));
@ -137,7 +141,17 @@ int main(int argc, char** argv) {
std::this_thread::sleep_for(std::chrono::duration<double>(silenceDuration));
}
/*
for (int i = 65; i < 90; ++i) {
fluid_synth_noteon(raw_synth, 0, i, 80); // Soundfont root key is TWELVE OUT??
std::this_thread::sleep_for(std::chrono::duration<double>(0.1));
// Silence between tone groups
fluid_synth_all_notes_off(raw_synth, ALL_CHANNELS);
std::this_thread::sleep_for(std::chrono::duration<double>(0.01));
}*/
// Wait long enough for the full tone to play before tearing down.
using namespace std::chrono_literals;
std::this_thread::sleep_for(500ms);
//std::this_thread::sleep_for(500ms);
}

View File

@ -14,6 +14,15 @@ Synth::Synth() {
throw new std::runtime_error("Unable to create fluid synth");
}
fluid_settings_setstr(settings, "audio.driver", "file");
fluid_settings_setstr(settings, "audio.file.name", "output.raw");
fluid_settings_setstr(settings, "audio.file.format", "s16");
fluid_settings_setstr(settings, "audio.file.type", "raw");
fluid_settings_setnum(settings, "synth.sample-rate", 44100);
fluid_settings_setnum(settings, "synth.gain", 1.0);
fluid_settings_setint(settings, "synth.chorus.active", 0);
fluid_settings_setint(settings, "synth.reverb.active", 0);
adriver = new_fluid_audio_driver(settings, synth);
if (adriver == nullptr) {
throw new std::runtime_error("Unable to create audio driver");