Skip to content

Commit

Permalink
sample editor: instant audiovisual feedback
Browse files Browse the repository at this point in the history
Should close #811 and #1304
  • Loading branch information
charbeljc committed Jul 15, 2021
1 parent f2175f3 commit 0ea0925
Show file tree
Hide file tree
Showing 7 changed files with 453 additions and 362 deletions.
6 changes: 3 additions & 3 deletions src/core/Basics/Sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace H2Core
{

const char* Sample::__class_name = "Sample";
const char* EnvelopePoint::__class_name = "EnvolopePoint";
const char* EnvelopePoint::__class_name = "EnvelopePoint";

const std::vector<QString> Sample::__loop_modes = { "forward", "reverse", "pingpong" };

Expand All @@ -51,11 +51,11 @@ static RubberBand::RubberBandStretcher::Options compute_rubberband_options( cons


/* EnvelopePoint */
EnvelopePoint::EnvelopePoint() : Object( EnvelopePoint::__class_name ), frame( 0 ), value( 0 )
EnvelopePoint::EnvelopePoint() : Object( EnvelopePoint::__class_name ), frame( 0 ), value( 0 )
{
}

EnvelopePoint::EnvelopePoint( int f, int v ) : Object( EnvelopePoint::__class_name ), frame( f ), value( v )
EnvelopePoint::EnvelopePoint( int f, int v ) : Object ( EnvelopePoint::__class_name), frame( f ), value( v )
{
}

Expand Down
183 changes: 92 additions & 91 deletions src/gui/src/SampleEditor/MainSampleWaveDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,8 @@ MainSampleWaveDisplay::MainSampleWaveDisplay(QWidget* pParent)
m_bUpdatePosition = false;
m_nSampleLength = 0;

m_bStartSliderIsMoved = false;
m_bLoopSliderIsMoved = false;
m_bEndSliderIsmoved = false;

m_SelectedSlider = NONE;
m_SelectedSlider = SampleEditor::Slider::NoSlider;
m_pEditedSample = nullptr;
setMouseTracking(true);
}

Expand All @@ -89,14 +86,14 @@ void MainSampleWaveDisplay::paintLocatorEvent( int pos, bool updateposi)
update();
}

static void set_paint_color(QPainter & painter, const QColor & color, bool selected, MainSampleWaveDisplay::Slider which)
static void set_paint_color(QPainter & painter, const QColor & color, bool selected, SampleEditor::Slider which)
{
if (!selected) {
painter.setPen( color );
} else {
QColor highlight = QColor(std::min(255, color.red() + 20 + 20 * (which == MainSampleWaveDisplay::END)),
std::min(255, color.green() + 20 + 20 * (which == MainSampleWaveDisplay::START)),
std::min(255, color.blue() + 20 + 20 * (which == MainSampleWaveDisplay::LOOP)));
QColor highlight = QColor(std::min(255, color.red() + 20 + 20 * (which == SampleEditor::EndSlider)),
std::min(255, color.green() + 20 + 20 * (which == SampleEditor::StartSlider)),
std::min(255, color.blue() + 20 + 20 * (which == SampleEditor::LoopSlider)));

painter.setPen ( highlight );
}
Expand All @@ -119,13 +116,13 @@ void MainSampleWaveDisplay::paintEvent(QPaintEvent *ev)
for ( int x = 25; x < width() -25; x++ ) {
if ( !issmaller || x <= m_nSampleLength){
painter.drawLine( x, -m_pPeakDatal[x -25] +VCenterl, x, -m_pPeakDatal[x -24] +VCenterl );
painter.drawLine( x, -m_pPeakDatar[x -25] +VCenterr, x, -m_pPeakDatar[x -24] +VCenterr );
painter.drawLine( x, -m_pPeakDatar[x -25] +VCenterr, x, -m_pPeakDatar[x -24] +VCenterr );
}else
{
painter.drawLine( x, 0 +VCenterl, x, 0 +VCenterl );
painter.drawLine( x, 0 +VCenterr, x, 0 +VCenterr );
}

}


Expand All @@ -147,15 +144,15 @@ void MainSampleWaveDisplay::paintEvent(QPaintEvent *ev)
font.setWeight( 63 );
painter.setFont( font );
//start frame pointer
set_paint_color(painter, startColor, m_SelectedSlider == START, m_SelectedSlider);
painter.drawLine( m_nStartFramePosition, 4, m_nStartFramePosition, height() -4 );
set_paint_color(painter, startColor, m_SelectedSlider == SampleEditor::Slider::StartSlider, m_SelectedSlider);
painter.drawLine( m_nStartFramePosition, 4, m_nStartFramePosition, height() -4 );
painter.drawText( m_nStartFramePosition -10, 250, 10,20, Qt::AlignRight, "S" );
//endframe pointer
set_paint_color(painter, endColor, m_SelectedSlider == END, m_SelectedSlider);
set_paint_color(painter, endColor, m_SelectedSlider == SampleEditor::Slider::EndSlider, m_SelectedSlider);
painter.drawLine( m_nEndFramePosition, 4, m_nEndFramePosition, height() -4 );
painter.drawText( m_nEndFramePosition -10, 123, 10, 20, Qt::AlignRight, "E" );
//loopframe pointer
set_paint_color(painter, loopColor, m_SelectedSlider == LOOP, m_SelectedSlider);
set_paint_color(painter, loopColor, m_SelectedSlider == SampleEditor::Slider::LoopSlider, m_SelectedSlider);
painter.drawLine( m_nLoopFramePosition, 4, m_nLoopFramePosition, height() -4 );
painter.drawText( m_nLoopFramePosition , 0, 10, 20, Qt::AlignLeft, "L" );

Expand All @@ -171,78 +168,76 @@ void MainSampleWaveDisplay::updateDisplayPointer()



void MainSampleWaveDisplay::updateDisplay( const QString& filename )
std::shared_ptr<H2Core::Sample> MainSampleWaveDisplay::loadSampleAndUpdateDisplay( const QString& filename )
{

auto pNewSample = Sample::load( filename );

if ( pNewSample ) {

int nSampleLength = pNewSample->get_frames();
m_nSampleLength = nSampleLength;
float nScaleFactor = nSampleLength / (width() -50);
if ( nScaleFactor < 1 ){
nScaleFactor = 1;
}
if ( ! pNewSample ) {
update();
return nullptr;
}
m_pEditedSample = pNewSample;
int nSampleLength = pNewSample->get_frames();
m_nSampleLength = nSampleLength;
float nScaleFactor = nSampleLength / (width() -50);
if ( nScaleFactor < 1 ){
nScaleFactor = 1;
}

float fGain = height() / 4.0 * 1.0;

auto pSampleDatal = pNewSample->get_data_l();
auto pSampleDatar = pNewSample->get_data_r();

unsigned nSamplePos = 0;
int nVall = 0;
int nValr = 0;
int newVall = 0;
int newValr = 0;
for ( int i = 0; i < width(); ++i ){
for ( int j = 0; j < nScaleFactor; ++j ) {
if ( j < nSampleLength && nSamplePos < nSampleLength) {
if ( pSampleDatal[ nSamplePos ] && pSampleDatar[ nSamplePos ] ){
newVall = static_cast<int>( pSampleDatal[ nSamplePos ] * fGain );
newValr = static_cast<int>( pSampleDatar[ nSamplePos ] * fGain );
nVall = newVall;
nValr = newValr;
}else
{
nVall = 0;
nValr = 0;
}
float fGain = height() / 4.0 * 1.0;

auto pSampleDatal = pNewSample->get_data_l();
auto pSampleDatar = pNewSample->get_data_r();

unsigned nSamplePos = 0;
int nVall = 0;
int nValr = 0;
int newVall = 0;
int newValr = 0;
for ( int i = 0; i < width(); ++i ){
for ( int j = 0; j < nScaleFactor; ++j ) {
if ( j < nSampleLength && nSamplePos < nSampleLength) {
if ( pSampleDatal[ nSamplePos ] && pSampleDatar[ nSamplePos ] ){
newVall = static_cast<int>( pSampleDatal[ nSamplePos ] * fGain );
newValr = static_cast<int>( pSampleDatar[ nSamplePos ] * fGain );
nVall = newVall;
nValr = newValr;
}else
{
nVall = 0;
nValr = 0;
}
++nSamplePos;
}
m_pPeakDatal[ i ] = nVall;
m_pPeakDatar[ i ] = nValr;
++nSamplePos;
}
m_pPeakDatal[ i ] = nVall;
m_pPeakDatar[ i ] = nValr;
}
update();

}
void MainSampleWaveDisplay::mouseUpdateDone() {
HydrogenApp::get_instance()->getSampleEditor()->returnAllMainWaveDisplayValues();
m_bStartSliderIsMoved = false;
m_bLoopSliderIsMoved = false;
m_bEndSliderIsmoved = false;
return pNewSample;
}


void MainSampleWaveDisplay::mouseMoveEvent(QMouseEvent *ev)
{
if (ev->buttons() && Qt::LeftButton) {
testPosition( ev );
if ( ev->buttons() && Qt::LeftButton ) {
if ( m_SelectedSlider != SampleEditor::Slider::NoSlider ) {
testPosition( ev );
emit sliderEdited( m_SelectedSlider );
}
} else {
chooseSlider( ev );
}
update();
mouseUpdateDone();
}

void MainSampleWaveDisplay::mousePressEvent(QMouseEvent *ev)
{
chooseSlider( ev );
testPosition( ev );
if ( m_SelectedSlider != SampleEditor::Slider::NoSlider ) {
testPosition( ev );
emit sliderEdited( m_SelectedSlider );
}
update();
mouseUpdateDone();
}

void MainSampleWaveDisplay::testPosition( QMouseEvent *ev )
Expand All @@ -251,69 +246,75 @@ void MainSampleWaveDisplay::testPosition( QMouseEvent *ev )
//startframepointer
int x = std::min(width() - 25, std::max(25, ev->x()));

if ( m_SelectedSlider == START ) {
if ( m_SelectedSlider == SampleEditor::Slider::StartSlider ) {
m_nStartFramePosition = x;
m_bStartSliderIsMoved = true;
if ( m_nStartFramePosition > m_nLoopFramePosition ){
m_nLoopFramePosition = m_nStartFramePosition;
m_bLoopSliderIsMoved = true;
}
if ( m_nStartFramePosition > m_nEndFramePosition ){
m_nEndFramePosition = m_nStartFramePosition;
m_bEndSliderIsmoved = true;
}
}

//loopframeposition
else if ( m_SelectedSlider == LOOP ) {
else if ( m_SelectedSlider == SampleEditor::Slider::LoopSlider ) {
if (x >= m_nStartFramePosition && x <= m_nEndFramePosition ) {
m_nLoopFramePosition = x ;
m_bLoopSliderIsMoved = true;
}
}
//endframeposition
else if ( m_SelectedSlider == END) {
else if ( m_SelectedSlider == SampleEditor::Slider::EndSlider) {
if (x >= m_nStartFramePosition) {
m_nEndFramePosition = x ;
m_bEndSliderIsmoved = true;
}
if ( m_nEndFramePosition < m_nLoopFramePosition ){
m_nLoopFramePosition = m_nEndFramePosition;
m_bLoopSliderIsMoved = true;
}
}
}


void MainSampleWaveDisplay::mouseReleaseEvent(QMouseEvent *ev)
{
m_SelectedSlider = NONE;
if ( m_SelectedSlider != SampleEditor::Slider::NoSlider ) {
emit doneEditingSlider( m_SelectedSlider );
}
m_SelectedSlider = SampleEditor::Slider::NoSlider;
update();
mouseUpdateDone();
}




void MainSampleWaveDisplay::chooseSlider(QMouseEvent * ev)
{
assert(ev);

QPoint start = QPoint(m_nStartFramePosition, height());
QPoint end = QPoint(m_nEndFramePosition, height() / 2);
QPoint loop = QPoint(m_nLoopFramePosition, 0);

int ds = (ev->pos() - start).manhattanLength();
int de = (ev->pos() - end).manhattanLength();
int dl = (ev->pos() - loop).manhattanLength();
m_SelectedSlider = NONE;

if (ds <= de && ds <= dl) {
m_SelectedSlider = START;
} else if (de < ds && de <= dl) {
m_SelectedSlider = END;
int ds = std::abs(ev->x() - m_nStartFramePosition);
int de = std::abs(ev->x() - m_nEndFramePosition);
int dl = std::abs(ev->x() - m_nLoopFramePosition);

if (ds < de && ds < dl) {
m_SelectedSlider = SampleEditor::Slider::StartSlider;
} else if (de < ds && de < dl) {
m_SelectedSlider = SampleEditor::Slider::EndSlider;
} else if (dl < ds && dl < de) {
m_SelectedSlider = LOOP;
m_SelectedSlider = SampleEditor::Slider::LoopSlider;
} else {
QPoint start = QPoint(m_nStartFramePosition, height());
QPoint end = QPoint(m_nEndFramePosition, height() / 2);
QPoint loop = QPoint(m_nLoopFramePosition, 0);

ds = (ev->pos() - start).manhattanLength();
de = (ev->pos() - end).manhattanLength();
dl = (ev->pos() - loop).manhattanLength();
if (ds <= de && ds <= dl) {
m_SelectedSlider = SampleEditor::Slider::StartSlider;
} else if (de < ds && de <= dl) {
m_SelectedSlider = SampleEditor::Slider::EndSlider;
} else if (dl < ds && dl < de) {
m_SelectedSlider = SampleEditor::Slider::LoopSlider;
} else {
m_SelectedSlider = SampleEditor::Slider::NoSlider; // should never occur
}
}
}

30 changes: 12 additions & 18 deletions src/gui/src/SampleEditor/MainSampleWaveDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,43 +28,36 @@

#include <core/Object.h>
#include "SampleEditor.h"
class SampleEditor;

class MainSampleWaveDisplay : public QWidget, public H2Core::Object
{
H2_OBJECT
Q_OBJECT

public:

enum Slider {
NONE,
START,
LOOP,
END
};

explicit MainSampleWaveDisplay(QWidget* pParent);
~MainSampleWaveDisplay();

void updateDisplay( const QString& filename );
std::shared_ptr<H2Core::Sample> loadSampleAndUpdateDisplay( const QString& filename );
void updateDisplayPointer();

void paintLocatorEvent( int pos, bool last_event);
void paintEvent(QPaintEvent *ev);

void testPositionFromSampleeditor();

int m_nStartFramePosition;
int m_nLoopFramePosition;
int m_nEndFramePosition;

bool m_bStartSliderIsMoved;
bool m_bLoopSliderIsMoved;
bool m_bEndSliderIsmoved;

Slider m_SelectedSlider;
SampleEditor::Slider m_SelectedSlider;

std::shared_ptr<H2Core::Sample> getEditedSample() { return m_pEditedSample; }

signals:
void doneEditingSlider ( SampleEditor::Slider slider );
void sliderEdited ( SampleEditor::Slider slider );

private:
virtual void mouseMoveEvent(QMouseEvent *ev);
Expand All @@ -73,11 +66,12 @@ class MainSampleWaveDisplay : public QWidget, public H2Core::Object
void testPosition( QMouseEvent *ev );
void chooseSlider( QMouseEvent *ev );
void mouseUpdateDone();


std::shared_ptr<H2Core::Sample> m_pEditedSample;
QPixmap m_background;
int* m_pPeakDatal;
int* m_pPeakDatar;

int m_nSampleLength;
int m_nLocator;
bool m_bUpdatePosition;
Expand Down
Loading

0 comments on commit 0ea0925

Please sign in to comment.