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());  	}  }  | 
