diff --git a/samplebrain/qt/MainWindow.cpp b/samplebrain/qt/MainWindow.cpp index 5a663ec..aad208c 100644 --- a/samplebrain/qt/MainWindow.cpp +++ b/samplebrain/qt/MainWindow.cpp @@ -28,25 +28,26 @@ MainWindow::MainWindow() : m_last_file("."), m_feedback("8890") { - m_Ui.setupUi(this); - setUnifiedTitleAndToolBarOnMac(true); + m_sound_item_enable_mapper = new QSignalMapper(this); + m_sound_item_delete_mapper = new QSignalMapper(this); - m_sound_item_enable_mapper = new QSignalMapper(this); - m_sound_item_delete_mapper = new QSignalMapper(this); - m_Ui.brain_contents->setAlignment(Qt::AlignTop); - m_Ui.brain_contents->setSpacing(0); - m_Ui.brain_contents->setMargin(0); - m_Ui.brain_contents->setContentsMargins(0,0,0,0); - connect(m_sound_item_enable_mapper, - SIGNAL(mapped(int)), this, SLOT(sound_enable(int))); - connect(m_sound_item_delete_mapper, - SIGNAL(mapped(int)), this, SLOT(delete_sound(int))); - m_current_sound_id=0; + connect(m_sound_item_enable_mapper, + SIGNAL(mapped(int)), this, SLOT(sound_enable(int))); + connect(m_sound_item_delete_mapper, + SIGNAL(mapped(int)), this, SLOT(delete_sound(int))); + + m_Ui.setupUi(this); + setUnifiedTitleAndToolBarOnMac(true); + + m_Ui.brain_contents->setAlignment(Qt::AlignTop); + m_Ui.brain_contents->setSpacing(0); + m_Ui.brain_contents->setMargin(0); + m_Ui.brain_contents->setContentsMargins(0,0,0,0); // add default local dest // turn on first one - QSignalMapper* enable_mapper = new QSignalMapper(this); + QSignalMapper* enable_mapper = new QSignalMapper(this); for (int i=0; i<10; i++) { osc_destination d; @@ -156,11 +157,17 @@ void MainWindow::init_from_session(const string &filename) { m_Ui.comboBoxBrainShape->setCurrentIndex(source_window); // brain samples - clear_sound_items(); + m_sound_items.clear(); for (auto &i:s.get_samples()) { - add_sound_item(i.m_filename,i.m_enabled); - } + sound_items::sound_item &si = m_sound_items.add(m_Ui.brain_contents,i.m_filename,i.m_enabled); + 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); + } + // todo: might contain unprocessed samples in colour scheme + m_sound_items.recolour(); // mix m_Ui.sliderTargetMix->setValue(r.get_target_mix()*100); @@ -173,80 +180,3 @@ void MainWindow::init_from_session(const string &filename) { } - - -void MainWindow::add_sound_item(const string &name, bool enabled) { - sound_item si; - si.m_filename = name; - si.m_id = m_current_sound_id++; - QString style("background-color:lightblue;"); - if (m_sound_items.size()%2==0) style="background-color:pink;"; - - si.m_container = new QHBoxLayout(); - si.m_enable = new QCheckBox(); - si.m_enable->setChecked(enabled); - si.m_enable->setStyleSheet(style); - si.m_container->addWidget(si.m_enable); - - si.m_label = new QLabel(); - QFileInfo fi(QString::fromStdString(name)); - si.m_label->setText(fi.fileName()); - si.m_label->setStyleSheet(style); - si.m_label->setSizePolicy(QSizePolicy::MinimumExpanding, - QSizePolicy::Minimum); - si.m_container->addWidget(si.m_label); - - si.m_del = new QPushButton(); - si.m_del->setText("x"); - si.m_del->setMaximumWidth(20); - si.m_del->setMaximumHeight(20); - si.m_del->setStyleSheet(style); - si.m_container->addWidget(si.m_del); - - m_Ui.brain_contents->addLayout(si.m_container); - - 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); - - m_sound_items.push_back(si); -} - -void MainWindow::clear_sound_items() { - for (auto &si:m_sound_items) { - delete si.m_enable; - delete si.m_del; - delete si.m_label; - delete si.m_container; - } - m_sound_items.clear(); -} - -void MainWindow::recolour_sound_items() { - u32 c=0; - for (auto &si:m_sound_items) { - QString style("background-color:lightblue;"); - if (c%2==0) style="background-color:pink;"; - si.m_enable->setStyleSheet(style); - si.m_del->setStyleSheet(style); - si.m_label->setStyleSheet(style); - c++; - } -} - -void MainWindow::delete_sound_item(const string &name) { - for (auto i=m_sound_items.begin(); i!=m_sound_items.end(); ++i) { - if (i->m_filename==name) { - // not sure why deleteLater-ing the container does not - // remove the children (like it does with delete) - i->m_container->deleteLater(); - i->m_enable->deleteLater(); - i->m_label->deleteLater(); - i->m_del->deleteLater(); - m_sound_items.erase(i); - recolour_sound_items(); - return; - } - } -} diff --git a/samplebrain/qt/MainWindow.h b/samplebrain/qt/MainWindow.h index e120082..95cc557 100644 --- a/samplebrain/qt/MainWindow.h +++ b/samplebrain/qt/MainWindow.h @@ -23,6 +23,7 @@ #include #include "window.h" #include "feedback.h" +#include "sound_items.h" using namespace std; using namespace spiralcore; @@ -156,12 +157,17 @@ private slots: send_process_osc("/load_sample","s",m_last_file.toStdString().c_str()); - add_sound_item(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 sound_enable(int id) { // search for this id... - for (auto si:m_sound_items) { + 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()); @@ -174,10 +180,10 @@ private slots: void delete_sound(int id) { // search for this id... - for (auto &si:m_sound_items) { + 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()); - delete_sound_item(si.m_filename); + m_sound_items.remove(si.m_filename); // iterator is now invalidated... return; } @@ -186,10 +192,10 @@ private slots: void clear_brain() { cerr<<"clear brain"< m_sound_items; - - void add_sound_item(const string &name, bool enabled); - void delete_sound_item(const string &name); - void clear_sound_items(); - void recolour_sound_items(); //////////////////////////////////////////////// @@ -378,8 +367,9 @@ private: u32 m_record_id; Ui_MainWindow m_Ui; feedback m_feedback; - - int m_current_sound_id; QSignalMapper* m_sound_item_enable_mapper; QSignalMapper* m_sound_item_delete_mapper; + sound_items m_sound_items; + + }; diff --git a/samplebrain/qt/feedback.cpp b/samplebrain/qt/feedback.cpp index db58fa1..30d4887 100644 --- a/samplebrain/qt/feedback.cpp +++ b/samplebrain/qt/feedback.cpp @@ -15,6 +15,7 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "feedback.h" +#include "sound_items.h" #include using namespace spiralcore; @@ -27,13 +28,20 @@ feedback::feedback(string address) : } -void feedback::poll(QStatusBar *s) { +void feedback::poll(QStatusBar *s, sound_items *sound_items) { command_ring_buffer::command cmd; while (m_osc.get(cmd)) { string name = cmd.m_name; if (name=="/report") { - s->showMessage(QString(cmd.get_string(0))); + s->showMessage(QString(cmd.get_string(0))); + } + if (name=="/sound-item") { + sound_items->change_colour(cmd.get_string(0), + cmd.get_string(1)); + } + if (name=="/sound-item-refresh") { + sound_items->recolour(); } } } diff --git a/samplebrain/qt/feedback.h b/samplebrain/qt/feedback.h index a21149e..1d9a347 100644 --- a/samplebrain/qt/feedback.h +++ b/samplebrain/qt/feedback.h @@ -21,11 +21,12 @@ #pragma once namespace spiralcore { +class sound_items; class feedback { public: feedback(std::string address); - void poll(QStatusBar *s); + void poll(QStatusBar *s, sound_items *sound_items); private: diff --git a/samplebrain/qt/samplebrain.pro b/samplebrain/qt/samplebrain.pro index 16524f0..d8caea6 100644 --- a/samplebrain/qt/samplebrain.pro +++ b/samplebrain/qt/samplebrain.pro @@ -14,6 +14,7 @@ HEADERS += MainWindow.h \ generated/ui_samplebrain.h \ SOURCES += MainWindow.cpp \ + sound_items.cpp \ audio_thread.cpp \ process_thread.cpp \ feedback.cpp \ diff --git a/samplebrain/qt/sound_items.cpp b/samplebrain/qt/sound_items.cpp new file mode 100644 index 0000000..3c07f7f --- /dev/null +++ b/samplebrain/qt/sound_items.cpp @@ -0,0 +1,113 @@ +// Copyright (C) 2016 Foam Kernow +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include +#include +#include +#include "jellyfish/core/types.h" + +#include "sound_items.h" + +using namespace spiralcore; +using namespace std; + +sound_items::sound_items(): + m_current_sound_id(0) +{ +} + +sound_items::sound_item &sound_items::add(QVBoxLayout *container, const string &name, bool enabled) { + sound_item si; + si.m_filename = name; + si.m_id = m_current_sound_id++; + QString style("background-color:lightgrey;"); + + si.m_container = new QHBoxLayout(); + si.m_enable = new QCheckBox(); + si.m_enable->setChecked(enabled); + si.m_enable->setStyleSheet(style); + si.m_container->addWidget(si.m_enable); + + si.m_label = new QLabel(); + QFileInfo fi(QString::fromStdString(name)); + si.m_label->setText(fi.fileName()); + si.m_label->setStyleSheet(style); + si.m_label->setSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::Minimum); + si.m_container->addWidget(si.m_label); + + si.m_del = new QPushButton(); + si.m_del->setText("x"); + si.m_del->setMaximumWidth(20); + si.m_del->setMaximumHeight(20); + si.m_del->setStyleSheet(style); + si.m_container->addWidget(si.m_del); + + container->addLayout(si.m_container); + + m_sound_items.push_back(si); + return m_sound_items[m_sound_items.size()-1]; +} + +void sound_items::clear() { + for (auto &si:m_sound_items) { + delete si.m_enable; + delete si.m_del; + delete si.m_label; + delete si.m_container; + } + m_sound_items.clear(); +} + +void sound_items::recolour() { + u32 c=0; + for (auto &si:m_sound_items) { + QString style("background-color:lightblue;"); + if (c%2==0) style="background-color:pink;"; + si.m_enable->setStyleSheet(style); + si.m_del->setStyleSheet(style); + si.m_label->setStyleSheet(style); + c++; + } +} + +void sound_items::change_colour(const std::string &name, const std::string &colour) { + for (auto &si:m_sound_items) { + if (si.m_filename==name) { + QString style("background-color:"+QString::fromStdString(colour)+";"); + si.m_enable->setStyleSheet(style); + si.m_del->setStyleSheet(style); + si.m_label->setStyleSheet(style); + } + } +} + + +void sound_items::remove(const string &name) { + for (auto i=m_sound_items.begin(); i!=m_sound_items.end(); ++i) { + if (i->m_filename==name) { + // not sure why deleteLater-ing the container does not + // remove the children (like it does with delete) + i->m_container->deleteLater(); + i->m_enable->deleteLater(); + i->m_label->deleteLater(); + i->m_del->deleteLater(); + m_sound_items.erase(i); + recolour(); + return; + } + } +} diff --git a/samplebrain/qt/sound_items.h b/samplebrain/qt/sound_items.h new file mode 100644 index 0000000..d0be7a0 --- /dev/null +++ b/samplebrain/qt/sound_items.h @@ -0,0 +1,56 @@ +// Copyright (C) 2016 Foam Kernow +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include +#include +#include +#include + +#pragma once + +namespace spiralcore { + +class sound_items { + public: + sound_items(); + + class sound_item { + public: + int m_id; + std::string m_filename; + // can't find a way to address these via qt + QCheckBox *m_enable; + QPushButton *m_del; + QLabel *m_label; + QHBoxLayout *m_container; + }; + + // arg - need to return it to stitch up the mapper which needs + // to belong to the main window?? + sound_item &add(QVBoxLayout *container, const std::string &name, bool enabled); + void remove(const std::string &name); + void clear(); + void recolour(); + void change_colour(const std::string &name, const std::string &colour); + + + std::vector m_sound_items; + + private: + int m_current_sound_id; +}; + +} diff --git a/samplebrain/src/brain.cpp b/samplebrain/src/brain.cpp index c7e958c..b67e565 100644 --- a/samplebrain/src/brain.cpp +++ b/samplebrain/src/brain.cpp @@ -106,10 +106,17 @@ void brain::init(u32 block_size, u32 overlap, window::type t, bool ditchpcm) { m_window.init(block_size); m_window.set_current_type(t); u32 count=0; - for (auto s=m_samples.begin(); s!=m_samples.end(); ++s) { - count++; - chop_and_add(*s, count, ditchpcm); + for (auto &s:m_samples) { + status::sound_item(s.m_filename,"lightgrey"); } + for (auto &s:m_samples) { + status::sound_item(s.m_filename,"yellow"); + count++; + chop_and_add(s, count, ditchpcm); + if (count%2==0) status::sound_item(s.m_filename,"lightblue"); + else status::sound_item(s.m_filename,"pink"); + } + status::sound_item_refresh(); status::update("all samples processed"); } @@ -117,17 +124,27 @@ void brain::chop_and_add(sound &s, u32 count, bool ditchpcm) { s.m_start = m_blocks.size(); u32 pos=0; if (m_overlap>=m_block_size) m_overlap=0; - while (pos+m_block_size-1update_period) { + status::update("processing sample %d: %d%%",count,(int)(pos/(float)s.m_sample.get_length()*100)); + update_tick=0; + } + update_tick++; } s.m_end = m_blocks.size()-1; s.m_num_blocks = s.m_end-s.m_start; - - cerr<