Compare commits
14 Commits
1d03e9addd
...
7a02dcfa3c
| Author | SHA1 | Date |
|---|---|---|
|
|
7a02dcfa3c | |
|
|
b983408bd7 | |
|
|
fa44d2b4c7 | |
|
|
8e7a9abe1a | |
|
|
65ea2080be | |
|
|
edf2071467 | |
|
|
2e517e3bff | |
|
|
1b766822f6 | |
|
|
bc8002a9f0 | |
|
|
f9f3557b79 | |
|
|
c4499ce7c9 | |
|
|
46ab0a131a | |
|
|
884c8ad91f | |
|
|
8aa0dee3d1 |
|
|
@ -3,7 +3,7 @@ build-job:
|
||||||
image: ubuntu:22.04
|
image: ubuntu:22.04
|
||||||
script:
|
script:
|
||||||
- apt-get update
|
- apt-get update
|
||||||
- apt-get install -y git cmake g++ freeglut3-dev qtbase5-dev qt5-qmake qtbase5-dev-tools
|
- apt-get install -y git cmake g++ freeglut3-dev qt6-base-dev qt5-qmake qtbase5-dev-tools
|
||||||
- mkdir -p build
|
- mkdir -p build
|
||||||
- cd build
|
- cd build
|
||||||
- cmake ..
|
- cmake ..
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,9 @@ set(CMAKE_AUTOUIC ON)
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
find_package(QT NAMES Qt5 REQUIRED COMPONENTS Core)
|
find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Core)
|
||||||
find_package(Qt5 REQUIRED COMPONENTS Gui Widgets)
|
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui Widgets)
|
||||||
|
find_package(OpenMP)
|
||||||
|
|
||||||
add_executable(samplebrain WIN32 MACOSX_BUNDLE
|
add_executable(samplebrain WIN32 MACOSX_BUNDLE
|
||||||
app/MainWindow.cpp app/MainWindow.h
|
app/MainWindow.cpp app/MainWindow.h
|
||||||
|
|
@ -55,15 +56,20 @@ target_include_directories(samplebrain PRIVATE
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(samplebrain PRIVATE
|
target_link_libraries(samplebrain PRIVATE
|
||||||
Qt5::Core
|
Qt::Core
|
||||||
Qt5::Gui
|
Qt::Gui
|
||||||
Qt5::Widgets
|
Qt::Widgets
|
||||||
fftw3
|
fftw3
|
||||||
lo_shared
|
lo_shared
|
||||||
portaudio
|
portaudio
|
||||||
sndfile
|
sndfile
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(OpenMP_CXX_FOUND)
|
||||||
|
target_link_libraries(samplebrain PUBLIC OpenMP::OpenMP_CXX)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# Resources:
|
# Resources:
|
||||||
set(samplebrain_resource_files
|
set(samplebrain_resource_files
|
||||||
"app/images/at.png"
|
"app/images/at.png"
|
||||||
|
|
@ -74,14 +80,14 @@ set(samplebrain_resource_files
|
||||||
"app/images/stop.png"
|
"app/images/stop.png"
|
||||||
)
|
)
|
||||||
|
|
||||||
#qt5_add_resources(samplebrain "samplebrain"
|
qt_add_resources(samplebrain "samplebrain"
|
||||||
# PREFIX
|
PREFIX
|
||||||
# "/images"
|
"/images"
|
||||||
# BASE
|
BASE
|
||||||
# "app"
|
"app"
|
||||||
# FILES
|
FILES
|
||||||
# ${samplebrain_resource_files}
|
${samplebrain_resource_files}
|
||||||
#)
|
)
|
||||||
|
|
||||||
install(TARGETS samplebrain
|
install(TARGETS samplebrain
|
||||||
BUNDLE DESTINATION .
|
BUNDLE DESTINATION .
|
||||||
|
|
|
||||||
18
README.md
18
README.md
|
|
@ -34,6 +34,10 @@ both the target and brain samples). The original samples used to
|
||||||
create the demo session [can be found here for
|
create the demo session [can be found here for
|
||||||
testing](https://static.thentrythis.org/samplebrain/samples/).
|
testing](https://static.thentrythis.org/samplebrain/samples/).
|
||||||
|
|
||||||
|
# Community
|
||||||
|
|
||||||
|
* https://www.reddit.com/r/samplebrain/
|
||||||
|
|
||||||
# Download
|
# Download
|
||||||
|
|
||||||
As this is experimental non-commercial software (only originally
|
As this is experimental non-commercial software (only originally
|
||||||
|
|
@ -41,12 +45,16 @@ written to run on a couple of computers!) you will have to bear with
|
||||||
us as we gradually stabilise things based on your feedback. There
|
us as we gradually stabilise things based on your feedback. There
|
||||||
might currently be problems running it on 64bit Windows.
|
might currently be problems running it on 64bit Windows.
|
||||||
|
|
||||||
* **Windows**: [samplebrain_0.18.4_win.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18.4_win.zip)
|
* **Windows**: [samplebrain_0.18.5_win.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18.5_win.zip)
|
||||||
* **Mac (intel/m1)**: [samplebrain_0.18.4_macintel.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18.4_macintel.app.zip)
|
* **Mac (intel/m1)**: [samplebrain_0.18.5_macintel.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18.5_macintel.app.zip)
|
||||||
|
|
||||||
Changes in 0.18.4: New audio device settings window and updated
|
Changes in 0.18.5 (relased 28/10/22):
|
||||||
windows build. Better default block size, tool tip tweaks and fixes
|
|
||||||
for dark themes by [Claude Heiland-Allen](https://mathr.co.uk/).
|
* Target sound filename shown (and tells you if you don't have one)
|
||||||
|
* More soundfile formats supported (aiff,aifc,au,snd,fasttracker xi,flac)
|
||||||
|
* New configurable OSC ports in settings
|
||||||
|
* Warning boxes if the OSC network connection fails
|
||||||
|
* File path memory per-dialog rather than global
|
||||||
|
|
||||||
For old versions see the [changelog](changelog.md)
|
For old versions see the [changelog](changelog.md)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,11 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
MainWindow::MainWindow(const string &port, const string &audio_port, const string &process_port, QSettings *settings) :
|
MainWindow::MainWindow(const string &port, const string &audio_port, const string &process_port, QSettings *settings) :
|
||||||
m_last_file("."),
|
m_last_sound_file("."),
|
||||||
|
m_last_target_file("."),
|
||||||
|
m_last_brain_file("."),
|
||||||
|
m_last_session_file("."),
|
||||||
|
m_last_recording_file("."),
|
||||||
m_feedback(port),
|
m_feedback(port),
|
||||||
m_audio_port(audio_port),
|
m_audio_port(audio_port),
|
||||||
m_process_port(process_port),
|
m_process_port(process_port),
|
||||||
|
|
@ -157,6 +161,12 @@ void MainWindow::init_from_session(const string &filename) {
|
||||||
m_Ui.spinBoxSlideError->setValue(r.get_slide_error());
|
m_Ui.spinBoxSlideError->setValue(r.get_slide_error());
|
||||||
|
|
||||||
// target
|
// target
|
||||||
|
if (t.get_samples().size()>0) {
|
||||||
|
// extract target filename from brain sample
|
||||||
|
string fn = t.get_samples().begin()->m_filename;
|
||||||
|
m_Ui.labelTargetSound->setText("loaded: "+QFileInfo(QString::fromStdString(fn)).fileName());
|
||||||
|
}
|
||||||
|
|
||||||
m_Ui.spinBoxBlockSizeTarget->setValue(t.get_block_size());
|
m_Ui.spinBoxBlockSizeTarget->setValue(t.get_block_size());
|
||||||
m_Ui.doubleSpinBoxBlockOverlapTarget->setValue(t.get_overlap()/(float)t.get_block_size());
|
m_Ui.doubleSpinBoxBlockOverlapTarget->setValue(t.get_overlap()/(float)t.get_block_size());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -206,12 +206,15 @@ private slots:
|
||||||
|
|
||||||
void run_slot() {}
|
void run_slot() {}
|
||||||
void load_target() {
|
void load_target() {
|
||||||
m_last_file=QFileDialog::getOpenFileName(this,
|
QString path=QFileDialog::getOpenFileName(this,
|
||||||
QString("Select an audio file"),
|
QString("Select an audio file"),
|
||||||
m_last_file,
|
m_last_target_file,
|
||||||
m_format_string);
|
m_format_string);
|
||||||
|
if (m_last_target_file!="") {
|
||||||
send_process_osc("/load_target","s",m_last_file.toStdString().c_str());
|
m_last_target_file=path;
|
||||||
|
m_Ui.labelTargetSound->setText("loaded: "+QFileInfo(path).fileName());
|
||||||
|
send_process_osc("/load_target","s",m_last_target_file.toStdString().c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void target_block_size(int s) { send_process_osc("/target_block_size","i",s); }
|
void target_block_size(int s) { send_process_osc("/target_block_size","i",s); }
|
||||||
void target_block_overlap(double s) { send_process_osc("/target_overlap","f",s); }
|
void target_block_overlap(double s) { send_process_osc("/target_overlap","f",s); }
|
||||||
|
|
@ -221,14 +224,15 @@ private slots:
|
||||||
void fft_spectrum_size(int) {}
|
void fft_spectrum_size(int) {}
|
||||||
void generate() { send_process_osc("/generate_brain",""); }
|
void generate() { send_process_osc("/generate_brain",""); }
|
||||||
void load_sound() {
|
void load_sound() {
|
||||||
m_last_file=QFileDialog::getOpenFileName(this,
|
QString path=QFileDialog::getOpenFileName(this,
|
||||||
QString("Select a wav file"),
|
QString("Select a wav file"),
|
||||||
m_last_file,
|
m_last_sound_file,
|
||||||
m_format_string);
|
m_format_string);
|
||||||
|
|
||||||
if (m_last_file!="") {
|
if (path!="") {
|
||||||
send_process_osc("/load_sample","s",m_last_file.toStdString().c_str());
|
m_last_sound_file=path;
|
||||||
sound_items::sound_item &si = m_sound_items.add(m_Ui.brain_contents, m_last_file.toStdString(),true);
|
send_process_osc("/load_sample","s",m_last_sound_file.toStdString().c_str());
|
||||||
|
sound_items::sound_item &si = m_sound_items.add(m_Ui.brain_contents, m_last_sound_file.toStdString(),true);
|
||||||
QObject::connect(si.m_enable, SIGNAL(clicked()), m_sound_item_enable_mapper, SLOT(map()));
|
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);
|
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()));
|
QObject::connect(si.m_del, SIGNAL(clicked()), m_sound_item_delete_mapper, SLOT(map()));
|
||||||
|
|
@ -238,12 +242,13 @@ private slots:
|
||||||
|
|
||||||
|
|
||||||
void load_sounds() {
|
void load_sounds() {
|
||||||
m_last_file=QFileDialog::getExistingDirectory(this,
|
QString path=QFileDialog::getExistingDirectory(this,
|
||||||
QString("Select a directory of wav files"),
|
QString("Select a directory of wav files"),
|
||||||
m_last_file);
|
m_last_directory_file);
|
||||||
|
|
||||||
|
if (path!="") {
|
||||||
QDirIterator dirIt(m_last_file,QDirIterator::Subdirectories);
|
m_last_directory_file=path;
|
||||||
|
QDirIterator dirIt(m_last_directory_file,QDirIterator::Subdirectories);
|
||||||
while (dirIt.hasNext()) {
|
while (dirIt.hasNext()) {
|
||||||
dirIt.next();
|
dirIt.next();
|
||||||
if (QFileInfo(dirIt.filePath()).isFile() &&
|
if (QFileInfo(dirIt.filePath()).isFile() &&
|
||||||
|
|
@ -260,6 +265,7 @@ private slots:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void select_all() {
|
void select_all() {
|
||||||
for (auto &si:m_sound_items.m_sound_items) {
|
for (auto &si:m_sound_items.m_sound_items) {
|
||||||
|
|
@ -313,12 +319,11 @@ private slots:
|
||||||
|
|
||||||
void record() {
|
void record() {
|
||||||
if (m_save_wav=="") {
|
if (m_save_wav=="") {
|
||||||
m_last_file=QFileDialog::getSaveFileName(
|
m_last_recording_file=QFileDialog::getSaveFileName(this,
|
||||||
this,
|
|
||||||
QString("Select a wav file"),
|
QString("Select a wav file"),
|
||||||
m_last_file,
|
m_last_recording_file,
|
||||||
QString("Sounds (*.wav);;All files (*.*)"));
|
QString("Sounds (*.wav);;All files (*.*)"));
|
||||||
m_save_wav = m_last_file.toStdString();
|
m_save_wav = m_last_recording_file.toStdString();
|
||||||
// chop off .wav
|
// chop off .wav
|
||||||
size_t pos = m_save_wav.find_last_of(".");
|
size_t pos = m_save_wav.find_last_of(".");
|
||||||
if (pos!=string::npos) {
|
if (pos!=string::npos) {
|
||||||
|
|
@ -339,43 +344,48 @@ private slots:
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_brain() {
|
void load_brain() {
|
||||||
m_last_file=QFileDialog::getOpenFileName(
|
QString path=QFileDialog::getOpenFileName(this,
|
||||||
this,
|
|
||||||
QString("Select a brain file"),
|
QString("Select a brain file"),
|
||||||
m_last_file,
|
m_last_brain_file,
|
||||||
QString("Brains (*.brain);;All files (*.*)"));
|
QString("Brains (*.brain);;All files (*.*)"));
|
||||||
|
|
||||||
send_process_osc("/load_brain","s",m_last_file.toStdString().c_str());
|
if (path!="") {
|
||||||
|
m_last_brain_file=path;
|
||||||
|
send_process_osc("/load_brain","s",m_last_brain_file.toStdString().c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void save_brain() {
|
void save_brain() {
|
||||||
m_last_file=QFileDialog::getSaveFileName(
|
QString path=QFileDialog::getSaveFileName(this,
|
||||||
this,
|
|
||||||
QString("Select a brain file"),
|
QString("Select a brain file"),
|
||||||
m_last_file,
|
m_last_brain_file,
|
||||||
QString("Brains (*.brain);;All files (*.*)"));
|
QString("Brains (*.brain);;All files (*.*)"));
|
||||||
|
if (path!="") {
|
||||||
send_process_osc("/save_brain","s",m_last_file.toStdString().c_str());
|
m_last_brain_file=path;
|
||||||
|
send_process_osc("/save_brain","s",m_last_brain_file.toStdString().c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_session() {
|
void load_session() {
|
||||||
m_last_file=QFileDialog::getOpenFileName(
|
QString path=QFileDialog::getOpenFileName(this,
|
||||||
this,
|
|
||||||
QString("Select a session file"),
|
QString("Select a session file"),
|
||||||
m_last_file,
|
m_last_session_file,
|
||||||
QString("Sessions *.samplebrain (*.samplebrain);;All files (*.*)"));
|
QString("Sessions *.samplebrain (*.samplebrain);;All files (*.*)"));
|
||||||
|
if (path!="") {
|
||||||
send_process_osc("/load_session","s",m_last_file.toStdString().c_str());
|
m_last_session_file=path;
|
||||||
init_from_session(m_last_file.toStdString());
|
send_process_osc("/load_session","s",m_last_session_file.toStdString().c_str());
|
||||||
|
init_from_session(m_last_session_file.toStdString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_session() {
|
void save_session() {
|
||||||
m_last_file=QFileDialog::getSaveFileName(
|
QString path=QFileDialog::getSaveFileName(this,
|
||||||
this,
|
|
||||||
QString("Select a session file"),
|
QString("Select a session file"),
|
||||||
m_last_file,
|
m_last_session_file,
|
||||||
QString("Sessions *.samplebrain (*.samplebrain)"));
|
QString("Sessions *.samplebrain (*.samplebrain)"));
|
||||||
|
if (path!="") {
|
||||||
send_process_osc("/save_session","s",m_last_file.toStdString().c_str());
|
m_last_session_file=path;
|
||||||
|
send_process_osc("/save_session","s",m_last_session_file.toStdString().c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_status() {
|
void update_status() {
|
||||||
|
|
@ -440,7 +450,12 @@ private:
|
||||||
QSignalMapper* enable_mapper);
|
QSignalMapper* enable_mapper);
|
||||||
|
|
||||||
string m_save_wav;
|
string m_save_wav;
|
||||||
QString m_last_file;
|
QString m_last_sound_file;
|
||||||
|
QString m_last_target_file;
|
||||||
|
QString m_last_directory_file;
|
||||||
|
QString m_last_brain_file;
|
||||||
|
QString m_last_session_file;
|
||||||
|
QString m_last_recording_file;
|
||||||
unsigned int m_record_id;
|
unsigned int m_record_id;
|
||||||
Ui_MainWindow m_Ui;
|
Ui_MainWindow m_Ui;
|
||||||
feedback m_feedback;
|
feedback m_feedback;
|
||||||
|
|
|
||||||
|
|
@ -728,6 +728,13 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelTargetSound">
|
||||||
|
<property name="text">
|
||||||
|
<string>no target sound loaded</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pushButtonLoadTarget">
|
<widget class="QPushButton" name="pushButtonLoadTarget">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
|
|
@ -1112,8 +1119,8 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>20</width>
|
<width>17</width>
|
||||||
<height>40</height>
|
<height>13</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
|
|
@ -1466,7 +1473,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../app/samplebrain.qrc">
|
<iconset resource="../samplebrain.qrc">
|
||||||
<normaloff>:/images/images/play.png</normaloff>:/images/images/play.png</iconset>
|
<normaloff>:/images/images/play.png</normaloff>:/images/images/play.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
|
|
@ -1493,7 +1500,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../app/samplebrain.qrc">
|
<iconset resource="../samplebrain.qrc">
|
||||||
<normaloff>:/images/images/pause.png</normaloff>:/images/images/pause.png</iconset>
|
<normaloff>:/images/images/pause.png</normaloff>:/images/images/pause.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
|
|
@ -1513,7 +1520,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../app/samplebrain.qrc">
|
<iconset resource="../samplebrain.qrc">
|
||||||
<normaloff>:/images/images/record.png</normaloff>:/images/images/record.png</iconset>
|
<normaloff>:/images/images/record.png</normaloff>:/images/images/record.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
|
|
@ -1533,7 +1540,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../app/samplebrain.qrc">
|
<iconset resource="../samplebrain.qrc">
|
||||||
<normaloff>:/images/images/stop.png</normaloff>:/images/images/stop.png</iconset>
|
<normaloff>:/images/images/stop.png</normaloff>:/images/images/stop.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
|
|
@ -1599,7 +1606,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../app/samplebrain.qrc">
|
<iconset resource="../samplebrain.qrc">
|
||||||
<normaloff>:/images/images/settings.png</normaloff>:/images/images/settings.png</iconset>
|
<normaloff>:/images/images/settings.png</normaloff>:/images/images/settings.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
|
|
@ -1632,7 +1639,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="pixmap">
|
<property name="pixmap">
|
||||||
<pixmap resource="../app/samplebrain.qrc">:/images/images/at.png</pixmap>
|
<pixmap resource="../samplebrain.qrc">:/images/images/at.png</pixmap>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -1643,6 +1650,7 @@
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
|
<include location="../samplebrain.qrc"/>
|
||||||
<include location="../app/samplebrain.qrc"/>
|
<include location="../app/samplebrain.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ void block::process(const sample &pcm, sample &fft, sample &mfcc, float &freq) {
|
||||||
|
|
||||||
// calculate fft
|
// calculate fft
|
||||||
std::vector<std::complex<double> > mfspec;
|
std::vector<std::complex<double> > mfspec;
|
||||||
|
mfspec.reserve(m_block_size);
|
||||||
for (u32 i=0; i<m_block_size; ++i) {
|
for (u32 i=0; i<m_block_size; ++i) {
|
||||||
mfspec.push_back(std::complex<double>(m_fftw->m_spectrum[i][0],
|
mfspec.push_back(std::complex<double>(m_fftw->m_spectrum[i][0],
|
||||||
m_fftw->m_spectrum[i][1]));
|
m_fftw->m_spectrum[i][1]));
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ void block_stream::init(u32 block_size, u32 overlap, window::type t, bool ditchp
|
||||||
m_window.set_current_type(t);
|
m_window.set_current_type(t);
|
||||||
|
|
||||||
m_blocks.clear();
|
m_blocks.clear();
|
||||||
|
m_blocks.reserve(MAX_BLOCKS);
|
||||||
sample dummy(block_size);
|
sample dummy(block_size);
|
||||||
for (u32 i=0; i<MAX_BLOCKS; i++) {
|
for (u32 i=0; i<MAX_BLOCKS; i++) {
|
||||||
m_blocks.push_back(block(0,"dummy",dummy,44100,m_window));
|
m_blocks.push_back(block(0,"dummy",dummy,44100,m_window));
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <atomic>
|
||||||
#include <sndfile.h>
|
#include <sndfile.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <spiralcore/audio.h>
|
#include <spiralcore/audio.h>
|
||||||
|
|
@ -228,6 +229,7 @@ u32 brain::rev_search(const block &target, const search_params ¶ms) {
|
||||||
return furthest_index;
|
return furthest_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// really slow - every to every comparison of blocks calculating average distance
|
// really slow - every to every comparison of blocks calculating average distance
|
||||||
double brain::calc_average_diff(search_params ¶ms) {
|
double brain::calc_average_diff(search_params ¶ms) {
|
||||||
double diff=0;
|
double diff=0;
|
||||||
|
|
@ -244,10 +246,12 @@ void brain::build_synapses_thresh(search_params ¶ms, double thresh) {
|
||||||
m_average_error = calc_average_diff(params)*thresh;
|
m_average_error = calc_average_diff(params)*thresh;
|
||||||
double err = m_average_error*thresh;
|
double err = m_average_error*thresh;
|
||||||
u32 brain_size = m_blocks.size();
|
u32 brain_size = m_blocks.size();
|
||||||
u32 outer_index = 0;
|
std::atomic<u32> progress{0};
|
||||||
for (auto &i : m_blocks) {
|
#pragma omp parallel for
|
||||||
|
for (u32 outer_index = 0; outer_index < brain_size; ++outer_index) {
|
||||||
|
auto &i = m_blocks[outer_index];
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
status::update("building synapses %d%%",(int)(outer_index/(float)brain_size*100));
|
status::update("building synapses %d%%",(int)(progress/(float)brain_size*100));
|
||||||
for (auto &j : m_blocks) {
|
for (auto &j : m_blocks) {
|
||||||
if (index!=outer_index) {
|
if (index!=outer_index) {
|
||||||
// collect connections that are under threshold in closeness
|
// collect connections that are under threshold in closeness
|
||||||
|
|
@ -258,30 +262,33 @@ void brain::build_synapses_thresh(search_params ¶ms, double thresh) {
|
||||||
}
|
}
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
++outer_index;
|
++progress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void brain::build_synapses_fixed(search_params ¶ms) {
|
void brain::build_synapses_fixed(search_params ¶ms) {
|
||||||
//m_average_error = calc_average_diff(params)*thresh;
|
//m_average_error = calc_average_diff(params)*thresh;
|
||||||
u32 brain_size = m_blocks.size();
|
u32 brain_size = m_blocks.size();
|
||||||
u32 outer_index = 0;
|
|
||||||
u32 num_synapses = NUM_FIXED_SYNAPSES;
|
u32 num_synapses = NUM_FIXED_SYNAPSES;
|
||||||
if (num_synapses>=m_blocks.size()) num_synapses=m_blocks.size()-1;
|
if (num_synapses>=m_blocks.size()) num_synapses=m_blocks.size()-1;
|
||||||
|
|
||||||
// need to stop the progress updates flooding osc
|
// need to stop the progress updates flooding osc
|
||||||
u32 update_period = 100;
|
u32 update_period = 100;
|
||||||
u32 update_tick = 0;
|
std::atomic<u32> update_tick{0};
|
||||||
|
std::atomic<u32> progress{0};
|
||||||
for (auto &i:m_blocks) {
|
#pragma omp parallel for
|
||||||
|
for (u32 outer_index = 0; outer_index < brain_size; ++outer_index) {
|
||||||
|
auto &i = m_blocks[outer_index];
|
||||||
if (update_tick>update_period) {
|
if (update_tick>update_period) {
|
||||||
status::update("building synapses %d%%",(int)(outer_index/(float)brain_size*100));
|
status::update("building synapses %d%%",(int)(progress/(float)brain_size*100));
|
||||||
update_tick=0;
|
update_tick=0;
|
||||||
}
|
}
|
||||||
update_tick++;
|
update_tick++;
|
||||||
|
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
vector<pair<u32,double>> collect;
|
vector<pair<u32,double>> collect;
|
||||||
|
collect.reserve(brain_size);
|
||||||
|
|
||||||
// collect comparisons to all other blocks
|
// collect comparisons to all other blocks
|
||||||
for (auto &j:m_blocks) {
|
for (auto &j:m_blocks) {
|
||||||
|
|
@ -306,7 +313,7 @@ void brain::build_synapses_fixed(search_params ¶ms) {
|
||||||
i.get_synapse().push_back(collect[n].first);
|
i.get_synapse().push_back(collect[n].first);
|
||||||
}
|
}
|
||||||
|
|
||||||
++outer_index;
|
++progress;
|
||||||
}
|
}
|
||||||
status::update("Done: %d synapses grown for %d blocks",num_synapses*brain_size,brain_size);
|
status::update("Done: %d synapses grown for %d blocks",num_synapses*brain_size,brain_size);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,8 @@ public:
|
||||||
u32 rev_search(const block &target, const search_params ¶ms);
|
u32 rev_search(const block &target, const search_params ¶ms);
|
||||||
|
|
||||||
// synaptic search
|
// synaptic search
|
||||||
double calc_average_diff(search_params ¶ms);
|
// double calc_average_diff(search_params ¶ms);
|
||||||
void build_synapses_thresh(search_params ¶ms, double threshold);
|
// void build_synapses_thresh(search_params ¶ms, double threshold);
|
||||||
void build_synapses_fixed(search_params ¶ms);
|
void build_synapses_fixed(search_params ¶ms);
|
||||||
u32 search_synapses(const block &target, search_params ¶ms);
|
u32 search_synapses(const block &target, search_params ¶ms);
|
||||||
double get_current_error() { return m_current_error; }
|
double get_current_error() { return m_current_error; }
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,14 @@
|
||||||
# Changlog
|
# Changlog
|
||||||
|
|
||||||
|
0.18.4
|
||||||
|
|
||||||
|
* **Windows**: [samplebrain_0.18.4_win.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18.4_win.zip)
|
||||||
|
* **Mac (intel/m1)**: [samplebrain_0.18.4_macintel.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18.4_macintel.app.zip)
|
||||||
|
|
||||||
|
Changes in 0.18.4: New audio device settings window and updated
|
||||||
|
windows build. Better default block size, tool tip tweaks and fixes
|
||||||
|
for dark themes by [Claude Heiland-Allen](https://mathr.co.uk/).
|
||||||
|
|
||||||
0.18.3
|
0.18.3
|
||||||
|
|
||||||
* **Windows**: [samplebrain_0.18.3_win.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18.3_win.zip)
|
* **Windows**: [samplebrain_0.18.3_win.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18.3_win.zip)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
samplebrain (0.18rc2-1ubuntu0~bionic4) bionic; urgency=medium
|
samplebrain (0.18.5rc1-1ubuntu0~bionic1) bionic; urgency=medium
|
||||||
|
|
||||||
* Initial release
|
* Target sound filename shown (and tells you if you don't have one)
|
||||||
|
* More soundfile formats supported (aiff,aifc,au,snd,fasttracker xi,flac)
|
||||||
|
* New configurable OSC ports in settings
|
||||||
|
* Warning boxes if the OSC network connection fails
|
||||||
|
* File path memory per-dialog rather than global
|
||||||
|
|
||||||
|
-- Dave Griffiths <dave@thentrythis.org> Thu, 29 Oct 2022 08:47:10 +0100
|
||||||
|
|
||||||
-- Dave Griffiths <dave@thentrythis.org> Thu, 08 Sep 2022 13:08:26 +0100
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue