plugging in...

This commit is contained in:
Dave Griffiths 2015-07-11 12:29:51 +01:00
parent 5b966786d4
commit f6f6fcdc2d
11 changed files with 107 additions and 108 deletions

View File

@ -37,6 +37,6 @@ void MainWindow::init_brain() {
//target.resynth_listen("shosta-dream-0.5.wav",source,0.5,a);
m_renderer = new renderer(m_source,m_target,1);
m_renderer = new renderer(m_source,m_target);
}

View File

@ -20,15 +20,15 @@ protected:
private slots:
void play_slot() {}
void stop_slot() {}
void ratio_slot(int s) { m_renderer->set_ratio(s/100.0f); }
void ratio_slot(double) {}
void fft1_start_slot(int) {}
void fft1_end_slot(int) {}
void fft2_start_slot(int) {}
void fft2_end_slot(int) {}
void volume_slot(int) {}
void play_slot() { m_renderer->set_playing(true); }
void stop_slot() { m_renderer->set_playing(false); }
void ratio_slot(int s) { m_renderer->get_params()->m_ratio=s/100.0f; }
void ratio_slot(double s) { m_renderer->get_params()->m_ratio=s/100.0f; }
void fft1_start_slot(int s) { m_renderer->get_params()->m_fft1_start=s; }
void fft1_end_slot(int s) { m_renderer->get_params()->m_fft1_end=s; }
void fft2_start_slot(int s) { m_renderer->get_params()->m_fft2_start=s; }
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) {}

View File

@ -1 +0,0 @@
dave@fulmar.5193:1436562455

View File

@ -1,14 +1,14 @@
/********************************************************************************
** Form generated from reading UI file 'samplebrainYv5241.ui'
** Form generated from reading UI file 'samplebrainxS5241.ui'
**
** Created: Sat Jul 11 10:34:17 2015
** Created: Sat Jul 11 12:25:49 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 SAMPLEBRAINYV5241_H
#define SAMPLEBRAINYV5241_H
#ifndef SAMPLEBRAINXS5241_H
#define SAMPLEBRAINXS5241_H
#include <QtCore/QVariant>
#include <QtGui/QAction>
@ -22,12 +22,10 @@
#include <QtGui/QListWidget>
#include <QtGui/QMainWindow>
#include <QtGui/QPushButton>
#include <QtGui/QSlider>
#include <QtGui/QSpacerItem>
#include <QtGui/QSpinBox>
#include <QtGui/QStatusBar>
#include <QtGui/QTabWidget>
#include <QtGui/QTextEdit>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWidget>
@ -47,6 +45,7 @@ public:
QPushButton *pushButtonPlay;
QPushButton *pushButtonStop;
QVBoxLayout *verticalLayout_3;
QHBoxLayout *horizontalLayout_16;
QLabel *label_6;
QDial *dialRatio;
QDoubleSpinBox *doubleSpinBoxRatio;
@ -66,10 +65,10 @@ public:
QHBoxLayout *horizontalLayout_11;
QLabel *label_12;
QSpinBox *spinBoxFFT2End;
QSpacerItem *verticalSpacer_3;
QVBoxLayout *verticalLayout_6;
QLabel *label_13;
QSlider *verticalSliderVolume;
QSpacerItem *verticalSpacer_3;
QDial *dialVolume;
QVBoxLayout *verticalLayout_9;
QLabel *label_16;
QLabel *label_15;
@ -82,10 +81,6 @@ public:
QSpinBox *spinBoxBlockOverlapTarget;
QPushButton *pushButtonGenerateTarget;
QSpacerItem *verticalSpacer;
QVBoxLayout *verticalLayout_8;
QLabel *label_14;
QTextEdit *textEdit;
QPushButton *pushButtonRun;
QWidget *sampleTab;
QHBoxLayout *horizontalLayout_8;
QVBoxLayout *verticalLayout_2;
@ -115,7 +110,7 @@ public:
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(800, 603);
MainWindow->resize(724, 603);
centralwidget = new QWidget(MainWindow);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
horizontalLayout = new QHBoxLayout(centralwidget);
@ -163,17 +158,33 @@ public:
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);
label_6->setObjectName(QString::fromUtf8("label_6"));
label_6->setFont(font1);
QFont font2;
font2.setFamily(QString::fromUtf8("Comic Sans MS"));
font2.setPointSize(14);
font2.setBold(true);
font2.setWeight(75);
label_6->setFont(font2);
verticalLayout_3->addWidget(label_6);
horizontalLayout_16->addWidget(label_6);
dialRatio = new QDial(controlTab);
dialRatio->setObjectName(QString::fromUtf8("dialRatio"));
dialRatio->setEnabled(true);
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(dialRatio->sizePolicy().hasHeightForWidth());
dialRatio->setSizePolicy(sizePolicy);
dialRatio->setMinimumSize(QSize(60, 60));
verticalLayout_3->addWidget(dialRatio);
horizontalLayout_16->addWidget(dialRatio);
verticalLayout_3->addLayout(horizontalLayout_16);
doubleSpinBoxRatio = new QDoubleSpinBox(controlTab);
doubleSpinBoxRatio->setObjectName(QString::fromUtf8("doubleSpinBoxRatio"));
@ -184,7 +195,7 @@ public:
verticalLayout_4->setObjectName(QString::fromUtf8("verticalLayout_4"));
label_7 = new QLabel(controlTab);
label_7->setObjectName(QString::fromUtf8("label_7"));
label_7->setFont(font1);
label_7->setFont(font2);
verticalLayout_4->addWidget(label_7);
@ -227,7 +238,7 @@ public:
verticalLayout_5->setObjectName(QString::fromUtf8("verticalLayout_5"));
label_8 = new QLabel(controlTab);
label_8->setObjectName(QString::fromUtf8("label_8"));
label_8->setFont(font1);
label_8->setFont(font2);
verticalLayout_5->addWidget(label_8);
@ -269,6 +280,10 @@ public:
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);
@ -277,19 +292,15 @@ public:
verticalLayout_6->addWidget(label_13);
verticalSliderVolume = new QSlider(controlTab);
verticalSliderVolume->setObjectName(QString::fromUtf8("verticalSliderVolume"));
verticalSliderVolume->setOrientation(Qt::Vertical);
dialVolume = new QDial(controlTab);
dialVolume->setObjectName(QString::fromUtf8("dialVolume"));
dialVolume->setValue(99);
verticalLayout_6->addWidget(verticalSliderVolume);
verticalLayout_6->addWidget(dialVolume);
verticalLayout_7->addLayout(verticalLayout_6);
verticalSpacer_3 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
verticalLayout_7->addItem(verticalSpacer_3);
horizontalLayout_15->addLayout(verticalLayout_7);
@ -358,28 +369,6 @@ public:
horizontalLayout_15->addLayout(verticalLayout_9);
verticalLayout_8 = new QVBoxLayout();
verticalLayout_8->setObjectName(QString::fromUtf8("verticalLayout_8"));
label_14 = new QLabel(controlTab);
label_14->setObjectName(QString::fromUtf8("label_14"));
label_14->setFont(font);
verticalLayout_8->addWidget(label_14);
textEdit = new QTextEdit(controlTab);
textEdit->setObjectName(QString::fromUtf8("textEdit"));
verticalLayout_8->addWidget(textEdit);
pushButtonRun = new QPushButton(controlTab);
pushButtonRun->setObjectName(QString::fromUtf8("pushButtonRun"));
pushButtonRun->setFont(font1);
verticalLayout_8->addWidget(pushButtonRun);
horizontalLayout_15->addLayout(verticalLayout_8);
tabWidget->addTab(controlTab, QString());
sampleTab = new QWidget();
sampleTab->setObjectName(QString::fromUtf8("sampleTab"));
@ -516,8 +505,6 @@ public:
QObject::connect(spinBoxFFT1End, SIGNAL(valueChanged(int)), MainWindow, SLOT(fft1_end_slot(int)));
QObject::connect(spinBoxFFT2Start, SIGNAL(valueChanged(int)), MainWindow, SLOT(fft2_start_slot(int)));
QObject::connect(spinBoxFFT2End, SIGNAL(valueChanged(int)), MainWindow, SLOT(fft2_end_slot(int)));
QObject::connect(verticalSliderVolume, SIGNAL(sliderMoved(int)), MainWindow, SLOT(volume_slot(int)));
QObject::connect(pushButtonRun, SIGNAL(released()), MainWindow, SLOT(run_slot()));
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)));
@ -527,8 +514,9 @@ public:
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)));
tabWidget->setCurrentIndex(1);
tabWidget->setCurrentIndex(0);
QMetaObject::connectSlotsByName(MainWindow);
@ -549,13 +537,11 @@ public:
label_12->setText(QApplication::translate("MainWindow", "End", 0, QApplication::UnicodeUTF8));
label_13->setText(QApplication::translate("MainWindow", "Volume", 0, QApplication::UnicodeUTF8));
label_16->setText(QApplication::translate("MainWindow", "target sound", 0, QApplication::UnicodeUTF8));
label_15->setText(QApplication::translate("MainWindow", "TextLabel", 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));
label_14->setText(QApplication::translate("MainWindow", "livecode brain", 0, QApplication::UnicodeUTF8));
pushButtonRun->setText(QApplication::translate("MainWindow", "run", 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));
@ -577,4 +563,4 @@ namespace Ui {
QT_END_NAMESPACE
#endif // SAMPLEBRAINYV5241_H
#endif // SAMPLEBRAINXS5241_H

View File

@ -68,7 +68,7 @@ void block::init_fft(u32 block_size)
#define FFT_BIAS 200
double block::compare(const block &other, float ratio, int fftwack) const {
double block::compare(const block &other, const search_params &params) const {
double mfcc_acc=0;
double fft_acc=0;
@ -77,17 +77,17 @@ double block::compare(const block &other, float ratio, int fftwack) const {
if (fft_start<0) fft_start=0;
if (fft_end>m_fft.get_length()) fft_end=m_fft.get_length();
*/
s32 fft_start = 0;
s32 fft_end = m_fft.get_length();
s32 fft_start = params.m_fft1_start;
s32 fft_end = fmin(params.m_fft1_end,m_fft.get_length());
if (ratio==0) {
if (params.m_ratio==0) {
for (u32 i=fft_start; i<fft_end; ++i) {
fft_acc+=(m_fft[i]-other.m_fft[i]) * (m_fft[i]-other.m_fft[i]);
}
return (fft_acc/(float)m_fft.get_length())*FFT_BIAS;
}
if (ratio==1) {
if (params.m_ratio==1) {
for (u32 i=0; i<MFCC_FILTERS; ++i) {
mfcc_acc+=(m_mfcc[i]-other.m_mfcc[i]) * (m_mfcc[i]-other.m_mfcc[i]);
}
@ -102,8 +102,8 @@ double block::compare(const block &other, float ratio, int fftwack) const {
mfcc_acc+=(m_mfcc[i]-other.m_mfcc[i]) * (m_mfcc[i]-other.m_mfcc[i]);
}
return (fft_acc/(float)m_fft.get_length())*(1-ratio)*FFT_BIAS +
(mfcc_acc/(float)MFCC_FILTERS)*ratio;
return (fft_acc/(float)m_fft.get_length())*(1-params.m_ratio)*FFT_BIAS +
(mfcc_acc/(float)MFCC_FILTERS)*params.m_ratio;
}
@ -122,10 +122,14 @@ bool block::unit_test() {
assert(bb.m_rate==44100);
assert(bb.m_block_size==data.get_length());
search_params p(0,0,100,0,100);
block bb2("test",data,44100,0);
assert(bb.compare(bb2,1,0)==0);
assert(bb.compare(bb2,0,0)==0);
assert(bb.compare(bb2,0.5,0)==0);
assert(bb.compare(bb2,p)==0);
p.m_ratio=1;
assert(bb.compare(bb2,p)==0);
p.m_ratio=0.5;
assert(bb.compare(bb2,p)==0);
sample data2(200);
for (u32 i=0; i<data.get_length(); i++) {
@ -135,9 +139,11 @@ bool block::unit_test() {
block cpy("test",data,100,4);
{
block bb3("test",data2,44100,4);
assert(bb.compare(bb3,1,0)!=0);
assert(bb.compare(bb3,0,0)!=0);
assert(bb.compare(bb3,0.5,0)!=0);
p.m_ratio=0.0;
assert(bb.compare(bb3,p)!=0);
assert(bb.compare(bb3,p)!=0);
p.m_ratio=0.5;
assert(bb.compare(bb3,p)!=0);
cpy=bb3;
}

View File

@ -3,6 +3,7 @@
#include "jellyfish/core/types.h"
#include "fft.h"
#include "mfcc.h"
#include "search_params.h"
#ifndef BLOCK
#define BLOCK
@ -15,7 +16,7 @@ public:
block(const std::string &filename, const sample &pcm, u32 rate, u32 env, bool ditchpcm=false);
// returns distance based on ratio of fft-mfcc values
double compare(const block &other, float ratio, int fftwack) const;
double compare(const block &other, const search_params &params) const;
static void init_fft(u32 block_size);
static bool unit_test();

View File

@ -68,12 +68,12 @@ const block &brain::get_block(u32 index) const {
}
// returns index to block
u32 brain::search(const block &target, float ratio, u32 fftwack) const {
u32 brain::search(const block &target, const search_params &params) const {
double closest = 999999999;
u32 closest_index = 0;
u32 index = 0;
for (vector<block>::const_iterator i=m_blocks.begin(); i!=m_blocks.end(); ++i) {
double diff = target.compare(*i,ratio,fftwack);
double diff = target.compare(*i,params);
if (diff<closest) {
closest=diff;
closest_index = index;
@ -85,7 +85,7 @@ u32 brain::search(const block &target, float ratio, u32 fftwack) const {
// take another brain and rebuild this brain from bits of that one
// (presumably this one is made from a single sample)
void brain::resynth(const string &filename, const brain &other, float ratio, u32 fftwack){
void brain::resynth(const string &filename, const brain &other, const search_params &params){
sample out((m_block_size-m_overlap)*m_blocks.size());
out.zero();
u32 pos = 0;
@ -95,7 +95,7 @@ void brain::resynth(const string &filename, const brain &other, float ratio, u32
for (vector<block>::iterator i=m_blocks.begin(); i!=m_blocks.end(); ++i) {
cerr<<'\r';
cerr<<"searching: "<<count/float(m_blocks.size())*100;
u32 index = other.search(*i,ratio, fftwack);
u32 index = other.search(*i, params);
//cerr<<index<<endl;
out.mul_mix(other.get_block_pcm(index),pos,0.2);
@ -141,10 +141,13 @@ bool brain::unit_test() {
b2.init(512, 0, 20);
b3.init(512, 0, 20);
assert(b3.search(b2.m_blocks[0],1,0)==0);
assert(b3.search(b2.m_blocks[9],1,0)==9);
assert(b3.search(b2.m_blocks[19],1,0)==19);
assert(b3.search(b2.m_blocks[29],1,0)==29);
search_params p(1,0,100,0,100);
assert(b3.search(b2.m_blocks[0],p)==0);
assert(b3.search(b2.m_blocks[9],p)==9);
assert(b3.search(b2.m_blocks[19],p)==19);
assert(b3.search(b2.m_blocks[29],p)==29);
// sample r = b2.resynth(b,1);
// assert(r.get_length()==200);

View File

@ -3,6 +3,7 @@
#include "jellyfish/core/types.h"
#include "jellyfish/fluxa/sample.h"
#include "block.h"
#include "search_params.h"
#ifndef BRAIN
#define BRAIN
@ -21,7 +22,7 @@ public:
sample load_sound(std::string filename);
// 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, float ratio, u32 fftwack);
void resynth(const std::string &filename, const brain &other, const search_params &params);
const sample &get_block_pcm(u32 index) const;
const block &get_block(u32 index) const;
@ -29,7 +30,7 @@ public:
const u32 get_block_size() const { return m_block_size; }
const u32 get_overlap() const { return m_overlap; }
u32 search(const block &target, float ratio, u32 fftwack) const;
u32 search(const block &target, const search_params &params) const;
static bool unit_test();

View File

@ -53,7 +53,7 @@ void run_audio(void* c, unsigned int frames) {
int main(int argc, char *argv[])
{
// unit_test();
unit_test();
cerr<<"starting"<<endl;
brain source, target;
@ -81,7 +81,7 @@ int main(int argc, char *argv[])
//target.resynth_listen("shosta-dream-0.5.wav",source,0.5,a);
renderer rr(source,target,1);
renderer rr(source,target);
a->m_client.set_callback(run_audio, &rr);

View File

@ -4,27 +4,23 @@
using namespace spiralcore;
using namespace std;
void renderer::init(brain &source, brain &target, float ratio) {
void renderer::init(brain &source, brain &target) {
m_source=source;
m_target=target;
m_render_time=0;
m_render_blocks.clear();
m_ratio = ratio;
}
static int ratio_time = 0;
void renderer::process(u32 nframes, float *buf) {
if (!m_playing) return;
// get blocks from source for the current buffer
u32 tgt_shift = m_target.get_block_size()-m_target.get_overlap();
u32 tgt_start = m_render_time/(float)tgt_shift;
u32 tgt_end = (m_render_time+nframes)/(float)tgt_shift;
cerr<<'\r';
cerr<<m_ratio;
u32 fftwack = 0; //100*(sin((ratio_time++)*0.01)*0.5+0.5);
//m_ratio = 0;
if (tgt_end>=m_target.get_num_blocks()) {
m_render_time=0;
@ -40,7 +36,7 @@ void renderer::process(u32 nframes, float *buf) {
// get indices for current buffer
for (u32 tgt_index = tgt_start; tgt_index<=tgt_end; tgt_index++) {
u32 time=tgt_index*tgt_shift;
u32 src_index = m_source.search(m_target.get_block(tgt_index), m_ratio, fftwack);
u32 src_index = m_source.search(m_target.get_block(tgt_index), m_search_params);
// put them in the index list
m_render_blocks.push_back(render_block(src_index,time));
}
@ -72,7 +68,7 @@ void renderer::process(u32 nframes, float *buf) {
u32 block_pos = block_start;
u32 block_end = pcm.get_length();
while (block_pos<block_end && buffer_pos<nframes) {
buf[buffer_pos]+=pcm[block_pos]*0.2;
buf[buffer_pos]+=pcm[block_pos]*0.2*m_volume;
++buffer_pos;
++block_pos;
}
@ -100,7 +96,7 @@ bool renderer::unit_test() {
target.load_sound("test_data/up.wav");
target.init(10,0,0);
renderer rr(source,target,1);
renderer rr(source,target);
float *buf=new float[10];
rr.process(10,buf);
assert(rr.m_render_blocks.size()==2);

View File

@ -9,14 +9,18 @@ namespace spiralcore {
class renderer {
public:
renderer(brain &source, brain &target, float ratio) :
m_source(source), m_target(target)
{ init(source,target,ratio); }
renderer(brain &source, brain &target) :
m_source(source),
m_target(target),
m_search_params(0,0,100,0,100)
{ init(source,target); }
void init(brain &source, brain &target, float ratio);
void init(brain &source, brain &target);
void process(u32 nframes, float *buf);
void set_ratio(float s) { m_ratio=s; }
void set_playing(bool s) { m_playing=s; }
void set_volume(float s) { m_volume=s; }
search_params *get_params() { return &m_search_params; }
static bool unit_test();
@ -34,7 +38,10 @@ private:
brain &m_source;
brain &m_target;
float m_ratio;
search_params m_search_params;
float m_volume;
bool m_playing;
std::list<render_block> m_render_blocks;
u32 m_render_time;