summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2024-07-27 13:39:32 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2024-07-27 13:39:32 +0200
commitfc29354d86e6a8b5601e92405b89a1da27406ce7 (patch)
treee31069154ad5bd9497764b6205dd4d3a411b40eb /src
parent329110e3230a6518f024c612842b04afdea1cd03 (diff)
WIP
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am130
-rw-r--r--src/audiocache.cc28
-rw-r--r--src/audiocache.h55
-rw-r--r--src/audiodata.h28
-rw-r--r--src/audioextractor.cc24
-rw-r--r--src/audioextractor.h4
-rw-r--r--src/audiofile.h28
-rw-r--r--src/canvastool.cc2
-rw-r--r--src/canvastool.h2
-rw-r--r--src/canvastoollisten.cc3
-rw-r--r--src/canvastoolposition.cc161
-rw-r--r--src/canvastoolposition.h72
-rw-r--r--src/canvastoolranges.cc (renamed from src/canvastoolselections.cc)222
-rw-r--r--src/canvastoolranges.h (renamed from src/canvastoolselections.h)51
-rw-r--r--src/canvastoolthreshold.cc34
-rw-r--r--src/canvastoolthreshold.h13
-rw-r--r--src/detector.cc28
-rw-r--r--src/detector.h44
-rw-r--r--src/filelist.cc652
-rw-r--r--src/filelist.h58
-rw-r--r--src/instrumentwidget.cc275
-rw-r--r--src/instrumentwidget.h22
-rw-r--r--src/player.cc40
-rw-r--r--src/player.h14
-rw-r--r--src/project.cc56
-rw-r--r--src/project.h36
-rw-r--r--src/projectrenderer.cc6
-rw-r--r--src/projectserialiser.cc36
-rw-r--r--src/range.cc (renamed from src/selection.cc)34
-rw-r--r--src/range.h (renamed from src/selection.h)78
-rw-r--r--src/rangeeditor.cc (renamed from src/selectioneditor.cc)33
-rw-r--r--src/rangeeditor.h (renamed from src/selectioneditor.h)13
-rw-r--r--src/samplesorter.cc205
-rw-r--r--src/samplesorter.h24
-rw-r--r--src/ts/dgedit_da.ts152
-rw-r--r--src/ts/dgedit_fr.ts153
36 files changed, 1953 insertions, 863 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index a38b804..596767e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,74 +10,76 @@ dgedit_CXXFLAGS = -g $(SNDFILE_CXXFLAGS) $(QT_CFLAGS) $(AO_CFLAGS) \
AM_CXXFLAGS = $(QT_CFLAGS)
dgedit_TRANSLATIONS = \
- ts/dgedit_da.ts \
- ts/dgedit_fr.ts
+ $(top_srcdir)/src/ts/dgedit_da.ts \
+ $(top_srcdir)/src/ts/dgedit_fr.ts
dgedit_SOURCES = \
- dgedit.cc \
- aboutdialog.cc \
- audioextractor.cc \
- canvas.cc \
- canvastool.cc \
- canvastoollisten.cc \
- canvastoolselections.cc \
- canvastoolthreshold.cc \
- canvaswidget.cc \
- channeldialog.cc \
- channelswidget.cc \
- filelist.cc \
- imageeditor.cc \
- instrumentdialog.cc \
- instrumentwidget.cc \
- itemeditor.cc \
- localehandler.cc \
- mainwindow.cc \
- mipmap.cc \
- player.cc \
- project.cc \
- projectdialog.cc \
- projectrenderer.cc \
- projectserialiser.cc \
- renderdialog.cc \
- samplesorter.cc \
- selection.cc \
- selectioneditor.cc \
- settings.cc \
- volumefader.cc \
- zoomslider.cc
+ $(top_srcdir)/src/dgedit.cc \
+ $(top_srcdir)/src/aboutdialog.cc \
+ $(top_srcdir)/src/audioextractor.cc \
+ $(top_srcdir)/src/canvas.cc \
+ $(top_srcdir)/src/canvastool.cc \
+ $(top_srcdir)/src/canvastoollisten.cc \
+ $(top_srcdir)/src/canvastoolposition.cc \
+ $(top_srcdir)/src/canvastoolranges.cc \
+ $(top_srcdir)/src/canvastoolthreshold.cc \
+ $(top_srcdir)/src/canvaswidget.cc \
+ $(top_srcdir)/src/channeldialog.cc \
+ $(top_srcdir)/src/channelswidget.cc \
+ $(top_srcdir)/src/filelist.cc \
+ $(top_srcdir)/src/imageeditor.cc \
+ $(top_srcdir)/src/instrumentdialog.cc \
+ $(top_srcdir)/src/instrumentwidget.cc \
+ $(top_srcdir)/src/itemeditor.cc \
+ $(top_srcdir)/src/localehandler.cc \
+ $(top_srcdir)/src/mainwindow.cc \
+ $(top_srcdir)/src/mipmap.cc \
+ $(top_srcdir)/src/player.cc \
+ $(top_srcdir)/src/project.cc \
+ $(top_srcdir)/src/projectdialog.cc \
+ $(top_srcdir)/src/projectrenderer.cc \
+ $(top_srcdir)/src/projectserialiser.cc \
+ $(top_srcdir)/src/renderdialog.cc \
+ $(top_srcdir)/src/samplesorter.cc \
+ $(top_srcdir)/src/range.cc \
+ $(top_srcdir)/src/rangeeditor.cc \
+ $(top_srcdir)/src/settings.cc \
+ $(top_srcdir)/src/volumefader.cc \
+ $(top_srcdir)/src/zoomslider.cc
HDRS = \
- aboutdialog.h \
- audioextractor.h \
- canvas.h \
- canvastool.h \
- canvastoollisten.h \
- canvastoolselections.h \
- canvastoolthreshold.h \
- canvaswidget.h \
- channeldialog.h \
- channelswidget.h \
- filelist.h \
- imageeditor.h \
- instrumentdialog.h \
- instrumentwidget.h \
- itemeditor.h \
- localehandler.h \
- mainwindow.h \
- mipmap.h \
- player.h \
- project.h \
- projectdialog.h \
- projectrenderer.h \
- projectserialiser.h \
- renderdialog.h \
- samplesorter.h \
- selection.h \
- selectioneditor.h \
- sleep.h \
- settings.h \
- volumefader.h \
- zoomslider.h
+ $(top_srcdir)/src/aboutdialog.h \
+ $(top_srcdir)/src/audioextractor.h \
+ $(top_srcdir)/src/canvas.h \
+ $(top_srcdir)/src/canvastool.h \
+ $(top_srcdir)/src/canvastoollisten.h \
+ $(top_srcdir)/src/canvastoolposition.h \
+ $(top_srcdir)/src/canvastoolranges.h \
+ $(top_srcdir)/src/canvastoolthreshold.h \
+ $(top_srcdir)/src/canvaswidget.h \
+ $(top_srcdir)/src/channeldialog.h \
+ $(top_srcdir)/src/channelswidget.h \
+ $(top_srcdir)/src/filelist.h \
+ $(top_srcdir)/src/imageeditor.h \
+ $(top_srcdir)/src/instrumentdialog.h \
+ $(top_srcdir)/src/instrumentwidget.h \
+ $(top_srcdir)/src/itemeditor.h \
+ $(top_srcdir)/src/localehandler.h \
+ $(top_srcdir)/src/mainwindow.h \
+ $(top_srcdir)/src/mipmap.h \
+ $(top_srcdir)/src/player.h \
+ $(top_srcdir)/src/project.h \
+ $(top_srcdir)/src/projectdialog.h \
+ $(top_srcdir)/src/projectrenderer.h \
+ $(top_srcdir)/src/projectserialiser.h \
+ $(top_srcdir)/src/renderdialog.h \
+ $(top_srcdir)/src/samplesorter.h \
+ $(top_srcdir)/src/range.h \
+ $(top_srcdir)/src/rangeeditor.h \
+ $(top_srcdir)/src/sleep.h \
+ $(top_srcdir)/src/settings.h \
+ $(top_srcdir)/src/volumefader.h \
+ $(top_srcdir)/src/zoomslider.h
EXTRA_DIST = \
$(dgedit_TRANSLATIONS) \
diff --git a/src/audiocache.cc b/src/audiocache.cc
new file mode 100644
index 0000000..74b6498
--- /dev/null
+++ b/src/audiocache.cc
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * audiocache.cc
+ *
+ * Wed Mar 15 09:06:46 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "audiocache.h"
+
diff --git a/src/audiocache.h b/src/audiocache.h
new file mode 100644
index 0000000..fc5fd5b
--- /dev/null
+++ b/src/audiocache.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * audiocache.h
+ *
+ * Wed Mar 15 09:06:46 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
+class AudioData
+{
+public:
+ AudioData(const AudioFile& audiofile);
+
+ //load();
+ //unload();
+
+ AudioData::ID id;
+ std::vector<float> data;
+};
+
+class AudioCache
+{
+public:
+ using ID = int;
+
+ static AudioCache& get()
+ {
+ static AudioCache cache;
+ return cache;
+ }
+
+ ID add(const AudioFile&);
+ AudioData& get(ID);
+ void remove(ID);
+};
diff --git a/src/audiodata.h b/src/audiodata.h
new file mode 100644
index 0000000..884717b
--- /dev/null
+++ b/src/audiodata.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * audiodata.h
+ *
+ * Wed Mar 15 08:58:33 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
diff --git a/src/audioextractor.cc b/src/audioextractor.cc
index 95fe6b2..681edaf 100644
--- a/src/audioextractor.cc
+++ b/src/audioextractor.cc
@@ -50,14 +50,14 @@ AudioExtractor::AudioExtractor(Instrument& instrument, QObject *parent)
{
}
-bool AudioExtractor::exportSelections()
+bool AudioExtractor::exportRanges()
{
- auto selections = instrument.getSelections();
+ auto ranges = instrument.getRanges();
auto exportpath = instrument.getProject().getExportPath();
auto prefix = instrument.getPrefix();
int samplerate = -1;
- emit setMaximumProgress(selections.ids().size() + 1/* for xml writing*/);
+ emit setMaximumProgress(ranges.ids().size() + 1/* for xml writing*/);
int progress = 0;
emit progressUpdate(progress++);
qApp->processEvents();
@@ -92,15 +92,16 @@ bool AudioExtractor::exportSelections()
}
idx = 1;
- QVector<sel_id_t> sels = selections.ids();
+ QVector<sel_id_t> sels = ranges.ids();
- // Sort selections by velocity
+/*
+ // Sort ranges by velocity
for(int v1 = 0; v1 < sels.size(); v1++)
{
for(int v2 = 0; v2 < sels.size(); v2++)
{
- Selection sel1 = selections.get(sels[v1]);
- Selection sel2 = selections.get(sels[v2]);
+ Range sel1 = ranges.get(sels[v1]);
+ Range sel2 = ranges.get(sels[v2]);
if(sel1.energy < sel2.energy)
{
@@ -110,7 +111,7 @@ bool AudioExtractor::exportSelections()
}
}
}
-
+*/
if(samplerate == -1)
{
// For some reason we never got a samplerate. Set it to 44k1Hz
@@ -121,7 +122,7 @@ bool AudioExtractor::exportSelections()
QVector<sel_id_t>::iterator si = sels.begin();
while(si != sels.end())
{
- Selection sel = selections.get(*si);
+ Range sel = ranges.get(*si);
size_t offset = sel.from;
size_t size = sel.to - sel.from;
size_t fadein = sel.fadein;
@@ -241,15 +242,16 @@ bool AudioExtractor::exportSelections()
{
index++;
- Selection i = selections.get(*si);
+ Range i = ranges.get(*si);
i.name = prefix + "-" + QString::number(index);
QDomElement sample = doc.createElement("sample");
sample.setAttribute("name", i.name);
sample.setAttribute("power", QString::number(i.energy));
+ sample.setAttribute("position", QString::number(i.position));
samples.appendChild(sample);
- selections.update(*si, i);
+ ranges.update(*si, i);
int channelnum = 1; // Filechannel numbers are 1-based.
diff --git a/src/audioextractor.h b/src/audioextractor.h
index 134c582..aa85d98 100644
--- a/src/audioextractor.h
+++ b/src/audioextractor.h
@@ -32,7 +32,7 @@
#include <QString>
#include <QVector>
-#include "selection.h"
+#include "range.h"
#include "samplesorter.h"
class Instrument;
@@ -45,7 +45,7 @@ public:
AudioExtractor(Instrument& instrument, QObject* parent);
public slots:
- bool exportSelections();
+ bool exportRanges();
signals:
void progressUpdate(int value);
diff --git a/src/audiofile.h b/src/audiofile.h
new file mode 100644
index 0000000..0513f64
--- /dev/null
+++ b/src/audiofile.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * audiofile.h
+ *
+ * Wed Mar 15 08:47:33 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
diff --git a/src/canvastool.cc b/src/canvastool.cc
index a00a5a2..0ec7f6d 100644
--- a/src/canvastool.cc
+++ b/src/canvastool.cc
@@ -66,7 +66,7 @@ void CanvasTool::activate()
setActive(true);
}
-void CanvasTool::disactivate()
+void CanvasTool::deactivate()
{
setActive(false);
}
diff --git a/src/canvastool.h b/src/canvastool.h
index c890422..dd4a8b3 100644
--- a/src/canvastool.h
+++ b/src/canvastool.h
@@ -54,7 +54,7 @@ signals:
public slots:
void setActive(bool active);
void activate();
- void disactivate();
+ void deactivate();
private:
bool _active;
diff --git a/src/canvastoollisten.cc b/src/canvastoollisten.cc
index b49e8bc..145d4f9 100644
--- a/src/canvastoollisten.cc
+++ b/src/canvastoollisten.cc
@@ -27,6 +27,8 @@
#include "canvastoollisten.h"
#include <QApplication>
+#include <iostream>
+
CanvasToolListen::CanvasToolListen(Canvas* c, Player& p)
: player(p)
@@ -42,6 +44,7 @@ bool CanvasToolListen::mousePressEvent(QMouseEvent* event)
return false;
}
player.setPosition(canvas->unmapX(event->x()));
+ std::cout << (size_t)canvas->unmapX(event->x()) << std::endl;
canvas->update();
connect(&player, SIGNAL(positionUpdate(size_t)), this, SLOT(update(size_t)));
return true;
diff --git a/src/canvastoolposition.cc b/src/canvastoolposition.cc
new file mode 100644
index 0000000..7784720
--- /dev/null
+++ b/src/canvastoolposition.cc
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * canvastoolposition.cc
+ *
+ * Sat Mar 25 11:45:34 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "canvastoolposition.h"
+
+#include "project.h"
+#include "canvas.h"
+#include "range.h"
+
+#include <iostream>
+
+#define mapX(x) canvas.mapX(x)
+#define mapY(x) canvas.mapY(x)
+#define unmapX(x) canvas.unmapX(x)
+#define unmapY(x) canvas.unmapY(x)
+
+CanvasToolPosition::CanvasToolPosition(Instrument& instrument,
+ Canvas& canvas,
+ Ranges& ranges,
+ Ranges& ranges_preview)
+ : instrument(instrument)
+ , canvas(canvas)
+ , ranges(ranges)
+ , ranges_preview(ranges_preview)
+{
+ colSelBg = QColor(255, 0, 0, 60);
+ colSel = QColor(255, 0, 0, 160);
+ colActiveSelBg = QColor(255, 255, 0, 60);
+ colActiveSel = QColor(255, 255, 0, 160);
+ colPreviewSelBg = QColor(0, 0, 255, 60);
+ colPreviewSel = QColor(0, 0, 255, 160);
+}
+
+bool CanvasToolPosition::mouseMoveEvent(QMouseEvent* event)
+{
+ return false;
+}
+
+bool CanvasToolPosition::mousePressEvent(QMouseEvent* event)
+{
+ return false;
+}
+
+bool CanvasToolPosition::mouseReleaseEvent(QMouseEvent* event)
+{
+ return false;
+}
+
+namespace {
+void drawRange(const Range& range, Canvas& canvas, QPainter& painter)
+{
+ int x1 = mapX(range.pos1);
+ int x2 = mapX(range.pos2);
+
+ if(x1 > x2)
+ {
+ std::swap(x1, x2);
+ }
+
+ // x1 x2
+ // | |
+ // | |
+ // |<---->|
+ // | |
+ // | |
+ constexpr auto len = 8;
+ painter.drawLine(x1, mapY(-1.0), x1, mapY(1.0)); // left bar
+
+ painter.drawLine(x1, mapY( 0.0), x1 + len, mapY(0.0) + len); // left arrow
+ painter.drawLine(x1, mapY( 0.0), x1 + len, mapY(0.0) - len); // left arrow
+
+ painter.drawLine(x1, mapY( 0.0), x2, mapY(0.0)); // horizontal line
+
+ painter.drawLine(x2, mapY( 0.0), x2 - len, mapY(0.0) + len); // right arrow
+ painter.drawLine(x2, mapY( 0.0), x2 - len, mapY(0.0) - len); // right arrow
+
+ painter.drawLine(x2, mapY(-1.0), x2, mapY(1.0)); // right bar
+}
+}
+
+void CanvasToolPosition::paintEvent(QPaintEvent* event, QPainter& painter)
+{
+ int pos = unmapX(event->rect().x());
+ int width = unmapX(event->rect().width());
+
+ {
+ QVector<sel_id_t> ids = ranges.ids();
+ QVector<sel_id_t>::iterator i = ids.begin();
+ while(i != ids.end())
+ {
+ Range range = ranges.get(*i);
+
+ if(ranges.active() == *i)
+ {
+ painter.setBrush(colActiveSelBg);
+ painter.setPen(colActiveSel);
+ }
+ else
+ {
+ painter.setBrush(colSelBg);
+ painter.setPen(colSel);
+ }
+
+ drawRange(range, canvas, painter);
+ i++;
+ }
+ }
+
+ if(show_preview)
+ {
+ QVector<sel_id_t> ids = ranges_preview.ids();
+ QVector<sel_id_t>::iterator i = ids.begin();
+ while(i != ids.end())
+ {
+ Range range = ranges.get(*i);
+ painter.setBrush(colPreviewSelBg);
+ painter.setPen(colPreviewSel);
+ drawRange(range, canvas, painter);
+ i++;
+ }
+ }
+}
+
+void CanvasToolPosition::keyReleaseEvent(QKeyEvent* event)
+{
+}
+
+void CanvasToolPosition::rangesChanged()
+{
+ //auto ranges = instrument.getRanges();
+ canvas.update();
+}
+
+void CanvasToolPosition::setShowPreview(bool show_preview)
+{
+ this->show_preview = show_preview;
+ canvas.update();
+}
diff --git a/src/canvastoolposition.h b/src/canvastoolposition.h
new file mode 100644
index 0000000..0265a37
--- /dev/null
+++ b/src/canvastoolposition.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * canvastoolposition.h
+ *
+ * Sat Mar 25 11:45:34 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
+#include "canvastool.h"
+
+#include <QColor>
+
+class Instrument;
+class Canvas;
+class Ranges;
+
+class CanvasToolPosition
+ : public CanvasTool
+{
+ Q_OBJECT
+public:
+ CanvasToolPosition(Instrument& instrument,
+ Canvas& canvas,
+ Ranges& ranges,
+ Ranges& ranges_preview);
+
+ QString name() override { return tr("Position"); }
+ bool mouseMoveEvent(QMouseEvent* event) override;
+ bool mousePressEvent(QMouseEvent* event) override;
+ bool mouseReleaseEvent(QMouseEvent* event) override;
+ void paintEvent(QPaintEvent* event, QPainter& painter) override;
+ void keyReleaseEvent(QKeyEvent* event) override;
+
+public slots:
+ void rangesChanged();
+ void setShowPreview(bool show_preview);
+
+private:
+ Instrument& instrument;
+ Canvas& canvas;
+ Ranges& ranges;
+ Ranges& ranges_preview;
+
+ QColor colSelBg;
+ QColor colSel;
+ QColor colActiveSelBg;
+ QColor colActiveSel;
+ QColor colPreviewSelBg;
+ QColor colPreviewSel;
+
+ bool show_preview{false};
+};
diff --git a/src/canvastoolselections.cc b/src/canvastoolranges.cc
index d3e90f1..9a76163 100644
--- a/src/canvastoolselections.cc
+++ b/src/canvastoolranges.cc
@@ -1,6 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
- * canvastoolselections.cc
+ * canvastoolranges.cc
*
* Thu Jul 28 20:16:59 CEST 2011
* Copyright 2011 Bent Bisballe Nyeng
@@ -24,28 +24,32 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "canvastoolselections.h"
+#include "canvastoolranges.h"
+
+#include "project.h"
#include <math.h>
#include <stdio.h>
+#include <iostream>
#define mapX(x) canvas->mapX(x)
#define mapY(x) canvas->mapY(x)
#define unmapX(x) canvas->unmapX(x)
#define unmapY(x) canvas->unmapY(x)
-CanvasToolSelections::CanvasToolSelections(Canvas* c, Selections& s,
- Selections& p)
- : selections(s)
- , selections_preview(p)
+CanvasToolRanges::CanvasToolRanges(Instrument& instrument,
+ Canvas* c, Ranges& s,
+ Ranges& p)
+ : instrument(instrument)
+ , ranges(s)
+ , ranges_preview(p)
{
- threshold = 0.5; // Default from CanvasToolThreshold
hold = 100;
canvas = c;
- selection_is_moving_left = false;
- selection_is_moving_right = false;
+ range_is_moving_left = false;
+ range_is_moving_right = false;
colSelBg = QColor(255, 0, 0, 60);
colSel = QColor(255, 0, 0, 160);
@@ -55,39 +59,39 @@ CanvasToolSelections::CanvasToolSelections(Canvas* c, Selections& s,
colPreviewSel = QColor(0, 0, 255, 160);
}
-bool CanvasToolSelections::mouseMoveEvent(QMouseEvent* event)
+bool CanvasToolRanges::mouseMoveEvent(QMouseEvent* event)
{
- sel_id_t active_selection = selections.active();
- Selection act_sel = selections.get(active_selection);
+ sel_id_t active_range = ranges.active();
+ Range act_sel = ranges.get(active_range);
- if(selection_is_moving_left)
+ if(range_is_moving_left)
{
float val = unmapX(event->x());
if(val > act_sel.to) val = act_sel.to - 1;
act_sel.from = std::max(0.0f, val);
- selections.update(active_selection, act_sel);
+ ranges.update(active_range, act_sel);
canvas->update();
return true;
}
- if(selection_is_moving_right)
+ if(range_is_moving_right)
{
float val = unmapX(event->x());
if(val < act_sel.from) val = act_sel.from + 1;
act_sel.to = std::min(val, (float)canvas->size);
- selections.update(active_selection, act_sel);
+ ranges.update(active_range, act_sel);
canvas->update();
return true;
}
if(event->button() != Qt::LeftButton)
{
- // Check if a selection is being dragged.
- QVector<sel_id_t> ids = selections.ids();
+ // Check if a range is being dragged.
+ QVector<sel_id_t> ids = ranges.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
+ Range sel = ranges.get(*i);
if(abs(event->x() - mapX(sel.from)) < 2
|| abs(event->x() - mapX(sel.to)) < 2)
{
@@ -101,42 +105,42 @@ bool CanvasToolSelections::mouseMoveEvent(QMouseEvent* event)
return false;
}
-bool CanvasToolSelections::mousePressEvent(QMouseEvent* event)
+bool CanvasToolRanges::mousePressEvent(QMouseEvent* event)
{
if(event->button() == Qt::LeftButton)
{
- // Check if a selection is being dragged.
- QVector<sel_id_t> ids = selections.ids();
+ // Check if a range is being dragged.
+ QVector<sel_id_t> ids = ranges.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
+ Range sel = ranges.get(*i);
if(abs(event->x() - mapX(sel.from)) < 2)
{
- selections.setActive(*i);
- selection_is_moving_left = true;
+ ranges.setActive(*i);
+ range_is_moving_left = true;
return true;
}
if(abs(event->x() - mapX(sel.to)) < 2)
{
- selections.setActive(*i);
- selection_is_moving_right = true;
+ ranges.setActive(*i);
+ range_is_moving_right = true;
return true;
}
i++;
}
- // Check if a selection is being selected.
+ // Check if a range is being selected.
i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
+ Range sel = ranges.get(*i);
if(event->x() > mapX(sel.from) &&
event->x() < mapX(sel.to))
{
- selections.setActive(*i);
+ ranges.setActive(*i);
canvas->update();
return true;
}
@@ -144,12 +148,12 @@ bool CanvasToolSelections::mousePressEvent(QMouseEvent* event)
i++;
}
- // Make new selection
+ // Make new range
int from = unmapX(event->x());
- Selection new_selection(from, from);
- sel_id_t id = selections.add(new_selection);
- selections.setActive(id);
- selection_is_moving_right = true;
+ Range new_range{.from = from, .to = from};
+ sel_id_t id = ranges.add(new_range);
+ ranges.setActive(id);
+ range_is_moving_right = true;
canvas->update();
return true;
}
@@ -157,14 +161,14 @@ bool CanvasToolSelections::mousePressEvent(QMouseEvent* event)
return false;
}
-bool CanvasToolSelections::mouseReleaseEvent(QMouseEvent* event)
+bool CanvasToolRanges::mouseReleaseEvent(QMouseEvent* event)
{
if(event->button() == Qt::LeftButton)
{
- if(selection_is_moving_left || selection_is_moving_right)
+ if(range_is_moving_left || range_is_moving_right)
{
- selection_is_moving_left = false;
- selection_is_moving_right = false;
+ range_is_moving_left = false;
+ range_is_moving_right = false;
canvas->setCursor(Qt::ArrowCursor);
canvas->update();
return true;
@@ -174,24 +178,24 @@ bool CanvasToolSelections::mouseReleaseEvent(QMouseEvent* event)
return false;
}
-void CanvasToolSelections::paintEvent(QPaintEvent* event, QPainter& painter)
+void CanvasToolRanges::paintEvent(QPaintEvent* event, QPainter& painter)
{
int pos = unmapX(event->rect().x());
int width = unmapX(event->rect().width());
{
- QVector<sel_id_t> ids = selections.ids();
+ QVector<sel_id_t> ids = ranges.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
+ Range sel = ranges.get(*i);
int from = sel.from;
int to = sel.to;
int fadein = sel.fadein;
int fadeout = sel.fadeout;
if(from > pos + width || to + width < pos)
{ i++; continue; }
- if(selections.active() ==* i)
+ if(ranges.active() == *i)
{
painter.setBrush(colActiveSelBg);
painter.setPen(colActiveSel);
@@ -213,11 +217,11 @@ void CanvasToolSelections::paintEvent(QPaintEvent* event, QPainter& painter)
if(show_preview)
{
- QVector<sel_id_t> ids = selections_preview.ids();
+ QVector<sel_id_t> ids = ranges_preview.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections_preview.get(*i);
+ Range sel = ranges_preview.get(*i);
int from = sel.from;
int to = sel.to;
int fadein = sel.fadein;
@@ -238,56 +242,68 @@ void CanvasToolSelections::paintEvent(QPaintEvent* event, QPainter& painter)
}
}
-void CanvasToolSelections::keyReleaseEvent(QKeyEvent* event)
+void CanvasToolRanges::keyReleaseEvent(QKeyEvent* event)
{
- if(selections.active() != SEL_NONE && event->key() == Qt::Key_Delete)
+ if(ranges.active() != SEL_NONE && event->key() == Qt::Key_Delete)
{
- selections.remove(selections.active());
+ ranges.remove(ranges.active());
canvas->update();
}
}
-void CanvasToolSelections::thresholdChanged(double t)
-{
- threshold = t;
-}
-
-void CanvasToolSelections::holdChanged(int h)
+void CanvasToolRanges::holdChanged(int h)
{
hold = h;
}
-void CanvasToolSelections::noiseFloorChanged(int t)
+void CanvasToolRanges::noiseFloorChanged(int t)
{
double div = 666.0 / 0.00003;
noise_floor = (double)t/div;
}
-void CanvasToolSelections::fadeoutChanged(int t)
+void CanvasToolRanges::fadeoutChanged(int t)
{
fadeout = (double)t/1000.0;
}
-void CanvasToolSelections::autoCreateSelections()
+void CanvasToolRanges::autoCreateRanges()
{
- doAutoCreateSelections(false);
+ doAutoCreateRanges(false);
}
-void CanvasToolSelections::autoCreateSelectionsPreview()
+void CanvasToolRanges::autoCreateRangesPreview()
{
- doAutoCreateSelections(true);
+ doAutoCreateRanges(true);
}
-void CanvasToolSelections::doAutoCreateSelections(bool preview)
+void CanvasToolRanges::setPositionData(const float* positionData1,
+ size_t positionSize1,
+ const float* positionData2,
+ size_t positionSize2)
{
+ std::cout << __PRETTY_FUNCTION__ << std::endl;
+ std::cout << positionSize1 << " " << positionSize2 << std::endl;
+ this->positionData1 = positionData1;
+ this->positionSize1 = positionSize1;
+
+ this->positionData2 = positionData2;
+ this->positionSize2 = positionSize2;
+}
+
+void CanvasToolRanges::doAutoCreateRanges(bool preview)
+{
+ std::cout << __PRETTY_FUNCTION__ << std::endl;
+
+ // TODO: Get data from master file instead of canvas
float* data = canvas->data;
size_t size = canvas->size;
- if(preview) selections_preview.clear();
+ if(preview) ranges_preview.clear();
for(size_t i = 0; i < size; i++)
{
- if(fabs(data[i]) > fabs(threshold))
+ if(fabs(data[i]) > fabs(instrument.getThreshold()))
{
int from = i;
@@ -320,32 +336,94 @@ void CanvasToolSelections::doAutoCreateSelections(bool preview)
to++;
}
- Selection s(from, to, 2, ((to - from) / 3) * fadeout);
+ Range range{
+ .from = from,
+ .to = to,
+ .fadein = 2,
+ .fadeout = ((to - from) / 3) * fadeout
+ };
+
+ /////////////////////////////////////////////////////////////////////////
+ if(positionData1 && positionData2)
+ {
+ //TODO: set window in ms instead of samples
+ int pos_window_size{1000}; // +/- 500 from detected,
+ double threshold = 0.1; // 1/3 is about right
+
+ float norm{0};
+ for(int idx = range.from - pos_window_size / 2;
+ idx < range.from + pos_window_size / 2;
+ ++idx)
+ {
+ norm = std::max(std::abs(positionData1[idx]), norm);
+ }
+
+ int pos1{range.from - pos_window_size / 2};
+ for(int idx = range.from - pos_window_size / 2;
+ idx < range.from + pos_window_size / 2;
+ ++idx)
+ {
+ if(std::abs(positionData1[idx]) / norm > threshold)
+ {
+ pos1 = idx;
+ range.pos1 = pos1;
+ break;
+ }
+ }
+
+ norm = 0;
+ for(int idx = range.from - pos_window_size / 2;
+ idx < range.from + pos_window_size / 2;
+ ++idx)
+ {
+ norm = std::max(std::abs(positionData1[idx]), norm);
+ }
+
+ int pos2{range.from + pos_window_size / 2};
+ for(int idx = range.from - pos_window_size / 2;
+ idx < range.from + pos_window_size / 2;
+ ++idx)
+ {
+ if(std::abs(positionData2[idx]) / norm > threshold)
+ {
+ pos2 = idx;
+ range.pos2 = pos2;
+ break;
+ }
+ }
+
+ constexpr double speed_of_sound{343100}; // mm/s
+ constexpr double samplerate{48000}; // 48kHz - TODO get from audio
+
+ range.position = std::abs(pos1 - pos2) * speed_of_sound / samplerate / 2.0;
+ }
+ /////////////////////////////////////////////////////////////////////////
+
if(preview)
{
- selections_preview.add(s);
+ ranges_preview.add(range);
}
else
{
- selections.add(s);
+ ranges.add(range);
}
- i = to+1;
+ i = to + 1;
}
}
canvas->update();
}
-void CanvasToolSelections::clearSelections()
+void CanvasToolRanges::clearRanges()
{
- selections.clear();
- selection_is_moving_left = false;
- selection_is_moving_right = false;
+ ranges.clear();
+ range_is_moving_left = false;
+ range_is_moving_right = false;
canvas->setCursor(Qt::ArrowCursor);
canvas->update();
}
-void CanvasToolSelections::setShowPreview(bool s)
+void CanvasToolRanges::setShowPreview(bool s)
{
show_preview = s;
canvas->update();
diff --git a/src/canvastoolselections.h b/src/canvastoolranges.h
index 21f00c6..164532a 100644
--- a/src/canvastoolselections.h
+++ b/src/canvastoolranges.h
@@ -1,6 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
- * canvastoolselections.h
+ * canvastoolranges.h
*
* Thu Jul 28 20:16:59 CEST 2011
* Copyright 2011 Bent Bisballe Nyeng
@@ -32,48 +32,56 @@
#include "canvas.h"
-#include "selection.h"
+#include "range.h"
-class CanvasToolSelections
+class Instrument;
+
+class CanvasToolRanges
: public CanvasTool
{
Q_OBJECT
public:
- CanvasToolSelections(Canvas* canvas, Selections& selections,
- Selections& selections_preview);
+ CanvasToolRanges(Instrument& instrument,
+ Canvas* canvas, Ranges& ranges,
+ Ranges& ranges_preview);
- QString name() { return tr("Selections"); }
+ QString name() { return tr("Ranges"); }
bool mouseMoveEvent(QMouseEvent* event);
bool mousePressEvent(QMouseEvent* event);
bool mouseReleaseEvent(QMouseEvent* event);
void paintEvent(QPaintEvent* event, QPainter& painter);
void keyReleaseEvent(QKeyEvent* event);
- //Selections selections();
+ //Ranges ranges();
+
+ void setPositionData(const float* positionData1,
+ size_t positionSize1,
+ const float* positionData2,
+ size_t positionSize2);
signals:
- //void selectionsChanged(Selections selections);
- //void activeSelectionChanged(sel_id_t id);
+ //void rangesChanged(Ranges ranges);
+ //void activeRangeChanged(sel_id_t id);
public slots:
- void autoCreateSelections();
- void autoCreateSelectionsPreview();
- void clearSelections();
- void thresholdChanged(double threshold);
+ void autoCreateRanges();
+ void autoCreateRangesPreview();
+ void clearRanges();
void noiseFloorChanged(int t);
void holdChanged(int h);
void fadeoutChanged(int f);
void setShowPreview(bool show_preview);
private:
- void doAutoCreateSelections(bool preview);
+ void doAutoCreateRanges(bool preview);
- bool selection_is_moving_left;
- bool selection_is_moving_right;
+ Instrument& instrument;
+
+ bool range_is_moving_left;
+ bool range_is_moving_right;
Canvas* canvas;
- double threshold;
double noise_floor;
double fadeout;
int hold;
@@ -85,8 +93,13 @@ private:
QColor colPreviewSelBg;
QColor colPreviewSel;
- Selections& selections;
- Selections& selections_preview;
+ Ranges& ranges;
+ Ranges& ranges_preview;
bool show_preview;
+
+ const float* positionData1{};
+ size_t positionSize1{};
+ const float* positionData2{};
+ size_t positionSize2{};
};
diff --git a/src/canvastoolthreshold.cc b/src/canvastoolthreshold.cc
index a905766..65a195b 100644
--- a/src/canvastoolthreshold.cc
+++ b/src/canvastoolthreshold.cc
@@ -27,24 +27,23 @@
#include "canvastoolthreshold.h"
#include <math.h>
+#include <iostream>
+#include "canvas.h"
#include "project.h"
-#define mapX(x) canvas->mapX(x)
-#define mapY(x) canvas->mapY(x)
-#define unmapX(x) canvas->unmapX(x)
-#define unmapY(x) canvas->unmapY(x)
+#define mapY(x) canvas.mapY(x)
+#define unmapY(x) canvas.unmapY(x)
-CanvasToolThreshold::CanvasToolThreshold(Canvas* c, Instrument& instrument)
- : instrument(instrument)
+CanvasToolThreshold::CanvasToolThreshold(Canvas& canvas, double default_value,
+ QColor color, QColor moving_color)
+ : canvas(canvas)
+ , colThreshold(color)
+ , colThresholdMoving(moving_color)
{
- canvas = c;
- threshold = instrument.getThreshold();
+ threshold = default_value;
threshold_is_moving = false;
-
- colThreshold = QColor(255, 127, 127);
- colThresholdMoving = QColor(180, 0, 0);
}
bool CanvasToolThreshold::mouseMoveEvent(QMouseEvent* event)
@@ -60,7 +59,7 @@ bool CanvasToolThreshold::mouseMoveEvent(QMouseEvent* event)
abs(event->y() - mapY(-threshold)) < 2 )
{
- canvas->setCursor(Qt::SplitVCursor);
+ canvas.setCursor(Qt::SplitVCursor);
return true;
}
}
@@ -73,10 +72,10 @@ bool CanvasToolThreshold::mouseMoveEvent(QMouseEvent* event)
val = 1.0;
}
threshold = fabs(val);
- canvas->update();
+ canvas.update();
emit thresholdChanging(threshold);
- instrument.setThreshold(threshold);
+ std::cout << threshold << "\n";
return true;
}
@@ -97,7 +96,7 @@ bool CanvasToolThreshold::mousePressEvent(QMouseEvent* event)
abs(event->y() - mapY(-threshold)) < 2)
{
threshold_is_moving = true;
- canvas->update();
+ canvas.update();
return true;
}
}
@@ -117,11 +116,10 @@ bool CanvasToolThreshold::mouseReleaseEvent(QMouseEvent* event)
if(threshold_is_moving)
{
threshold_is_moving = false;
- canvas->setCursor(Qt::ArrowCursor);
- canvas->update();
+ canvas.setCursor(Qt::ArrowCursor);
+ canvas.update();
emit thresholdChanged(threshold);
- instrument.setThreshold(threshold);
return true;
}
}
diff --git a/src/canvastoolthreshold.h b/src/canvastoolthreshold.h
index 936bf68..8847ecb 100644
--- a/src/canvastoolthreshold.h
+++ b/src/canvastoolthreshold.h
@@ -30,16 +30,15 @@
#include <QColor>
-#include "canvas.h"
-
-class Instrument;
+class Canvas;
class CanvasToolThreshold
: public CanvasTool
{
Q_OBJECT
public:
- CanvasToolThreshold(Canvas* canvas, Instrument& instrument);
+ CanvasToolThreshold(Canvas& canvas, double default_value,
+ QColor color, QColor moving_color);
QString name() { return tr("Threshold"); }
bool mouseMoveEvent(QMouseEvent* event);
@@ -52,13 +51,11 @@ signals:
void thresholdChanging(double threshold);
private:
- float threshold;
+ double threshold;
bool threshold_is_moving;
- Canvas* canvas;
+ Canvas& canvas;
QColor colThreshold;
QColor colThresholdMoving;
-
- Instrument& instrument;
};
diff --git a/src/detector.cc b/src/detector.cc
new file mode 100644
index 0000000..4a83659
--- /dev/null
+++ b/src/detector.cc
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * detector.cc
+ *
+ * Wed Mar 15 08:34:24 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "detector.h"
+
diff --git a/src/detector.h b/src/detector.h
new file mode 100644
index 0000000..8bd84d1
--- /dev/null
+++ b/src/detector.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * detector.h
+ *
+ * Wed Mar 15 08:34:24 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
+#include <QObject>
+
+class Detector
+ : public QObject
+{
+public slots:
+ // threshold changed (double)
+ // master file changed (float*, size)
+
+ // pos threshold changed, 1/2 (double)
+ // pos file changed, 1/2 (float*, size)
+
+signals:
+ // ranges changed
+ // pos changed, 1/2
+};
diff --git a/src/filelist.cc b/src/filelist.cc
index e1467e3..b746450 100644
--- a/src/filelist.cc
+++ b/src/filelist.cc
@@ -35,7 +35,6 @@
#include "itemeditor.h"
#include "project.h"
-#include <QAbstractItemModel>
#include <QTreeView>
#include <iostream>
@@ -43,7 +42,6 @@
#include <QComboBox>
#include <QLineEdit>
#include <QCheckBox>
-#include <QStyledItemDelegate>
#include <QPainter>
#include <QHeaderView>
#include <QStyleOptionButton>
@@ -51,378 +49,225 @@
#include <sndfile.h>
-class ChannelMapDeligate
- : public QStyledItemDelegate
+FileDataModel::FileDataModel(Instrument& instrument, FileList* fileList)
+ : instrument(instrument)
+ , fileList(fileList)
+{
+}
+
+QModelIndex FileDataModel::index(int row, int column, const QModelIndex &parent) const
{
-public:
- ChannelMapDeligate(Instrument& instrument)
- : instrument(instrument)
+ if(!hasIndex(row, column, parent))
{
+ return QModelIndex();
}
- QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option,
- const QModelIndex &index) const override
+ auto audiofile_ids = instrument.getAudioFileList();
+ if(!parent.isValid())
{
- // Main channel:
- if(index.column() == 2)
- {
- auto w = new QCheckBox(parent);
- auto audiofile_ids = instrument.getAudioFileList();
- auto audiofile_id = audiofile_ids.begin() + index.row();
- auto& audiofile = instrument.getAudioFile(*audiofile_id);
-
- connect(w, &QCheckBox::stateChanged,
- [&audiofile](int state)
- {
- audiofile.setMainChannel(state == Qt::Checked);
- });
-
- return w;
- }
-
- // Name:
- if(index.column() == 3)
+ if(row < audiofile_ids.size())
{
- auto w = new QLineEdit(parent);
-
- auto audiofile_ids = instrument.getAudioFileList();
- auto audiofile_id = audiofile_ids.begin() + index.row();
- auto& audiofile = instrument.getAudioFile(*audiofile_id);
-
- connect(w, &QLineEdit::textEdited,
- [&audiofile](const QString& name)
- {
- audiofile.setName(name);
- });
- return w;
+ return createIndex(row, column, &instrument);
}
-
- // Channel Map ID:
- if(index.column() == 4)
+ else
{
- auto w = new QComboBox(parent);
- w->addItem(tr("<None>"), -1);
- auto channel_ids = instrument.getProject().getChannelList();
- for(auto channel_id : channel_ids)
- {
- const auto& channel = instrument.getProject().getChannel(channel_id);
- w->addItem(channel.getChannelName(), channel.getId());
- }
-
- auto audiofile_ids = instrument.getAudioFileList();
- auto audiofile_id = audiofile_ids.begin() + index.row();
- auto& audiofile = instrument.getAudioFile(*audiofile_id);
-
- connect(w,
- // This wierd line points the compiler to the correct overloaded
- // version of QComboBox::currentIndexChanged
- // ie. chooses the (int) version over the (const QString&) version
- QOverload<int>::of(&QComboBox::currentIndexChanged),
- [w, &audiofile](int idx)
- {
- audiofile.setChannelMapId(w->itemData(idx).toInt());
- });
- return w;
+ return QModelIndex(); // row is out of bounds.
}
-
- return QStyledItemDelegate::createEditor(parent, option, index);
}
- void setEditorData(QWidget *editor, const QModelIndex &index) const override
- {
- // Main channel:
- if(index.column() == 2)
- {
- auto w = static_cast<QCheckBox*>(editor);
- auto b = index.data(Qt::EditRole).toBool();
- w->setCheckState(b ? Qt::Checked : Qt::Unchecked);
- }
-
- // Name:
- if(index.column() == 3)
- {
- auto w = static_cast<QLineEdit*>(editor);
- auto s = index.data(Qt::EditRole).toString();
- w->setText(s);
- }
+ return QModelIndex();
+}
- // Channel Map ID:
- if(index.column() == 4)
- {
- auto w = static_cast<QComboBox*>(editor);
- auto i = w->findData(index.data(Qt::EditRole).toInt());
- w->setCurrentIndex(i);
- }
+QModelIndex FileDataModel::parent(const QModelIndex &index) const
+{
+ return QModelIndex(); // no parent
}
- void setModelData(QWidget *editor, QAbstractItemModel *model,
- const QModelIndex &index) const override
+int FileDataModel::rowCount(const QModelIndex &parent) const
+{
+ if(parent.column() > 0) // only return row count on first column
{
- // Main channel:
- if(index.column() == 2)
- {
- model->setData(index,
- static_cast<QCheckBox*>(editor)->checkState() == Qt::Checked,
- Qt::EditRole);
- }
-
- // Name:
- if(index.column() == 3)
- {
- model->setData(index, static_cast<QLineEdit*>(editor)->text(),
- Qt::EditRole);
- }
-
- // Channel Map ID:
- if(index.column() == 4)
- {
- model->setData(index, static_cast<QComboBox*>(editor)->currentData(),
- Qt::EditRole);
- }
+ return 0;
}
- void paint(QPainter* painter, const QStyleOptionViewItem& option,
- const QModelIndex& index) const override
+ if(!parent.isValid())
{
- if(index.column() == 2) // Main Channel
- {
- auto audiofile_ids = instrument.getAudioFileList();
- auto audiofile_id = audiofile_ids.begin() + index.row();
- const auto& audiofile = instrument.getAudioFile(*audiofile_id);
-
- bool checked = audiofile.getMainChannel();
- QStyleOptionButton butOpt;
- butOpt.state = QStyle::State_Enabled;
- butOpt.state |= checked ? QStyle::State_On : QStyle::State_Off;
- butOpt.rect = option.rect;
- QApplication::style()->drawControl( QStyle::CE_CheckBox,
- &butOpt, painter );
- }
- else
- {
- QStyledItemDelegate::paint(painter, option, index);
- }
+ auto audiofile_ids = instrument.getAudioFileList();
+ return audiofile_ids.size(); // root level
}
-private:
- Instrument& instrument;
-};
+ return 0; // no children
+}
-class FileDataModel
- : public QAbstractItemModel
+int FileDataModel::columnCount(const QModelIndex &parent) const
{
-public:
- FileDataModel(Instrument& instrument)
- : instrument(instrument)
+ return 6;
+}
+
+QVariant FileDataModel::data(const QModelIndex &index, int role) const
+{
+ if(!index.isValid())
{
+ return QVariant();
}
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
- {
- if(!hasIndex(row, column, parent))
- {
- return QModelIndex();
- }
+ auto audiofile_ids = instrument.getAudioFileList();
- auto audiofile_ids = instrument.getAudioFileList();
- if(!parent.isValid())
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ const auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ if(role == Qt::DecorationRole )
+ {
+ if(index.column() == 0)
{
- if(row < audiofile_ids.size())
+ if(audiofile.getAbsoluteFile() == instrument.getMasterFile())
{
- return createIndex(row, column, &instrument);
+ return QPixmap(":/icons/master.png");
}
else
{
- return QModelIndex(); // row is out of bounds.
+ return QPixmap(":/icons/file.png");
}
}
-
- return QModelIndex();
- }
-
- QModelIndex parent(const QModelIndex &index) const override
- {
- return QModelIndex(); // no parent
- }
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const override
- {
- if(parent.column() > 0) // only return row count on first column
- {
- return 0;
- }
-
- if(!parent.isValid())
- {
- auto audiofile_ids = instrument.getAudioFileList();
- return audiofile_ids.size(); // root level
- }
-
- return 0; // no children
}
- int columnCount(const QModelIndex &parent = QModelIndex()) const override
+ if(role == Qt::DisplayRole)
{
- return 5;
- }
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
- {
- if(!index.isValid())
- {
- return QVariant();
- }
-
- auto audiofile_ids = instrument.getAudioFileList();
-
- auto audiofile_id = audiofile_ids.begin() + index.row();
- const auto& audiofile = instrument.getAudioFile(*audiofile_id);
-
- if(role == Qt::DecorationRole )
- {
- if(index.column() == 0)
- {
- if(audiofile.getAbsoluteFile() == instrument.getMasterFile())
- {
- return QPixmap(":/icons/master.png");
- }
- else
- {
- return QPixmap(":/icons/file.png");
- }
- }
- }
-
- if(role == Qt::DisplayRole)
+ switch(index.column())
{
- switch(index.column())
- {
- case 0: return QVariant(); // Master
- case 1: return audiofile.getFile();
- case 2: return audiofile.getMainChannel() ? "x" : " ";
- case 3: return audiofile.getName();
- case 4:
- {
- auto channelMapId = audiofile.getChannelMapId();
- if(channelMapId == -1)
- {
- return tr("<None>");
- }
- return instrument.getProject().getChannel(channelMapId).getChannelName();
- }
- default: return QVariant();
- }
- }
- else if(role == Qt::EditRole)
+ case 0: return QVariant(); // Master
+ case 1: return audiofile.getFile();
+ case 2: return audiofile.getMainChannel() ? "x" : " ";
+ case 3: return audiofile.getName();
+ case 4:
{
- switch(index.column())
+ auto channelMapId = audiofile.getChannelMapId();
+ if(channelMapId == -1)
{
- case 0: return QVariant(); // Master
- case 1: return audiofile.getFile();
- case 2: return audiofile.getMainChannel();
- case 3: return audiofile.getName();
- case 4: return audiofile.getChannelMapId();
- default: return QVariant();
+ return tr("<None>");
}
+ return instrument.getProject().getChannel(channelMapId).getChannelName();
}
- else
-
- {
- return QVariant();
+ case 5: return audiofile.getPositionChannel() ? "x" : " ";
+ default: return QVariant();
}
}
-
- QVariant headerData(int section, Qt::Orientation orientation, int role) const override
+ else if(role == Qt::EditRole)
{
- if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
+ switch(index.column())
{
- switch(section)
- {
- case 0: return tr("M");
- case 1: return tr("Filename");
- case 2: return tr("m");
- case 3: return tr("Name");
- case 4: return tr("Kit Channel");
- default: return QVariant();
- }
+ case 0: return QVariant(); // Master
+ case 1: return audiofile.getFile();
+ case 2: return audiofile.getMainChannel();
+ case 3: return audiofile.getName();
+ case 4: return audiofile.getChannelMapId();
+ case 5: return audiofile.getPositionChannel();
+ default: return QVariant();
}
+ }
+ else
+ {
return QVariant();
}
+}
- Qt::ItemFlags flags(const QModelIndex &index) const override
+QVariant FileDataModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
{
- if(!index.isValid())
+ switch(section)
{
- return 0;
- }
-
- switch(index.column())
- {
- case 0: // Master
- return QAbstractItemModel::flags(index);
- case 1: // File
- return QAbstractItemModel::flags(index);
- case 2: // Main channel
- return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
- case 3: // Name
- return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
- case 4: // Channel map id
- return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
+ case 0: return tr("M");
+ case 1: return tr("Filename");
+ case 2: return tr("m");
+ case 3: return tr("Name");
+ case 4: return tr("Kit Channel");
+ case 5: return tr("p");
+ default: return QVariant();
}
}
- bool setData(const QModelIndex &index, const QVariant &value,
- int role = Qt::EditRole) override
+ return QVariant();
+}
+
+Qt::ItemFlags FileDataModel::flags(const QModelIndex &index) const
+{
+ if(!index.isValid())
{
- auto audiofile_ids = instrument.getAudioFileList();
+ return 0;
+ }
- if(index.row() > audiofile_ids.size() ||
- index.column() > (columnCount() - 1))
- {
- return false;
- }
+ switch(index.column())
+ {
+ case 0: // Master
+ return QAbstractItemModel::flags(index);
+ case 1: // File
+ return QAbstractItemModel::flags(index);
+ case 2: // Main channel
+ return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
+ case 3: // Name
+ return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
+ case 4: // Channel map id
+ return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
+ case 5: // Pos channel
+ return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
+ }
- auto audiofile_id = audiofile_ids.begin() + index.row();
- auto& audiofile = instrument.getAudioFile(*audiofile_id);
+ return 0;
+}
- switch(index.column())
- {
- case 0: // Master
- break;
- case 1: // File
- break;
- case 2: // Main Channel
- audiofile.setMainChannel(value.toBool());
- break;
- case 3: // Name
- audiofile.setName(value.toString());
- break;
- case 4: // Channel map id
- audiofile.setChannelMapId(value.toInt());
- break;
- default: break;
- }
+bool FileDataModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ auto audiofile_ids = instrument.getAudioFileList();
- return true;
+ if(index.row() > audiofile_ids.size() ||
+ index.column() > (columnCount() - 1))
+ {
+ return false;
}
- void refresh()
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ switch(index.column())
{
- beginResetModel();
- endResetModel();
+ case 0: // Master
+ break;
+ case 1: // File
+ break;
+ case 2: // Main Channel
+ audiofile.setMainChannel(value.toBool());
+ break;
+ case 3: // Name
+ audiofile.setName(value.toString());
+ break;
+ case 4: // Channel map id
+ audiofile.setChannelMapId(value.toInt());
+ break;
+ case 5: // Pos Channel
+ audiofile.setPositionChannel(value.toBool());
+ fileList->positionFilesChanged();
+ break;
+ default: break;
}
-private:
- Instrument& instrument;
-};
+ return true;
+}
+
+void FileDataModel::refresh()
+{
+ beginResetModel();
+ endResetModel();
+}
+
FileList::FileList(Instrument& instrument)
: instrument(instrument)
{
- model = new FileDataModel(instrument);
+ model = new FileDataModel(instrument, this);
setModel(model);
- setItemDelegate(new ChannelMapDeligate(instrument));
+ setItemDelegate(new ChannelMapDeligate(instrument, this));
setEditTriggers(QAbstractItemView::AllEditTriggers); // show list on click
setContextMenuPolicy(Qt::CustomContextMenu); // enable context menu
@@ -584,3 +429,202 @@ void FileList::removeAllFiles()
emit masterFileChanged(""); // Clear canvas
emit allFilesRemoved();
}
+
+
+ChannelMapDeligate::ChannelMapDeligate(Instrument& instrument, FileList* fileList)
+ : instrument(instrument)
+ , fileList(fileList)
+{
+}
+
+QWidget* ChannelMapDeligate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ // Main channel:
+ if(index.column() == 2)
+ {
+ auto w = new QCheckBox(parent);
+ auto audiofile_ids = instrument.getAudioFileList();
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ connect(w, &QCheckBox::stateChanged,
+ [&audiofile](int state)
+ {
+ audiofile.setMainChannel(state == Qt::Checked);
+ });
+
+ return w;
+ }
+
+ // Name:
+ if(index.column() == 3)
+ {
+ auto w = new QLineEdit(parent);
+
+ auto audiofile_ids = instrument.getAudioFileList();
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ connect(w, &QLineEdit::textEdited,
+ [&audiofile](const QString& name)
+ {
+ audiofile.setName(name);
+ });
+ return w;
+ }
+
+ // Channel Map ID:
+ if(index.column() == 4)
+ {
+ auto w = new QComboBox(parent);
+ w->addItem(tr("<None>"), -1);
+ auto channel_ids = instrument.getProject().getChannelList();
+ for(auto channel_id : channel_ids)
+ {
+ const auto& channel = instrument.getProject().getChannel(channel_id);
+ w->addItem(channel.getChannelName(), channel.getId());
+ }
+
+ auto audiofile_ids = instrument.getAudioFileList();
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ connect(w,
+ // This wierd line points the compiler to the correct overloaded
+ // version of QComboBox::currentIndexChanged
+ // ie. chooses the (int) version over the (const QString&) version
+ QOverload<int>::of(&QComboBox::currentIndexChanged),
+ [w, &audiofile](int idx)
+ {
+ audiofile.setChannelMapId(w->itemData(idx).toInt());
+ });
+ return w;
+ }
+
+ // Pos channel:
+ if(index.column() == 5)
+ {
+ auto w = new QCheckBox(parent);
+ auto audiofile_ids = instrument.getAudioFileList();
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ connect(w, &QCheckBox::stateChanged,
+ [&](int state)
+ {
+ audiofile.setPositionChannel(state == Qt::Checked);
+ fileList->positionFilesChanged();
+ });
+
+ return w;
+ }
+
+ return QStyledItemDelegate::createEditor(parent, option, index);
+}
+
+void ChannelMapDeligate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ // Main channel:
+ if(index.column() == 2)
+ {
+ auto w = static_cast<QCheckBox*>(editor);
+ auto b = index.data(Qt::EditRole).toBool();
+ w->setCheckState(b ? Qt::Checked : Qt::Unchecked);
+ }
+
+ // Name:
+ if(index.column() == 3)
+ {
+ auto w = static_cast<QLineEdit*>(editor);
+ auto s = index.data(Qt::EditRole).toString();
+ w->setText(s);
+ }
+
+ // Channel Map ID:
+ if(index.column() == 4)
+ {
+ auto w = static_cast<QComboBox*>(editor);
+ auto i = w->findData(index.data(Qt::EditRole).toInt());
+ w->setCurrentIndex(i);
+ }
+
+ // Pos channel:
+ if(index.column() == 5)
+ {
+ auto w = static_cast<QCheckBox*>(editor);
+ auto b = index.data(Qt::EditRole).toBool();
+ w->setCheckState(b ? Qt::Checked : Qt::Unchecked);
+ }
+}
+
+void ChannelMapDeligate::setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const
+{
+ // Main channel:
+ if(index.column() == 2)
+ {
+ model->setData(index,
+ static_cast<QCheckBox*>(editor)->checkState() == Qt::Checked,
+ Qt::EditRole);
+ }
+
+ // Name:
+ if(index.column() == 3)
+ {
+ model->setData(index, static_cast<QLineEdit*>(editor)->text(),
+ Qt::EditRole);
+ }
+
+ // Channel Map ID:
+ if(index.column() == 4)
+ {
+ model->setData(index, static_cast<QComboBox*>(editor)->currentData(),
+ Qt::EditRole);
+ }
+
+ // Pos channel:
+ if(index.column() == 5)
+ {
+ model->setData(index,
+ static_cast<QCheckBox*>(editor)->checkState() == Qt::Checked,
+ Qt::EditRole);
+ }
+}
+
+void ChannelMapDeligate::paint(QPainter* painter, const QStyleOptionViewItem& option,
+ const QModelIndex& index) const
+{
+ if(index.column() == 2) // Main Channel
+ {
+ auto audiofile_ids = instrument.getAudioFileList();
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ const auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ bool checked = audiofile.getMainChannel();
+ QStyleOptionButton butOpt;
+ butOpt.state = QStyle::State_Enabled;
+ butOpt.state |= checked ? QStyle::State_On : QStyle::State_Off;
+ butOpt.rect = option.rect;
+ QApplication::style()->drawControl( QStyle::CE_CheckBox,
+ &butOpt, painter );
+ }
+ else if(index.column() == 5) // Pos Channel
+ {
+ auto audiofile_ids = instrument.getAudioFileList();
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ const auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ bool checked = audiofile.getPositionChannel();
+ QStyleOptionButton butOpt;
+ butOpt.state = QStyle::State_Enabled;
+ butOpt.state |= checked ? QStyle::State_On : QStyle::State_Off;
+ butOpt.rect = option.rect;
+ QApplication::style()->drawControl( QStyle::CE_CheckBox,
+ &butOpt, painter );
+ }
+ else
+ {
+ QStyledItemDelegate::paint(painter, option, index);
+ }
+}
diff --git a/src/filelist.h b/src/filelist.h
index 165af83..af0d40a 100644
--- a/src/filelist.h
+++ b/src/filelist.h
@@ -29,9 +29,41 @@
#include <QTreeView>
#include <QAction>
#include <QMenu>
+#include <QStyledItemDelegate>
+#include <QAbstractItemModel>
class Instrument;
-class FileDataModel;
+class FileList;
+
+class FileDataModel
+ : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ FileDataModel(Instrument& instrument, FileList* fileList);
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
+ QModelIndex parent(const QModelIndex &index) const override;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+
+ Qt::ItemFlags flags(const QModelIndex &index) const override;
+
+ bool setData(const QModelIndex &index, const QVariant &value,
+ int role = Qt::EditRole) override;
+
+ void refresh();
+
+private:
+ Instrument& instrument;
+ FileList* fileList;
+};
class FileList
: public QTreeView
@@ -44,6 +76,7 @@ public:
signals:
void masterFileChanged(QString filename);
+ void positionFilesChanged();
// void fileAdded(QString file, QString name);
void fileRemoved(QString file, QString name);
void allFilesRemoved();
@@ -83,3 +116,26 @@ private:
Instrument& instrument;
FileDataModel* model;
};
+
+class ChannelMapDeligate
+ : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ ChannelMapDeligate(Instrument& instrument, FileList* fileList);
+
+ QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const override;
+
+ void setEditorData(QWidget *editor, const QModelIndex &index) const override;
+
+ void setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const override;
+
+ void paint(QPainter* painter, const QStyleOptionViewItem& option,
+ const QModelIndex& index) const override;
+
+private:
+ Instrument& instrument;
+ FileList* fileList;
+};
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 =
diff --git a/src/instrumentwidget.h b/src/instrumentwidget.h
index 721b829..d3678d2 100644
--- a/src/instrumentwidget.h
+++ b/src/instrumentwidget.h
@@ -38,10 +38,11 @@
#include "audioextractor.h"
#include "samplesorter.h"
#include "filelist.h"
-#include "canvastoolselections.h"
+#include "canvastoolranges.h"
+#include "canvastoolposition.h"
#include "canvastoolthreshold.h"
#include "canvastoollisten.h"
-#include "selection.h"
+#include "range.h"
#include "player.h"
#include "zoomslider.h"
#include "canvaswidget.h"
@@ -70,11 +71,12 @@ public:
public slots:
void doExport();
void loadFile(QString filename);
+ void recalcPositions();
void playSamples();
void browse();
void tabChanged(int tabid);
void generateSlidersChanged();
- void selectionChanged();
+ void rangeChanged();
void prefixChanged();
void exportPathChanged();
@@ -87,8 +89,10 @@ private:
int generateTabId;
SampleSorter* sorter;
- CanvasToolSelections* tool_selections;
+ CanvasToolRanges* tool_ranges;
+ CanvasToolPosition* tool_position;
CanvasToolThreshold* threshold;
+ CanvasToolThreshold* pos_threshold;
CanvasToolListen* listen;
AudioExtractor* extractor;
FileList* filelist;
@@ -108,10 +112,16 @@ private:
QTabWidget* tabs;
// Session state information:
- Selections selections;
- Selections selections_preview;
+ Ranges ranges;
+ Ranges ranges_preview;
Player player;
Settings& settings;
Instrument& instrument;
+
+ // TODO: These should not be stored here...
+ float* positionData1{nullptr};
+ size_t positionSize1{0};
+ float* positionData2{nullptr};
+ size_t positionSize2{0};
};
diff --git a/src/player.cc b/src/player.cc
index d598d9f..a3eeaa2 100644
--- a/src/player.cc
+++ b/src/player.cc
@@ -38,7 +38,7 @@ Player::Player()
pcm_data = NULL;
pcm_size = 0;
end = 0;
- new_selection = false;
+ new_range = false;
connect(&report_timer, SIGNAL(timeout()), this, SLOT(reportTimeout()));
report_timer.start(50); // Update 25 times per second
@@ -55,7 +55,7 @@ Player::~Player()
#define _MIN(a, b) (a<b?a:b)
void Player::run()
{
- Selection sel;
+ Range sel;
static int init = 0;
if(init == 0)
@@ -79,14 +79,14 @@ void Player::run()
while(running)
{
{
- // Check for new Selection.
+ // Check for new Range.
QMutexLocker lock(&mutex);
- if(new_selection)
+ if(new_range)
{
- sel = selection;
+ sel = range;
pos = sel.from;
end = sel_end;
- new_selection = false;
+ new_range = false;
}
}
@@ -134,18 +134,18 @@ void Player::run()
}
}
-bool Player::playSelectionDone()
+bool Player::playRangeDone()
{
- return pos >= sel_end || pos >= selection.to;
+ return pos >= sel_end || pos >= range.to;
}
-void Player::playSelection(Selection s, int len)
+void Player::playRange(Range s, int len)
{
{
- // Enqueue new Selection for player consumation
+ // Enqueue new Range for player consumation
QMutexLocker lock(&mutex);
- selection = s;
+ range = s;
if(len > 0)
{
@@ -153,16 +153,16 @@ void Player::playSelection(Selection s, int len)
}
else
{
- sel_end = selection.to - selection.from;
+ sel_end = range.to - range.from;
}
- sel_end += selection.from;
+ sel_end += range.from;
- new_selection = true;
+ new_range = true;
}
- // Wait until player actually consumed the new Selection.
- while(new_selection)
+ // Wait until player actually consumed the new Range.
+ while(new_range)
{
msleep(1);
}
@@ -197,20 +197,20 @@ void Player::setPcmData(float* data, size_t size, double samplerate)
void Player::setPosition(size_t position)
{
- Selection s;
+ Range s;
s.from = position;
s.to = pcm_size;
s.fadein = 0;
s.fadeout = 0;
- playSelection(s);
+ playRange(s);
}
void Player::stop()
{
- Selection s;
+ Range s;
s.from = 0;
s.to = 0;
s.fadein = 0;
s.fadeout = 0;
- playSelection(s, pos);
+ playRange(s, pos);
}
diff --git a/src/player.h b/src/player.h
index 0f5b780..9bc03b7 100644
--- a/src/player.h
+++ b/src/player.h
@@ -32,7 +32,7 @@
#include <ao/ao.h>
-#include "selection.h"
+#include "range.h"
class Player
: public QThread
@@ -67,12 +67,12 @@ public slots:
//! Set player position as sample offset.
void setPosition(size_t position);
- //! Play range based on selection including fade-in/out.
+ //! Play range based on range including fade-in/out.
//! \param length Stop playing after length samples. -1 means play all.
- void playSelection(Selection selection, int length = -1);
+ void playRange(Range range, int length = -1);
- //! Return true if last selection is done playing.
- bool playSelectionDone();
+ //! Return true if last range is done playing.
+ bool playRangeDone();
//! Stop playing
void stop();
@@ -105,7 +105,7 @@ private:
bool running;
QMutex mutex;
- volatile bool new_selection;
+ volatile bool new_range;
size_t sel_end;
- Selection selection;
+ Range range;
};
diff --git a/src/project.cc b/src/project.cc
index 9cac537..bc96e07 100644
--- a/src/project.cc
+++ b/src/project.cc
@@ -127,8 +127,27 @@ void AudioFile::setMainChannel(bool main_channel)
}
}
+bool AudioFile::getPositionChannel() const
+{
+ return pos_channel;
+}
+
+void AudioFile::setPositionChannel(bool pos_channel)
+{
+ if(this->pos_channel == pos_channel)
+ {
+ return;
+ }
+
+ {
+ Project::RAIIBulkUpdate bulkUpdate(instrument.getProject());
+ this->pos_channel = pos_channel;
+ }
+}
+
Instrument::Instrument(Project& project, int id)
- : id(id)
+ : QObject(nullptr)
+ , id(id)
, project(project)
{
}
@@ -317,12 +336,12 @@ void Instrument::setFadeLength(std::size_t fade_length)
}
}
-float Instrument::getThreshold() const
+double Instrument::getThreshold() const
{
return threshold;
}
-void Instrument::setThreshold(float threshold)
+void Instrument::setThreshold(double threshold)
{
if(this->threshold == threshold)
{
@@ -333,19 +352,42 @@ void Instrument::setThreshold(float threshold)
Project::RAIIBulkUpdate bulkUpdate(project);
this->threshold = threshold;
}
+
+ emit thresholdChanged();
}
-Selections Instrument::getSelections() const
+double Instrument::getPositionThreshold() const
{
- return selections;
+ return position_threshold;
}
-void Instrument::setSelections(const Selections& selections)
+void Instrument::setPositionThreshold(double position_threshold)
{
+ std::cout << __PRETTY_FUNCTION__ << std::endl;
+ std::cout << position_threshold << std::endl;
+ if(this->position_threshold == position_threshold)
+ {
+ return;
+ }
+
{
Project::RAIIBulkUpdate bulkUpdate(project);
- this->selections = selections;
+ this->position_threshold = position_threshold;
}
+
+ emit positionThresholdChanged();
+}
+
+Ranges Instrument::getRanges() const
+{
+ return ranges;
+}
+
+void Instrument::setRanges(const Ranges& ranges)
+{
+ Project::RAIIBulkUpdate bulkUpdate(project);
+ this->ranges = ranges;
+ emit rangesChanged();
}
QString Instrument::getPrefix() const
diff --git a/src/project.h b/src/project.h
index 3e2b886..bbc7771 100644
--- a/src/project.h
+++ b/src/project.h
@@ -26,13 +26,14 @@
*/
#pragma once
-#include <list>
+#include "audioextractor.h"
+#include "range.h"
#include <QObject>
#include <QString>
-#include "audioextractor.h"
-#include "selection.h"
+#include <list>
+#include <array>
class Project;
class Instrument;
@@ -57,6 +58,9 @@ public:
bool getMainChannel() const;
void setMainChannel(bool main);
+ bool getPositionChannel() const;
+ void setPositionChannel(bool pos);
+
private:
friend class ProjectSerialiser;
@@ -64,15 +68,19 @@ private:
QString name;
int channel_map_id;
bool main_channel;
+ bool pos_channel{false};
int id;
Instrument& instrument;
};
class Instrument
+ : public QObject
{
+ Q_OBJECT
public:
Instrument(Project& project, int id);
+ virtual ~Instrument() = default;
int getId() const;
@@ -102,17 +110,26 @@ public:
std::size_t getFadeLength() const;
void setFadeLength(std::size_t fade_length);
- float getThreshold() const;
- void setThreshold(float threshold);
+ double getThreshold() const;
+ double getPositionThreshold() const;
- Selections getSelections() const;
- void setSelections(const Selections& selectios);
+ Ranges getRanges() const;
+ void setRanges(const Ranges& ranges);
QString getPrefix() const;
void setPrefix(const QString& prefix);
Project& getProject();
+public slots:
+ void setThreshold(double threshold);
+ void setPositionThreshold(double threshold);
+
+signals:
+ void thresholdChanged();
+ void positionThresholdChanged();
+ void rangesChanged();
+
private:
friend class ProjectSerialiser;
@@ -131,10 +148,11 @@ private:
std::size_t fade_length{666};
// Canvas
- float threshold{0.5f};
+ double threshold{0.1};
+ double position_threshold{0.1f};
// Edit tab
- Selections selections;
+ Ranges ranges;
// Export tab
QString prefix;
diff --git a/src/projectrenderer.cc b/src/projectrenderer.cc
index 62d646e..a8e805b 100644
--- a/src/projectrenderer.cc
+++ b/src/projectrenderer.cc
@@ -85,8 +85,8 @@ void ProjectRenderer::render()
instrument.getInstrumentName());
{
- auto selections = instrument.getSelections().ids();
- emit progressRenderStart(selections.count());
+ auto ranges = instrument.getRanges().ids();
+ emit progressRenderStart(ranges.count());
qApp->processEvents();
}
@@ -94,7 +94,7 @@ void ProjectRenderer::render()
connect(&extractor, SIGNAL(progressUpdate(int)),
this, SIGNAL(progressRenderTask(int)));
- if(!extractor.exportSelections())
+ if(!extractor.exportRanges())
{
emit progressFinished(1);
qApp->processEvents();
diff --git a/src/projectserialiser.cc b/src/projectserialiser.cc
index 6a204eb..8d9d824 100644
--- a/src/projectserialiser.cc
+++ b/src/projectserialiser.cc
@@ -188,15 +188,16 @@ QString ProjectSerialiser::serialise(const Project& project)
file.setAttribute("channel_map_id", audiofile.getChannelMapId());
file.setAttribute("master", i.master_file == audiofile.getAbsoluteFile());
file.setAttribute("main", audiofile.getMainChannel() ? "true" : "false");
+ file.setAttribute("pos", audiofile.getPositionChannel() ? "true" : "false");
file_list.appendChild(file);
}
auto regions = doc.createElement("regions");
- regions.setAttribute("nextid", i.selections.nextid);
- regions.setAttribute("act", i.selections.act);
+ regions.setAttribute("nextid", i.ranges.nextid);
+ regions.setAttribute("act", i.ranges.act);
instrument.appendChild(regions);
- for(auto r = i.selections.sels.begin(); r != i.selections.sels.end(); ++r)
+ for(auto r = i.ranges.sels.begin(); r != i.ranges.sels.end(); ++r)
{
auto region = doc.createElement("region");
region.setAttribute("id", (int)r.key());
@@ -205,6 +206,7 @@ QString ProjectSerialiser::serialise(const Project& project)
region.setAttribute("fadein", (int)r.value().fadein);
region.setAttribute("fadeout", (int)r.value().fadeout);
region.setAttribute("energy", r.value().energy);
+ region.setAttribute("position", r.value().position);
region.setAttribute("name", r.value().name);
regions.appendChild(region);
}
@@ -257,7 +259,7 @@ bool ProjectSerialiser::deserialise(const QString& data, Project& project)
for(auto& instrument : instruments)
{
auto id = instrument["id"].toInt();
- project.instruments.emplace_back(Instrument(project, id));
+ project.instruments.emplace_back(project, id);
auto& instr = project.instruments.back();
instr.instrument_name = instrument("instrument_name").text();
@@ -273,6 +275,7 @@ bool ProjectSerialiser::deserialise(const QString& data, Project& project)
audiofile.name = file["name"];
audiofile.channel_map_id = file["channel_map_id"].toInt();
audiofile.main_channel = file["main"] == "true";
+ audiofile.pos_channel = file["pos"] == "true";
if(file["master"] == "1")
{
@@ -292,20 +295,21 @@ bool ProjectSerialiser::deserialise(const QString& data, Project& project)
instr.prefix = instrument("prefix").text();
- auto selections = instrument("regions");
- instr.selections.nextid = selections["nextid"].toInt();
- instr.selections.act = selections["act"].toInt();
+ auto ranges = instrument("regions");
+ instr.ranges.nextid = ranges["nextid"].toInt();
+ instr.ranges.act = ranges["act"].toInt();
- for(auto& selection : selections.children())
+ for(auto& range : ranges.children())
{
- Selection s;
- s.from = selection["from"].toInt();
- s.to = selection["to"].toInt();
- s.fadein = selection["fadein"].toInt();
- s.fadeout = selection["fadeout"].toInt();
- s.energy = selection["energy"].toFloat();
- s.name = selection["name"];
- instr.selections.sels[selection["id"].toInt()] = s;
+ Range s;
+ s.from = range["from"].toInt();
+ s.to = range["to"].toInt();
+ s.fadein = range["fadein"].toInt();
+ s.fadeout = range["fadeout"].toInt();
+ s.energy = range["energy"].toFloat();
+ s.position = range["position"].toFloat();
+ s.name = range["name"];
+ instr.ranges.sels[range["id"].toInt()] = s;
}
}
diff --git a/src/selection.cc b/src/range.cc
index e18e485..980a8ae 100644
--- a/src/selection.cc
+++ b/src/range.cc
@@ -1,6 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
- * selection.cc
+ * range.cc
*
* Mon Apr 14 10:13:21 CEST 2014
* Copyright 2014 Bent Bisballe Nyeng
@@ -24,50 +24,50 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "selection.h"
+#include "range.h"
-Selections::Selections()
+Ranges::Ranges()
: QObject(NULL)
{
nextid = 0;
act = SEL_NONE;
}
-Selections::Selections(const Selections& other)
+Ranges::Ranges(const Ranges& other)
{
*this = other;
}
-void Selections::operator=(const Selections& other)
+void Ranges::operator=(const Ranges& other)
{
sels = other.sels;
nextid = other.nextid;
act = other.act;
}
-sel_id_t Selections::add(Selection selection)
+sel_id_t Ranges::add(Range range)
{
sel_id_t id = nextid++;
- sels[id] = selection;
+ sels[id] = range;
added(id);
return id;
}
-Selection Selections::get(sel_id_t id)
+Range& Ranges::get(sel_id_t id)
{
if(sels.find(id) == sels.end())
{
- Selection s(0,0,0,0);
+ static Range s{};
return s;
}
return sels[id];
}
-QVector<sel_id_t> Selections::ids()
+QVector<sel_id_t> Ranges::ids()
{
QVector<sel_id_t> v;
- QMap<sel_id_t, Selection>::iterator i = sels.begin();
+ QMap<sel_id_t, Range>::iterator i = sels.begin();
while(i != sels.end())
{
v.push_back(i.key());
@@ -77,16 +77,16 @@ QVector<sel_id_t> Selections::ids()
return v;
}
-void Selections::update(sel_id_t id, Selection selection)
+void Ranges::update(sel_id_t id, Range range)
{
if(sels.find(id) != sels.end())
{
- sels[id] = selection;
+ sels[id] = range;
emit updated(id);
}
}
-void Selections::remove(sel_id_t id)
+void Ranges::remove(sel_id_t id)
{
if(sels.find(id) != sels.end())
{
@@ -99,7 +99,7 @@ void Selections::remove(sel_id_t id)
}
}
-void Selections::clear()
+void Ranges::clear()
{
QVector<sel_id_t> _ids = ids();
QVector<sel_id_t>::iterator i = _ids.begin();
@@ -110,7 +110,7 @@ void Selections::clear()
}
}
-void Selections::setActive(sel_id_t id)
+void Ranges::setActive(sel_id_t id)
{
if(sels.find(id) != sels.end())
{
@@ -123,7 +123,7 @@ void Selections::setActive(sel_id_t id)
emit activeChanged(act);
}
-sel_id_t Selections::active()
+sel_id_t Ranges::active()
{
return act;
}
diff --git a/src/selection.h b/src/range.h
index 338b381..36782dc 100644
--- a/src/selection.h
+++ b/src/range.h
@@ -1,6 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
- * selection.h
+ * range.h
*
* Sat Nov 21 13:20:46 CET 2009
* Copyright 2009 Bent Bisballe Nyeng
@@ -31,85 +31,81 @@
#include <QMap>
#include <QVector>
-class Selection
+struct Range
{
-public:
- Selection(int from = 0, int to = 0, int fadein = 0, int fadeout = 0)
- {
- this->from = from;
- this->to = to;
- this->fadein = fadein;
- this->fadeout = fadeout;
- }
- size_t from;
- size_t to;
- size_t fadein;
- size_t fadeout;
-
- double energy;
+ size_t from{};
+ size_t to{};
+ size_t fadein{};
+ size_t fadeout{};
+
+ size_t pos1{};
+ size_t pos2{};
+
+ double energy{};
+ double position{};
QString name;
};
-typedef int sel_id_t;
-#define SEL_NONE -1
+using sel_id_t = int;
+static constexpr sel_id_t SEL_NONE = -1;
-class Selections
+class Ranges
: public QObject
{
Q_OBJECT
public:
- Selections();
- Selections(const Selections&);
+ Ranges();
+ Ranges(const Ranges&);
- void operator=(const Selections& other);
+ void operator=(const Ranges& other);
- //! Add a new selection object. The new id is returned.
- //! Adding a new selections will emit an added signal with the new id.
- sel_id_t add(Selection selection);
+ //! Add a new range object. The new id is returned.
+ //! Adding a new ranges will emit an added signal with the new id.
+ sel_id_t add(Range range);
- //! Get a stack copy of a specific selection object, by id.
- //! NOTE: If id does not exist an empty selection (from = to = 0) is
+ //! Get a stack copy of a specific range object, by id.
+ //! NOTE: If id does not exist an empty range (from = to = 0) is
//! returned.
- Selection get(sel_id_t id);
+ Range& get(sel_id_t id);
//! Return vector (unsorted) of all ids in the object.
QVector<sel_id_t> ids();
- //! Set active selection (to be rendered yellow)
+ //! Set active range (to be rendered yellow)
void setActive(sel_id_t id);
- //! Get active selection id.
+ //! Get active range id.
sel_id_t active();
public slots:
- //! Update a selection by id.
- //! Updating a selection will emit a updated signal.
- void update(sel_id_t id, Selection selection);
+ //! Update a range by id.
+ //! Updating a range will emit a updated signal.
+ void update(sel_id_t id, Range range);
- //! Delete a selection by id.
- //! Deleting a selection will emit a deleted signal.
+ //! Delete a range by id.
+ //! Deleting a range will emit a deleted signal.
void remove(sel_id_t id);
- //! Delete all selections
+ //! Delete all ranges
void clear();
signals:
- //! This signal is emitted when a new selection has been added.
+ //! This signal is emitted when a new range has been added.
void added(sel_id_t id);
- //! This signal is emitted when an existing selection has been updated.
+ //! This signal is emitted when an existing range has been updated.
void updated(sel_id_t id);
- //! This signal is emitted when a selection has been removed.
+ //! This signal is emitted when a range has been removed.
void removed(sel_id_t id);
- //! The active selection changed.
+ //! The active range changed.
void activeChanged(sel_id_t id);
private:
friend class ProjectSerialiser;
- QMap<sel_id_t, Selection> sels;
+ QMap<sel_id_t, Range> sels;
sel_id_t nextid;
sel_id_t act;
};
diff --git a/src/selectioneditor.cc b/src/rangeeditor.cc
index 417059d..504500d 100644
--- a/src/selectioneditor.cc
+++ b/src/rangeeditor.cc
@@ -1,6 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
- * selectioneditor.cc
+ * rangeeditor.cc
*
* Thu Apr 17 17:25:18 CEST 2014
* Copyright 2014 Bent Bisballe Nyeng
@@ -24,7 +24,7 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "selectioneditor.h"
+#include "rangeeditor.h"
#include "project.h"
@@ -40,7 +40,7 @@ static QLineEdit *createWidget(QString name, QWidget* parent)
QLineEdit* edt = new QLineEdit();
QObject::connect(edt, SIGNAL(editingFinished()),
- parent, SLOT(updateSelection()));
+ parent, SLOT(updateRange()));
l->addWidget(edt);
@@ -49,8 +49,8 @@ static QLineEdit *createWidget(QString name, QWidget* parent)
return edt;
}
-SelectionEditor::SelectionEditor(Selections &s, Instrument& instrument)
- : selections(s)
+RangeEditor::RangeEditor(Ranges &s, Instrument& instrument)
+ : ranges(s)
, instrument(instrument)
{
cur = SEL_NONE;
@@ -62,44 +62,47 @@ SelectionEditor::SelectionEditor(Selections &s, Instrument& instrument)
fadein = createWidget(tr("FadeIn:"), this);
fadeout = createWidget(tr("FadeOut:"), this);
energy = createWidget(tr("Energy:"), this);
+ position = createWidget(tr("Position:"), this);
name = createWidget(tr("Name:"), this);
((QHBoxLayout*)layout())->addStretch();
}
-void SelectionEditor::updateSelection()
+void RangeEditor::updateRange()
{
- Selection sel;
+ Range sel;
sel.from = from->text().toInt();
sel.to = to->text().toInt();
sel.fadein = fadein->text().toInt();
sel.fadeout = fadeout->text().toInt();
sel.energy = energy->text().toDouble();
+ sel.position = position->text().toDouble();
sel.name = name->text();
- selections.update(cur, sel);
+ ranges.update(cur, sel);
- instrument.setSelections(selections);
+ instrument.setRanges(ranges);
}
-void SelectionEditor::update()
+void RangeEditor::update()
{
- Selection sel = selections.get(cur);
+ Range sel = ranges.get(cur);
from->setText(QString::number(sel.from));
to->setText(QString::number(sel.to));
fadein->setText(QString::number(sel.fadein));
fadeout->setText(QString::number(sel.fadeout));
energy->setText(QString::number(sel.energy));
+ position->setText(QString::number(sel.position));
name->setText(sel.name);
}
-void SelectionEditor::added(sel_id_t id)
+void RangeEditor::added(sel_id_t id)
{
// Nothing to do here...
}
-void SelectionEditor::updated(sel_id_t id)
+void RangeEditor::updated(sel_id_t id)
{
if(cur == id)
{
@@ -107,7 +110,7 @@ void SelectionEditor::updated(sel_id_t id)
}
}
-void SelectionEditor::removed(sel_id_t id)
+void RangeEditor::removed(sel_id_t id)
{
if(cur == id)
{
@@ -116,7 +119,7 @@ void SelectionEditor::removed(sel_id_t id)
}
}
-void SelectionEditor::activeChanged(sel_id_t id)
+void RangeEditor::activeChanged(sel_id_t id)
{
cur = id;
update();
diff --git a/src/selectioneditor.h b/src/rangeeditor.h
index cdbf2de..d37e82c 100644
--- a/src/selectioneditor.h
+++ b/src/rangeeditor.h
@@ -1,6 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
- * selectioneditor.h
+ * rangeeditor.h
*
* Thu Apr 17 17:25:17 CEST 2014
* Copyright 2014 Bent Bisballe Nyeng
@@ -29,16 +29,16 @@
#include <QWidget>
#include <QLineEdit>
-#include "selection.h"
+#include "range.h"
class Instrument;
-class SelectionEditor
+class RangeEditor
: public QWidget
{
Q_OBJECT
public:
- SelectionEditor(Selections& selections, Instrument& instrument);
+ RangeEditor(Ranges& ranges, Instrument& instrument);
public slots:
void added(sel_id_t id);
@@ -48,10 +48,10 @@ public slots:
private slots:
void update();
- void updateSelection();
+ void updateRange();
private:
- Selections& selections;
+ Ranges& ranges;
sel_id_t cur;
@@ -60,6 +60,7 @@ private:
QLineEdit* fadein;
QLineEdit* fadeout;
QLineEdit* energy;
+ QLineEdit* position;
QLineEdit* name;
Instrument& instrument;
diff --git a/src/samplesorter.cc b/src/samplesorter.cc
index 29c24e6..4e930e4 100644
--- a/src/samplesorter.cc
+++ b/src/samplesorter.cc
@@ -26,10 +26,13 @@
*/
#include "samplesorter.h"
+#include "project.h"
+
#include <QPainter>
#include <QPaintEvent>
#include <QKeyEvent>
+#include <iostream>
#include <stdio.h>
#include <math.h>
@@ -37,9 +40,9 @@
#define MAXFLOAT (3.40282347e+38F)
#endif
-SampleSorter::SampleSorter(Selections& s, Selections& p, Instrument& instrument)
- : selections(s)
- , selections_preview(p)
+SampleSorter::SampleSorter(Ranges& s, Ranges& p, Instrument& instrument)
+ : ranges(s)
+ , ranges_preview(p)
, instrument(instrument)
{
setMouseTracking(true);
@@ -66,6 +69,18 @@ void SampleSorter::setWavData(const float* data, size_t size)
relayout();
}
+void SampleSorter::setPositionData(const float* positionData1, size_t positionSize1,
+ const float* positionData2, size_t positionSize2)
+{
+ this->positionData1 = positionData1;
+ this->positionSize1 = positionSize1;
+
+ this->positionData2 = positionData2;
+ this->positionSize2 = positionSize2;
+
+ relayout();
+}
+
int SampleSorter::attackLength()
{
return attlen;
@@ -84,28 +99,152 @@ void SampleSorter::setAttackLength(int len)
relayout();
}
-void SampleSorter::addSelection(sel_id_t id)
+void SampleSorter::addRange(sel_id_t id)
{
- Selection s = selections.get(id);
+ auto range = ranges.get(id);
double energy = 0.0;
- for(size_t idx = s.from;
- (idx < (size_t)s.from + (size_t)attackLength()) &&
- (idx < (size_t)s.to) && (idx < size);
+ for(size_t idx = range.from;
+ (idx < (size_t)range.from + (size_t)attackLength()) &&
+ (idx < (size_t)range.to) && (idx < size);
idx++)
{
energy += data[idx] * data[idx];
}
- s.energy = pow(energy, spread);
- selections.update(id, s);
+ range.energy = pow(energy, spread);
+
+// constexpr int window_size{10}; // TODO: Specify in ms
+//
+// std::vector<float> corr;
+// corr.resize(window_size);
+//
+// double position = 0.0;
+//
+// std::cout << "\n\nRange from: " << range.from << "\n";
+//
+//
+// float max_val1{0};
+// for(int idx = range.from - window_size / 2; idx < range.from + window_size / 2; ++idx)
+// {
+// if(std::abs(positionData1[idx]) > max_val1)
+// {
+// max_val1 = std::abs(positionData1[idx]);
+// }
+// }
+// float norm1 = 1.0f / max_val1;
+//
+// float max_val2{0};
+// for(int idx = range.from - window_size / 2; idx < range.from + window_size / 2; ++idx)
+// {
+// if(std::abs(positionData2[idx]) > max_val2)
+// {
+// max_val2 = std::abs(positionData2[idx]);
+// }
+// }
+// float norm2 = 1.0f / max_val2;
+//
+//
+// //constexpr auto lpf_beta = 0.025f; // 0<ß<1
+// constexpr auto lpf_beta = 1.0f; // 0<ß<1
+//
+// auto filter1 =
+// [lpf_beta](auto in)
+// {
+// static auto v{0.0f};
+// v = v - (lpf_beta * (v - in));
+// return v;
+// };
+// auto filter2 =
+// [lpf_beta](auto in)
+// {
+// static auto v{0.0f};
+// v = v - (lpf_beta * (v - in));
+// return v;
+// };
+//
+//
+//#if 0 // Cross-correlation
+//
+// if(positionData1 && positionSize1 &&
+// positionData2 && positionSize2)
+// {
+// // From: http://eceweb1.rutgers.edu/~gajic/solmanual/slides/chapter9_CORR.pdf
+// for(int k = 0; k < window_size; ++k)
+// {
+// corr[k] = 0.0f;
+// for(int m = range.from - window_size / 2; m < range.from + window_size / 2; ++m)
+// {
+// corr[k] +=
+// (filter1(positionData1[m] * norm1)) *
+// (filter2(positionData2[m - k] * norm2));
+// }
+// }
+// }
+//
+// float max_corr{0.0f};
+// for(int idx = 0; idx < corr.size(); ++idx)
+// {
+// std::cout << idx << ": " << corr[idx] << "\n";
+// if(corr[idx] > max_corr)
+// {
+// max_corr = corr[idx];
+// position = idx;
+// }
+// }
+//
+// std::cout << "Maximum found: " << max_corr << " at idx " << position << "\n";
+//
+//#else // Rising edge detection
+//
+// float threshold = instrument.getPositionThreshold();//{0.003f};
+// int pos_window_size{100}; // +/- 50 from detected,
+// // ~40 samples between left/right impirically detected when at edge, same for main mic to each of
+// // the piezos
+// norm1 = norm2 = 1.0f;
+// int pos1{0};
+// for(int idx = range.from - pos_window_size / 2;
+// idx < range.from + pos_window_size / 2;
+// ++idx)
+// {
+// if(std::abs(filter1(positionData1[idx])) * norm1 > threshold)
+// {
+// pos1 = idx;
+// range.pos1 = pos1;
+// break;
+// }
+// }
+//
+// int pos2{0};
+// for(int idx = range.from - pos_window_size / 2;
+// idx < range.from + pos_window_size / 2;
+// ++idx)
+// {
+// if(std::abs(filter2(positionData2[idx])) * norm2 > threshold)
+// {
+// pos2 = idx;
+// range.pos2 = pos1;
+// break;
+// }
+// }
+//
+// position = std::abs(pos1 - pos2);
+//#endif
+//
+// std::cout << "[" << pos1 << " <-> " << pos2 << "]\n";
+//
+// constexpr double speed_of_sound{3431000}; // mm/s
+// constexpr double samplerate{48000}; // 48kHz - TODO get from audio
+// range.position = position * speed_of_sound / samplerate / 2.0;
+//
+ ranges.update(id, range);
relayout();
}
-void SampleSorter::addSelectionPreview(sel_id_t id)
+void SampleSorter::addRangePreview(sel_id_t id)
{
- Selection s = selections_preview.get(id);
+ Range s = ranges_preview.get(id);
double energy = 0.0;
for(size_t idx = s.from;
@@ -117,7 +256,7 @@ void SampleSorter::addSelectionPreview(sel_id_t id)
}
s.energy = pow(energy, spread);
- selections_preview.update(id, s);
+ ranges_preview.update(id, s);
relayout();
}
@@ -128,11 +267,11 @@ void SampleSorter::relayout()
max = 0.0;
{
- QVector<sel_id_t> ids = selections.ids();
+ QVector<sel_id_t> ids = ranges.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
+ Range sel = ranges.get(*i);
if(sel.energy < min)
{
@@ -149,11 +288,11 @@ void SampleSorter::relayout()
if(show_preview)
{
- QVector<sel_id_t> ids = selections_preview.ids();
+ QVector<sel_id_t> ids = ranges_preview.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections_preview.get(*i);
+ Range sel = ranges_preview.get(*i);
if(sel.energy < min)
{
@@ -203,12 +342,12 @@ void SampleSorter::paintEvent(QPaintEvent* event)
{
- QVector<sel_id_t> ids = selections.ids();
+ QVector<sel_id_t> ids = ranges.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
- if(*i == selections.active())
+ Range sel = ranges.get(*i);
+ if(*i == ranges.active())
{
painter.setPen(colPtSel);
}
@@ -226,11 +365,11 @@ void SampleSorter::paintEvent(QPaintEvent* event)
if(show_preview)
{
- QVector<sel_id_t> ids = selections_preview.ids();
+ QVector<sel_id_t> ids = ranges_preview.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections_preview.get(*i);
+ Range sel = ranges_preview.get(*i);
painter.setPen(colPtPreview);
float x = (sel.energy / max);
x = sqrt(x);
@@ -243,16 +382,16 @@ void SampleSorter::paintEvent(QPaintEvent* event)
}
-sel_id_t SampleSorter::getSelectionByCoordinate(int px, int py)
+sel_id_t SampleSorter::getRangeByCoordinate(int px, int py)
{
// Hit radius is slithly larger than the circles themselves.
int hit_r = C_RADIUS + 1;
- QVector<sel_id_t> ids = selections.ids();
+ QVector<sel_id_t> ids = ranges.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
+ Range sel = ranges.get(*i);
float x = (sel.energy/max);
x = sqrt(x);
x *= (float)width() * 0.9;
@@ -273,14 +412,14 @@ void SampleSorter::mouseMoveEvent(QMouseEvent* event)
{
if(sel_moving != SEL_NONE)
{
- Selection sel = selections.get(sel_moving);
+ Range sel = ranges.get(sel_moving);
if(sel_moving != SEL_NONE)
{
double power = unmapX(event->x());
power *= power;
power *= max;
sel.energy = power;
- selections.update(sel_moving, sel);
+ ranges.update(sel_moving, sel);
}
update();
@@ -288,7 +427,7 @@ void SampleSorter::mouseMoveEvent(QMouseEvent* event)
}
else
{
- sel_id_t psel = getSelectionByCoordinate(event->x(), event->y());
+ sel_id_t psel = getRangeByCoordinate(event->x(), event->y());
if(psel != SEL_NONE)
{
setCursor(Qt::OpenHandCursor);
@@ -304,9 +443,9 @@ void SampleSorter::mousePressEvent(QMouseEvent* event)
{
if(event->button() == Qt::LeftButton)
{
- sel_id_t psel = getSelectionByCoordinate(event->x(), event->y());
+ sel_id_t psel = getRangeByCoordinate(event->x(), event->y());
sel_moving = psel;
- selections.setActive(psel);
+ ranges.setActive(psel);
if(psel != SEL_NONE)
{
setCursor(Qt::ClosedHandCursor);
@@ -319,7 +458,7 @@ void SampleSorter::mouseReleaseEvent(QMouseEvent* event)
if(event->button() == Qt::LeftButton)
{
sel_moving = SEL_NONE;
- sel_id_t psel = getSelectionByCoordinate(event->x(), event->y());
+ sel_id_t psel = getRangeByCoordinate(event->x(), event->y());
if(psel != SEL_NONE)
{
setCursor(Qt::OpenHandCursor);
@@ -333,8 +472,8 @@ void SampleSorter::mouseReleaseEvent(QMouseEvent* event)
void SampleSorter::keyReleaseEvent(QKeyEvent* event)
{
- if(selections.active() != SEL_NONE && event->key() == Qt::Key_Delete)
+ if(ranges.active() != SEL_NONE && event->key() == Qt::Key_Delete)
{
- selections.remove(selections.active());
+ ranges.remove(ranges.active());
}
}
diff --git a/src/samplesorter.h b/src/samplesorter.h
index 056161d..58a784a 100644
--- a/src/samplesorter.h
+++ b/src/samplesorter.h
@@ -28,7 +28,7 @@
#include <QWidget>
#include <QVector>
-#include "selection.h"
+#include "range.h"
class Instrument;
@@ -37,16 +37,18 @@ class SampleSorter
{
Q_OBJECT
public:
- SampleSorter(Selections& selections, Selections& selections_preview,
+ SampleSorter(Ranges& ranges, Ranges& ranges_preview,
Instrument& instrument);
public slots:
void setWavData(const float* data, size_t size);
+ void setPositionData(const float* positionData1, size_t positionSize1,
+ const float* positionData2, size_t positionSize2);
void setAttackLength(int len);
int attackLength();
- void addSelection(sel_id_t id);
- void addSelectionPreview(sel_id_t id);
+ void addRange(sel_id_t id);
+ void addRangePreview(sel_id_t id);
void relayout();
@@ -62,10 +64,10 @@ protected:
void keyReleaseEvent(QKeyEvent* event) override;
private:
- sel_id_t getSelectionByCoordinate(int x, int y);
+ sel_id_t getRangeByCoordinate(int x, int y);
- Selections& selections;
- Selections& selections_preview;
+ Ranges& ranges;
+ Ranges& ranges_preview;
bool show_preview;
@@ -77,7 +79,13 @@ private:
const float* data;
size_t size;
- Selection sel;
+ const float* positionData1{nullptr};
+ size_t positionSize1{0};
+
+ const float* positionData2{nullptr};
+ size_t positionSize2{0};
+
+ Range sel;
sel_id_t sel_moving;
diff --git a/src/ts/dgedit_da.ts b/src/ts/dgedit_da.ts
index bda3ba5..62ea715 100644
--- a/src/ts/dgedit_da.ts
+++ b/src/ts/dgedit_da.ts
@@ -23,17 +23,32 @@
</message>
</context>
<context>
+ <name>CanvasToolPosition</name>
+ <message>
+ <location filename="../canvastoolposition.h" line="47"/>
+ <source>Position</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CanvasToolRanges</name>
+ <message>
+ <location filename="../canvastoolranges.h" line="48"/>
+ <source>Ranges</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>CanvasToolSelections</name>
<message>
- <location filename="../canvastoolselections.h" line="45"/>
<source>Selections</source>
- <translation>Markeringer</translation>
+ <translation type="vanished">Markeringer</translation>
</message>
</context>
<context>
<name>CanvasToolThreshold</name>
<message>
- <location filename="../canvastoolthreshold.h" line="44"/>
+ <location filename="../canvastoolthreshold.h" line="43"/>
<source>Threshold</source>
<translation>Grænseværdi</translation>
</message>
@@ -54,7 +69,7 @@
<context>
<name>ChannelMapDeligate</name>
<message>
- <location filename="../filelist.cc" line="104"/>
+ <location filename="../filelist.cc" line="481"/>
<source>&lt;None&gt;</source>
<translation>&lt;Ingen&gt;</translation>
</message>
@@ -62,50 +77,55 @@
<context>
<name>FileDataModel</name>
<message>
- <location filename="../filelist.cc" line="309"/>
+ <location filename="../filelist.cc" line="147"/>
<source>&lt;None&gt;</source>
<translation>&lt;Ingen&gt;</translation>
</message>
<message>
- <location filename="../filelist.cc" line="341"/>
+ <location filename="../filelist.cc" line="181"/>
<source>M</source>
<translation>M</translation>
</message>
<message>
- <location filename="../filelist.cc" line="342"/>
+ <location filename="../filelist.cc" line="182"/>
<source>Filename</source>
<translation>Filnavn</translation>
</message>
<message>
- <location filename="../filelist.cc" line="343"/>
+ <location filename="../filelist.cc" line="183"/>
<source>m</source>
<translation>m</translation>
</message>
<message>
- <location filename="../filelist.cc" line="344"/>
+ <location filename="../filelist.cc" line="184"/>
<source>Name</source>
<translation>Navn</translation>
</message>
<message>
- <location filename="../filelist.cc" line="345"/>
+ <location filename="../filelist.cc" line="185"/>
<source>Kit Channel</source>
<translation>Trommesæt kanal</translation>
</message>
+ <message>
+ <location filename="../filelist.cc" line="186"/>
+ <source>p</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>FileList</name>
<message>
- <location filename="../filelist.cc" line="462"/>
+ <location filename="../filelist.cc" line="307"/>
<source>Open file</source>
<translation>Åbn fil</translation>
</message>
<message>
- <location filename="../filelist.cc" line="463"/>
+ <location filename="../filelist.cc" line="308"/>
<source>Audio Files (*.wav)</source>
<translation>Lyd filer (*.wav)</translation>
</message>
<message>
- <location filename="../filelist.cc" line="530"/>
+ <location filename="../filelist.cc" line="375"/>
<source>Set as Master (dbl-click)</source>
<translation>Vælg hovedkanal (dbl klik)</translation>
</message>
@@ -114,12 +134,12 @@
<translation type="vanished">Redigér navn</translation>
</message>
<message>
- <location filename="../filelist.cc" line="533"/>
+ <location filename="../filelist.cc" line="378"/>
<source>Remove</source>
<translation>Fjern</translation>
</message>
<message>
- <location filename="../filelist.cc" line="536"/>
+ <location filename="../filelist.cc" line="381"/>
<source>Remove all</source>
<translation>Fjern alle</translation>
</message>
@@ -140,108 +160,106 @@
<context>
<name>InstrumentWidget</name>
<message>
- <location filename="../instrumentwidget.cc" line="92"/>
+ <location filename="../instrumentwidget.cc" line="94"/>
<source>Tools</source>
<translation>Værktøjer</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="123"/>
+ <location filename="../instrumentwidget.cc" line="159"/>
<source>Play samples</source>
<translation>Afspil lydbidder</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="137"/>
+ <location filename="../instrumentwidget.cc" line="173"/>
<source>Process</source>
<translation>Processér</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="146"/>
+ <location filename="../instrumentwidget.cc" line="182"/>
<source>Files</source>
<translation>Filer</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="147"/>
- <location filename="../instrumentwidget.cc" line="272"/>
+ <location filename="../instrumentwidget.cc" line="183"/>
+ <location filename="../instrumentwidget.cc" line="313"/>
<source>Generate</source>
<translation>Generér</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="148"/>
+ <location filename="../instrumentwidget.cc" line="184"/>
<source>Edit</source>
<translation>Redigér</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="193"/>
+ <location filename="../instrumentwidget.cc" line="232"/>
<source>Files: (double-click to set as master)</source>
<translation>Filer: (dobbeltklik for at vælge som hovedkanal)</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="195"/>
+ <location filename="../instrumentwidget.cc" line="234"/>
<source>Add files...</source>
<translation>Tilføj filer...</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="284"/>
+ <location filename="../instrumentwidget.cc" line="320"/>
<source>Clear</source>
<translation>Ryd</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="293"/>
+ <location filename="../instrumentwidget.cc" line="329"/>
<source>Attack length:</source>
<translation>Attack længde:</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="302"/>
+ <location filename="../instrumentwidget.cc" line="338"/>
<source>Power spread:</source>
<translation>Energi spredning:</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="311"/>
+ <location filename="../instrumentwidget.cc" line="347"/>
<source>Minimum size (samples):</source>
<translation>Minimum størrelse (samples):</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="320"/>
+ <location filename="../instrumentwidget.cc" line="356"/>
<source>Falloff:</source>
<translation>Falloff:</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="329"/>
+ <location filename="../instrumentwidget.cc" line="365"/>
<source>Fadelength:</source>
<translation>Fadelængde:</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="359"/>
+ <location filename="../instrumentwidget.cc" line="395"/>
<source>Prefix:</source>
<translation>Præfix:</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="366"/>
<source>Export path:</source>
- <translation>Eksporteringssti:</translation>
+ <translation type="vanished">Eksporteringssti:</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="373"/>
<source>...</source>
- <translation>...</translation>
+ <translation type="vanished">...</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="380"/>
+ <location filename="../instrumentwidget.cc" line="185"/>
<source>Export</source>
<translation>Eksportér</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="475"/>
+ <location filename="../instrumentwidget.cc" line="511"/>
<source>Loading...</source>
<translation>Indlæser...</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="486"/>
+ <location filename="../instrumentwidget.cc" line="522"/>
<source>Ready</source>
<translation>Klar</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="495"/>
+ <location filename="../instrumentwidget.cc" line="628"/>
<source>Select export path</source>
<translation>Vælg eksporteringssti</translation>
</message>
@@ -507,6 +525,44 @@
</message>
</context>
<context>
+ <name>RangeEditor</name>
+ <message>
+ <location filename="../rangeeditor.cc" line="60"/>
+ <source>From:</source>
+ <translation type="unfinished">Fra:</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="61"/>
+ <source>To:</source>
+ <translation type="unfinished">Til:</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="62"/>
+ <source>FadeIn:</source>
+ <translation type="unfinished">FadeIn:</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="63"/>
+ <source>FadeOut:</source>
+ <translation type="unfinished">FadeOut:</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="64"/>
+ <source>Energy:</source>
+ <translation type="unfinished">Energi:</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="65"/>
+ <source>Position:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="66"/>
+ <source>Name:</source>
+ <translation type="unfinished">Navn:</translation>
+ </message>
+</context>
+<context>
<name>RenderDialog</name>
<message>
<location filename="../renderdialog.cc" line="280"/>
@@ -537,34 +593,28 @@
<context>
<name>SelectionEditor</name>
<message>
- <location filename="../selectioneditor.cc" line="60"/>
<source>From:</source>
- <translation>Fra:</translation>
+ <translation type="vanished">Fra:</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="61"/>
<source>To:</source>
- <translation>Til:</translation>
+ <translation type="vanished">Til:</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="62"/>
<source>FadeIn:</source>
- <translation>FadeIn:</translation>
+ <translation type="vanished">FadeIn:</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="63"/>
<source>FadeOut:</source>
- <translation>FadeOut:</translation>
+ <translation type="vanished">FadeOut:</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="64"/>
<source>Energy:</source>
- <translation>Energi:</translation>
+ <translation type="vanished">Energi:</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="65"/>
<source>Name:</source>
- <translation>Navn:</translation>
+ <translation type="vanished">Navn:</translation>
</message>
</context>
<context>
diff --git a/src/ts/dgedit_fr.ts b/src/ts/dgedit_fr.ts
index deb07bd..17fd995 100644
--- a/src/ts/dgedit_fr.ts
+++ b/src/ts/dgedit_fr.ts
@@ -23,17 +23,32 @@
</message>
</context>
<context>
+ <name>CanvasToolPosition</name>
+ <message>
+ <location filename="../canvastoolposition.h" line="47"/>
+ <source>Position</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CanvasToolRanges</name>
+ <message>
+ <location filename="../canvastoolranges.h" line="48"/>
+ <source>Ranges</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>CanvasToolSelections</name>
<message>
- <location filename="../canvastoolselections.h" line="45"/>
<source>Selections</source>
- <translation>Sélections</translation>
+ <translation type="vanished">Sélections</translation>
</message>
</context>
<context>
<name>CanvasToolThreshold</name>
<message>
- <location filename="../canvastoolthreshold.h" line="44"/>
+ <location filename="../canvastoolthreshold.h" line="43"/>
<source>Threshold</source>
<translation>Seuil de déclenchement</translation>
</message>
@@ -54,7 +69,7 @@
<context>
<name>ChannelMapDeligate</name>
<message>
- <location filename="../filelist.cc" line="104"/>
+ <location filename="../filelist.cc" line="481"/>
<source>&lt;None&gt;</source>
<translation>&lt;None&gt;</translation>
</message>
@@ -62,50 +77,55 @@
<context>
<name>FileDataModel</name>
<message>
- <location filename="../filelist.cc" line="309"/>
+ <location filename="../filelist.cc" line="147"/>
<source>&lt;None&gt;</source>
<translation>&lt;Aucun&gt;</translation>
</message>
<message>
- <location filename="../filelist.cc" line="341"/>
+ <location filename="../filelist.cc" line="181"/>
<source>M</source>
<translation>M</translation>
</message>
<message>
- <location filename="../filelist.cc" line="342"/>
+ <location filename="../filelist.cc" line="182"/>
<source>Filename</source>
<translation>Nom de fichier</translation>
</message>
<message>
- <location filename="../filelist.cc" line="343"/>
+ <location filename="../filelist.cc" line="183"/>
<source>m</source>
<translation>m</translation>
</message>
<message>
- <location filename="../filelist.cc" line="344"/>
+ <location filename="../filelist.cc" line="184"/>
<source>Name</source>
<translation>Nom</translation>
</message>
<message>
- <location filename="../filelist.cc" line="345"/>
+ <location filename="../filelist.cc" line="185"/>
<source>Kit Channel</source>
<translation>Canal de kit</translation>
</message>
+ <message>
+ <location filename="../filelist.cc" line="186"/>
+ <source>p</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>FileList</name>
<message>
- <location filename="../filelist.cc" line="462"/>
+ <location filename="../filelist.cc" line="307"/>
<source>Open file</source>
<translation>Ouvrir un fichier</translation>
</message>
<message>
- <location filename="../filelist.cc" line="463"/>
+ <location filename="../filelist.cc" line="308"/>
<source>Audio Files (*.wav)</source>
<translation>Fichiers audio (*.wav)</translation>
</message>
<message>
- <location filename="../filelist.cc" line="530"/>
+ <location filename="../filelist.cc" line="375"/>
<source>Set as Master (dbl-click)</source>
<translation>Paramétrer en tant que maître (dbl-clic)</translation>
</message>
@@ -114,12 +134,12 @@
<translation type="vanished">Éditer le nom</translation>
</message>
<message>
- <location filename="../filelist.cc" line="533"/>
+ <location filename="../filelist.cc" line="378"/>
<source>Remove</source>
<translation>Supprimer</translation>
</message>
<message>
- <location filename="../filelist.cc" line="536"/>
+ <location filename="../filelist.cc" line="381"/>
<source>Remove all</source>
<translation>Supprimer tout</translation>
</message>
@@ -140,108 +160,106 @@
<context>
<name>InstrumentWidget</name>
<message>
- <location filename="../instrumentwidget.cc" line="92"/>
+ <location filename="../instrumentwidget.cc" line="94"/>
<source>Tools</source>
<translation>Outils</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="123"/>
+ <location filename="../instrumentwidget.cc" line="159"/>
<source>Play samples</source>
<translation>Lire les échantillons</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="137"/>
+ <location filename="../instrumentwidget.cc" line="173"/>
<source>Process</source>
<translation>Traiter</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="146"/>
+ <location filename="../instrumentwidget.cc" line="182"/>
<source>Files</source>
<translation>Fichiers</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="147"/>
- <location filename="../instrumentwidget.cc" line="272"/>
+ <location filename="../instrumentwidget.cc" line="183"/>
+ <location filename="../instrumentwidget.cc" line="313"/>
<source>Generate</source>
<translation>Générer</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="148"/>
+ <location filename="../instrumentwidget.cc" line="184"/>
<source>Edit</source>
<translation>Éditer</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="193"/>
+ <location filename="../instrumentwidget.cc" line="232"/>
<source>Files: (double-click to set as master)</source>
<translation>Fichiers : (double-clic pour paramétrer en tant que maître)</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="195"/>
+ <location filename="../instrumentwidget.cc" line="234"/>
<source>Add files...</source>
<translation>Ajouter des fichiers...</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="284"/>
+ <location filename="../instrumentwidget.cc" line="320"/>
<source>Clear</source>
<translation>Vider</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="293"/>
+ <location filename="../instrumentwidget.cc" line="329"/>
<source>Attack length:</source>
<translation>Longueur d&apos;attaque :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="302"/>
+ <location filename="../instrumentwidget.cc" line="338"/>
<source>Power spread:</source>
<translation>Étalement de la puissance :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="311"/>
+ <location filename="../instrumentwidget.cc" line="347"/>
<source>Minimum size (samples):</source>
<translation>Taille minimum (échantillons) :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="320"/>
+ <location filename="../instrumentwidget.cc" line="356"/>
<source>Falloff:</source>
<translation>Temps de chute :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="329"/>
+ <location filename="../instrumentwidget.cc" line="365"/>
<source>Fadelength:</source>
<translation>Longueur de fondu :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="359"/>
+ <location filename="../instrumentwidget.cc" line="395"/>
<source>Prefix:</source>
<translation>Préfixe :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="366"/>
<source>Export path:</source>
- <translation>Chemin d&apos;exportation :</translation>
+ <translation type="vanished">Chemin d&apos;exportation :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="373"/>
<source>...</source>
- <translation>...</translation>
+ <translation type="vanished">...</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="380"/>
+ <location filename="../instrumentwidget.cc" line="185"/>
<source>Export</source>
<translation>Exporter</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="475"/>
+ <location filename="../instrumentwidget.cc" line="511"/>
<source>Loading...</source>
<translation>Chargement...</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="486"/>
+ <location filename="../instrumentwidget.cc" line="522"/>
<source>Ready</source>
<translation>Prêt</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="495"/>
+ <location filename="../instrumentwidget.cc" line="628"/>
<source>Select export path</source>
<translation>Sélectionner le chemin d&apos;exportation</translation>
</message>
@@ -507,6 +525,44 @@
</message>
</context>
<context>
+ <name>RangeEditor</name>
+ <message>
+ <location filename="../rangeeditor.cc" line="60"/>
+ <source>From:</source>
+ <translation type="unfinished">Depuis :</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="61"/>
+ <source>To:</source>
+ <translation type="unfinished">Jusqu&apos;à :</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="62"/>
+ <source>FadeIn:</source>
+ <translation type="unfinished">Fondu ouverture :</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="63"/>
+ <source>FadeOut:</source>
+ <translation type="unfinished">Fondu fermeture :</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="64"/>
+ <source>Energy:</source>
+ <translation type="unfinished">Énergie :</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="65"/>
+ <source>Position:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="66"/>
+ <source>Name:</source>
+ <translation type="unfinished">Nom :</translation>
+ </message>
+</context>
+<context>
<name>RenderDialog</name>
<message>
<location filename="../renderdialog.cc" line="280"/>
@@ -537,34 +593,28 @@
<context>
<name>SelectionEditor</name>
<message>
- <location filename="../selectioneditor.cc" line="60"/>
<source>From:</source>
- <translation>Depuis :</translation>
+ <translation type="vanished">Depuis :</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="61"/>
<source>To:</source>
- <translation>Jusqu&apos;à :</translation>
+ <translation type="vanished">Jusqu&apos;à :</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="62"/>
<source>FadeIn:</source>
- <translation>Fondu ouverture :</translation>
+ <translation type="vanished">Fondu ouverture :</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="63"/>
<source>FadeOut:</source>
- <translation>Fondu fermeture :</translation>
+ <translation type="vanished">Fondu fermeture :</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="64"/>
<source>Energy:</source>
- <translation>Énergie :</translation>
+ <translation type="vanished">Énergie :</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="65"/>
<source>Name:</source>
- <translation>Nom :</translation>
+ <translation type="vanished">Nom :</translation>
</message>
</context>
<context>
@@ -581,4 +631,3 @@
</message>
</context>
</TS>
-