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
This commit is contained in:
Javier Serrano Polo
2007-05-07 20:03:03 +00:00
parent 793c5ab7ff
commit 54fd7467b2
6 changed files with 251 additions and 92 deletions

View File

@@ -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

View File

@@ -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<W>( m_phase ) * *m_volume;
_ab[frame][_chnl] = getSample<W>( 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<W>( 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<W>( m_phase ) * *m_volume;
_ab[frame][_chnl] *= getSample<W>( 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<W>( m_phase ) * *m_volume;
_ab[frame][_chnl] += getSample<W>( 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<W>( m_phase ) * *m_volume;
_ab[frame][_chnl] = getSample<W>( 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<W>( m_phase ) * *m_volume;
_ab[frame][_chnl] = getSample<W>( m_phase ) * m_volume;
m_phase += osc_coeff;
}
}

View File

@@ -41,7 +41,8 @@
projectJournal::projectJournal( void ) :
m_joIDs(),
m_journalEntries(),
m_currentJournalEntry( m_journalEntries.end() )
m_currentJournalEntry( m_journalEntries.end() ),
m_journalling( TRUE )
{
}

View File

@@ -0,0 +1,72 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* project_version.cpp - compare versions in import upgrades
*
* Copyright (c) 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 "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

View File

@@ -36,7 +36,6 @@
#include <QtCore/QBuffer>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QMutex>
#include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>
#include <QtGui/QPainter>
@@ -44,7 +43,6 @@
#else
#include <qpainter.h>
#include <qmutex.h>
#include <qmessagebox.h>
#include <qfiledialog.h>
#include <qfileinfo.h>
@@ -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();
}

View File

@@ -87,6 +87,7 @@ void midiClient::removePort( midiPort * _port )
_port );
if( it != m_midiPorts.end() )
{
delete *it;
m_midiPorts.erase( it );
}
}