Skip to content

Commit

Permalink
rework envelope, make envelope points lightweight
Browse files Browse the repository at this point in the history
  • Loading branch information
charbeljc committed Jul 6, 2021
1 parent 3b5f750 commit b3160e9
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 67 deletions.
39 changes: 19 additions & 20 deletions src/core/Basics/Sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ namespace H2Core
{

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

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

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


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

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

EnvelopePoint::EnvelopePoint( EnvelopePoint* other ) : Object( EnvelopePoint::__class_name )
EnvelopePoint::EnvelopePoint( const EnvelopePoint& other )
{
frame = other->frame;
value = other->value;
frame = other.frame;
value = other.value;
}
/* EnvelopePoint */

Expand Down Expand Up @@ -101,12 +100,12 @@ Sample::Sample( std::shared_ptr<Sample> pOther ): Object( __class_name ),

PanEnvelope* pPan = pOther->get_pan_envelope();
for( int i=0; i<pPan->size(); i++ ) {
__pan_envelope.push_back( std::make_unique<EnvelopePoint>( pPan->at(i).get() ) );
__pan_envelope.push_back( pPan->at(i) );
}

PanEnvelope* pVelocity = pOther->get_velocity_envelope();
for( int i=0; i<pVelocity->size(); i++ ) {
__velocity_envelope.push_back( std::make_unique<EnvelopePoint>( pVelocity->at(i).get() ) );
__velocity_envelope.push_back( pVelocity->at(i) );
}
}

Expand Down Expand Up @@ -355,10 +354,10 @@ void Sample::apply_velocity( const VelocityEnvelope& v )
if ( v.size() > 0 ) {
float inv_resolution = __frames / 841.0F;
for ( int i = 1; i < v.size(); i++ ) {
float y = ( 91 - v[i - 1]->value ) / 91.0F;
float k = ( 91 - v[i]->value ) / 91.0F;
int start_frame = v[i - 1]->frame * inv_resolution;
int end_frame = v[i]->frame * inv_resolution;
float y = ( 91 - v[i - 1].value ) / 91.0F;
float k = ( 91 - v[i].value ) / 91.0F;
int start_frame = v[i - 1].frame * inv_resolution;
int end_frame = v[i].frame * inv_resolution;
if ( i == v.size() -1 ) {
end_frame = __frames;
}
Expand All @@ -371,8 +370,8 @@ void Sample::apply_velocity( const VelocityEnvelope& v )
}
}

for(auto& pEnvPtr : v){
__velocity_envelope.emplace_back( std::make_unique<EnvelopePoint>( pEnvPtr.get() ) );
for(auto& pEnvPt : v){
__velocity_envelope.emplace_back( pEnvPt );
}
}
__is_modified = true;
Expand All @@ -390,10 +389,10 @@ void Sample::apply_pan( const PanEnvelope& p )
if ( p.size() > 0 ) {
float inv_resolution = __frames / 841.0F;
for ( int i = 1; i < p.size(); i++ ) {
float y = ( 45 - p[i - 1]->value ) / 45.0F;
float k = ( 45 - p[i]->value ) / 45.0F;
int start_frame = p[i - 1]->frame * inv_resolution;
int end_frame = p[i]->frame * inv_resolution;
float y = ( 45 - p[i - 1].value ) / 45.0F;
float k = ( 45 - p[i].value ) / 45.0F;
int start_frame = p[i - 1].frame * inv_resolution;
int end_frame = p[i].frame * inv_resolution;
if ( i == p.size() -1 ) {
end_frame = __frames;
}
Expand All @@ -417,8 +416,8 @@ void Sample::apply_pan( const PanEnvelope& p )
}
}

for(auto& pEnvPtr : p){
__pan_envelope.emplace_back( std::make_unique<EnvelopePoint>( pEnvPtr.get() ) );
for(auto& pEnvPt : p){
__pan_envelope.emplace_back( pEnvPt );
}
}
__is_modified = true;
Expand Down
13 changes: 6 additions & 7 deletions src/core/Basics/Sample.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,16 @@ namespace H2Core
*/

/** an envelope point within a frame */
class EnvelopePoint : public H2Core::Object
class EnvelopePoint
{
H2_OBJECT
public:
int frame; ///< frame index
int value; ///< value
/** to be able to sort velocity points vectors */
struct Comparator {
bool operator()( std::unique_ptr<EnvelopePoint>& a, std::unique_ptr<EnvelopePoint>& b )
bool operator()( const EnvelopePoint& a, const EnvelopePoint& b )
{
return a->frame < b->frame;
return a.frame < b.frame;
}
};
/** default constructor */
Expand All @@ -59,7 +58,7 @@ class EnvelopePoint : public H2Core::Object
*/
EnvelopePoint( int f, int v );
/** copy constructor */
EnvelopePoint( EnvelopePoint* other );
EnvelopePoint( const EnvelopePoint& other );
};

class Sample : public H2Core::Object
Expand All @@ -68,9 +67,9 @@ class Sample : public H2Core::Object
public:

/** define the type used to store pan envelope points */
using PanEnvelope = std::vector<std::unique_ptr<EnvelopePoint>>;
using PanEnvelope = std::vector<EnvelopePoint>;
/** define the type used to store velocity envelope points */
using VelocityEnvelope = std::vector<std::unique_ptr<EnvelopePoint>>;
using VelocityEnvelope = std::vector<EnvelopePoint>;
/** set of loop configuration flags */
class Loops
{
Expand Down
30 changes: 14 additions & 16 deletions src/core/Basics/Song.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1132,26 +1132,25 @@ Song* SongReader::readSong( const QString& sFileName )
if ( !sIsModified ) {
pSample = Sample::load( sFilename );
} else {
// FIXME, kill EnvelopePoint, create Envelope class
EnvelopePoint pt;
int Frame = 0;
int Value = 0;

Sample::VelocityEnvelope velocity;
QDomNode volumeNode = layerNode.firstChildElement( "volume" );
while ( ! volumeNode.isNull() ) {
Frame = LocalFileMng::readXmlInt( volumeNode, "volume-position", 0 );
Value = LocalFileMng::readXmlInt( volumeNode, "volume-value", 0 );
velocity.push_back( std::make_unique<EnvelopePoint>(Frame, Value) );
pt.frame = LocalFileMng::readXmlInt( volumeNode, "volume-position", 0 );
pt.value = LocalFileMng::readXmlInt( volumeNode, "volume-value", 0 );
velocity.push_back( pt );
volumeNode = volumeNode.nextSiblingElement( "volume" );
//ERRORLOG( QString("volume-posi %1").arg(LocalFileMng::readXmlInt( volumeNode, "volume-position", 0)) );
}

Sample::VelocityEnvelope pan;
QDomNode panNode = layerNode.firstChildElement( "pan" );
while ( ! panNode.isNull() ) {
Frame = LocalFileMng::readXmlInt( panNode, "pan-position", 0 );
Value = LocalFileMng::readXmlInt( panNode, "pan-value", 0 );
pan.push_back( std::make_unique<EnvelopePoint>(Frame, Value) );
pt.frame = LocalFileMng::readXmlInt( panNode, "pan-position", 0 );
pt.value = LocalFileMng::readXmlInt( panNode, "pan-value", 0 );
pan.push_back( pt );
panNode = panNode.nextSiblingElement( "pan" );
}

Expand Down Expand Up @@ -1221,25 +1220,24 @@ Song* SongReader::readSong( const QString& sFileName )
if ( !sIsModified ) {
pSample = Sample::load( sFilename );
} else {
int Frame = 0;
int Value = 0;
EnvelopePoint pt;

Sample::VelocityEnvelope velocity;
QDomNode volumeNode = layerNode.firstChildElement( "volume" );
while ( ! volumeNode.isNull() ) {
Frame = LocalFileMng::readXmlInt( volumeNode, "volume-position", 0 );
Value = LocalFileMng::readXmlInt( volumeNode, "volume-value", 0 );
velocity.push_back( std::make_unique<EnvelopePoint>(Frame, Value) );
pt.frame = LocalFileMng::readXmlInt( volumeNode, "volume-position", 0 );
pt.value = LocalFileMng::readXmlInt( volumeNode, "volume-value", 0 );
velocity.push_back( pt );
volumeNode = volumeNode.nextSiblingElement( "volume" );
//ERRORLOG( QString("volume-posi %1").arg(LocalFileMng::readXmlInt( volumeNode, "volume-position", 0)) );
}

Sample::VelocityEnvelope pan;
QDomNode panNode = layerNode.firstChildElement( "pan" );
while ( ! panNode.isNull() ) {
Frame = LocalFileMng::readXmlInt( panNode, "pan-position", 0 );
Value = LocalFileMng::readXmlInt( panNode, "pan-value", 0 );
pan.push_back( std::make_unique<EnvelopePoint>(Frame, Value) );
pt.frame = LocalFileMng::readXmlInt( panNode, "pan-position", 0 );
pt.value = LocalFileMng::readXmlInt( panNode, "pan-value", 0 );
pan.push_back( pt );
panNode = panNode.nextSiblingElement( "pan" );
}

Expand Down
8 changes: 4 additions & 4 deletions src/core/LocalFileMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,16 +599,16 @@ int SongWriter::writeSong( Song * pSong, const QString& filename )
Sample::VelocityEnvelope* velocity = pSample->get_velocity_envelope();
for (int y = 0; y < velocity->size(); y++){
QDomNode volumeNode = doc.createElement( "volume" );
LocalFileMng::writeXmlString( volumeNode, "volume-position", QString("%1").arg( velocity->at(y)->frame ) );
LocalFileMng::writeXmlString( volumeNode, "volume-value", QString("%1").arg( velocity->at(y)->value ) );
LocalFileMng::writeXmlString( volumeNode, "volume-position", QString("%1").arg( velocity->at(y).frame ) );
LocalFileMng::writeXmlString( volumeNode, "volume-value", QString("%1").arg( velocity->at(y).value ) );
layerNode.appendChild( volumeNode );
}

Sample::PanEnvelope* pan = pSample->get_pan_envelope();
for (int y = 0; y < pan->size(); y++){
QDomNode panNode = doc.createElement( "pan" );
LocalFileMng::writeXmlString( panNode, "pan-position", QString("%1").arg( pan->at(y)->frame ) );
LocalFileMng::writeXmlString( panNode, "pan-value", QString("%1").arg( pan->at(y)->value ) );
LocalFileMng::writeXmlString( panNode, "pan-position", QString("%1").arg( pan->at(y).frame ) );
LocalFileMng::writeXmlString( panNode, "pan-value", QString("%1").arg( pan->at(y).value ) );
layerNode.appendChild( panNode );
}

Expand Down
16 changes: 8 additions & 8 deletions src/gui/src/SampleEditor/SampleEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,23 +208,23 @@ void SampleEditor::getAllFrameInfos()

if ( pSample->get_velocity_envelope()->size()==0 ) {
m_pTargetSampleView->get_velocity()->clear();
m_pTargetSampleView->get_velocity()->push_back( std::make_unique<EnvelopePoint>( 0, 0 ) );
m_pTargetSampleView->get_velocity()->push_back( std::make_unique<EnvelopePoint>( m_pTargetSampleView->width(), 0 ) );
m_pTargetSampleView->get_velocity()->push_back( EnvelopePoint( 0, 0 ) );
m_pTargetSampleView->get_velocity()->push_back( EnvelopePoint( m_pTargetSampleView->width(), 0 ) );
} else {
m_pTargetSampleView->get_velocity()->clear();

for(auto& pEnvPtr : *pSample->get_velocity_envelope() ){
m_pTargetSampleView->get_velocity()->emplace_back( std::make_unique<EnvelopePoint>( pEnvPtr.get() ) );
for(auto& pt : *pSample->get_velocity_envelope() ){
m_pTargetSampleView->get_velocity()->emplace_back( pt );
}
}

if ( pSample->get_pan_envelope()->size()==0 ) {
m_pTargetSampleView->get_pan()->clear();
m_pTargetSampleView->get_pan()->push_back( std::make_unique<EnvelopePoint>( 0, m_pTargetSampleView->height()/2 ) );
m_pTargetSampleView->get_pan()->push_back( std::make_unique<EnvelopePoint>( m_pTargetSampleView->width(), m_pTargetSampleView->height()/2 ) );
m_pTargetSampleView->get_pan()->push_back( EnvelopePoint( 0, m_pTargetSampleView->height()/2 ) );
m_pTargetSampleView->get_pan()->push_back( EnvelopePoint( m_pTargetSampleView->width(), m_pTargetSampleView->height()/2 ) );
} else {
for(auto& pEnvPtr : *pSample->get_pan_envelope() ){
m_pTargetSampleView->get_pan()->emplace_back( std::make_unique<EnvelopePoint>( pEnvPtr.get() ) );
for(auto& pt : *pSample->get_pan_envelope() ){
m_pTargetSampleView->get_pan()->emplace_back( pt );
}
}

Expand Down
24 changes: 12 additions & 12 deletions src/gui/src/SampleEditor/TargetWaveDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,25 +91,25 @@ static void paintEnvelope(Sample::VelocityEnvelope &envelope, QPainter &painter,
return;
for ( int i = 0; i < static_cast<int>(envelope.size()) -1; i++){
painter.setPen( QPen(lineColor, 1 , Qt::SolidLine) );
painter.drawLine( envelope[i]->frame, envelope[i]->value, envelope[i + 1]->frame, envelope[i +1]->value );
painter.drawLine( envelope[i].frame, envelope[i].value, envelope[i + 1].frame, envelope[i +1].value );
if ( i == selected )
painter.setBrush( selectedColor );
else
painter.setBrush( handleColor );
painter.drawEllipse ( envelope[i]->frame - 6/2, envelope[i]->value - 6/2, 6, 6 );
painter.drawEllipse ( envelope[i].frame - 6/2, envelope[i].value - 6/2, 6, 6 );
}
// draw first and last points as squares
if ( 0 == selected )
painter.setBrush( selectedColor );
else
painter.setBrush( handleColor );
painter.drawRect ( envelope[0]->frame - 12/2, envelope[0]->value - 6/2, 12, 6 );
painter.drawRect ( envelope[0].frame - 12/2, envelope[0].value - 6/2, 12, 6 );

if ( envelope.size() - 1 == selected )
painter.setBrush( selectedColor );
else
painter.setBrush( handleColor );
painter.drawRect ( envelope[envelope.size() -1]->frame - 12/2, envelope[envelope.size() -1]->value - 6/2, 12, 6 );
painter.drawRect ( envelope[envelope.size() -1].frame - 12/2, envelope[envelope.size() -1].value - 6/2, 12, 6 );
}

void TargetWaveDisplay::paintEvent(QPaintEvent *ev)
Expand Down Expand Up @@ -262,8 +262,8 @@ void TargetWaveDisplay::updateMouseSelection(QMouseEvent *ev)
int selection = -1;
int min_distance = 1000000;
for ( int i = 0; i < static_cast<int>(envelope.size()); i++){
if ( envelope[i]->frame >= m_nX - m_nSnapRadius && envelope[i]->frame <= m_nX + m_nSnapRadius ) {
QPoint envelopePoint(envelope[i]->frame, envelope[i]->value);
if ( envelope[i].frame >= m_nX - m_nSnapRadius && envelope[i].frame <= m_nX + m_nSnapRadius ) {
QPoint envelopePoint(envelope[i].frame, envelope[i].value);
int delta = (mousePoint - envelopePoint).manhattanLength();
if (delta < min_distance) {
min_distance = delta;
Expand All @@ -276,7 +276,7 @@ void TargetWaveDisplay::updateMouseSelection(QMouseEvent *ev)
if (m_nSelectedEnvelopePoint == -1)
m_sInfo = "";
else {
float info = (UI_HEIGHT - envelope[m_nSelectedEnvelopePoint]->value) / (float)UI_HEIGHT;
float info = (UI_HEIGHT - envelope[m_nSelectedEnvelopePoint].value) / (float)UI_HEIGHT;
m_sInfo.setNum( info, 'g', 2 );
}
}
Expand All @@ -294,10 +294,10 @@ void TargetWaveDisplay::updateEnvelope()
} else if ( m_nSelectedEnvelopePoint == static_cast<int>(envelope.size()) ) {
m_nX = UI_WIDTH;
}
envelope.push_back( std::make_unique<EnvelopePoint>( m_nX, m_nY ) );
envelope.push_back( EnvelopePoint( m_nX, m_nY ) );
sort( envelope.begin(), envelope.end(), EnvelopePoint::Comparator() );
for (int i = 0; i < envelope.size() - 1; ++i) {
if (envelope[i]->frame == envelope[i+1]->frame) {
if (envelope[i].frame == envelope[i+1].frame) {
envelope.erase( envelope.begin() + i);
if (i + 1 == m_nSelectedEnvelopePoint) {
m_nSelectedEnvelopePoint = i;
Expand Down Expand Up @@ -340,10 +340,10 @@ void TargetWaveDisplay::mousePressEvent(QMouseEvent *ev)

if (NewPoint){
if (envelope.empty()) {
envelope.push_back( std::make_unique<EnvelopePoint>(0, m_nY) );
envelope.push_back( std::make_unique<EnvelopePoint>(UI_WIDTH, m_nY));
envelope.push_back( EnvelopePoint( 0, m_nY ) );
envelope.push_back( EnvelopePoint( UI_WIDTH, m_nY ) );
} else {
envelope.push_back( std::make_unique<EnvelopePoint>( m_nX, m_nY ) );
envelope.push_back( EnvelopePoint( m_nX, m_nY ) );
}
sort( envelope.begin(), envelope.end(), EnvelopePoint::Comparator() );
} else {
Expand Down

0 comments on commit b3160e9

Please sign in to comment.