Merge branch 'stable-1.2'

# Conflicts:
#	CMakeLists.txt
#	cmake/linux/package_linux.sh.in
#	src/3rdparty/CMakeLists.txt
#	src/core/Track.cpp
#	src/gui/editors/PianoRoll.cpp
#	src/tracks/SampleTrack.cpp
This commit is contained in:
Hyunjin Song
2019-05-06 15:46:17 +09:00
26 changed files with 143 additions and 100 deletions

View File

@@ -1,2 +1,3 @@
314ef4af137903dfb13e8c3ef1e6ea56cfdb23808d52ec4f5f50e288c73610c5 pbuilder_0.229.1_all.deb
fa82aa8ed3055c6f6330104deedf080b26778295e589426d4c4dd0f2c2a5defa debootstrap_1.0.95_all.deb
2ef4c09f7841b72f93412803ddd142f72658536dbfabe00e449eb548f432f3f8 debian-archive-keyring_2017.7ubuntu1_all.deb

View File

@@ -2,15 +2,16 @@
set -e
sudo apt-get install -y \
debian-archive-keyring \
dpkg \
pbuilder
# work around a pbuilder bug which breaks ccache
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666525
# and also missing signing keys in Trusty's debian-archive-keyring
cd /tmp
wget http://archive.ubuntu.com/ubuntu/pool/main/p/pbuilder/pbuilder_0.229.1_all.deb
wget http://archive.ubuntu.com/ubuntu/pool/main/d/debootstrap/debootstrap_1.0.95_all.deb
wget http://archive.ubuntu.com/ubuntu/pool/universe/d/debian-archive-keyring/debian-archive-keyring_2017.7ubuntu1_all.deb
sha256sum -c "$TRAVIS_BUILD_DIR/.travis/debian_pkgs.sha256"
sudo dpkg -i pbuilder_0.229.1_all.deb debootstrap_1.0.95_all.deb
sudo dpkg -i pbuilder_0.229.1_all.deb debootstrap_1.0.95_all.deb debian-archive-keyring_2017.7ubuntu1_all.deb
cd "$OLDPWD"

View File

@@ -157,7 +157,7 @@ SET(QT_LIBRARIES
Qt5::Xml
)
IF(LMMS_BUILD_LINUX)
IF(LMMS_BUILD_LINUX AND WANT_VST)
FIND_PACKAGE(Qt5 COMPONENTS X11Extras REQUIRED)
LIST(APPEND QT_LIBRARIES Qt5::X11Extras)
ENDIF()

View File

@@ -74,8 +74,9 @@ else
success "Downloaded $LINUXDEPLOYQT"
# Extract AppImage and replace LINUXDEPLOYQT variable with extracted binary
# to support systems without fuse
"$LINUXDEPLOYQT" --appimage-extract > /dev/null 2>&1
LINUXDEPLOYQT="squashfs-root/AppRun"
# Also, we need to set LD_LIBRARY_PATH, but linuxdepoyqt's AppRun unsets it
# See https://github.com/probonopd/linuxdeployqt/pull/370/
LINUXDEPLOYQT="squashfs-root/usr/bin/linuxdeployqt"
success "Extracted $APPIMAGETOOL"
fi

View File

@@ -303,6 +303,7 @@ private:
NotePlayHandleList m_subNotes; // used for chords and arpeggios
volatile bool m_released; // indicates whether note is released
bool m_releaseStarted;
bool m_hasMidiNote;
bool m_hasParent; // indicates whether note has parent
NotePlayHandle * m_parent; // parent note
bool m_hadChildren;

View File

@@ -55,10 +55,10 @@ EqControlsDialog::EqControlsDialog( EqControls *controls ) :
EqSpectrumView * inSpec = new EqSpectrumView( &controls->m_inFftBands, this );
inSpec->move( 26, 17 );
inSpec->setColor( QColor( 54, 45, 142, 150 ) );
inSpec->setColor( QColor( 77, 101, 242, 150 ) );
EqSpectrumView * outSpec = new EqSpectrumView( &controls->m_outFftBands, this );
outSpec->setColor( QColor( 9, 166, 156, 150 ) );
outSpec->setColor( QColor( 0, 255, 239, 150 ) );
outSpec->move( 26, 17 );
m_parameterWidget = new EqParameterWidget( this , controls );

View File

@@ -36,7 +36,8 @@ LadspaControls::LadspaControls( LadspaEffect * _eff ) :
{
connect( &m_stereoLinkModel, SIGNAL( dataChanged() ),
this, SLOT( updateLinkStatesFromGlobal() ) );
this, SLOT( updateLinkStatesFromGlobal() ),
Qt::DirectConnection );
multi_proc_t controls = m_effect->getPortControls();
m_controlCount = controls.count();
@@ -59,7 +60,8 @@ LadspaControls::LadspaControls( LadspaEffect * _eff ) :
if( linked_control )
{
connect( (*it)->control, SIGNAL( linkChanged( int, bool ) ),
this, SLOT( linkPort( int, bool ) ) );
this, SLOT( linkPort( int, bool ) ),
Qt::DirectConnection );
}
}
}

View File

@@ -145,9 +145,6 @@ void VstEffect::openPlugin( const QString & _plugin )
return;
}
VstPlugin::connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ), m_plugin.data(), SLOT( setTempo( bpm_t ) ) );
m_plugin->setTempo( Engine::getSong()->getTempo() );
delete tf;
m_key.attributes["file"] = _plugin;

View File

@@ -1962,7 +1962,8 @@ DWORD WINAPI RemoteVstPlugin::processingThread( LPVOID _param )
{
if( m.id == IdStartProcessing
|| m.id == IdMidiEvent
|| m.id == IdVstSetParameter )
|| m.id == IdVstSetParameter
|| m.id == IdVstSetTempo )
{
_this->processMessage( m );
}

View File

@@ -162,7 +162,7 @@ VstPlugin::VstPlugin( const QString & _plugin ) :
setTempo( Engine::getSong()->getTempo() );
connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ),
this, SLOT( setTempo( bpm_t ) ) );
this, SLOT( setTempo( bpm_t ) ), Qt::DirectConnection );
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ),
this, SLOT( updateSampleRate() ) );

View File

@@ -3,7 +3,7 @@ set(CMAKE_CXX_FLAGS "")
set(CMAKE_C_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_DEBUG "")
IF(LMMS_BUILD_LINUX)
IF(LMMS_BUILD_LINUX AND WANT_VST)
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(qt5-x11embed)
ENDIF()

View File

@@ -205,7 +205,7 @@ void ControllerConnection::loadSettings( const QDomElement & _this )
else
{
m_controllerId = _this.attribute( "id", "-1" ).toInt();
if( m_controllerId < 0 )
if( m_controllerId < 0 || m_controllerId >= Engine::getSong()->controllers().size() )
{
qWarning( "controller index invalid\n" );
m_controllerId = -1;

View File

@@ -131,32 +131,32 @@ EnvelopeAndLfoParameters::EnvelopeAndLfoParameters(
instances()->add( this );
connect( &m_predelayModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( &m_attackModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( &m_holdModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( &m_decayModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( &m_sustainModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( &m_releaseModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( &m_amountModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( &m_lfoPredelayModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( &m_lfoAttackModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( &m_lfoSpeedModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( &m_lfoAmountModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( &m_lfoWaveModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( &m_x100Model, SIGNAL( dataChanged() ),
this, SLOT( updateSampleVars() ) );
this, SLOT( updateSampleVars() ), Qt::DirectConnection );
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ),
this, SLOT( updateSampleVars() ) );

View File

@@ -42,7 +42,8 @@ LadspaControl::LadspaControl( Model * _parent, port_desc_t * _port,
if( m_link )
{
connect( &m_linkEnabledModel, SIGNAL( dataChanged() ),
this, SLOT( linkStateChanged() ) );
this, SLOT( linkStateChanged() ),
Qt::DirectConnection );
}
switch( m_port->data_type )

View File

@@ -49,12 +49,12 @@ LfoController::LfoController( Model * _parent ) :
{
setSampleExact( true );
connect( &m_waveModel, SIGNAL( dataChanged() ),
this, SLOT( updateSampleFunction() ) );
this, SLOT( updateSampleFunction() ), Qt::DirectConnection );
connect( &m_speedModel, SIGNAL( dataChanged() ),
this, SLOT( updateDuration() ) );
this, SLOT( updateDuration() ), Qt::DirectConnection );
connect( &m_multiplierModel, SIGNAL( dataChanged() ),
this, SLOT( updateDuration() ) );
this, SLOT( updateDuration() ), Qt::DirectConnection );
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ),
this, SLOT( updateDuration() ) );

View File

@@ -33,9 +33,9 @@ MeterModel::MeterModel( ::Model * _parent ) :
m_denominatorModel( 4, 1, 32, this, tr( "Denominator" ) )
{
connect( &m_numeratorModel, SIGNAL( dataChanged() ),
this, SIGNAL( dataChanged() ) );
this, SIGNAL( dataChanged() ), Qt::DirectConnection );
connect( &m_denominatorModel, SIGNAL( dataChanged() ),
this, SIGNAL( dataChanged() ) );
this, SIGNAL( dataChanged() ), Qt::DirectConnection );
}

View File

@@ -62,6 +62,7 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack,
m_subNotes(),
m_released( false ),
m_releaseStarted( false ),
m_hasMidiNote( false ),
m_hasParent( parent != NULL ),
m_parent( parent ),
m_hadChildren( false ),
@@ -105,17 +106,6 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack,
m_instrumentTrack->midiNoteOn( *this );
}
if( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() )
{
const int baseVelocity = m_instrumentTrack->midiPort()->baseVelocity();
// send MidiNoteOn event
m_instrumentTrack->processOutEvent(
MidiEvent( MidiNoteOn, midiChannel(), midiKey(), midiVelocity( baseVelocity ) ),
MidiTime::fromFrames( offset(), Engine::framesPerTick() ),
offset() );
}
if( m_instrumentTrack->instrument()->flags() & Instrument::IsSingleStreamed )
{
setUsesBuffer( false );
@@ -205,6 +195,21 @@ void NotePlayHandle::play( sampleFrame * _working_buffer )
}
lock();
if( m_totalFramesPlayed == 0 && !m_hasMidiNote
&& ( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() ) )
{
m_hasMidiNote = true;
const int baseVelocity = m_instrumentTrack->midiPort()->baseVelocity();
// send MidiNoteOn event
m_instrumentTrack->processOutEvent(
MidiEvent( MidiNoteOn, midiChannel(), midiKey(), midiVelocity( baseVelocity ) ),
MidiTime::fromFrames( offset(), Engine::framesPerTick() ),
offset() );
}
if( m_frequencyNeedsUpdate )
{
updateFrequency();
@@ -357,8 +362,10 @@ void NotePlayHandle::noteOff( const f_cnt_t _s )
m_framesBeforeRelease = _s;
m_releaseFramesToDo = qMax<f_cnt_t>( 0, actualReleaseFramesToDo() );
if( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() )
if( m_hasMidiNote )
{
m_hasMidiNote = false;
// send MidiNoteOff event
m_instrumentTrack->processOutEvent(
MidiEvent( MidiNoteOff, midiChannel(), midiKey(), 0 ),

View File

@@ -53,8 +53,10 @@ PeakController::PeakController( Model * _parent,
this, SLOT( handleDestroyedEffect( ) ) );
}
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( updateCoeffs() ) );
connect( m_peakEffect->attackModel(), SIGNAL( dataChanged() ), this, SLOT( updateCoeffs() ) );
connect( m_peakEffect->decayModel(), SIGNAL( dataChanged() ), this, SLOT( updateCoeffs() ) );
connect( m_peakEffect->attackModel(), SIGNAL( dataChanged() ),
this, SLOT( updateCoeffs() ), Qt::DirectConnection );
connect( m_peakEffect->decayModel(), SIGNAL( dataChanged() ),
this, SLOT( updateCoeffs() ), Qt::DirectConnection );
m_coeffNeedsUpdate = true;
}

View File

@@ -92,18 +92,18 @@ Song::Song() :
{
for(int i = 0; i < Mode_Count; ++i) m_elapsedMilliSeconds[i] = 0;
connect( &m_tempoModel, SIGNAL( dataChanged() ),
this, SLOT( setTempo() ) );
this, SLOT( setTempo() ), Qt::DirectConnection );
connect( &m_tempoModel, SIGNAL( dataUnchanged() ),
this, SLOT( setTempo() ) );
this, SLOT( setTempo() ), Qt::DirectConnection );
connect( &m_timeSigModel, SIGNAL( dataChanged() ),
this, SLOT( setTimeSignature() ) );
this, SLOT( setTimeSignature() ), Qt::DirectConnection );
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this,
SLOT( updateFramesPerTick() ) );
connect( &m_masterVolumeModel, SIGNAL( dataChanged() ),
this, SLOT( masterVolumeChanged() ) );
this, SLOT( masterVolumeChanged() ), Qt::DirectConnection );
/* connect( &m_masterPitchModel, SIGNAL( dataChanged() ),
this, SLOT( masterPitchChanged() ) );*/

View File

@@ -42,7 +42,8 @@ TempoSyncKnobModel::TempoSyncKnobModel( const float _val, const float _min,
m_custom( _parent )
{
connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ),
this, SLOT( calculateTempoSyncTime( bpm_t ) ) );
this, SLOT( calculateTempoSyncTime( bpm_t ) ),
Qt::DirectConnection );
}
@@ -154,7 +155,8 @@ void TempoSyncKnobModel::setSyncMode( TempoSyncMode _new_mode )
if( _new_mode == SyncCustom )
{
connect( &m_custom, SIGNAL( dataChanged() ),
this, SLOT( updateCustom() ) );
this, SLOT( updateCustom() ),
Qt::DirectConnection );
}
}
calculateTempoSyncTime( Engine::getSong()->getTempo() );

View File

@@ -328,8 +328,8 @@ TrackContentObjectView::~TrackContentObjectView()
/*! \brief Update a TrackContentObjectView
*
* TCO's get drawn only when needed,
* and when a TCO is updated,
* TCO's get drawn only when needed,
* and when a TCO is updated,
* it needs to be redrawn.
*
*/
@@ -598,9 +598,9 @@ void TrackContentObjectView::dropEvent( QDropEvent * de )
*/
void TrackContentObjectView::leaveEvent( QEvent * e )
{
while( QApplication::overrideCursor() != NULL )
if( cursor().shape() != Qt::BitmapCursor )
{
QApplication::restoreOverrideCursor();
setCursor( QCursor( embed::getIconPixmap( "hand" ), 3, 3 ) );
}
if( e != NULL )
{
@@ -746,20 +746,17 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me )
&& !m_tco->getAutoResize() )
{
m_action = ResizeLeft;
QCursor c( Qt::SizeHorCursor );
QApplication::setOverrideCursor( c );
setCursor( Qt::SizeHorCursor );
}
else if( me->x() < width() - RESIZE_GRIP_WIDTH )
{
m_action = Move;
QCursor c( Qt::SizeAllCursor );
QApplication::setOverrideCursor( c );
setCursor( Qt::SizeAllCursor );
}
else if( !m_tco->getAutoResize() )
{
m_action = Resize;
QCursor c( Qt::SizeHorCursor );
QApplication::setOverrideCursor( c );
setCursor( Qt::SizeHorCursor );
}
if( m_action == Move )
@@ -1007,17 +1004,7 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me )
if( ( me->x() > width() - RESIZE_GRIP_WIDTH && !me->buttons() && !m_tco->getAutoResize() )
|| ( me->x() < RESIZE_GRIP_WIDTH && !me->buttons() && sTco && !m_tco->getAutoResize() ) )
{
if( QApplication::overrideCursor() != NULL &&
QApplication::overrideCursor()->shape() !=
Qt::SizeHorCursor )
{
while( QApplication::overrideCursor() != NULL )
{
QApplication::restoreOverrideCursor();
}
}
QCursor c( Qt::SizeHorCursor );
QApplication::setOverrideCursor( c );
setCursor( Qt::SizeHorCursor );
}
else
{
@@ -1194,7 +1181,7 @@ void TrackContentWidget::updateBackground()
// draw lines
// vertical lines
pmp.setPen( QPen( gridColor(), 1 ) );
pmp.setPen( QPen( gridColor(), 1 ) );
for( float x = 0; x < w * 2; x += ppt )
{
pmp.drawLine( QLineF( x, 0.0, x, h ) );
@@ -1205,9 +1192,9 @@ void TrackContentWidget::updateBackground()
{
pmp.drawLine( QLineF( x, 0.0, x, h ) );
}
// horizontal line
pmp.setPen( QPen( gridColor(), 1 ) );
pmp.setPen( QPen( gridColor(), 1 ) );
pmp.drawLine( 0, h-1, w*2, h-1 );
pmp.end();
@@ -1390,7 +1377,7 @@ MidiTime TrackContentWidget::getPosition( int mouseX )
*/
void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
{
MidiTime tcoPos = MidiTime( getPosition( dee->pos().x() ).getTact(), 0 );
MidiTime tcoPos = getPosition( dee->pos().x() );
if( canPasteSelection( tcoPos, dee ) == false )
{
dee->ignore();
@@ -1928,7 +1915,7 @@ void TrackOperationsWidget::updateMenu()
toMenu->addAction( embed::getIconPixmap( "cancel", 16, 16 ),
tr( "Remove this track" ),
this, SLOT( removeTrack() ) );
if( ! m_trackView->trackContainerView()->fixedTCOs() )
{
toMenu->addAction( tr( "Clear this track" ), this, SLOT( clearTrack() ) );
@@ -2624,7 +2611,7 @@ TrackView::TrackView( Track * track, TrackContainerView * tcv ) :
&m_trackContentWidget, SLOT( update() ) );
connect( &m_track->m_soloModel, SIGNAL( dataChanged() ),
m_track, SLOT( toggleSolo() ) );
m_track, SLOT( toggleSolo() ), Qt::DirectConnection );
// create views for already existing TCOs
for( Track::tcoVector::iterator it =
m_track->m_trackContentObjects.begin();
@@ -2871,12 +2858,12 @@ void TrackView::mouseMoveEvent( QMouseEvent * me )
else if( m_action == MoveTrack )
{
// look which track-widget the mouse-cursor is over
const int yPos =
const int yPos =
m_trackContainerView->contentWidget()->mapFromGlobal( me->globalPos() ).y();
const TrackView * trackAtY = m_trackContainerView->trackViewAt( yPos );
// debug code
// qDebug( "y position %d", yPos );
// debug code
// qDebug( "y position %d", yPos );
// a track-widget not equal to ourself?
if( trackAtY != NULL && trackAtY != this )

View File

@@ -100,7 +100,7 @@ MidiAlsaSeq::MidiAlsaSeq() :
snd_seq_start_queue( m_seqHandle, m_queueID, NULL );
changeQueueTempo( Engine::getSong()->getTempo() );
connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ),
this, SLOT( changeQueueTempo( bpm_t ) ) );
this, SLOT( changeQueueTempo( bpm_t ) ), Qt::DirectConnection );
// initial list-update
updatePortList();

View File

@@ -63,9 +63,12 @@ MidiPort::MidiPort( const QString& name,
m_readableModel.setValue( m_mode == Input || m_mode == Duplex );
m_writableModel.setValue( m_mode == Output || m_mode == Duplex );
connect( &m_readableModel, SIGNAL( dataChanged() ), this, SLOT( updateMidiPortMode() ) );
connect( &m_writableModel, SIGNAL( dataChanged() ), this, SLOT( updateMidiPortMode() ) );
connect( &m_outputProgramModel, SIGNAL( dataChanged() ), this, SLOT( updateOutputProgram() ) );
connect( &m_readableModel, SIGNAL( dataChanged() ),
this, SLOT( updateMidiPortMode() ), Qt::DirectConnection );
connect( &m_writableModel, SIGNAL( dataChanged() ),
this, SLOT( updateMidiPortMode() ), Qt::DirectConnection );
connect( &m_outputProgramModel, SIGNAL( dataChanged() ),
this, SLOT( updateOutputProgram() ), Qt::DirectConnection );
// when using with non-raw-clients we can provide buttons showing

View File

@@ -313,7 +313,7 @@ FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv,
m_soloBtn->setCheckable( true );
m_soloBtn->move( 9, m_fader->y()-21);
connect(&fxChannel->m_soloModel, SIGNAL( dataChanged() ),
_mv, SLOT ( toggledSolo() ) );
_mv, SLOT ( toggledSolo() ), Qt::DirectConnection );
ToolTip::add( m_soloBtn, tr( "Solo FX channel" ) );
// Create EffectRack for the channel

View File

@@ -1007,6 +1007,9 @@ void PianoRoll::drawDetuningInfo( QPainter & _p, const Note * _n, int _x,
{
int middle_y = _y + KEY_LINE_HEIGHT / 2;
_p.setPen( noteColor() );
_p.setClipRect(WHITE_KEY_WIDTH, PR_TOP_MARGIN,
width() - WHITE_KEY_WIDTH,
keyAreaBottom() - PR_TOP_MARGIN);
int old_x = 0;
int old_y = 0;
@@ -3255,6 +3258,9 @@ void PianoRoll::paintEvent(QPaintEvent * pe )
drawDetuningInfo( p, note,
x + WHITE_KEY_WIDTH,
y_base - key * KEY_LINE_HEIGHT );
p.setClipRect(WHITE_KEY_WIDTH, PR_TOP_MARGIN,
width() - WHITE_KEY_WIDTH,
height() - PR_TOP_MARGIN);
}
}
@@ -3783,6 +3789,21 @@ void PianoRoll::finishRecordNote(const Note & n )
it->key(), it->getVolume(),
it->getPanning() );
n1.quantizeLength( quantization() );
//Get selected chord
const InstrumentFunctionNoteStacking::Chord & chord = InstrumentFunctionNoteStacking::ChordTable::getInstance()
.getChordByName( m_chordModel.currentText() );
if( !chord.isEmpty() )
{
for( int i = 1; i < chord.size(); i++ )
{
Note new_note( n.length(), it->pos(), it->key() + chord[i] );
new_note.setPanning( it->getPanning() );
new_note.setVolume( it->getVolume() );
m_pattern->addNote( new_note );
}
}
m_pattern->addNote( n1 );
update();
m_recordingNotes.erase( it );

View File

@@ -65,7 +65,7 @@ SampleTCO::SampleTCO( Track * _track ) :
// we need to receive bpm-change-events, because then we have to
// change length of this TCO
connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ),
this, SLOT( updateLength() ) );
this, SLOT( updateLength() ), Qt::DirectConnection );
connect( Engine::getSong(), SIGNAL( timeSignatureChanged( int,int ) ),
this, SLOT( updateLength() ) );
@@ -110,7 +110,7 @@ SampleTCO::SampleTCO( Track * _track ) :
SampleTCO::~SampleTCO()
{
SampleTrack * sampletrack = dynamic_cast<SampleTrack*>( getTrack() );
if( sampletrack)
if ( sampletrack )
{
sampletrack->updateTcos();
}
@@ -122,10 +122,7 @@ SampleTCO::~SampleTCO()
void SampleTCO::changeLength( const MidiTime & _length )
{
float nom = Engine::getSong()->getTimeSigModel().getNumerator();
float den = Engine::getSong()->getTimeSigModel().getDenominator();
int ticksPerTact = DefaultTicksPerTact * ( nom / den );
TrackContentObject::changeLength( qMax( static_cast<int>( _length ), ticksPerTact ) );
TrackContentObject::changeLength( qMax( static_cast<int>( _length ), 1 ) );
}
@@ -151,9 +148,21 @@ void SampleTCO::setSampleBuffer( SampleBuffer* sb )
void SampleTCO::setSampleFile( const QString & _sf )
{
m_sampleBuffer->setAudioFile( _sf );
int length;
if ( _sf.isEmpty() )
{ //When creating an empty sample pattern make it a bar long
float nom = Engine::getSong()->getTimeSigModel().getNumerator();
float den = Engine::getSong()->getTimeSigModel().getDenominator();
length = DefaultTicksPerTact * ( nom / den );
}
else
{ //Otherwise set it to the sample's length
m_sampleBuffer->setAudioFile( _sf );
length = sampleLength();
}
changeLength(length);
setStartTimeOffset( 0 );
changeLength( (int) ( m_sampleBuffer->frames() / Engine::framesPerTick() ) );
emit sampleChanged();
emit playbackPositionChanged();
@@ -440,8 +449,15 @@ void SampleTCOView::mouseReleaseEvent(QMouseEvent *_me)
void SampleTCOView::mouseDoubleClickEvent( QMouseEvent * )
{
QString af = m_tco->m_sampleBuffer->openAudioFile();
if( af != "" && af != m_tco->m_sampleBuffer->audioFile() )
{
if ( af.isEmpty() ) {} //Don't do anything if no file is loaded
else if ( af == m_tco->m_sampleBuffer->audioFile() )
{ //Instead of reloading the existing file, just reset the size
int length = (int) ( m_tco->m_sampleBuffer->frames() / Engine::framesPerTick() );
m_tco->changeLength(length);
}
else
{ //Otherwise load the new file as ususal
m_tco->setSampleFile( af );
Engine::getSong()->setModified();
}