diff options
Diffstat (limited to 'src/samplesorter.cc')
-rw-r--r-- | src/samplesorter.cc | 205 |
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()); } } |