From 27b1ce914b40bea0bfa4b9ac857ffe2a92fb4407 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> Date: Wed, 22 Apr 2020 10:35:00 +0200 Subject: [PATCH 1/9] Remove plugins/LadspaEffect/swh/ladspa-util.c (#5451) This file contains no used code and it caused build problems, so we remove it. Thanks to @plater for the issue report. --- plugins/LadspaEffect/swh/ladspa-util.c | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 plugins/LadspaEffect/swh/ladspa-util.c diff --git a/plugins/LadspaEffect/swh/ladspa-util.c b/plugins/LadspaEffect/swh/ladspa-util.c deleted file mode 100644 index 431ba955e..000000000 --- a/plugins/LadspaEffect/swh/ladspa-util.c +++ /dev/null @@ -1,22 +0,0 @@ -/* truncate: - - Truncates a float down to an int without worrying about - the stack and crap like that. -*/ - -//static const float _truncate_half = 0.5f; - -int truncate(float flt) { - int i; - - i = flt; -/* - asm ( - "flds 8(%ebp)\n" - "\tfsubs _truncate_half\n" - "\tfistpl -4(%ebp)\n" - ); -*/ - - return i; -} From 149eca1ec9beb96b9da7fde361b373ac73d0f191 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Wed, 22 Apr 2020 22:25:14 +0200 Subject: [PATCH 2/9] Note selection: Editing values works in dialog (#5438) --- src/gui/editors/PianoRoll.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 924463995..d6dec21ee 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -1772,8 +1772,9 @@ void PianoRoll::mouseDoubleClickEvent(QMouseEvent * me ) { const Note * closest = NULL; int closest_dist = 9999999; - // if we caught multiple notes, find the closest... - if( nv.size() > 1 ) + // if we caught multiple notes and we're not editing a + // selection, find the closest... + if( nv.size() > 1 && !isSelection() ) { for ( const Note * i : nv ) { From 1c5a3f8a36dcaca33b44ec3c368f875ae4cff386 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sun, 26 Apr 2020 17:59:43 +0900 Subject: [PATCH 3/9] DrumSynth: ensure correct envelope length in any sample rate (#5467) --- src/core/DrumSynth.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/DrumSynth.cpp b/src/core/DrumSynth.cpp index b39e8f52e..6532ecae2 100644 --- a/src/core/DrumSynth.cpp +++ b/src/core/DrumSynth.cpp @@ -320,6 +320,8 @@ int DrumSynth::GetDSFileSamples(QString dsfile, int16_t *&wave, int channels, sa timestretch = .01f * mem_time * GetPrivateProfileFloat(sec,"Stretch",100.0,dsfile); if(timestretch<0.2f) timestretch=0.2f; if(timestretch>10.f) timestretch=10.f; + // the unit of envelope lengths is a sample in 44100Hz sample rate, so correct it + timestretch *= Fs / 44100.f; DGain = 1.0f; //leave this here! DGain = (float)powf(10.0, 0.05 * GetPrivateProfileFloat(sec,"Level",0,dsfile)); From 687870d3029b87c658f319ce714e189b8abee7ed Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 28 Apr 2020 14:41:11 +0900 Subject: [PATCH 4/9] AFP: fix loading start and loop points if the loop point is automated (#5472) --- plugins/audio_file_processor/audio_file_processor.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index 6be59f3cd..9459eff3a 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -253,17 +253,16 @@ void audioFileProcessor::loadSettings( const QDomElement & _this ) m_loopModel.loadSettings( _this, "looped" ); m_ampModel.loadSettings( _this, "amp" ); m_endPointModel.loadSettings( _this, "eframe" ); + m_startPointModel.loadSettings( _this, "sframe" ); // compat code for not having a separate loopback point - if( _this.hasAttribute( "lframe" ) ) + if (_this.hasAttribute("lframe") || !(_this.firstChildElement("lframe").isNull())) { m_loopPointModel.loadSettings( _this, "lframe" ); - m_startPointModel.loadSettings( _this, "sframe" ); } else { m_loopPointModel.loadSettings( _this, "sframe" ); - m_startPointModel.setValue( m_loopPointModel.value() ); } m_reverseModel.loadSettings( _this, "reversed" ); From ca09b2908754d9e41d3d2d9efcc34cb9051cf9bd Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Sat, 2 May 2020 09:41:44 +0200 Subject: [PATCH 5/9] Select the correct piano key for marking semitones (#5478) When selecting a Piano Key to mark semitones in the Piano Roll we select key from the y position of the pop-up menu and not the mouse. Incidentally these two are most often the same as the menu builds from the mouse y positon and down. If there is room for it. If there is no room downward it will create the menu so the lower part of the frame aligns with the mouse y position. Fixed by creating a variable to hold the pressed key before creating the menu. --- include/PianoRoll.h | 1 + src/gui/editors/PianoRoll.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/PianoRoll.h b/include/PianoRoll.h index 9167804ae..125ed56d9 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -250,6 +250,7 @@ private: QList m_markedSemiTones; QMenu * m_semiToneMarkerMenu; // when you right click on the key area + int m_pianoKeySelected; PianoRoll(); PianoRoll( const PianoRoll & ); diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index d6dec21ee..358be5ab5 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -507,7 +507,7 @@ void PianoRoll::changeNoteEditMode( int i ) void PianoRoll::markSemiTone( int i ) { - const int key = getKey( mapFromGlobal( m_semiToneMarkerMenu->pos() ).y() ); + const int key = m_pianoKeySelected; const InstrumentFunctionNoteStacking::Chord * chord = nullptr; switch( static_cast( i ) ) @@ -1704,6 +1704,7 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) if( me->buttons() == Qt::RightButton ) { // right click, tone marker contextual menu + m_pianoKeySelected = getKey( me->y() ); m_semiToneMarkerMenu->popup( mapToGlobal( QPoint( me->x(), me->y() ) ) ); } else From f4f10c11fcfb6adb5dade1637719b25bd19dd8f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=BCller?= Date: Sat, 2 May 2020 22:55:06 +0200 Subject: [PATCH 6/9] 3rdparty/cmake: Do not reset CMAKE_C(XX)_FLAGS (#4080) CMake 3rdparty: Do not overwrite CMAKE_C(XX)_FLAGS Co-authored-by: tresf --- src/3rdparty/CMakeLists.txt | 5 ++--- src/3rdparty/rpmalloc/CMakeLists.txt | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt index d546fd06e..19e49c344 100644 --- a/src/3rdparty/CMakeLists.txt +++ b/src/3rdparty/CMakeLists.txt @@ -1,8 +1,7 @@ -set(CMAKE_C_FLAGS "") -set(CMAKE_CXX_FLAGS "") - +# TODO: Move submodules to dedicated directories for flag control IF(QT5 AND LMMS_BUILD_LINUX AND WANT_VST) set(BUILD_SHARED_LIBS OFF) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated") add_subdirectory(qt5-x11embed) ENDIF() diff --git a/src/3rdparty/rpmalloc/CMakeLists.txt b/src/3rdparty/rpmalloc/CMakeLists.txt index 23d1551c2..da6e7223e 100644 --- a/src/3rdparty/rpmalloc/CMakeLists.txt +++ b/src/3rdparty/rpmalloc/CMakeLists.txt @@ -1,4 +1,4 @@ -set(CMAKE_C_FLAGS "-std=c11") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Wno-unused-variable") add_library(rpmalloc STATIC rpmalloc/rpmalloc/rpmalloc.c From 71b6107d9bd7bc07e0281c709a17de66e0f53db9 Mon Sep 17 00:00:00 2001 From: tresf Date: Sun, 3 May 2020 02:24:28 -0400 Subject: [PATCH 7/9] Remove unwarranted CXX flag Per https://github.com/LMMS/lmms/pull/4080#issuecomment-623058847 --- src/3rdparty/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt index 19e49c344..3939a58ad 100644 --- a/src/3rdparty/CMakeLists.txt +++ b/src/3rdparty/CMakeLists.txt @@ -1,7 +1,5 @@ -# TODO: Move submodules to dedicated directories for flag control IF(QT5 AND LMMS_BUILD_LINUX AND WANT_VST) set(BUILD_SHARED_LIBS OFF) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated") add_subdirectory(qt5-x11embed) ENDIF() From 56fbefc700f6e82c9196aaca93e77d5b04519e87 Mon Sep 17 00:00:00 2001 From: thmueller64 <64359888+thmueller64@users.noreply.github.com> Date: Wed, 6 May 2020 11:23:40 +0200 Subject: [PATCH 8/9] Fix #5461 and ensure consistent use of check gate (#5475) * Multiple effects: Calculation of `outSum` should be after D/W mixing * CrossoverEQ.cpp: `outSum` must be divided by frames in the end * CrossoverEQ.cpp: don't overwrite `outSum` in for loop, but increment it --- plugins/Amplifier/Amplifier.cpp | 2 +- plugins/BassBooster/BassBooster.cpp | 2 +- plugins/CrossoverEQ/CrossoverEQ.cpp | 4 ++-- plugins/DualFilter/DualFilter.cpp | 2 +- plugins/dynamics_processor/dynamics_processor.cpp | 2 +- plugins/waveshaper/waveshaper.cpp | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/Amplifier/Amplifier.cpp b/plugins/Amplifier/Amplifier.cpp index 652a929ba..b41a598ba 100644 --- a/plugins/Amplifier/Amplifier.cpp +++ b/plugins/Amplifier/Amplifier.cpp @@ -83,7 +83,6 @@ bool AmplifierEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) for( fpp_t f = 0; f < frames; ++f ) { // qDebug( "offset %d, value %f", f, m_ampControls.m_volumeModel.value( f ) ); - outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1]; sample_t s[2] = { buf[f][0], buf[f][1] }; @@ -123,6 +122,7 @@ bool AmplifierEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) buf[f][0] = d * buf[f][0] + w * s[0]; buf[f][1] = d * buf[f][1] + w * s[1]; + outSum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; } checkGate( outSum / frames ); diff --git a/plugins/BassBooster/BassBooster.cpp b/plugins/BassBooster/BassBooster.cpp index f395fb730..c7484cdca 100644 --- a/plugins/BassBooster/BassBooster.cpp +++ b/plugins/BassBooster/BassBooster.cpp @@ -100,13 +100,13 @@ bool BassBoosterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames //float gain = gainBuffer ? gainBuffer[f] : gain; m_bbFX.leftFX().setGain( gain ); m_bbFX.rightFX().setGain( gain); - outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1]; sample_t s[2] = { buf[f][0], buf[f][1] }; m_bbFX.nextSample( s[0], s[1] ); buf[f][0] = d * buf[f][0] + w * s[0]; buf[f][1] = d * buf[f][1] + w * s[1]; + outSum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; } checkGate( outSum / frames ); diff --git a/plugins/CrossoverEQ/CrossoverEQ.cpp b/plugins/CrossoverEQ/CrossoverEQ.cpp index 325c73d86..bbe395f96 100644 --- a/plugins/CrossoverEQ/CrossoverEQ.cpp +++ b/plugins/CrossoverEQ/CrossoverEQ.cpp @@ -190,12 +190,12 @@ bool CrossoverEQEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames double outSum = 0.0; for( int f = 0; f < frames; ++f ) { - outSum = buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; buf[f][0] = d * buf[f][0] + w * m_work[f][0]; buf[f][1] = d * buf[f][1] + w * m_work[f][1]; + outSum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; } - checkGate( outSum ); + checkGate( outSum / frames ); return isRunning(); } diff --git a/plugins/DualFilter/DualFilter.cpp b/plugins/DualFilter/DualFilter.cpp index cb4b91b92..94f8e97b5 100644 --- a/plugins/DualFilter/DualFilter.cpp +++ b/plugins/DualFilter/DualFilter.cpp @@ -193,11 +193,11 @@ bool DualFilterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames s[0] += ( s2[0] * mix2 ); s[1] += ( s2[1] * mix2 ); } - outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1]; // do another mix with dry signal buf[f][0] = d * buf[f][0] + w * s[0]; buf[f][1] = d * buf[f][1] + w * s[1]; + outSum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; //increment pointers cut1Ptr += cut1Inc; diff --git a/plugins/dynamics_processor/dynamics_processor.cpp b/plugins/dynamics_processor/dynamics_processor.cpp index 2005d5e86..358bbf0d9 100644 --- a/plugins/dynamics_processor/dynamics_processor.cpp +++ b/plugins/dynamics_processor/dynamics_processor.cpp @@ -214,10 +214,10 @@ bool dynProcEffect::processAudioBuffer( sampleFrame * _buf, s[0] *= outputGain; s[1] *= outputGain; - out_sum += _buf[f][0]*_buf[f][0] + _buf[f][1]*_buf[f][1]; // mix wet/dry signals _buf[f][0] = d * _buf[f][0] + w * s[0]; _buf[f][1] = d * _buf[f][1] + w * s[1]; + out_sum += _buf[f][0] * _buf[f][0] + _buf[f][1] * _buf[f][1]; } checkGate( out_sum / _frames ); diff --git a/plugins/waveshaper/waveshaper.cpp b/plugins/waveshaper/waveshaper.cpp index df09456dd..ff8e03444 100644 --- a/plugins/waveshaper/waveshaper.cpp +++ b/plugins/waveshaper/waveshaper.cpp @@ -139,10 +139,10 @@ bool waveShaperEffect::processAudioBuffer( sampleFrame * _buf, s[0] *= *outputPtr; s[1] *= *outputPtr; - out_sum += _buf[f][0]*_buf[f][0] + _buf[f][1]*_buf[f][1]; // mix wet/dry signals _buf[f][0] = d * _buf[f][0] + w * s[0]; _buf[f][1] = d * _buf[f][1] + w * s[1]; + out_sum += _buf[f][0] * _buf[f][0] + _buf[f][1] * _buf[f][1]; outputPtr += outputInc; inputPtr += inputInc; From 317be010124236000935937b446629402d807694 Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Thu, 7 May 2020 07:18:15 -0500 Subject: [PATCH 9/9] Fix #4098 (#5449) Fixes piano roll crashing when window is scaled too large. --- src/gui/editors/PianoRoll.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 358be5ab5..807696775 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -2664,7 +2664,12 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) break; } // start drawing at the bottom - int key_line_y = keyAreaBottom() - 1; + int key_line_y = qMin(keyAreaBottom() - 1, KEY_LINE_HEIGHT * NumKeys); + // we need to set m_notesEditHeight here because it needs to fill in the + // rest of the window if key_line_y is bound to KEY_LINE_HEIGHT * NumKeys + if (key_line_y == KEY_LINE_HEIGHT * NumKeys) { + m_notesEditHeight = height() - (PR_TOP_MARGIN + KEY_LINE_HEIGHT * NumKeys); + } // used for aligning black-keys later int first_white_key_height = WHITE_KEY_SMALL_HEIGHT; // key-counter - only needed for finding out whether the processed @@ -2784,9 +2789,10 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) key = m_startKey; keys_processed = 0; int white_cnt = 0; + key_line_y = qMin(keyAreaBottom(), KEY_LINE_HEIGHT * NumKeys); // and go! - for( int y = keyAreaBottom() + y_offset; + for( int y = key_line_y + y_offset; y > PR_TOP_MARGIN; ++keys_processed ) { // check for black key that is only half visible on the bottom @@ -2852,16 +2858,16 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) // erase the area below the piano, because there might be keys that // should be only half-visible - p.fillRect( QRect( 0, keyAreaBottom(), - WHITE_KEY_WIDTH, noteEditBottom() - keyAreaBottom() ), bgColor ); + p.fillRect( QRect( 0, key_line_y, + WHITE_KEY_WIDTH, noteEditBottom() - key_line_y ), bgColor ); // display note editing info QFont f = p.font(); f.setBold( false ); p.setFont( pointSize<10>( f ) ); p.setPen( noteModeColor() ); - p.drawText( QRect( 0, keyAreaBottom(), - WHITE_KEY_WIDTH, noteEditBottom() - keyAreaBottom() ), + p.drawText( QRect( 0, key_line_y, + WHITE_KEY_WIDTH, noteEditBottom() - key_line_y ), Qt::AlignCenter | Qt::TextWordWrap, m_nemStr.at( m_noteEditMode ) + ":" ); @@ -2902,7 +2908,7 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) // Draw horizontal lines key = m_startKey; - for( int y = keyAreaBottom() - 1; y > PR_TOP_MARGIN; + for( int y = key_line_y - 1; y > PR_TOP_MARGIN; y -= KEY_LINE_HEIGHT ) { if( static_cast( key % KeysPerOctave ) == Key_C ) @@ -2961,10 +2967,10 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) for( int i = 0; i < m_markedSemiTones.size(); i++ ) { const int key_num = m_markedSemiTones.at( i ); - const int y = keyAreaBottom() + 5 + const int y = key_line_y + 5 - KEY_LINE_HEIGHT * ( key_num - m_startKey + 1 ); - if( y > keyAreaBottom() ) + if( y > key_line_y ) { break; } @@ -2992,14 +2998,14 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) qSwap( sel_key_start, sel_key_end ); } - int y_base = keyAreaBottom() - 1; + int y_base = key_line_y - 1; if( hasValidPattern() ) { p.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN, width() - WHITE_KEY_WIDTH, height() - PR_TOP_MARGIN ); - const int visible_keys = ( keyAreaBottom()-keyAreaTop() ) / + const int visible_keys = ( key_line_y-keyAreaTop() ) / KEY_LINE_HEIGHT + 2; QPolygonF editHandles; @@ -3148,13 +3154,13 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) if( hasValidPattern() ) { int key_num = getKey( mapFromGlobal( QCursor::pos() ).y() ); - p.fillRect( 10, keyAreaBottom() + 3 - KEY_LINE_HEIGHT * + p.fillRect( 10, key_line_y + 3 - KEY_LINE_HEIGHT * ( key_num - m_startKey + 1 ), width() - 10, KEY_LINE_HEIGHT - 7, currentKeyCol ); } // bar to resize note edit area p.setClipRect( 0, 0, width(), height() ); - p.fillRect( QRect( 0, keyAreaBottom(), + p.fillRect( QRect( 0, key_line_y, width()-PR_RIGHT_MARGIN, NOTE_EDIT_RESIZE_BAR ), editAreaCol ); const QPixmap * cursor = NULL;