From 5e347f7f134254381b2acadf9ceb56212de3a30d Mon Sep 17 00:00:00 2001 From: Dave Griffiths Date: Fri, 14 Oct 2022 18:27:59 +0100 Subject: [PATCH 1/4] made the 3 osc ports configurable via (cross-platform) config scripts and move them outside of well used ranges for UDP --- app/MainWindow.cpp | 10 +- app/MainWindow.h | 593 ++++++++++++++-------------- app/audio_thread.cpp | 11 +- app/audio_thread.h | 4 +- app/feedback.h | 3 +- app/process_thread.cpp | 4 +- app/process_thread.h | 13 +- app/qtmain.cpp | 48 ++- brain/src/spiralcore/OSC_server.cpp | 188 +++++---- brain/src/spiralcore/OSC_server.h | 25 +- brain/src/status.cpp | 4 + brain/src/status.h | 1 + 12 files changed, 472 insertions(+), 432 deletions(-) diff --git a/app/MainWindow.cpp b/app/MainWindow.cpp index 8a0555f..2b0da8e 100644 --- a/app/MainWindow.cpp +++ b/app/MainWindow.cpp @@ -27,9 +27,11 @@ using namespace std; -MainWindow::MainWindow() : +MainWindow::MainWindow(const string &port, const string &audio_port, const string &process_port) : m_last_file("."), - m_feedback("8890") + m_feedback(port), + m_audio_port(audio_port), + m_process_port(process_port) { m_sound_item_enable_mapper = new QSignalMapper(this); m_sound_item_delete_mapper = new QSignalMapper(this); @@ -59,8 +61,8 @@ MainWindow::MainWindow() : for (int i=0; i<10; i++) { osc_destination d; d.m_id=i; - d.m_audio_address = lo_address_new_from_url("osc.udp://localhost:8888"); - d.m_process_address = lo_address_new_from_url("osc.udp://localhost:8889"); + d.m_audio_address = lo_address_new_from_url(string("osc.udp://localhost:"+m_audio_port).c_str()); + d.m_process_address = lo_address_new_from_url(string("osc.udp://localhost:"+m_process_port).c_str()); if (i==0) d.m_enabled=true; else d.m_enabled=false; add_gui_address(d,enable_mapper); diff --git a/app/MainWindow.h b/app/MainWindow.h index 14d05c4..f68cc3c 100644 --- a/app/MainWindow.h +++ b/app/MainWindow.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "ui_samplebrain.h" #include "SettingsDialog.h" @@ -34,11 +35,19 @@ using namespace spiralcore; class MainWindow : public QMainWindow { - Q_OBJECT + Q_OBJECT public: - MainWindow(); + MainWindow(const string &port, const string &audio_port, const string &process_port); + void message(const string &msg) { + QMessageBox::information(this,"problem",msg.c_str(), QMessageBox::Ok); + } + + bool ok() { + return m_feedback.ok(); + } + // all this to work around liblo's use of varargs... void send_audio_osc(const char *name, const char *types) { for (auto dest:m_destinations) { @@ -102,344 +111,346 @@ protected: private slots: - void play_slot() { send_audio_osc("/start",""); } - void stop_slot() { send_audio_osc("/pause",""); } + void play_slot() { send_audio_osc("/start",""); } + void stop_slot() { send_audio_osc("/pause",""); } - void ratio_slot(int s) { - send_audio_osc("/ratio","f",s/100.0f); - m_Ui.doubleSpinBoxRatio->setValue(s/100.0f); - } - void ratio_slot(double s) { - send_audio_osc("/ratio","f",s); - m_Ui.sliderRatio->setValue(s*100); - } + void ratio_slot(int s) { + send_audio_osc("/ratio","f",s/100.0f); + m_Ui.doubleSpinBoxRatio->setValue(s/100.0f); + } + void ratio_slot(double s) { + send_audio_osc("/ratio","f",s); + m_Ui.sliderRatio->setValue(s*100); + } - void n_ratio_slot(int s) { - send_audio_osc("/n_ratio","f",s/100.0f); - m_Ui.doubleSpinBoxNRatio->setValue(s/100.0f); - } - void n_ratio_slot(double s) { - send_audio_osc("/n_ratio","f",s); - m_Ui.sliderNRatio->setValue(s*100); - } + void n_ratio_slot(int s) { + send_audio_osc("/n_ratio","f",s/100.0f); + m_Ui.doubleSpinBoxNRatio->setValue(s/100.0f); + } + void n_ratio_slot(double s) { + send_audio_osc("/n_ratio","f",s); + m_Ui.sliderNRatio->setValue(s*100); + } - void autotune(int s) { - send_audio_osc("/autotune","f",s/100.0f); - m_Ui.doubleSpinBoxAutotune->setValue(s/100.0f); - } - void autotune(double s) { - send_audio_osc("/autotune","f",s); - m_Ui.sliderAutotune->setValue(s*100); - } + void autotune(int s) { + send_audio_osc("/autotune","f",s/100.0f); + m_Ui.doubleSpinBoxAutotune->setValue(s/100.0f); + } + void autotune(double s) { + send_audio_osc("/autotune","f",s); + m_Ui.sliderAutotune->setValue(s*100); + } - void fft1_start_slot(int s) { send_audio_osc("/fft1_start","i",s); } - void fft1_end_slot(int s) { send_audio_osc("/fft1_end","i",s); } - void fft2_start_slot(int s){} // { m_renderer->get_params()->m_fft2_start=s; } - void fft2_end_slot(int s){} // { m_renderer->get_params()->m_fft2_end=s; } + void fft1_start_slot(int s) { send_audio_osc("/fft1_start","i",s); } + void fft1_end_slot(int s) { send_audio_osc("/fft1_end","i",s); } + void fft2_start_slot(int s){} // { m_renderer->get_params()->m_fft2_start=s; } + void fft2_end_slot(int s){} // { m_renderer->get_params()->m_fft2_end=s; } - void n_mix_slot(int s) { - send_audio_osc("/n_mix","f",s/100.0f); - m_Ui.doubleSpinBoxNMix->setValue(s/100.0f); - } - void n_mix_slot(double s) { - send_audio_osc("/n_mix","f",s); - m_Ui.sliderNMix->setValue(s*100); - } + void n_mix_slot(int s) { + send_audio_osc("/n_mix","f",s/100.0f); + m_Ui.doubleSpinBoxNMix->setValue(s/100.0f); + } + void n_mix_slot(double s) { + send_audio_osc("/n_mix","f",s); + m_Ui.sliderNMix->setValue(s*100); + } - void novelty_slot(int s) { - send_audio_osc("/novelty","f",s/100.0f); - m_Ui.doubleSpinBoxNovelty->setValue(s/100.0f); - } - void novelty_slot(double s) { - send_audio_osc("/novelty","f",s); - m_Ui.sliderNovelty->setValue(s*100); - } + void novelty_slot(int s) { + send_audio_osc("/novelty","f",s/100.0f); + m_Ui.doubleSpinBoxNovelty->setValue(s/100.0f); + } + void novelty_slot(double s) { + send_audio_osc("/novelty","f",s); + m_Ui.sliderNovelty->setValue(s*100); + } - void boredom_slot(int s) { - float v=s/100.0f; - send_audio_osc("/boredom","f",v); - m_Ui.doubleSpinBoxBoredom->setValue(v); - } - void boredom_slot(double s) { - send_audio_osc("/boredom","f",s); - m_Ui.sliderBoredom->setValue(s*100); - } - void synapses(int s) { - send_audio_osc("/synapses","i",s); - } - void target_mix_slot(int s) { - send_audio_osc("/target_mix","f",s/100.0f); - m_Ui.doubleSpinBoxTargetMix->setValue(s/100.0f); - } - void target_mix_slot(double s) { - send_audio_osc("/target_mix","f",s); - m_Ui.sliderTargetMix->setValue(s*100); - } - void search_stretch(int s) { - send_audio_osc("/search-stretch","i",s); - } - void slide_error(int s) { - send_audio_osc("/slide-error","i",s); - } - void stickyness_slot(int s) { - send_audio_osc("/stickyness","f",s/100.0f); - m_Ui.doubleSpinBoxStickyness->setValue(s/100.0f); - } - void stickyness_slot(double s) { - send_audio_osc("/stickyness","f",s); - m_Ui.sliderStickyness->setValue(s*100); - } + void boredom_slot(int s) { + float v=s/100.0f; + send_audio_osc("/boredom","f",v); + m_Ui.doubleSpinBoxBoredom->setValue(v); + } + void boredom_slot(double s) { + send_audio_osc("/boredom","f",s); + m_Ui.sliderBoredom->setValue(s*100); + } + void synapses(int s) { + send_audio_osc("/synapses","i",s); + } + void target_mix_slot(int s) { + send_audio_osc("/target_mix","f",s/100.0f); + m_Ui.doubleSpinBoxTargetMix->setValue(s/100.0f); + } + void target_mix_slot(double s) { + send_audio_osc("/target_mix","f",s); + m_Ui.sliderTargetMix->setValue(s*100); + } + void search_stretch(int s) { + send_audio_osc("/search-stretch","i",s); + } + void slide_error(int s) { + send_audio_osc("/slide-error","i",s); + } + void stickyness_slot(int s) { + send_audio_osc("/stickyness","f",s/100.0f); + m_Ui.doubleSpinBoxStickyness->setValue(s/100.0f); + } + void stickyness_slot(double s) { + send_audio_osc("/stickyness","f",s); + m_Ui.sliderStickyness->setValue(s*100); + } - void volume_slot(int s) { send_audio_osc("/volume","f",s/100.0f); } - void algo(int n) { send_audio_osc("/search_algo","i",n); } + void volume_slot(int s) { send_audio_osc("/volume","f",s/100.0f); } + void algo(int n) { send_audio_osc("/search_algo","i",n); } - void run_slot() {} - void load_target() { - m_last_file=QFileDialog::getOpenFileName( - this, - QString("Select an wav file"), - m_last_file, - QString("Sounds (*.wav)")); + void run_slot() {} + void load_target() { + m_last_file=QFileDialog::getOpenFileName( + this, + QString("Select an wav file"), + m_last_file, + QString("Sounds (*.wav)")); - send_process_osc("/load_target","s",m_last_file.toStdString().c_str()); - } - void target_block_size(int s) { send_process_osc("/target_block_size","i",s); } - void target_block_overlap(double s) { send_process_osc("/target_overlap","f",s); } - void generate_target_blocks() { send_process_osc("/generate_target",""); } - void block_size(int s) { send_process_osc("/source_block_size","i",s); } - void block_overlap(double s) { send_process_osc("/source_overlap","f",s); } - void fft_spectrum_size(int) {} - void generate() { send_process_osc("/generate_brain",""); } - void load_sound() { - m_last_file=QFileDialog::getOpenFileName( - this, - QString("Select a wav file"), - m_last_file, - QString("Sounds (*.wav)")); + send_process_osc("/load_target","s",m_last_file.toStdString().c_str()); + } + void target_block_size(int s) { send_process_osc("/target_block_size","i",s); } + void target_block_overlap(double s) { send_process_osc("/target_overlap","f",s); } + void generate_target_blocks() { send_process_osc("/generate_target",""); } + void block_size(int s) { send_process_osc("/source_block_size","i",s); } + void block_overlap(double s) { send_process_osc("/source_overlap","f",s); } + void fft_spectrum_size(int) {} + void generate() { send_process_osc("/generate_brain",""); } + void load_sound() { + m_last_file=QFileDialog::getOpenFileName( + this, + QString("Select a wav file"), + m_last_file, + QString("Sounds (*.wav)")); - send_process_osc("/load_sample","s",m_last_file.toStdString().c_str()); + send_process_osc("/load_sample","s",m_last_file.toStdString().c_str()); - sound_items::sound_item &si = m_sound_items.add(m_Ui.brain_contents, m_last_file.toStdString(),true); + sound_items::sound_item &si = m_sound_items.add(m_Ui.brain_contents, m_last_file.toStdString(),true); + + QObject::connect(si.m_enable, SIGNAL(clicked()), m_sound_item_enable_mapper, SLOT(map())); + m_sound_item_enable_mapper->setMapping(si.m_enable, si.m_id); + QObject::connect(si.m_del, SIGNAL(clicked()), m_sound_item_delete_mapper, SLOT(map())); + m_sound_item_delete_mapper->setMapping(si.m_del, si.m_id); + } + + + void load_sounds() { + m_last_file=QFileDialog::getExistingDirectory(this, + QString("Select a directory"), + m_last_file); + + + QDirIterator dirIt(m_last_file,QDirIterator::Subdirectories); + while (dirIt.hasNext()) { + dirIt.next(); + if (QFileInfo(dirIt.filePath()).isFile() && + QFileInfo(dirIt.filePath()).suffix() == "wav") { + send_process_osc("/load_sample","s",dirIt.filePath().toStdString().c_str()); + + sound_items::sound_item &si = m_sound_items.add(m_Ui.brain_contents, dirIt.filePath().toStdString(),true); QObject::connect(si.m_enable, SIGNAL(clicked()), m_sound_item_enable_mapper, SLOT(map())); m_sound_item_enable_mapper->setMapping(si.m_enable, si.m_id); QObject::connect(si.m_del, SIGNAL(clicked()), m_sound_item_delete_mapper, SLOT(map())); m_sound_item_delete_mapper->setMapping(si.m_del, si.m_id); + + } } + } + void select_all() { + for (auto &si:m_sound_items.m_sound_items) { + si.m_enable->setChecked(true); + send_process_osc("/activate_sound","s",si.m_filename.c_str()); + } + } - void load_sounds() { - m_last_file=QFileDialog::getExistingDirectory(this, - QString("Select a directory"), - m_last_file); + void select_none() { + for (auto &si:m_sound_items.m_sound_items) { + si.m_enable->setChecked(false); + send_process_osc("/deactivate_sound","s",si.m_filename.c_str()); + } + } - - QDirIterator dirIt(m_last_file,QDirIterator::Subdirectories); - while (dirIt.hasNext()) { - dirIt.next(); - if (QFileInfo(dirIt.filePath()).isFile() && - QFileInfo(dirIt.filePath()).suffix() == "wav") { - send_process_osc("/load_sample","s",dirIt.filePath().toStdString().c_str()); - - sound_items::sound_item &si = m_sound_items.add(m_Ui.brain_contents, dirIt.filePath().toStdString(),true); - - QObject::connect(si.m_enable, SIGNAL(clicked()), m_sound_item_enable_mapper, SLOT(map())); - m_sound_item_enable_mapper->setMapping(si.m_enable, si.m_id); - QObject::connect(si.m_del, SIGNAL(clicked()), m_sound_item_delete_mapper, SLOT(map())); - m_sound_item_delete_mapper->setMapping(si.m_del, si.m_id); - - } - } - } - - void select_all() { - for (auto &si:m_sound_items.m_sound_items) { - si.m_enable->setChecked(true); - send_process_osc("/activate_sound","s",si.m_filename.c_str()); - } - } - - void select_none() { - for (auto &si:m_sound_items.m_sound_items) { - si.m_enable->setChecked(false); - send_process_osc("/deactivate_sound","s",si.m_filename.c_str()); - } - } - - void sound_enable(int id) { - // search for this id... - for (auto &si:m_sound_items.m_sound_items) { - if (si.m_id==id) { - if (si.m_enable->isChecked()) { - send_process_osc("/activate_sound","s",si.m_filename.c_str()); - } else { - send_process_osc("/deactivate_sound","s",si.m_filename.c_str()); - } + void sound_enable(int id) { + // search for this id... + for (auto &si:m_sound_items.m_sound_items) { + if (si.m_id==id) { + if (si.m_enable->isChecked()) { + send_process_osc("/activate_sound","s",si.m_filename.c_str()); + } else { + send_process_osc("/deactivate_sound","s",si.m_filename.c_str()); } } } + } - void delete_sound(int id) { - // search for this id... - for (auto &si:m_sound_items.m_sound_items) { - if (si.m_id==id) { - send_process_osc("/delete_sample","s",si.m_filename.c_str()); - m_sound_items.remove(si.m_filename); - // iterator is now invalidated... - return; - } - } - } - void clear_brain() { - for (auto &si:m_sound_items.m_sound_items) { + void delete_sound(int id) { + // search for this id... + for (auto &si:m_sound_items.m_sound_items) { + if (si.m_id==id) { send_process_osc("/delete_sample","s",si.m_filename.c_str()); + m_sound_items.remove(si.m_filename); + // iterator is now invalidated... + return; } - m_sound_items.clear(); } - void restart_audio() { send_audio_osc("/restart_audio",""); } - - void brain_shape(int n) { send_process_osc("/window_type","i",n); } - void target_shape(int n) { send_process_osc("/target_window_type","i",n); } - void mic(bool n) { send_audio_osc("/mic","i",(int)n); } - - void record() { - if (m_save_wav=="") { - m_last_file=QFileDialog::getSaveFileName( - this, - QString("Select a wav file"), - m_last_file, - QString("Sounds (*.wav)")); - m_save_wav = m_last_file.toStdString(); - // chop off .wav - size_t pos = m_save_wav.find_last_of("."); - if (pos!=string::npos) { - m_save_wav = m_save_wav.substr(0,pos); - } - - } - - char fn[1024]; - snprintf(fn,1024,"%s-%i",m_save_wav.c_str(),m_record_id); - send_audio_osc("/record","s",fn); - cerr<isChecked()) { - // reconnect - string url = d.m_address->text().toUtf8().constData(); - lo_address_free(d.m_audio_address); - lo_address_free(d.m_process_address); - d.m_audio_address = lo_address_new_from_url(string(url+":8888").c_str()); - d.m_process_address = lo_address_new_from_url(string(url+":8889").c_str()); - // start sending messages here - d.m_enabled=true; - } else { - // stop sending messages here - d.m_enabled=false; + void record() { + if (m_save_wav=="") { + m_last_file=QFileDialog::getSaveFileName( + this, + QString("Select a wav file"), + m_last_file, + QString("Sounds (*.wav)")); + m_save_wav = m_last_file.toStdString(); + // chop off .wav + size_t pos = m_save_wav.find_last_of("."); + if (pos!=string::npos) { + m_save_wav = m_save_wav.substr(0,pos); } } + char fn[1024]; + snprintf(fn,1024,"%s-%i",m_save_wav.c_str(),m_record_id); + send_audio_osc("/record","s",fn); + cerr<isChecked()) { + // reconnect + string url = d.m_address->text().toUtf8().constData(); + lo_address_free(d.m_audio_address); + lo_address_free(d.m_process_address); + d.m_audio_address = lo_address_new_from_url(string(url+":"+m_audio_port).c_str()); + d.m_process_address = lo_address_new_from_url(string(url+":"+m_process_port).c_str()); + // start sending messages here + d.m_enabled=true; + } else { + // stop sending messages here + d.m_enabled=false; + } + + } + void settings() { m_settings_dialog->show(); } private: - /////////////////////////////////////////////// + /////////////////////////////////////////////// - // we want to be able to send out to - // multiple addresses over the network + // we want to be able to send out to + // multiple addresses over the network - //////////////////////////////////////////////// + //////////////////////////////////////////////// - // we want to be able to send out to - // multiple addresses over the network - class osc_destination { - public: - int m_id; - lo_address m_audio_address; - lo_address m_process_address; - // can't find a way to address these via qt - QLineEdit *m_address; - QCheckBox *m_enable; - bool m_enabled; - }; + // we want to be able to send out to + // multiple addresses over the network + class osc_destination { + public: + int m_id; + lo_address m_audio_address; + lo_address m_process_address; + // can't find a way to address these via qt + QLineEdit *m_address; + QCheckBox *m_enable; + bool m_enabled; + }; - vector m_destinations; + vector m_destinations; - void init_from_session(const string &filename); - void add_gui_address(osc_destination &dest, - QSignalMapper* enable_mapper); + void init_from_session(const string &filename); + void add_gui_address(osc_destination &dest, + QSignalMapper* enable_mapper); - string m_save_wav; - QString m_last_file; - unsigned int m_record_id; - Ui_MainWindow m_Ui; - feedback m_feedback; - QSignalMapper* m_sound_item_enable_mapper; - QSignalMapper* m_sound_item_delete_mapper; - sound_items m_sound_items; + string m_save_wav; + QString m_last_file; + unsigned int m_record_id; + Ui_MainWindow m_Ui; + feedback m_feedback; + QSignalMapper* m_sound_item_enable_mapper; + QSignalMapper* m_sound_item_delete_mapper; + sound_items m_sound_items; - SettingsDialog *m_settings_dialog; + SettingsDialog *m_settings_dialog; audio_thread *m_audio_thread; - + + string m_audio_port; + string m_process_port; }; diff --git a/app/audio_thread.cpp b/app/audio_thread.cpp index 1d51bcf..7da0aa0 100644 --- a/app/audio_thread.cpp +++ b/app/audio_thread.cpp @@ -20,26 +20,23 @@ using namespace spiralcore; using namespace std; -audio_thread::audio_thread(process_thread &p) : +audio_thread::audio_thread(const string &port, process_thread &p) : m_audio_device(NULL), - m_osc("8888"), + m_osc(port), m_process_thread(p), m_brain_mutex(p.m_brain_mutex), m_stereo_mode(false), m_mic_mode(false), m_bufsize(2048), m_samplerate(44100), - m_device("") -{ - // start_audio(); + m_device("") { + pthread_mutex_lock(m_brain_mutex); m_left_renderer = new renderer(p.m_source,p.m_left_target); m_right_renderer = new renderer(p.m_source,p.m_right_target); m_block_stream = new block_stream(); pthread_mutex_unlock(m_brain_mutex); m_osc.run(); - // it this threadsafe? - // m_audio_device->report_devices(); } static bool state = 1; diff --git a/app/audio_thread.h b/app/audio_thread.h index bcee447..66ccd40 100644 --- a/app/audio_thread.h +++ b/app/audio_thread.h @@ -26,12 +26,12 @@ namespace spiralcore { class audio_thread { public: - audio_thread(process_thread &p); + audio_thread(const string &port, process_thread &p); ~audio_thread(); void start_audio(); void restart_audio(const string device, unsigned int samplerate, unsigned int bufsize); - + bool ok() { return m_osc.ok(); } void process(sample &left_in, sample &right_in, sample &left_out, sample &right_out); static void run_audio(void* c, unsigned int frames); diff --git a/app/feedback.h b/app/feedback.h index 4de48d8..1c52949 100644 --- a/app/feedback.h +++ b/app/feedback.h @@ -29,7 +29,8 @@ class feedback { public: feedback(std::string address); void poll(QStatusBar *s, sound_items *sound_items, SettingsDialog *settings); - + bool ok() { return m_osc.ok(); } + private: OSC_server m_osc; diff --git a/app/process_thread.cpp b/app/process_thread.cpp index 8208b5b..d09e127 100644 --- a/app/process_thread.cpp +++ b/app/process_thread.cpp @@ -32,8 +32,8 @@ static void* _process(void *c) { return NULL; } -process_thread::process_thread() : - m_osc("8889"), +process_thread::process_thread(const string &port) : + m_osc(port), m_source_block_size(1000), m_source_overlap(0.75), m_target_block_size(1000), diff --git a/app/process_thread.h b/app/process_thread.h index 7464f45..8523d69 100644 --- a/app/process_thread.h +++ b/app/process_thread.h @@ -25,9 +25,9 @@ namespace spiralcore { -class process_thread { -public: - process_thread(); + class process_thread { + public: + process_thread(const string &port); ~process_thread(); pthread_mutex_t* m_brain_mutex; @@ -47,10 +47,13 @@ public: void load_session(const std::string &filename); void save_session(const std::string &filename); + + bool ok() { return m_osc.ok(); } + // only for use in mutex brain m_source, m_left_target, m_right_target; -private: + private: OSC_server m_osc; u32 m_source_block_size; float m_source_overlap; @@ -64,6 +67,6 @@ private: renderer *m_left_renderer; renderer *m_right_renderer; block_stream *m_block_stream; -}; + }; } diff --git a/app/qtmain.cpp b/app/qtmain.cpp index c505db3..f2c5cdb 100644 --- a/app/qtmain.cpp +++ b/app/qtmain.cpp @@ -19,22 +19,54 @@ #include #include #include +#include + #include "MainWindow.h" #include "process_thread.h" #include "audio_thread.h" +#include "status.h" using namespace std; int main( int argc , char *argv[] ){ - QApplication app(argc, argv); - MainWindow mainWin; - mainWin.show(); - process_thread pt; - audio_thread at(pt); - pt.register_renderer(at.m_left_renderer, at.m_right_renderer, at.m_block_stream); - mainWin.set_audio_thread(&at); + + QApplication app(argc, argv); + + QSettings settings("thentrythis", "samplebrain"); - return app.exec(); + // slight over-use of OSC servers here, but the are packaged nicely for + // threadsafe (nonblocking) communication, and it's useful to expose all + // moving parts for external control (i.e. the processing and the audio) + + if (!settings.contains("gui_port")) settings.setValue("gui_port", "62345"); + if (!settings.contains("audio_port")) settings.setValue("audio_port", "62346"); + if (!settings.contains("process_port")) settings.setValue("process_port", "62347"); + + string gui_port = settings.value("gui_port").toByteArray().constData(); + string audio_port = settings.value("audio_port").toByteArray().constData(); + string process_port = settings.value("process_port").toByteArray().constData(); + + status::set_port(gui_port); + + MainWindow mainWin(gui_port,audio_port,process_port); + mainWin.show(); + process_thread pt(process_port); + audio_thread at(audio_port,pt); + + pt.register_renderer(at.m_left_renderer, at.m_right_renderer, at.m_block_stream); + mainWin.set_audio_thread(&at); + + if (!at.ok()) { + mainWin.message("problem starting audio thread on port "+audio_port); + } + if (!pt.ok()) { + mainWin.message("problem starting process thread on port "+process_port); + } + if (!mainWin.ok()) { + mainWin.message("problem starting gui thread on port "+gui_port); + } + + return app.exec(); } diff --git a/brain/src/spiralcore/OSC_server.cpp b/brain/src/spiralcore/OSC_server.cpp index cfd1590..e37fa4a 100644 --- a/brain/src/spiralcore/OSC_server.cpp +++ b/brain/src/spiralcore/OSC_server.cpp @@ -31,117 +31,105 @@ extern "C" { #endif OSC_server::OSC_server(const string &port) : -m_port(port), -m_exit(false), -m_command_ring_buffer(262144) -{ - //cerr<<"using port: ["<COMMAND_DATA_SIZE) - { - cerr<<"osc data too big for ringbuffer command"<COMMAND_DATA_SIZE) - { - cerr<<"osc data too big for ringbuffer command"<s); - - if (pos+size+1>COMMAND_DATA_SIZE) - { - cerr<<"osc data too big for ringbuffer command"<s,size); - newdata[pos+size]='\0'; - pos+=size+1; - } - break; - default: - { - cerr<<"unsupported type: "<m_command_ring_buffer.send(command)) - { - //cerr<<"OSC_server - ringbuffer full!"<COMMAND_DATA_SIZE) { + cerr<<"osc data too big for ringbuffer command"<COMMAND_DATA_SIZE) { + cerr<<"osc data too big for ringbuffer command"<s); + + if (pos+size+1>COMMAND_DATA_SIZE) { + cerr<<"osc data too big for ringbuffer command"<s,size); + newdata[pos+size]='\0'; + pos+=size+1; + } + break; + default: { + cerr<<"unsupported type: "<m_command_ring_buffer.send(command)) { + //cerr<<"OSC_server - ringbuffer full!"< Date: Fri, 14 Oct 2022 19:23:07 +0100 Subject: [PATCH 2/4] added osc ports to the settings interface, bumped the version num --- app/MainWindow.cpp | 4 +- app/MainWindow.h | 7 +- app/SettingsDialog.cpp | 8 +- app/SettingsDialog.h | 26 +++- app/qtmain.cpp | 2 +- brain/src/spiralcore/OSC_server.cpp | 7 +- gui/samplebrain.ui | 2 +- gui/settings.ui | 197 ++++++++++++++++++++++++++-- 8 files changed, 224 insertions(+), 29 deletions(-) diff --git a/app/MainWindow.cpp b/app/MainWindow.cpp index 2b0da8e..5e0eb52 100644 --- a/app/MainWindow.cpp +++ b/app/MainWindow.cpp @@ -27,7 +27,7 @@ using namespace std; -MainWindow::MainWindow(const string &port, const string &audio_port, const string &process_port) : +MainWindow::MainWindow(const string &port, const string &audio_port, const string &process_port, QSettings *settings) : m_last_file("."), m_feedback(port), m_audio_port(audio_port), @@ -51,7 +51,7 @@ MainWindow::MainWindow(const string &port, const string &audio_port, const strin m_Ui.brain_contents->setSpacing(0); m_Ui.brain_contents->setContentsMargins(0,0,0,0); - m_settings_dialog = new SettingsDialog(this); + m_settings_dialog = new SettingsDialog(this,settings); // add default local dest // turn on first one diff --git a/app/MainWindow.h b/app/MainWindow.h index f68cc3c..7500cdb 100644 --- a/app/MainWindow.h +++ b/app/MainWindow.h @@ -33,13 +33,15 @@ using namespace std; using namespace spiralcore; +class QSettings; + class MainWindow : public QMainWindow { Q_OBJECT public: - MainWindow(const string &port, const string &audio_port, const string &process_port); - + MainWindow(const string &port, const string &audio_port, const string &process_port, QSettings *settings); + void message(const string &msg) { QMessageBox::information(this,"problem",msg.c_str(), QMessageBox::Ok); } @@ -453,4 +455,5 @@ private: string m_audio_port; string m_process_port; + }; diff --git a/app/SettingsDialog.cpp b/app/SettingsDialog.cpp index a2edf7b..d6e0cd5 100644 --- a/app/SettingsDialog.cpp +++ b/app/SettingsDialog.cpp @@ -24,12 +24,16 @@ using namespace std; -SettingsDialog::SettingsDialog(MainWindow *parent): +SettingsDialog::SettingsDialog(MainWindow *parent, QSettings *settings): m_device(""), m_parent(parent), m_buffersize(2048), - m_samplerate(44100) { + m_samplerate(44100), + m_settings(settings) { m_Ui.setupUi(this); + m_Ui.guiOSCLineEdit->setText(settings->value("gui_port").toByteArray().constData()); + m_Ui.processOSCLineEdit->setText(settings->value("process_port").toByteArray().constData()); + m_Ui.audioOSCLineEdit->setText(settings->value("audio_port").toByteArray().constData()); } void SettingsDialog::connect() { diff --git a/app/SettingsDialog.h b/app/SettingsDialog.h index df5248f..225e188 100644 --- a/app/SettingsDialog.h +++ b/app/SettingsDialog.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "ui_settings.h" #include @@ -36,7 +37,7 @@ class SettingsDialog : public QDialog { Q_OBJECT public: - SettingsDialog(MainWindow *parent); + SettingsDialog(MainWindow *parent, QSettings *settings); Ui_SettingsDialog m_Ui; string m_device; @@ -61,15 +62,28 @@ class SettingsDialog : public QDialog void accept() { connect(); hide(); } void reject() { hide(); } void apply() { connect(); } - + + void gui_port(QString str) { + m_settings->setValue("gui_port",str); + } + + void process_port(QString str) { + m_settings->setValue("process_port",str); + } + + void audio_port(QString str) { + m_settings->setValue("audio_port",str); + } + private: - void connect(); - MainWindow *m_parent; + void connect(); + MainWindow *m_parent; - unsigned int m_buffersize; - unsigned int m_samplerate; + unsigned int m_buffersize; + unsigned int m_samplerate; + QSettings *m_settings; }; #endif diff --git a/app/qtmain.cpp b/app/qtmain.cpp index f2c5cdb..a0573c1 100644 --- a/app/qtmain.cpp +++ b/app/qtmain.cpp @@ -50,7 +50,7 @@ int main( int argc , char *argv[] ){ status::set_port(gui_port); - MainWindow mainWin(gui_port,audio_port,process_port); + MainWindow mainWin(gui_port,audio_port,process_port,&settings); mainWin.show(); process_thread pt(process_port); audio_thread at(audio_port,pt); diff --git a/brain/src/spiralcore/OSC_server.cpp b/brain/src/spiralcore/OSC_server.cpp index e37fa4a..523e17f 100644 --- a/brain/src/spiralcore/OSC_server.cpp +++ b/brain/src/spiralcore/OSC_server.cpp @@ -34,11 +34,12 @@ OSC_server::OSC_server(const string &port) : m_port(port), m_exit(false), m_command_ring_buffer(262144) { - //cerr<<"using port: ["< - samplebrain 0.18.4 + samplebrain 0.18.5 diff --git a/gui/settings.ui b/gui/settings.ui index 9d740c0..e8f8835 100644 --- a/gui/settings.ui +++ b/gui/settings.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 522 + 438 + 656 @@ -31,7 +31,13 @@ - + + + + Comic Sans MS + + + @@ -57,6 +63,11 @@ 0 + + + Comic Sans MS + + 44100 @@ -73,7 +84,7 @@ - (note: this currently should probably match your sample file's input rate as no conversion is run on them - yet) + note: this currently should probably match your sample file's input rate as no conversion is run on them - yet true @@ -98,6 +109,11 @@ + + + Comic Sans MS + + 5 @@ -180,6 +196,112 @@ + + + + + Comic Sans MS + 8 + + + + restart needed for the ports below to update + + + + + + + + + + Comic Sans MS + + + + gui osc port + + + + + + + + 0 + 0 + + + + + Comic Sans MS + + + + + + + + + + + + + Comic Sans MS + + + + process osc port + + + + + + + + 0 + 0 + + + + + Comic Sans MS + + + + + + + + + + + + + Comic Sans MS + + + + audio osc port + + + + + + + + 0 + 0 + + + + + Comic Sans MS + + + + + + @@ -218,8 +340,8 @@ accept() - 231 - 358 + 244 + 642 157 @@ -234,8 +356,8 @@ reject() - 299 - 364 + 312 + 642 286 @@ -266,8 +388,8 @@ apply() - 112 - 321 + 125 + 592 4 @@ -298,8 +420,8 @@ buffersize(QString) - 326 - 131 + 390 + 215 395 @@ -307,11 +429,62 @@ + + guiOSCLineEdit + textChanged(QString) + SettingsDialog + gui_port(QString) + + + 346 + 432 + + + 401 + 419 + + + + + processOSCLineEdit + textChanged(QString) + SettingsDialog + process_port(QString) + + + 356 + 482 + + + 398 + 479 + + + + + audioOSCLineEdit + textChanged(QString) + SettingsDialog + audio_port(QString) + + + 374 + 511 + + + 398 + 517 + + + output_device(QString) samplerate(QString) buffersize(QString) apply() + gui_port(QString) + audio_port(QString) + process_port(QString) From e1c8e0ea67a1f1eb2da2d70a1a7f0a3cdcc5c20b Mon Sep 17 00:00:00 2001 From: Dave Griffiths Date: Fri, 14 Oct 2022 20:30:12 +0100 Subject: [PATCH 3/4] added more soundfile formats to the loading dialog and new error report when it can't load --- app/MainWindow.cpp | 3 ++- app/MainWindow.h | 40 +++++++++++++++++++--------------------- brain/src/brain.cpp | 2 ++ 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/app/MainWindow.cpp b/app/MainWindow.cpp index 5e0eb52..b7412ca 100644 --- a/app/MainWindow.cpp +++ b/app/MainWindow.cpp @@ -31,7 +31,8 @@ MainWindow::MainWindow(const string &port, const string &audio_port, const strin m_last_file("."), m_feedback(port), m_audio_port(audio_port), - m_process_port(process_port) + m_process_port(process_port), + m_format_string("Microsoft WAV (*.wav);;SGI/Apple AIFF (*.aiff);;SGI/Apple AIFC (*.aifc);;Sun/DEC/NeXT AU (*.au);;Sun/DEC/NeXT SND (*.snd);;Fasttracker 2 XI (*.xi);;All files (*.*)") { m_sound_item_enable_mapper = new QSignalMapper(this); m_sound_item_delete_mapper = new QSignalMapper(this); diff --git a/app/MainWindow.h b/app/MainWindow.h index 7500cdb..48ab6b5 100644 --- a/app/MainWindow.h +++ b/app/MainWindow.h @@ -206,11 +206,10 @@ private slots: void run_slot() {} void load_target() { - m_last_file=QFileDialog::getOpenFileName( - this, - QString("Select an wav file"), + m_last_file=QFileDialog::getOpenFileName(this, + QString("Select an audio file"), m_last_file, - QString("Sounds (*.wav)")); + m_format_string); send_process_osc("/load_target","s",m_last_file.toStdString().c_str()); } @@ -222,26 +221,25 @@ private slots: void fft_spectrum_size(int) {} void generate() { send_process_osc("/generate_brain",""); } void load_sound() { - m_last_file=QFileDialog::getOpenFileName( - this, + m_last_file=QFileDialog::getOpenFileName(this, QString("Select a wav file"), m_last_file, - QString("Sounds (*.wav)")); + m_format_string); - send_process_osc("/load_sample","s",m_last_file.toStdString().c_str()); - - sound_items::sound_item &si = m_sound_items.add(m_Ui.brain_contents, m_last_file.toStdString(),true); - - QObject::connect(si.m_enable, SIGNAL(clicked()), m_sound_item_enable_mapper, SLOT(map())); - m_sound_item_enable_mapper->setMapping(si.m_enable, si.m_id); - QObject::connect(si.m_del, SIGNAL(clicked()), m_sound_item_delete_mapper, SLOT(map())); - m_sound_item_delete_mapper->setMapping(si.m_del, si.m_id); + if (m_last_file!="") { + send_process_osc("/load_sample","s",m_last_file.toStdString().c_str()); + sound_items::sound_item &si = m_sound_items.add(m_Ui.brain_contents, m_last_file.toStdString(),true); + QObject::connect(si.m_enable, SIGNAL(clicked()), m_sound_item_enable_mapper, SLOT(map())); + m_sound_item_enable_mapper->setMapping(si.m_enable, si.m_id); + QObject::connect(si.m_del, SIGNAL(clicked()), m_sound_item_delete_mapper, SLOT(map())); + m_sound_item_delete_mapper->setMapping(si.m_del, si.m_id); + } } void load_sounds() { m_last_file=QFileDialog::getExistingDirectory(this, - QString("Select a directory"), + QString("Select a directory of wav files"), m_last_file); @@ -319,7 +317,7 @@ private slots: this, QString("Select a wav file"), m_last_file, - QString("Sounds (*.wav)")); + QString("Sounds (*.wav);;All files (*.*)")); m_save_wav = m_last_file.toStdString(); // chop off .wav size_t pos = m_save_wav.find_last_of("."); @@ -345,7 +343,7 @@ private slots: this, QString("Select a brain file"), m_last_file, - QString("Brains (*.brain)")); + QString("Brains (*.brain);;All files (*.*)")); send_process_osc("/load_brain","s",m_last_file.toStdString().c_str()); } @@ -354,7 +352,7 @@ private slots: this, QString("Select a brain file"), m_last_file, - QString("Brains (*.brain)")); + QString("Brains (*.brain);;All files (*.*)")); send_process_osc("/save_brain","s",m_last_file.toStdString().c_str()); } @@ -364,7 +362,7 @@ private slots: this, QString("Select a session file"), m_last_file, - QString("Sessions *.samplebrain (*.samplebrain)")); + QString("Sessions *.samplebrain (*.samplebrain);;All files (*.*)")); send_process_osc("/load_session","s",m_last_file.toStdString().c_str()); init_from_session(m_last_file.toStdString()); @@ -455,5 +453,5 @@ private: string m_audio_port; string m_process_port; - + QString m_format_string; }; diff --git a/brain/src/brain.cpp b/brain/src/brain.cpp index 6c63289..7625cb4 100644 --- a/brain/src/brain.cpp +++ b/brain/src/brain.cpp @@ -69,6 +69,8 @@ void brain::load_sound(std::string filename, stereo_mode mode) { delete[] temp; m_samples.push_back(sound(filename,s)); status::update("loaded %s",filename.c_str()); + } else { + status::update("problem loading %s",filename.c_str()); } } From 385563e64ef1cf0d1b2289126f01d5632a0ba9eb Mon Sep 17 00:00:00 2001 From: Dave Griffiths Date: Fri, 14 Oct 2022 21:24:56 +0100 Subject: [PATCH 4/4] forgot to add flac --- app/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/MainWindow.cpp b/app/MainWindow.cpp index b7412ca..623f583 100644 --- a/app/MainWindow.cpp +++ b/app/MainWindow.cpp @@ -32,7 +32,7 @@ MainWindow::MainWindow(const string &port, const string &audio_port, const strin m_feedback(port), m_audio_port(audio_port), m_process_port(process_port), - m_format_string("Microsoft WAV (*.wav);;SGI/Apple AIFF (*.aiff);;SGI/Apple AIFC (*.aifc);;Sun/DEC/NeXT AU (*.au);;Sun/DEC/NeXT SND (*.snd);;Fasttracker 2 XI (*.xi);;All files (*.*)") + m_format_string("Microsoft WAV (*.wav);;SGI/Apple AIFF (*.aiff);;SGI/Apple AIFC (*.aifc);;Sun/DEC/NeXT AU (*.au);;Sun/DEC/NeXT SND (*.snd);;Fasttracker 2 XI (*.xi);;Free Lossless Audio Codec FLAC (*.flac);;All files (*.*)") { m_sound_item_enable_mapper = new QSignalMapper(this); m_sound_item_delete_mapper = new QSignalMapper(this);