lots of gui work, boredom/novelty sliders, started synaptic stuff

This commit is contained in:
Dave Griffiths
2015-07-27 15:36:34 +01:00
parent fabd9cbe4f
commit 92f8997c1f
20 changed files with 890 additions and 225 deletions

View File

@ -8,6 +8,7 @@ SRCS := src/fft.cpp \
src/mfcc.cpp \
src/renderer.cpp \
src/window.cpp \
src/status.cpp \
src/aquila/filter/MelFilterBank.cpp \
src/aquila/filter/MelFilter.cpp \
src/aquila/transform/Dct.cpp \

39
samplebrain/configure vendored
View File

@ -3030,6 +3030,45 @@ _ACEOF
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -llo" >&5
$as_echo_n "checking for main in -llo... " >&6; }
if ${ac_cv_lib_lo_main+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-llo $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
return main ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_lo_main=yes
else
ac_cv_lib_lo_main=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lo_main" >&5
$as_echo "$ac_cv_lib_lo_main" >&6; }
if test "x$ac_cv_lib_lo_main" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBLO 1
_ACEOF
LIBS="-llo $LIBS"
fi
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'

View File

@ -7,6 +7,7 @@ AC_CHECK_LIB(fftw3, main)
AC_CHECK_LIB(portaudio, main)
AC_CHECK_LIB(jellyfish, main)
AC_CHECK_LIB(sndfile, main)
AC_CHECK_LIB(lo, main)
AC_PROG_CXX
AC_LANG(C++)

View File

@ -6,12 +6,12 @@
<rect>
<x>0</x>
<y>0</y>
<width>724</width>
<height>613</height>
<width>643</width>
<height>619</height>
</rect>
</property>
<property name="windowTitle">
<string>samplebrain 0.0.4</string>
<string>samplebrain 0.0.5</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_4">
@ -31,7 +31,7 @@
<attribute name="title">
<string>search</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<layout class="QHBoxLayout" name="horizontalLayout_17">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
@ -45,27 +45,27 @@
</font>
</property>
<property name="text">
<string>search</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="font">
<font>
<family>Comic Sans MS</family>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>fft &lt;-&gt; mfcc</string>
<string>brain tweaks</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_16">
<item>
<widget class="QLabel" name="label_6">
<property name="font">
<font>
<family>Comic Sans MS</family>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>fft / mfcc</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="sliderRatio">
<property name="sizePolicy">
@ -74,6 +74,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>plain fft match vs mfcc values </string>
</property>
<property name="value">
<number>50</number>
</property>
@ -103,23 +106,23 @@
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_20">
<property name="font">
<font>
<family>Comic Sans MS</family>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>freq &amp; dynamics &lt;-&gt; freq only</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_20">
<property name="font">
<font>
<family>Comic Sans MS</family>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>freq &amp; dynamics / freq only</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="sliderNRatio">
<property name="sizePolicy">
@ -128,6 +131,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>match original or normalised blocks</string>
</property>
<property name="value">
<number>0</number>
</property>
@ -157,25 +163,34 @@
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="font">
<font>
<family>Comic Sans MS</family>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>fft subsection</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_7">
<property name="font">
<font>
<family>Comic Sans MS</family>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>fft subsection</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Comic Sans MS</family>
@ -189,10 +204,20 @@
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBoxFFT1Start"/>
<widget class="QSpinBox" name="spinBoxFFT1Start">
<property name="toolTip">
<string>start frequency to use for fft match</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Comic Sans MS</family>
@ -207,6 +232,9 @@
</item>
<item>
<widget class="QSpinBox" name="spinBoxFFT1End">
<property name="toolTip">
<string>end frequency to use for fft match</string>
</property>
<property name="value">
<number>99</number>
</property>
@ -214,6 +242,126 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QLabel" name="label_24">
<property name="font">
<font>
<family>Comic Sans MS</family>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>novelty</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="sliderNovelty">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>use new blocks rather than similar ones</string>
</property>
<property name="value">
<number>0</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="doubleSpinBoxNovelty">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QLabel" name="label_25">
<property name="font">
<font>
<family>Comic Sans MS</family>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>boredom</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="sliderBoredom">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>how long it takes for the novelty to ware off</string>
</property>
<property name="value">
<number>0</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="doubleSpinBoxBoredom">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkBoxInvert">
<property name="sizeIncrement">
@ -222,6 +370,9 @@
<height>0</height>
</size>
</property>
<property name="toolTip">
<string extracomment="invert the search"/>
</property>
<property name="text">
<string>search for least similar</string>
</property>
@ -233,6 +384,32 @@
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_23">
<property name="font">
@ -248,23 +425,23 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_21">
<property name="font">
<font>
<family>Comic Sans MS</family>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>dynamic &lt;-&gt; normalised mix</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="label_21">
<property name="font">
<font>
<family>Comic Sans MS</family>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>dynamic / normalised </string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="sliderNMix">
<property name="sizePolicy">
@ -273,6 +450,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>mix in the normalised blocks</string>
</property>
<property name="value">
<number>0</number>
</property>
@ -302,23 +482,23 @@
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_22">
<property name="font">
<font>
<family>Comic Sans MS</family>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>brain &lt;-&gt; target mix</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QLabel" name="label_22">
<property name="font">
<font>
<family>Comic Sans MS</family>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>brain / target</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="sliderTargetMix">
<property name="sizePolicy">
@ -327,6 +507,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>mix in the original blocks</string>
</property>
<property name="value">
<number>0</number>
</property>
@ -359,19 +542,6 @@
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
@ -992,7 +1162,7 @@
</widget>
<resources>
<include location="../qt/samplebrain.qrc"/>
<include location="../../../../.designer/qt/samplebrain.qrc"/>
<include location="../qt/samplebrain.qrc"/>
</resources>
<connections>
<connection>
@ -1667,6 +1837,70 @@
</hint>
</hints>
</connection>
<connection>
<sender>doubleSpinBoxBoredom</sender>
<signal>valueChanged(double)</signal>
<receiver>MainWindow</receiver>
<slot>boredom_slot(double)</slot>
<hints>
<hint type="sourcelabel">
<x>411</x>
<y>253</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>309</y>
</hint>
</hints>
</connection>
<connection>
<sender>sliderBoredom</sender>
<signal>valueChanged(int)</signal>
<receiver>MainWindow</receiver>
<slot>boredom_slot(int)</slot>
<hints>
<hint type="sourcelabel">
<x>291</x>
<y>253</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>309</y>
</hint>
</hints>
</connection>
<connection>
<sender>doubleSpinBoxNovelty</sender>
<signal>valueChanged(double)</signal>
<receiver>MainWindow</receiver>
<slot>novelty_slot(double)</slot>
<hints>
<hint type="sourcelabel">
<x>411</x>
<y>217</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>309</y>
</hint>
</hints>
</connection>
<connection>
<sender>sliderNovelty</sender>
<signal>valueChanged(int)</signal>
<receiver>MainWindow</receiver>
<slot>novelty_slot(int)</slot>
<hints>
<hint type="sourcelabel">
<x>291</x>
<y>217</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>309</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>play_slot()</slot>
@ -1717,5 +1951,9 @@
<slot>n_mix_slot(double)</slot>
<slot>target_mix_slot(int)</slot>
<slot>target_mix_slot(double)</slot>
<slot>novelty_slot(int)</slot>
<slot>novelty_slot(double)</slot>
<slot>boredom_slot(int)</slot>
<slot>boredom_slot(double)</slot>
</slots>
</ui>

View File

@ -18,17 +18,25 @@
#include <iostream>
#include "MainWindow.h"
#include "feedback.h"
using namespace std;
MainWindow::MainWindow() :
m_last_file(".")
m_last_file("."),
m_feedback("8890")
{
m_Ui.setupUi(this);
setUnifiedTitleAndToolBarOnMac(true);
m_audio_address = lo_address_new_from_url("osc.udp://localhost:8888");
m_process_address = lo_address_new_from_url("osc.udp://localhost:8889");
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update_status()));
timer->start(1000);
timer->setInterval(500);
m_save_wav="";
m_record_id=0;
}

View File

@ -21,6 +21,7 @@
#include <lo/lo.h>
#include <string>
#include "window.h"
#include "feedback.h"
using namespace std;
using namespace spiralcore;
@ -40,23 +41,72 @@ private slots:
void play_slot() { lo_send(m_audio_address,"/start",""); }
void stop_slot() { lo_send(m_audio_address,"/pause",""); }
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 n_ratio_slot(int s) { lo_send(m_audio_address,"/n_ratio","f",s/100.0f); }
void n_ratio_slot(double s) { lo_send(m_audio_address,"/n_ratio","f",s); }
void ratio_slot(int s) {
lo_send(m_audio_address,"/ratio","f",s/100.0f);
m_Ui.doubleSpinBoxRatio->setValue(s/100.0f);
}
void ratio_slot(double s) {
lo_send(m_audio_address,"/ratio","f",s);
m_Ui.sliderRatio->setValue(s*100);
}
void n_ratio_slot(int s) {
lo_send(m_audio_address,"/n_ratio","f",s/100.0f);
m_Ui.doubleSpinBoxNRatio->setValue(s/100.0f);
}
void n_ratio_slot(double s) {
lo_send(m_audio_address,"/n_ratio","f",s);
m_Ui.sliderNRatio->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; }
void fft2_end_slot(int s){} // { m_renderer->get_params()->m_fft2_end=s; }
void n_mix_slot(int s) { lo_send(m_audio_address,"/n_mix","f",s/100.0f); }
void n_mix_slot(double s) { lo_send(m_audio_address,"/n_mix","f",s); }
void target_mix_slot(int s) { lo_send(m_audio_address,"/target_mix","f",s/100.0f); }
void target_mix_slot(double s) { lo_send(m_audio_address,"/target_mix","f",s); }
void n_mix_slot(int s) {
lo_send(m_audio_address,"/n_mix","f",s/100.0f);
m_Ui.doubleSpinBoxNMix->setValue(s/100.0f);
}
void n_mix_slot(double s) {
lo_send(m_audio_address,"/n_mix","f",s);
m_Ui.sliderNMix->setValue(s*100);
}
void novelty_slot(int s) {
lo_send(m_audio_address,"/novelty","f",s/100.0f);
m_Ui.doubleSpinBoxNovelty->setValue(s/100.0f);
}
void novelty_slot(double s) {
lo_send(m_audio_address,"/novelty","f",s);
m_Ui.sliderNovelty->setValue(s*100);
}
void boredom_slot(int s) {
float v=s/100.0f;
lo_send(m_audio_address,"/boredom","f",v);
m_Ui.doubleSpinBoxBoredom->setValue(v);
}
void boredom_slot(double s) {
lo_send(m_audio_address,"/boredom","f",s);
m_Ui.sliderBoredom->setValue(s*100);
}
void target_mix_slot(int s) {
lo_send(m_audio_address,"/target_mix","f",s/100.0f);
m_Ui.doubleSpinBoxTargetMix->setValue(s/100.0f);
}
void target_mix_slot(double s) {
lo_send(m_audio_address,"/target_mix","f",s);
m_Ui.sliderTargetMix->setValue(s*100);
}
void volume_slot(int s) { lo_send(m_audio_address,"/volume","f",s/100.0f); }
void invert_slot(bool s) { if (s) {
lo_send(m_audio_address,"/invert","i",1);
lo_send(m_audio_address,"/search_algo","i",1);
} else {
lo_send(m_audio_address,"/invert","i",0);
lo_send(m_audio_address,"/search_algo","i",0);
}}
void run_slot() {}
void load_target() {
@ -146,6 +196,10 @@ private slots:
lo_send(m_audio_address,"/stop","");
}
void update_status() {
m_feedback.poll(m_Ui.statusbar);
}
private:
string m_save_wav;
QString m_last_file;
@ -153,4 +207,5 @@ private:
Ui_MainWindow m_Ui;
lo_address m_audio_address;
lo_address m_process_address;
feedback m_feedback;
};

View File

@ -1,6 +1,6 @@
#############################################################################
# Makefile for building: samplebrain
# Generated by qmake (2.01a) (Qt 4.8.1) on: Sun Jul 19 11:22:53 2015
# Generated by qmake (2.01a) (Qt 4.8.1) on: Mon Jul 27 09:28:27 2015
# Project: samplebrain.pro
# Template: app
# Command: /usr/bin/qmake -o Makefile samplebrain.pro
@ -46,11 +46,13 @@ OBJECTS_DIR = ./
SOURCES = MainWindow.cpp \
audio_thread.cpp \
process_thread.cpp \
feedback.cpp \
qtmain.cpp moc_MainWindow.cpp \
qrc_samplebrain.cpp
OBJECTS = MainWindow.o \
audio_thread.o \
process_thread.o \
feedback.o \
qtmain.o \
moc_MainWindow.o \
qrc_samplebrain.o
@ -168,7 +170,7 @@ qmake: FORCE
dist:
@$(CHK_DIR_EXISTS) .tmp/samplebrain1.0.0 || $(MKDIR) .tmp/samplebrain1.0.0
$(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/samplebrain1.0.0/ && $(COPY_FILE) --parents MainWindow.h generated/ui_samplebrain.h .tmp/samplebrain1.0.0/ && $(COPY_FILE) --parents samplebrain.qrc .tmp/samplebrain1.0.0/ && $(COPY_FILE) --parents MainWindow.cpp audio_thread.cpp process_thread.cpp qtmain.cpp .tmp/samplebrain1.0.0/ && (cd `dirname .tmp/samplebrain1.0.0` && $(TAR) samplebrain1.0.0.tar samplebrain1.0.0 && $(COMPRESS) samplebrain1.0.0.tar) && $(MOVE) `dirname .tmp/samplebrain1.0.0`/samplebrain1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/samplebrain1.0.0
$(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/samplebrain1.0.0/ && $(COPY_FILE) --parents MainWindow.h generated/ui_samplebrain.h .tmp/samplebrain1.0.0/ && $(COPY_FILE) --parents samplebrain.qrc .tmp/samplebrain1.0.0/ && $(COPY_FILE) --parents MainWindow.cpp audio_thread.cpp process_thread.cpp feedback.cpp qtmain.cpp .tmp/samplebrain1.0.0/ && (cd `dirname .tmp/samplebrain1.0.0` && $(TAR) samplebrain1.0.0.tar samplebrain1.0.0 && $(COMPRESS) samplebrain1.0.0.tar) && $(MOVE) `dirname .tmp/samplebrain1.0.0`/samplebrain1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/samplebrain1.0.0
clean:compiler_clean
@ -203,6 +205,7 @@ qrc_samplebrain.cpp: samplebrain.qrc \
images/stop.png \
images/play.png \
images/record.png \
images/at.png \
images/pause.png
/usr/bin/rcc -name samplebrain samplebrain.qrc -o qrc_samplebrain.cpp
@ -224,7 +227,8 @@ compiler_clean: compiler_moc_header_clean compiler_rcc_clean
####### Compile
MainWindow.o: MainWindow.cpp MainWindow.h \
generated/ui_samplebrain.h
generated/ui_samplebrain.h \
feedback.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o MainWindow.o MainWindow.cpp
audio_thread.o: audio_thread.cpp audio_thread.h \
@ -234,6 +238,9 @@ audio_thread.o: audio_thread.cpp audio_thread.h \
process_thread.o: process_thread.cpp process_thread.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o process_thread.o process_thread.cpp
feedback.o: feedback.cpp feedback.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o feedback.o feedback.cpp
qtmain.o: qtmain.cpp MainWindow.h \
generated/ui_samplebrain.h \
process_thread.h \

View File

@ -33,9 +33,14 @@ audio_thread::audio_thread(process_thread &p) :
m_osc.run();
}
static bool state = 1;
audio_thread::~audio_thread() {
delete m_renderer;
state=0;
cerr<<"deleting audio device"<<endl;
if (m_audio_device!=NULL) delete m_audio_device;
cerr<<"deleting renderer"<<endl;
delete m_renderer;
}
void audio_thread::start_audio() {
@ -45,11 +50,13 @@ void audio_thread::start_audio() {
}
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,
at->m_audio_device->right_out);
at->m_audio_device->maybe_record();
if (state) {
audio_thread *at = (audio_thread*)c;
at->m_audio_device->left_out.zero();
at->process(at->m_audio_device->left_out,
at->m_audio_device->right_out);
at->m_audio_device->maybe_record();
}
}
void audio_thread::process(sample &s, sample &s2) {
@ -76,11 +83,8 @@ void audio_thread::process(sample &s, sample &s2) {
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=="/novelty") {
m_renderer->get_params()->m_usage_importance = cmd.get_float(0);
}
if (name=="/restart_audio") {
start_audio();
@ -88,8 +92,13 @@ void audio_thread::process(sample &s, sample &s2) {
if (name=="/volume") {
m_renderer->set_volume(cmd.get_float(0)*10);
}
if (name=="/invert") {
m_renderer->set_invert(cmd.get_int(0));
if (name=="/search_algo") {
switch(cmd.get_int(0)) {
case 0: m_renderer->set_search_algo(renderer::BASIC); break;
case 1: m_renderer->set_search_algo(renderer::REV_BASIC); break;
case 2: m_renderer->set_search_algo(renderer::SYNAPTIC); break;
case 3: m_renderer->set_search_algo(renderer::SYNAPTIC_SLIDE); break;
}
}
if (name=="/n_mix") {
m_renderer->set_n_mix(cmd.get_float(0));
@ -105,6 +114,9 @@ void audio_thread::process(sample &s, sample &s2) {
m_audio_device->stop_recording();
m_renderer->set_playing(false);
}
if (name=="/boredom") {
m_renderer->get_source().set_usage_falloff(cmd.get_float(0));
}
}
s.zero();

View File

@ -1,14 +1,14 @@
/********************************************************************************
** Form generated from reading UI file 'samplebrainC26316.ui'
** Form generated from reading UI file 'samplebraing19815.ui'
**
** Created: Wed Jul 22 15:20:00 2015
** Created: Mon Jul 27 14:41:28 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 SAMPLEBRAINC26316_H
#define SAMPLEBRAINC26316_H
#ifndef SAMPLEBRAING19815_H
#define SAMPLEBRAING19815_H
#include <QtCore/QVariant>
#include <QtGui/QAction>
@ -43,34 +43,43 @@ public:
QVBoxLayout *verticalLayout_4;
QTabWidget *tabWidget;
QWidget *controlTab;
QHBoxLayout *horizontalLayout_10;
QHBoxLayout *horizontalLayout_17;
QVBoxLayout *verticalLayout_3;
QLabel *label_19;
QLabel *label_6;
QHBoxLayout *horizontalLayout_16;
QLabel *label_6;
QSlider *sliderRatio;
QDoubleSpinBox *doubleSpinBoxRatio;
QLabel *label_20;
QHBoxLayout *horizontalLayout;
QLabel *label_20;
QSlider *sliderNRatio;
QDoubleSpinBox *doubleSpinBoxNRatio;
QLabel *label_7;
QHBoxLayout *horizontalLayout_3;
QLabel *label_7;
QLabel *label_9;
QSpinBox *spinBoxFFT1Start;
QLabel *label_10;
QSpinBox *spinBoxFFT1End;
QHBoxLayout *horizontalLayout_10;
QLabel *label_24;
QSlider *sliderNovelty;
QDoubleSpinBox *doubleSpinBoxNovelty;
QHBoxLayout *horizontalLayout_11;
QLabel *label_25;
QSlider *sliderBoredom;
QDoubleSpinBox *doubleSpinBoxBoredom;
QCheckBox *checkBoxInvert;
QSpacerItem *horizontalSpacer_2;
QSpacerItem *verticalSpacer_3;
QLabel *label_23;
QLabel *label_21;
QHBoxLayout *horizontalLayout_8;
QLabel *label_21;
QSlider *sliderNMix;
QDoubleSpinBox *doubleSpinBoxNMix;
QLabel *label_22;
QHBoxLayout *horizontalLayout_9;
QLabel *label_22;
QSlider *sliderTargetMix;
QDoubleSpinBox *doubleSpinBoxTargetMix;
QSpacerItem *verticalSpacer_3;
QVBoxLayout *verticalLayout_6;
QLabel *label_16;
QPushButton *pushButtonLoadTarget;
@ -141,7 +150,7 @@ public:
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(724, 613);
MainWindow->resize(643, 619);
centralwidget = new QWidget(MainWindow);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
verticalLayout_4 = new QVBoxLayout(centralwidget);
@ -155,8 +164,8 @@ public:
tabWidget->setFont(font);
controlTab = new QWidget();
controlTab->setObjectName(QString::fromUtf8("controlTab"));
horizontalLayout_10 = new QHBoxLayout(controlTab);
horizontalLayout_10->setObjectName(QString::fromUtf8("horizontalLayout_10"));
horizontalLayout_17 = new QHBoxLayout(controlTab);
horizontalLayout_17->setObjectName(QString::fromUtf8("horizontalLayout_17"));
verticalLayout_3 = new QVBoxLayout();
verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3"));
label_19 = new QLabel(controlTab);
@ -170,6 +179,8 @@ public:
verticalLayout_3->addWidget(label_19);
horizontalLayout_16 = new QHBoxLayout();
horizontalLayout_16->setObjectName(QString::fromUtf8("horizontalLayout_16"));
label_6 = new QLabel(controlTab);
label_6->setObjectName(QString::fromUtf8("label_6"));
QFont font2;
@ -179,10 +190,8 @@ public:
font2.setWeight(75);
label_6->setFont(font2);
verticalLayout_3->addWidget(label_6);
horizontalLayout_16->addWidget(label_6);
horizontalLayout_16 = new QHBoxLayout();
horizontalLayout_16->setObjectName(QString::fromUtf8("horizontalLayout_16"));
sliderRatio = new QSlider(controlTab);
sliderRatio->setObjectName(QString::fromUtf8("sliderRatio"));
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
@ -211,14 +220,14 @@ public:
verticalLayout_3->addLayout(horizontalLayout_16);
horizontalLayout = new QHBoxLayout();
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
label_20 = new QLabel(controlTab);
label_20->setObjectName(QString::fromUtf8("label_20"));
label_20->setFont(font2);
verticalLayout_3->addWidget(label_20);
horizontalLayout->addWidget(label_20);
horizontalLayout = new QHBoxLayout();
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
sliderNRatio = new QSlider(controlTab);
sliderNRatio->setObjectName(QString::fromUtf8("sliderNRatio"));
sizePolicy.setHeightForWidth(sliderNRatio->sizePolicy().hasHeightForWidth());
@ -241,16 +250,21 @@ public:
verticalLayout_3->addLayout(horizontalLayout);
horizontalLayout_3 = new QHBoxLayout();
horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
label_7 = new QLabel(controlTab);
label_7->setObjectName(QString::fromUtf8("label_7"));
label_7->setFont(font2);
verticalLayout_3->addWidget(label_7);
horizontalLayout_3->addWidget(label_7);
horizontalLayout_3 = new QHBoxLayout();
horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
label_9 = new QLabel(controlTab);
label_9->setObjectName(QString::fromUtf8("label_9"));
QSizePolicy sizePolicy2(QSizePolicy::Fixed, QSizePolicy::Preferred);
sizePolicy2.setHorizontalStretch(0);
sizePolicy2.setVerticalStretch(0);
sizePolicy2.setHeightForWidth(label_9->sizePolicy().hasHeightForWidth());
label_9->setSizePolicy(sizePolicy2);
label_9->setFont(font);
horizontalLayout_3->addWidget(label_9);
@ -262,6 +276,8 @@ public:
label_10 = new QLabel(controlTab);
label_10->setObjectName(QString::fromUtf8("label_10"));
sizePolicy2.setHeightForWidth(label_10->sizePolicy().hasHeightForWidth());
label_10->setSizePolicy(sizePolicy2);
label_10->setFont(font);
horizontalLayout_3->addWidget(label_10);
@ -275,6 +291,66 @@ public:
verticalLayout_3->addLayout(horizontalLayout_3);
horizontalLayout_10 = new QHBoxLayout();
horizontalLayout_10->setObjectName(QString::fromUtf8("horizontalLayout_10"));
label_24 = new QLabel(controlTab);
label_24->setObjectName(QString::fromUtf8("label_24"));
label_24->setFont(font2);
horizontalLayout_10->addWidget(label_24);
sliderNovelty = new QSlider(controlTab);
sliderNovelty->setObjectName(QString::fromUtf8("sliderNovelty"));
sizePolicy.setHeightForWidth(sliderNovelty->sizePolicy().hasHeightForWidth());
sliderNovelty->setSizePolicy(sizePolicy);
sliderNovelty->setValue(0);
sliderNovelty->setOrientation(Qt::Horizontal);
horizontalLayout_10->addWidget(sliderNovelty);
doubleSpinBoxNovelty = new QDoubleSpinBox(controlTab);
doubleSpinBoxNovelty->setObjectName(QString::fromUtf8("doubleSpinBoxNovelty"));
sizePolicy1.setHeightForWidth(doubleSpinBoxNovelty->sizePolicy().hasHeightForWidth());
doubleSpinBoxNovelty->setSizePolicy(sizePolicy1);
doubleSpinBoxNovelty->setMaximum(1);
doubleSpinBoxNovelty->setSingleStep(0.01);
doubleSpinBoxNovelty->setValue(0);
horizontalLayout_10->addWidget(doubleSpinBoxNovelty);
verticalLayout_3->addLayout(horizontalLayout_10);
horizontalLayout_11 = new QHBoxLayout();
horizontalLayout_11->setObjectName(QString::fromUtf8("horizontalLayout_11"));
label_25 = new QLabel(controlTab);
label_25->setObjectName(QString::fromUtf8("label_25"));
label_25->setFont(font2);
horizontalLayout_11->addWidget(label_25);
sliderBoredom = new QSlider(controlTab);
sliderBoredom->setObjectName(QString::fromUtf8("sliderBoredom"));
sizePolicy.setHeightForWidth(sliderBoredom->sizePolicy().hasHeightForWidth());
sliderBoredom->setSizePolicy(sizePolicy);
sliderBoredom->setValue(0);
sliderBoredom->setOrientation(Qt::Horizontal);
horizontalLayout_11->addWidget(sliderBoredom);
doubleSpinBoxBoredom = new QDoubleSpinBox(controlTab);
doubleSpinBoxBoredom->setObjectName(QString::fromUtf8("doubleSpinBoxBoredom"));
sizePolicy1.setHeightForWidth(doubleSpinBoxBoredom->sizePolicy().hasHeightForWidth());
doubleSpinBoxBoredom->setSizePolicy(sizePolicy1);
doubleSpinBoxBoredom->setMaximum(1);
doubleSpinBoxBoredom->setSingleStep(0.01);
doubleSpinBoxBoredom->setValue(0);
horizontalLayout_11->addWidget(doubleSpinBoxBoredom);
verticalLayout_3->addLayout(horizontalLayout_11);
checkBoxInvert = new QCheckBox(controlTab);
checkBoxInvert->setObjectName(QString::fromUtf8("checkBoxInvert"));
checkBoxInvert->setSizeIncrement(QSize(0, 0));
@ -282,20 +358,28 @@ public:
verticalLayout_3->addWidget(checkBoxInvert);
horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
verticalLayout_3->addItem(horizontalSpacer_2);
verticalSpacer_3 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
verticalLayout_3->addItem(verticalSpacer_3);
label_23 = new QLabel(controlTab);
label_23->setObjectName(QString::fromUtf8("label_23"));
label_23->setFont(font1);
verticalLayout_3->addWidget(label_23);
horizontalLayout_8 = new QHBoxLayout();
horizontalLayout_8->setObjectName(QString::fromUtf8("horizontalLayout_8"));
label_21 = new QLabel(controlTab);
label_21->setObjectName(QString::fromUtf8("label_21"));
label_21->setFont(font2);
verticalLayout_3->addWidget(label_21);
horizontalLayout_8->addWidget(label_21);
horizontalLayout_8 = new QHBoxLayout();
horizontalLayout_8->setObjectName(QString::fromUtf8("horizontalLayout_8"));
sliderNMix = new QSlider(controlTab);
sliderNMix->setObjectName(QString::fromUtf8("sliderNMix"));
sizePolicy.setHeightForWidth(sliderNMix->sizePolicy().hasHeightForWidth());
@ -318,14 +402,14 @@ public:
verticalLayout_3->addLayout(horizontalLayout_8);
horizontalLayout_9 = new QHBoxLayout();
horizontalLayout_9->setObjectName(QString::fromUtf8("horizontalLayout_9"));
label_22 = new QLabel(controlTab);
label_22->setObjectName(QString::fromUtf8("label_22"));
label_22->setFont(font2);
verticalLayout_3->addWidget(label_22);
horizontalLayout_9->addWidget(label_22);
horizontalLayout_9 = new QHBoxLayout();
horizontalLayout_9->setObjectName(QString::fromUtf8("horizontalLayout_9"));
sliderTargetMix = new QSlider(controlTab);
sliderTargetMix->setObjectName(QString::fromUtf8("sliderTargetMix"));
sizePolicy.setHeightForWidth(sliderTargetMix->sizePolicy().hasHeightForWidth());
@ -349,12 +433,8 @@ public:
verticalLayout_3->addLayout(horizontalLayout_9);
verticalSpacer_3 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
verticalLayout_3->addItem(verticalSpacer_3);
horizontalLayout_10->addLayout(verticalLayout_3);
horizontalLayout_17->addLayout(verticalLayout_3);
verticalLayout_6 = new QVBoxLayout();
verticalLayout_6->setObjectName(QString::fromUtf8("verticalLayout_6"));
@ -469,7 +549,7 @@ public:
verticalLayout_6->addItem(verticalSpacer);
horizontalLayout_10->addLayout(verticalLayout_6);
horizontalLayout_17->addLayout(verticalLayout_6);
tabWidget->addTab(controlTab, QString());
sampleTab = new QWidget();
@ -766,6 +846,10 @@ public:
QObject::connect(sliderTargetMix, SIGNAL(valueChanged(int)), MainWindow, SLOT(target_mix_slot(int)));
QObject::connect(doubleSpinBoxNMix, SIGNAL(valueChanged(double)), MainWindow, SLOT(n_mix_slot(double)));
QObject::connect(doubleSpinBoxTargetMix, SIGNAL(valueChanged(double)), MainWindow, SLOT(target_mix_slot(double)));
QObject::connect(doubleSpinBoxBoredom, SIGNAL(valueChanged(double)), MainWindow, SLOT(boredom_slot(double)));
QObject::connect(sliderBoredom, SIGNAL(valueChanged(int)), MainWindow, SLOT(boredom_slot(int)));
QObject::connect(doubleSpinBoxNovelty, SIGNAL(valueChanged(double)), MainWindow, SLOT(novelty_slot(double)));
QObject::connect(sliderNovelty, SIGNAL(valueChanged(int)), MainWindow, SLOT(novelty_slot(int)));
tabWidget->setCurrentIndex(0);
@ -775,17 +859,55 @@ public:
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "samplebrain 0.0.4", 0, QApplication::UnicodeUTF8));
label_19->setText(QApplication::translate("MainWindow", "search", 0, QApplication::UnicodeUTF8));
label_6->setText(QApplication::translate("MainWindow", "fft <-> mfcc", 0, QApplication::UnicodeUTF8));
label_20->setText(QApplication::translate("MainWindow", "freq & dynamics <-> freq only", 0, QApplication::UnicodeUTF8));
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "samplebrain 0.0.5", 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", "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
#ifndef QT_NO_TOOLTIP
label_7->setToolTip(QString());
#endif // QT_NO_TOOLTIP
label_7->setText(QApplication::translate("MainWindow", "fft subsection", 0, QApplication::UnicodeUTF8));
label_9->setText(QApplication::translate("MainWindow", "Start", 0, QApplication::UnicodeUTF8));
#ifndef QT_NO_TOOLTIP
spinBoxFFT1Start->setToolTip(QApplication::translate("MainWindow", "start frequency to use for fft match", 0, QApplication::UnicodeUTF8));
#endif // QT_NO_TOOLTIP
label_10->setText(QApplication::translate("MainWindow", "End", 0, QApplication::UnicodeUTF8));
#ifndef QT_NO_TOOLTIP
spinBoxFFT1End->setToolTip(QApplication::translate("MainWindow", "end frequency to use for fft match", 0, QApplication::UnicodeUTF8));
#endif // QT_NO_TOOLTIP
#ifndef QT_NO_TOOLTIP
label_24->setToolTip(QString());
#endif // QT_NO_TOOLTIP
label_24->setText(QApplication::translate("MainWindow", "novelty", 0, QApplication::UnicodeUTF8));
#ifndef QT_NO_TOOLTIP
sliderNovelty->setToolTip(QApplication::translate("MainWindow", "use new blocks rather than similar ones", 0, QApplication::UnicodeUTF8));
#endif // QT_NO_TOOLTIP
#ifndef QT_NO_TOOLTIP
label_25->setToolTip(QString());
#endif // QT_NO_TOOLTIP
label_25->setText(QApplication::translate("MainWindow", "boredom", 0, QApplication::UnicodeUTF8));
#ifndef QT_NO_TOOLTIP
sliderBoredom->setToolTip(QApplication::translate("MainWindow", "how long it takes for the novelty to ware off", 0, QApplication::UnicodeUTF8));
#endif // QT_NO_TOOLTIP
#ifndef QT_NO_TOOLTIP
checkBoxInvert->setToolTip(QString());
#endif // QT_NO_TOOLTIP
checkBoxInvert->setText(QApplication::translate("MainWindow", "search for least similar", 0, QApplication::UnicodeUTF8));
label_23->setText(QApplication::translate("MainWindow", "mix", 0, QApplication::UnicodeUTF8));
label_21->setText(QApplication::translate("MainWindow", "dynamic <-> normalised mix", 0, QApplication::UnicodeUTF8));
label_22->setText(QApplication::translate("MainWindow", "brain <-> target mix", 0, QApplication::UnicodeUTF8));
label_21->setText(QApplication::translate("MainWindow", "dynamic / normalised ", 0, QApplication::UnicodeUTF8));
#ifndef QT_NO_TOOLTIP
sliderNMix->setToolTip(QApplication::translate("MainWindow", "mix in the normalised blocks", 0, QApplication::UnicodeUTF8));
#endif // QT_NO_TOOLTIP
label_22->setText(QApplication::translate("MainWindow", "brain / target", 0, QApplication::UnicodeUTF8));
#ifndef QT_NO_TOOLTIP
sliderTargetMix->setToolTip(QApplication::translate("MainWindow", "mix in the original blocks", 0, QApplication::UnicodeUTF8));
#endif // QT_NO_TOOLTIP
label_16->setText(QApplication::translate("MainWindow", "target sound", 0, QApplication::UnicodeUTF8));
pushButtonLoadTarget->setText(QApplication::translate("MainWindow", "load target", 0, QApplication::UnicodeUTF8));
label_17->setText(QApplication::translate("MainWindow", "block size", 0, QApplication::UnicodeUTF8));
@ -837,4 +959,4 @@ namespace Ui {
QT_END_NAMESPACE
#endif // SAMPLEBRAINC26316_H
#endif // SAMPLEBRAING19815_H

View File

@ -17,6 +17,7 @@
#include "process_thread.h"
#include <iostream>
#include <unistd.h>
#include "status.h"
using namespace spiralcore;
using namespace std;
@ -103,7 +104,6 @@ void process_thread::process() {
if (name=="/target_window_type") {
m_target_window_type=(window::type)cmd.get_int(0);
}
}
usleep(500);
}

View File

@ -16,6 +16,7 @@ HEADERS += MainWindow.h \
SOURCES += MainWindow.cpp \
audio_thread.cpp \
process_thread.cpp \
feedback.cpp \
qtmain.cpp
INCLUDEPATH += ../src

View File

@ -27,6 +27,14 @@ Aquila::Mfcc *block::m_mfcc_proc;
static const int MFCC_FILTERS=12;
double blend(double a, double b, double t) {
return a*(1-t)+b*t;
}
double square(double a) {
return a*a;
}
void normalise(sample &in) {
// find min/max
float max = 0;
@ -64,7 +72,8 @@ block::block(const string &filename, const sample &pcm, u32 rate, const window &
m_n_mfcc(MFCC_FILTERS),
m_block_size(pcm.get_length()),
m_rate(rate),
m_orig_filename(filename)
m_orig_filename(filename),
m_usage(0)
{
init_fft(m_pcm.get_length());
assert(m_mfcc_proc!=NULL);
@ -138,33 +147,37 @@ double block::_compare(const sample &fft_a, const sample &mfcc_a,
if (params.m_ratio==0) {
for (u32 i=fft_start; i<fft_end; ++i) {
fft_acc+=(fft_a[i]-fft_b[i]) * (fft_a[i]-fft_b[i]);
fft_acc+=square(fft_a[i]-fft_b[i]);
}
return (fft_acc/(float)fft_a.get_length())*FFT_BIAS;
}
if (params.m_ratio==1) {
for (u32 i=0; i<MFCC_FILTERS; ++i) {
mfcc_acc+=(mfcc_a[i]-mfcc_b[i]) * (mfcc_a[i]-mfcc_b[i]);
mfcc_acc+=square(mfcc_a[i]-mfcc_b[i]);
}
return mfcc_acc/(float)MFCC_FILTERS;
}
// calculate both
for (u32 i=fft_start; i<fft_end; ++i) {
fft_acc+=(fft_a[i]-fft_b[i]) * (fft_a[i]-fft_b[i]);
fft_acc+=square(fft_a[i]-fft_b[i]);
}
for (u32 i=0; i<MFCC_FILTERS; ++i) {
mfcc_acc+=(mfcc_a[i]-mfcc_b[i]) * (mfcc_a[i]-mfcc_b[i]);
mfcc_acc+=square(mfcc_a[i]-mfcc_b[i]);
}
return (fft_acc/(float)fft_a.get_length())*(1-params.m_ratio)*FFT_BIAS +
(mfcc_acc/(float)MFCC_FILTERS)*params.m_ratio;
return blend(fft_acc/(float)fft_a.get_length(),
mfcc_acc/(float)MFCC_FILTERS,
params.m_ratio);
}
double block::compare(const block &other, const search_params &params) const {
return _compare(m_fft, m_mfcc, other.m_fft, other.m_mfcc, params) * (1-params.m_n_ratio) +
_compare(m_n_fft, m_n_mfcc, other.m_n_fft, other.m_n_mfcc, params) * params.m_n_ratio;
return blend(
blend(_compare(m_fft, m_mfcc, other.m_fft, other.m_mfcc, params),
_compare(m_n_fft, m_n_mfcc, other.m_n_fft, other.m_n_mfcc, params),
params.m_n_ratio),
other.m_usage, params.m_usage_importance);
}
bool block::unit_test() {
@ -215,7 +228,7 @@ bool block::unit_test() {
assert(bb.m_rate==44100);
assert(bb.m_block_size==data.get_length());
search_params p(0,0,0,100,0,100);
search_params p(0,0,0,100,0);
block bb2("test",data,44100,w);
assert(bb.compare(bb2,p)==0);
p.m_ratio=1;

View File

@ -15,6 +15,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <string>
#include <vector>
#include "jellyfish/fluxa/sample.h"
#include "jellyfish/core/types.h"
#include "fft.h"
@ -41,6 +42,10 @@ public:
const sample &get_pcm() const { return m_pcm; }
const sample &get_n_pcm() const { return m_n_pcm; }
std::vector<u32> &get_synapse() { return m_synapse; }
const std::vector<u32> &get_synapse_const() const { return m_synapse; }
float &get_usage() { return m_usage; }
private:
void process(const sample &pcm, sample &fft, sample &mfcc);
@ -63,6 +68,9 @@ private:
static FFT *m_fftw;
static Aquila::Mfcc *m_mfcc_proc;
std::vector<u32> m_synapse;
float m_usage;
};
}

View File

@ -15,16 +15,23 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <iostream>
#include <algorithm>
#include <sndfile.h>
#include <float.h>
#include <jellyfish/audio.h>
#include "brain.h"
#include "status.h"
using namespace std;
using namespace spiralcore;
brain::brain()
brain::brain() :
m_current_block_index(0),
m_average_error(0),
m_current_error(0),
m_usage_falloff(0.9)
{
status::update("brain ready...");
}
// load, chop up and add to brain
@ -37,6 +44,7 @@ void brain::load_sound(std::string filename) {
sample s(sfinfo.frames);
sf_readf_float(f, s.get_non_const_buffer(), s.get_length());
m_samples.push_back(sound(filename,s));
status::update("loaded %s",filename.c_str());
}
}
@ -44,6 +52,7 @@ void brain::delete_sound(std::string filename) {
for (std::list<sound>::iterator i=m_samples.begin(); i!=m_samples.end(); ++i) {
if (i->m_filename==filename) {
m_samples.erase(i);
status::update("deleted %s",filename.c_str());
return;
}
}
@ -56,17 +65,19 @@ void brain::init(u32 block_size, u32 overlap, window::type t, bool ditchpcm) {
m_overlap = overlap;
m_window.init(block_size);
m_window.set_current_type(t);
u32 count=0;
for (std::list<sound>::iterator i=m_samples.begin(); i!=m_samples.end(); ++i) {
chop_and_add(i->m_sample, ditchpcm);
count++;
chop_and_add(i->m_sample, count, ditchpcm);
}
status::update("all samples processed");
}
void brain::chop_and_add(const sample &s, bool ditchpcm) {
void brain::chop_and_add(const sample &s, u32 count, bool ditchpcm) {
u32 pos=0;
if (m_overlap>=m_block_size) m_overlap=0;
while (pos+m_block_size-1<s.get_length()) {
cerr<<'\r';
cerr<<"adding: "<<pos/(float)s.get_length()*100;
status::update("processing sample %d: %d%%",count,(int)(pos/(float)s.get_length()*100));
sample region;
s.get_region(region,pos,pos+m_block_size-1);
m_blocks.push_back(block("",region,44100,m_window,ditchpcm));
@ -78,8 +89,10 @@ const block &brain::get_block(u32 index) const {
return m_blocks[index];
}
static const double usage_factor = 1000000;
// returns index to block
u32 brain::search(const block &target, const search_params &params) const {
u32 brain::search(const block &target, const search_params &params) {
double closest = FLT_MAX;
u32 closest_index = 0;
u32 index = 0;
@ -91,11 +104,13 @@ u32 brain::search(const block &target, const search_params &params) const {
}
++index;
}
deplete_usage();
m_blocks[closest_index].get_usage()+=usage_factor;
return closest_index;
}
// returns index to block
u32 brain::rev_search(const block &target, const search_params &params) const {
u32 brain::rev_search(const block &target, const search_params &params) {
double furthest = 0;
u32 furthest_index = 0;
u32 index = 0;
@ -107,9 +122,80 @@ u32 brain::rev_search(const block &target, const search_params &params) const {
}
++index;
}
deplete_usage();
m_blocks[furthest_index].get_usage()+=usage_factor;
return furthest_index;
}
double brain::calc_average_diff(search_params &params) {
double diff=0;
for (vector<block>::const_iterator i=m_blocks.begin(); i!=m_blocks.end(); ++i) {
for (vector<block>::const_iterator j=m_blocks.begin(); j!=m_blocks.end(); ++j) {
diff += j->compare(*i,params);
}
diff/=(double)m_blocks.size();
}
return diff;
}
void brain::build_synapses(search_params &params, double thresh) {
m_average_error = calc_average_diff(params)*thresh;
double err=m_average_error*thresh;
u32 brain_size = m_blocks.size();
u32 outer_index=0;
for (vector<block>::iterator i=m_blocks.begin(); i!=m_blocks.end(); ++i) {
u32 index = 0;
status::update("building synapses %d%%",(int)(outer_index/(float)brain_size*100));
for (vector<block>::const_iterator j=m_blocks.begin(); j!=m_blocks.end(); ++j) {
if (index!=outer_index) {
double diff = i->compare(*j,params);
if (diff<err) {
i->get_synapse().push_back(index);
}
}
++index;
}
++outer_index;
}
}
u32 brain::search_synapses(const block &target, search_params &params) {
const block &current = get_block(m_current_block_index);
double closest = DBL_MAX;
u32 closest_index = 0;
// find nearest in synaptic connections
// cerr<<"searching "<<current.get_synapse_const().size()<<" connections"<<endl;
for (vector<u32>::const_iterator i=current.get_synapse_const().begin();
i!=current.get_synapse_const().end(); ++i) {
const block &other = get_block(*i);
double diff = target.compare(other,params);
if (diff<closest) {
closest=diff;
closest_index = *i;
}
}
deplete_usage();
m_blocks[m_current_block_index].get_usage()+=usage_factor;
m_current_error = closest;
if (closest_index!=0) {
//cerr<<"usage:"<<m_blocks[closest_index].get_usage()<<endl;
m_current_block_index = closest_index;
}
return m_current_block_index;
}
void brain::deplete_usage() {
for (vector<block>::iterator i=m_blocks.begin(); i!=m_blocks.end(); ++i) {
i->get_usage()*=m_usage_falloff;
}
}
// 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, const search_params &params){
@ -145,7 +231,6 @@ bool brain::unit_test() {
b.load_sound("test_data/100f32.wav");
b.load_sound("test_data/100i16.wav");
assert(b.m_samples.size()==2);
cerr<<"hjelele"<<endl;
b.init(10, 0, window::RECTANGLE);
assert(b.m_blocks.size()==20);
@ -166,7 +251,7 @@ bool brain::unit_test() {
b2.init(512, 0, window::BLACKMAN);
b3.init(512, 0, window::BLACKMAN);
search_params p(1,0,0,100,0,100);
search_params p(1,0,0,100,0);
assert(b3.search(b2.m_blocks[0],p)==0);
assert(b3.search(b2.m_blocks[9],p)==9);

View File

@ -60,14 +60,24 @@ public:
u32 get_block_size() const { return m_block_size; }
u32 get_overlap() const { return m_overlap; }
u32 search(const block &target, const search_params &params) const;
u32 rev_search(const block &target, const search_params &params) const;
void set_usage_falloff(float s) { m_usage_falloff=s; }
// basic search
u32 search(const block &target, const search_params &params);
u32 rev_search(const block &target, const search_params &params);
// synaptic search
double calc_average_diff(search_params &params);
void build_synapses(search_params &params, double threshold);
u32 search_synapses(const block &target, search_params &params);
double get_current_error() { return m_current_error/m_average_error; }
static bool unit_test();
private:
void chop_and_add(const sample &s, bool ditchpcm=false);
void chop_and_add(const sample &s, u32 count, bool ditchpcm=false);
void deplete_usage();
vector<block> m_blocks;
std::list<sound> m_samples;
@ -77,6 +87,10 @@ private:
window m_window;
u32 m_current_block_index;
double m_current_error;
double m_average_error;
float m_usage_falloff;
};
}

View File

@ -12,6 +12,9 @@
/* Define to 1 if you have the `jellyfish' library (-ljellyfish). */
#undef HAVE_LIBJELLYFISH
/* Define to 1 if you have the `lo' library (-llo). */
#undef HAVE_LIBLO
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM

View File

@ -18,6 +18,7 @@
#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <float.h>
#include "jellyfish/audio.h"
@ -47,7 +48,7 @@ void run_audio(void* c, unsigned int frames) {
a->left_out.zero();
renderer *rr = (renderer*)c;
rr->process(frames,a->left_out.get_non_const_buffer());
a->right_out=a->left_out;
a->maybe_record();
// sleep(1);
@ -61,25 +62,39 @@ int main(int argc, char *argv[])
brain source, target;
// source.load_sound("../sound/source/shostakovich6.wav");
/* source.load_sound("../sound/source/808.wav");
// source.load_sound("../sound/source/808.wav");
source.load_sound("../sound/source/joey.wav");
source.load_sound("../sound/source/pw2.wav");
source.load_sound("../sound/source/pw3.wav");
// source.load_sound("../sound/source/pw3.wav");
source.load_sound("../sound/source/claps.wav");
source.load_sound("../sound/source/eagle.wav");
target.load_sound("../sound/source/apache.wav");
*/
source.load_sound("../sound/source/totalsine.wav");
// source.load_sound("../sound/source/eagle.wav");
// source.load_sound("../sound/source/rise.wav");
// source.load_sound("../sound/source/totalsine.wav");
// target.load_sound("../sound/source/apache.wav");
target.load_sound("../sound/source/sailingbybit.wav");
// source.load_sound("../sound/source/totalsine.wav");
//target.load_sound("../sound/source/sailingbybit.wav");
target.load_sound("../sound/source/apache.wav");
//target.load_sound("../sound/source/dreambit.wav");
//target.load_sound("../sound/source/sb-left.wav");
// target.load_sound("../sound/source/rise.wav");
//target.load_sound("../sound/source/rise.wav");
cerr<<"loaded sounds"<<endl;
cerr<<endl;
u32 len=3000;
source.init(len,len-len,window::HANN);
target.init(len,len-len,window::HANN);
target.init(len,len-len/8,window::HANN);
cerr<<"synapse stuff"<<endl;
cerr<<"synapse stuff"<<endl;
cerr<<"synapse stuff"<<endl;
search_params p(0.5,0,0,99,0);
source.build_synapses(p,0.9);
source.set_usage_falloff(0.9);
cerr<<"ready..."<<endl;
cerr<<"we have "<<source.get_num_blocks()<<" brain blocks ("<<source.get_num_blocks()*len/44100.0<<" secs)"<<endl<<endl;
@ -90,6 +105,9 @@ int main(int argc, char *argv[])
renderer rr(source,target);
rr.set_playing(true);
rr.get_params()->m_ratio=0.5;
rr.get_params()->m_usage_importance=0.5;
rr.set_slide_error(5.5);
rr.set_search_algo(renderer::SYNAPTIC);
a->start_recording("debug");
a->m_client.set_callback(run_audio, &rr);

View File

@ -22,14 +22,17 @@ using namespace std;
void renderer::init(brain &source, brain &target) {
m_volume=1;
m_invert=false;
m_playing=false;
m_source=source;
m_target=target;
m_target_time=0;
m_render_time=0;
m_n_mix=0;
m_target_mix=0;
m_render_blocks.clear();
m_search_algo=BASIC;
m_slide_error=1;
m_target_index=0;
}
static int ratio_time = 0;
@ -39,32 +42,55 @@ void renderer::process(u32 nframes, float *buf) {
// get new 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;
u32 tgt_end = (m_target_time+nframes)/(float)tgt_shift;
if (tgt_end>=m_target.get_num_blocks() || m_source.get_num_blocks()==0) {
m_target_time=0;
m_render_time=0;
m_target_index=0;
m_render_blocks.clear();
// next time...
return;
}
//cerr<<"-----------------"<<endl;
//cerr<<"tgt start:"<<tgt_start<<endl;
//cerr<<"tgt end:"<<tgt_end<<endl;
// cerr<<"-----------------"<<endl;
// cerr<<"tgt start:"<<m_target_index<<endl;
// cerr<<"tgt end:"<<tgt_end<<endl;
// get indices for current buffer
for (u32 tgt_index = tgt_start+1; tgt_index<=tgt_end; tgt_index++) {
u32 time=tgt_index*tgt_shift;
u32 src_index;
if (!m_invert) {
src_index = m_source.search(m_target.get_block(tgt_index), m_search_params);
} else {
src_index = m_source.rev_search(m_target.get_block(tgt_index), m_search_params);
u32 counter = m_target_index;
//u32 cur_time = m_render_time;
while (counter<=tgt_end) {
u32 time=m_target_index*tgt_shift;
u32 src_index=0;
switch (m_search_algo) {
case BASIC:
src_index = m_source.search(m_target.get_block(m_target_index), m_search_params);
break;
case REV_BASIC:
src_index = m_source.rev_search(m_target.get_block(m_target_index), m_search_params);
break;
case SYNAPTIC:
case SYNAPTIC_SLIDE:
src_index = m_source.search_synapses(m_target.get_block(m_target_index), m_search_params);
break;
}
// put them in the index list
m_render_blocks.push_back(render_block(src_index,tgt_index,time));
if (m_search_algo==SYNAPTIC_SLIDE) {
m_render_blocks.push_back(render_block(src_index,m_target_index,time));
if (m_source.get_current_error()<m_slide_error) {
m_target_index++;
}
else{ cerr<<"skip"<<endl; }
} else {
// put them in the index list
m_render_blocks.push_back(render_block(src_index,m_target_index,time));
m_target_index++;
}
counter++;
}
// render all blocks in list
@ -123,6 +149,7 @@ void renderer::process(u32 nframes, float *buf) {
}
m_render_time+=nframes;
m_target_time+=nframes;
}
bool renderer::unit_test() {
@ -138,7 +165,7 @@ bool renderer::unit_test() {
rr.set_playing(true);
float *buf=new float[10];
rr.process(10,buf);
assert(rr.m_render_blocks.size()==1);
assert(rr.m_render_blocks.size()==2);
rr.process(10,buf);
assert(rr.m_render_blocks.size()==2);
delete[] buf;
@ -150,7 +177,7 @@ bool renderer::unit_test() {
target.init(10,5,window::RECTANGLE);
rr.process(10,buf);
assert(rr.m_render_blocks.size()==3);
assert(rr.m_render_blocks.size()==5);
delete[] buf;
}

View File

@ -28,19 +28,29 @@ public:
renderer(brain &source, brain &target) :
m_source(source),
m_target(target),
m_search_params(0,0,0,100,0,100)
{ init(source,target); }
m_search_params(0,0,0,100,1)
{ init(source,target); }
enum search_algo {
BASIC = 0,
REV_BASIC,
SYNAPTIC,
SYNAPTIC_SLIDE
};
void init(brain &source, brain &target);
void process(u32 nframes, float *buf);
void set_search_algo(search_algo s) { m_search_algo=s; }
void set_playing(bool s) { m_playing=s; }
void set_volume(float s) { m_volume=s; }
void set_invert(bool s) { m_invert=s; }
void set_n_mix(float s) { m_n_mix=s; }
void set_target_mix(float s) { m_target_mix=s; }
void set_slide_error(double s) { m_slide_error=s; }
search_params *get_params() { return &m_search_params; }
brain &get_source() { return m_source; }
static bool unit_test();
private:
@ -62,11 +72,17 @@ private:
search_params m_search_params;
float m_volume;
bool m_playing;
bool m_invert;
std::list<render_block> m_render_blocks;
u32 m_target_index;
u32 m_target_time;
u32 m_render_time;
float m_n_mix;
float m_target_mix;
search_algo m_search_algo;
double m_slide_error;
std::list<render_block> m_render_blocks;
};
}

View File

@ -21,21 +21,18 @@ namespace spiralcore {
class search_params {
public:
search_params(float ratio, float n_ratio, int s1, int e1, int s2, int e2) :
search_params(float ratio, float n_ratio, int s1, int e1, float usage_importance) :
m_ratio(ratio),
m_n_ratio(n_ratio),
m_fft1_start(s1),
m_fft1_end(e1),
m_fft2_start(s2),
m_fft2_end(e2) {}
m_usage_importance(usage_importance) {}
float m_ratio;
float m_n_ratio;
int m_fft1_start;
int m_fft1_end;
int m_fft2_start;
int m_fft2_end;
float m_usage_importance;
};
}