mirror of
https://gitlab.com/then-try-this/samplebrain.git
synced 2025-07-03 18:53:35 +00:00
Compare commits
43 Commits
0.18_relea
...
0.18.3_rel
Author | SHA1 | Date | |
---|---|---|---|
524cd58945 | |||
43890c905e | |||
99e59a6f11 | |||
e3619746a4 | |||
74eb5b0b9b | |||
287ba85c14 | |||
a7b866b4fc | |||
7bda8195c9 | |||
dc0c047ad6 | |||
672fb1868f | |||
30d93be49c | |||
297972cd5b | |||
d783b8c16a | |||
cdb6a912c0 | |||
1374c47afd | |||
79fef7cd66 | |||
b4c72412f3 | |||
95de445d9e | |||
defee25db7 | |||
2cd44183b9 | |||
108029b6f9 | |||
43bd1eff3e | |||
f521ccafc9 | |||
11ed7413b3 | |||
0af0d8e20c | |||
dcdf481a02 | |||
e741246b1f | |||
6241b1030d | |||
70a277afb8 | |||
b965130cd9 | |||
79b1c1aeda | |||
129b6ea416 | |||
395ff352e3 | |||
dd92364be6 | |||
9d7931c8c2 | |||
74b00570dd | |||
493209c28d | |||
6bc1cbeec3 | |||
ff1d4cafd2 | |||
a831638171 | |||
0cfacdc8a8 | |||
df0fd84b48 | |||
b6dcb229d5 |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*.*~
|
||||||
|
*.o
|
||||||
|
|
124
README.md
124
README.md
@ -5,50 +5,62 @@ A custom sample mashing app designed by Aphex Twin.
|
|||||||
Samplebrain chops samples up into a 'brain' of interconnected small
|
Samplebrain chops samples up into a 'brain' of interconnected small
|
||||||
sections called blocks which are connected into a network by
|
sections called blocks which are connected into a network by
|
||||||
similarity. It processes a target sample, chopping it up into blocks
|
similarity. It processes a target sample, chopping it up into blocks
|
||||||
in the same way, and tries to match each block with one in it's brain
|
in the same way, and tries to match each block with one in its brain
|
||||||
to play in realtime.
|
to play in realtime.
|
||||||
|
|
||||||
This allows you to interpret a sound with a different one. As we
|
This allows you to interpret a sound with a different one. As we
|
||||||
worked on it (during 2015 and 2016) we gradually added more and more
|
worked on it (during 2015 and 2016) we gradually added more and more
|
||||||
tweakable parameters until it became slightly out of control.
|
tweakable parameters until it became slightly out of control.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Quick start:
|
Quick start:
|
||||||
|
|
||||||
1. Load a bunch of samples into the brain
|
1. Load a bunch of short wav files into the brain
|
||||||
2. Click (re)generate brain
|
2. Click (re)generate brain
|
||||||
3. Load a loop sample into the target
|
3. Load a short loop sample into the target
|
||||||
4. Click (re)generate target
|
4. Click (re)generate blocks
|
||||||
5. Press play
|
5. Press play
|
||||||
6. Tweak brain
|
6. Tweak brain
|
||||||
|
|
||||||
The default block size (3000) is really high to prevent CPU glitches -
|
The default block size (3000) is really high to prevent CPU glitches -
|
||||||
500 to 1000 is a better range.
|
500 to 1000 is a better range. Larger wav files like whole tracks can
|
||||||
|
be used, but take a long time to process, after which they can be
|
||||||
# [Demo brain session](https://static.thentrythis.org/samplebrain/demo.samplebrain)
|
saved as "brain" files and instantly reloaded.
|
||||||
|
|
||||||
|
# [Demo brain session](https://static.thentrythis.org/samplebrain/demo.samplebrain)
|
||||||
|
|
||||||
Load this file using "load session" not "load brain" (sessions contain
|
Load this file using "load session" not "load brain" (sessions contain
|
||||||
both the target and brain samples).
|
both the target and brain samples). The original samples used to
|
||||||
|
create the demo session [can be found here for
|
||||||
|
testing](https://static.thentrythis.org/samplebrain/samples/).
|
||||||
|
|
||||||
# [Manual](docs/manual.md)
|
# [Manual](docs/manual.md)
|
||||||
|
|
||||||
Full description of all the parameters and a bit of the thinking
|
Full description of all the parameters and a bit of the thinking
|
||||||
behind it.
|
behind it.
|
||||||
|
|
||||||
# Binaries
|
|
||||||
|
|
||||||
* **Windows**: [samplebrain_0.18_win.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18_win.zip)
|
# Download
|
||||||
* **Mac (intel)**: [samplebrain_0.18_macintel.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18_macintel.zip)
|
|
||||||
* **Mac (m1)**: [samplebrain_0.18_m1.dmg](https://static.thentrythis.org/samplebrain/samplebrain_0.18_m1.dmg) (thank you to [Nik Gaffney](http://fo.am) for building)
|
As this is experimental non-commercial software (only originally
|
||||||
|
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
|
||||||
|
might currently be problems running it on 64bit Windows.
|
||||||
|
|
||||||
|
* **Windows**: [samplebrain_0.18.2_win.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18.2_win.zip)
|
||||||
|
* **Mac (intel/m1)**: [samplebrain_0.18.1_macintel.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18.1_macintel.app.zip)
|
||||||
|
|
||||||
|
Thank you to [Nik Gaffney](http://fo.am) for help with the Apple builds
|
||||||
|
|
||||||
Mac note: As this software is not on the apple store, to run the
|
Mac note: As this software is not on the apple store, to run the
|
||||||
binary you need to tell your mac it's ok: Go to System Preferences >
|
binary you need to tell your mac it's ok: Go to System Preferences >
|
||||||
Security & Privacy > General. At the bottom of the window, select
|
Security & Privacy > General. At the bottom of the window, select
|
||||||
"Allow apps to be downloaded from Anywhere".
|
"Allow apps to be downloaded from Anywhere".
|
||||||
|
|
||||||
**Linux install (Ubuntu)**
|
### Linux
|
||||||
|
<a href='https://flathub.org/apps/details/org.thentrythis.Samplebrain'><img width='200' alt='Download on Flathub' src='https://flathub.org/assets/badges/flathub-badge-en.png'/></a>
|
||||||
|
|
||||||
|
#### Ubuntu
|
||||||
$ sudo add-apt-repository ppa:thentrythis/samplebrain
|
$ sudo add-apt-repository ppa:thentrythis/samplebrain
|
||||||
$ sudo apt update
|
$ sudo apt update
|
||||||
$ sudo apt install samplebrain
|
$ sudo apt install samplebrain
|
||||||
@ -56,33 +68,74 @@ Security & Privacy > General. At the bottom of the window, select
|
|||||||
If you'd like the right font, optionally:
|
If you'd like the right font, optionally:
|
||||||
|
|
||||||
$ sudo apt install ttf-mscorefonts-installer
|
$ sudo apt install ttf-mscorefonts-installer
|
||||||
|
|
||||||
# Building from source
|
|
||||||
|
|
||||||
Install libraries for the sample engine (use brew on mac, MinGW on win):
|
# Old/broken/spurious binaries
|
||||||
|
|
||||||
|
* **Windows**: [samplebrain_0.18.1_win.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18.1_win.zip)
|
||||||
|
* **Windows**: [samplebrain_0.18_win.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18_win.zip)
|
||||||
|
* **Mac (intel)**: [samplebrain_0.18_macintel.zip](https://static.thentrythis.org/samplebrain/samplebrain_0.18_macintel.zip)
|
||||||
|
* **Mac (m1)**: [samplebrain_0.18_m1_v2.dmg](https://static.thentrythis.org/samplebrain/samplebrain_0.18_m1_v2.dmg)
|
||||||
|
|
||||||
|
# Building from source
|
||||||
|
## Linux (Ubuntu)
|
||||||
|
Install libraries for the sample engine (use brew on mac, MinGW on win):
|
||||||
|
|
||||||
$ sudo apt install libsndfile1-dev portaudio19-dev liblo-dev libfftw3-dev
|
$ sudo apt install libsndfile1-dev portaudio19-dev liblo-dev libfftw3-dev
|
||||||
|
|
||||||
Install dependancies for the interface:
|
Install dependencies for the interface:
|
||||||
|
|
||||||
$ sudo apt install build-essential qtcreator qt5-default
|
$ sudo apt install build-essential qtcreator qt5-default
|
||||||
|
|
||||||
Build & run it:
|
Build & run it:
|
||||||
|
|
||||||
$ cd app
|
$ mkdir build
|
||||||
$ qmake
|
$ cd build
|
||||||
|
$ qmake ..
|
||||||
$ make
|
$ make
|
||||||
$ sudo make install
|
$ sudo make install
|
||||||
$ samplebrain
|
$ samplebrain
|
||||||
|
|
||||||
|
## Mac
|
||||||
|
Install libraries for sample engine:
|
||||||
|
|
||||||
|
$ brew install fftw portaudio liblo libsndfile
|
||||||
|
|
||||||
|
Install dependencies for the interface:
|
||||||
|
|
||||||
|
$ brew install qt
|
||||||
|
$ brew link qt
|
||||||
|
|
||||||
|
Build & run it:
|
||||||
|
|
||||||
|
$ mkdir build
|
||||||
|
$ cd build
|
||||||
|
$ qmake ..
|
||||||
|
$ make
|
||||||
|
|
||||||
|
`samplebrain.app` should then be in the app folder for you to run.
|
||||||
|
|
||||||
# Mac build additions
|
# Mac build additions
|
||||||
|
|
||||||
To make a mac app bundle:
|
To make a mac app bundle:
|
||||||
|
|
||||||
* Run `macdeployqt` to copy all dependancies inside the app.
|
Run `macdeployqt` which copies all dependencies inside the app.
|
||||||
* Copy desktop/samplebrain.icns (the icon) to the Resources directory in the bundle.
|
|
||||||
* Edit Info.plist to add samplebrain.icns to CFBundleIconFile.
|
$ cd build
|
||||||
|
$ macdeployqt
|
||||||
|
|
||||||
|
If the icon is not visible, you might need to copy desktop/samplebrain.icns (the icon) to the Resources directory in the app bundle.
|
||||||
|
|
||||||
|
$ cp ../desktop/samplebrain.icns samplebrain.app/Contents/Resources
|
||||||
|
|
||||||
|
Then edit Info.plist to add samplebrain.icns to CFBundleIconFile. Key `CFBundleIconFile` should match:
|
||||||
|
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>samplebrain.icns</string>
|
||||||
|
|
||||||
|
You might also need to resign the app bundle after making any changes
|
||||||
|
|
||||||
|
$ codesign --force --deep --sign - samplebrain.app
|
||||||
|
|
||||||
## What's here
|
## What's here
|
||||||
|
|
||||||
1. brain:
|
1. brain:
|
||||||
@ -96,13 +149,16 @@ To make a mac app bundle:
|
|||||||
4. cooking:
|
4. cooking:
|
||||||
* some sketches and ideas
|
* some sketches and ideas
|
||||||
* proof of concept written in python
|
* proof of concept written in python
|
||||||
* brief initial (abandoned) attempt at clojure version
|
* brief initial (abandoned) attempt at clojure version
|
||||||
|
|
||||||
MFCC algo courtesy of the Aquila library by Zbigniew Siciarz MIT/X11
|
MFCC algo courtesy of the Aquila library by Zbigniew Siciarz MIT/X11
|
||||||
licence 2007-2014 (see brain/src/aquila/LICENCE)
|
licence 2007-2014 (see brain/src/aquila/LICENCE)
|
||||||
|
|
||||||
This program is free software licenced under GNU General Public
|
This program is free software licenced under GNU General Public
|
||||||
License version 2 (see LICENCE).
|
License version 2 (see LICENCE).
|
||||||
|
|
||||||
Written by [Dave Griffiths at Then Try This](http://thentrythis.org).
|
Written by [Dave Griffiths at Then Try This](http://thentrythis.org).
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
To find related tech like [CataRT](http://imtr.ircam.fr/imtr/CataRT), [bbcut2](https://composerprogrammer.com/bbcut2.html), [eargram](https://sites.google.com/site/eargram/) and [sCrAmBlEd?HaCkZ!](https://www.youtube.com/watch?v=eRlhKaxcKpA) search up [granular synthesis](http://granularsynthesis.com/guide.php), [concatenative synthesis](https://hal.archives-ouvertes.fr/hal-01161337), [neural audio synthesis](https://github.com/acids-ircam/RAVE), [sinewave speech](http://www.lifesci.sussex.ac.uk/home/Chris_Darwin/SWS/), automated breakbeat cutting, audio mosaicing and plunderphonics/plundermatics.
|
||||||
|
@ -40,12 +40,10 @@ MainWindow::MainWindow() :
|
|||||||
setUnifiedTitleAndToolBarOnMac(true);
|
setUnifiedTitleAndToolBarOnMac(true);
|
||||||
|
|
||||||
m_Ui.verticalLayout_5->setSpacing(0);
|
m_Ui.verticalLayout_5->setSpacing(0);
|
||||||
m_Ui.verticalLayout_5->setMargin(0);
|
|
||||||
m_Ui.verticalLayout_5->setContentsMargins(0,0,0,0);
|
m_Ui.verticalLayout_5->setContentsMargins(0,0,0,0);
|
||||||
|
|
||||||
m_Ui.brain_contents->setAlignment(Qt::AlignTop);
|
m_Ui.brain_contents->setAlignment(Qt::AlignTop);
|
||||||
m_Ui.brain_contents->setSpacing(0);
|
m_Ui.brain_contents->setSpacing(0);
|
||||||
m_Ui.brain_contents->setMargin(0);
|
|
||||||
m_Ui.brain_contents->setContentsMargins(0,0,0,0);
|
m_Ui.brain_contents->setContentsMargins(0,0,0,0);
|
||||||
|
|
||||||
// add default local dest
|
// add default local dest
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include "generated/ui_samplebrain.h"
|
#include "ui_samplebrain.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <lo/lo.h>
|
#include <lo/lo.h>
|
||||||
|
@ -168,7 +168,9 @@ void audio_thread::process(sample &left_in, sample &right_in, sample &left_out,
|
|||||||
m_right_renderer->reset();
|
m_right_renderer->reset();
|
||||||
}
|
}
|
||||||
if (name=="/mic") {
|
if (name=="/mic") {
|
||||||
m_mic_mode = cmd.get_int(0);
|
//m_mic_mode = cmd.get_int(0);
|
||||||
|
//if (m_mic_mode==1) m_block_stream->start();
|
||||||
|
//else m_block_stream->stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,93 +0,0 @@
|
|||||||
/********************************************************************************
|
|
||||||
** Form generated from reading UI file 'sampleSy5241.ui'
|
|
||||||
**
|
|
||||||
** Created: Sat Jul 11 10:24:07 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 SAMPLESY5241_H
|
|
||||||
#define SAMPLESY5241_H
|
|
||||||
|
|
||||||
#include <QtCore/QVariant>
|
|
||||||
#include <QtGui/QAction>
|
|
||||||
#include <QtGui/QApplication>
|
|
||||||
#include <QtGui/QButtonGroup>
|
|
||||||
#include <QtGui/QCheckBox>
|
|
||||||
#include <QtGui/QHBoxLayout>
|
|
||||||
#include <QtGui/QHeaderView>
|
|
||||||
#include <QtGui/QLabel>
|
|
||||||
#include <QtGui/QPushButton>
|
|
||||||
#include <QtGui/QWidget>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
class Ui_FormSample
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QHBoxLayout *horizontalLayout;
|
|
||||||
QCheckBox *checkBox;
|
|
||||||
QLabel *labelSampleName;
|
|
||||||
QLabel *labelSampleInfo;
|
|
||||||
QPushButton *pushButton;
|
|
||||||
|
|
||||||
void setupUi(QWidget *FormSample)
|
|
||||||
{
|
|
||||||
if (FormSample->objectName().isEmpty())
|
|
||||||
FormSample->setObjectName(QString::fromUtf8("FormSample"));
|
|
||||||
FormSample->resize(400, 46);
|
|
||||||
horizontalLayout = new QHBoxLayout(FormSample);
|
|
||||||
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
|
|
||||||
checkBox = new QCheckBox(FormSample);
|
|
||||||
checkBox->setObjectName(QString::fromUtf8("checkBox"));
|
|
||||||
QFont font;
|
|
||||||
font.setFamily(QString::fromUtf8("Comic Sans MS"));
|
|
||||||
font.setBold(true);
|
|
||||||
font.setWeight(75);
|
|
||||||
checkBox->setFont(font);
|
|
||||||
|
|
||||||
horizontalLayout->addWidget(checkBox);
|
|
||||||
|
|
||||||
labelSampleName = new QLabel(FormSample);
|
|
||||||
labelSampleName->setObjectName(QString::fromUtf8("labelSampleName"));
|
|
||||||
labelSampleName->setFont(font);
|
|
||||||
|
|
||||||
horizontalLayout->addWidget(labelSampleName);
|
|
||||||
|
|
||||||
labelSampleInfo = new QLabel(FormSample);
|
|
||||||
labelSampleInfo->setObjectName(QString::fromUtf8("labelSampleInfo"));
|
|
||||||
labelSampleInfo->setFont(font);
|
|
||||||
|
|
||||||
horizontalLayout->addWidget(labelSampleInfo);
|
|
||||||
|
|
||||||
pushButton = new QPushButton(FormSample);
|
|
||||||
pushButton->setObjectName(QString::fromUtf8("pushButton"));
|
|
||||||
pushButton->setFont(font);
|
|
||||||
|
|
||||||
horizontalLayout->addWidget(pushButton);
|
|
||||||
|
|
||||||
|
|
||||||
retranslateUi(FormSample);
|
|
||||||
|
|
||||||
QMetaObject::connectSlotsByName(FormSample);
|
|
||||||
} // setupUi
|
|
||||||
|
|
||||||
void retranslateUi(QWidget *FormSample)
|
|
||||||
{
|
|
||||||
FormSample->setWindowTitle(QApplication::translate("FormSample", "Form", 0, QApplication::UnicodeUTF8));
|
|
||||||
checkBox->setText(QApplication::translate("FormSample", "active", 0, QApplication::UnicodeUTF8));
|
|
||||||
labelSampleName->setText(QApplication::translate("FormSample", "TextLabel", 0, QApplication::UnicodeUTF8));
|
|
||||||
labelSampleInfo->setText(QApplication::translate("FormSample", "TextLabel", 0, QApplication::UnicodeUTF8));
|
|
||||||
pushButton->setText(QApplication::translate("FormSample", "delete", 0, QApplication::UnicodeUTF8));
|
|
||||||
} // retranslateUi
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class FormSample: public Ui_FormSample {};
|
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif // SAMPLESY5241_H
|
|
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,6 @@ sound_items::sound_item &sound_items::add(QVBoxLayout *container, const string &
|
|||||||
|
|
||||||
si.m_container = new QHBoxLayout();
|
si.m_container = new QHBoxLayout();
|
||||||
si.m_container->setSpacing(10);
|
si.m_container->setSpacing(10);
|
||||||
si.m_container->setMargin(0);
|
|
||||||
si.m_container->setContentsMargins(0,0,0,0);
|
si.m_container->setContentsMargins(0,0,0,0);
|
||||||
|
|
||||||
si.m_enable = new QCheckBox();
|
si.m_enable = new QCheckBox();
|
||||||
@ -56,7 +55,7 @@ sound_items::sound_item &sound_items::add(QVBoxLayout *container, const string &
|
|||||||
QFont font;
|
QFont font;
|
||||||
font.setFamily(QString::fromUtf8("Comic Sans MS"));
|
font.setFamily(QString::fromUtf8("Comic Sans MS"));
|
||||||
font.setBold(true);
|
font.setBold(true);
|
||||||
font.setWeight(75);
|
font.setWeight(QFont::Bold);
|
||||||
si.m_label->setFont(font);
|
si.m_label->setFont(font);
|
||||||
si.m_label->setContentsMargins(0,0,0,0);
|
si.m_label->setContentsMargins(0,0,0,0);
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ double square(double a) {
|
|||||||
return a*a;
|
return a*a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void normalise(sample &in) {
|
void normalise(spiralcore::sample &in) {
|
||||||
// find min/max
|
// find min/max
|
||||||
float max = 0;
|
float max = 0;
|
||||||
float min = FLT_MAX;
|
float min = FLT_MAX;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <signal.h>
|
||||||
#include "block_stream.h"
|
#include "block_stream.h"
|
||||||
|
|
||||||
using namespace spiralcore;
|
using namespace spiralcore;
|
||||||
@ -34,15 +35,36 @@ block_stream::block_stream() :
|
|||||||
m_block_index_offset(0),
|
m_block_index_offset(0),
|
||||||
m_sent_block_index(0)
|
m_sent_block_index(0)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
block_stream::~block_stream() {}
|
||||||
|
|
||||||
|
void block_stream::start() {
|
||||||
|
cerr<<"block stream starting up"<<endl;
|
||||||
for (u32 i=0; i<NUM_WORKERS; ++i) {
|
for (u32 i=0; i<NUM_WORKERS; ++i) {
|
||||||
m_workers.push_back(new worker(i,&m_window));
|
m_workers.push_back(new worker(i,&m_window));
|
||||||
|
// ????
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
usleep(1);
|
usleep(1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
block_stream::~block_stream() {}
|
void block_stream::stop() {
|
||||||
|
cerr<<"block stream ending"<<endl;
|
||||||
|
|
||||||
|
bool killcount = 0;
|
||||||
|
for (auto &w : m_workers) {
|
||||||
|
pthread_join(*w->m_thread,NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(500);
|
||||||
|
|
||||||
|
for (u32 i=0; i<NUM_WORKERS; ++i) {
|
||||||
|
delete m_workers[i];
|
||||||
|
}
|
||||||
|
m_workers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void block_stream::init(u32 block_size, u32 overlap, window::type t, bool ditchpcm) {
|
void block_stream::init(u32 block_size, u32 overlap, window::type t, bool ditchpcm) {
|
||||||
m_block_size=block_size;
|
m_block_size=block_size;
|
||||||
@ -82,7 +104,7 @@ void block_stream::process(const sample &left, const sample &right) {
|
|||||||
// with the buffer wrapping...
|
// with the buffer wrapping...
|
||||||
//cerr<<(s32)(m_buffer_position-m_block_size)<<" to "<<m_buffer_position<<endl;
|
//cerr<<(s32)(m_buffer_position-m_block_size)<<" to "<<m_buffer_position<<endl;
|
||||||
m_buffer.get_region(region,(s32)(m_buffer_position-m_block_size),
|
m_buffer.get_region(region,(s32)(m_buffer_position-m_block_size),
|
||||||
m_buffer_position);
|
m_buffer_position);
|
||||||
|
|
||||||
//cerr<<"starting block "<<m_block_index<<endl;
|
//cerr<<"starting block "<<m_block_index<<endl;
|
||||||
scatter_gather(m_block_index,region);
|
scatter_gather(m_block_index,region);
|
||||||
@ -93,10 +115,9 @@ void block_stream::process(const sample &left, const sample &right) {
|
|||||||
|
|
||||||
m_block_position=0;
|
m_block_position=0;
|
||||||
|
|
||||||
|
|
||||||
if (m_blocks.size()>MAX_BLOCKS) {
|
if (m_blocks.size()>MAX_BLOCKS) {
|
||||||
m_blocks.erase(m_blocks.begin());
|
m_blocks.erase(m_blocks.begin());
|
||||||
m_block_index_offset++;
|
m_block_index_offset++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,8 +152,12 @@ block_stream::worker::worker(u32 id, window *w) :
|
|||||||
pthread_create(m_thread,NULL,(void*(*)(void*))_run_worker,this);
|
pthread_create(m_thread,NULL,(void*(*)(void*))_run_worker,this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
block_stream::worker::~worker() {
|
||||||
|
delete m_worker_mutex;
|
||||||
|
delete m_thread;
|
||||||
|
}
|
||||||
|
|
||||||
void block_stream::worker::run() {
|
void block_stream::worker::run() {
|
||||||
//cerr<<"worker "<<m_id<<" started..."<<endl;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
pthread_mutex_lock(m_worker_mutex);
|
pthread_mutex_lock(m_worker_mutex);
|
||||||
if (m_status==ACTIVATE) {
|
if (m_status==ACTIVATE) {
|
||||||
@ -142,6 +167,7 @@ void block_stream::worker::run() {
|
|||||||
m_status=FINISHED;
|
m_status=FINISHED;
|
||||||
cerr<<"ending "<<m_id<<endl;
|
cerr<<"ending "<<m_id<<endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(m_worker_mutex);
|
pthread_mutex_unlock(m_worker_mutex);
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
usleep(5);
|
usleep(5);
|
||||||
@ -149,24 +175,24 @@ void block_stream::worker::run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void block_stream::scatter_gather(u32 block_index, const sample ®ion) {
|
void block_stream::scatter_gather(u32 block_index, const sample ®ion) {
|
||||||
while(true) {
|
while(true) {
|
||||||
for (auto &w : m_workers) {
|
for (auto &w : m_workers) {
|
||||||
if (pthread_mutex_trylock(w->m_worker_mutex)) {
|
if (pthread_mutex_trylock(w->m_worker_mutex)==0) {
|
||||||
if (w->m_status == worker::FINISHED) {
|
if (w->m_status == worker::FINISHED) {
|
||||||
//cerr<<"adding finished block "<<w->m_block_index<<endl;
|
//cerr<<"adding finished block "<<w->m_block_index<<endl;
|
||||||
m_blocks[w->m_block_index]=*w->m_output;
|
m_blocks[w->m_block_index]=*w->m_output;
|
||||||
w->m_status = worker::READY;
|
w->m_status = worker::READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w->m_status == worker::READY) {
|
if (w->m_status == worker::READY) {
|
||||||
w->m_region = region;
|
w->m_region = region;
|
||||||
w->m_status = worker::ACTIVATE;
|
w->m_status = worker::ACTIVATE;
|
||||||
w->m_block_index = block_index;
|
w->m_block_index = block_index;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(w->m_worker_mutex);
|
|
||||||
|
pthread_mutex_unlock(w->m_worker_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,11 +41,15 @@ class block_stream : public block_source {
|
|||||||
virtual const block &get_block(u32 index) const;
|
virtual const block &get_block(u32 index) const;
|
||||||
virtual u32 get_num_blocks() const { return UINT_MAX; }
|
virtual u32 get_num_blocks() const { return UINT_MAX; }
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
|
||||||
u32 last_block_index() const { return m_block_index_offset+m_blocks.size()-1; }
|
u32 last_block_index() const { return m_block_index_offset+m_blocks.size()-1; }
|
||||||
|
|
||||||
class worker {
|
class worker {
|
||||||
public:
|
public:
|
||||||
worker(u32 id, window *w);
|
worker(u32 id, window *w);
|
||||||
|
~worker();
|
||||||
|
|
||||||
enum worker_status { READY=0, ACTIVATE, WORKING, FINISHED };
|
enum worker_status { READY=0, ACTIVATE, WORKING, FINISHED };
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#ifndef COMMAND_RING_BUFFER
|
#ifndef COMMAND_RING_BUFFER
|
||||||
#define COMMAND_RING_BUFFER
|
#define COMMAND_RING_BUFFER
|
||||||
|
|
||||||
static const unsigned int COMMAND_DATA_SIZE = 128;
|
static const unsigned int COMMAND_DATA_SIZE = 1024;
|
||||||
|
|
||||||
class command_ring_buffer : public ring_buffer
|
class command_ring_buffer : public ring_buffer
|
||||||
{
|
{
|
||||||
|
@ -74,7 +74,7 @@ bool portaudio_client::attach(const string &client_name, const device_options &d
|
|||||||
PaStreamParameters input_parameters;
|
PaStreamParameters input_parameters;
|
||||||
PaStreamParameters *input_p=&input_parameters;
|
PaStreamParameters *input_p=&input_parameters;
|
||||||
input_parameters.device = input_device_num;
|
input_parameters.device = input_device_num;
|
||||||
if (input_parameters.device == paNoDevice) {
|
if (true || input_parameters.device == paNoDevice) {
|
||||||
cerr<<"error: no default input device."<<endl;
|
cerr<<"error: no default input device."<<endl;
|
||||||
input_p=0;
|
input_p=0;
|
||||||
} else {
|
} else {
|
||||||
|
31
build-aux/flatpak/README.md
Normal file
31
build-aux/flatpak/README.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Flatpak Build Instructions
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
To build the Flatpak, install the `flatpak` and `flatpak-builder` packages
|
||||||
|
from your repositories. Then, [add Flathub](https://flatpak.org/setup/).
|
||||||
|
|
||||||
|
Now, install the KDE SDK:
|
||||||
|
```sh
|
||||||
|
flatpak install flathub org.kde.Sdk//5.15-22.08
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building and installing
|
||||||
|
To build and install the app locally:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flatpak-builder --force-clean --install --user builddir build-aux/flatpak/org.thentrythis.Samplebrain.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building and exporting
|
||||||
|
To build and export a Flatpak bundle:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flatpak-builder --force-clean --repo=repo builddir build-aux/flatpak/org.thentrythis.Samplebrain.yaml
|
||||||
|
flatpak build-bundle repo org.thentrythis.Samplebrain.flatpak org.thentrythis.Samplebrain
|
||||||
|
```
|
||||||
|
|
||||||
|
To install the bundle:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flatpak install org.thentrythis.Samplebrain.flatpak
|
||||||
|
```
|
73
build-aux/flatpak/org.thentrythis.Samplebrain.yaml
Normal file
73
build-aux/flatpak/org.thentrythis.Samplebrain.yaml
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
id: org.thentrythis.Samplebrain
|
||||||
|
runtime: org.kde.Platform
|
||||||
|
runtime-version: "5.15-22.08"
|
||||||
|
sdk: org.kde.Sdk
|
||||||
|
|
||||||
|
rename-desktop-file: samplebrain.desktop
|
||||||
|
rename-icon: samplebrain
|
||||||
|
|
||||||
|
command: samplebrain
|
||||||
|
|
||||||
|
finish-args:
|
||||||
|
- "--share=ipc"
|
||||||
|
- "--socket=wayland"
|
||||||
|
- "--socket=fallback-x11"
|
||||||
|
- "--socket=pulseaudio"
|
||||||
|
- "--device=dri"
|
||||||
|
- "--share=network"
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
- "/include"
|
||||||
|
- "/lib/cmake"
|
||||||
|
- "/lib/pkgconfig"
|
||||||
|
- "/share/doc"
|
||||||
|
|
||||||
|
modules:
|
||||||
|
- name: libsndfile
|
||||||
|
buildsystem: cmake-ninja
|
||||||
|
config-opts:
|
||||||
|
- "-DCMAKE_BUILD_TYPE=Release"
|
||||||
|
- "-DBUILD_SHARED_LIBS=ON"
|
||||||
|
- "-DENABLE_EXTERNAL_LIBS=NO"
|
||||||
|
- "-DENABLE_CPACK=NO"
|
||||||
|
- "-DBUILD_PROGRAMS=OFF"
|
||||||
|
- "-DBUILD_EXAMPLES=OFF"
|
||||||
|
sources:
|
||||||
|
- type: archive
|
||||||
|
url: https://github.com/libsndfile/libsndfile/releases/download/1.1.0/libsndfile-1.1.0.tar.xz
|
||||||
|
sha256: 0f98e101c0f7c850a71225fb5feaf33b106227b3d331333ddc9bacee190bcf41
|
||||||
|
|
||||||
|
- name: portaudio
|
||||||
|
buildsystem: autotools
|
||||||
|
config-opts:
|
||||||
|
- "--with-alsa"
|
||||||
|
- "--without-jack"
|
||||||
|
- "--without-oss"
|
||||||
|
- "--without-asihpi"
|
||||||
|
sources:
|
||||||
|
- type: archive
|
||||||
|
url: http://files.portaudio.com/archives/pa_stable_v190700_20210406.tgz
|
||||||
|
sha256: 47efbf42c77c19a05d22e627d42873e991ec0c1357219c0d74ce6a2948cb2def
|
||||||
|
|
||||||
|
- name: liblo
|
||||||
|
buildsystem: autotools
|
||||||
|
config-opts:
|
||||||
|
- "--disable-tests"
|
||||||
|
- "--disable-network-tests"
|
||||||
|
- "--disable-tools"
|
||||||
|
- "--disable-examples"
|
||||||
|
sources:
|
||||||
|
- type: archive
|
||||||
|
url: https://versaweb.dl.sourceforge.net/project/liblo/liblo/0.31/liblo-0.31.tar.gz
|
||||||
|
sha256: 2b4f446e1220dcd624ecd8405248b08b7601e9a0d87a0b94730c2907dbccc750
|
||||||
|
|
||||||
|
- name: samplebrain
|
||||||
|
buildsystem: qmake
|
||||||
|
build-options:
|
||||||
|
env:
|
||||||
|
PREFIX: /app
|
||||||
|
config-opts:
|
||||||
|
- "LIBS+=-L/app/lib"
|
||||||
|
sources:
|
||||||
|
- type: dir
|
||||||
|
path: ../../
|
42
desktop/org.thentrythis.Samplebrain.metainfo.xml
Normal file
42
desktop/org.thentrythis.Samplebrain.metainfo.xml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<component type="desktop-application">
|
||||||
|
<id>org.thentrythis.Samplebrain</id>
|
||||||
|
|
||||||
|
<name>Samplebrain</name>
|
||||||
|
<summary>A custom sample mashing app designed by Aphex Twin</summary>
|
||||||
|
|
||||||
|
<metadata_license>CC0-1.0</metadata_license>
|
||||||
|
<project_license>GPL-2.0-only</project_license>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
<p>
|
||||||
|
Samplebrain chops samples up into a 'brain' of interconnected small sections called blocks which are connected into a network by similarity. It processes a target sample, chopping it up into blocks in the same way, and tries to match each block with one in it's brain to play in realtime.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This allows you to interpret a sound with a different one. As we worked on it (during 2015 and 2016) we gradually added more and more tweakable parameters until it became slightly out of control.
|
||||||
|
</p>
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<launchable type="desktop-id">samplebrain.desktop</launchable>
|
||||||
|
|
||||||
|
<categories>
|
||||||
|
<category>AudioVideo</category>
|
||||||
|
<category>Music</category>
|
||||||
|
</categories>
|
||||||
|
|
||||||
|
<content_rating type="oars-1.0"></content_rating>
|
||||||
|
|
||||||
|
<url type="homepage">https://thentrythis.org/projects/samplebrain/</url>
|
||||||
|
<url type="bugtracker">https://gitlab.com/then-try-this/samplebrain/-/issues</url>
|
||||||
|
<url type="vcs-browser">https://gitlab.com/then-try-this/samplebrain</url>
|
||||||
|
|
||||||
|
<screenshots>
|
||||||
|
<screenshot type="default">
|
||||||
|
<image type="source" width="1280" height="720">https://gitlab.com/then-try-this/samplebrain/-/raw/main/desktop/screenshots/01-main-with-project.png</image>
|
||||||
|
</screenshot>
|
||||||
|
</screenshots>
|
||||||
|
|
||||||
|
<releases>
|
||||||
|
<release version="0.18" date="2022-09-22"/>
|
||||||
|
</releases>
|
||||||
|
</component>
|
@ -1,10 +1,8 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Encoding=UTF-8
|
|
||||||
Type=Application
|
Type=Application
|
||||||
Name=Samplebrain
|
Name=Samplebrain
|
||||||
Comment=A sample masher designed by Aphex Twin
|
Comment=A custom sample mashing app designed by Aphex Twin
|
||||||
Exec=/usr/bin/samplebrain
|
Icon=samplebrain
|
||||||
Icon=/usr/share/icons/hicolor/scalable/apps/samplebrain.svg
|
Exec=samplebrain
|
||||||
Terminal=false
|
Categories=AudioVideo;Music
|
||||||
Categories=GNOME;Application;
|
StartupNotify=true
|
||||||
StartupNotify=true
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
[Desktop Entry]
|
|
||||||
Type=Application
|
|
||||||
Version=1.0
|
|
||||||
Name=Samplebrain
|
|
||||||
GenericName="Samplebrain"
|
|
||||||
Exec=samplebrain
|
|
||||||
Icon=samplebrain
|
|
BIN
desktop/screenshots/01-main-with-project.png
Normal file
BIN
desktop/screenshots/01-main-with-project.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 113 KiB |
@ -1,77 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>FormSample</class>
|
|
||||||
<widget class="QWidget" name="FormSample">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>400</width>
|
|
||||||
<height>46</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Form</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="checkBox">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>Comic Sans MS</family>
|
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>active</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labelSampleName">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>Comic Sans MS</family>
|
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>TextLabel</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labelSampleInfo">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>Comic Sans MS</family>
|
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>TextLabel</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pushButton">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>Comic Sans MS</family>
|
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>delete</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
@ -11,7 +11,7 @@
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>samplebrain 0.18</string>
|
<string>samplebrain 0.18.3</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
@ -867,14 +867,22 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="mic">
|
<widget class="QCheckBox" name="mic">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<family>Comic Sans MS</family>
|
<family>Comic Sans MS</family>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>use mic input</string>
|
<string>use mic input</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -10,8 +10,9 @@ INCLUDEPATH += . 2
|
|||||||
QT += core gui widgets
|
QT += core gui widgets
|
||||||
|
|
||||||
# Input
|
# Input
|
||||||
HEADERS += app/MainWindow.h \
|
HEADERS += app/MainWindow.h
|
||||||
app/generated/ui_samplebrain.h \
|
|
||||||
|
FORMS += gui/samplebrain.ui
|
||||||
|
|
||||||
SOURCES += app/MainWindow.cpp \
|
SOURCES += app/MainWindow.cpp \
|
||||||
app/sound_items.cpp \
|
app/sound_items.cpp \
|
||||||
@ -42,19 +43,26 @@ SOURCES += app/MainWindow.cpp \
|
|||||||
|
|
||||||
INCLUDEPATH += brain/src
|
INCLUDEPATH += brain/src
|
||||||
INCLUDEPATH += /usr/local/include
|
INCLUDEPATH += /usr/local/include
|
||||||
LIBS += -L.. -L/usr/local/lib -lportaudio -lfftw3 -lsndfile -llo -ldl -lpthread -lm
|
INCLUDEPATH += /opt/homebrew/include
|
||||||
|
LIBS += -L.. -L/usr/local/lib -L/opt/homebrew/lib -lportaudio -lfftw3 -lsndfile -llo -ldl -lpthread -lm
|
||||||
|
|
||||||
QMAKE_CXXFLAGS += -O3 -Wall -Wno-unused -std=c++11
|
QMAKE_CXXFLAGS += -O3 -Wall -Wno-unused -std=c++11
|
||||||
|
|
||||||
# assets
|
# assets
|
||||||
RESOURCES = app/samplebrain.qrc
|
RESOURCES = app/samplebrain.qrc
|
||||||
|
ICON = desktop/samplebrain.icns
|
||||||
|
|
||||||
unix:desktopfile.path = /usr/share/applications/
|
PREFIX = $$(PREFIX)
|
||||||
|
isEmpty(PREFIX) {
|
||||||
|
PREFIX = /usr
|
||||||
|
}
|
||||||
|
|
||||||
|
unix:desktopfile.path = $$PREFIX/share/applications/
|
||||||
unix:desktopfile.files = desktop/samplebrain.desktop
|
unix:desktopfile.files = desktop/samplebrain.desktop
|
||||||
unix:iconfile.path = /usr/share/icons/hicolor/scalable/apps
|
unix:iconfile.path = $$PREFIX/share/icons/hicolor/scalable/apps
|
||||||
unix:iconfile.files = desktop/samplebrain.svg
|
unix:iconfile.files = desktop/samplebrain.svg
|
||||||
|
unix:metainfofile.path = $$PREFIX/share/metainfo
|
||||||
|
unix:metainfofile.files = desktop/org.thentrythis.Samplebrain.metainfo.xml
|
||||||
|
|
||||||
target.path = /usr/bin
|
target.path = $$PREFIX/bin
|
||||||
INSTALLS += target desktopfile iconfile
|
INSTALLS += target desktopfile iconfile metainfofile
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user