Merge branch 'stable-1.2'

# Conflicts:
#	.travis.yml
#	.travis/linux..script.sh
#	.travis/linux.win.download.sh
#	.travis/linux.win32.script.sh
#	.travis/linux.win64.script.sh
#	.travis/osx..script.sh
#	include/VstSyncController.h
#	plugins/audio_file_processor/audio_file_processor.cpp
#	plugins/zynaddsubfx/zynaddsubfx
#	plugins/zynaddsubfx/zynaddsubfx/src/Misc/Bank.cpp
#	plugins/zynaddsubfx/zynaddsubfx/src/Misc/Bank.h
#	src/gui/SetupDialog.cpp
#	src/gui/editors/SongEditor.cpp
This commit is contained in:
Hyunjin Song
2019-03-26 09:52:37 +09:00
29 changed files with 188 additions and 60 deletions

View File

@@ -4,7 +4,7 @@ dist: trusty
sudo: required
cache:
directories:
- apt_mingw_cache
- $HOME/apt_mingw_cache
- $HOME/.ccache
- $HOME/pbuilder-bases
matrix:
@@ -14,9 +14,15 @@ matrix:
- env: TARGET_OS=win32
- env: TARGET_OS=win64
- env: TARGET_OS=debian-sid TARGET_DEPLOY=True
git:
depth: false
- env: TARGET_OS=debian-sid TARGET_ARCH=i386
git:
depth: false
- compiler: clang
env: TARGET_OS=debian-sid
git:
depth: false
- os: osx
osx_image: xcode8.3
install: ${TRAVIS_BUILD_DIR}/.travis/install.sh

View File

@@ -23,4 +23,4 @@ sudo apt-get install -y $PACKAGES
sudo add-apt-repository -y ppa:kxstudio-debian/libs
sudo add-apt-repository -y ppa:kxstudio-debian/apps
sudo apt-get update
sudo apt-get install -y carla-git
sudo apt-get install -y carla

View File

@@ -31,6 +31,40 @@ else
sudo pbuilder --update --basetgz "$BASETGZ"
fi
sync_version() {
local VERSION
local MMR
local STAGE
local EXTRA
VERSION=$(git describe --tags --match v[0-9].[0-9].[0-9]*)
VERSION=${VERSION#v}
MMR=${VERSION%%-*}
case $VERSION in
*-*-*-*)
VERSION=${VERSION%-*}
STAGE=${VERSION#*-}
STAGE=${STAGE%-*}
EXTRA=${VERSION##*-}
VERSION=$MMR~$STAGE.$EXTRA
;;
*-*-*)
VERSION=${VERSION%-*}
EXTRA=${VERSION##*-}
VERSION=$MMR.$EXTRA
;;
*-*)
STAGE=${VERSION#*-}
VERSION=$MMR~$STAGE
;;
esac
sed "1 s/@VERSION@/$VERSION/" -i debian/changelog
echo Set Debian version to $VERSION
}
sync_version
DIR="$PWD"
cd ..
dpkg-source -b "$DIR"

View File

@@ -2,7 +2,7 @@
set -e
CACHE_DIR=$TRAVIS_BUILD_DIR/apt_mingw_cache/$1
CACHE_DIR=$HOME/apt_mingw_cache/$1
mkdir -p "$CACHE_DIR"
pushd "$CACHE_DIR"

View File

@@ -76,6 +76,7 @@ OPTION(WANT_DEBUG_FPE "Debug floating point exceptions" OFF)
IF(LMMS_BUILD_APPLE)
# Fix linking on 10.14+. See issue #4762 on github
LINK_DIRECTORIES(/usr/local/lib)
SET(WANT_SOUNDIO OFF)
SET(WANT_ALSA OFF)
SET(WANT_PULSEAUDIO OFF)
SET(WANT_VST OFF)

View File

@@ -101,6 +101,7 @@ mv "${APPDIR}usr/bin/lmms" "${APPDIR}usr/bin/lmms.real"
cat >"${APPDIR}usr/bin/lmms" <<EOL
#!/usr/bin/env bash
DIR="\$( cd "\$( dirname "\${BASH_SOURCE[0]}" )" && pwd )"
export PATH="$PATH:/sbin"
if which carla > /dev/null 2>&1; then
CARLAPATH="\$(which carla)"
CARLAPREFIX="\${CARLAPATH%/bin*}"

2
debian/changelog vendored
View File

@@ -1,4 +1,4 @@
lmms (1.2.0~rc7.1) unstable; urgency=low
lmms (@VERSION@) unstable; urgency=low
* Upstream integration.
* Drop Debian menu entry (policy 9.6).

View File

@@ -47,6 +47,7 @@ protected:
DropToolBar * addDropToolBar(Qt::ToolBarArea whereToAdd, QString const & windowTitle);
DropToolBar * addDropToolBar(QWidget * parent, Qt::ToolBarArea whereToAdd, QString const & windowTitle);
virtual void closeEvent( QCloseEvent * _ce );
protected slots:
virtual void play() {}
virtual void record() {}

View File

@@ -122,6 +122,9 @@ private slots:
void toggleDisplayWaveform( bool en );
void toggleDisableAutoquit( bool en );
void vstEmbedMethodChanged();
void toggleVSTAlwaysOnTop( bool en );
void setLanguage( int lang );
@@ -203,6 +206,8 @@ private:
QComboBox* m_vstEmbedComboBox;
QString m_vstEmbedMethod;
LedCheckBox * m_vstAlwaysOnTopCheckBox;
bool m_vstAlwaysOnTop;
} ;

View File

@@ -352,7 +352,7 @@ public:
}
}
bool canPasteSelection( MidiTime tcoPos, const QMimeData * mimeData );
bool canPasteSelection( MidiTime tcoPos, const QDropEvent *de );
bool pasteSelection( MidiTime tcoPos, QDropEvent * de );
MidiTime endPosition( const MidiTime & posStart );

View File

@@ -41,10 +41,10 @@
struct VstSyncData
{
bool isPlaying;
double ppqPos;
int timeSigNumer;
int timeSigDenom;
bool isPlaying;
bool isCycle;
bool hasSHM;
float cycleStart;

View File

@@ -45,11 +45,11 @@ EqAnalyser::EqAnalyser() :
const float a2 = 0.14128;
const float a3 = 0.01168;
for(int i = 0; i < FFT_BUFFER_SIZE; i++)
for (int i = 0; i < FFT_BUFFER_SIZE; i++)
{
m_fftWindow[i] = ( a0 - a1 * cosf( 2 * F_PI * i / (float)FFT_BUFFER_SIZE - 1 )
+ a2 * cosf( 4 * F_PI * i / (float)FFT_BUFFER_SIZE-1)
- a3 * cos( 6 * F_PI * i / (float)FFT_BUFFER_SIZE - 1.0 ));
m_fftWindow[i] = (a0 - a1 * cos(2 * F_PI * i / ((float)FFT_BUFFER_SIZE - 1.0))
+ a2 * cos(4 * F_PI * i / ((float)FFT_BUFFER_SIZE - 1.0))
- a3 * cos(6 * F_PI * i / ((float)FFT_BUFFER_SIZE - 1.0)));
}
clear();
}

View File

@@ -505,7 +505,7 @@ AudioFileProcessorView::AudioFileProcessorView( Instrument * _instrument,
"loop_pingpong_on" ) );
m_loopPingPongButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
"loop_pingpong_off" ) );
ToolTip::add( m_loopPingPongButton, tr( "Enable loop" ) );
ToolTip::add( m_loopPingPongButton, tr( "Enable ping-pong loop" ) );
m_loopGroup = new automatableButtonGroup( this );
m_loopGroup->addButton( m_loopOffButton );
@@ -753,6 +753,7 @@ AudioFileProcessorWaveView::AudioFileProcessorWaveView( QWidget * _parent, int _
m_graph.fill( Qt::transparent );
update();
updateCursor();
}
@@ -769,7 +770,7 @@ void AudioFileProcessorWaveView::isPlaying( f_cnt_t _current_frame )
void AudioFileProcessorWaveView::enterEvent( QEvent * _e )
{
QApplication::setOverrideCursor( Qt::OpenHandCursor );
updateCursor();
}
@@ -777,10 +778,7 @@ void AudioFileProcessorWaveView::enterEvent( QEvent * _e )
void AudioFileProcessorWaveView::leaveEvent( QEvent * _e )
{
while( QApplication::overrideCursor() )
{
QApplication::restoreOverrideCursor();
}
updateCursor();
}
@@ -808,7 +806,7 @@ void AudioFileProcessorWaveView::mousePressEvent( QMouseEvent * _me )
else
{
m_draggingType = wave;
QApplication::setOverrideCursor( Qt::ClosedHandCursor );
updateCursor(_me);
}
}
@@ -820,7 +818,7 @@ void AudioFileProcessorWaveView::mouseReleaseEvent( QMouseEvent * _me )
m_isDragging = false;
if( m_draggingType == wave )
{
QApplication::restoreOverrideCursor();
updateCursor(_me);
}
}
@@ -831,22 +829,7 @@ void AudioFileProcessorWaveView::mouseMoveEvent( QMouseEvent * _me )
{
if( ! m_isDragging )
{
const bool is_size_cursor =
QApplication::overrideCursor()->shape() == Qt::SizeHorCursor;
if( isCloseTo( _me->x(), m_startFrameX ) ||
isCloseTo( _me->x(), m_endFrameX ) ||
isCloseTo( _me->x(), m_loopFrameX ) )
{
if( ! is_size_cursor )
{
QApplication::setOverrideCursor( Qt::SizeHorCursor );
}
}
else if( is_size_cursor )
{
QApplication::restoreOverrideCursor();
}
updateCursor(_me);
return;
}
@@ -1219,6 +1202,24 @@ void AudioFileProcessorWaveView::reverse()
void AudioFileProcessorWaveView::updateCursor( QMouseEvent * _me )
{
bool const waveIsDragged = m_isDragging && (m_draggingType == wave);
bool const pointerCloseToStartEndOrLoop = (_me != nullptr ) &&
( isCloseTo( _me->x(), m_startFrameX ) ||
isCloseTo( _me->x(), m_endFrameX ) ||
isCloseTo( _me->x(), m_loopFrameX ) );
if( !m_isDragging && pointerCloseToStartEndOrLoop)
setCursor(Qt::SizeHorCursor);
else if( waveIsDragged )
setCursor(Qt::ClosedHandCursor);
else
setCursor(Qt::OpenHandCursor);
}
void AudioFileProcessorWaveView::knob::slideTo( double _v, bool _check_bound )
{

View File

@@ -211,7 +211,6 @@ public:
private:
bool checkBound( double _v ) const;
} ;
@@ -276,6 +275,7 @@ private:
void updateGraph();
void reverse();
void updateCursor( QMouseEvent * _me = nullptr );
static bool isCloseTo( int _a, int _b )
{

View File

@@ -186,7 +186,13 @@ vestigeInstrument::~vestigeInstrument()
void vestigeInstrument::loadSettings( const QDomElement & _this )
{
loadFile( _this.attribute( "plugin" ) );
QString plugin = _this.attribute( "plugin" );
if( plugin.isEmpty() )
{
return;
}
loadFile( plugin );
m_pluginMutex.lock();
if( m_plugin != NULL )
{

View File

@@ -791,10 +791,6 @@ void RemoteVstPlugin::initEditor()
SWP_NOMOVE | SWP_NOZORDER );
pluginDispatch( effEditTop );
if (! EMBED) {
showEditor();
}
#ifdef LMMS_BUILD_LINUX
m_windowID = (intptr_t) GetProp( m_window, "__wine_x11_whole_window" );
#else

View File

@@ -386,7 +386,9 @@ bool VstPlugin::processMessage( const message & _m )
{
case IdVstPluginWindowID:
m_pluginWindowID = _m.getInt();
if( m_embedMethod == "none" )
if( m_embedMethod == "none"
&& ConfigManager::inst()->value(
"ui", "vstalwaysontop" ).toInt() )
{
#ifdef LMMS_BUILD_WIN32
// We're changing the owner, not the parent,

View File

@@ -27,6 +27,7 @@
#include <QDir>
#include <QDomDocument>
#include <QTemporaryFile>
#include <QtGlobal>
#include <QDropEvent>
#include <QGridLayout>
#include <QPushButton>
@@ -290,6 +291,10 @@ void ZynAddSubFxInstrument::loadSettings( const QDomElement & _this )
emit settingsChanged();
}
// FIXME: Remove this check in future versions. Slots are public in Qt5+
#if QT_VERSION >= 0x050000
emit instrumentTrack()->pitchModel()->dataChanged();
#endif
}

View File

@@ -511,8 +511,9 @@ void ConfigManager::loadConfigFile( const QString & configFile )
cfg_file.close();
}
// Plugins are searched recursively, blacklist problematic locations
if( m_vstDir.isEmpty() || m_vstDir == QDir::separator() || m_vstDir == "/" ||
m_vstDir == ensureTrailingSlash( QDir::homePath() ) ||
!QDir( m_vstDir ).exists() )
{
#ifdef LMMS_BUILD_WIN32

View File

@@ -124,7 +124,10 @@ void DrumSynth::GetEnv(int env, const char *sec, const char *key, QString ini)
char en[256], s[8];
int i=0, o=0, ep=0;
GetPrivateProfileString(sec, key, "0,0 100,0", en, sizeof(en), ini);
en[255]=0; //be safe!
//be safe!
en[255]=0;
s[0]=0;
while(en[i]!=0)
{

View File

@@ -23,6 +23,9 @@
*/
#include "MixHelpers.h"
#include <cstdio>
#include "lmms_math.h"
#include "ValueBuffer.h"

View File

@@ -186,8 +186,8 @@ Mixer::~Mixer()
}
delete m_fifo;
delete m_audioDev;
delete m_midiClient;
delete m_audioDev;
for( int i = 0; i < 3; i++ )
{

View File

@@ -525,7 +525,7 @@ void TrackContentObjectView::dragEnterEvent( QDragEnterEvent * dee )
{
TrackContentWidget * tcw = getTrackView()->getTrackContentWidget();
MidiTime tcoPos = MidiTime( m_tco->startPosition().getTact(), 0 );
if( tcw->canPasteSelection( tcoPos, dee->mimeData() ) == false )
if( tcw->canPasteSelection( tcoPos, dee ) == false )
{
dee->ignore();
}
@@ -630,9 +630,12 @@ DataFile TrackContentObjectView::createTCODataFiles(
it != tcoViews.end(); ++it )
{
// Insert into the dom under the "tcos" element
int trackIndex = tc->tracks().indexOf( ( *it )->m_trackView->getTrack() );
Track* tcoTrack = ( *it )->m_trackView->getTrack();
int trackIndex = tc->tracks().indexOf( tcoTrack );
QDomElement tcoElement = dataFile.createElement( "tco" );
tcoElement.setAttribute( "trackIndex", trackIndex );
tcoElement.setAttribute( "trackType", tcoTrack->type() );
tcoElement.setAttribute( "trackName", tcoTrack->name() );
( *it )->m_tco->saveState( dataFile, tcoElement );
tcoParent.appendChild( tcoElement );
}
@@ -649,6 +652,7 @@ DataFile TrackContentObjectView::createTCODataFiles(
QDomElement metadata = dataFile.createElement( "copyMetadata" );
// initialTrackIndex is the index of the track that was touched
metadata.setAttribute( "initialTrackIndex", initialTrackIndex );
metadata.setAttribute( "trackContainerId", tc->id() );
// grabbedTCOPos is the pos of the tact containing the TCO we grabbed
metadata.setAttribute( "grabbedTCOPos", m_tco->startPosition() );
@@ -1387,7 +1391,7 @@ MidiTime TrackContentWidget::getPosition( int mouseX )
void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
{
MidiTime tcoPos = MidiTime( getPosition( dee->pos().x() ).getTact(), 0 );
if( canPasteSelection( tcoPos, dee->mimeData() ) == false )
if( canPasteSelection( tcoPos, dee ) == false )
{
dee->ignore();
}
@@ -1406,8 +1410,10 @@ void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
* \param tcoPos the position of the TCO slot being pasted on
* \param de the DropEvent generated
*/
bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * mimeData )
bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QDropEvent* de )
{
const QMimeData * mimeData = de->mimeData();
Track * t = getTrack();
QString type = StringPairDrag::decodeMimeKey( mimeData );
QString value = StringPairDrag::decodeMimeValue( mimeData );
@@ -1437,7 +1443,9 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m
const int currentTrackIndex = tracks.indexOf( t );
// Don't paste if we're on the same tact
if( tcoPos == grabbedTCOTact && currentTrackIndex == initialTrackIndex )
auto sourceTrackContainerId = metadata.attributeNode( "trackContainerId" ).value().toUInt();
if( de->source() && sourceTrackContainerId == t->trackContainer()->id() &&
tcoPos == grabbedTCOTact && currentTrackIndex == initialTrackIndex )
{
return false;
}
@@ -1460,9 +1468,9 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m
}
// Track must be of the same type
Track * startTrack = tracks.at( trackIndex );
auto startTrackType = tcoElement.attributeNode("trackType").value().toInt();
Track * endTrack = tracks.at( finalTrackIndex );
if( startTrack->type() != endTrack->type() )
if( startTrackType != endTrack->type() )
{
return false;
}
@@ -1478,7 +1486,7 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m
*/
bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de )
{
if( canPasteSelection( tcoPos, de->mimeData() ) == false )
if( canPasteSelection( tcoPos, de ) == false )
{
return false;
}
@@ -1548,7 +1556,8 @@ bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de )
}
//check tco name, if the same as source track name dont copy
if( tco->name() == tracks[trackIndex]->name() )
QString sourceTrackName = outerTCOElement.attributeNode( "trackName" ).value();
if( tco->name() == sourceTrackName )
{
tco->setName( "" );
}

View File

@@ -61,6 +61,7 @@ static void JackMidiShutdown(void *arg)
MidiJack::MidiJack() :
MidiClientRaw(),
m_jackClient( nullptr ),
m_input_port( NULL ),
m_output_port( NULL ),
m_quit( false )

View File

@@ -139,7 +139,9 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
"displaywaveform").toInt() ),
m_disableAutoQuit(ConfigManager::inst()->value( "ui",
"disableautoquit", "1" ).toInt() ),
m_vstEmbedMethod( ConfigManager::inst()->vstEmbedMethod() )
m_vstEmbedMethod( ConfigManager::inst()->vstEmbedMethod() ),
m_vstAlwaysOnTop( ConfigManager::inst()->value( "ui",
"vstalwaysontop" ).toInt() )
{
setWindowIcon( embed::getIconPixmap( "setup_general" ) );
setWindowTitle( tr( "Setup LMMS" ) );
@@ -259,7 +261,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
}
TabWidget* embed_tw = new TabWidget( tr( "PLUGIN EMBEDDING" ), general);
embed_tw->setFixedHeight( 48 );
embed_tw->setFixedHeight( 66 );
m_vstEmbedComboBox = new QComboBox( embed_tw );
m_vstEmbedComboBox->move( XDelta, YDelta );
@@ -278,6 +280,17 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
m_vstEmbedComboBox->addItem( tr( "Embed using XEmbed protocol" ), "xembed" );
}
m_vstEmbedComboBox->setCurrentIndex( m_vstEmbedComboBox->findData( m_vstEmbedMethod ) );
connect( m_vstEmbedComboBox, SIGNAL( currentIndexChanged( int ) ),
this, SLOT( vstEmbedMethodChanged() ) );
m_vstAlwaysOnTopCheckBox = new LedCheckBox(
tr( "Keep plugin windows on top when not embedded" ),
embed_tw );
m_vstAlwaysOnTopCheckBox->move( 20, 44 );
m_vstAlwaysOnTopCheckBox->setChecked( m_vstAlwaysOnTop );
m_vstAlwaysOnTopCheckBox->setVisible( m_vstEmbedMethod == "none" );
connect( m_vstAlwaysOnTopCheckBox, SIGNAL( toggled( bool ) ),
this, SLOT( toggleVSTAlwaysOnTop( bool ) ) );
TabWidget * lang_tw = new TabWidget( tr( "LANGUAGE" ), general );
lang_tw->setFixedHeight( 48 );
@@ -854,7 +867,9 @@ void SetupDialog::accept()
QString::number( m_disableAutoQuit ) );
ConfigManager::inst()->setValue( "app", "language", m_lang );
ConfigManager::inst()->setValue( "ui", "vstembedmethod",
m_vstEmbedComboBox->currentData().toString() );
m_vstEmbedMethod );
ConfigManager::inst()->setValue( "ui", "vstalwaysontop",
QString::number( m_vstAlwaysOnTop ) );
ConfigManager::inst()->setWorkingDir(QDir::fromNativeSeparators(m_workingDir));
@@ -1057,6 +1072,25 @@ void SetupDialog::toggleOneInstrumentTrackWindow( bool _enabled )
m_oneInstrumentTrackWindow = _enabled;
}
void SetupDialog::vstEmbedMethodChanged()
{
#if QT_VERSION >= 0x050000
m_vstEmbedMethod = m_vstEmbedComboBox->currentData().toString();
#else
m_vstEmbedMethod = m_vstEmbedComboBox->itemData(
m_vstEmbedComboBox->currentIndex()).toString();
#endif
m_vstAlwaysOnTopCheckBox->setVisible( m_vstEmbedMethod == "none" );
}
void SetupDialog::toggleVSTAlwaysOnTop( bool en )
{
m_vstAlwaysOnTop = en;
}
void SetupDialog::setLanguage( int lang )
{
m_lang = m_languages[lang];

View File

@@ -405,6 +405,7 @@ void AutomationEditor::keyPressEvent(QKeyEvent * ke )
}
break;
case Qt::Key_Backspace:
case Qt::Key_Delete:
deleteSelectedValues();
ke->accept();
@@ -2487,6 +2488,9 @@ void AutomationEditorWindow::dropEvent( QDropEvent *_de )
void AutomationEditorWindow::dragEnterEvent( QDragEnterEvent *_dee )
{
if (! m_editor->validPattern() ) {
return;
}
StringPairDrag::processDragEnterEvent( _dee, "automatable_model" );
}

View File

@@ -32,6 +32,7 @@
#include <QAction>
#include <QMdiArea>
#include <QShortcut>
#include <QCloseEvent>
void Editor::setPauseIcon(bool displayPauseIcon)
@@ -128,8 +129,18 @@ QAction *Editor::playAction() const
return m_playAction;
}
void Editor::closeEvent( QCloseEvent * _ce )
{
if( parentWidget() )
{
parentWidget()->hide();
}
else
{
hide();
}
_ce->ignore();
}
DropToolBar::DropToolBar(QWidget* parent) : QToolBar(parent)
{
@@ -145,3 +156,6 @@ void DropToolBar::dropEvent(QDropEvent* event)
{
dropped(event);
}

View File

@@ -1319,6 +1319,7 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke)
clearSelectedNotes();
break;
case Qt::Key_Backspace:
case Qt::Key_Delete:
deleteSelectedNotes();
ke->accept();

View File

@@ -304,12 +304,12 @@ void SongEditor::setEditModeSelect()
void SongEditor::keyPressEvent( QKeyEvent * ke )
{
if( ke->modifiers() & Qt::ShiftModifier &&
ke->key() == Qt::Key_Insert )
( ke->key() == Qt::Key_Insert || ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return ) )
{
m_song->insertBar();
}
else if( ke->modifiers() & Qt::ShiftModifier &&
ke->key() == Qt::Key_Delete )
( ke->key() == Qt::Key_Delete || ke->key() == Qt::Key_Backspace ) )
{
m_song->removeBar();
}