diff --git a/samplebrain/interface/samplebrain.ui b/samplebrain/interface/samplebrain.ui index 0f6807d..ea36146 100644 Binary files a/samplebrain/interface/samplebrain.ui and b/samplebrain/interface/samplebrain.ui differ diff --git a/samplebrain/qt/MainWindow.cpp b/samplebrain/qt/MainWindow.cpp index 07736aa..34de1a6 100644 --- a/samplebrain/qt/MainWindow.cpp +++ b/samplebrain/qt/MainWindow.cpp @@ -16,9 +16,11 @@ #include #include +#include #include "MainWindow.h" #include "feedback.h" +#include "renderer.h" using namespace std; @@ -40,3 +42,116 @@ MainWindow::MainWindow() : m_save_wav=""; m_record_id=0; } + +void MainWindow::init_from_session(const string &filename) { + // pull the bits out of the file to set the interface... + // is this easier than direct access? no idea?? + ifstream ifs(filename.c_str(),ios::binary); + + brain s,t; + + renderer r(s,t); + ifs||r; + + u32 target_windowsize; + u32 source_windowsize; + window::type target_window; + window::type source_window; + float target_overlap; + float source_overlap; + int t_int; + // skip this... + ifs||target_windowsize||target_overlap; + ifs||source_windowsize||source_overlap; + ifs||target_window||source_window; + // todo: probably don't need to load all the sample data too :/ + ifs||s; + ifs||t; + + // brain tweaks + search_params * p = r.get_params(); + + m_Ui.sliderRatio->setValue(p->m_ratio*100); + m_Ui.doubleSpinBoxRatio->setValue(p->m_ratio); + m_Ui.sliderNRatio->setValue(p->m_n_ratio*100); + m_Ui.doubleSpinBoxNRatio->setValue(p->m_n_ratio); + m_Ui.spinBoxFFT1Start->setValue(p->m_fft1_start); + m_Ui.spinBoxFFT1End->setValue(p->m_fft1_end); + m_Ui.sliderNovelty->setValue(p->m_usage_importance*100); + m_Ui.doubleSpinBoxNovelty->setValue(p->m_usage_importance); + m_Ui.sliderBoredom->setValue(s.get_usage_falloff()*100); + m_Ui.doubleSpinBoxBoredom->setValue(s.get_usage_falloff()); + m_Ui.sliderStickyness->setValue(p->m_stickyness*100); + m_Ui.doubleSpinBoxStickyness->setValue(p->m_stickyness); + m_Ui.sliderSearchStretch->setValue(r.get_stretch()); + m_Ui.spinBoxSearchStretch->setValue(r.get_stretch()); + + switch(r.get_search_algo()) { + case renderer::BASIC: m_Ui.radioButtonAlgoBasic->setChecked(true); break; + case renderer::REV_BASIC: m_Ui.radioButtonAlgoRevBasic->setChecked(true); break; + case renderer::SYNAPTIC: m_Ui.radioButtonSynaptic->setChecked(true); break; + case renderer::SYNAPTIC_SLIDE: m_Ui.radioButtonSynapticSlide->setChecked(true); break; + }; + + m_Ui.sliderSynapses->setValue(p->m_num_synapses); + m_Ui.spinBoxSynapses->setValue(p->m_num_synapses); + m_Ui.sliderSlideError->setValue(r.get_slide_error()); + m_Ui.spinBoxSlideError->setValue(r.get_slide_error()); + + // target + m_Ui.spinBoxBlockSizeTarget->setValue(t.get_block_size()); + m_Ui.doubleSpinBoxBlockOverlapTarget->setValue(t.get_overlap()/(float)t.get_block_size()); + + m_Ui.radioButton_dodgyTarget->setChecked(false); + m_Ui.radioButton_bartlettTarget->setChecked(false); + m_Ui.radioButton_blackmanTarget->setChecked(false); + m_Ui.radioButton_flattopTarget->setChecked(false); + m_Ui.radioButton_gaussianTarget->setChecked(false); + m_Ui.radioButton_hammingTarget->setChecked(false); + m_Ui.radioButton_hannTarget->setChecked(false); + m_Ui.radioButton_rectangleTarget->setChecked(false); + + switch(target_window) { + case window::DODGY: m_Ui.radioButton_dodgyTarget->setChecked(true); break; + case window::BARTLETT: m_Ui.radioButton_bartlettTarget->setChecked(true); break; + case window::BLACKMAN: m_Ui.radioButton_blackmanTarget->setChecked(true); break; + case window::FLAT_TOP: m_Ui.radioButton_flattopTarget->setChecked(true); break; + case window::GAUSSIAN: m_Ui.radioButton_gaussianTarget->setChecked(true); break; + case window::HAMMING: m_Ui.radioButton_hammingTarget->setChecked(true); break; + case window::HANN: m_Ui.radioButton_hannTarget->setChecked(true); break; + case window::RECTANGLE: m_Ui.radioButton_rectangleTarget->setChecked(true); break; + }; + + // source + m_Ui.spinBoxBlockSize->setValue(s.get_block_size()); + m_Ui.doubleSpinBoxBlockOverlap->setValue(s.get_overlap()/(float)s.get_block_size()); + switch(source_window) { + case window::DODGY: m_Ui.radioButton_dodgy->setChecked(true); break; + case window::BARTLETT: m_Ui.radioButton_bartlett->setChecked(true); break; + case window::BLACKMAN: m_Ui.radioButton_blackman->setChecked(true); break; + case window::FLAT_TOP: m_Ui.radioButton_flattop->setChecked(true); break; + case window::GAUSSIAN: m_Ui.radioButton_gaussian->setChecked(true); break; + case window::HAMMING: m_Ui.radioButton_hamming->setChecked(true); break; + case window::HANN: m_Ui.radioButton_hann->setChecked(true); break; + case window::RECTANGLE: m_Ui.radioButton_rectagle->setChecked(true); break; + }; + + // brain samples + m_Ui.listWidgetSounds->clear(); + const std::list samples = s.get_samples(); + for (std::list::const_iterator i=samples.begin(); + i!=samples.end(); ++i) { + m_Ui.listWidgetSounds->addItem(QString::fromStdString(i->m_filename)); + } + + // mix + m_Ui.sliderTargetMix->setValue(r.get_target_mix()*100); + m_Ui.doubleSpinBoxTargetMix->setValue(r.get_target_mix()); + m_Ui.sliderNMix->setValue(r.get_n_mix()*100); + m_Ui.doubleSpinBoxNMix->setValue(r.get_n_mix()); + m_Ui.sliderAutotune->setValue(r.get_autotune()*100); + m_Ui.doubleSpinBoxAutotune->setValue(r.get_autotune()); + + + +} diff --git a/samplebrain/qt/MainWindow.h b/samplebrain/qt/MainWindow.h index 5080f3b..390e2e7 100644 --- a/samplebrain/qt/MainWindow.h +++ b/samplebrain/qt/MainWindow.h @@ -69,7 +69,6 @@ private slots: m_Ui.sliderAutotune->setValue(s*100); } - void fft1_start_slot(int s) { lo_send(m_audio_address,"/fft1_start","i",s); } void fft1_end_slot(int s) { lo_send(m_audio_address,"/fft1_end","i",s); } void fft2_start_slot(int s){} // { m_renderer->get_params()->m_fft2_start=s; } @@ -200,7 +199,7 @@ private slots: if (m_save_wav=="") { m_last_file=QFileDialog::getSaveFileName( this, - QString("Select an wav file"), + QString("Select a wav file"), m_last_file, QString("Sounds (*.wav)")); m_save_wav = m_last_file.toStdString(); @@ -242,12 +241,35 @@ private slots: lo_send(m_process_address,"/save_brain","s",m_last_file.toStdString().c_str()); } + void load_session() { + m_last_file=QFileDialog::getOpenFileName( + this, + QString("Select a session file"), + m_last_file, + QString("Sessions (*.samplebrain)")); + + lo_send(m_process_address,"/load_session","s",m_last_file.toStdString().c_str()); + init_from_session(m_last_file.toStdString()); + } + + void save_session() { + m_last_file=QFileDialog::getSaveFileName( + this, + QString("Select a session file"), + m_last_file, + QString("Sessions (*.samplebrain)")); + + lo_send(m_process_address,"/save_session","s",m_last_file.toStdString().c_str()); + } void update_status() { m_feedback.poll(m_Ui.statusbar); } private: + + void init_from_session(const string &filename); + string m_save_wav; QString m_last_file; u32 m_record_id; diff --git a/samplebrain/qt/generated/ui_samplebrain.h b/samplebrain/qt/generated/ui_samplebrain.h index 088642b..6f85f8c 100644 --- a/samplebrain/qt/generated/ui_samplebrain.h +++ b/samplebrain/qt/generated/ui_samplebrain.h @@ -1,13 +1,13 @@ /******************************************************************************** -** Form generated from reading UI file 'samplebrainPm4153.ui' +** Form generated from reading UI file 'samplebraing13021.ui' ** ** Created by: Qt User Interface Compiler version 4.8.6 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ -#ifndef SAMPLEBRAINPM4153_H -#define SAMPLEBRAINPM4153_H +#ifndef SAMPLEBRAING13021_H +#define SAMPLEBRAING13021_H #include #include @@ -88,6 +88,7 @@ public: QLabel *label_29; QSlider *sliderSlideError; QSpinBox *spinBoxSlideError; + QSpacerItem *horizontalSpacer_2; QVBoxLayout *verticalLayout_6; QLabel *label_16; QPushButton *pushButtonLoadTarget; @@ -122,7 +123,7 @@ public: QSlider *sliderTargetMix; QDoubleSpinBox *doubleSpinBoxTargetMix; QSpacerItem *verticalSpacer; - QVBoxLayout *verticalLayout; + QVBoxLayout *verticalLayout_2; QLabel *label_3; QListWidget *listWidgetSounds; QHBoxLayout *horizontalLayout_2; @@ -136,8 +137,8 @@ public: QLabel *label_2; QDoubleSpinBox *doubleSpinBoxBlockOverlap; QGridLayout *gridLayout; - QRadioButton *radioButton_hamming; QRadioButton *radioButton_gaussian; + QRadioButton *radioButton_hamming; QRadioButton *radioButton_dodgy; QRadioButton *radioButton_blackman; QRadioButton *radioButton_rectagle; @@ -149,6 +150,7 @@ public: QHBoxLayout *horizontalLayout_7; QPushButton *pushButtonLoadBrain; QPushButton *pushButtonSaveBrain; + QSpacerItem *verticalSpacer_2; QWidget *logTab; QHBoxLayout *horizontalLayout_15; QPlainTextEdit *plainTextEdit; @@ -158,6 +160,9 @@ public: QPushButton *pushButtonRecord; QPushButton *pushButtonStopRecord; QDial *dialVolume; + QVBoxLayout *verticalLayout; + QPushButton *pushButtonLoadSession; + QPushButton *pushButtonSaveSession; QSpacerItem *horizontalSpacer; QLabel *label_13; QStatusBar *statusbar; @@ -169,7 +174,7 @@ public: { if (MainWindow->objectName().isEmpty()) MainWindow->setObjectName(QString::fromUtf8("MainWindow")); - MainWindow->resize(1012, 707); + MainWindow->resize(910, 795); centralwidget = new QWidget(MainWindow); centralwidget->setObjectName(QString::fromUtf8("centralwidget")); verticalLayout_4 = new QVBoxLayout(centralwidget); @@ -545,6 +550,10 @@ public: verticalLayout_3->addLayout(horizontalLayout_20); + horizontalSpacer_2 = new QSpacerItem(21, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + + verticalLayout_3->addItem(horizontalSpacer_2); + horizontalLayout_5->addLayout(verticalLayout_3); @@ -685,7 +694,6 @@ public: sizePolicy.setHeightForWidth(sliderAutotune->sizePolicy().hasHeightForWidth()); sliderAutotune->setSizePolicy(sizePolicy); sliderAutotune->setValue(0); - sliderAutotune->setSliderPosition(0); sliderAutotune->setOrientation(Qt::Horizontal); horizontalLayout_22->addWidget(sliderAutotune); @@ -771,18 +779,18 @@ public: horizontalLayout_5->addLayout(verticalLayout_6); - verticalLayout = new QVBoxLayout(); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + verticalLayout_2 = new QVBoxLayout(); + verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); label_3 = new QLabel(controlTab); label_3->setObjectName(QString::fromUtf8("label_3")); label_3->setFont(font1); - verticalLayout->addWidget(label_3); + verticalLayout_2->addWidget(label_3); listWidgetSounds = new QListWidget(controlTab); listWidgetSounds->setObjectName(QString::fromUtf8("listWidgetSounds")); - verticalLayout->addWidget(listWidgetSounds); + verticalLayout_2->addWidget(listWidgetSounds); horizontalLayout_2 = new QHBoxLayout(); horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); @@ -799,13 +807,13 @@ public: horizontalLayout_2->addWidget(pushButtonDeleteSound); - verticalLayout->addLayout(horizontalLayout_2); + verticalLayout_2->addLayout(horizontalLayout_2); pushButtonClearBrain = new QPushButton(controlTab); pushButtonClearBrain->setObjectName(QString::fromUtf8("pushButtonClearBrain")); pushButtonClearBrain->setFont(font); - verticalLayout->addWidget(pushButtonClearBrain); + verticalLayout_2->addWidget(pushButtonClearBrain); horizontalLayout_4 = new QHBoxLayout(); horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4")); @@ -823,7 +831,7 @@ public: horizontalLayout_4->addWidget(spinBoxBlockSize); - verticalLayout->addLayout(horizontalLayout_4); + verticalLayout_2->addLayout(horizontalLayout_4); horizontalLayout_6 = new QHBoxLayout(); horizontalLayout_6->setObjectName(QString::fromUtf8("horizontalLayout_6")); @@ -842,24 +850,24 @@ public: horizontalLayout_6->addWidget(doubleSpinBoxBlockOverlap); - verticalLayout->addLayout(horizontalLayout_6); + verticalLayout_2->addLayout(horizontalLayout_6); gridLayout = new QGridLayout(); gridLayout->setObjectName(QString::fromUtf8("gridLayout")); - radioButton_hamming = new QRadioButton(controlTab); + radioButton_gaussian = new QRadioButton(controlTab); buttonGroup = new QButtonGroup(MainWindow); buttonGroup->setObjectName(QString::fromUtf8("buttonGroup")); - buttonGroup->addButton(radioButton_hamming); - radioButton_hamming->setObjectName(QString::fromUtf8("radioButton_hamming")); - - gridLayout->addWidget(radioButton_hamming, 4, 1, 1, 1); - - radioButton_gaussian = new QRadioButton(controlTab); buttonGroup->addButton(radioButton_gaussian); radioButton_gaussian->setObjectName(QString::fromUtf8("radioButton_gaussian")); gridLayout->addWidget(radioButton_gaussian, 3, 1, 1, 1); + radioButton_hamming = new QRadioButton(controlTab); + buttonGroup->addButton(radioButton_hamming); + radioButton_hamming->setObjectName(QString::fromUtf8("radioButton_hamming")); + + gridLayout->addWidget(radioButton_hamming, 4, 1, 1, 1); + radioButton_dodgy = new QRadioButton(controlTab); buttonGroup->addButton(radioButton_dodgy); radioButton_dodgy->setObjectName(QString::fromUtf8("radioButton_dodgy")); @@ -903,13 +911,13 @@ public: gridLayout->addWidget(label_4, 2, 0, 1, 1); - verticalLayout->addLayout(gridLayout); + verticalLayout_2->addLayout(gridLayout); pushButtonGenerate = new QPushButton(controlTab); pushButtonGenerate->setObjectName(QString::fromUtf8("pushButtonGenerate")); pushButtonGenerate->setFont(font); - verticalLayout->addWidget(pushButtonGenerate); + verticalLayout_2->addWidget(pushButtonGenerate); horizontalLayout_7 = new QHBoxLayout(); horizontalLayout_7->setObjectName(QString::fromUtf8("horizontalLayout_7")); @@ -926,10 +934,14 @@ public: horizontalLayout_7->addWidget(pushButtonSaveBrain); - verticalLayout->addLayout(horizontalLayout_7); + verticalLayout_2->addLayout(horizontalLayout_7); + + verticalSpacer_2 = new QSpacerItem(20, 508, QSizePolicy::Minimum, QSizePolicy::Expanding); + + verticalLayout_2->addItem(verticalSpacer_2); - horizontalLayout_5->addLayout(verticalLayout); + horizontalLayout_5->addLayout(verticalLayout_2); tabWidget->addTab(controlTab, QString()); logTab = new QWidget(); @@ -995,6 +1007,21 @@ public: horizontalLayout_12->addWidget(dialVolume); + verticalLayout = new QVBoxLayout(); + verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + pushButtonLoadSession = new QPushButton(centralwidget); + pushButtonLoadSession->setObjectName(QString::fromUtf8("pushButtonLoadSession")); + + verticalLayout->addWidget(pushButtonLoadSession); + + pushButtonSaveSession = new QPushButton(centralwidget); + pushButtonSaveSession->setObjectName(QString::fromUtf8("pushButtonSaveSession")); + + verticalLayout->addWidget(pushButtonSaveSession); + + + horizontalLayout_12->addLayout(verticalLayout); + horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_12->addItem(horizontalSpacer); @@ -1077,8 +1104,10 @@ public: QObject::connect(sliderSlideError, SIGNAL(valueChanged(int)), MainWindow, SLOT(slide_error(int))); QObject::connect(doubleSpinBoxStickyness, SIGNAL(valueChanged(double)), MainWindow, SLOT(stickyness_slot(double))); QObject::connect(sliderStickyness, SIGNAL(valueChanged(int)), MainWindow, SLOT(stickyness_slot(int))); - QObject::connect(doubleSpinBoxAutotune, SIGNAL(valueChanged(double)), MainWindow, SLOT(autotune(double))); QObject::connect(sliderAutotune, SIGNAL(sliderMoved(int)), MainWindow, SLOT(autotune(int))); + QObject::connect(doubleSpinBoxAutotune, SIGNAL(valueChanged(double)), MainWindow, SLOT(autotune(double))); + QObject::connect(pushButtonLoadSession, SIGNAL(released()), MainWindow, SLOT(load_session())); + QObject::connect(pushButtonSaveSession, SIGNAL(released()), MainWindow, SLOT(save_session())); tabWidget->setCurrentIndex(0); @@ -1088,13 +1117,13 @@ public: void retranslateUi(QMainWindow *MainWindow) { - MainWindow->setWindowTitle(QApplication::translate("MainWindow", "samplebrain 0.11", 0, QApplication::UnicodeUTF8)); + MainWindow->setWindowTitle(QApplication::translate("MainWindow", "samplebrain 0.12", 0, QApplication::UnicodeUTF8)); label_19->setText(QApplication::translate("MainWindow", "brain tweaks", 0, QApplication::UnicodeUTF8)); label_6->setText(QApplication::translate("MainWindow", "fft / mfcc", 0, QApplication::UnicodeUTF8)); #ifndef QT_NO_TOOLTIP sliderRatio->setToolTip(QApplication::translate("MainWindow", "plain fft match vs mfcc values ", 0, QApplication::UnicodeUTF8)); #endif // QT_NO_TOOLTIP - label_20->setText(QApplication::translate("MainWindow", "dynamics / freq", 0, QApplication::UnicodeUTF8)); + label_20->setText(QApplication::translate("MainWindow", "freq & dynamics / freq only", 0, QApplication::UnicodeUTF8)); #ifndef QT_NO_TOOLTIP sliderNRatio->setToolTip(QApplication::translate("MainWindow", "match original or normalised blocks", 0, QApplication::UnicodeUTF8)); #endif // QT_NO_TOOLTIP @@ -1129,7 +1158,7 @@ public: #endif // QT_NO_TOOLTIP label_30->setText(QApplication::translate("MainWindow", "stickyness", 0, QApplication::UnicodeUTF8)); #ifndef QT_NO_TOOLTIP - sliderStickyness->setToolTip(QApplication::translate("MainWindow", "prioritise brain order over closeness", 0, QApplication::UnicodeUTF8)); + sliderStickyness->setToolTip(QApplication::translate("MainWindow", "how long it takes for the novelty to wear off", 0, QApplication::UnicodeUTF8)); #endif // QT_NO_TOOLTIP #ifndef QT_NO_TOOLTIP label_28->setToolTip(QString()); @@ -1149,7 +1178,7 @@ public: #ifndef QT_NO_TOOLTIP radioButtonAlgoRevBasic->setToolTip(QApplication::translate("MainWindow", "full brain reverse search", 0, QApplication::UnicodeUTF8)); #endif // QT_NO_TOOLTIP - radioButtonAlgoRevBasic->setText(QApplication::translate("MainWindow", "rev", 0, QApplication::UnicodeUTF8)); + radioButtonAlgoRevBasic->setText(QApplication::translate("MainWindow", "rev basic", 0, QApplication::UnicodeUTF8)); #ifndef QT_NO_TOOLTIP radioButtonSynaptic->setToolTip(QApplication::translate("MainWindow", "search based on synapse connections", 0, QApplication::UnicodeUTF8)); #endif // QT_NO_TOOLTIP @@ -1211,8 +1240,8 @@ public: pushButtonClearBrain->setText(QApplication::translate("MainWindow", "clear brain", 0, QApplication::UnicodeUTF8)); label->setText(QApplication::translate("MainWindow", "block size", 0, QApplication::UnicodeUTF8)); label_2->setText(QApplication::translate("MainWindow", "block overlap", 0, QApplication::UnicodeUTF8)); - radioButton_hamming->setText(QApplication::translate("MainWindow", "hamming", 0, QApplication::UnicodeUTF8)); radioButton_gaussian->setText(QApplication::translate("MainWindow", "gaussian", 0, QApplication::UnicodeUTF8)); + radioButton_hamming->setText(QApplication::translate("MainWindow", "hamming", 0, QApplication::UnicodeUTF8)); radioButton_dodgy->setText(QApplication::translate("MainWindow", "dodgy", 0, QApplication::UnicodeUTF8)); radioButton_blackman->setText(QApplication::translate("MainWindow", "blackman", 0, QApplication::UnicodeUTF8)); radioButton_rectagle->setText(QApplication::translate("MainWindow", "rectangle", 0, QApplication::UnicodeUTF8)); @@ -1229,6 +1258,8 @@ public: pushButtonStop->setText(QString()); pushButtonRecord->setText(QString()); pushButtonStopRecord->setText(QString()); + pushButtonLoadSession->setText(QApplication::translate("MainWindow", "load session", 0, QApplication::UnicodeUTF8)); + pushButtonSaveSession->setText(QApplication::translate("MainWindow", "save session", 0, QApplication::UnicodeUTF8)); label_13->setText(QString()); } // retranslateUi @@ -1240,4 +1271,4 @@ namespace Ui { QT_END_NAMESPACE -#endif // SAMPLEBRAINPM4153_H +#endif // SAMPLEBRAING13021_H diff --git a/samplebrain/qt/process_thread.cpp b/samplebrain/qt/process_thread.cpp index cd96302..1900a42 100644 --- a/samplebrain/qt/process_thread.cpp +++ b/samplebrain/qt/process_thread.cpp @@ -110,6 +110,12 @@ void process_thread::process() { if (name=="/save_brain") { save_source(cmd.get_string(0)); } + if (name=="/load_session") { + load_session(cmd.get_string(0)); + } + if (name=="/save_session") { + save_session(cmd.get_string(0)); + } } usleep(500); } @@ -118,20 +124,13 @@ void process_thread::process() { void process_thread::load_source(const std::string &filename) { pthread_mutex_lock(m_brain_mutex); + m_source.clear(); ifstream ifs(filename.c_str(),ios::binary); ifs||m_source; ifs.close(); pthread_mutex_unlock(m_brain_mutex); } -void process_thread::load_target(const std::string &filename) { - pthread_mutex_lock(m_brain_mutex); - ifstream ifs(filename.c_str(),ios::binary); - ifs||m_target; - ifs.close(); - pthread_mutex_unlock(m_brain_mutex); -} - void process_thread::save_source(const std::string &filename) { pthread_mutex_lock(m_brain_mutex); ofstream ofs(filename.c_str(),ios::binary); @@ -140,9 +139,30 @@ void process_thread::save_source(const std::string &filename) { pthread_mutex_unlock(m_brain_mutex); } -void process_thread::save_target(const std::string &filename) { +// remember to change GUI side to match... +void process_thread::load_session(const std::string &filename) { + pthread_mutex_lock(m_brain_mutex); + m_source.clear(); + m_target.clear(); + ifstream ifs(filename.c_str(),ios::binary); + ifs||(*m_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_target; + ifs.close(); + pthread_mutex_unlock(m_brain_mutex); +} + +void process_thread::save_session(const std::string &filename) { pthread_mutex_lock(m_brain_mutex); ofstream ofs(filename.c_str(),ios::binary); + ofs||(*m_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_target; ofs.close(); pthread_mutex_unlock(m_brain_mutex); diff --git a/samplebrain/qt/process_thread.h b/samplebrain/qt/process_thread.h index 9745374..7d87c69 100644 --- a/samplebrain/qt/process_thread.h +++ b/samplebrain/qt/process_thread.h @@ -35,9 +35,10 @@ public: void process(); void load_source(const std::string &filename); - void load_target(const std::string &filename); void save_source(const std::string &filename); - void save_target(const std::string &filename); + + void load_session(const std::string &filename); + void save_session(const std::string &filename); // only for use in mutex brain m_source, m_target; diff --git a/samplebrain/qt/samplebrain.pro b/samplebrain/qt/samplebrain.pro index ba3cbe9..16524f0 100644 --- a/samplebrain/qt/samplebrain.pro +++ b/samplebrain/qt/samplebrain.pro @@ -23,6 +23,7 @@ SOURCES += MainWindow.cpp \ ../src/fft.cpp \ ../src/mfcc.cpp \ ../src/renderer.cpp \ + ../src/search_params.cpp \ ../src/status.cpp \ ../src/window.cpp \ ../src/aquila/filter/MelFilterBank.cpp \ diff --git a/samplebrain/src/brain.cpp b/samplebrain/src/brain.cpp index a992e01..5fa8173 100644 --- a/samplebrain/src/brain.cpp +++ b/samplebrain/src/brain.cpp @@ -61,6 +61,12 @@ void brain::delete_sound(std::string filename) { } } +void brain::clear() { + m_blocks.clear(); + m_samples.clear(); + m_active_sounds.clear(); +} + // rewrites whole brain void brain::init(u32 block_size, u32 overlap, window::type t, bool ditchpcm) { m_blocks.clear(); @@ -322,6 +328,7 @@ ios &spiralcore::operator||(ios &s, brain::sound &b) { ios &spiralcore::operator||(ios &s, brain &b) { u32 version=0; string id("brain"); + // changes here need to be reflected in interface loading s||id||version; stream_vector(s,b.m_blocks); stream_list(s,b.m_samples); diff --git a/samplebrain/src/brain.h b/samplebrain/src/brain.h index c06bfe4..52a442d 100644 --- a/samplebrain/src/brain.h +++ b/samplebrain/src/brain.h @@ -49,6 +49,8 @@ public: sample m_sample; }; + void clear(); + // load, chop up and add to brain // todo: add tags void load_sound(std::string filename); @@ -58,6 +60,8 @@ public: // (presumably this one is made from a single sample) //void resynth(const std::string &filename, const brain &other, const search_params ¶ms); + + const std::list &get_samples() { return m_samples; } const sample &get_block_pcm(u32 index) const; const sample &get_block_n_pcm(u32 index) const; const block &get_block(u32 index) const; @@ -66,6 +70,7 @@ public: u32 get_overlap() const { return m_overlap; } void set_usage_falloff(float s) { m_usage_falloff=s; } + float get_usage_falloff() { return m_usage_falloff; } // basic search u32 search(const block &target, const search_params ¶ms); diff --git a/samplebrain/src/renderer.cpp b/samplebrain/src/renderer.cpp index 627afb2..5170915 100644 --- a/samplebrain/src/renderer.cpp +++ b/samplebrain/src/renderer.cpp @@ -244,6 +244,18 @@ void renderer::clean_up() { } } +ios &spiralcore::operator||(ios &s, renderer &r) { + u32 version=0; + string id("renderer"); + s||id||version; + s||r.m_search_params; + s||r.m_volume||r.m_playing||r.m_target_index||r.m_render_index; + s||r.m_target_time||r.m_render_time||r.m_stretch; + s||r.m_n_mix||r.m_target_mix||r.m_autotune; + s||r.m_search_algo||r.m_slide_error||r.m_last_tgt_shift; + return s; +} + bool renderer::unit_test() { brain source; source.load_sound("test_data/up.wav"); diff --git a/samplebrain/src/renderer.h b/samplebrain/src/renderer.h index 8091a41..bfe2dff 100644 --- a/samplebrain/src/renderer.h +++ b/samplebrain/src/renderer.h @@ -55,10 +55,20 @@ namespace spiralcore { void set_autotune(float s) { m_autotune=s; } search_params *get_params() { return &m_search_params; } + search_algo get_search_algo() { return m_search_algo; } + float get_volume() { return m_volume; } + float get_n_mix() { return m_n_mix; } + float get_target_mix() { return m_target_mix; } + double get_slide_error() { return m_slide_error; } + u32 get_stretch() { return m_stretch; } + float get_autotune() { return m_autotune; } + brain &get_source() { return m_source; } static bool unit_test(); + friend ios &operator||(ios &s, renderer &b); + private: bool find_render_blocks(u32 nframes); @@ -104,6 +114,9 @@ namespace spiralcore { std::list m_render_blocks; }; + std::ios &operator||(std::ios &s, renderer &b); + } + #endif diff --git a/samplebrain/src/search_params.h b/samplebrain/src/search_params.h index 9ca9abd..a9e3fd2 100644 --- a/samplebrain/src/search_params.h +++ b/samplebrain/src/search_params.h @@ -17,6 +17,12 @@ #ifndef SEARCH_PARAMS #define SEARCH_PARAMS +#include "jellyfish/core/types.h" +#include "jellyfish/core/stream.h" +#include + +#pragma once + namespace spiralcore { class search_params { @@ -40,6 +46,8 @@ public: f32 m_stickyness; }; + std::ios &operator||(std::ios &s, search_params &b); + } #endif