mutex, detuning helpers, GUI updates, play handles, many many changes... (4)

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@482 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Javier Serrano Polo
2007-05-07 19:51:55 +00:00
parent 5afcc9414b
commit 793c5ab7ff
29 changed files with 834 additions and 671 deletions

View File

@@ -66,7 +66,6 @@ audioJACK::audioJACK( const sample_rate_t _sample_rate, bool & _success_ful,
_mixer ),
m_client( NULL ),
m_active( FALSE ),
// m_processCallbackMutex(),
m_stop_semaphore( 1 ),
m_outBuf( new surroundSampleFrame[getMixer()->framesPerAudioBuffer()] ),
m_framesDoneInCurBuf( 0 ),
@@ -286,7 +285,6 @@ void audioJACK::registerPort( audioPort * _port )
const QString name[2] = { _port->name() + " L",
_port->name() + " R" } ;
m_processCallbackMutex.lock();
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
m_portMap[_port].ports[ch] = jack_port_register( m_client,
@@ -298,8 +296,7 @@ void audioJACK::registerPort( audioPort * _port )
#endif
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0 );
}
m_processCallbackMutex.unlock();*/
}*/
}
@@ -310,7 +307,6 @@ void audioJACK::unregisterPort( audioPort * _port )
return;
/* if( m_portMap.contains( _port ) )
{
m_processCallbackMutex.lock();
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
if( m_portMap[_port].ports[ch] != NULL )
@@ -320,7 +316,6 @@ void audioJACK::unregisterPort( audioPort * _port )
}
}
m_portMap.erase( m_portMap.find( _port ) );
m_processCallbackMutex.unlock();
}*/
}
@@ -354,7 +349,6 @@ void audioJACK::renamePort( audioPort * _port )
int audioJACK::processCallback( jack_nframes_t _nframes, void * _udata )
{
audioJACK * _this = static_cast<audioJACK *>( _udata );
// _this->m_processCallbackMutex.lock();
/* printf( "%f\n", jack_cpu_load( _this->m_client ) );*/
@@ -444,8 +438,6 @@ int audioJACK::processCallback( jack_nframes_t _nframes, void * _udata )
}
}
// _this->m_processCallbackMutex.unlock();
return( 0 );
}

View File

@@ -64,6 +64,7 @@ audioPort::~audioPort()
}
delete[] m_firstBuffer;
delete[] m_secondBuffer;
delete m_effects;
}

View File

@@ -42,25 +42,21 @@
#endif
/*#ifdef HAVE_STDLIB_H*/
#include <stdlib.h>
/*#endif*/
#include "arp_and_chords_tab_widget.h"
#include "combobox.h"
#include "embed.h"
#include "engine.h"
#include "group_box.h"
#include "gui_templates.h"
#include "instrument_track.h"
#include "knob.h"
#include "led_checkbox.h"
#include "note_play_handle.h"
#include "song_editor.h"
#include "group_box.h"
#include "pixmap_button.h"
#include "knob.h"
#include "tooltip.h"
#include "gui_templates.h"
#include "tempo_sync_knob.h"
#include "instrument_track.h"
#include "led_checkbox.h"
#include "preset_preview_play_handle.h"
#include "combobox.h"
#include "tempo_sync_knob.h"
#include "tooltip.h"
@@ -469,21 +465,12 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n )
_n->getVolume(),
_n->getPanning(),
_n->detuning() );
// duplicate note-play-handle, only note is
// create sub-note-play-handle, only note is
// different
notePlayHandle * note_play_handle =
new notePlayHandle(
_n->getInstrumentTrack(),
_n->framesAhead(),
_n->frames(), note_copy );
note_play_handle->setBBTrackFrom( _n );
#if SINGERBOT_SUPPORT
note_play_handle->setPatternIndex(
_n->patternIndex() );
#endif
// add sub-note to base-note, now all stuff is
// done by notePlayHandle::play_note()
_n->addSubNote( note_play_handle );
new notePlayHandle( _n->getInstrumentTrack(),
_n->framesAhead(),
_n->frames(), note_copy,
_n );
}
}
}
@@ -631,26 +618,16 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n )
vol_level ),
_n->getPanning(), _n->detuning() );
// duplicate note-play-handle, only ptr to note is different
// create sub-note-play-handle, only ptr to note is different
// and is_arp_note=TRUE
notePlayHandle * note_play_handle = new notePlayHandle(
_n->getInstrumentTrack(),
( ( m_arpModeComboBox->value() !=
FREE ) ?
new notePlayHandle( _n->getInstrumentTrack(),
( ( m_arpModeComboBox->value() != FREE ) ?
cnphv.first()->framesAhead() :
_n->framesAhead() ) +
frames_processed,
gated_frames,
new_note,
TRUE );
note_play_handle->setBBTrackFrom( _n );
#if SINGERBOT_SUPPORT
note_play_handle->setPatternIndex( _n->patternIndex() );
#endif
// add sub-note to base-note - now all stuff is done by
// notePlayHandle::playNote()
_n->addSubNote( note_play_handle );
_n, TRUE );
// update counters
frames_processed += arp_frames;
@@ -698,21 +675,9 @@ void arpAndChordsTabWidget::loadSettings( const QDomElement & _this )
m_arpRangeKnob->loadSettings( _this, "arprange" );
m_arpTimeKnob->loadSettings( _this, "arptime" );
m_arpGateKnob->loadSettings( _this, "arpgate" );
if( _this.hasAttribute( "arpdir" ) )
{
m_arpDirectionBtnGrp->setInitValue(
_this.attribute( "arpdir" ).toInt() - 1 );
m_arpGroupBox->setState(
_this.attribute( "arpdir" ).toInt() != OFF &&
!_this.attribute( "arpdisabled" ).toInt() );
}
else
{
m_arpDirectionBtnGrp->loadSettings( _this, "arpdir" );
m_arpGroupBox->setState(
!_this.attribute( "arpdisabled" ).toInt() );
}
m_arpDirectionBtnGrp->loadSettings( _this, "arpdir" );
m_arpGroupBox->setState( !_this.attribute( "arpdisabled" ).toInt() );
// Keep compatibility with version 2.1 file format
if( _this.hasAttribute( "arpsyncmode" ) )
{

View File

@@ -89,7 +89,6 @@ QPixmap * automationEditor::s_toolMove = NULL;
automationEditor::automationEditor( void ) :
QWidget( engine::getMainWindow()->workspace() ),
m_paintPixmap(),
m_pattern( NULL ),
m_min_level( 0 ),
m_max_level( 0 ),
@@ -502,14 +501,10 @@ inline void automationEditor::drawValueRect( QPainter & _p,
void automationEditor::updatePaintPixmap( void )
void automationEditor::updatePaintPixmap( QPixmap & _p )
{
if( m_paintPixmap.isNull() == TRUE || m_paintPixmap.size() != size() )
{
m_paintPixmap = QPixmap( size() );
}
m_paintPixmap.fill( QColor( 0, 0, 0 ) );
QPainter p( &m_paintPixmap );
_p.fill( QColor( 0, 0, 0 ) );
QPainter p( &_p );
// set font-size to 8
p.setFont( pointSize<8>( p.font() ) );
@@ -1562,9 +1557,30 @@ void automationEditor::mouseMoveEvent( QMouseEvent * _me )
inline void automationEditor::drawCross( QPainter & _p )
{
QPoint mouse_pos = mapFromGlobal( QCursor::pos() );
int level = getLevel( mouse_pos.y() );
int grid_bottom = height() - SCROLLBAR_SIZE - 1;
int cross_y = m_y_auto ?
grid_bottom - (int)roundf( ( grid_bottom - TOP_MARGIN )
* ( level - m_min_level )
/ (float)( m_max_level - m_min_level ) ) :
grid_bottom - ( level - m_bottom_level ) * m_y_delta;
_p.setPen( QColor( 0xFF, 0x33, 0x33 ) );
_p.drawLine( VALUES_WIDTH, cross_y, width(), cross_y );
_p.drawLine( mouse_pos.x(), TOP_MARGIN, mouse_pos.x(),
height() - SCROLLBAR_SIZE );
}
void automationEditor::paintEvent( QPaintEvent * )
{
updatePaintPixmap();
QPixmap paintPixmap( size() );
updatePaintPixmap( paintPixmap );
#ifdef QT4
QPainter p( this );
#else
@@ -1573,7 +1589,7 @@ void automationEditor::paintEvent( QPaintEvent * )
QPainter p( &draw_pm, this );
#endif
p.drawPixmap( 0, 0, m_paintPixmap );
p.drawPixmap( 0, 0, paintPixmap );
p.setClipRect( VALUES_WIDTH, TOP_MARGIN, width() - VALUES_WIDTH,
height() - TOP_MARGIN - SCROLLBAR_SIZE );
@@ -1604,26 +1620,6 @@ void automationEditor::paintEvent( QPaintEvent * )
inline void automationEditor::drawCross( QPainter & _p )
{
QPoint mouse_pos = mapFromGlobal( QCursor::pos() );
int level = getLevel( mouse_pos.y() );
int grid_bottom = height() - SCROLLBAR_SIZE - 1;
int cross_y = m_y_auto ?
grid_bottom - (int)roundf( ( grid_bottom - TOP_MARGIN )
* ( level - m_min_level )
/ (float)( m_max_level - m_min_level ) ) :
grid_bottom - ( level - m_bottom_level ) * m_y_delta;
_p.setPen( QColor( 0xFF, 0x33, 0x33 ) );
_p.drawLine( VALUES_WIDTH, cross_y, width(), cross_y );
_p.drawLine( mouse_pos.x(), TOP_MARGIN, mouse_pos.x(),
height() - SCROLLBAR_SIZE );
}
// responsible for moving/resizing scrollbars after window-resizing
void automationEditor::resizeEvent( QResizeEvent * )
{
@@ -1737,6 +1733,15 @@ int automationEditor::getLevel( int _y )
inline bool automationEditor::inBBEditor( void )
{
return( m_pattern->getTrack()->getTrackContainer()
== engine::getBBEditor() );
}
void automationEditor::play( void )
{
if( validPattern() == FALSE )
@@ -2226,15 +2231,6 @@ void automationEditor::updateTopBottomLevels( void )
inline bool automationEditor::inBBEditor( void )
{
return( m_pattern->getTrack()->getTrackContainer()
== engine::getBBEditor() );
}
void automationEditor::update( void )
{
QWidget::update();

View File

@@ -0,0 +1,302 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* automation_pattern.cpp - implementation of class automationPattern which
* holds dynamic values
*
* Copyright (c) 2006-2007 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#include "qt3support.h"
#ifdef QT4
#include <Qt/QtXml>
#else
#include <qdom.h>
#define value data
#endif
#include "automation_pattern.h"
#include "automation_editor.h"
#include "engine.h"
#include "level_object.h"
#include "note.h"
#include "templates.h"
#include "track.h"
automationPattern::automationPattern( track * _track, levelObject * _object ) :
m_track( _track ),
m_object( _object ),
m_update_first( TRUE ),
m_dynamic( FALSE )
{
}
automationPattern::automationPattern( const automationPattern & _pat_to_copy ) :
QObject(),
journallingObject(),
m_track( _pat_to_copy.m_track ),
m_object( _pat_to_copy.m_object ),
m_update_first( _pat_to_copy.m_update_first ),
m_dynamic( _pat_to_copy.m_dynamic )
{
for( timeMap::const_iterator it = _pat_to_copy.m_time_map.begin();
it != _pat_to_copy.m_time_map.end(); ++it )
{
m_time_map[it.key()] = it.value();
}
if( m_dynamic && m_track )
{
m_track->addAutomationPattern( this );
}
}
automationPattern::automationPattern( const automationPattern & _pat_to_copy,
levelObject * _object ) :
m_track( _pat_to_copy.m_track ),
m_object( _object ),
m_update_first( _pat_to_copy.m_update_first ),
m_dynamic( _pat_to_copy.m_dynamic )
{
for( timeMap::const_iterator it = _pat_to_copy.m_time_map.begin();
it != _pat_to_copy.m_time_map.end(); ++it )
{
m_time_map[it.key()] = it.value();
}
if( m_dynamic && m_track )
{
m_track->addAutomationPattern( this );
}
}
automationPattern::~automationPattern()
{
if( m_dynamic && m_track )
{
m_track->removeAutomationPattern( this );
}
if( engine::getAutomationEditor()
&& engine::getAutomationEditor()->currentPattern() == this )
{
engine::getAutomationEditor()->setCurrentPattern( NULL );
}
}
//TODO: Improve this
midiTime automationPattern::length( void ) const
{
Sint32 max_length = 0;
for( timeMap::const_iterator it = m_time_map.begin();
it != m_time_map.end();
++it )
{
max_length = tMax<Sint32>( max_length, -it.key() );
}
if( max_length % 64 == 0 )
{
return( midiTime( tMax<Sint32>( max_length, 64 ) ) );
}
return( midiTime( tMax( midiTime( max_length ).getTact() + 1, 1 ),
0 ) );
}
midiTime automationPattern::putValue( const midiTime & _time, const int _value,
const bool _quant_pos )
{
midiTime new_time = _quant_pos ?
note::quantized( _time,
engine::getAutomationEditor()->quantization() ) :
_time;
m_time_map[-new_time] = _value;
if( !m_dynamic && new_time != 0 )
{
m_dynamic = TRUE;
if( m_track )
{
m_track->addAutomationPattern( this );
}
}
return( new_time );
}
void automationPattern::removeValue( const midiTime & _time )
{
if( _time != 0 )
{
m_time_map.remove( -_time );
if( m_time_map.size() == 1 )
{
m_dynamic = FALSE;
m_object->setLevel( m_time_map[0] );
if( m_track )
{
m_track->removeAutomationPattern( this );
}
}
}
}
void automationPattern::clear( void )
{
m_time_map.clear();
if( engine::getAutomationEditor()->currentPattern() == this )
{
engine::getAutomationEditor()->update();
}
}
int automationPattern::valueAt( const midiTime & _time )
{
return( m_time_map.lowerBound( -_time ).value() );
}
void automationPattern::saveSettings( QDomDocument & _doc, QDomElement & _this )
{
for( timeMap::iterator it = m_time_map.begin(); it != m_time_map.end();
++it )
{
QDomElement element = _doc.createElement( "time" );
element.setAttribute( "pos", -it.key() );
element.setAttribute( "value", m_object->levelToLabel(
it.value() ) );
_this.appendChild( element );
}
}
void automationPattern::loadSettings( const QDomElement & _this )
{
clear();
for( QDomNode node = _this.firstChild(); !node.isNull();
node = node.nextSibling() )
{
QDomElement element = node.toElement();
if( element.isNull() || element.tagName() != "time" )
{
continue;
}
m_time_map[-element.attribute( "pos" ).toInt()]
= m_object->labelToLevel(
element.attribute( "value" ) );
}
if( !m_dynamic )
{
m_dynamic = TRUE;
if( m_track )
{
m_track->addAutomationPattern( this );
}
}
}
void automationPattern::openInAutomationEditor( void )
{
engine::getAutomationEditor()->setCurrentPattern( this );
engine::getAutomationEditor()->show();
engine::getAutomationEditor()->setFocus();
}
const QString automationPattern::name( void )
{
if( m_track )
{
QString widget_name = dynamic_cast<QWidget *>( m_object )
->accessibleName();
return( m_track->name() + " - " + widget_name );
}
else
{
return( m_object->displayName() );
}
}
void automationPattern::processMidiTime( const midiTime & _time )
{
if( _time >= 0 )
{
m_object->setLevel( m_time_map.lowerBound( -_time ).value() );
}
}
#undef value
#include "automation_pattern.moc"
#endif

View File

@@ -661,7 +661,11 @@ void configManager::nextButtonClicked( void )
void configManager::switchPage( csize _pg )
{
#ifdef QT4
if( m_currentPage >= 0 && m_currentPage < m_pages.size() )
#else
if( m_currentPage < m_pages.size() )
#endif
{
m_pages[m_currentPage].first->hide();
#ifdef QT4

View File

@@ -77,10 +77,8 @@ bool FASTCALL effect::processAudioBuffer( surroundSampleFrame * _buf,
void FASTCALL effect::setGate( float _level )
{
m_processLock.lock();
m_gate = _level * _level * m_processors *
engine::getMixer()->framesPerAudioBuffer();
m_processLock.unlock();
}

View File

@@ -26,6 +26,10 @@
#include "effect_chain.h"
#include "engine.h"
effectChain::effectChain( void ) :
m_bypassed( TRUE )
@@ -35,15 +39,13 @@ effectChain::effectChain( void ) :
effectChain::~ effectChain()
effectChain::~effectChain()
{
m_processLock.lock();
for( Uint32 eff = 0; eff < m_effects.count(); eff++ )
for( effect_list_t::size_type eff = 0; eff < m_effects.count(); eff++ )
{
free( m_effects[eff] );
delete m_effects[eff];
}
m_effects.clear();
m_processLock.unlock();
}
@@ -51,33 +53,18 @@ effectChain::~ effectChain()
void FASTCALL effectChain::appendEffect( effect * _effect )
{
m_processLock.lock();
engine::getMixer()->lock();
m_effects.append( _effect );
m_processLock.unlock();
engine::getMixer()->unlock();
}
void FASTCALL effectChain::deleteEffect( effect * _effect )
void FASTCALL effectChain::removeEffect( effect * _effect )
{
m_processLock.lock();
effect_list_t::iterator which = NULL;
for( effect_list_t::iterator it = m_effects.begin();
it != m_effects.end(); it++ )
{
if( (*it) == _effect )
{
which = it;
break;
}
}
if( which != NULL )
{
m_effects.erase( which );
}
m_processLock.unlock();
engine::getMixer()->lock();
m_effects.erase( qFind( m_effects.begin(), m_effects.end(), _effect ) );
engine::getMixer()->unlock();
}
@@ -85,8 +72,6 @@ void FASTCALL effectChain::deleteEffect( effect * _effect )
void FASTCALL effectChain::moveDown( effect * _effect )
{
m_processLock.lock();
if( _effect != m_effects.last() )
{
int i = 0;
@@ -103,8 +88,6 @@ void FASTCALL effectChain::moveDown( effect * _effect )
m_effects[i + 1] = _effect;
m_effects[i] = temp;
}
m_processLock.unlock();
}
@@ -112,8 +95,6 @@ void FASTCALL effectChain::moveDown( effect * _effect )
void FASTCALL effectChain::moveUp( effect * _effect )
{
m_processLock.lock();
if( _effect != m_effects.first() )
{
int i = 0;
@@ -130,8 +111,6 @@ void FASTCALL effectChain::moveUp( effect * _effect )
m_effects[i - 1] = _effect;
m_effects[i] = temp;
}
m_processLock.unlock();
}
@@ -140,7 +119,7 @@ void FASTCALL effectChain::moveUp( effect * _effect )
bool FASTCALL effectChain::processAudioBuffer( surroundSampleFrame * _buf,
const fpab_t _frames )
{
if( m_bypassed || ! m_processLock.tryLock() )
if( m_bypassed )
{
return( FALSE );
}
@@ -150,7 +129,6 @@ bool FASTCALL effectChain::processAudioBuffer( surroundSampleFrame * _buf,
{
more_effects |= (*it)->processAudioBuffer( _buf, _frames );
}
m_processLock.unlock();
return( more_effects );
}

View File

@@ -40,6 +40,7 @@
#endif
#include "effect_control_dialog.h"
#include "effect.h"
effectControlDialog::effectControlDialog( QWidget * _parent, effect * _eff ) :

View File

@@ -52,6 +52,7 @@
#include "embed.h"
#include "effect_select_dialog.h"
#include "rack_plugin.h"
#include "rack_view.h"
#include "audio_port.h"

View File

@@ -104,6 +104,10 @@ void engine::destroy( void )
delete s_automationEditor;
s_automationEditor = NULL;
#ifdef LADSPA_SUPPORT
delete s_ladspaManager;
#endif
presetPreviewPlayHandle::cleanUp();
// now we can clean up all allocated buffer

View File

@@ -121,14 +121,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount,
m_lfoFrame( 0 ),
m_lfoAmountIsZero( FALSE ),
m_lfoShapeData( NULL ),
m_lfoShape( SIN ),
m_busyMutex(
#ifdef QT3
TRUE
#else
QMutex::Recursive
#endif
)
m_lfoShape( SIN )
{
if( s_envGraph == NULL )
{
@@ -511,15 +504,44 @@ envelopeAndLFOWidget::~envelopeAndLFOWidget()
inline sample_t envelopeAndLFOWidget::lfoShapeSample( fpab_t _frame_offset )
{
f_cnt_t frame = ( m_lfoFrame + _frame_offset ) % m_lfoOscillationFrames;
const float phase = frame / static_cast<float>(
m_lfoOscillationFrames );
sample_t shape_sample;
switch( m_lfoShape )
{
case TRIANGLE:
shape_sample = oscillator::triangleSample( phase );
break;
case SQUARE:
shape_sample = oscillator::squareSample( phase );
break;
case SAW:
shape_sample = oscillator::sawSample( phase );
break;
case USER:
shape_sample = m_userWave.userWaveSample( phase );
break;
case SIN:
default:
shape_sample = oscillator::sinSample( phase );
break;
}
return( shape_sample * m_lfoAmount );
}
void envelopeAndLFOWidget::updateLFOShapeData( void )
{
const fpab_t frames = engine::getMixer()->framesPerAudioBuffer();
m_userWave.lock();
for( fpab_t offset = 0; offset < frames; ++offset )
{
m_lfoShapeData[offset] = lfoShapeSample( offset );
}
m_userWave.unlock();
m_bad_lfoShapeData = FALSE;
}
@@ -655,8 +677,6 @@ void envelopeAndLFOWidget::saveSettings( QDomDocument & _doc,
void envelopeAndLFOWidget::loadSettings( const QDomElement & _this )
{
m_busyMutex.lock();
m_predelayKnob->loadSettings( _this, "pdel" );
m_attackKnob->loadSettings( _this, "att" );
m_holdKnob->loadSettings( _this, "hold" );
@@ -682,8 +702,6 @@ void envelopeAndLFOWidget::loadSettings( const QDomElement & _this )
m_userWave.setAudioFile( _this.attribute( "userwavefile" ) );
m_busyMutex.unlock();
updateSampleVars();
}
@@ -939,10 +957,11 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * )
void envelopeAndLFOWidget::updateSampleVars( void )
{
m_busyMutex.lock();
engine::getMixer()->lock();
const float frames_per_env_seg = SECS_PER_ENV_SEGMENT *
engine::getMixer()->sampleRate();
// TODO: Remove the expKnobVals, time should be linear
const f_cnt_t predelay_frames = static_cast<f_cnt_t>(
frames_per_env_seg *
expKnobVal( m_predelayKnob->value() ) );
@@ -979,46 +998,43 @@ void envelopeAndLFOWidget::updateSampleVars( void )
m_rFrames = 0;
}
sample_t * new_pahd_env = new sample_t[m_pahdFrames];
sample_t * new_r_env = new sample_t[m_rFrames];
delete[] m_pahdEnv;
delete[] m_rEnv;
m_pahdEnv = new sample_t[m_pahdFrames];
m_rEnv = new sample_t[m_rFrames];
for( f_cnt_t i = 0; i < predelay_frames; ++i )
{
new_pahd_env[i] = m_amountAdd;
m_pahdEnv[i] = m_amountAdd;
}
f_cnt_t add = predelay_frames;
for( f_cnt_t i = 0; i < attack_frames; ++i )
{
new_pahd_env[add+i] = ( (float)i / attack_frames ) *
m_pahdEnv[add + i] = ( (float)i / attack_frames ) *
m_amount + m_amountAdd;
}
add += attack_frames;
for( f_cnt_t i = 0; i < hold_frames; ++i )
{
new_pahd_env[add+i] = m_amount + m_amountAdd;
m_pahdEnv[add + i] = m_amount + m_amountAdd;
}
add += hold_frames;
for( f_cnt_t i = 0; i < decay_frames; ++i )
{
new_pahd_env[add+i] = ( m_sustainLevel + ( 1.0f -
m_pahdEnv[add + i] = ( m_sustainLevel + ( 1.0f -
(float)i / decay_frames ) *
( 1.0f - m_sustainLevel ) ) *
m_amount + m_amountAdd;
}
delete[] m_pahdEnv;
delete[] m_rEnv;
m_pahdEnv = new_pahd_env;
m_rEnv = new_r_env;
for( f_cnt_t i = 0; i < m_rFrames; ++i )
{
new_r_env[i] = ( (float)( m_rFrames - i ) / m_rFrames
m_rEnv[i] = ( (float)( m_rFrames - i ) / m_rFrames
// * m_sustainLevel
) * m_amount;
}
@@ -1058,40 +1074,9 @@ void envelopeAndLFOWidget::updateSampleVars( void )
m_bad_lfoShapeData = TRUE;
m_busyMutex.unlock();
update();
}
inline sample_t envelopeAndLFOWidget::lfoShapeSample( fpab_t _frame_offset )
{
f_cnt_t frame = ( m_lfoFrame + _frame_offset ) % m_lfoOscillationFrames;
const float phase = frame / static_cast<float>(
m_lfoOscillationFrames );
sample_t shape_sample;
switch( m_lfoShape )
{
case TRIANGLE:
shape_sample = oscillator::triangleSample( phase );
break;
case SQUARE:
shape_sample = oscillator::squareSample( phase );
break;
case SAW:
shape_sample = oscillator::sawSample( phase );
break;
case USER:
shape_sample = m_userWave.userWaveSample( phase );
break;
case SIN:
default:
shape_sample = oscillator::sinSample( phase );
break;
}
return( shape_sample * m_lfoAmount );
engine::getMixer()->unlock();
}

View File

@@ -41,16 +41,17 @@
#include "envelope_tab_widget.h"
#include "envelope_and_lfo_widget.h"
#include "note_play_handle.h"
#include "knob.h"
#include "pixmap_button.h"
#include "group_box.h"
#include "tab_widget.h"
#include "combobox.h"
#include "embed.h"
#include "engine.h"
#include "envelope_and_lfo_widget.h"
#include "group_box.h"
#include "gui_templates.h"
#include "instrument_track.h"
#include "combobox.h"
#include "knob.h"
#include "note_play_handle.h"
#include "pixmap_button.h"
#include "tab_widget.h"
@@ -238,10 +239,8 @@ float FASTCALL envelopeTabWidget::volumeLevel( notePlayHandle * _n,
}
float volume_level;
m_envLFOWidgets[VOLUME]->lock();
m_envLFOWidgets[VOLUME]->fillLevel( &volume_level, _frame,
release_begin, 1 );
m_envLFOWidgets[VOLUME]->unlock();
return( volume_level );
}
@@ -285,9 +284,6 @@ void envelopeTabWidget::processAudioBuffer( sampleFrame * _ab,
float * cut_buf = NULL;
float * res_buf = NULL;
m_envLFOWidgets[CUT]->lock();
m_envLFOWidgets[RES]->lock();
if( m_envLFOWidgets[CUT]->used() )
{
cut_buf = new float[_frames];
@@ -377,14 +373,10 @@ void envelopeTabWidget::processAudioBuffer( sampleFrame * _ab,
}
}
m_envLFOWidgets[RES]->unlock();
m_envLFOWidgets[CUT]->unlock();
delete[] cut_buf;
delete[] res_buf;
}
m_envLFOWidgets[VOLUME]->lock();
if( m_envLFOWidgets[VOLUME]->used() )
{
float * vol_buf = new float[_frames];
@@ -403,7 +395,6 @@ void envelopeTabWidget::processAudioBuffer( sampleFrame * _ab,
}
delete[] vol_buf;
}
m_envLFOWidgets[VOLUME]->unlock();
/* else if( m_envLFOWidgets[VOLUME]->used() == FALSE && m_envLFOWidgets[PANNING]->used() )
{

View File

@@ -48,20 +48,21 @@
#include "file_browser.h"
#include "song_editor.h"
#include "bb_editor.h"
#include "config_mgr.h"
#include "debug.h"
#include "embed.h"
#include "engine.h"
#include "gui_templates.h"
#include "instrument.h"
#include "instrument_track.h"
#include "main_window.h"
#include "mmp.h"
#include "preset_preview_play_handle.h"
#include "sample_play_handle.h"
#include "debug.h"
#include "gui_templates.h"
#include "instrument.h"
#include "text_float.h"
#include "song_editor.h"
#include "string_pair_drag.h"
#include "main_window.h"
#include "config_mgr.h"
#include "text_float.h"
@@ -297,67 +298,67 @@ void fileBrowser::contextMenuRequest( QListViewItem * i, const QPoint &, int )
void fileBrowser::sendToActiveInstrumentTrack( void )
{
if( engine::getMainWindow()->workspace() != NULL )
if( engine::getMainWindow()->workspace() == NULL )
{
// get all windows opened in the workspace
QWidgetList pl =
engine::getMainWindow()->workspace()->windowList(
return;
}
// get all windows opened in the workspace
QWidgetList pl = engine::getMainWindow()->workspace()->windowList(
#if QT_VERSION >= 0x030200
QWorkspace::StackingOrder
#endif
);
#ifdef QT4
QListIterator<QWidget *> w( pl );
w.toBack();
// now we travel through the window-list until we find an
// instrument-track
while( w.hasPrevious() )
{
instrumentTrack * ct = dynamic_cast<instrumentTrack *>(
QListIterator<QWidget *> w( pl );
w.toBack();
// now we travel through the window-list until we find an
// instrument-track
while( w.hasPrevious() )
{
instrumentTrack * ct = dynamic_cast<instrumentTrack *>(
w.previous() );
#else
QWidget * w = pl.last();
// now we travel through the window-list until we find an
// instrument-track
while( w != NULL )
{
instrumentTrack * ct =
dynamic_cast<instrumentTrack *>( w );
QWidget * w = pl.last();
// now we travel through the window-list until we find an
// instrument-track
while( w != NULL )
{
instrumentTrack * ct = dynamic_cast<instrumentTrack *>( w );
#endif
if( ct != NULL && ct->isHidden() == FALSE )
if( ct != NULL && ct->isHidden() == FALSE )
{
// ok, it's an instrument-track, so we can apply the
// sample or the preset
engine::getMixer()->lock();
if( m_contextMenuItem->type() == fileItem::SAMPLE_FILE )
{
// ok, it's an instrument-track, so we can apply
// the sample or the preset
if( m_contextMenuItem->type() ==
fileItem::SAMPLE_FILE )
{
instrument * afp = ct->loadInstrument(
instrument * afp = ct->loadInstrument(
engine::sampleExtensions()
[m_contextMenuItem
->extension()] );
if( afp != NULL )
{
afp->setParameter( "samplefile",
m_contextMenuItem->fullName() );
}
}
else if( m_contextMenuItem->type() ==
fileItem::PRESET_FILE )
if( afp != NULL )
{
multimediaProject mmp(
afp->setParameter( "samplefile",
m_contextMenuItem->fullName() );
ct->loadTrackSpecificSettings(
mmp.content().
}
}
else if( m_contextMenuItem->type() ==
fileItem::PRESET_FILE )
{
multimediaProject mmp(
m_contextMenuItem->fullName() );
ct->loadTrackSpecificSettings( mmp.content().
firstChild().
toElement() );
}
ct->toggledInstrumentTrackButton( TRUE );
break;
}
#ifndef QT4
w = pl.prev();
#endif
ct->toggledInstrumentTrackButton( TRUE );
engine::getMixer()->unlock();
break;
}
#ifndef QT4
w = pl.prev();
#endif
}
}
@@ -366,6 +367,7 @@ void fileBrowser::sendToActiveInstrumentTrack( void )
void fileBrowser::openInNewInstrumentTrack( trackContainer * _tc )
{
engine::getMixer()->lock();
if( m_contextMenuItem->type() == fileItem::SAMPLE_FILE )
{
instrumentTrack * ct = dynamic_cast<instrumentTrack *>(
@@ -397,6 +399,7 @@ void fileBrowser::openInNewInstrumentTrack( trackContainer * _tc )
ct->toggledInstrumentTrackButton( TRUE );
}
}
engine::getMixer()->unlock();
}
@@ -451,50 +454,53 @@ void listView::contentsMouseDoubleClickEvent( QMouseEvent * _me )
Q3ListView::contentsMouseDoubleClickEvent( _me );
fileItem * f = dynamic_cast<fileItem *>( itemAt(
contentsToViewport( _me->pos() ) ) );
if( f != NULL )
if( f == NULL )
{
if( f->type() == fileItem::SAMPLE_FILE )
{
// samples are per default opened in bb-editor because
// they're likely drum-samples etc.
instrumentTrack * it = dynamic_cast<instrumentTrack *>(
return;
}
if( f->type() == fileItem::SAMPLE_FILE )
{
// samples are per default opened in bb-editor because they're
// likely drum-samples etc.
engine::getMixer()->lock();
instrumentTrack * it = dynamic_cast<instrumentTrack *>(
track::create( track::INSTRUMENT_TRACK,
engine::getBBEditor() ) );
#ifdef LMMS_DEBUG
assert( it != NULL );
assert( it != NULL );
#endif
instrument * afp = it->loadInstrument(
instrument * afp = it->loadInstrument(
engine::sampleExtensions()[f->extension()] );
if( afp != NULL )
{
afp->setParameter( "samplefile",
f->fullName() );
}
it->toggledInstrumentTrackButton( TRUE );
}
else if( f->type() == fileItem::PRESET_FILE )
if( afp != NULL )
{
// presets are per default opened in bb-editor
multimediaProject mmp( f->fullName() );
track * t = track::create( track::INSTRUMENT_TRACK,
engine::getBBEditor() );
instrumentTrack * it = dynamic_cast<instrumentTrack *>(
t );
if( it != NULL )
{
it->loadTrackSpecificSettings( mmp.content().
afp->setParameter( "samplefile", f->fullName() );
}
it->toggledInstrumentTrackButton( TRUE );
engine::getMixer()->unlock();
}
else if( f->type() == fileItem::PRESET_FILE )
{
// presets are per default opened in bb-editor
multimediaProject mmp( f->fullName() );
engine::getMixer()->lock();
instrumentTrack * it = dynamic_cast<instrumentTrack *>(
track::create( track::INSTRUMENT_TRACK,
engine::getBBEditor() ) );
if( it != NULL )
{
it->loadTrackSpecificSettings( mmp.content().
firstChild().
toElement() );
it->toggledInstrumentTrackButton( TRUE );
}
it->toggledInstrumentTrackButton( TRUE );
}
else if( f->type() == fileItem::PROJECT_FILE )
engine::getMixer()->unlock();
}
else if( f->type() == fileItem::PROJECT_FILE )
{
if( engine::getSongEditor()->mayChangeProject() )
{
if( engine::getSongEditor()->mayChangeProject() )
{
engine::getSongEditor()->loadProject(
f->fullName() );
}
engine::getSongEditor()->loadProject( f->fullName() );
}
}
}

View File

@@ -34,8 +34,7 @@ instrument::instrument( instrumentTrack * _instrument_track,
const descriptor * _descriptor ) :
QWidget( _instrument_track->tabWidgetParent() ),
plugin( _descriptor ),
m_instrumentTrack( _instrument_track ),
m_valid( TRUE )
m_instrumentTrack( _instrument_track )
{
setFixedSize( 250, 250 );
m_instrumentTrack->setWindowIcon( *getDescriptor()->logo );
@@ -46,7 +45,6 @@ instrument::instrument( instrumentTrack * _instrument_track,
instrument::~instrument()
{
invalidate();
}
@@ -98,4 +96,14 @@ instrument * instrument::instantiate( const QString & _plugin_name,
}
bool instrument::isFromTrack( const track * _track ) const
{
return( m_instrumentTrack == _track );
}
#endif

View File

@@ -48,15 +48,17 @@
#include "midi_tab_widget.h"
#include "embed.h"
#include "engine.h"
#include "gui_templates.h"
#include "instrument_track.h"
#include "midi_client.h"
#include "midi_port.h"
#include "tab_widget.h"
#include "led_checkbox.h"
#include "lcd_spinbox.h"
#include "tooltip.h"
#include "song_editor.h"
#include "midi_client.h"
#include "embed.h"
#include "tab_widget.h"
#include "tooltip.h"
@@ -81,6 +83,7 @@ midiTabWidget::midiTabWidget( instrumentTrack * _instrument_track,
m_inputChannelSpinBox->setValue( m_midiPort->inputChannel() + 1 );
m_inputChannelSpinBox->setLabel( tr( "CHANNEL" ) );
m_inputChannelSpinBox->move( 28, 52 );
m_inputChannelSpinBox->setEnabled( FALSE );
connect( m_inputChannelSpinBox, SIGNAL( valueChanged( int ) ),
this, SLOT( inputChannelChanged( int ) ) );
inputChannelChanged( m_inputChannelSpinBox->value() );
@@ -93,6 +96,7 @@ midiTabWidget::midiTabWidget( instrumentTrack * _instrument_track,
//m_outputChannelSpinBox->addTextForValue( 0, "---" );
m_outputChannelSpinBox->setLabel( tr( "CHANNEL" ) );
m_outputChannelSpinBox->move( 28, 132 );
m_outputChannelSpinBox->setEnabled( FALSE );
connect( m_outputChannelSpinBox, SIGNAL( valueChanged( int ) ),
this, SLOT( outputChannelChanged( int ) ) );
outputChannelChanged( m_outputChannelSpinBox->value() );

View File

@@ -71,8 +71,11 @@ mixer::mixer( void ) :
m_masterGain( 1.0f ),
m_audioDev( NULL ),
m_oldAudioDev( NULL ),
m_mixMutex(),
m_mixMutexLockLevel( 0 )
#ifndef QT3
m_mixMutex( QMutex::Recursive )
#else
m_mixMutex( TRUE )
#endif
{
if( configManager::inst()->value( "mixer", "framesperaudiobuffer"
).toInt() >= 32 )
@@ -250,23 +253,19 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
// remove all play-handles that have to be deleted and delete
// them if they still exist...
// maybe this algorithm could be optimized...
while( !m_playHandlesToRemove.empty() )
constPlayHandleVector::iterator it_rem = m_playHandlesToRemove.begin();
while( it_rem != m_playHandlesToRemove.end() )
{
playHandleVector::iterator it = m_playHandles.begin();
playHandleVector::iterator it = qFind( m_playHandles.begin(),
m_playHandles.end(), *it_rem );
while( it != m_playHandles.end() )
if( it != m_playHandles.end() )
{
if( *it == m_playHandlesToRemove.front() )
{
delete *it;
m_playHandles.erase( it );
//delete m_playHandlesToRemove.front();
break;
}
++it;
delete *it;
m_playHandles.erase( it );
}
m_playHandlesToRemove.erase( m_playHandlesToRemove.begin() );
m_playHandlesToRemove.erase( it_rem );
}
// now swap the buffers... current buffer becomes next (last)
@@ -395,18 +394,15 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
// removes all play-handles. this is neccessary, when the song is stopped ->
// all remaining notes etc. would be played until their end
void mixer::clear( bool _everything )
void mixer::clear( void )
{
// TODO: m_midiClient->noteOffAll();
for( playHandleVector::iterator it = m_playHandles.begin();
it != m_playHandles.end(); ++it )
{
// we must not delete instrument-play-handles as they exist
// during the whole lifetime of an instrument - exception if
// parameter _everything is true (which is the case when
// clearing song for example)
if( _everything == TRUE ||
( *it )->type() != playHandle::InstrumentPlayHandle )
// during the whole lifetime of an instrument
if( ( *it )->type() != playHandle::InstrumentPlayHandle )
{
m_playHandlesToRemove.push_back( *it );
}
@@ -556,13 +552,20 @@ void mixer::restoreAudioDevice( void )
void mixer::checkValidityOfPlayHandles( void )
void mixer::removePlayHandles( track * _track )
{
playHandleVector::iterator it = m_playHandles.begin();
while( it != m_playHandles.end() )
{
( *it )->checkValidity();
++it;
if( ( *it )->isFromTrack( _track ) )
{
delete *it;
m_playHandles.erase( it );
}
else
{
++it;
}
}
}

View File

@@ -41,7 +41,7 @@
#include "note.h"
#include "automatable_object_templates.h"
#include "knob.h"
#include "detuning_helper.h"
#include "templates.h"
@@ -52,7 +52,7 @@ const float note::MAX_DETUNING = 4 * 12.0f;
note::note( const midiTime & _length, const midiTime & _pos,
tones _tone, octaves _octave, volume _volume,
panning _panning, knob * _detuning ) :
panning _panning, detuningHelper * _detuning ) :
m_tone( C ),
m_octave( DEFAULT_OCTAVE ),
m_volume( DEFAULT_VOLUME ),
@@ -70,7 +70,7 @@ note::note( const midiTime & _length, const midiTime & _pos,
if( _detuning )
{
setDetuning( _detuning );
m_detuning = sharedObject::ref( _detuning );
}
else
{
@@ -91,7 +91,7 @@ note::note( const note & _note ) :
m_length( _note.m_length ),
m_pos( _note.m_pos )
{
setDetuning( _note.m_detuning );
m_detuning = sharedObject::ref( _note.m_detuning );
}
@@ -99,18 +99,7 @@ note::note( const note & _note ) :
note::~note()
{
if( m_detuning )
{
knob::autoObj * o = dynamic_cast<knob::autoObj *>( m_detuning );
if( o->data().toInt() )
{
o->setData( o->data().toInt() - 1 );
}
else
{
delete m_detuning;
}
}
sharedObject::unref( m_detuning );
}
@@ -229,7 +218,7 @@ void note::saveSettings( QDomDocument & _doc, QDomElement & _this )
_this.setAttribute( "pan", m_panning );
_this.setAttribute( "len", m_length );
_this.setAttribute( "pos", m_pos );
if( m_length > 0 && m_detuning )
if( m_length > 0 )
{
m_detuning->saveSettings( _doc, _this, "detuning" );
}
@@ -300,26 +289,10 @@ void note::editDetuningPattern( void )
void note::setDetuning( knob * _detuning )
{
m_detuning = _detuning;
if( m_detuning )
{
knob::autoObj * o = dynamic_cast<knob::autoObj *>( m_detuning );
o->setData( o->data().toInt() + 1 );
}
}
void note::createDetuning( void )
{
m_detuning = new knob( knobDark_28, NULL,
QObject::tr( "Note detuning" ),
NULL );
m_detuning = new detuningHelper;
m_detuning->initAutomationPattern();
m_detuning->setData( 0 );
m_detuning->setRange( -MAX_DETUNING, MAX_DETUNING, 0.1f );
}
@@ -328,17 +301,12 @@ void note::createDetuning( void )
void note::detachCurrentDetuning( void )
{
knob::autoObj * o = dynamic_cast<knob::autoObj *>( m_detuning );
if( o->data().toInt() )
{
o->setData( o->data().toInt() - 1 );
QDomDocument doc;
QDomElement parent = doc.createElement( "clone" );
m_detuning->saveSettings( doc, parent );
createDetuning();
m_detuning->loadSettings( parent );
}
QDomDocument doc;
QDomElement parent = doc.createElement( "clone" );
m_detuning->saveSettings( doc, parent );
sharedObject::unref( m_detuning );
createDetuning();
m_detuning->loadSettings( parent );
}
@@ -346,10 +314,6 @@ void note::detachCurrentDetuning( void )
bool note::hasDetuningInfo( void )
{
if( m_detuning == NULL )
{
return( FALSE );
}
automationPattern::timeMap map =
m_detuning->getAutomationPattern()->getTimeMap();
return( map.size() > 1 || map[0] != 0 );

View File

@@ -28,20 +28,43 @@
#include "note_play_handle.h"
#include "automatable_object_templates.h"
#include "instrument_track.h"
#include "config_mgr.h"
#include "detuning_helper.h"
#include "envelope_tab_widget.h"
#include "midi.h"
#include "instrument_track.h"
#include "midi_port.h"
#include "song_editor.h"
#include "piano_widget.h"
#include "config_mgr.h"
#include "project_journal.h"
inline notePlayHandle::baseDetuning::baseDetuning(
detuningHelper * _detuning ) :
m_detuning( _detuning )
{
m_level = m_detuning->getAutomationPattern()->valueAt( 0 );
m_value = m_detuning->value( m_level );
}
inline void notePlayHandle::baseDetuning::setLevel( int _level )
{
m_level = _level;
m_value = m_detuning->value( m_level );
}
notePlayHandle::notePlayHandle( instrumentTrack * _it,
const f_cnt_t _frames_ahead,
const f_cnt_t _frames,
const note & _n,
notePlayHandle * _parent,
const bool _arp_note ) :
playHandle( NotePlayHandle ),
note( _n.length(), _n.pos(), _n.tone(), _n.octave(),
@@ -56,7 +79,7 @@ notePlayHandle::notePlayHandle( instrumentTrack * _it,
m_releaseFramesToDo( 0 ),
m_releaseFramesDone( 0 ),
m_released( FALSE ),
m_baseNote( TRUE ),
m_baseNote( _parent == NULL ),
m_arpNote( _arp_note ),
m_muted( FALSE ),
m_bbTrack( NULL ),
@@ -65,23 +88,30 @@ notePlayHandle::notePlayHandle( instrumentTrack * _it,
#endif
m_orig_bpm( engine::getSongEditor()->getTempo() )
{
if( detuning() )
if( m_baseNote )
{
processMidiTime( pos() );
m_base_detuning = new baseDetuning( detuning() );
m_instrumentTrack->m_processHandles.push_back( this );
connect( detuning(), SIGNAL( valueChanged( float ) ),
this, SLOT( updateFrequency() ) );
}
connect( m_instrumentTrack, SIGNAL( baseNoteChanged() ),
this, SLOT( updateFrequency() ) );
else
{
m_base_detuning = _parent->m_base_detuning;
_parent->m_subNotes.push_back( this );
// if there was an arp-note added and parent is a base-note
// we set arp-note-flag for indicating that parent is an
// arpeggio-base-note
_parent->m_arpNote = arpNote() && _parent->baseNote();
m_bbTrack = _parent->m_bbTrack;
#if SINGERBOT_SUPPORT
m_patternIndex = _parent->m_patternIndex;
#endif
}
updateFrequency();
setFrames( _frames );
if( !configManager::inst()->value( "ui",
"manualchannelpiano" ).toInt() )
{
m_instrumentTrack->m_pianoWidget->setKeyState( key(), TRUE );
}
// send MIDI-note-on-event
m_instrumentTrack->processOutEvent( midiEvent( NOTE_ON,
m_instrumentTrack->m_midiPort->outputChannel(),
@@ -104,16 +134,15 @@ notePlayHandle::~notePlayHandle()
noteOff( 0 );
}
if( m_instrumentTrack != NULL )
if( m_baseNote )
{
if( detuning() )
{
m_instrumentTrack->m_processHandles.removeAll( this );
}
if( m_pluginData != NULL )
{
m_instrumentTrack->deleteNotePluginData( this );
}
delete m_base_detuning;
m_instrumentTrack->m_processHandles.removeAll( this );
}
if( m_pluginData != NULL )
{
m_instrumentTrack->deleteNotePluginData( this );
}
for( notePlayHandleVector::iterator it = m_subNotes.begin();
@@ -131,7 +160,7 @@ notePlayHandle::~notePlayHandle()
void notePlayHandle::play( bool _try_parallelizing )
{
if( m_muted == TRUE || m_instrumentTrack == NULL )
if( m_muted == TRUE )
{
return;
}
@@ -232,30 +261,9 @@ void notePlayHandle::play( bool _try_parallelizing )
void notePlayHandle::checkValidity( void )
bool notePlayHandle::isFromTrack( const track * _track ) const
{
if( m_instrumentTrack != NULL &&
m_instrumentTrack->type() == track::NULL_TRACK )
{
// track-type being track::NULL_TRACK indicates a track whose
// removal is in progress, so we have to invalidate ourself
if( m_released == FALSE )
{
noteOff( 0 );
}
if( m_pluginData )
{
m_instrumentTrack->deleteNotePluginData( this );
}
m_instrumentTrack = NULL;
}
// sub-notes might not be registered at mixer (for example arpeggio-
// notes), so they wouldn't invalidate them-selves
for( notePlayHandleVector::iterator it = m_subNotes.begin();
it != m_subNotes.end(); ++it )
{
( *it )->checkValidity();
}
return( m_instrumentTrack == _track || m_bbTrack == _track );
}
@@ -272,27 +280,14 @@ void notePlayHandle::noteOff( const f_cnt_t _s )
// then set some variables indicating release-state
m_framesBeforeRelease = _s;
if( m_instrumentTrack != NULL )
{
m_releaseFramesToDo = tMax<f_cnt_t>( 10,
m_releaseFramesToDo = tMax<f_cnt_t>( 10,
m_instrumentTrack->m_envWidget->releaseFrames() );
if( !configManager::inst()->value( "ui",
"manualchannelpiano" ).toInt() )
{
m_instrumentTrack->m_pianoWidget->setKeyState( key(),
FALSE );
}
// send MIDI-note-off-event
m_instrumentTrack->processOutEvent( midiEvent( NOTE_OFF,
// send MIDI-note-off-event
m_instrumentTrack->processOutEvent( midiEvent( NOTE_OFF,
m_instrumentTrack->m_midiPort->outputChannel(),
key(), 0 ),
midiTime::fromFrames( m_framesBeforeRelease,
engine::framesPerTact64th() ) );
}
else
{
m_releaseFramesToDo = 10;
}
m_released = TRUE;
}
@@ -302,9 +297,8 @@ void notePlayHandle::noteOff( const f_cnt_t _s )
f_cnt_t notePlayHandle::actualReleaseFramesToDo( void ) const
{
return( ( m_instrumentTrack != NULL ) ?
m_instrumentTrack->m_envWidget->releaseFrames(
arpBaseNote() ) : 0 );
return( m_instrumentTrack->m_envWidget->releaseFrames(
arpBaseNote() ) );
}
@@ -313,7 +307,7 @@ f_cnt_t notePlayHandle::actualReleaseFramesToDo( void ) const
void notePlayHandle::setFrames( const f_cnt_t _frames )
{
m_frames = _frames;
if( m_frames == 0 && m_instrumentTrack != NULL )
if( m_frames == 0 )
{
m_frames = m_instrumentTrack->beatLen( this );
}
@@ -325,10 +319,7 @@ void notePlayHandle::setFrames( const f_cnt_t _frames )
float notePlayHandle::volumeLevel( const f_cnt_t _frame )
{
return( ( m_instrumentTrack != NULL ) ?
m_instrumentTrack->m_envWidget->volumeLevel( this, _frame )
:
0 );
return( m_instrumentTrack->m_envWidget->volumeLevel( this, _frame ) );
}
@@ -420,7 +411,17 @@ bool notePlayHandle::operator==( const notePlayHandle & _nph ) const
void notePlayHandle::updateFrequency( void )
{
m_frequency = m_instrumentTrack->frequency( this );
float pitch = (float)( tone() - m_instrumentTrack->baseTone() +
engine::getSongEditor()->masterPitch() ) / 12.0f +
(float)( octave() - m_instrumentTrack->baseOctave() )
+ m_base_detuning->value() / 12.0f;
m_frequency = BASE_FREQ * powf( 2.0f, pitch );
for( notePlayHandleVector::iterator it = m_subNotes.begin();
it != m_subNotes.end(); ++it )
{
( *it )->updateFrequency();
}
}
@@ -428,7 +429,16 @@ void notePlayHandle::updateFrequency( void )
void notePlayHandle::processMidiTime( const midiTime & _time )
{
detuning()->getAutomationPattern()->processMidiTime( _time - pos() );
if( _time >= pos() )
{
int level = detuning()->getAutomationPattern()->valueAt( _time -
pos() );
if( level != m_base_detuning->level() )
{
m_base_detuning->setLevel( level );
updateFrequency();
}
}
}
@@ -451,7 +461,4 @@ void notePlayHandle::resize( const bpm_t _new_bpm )
#include "note_play_handle.moc"
#endif

View File

@@ -63,22 +63,23 @@
#include "piano_roll.h"
#include "automatable_object_templates.h"
#include "song_editor.h"
#include "main_window.h"
#include "pattern.h"
#include "embed.h"
#include "pixmap_button.h"
#include "templates.h"
#include "gui_templates.h"
#include "timeline.h"
#include "instrument_track.h"
#include "tooltip.h"
#include "midi.h"
#include "tool_button.h"
#include "text_float.h"
#include "combobox.h"
#include "piano_widget.h"
#include "debug.h"
#include "detuning_helper.h"
#include "embed.h"
#include "gui_templates.h"
#include "instrument_track.h"
#include "main_window.h"
#include "midi.h"
#include "pattern.h"
#include "piano_widget.h"
#include "pixmap_button.h"
#include "song_editor.h"
#include "templates.h"
#include "text_float.h"
#include "timeline.h"
#include "tool_button.h"
#include "tooltip.h"
typedef automationPattern::timeMap timeMap;
@@ -139,7 +140,6 @@ const int DEFAULT_PR_PPT = KEY_LINE_HEIGHT * DEFAULT_STEPS_PER_TACT;
pianoRoll::pianoRoll( void ) :
QWidget( engine::getMainWindow()->workspace() ),
m_paintPixmap(),
m_pattern( NULL ),
m_currentPosition(),
m_recording( FALSE ),
@@ -524,13 +524,13 @@ void pianoRoll::setCurrentPattern( pattern * _new_pattern )
}
noteVector & notes = m_pattern->notes();
const noteVector & notes = m_pattern->notes();
int central_key = 0;
if( notes.empty() == FALSE )
{
// determine the central key so that we can scroll to it
int total_notes = 0;
for( noteVector::iterator it = notes.begin();
for( noteVector::const_iterator it = notes.begin();
it != notes.end(); ++it )
{
if( ( *it )->length() > 0 )
@@ -634,14 +634,43 @@ inline void pianoRoll::drawNoteRect( QPainter & _p, Uint16 _x, Uint16 _y,
void pianoRoll::updatePaintPixmap( void )
inline void pianoRoll::drawDetuningInfo( QPainter & _p, note * _n, Uint16 _x,
Uint16 _y )
{
if( m_paintPixmap.isNull() == TRUE || m_paintPixmap.size() != size() )
Uint16 middle_y = _y + KEY_LINE_HEIGHT / 2;
_p.setPen( QColor( 0xFF, 0xDF, 0x20 ) );
timeMap & map = _n->detuning()->getAutomationPattern()->getTimeMap();
timeMap::iterator it = map.end();
do
{
m_paintPixmap = QPixmap( size() );
}
m_paintPixmap.fill( QColor( 0, 0, 0 ) );
QPainter p( &m_paintPixmap );
--it;
Sint32 pos_tact_64th = -it.key();
if( pos_tact_64th > _n->length() )
{
break;
}
Uint16 pos_x = _x + pos_tact_64th * m_ppt / 64;
#ifdef QT3
const int level = it.data();
#else
const int level = it.value();
#endif
Uint16 pos_y = middle_y - level * KEY_LINE_HEIGHT / 10;
_p.drawLine( pos_x - 1, pos_y, pos_x + 1, pos_y );
_p.drawLine( pos_x, pos_y - 1, pos_x, pos_y + 1 );
} while( it != map.begin() );
}
void pianoRoll::updatePaintPixmap( QPixmap & _p )
{
_p.fill( QColor( 0, 0, 0 ) );
QPainter p( &_p );
// set font-size to 8
p.setFont( pointSize<8>( p.font() ) );
@@ -871,20 +900,20 @@ void pianoRoll::updatePaintPixmap( void )
int y_base = height() - PR_BOTTOM_MARGIN - m_notesEditHeight - 1;
if( validPattern() == TRUE )
{
QPainter p_detuning( &m_paintPixmap );
QPainter p_detuning( &_p );
p_detuning.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN,
width() - WHITE_KEY_WIDTH,
height() - PR_TOP_MARGIN - PR_BOTTOM_MARGIN
- m_notesEditHeight );
noteVector & notes = m_pattern->notes();
const noteVector & notes = m_pattern->notes();
const int visible_keys = ( height() - PR_TOP_MARGIN -
PR_BOTTOM_MARGIN - m_notesEditHeight ) /
KEY_LINE_HEIGHT + 2;
for( noteVector::iterator it = notes.begin(); it != notes.end();
++it )
for( noteVector::const_iterator it = notes.begin();
it != notes.end(); ++it )
{
Sint32 len_tact_64th = ( *it )->length();
@@ -1001,39 +1030,6 @@ void pianoRoll::updatePaintPixmap( void )
inline void pianoRoll::drawDetuningInfo( QPainter & _p, note * _n, Uint16 _x,
Uint16 _y )
{
Uint16 middle_y = _y + KEY_LINE_HEIGHT / 2;
_p.setPen( QColor( 0xFF, 0xDF, 0x20 ) );
timeMap & map = _n->detuning()->getAutomationPattern()->getTimeMap();
timeMap::iterator it = map.end();
do
{
--it;
Sint32 pos_tact_64th = -it.key();
if( pos_tact_64th > _n->length() )
{
break;
}
Uint16 pos_x = _x + pos_tact_64th * m_ppt / 64;
#ifdef QT3
const int level = it.data();
#else
const int level = it.value();
#endif
Uint16 pos_y = middle_y - level * KEY_LINE_HEIGHT / 10;
_p.drawLine( pos_x - 1, pos_y, pos_x + 1, pos_y );
_p.drawLine( pos_x, pos_y - 1, pos_x, pos_y + 1 );
} while( it != map.begin() );
}
void pianoRoll::removeSelection( void )
{
m_selectStartTact64th = 0;
@@ -1296,10 +1292,10 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me )
m_currentPosition;
// get note-vector of current pattern
noteVector & notes = m_pattern->notes();
const noteVector & notes = m_pattern->notes();
// will be our iterator in the following loop
noteVector::iterator it = notes.begin();
noteVector::const_iterator it = notes.begin();
// loop through whole note-vector...
while( it != notes.end() )
@@ -1680,10 +1676,10 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
m_currentPosition;
// get note-vector of current pattern
noteVector & notes = m_pattern->notes();
const noteVector & notes = m_pattern->notes();
// will be our iterator in the following loop
noteVector::iterator it = notes.begin();
noteVector::const_iterator it = notes.begin();
// loop through whole note-vector...
while( it != notes.end() )
@@ -2038,7 +2034,8 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
void pianoRoll::paintEvent( QPaintEvent * )
{
updatePaintPixmap();
QPixmap paintPixmap( size() );
updatePaintPixmap( paintPixmap );
#ifdef QT4
QPainter p( this );
#else
@@ -2047,7 +2044,7 @@ void pianoRoll::paintEvent( QPaintEvent * )
QPainter p( &draw_pm, this );
#endif
p.drawPixmap( 0, 0, m_paintPixmap );
p.drawPixmap( 0, 0, paintPixmap );
p.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN, width() -
WHITE_KEY_WIDTH, height() - PR_TOP_MARGIN -
@@ -2263,14 +2260,8 @@ void pianoRoll::recordNote( const note & _n )
_n.tone(), _n.octave(),
_n.getVolume(), _n.getPanning() );
n.quantizeLength( quantization() );
#ifndef QT4
qApp->lock();
#endif
m_pattern->addNote( n );
update();
#ifndef QT4
qApp->unlock();
#endif
engine::getSongEditor()->setModified();
}
}
@@ -2347,12 +2338,13 @@ void pianoRoll::selectAll( void )
return;
}
noteVector & notes = m_pattern->notes();
const noteVector & notes = m_pattern->notes();
// if first_time = TRUE, we HAVE to set the vars for select
bool first_time = TRUE;
for( noteVector::iterator it = notes.begin(); it != notes.end(); ++it )
for( noteVector::const_iterator it = notes.begin(); it != notes.end();
++it )
{
Uint32 len_tact_64th = ( *it )->length();
@@ -2419,9 +2411,10 @@ void pianoRoll::getSelectedNotes( noteVector & _selected_notes )
qSwap<int>( sel_key_start, sel_key_end );
}
noteVector & notes = m_pattern->notes();
const noteVector & notes = m_pattern->notes();
for( noteVector::iterator it = notes.begin(); it != notes.end(); ++it )
for( noteVector::const_iterator it = notes.begin(); it != notes.end();
++it )
{
Sint32 len_tact_64th = ( *it )->length();
@@ -2661,12 +2654,12 @@ note * pianoRoll::noteUnderMouse( void )
noteVector::iterator pianoRoll::noteIteratorUnderMouse( void )
noteVector::const_iterator pianoRoll::noteIteratorUnderMouse( void )
{
QPoint pos = mapFromGlobal( QCursor::pos() );
// get note-vector of current pattern
noteVector & notes = m_pattern->notes();
const noteVector & notes = m_pattern->notes();
if( pos.x() <= WHITE_KEY_WIDTH || pos.x() > width() - SCROLLBAR_SIZE
|| pos.y() < PR_TOP_MARGIN
@@ -2680,7 +2673,7 @@ noteVector::iterator pianoRoll::noteIteratorUnderMouse( void )
+ m_currentPosition;
// will be our iterator in the following loop
noteVector::iterator it = notes.begin();
noteVector::const_iterator it = notes.begin();
// loop through whole note-vector...
while( it != notes.end() )

View File

@@ -49,10 +49,13 @@
#include "piano_widget.h"
#include "automatable_object_templates.h"
#include "embed.h"
#include "gui_templates.h"
#include "instrument_track.h"
#include "knob.h"
#include "midi.h"
#include "templates.h"
#include "embed.h"
#include "update_event.h"
#ifdef Q_WS_X11
@@ -483,6 +486,28 @@ void pianoWidget::keyReleaseEvent( QKeyEvent * _ke )
void pianoWidget::setKeyState( int _key, bool _on )
{
m_pressedKeys[tLimit( _key, 0, NOTES_PER_OCTAVE * OCTAVES - 1 )] = _on;
QApplication::postEvent( this, new updateEvent() );
}
#ifndef QT3
void pianoWidget::customEvent( QEvent * )
#else
void pianoWidget::customEvent( QCustomEvent * )
#endif
{
update();
}
void pianoWidget::focusOutEvent( QFocusEvent * )
{
// if we loose focus, we HAVE to note off all running notes because

View File

@@ -32,12 +32,14 @@
#include <QtCore/QDir>
#include <QtCore/QLibrary>
#include <QtGui/QMessageBox>
#include <QtGui/QPixmap>
#else
#include <qmessagebox.h>
#include <qdir.h>
#include <qlibrary.h>
#include <qpixmap.h>
#endif
@@ -58,6 +60,7 @@ static plugin::descriptor dummy_plugin_descriptor =
"Tobias Doerffel <tobydox/at/users.sf.net>",
0x0100,
plugin::Undefined,
NULL,
NULL
} ;

View File

@@ -41,13 +41,14 @@
#include "preset_preview_play_handle.h"
#include "note_play_handle.h"
#include "instrument_track.h"
#include "track_container.h"
#include "mmp.h"
#include "debug.h"
#include "engine.h"
#include "instrument_track.h"
#include "midi_port.h"
#include "mmp.h"
#include "note_play_handle.h"
#include "project_journal.h"
#include "track_container.h"
@@ -204,6 +205,14 @@ bool presetPreviewPlayHandle::done( void ) const
bool presetPreviewPlayHandle::isFromTrack( const track * _track ) const
{
return( s_previewTC->previewInstrumentTrack() == _track );
}
void presetPreviewPlayHandle::cleanUp( void )
{
delete s_previewTC;

View File

@@ -26,12 +26,13 @@
#include "sample_play_handle.h"
#include "audio_port.h"
#include "bb_track.h"
#include "engine.h"
#include "instrument_track.h"
#include "pattern.h"
#include "sample_buffer.h"
#include "sample_track.h"
#include "audio_port.h"
@@ -158,6 +159,14 @@ bool samplePlayHandle::done( void ) const
bool samplePlayHandle::isFromTrack( const track * _track ) const
{
return( m_track == _track || m_bbTrack == _track );
}
f_cnt_t samplePlayHandle::totalFrames( void ) const
{
return( ( m_sampleBuffer->endFrame() - m_sampleBuffer->startFrame() ) *

View File

@@ -40,7 +40,6 @@
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QFileDialog>
#include <QtGui/QKeyEvent>
@@ -51,7 +50,6 @@
#else
#include <qapplication.h>
#include <qfile.h>
#include <qmessagebox.h>
#include <qfiledialog.h>
@@ -114,8 +112,7 @@ songEditor::songEditor( void ) :
m_trackToPlay( NULL ),
m_patternToPlay( NULL ),
m_loopPattern( FALSE ),
m_scrollBack( FALSE ),
m_destroyed( FALSE )
m_scrollBack( FALSE )
{
setWindowTitle( tr( "Song-Editor" ) );
setWindowIcon( embed::getIconPixmap( "songeditor" ) );
@@ -453,8 +450,8 @@ songEditor::songEditor( void ) :
songEditor::~songEditor()
{
m_playing = FALSE;
delete m_automation_track;
m_destroyed = TRUE;
}
@@ -1239,10 +1236,6 @@ void songEditor::updateTimeLinePosition( void )
void songEditor::stop( void )
{
if( m_destroyed )
{
return;
}
m_actions.push_back( ACT_STOP_PLAY );
#ifdef QT4
m_playButton->setIcon( embed::getIconPixmap( "play" ) );
@@ -1420,24 +1413,10 @@ void songEditor::clearProject( void )
if( m_playing )
{
// stop play, because it's dangerous that play-routines try to
// access non existing data (as you can see in the next lines,
// all data is cleared!)
stop();
}
// make sure all running notes are cleared, otherwise the whole
// thing will end up in a SIGSEGV...
engine::getMixer()->clear( TRUE );
while( engine::getMixer()->haveNoRunningNotes() == FALSE )
{
#ifdef QT4
QApplication::processEvents( QEventLoop::AllEvents );
#else
qApp->processEvents();
#endif
}
engine::getMixer()->lock();
clearAllTracks();
engine::getAutomationEditor()->setCurrentPattern( NULL );
@@ -1446,6 +1425,7 @@ void songEditor::clearProject( void )
m_masterPitchSlider->clearAutomationValues();
engine::getBBEditor()->clearAllTracks();
engine::getMixer()->unlock();
engine::getProjectNotes()->clear();
@@ -1545,52 +1525,11 @@ void FASTCALL songEditor::loadProject( const QString & _file_name )
}
// get the header information from the DOM
QDomNode node = mmp.head().firstChild();
while( !node.isNull() )
{
if( node.isElement() )
{
if( node.nodeName() == "bpm" &&
node.toElement().attribute( "value" ).toInt() > 0 )
{
m_bpmSpinBox->setInitValue( node.toElement()
.attribute( "value" ).toInt() );
}
else if( node.nodeName() == "mastervol" )
{
if( node.toElement().attribute( "value"
).toInt() > 0 )
{
m_masterVolumeSlider->setInitValue(
node.toElement().attribute(
"value" ).toInt() );
}
else
{
m_masterVolumeSlider->setInitValue(
DEFAULT_VOLUME );
}
}
else if( node.nodeName() == "masterpitch" )
{
m_masterPitchSlider->setInitValue(
-node.toElement().attribute( "value"
).toInt() );
}
else if( node.nodeName()
== automationPattern::classNodeName() )
{
m_bpmSpinBox->loadSettings( mmp.head(), "bpm" );
m_masterVolumeSlider->loadSettings( mmp.head(),
"mastervol" );
m_masterPitchSlider->loadSettings( mmp.head(),
"masterpitch" );
}
}
node = node.nextSibling();
}
m_bpmSpinBox->loadSettings( mmp.head(), "bpm" );
m_masterVolumeSlider->loadSettings( mmp.head(), "mastervol" );
m_masterPitchSlider->loadSettings( mmp.head(), "masterpitch" );
node = mmp.content().firstChild();
QDomNode node = mmp.content().firstChild();
while( !node.isNull() )
{
if( node.isElement() )

View File

@@ -54,6 +54,7 @@
#include "surround_area.h"
#include "automatable_object_templates.h"
#include "embed.h"
#include "knob.h"
#include "templates.h"
#include "tooltip.h"

View File

@@ -128,7 +128,10 @@ timeLine::timeLine( const int _xoff, const int _yoff, const float _ppt,
timeLine::~timeLine()
{
m_pos.m_timeLine = NULL;
if( engine::getSongEditor() )
{
m_pos.m_timeLine = NULL;
}
delete m_hint;
}

View File

@@ -44,7 +44,6 @@
#include <qlayout.h>
#include <qcursor.h>
#include <qwhatsthis.h>
#include <qtimer.h>
#endif
@@ -61,6 +60,8 @@
#include "templates.h"
#include "clipboard.h"
#include "embed.h"
#include "engine.h"
#include "gui_templates.h"
#include "pixmap_button.h"
#include "debug.h"
#include "tooltip.h"
@@ -1141,8 +1142,9 @@ void trackOperationsWidget::paintEvent( QPaintEvent * _pe )
void trackOperationsWidget::cloneTrack( void )
{
m_trackWidget->getTrack()->getTrackContainer()->cloneTrack(
m_trackWidget->getTrack() );
engine::getMixer()->lock();
m_trackWidget->getTrack()->clone();
engine::getMixer()->unlock();
}
@@ -1150,21 +1152,10 @@ void trackOperationsWidget::cloneTrack( void )
void trackOperationsWidget::removeTrack( void )
{
#ifdef QT3
QTimer::singleShot( 10, this, SLOT( removeTrackTimer() ) );
#else
//#warning fixme
removeTrackTimer();
#endif
}
void trackOperationsWidget::removeTrackTimer( void )
{
engine::getMixer()->lock();
m_trackWidget->getTrack()->getTrackContainer()->removeTrack(
m_trackWidget->getTrack() );
engine::getMixer()->unlock();
}
@@ -1648,10 +1639,6 @@ track::~track()
track * track::create( trackTypes _tt, trackContainer * _tc )
{
// while adding track, pause mixer for not getting into any trouble
// because of track being not created completely so far
engine::getMixer()->pause();
track * t = NULL;
switch( _tt )
@@ -1669,33 +1656,27 @@ track * track::create( trackTypes _tt, trackContainer * _tc )
assert( t != NULL );
#endif
// allow mixer to continue
engine::getMixer()->play();
return( t );
}
track * track::create( const QDomElement & _this, trackContainer * _tc )
void track::create( const QDomElement & _this, trackContainer * _tc )
{
track * t = create( static_cast<trackTypes>( _this.attribute(
"type" ).toInt() ), _tc );
t->restoreState( _this );
return( t );
create( static_cast<trackTypes>( _this.attribute( "type" ).toInt() ),
_tc )->restoreState( _this );
}
track * track::clone( track * _track )
void track::clone( void )
{
QDomDocument doc;
QDomElement parent = doc.createElement( "clone" );
_track->saveState( doc, parent );
QDomElement e = parent.firstChild().toElement();
return( create( e, _track->getTrackContainer() ) );
saveState( doc, parent );
create( parent.firstChild().toElement(), m_trackContainer );
}

View File

@@ -48,22 +48,23 @@
#include "track_container.h"
#include "track.h"
#include "templates.h"
#include "bb_track.h"
#include "main_window.h"
#include "mixer.h"
#include "song_editor.h"
#include "string_pair_drag.h"
#include "instrument_track.h"
#include "mmp.h"
#include "config_mgr.h"
#include "debug.h"
#include "engine.h"
#include "file_browser.h"
#include "import_filter.h"
#include "instrument.h"
#include "rubberband.h"
#include "instrument_track.h"
#include "main_window.h"
#include "mixer.h"
#include "mmp.h"
#include "project_journal.h"
#include "debug.h"
#include "file_browser.h"
#include "rubberband.h"
#include "song_editor.h"
#include "string_pair_drag.h"
#include "templates.h"
#include "track.h"
trackContainer::trackContainer( void ) :
@@ -195,16 +196,6 @@ void trackContainer::loadSettings( const QDomElement & _this )
void trackContainer::cloneTrack( track * _track )
{
engine::getMixer()->pause();
track::clone( _track );
engine::getMixer()->play();
}
void trackContainer::addTrack( track * _track )
{
QMap<QString, QVariant> map;
@@ -237,7 +228,6 @@ void trackContainer::removeTrack( track * _track )
map["state"] = mmp.toString();
addJournalEntry( journalEntry( REMOVE_TRACK, map ) );
engine::getMixer()->pause();
#ifndef QT4
m_scrollArea->removeChild( _track->getTrackWidget() );
#endif
@@ -245,8 +235,6 @@ void trackContainer::removeTrack( track * _track )
delete _track;
engine::getMixer()->play();
realignTracks();
if( engine::getSongEditor() )
{
@@ -334,7 +322,7 @@ void trackContainer::realignTracks( bool _complete_update )
void trackContainer::clearAllTracks( void )
{
while( m_trackWidgets.size() )
while( !m_trackWidgets.empty() )
{
removeTrack( m_trackWidgets.front()->getTrack() );
}
@@ -513,6 +501,7 @@ void trackContainer::dropEvent( QDropEvent * _de )
{
QString type = stringPairDrag::decodeKey( _de );
QString value = stringPairDrag::decodeValue( _de );
engine::getMixer()->lock();
if( type == "instrument" )
{
instrumentTrack * it = dynamic_cast<instrumentTrack *>(
@@ -560,6 +549,7 @@ void trackContainer::dropEvent( QDropEvent * _de )
updateAfterTrackAdd();
_de->accept();
}
engine::getMixer()->unlock();
}