Merge branch 'stable-0.4' into next

This commit is contained in:
Paul Giblock
2013-02-27 17:34:21 -05:00
92 changed files with 1946 additions and 369 deletions

View File

@@ -2,7 +2,7 @@
* AutomationPattern.cpp - implementation of class AutomationPattern which
* holds dynamic values
*
* Copyright (c) 2008-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2006-2008 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
@@ -45,7 +45,6 @@ AutomationPattern::AutomationPattern( AutomationTrack * _auto_track ) :
m_hasAutomation( false )
{
changeLength( midiTime( 1, 0 ) );
m_timeMap[0] = 0;
}
@@ -101,12 +100,6 @@ void AutomationPattern::addObject( AutomatableModel * _obj, bool _search_dup )
if( addIt )
{
m_objects += _obj;
// been empty before?
if( m_objects.size() == 1 && !hasAutomation() )
{
// then initialize default-value
putValue( 0, _obj->value<float>(), false );
}
connect( _obj, SIGNAL( destroyed( jo_id_t ) ),
this, SLOT( objectDestroyed( jo_id_t ) ),
Qt::DirectConnection );
@@ -152,6 +145,8 @@ midiTime AutomationPattern::putValue( const midiTime & _time,
const float _value,
const bool _quant_pos )
{
cleanObjects();
midiTime newTime = _quant_pos && engine::automationEditor() ?
note::quantized( _time,
engine::automationEditor()->quantization() ) :
@@ -159,43 +154,7 @@ midiTime AutomationPattern::putValue( const midiTime & _time,
m_timeMap[newTime] = _value;
if( newTime == 0 )
{
for( objectVector::iterator it = m_objects.begin();
it != m_objects.end(); )
{
if( *it )
{
( *it )->setValue( _value );
++it;
}
else
{
it = m_objects.erase( it );
}
}
}
// just one automation value?
if( m_timeMap.size() == 1 )
{
m_hasAutomation = m_objects.isEmpty(); // usually false
for( objectVector::iterator it = m_objects.begin();
it != m_objects.end(); ++it )
{
// default value differs from current value?
if( *it && _value != ( *it )->initValue<float>() )
{
// then enable automating this object
m_hasAutomation = true;
}
}
}
else
{
// in all other cases assume we have automation
m_hasAutomation = true;
}
m_hasAutomation = true;
// we need to maximize our length in case we're part of a hidden
// automation track as the user can't resize this pattern
@@ -214,41 +173,22 @@ midiTime AutomationPattern::putValue( const midiTime & _time,
void AutomationPattern::removeValue( const midiTime & _time )
{
if( _time != 0 )
cleanObjects();
m_timeMap.remove( _time );
if( getTrack() &&
getTrack()->type() == track::HiddenAutomationTrack )
{
m_timeMap.remove( _time );
if( m_timeMap.size() == 1 )
{
const float val = m_timeMap[0];
m_hasAutomation = false;
for( objectVector::iterator it = m_objects.begin();
it != m_objects.end(); )
{
if( *it )
{
( *it )->setValue( val );
if( ( *it )->initValue<float>() != val )
{
m_hasAutomation = true;
}
++it;
}
else
{
it = m_objects.erase( it );
}
}
}
if( getTrack() &&
getTrack()->type() == track::HiddenAutomationTrack )
{
changeLength( length() );
}
emit dataChanged();
changeLength( length() );
}
if( m_timeMap.isEmpty() )
{
m_hasAutomation = false;
}
emit dataChanged();
}
@@ -260,10 +200,22 @@ float AutomationPattern::valueAt( const midiTime & _time ) const
{
return 0;
}
timeMap::const_iterator v = m_timeMap.lowerBound( _time );
if( m_timeMap.contains( _time ) )
{
return m_timeMap[_time];
}
// lowerBound returns next value with greater key, therefore we take
// the previous element to get the current value
return ( v != m_timeMap.begin() ) ? (v-1).value() : v.value();
timeMap::ConstIterator v = m_timeMap.lowerBound( _time );
if( v == m_timeMap.begin() )
{
return 0;
}
return (v-1).value();
}
@@ -326,17 +278,7 @@ void AutomationPattern::loadSettings( const QDomElement & _this )
}
m_hasAutomation = m_timeMap.size() > 0;
if( m_hasAutomation == false )
{
for( objectVector::iterator it = m_objects.begin();
it != m_objects.end(); ++it )
{
if( *it )
{
( *it )->setValue( m_timeMap[0] );
}
}
}
int len = _this.attribute( "len" ).toInt();
if( len <= 0 )
{
@@ -366,7 +308,7 @@ const QString AutomationPattern::name() const
void AutomationPattern::processMidiTime( const midiTime & _time )
{
if( _time >= 0 && m_hasAutomation )
if( _time >= 0 && hasAutomation() )
{
const float val = valueAt( _time );
for( objectVector::iterator it = m_objects.begin();
@@ -502,9 +444,9 @@ void AutomationPattern::resolveAllIDs()
void AutomationPattern::clear()
{
const float val = firstObject()->value<float>();
m_timeMap.clear();
putValue( 0, val );
emit dataChanged();
if( engine::automationEditor() &&
engine::automationEditor()->currentPattern() == this )
@@ -537,6 +479,21 @@ void AutomationPattern::objectDestroyed( jo_id_t _id )
void AutomationPattern::cleanObjects()
{
for( objectVector::iterator it = m_objects.begin(); it != m_objects.end(); )
{
if( *it )
{
++it;
}
else
{
it = m_objects.erase( it );
}
}
}
#include "moc_AutomationPattern.cxx"

View File

@@ -1,7 +1,7 @@
/*
* InstrumentFunctions.cpp - models for instrument-function-tab
*
* Copyright (c) 2004-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -48,7 +48,7 @@ ChordCreator::ChordTable::Init ChordCreator::ChordTable::s_initTable[] =
{ QT_TRANSLATE_NOOP( "ChordCreator", "6" ), { 0, 4, 7, 9, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "6sus4" ), { 0, 5, 7, 9, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "6add9" ), { 0, 4, 7, 12, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "6add9" ), { 0, 4, 7, 9, 14, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "m6" ), { 0, 3, 7, 9, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "m6add9" ), { 0, 3, 7, 9, 14, -1 } },
@@ -56,11 +56,11 @@ ChordCreator::ChordTable::Init ChordCreator::ChordTable::s_initTable[] =
{ QT_TRANSLATE_NOOP( "ChordCreator", "7sus4" ), { 0, 5, 7, 10, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#5" ), { 0, 4, 8, 10, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7b5" ), { 0, 4, 6, 10, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#9" ), { 0, 4, 7, 10, 13, 18, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7b9" ), { 0, 4, 7, 10, 13, 16, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#5#9" ), { 0, 4, 8, 12, 14, 19, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#5b9" ), { 0, 4, 8, 12, 14, 17, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7b5b9" ), { 0, 4, 6, 10, 12, 15, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#9" ), { 0, 4, 7, 10, 15, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7b9" ), { 0, 4, 7, 10, 13, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#5#9" ), { 0, 4, 8, 10, 15, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#5b9" ), { 0, 4, 8, 10, 13, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7b5b9" ), { 0, 4, 6, 10, 13, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7add11" ), { 0, 4, 7, 10, 17, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7add13" ), { 0, 4, 7, 10, 21, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#11" ), { 0, 4, 7, 10, 18, -1 } },
@@ -130,6 +130,7 @@ ChordCreator::ChordTable::Init ChordCreator::ChordTable::s_initTable[] =
{ QT_TRANSLATE_NOOP( "ChordCreator", "Mixolydian" ), { 0, 2, 4, 5, 7, 9, 10, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "Aeolian" ), { 0, 2, 3, 5, 7, 8, 10, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "Locrian" ), { 0, 1, 3, 5, 6, 8, 10, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "Minor" ), { 0, 2, 3, 5, 7, 8, 10, -1 } },
} ;

View File

@@ -230,14 +230,13 @@ bool RemotePlugin::process( const sampleFrame * _in_buf,
lock();
sendMessage( IdStartProcessing );
unlock();
if( m_failed || _out_buf == NULL || m_outputCount == 0 )
{
unlock();
return false;
}
lock();
waitForMessage( IdProcessingDone );
unlock();

View File

@@ -2,7 +2,7 @@
* MidiPort.cpp - abstraction of MIDI-ports which are part of LMMS's MIDI-
* sequencing system
*
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -45,17 +45,17 @@ MidiPort::MidiPort( const QString & _name, MidiClient * _mc,
m_outputChannelModel( 1, 1, MidiChannelCount, this,
tr( "Output channel" ) ),
m_inputControllerModel( 0, 0, MidiControllerCount, this,
tr( "Input controller" ) ),
tr( "Input controller" ) ),
m_outputControllerModel( 0, 0, MidiControllerCount, this,
tr( "Output controller" ) ),
tr( "Output controller" ) ),
m_fixedInputVelocityModel( -1, -1, MidiMaxVelocity, this,
tr( "Fixed input velocity" ) ),
tr( "Fixed input velocity" ) ),
m_fixedOutputVelocityModel( -1, -1, MidiMaxVelocity, this,
tr( "Fixed output velocity" ) ),
m_fixedOutputNoteModel( -1, -1, MidiMaxNote, this,
tr( "Fixed output note" ) ),
m_outputProgramModel( 1, 1, MidiProgramCount, this,
tr( "Output MIDI program" ) ),
tr( "Output MIDI program" ) ),
m_readableModel( false, this, tr( "Receive MIDI-events" ) ),
m_writableModel( false, this, tr( "Send MIDI-events" ) )
{
@@ -129,20 +129,24 @@ void MidiPort::processInEvent( const midiEvent & _me, const midiTime & _time )
if( inputEnabled() &&
( inputChannel()-1 == _me.m_channel || inputChannel() == 0 ) )
{
midiEvent ev = _me;
if( _me.m_type == MidiNoteOn ||
_me.m_type == MidiNoteOff ||
_me.m_type == MidiKeyPressure )
{
if( _me.key() < 0 || _me.key() >= NumKeys )
ev.key() = ev.key() + KeysPerOctave;
if( ev.key() < 0 || ev.key() >= NumKeys )
{
return;
}
}
midiEvent ev = _me;
if( fixedInputVelocity() >= 0 && _me.velocity() > 0 )
{
ev.velocity() = fixedInputVelocity();
}
ev.setFromMidiPort( true );
m_midiEventProcessor->processInEvent( ev, _time );
}
}
@@ -164,10 +168,11 @@ void MidiPort::processOutEvent( const midiEvent & _me, const midiTime & _time )
--ev.m_channel;
} */
if( ( _me.m_type == MidiNoteOn || _me.m_type == MidiNoteOff ) &&
fixedOutputNote() >=0 ) {
// Convert MIDI note number (from spinbox) -> LMMS note number
// that will be converted back when outputted.
ev.key() = fixedOutputNote() - KeysPerOctave;
fixedOutputNote() >= 0 )
{
// Convert MIDI note number (from spinbox) -> LMMS note number
// that will be converted back when outputted.
ev.key() = fixedOutputNote() - KeysPerOctave;
}
if( fixedOutputVelocity() >= 0 && _me.velocity() > 0 &&
( _me.m_type == MidiNoteOn ||

View File

@@ -1,7 +1,7 @@
/*
* song.cpp - root of the model tree
*
* Copyright (c) 2004-2012 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -61,6 +61,21 @@
#include "text_float.h"
#include "timeline.h"
#ifdef LMMS_BUILD_WIN32
#ifndef USE_QT_SHMEM
#define USE_QT_SHMEM
#endif
#endif
#ifndef USE_QT_SHMEM
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
tick_t midiTime::s_ticksPerTact = DefaultTicksPerTact;
@@ -88,7 +103,10 @@ song::song() :
m_length( 0 ),
m_trackToPlay( NULL ),
m_patternToPlay( NULL ),
m_loopPattern( false )
m_loopPattern( false ),
m_shmID( -1 ),
m_SncVSTplug( NULL ),
m_shmQtID( "/usr/bin/lmms" )
{
connect( &m_tempoModel, SIGNAL( dataChanged() ),
this, SLOT( setTempo() ) );
@@ -101,6 +119,59 @@ song::song() :
connect( engine::getMixer(), SIGNAL( sampleRateChanged() ), this,
SLOT( updateFramesPerTick() ) );
// handle VST plugins sync
if( configManager::inst()->value( "ui", "syncvstplugins" ).toInt() )
{
connect( engine::getMixer(), SIGNAL( sampleRateChanged() ), this,
SLOT( updateSampleRateSHM() ) );
#ifdef USE_QT_SHMEM
if ( !m_shmQtID.create( sizeof( sncVST ) ) )
{
fprintf(stderr, "song.cpp::m_shmQtID create SHM error: %s\n",
m_shmQtID.errorString().toStdString().c_str() );
}
m_SncVSTplug = (sncVST *) m_shmQtID.data();
#else
key_t key; // make the key:
if( ( key = ftok( VST_SNC_SHM_KEY_FILE, 'R' ) ) == -1 )
{
perror( "song.cpp::ftok" );
}
else
{ // connect to shared memory segment
if( ( m_shmID = shmget( key, sizeof( sncVST ),
0644 | IPC_CREAT ) ) == -1 )
{
perror( "song.cpp::shmget" );
}
else
{ // attach segment
m_SncVSTplug = (sncVST *)shmat(m_shmID, 0, 0);
if( m_SncVSTplug == (sncVST *)( -1 ) )
{
perror( "song.cpp::shmat" );
}
}
}
#endif
// if we are connected into shared memory
if( m_SncVSTplug != NULL )
{
m_SncVSTplug->isPlayin = m_playing | m_exporting;
m_SncVSTplug->hasSHM = true;
m_SncVSTplug->m_sampleRate =
engine::getMixer()->processingSampleRate();
m_SncVSTplug->m_bufferSize =
engine::getMixer()->framesPerPeriod();
m_SncVSTplug->timeSigNumer = 4;
m_SncVSTplug->timeSigDenom = 4;
}
} // end of VST plugin sync section
if( m_SncVSTplug == NULL )
{
m_SncVSTplug = (sncVST*) malloc( sizeof( sncVST ) );
}
connect( &m_masterVolumeModel, SIGNAL( dataChanged() ),
this, SLOT( masterVolumeChanged() ) );
@@ -116,6 +187,24 @@ song::song() :
song::~song()
{
// detach shared memory, delete it:
#ifdef USE_QT_SHMEM
m_shmQtID.detach();
#else
if( shmdt( m_SncVSTplug ) == -1)
{
if( m_SncVSTplug->hasSHM )
{
perror("~song::shmdt");
}
if( m_SncVSTplug != NULL )
{
delete m_SncVSTplug;
m_SncVSTplug = NULL;
}
}
shmctl(m_shmID, IPC_RMID, NULL);
#endif
m_playing = false;
delete m_globalAutomationTrack;
}
@@ -150,6 +239,13 @@ void song::setTempo()
engine::updateFramesPerTick();
m_SncVSTplug->m_bpm = tempo;
#ifdef VST_SNC_LATENCY
m_SncVSTplug->m_latency = m_SncVSTplug->m_bufferSize * tempo /
( (float) m_SncVSTplug->m_sampleRate * 60 );
#endif
emit tempoChanged( tempo );
}
@@ -162,6 +258,8 @@ void song::setTimeSignature()
emit timeSignatureChanged( m_oldTicksPerTact, ticksPerTact() );
emit dataChanged();
m_oldTicksPerTact = ticksPerTact();
m_SncVSTplug->timeSigNumer = getTimeSigModel().getNumerator();
m_SncVSTplug->timeSigDenom = getTimeSigModel().getDenominator();
}
@@ -178,6 +276,7 @@ void song::doActions()
timeLine * tl =
m_playPos[m_playMode].m_timeLine;
m_playing = false;
m_SncVSTplug->isPlayin = m_exporting;
m_recording = true;
if( tl != NULL )
{
@@ -219,31 +318,37 @@ void song::doActions()
case ActionPlaySong:
m_playMode = Mode_PlaySong;
m_playing = true;
m_SncVSTplug->isPlayin = true;
Controller::resetFrameCounter();
break;
case ActionPlayTrack:
m_playMode = Mode_PlayTrack;
m_playing = true;
m_SncVSTplug->isPlayin = true;
break;
case ActionPlayBB:
m_playMode = Mode_PlayBB;
m_playing = true;
m_SncVSTplug->isPlayin = true;
break;
case ActionPlayPattern:
m_playMode = Mode_PlayPattern;
m_playing = true;
m_SncVSTplug->isPlayin = true;
break;
case ActionPause:
m_playing = false;// just set the play-flag
m_SncVSTplug->isPlayin = m_exporting;
m_paused = true;
break;
case ActionResumeFromPause:
m_playing = true;// just set the play-flag
m_SncVSTplug->isPlayin = true;
m_paused = false;
break;
}
@@ -360,8 +465,14 @@ void song::processNextBuffer()
while( total_frames_played
< engine::getMixer()->framesPerPeriod() )
{
f_cnt_t played_frames = engine::getMixer()
->framesPerPeriod() - total_frames_played;
f_cnt_t played_frames = ( m_SncVSTplug->m_bufferSize = engine::getMixer()
->framesPerPeriod() ) - total_frames_played;
#ifdef VST_SNC_LATENCY
m_SncVSTplug->m_latency = m_SncVSTplug->m_bufferSize *
m_SncVSTplug->m_bpm /
( (float) m_SncVSTplug->m_sampleRate * 60 );
#endif
float current_frame = m_playPos[m_playMode].currentFrame();
// did we play a tick?
@@ -369,6 +480,14 @@ void song::processNextBuffer()
{
int ticks = m_playPos[m_playMode].getTicks()
+ (int)( current_frame / frames_per_tick );
#ifdef VST_SNC_LATENCY
m_SncVSTplug->ppqPos = ( ( ticks + 0 ) / (float)48 ) -
m_SncVSTplug->m_latency;
#else
m_SncVSTplug->ppqPos = ( ( ticks + 0 ) / (float)48 );
#endif
// did we play a whole tact?
if( ticks >= midiTime::ticksPerTact() )
{
@@ -402,18 +521,37 @@ void song::processNextBuffer()
// offset
ticks = ticks % ( max_tact *
midiTime::ticksPerTact() );
#ifdef VST_SNC_LATENCY
m_SncVSTplug->ppqPos = ( ( ticks + 0 )
/ (float)48 )
- m_SncVSTplug->m_latency;
#else
m_SncVSTplug->ppqPos = ( ( ticks + 0 )
/ (float)48 );
#endif
}
}
m_playPos[m_playMode].setTicks( ticks );
if( check_loop )
{
m_SncVSTplug->isCycle = true;
m_SncVSTplug->cycleStart =
( tl->loopBegin().getTicks() )
/ (float)48;
m_SncVSTplug->cycleEnd =
( tl->loopEnd().getTicks() )
/ (float)48;
if( m_playPos[m_playMode] >= tl->loopEnd() )
{
m_playPos[m_playMode].setTicks(
tl->loopBegin().getTicks() );
}
}
else
{
m_SncVSTplug->isCycle = false;
}
current_frame = fmodf( current_frame, frames_per_tick );
m_playPos[m_playMode].setCurrentFrame( current_frame );
@@ -637,6 +775,7 @@ void song::startExport()
doActions();
m_exporting = true;
m_SncVSTplug->isPlayin = true;
}
@@ -647,6 +786,7 @@ void song::stopExport()
stop();
m_exporting = false;
m_exportLoop = false;
m_SncVSTplug->isPlayin = m_playing;
}
@@ -1096,8 +1236,9 @@ void song::importProject()
tr("MIDI sequences") +
" (*.mid *.midi *.rmi);;" +
tr("FL Studio projects") +
" (*.flp"
");;" +
" (*.flp);;" +
tr("Hydrogen projects") +
" (*.h2song);;" +
tr("All file types") +
" (*.*)");
@@ -1215,6 +1356,19 @@ void song::updateFramesPerTick()
void song::updateSampleRateSHM()
{
m_SncVSTplug->m_sampleRate = engine::getMixer()->processingSampleRate();
#ifdef VST_SNC_LATENCY
m_SncVSTplug->m_latency = m_SncVSTplug->m_bufferSize * m_SncVSTplug->m_bpm /
( (float) m_SncVSTplug->m_sampleRate * 60 );
#endif
}
void song::setModified()
{
if( !m_loadingProject )

View File

@@ -1,7 +1,7 @@
/*
* AutomatableModelView.cpp - implementation of AutomatableModelView
*
* Copyright (c) 2011 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2011-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -88,6 +88,12 @@ void AutomatableModelView::addDefaultActions( QMenu * _menu )
AutomatableModel::tr( "Edit song-global automation" ),
amvSlots,
SLOT( editSongGlobalAutomation() ) );
_menu->addAction( QPixmap(),
AutomatableModel::tr( "Remove song-global automation" ),
amvSlots,
SLOT( removeSongGlobalAutomation() ) );
_menu->addSeparator();
QString controllerTxt;
@@ -241,4 +247,11 @@ void AutomatableModelViewSlots::editSongGlobalAutomation()
void AutomatableModelViewSlots::removeSongGlobalAutomation()
{
delete AutomationPattern::globalAutomationPattern( amv->modelUntyped() );
}
#include "moc_AutomatableModelView.cxx"

View File

@@ -2,7 +2,7 @@
* AutomationEditor.cpp - implementation of AutomationEditor which is used for
* actual setting of dynamic values
*
* Copyright (c) 2008-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2006-2008 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
@@ -1424,7 +1424,8 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe )
timeMap & time_map = m_pattern->getTimeMap();
timeMap::iterator it = time_map.begin();
p.setPen( QColor( 0xFF, 0xDF, 0x20 ) );
do
while( it != time_map.end() )
{
Sint32 len_ticks = 4;
@@ -1516,7 +1517,7 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe )
}
else printf("not in range\n");
++it;
} while( it != time_map.end() );
}
}
else
{

View File

@@ -1,9 +1,7 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* main_window.cpp - implementation of LMMS-main-window
*
* Copyright (c) 2004-2011 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -810,16 +808,17 @@ void MainWindow::help( void )
void MainWindow::toggleWindow( QWidget * _w )
void MainWindow::toggleWindow( QWidget *window, bool forceShow )
{
QWidget * parent = _w->parentWidget();
QWidget *parent = window->parentWidget();
if( m_workspace->activeSubWindow() != parent
|| parent->isHidden() )
if( forceShow ||
m_workspace->activeSubWindow() != parent ||
parent->isHidden() )
{
parent->show();
_w->show();
_w->setFocus();
window->show();
window->setFocus();
}
else
{
@@ -836,9 +835,9 @@ void MainWindow::toggleWindow( QWidget * _w )
void MainWindow::toggleBBEditorWin( void )
void MainWindow::toggleBBEditorWin( bool forceShow )
{
toggleWindow( engine::getBBEditor() );
toggleWindow( engine::getBBEditor(), forceShow );
}
@@ -1072,5 +1071,3 @@ void MainWindow::autoSave()
#include "moc_MainWindow.cxx"
#endif

View File

@@ -125,7 +125,7 @@
<item>
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>Copyright (c) 2004-2012, LMMS developers</string>
<string>Copyright (c) 2004-2013, LMMS developers</string>
</property>
<property name="wordWrap" >
<bool>true</bool>

View File

@@ -1,7 +1,7 @@
/*
* export_project_dialog.cpp - implementation of dialog for exporting project
*
* Copyright (c) 2004-2012 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -39,6 +39,7 @@ exportProjectDialog::exportProjectDialog( const QString & _file_name,
QDialog( _parent ),
Ui::ExportProjectDialog(),
m_fileName( _file_name ),
m_fileExtension(),
m_multiExport(multi_export)
{
setupUi( this );
@@ -103,6 +104,8 @@ void exportProjectDialog::reject()
{
(*it)->abortProcessing();
}
QDialog::reject();
}
@@ -198,7 +201,7 @@ void exportProjectDialog::multiRender()
m_unmuted.push_back(tk);
QString nextName = tk->name();
nextName = nextName.remove(QRegExp("[^a-zA-Z]"));
QString name = QString("%1_%2.wav").arg(x++).arg(nextName);
QString name = QString( "%1_%2%3" ).arg( x++ ).arg( nextName ).arg( m_fileExtension );
m_fileName = QDir(m_dirName).filePath(name);
prepRender();
}
@@ -219,7 +222,7 @@ void exportProjectDialog::multiRender()
m_unmuted.push_back(tk);
QString nextName = tk->name();
nextName = nextName.remove(QRegExp("[^a-zA-Z]"));
QString name = QString("%1_%2.wav").arg(x++).arg(nextName);
QString name = QString( "%1_%2%3" ).arg( x++ ).arg( nextName ).arg( m_fileExtension );
m_fileName = QDir(m_dirName).filePath(name);
prepRender();
}
@@ -290,6 +293,7 @@ void exportProjectDialog::startBtnClicked()
__fileEncodeDevices[i].m_description ) )
{
m_ft = __fileEncodeDevices[i].m_fileFormat;
m_fileExtension = QString( QLatin1String( __fileEncodeDevices[i].m_extension ) );
break;
}
}

View File

@@ -117,7 +117,9 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) :
m_oneInstrumentTrackWindow( configManager::inst()->value( "ui",
"oneinstrumenttrackwindow" ).toInt() ),
m_compactTrackButtons( configManager::inst()->value( "ui",
"compacttrackbuttons" ).toInt() )
"compacttrackbuttons" ).toInt() ),
m_syncVSTPlugins( configManager::inst()->value( "ui",
"syncvstplugins" ).toInt() )
{
setWindowIcon( embed::getIconPixmap( "setup_general" ) );
setWindowTitle( tr( "Setup LMMS" ) );
@@ -186,7 +188,7 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) :
tabWidget * misc_tw = new tabWidget( tr( "MISC" ), general );
misc_tw->setFixedHeight( 156 );
misc_tw->setFixedHeight( 174 );
ledCheckBox * enable_tooltips = new ledCheckBox(
tr( "Enable tooltips" ),
@@ -247,6 +249,15 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) :
this, SLOT( toggleCompactTrackButtons( bool ) ) );
ledCheckBox * syncVST = new ledCheckBox(
tr( "Sync VST plugins to host playback" ),
misc_tw );
syncVST->move( 10, 144 );
syncVST->setChecked( m_syncVSTPlugins );
connect( syncVST, SIGNAL( toggled( bool ) ),
this, SLOT( toggleSyncVSTPlugins( bool ) ) );
gen_layout->addWidget( bufsize_tw );
gen_layout->addSpacing( 10 );
@@ -774,6 +785,8 @@ void setupDialog::accept()
QString::number( m_oneInstrumentTrackWindow ) );
configManager::inst()->setValue( "ui", "compacttrackbuttons",
QString::number( m_compactTrackButtons ) );
configManager::inst()->setValue( "ui", "syncvstplugins",
QString::number( m_syncVSTPlugins ) );
configManager::inst()->setWorkingDir( m_workingDir );
configManager::inst()->setVSTDir( m_vstDir );
@@ -956,6 +969,15 @@ void setupDialog::toggleCompactTrackButtons( bool _enabled )
void setupDialog::toggleSyncVSTPlugins( bool _enabled )
{
m_syncVSTPlugins = _enabled;
}
void setupDialog::toggleOneInstrumentTrackWindow( bool _enabled )
{
m_oneInstrumentTrackWindow = _enabled;

View File

@@ -175,29 +175,36 @@ void EffectRackView::update()
Qt::QueuedConnection );
view->show();
m_effectViews.append( view );
view_map[i] = true;
if( i < view_map.size() )
{
view_map[i] = true;
}
else
{
view_map.append( true );
}
}
}
int i = m_lastY = 0;
int i = m_lastY = 0, nView = 0;
for( QVector<EffectView *>::Iterator it = m_effectViews.begin();
it != m_effectViews.end(); )
it != m_effectViews.end(); i++ )
{
if( i < view_map.size() && i < m_effectViews.size() &&
view_map[i] == false )
if( i < view_map.size() && view_map[i] == false )
{
delete m_effectViews[i];
delete m_effectViews[nView];
it = m_effectViews.erase( it );
}
else
{
( *it )->move( 0, m_lastY );
m_lastY += ( *it )->height();
++nView;
++it;
++i;
}
}
w->setFixedSize( 210, m_lastY );
QWidget::update();
@@ -242,7 +249,7 @@ void EffectRackView::addEffect()
void EffectRackView::modelChanged()
{
clearViews();
//clearViews();
m_effectsGroupBox->setModel( &fxChain()->m_enabledModel );
connect( fxChain(), SIGNAL( aboutToClear() ),
this, SLOT( clearViews() ) );

View File

@@ -85,6 +85,8 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
"while deciding when to stop processing signals." ) );
setModel( _model );
if( effect()->controls()->controlCount() > 0 )
{
QPushButton * ctls_btn = new QPushButton( tr( "Controls" ),
@@ -94,6 +96,7 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
ctls_btn->setGeometry( 140, 14, 50, 20 );
connect( ctls_btn, SIGNAL( clicked() ),
this, SLOT( editControls() ) );
m_controlView = effect()->controls()->createView();
if( m_controlView )
{
@@ -141,7 +144,8 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
"Right clicking will bring up a context menu where you can change the order "
"in which the effects are processed or delete an effect altogether." ) );
setModel( _model );
//move above vst effect view creation
//setModel( _model );
}
@@ -149,7 +153,15 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
EffectView::~EffectView()
{
#ifdef LMMS_BUILD_LINUX
delete m_subWindow;
#else
// otherwise on win32 build VST GUI can get lost
m_subWindow->hide();
#endif
}
@@ -159,7 +171,7 @@ void EffectView::editControls()
{
if( m_subWindow )
{
if( !effect()->controls()->isViewVisible() )
if( !m_subWindow->isVisible() )
{
m_subWindow->show();
m_subWindow->raise();

View File

@@ -2,7 +2,7 @@
* pixmap_button.cpp - implementation of pixmap-button (often used as "themed"
* checkboxes/radiobuttons etc)
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -57,7 +57,7 @@ void pixmapButton::paintEvent( QPaintEvent * )
{
QPainter p( this );
if( model()->value() || m_pressed )
if( ( model() != NULL && model()->value() ) || m_pressed )
{
if( !m_activePixmap.isNull() )
{

View File

@@ -221,6 +221,18 @@ void InstrumentTrack::processInEvent( const midiEvent & _me,
const midiTime & _time )
{
engine::getMixer()->lock();
// in the special case this event comes from a MIDI port, the instrument
// is MIDI based (VST plugin, Sf2Player etc.) and the user did not set
// a dedicated MIDI output channel, directly pass the MIDI event to the
// instrument plugin
if( _me.isFromMidiPort() && m_instrument->isMidiBased()/* &&
midiPort()->realOutputChannel() < 0 */ )
{
m_instrument->handleMidiEvent( _me, _time );
return;
}
switch( _me.m_type )
{
// we don't send MidiNoteOn, MidiNoteOff and MidiKeyPressure
@@ -315,6 +327,17 @@ void InstrumentTrack::processInEvent( const midiEvent & _me,
m_sustainPedalPressed = false;
}
}
if( _me.controllerNumber() == MidiControllerAllSoundOff ||
_me.controllerNumber() == MidiControllerAllNotesOff ||
_me.controllerNumber() == MidiControllerOmniOn ||
_me.controllerNumber() == MidiControllerOmniOff ||
_me.controllerNumber() == MidiControllerMonoOn ||
_me.controllerNumber() == MidiControllerPolyOn )
{
silenceAllNotes();
}
m_instrument->handleMidiEvent( _me, _time );
break;
case MidiProgramChange:
m_instrument->handleMidiEvent( _me, _time );
@@ -1036,9 +1059,9 @@ void InstrumentTrackView::freeInstrumentTrackWindow()
model()->setHook( NULL );
m_window->setInstrumentTrackView( NULL );
m_window->parentWidget()->hide();
m_window->setModel(
engine::dummyTrackContainer()->
dummyInstrumentTrack() );
//m_window->setModel(
// engine::dummyTrackContainer()->
// dummyInstrumentTrack() );
m_window->updateInstrumentView();
s_windowCache << m_window;
}

View File

@@ -1,7 +1,7 @@
/*
* bb_track.cpp - implementation of class bbTrack and bbTCO
*
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -33,6 +33,7 @@
#include "embed.h"
#include "engine.h"
#include "gui_templates.h"
#include "MainWindow.h"
#include "mixer.h"
#include "rename_dialog.h"
#include "song.h"
@@ -223,10 +224,9 @@ void bbTCOView::paintEvent( QPaintEvent * )
void bbTCOView::openInBBEditor()
{
engine::getBBTrackContainer()->setCurrentBB( bbTrack::numOfBBTrack(
m_bbTCO->getTrack() ) );
engine::getBBEditor()->show();
engine::getBBEditor()->setFocus();
engine::getBBTrackContainer()->setCurrentBB( bbTrack::numOfBBTrack( m_bbTCO->getTrack() ) );
engine::mainWindow()->toggleBBEditorWin( true );
}