stuff and more feedback

This commit is contained in:
dave griffiths 2016-02-26 16:11:46 +00:00
parent 7411d911c6
commit 732bfaa61b
10 changed files with 258 additions and 133 deletions

View File

@ -28,25 +28,26 @@ MainWindow::MainWindow() :
m_last_file("."), m_last_file("."),
m_feedback("8890") m_feedback("8890")
{ {
m_Ui.setupUi(this); m_sound_item_enable_mapper = new QSignalMapper(this);
setUnifiedTitleAndToolBarOnMac(true); m_sound_item_delete_mapper = new QSignalMapper(this);
m_sound_item_enable_mapper = new QSignalMapper(this); connect(m_sound_item_enable_mapper,
m_sound_item_delete_mapper = new QSignalMapper(this); SIGNAL(mapped(int)), this, SLOT(sound_enable(int)));
m_Ui.brain_contents->setAlignment(Qt::AlignTop); connect(m_sound_item_delete_mapper,
m_Ui.brain_contents->setSpacing(0); SIGNAL(mapped(int)), this, SLOT(delete_sound(int)));
m_Ui.brain_contents->setMargin(0);
m_Ui.brain_contents->setContentsMargins(0,0,0,0); m_Ui.setupUi(this);
connect(m_sound_item_enable_mapper, setUnifiedTitleAndToolBarOnMac(true);
SIGNAL(mapped(int)), this, SLOT(sound_enable(int)));
connect(m_sound_item_delete_mapper, m_Ui.brain_contents->setAlignment(Qt::AlignTop);
SIGNAL(mapped(int)), this, SLOT(delete_sound(int))); m_Ui.brain_contents->setSpacing(0);
m_current_sound_id=0; m_Ui.brain_contents->setMargin(0);
m_Ui.brain_contents->setContentsMargins(0,0,0,0);
// add default local dest // add default local dest
// turn on first one // turn on first one
QSignalMapper* enable_mapper = new QSignalMapper(this); QSignalMapper* enable_mapper = new QSignalMapper(this);
for (int i=0; i<10; i++) { for (int i=0; i<10; i++) {
osc_destination d; osc_destination d;
@ -156,11 +157,17 @@ void MainWindow::init_from_session(const string &filename) {
m_Ui.comboBoxBrainShape->setCurrentIndex(source_window); m_Ui.comboBoxBrainShape->setCurrentIndex(source_window);
// brain samples // brain samples
clear_sound_items(); m_sound_items.clear();
for (auto &i:s.get_samples()) { 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 // mix
m_Ui.sliderTargetMix->setValue(r.get_target_mix()*100); 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;
}
}
}

View File

@ -23,6 +23,7 @@
#include <list> #include <list>
#include "window.h" #include "window.h"
#include "feedback.h" #include "feedback.h"
#include "sound_items.h"
using namespace std; using namespace std;
using namespace spiralcore; using namespace spiralcore;
@ -156,12 +157,17 @@ private slots:
send_process_osc("/load_sample","s",m_last_file.toStdString().c_str()); 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) { void sound_enable(int id) {
// search for this 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_id==id) {
if (si.m_enable->isChecked()) { if (si.m_enable->isChecked()) {
send_process_osc("/activate_sound","s",si.m_filename.c_str()); send_process_osc("/activate_sound","s",si.m_filename.c_str());
@ -174,10 +180,10 @@ private slots:
void delete_sound(int id) { void delete_sound(int id) {
// search for this 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_id==id) {
send_process_osc("/delete_sample","s",si.m_filename.c_str()); 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... // iterator is now invalidated...
return; return;
} }
@ -186,10 +192,10 @@ private slots:
void clear_brain() { void clear_brain() {
cerr<<"clear brain"<<endl; cerr<<"clear brain"<<endl;
for (auto &si:m_sound_items) { for (auto &si:m_sound_items.m_sound_items) {
send_process_osc("/delete_sample","s",si.m_filename.c_str()); send_process_osc("/delete_sample","s",si.m_filename.c_str());
} }
clear_sound_items(); m_sound_items.clear();
} }
void restart_audio() { send_audio_osc("/restart_audio",""); } void restart_audio() { send_audio_osc("/restart_audio",""); }
@ -264,7 +270,7 @@ private slots:
} }
void update_status() { void update_status() {
m_feedback.poll(m_Ui.statusbar); m_feedback.poll(m_Ui.statusbar,&m_sound_items);
} }
void stereo_mode(bool s) { void stereo_mode(bool s) {
@ -297,23 +303,6 @@ private:
// we want to be able to send out to // we want to be able to send out to
// multiple addresses over the network // multiple addresses over the network
class sound_item {
public:
int m_id;
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;
};
vector<sound_item> 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; u32 m_record_id;
Ui_MainWindow m_Ui; Ui_MainWindow m_Ui;
feedback m_feedback; feedback m_feedback;
int m_current_sound_id;
QSignalMapper* m_sound_item_enable_mapper; QSignalMapper* m_sound_item_enable_mapper;
QSignalMapper* m_sound_item_delete_mapper; QSignalMapper* m_sound_item_delete_mapper;
sound_items m_sound_items;
}; };

View File

@ -15,6 +15,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "feedback.h" #include "feedback.h"
#include "sound_items.h"
#include <iostream> #include <iostream>
using namespace spiralcore; 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; command_ring_buffer::command cmd;
while (m_osc.get(cmd)) { while (m_osc.get(cmd)) {
string name = cmd.m_name; string name = cmd.m_name;
if (name=="/report") { 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();
} }
} }
} }

View File

@ -21,11 +21,12 @@
#pragma once #pragma once
namespace spiralcore { namespace spiralcore {
class sound_items;
class feedback { class feedback {
public: public:
feedback(std::string address); feedback(std::string address);
void poll(QStatusBar *s); void poll(QStatusBar *s, sound_items *sound_items);
private: private:

View File

@ -14,6 +14,7 @@ HEADERS += MainWindow.h \
generated/ui_samplebrain.h \ generated/ui_samplebrain.h \
SOURCES += MainWindow.cpp \ SOURCES += MainWindow.cpp \
sound_items.cpp \
audio_thread.cpp \ audio_thread.cpp \
process_thread.cpp \ process_thread.cpp \
feedback.cpp \ feedback.cpp \

View File

@ -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 <QtGui>
#include <iostream>
#include <list>
#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;
}
}
}

View File

@ -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 <QtGui>
#include <iostream>
#include <string>
#include <list>
#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<sound_item> m_sound_items;
private:
int m_current_sound_id;
};
}

View File

@ -106,10 +106,17 @@ void brain::init(u32 block_size, u32 overlap, window::type t, bool ditchpcm) {
m_window.init(block_size); m_window.init(block_size);
m_window.set_current_type(t); m_window.set_current_type(t);
u32 count=0; u32 count=0;
for (auto s=m_samples.begin(); s!=m_samples.end(); ++s) { for (auto &s:m_samples) {
count++; status::sound_item(s.m_filename,"lightgrey");
chop_and_add(*s, count, ditchpcm);
} }
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"); 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(); s.m_start = m_blocks.size();
u32 pos=0; u32 pos=0;
if (m_overlap>=m_block_size) m_overlap=0; if (m_overlap>=m_block_size) m_overlap=0;
while (pos+m_block_size-1<s.m_sample.get_length()) { u32 len = s.m_sample.get_length();
status::update("processing sample %d: %d%%",count,(int)(pos/(float)s.m_sample.get_length()*100));
// need to stop the progress updates flooding osc
u32 update_period = (len/m_block_size)/100;
u32 update_tick = 0;
while (pos+m_block_size-1<len) {
sample region; sample region;
s.m_sample.get_region(region,pos,pos+m_block_size-1); s.m_sample.get_region(region,pos,pos+m_block_size-1);
m_blocks.push_back(block(m_blocks.size(),s.m_filename,region,44100,m_window,ditchpcm)); m_blocks.push_back(block(m_blocks.size(),s.m_filename,region,44100,m_window,ditchpcm));
pos += (m_block_size-m_overlap); pos += (m_block_size-m_overlap);
// periodic progress update
if (update_tick>update_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_end = m_blocks.size()-1;
s.m_num_blocks = s.m_end-s.m_start; s.m_num_blocks = s.m_end-s.m_start;
cerr<<s.m_start<<" "<<s.m_end;
} }
// needed after we delete a sample from the brain // needed after we delete a sample from the brain

View File

@ -6,11 +6,18 @@ using namespace std;
lo_address status::m_address = lo_address_new_from_url("osc.udp://localhost:8890"); lo_address status::m_address = lo_address_new_from_url("osc.udp://localhost:8890");
void status::_update(std::string msg) { void status::_update(const std::string &msg) {
//cerr<<msg<<endl;
lo_send(m_address,"/report","s",msg.c_str()); lo_send(m_address,"/report","s",msg.c_str());
} }
void status::sound_item(const std::string &name, const std::string &colour) {
lo_send(m_address,"/sound-item","ss",name.c_str(),colour.c_str());
}
void status::sound_item_refresh() {
lo_send(m_address,"/sound-item-refresh","");
}
void status::update(const char *msg, ...) { void status::update(const char *msg, ...) {
va_list args; va_list args;
va_start(args, msg); va_start(args, msg);

View File

@ -8,8 +8,10 @@ namespace spiralcore {
class status { class status {
public: public:
static void _update(std::string msg); static void _update(const std::string &msg);
static void update(const char *msg, ...); static void update(const char *msg, ...);
static void sound_item(const std::string &name, const std::string &colour);
static void sound_item_refresh();
static lo_address m_address; static lo_address m_address;
}; };