2 Commits

Author SHA1 Message Date
6a89c19d24 saving stereo 2023-04-12 15:48:56 +01:00
13ee3ed817 streaming stereo status, fixes: #74 2022-12-05 09:16:05 +00:00
9 changed files with 67 additions and 44 deletions

View File

@ -33,6 +33,10 @@ Load the demo using "load session" not "load brain" (sessions contain
both the target and brain samples). The original samples used to both the target and brain samples). The original samples used to
create the demo session [can be found here for create the demo session [can be found here for
testing](https://static.thentrythis.org/samplebrain/samples/). testing](https://static.thentrythis.org/samplebrain/samples/).
# Community
* https://www.reddit.com/r/samplebrain/
# Download # Download

View File

@ -113,8 +113,8 @@ void MainWindow::init_from_session(const string &filename) {
ifstream ifs(filename.c_str(),ios::binary); ifstream ifs(filename.c_str(),ios::binary);
if (!ifs) return; if (!ifs) return;
brain s,t; brain s,t,lt;
u32 version=0; u32 version=1;
ifs||version; ifs||version;
renderer r(s,t); renderer r(s,t);
ifs||r; ifs||r;
@ -133,7 +133,14 @@ void MainWindow::init_from_session(const string &filename) {
ifs||source_window||target_window; ifs||source_window||target_window;
// todo: probably don't need to load all the sample data too :/ // todo: probably don't need to load all the sample data too :/
ifs||s; ifs||s;
ifs||t; ifs||t; // left
ifs||lt; // right
if (version>0) {
ifs||m_stereo;
m_Ui.checkBoxStereo->setChecked(m_stereo);
}
// brain tweaks // brain tweaks
search_params * p = r.get_params(); search_params * p = r.get_params();
@ -159,7 +166,7 @@ void MainWindow::init_from_session(const string &filename) {
m_Ui.spinBoxSynapses->setValue(p->m_num_synapses); m_Ui.spinBoxSynapses->setValue(p->m_num_synapses);
m_Ui.sliderSlideError->setValue(r.get_slide_error()); m_Ui.sliderSlideError->setValue(r.get_slide_error());
m_Ui.spinBoxSlideError->setValue(r.get_slide_error()); m_Ui.spinBoxSlideError->setValue(r.get_slide_error());
// target // target
if (t.get_samples().size()>0) { if (t.get_samples().size()>0) {
// extract target filename from brain sample // extract target filename from brain sample
@ -198,8 +205,6 @@ void MainWindow::init_from_session(const string &filename) {
m_Ui.sliderAutotune->setValue(r.get_autotune()*100); m_Ui.sliderAutotune->setValue(r.get_autotune()*100);
m_Ui.doubleSpinBoxAutotune->setValue(r.get_autotune()); m_Ui.doubleSpinBoxAutotune->setValue(r.get_autotune());
} }
#endif #endif

View File

@ -393,7 +393,11 @@ private slots:
} }
void stereo_mode(bool s) { void stereo_mode(bool s) {
m_stereo=s;
send_audio_osc("/stereo","i",s); send_audio_osc("/stereo","i",s);
// irritating but need to tell process thread about stereo state
// just to it can save it to the session file
send_process_osc("/stereo","i",s);
} }
void net_enable(int id) { void net_enable(int id) {
@ -467,6 +471,7 @@ private:
audio_thread *m_audio_thread; audio_thread *m_audio_thread;
string m_audio_port; string m_audio_port;
string m_process_port; string m_process_port;
QString m_format_string; QString m_format_string;
bool m_stereo;
}; };

View File

@ -140,6 +140,10 @@ void process_thread::process() {
if (name=="/save_session") { if (name=="/save_session") {
save_session(cmd.get_string(0)); save_session(cmd.get_string(0));
} }
if (name=="/stereo") {
// only for session file save
m_stereo=cmd.get_int(0);
}
} }
#ifdef WIN32 #ifdef WIN32
Sleep(1); Sleep(1);
@ -174,16 +178,7 @@ void process_thread::load_session(const std::string &filename) {
m_left_target.clear(); m_left_target.clear();
m_right_target.clear(); m_right_target.clear();
ifstream ifs(filename.c_str(),ios::binary); ifstream ifs(filename.c_str(),ios::binary);
u32 version=0; stream_session(ifs);
ifs||version;
ifs||(*m_left_renderer);
ifs||(*m_right_renderer);
ifs||m_source_block_size||m_source_overlap;
ifs||m_target_block_size||m_target_overlap;
ifs||m_window_type||m_target_window_type;
ifs||m_source;
ifs||m_left_target;
ifs||m_right_target;
ifs.close(); ifs.close();
pthread_mutex_unlock(m_brain_mutex); pthread_mutex_unlock(m_brain_mutex);
} }
@ -191,16 +186,23 @@ void process_thread::load_session(const std::string &filename) {
void process_thread::save_session(const std::string &filename) { void process_thread::save_session(const std::string &filename) {
pthread_mutex_lock(m_brain_mutex); pthread_mutex_lock(m_brain_mutex);
ofstream ofs(filename.c_str(),ios::binary); ofstream ofs(filename.c_str(),ios::binary);
u32 version=0; stream_session(ofs);
ofs||version;
ofs||(*m_left_renderer);
ofs||(*m_right_renderer);
ofs||m_source_block_size||m_source_overlap;
ofs||m_target_block_size||m_target_overlap;
ofs||m_window_type||m_target_window_type;
ofs||m_source;
ofs||m_left_target;
ofs||m_right_target;
ofs.close(); ofs.close();
pthread_mutex_unlock(m_brain_mutex); pthread_mutex_unlock(m_brain_mutex);
} }
void process_thread::stream_session(std::ios &fs) {
u32 version=1;
fs||version;
fs||(*m_left_renderer);
fs||(*m_right_renderer);
fs||m_source_block_size||m_source_overlap;
fs||m_target_block_size||m_target_overlap;
fs||m_window_type||m_target_window_type;
fs||m_source;
fs||m_left_target;
fs||m_right_target;
if (version>0) {
fs||m_stereo;
}
}

View File

@ -54,13 +54,16 @@ namespace spiralcore {
brain m_source, m_left_target, m_right_target; brain m_source, m_left_target, m_right_target;
private: private:
OSC_server m_osc; void stream_session(std::ios &fs);
OSC_server m_osc;
u32 m_source_block_size; u32 m_source_block_size;
float m_source_overlap; float m_source_overlap;
u32 m_target_block_size; u32 m_target_block_size;
float m_target_overlap; float m_target_overlap;
window::type m_window_type; window::type m_window_type;
window::type m_target_window_type; window::type m_target_window_type;
bool m_stereo;
pthread_t *m_thread; pthread_t *m_thread;
// only use in mutex obvs... // only use in mutex obvs...

View File

@ -60,7 +60,7 @@ void OSC_server::error_handler(int num, const char *msg, const char *path) {
} }
int OSC_server::default_handler(const char *path, const char *types, lo_arg **argv, int OSC_server::default_handler(const char *path, const char *types, lo_arg **argv,
int argc, lo_message data, void *user_data) { int argc, void *data, void *user_data) {
OSC_server *server = (OSC_server*)user_data; OSC_server *server = (OSC_server*)user_data;
if (!server) return -1; if (!server) return -1;

View File

@ -32,7 +32,7 @@ public:
bool ok() { return m_server!=NULL; } bool ok() { return m_server!=NULL; }
private: private:
static int default_handler(const char *path, const char *types, lo_arg **argv, int argc, lo_message data, void *user_data); static int default_handler(const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data);
static void error_handler(int num, const char *m, const char *path); static void error_handler(int num, const char *m, const char *path);
lo_server_thread m_server; lo_server_thread m_server;

View File

@ -51,12 +51,12 @@ void audio_device::connect(const string &output_device_name, const string &clien
m_client.attach(output_device_name,clientname,opt); m_client.attach(output_device_name,clientname,opt);
} }
void audio_device::save_sample(const string &filename, const sample s) { void audio_device::save_sample(const string &filename, unsigned int channels, const sample s) {
SF_INFO sfinfo; SF_INFO sfinfo;
sfinfo.format=SF_FORMAT_WAV | SF_FORMAT_FLOAT; sfinfo.format=SF_FORMAT_WAV | SF_FORMAT_FLOAT;
sfinfo.frames=s.get_length(); sfinfo.frames=s.get_length();
sfinfo.samplerate=m_samplerate; sfinfo.samplerate=m_samplerate;
sfinfo.channels=1; sfinfo.channels=channels;
sfinfo.sections=1; sfinfo.sections=1;
sfinfo.seekable=0; sfinfo.seekable=0;
SNDFILE* f=sf_open(filename.c_str(), SFM_WRITE, &sfinfo); SNDFILE* f=sf_open(filename.c_str(), SFM_WRITE, &sfinfo);
@ -69,8 +69,7 @@ void audio_device::save_sample(const string &filename, const sample s) {
void audio_device::start_recording(std::string filename) { void audio_device::start_recording(std::string filename) {
m_record_filename=filename; m_record_filename=filename;
m_recording=true; m_recording=true;
m_record_buffer_left.clear(); m_record_buffer.clear();
m_record_buffer_right.clear();
m_record_counter=0; m_record_counter=0;
} }
@ -81,13 +80,19 @@ void audio_device::stop_recording() {
void audio_device::maybe_record() { void audio_device::maybe_record() {
if (m_recording) { if (m_recording) {
m_record_buffer_left.add(left_out); sample news(left_out.get_length()*2);
m_record_buffer_right.add(right_out); for (unsigned int i=0; i<left_out.get_length(); i++) {
m_record_counter++; news[i*2]=left_out[i];
if (m_record_counter%10==0) { news[i*2+1]=right_out[i];
save_sample(m_record_filename+"-left.wav", m_record_buffer_left); }
save_sample(m_record_filename+"-right.wav", m_record_buffer_right);
} m_record_buffer.add(news);
m_record_counter++;
// save "every now and again"
if (m_record_counter%10==0) {
save_sample(m_record_filename+".wav",2,m_record_buffer);
}
} }
} }

View File

@ -42,13 +42,12 @@ namespace spiralcore {
portaudio_client m_client; portaudio_client m_client;
void save_sample(const std::string &filename, const sample s); void save_sample(const std::string &filename, unsigned int channels, const sample s);
private: private:
bool m_recording; bool m_recording;
std::string m_record_filename; std::string m_record_filename;
sample m_record_buffer_left; sample m_record_buffer;
sample m_record_buffer_right;
u32 m_record_counter; u32 m_record_counter;
u32 m_samplerate; u32 m_samplerate;
}; };