diff options
Diffstat (limited to 'src/instrumentwidget.cc')
-rw-r--r-- | src/instrumentwidget.cc | 275 |
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 = |