feat: parse patch files from json

This commit is contained in:
2024-01-18 01:56:00 +07:00
parent f0e2d98c12
commit b996685fe6
13 changed files with 24893 additions and 7 deletions

15
.vscode/settings.json vendored
View File

@@ -64,7 +64,20 @@
"__string": "cpp",
"compare": "cpp",
"concepts": "cpp",
"numeric": "cpp"
"numeric": "cpp",
"__tree": "cpp",
"any": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"fstream": "cpp",
"iomanip": "cpp",
"map": "cpp",
"shared_mutex": "cpp",
"span": "cpp",
"stack": "cpp",
"valarray": "cpp",
"ranges": "cpp",
"iostream": "cpp"
},
"FSharp.suggestGitignore": false,
}

View File

@@ -17,6 +17,10 @@ FetchContent_Declare(
FetchContent_MakeAvailable(raylib)
# Add nlohmann_json
# FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz)
# FetchContent_MakeAvailable(json)
# Adding our source files
file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_LIST_DIR}/src/*.cpp") # Define PROJECT_SOURCES as a list of all source files
set(PROJECT_INCLUDE "${CMAKE_CURRENT_LIST_DIR}/inc/") # Define PROJECT_INCLUDE to be the path to the include directory of the project
@@ -31,6 +35,7 @@ set_target_properties(
target_sources(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCES})
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_INCLUDE})
target_link_libraries(${PROJECT_NAME} PRIVATE raylib)
# target_link_libraries(${PROJECT_NAME} PRIVATE json)
# Setting ASSETS_PATH
target_compile_definitions(${PROJECT_NAME} PUBLIC ASSETS_PATH="${CMAKE_CURRENT_SOURCE_DIR}/assets/") # Set the asset path macro to the absolute path on the dev machine

View File

@@ -18,9 +18,10 @@ class Application {
void InitAudio();
void UpdateOnNoteInput();
void PlayBufferedAudio();
public:
Application(/* args */);
~Application();
void Run();
void ParsePatch(std::string file_path);
};

View File

@@ -29,6 +29,7 @@ class Oscillator {
~Oscillator();
OscillatorType GetType() { return m_osc; }
void SetType(OscillatorType osc);
void SetType(std::string const& osc_name);
float GetVolume() { return m_volume; }
void SetVolume(float volume) { m_volume = volume; }
float GetKey() { return m_key; }

View File

@@ -17,6 +17,7 @@ class Synth {
std::vector<IEffect*> m_effects;
std::vector<float> m_out_signal;
LFO* m_lfo;
float m_lfo_level;
void ZeroSignal();
void GetNote();
void TriggerNoteOnEffects();
@@ -36,5 +37,8 @@ class Synth {
const bool& GetIsNoteTriggered() { return is_note_triggered; }
ADSR* GetADSR() { return (ADSR*)m_effects[0]; }
Filter* GetFilter() { return (Filter*)m_effects[1]; }
LFO* GetLFO() { return m_lfo; }
const float& GetLFOLevel() { return m_lfo_level; }
void SetLFOLevel(float lvl) { assert(0.f >= lvl <= 1.f); m_lfo_level = lvl; }
void SetFilter(FilterType type);
};

View File

@@ -1,6 +1,6 @@
#pragma once
#include "OscillatorType.h"
#include "raygui.h"
#include "raysan/raygui.h"
#include <vector>
#include "Filter.h"

24765
inc/nlohmann/json.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,10 @@
#include "Logger.h"
#include "Settings.h"
#include <string>
#include <fstream> //read file
#include <cmath> // log10f
#include <nlohmann/json.hpp>
using json = nlohmann::json;
Application::Application(/* args */) {
InitSynth();
@@ -118,3 +122,33 @@ void Application::Run() {
m_renderer.Draw(m_synth, m_synth_gui_state);
}
}
void Application::ParsePatch(std::string file_path) {
std::ifstream f(file_path);
json data = json::parse(f);
auto oscillators = m_synth.GetOscillators();
for (int i = 0; i < oscillators.size(); i++) {
auto osc = oscillators[i];
osc->SetType(data["Oscillators"][i]["Wave"].template get<std::string>());
osc->SetVolume(data["Oscillators"][i]["Volume"].template get<float>());
osc->SetFine(data["Oscillators"][i]["Tune"].template get<float>());
}
auto adsr = m_synth.GetADSR();
auto adsr_params = data["ADSR"];
adsr->SetParameters(adsr_params["Attack"].template get<float>(),
adsr_params["Decay"].template get<float>(),
adsr_params["Sustain"].template get<float>(),
adsr_params["Release"].template get<float>());
auto lfo = m_synth.GetLFO();
lfo->SetFreq(data["LFO"]["Freq"].template get<float>());
m_synth.SetLFOLevel(data["LFO"]["Level"].template get<float>());
m_synth.SetFilter((FilterType)data["Filter"]["Cutoff"].template get<int>());
auto filter = m_synth.GetFilter();
filter->SetParameters(std::log10f(data["Filter"]["Cutoff"].template get<float>()),
data["Filter"]["Res"].template get<float>(),
data["Filter"]["Drive"].template get<float>());
}

View File

@@ -43,6 +43,19 @@ void Oscillator::SetType(OscillatorType osc) {
}
}
void Oscillator::SetType(std::string const& osc_name) {
if (osc_name == "Sine")
m_osc = Sine;
else if (osc_name == "Triangle")
m_osc = Triangle;
else if (osc_name == "Saw")
m_osc = Saw;
else if (osc_name == "Square")
m_osc = Square;
SetType(m_osc);
}
void Oscillator::SetKey(float key) {
m_key = key;
float freq = KeyBoard::GetHzBySemitone(m_key + m_fine);

View File

@@ -7,7 +7,7 @@
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
#pragma clang diagnostic ignored "-Wunused-variable"
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#include "raygui.h"
#include "raysan/raygui.h"
#pragma clang diagnostic pop
Renderer::Renderer(/* args */) {

View File

@@ -1,7 +1,57 @@
#include "Application.h"
#include <string_view>
#include <vector>
#include <string>
#include <iostream>
inline bool file_exists(const std::string& name) {
if (FILE *file = fopen(name.c_str(), "r")) {
fclose(file);
return true;
} else {
return false;
}
}
[[noreturn]] void print_help(char* const executable) {
std::cout << executable << " [options]\n" <<
"Options:\n" <<
" -h | --help Print this help\n" <<
" -p | --patch Path to a json file with a patch to apply\n" <<
" -v | --version Print a program version" << std::endl;
std::exit(0);
}
int main(int argc, char* argv[]) {
if (argc > 32) {
throw std::runtime_error("Too many input parameters!");
}
std::string patch_file_path;
for (int i = 0; i < argc; i++) {
auto arg = std::string(argv[i]);
if (arg == "-p" || arg == "--patch") {
patch_file_path = std::string(argv[i+1]);
if (patch_file_path.empty()) {
std::cerr << "no file path provided\n";
print_help(argv[0]);
}
else if (!file_exists(patch_file_path)) {
std::cerr << patch_file_path << ": no such file\n";
print_help(argv[0]);
}
}
else if (arg == "-h" || arg == "--help") {
print_help(argv[0]);
}
}
int main() {
Application* app = new Application();
if (!patch_file_path.empty()) {
app->ParsePatch(patch_file_path);
}
app->Run();
delete app;

View File

@@ -7,7 +7,7 @@
Synth::Synth(/* args */) {
m_lfo = new LFO();
m_lfo->SetFreq(5.0);
m_lfo->SetFreq(2.0);
AddOscillator();
AddOscillator();
AddEffect(new ADSR());
@@ -79,7 +79,7 @@ void Synth::ApplyFilterLfo() {
float dt = m_lfo->Process();
Filter* filter = (Filter*)m_effects[1];
float freq = filter->GetFreq();
filter->SetParameters(freq + dt, filter->GetRes(), filter->GetPeakGain());
filter->SetParameters(freq + dt*0.5f, filter->GetRes(), filter->GetPeakGain());
}
void Synth::Process() {