diff --git a/samplebrain/interface/samplebrain.ui b/samplebrain/interface/samplebrain.ui index 3438526..6efc474 100644 --- a/samplebrain/interface/samplebrain.ui +++ b/samplebrain/interface/samplebrain.ui @@ -17,6 +17,13 @@ + + + Comic Sans MS + 75 + true + + 0 @@ -26,7 +33,7 @@ - + @@ -78,189 +85,211 @@ - + - + + + + Comic Sans MS + 14 + 75 + true + + + + fft <-> mfcc ratio + + + + + + + true + + + + 0 + 0 + + + + + 60 + 60 + + + + + + + + + + 1.000000000000000 + + + 0.010000000000000 + + + 0.500000000000000 + + + + + + + + + + Comic Sans MS + 14 + 75 + true + + + + fft subsection 1 + + + + + - + Comic Sans MS - 14 75 true - fft <-> mfcc ratio + Start - - - true - - - - 0 - 0 - - - - - 60 - 60 - - - + - - - - + - + Comic Sans MS - 14 75 true - fft subsection 1 + End - - - - - - Comic Sans MS - 75 - true - - - - Start - - - - - - - - - - - - - - - Comic Sans MS - 75 - true - - - - End - - - - - - - - - - - - - - - - - Comic Sans MS - 14 - 75 - true - - - - fft subsection 2 + + + 99 - - - - - - - Comic Sans MS - 75 - true - - - - Start - - - - - - - - - - - - - - - Comic Sans MS - 75 - true - - - - End - - - - - - - - - - - Qt::Vertical - - - - 323 - 511 - - - + + + + + + Comic Sans MS + 14 + 75 + true + + + + fft subsection 2 + + + + + + + + + + Comic Sans MS + 75 + true + + + + Start + + + + + + + + + + + + + + + Comic Sans MS + 75 + true + + + + End + + + + + + + 99 + + + + + + - + + + + Comic Sans MS + 75 + true + + + + Volume + + + + + - + + + 99 + + + + + Comic Sans MS @@ -269,14 +298,7 @@ - Volume - - - - - - - 99 + restart audio @@ -346,7 +368,14 @@ - + + + 99999 + + + 3000 + + @@ -367,7 +396,17 @@ - + + + 1.000000000000000 + + + 0.010000000000000 + + + 0.750000000000000 + + @@ -381,7 +420,7 @@ - generate blocks + (re)generate blocks @@ -441,7 +480,14 @@ - + + + 99999 + + + 3000 + + @@ -462,7 +508,17 @@ - + + + 1.000000000000000 + + + 0.010000000000000 + + + 0.750000000000000 + + @@ -497,7 +553,7 @@ - generate + (re)generate @@ -583,6 +639,34 @@ + + + + + Comic Sans MS + 75 + true + + + + delete selected + + + + + + + + Comic Sans MS + 75 + true + + + + clear brain + + + @@ -757,22 +841,6 @@ - - spinBoxBlockOverlapTarget - valueChanged(int) - MainWindow - target_block_overlap(int) - - - 320 - 169 - - - 399 - 301 - - - pushButtonGenerateTarget released() @@ -805,22 +873,6 @@ - - spinBoxBlockOverlap - valueChanged(int) - MainWindow - block_overlap(int) - - - 188 - 138 - - - 399 - 301 - - - spinBoxSpectSize valueChanged(int) @@ -885,6 +937,86 @@ + + doubleSpinBoxBlockOverlap + valueChanged(double) + MainWindow + block_overlap(double) + + + 188 + 138 + + + 361 + 301 + + + + + doubleSpinBoxBlockOverlapTarget + valueChanged(double) + MainWindow + target_block_overlap(double) + + + 619 + 196 + + + 361 + 301 + + + + + pushButtonClearBrain + released() + MainWindow + clear_brain() + + + 590 + 544 + + + 361 + 301 + + + + + pushButtonDeleteSound + released() + MainWindow + delete_sound() + + + 476 + 544 + + + 361 + 301 + + + + + pushButtonRestartAudio + released() + MainWindow + restart_audio() + + + 274 + 533 + + + 361 + 301 + + + play_slot() @@ -898,7 +1030,7 @@ volume_slot(int) run_slot() block_size(int) - block_overlap(int) + block_overlap(double) fft_spectrum_size(int) generate() load_sound() @@ -906,7 +1038,9 @@ slot2() load_target() target_block_size(int) - target_block_overlap(int) + target_block_overlap(double) generate_target_blocks() + clear_brain() + restart_audio() diff --git a/samplebrain/qt/MainWindow.h b/samplebrain/qt/MainWindow.h index f9e80b3..7e1dab0 100644 --- a/samplebrain/qt/MainWindow.h +++ b/samplebrain/qt/MainWindow.h @@ -4,6 +4,8 @@ #include #include +using namespace std; + class MainWindow : public QMainWindow { Q_OBJECT @@ -17,8 +19,8 @@ protected: private slots: - void play_slot() { lo_send(m_process_address,"/init",""); } - void stop_slot() {} //{ m_renderer->set_playing(false); } + void play_slot() { lo_send(m_audio_address,"/start",""); } + void stop_slot() { lo_send(m_audio_address,"/stop",""); } void ratio_slot(int s) { lo_send(m_audio_address,"/ratio","f",s/100.0f); } void ratio_slot(double s) { lo_send(m_audio_address,"/ratio","f",s); } void fft1_start_slot(int s) { lo_send(m_audio_address,"/fft1_start","i",s); } @@ -27,15 +29,47 @@ private slots: void fft2_end_slot(int s){} // { m_renderer->get_params()->m_fft2_end=s; } void volume_slot(int s){} // { m_renderer->set_volume(s/50.0f); } void run_slot() {} - void load_target() {} - void target_block_size(int) {} - void target_block_overlap(int) {} - void generate_target_blocks() {} - void block_size(int) {} - void block_overlap(int) {} + void load_target() { + QString s=QFileDialog::getOpenFileName( + this, + QString("Select an wav file"), + ".", + QString("Sounds (*.wav)")); + + lo_send(m_process_address,"/load_target","s",s.toStdString().c_str()); + } + void target_block_size(int s) { lo_send(m_process_address,"/target_block_size","i",s); } + void target_block_overlap(double s) { lo_send(m_process_address,"/target_overlap","f",s); } + void generate_target_blocks() { lo_send(m_process_address,"/generate_target",""); } + void block_size(int s) { lo_send(m_process_address,"/source_block_size","i",s); } + void block_overlap(double s) { lo_send(m_process_address,"/source_overlap","f",s); } void fft_spectrum_size(int) {} - void generate() {} - void load_sound() {} + void generate() { lo_send(m_process_address,"/generate_brain",""); } + void load_sound() { + QString s=QFileDialog::getOpenFileName( + this, + QString("Select an wav file"), + ".", + QString("Sounds (*.wav)")); + + lo_send(m_process_address,"/load_sample","s",s.toStdString().c_str()); + + m_Ui.listWidgetSounds->addItem(s); + } + void delete_sound() { + QList itemList = m_Ui.listWidgetSounds->selectedItems(); + for (int i=0; itext().toStdString().c_str()); + } + qDeleteAll(m_Ui.listWidgetSounds->selectedItems()); + } + void clear_brain() { + for (int i=0; icount(); i++) { + lo_send(m_process_address,"/delete_sample","s",m_Ui.listWidgetSounds->item(i)->text().toStdString().c_str()); + } + m_Ui.listWidgetSounds->clear(); + } + void restart_audio() { lo_send(m_audio_address,"/restart_audio",""); } private: Ui_MainWindow m_Ui; diff --git a/samplebrain/qt/audio_thread.cpp b/samplebrain/qt/audio_thread.cpp index 57f8cf7..8f2b693 100644 --- a/samplebrain/qt/audio_thread.cpp +++ b/samplebrain/qt/audio_thread.cpp @@ -5,6 +5,7 @@ using namespace spiralcore; using namespace std; audio_thread::audio_thread(process_thread &p) : + m_audio_device(NULL), m_process_thread(p), m_brain_mutex(p.m_brain_mutex), m_osc("8888") @@ -13,6 +14,19 @@ audio_thread::audio_thread(process_thread &p) : m_renderer = new renderer(p.m_source,p.m_target); pthread_mutex_unlock(m_brain_mutex); m_osc.run(); + start_audio(); +} + +void audio_thread::start_audio() { + if (m_audio_device!=NULL) delete m_audio_device; + m_audio_device = new audio_device("samplebrain",44100,2048); + m_audio_device->m_client.set_callback(run_audio, this); +} + +void audio_thread::run_audio(void* c, unsigned int frames) { + audio_thread *at = (audio_thread*)c; + at->m_audio_device->left_out.zero(); + at->process(at->m_audio_device->left_out); } void audio_thread::process(sample &s) { @@ -21,12 +35,32 @@ void audio_thread::process(sample &s) { while (m_osc.get(cmd)) { string name = cmd.m_name; cerr<set_playing(true); + } + if (name=="/stop") { + m_renderer->set_playing(false); + } if (name=="/ratio") { m_renderer->get_params()->m_ratio = cmd.get_float(0); } + if (name=="/fft1_start") { + m_renderer->get_params()->m_fft1_start = cmd.get_int(0); + } + if (name=="/fft1_end") { + m_renderer->get_params()->m_fft1_end = cmd.get_int(0); + } + if (name=="/fft2_start") { + m_renderer->get_params()->m_fft2_start = cmd.get_int(0); + } + if (name=="/fft2_end") { + m_renderer->get_params()->m_fft2_end = cmd.get_int(0); + } + if (name=="/restart_audio") { + start_audio(); + } } - s.zero(); if (!pthread_mutex_trylock(m_brain_mutex)) { m_renderer->process(s.get_length(),s.get_non_const_buffer()); diff --git a/samplebrain/qt/audio_thread.h b/samplebrain/qt/audio_thread.h index 001aff7..4162d28 100644 --- a/samplebrain/qt/audio_thread.h +++ b/samplebrain/qt/audio_thread.h @@ -1,6 +1,7 @@ #include "jellyfish/fluxa/OSC_server.h" #include "process_thread.h" #include "renderer.h" +#include "jellyfish/audio.h" #pragma once @@ -11,7 +12,11 @@ public: audio_thread(process_thread &p); void process(sample &s); + static void run_audio(void* c, unsigned int frames); + audio_device *m_audio_device; + private: + void start_audio(); renderer *m_renderer; OSC_server m_osc; diff --git a/samplebrain/qt/generated/ui_samplebrain.h b/samplebrain/qt/generated/ui_samplebrain.h index aec1ed1..7304627 100644 --- a/samplebrain/qt/generated/ui_samplebrain.h +++ b/samplebrain/qt/generated/ui_samplebrain.h @@ -1,14 +1,14 @@ /******************************************************************************** -** Form generated from reading UI file 'samplebrainxS5241.ui' +** Form generated from reading UI file 'samplebrainHz5241.ui' ** -** Created: Sat Jul 11 12:25:49 2015 +** Created: Sat Jul 11 20:24:05 2015 ** by: Qt User Interface Compiler version 4.8.1 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ -#ifndef SAMPLEBRAINXS5241_H -#define SAMPLEBRAINXS5241_H +#ifndef SAMPLEBRAINHZ5241_H +#define SAMPLEBRAINHZ5241_H #include #include @@ -39,12 +39,11 @@ public: QTabWidget *tabWidget; QWidget *controlTab; QHBoxLayout *horizontalLayout_15; - QVBoxLayout *verticalLayout_7; + QVBoxLayout *verticalLayout_3; QLabel *label_19; QHBoxLayout *horizontalLayout_12; QPushButton *pushButtonPlay; QPushButton *pushButtonStop; - QVBoxLayout *verticalLayout_3; QHBoxLayout *horizontalLayout_16; QLabel *label_6; QDial *dialRatio; @@ -65,10 +64,10 @@ public: QHBoxLayout *horizontalLayout_11; QLabel *label_12; QSpinBox *spinBoxFFT2End; - QSpacerItem *verticalSpacer_3; - QVBoxLayout *verticalLayout_6; QLabel *label_13; + QHBoxLayout *horizontalLayout_17; QDial *dialVolume; + QPushButton *pushButtonRestartAudio; QVBoxLayout *verticalLayout_9; QLabel *label_16; QLabel *label_15; @@ -78,7 +77,7 @@ public: QSpinBox *spinBoxBlockSizeTarget; QHBoxLayout *horizontalLayout_14; QLabel *label_18; - QSpinBox *spinBoxBlockOverlapTarget; + QDoubleSpinBox *doubleSpinBoxBlockOverlapTarget; QPushButton *pushButtonGenerateTarget; QSpacerItem *verticalSpacer; QWidget *sampleTab; @@ -90,7 +89,7 @@ public: QSpinBox *spinBoxBlockSize; QHBoxLayout *horizontalLayout_6; QLabel *label_2; - QSpinBox *spinBoxBlockOverlap; + QDoubleSpinBox *doubleSpinBoxBlockOverlap; QHBoxLayout *horizontalLayout_5; QLabel *label_4; QSpinBox *spinBoxSpectSize; @@ -104,6 +103,8 @@ public: QListWidget *listWidgetSounds; QHBoxLayout *horizontalLayout_2; QPushButton *pushButtonLoadSound; + QPushButton *pushButtonDeleteSound; + QPushButton *pushButtonClearBrain; QStatusBar *statusbar; void setupUi(QMainWindow *MainWindow) @@ -117,47 +118,46 @@ public: horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); tabWidget = new QTabWidget(centralwidget); tabWidget->setObjectName(QString::fromUtf8("tabWidget")); + QFont font; + font.setFamily(QString::fromUtf8("Comic Sans MS")); + font.setBold(true); + font.setWeight(75); + tabWidget->setFont(font); controlTab = new QWidget(); controlTab->setObjectName(QString::fromUtf8("controlTab")); horizontalLayout_15 = new QHBoxLayout(controlTab); horizontalLayout_15->setObjectName(QString::fromUtf8("horizontalLayout_15")); - verticalLayout_7 = new QVBoxLayout(); - verticalLayout_7->setObjectName(QString::fromUtf8("verticalLayout_7")); + verticalLayout_3 = new QVBoxLayout(); + verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3")); label_19 = new QLabel(controlTab); label_19->setObjectName(QString::fromUtf8("label_19")); - QFont font; - font.setFamily(QString::fromUtf8("Comic Sans MS")); - font.setPointSize(20); - font.setBold(true); - font.setWeight(75); - label_19->setFont(font); + QFont font1; + font1.setFamily(QString::fromUtf8("Comic Sans MS")); + font1.setPointSize(20); + font1.setBold(true); + font1.setWeight(75); + label_19->setFont(font1); - verticalLayout_7->addWidget(label_19); + verticalLayout_3->addWidget(label_19); horizontalLayout_12 = new QHBoxLayout(); horizontalLayout_12->setObjectName(QString::fromUtf8("horizontalLayout_12")); pushButtonPlay = new QPushButton(controlTab); pushButtonPlay->setObjectName(QString::fromUtf8("pushButtonPlay")); - QFont font1; - font1.setFamily(QString::fromUtf8("Comic Sans MS")); - font1.setBold(true); - font1.setWeight(75); - pushButtonPlay->setFont(font1); + pushButtonPlay->setFont(font); pushButtonPlay->setFlat(false); horizontalLayout_12->addWidget(pushButtonPlay); pushButtonStop = new QPushButton(controlTab); pushButtonStop->setObjectName(QString::fromUtf8("pushButtonStop")); - pushButtonStop->setFont(font1); + pushButtonStop->setFont(font); horizontalLayout_12->addWidget(pushButtonStop); - verticalLayout_7->addLayout(horizontalLayout_12); + verticalLayout_3->addLayout(horizontalLayout_12); - verticalLayout_3 = new QVBoxLayout(); - verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3")); horizontalLayout_16 = new QHBoxLayout(); horizontalLayout_16->setObjectName(QString::fromUtf8("horizontalLayout_16")); label_6 = new QLabel(controlTab); @@ -188,6 +188,9 @@ public: doubleSpinBoxRatio = new QDoubleSpinBox(controlTab); doubleSpinBoxRatio->setObjectName(QString::fromUtf8("doubleSpinBoxRatio")); + doubleSpinBoxRatio->setMaximum(1); + doubleSpinBoxRatio->setSingleStep(0.01); + doubleSpinBoxRatio->setValue(0.5); verticalLayout_3->addWidget(doubleSpinBoxRatio); @@ -203,7 +206,7 @@ public: horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3")); label_9 = new QLabel(controlTab); label_9->setObjectName(QString::fromUtf8("label_9")); - label_9->setFont(font1); + label_9->setFont(font); horizontalLayout_3->addWidget(label_9); @@ -219,12 +222,13 @@ public: horizontalLayout_9->setObjectName(QString::fromUtf8("horizontalLayout_9")); label_10 = new QLabel(controlTab); label_10->setObjectName(QString::fromUtf8("label_10")); - label_10->setFont(font1); + label_10->setFont(font); horizontalLayout_9->addWidget(label_10); spinBoxFFT1End = new QSpinBox(controlTab); spinBoxFFT1End->setObjectName(QString::fromUtf8("spinBoxFFT1End")); + spinBoxFFT1End->setValue(99); horizontalLayout_9->addWidget(spinBoxFFT1End); @@ -246,7 +250,7 @@ public: horizontalLayout_10->setObjectName(QString::fromUtf8("horizontalLayout_10")); label_11 = new QLabel(controlTab); label_11->setObjectName(QString::fromUtf8("label_11")); - label_11->setFont(font1); + label_11->setFont(font); horizontalLayout_10->addWidget(label_11); @@ -262,12 +266,13 @@ public: horizontalLayout_11->setObjectName(QString::fromUtf8("horizontalLayout_11")); label_12 = new QLabel(controlTab); label_12->setObjectName(QString::fromUtf8("label_12")); - label_12->setFont(font1); + label_12->setFont(font); horizontalLayout_11->addWidget(label_12); spinBoxFFT2End = new QSpinBox(controlTab); spinBoxFFT2End->setObjectName(QString::fromUtf8("spinBoxFFT2End")); + spinBoxFFT2End->setValue(99); horizontalLayout_11->addWidget(spinBoxFFT2End); @@ -277,50 +282,49 @@ public: verticalLayout_3->addLayout(verticalLayout_5); - - verticalLayout_7->addLayout(verticalLayout_3); - - verticalSpacer_3 = new QSpacerItem(323, 511, QSizePolicy::Minimum, QSizePolicy::Expanding); - - verticalLayout_7->addItem(verticalSpacer_3); - - verticalLayout_6 = new QVBoxLayout(); - verticalLayout_6->setObjectName(QString::fromUtf8("verticalLayout_6")); label_13 = new QLabel(controlTab); label_13->setObjectName(QString::fromUtf8("label_13")); - label_13->setFont(font1); + label_13->setFont(font); - verticalLayout_6->addWidget(label_13); + verticalLayout_3->addWidget(label_13); + horizontalLayout_17 = new QHBoxLayout(); + horizontalLayout_17->setObjectName(QString::fromUtf8("horizontalLayout_17")); dialVolume = new QDial(controlTab); dialVolume->setObjectName(QString::fromUtf8("dialVolume")); dialVolume->setValue(99); - verticalLayout_6->addWidget(dialVolume); + horizontalLayout_17->addWidget(dialVolume); + + pushButtonRestartAudio = new QPushButton(controlTab); + pushButtonRestartAudio->setObjectName(QString::fromUtf8("pushButtonRestartAudio")); + pushButtonRestartAudio->setFont(font); + + horizontalLayout_17->addWidget(pushButtonRestartAudio); - verticalLayout_7->addLayout(verticalLayout_6); + verticalLayout_3->addLayout(horizontalLayout_17); - horizontalLayout_15->addLayout(verticalLayout_7); + horizontalLayout_15->addLayout(verticalLayout_3); verticalLayout_9 = new QVBoxLayout(); verticalLayout_9->setObjectName(QString::fromUtf8("verticalLayout_9")); label_16 = new QLabel(controlTab); label_16->setObjectName(QString::fromUtf8("label_16")); - label_16->setFont(font); + label_16->setFont(font1); verticalLayout_9->addWidget(label_16); label_15 = new QLabel(controlTab); label_15->setObjectName(QString::fromUtf8("label_15")); - label_15->setFont(font1); + label_15->setFont(font); verticalLayout_9->addWidget(label_15); pushButtonLoadTarget = new QPushButton(controlTab); pushButtonLoadTarget->setObjectName(QString::fromUtf8("pushButtonLoadTarget")); - pushButtonLoadTarget->setFont(font1); + pushButtonLoadTarget->setFont(font); verticalLayout_9->addWidget(pushButtonLoadTarget); @@ -328,12 +332,14 @@ public: horizontalLayout_13->setObjectName(QString::fromUtf8("horizontalLayout_13")); label_17 = new QLabel(controlTab); label_17->setObjectName(QString::fromUtf8("label_17")); - label_17->setFont(font1); + label_17->setFont(font); horizontalLayout_13->addWidget(label_17); spinBoxBlockSizeTarget = new QSpinBox(controlTab); spinBoxBlockSizeTarget->setObjectName(QString::fromUtf8("spinBoxBlockSizeTarget")); + spinBoxBlockSizeTarget->setMaximum(99999); + spinBoxBlockSizeTarget->setValue(3000); horizontalLayout_13->addWidget(spinBoxBlockSizeTarget); @@ -344,21 +350,24 @@ public: horizontalLayout_14->setObjectName(QString::fromUtf8("horizontalLayout_14")); label_18 = new QLabel(controlTab); label_18->setObjectName(QString::fromUtf8("label_18")); - label_18->setFont(font1); + label_18->setFont(font); horizontalLayout_14->addWidget(label_18); - spinBoxBlockOverlapTarget = new QSpinBox(controlTab); - spinBoxBlockOverlapTarget->setObjectName(QString::fromUtf8("spinBoxBlockOverlapTarget")); + doubleSpinBoxBlockOverlapTarget = new QDoubleSpinBox(controlTab); + doubleSpinBoxBlockOverlapTarget->setObjectName(QString::fromUtf8("doubleSpinBoxBlockOverlapTarget")); + doubleSpinBoxBlockOverlapTarget->setMaximum(1); + doubleSpinBoxBlockOverlapTarget->setSingleStep(0.01); + doubleSpinBoxBlockOverlapTarget->setValue(0.75); - horizontalLayout_14->addWidget(spinBoxBlockOverlapTarget); + horizontalLayout_14->addWidget(doubleSpinBoxBlockOverlapTarget); verticalLayout_9->addLayout(horizontalLayout_14); pushButtonGenerateTarget = new QPushButton(controlTab); pushButtonGenerateTarget->setObjectName(QString::fromUtf8("pushButtonGenerateTarget")); - pushButtonGenerateTarget->setFont(font1); + pushButtonGenerateTarget->setFont(font); verticalLayout_9->addWidget(pushButtonGenerateTarget); @@ -378,7 +387,7 @@ public: verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); label_3 = new QLabel(sampleTab); label_3->setObjectName(QString::fromUtf8("label_3")); - label_3->setFont(font); + label_3->setFont(font1); verticalLayout_2->addWidget(label_3); @@ -386,12 +395,14 @@ public: horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4")); label = new QLabel(sampleTab); label->setObjectName(QString::fromUtf8("label")); - label->setFont(font1); + label->setFont(font); horizontalLayout_4->addWidget(label); spinBoxBlockSize = new QSpinBox(sampleTab); spinBoxBlockSize->setObjectName(QString::fromUtf8("spinBoxBlockSize")); + spinBoxBlockSize->setMaximum(99999); + spinBoxBlockSize->setValue(3000); horizontalLayout_4->addWidget(spinBoxBlockSize); @@ -402,14 +413,17 @@ public: horizontalLayout_6->setObjectName(QString::fromUtf8("horizontalLayout_6")); label_2 = new QLabel(sampleTab); label_2->setObjectName(QString::fromUtf8("label_2")); - label_2->setFont(font1); + label_2->setFont(font); horizontalLayout_6->addWidget(label_2); - spinBoxBlockOverlap = new QSpinBox(sampleTab); - spinBoxBlockOverlap->setObjectName(QString::fromUtf8("spinBoxBlockOverlap")); + doubleSpinBoxBlockOverlap = new QDoubleSpinBox(sampleTab); + doubleSpinBoxBlockOverlap->setObjectName(QString::fromUtf8("doubleSpinBoxBlockOverlap")); + doubleSpinBoxBlockOverlap->setMaximum(1); + doubleSpinBoxBlockOverlap->setSingleStep(0.01); + doubleSpinBoxBlockOverlap->setValue(0.75); - horizontalLayout_6->addWidget(spinBoxBlockOverlap); + horizontalLayout_6->addWidget(doubleSpinBoxBlockOverlap); verticalLayout_2->addLayout(horizontalLayout_6); @@ -418,7 +432,7 @@ public: horizontalLayout_5->setObjectName(QString::fromUtf8("horizontalLayout_5")); label_4 = new QLabel(sampleTab); label_4->setObjectName(QString::fromUtf8("label_4")); - label_4->setFont(font1); + label_4->setFont(font); horizontalLayout_5->addWidget(label_4); @@ -432,7 +446,7 @@ public: pushButtonGenerate = new QPushButton(sampleTab); pushButtonGenerate->setObjectName(QString::fromUtf8("pushButtonGenerate")); - pushButtonGenerate->setFont(font1); + pushButtonGenerate->setFont(font); verticalLayout_2->addWidget(pushButtonGenerate); @@ -440,13 +454,13 @@ public: horizontalLayout_7->setObjectName(QString::fromUtf8("horizontalLayout_7")); pushButtonLosdBrain = new QPushButton(sampleTab); pushButtonLosdBrain->setObjectName(QString::fromUtf8("pushButtonLosdBrain")); - pushButtonLosdBrain->setFont(font1); + pushButtonLosdBrain->setFont(font); horizontalLayout_7->addWidget(pushButtonLosdBrain); pushButtonSaveBrain = new QPushButton(sampleTab); pushButtonSaveBrain->setObjectName(QString::fromUtf8("pushButtonSaveBrain")); - pushButtonSaveBrain->setFont(font1); + pushButtonSaveBrain->setFont(font); horizontalLayout_7->addWidget(pushButtonSaveBrain); @@ -464,7 +478,7 @@ public: verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); label_5 = new QLabel(sampleTab); label_5->setObjectName(QString::fromUtf8("label_5")); - label_5->setFont(font1); + label_5->setFont(font); verticalLayout->addWidget(label_5); @@ -477,10 +491,22 @@ public: horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); pushButtonLoadSound = new QPushButton(sampleTab); pushButtonLoadSound->setObjectName(QString::fromUtf8("pushButtonLoadSound")); - pushButtonLoadSound->setFont(font1); + pushButtonLoadSound->setFont(font); horizontalLayout_2->addWidget(pushButtonLoadSound); + pushButtonDeleteSound = new QPushButton(sampleTab); + pushButtonDeleteSound->setObjectName(QString::fromUtf8("pushButtonDeleteSound")); + pushButtonDeleteSound->setFont(font); + + horizontalLayout_2->addWidget(pushButtonDeleteSound); + + pushButtonClearBrain = new QPushButton(sampleTab); + pushButtonClearBrain->setObjectName(QString::fromUtf8("pushButtonClearBrain")); + pushButtonClearBrain->setFont(font); + + horizontalLayout_2->addWidget(pushButtonClearBrain); + verticalLayout->addLayout(horizontalLayout_2); @@ -507,14 +533,17 @@ public: QObject::connect(spinBoxFFT2End, SIGNAL(valueChanged(int)), MainWindow, SLOT(fft2_end_slot(int))); QObject::connect(pushButtonLoadTarget, SIGNAL(released()), MainWindow, SLOT(load_target())); QObject::connect(spinBoxBlockSizeTarget, SIGNAL(valueChanged(int)), MainWindow, SLOT(target_block_size(int))); - QObject::connect(spinBoxBlockOverlapTarget, SIGNAL(valueChanged(int)), MainWindow, SLOT(target_block_overlap(int))); QObject::connect(pushButtonGenerateTarget, SIGNAL(released()), MainWindow, SLOT(generate_target_blocks())); QObject::connect(spinBoxBlockSize, SIGNAL(valueChanged(int)), MainWindow, SLOT(block_size(int))); - QObject::connect(spinBoxBlockOverlap, SIGNAL(valueChanged(int)), MainWindow, SLOT(block_overlap(int))); QObject::connect(spinBoxSpectSize, SIGNAL(valueChanged(int)), MainWindow, SLOT(fft_spectrum_size(int))); QObject::connect(pushButtonGenerate, SIGNAL(released()), MainWindow, SLOT(generate())); QObject::connect(pushButtonLoadSound, SIGNAL(released()), MainWindow, SLOT(load_sound())); QObject::connect(dialVolume, SIGNAL(sliderMoved(int)), MainWindow, SLOT(volume_slot(int))); + QObject::connect(doubleSpinBoxBlockOverlap, SIGNAL(valueChanged(double)), MainWindow, SLOT(block_overlap(double))); + QObject::connect(doubleSpinBoxBlockOverlapTarget, SIGNAL(valueChanged(double)), MainWindow, SLOT(target_block_overlap(double))); + QObject::connect(pushButtonClearBrain, SIGNAL(released()), MainWindow, SLOT(clear_brain())); + QObject::connect(pushButtonDeleteSound, SIGNAL(released()), MainWindow, SLOT(delete_sound())); + QObject::connect(pushButtonRestartAudio, SIGNAL(released()), MainWindow, SLOT(restart_audio())); tabWidget->setCurrentIndex(0); @@ -536,22 +565,25 @@ public: label_11->setText(QApplication::translate("MainWindow", "Start", 0, QApplication::UnicodeUTF8)); label_12->setText(QApplication::translate("MainWindow", "End", 0, QApplication::UnicodeUTF8)); label_13->setText(QApplication::translate("MainWindow", "Volume", 0, QApplication::UnicodeUTF8)); + pushButtonRestartAudio->setText(QApplication::translate("MainWindow", "restart audio", 0, QApplication::UnicodeUTF8)); label_16->setText(QApplication::translate("MainWindow", "target sound", 0, QApplication::UnicodeUTF8)); label_15->setText(QApplication::translate("MainWindow", "no sound yet...", 0, QApplication::UnicodeUTF8)); pushButtonLoadTarget->setText(QApplication::translate("MainWindow", "load target", 0, QApplication::UnicodeUTF8)); label_17->setText(QApplication::translate("MainWindow", "block size", 0, QApplication::UnicodeUTF8)); label_18->setText(QApplication::translate("MainWindow", "block overlap", 0, QApplication::UnicodeUTF8)); - pushButtonGenerateTarget->setText(QApplication::translate("MainWindow", "generate blocks", 0, QApplication::UnicodeUTF8)); + pushButtonGenerateTarget->setText(QApplication::translate("MainWindow", "(re)generate blocks", 0, QApplication::UnicodeUTF8)); tabWidget->setTabText(tabWidget->indexOf(controlTab), QApplication::translate("MainWindow", "search", 0, QApplication::UnicodeUTF8)); label_3->setText(QApplication::translate("MainWindow", "brain parameters", 0, QApplication::UnicodeUTF8)); label->setText(QApplication::translate("MainWindow", "block size", 0, QApplication::UnicodeUTF8)); label_2->setText(QApplication::translate("MainWindow", "block overlap", 0, QApplication::UnicodeUTF8)); label_4->setText(QApplication::translate("MainWindow", "fft spectrum size", 0, QApplication::UnicodeUTF8)); - pushButtonGenerate->setText(QApplication::translate("MainWindow", "generate", 0, QApplication::UnicodeUTF8)); + pushButtonGenerate->setText(QApplication::translate("MainWindow", "(re)generate", 0, QApplication::UnicodeUTF8)); pushButtonLosdBrain->setText(QApplication::translate("MainWindow", "load", 0, QApplication::UnicodeUTF8)); pushButtonSaveBrain->setText(QApplication::translate("MainWindow", "save", 0, QApplication::UnicodeUTF8)); label_5->setText(QApplication::translate("MainWindow", "brain contents", 0, QApplication::UnicodeUTF8)); pushButtonLoadSound->setText(QApplication::translate("MainWindow", "load sound", 0, QApplication::UnicodeUTF8)); + pushButtonDeleteSound->setText(QApplication::translate("MainWindow", "delete selected", 0, QApplication::UnicodeUTF8)); + pushButtonClearBrain->setText(QApplication::translate("MainWindow", "clear brain", 0, QApplication::UnicodeUTF8)); tabWidget->setTabText(tabWidget->indexOf(sampleTab), QApplication::translate("MainWindow", "brain", 0, QApplication::UnicodeUTF8)); } // retranslateUi @@ -563,4 +595,4 @@ namespace Ui { QT_END_NAMESPACE -#endif // SAMPLEBRAINXS5241_H +#endif // SAMPLEBRAINHZ5241_H diff --git a/samplebrain/qt/process_thread.cpp b/samplebrain/qt/process_thread.cpp index 3dba804..78ebaf8 100644 --- a/samplebrain/qt/process_thread.cpp +++ b/samplebrain/qt/process_thread.cpp @@ -4,8 +4,18 @@ using namespace spiralcore; using namespace std; +static void _process(void *c) { + process_thread *p=(process_thread*)c; + p->process(); +} + process_thread::process_thread() : - m_osc("8889") + m_osc("8889"), + m_source_block_size(3000), + m_source_overlap(0.75), + m_target_block_size(3000), + m_target_overlap(0.75), + m_env(50) { m_brain_mutex = new pthread_mutex_t; pthread_mutex_init(m_brain_mutex,NULL); @@ -13,20 +23,57 @@ process_thread::process_thread() : // start the processing thread pthread_t *thread = new pthread_t; - pthread_create(thread,NULL,(void*(*)(void*))process_thread::process,this); + pthread_create(thread,NULL,(void*(*)(void*))_process,this); } -void process_thread::process(void *c) { - process_thread *p=(process_thread*)c; +void process_thread::process() { command_ring_buffer::command cmd; while(true) { - while (p->m_osc.get(cmd)) { + while (m_osc.get(cmd)) { string name = cmd.m_name; cerr<init_brain(); + init_brain(); + } + if (name=="/load_sample") { + pthread_mutex_lock(m_brain_mutex); + m_source.load_sound(cmd.get_string(0)); + pthread_mutex_unlock(m_brain_mutex); + } + if (name=="/delete_sample") { + pthread_mutex_lock(m_brain_mutex); + m_source.delete_sound(cmd.get_string(0)); + pthread_mutex_unlock(m_brain_mutex); + } + if (name=="/source_block_size") { + m_source_block_size = cmd.get_int(0); + } + if (name=="/source_overlap") { + m_source_overlap = m_source_block_size-m_source_block_size/cmd.get_float(0); + } + if (name=="/generate_brain") { + pthread_mutex_lock(m_brain_mutex); + m_source.init(m_source_block_size, m_source_overlap, m_env); + pthread_mutex_unlock(m_brain_mutex); + } + if (name=="/load_target") { + pthread_mutex_lock(m_brain_mutex); + m_target.clear_sounds(); + m_target.load_sound(cmd.get_string(0)); + pthread_mutex_unlock(m_brain_mutex); + } + if (name=="/target_block_size") { + m_target_block_size = cmd.get_int(0); + } + if (name=="/target_overlap") { + m_target_overlap = m_target_block_size-m_target_block_size/cmd.get_float(0); + } + if (name=="/generate_target") { + pthread_mutex_lock(m_brain_mutex); + m_target.init(m_target_block_size, m_target_overlap, m_env); + pthread_mutex_unlock(m_brain_mutex); } } usleep(500); @@ -34,6 +81,7 @@ void process_thread::process(void *c) { } + void process_thread::init_brain() { pthread_mutex_lock(m_brain_mutex); diff --git a/samplebrain/qt/process_thread.h b/samplebrain/qt/process_thread.h index 63ace61..a377a1a 100644 --- a/samplebrain/qt/process_thread.h +++ b/samplebrain/qt/process_thread.h @@ -14,9 +14,15 @@ public: brain m_source, m_target; pthread_mutex_t* m_brain_mutex; + void process(); + private: - static void process(void *c); OSC_server m_osc; + u32 m_source_block_size; + float m_source_overlap; + u32 m_target_block_size; + float m_target_overlap; + float m_env; }; } diff --git a/samplebrain/qt/qtmain.cpp b/samplebrain/qt/qtmain.cpp index 8ca302f..a2b0da7 100644 --- a/samplebrain/qt/qtmain.cpp +++ b/samplebrain/qt/qtmain.cpp @@ -5,21 +5,11 @@ #include #include "MainWindow.h" -#include "jellyfish/audio.h" - #include "process_thread.h" #include "audio_thread.h" using namespace std; -audio_device *a = NULL; - -void run_audio(void* c, unsigned int frames) { - audio_thread *at = (audio_thread*)c; - a->left_out.zero(); - at->process(a->left_out); -} - int main( int argc , char *argv[] ){ QApplication app(argc, argv); MainWindow mainWin; @@ -28,8 +18,5 @@ int main( int argc , char *argv[] ){ process_thread pt; audio_thread at(pt); - a = new audio_device("samplebrain",44100,2048); - a->m_client.set_callback(run_audio, &at); - return app.exec(); } diff --git a/samplebrain/src/brain.cpp b/samplebrain/src/brain.cpp index 964b4bf..d7c65bb 100644 --- a/samplebrain/src/brain.cpp +++ b/samplebrain/src/brain.cpp @@ -11,15 +11,24 @@ brain::brain() // load, chop up and add to brain // todo: add tags -sample brain::load_sound(std::string filename) { +void brain::load_sound(std::string filename) { SF_INFO sfinfo; sfinfo.format=0; SNDFILE* f=sf_open(filename.c_str(), SFM_READ, &sfinfo); - sample s(sfinfo.frames); - sf_readf_float(f, s.get_non_const_buffer(), s.get_length()); - sf_close(f); - m_samples.push_back(s); - return s; + if (f!=NULL) { + sample s(sfinfo.frames); + sf_readf_float(f, s.get_non_const_buffer(), s.get_length()); + m_samples.push_back(sound(filename,s)); + } +} + +void brain::delete_sound(std::string filename) { + for (std::list::iterator i=m_samples.begin(); i!=m_samples.end(); ++i) { + if (i->m_filename==filename) { + m_samples.erase(i); + return; + } + } } void save_sample(const string &filename, const sample s) { @@ -42,8 +51,8 @@ void brain::init(u32 block_size, u32 overlap, u32 env, bool ditchpcm) { m_blocks.clear(); m_block_size = block_size; m_overlap = overlap; - for (vector::iterator i=m_samples.begin(); i!=m_samples.end(); ++i) { - chop_and_add(*i, block_size, overlap, env, ditchpcm); + for (std::list::iterator i=m_samples.begin(); i!=m_samples.end(); ++i) { + chop_and_add(i->m_sample, block_size, overlap, env, ditchpcm); } } @@ -115,16 +124,10 @@ bool brain::unit_test() { assert(b.m_samples.size()==0); assert(b.m_blocks.size()==0); - sample s=b.load_sound("test_data/100f32.wav"); - assert(b.m_samples.size()==1); - assert(s.get_length()==100); - - s=b.load_sound("test_data/100i16.wav"); + b.load_sound("test_data/100f32.wav"); + b.load_sound("test_data/100i16.wav"); assert(b.m_samples.size()==2); - assert(s.get_length()==100); - b.init(10, 0, 0); - assert(b.m_samples.size()==2); assert(b.m_blocks.size()==20); b.init(10, 5, 0); assert(b.m_samples.size()==2); diff --git a/samplebrain/src/brain.h b/samplebrain/src/brain.h index 5b4f7f4..d890e81 100644 --- a/samplebrain/src/brain.h +++ b/samplebrain/src/brain.h @@ -1,3 +1,4 @@ +#include #include #include #include "jellyfish/core/types.h" @@ -17,9 +18,20 @@ public: // rewrites whole brain void init(u32 block_size, u32 overlap, u32 env, bool ditchpcm=false); + class sound { + public: + sound(const std::string &name, const sample &sample) : + m_filename(name), m_sample(sample) {} + + std::string m_filename; + sample m_sample; + }; + // load, chop up and add to brain // todo: add tags - sample load_sound(std::string filename); + void load_sound(std::string filename); + void delete_sound(std::string filename); + void clear_sounds() { m_samples.clear(); } // take another brain and rebuild this brain from bits of that one // (presumably this one is made from a single sample) void resynth(const std::string &filename, const brain &other, const search_params ¶ms); @@ -39,7 +51,7 @@ private: void chop_and_add(const sample &s, u32 block_size, u32 overlap, u32 env, bool ditchpcm=false); vector m_blocks; - vector m_samples; + std::list m_samples; u32 m_block_size; u32 m_overlap;