summaryrefslogtreecommitdiff
path: root/src/instrumentwidget.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/instrumentwidget.cc')
-rw-r--r--src/instrumentwidget.cc275
1 files changed, 204 insertions, 71 deletions
diff --git a/src/instrumentwidget.cc b/src/instrumentwidget.cc
index 6a2e17e..42b549b 100644
--- a/src/instrumentwidget.cc
+++ b/src/instrumentwidget.cc
@@ -47,11 +47,13 @@
#include <QTime>
#include <QSpinBox>
+#include <sndfile.h>
+
#include "sleep.h"
#include "canvastool.h"
#include "canvastoolthreshold.h"
#include "volumefader.h"
-#include "selectioneditor.h"
+#include "rangeeditor.h"
#include "zoomslider.h"
#include "settings.h"
#include "project.h"
@@ -74,11 +76,11 @@ InstrumentWidget::InstrumentWidget(Settings& settings, Instrument& instrument)
{
setProperty("id", instrument.getId());
- {
- int start = 44100 * 60;
- Selection p(start, start + 44100 * 60, 0, 0); // one minute selection
- selections_preview.add(p);
- }
+ //{
+ // int start = 44100 * 60;
+ // Range p(start, start + 44100 * 60, 0, 0); // one minute range
+ // ranges_preview.add(p);
+ //}
QWidget* central = new QWidget();
QHBoxLayout* lh = new QHBoxLayout();
@@ -92,32 +94,66 @@ InstrumentWidget::InstrumentWidget(Settings& settings, Instrument& instrument)
QToolBar* toolbar = addToolBar(tr("Tools"));
listen = new CanvasToolListen(canvaswidget->canvas, player);
addTool(toolbar, canvaswidget->canvas, listen);
- threshold = new CanvasToolThreshold(canvaswidget->canvas, instrument);
+
+ threshold = new CanvasToolThreshold(*canvaswidget->canvas,
+ instrument.getThreshold(),
+ QColor(255, 127, 127),
+ QColor(180, 0, 0));
+
+ pos_threshold = new CanvasToolThreshold(*canvaswidget->canvas,
+ instrument.getPositionThreshold(),
+ QColor(127, 127, 255),
+ QColor(0, 0, 180));
+
canvaswidget->canvas->tools.push_back(threshold);
- tool_selections = new CanvasToolSelections(canvaswidget->canvas, selections,
- selections_preview);
- connect(threshold, SIGNAL(thresholdChanged(double)),
- tool_selections, SLOT(thresholdChanged(double)));
+ canvaswidget->canvas->tools.push_back(pos_threshold);
+
+ tool_ranges = new CanvasToolRanges(instrument,
+ canvaswidget->canvas, ranges,
+ ranges_preview);
+
+ tool_position = new CanvasToolPosition(instrument,
+ *canvaswidget->canvas, ranges,
+ ranges_preview);
+
+ connect(&instrument, SIGNAL(rangesChanged()),
+ tool_position, SLOT(rangesChanged()));
+
+ connect(&instrument, SIGNAL(thresholdChanged()),
+ tool_ranges, SLOT(autoCreateRangesPreview()));
+
+ connect(&instrument, SIGNAL(positionThresholdChanged()),
+ tool_ranges, SLOT(autoCreateRangesPreview()));
+
connect(threshold, SIGNAL(thresholdChanging(double)),
- tool_selections, SLOT(thresholdChanged(double)));
- connect(&selections, SIGNAL(activeChanged(sel_id_t)),
+ &instrument, SLOT(setThreshold(double)));
+ connect(threshold, SIGNAL(thresholdChanged(double)),
+ &instrument, SLOT(setThreshold(double)));
+
+ connect(pos_threshold, SIGNAL(thresholdChanging(double)),
+ &instrument, SLOT(setPositionThreshold(double)));
+ connect(pos_threshold, SIGNAL(thresholdChanged(double)),
+ &instrument, SLOT(setPositionThreshold(double)));
+
+ connect(&ranges, SIGNAL(activeChanged(sel_id_t)),
canvaswidget->canvas, SLOT(update()));
- connect(&selections, SIGNAL(updated(sel_id_t)),
+ connect(&ranges, SIGNAL(updated(sel_id_t)),
canvaswidget->canvas, SLOT(update()));
- addTool(toolbar, canvaswidget->canvas, tool_selections);
-
- sorter = new SampleSorter(selections, selections_preview, instrument);
- connect(&selections, SIGNAL(added(sel_id_t)),
- sorter, SLOT(addSelection(sel_id_t)));
- connect(&selections_preview, SIGNAL(added(sel_id_t)),
- sorter, SLOT(addSelectionPreview(sel_id_t)));
- connect(&selections, SIGNAL(updated(sel_id_t)), sorter, SLOT(relayout()));
- connect(&selections_preview, SIGNAL(updated(sel_id_t)),
+ addTool(toolbar, canvaswidget->canvas, tool_ranges);
+ addTool(toolbar, canvaswidget->canvas, tool_position);
+
+ sorter = new SampleSorter(ranges, ranges_preview, instrument);
+ connect(&ranges, SIGNAL(added(sel_id_t)),
+ sorter, SLOT(addRange(sel_id_t)));
+ connect(&ranges_preview, SIGNAL(added(sel_id_t)),
+ sorter, SLOT(addRangePreview(sel_id_t)));
+ connect(&ranges, SIGNAL(updated(sel_id_t)), sorter, SLOT(relayout()));
+ connect(&ranges_preview, SIGNAL(updated(sel_id_t)),
sorter, SLOT(relayout()));
- connect(&selections, SIGNAL(removed(sel_id_t)), sorter, SLOT(relayout()));
- connect(&selections_preview, SIGNAL(removed(sel_id_t)),
+ connect(&ranges, SIGNAL(removed(sel_id_t)), sorter, SLOT(relayout()));
+ connect(&ranges_preview, SIGNAL(removed(sel_id_t)),
sorter, SLOT(relayout()));
- connect(&selections, SIGNAL(activeChanged(sel_id_t)),
+ connect(&ranges, SIGNAL(activeChanged(sel_id_t)),
sorter, SLOT(relayout()));
QPushButton* btn_playsamples = new QPushButton(tr("Play samples"));
@@ -142,11 +178,11 @@ InstrumentWidget::InstrumentWidget(Settings& settings, Instrument& instrument)
dockWidget->widget()->setLayout(new QVBoxLayout());
tabs = new QTabWidget(this);
- tabs->setMinimumWidth(350);
+ tabs->setMinimumWidth(416);
tabs->addTab(createFilesTab(), tr("Files"));
generateTabId = tabs->addTab(createGenerateTab(), tr("Generate"));
tabs->addTab(createEditTab(), tr("Edit"));
- //tabs->addTab(createExportTab(), tr("Export"));
+ tabs->addTab(createExportTab(), tr("Export"));
connect(tabs, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
tabChanged(tabs->currentIndex());
@@ -168,8 +204,9 @@ InstrumentWidget::InstrumentWidget(Settings& settings, Instrument& instrument)
canvaswidget->xscale->setValue(0);
canvaswidget->xoffset->setValue(0);
- // Update selections according to threshold
- tool_selections->thresholdChanged(instrument.getThreshold());
+ // Update ranges according to threshold
+// tool_ranges->thresholdChanged(instrument.getThreshold());
+ recalcPositions();
}
InstrumentWidget::~InstrumentWidget()
@@ -178,10 +215,12 @@ InstrumentWidget::~InstrumentWidget()
void InstrumentWidget::tabChanged(int tabid)
{
- tool_selections->setShowPreview(tabid == generateTabId);
+ tool_ranges->setShowPreview(tabid == generateTabId);
+ tool_position->setShowPreview(tabid == generateTabId);
sorter->setShowPreview(tabid == generateTabId);
- tool_selections->autoCreateSelectionsPreview();
+ tool_ranges->autoCreateRangesPreview();
threshold->setActive(tabid == generateTabId);
+ pos_threshold->setActive(tabid == generateTabId); // TODO && current waveform is pos
}
QWidget* InstrumentWidget::createFilesTab()
@@ -198,6 +237,8 @@ QWidget* InstrumentWidget::createFilesTab()
filelist = new FileList(instrument);
connect(filelist, SIGNAL(masterFileChanged(QString)),
this, SLOT(loadFile(QString)));
+ connect(filelist, SIGNAL(positionFilesChanged()),
+ this, SLOT(recalcPositions()));
connect(loadbtn, SIGNAL(clicked()), filelist, SLOT(addFiles()));
l->addWidget(filelist);
@@ -211,26 +252,26 @@ QWidget* InstrumentWidget::createFilesTab()
QWidget* InstrumentWidget::createEditTab()
{
- selections = instrument.getSelections();
- SelectionEditor* se = new SelectionEditor(selections, instrument);
+ ranges = instrument.getRanges();
+ RangeEditor* se = new RangeEditor(ranges, instrument);
- connect(&selections, SIGNAL(added(sel_id_t)), se, SLOT(added(sel_id_t)));
- connect(&selections, SIGNAL(updated(sel_id_t)), se, SLOT(updated(sel_id_t)));
- connect(&selections, SIGNAL(removed(sel_id_t)), se, SLOT(removed(sel_id_t)));
- connect(&selections, SIGNAL(activeChanged(sel_id_t)),
+ connect(&ranges, SIGNAL(added(sel_id_t)), se, SLOT(added(sel_id_t)));
+ connect(&ranges, SIGNAL(updated(sel_id_t)), se, SLOT(updated(sel_id_t)));
+ connect(&ranges, SIGNAL(removed(sel_id_t)), se, SLOT(removed(sel_id_t)));
+ connect(&ranges, SIGNAL(activeChanged(sel_id_t)),
se, SLOT(activeChanged(sel_id_t)));
- connect(&selections, SIGNAL(added(sel_id_t)), this, SLOT(selectionChanged()));
- connect(&selections, SIGNAL(updated(sel_id_t)), this, SLOT(selectionChanged()));
- connect(&selections, SIGNAL(removed(sel_id_t)), this, SLOT(selectionChanged()));
- connect(&selections, SIGNAL(activeChanged(sel_id_t)), this, SLOT(selectionChanged()));
+ connect(&ranges, SIGNAL(added(sel_id_t)), this, SLOT(rangeChanged()));
+ connect(&ranges, SIGNAL(updated(sel_id_t)), this, SLOT(rangeChanged()));
+ connect(&ranges, SIGNAL(removed(sel_id_t)), this, SLOT(rangeChanged()));
+ connect(&ranges, SIGNAL(activeChanged(sel_id_t)), this, SLOT(rangeChanged()));
return se;
}
-void InstrumentWidget::selectionChanged()
+void InstrumentWidget::rangeChanged()
{
- instrument.setSelections(selections);
+ instrument.setRanges(ranges);
}
static QSlider* createAttribute(QWidget* parent, QString name,
@@ -271,19 +312,14 @@ QWidget* InstrumentWidget::createGenerateTab()
QPushButton* autosel = new QPushButton();
autosel->setText(tr("Generate"));
connect(autosel, SIGNAL(clicked()),
- tool_selections, SLOT(clearSelections()));
+ tool_ranges, SLOT(clearRanges()));
connect(autosel, SIGNAL(clicked()),
- tool_selections, SLOT(autoCreateSelections()));
-
- connect(threshold, SIGNAL(thresholdChanged(double)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
- connect(threshold, SIGNAL(thresholdChanging(double)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
+ tool_ranges, SLOT(autoCreateRanges()));
QPushButton* clearsel = new QPushButton();
clearsel->setText(tr("Clear"));
connect(clearsel, SIGNAL(clicked()),
- tool_selections, SLOT(clearSelections()));
+ tool_ranges, SLOT(clearRanges()));
btns->addWidget(autosel);
btns->addWidget(clearsel);
@@ -294,7 +330,7 @@ QWidget* InstrumentWidget::createGenerateTab()
connect(slider_attacklength, SIGNAL(valueChanged(int)),
sorter, SLOT(setAttackLength(int)));
connect(slider_attacklength, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
+ tool_ranges, SLOT(autoCreateRangesPreview()));
slider_attacklength->setValue(instrument.getAttackLength());
connect(slider_attacklength, SIGNAL(valueChanged(int)),
this, SLOT(generateSlidersChanged()));
@@ -303,34 +339,34 @@ QWidget* InstrumentWidget::createGenerateTab()
connect(slider_spread, SIGNAL(valueChanged(int)),
sorter, SLOT(setSpreadFactor(int)));
connect(slider_spread, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
+ tool_ranges, SLOT(autoCreateRangesPreview()));
slider_spread->setValue(instrument.getPowerSpread());
connect(slider_spread, SIGNAL(valueChanged(int)),
this, SLOT(generateSlidersChanged()));
slider_hold = createAttribute(w, tr("Minimum size (samples):"), 0, 200000);
connect(slider_hold, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(holdChanged(int)));
+ tool_ranges, SLOT(holdChanged(int)));
connect(slider_hold, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
+ tool_ranges, SLOT(autoCreateRangesPreview()));
slider_hold->setValue(instrument.getMinimumSize());
connect(slider_hold, SIGNAL(valueChanged(int)),
this, SLOT(generateSlidersChanged()));
slider_falloff = createAttribute(w, tr("Falloff:"), 10, 5000);
connect(slider_falloff, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(noiseFloorChanged(int)));
+ tool_ranges, SLOT(noiseFloorChanged(int)));
connect(slider_falloff, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
+ tool_ranges, SLOT(autoCreateRangesPreview()));
slider_falloff->setValue(instrument.getFalloff());
connect(slider_falloff, SIGNAL(valueChanged(int)),
this, SLOT(generateSlidersChanged()));
slider_fadelength = createAttribute(w, tr("Fadelength:"), 0, 2000);
connect(slider_fadelength, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(fadeoutChanged(int)));
+ tool_ranges, SLOT(fadeoutChanged(int)));
connect(slider_fadelength, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
+ tool_ranges, SLOT(autoCreateRangesPreview()));
slider_fadelength->setValue(instrument.getFadeLength());
connect(slider_fadelength, SIGNAL(valueChanged(int)),
this, SLOT(generateSlidersChanged()));
@@ -362,7 +398,7 @@ QWidget* InstrumentWidget::createExportTab()
connect(prefix, SIGNAL(textChanged(const QString &)),
this, SLOT(prefixChanged()));
l->addWidget(prefix);
-
+/*
l->addWidget(new QLabel(tr("Export path:")));
QHBoxLayout* lo_exportp = new QHBoxLayout();
lineed_exportp = new QLineEdit();
@@ -386,7 +422,7 @@ QWidget* InstrumentWidget::createExportTab()
connect(extractor, SIGNAL(setMaximumProgress(int)),
bar, SLOT(setMaximum(int)));
l->addWidget(bar);
-
+*/
l->addStretch();
return w;
@@ -404,10 +440,10 @@ void InstrumentWidget::exportPathChanged()
void InstrumentWidget::playSamples()
{
- Selections* sels = &selections;
+ Ranges* sels = &ranges;
if(tabs->currentIndex() == generateTabId)
{
- sels = &selections_preview;
+ sels = &ranges_preview;
}
QVector<sel_id_t> ids = sels->ids();
@@ -415,8 +451,8 @@ void InstrumentWidget::playSamples()
{
for(int v2 = 0; v2 < ids.size(); v2++)
{
- Selection sel1 = sels->get(ids[v1]);
- Selection sel2 = sels->get(ids[v2]);
+ Range sel1 = sels->get(ids[v1]);
+ Range sel2 = sels->get(ids[v2]);
if(sel1.energy < sel2.energy)
{
@@ -430,7 +466,7 @@ void InstrumentWidget::playSamples()
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = sels->get(*i);
+ Range sel = sels->get(*i);
unsigned int length = sb_playsamples->value() * 44100 / 1000;
@@ -448,7 +484,7 @@ void InstrumentWidget::playSamples()
connect(&player, SIGNAL(positionUpdate(size_t)),
listen, SLOT(update(size_t)));
- player.playSelection(sel, to - sel.from);
+ player.playRange(sel, to - sel.from);
QTime t;
t.start();
while(t.elapsed() < sb_playsamples->value())
@@ -466,7 +502,7 @@ void InstrumentWidget::playSamples()
void InstrumentWidget::doExport()
{
- extractor->exportSelections();
+ extractor->exportRanges();
}
void InstrumentWidget::loadFile(QString filename)
@@ -475,8 +511,8 @@ void InstrumentWidget::loadFile(QString filename)
statusBar()->showMessage(tr("Loading..."));
qApp->processEvents();
- sorter->setWavData(NULL, 0);
- player.setPcmData(NULL, 0, 0);
+ sorter->setWavData(nullptr, 0);
+ player.setPcmData(nullptr, 0, 0);
canvaswidget->canvas->load(filename);
@@ -489,6 +525,103 @@ void InstrumentWidget::loadFile(QString filename)
instrument.setMasterFile(filename);
}
+void InstrumentWidget::recalcPositions()
+{
+ size_t cnt{0};
+ QString file[2];
+ for(auto audioFileIdx : instrument.getAudioFileList())
+ {
+ auto& audioFile = instrument.getAudioFile(audioFileIdx);
+ if(audioFile.getPositionChannel())
+ {
+ file[cnt] = audioFile.getAbsoluteFile();
+ cnt++;
+ }
+
+ if(cnt == 2)
+ {
+ break;
+ }
+ }
+
+ if(cnt != 2)
+ {
+ return; // we need precisely two position files for this to work
+ }
+
+ //TODO: Load pos files and set data on sample sorter
+ {
+ SF_INFO sf_info;
+ SNDFILE *fh = sf_open(file[0].toStdString().c_str(), SFM_READ, &sf_info);
+ if(!fh)
+ {
+ printf("Load error '%s'\n", file[0].toStdString().c_str());
+ // Just clear the canvas
+ return;
+ }
+
+ positionSize1 = sf_info.frames;
+ if(positionData1)
+ {
+ delete[] positionData1;
+ }
+ positionData1 = new float[positionSize1];
+
+ sf_read_float(fh, positionData1, positionSize1);
+
+ sf_close(fh);
+ }
+
+ {
+ SF_INFO sf_info;
+ SNDFILE *fh = sf_open(file[1].toStdString().c_str(), SFM_READ, &sf_info);
+ if(!fh)
+ {
+ printf("Load error '%s'\n", file[1].toStdString().c_str());
+ // Just clear the canvas
+ return;
+ }
+
+ positionSize2 = sf_info.frames;
+ if(positionData2)
+ {
+ delete[] positionData2;
+ }
+ positionData2 = new float[positionSize2];
+
+ sf_read_float(fh, positionData2, positionSize2);
+
+ sf_close(fh);
+ }
+
+#if 0
+ // Lowpass filter with runnig avarage
+ float p = 0.999;
+ {
+ float running{0};
+ for(int i = 0; i < positionSize1; ++i)
+ {
+ running = running * (1.0f - p) + positionData1[i] * p;
+ positionData1[i] = running;
+ }
+ }
+
+ {
+ float running{0};
+ for(int i = 0; i < positionSize2; ++i)
+ {
+ running = running * (1.0f - p) + positionData2[i] * p;
+ positionData2[i] = running;
+ }
+ }
+#endif
+
+ sorter->setPositionData(positionData1, positionSize1,
+ positionData2, positionSize2);
+ tool_ranges->setPositionData(positionData1, positionSize1,
+ positionData2, positionSize2);
+}
+
void InstrumentWidget::browse()
{
QString path =