From 54fd7467b2711f8d50a8a12490645669eddd1ee1 Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Mon, 7 May 2007 20:03:03 +0000 Subject: [PATCH] mutex, detuning helpers, GUI updates, play handles, many many changes... (5) git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@483 0778d3d1-df1d-0410-868b-ea421aaaa00d --- src/lib/mmp.cpp | 140 +++++++++++++++++++++++++++++++++++- src/lib/oscillator.cpp | 70 ++++++++---------- src/lib/project_journal.cpp | 3 +- src/lib/project_version.cpp | 72 +++++++++++++++++++ src/lib/sample_buffer.cpp | 57 +++------------ src/midi/midi_client.cpp | 1 + 6 files changed, 251 insertions(+), 92 deletions(-) create mode 100644 src/lib/project_version.cpp diff --git a/src/lib/mmp.cpp b/src/lib/mmp.cpp index b4379c318f..98371b434d 100644 --- a/src/lib/mmp.cpp +++ b/src/lib/mmp.cpp @@ -45,8 +45,9 @@ #include "mmp.h" -#include "song_editor.h" #include "config_mgr.h" +#include "project_version.h" +#include "song_editor.h" multimediaProject::typeDescStruct @@ -93,7 +94,8 @@ multimediaProject::multimediaProject( projectTypes _project_type ) : multimediaProject::multimediaProject( const QString & _in_file_name, - bool _is_filename ) : + bool _is_filename, + bool _upgrade ) : QDomDocument(), m_content(), m_head() @@ -183,6 +185,12 @@ multimediaProject::multimediaProject( const QString & _in_file_name, } node = node.nextSibling(); } + + if( _upgrade && root.hasAttribute( "creatorversion" ) + && root.attribute( "creatorversion" ) != VERSION ) + { + upgrade(); + } } @@ -321,7 +329,7 @@ bool multimediaProject::writeFile( const QString & _fn, bool _overwrite_check ) multimediaProject::projectTypes multimediaProject::typeOfFile( const QString & _fn ) { - multimediaProject m( _fn ); + multimediaProject m( _fn, TRUE, FALSE ); return( m.type() ); } @@ -390,4 +398,130 @@ void multimediaProject::cleanMetaNodes( QDomElement _de ) + +void multimediaProject::upgrade( void ) +{ + projectVersion version = documentElement().attribute( + "creatorversion" ); + + if( version < "0.2.1-svn20070501" ) + { + QDomNodeList list = elementsByTagName( "arpandchords" ); + for( int i = 0; !list.item( i ).isNull(); ++i ) + { + QDomElement el = list.item( i ).toElement(); + if( el.hasAttribute( "arpdir" ) ) + { + int arpdir = el.attribute( "arpdir" ).toInt(); + if( arpdir > 0 ) + { + el.setAttribute( "arpdir", arpdir - 1 ); + } + else + { + el.setAttribute( "arpdisabled", "1" ); + } + } + } + + list = elementsByTagName( "sampletrack" ); + for( int i = 0; !list.item( i ).isNull(); ++i ) + { + QDomElement el = list.item( i ).toElement(); + if( el.attribute( "vol" ) != "" ) + { + el.setAttribute( "vol", el.attribute( + "vol" ).toFloat() * 100.0f ); + } + else + { + QDomNode node = el.namedItem( + "automation-pattern" ); + if( !node.isElement() || + !node.namedItem( "vol" ).isElement() ) + { + el.setAttribute( "vol", 100.0f ); + } + } + } + + list = elementsByTagName( "ladspacontrols" ); + for( int i = 0; !list.item( i ).isNull(); ++i ) + { + QDomElement el = list.item( i ).toElement(); + QDomNode anode = el.namedItem( "automation-pattern" ); + QDomNode node = anode.firstChild(); + while( !node.isNull() ) + { + if( node.isElement() ) + { + QString name = node.nodeName(); + if( name.endsWith( "link" ) ) + { + el.setAttribute( name, + node.namedItem( "time" ) + .toElement() + .attribute( "value" ) ); + QDomNode oldNode = node; + node = node.nextSibling(); + anode.removeChild( oldNode ); + continue; + } + } + node = node.nextSibling(); + } + } + + QDomNode node = m_head.firstChild(); + while( !node.isNull() ) + { + if( node.isElement() ) + { + if( node.nodeName() == "bpm" ) + { + int value = node.toElement().attribute( + "value" ).toInt(); + if( value > 0 ) + { + m_head.setAttribute( "bpm", + value ); + QDomNode oldNode = node; + node = node.nextSibling(); + m_head.removeChild( oldNode ); + continue; + } + } + else if( node.nodeName() == "mastervol" ) + { + int value = node.toElement().attribute( + "value" ).toInt(); + if( value > 0 ) + { + m_head.setAttribute( + "mastervol", value ); + QDomNode oldNode = node; + node = node.nextSibling(); + m_head.removeChild( oldNode ); + continue; + } + } + else if( node.nodeName() == "masterpitch" ) + { + m_head.setAttribute( "masterpitch", + -node.toElement().attribute( + "value" ).toInt() ); + QDomNode oldNode = node; + node = node.nextSibling(); + m_head.removeChild( oldNode ); + continue; + } + } + node = node.nextSibling(); + } + } +} + + + + #endif diff --git a/src/lib/oscillator.cpp b/src/lib/oscillator.cpp index 7529675c46..40a35ca0d6 100644 --- a/src/lib/oscillator.cpp +++ b/src/lib/oscillator.cpp @@ -29,12 +29,12 @@ -oscillator::oscillator( const waveShapes * _wave_shape, - const modulationAlgos * _modulation_algo, - const float * _freq, - const float * _detuning, - const float * _phase_offset, - const float * _volume, +oscillator::oscillator( const waveShapes & _wave_shape, + const modulationAlgos & _modulation_algo, + const float & _freq, + const float & _detuning, + const float & _phase_offset, + const float & _volume, oscillator * _sub_osc ) : m_waveShape( _wave_shape ), m_modulationAlgo( _modulation_algo ), @@ -43,10 +43,10 @@ oscillator::oscillator( const waveShapes * _wave_shape, m_volume( _volume ), m_ext_phaseOffset( _phase_offset ), m_subOsc( _sub_osc ), + m_phaseOffset( _phase_offset ), + m_phase( _phase_offset ), m_userWave( NULL ) { - m_phaseOffset = *m_ext_phaseOffset; - m_phase = m_phaseOffset; } @@ -55,14 +55,9 @@ oscillator::oscillator( const waveShapes * _wave_shape, void oscillator::update( sampleFrame * _ab, const fpab_t _frames, const ch_cnt_t _chnl ) { - if( m_userWave ) - { - m_userWave->lock(); - } - if( m_subOsc != NULL ) { - switch( *m_modulationAlgo ) + switch( m_modulationAlgo ) { case PHASE_MODULATION: updatePM( _ab, _frames, _chnl ); @@ -84,11 +79,6 @@ void oscillator::update( sampleFrame * _ab, const fpab_t _frames, { updateNoSub( _ab, _frames, _chnl ); } - - if( m_userWave ) - { - m_userWave->unlock(); - } } @@ -97,7 +87,7 @@ void oscillator::update( sampleFrame * _ab, const fpab_t _frames, void oscillator::updateNoSub( sampleFrame * _ab, const fpab_t _frames, const ch_cnt_t _chnl ) { - switch( *m_waveShape ) + switch( m_waveShape ) { case SIN_WAVE: default: @@ -133,7 +123,7 @@ void oscillator::updateNoSub( sampleFrame * _ab, const fpab_t _frames, void oscillator::updatePM( sampleFrame * _ab, const fpab_t _frames, const ch_cnt_t _chnl ) { - switch( *m_waveShape ) + switch( m_waveShape ) { case SIN_WAVE: default: @@ -169,7 +159,7 @@ void oscillator::updatePM( sampleFrame * _ab, const fpab_t _frames, void oscillator::updateAM( sampleFrame * _ab, const fpab_t _frames, const ch_cnt_t _chnl ) { - switch( *m_waveShape ) + switch( m_waveShape ) { case SIN_WAVE: default: @@ -205,7 +195,7 @@ void oscillator::updateAM( sampleFrame * _ab, const fpab_t _frames, void oscillator::updateMix( sampleFrame * _ab, const fpab_t _frames, const ch_cnt_t _chnl ) { - switch( *m_waveShape ) + switch( m_waveShape ) { case SIN_WAVE: default: @@ -241,7 +231,7 @@ void oscillator::updateMix( sampleFrame * _ab, const fpab_t _frames, void oscillator::updateSync( sampleFrame * _ab, const fpab_t _frames, const ch_cnt_t _chnl ) { - switch( *m_waveShape ) + switch( m_waveShape ) { case SIN_WAVE: default: @@ -277,7 +267,7 @@ void oscillator::updateSync( sampleFrame * _ab, const fpab_t _frames, void oscillator::updateFM( sampleFrame * _ab, const fpab_t _frames, const ch_cnt_t _chnl ) { - switch( *m_waveShape ) + switch( m_waveShape ) { case SIN_WAVE: default: @@ -313,10 +303,10 @@ void oscillator::updateFM( sampleFrame * _ab, const fpab_t _frames, // should be called every time phase-offset is changed... inline void oscillator::recalcPhase( void ) { - if( m_phaseOffset != *m_ext_phaseOffset ) + if( m_phaseOffset != m_ext_phaseOffset ) { m_phase -= m_phaseOffset; - m_phaseOffset = *m_ext_phaseOffset; + m_phaseOffset = m_ext_phaseOffset; m_phase += m_phaseOffset; } m_phase = fraction( m_phase ); @@ -344,7 +334,7 @@ float oscillator::syncInit( sampleFrame * _ab, const fpab_t _frames, m_subOsc->update( _ab, _frames, _chnl ); } recalcPhase(); - return( *m_freq * *m_detuning ); + return( m_freq * m_detuning ); } @@ -356,11 +346,11 @@ void oscillator::updateNoSub( sampleFrame * _ab, const fpab_t _frames, const ch_cnt_t _chnl ) { recalcPhase(); - float osc_coeff = *m_freq * *m_detuning; + const float osc_coeff = m_freq * m_detuning; for( fpab_t frame = 0; frame < _frames; ++frame ) { - _ab[frame][_chnl] = getSample( m_phase ) * *m_volume; + _ab[frame][_chnl] = getSample( m_phase ) * m_volume; m_phase += osc_coeff; } } @@ -375,12 +365,12 @@ void oscillator::updatePM( sampleFrame * _ab, const fpab_t _frames, { m_subOsc->update( _ab, _frames, _chnl ); recalcPhase(); - const float osc_coeff = *m_freq * *m_detuning; + const float osc_coeff = m_freq * m_detuning; for( fpab_t frame = 0; frame < _frames; ++frame ) { _ab[frame][_chnl] = getSample( m_phase + _ab[frame][_chnl] ) - * *m_volume; + * m_volume; m_phase += osc_coeff; } } @@ -395,11 +385,11 @@ void oscillator::updateAM( sampleFrame * _ab, const fpab_t _frames, { m_subOsc->update( _ab, _frames, _chnl ); recalcPhase(); - const float osc_coeff = *m_freq * *m_detuning; + const float osc_coeff = m_freq * m_detuning; for( fpab_t frame = 0; frame < _frames; ++frame ) { - _ab[frame][_chnl] *= getSample( m_phase ) * *m_volume; + _ab[frame][_chnl] *= getSample( m_phase ) * m_volume; m_phase += osc_coeff; } } @@ -414,11 +404,11 @@ void oscillator::updateMix( sampleFrame * _ab, const fpab_t _frames, { m_subOsc->update( _ab, _frames, _chnl ); recalcPhase(); - const float osc_coeff = *m_freq * *m_detuning; + const float osc_coeff = m_freq * m_detuning; for( fpab_t frame = 0; frame < _frames; ++frame ) { - _ab[frame][_chnl] += getSample( m_phase ) * *m_volume; + _ab[frame][_chnl] += getSample( m_phase ) * m_volume; m_phase += osc_coeff; } } @@ -434,7 +424,7 @@ void oscillator::updateSync( sampleFrame * _ab, const fpab_t _frames, { const float sub_osc_coeff = m_subOsc->syncInit( _ab, _frames, _chnl ); recalcPhase(); - const float osc_coeff = *m_freq * *m_detuning; + const float osc_coeff = m_freq * m_detuning; for( fpab_t frame = 0; frame < _frames ; ++frame ) { @@ -442,7 +432,7 @@ void oscillator::updateSync( sampleFrame * _ab, const fpab_t _frames, { m_phase = m_phaseOffset; } - _ab[frame][_chnl] = getSample( m_phase ) * *m_volume; + _ab[frame][_chnl] = getSample( m_phase ) * m_volume; m_phase += osc_coeff; } } @@ -457,12 +447,12 @@ void oscillator::updateFM( sampleFrame * _ab, const fpab_t _frames, { m_subOsc->update( _ab, _frames, _chnl ); recalcPhase(); - const float osc_coeff = *m_freq * *m_detuning; + const float osc_coeff = m_freq * m_detuning; for( fpab_t frame = 0; frame < _frames; ++frame ) { m_phase += _ab[frame][_chnl]; - _ab[frame][_chnl] = getSample( m_phase ) * *m_volume; + _ab[frame][_chnl] = getSample( m_phase ) * m_volume; m_phase += osc_coeff; } } diff --git a/src/lib/project_journal.cpp b/src/lib/project_journal.cpp index d7d36636cb..cc42280332 100644 --- a/src/lib/project_journal.cpp +++ b/src/lib/project_journal.cpp @@ -41,7 +41,8 @@ projectJournal::projectJournal( void ) : m_joIDs(), m_journalEntries(), - m_currentJournalEntry( m_journalEntries.end() ) + m_currentJournalEntry( m_journalEntries.end() ), + m_journalling( TRUE ) { } diff --git a/src/lib/project_version.cpp b/src/lib/project_version.cpp new file mode 100644 index 0000000000..5577db70ef --- /dev/null +++ b/src/lib/project_version.cpp @@ -0,0 +1,72 @@ +#ifndef SINGLE_SOURCE_COMPILE + +/* + * project_version.cpp - compare versions in import upgrades + * + * Copyright (c) 2007 Javier Serrano Polo + * + * 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 "project_version.h" + + + + +int projectVersion::compare( const projectVersion & _v1, + const projectVersion & _v2 ) +{ + int n1, n2; + + // Major + n1 = _v1.section( '.', 0, 0 ).toInt(); + n2 = _v2.section( '.', 0, 0 ).toInt(); + if( n1 != n2 ) + { + return( n1 - n2 ); + } + + // Minor + n1 = _v1.section( '.', 1, 1 ).toInt(); + n2 = _v2.section( '.', 1, 1 ).toInt(); + if( n1 != n2 ) + { + return( n1 - n2 ); + } + + // Release + n1 = _v1.section( '.', 2 ).section( '-', 0, 0 ).toInt(); + n2 = _v2.section( '.', 2 ).section( '-', 0, 0 ).toInt(); + if( n1 != n2 ) + { + return( n1 - n2 ); + } + + // Build + return( QString::compare( _v1.section( '.', 2 ).section( '-', 1 ), + _v2.section( '.', 2 ).section( '-', 1 ) ) ); +} + + + + +#endif diff --git a/src/lib/sample_buffer.cpp b/src/lib/sample_buffer.cpp index 35c4d319c6..2d9cdccc8b 100644 --- a/src/lib/sample_buffer.cpp +++ b/src/lib/sample_buffer.cpp @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -44,7 +43,6 @@ #else #include -#include #include #include #include @@ -116,7 +114,6 @@ sampleBuffer::sampleBuffer( const QString & _audio_file, m_reversed( FALSE ), m_frequency( BASE_FREQ ), m_sample_rate( SAMPLE_RATES[DEFAULT_QUALITY_LEVEL] ), - m_dataMutex(), m_sample_fragment( NULL ) { #ifdef SDL_SDL_SOUND_H @@ -150,7 +147,6 @@ sampleBuffer::sampleBuffer( const sampleFrame * _data, const f_cnt_t _frames ) : m_reversed( FALSE ), m_frequency( BASE_FREQ ), m_sample_rate( SAMPLE_RATES[DEFAULT_QUALITY_LEVEL] ), - m_dataMutex(), m_sample_fragment( NULL ) { m_origData = new sampleFrame[_frames]; @@ -183,7 +179,6 @@ sampleBuffer::sampleBuffer( const f_cnt_t _frames ) : m_reversed( FALSE ), m_frequency( BASE_FREQ ), m_sample_rate( SAMPLE_RATES[DEFAULT_QUALITY_LEVEL] ), - m_dataMutex(), m_sample_fragment( NULL ) { m_origData = new sampleFrame[_frames]; @@ -204,18 +199,9 @@ sampleBuffer::sampleBuffer( const f_cnt_t _frames ) : sampleBuffer::~sampleBuffer() { - m_dataMutex.lock(); delete[] m_origData; - m_origData = NULL; delete[] m_data; - m_data = NULL; - - m_dataMutex.unlock(); - - if( m_sample_fragment ) - { - delete[] m_sample_fragment; - } + delete[] m_sample_fragment; } @@ -225,11 +211,9 @@ sampleBuffer::~sampleBuffer() void sampleBuffer::update( bool _keep_settings ) { - m_dataMutex.lock(); + engine::getMixer()->lock(); delete[] m_data; - m_data = NULL; - m_frames = 0; if( m_audioFile == "" && m_origData != NULL && m_origFrames > 0 ) { @@ -257,6 +241,8 @@ void sampleBuffer::update( bool _keep_settings ) ch_cnt_t channels = DEFAULT_CHANNELS; sample_rate_t samplerate = SAMPLE_RATES[DEFAULT_QUALITY_LEVEL]; + m_frames = 0; + #ifdef HAVE_SNDFILE_H if( m_frames == 0 ) { @@ -337,13 +323,13 @@ m_data[frame][chnl] = buf[idx] * fac; // neither an audio-file nor a buffer to copy from, so create // buffer containing one sample-frame m_data = new sampleFrame[1]; - memset( m_data, 0, sizeof( *m_data ) * 1 ); + memset( m_data, 0, sizeof( *m_data ) ); m_frames = 1; m_loop_startFrame = m_startFrame = 0; m_loop_endFrame = m_endFrame = 1; } - m_dataMutex.unlock(); + engine::getMixer()->unlock(); emit sampleUpdated(); } @@ -622,7 +608,7 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, handleState * _state, { engine::getMixer()->clearAudioBuffer( _ab, _frames ); - if( m_data == NULL || m_frames == 0 || m_endFrame == 0 || _frames == 0 ) + if( m_endFrame == 0 || _frames == 0 ) { return( FALSE ); } @@ -670,10 +656,6 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, handleState * _state, } } - // make sure, data isn't accessed in any other way (e.g. deleting - // of this buffer...) - m_dataMutex.lock(); - /* Uint32 f2 = 0; while( f2 < f1 ) { @@ -813,8 +795,6 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, handleState * _state, } } - m_dataMutex.unlock(); - _state->m_frame_index = play_frame; return( TRUE ); @@ -842,10 +822,7 @@ sampleFrame * sampleBuffer::getSampleFragment( f_cnt_t _start, } } - if( m_sample_fragment ) - { - delete[] m_sample_fragment; - } + delete[] m_sample_fragment; m_sample_fragment = new sampleFrame[_frames]; if( _looped ) @@ -909,12 +886,7 @@ void sampleBuffer::visualize( QPainter & _p, const QRect & _dr, const QRect isect = _dr.intersect( _clip ); - if( m_data == NULL || m_frames == 0 ) - { - _p.drawLine( isect.x(), y_base, isect.right(), y_base ); - return; - } - else if( _dm == LINE_CONNECT ) + if( _dm == LINE_CONNECT ) { #ifdef QT4 float old_x = _dr.x(); @@ -1114,11 +1086,6 @@ void flacStreamEncoderMetadataCallback( const FLAC__StreamEncoder *, QString & sampleBuffer::toBase64( QString & _dst ) const { - if( m_data == NULL || m_frames == 0 ) - { - return( _dst = "" ); - } - #ifdef HAVE_FLAC_STREAM_ENCODER_H const f_cnt_t FRAMES_PER_BUF = 1152; @@ -1429,10 +1396,7 @@ void sampleBuffer::loadFromBase64( const QString & _data ) void sampleBuffer::setStartFrame( const f_cnt_t _s ) { - // don't set this parameter while playing - m_dataMutex.lock(); m_loop_startFrame = m_startFrame = _s; - m_dataMutex.unlock(); } @@ -1440,10 +1404,7 @@ void sampleBuffer::setStartFrame( const f_cnt_t _s ) void sampleBuffer::setEndFrame( const f_cnt_t _e ) { - // don't set this parameter while playing - m_dataMutex.lock(); m_loop_endFrame = m_endFrame = _e; - m_dataMutex.unlock(); } diff --git a/src/midi/midi_client.cpp b/src/midi/midi_client.cpp index 7294c0dce0..f582ada9c0 100644 --- a/src/midi/midi_client.cpp +++ b/src/midi/midi_client.cpp @@ -87,6 +87,7 @@ void midiClient::removePort( midiPort * _port ) _port ); if( it != m_midiPorts.end() ) { + delete *it; m_midiPorts.erase( it ); } }