summaryrefslogtreecommitdiff
path: root/src/samplesorter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/samplesorter.cc')
-rw-r--r--src/samplesorter.cc205
1 files changed, 172 insertions, 33 deletions
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());
}
}