heavy improvements on mixer-system and GUI

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@26 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2005-12-05 12:26:16 +00:00
parent ab719618f7
commit 614b106752
79 changed files with 1429 additions and 1445 deletions

View File

@@ -61,7 +61,8 @@ audioALSA::audioALSA( Uint32 _sample_rate, bool & _success_ful ) :
m_handle( NULL ),
m_hwParams( NULL ),
m_swParams( NULL ),
m_littleEndian( isLittleEndian() )
m_littleEndian( isLittleEndian() ),
m_quit( FALSE )
{
_success_ful = FALSE;
@@ -105,6 +106,7 @@ audioALSA::audioALSA( Uint32 _sample_rate, bool & _success_ful ) :
audioALSA::~audioALSA()
{
stopProcessing();
if( m_handle != NULL )
{
snd_pcm_close( m_handle );
@@ -175,40 +177,77 @@ int audioALSA::handleError( int _err )
void audioALSA::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
float _master_gain )
void audioALSA::startProcessing( void )
{
outputSampleType * outbuf = bufferAllocator::alloc<outputSampleType>(
_frames * channels() );
bufferAllocator::autoCleaner<> ac( outbuf );
if( !running() )
{
start();
}
}
convertToS16( _ab, _frames, _master_gain, outbuf,
void audioALSA::stopProcessing( void )
{
if( running() )
{
m_quit = TRUE;
wait( 500 );
terminate();
}
}
void audioALSA::run( void )
{
surroundSampleFrame * temp =
bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() );
outputSampleType * outbuf =
bufferAllocator::alloc<outputSampleType>(
mixer::inst()->framesPerAudioBuffer() *
channels() );
m_quit = FALSE;
while( m_quit == FALSE )
{
const Uint32 frames = getNextBuffer( temp );
convertToS16( temp, frames, mixer::inst()->masterGain(), outbuf,
m_littleEndian != isLittleEndian() );
Uint32 frame = 0;
Uint32 frame = 0;
outputSampleType * ptr = outbuf;
while( frame < _frames )
{
int err = snd_pcm_writei( m_handle, outbuf, _frames );
if( err == -EAGAIN )
while( frame < frames )
{
continue;
}
int err = snd_pcm_writei( m_handle, ptr, frames );
if( err < 0 )
{
if( handleError( err ) < 0 )
if( err == -EAGAIN )
{
printf( "Write error: %s\n",
snd_strerror( err ) );
return;
usleep( 10 );
continue;
}
break; // skip this buffer
if( err < 0 )
{
if( handleError( err ) < 0 )
{
printf( "Write error: %s\n",
snd_strerror( err ) );
}
break; // skip this buffer
}
ptr += err * channels();
frame += err;
}
outbuf += err * channels();
frame += err;
}
bufferAllocator::free( temp );
bufferAllocator::free( outbuf );
}

View File

@@ -38,7 +38,9 @@
audioDevice::audioDevice( Uint32 _sample_rate, Uint8 _channels ) :
m_sampleRate( _sample_rate ),
m_channels( _channels )
m_channels( _channels ),
m_buffer( bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() ) )
{
#ifdef HAVE_SAMPLERATE_H
int error;
@@ -64,34 +66,46 @@ audioDevice::~audioDevice()
#ifdef HAVE_SAMPLERATE_H
src_delete( m_srcState );
#endif
bufferAllocator::free( m_buffer );
unlock();
}
void audioDevice::writeBuffer( surroundSampleFrame * _ab, Uint32 _frames,
Uint32 _src_sample_rate, float _master_gain )
void audioDevice::processNextBuffer( void )
{
const Uint32 frames = getNextBuffer( m_buffer );
writeBuffer( m_buffer, frames, mixer::inst()->masterGain() );
}
Uint32 audioDevice::getNextBuffer( surroundSampleFrame * _ab )
{
Uint32 frames = mixer::inst()->framesPerAudioBuffer();
const surroundSampleFrame * b = mixer::inst()->renderNextBuffer();
// make sure, no other thread is accessing device
lock();
// now were save to access the device
if( _src_sample_rate != m_sampleRate )
// now were safe to access the device
if( mixer::inst()->sampleRate() != m_sampleRate )
{
surroundSampleFrame * temp =
bufferAllocator::alloc<surroundSampleFrame>(
_frames * channels() );
resample( _ab, _frames, temp, _src_sample_rate, m_sampleRate );
writeBufferToDev( temp, _frames * m_sampleRate /
_src_sample_rate, _master_gain );
bufferAllocator::free( temp );
resample( b, frames, _ab, mixer::inst()->sampleRate(),
m_sampleRate );
frames = frames * m_sampleRate / mixer::inst()->sampleRate();
}
else
{
writeBufferToDev( _ab, _frames, _master_gain );
memcpy( _ab, b, frames * sizeof( surroundSampleFrame ) );
}
// release lock
unlock();
return( frames );
}
@@ -111,7 +125,7 @@ void audioDevice::unregisterPort( audioPort * _port )
void audioDevice::renamePort( audioPort *, const QString & )
void audioDevice::renamePort( audioPort * )
{
}
@@ -150,7 +164,8 @@ const float LP_FILTER_COEFFS[LP_FILTER_TAPS] =
#endif
void FASTCALL audioDevice::resample( surroundSampleFrame * _src, Uint32 _frames,
void FASTCALL audioDevice::resample( const surroundSampleFrame * _src,
Uint32 _frames,
surroundSampleFrame * _dst,
Uint32 _src_sr, Uint32 _dst_sr )
{
@@ -161,7 +176,7 @@ void FASTCALL audioDevice::resample( surroundSampleFrame * _src, Uint32 _frames,
}
m_srcData.input_frames = _frames;
m_srcData.output_frames = _frames;
m_srcData.data_in = _src[0];
m_srcData.data_in = (float *) _src[0];
m_srcData.data_out = _dst[0];
m_srcData.src_ratio = (float) _dst_sr / _src_sr;
@@ -172,7 +187,7 @@ void FASTCALL audioDevice::resample( surroundSampleFrame * _src, Uint32 _frames,
src_strerror( error ) );
}
#else
if( _src_sr == 2*SAMPLE_RATES[DEFAULT_QUALITY_LEVEL] )
if( _src_sr == 2 * SAMPLE_RATES[DEFAULT_QUALITY_LEVEL] )
{
// we use a simple N-tap FIR-Filter with
// precalculated/-designed LP-Coeffs

View File

@@ -39,6 +39,7 @@
#include "audio_file_device.h"
#include "export_project_dialog.h"
#include "buffer_allocator.h"
audioFileDevice::audioFileDevice( Uint32 _sample_rate, Uint8 _channels,

View File

@@ -1,5 +1,5 @@
/*
* audio_file_ogg.cpp - Audio-device which encodes wave-stream and writes it
* audio_file_ogg.cpp - audio-device which encodes wave-stream and writes it
* into an OGG-file. This is used for song-export.
*
* This file is based on encode.c from vorbis-tools-source, for more information
@@ -27,17 +27,6 @@
*/
/* OggEnc
**
** This program is distributed under the GNU General Public License, version 2.
** A copy of this license is included with this source.
**
** Copyright 2000-2002, Michael Smith <msmith@labyrinth.net.au>
**
** Portions from Vorbize, (c) Kenneth Arnold <kcarnold@yahoo.com>
** and libvorbis examples, (c) Monty <monty@xiph.org>
**/
#include <qpair.h>
@@ -84,7 +73,7 @@ inline int audioFileOgg::writePage( void )
bool audioFileOgg::startEncoding( void )
{
vorbis_comment vc;
char * comments = "Cool=This song was written with Linux "
char * comments = "Cool=This song has been made using Linux "
"MultiMedia Studio";
int comment_length = strlen( comments );
@@ -185,7 +174,7 @@ bool audioFileOgg::startEncoding( void )
void FASTCALL audioFileOgg::writeBufferToDev( surroundSampleFrame * _ab,
void FASTCALL audioFileOgg::writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain )
{
@@ -253,7 +242,7 @@ void FASTCALL audioFileOgg::writeBufferToDev( surroundSampleFrame * _ab,
void audioFileOgg::finishEncoding( void )
{
// just for flushing buffers...
writeBufferToDev( NULL, 0, 0.0f );
writeBuffer( NULL, 0, 0.0f );
// clean up
ogg_stream_clear( &m_os );

View File

@@ -1,5 +1,5 @@
/*
* audio_file_wave.cpp - Audio-device which encodes wave-stream and writes it
* audio_file_wave.cpp - audio-device which encodes wave-stream and writes it
* into a WAVE-file. This is used for song-export.
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
@@ -87,7 +87,7 @@ bool audioFileWave::startEncoding( void )
void FASTCALL audioFileWave::writeBufferToDev( surroundSampleFrame * _ab,
void FASTCALL audioFileWave::writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain )
{

View File

@@ -28,12 +28,6 @@
#ifdef JACK_SUPPORT
#ifdef HAVE_UNISTD_H
// for usleep
#include <unistd.h>
#endif
#ifdef QT4
#include <QLineEdit>
@@ -55,6 +49,7 @@
#include "buffer_allocator.h"
#include "config_mgr.h"
#include "lcd_spinbox.h"
#include "audio_port.h"
@@ -62,10 +57,13 @@ audioJACK::audioJACK( Uint32 _sample_rate, bool & _success_ful ) :
audioDevice( _sample_rate, tLimit<int>( configManager::inst()->value(
"audiojack", "channels" ).toInt(),
DEFAULT_CHANNELS, SURROUND_CHANNELS ) ),
m_client( NULL ),
m_stopped( FALSE ),
m_processCallbackMutex(),
m_outBuf( bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() ) ),
m_framesDoneInCurBuf( 0 ),
m_frameSync( 0 ),
m_jackBufSize( 0 ),
m_bufMutex()
m_framesToDoInCurBuf( 0 )
{
_success_ful = FALSE;
@@ -120,12 +118,6 @@ audioJACK::audioJACK( Uint32 _sample_rate, bool & _success_ful ) :
// set process-callback
jack_set_process_callback( m_client, processCallback, this );
m_jackBufSize = jack_get_buffer_size( m_client );
// we need to know about buffer-size changes to know how long to block
// in writeToDev()-method
jack_set_buffer_size_callback( m_client, bufSizeCallback, this );
// set shutdown-callback
jack_on_shutdown( m_client, shutdownCallback, this );
@@ -140,7 +132,7 @@ audioJACK::audioJACK( Uint32 _sample_rate, bool & _success_ful ) :
for( Uint8 ch = 0; ch < channels(); ++ch )
{
QString name = QString( "master_out_" ) +
QString name = QString( "master out " ) +
( ( ch % 2 ) ? "R" : "L" ) +
QString::number( ch / 2 + 1 );
m_outputPorts.push_back( jack_port_register( m_client,
@@ -212,80 +204,62 @@ audioJACK::audioJACK( Uint32 _sample_rate, bool & _success_ful ) :
audioJACK::~audioJACK()
{
while( m_portMap.size() )
{
unregisterPort( m_portMap.begin().key() );
}
if( m_client != NULL )
{
jack_deactivate( m_client );
jack_client_close( m_client );
}
while( m_bufferSets.size() )
{
while( m_bufferSets.front().size() )
{
bufferAllocator::free(
m_bufferSets.front().front().buf );
m_bufferSets.front().erase(
m_bufferSets.front().begin() );
}
m_bufferSets.erase( m_bufferSets.begin() );
}
bufferAllocator::free( m_outBuf );
}
void audioJACK::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
float _master_gain )
void audioJACK::startProcessing( void )
{
if( m_client == NULL )
{
return;
}
m_bufMutex.lock();
jack_transport_state_t ts = jack_transport_query( m_client, NULL );
if( ts == JackTransportRolling )
{
vvector<bufset> bufs;
for( Uint8 chnl = 0; chnl < channels(); ++chnl )
{
sampleType * buf = bufferAllocator::alloc<sampleType>(
_frames );
for( Uint32 frame = 0; frame < _frames; ++frame )
{
buf[frame] = _ab[frame][chnl] * _master_gain;
}
bufset b = { buf, _frames } ;
bufs.push_back( b );
}
m_bufferSets.push_back( bufs );
}
m_frameSync += _frames;
m_bufMutex.unlock();
// now wait until data has been collected/skipped by processCallback()
while( m_frameSync > m_jackBufSize )
{
#ifdef HAVE_UNISTD_H
#ifdef HAVE_USLEEP
// just wait and give cpu-time to other processes
// tobydox 20051019: causes LMMS to hang up when locking
// several other mutexes, so skip it
//usleep( 200 );
#endif
#endif
}
m_stopped = FALSE;
}
void audioJACK::registerPort( audioPort * )
void audioJACK::stopProcessing( void )
{
m_stopped = TRUE;
}
void audioJACK::registerPort( audioPort * _port )
{
return;
/* // make sure, port is not already registered
unregisterPort( _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,
name[ch].
#ifdef QT4
toAscii().constData(),
#else
ascii(),
#endif
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0 );
}
m_processCallbackMutex.unlock();*/
}
@@ -293,13 +267,45 @@ void audioJACK::registerPort( audioPort * )
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 )
{
jack_port_unregister( m_client,
m_portMap[_port].ports[ch] );
}
}
m_portMap.erase( m_portMap.find( _port ) );
m_processCallbackMutex.unlock();
}*/
}
void audioJACK::renamePort( audioPort *, const QString & )
void audioJACK::renamePort( audioPort * _port )
{
return;
/* if( m_portMap.contains( _port ) )
{
const QString name[2] = { _port->name() + " L",
_port->name() + " R" };
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
jack_port_set_name( m_portMap[_port].ports[ch],
name[ch].
#ifdef QT4
toAscii().constData()
#else
ascii()
#endif
) ;
}
}*/
}
@@ -308,6 +314,7 @@ void audioJACK::renamePort( audioPort *, const QString & )
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 ) );*/
@@ -316,104 +323,78 @@ int audioJACK::processCallback( jack_nframes_t _nframes, void * _udata )
#endif
jack_transport_state_t ts = jack_transport_query( _this->m_client,
NULL );
_this->m_bufMutex.lock();
if( ts != JackTransportRolling )
{
// always decrease frame-sync-var as we would do it if running
// in normal mode, so that the mixer-thread knows when to
// proceed
if( _nframes < _this->m_frameSync )
{
_this->m_frameSync -= _nframes;
}
else
{
_this->m_frameSync = 0;
}
_this->m_bufMutex.unlock();
return( 0 );
}
vvector<jack_default_audio_sample_t *> outbufs( _this->channels(),
NULL );
Uint8 ch = 0;
Uint8 chnl = 0;
for( vvector<jack_default_audio_sample_t *>::iterator it =
outbufs.begin(); it != outbufs.end(); ++it, ++ch )
outbufs.begin(); it != outbufs.end(); ++it, ++chnl )
{
*it = (jack_default_audio_sample_t *) jack_port_get_buffer(
_this->m_outputPorts[ch], _nframes );
_this->m_outputPorts[chnl], _nframes );
}
/* const Uint32 frames = tMin<Uint32>( _nframes,
mixer::inst()->framesPerAudioBuffer() );
for( jackPortMap::iterator it = _this->m_portMap.begin();
it != _this->m_portMap.end(); ++it )
{
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
if( it.data().ports[ch] == NULL )
{
continue;
}
jack_default_audio_sample_t * buf =
(jack_default_audio_sample_t *) jack_port_get_buffer(
it.data().ports[ch],
_nframes );
for( Uint32 frame = 0; frame < frames; ++frame )
{
buf[frame] = it.key()->firstBuffer()[ch][frame];
}
}
}*/
jack_nframes_t done = 0;
while( done < _nframes )
while( done < _nframes && _this->m_stopped == FALSE )
{
if( _this->m_bufferSets.size() == 0 )
{
break;
}
jack_nframes_t todo = tMin( _nframes - done,
_this->m_bufferSets.front()[0].frames -
jack_nframes_t todo = tMin<jack_nframes_t>(
_nframes,
_this->m_framesToDoInCurBuf -
_this->m_framesDoneInCurBuf );
for( Uint8 ch = 0; ch < _this->channels(); ++ch )
if( ts == JackTransportRolling )
{
memcpy( outbufs[ch] + done,
_this->m_bufferSets.front()[ch].buf +
_this->m_framesDoneInCurBuf,
sizeof( jack_default_audio_sample_t ) *
todo );
}
_this->m_framesDoneInCurBuf += todo;
if( _this->m_framesDoneInCurBuf >=
_this->m_bufferSets.front()[0].frames )
{
for( Uint8 ch = 0; ch < _this->channels(); ++ch )
for( Uint8 chnl = 0; chnl < _this->channels(); ++chnl )
{
bufferAllocator::free(
_this->m_bufferSets.front()[ch].buf );
for( Uint32 frame = 0; frame < todo; ++frame )
{
outbufs[chnl][done+frame] =
_this->m_outBuf[_this->m_framesDoneInCurBuf+frame][chnl] *
mixer::inst()->masterGain();
}
}
_this->m_bufferSets.erase(
_this->m_bufferSets.begin() );
_this->m_framesDoneInCurBuf = 0;
}
done += todo;
_this->m_frameSync -= todo;
_this->m_framesDoneInCurBuf += todo;
if( _this->m_framesDoneInCurBuf == _this->m_framesToDoInCurBuf )
{
_this->m_framesToDoInCurBuf = _this->getNextBuffer(
_this->m_outBuf );
_this->m_framesDoneInCurBuf = 0;
}
}
// we have to clear the part of the buffers, if we could not fill
// because no usable data is left, otherwise there's baaaaaad
// noise... ;-)
if( done < _nframes )
if( ts != JackTransportRolling || _this->m_stopped == TRUE )
{
for( Uint8 ch = 0; ch < _this->channels(); ++ch )
{
jack_default_audio_sample_t * b = outbufs[ch];
memset( b + done, 0,
sizeof( *b ) * ( _nframes - done ) );
/* for( Uint32 frame = done; frame < _nframes; ++frame )
{
b[frame] = 0.0f;
}*/
memset( b, 0, sizeof( *b ) * _nframes );
}
}
_this->m_bufMutex.unlock();
return( 0 );
}
int audioJACK::bufSizeCallback( jack_nframes_t _nframes, void * _udata )
{
audioJACK * _this = static_cast<audioJACK *>( _udata );
#ifdef LMMS_DEBUG
assert( _this != NULL );
#endif
_this->m_jackBufSize = _nframes;
_this->m_processCallbackMutex.unlock();
return( 0 );
}

View File

@@ -95,7 +95,8 @@ audioOSS::audioOSS( Uint32 _sample_rate, bool & _success_ful ) :
audioDevice( _sample_rate, tLimit<int>( configManager::inst()->value(
"audiooss", "channels" ).toInt(),
DEFAULT_CHANNELS, SURROUND_CHANNELS ) ),
m_convertEndian( FALSE )
m_convertEndian( FALSE ),
m_quit( FALSE )
{
_success_ful = FALSE;
@@ -231,6 +232,7 @@ audioOSS::audioOSS( Uint32 _sample_rate, bool & _success_ful ) :
audioOSS::~audioOSS()
{
stopProcessing();
close( m_audioFD );
}
@@ -278,15 +280,52 @@ QString audioOSS::probeDevice( void )
void audioOSS::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
float _master_gain )
void audioOSS::startProcessing( void )
{
outputSampleType * outbuf = bufferAllocator::alloc<outputSampleType>(
_frames * channels() );
int bytes = convertToS16( _ab, _frames, _master_gain, outbuf,
m_convertEndian );
write( m_audioFD, outbuf, bytes );
if( !running() )
{
start();
}
}
void audioOSS::stopProcessing( void )
{
if( running() )
{
m_quit = TRUE;
wait( 500 );
terminate();
}
}
void audioOSS::run( void )
{
surroundSampleFrame * temp =
bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() );
outputSampleType * outbuf =
bufferAllocator::alloc<outputSampleType>(
mixer::inst()->framesPerAudioBuffer() *
channels() );
m_quit = FALSE;
while( m_quit == FALSE )
{
const Uint32 frames = getNextBuffer( temp );
int bytes = convertToS16( temp, frames,
mixer::inst()->masterGain(), outbuf,
m_convertEndian );
write( m_audioFD, outbuf, bytes );
}
bufferAllocator::free( temp );
bufferAllocator::free( outbuf );
}

View File

@@ -35,13 +35,15 @@ audioPort::audioPort( const QString & _name ) :
m_secondBuffer( bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() ) ),
m_extOutputEnabled( FALSE ),
m_nextFxChannel( -1 )
m_nextFxChannel( -1 ),
m_name( "unnamed port" )
{
mixer::inst()->clearAudioBuffer( m_firstBuffer,
mixer::inst()->framesPerAudioBuffer() );
mixer::inst()->clearAudioBuffer( m_secondBuffer,
mixer::inst()->framesPerAudioBuffer() );
mixer::inst()->addAudioPort( this );
setExtOutputEnabled( TRUE );
}
@@ -95,6 +97,7 @@ void audioPort::setExtOutputEnabled( bool _enabled )
void audioPort::setName( const QString & _name )
{
mixer::inst()->audioDev()->renamePort( this, _name );
m_name = _name;
mixer::inst()->audioDev()->renamePort( this );
}

View File

@@ -96,7 +96,7 @@ void audioSampleRecorder::createSampleBuffer( sampleBuffer * * _sample_buf )
void audioSampleRecorder::writeBufferToDev( surroundSampleFrame * _ab,
void audioSampleRecorder::writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames, float )
{
sampleFrame * buf = bufferAllocator::alloc<sampleFrame>( _frames );

View File

@@ -50,11 +50,8 @@
audioSDL::audioSDL( Uint32 _sample_rate, bool & _success_ful ) :
audioDevice( _sample_rate, DEFAULT_CHANNELS ),
m_buffer( bufferAllocator::alloc<outputSampleType>(
mixer::inst()->framesPerAudioBuffer() *
channels() ) ),
m_bufMutex(),
m_callbackMutex(),
m_outBuf( bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() ) ),
m_convertEndian( FALSE )
{
_success_ful = FALSE;
@@ -99,11 +96,6 @@ audioSDL::audioSDL( Uint32 _sample_rate, bool & _success_ful ) :
}
m_convertEndian = ( m_audioHandle.format != actual.format );
clearS16Buffer( m_buffer, m_audioHandle.samples );
// start playing
SDL_PauseAudio( 0 );
_success_ful = TRUE;
}
@@ -112,31 +104,31 @@ audioSDL::audioSDL( Uint32 _sample_rate, bool & _success_ful ) :
audioSDL::~audioSDL()
{
SDL_PauseAudio( 1 );
stopProcessing();
SDL_CloseAudio();
SDL_Quit();
m_bufMutex.lock();
bufferAllocator::free( m_buffer );
m_bufMutex.unlock();
bufferAllocator::free( m_outBuf );
}
void audioSDL::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
float _master_gain )
void audioSDL::startProcessing( void )
{
m_bufMutex.lock();
convertToS16( _ab, _frames, _master_gain, m_buffer,
m_convertEndian );
m_bufMutex.unlock();
// before returning make sure, callback was called, so we're synced
// with it (otherwise it could be that (if there's not much to render)
// this function is called several times although we had to wait until
// we can proceed with next audio-output)
m_callbackMutex.lock();
SDL_PauseAudio( 0 );
SDL_UnlockAudio();
}
void audioSDL::stopProcessing( void )
{
if( SDL_GetAudioStatus() == SDL_AUDIO_PLAYING )
{
SDL_LockAudio();
SDL_PauseAudio( 1 );
}
}
@@ -150,21 +142,12 @@ void audioSDL::sdlAudioCallback( void * _udata, Uint8 * _buf, int _len )
assert( _this != NULL );
#endif
_this->m_bufMutex.lock();
const Uint32 frames = _this->getNextBuffer( _this->m_outBuf );
// writeBufferToDev() prepared everything for us, so we just have
// to do a memcpy() :-)
memcpy( _buf, _this->m_buffer, _len );
// clear our output buffer, so that we don't output the same noise
// when being called again without that writeBufferToDev() was called
// (e.g. if there's too much to render)
_this->clearS16Buffer( _this->m_buffer, _this->m_audioHandle.samples );
_this->m_bufMutex.unlock();
// we got our last buffer, so we let writeBufferToDev() return
_this->m_callbackMutex.unlock();
_this->convertToS16( _this->m_outBuf, frames,
mixer::inst()->masterGain(),
(outputSampleType *)( _buf ),
_this->m_convertEndian );
}

View File

@@ -39,6 +39,7 @@
#include <qdom.h>
#include <qlabel.h>
#include <qcombobox.h>
#include <qwhatsthis.h>
#define setChecked setOn

View File

@@ -30,10 +30,12 @@
#include <QPainter>
#include <QKeyEvent>
#include <QCloseEvent>
#include <QLayout>
#else
#include <qpainter.h>
#include <qlayout.h>
#endif
@@ -41,13 +43,12 @@
#include "bb_editor.h"
#include "song_editor.h"
#include "embed.h"
#include "pixmap_button.h"
#include "tool_button.h"
#include "track_container.h"
#include "bb_track.h"
#include "name_label.h"
#include "templates.h"
#include "debug.h"
#include "spc_bg_hndl_widget.h"
#include "tooltip.h"
@@ -57,18 +58,22 @@ const int BBE_PPT = 192;
bbEditor * bbEditor::s_instanceOfMe = NULL;
QPixmap * bbEditor::s_titleArtwork = NULL;
bbEditor::bbEditor() :
trackContainer()
{
if( s_titleArtwork == NULL )
{
s_titleArtwork = new QPixmap( embed::getIconPixmap(
"bb_editor_title_artwork" ) );
}
// create toolbar
m_toolBar = new QWidget( this );
m_toolBar->setFixedHeight( 32 );
m_toolBar->move( 0, 0 );
m_toolBar->setPaletteBackgroundPixmap( embed::getIconPixmap(
"toolbar_bg" ) );
QHBoxLayout * tb_layout = new QHBoxLayout( m_toolBar );
setWindowIcon( embed::getIconPixmap( "bb_track" ) );
setWindowTitle( tr( "Beat+Bassline Editor" ) );
@@ -83,33 +88,19 @@ bbEditor::bbEditor() :
setGeometry( 210, 340, minimumWidth(), 300 );
}
containerWidget()->move( 0, 47 );
containerWidget()->move( 0, 32 );
setPixelsPerTact( BBE_PPT );
updateBackground();
m_playButton = new pixmapButton( this );
m_playButton->move( 96, 7 );
m_playButton->setCheckable( FALSE );
m_playButton->setActiveGraphic( embed::getIconPixmap( "play" ) );
m_playButton->setInactiveGraphic( embed::getIconPixmap( "play" ) );
m_playButton->setBgGraphic( specialBgHandlingWidget::getBackground(
m_playButton ) );
connect( m_playButton, SIGNAL( clicked() ), this, SLOT( play() ) );
m_stopButton = new pixmapButton( this );
m_stopButton->move( 136, 7 );
m_stopButton->setCheckable( FALSE );
m_stopButton->setActiveGraphic( embed::getIconPixmap( "stop" ) );
m_stopButton->setInactiveGraphic( embed::getIconPixmap( "stop" ) );
m_stopButton->setBgGraphic( specialBgHandlingWidget::getBackground(
m_playButton ) );
connect( m_stopButton, SIGNAL( clicked() ), this, SLOT( stop() ) );
toolTip::add( m_playButton,
tr( "Play/pause current beat/bassline (Space)" ) );
toolTip::add( m_stopButton,
tr( "Stop playing of current beat/bassline (Space)" ) );
m_playButton = new toolButton( embed::getIconPixmap( "play" ),
tr( "Play/pause current beat/bassline (Space)" ),
this, SLOT( play() ), m_toolBar );
m_stopButton = new toolButton( embed::getIconPixmap( "stop" ),
tr( "Stop playing of current beat/bassline (Space)" ),
this, SLOT( stop() ), m_toolBar );
#ifdef QT4
m_playButton->setWhatsThis(
#else
@@ -126,9 +117,15 @@ bbEditor::bbEditor() :
tr( "Click here, if you want to stop playing of current "
"beat/bassline." ) );
#ifndef QT4
setBackgroundMode( Qt::NoBackground );
#endif
QLabel * l = new QLabel( m_toolBar );
l->setPixmap( embed::getIconPixmap( "drum" ) );
tb_layout->addSpacing( 5 );
tb_layout->addWidget( m_playButton );
tb_layout->addWidget( m_stopButton );
tb_layout->addStretch();
tb_layout->addWidget( l );
tb_layout->addSpacing( 15 );
show();
}
@@ -305,39 +302,11 @@ void bbEditor::keyPressEvent( QKeyEvent * _ke )
void bbEditor::resizeEvent( QResizeEvent * _re )
{
updateBackground();
setPixelsPerTact( width() - ( TRACK_OP_WIDTH +
DEFAULT_SETTINGS_WIDGET_WIDTH + 2 *
TCO_BORDER_WIDTH ) );
trackContainer::resizeEvent( _re );
}
void bbEditor::updateBackground( void )
{
QPixmap draw_pm( size() );
#ifdef QT4
draw_pm.fill( containerWidget()->palette().brush(
containerWidget()->backgroundRole() ).color() );
#else
draw_pm.fill( containerWidget()->paletteBackgroundColor() );
#endif
QPainter p( &draw_pm );
p.fillRect( 0, 0, width(), s_titleArtwork->height(),
QColor( 74, 125, 213 ) );
p.drawPixmap( 0, 0, *s_titleArtwork );
#ifdef QT4
QPalette pal = palette();
pal.setBrush( backgroundRole(), QBrush( draw_pm ) );
setPalette( pal );
#else
setErasePixmap( draw_pm );
#endif
m_toolBar->setFixedWidth( width() );
}
@@ -351,26 +320,24 @@ void bbEditor::play( void )
{
songEditor::inst()->stop();
songEditor::inst()->playBB();
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "pause" ) );
m_playButton->setPixmap( embed::getIconPixmap(
"pause" ) );
}
else
{
songEditor::inst()->pause();
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "play" ) );
m_playButton->setPixmap( embed::getIconPixmap(
"play" ) );
}
}
else if( songEditor::inst()->paused() )
{
songEditor::inst()->resumeFromPause();
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "pause" ) );
m_playButton->setPixmap( embed::getIconPixmap( "pause" ) );
}
else
{
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "pause" ) );
m_playButton->setPixmap( embed::getIconPixmap( "pause" ) );
songEditor::inst()->playBB();
}
@@ -382,7 +349,7 @@ void bbEditor::play( void )
void bbEditor::stop( void )
{
songEditor::inst()->stop();
m_playButton->setInactiveGraphic( embed::getIconPixmap( "play" ) );
m_playButton->setPixmap( embed::getIconPixmap( "play" ) );
m_playButton->update();
}

View File

@@ -740,7 +740,7 @@ bool configManager::loadConfigFile( void )
// get the head information from the DOM
QDomElement root = dom_tree.documentElement();
if( root.isElement() )
/* if( root.isElement() )
{
QString cfg_file_ver = root.toElement().attribute( "version" );
if( ( cfg_file_ver.length() == 0 || cfg_file_ver != VERSION ) &&
@@ -771,7 +771,7 @@ bool configManager::loadConfigFile( void )
return( loadConfigFile() );
}
}
}
}*/
QDomNode node = root.firstChild();

View File

@@ -32,10 +32,10 @@
#include <QProgressBar>
#include <QComboBox>
#include <QCheckBox>
#include <QTimer>
#include <QLabel>
#include <QPushButton>
#include <QCloseEvent>
#include <QApplication>
#else
@@ -44,21 +44,25 @@
#include <qprogressbar.h>
#include <qcombobox.h>
#include <qcheckbox.h>
#include <qtimer.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qapplication.h>
#endif
#include "export_project_dialog.h"
#include "song_editor.h"
#include "lmms_main_win.h"
#include "embed.h"
#include "audio_file_wave.h"
#include "audio_file_ogg.h"
extern QString file_to_render;
fileEncodeDevice fileEncodeDevices[] =
{
@@ -129,9 +133,7 @@ exportProjectDialog::exportProjectDialog( const QString & _file_name,
QDialog( _parent ),
m_fileName( _file_name ),
m_hourglassLbl( NULL ),
m_exportProgressBar( NULL ),
m_deleteFile( FALSE ),
m_oldProgressVal( -1 )
m_deleteFile( FALSE )
{
#ifdef QT4
m_fileType = getFileTypeFromExtension( "." +
@@ -312,35 +314,6 @@ void exportProjectDialog::exportBtnClicked( void )
{
if( fileEncodeDevices[idx].m_fileType == m_fileType )
{
bool success_ful = FALSE;
audioDevice * dev = fileEncodeDevices[idx].m_getDevInst(
DEFAULT_SAMPLE_RATE,
DEFAULT_CHANNELS,
success_ful,
m_fileName,
m_vbrCb->isChecked(),
m_kbpsCombo->currentText().toInt(),
m_kbpsCombo->currentText().toInt() - 64,
m_kbpsCombo->currentText().toInt() + 64
);
if( success_ful == FALSE )
{
QMessageBox::information( this,
tr( "Export failed" ),
tr( "The project-export failed, "
"because the output-file/-"
"device could not be opened.\n"
"Make sure, you have write "
"access to the selected "
"file/device!" ),
QMessageBox::Ok );
return;
}
mixer::inst()->pause();
mixer::inst()->setAudioDevice( dev,
m_hqmCb->isChecked() );
songEditor::inst()->startExport();
mixer::inst()->play();
break;
}
++idx;
@@ -351,6 +324,32 @@ void exportProjectDialog::exportBtnClicked( void )
return;
}
bool success_ful = FALSE;
audioFileDevice * dev = fileEncodeDevices[idx].m_getDevInst(
DEFAULT_SAMPLE_RATE,
DEFAULT_CHANNELS,
success_ful,
m_fileName,
m_vbrCb->isChecked(),
m_kbpsCombo->currentText().toInt(),
m_kbpsCombo->currentText().toInt() - 64,
m_kbpsCombo->currentText().toInt() + 64
);
if( success_ful == FALSE )
{
QMessageBox::information( this,
tr( "Export failed" ),
tr( "The project-export failed, "
"because the output-file/-"
"device could not be opened.\n"
"Make sure, you have write "
"access to the selected "
"file/device!" ),
QMessageBox::Ok );
return;
}
setWindowTitle( tr( "Exporting project to %1" ).arg(
QFileInfo( m_fileName ).fileName() ) );
@@ -379,11 +378,40 @@ void exportProjectDialog::exportBtnClicked( void )
m_cancelBtn->move( CANCEL_X_WHILE_EXPORT, CANCEL_Y_WHILE_EXPORT );
m_progressBarUpdateTimer = new QTimer( this );
connect( m_progressBarUpdateTimer, SIGNAL( timeout() ), this,
SLOT( redrawProgressBar() ) );
m_progressBarUpdateTimer->start( 100 );
mixer::inst()->setAudioDevice( dev, m_hqmCb->isChecked() );
songEditor::inst()->startExport();
songEditor::playPos & pp = songEditor::inst()->getPlayPos(
songEditor::PLAY_SONG );
while( songEditor::inst()->exportDone() == FALSE &&
songEditor::inst()->exporting() == TRUE )
{
dev->processNextBuffer();
int pval = pp * 100 /
( ( songEditor::inst()->lengthInTacts() + 1 ) * 64 );
#ifdef QT4
m_exportProgressBar->setValue( pval );
#else
m_exportProgressBar->setProgress( pval );
#endif
// update lmms-main-win-caption
lmmsMainWin::inst()->setWindowTitle( tr( "Rendering:" ) + " " +
QString::number( pval ) + "%" );
// process paint-events etc.
qApp->processEvents();
}
// if m_deleteFile == TRUE, user aborted export and finalization-
// routines were already called, so we only need to call them if
// export went through without any problems
if( m_deleteFile == FALSE )
{
finishProjectExport();
}
}
@@ -398,19 +426,6 @@ void exportProjectDialog::cancelBtnClicked( void )
abortProjectExport();
return;
}
// if the user aborted export-process, the file has to be deleted
if( m_deleteFile )
{
QFile( m_fileName ).remove();
}
// restore window-title
lmmsMainWin::inst()->resetWindowTitle();
// let's close us...
accept();
}
@@ -419,7 +434,6 @@ void exportProjectDialog::cancelBtnClicked( void )
// called whenever there's a reason for aborting song-export (like user-input)
void exportProjectDialog::abortProjectExport( void )
{
mixer::inst()->pause();
m_deleteFile = TRUE;
finishProjectExport();
@@ -430,53 +444,32 @@ void exportProjectDialog::abortProjectExport( void )
void exportProjectDialog::finishProjectExport( void )
{
m_progressBarUpdateTimer->stop();
delete m_progressBarUpdateTimer;
mixer::inst()->restoreAudioDevice();
// if the user aborted export-process, the file has to be deleted
if( m_deleteFile )
{
QFile( m_fileName ).remove();
}
// restore window-title
lmmsMainWin::inst()->resetWindowTitle();
songEditor::inst()->stopExport();
mixer::inst()->play();
// this method does the final cleanup...
cancelBtnClicked();
}
void exportProjectDialog::redrawProgressBar( void )
{
if( m_progressVal != m_oldProgressVal )
// if we rendered file from command line, quit after export
if( file_to_render != "" )
{
#ifdef QT4
m_exportProgressBar->setValue( m_progressVal );
#else
m_exportProgressBar->setProgress( m_progressVal );
#endif
// update lmms-main-win-caption
lmmsMainWin::inst()->setWindowTitle( tr( "Rendering:" ) + " " +
QString::number( m_progressVal ) + "%" );
m_oldProgressVal = m_progressVal;
}
if( songEditor::inst()->exportDone() == TRUE ||
songEditor::inst()->exporting() == FALSE )
{
finishProjectExport();
// qApp->quit(); - doesn't work for some reason...
exit( 0 );
}
// let's close us...
accept();
}
void exportProjectDialog::updateProgressBar( int _new_val )
{
m_progressVal = _new_val;
}
#include "export_project_dialog.moc"

View File

@@ -61,17 +61,37 @@ int main( int argc, char * * argv )
{
QApplication app( argc, argv );
QString extension = "wav";
for( int i = 1; i < app.argc(); ++i )
{
if( QString( app.argv()[i] ) == "--version" ||
QString( app.argv()[i] ) == "-v" )
{
printf( "\n%s\n\n"
printf( "\nLinux MultiMedia Studio %s\n\n"
"Copyright (c) 2004-2005 Tobias Doerffel and others.\n\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public\n"
"License as published by the Free Software Foundation; either\n"
"version 2 of the License, or (at your option) any later version.\n\n",
PACKAGE_STRING );
"version 2 of the License, or (at your option) any later version.\n\n"
"Try \"%s --help\" for more information.\n\n", PACKAGE_VERSION,
argv[0] );
return( 0 );
}
else if( app.argc() > i &&
( QString( app.argv()[i] ) == "--help" ||
QString( app.argv()[i] ) == "-h" ) )
{
printf( "\nLinux MultiMedia Studio %s\n"
"Copyright (c) 2004-2005 Tobias Doerffel and others.\n\n"
"usage: lmms [ -r <file_to_render> [ -o <format> ] [ -h ] "
"[ <file_to_load> ]\n"
"-r, --render render given file.\n"
"-o, --output-format <format> specify format of render-output where\n"
" format is either 'wav' or 'ogg'.\n"
"-v, --version show version information and exit.\n"
"-h, --help show this usage message and exit.\n\n",
PACKAGE_VERSION );
return( 0 );
}
else if( app.argc() > i &&
@@ -79,14 +99,42 @@ int main( int argc, char * * argv )
QString( app.argv()[i] ) == "-r" ) )
{
file_to_load = QString( app.argv()[i+1] );
file_to_render = QString( app.argv()[i+1] ) + ".wav";
file_to_render = baseName( file_to_load ) + ".";
++i;
}
else if( app.argc() > i &&
( QString( app.argv()[i] ) == "--output-format" ||
QString( app.argv()[i] ) == "-o" ) )
{
extension = QString( app.argv()[i+1] );
if( extension != "wav" && extension != "ogg" )
{
printf( "\nInvalid output format %s.\n\n"
"Try \"%s --help\" for more information.\n\n", app.argv()[i+1],
argv[0] );
return( -1 );
}
++i;
}
else
{
if( app.argv()[i][0] == '-' )
{
printf( "\nInvalid option %s.\n\n"
"Try \"%s --help\" for more information.\n\n", app.argv()[i],
argv[0] );
return( -1 );
}
file_to_load = app.argv()[i];
}
}
if( file_to_render != "" )
{
file_to_render += extension;
}
QString pos =
#ifdef QT4
QLocale::system().name().left( 2 );
@@ -172,7 +220,6 @@ int main( int argc, char * * argv )
exportProjectDialog * e = new exportProjectDialog(
file_to_render,
lmmsMainWin::inst() );
songEditor::inst()->setExportProjectDialog( e );
e->show();
e->exportBtnClicked();
}

View File

@@ -57,21 +57,12 @@ mixer * mixer::s_instanceOfMe = NULL;
mixer::mixer() :
#ifndef QT4
QObject(),
#endif
QThread(),
/* m_silence(),
#ifndef DISABLE_SURROUND
m_surroundSilence(),
#endif*/
m_framesPerAudioBuffer( DEFAULT_BUFFER_SIZE ),
m_curBuf( NULL ),
m_nextBuf( NULL ),
m_discardCurBuf( FALSE ),
m_qualityLevel( DEFAULT_QUALITY_LEVEL ),
m_masterOutput( 1.0f ),
m_quit( FALSE ),
m_masterGain( 1.0f ),
m_audioDev( NULL ),
m_oldAudioDev( NULL )
{
@@ -101,30 +92,12 @@ mixer::mixer() :
m_midiClient = tryMIDIClients();
/* m_silence = bufferAllocator::alloc<sampleFrame>(
m_framesPerAudioBuffer );
#ifndef DISABLE_SURROUND
m_surroundSilence = bufferAllocator::alloc<surroundSampleFrame>(
m_framesPerAudioBuffer );
#endif
for( Uint32 frame = 0; frame < m_framesPerAudioBuffer; ++frame )
{
for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
{
m_silence[frame][chnl] = 0.0f;
}
#ifndef DISABLE_SURROUND
for( Uint8 chnl = 0; chnl < SURROUND_CHANNELS; ++chnl )
{
m_surroundSilence[frame][chnl] = 0.0f;
}
#endif
}*/
// now clear our two output-buffers before using them...
clearAudioBuffer( m_curBuf, m_framesPerAudioBuffer );
clearAudioBuffer( m_nextBuf, m_framesPerAudioBuffer );
m_audioDev->startProcessing();
}
@@ -137,132 +110,98 @@ mixer::~mixer()
bufferAllocator::free( m_curBuf );
bufferAllocator::free( m_nextBuf );
/* bufferAllocator::free( m_silence );
#ifndef DISABLE_SURROUND
bufferAllocator::free( m_surroundSilence );
#endif*/
}
void mixer::quitThread( void )
void mixer::stopProcessing( void )
{
// make sure there're no mutexes locked anymore...
m_safetySyncMutex.unlock();
m_devMutex.unlock();
// now tell mixer-thread to quit
m_quit = TRUE;
wait( 1000 );
terminate();
m_audioDev->stopProcessing();
}
void mixer::run( void )
const surroundSampleFrame * mixer::renderNextBuffer( void )
{
while( m_quit == FALSE )
// 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() )
{
playHandleVector::iterator it = m_playHandles.begin();
// 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() )
while( it != m_playHandles.end() )
{
playHandleVector::iterator it = m_playHandles.begin();
while( it != m_playHandles.end() )
if( *it == m_playHandlesToRemove.front() )
{
if( *it == m_playHandlesToRemove.front() )
{
m_playHandles.erase( it );
delete m_playHandlesToRemove.front();
break;
}
++it;
m_playHandles.erase( it );
delete m_playHandlesToRemove.front();
break;
}
m_playHandlesToRemove.erase(
m_playHandlesToRemove.begin() );
++it;
}
// now we have to make sure no other thread does anything bad
// while we're acting...
m_safetySyncMutex.lock();
m_playHandlesToRemove.erase(
m_playHandlesToRemove.begin() );
}
csize idx = 0;
while( idx < m_playHandles.size() )
// now we have to make sure no other thread does anything bad
// while we're acting...
m_mixMutex.lock();
// now swap the buffers... current buffer becomes next (last)
// buffer and the next buffer becomes current (first) buffer
qSwap( m_curBuf, m_nextBuf );
// clear last audio-buffer
clearAudioBuffer( m_curBuf, m_framesPerAudioBuffer );
csize idx = 0;
while( idx < m_playHandles.size() )
{
register playHandle * n = m_playHandles[idx];
if( n->done() )
{
register playHandle * n = m_playHandles[idx];
if( n->done() )
{
// delete all play-handles which have
// played completely now
delete n;
m_playHandles.erase( m_playHandles.begin() +
idx );
}
else
{
// play all uncompletely-played play-handles...
n->play();
++idx;
}
}
songEditor::inst()->processNextBuffer();
for( vvector<audioPort *>::iterator it = m_audioPorts.begin();
it != m_audioPorts.end(); ++it )
{
if( ( *it )->m_bufferUsage != audioPort::NONE )
{
processBuffer( ( *it )->firstBuffer(),
( *it )->nextFxChannel() );
( *it )->nextPeriod();
}
}
if( !m_discardCurBuf )
{
m_devMutex.lock();
// write actual data to our current output-device
// (blocking!)
m_audioDev->writeBuffer( m_curBuf,
m_framesPerAudioBuffer,
SAMPLE_RATES[m_qualityLevel],
m_masterOutput );
m_devMutex.unlock();
// delete all play-handles which have
// played completely now
delete n;
m_playHandles.erase( m_playHandles.begin() +
idx );
}
else
{
m_discardCurBuf = FALSE;
// play all uncompletely-played play-handles...
n->play();
++idx;
}
emit nextAudioBuffer( m_curBuf, m_framesPerAudioBuffer );
usleep( 1 ); // give time to other threads/processes
m_safetySyncMutex.unlock();
// clear last audio-buffer
clearAudioBuffer( m_curBuf, m_framesPerAudioBuffer );
// now swap the buffers... current buffer becomes next (last)
// buffer and the next buffer becomes current (first) buffer
qSwap( m_curBuf, m_nextBuf );
// and trigger LFOs
envelopeAndLFOWidget::triggerLFO();
}
songEditor::inst()->processNextBuffer();
for( vvector<audioPort *>::iterator it = m_audioPorts.begin();
it != m_audioPorts.end(); ++it )
{
if( ( *it )->m_bufferUsage != audioPort::NONE )
{
processBuffer( ( *it )->firstBuffer(),
( *it )->nextFxChannel() );
( *it )->nextPeriod();
}
}
emit nextAudioBuffer( m_curBuf, m_framesPerAudioBuffer );
m_mixMutex.unlock();
// and trigger LFOs
envelopeAndLFOWidget::triggerLFO();
return( m_curBuf );
}
@@ -286,21 +225,6 @@ void mixer::clear( void )
void FASTCALL mixer::clearAudioBuffer( sampleFrame * _ab, Uint32 _frames )
{
memset( _ab, 0, sizeof( *_ab ) * _frames );
/* if( _frames == m_framesPerAudioBuffer )
{
memcpy( _ab, m_silence, m_framesPerAudioBuffer *
BYTES_PER_FRAME );
}
else
{
for( Uint32 frame = 0; frame < _frames; ++frame )
{
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
_ab[frame][ch] = 0.0f;
}
}
}*/
}
@@ -310,21 +234,6 @@ void FASTCALL mixer::clearAudioBuffer( surroundSampleFrame * _ab,
Uint32 _frames )
{
memset( _ab, 0, sizeof( *_ab ) * _frames );
/* if( _frames == m_framesPerAudioBuffer )
{
memcpy( _ab, m_surroundSilence, m_framesPerAudioBuffer *
BYTES_PER_SURROUND_FRAME );
}
else
{
for( Uint32 frame = 0; frame < _frames; ++frame )
{
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
_ab[frame][ch] = 0.0f;
}
}
}*/
}
#endif
@@ -377,8 +286,6 @@ void FASTCALL mixer::bufferToPort( sampleFrame * _buf, Uint32 _frames,
void mixer::setHighQuality( bool _hq_on )
{
m_safetySyncMutex.lock();
// delete (= close) our audio-device
delete m_audioDev;
@@ -393,8 +300,7 @@ void mixer::setHighQuality( bool _hq_on )
}
// and re-open device
m_audioDev = tryAudioDevices();
m_safetySyncMutex.unlock();
m_audioDev->startProcessing();
emit( sampleRateChanged() );
@@ -405,8 +311,7 @@ void mixer::setHighQuality( bool _hq_on )
void FASTCALL mixer::setAudioDevice( audioDevice * _dev, bool _hq )
{
m_devMutex.lock();
m_audioDev->stopProcessing();
m_oldAudioDev = m_audioDev;
@@ -423,9 +328,6 @@ void FASTCALL mixer::setAudioDevice( audioDevice * _dev, bool _hq )
m_qualityLevel = _hq ? 1 : 0;
emit sampleRateChanged();
m_devMutex.unlock();
}
@@ -433,11 +335,10 @@ void FASTCALL mixer::setAudioDevice( audioDevice * _dev, bool _hq )
void mixer::restoreAudioDevice( void )
{
m_devMutex.lock();
if( m_oldAudioDev != NULL )
{
delete m_audioDev;
delete m_audioDev; // dtor automatically calls
// stopProcessing()
m_audioDev = m_oldAudioDev;
for( Uint8 qli = 0; qli < QUALITY_LEVELS; ++qli )
{
@@ -449,10 +350,8 @@ void mixer::restoreAudioDevice( void )
}
}
m_oldAudioDev = NULL;
m_discardCurBuf = TRUE;
m_audioDev->startProcessing();
}
m_devMutex.unlock();
}
@@ -474,8 +373,6 @@ void mixer::checkValidityOfPlayHandles( void )
audioDevice * mixer::tryAudioDevices( void )
{
//m_discardCurBuf = TRUE;
bool success_ful = FALSE;
audioDevice * dev = NULL;
QString dev_name = configManager::inst()->value( "mixer", "audiodev" );

View File

@@ -34,6 +34,7 @@
#include <QKeyEvent>
#include <QWheelEvent>
#include <QComboBox>
#include <QLayout>
#else
@@ -41,6 +42,7 @@
#include <qbuttongroup.h>
#include <qpainter.h>
#include <qcombobox.h>
#include <qlayout.h>
#define setChecked setOn
@@ -56,9 +58,9 @@
#include "piano_roll.h"
#include "song_editor.h"
#include "lmms_main_win.h"
#include "pattern.h"
#include "embed.h"
#include "crystal_button.h"
#include "pixmap_button.h"
#include "templates.h"
#include "gui_templates.h"
@@ -66,6 +68,7 @@
#include "channel_track.h"
#include "tooltip.h"
#include "midi.h"
#include "tool_button.h"
extern tones whiteKeys[]; // defined in piano_widget.cpp
@@ -88,7 +91,7 @@ const int KEY_LINE_HEIGHT = 12;
const int OCTAVE_HEIGHT = KEY_LINE_HEIGHT * NOTES_PER_OCTAVE; // = 12 * 12;
const int PR_BOTTOM_MARGIN = SCROLLBAR_SIZE;
const int PR_TOP_MARGIN = 66;
const int PR_TOP_MARGIN = 48;
// width of area used for resizing (the grip at the end of a note)
const int RESIZE_AREA_WIDTH = 3;
@@ -106,8 +109,6 @@ pianoRoll * pianoRoll::s_instanceOfMe = NULL;
QPixmap * pianoRoll::s_whiteKeySmallPm = NULL;
QPixmap * pianoRoll::s_whiteKeyBigPm = NULL;
QPixmap * pianoRoll::s_blackKeyPm = NULL;
QPixmap * pianoRoll::s_artwork1 = NULL;
QPixmap * pianoRoll::s_artwork2 = NULL;
QPixmap * pianoRoll::s_toolDraw = NULL;
QPixmap * pianoRoll::s_toolErase = NULL;
QPixmap * pianoRoll::s_toolSelect = NULL;
@@ -160,16 +161,6 @@ pianoRoll::pianoRoll( void ) :
s_blackKeyPm = new QPixmap( embed::getIconPixmap(
"pr_black_key" ) );
}
if( s_artwork1 == NULL )
{
s_artwork1 = new QPixmap( embed::getIconPixmap(
"pr_artwork1" ) );
}
if( s_artwork2 == NULL )
{
s_artwork2 = new QPixmap( embed::getIconPixmap(
"pr_artwork2" ) );
}
if( s_toolDraw == NULL )
{
s_toolDraw = new QPixmap( embed::getIconPixmap(
@@ -196,39 +187,39 @@ pianoRoll::pianoRoll( void ) :
lmmsMainWin::inst()->workspace()->addWindow( this );
#endif
// add time-line
m_timeLine = new timeLine( WHITE_KEY_WIDTH, 32, m_ppt,
songEditor::inst()->getPlayPos(
songEditor::PLAY_PATTERN ),
m_currentPosition, this );
connect( this, SIGNAL( positionChanged( const midiTime & ) ),
m_timeLine, SLOT( updatePosition( const midiTime & ) ) );
connect( m_timeLine, SIGNAL( positionChanged( const midiTime & ) ),
this, SLOT( updatePosition( const midiTime & ) ) );
m_toolBar = new QWidget( this );
m_toolBar->setFixedHeight( 32 );
m_toolBar->move( 0, 0 );
m_toolBar->setPaletteBackgroundPixmap( embed::getIconPixmap(
"toolbar_bg" ) );
QHBoxLayout * tb_layout = new QHBoxLayout( m_toolBar );
// init control-buttons at the top
m_playButton = new pixmapButton( this );
m_playButton->move( 8, 7 );
m_playButton->setCheckable( FALSE );
m_playButton->setActiveGraphic( embed::getIconPixmap( "play" ) );
m_playButton->setInactiveGraphic( embed::getIconPixmap( "play" ) );
m_playButton->setBgGraphic( embed::getIconPixmap( "pr_play_ctrl_bg" ) );
connect( m_playButton, SIGNAL( clicked() ), this, SLOT( play() ) );
m_recordButton = new pixmapButton( this );
m_recordButton->move( 50, 7 );
m_recordButton->setCheckable( FALSE );
m_recordButton->setActiveGraphic( embed::getIconPixmap( "record" ) );
m_recordButton->setInactiveGraphic( embed::getIconPixmap( "record" ) );
m_recordButton->setBgGraphic(
embed::getIconPixmap( "pr_play_ctrl_bg" ) );
connect( m_recordButton, SIGNAL( clicked() ), this, SLOT( record() ) );
m_playButton = new toolButton( embed::getIconPixmap( "play" ),
tr( "Play/pause current pattern (Space)" ),
this, SLOT( play() ), m_toolBar );
m_stopButton = new pixmapButton( this );
m_stopButton->move( 92, 7 );
m_stopButton->setCheckable( FALSE );
m_stopButton->setActiveGraphic( embed::getIconPixmap( "stop" ) );
m_stopButton->setInactiveGraphic( embed::getIconPixmap( "stop" ) );
m_stopButton->setBgGraphic( embed::getIconPixmap( "pr_play_ctrl_bg" ) );
connect( m_stopButton, SIGNAL( clicked() ), this, SLOT( stop() ) );
m_recordButton = new toolButton( embed::getIconPixmap( "record" ),
tr( "Record notes from MIDI-device/channel-piano" ),
this, SLOT( record() ), m_toolBar );
toolTip::add( m_playButton,
tr( "Play/pause current pattern (Space)" ) );
toolTip::add( m_recordButton,
tr( "Record notes from MIDI-device to current "
"pattern" ) );
toolTip::add( m_stopButton,
tr( "Stop playing of current pattern (Space)" ) );
m_stopButton = new toolButton( embed::getIconPixmap( "stop" ),
tr( "Stop playing of current pattern (Space)" ),
this, SLOT( stop() ), m_toolBar );
#ifdef QT4
m_playButton->setWhatsThis(
@@ -246,8 +237,8 @@ pianoRoll::pianoRoll( void ) :
tr( "Click here, if you want to record notes from a MIDI-"
"device or the virtual test-piano of the according "
"channel-window to the current pattern. When recording "
"all notes you play will be written to this pattern "
"and you can edit, play etc. them afterwards." ) );
"all notes you play will be written to this pattern "
"and you can play and edit them afterwards." ) );
#ifdef QT4
m_stopButton->setWhatsThis(
#else
@@ -269,33 +260,31 @@ pianoRoll::pianoRoll( void ) :
SLOT( verScrolled( int ) ) );
// init edit-buttons at the top
m_drawButton = new crystalButton( embed::getIconPixmap( "pr_tool_bg" ),
embed::getIconPixmap(
"pr_tool_draw" ), this );
m_drawButton->move( 170, 1 );
m_drawButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_drawButton = new toolButton( embed::getIconPixmap( "pr_tool_draw" ),
tr( "Draw mode (D)" ),
this, SLOT( drawButtonToggled() ),
m_toolBar );
m_drawButton->setCheckable( TRUE );
m_drawButton->setChecked( TRUE );
m_eraseButton = new crystalButton( embed::getIconPixmap( "pr_tool_bg" ),
embed::getIconPixmap(
"pr_tool_erase" ), this );
m_eraseButton->move( 220, 1 );
m_eraseButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_selectButton = new crystalButton( embed::getIconPixmap(
"pr_tool_bg" ),
embed::getIconPixmap(
"pr_tool_select" ), this );
m_selectButton->move( 270, 1 );
m_selectButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_moveButton = new crystalButton( embed::getIconPixmap( "pr_tool_bg" ),
embed::getIconPixmap(
"pr_tool_move" ), this );
m_moveButton->move( 320, 1 );
m_moveButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_eraseButton = new toolButton( embed::getIconPixmap( "pr_tool_erase" ),
tr( "Erase mode (E)" ),
this, SLOT( eraseButtonToggled() ),
m_toolBar );
m_eraseButton->setCheckable( TRUE );
m_selectButton = new toolButton( embed::getIconPixmap(
"pr_tool_select" ),
tr( "Select mode (S)" ),
this, SLOT( selectButtonToggled() ),
m_toolBar );
m_selectButton->setCheckable( TRUE );
m_moveButton = new toolButton( embed::getIconPixmap( "pr_tool_move" ),
tr( "Move selection mode (M)" ),
this, SLOT( moveButtonToggled() ),
m_toolBar );
m_moveButton->setCheckable( TRUE );
QButtonGroup * tool_button_group = new QButtonGroup( this );
tool_button_group->addButton( m_drawButton );
@@ -307,26 +296,6 @@ pianoRoll::pianoRoll( void ) :
tool_button_group->hide();
#endif
connect( m_drawButton, SIGNAL( toggled( bool ) ), this,
SLOT( drawButtonToggled( bool ) ) );
connect( m_eraseButton, SIGNAL( toggled( bool ) ), this,
SLOT( eraseButtonToggled( bool ) ) );
connect( m_selectButton, SIGNAL( toggled( bool ) ), this,
SLOT( selectButtonToggled( bool ) ) );
connect( m_moveButton, SIGNAL( toggled( bool ) ), this,
SLOT( moveButtonToggled( bool ) ) );
toolTip::add( m_drawButton,
tr( "Click if you want to draw, resize or move single "
"notes (= key 'D')" ) );
toolTip::add( m_eraseButton,
tr( "Click if you want to erase single notes "
"(= key 'E')" ) );
toolTip::add( m_selectButton,
tr( "Click if you want to select notes (= key 'S')" ) );
toolTip::add( m_moveButton,
tr( "Click if you want to move selected notes "
"(= key 'M')" ) );
#ifdef QT4
m_drawButton->setWhatsThis(
#else
@@ -365,42 +334,22 @@ pianoRoll::pianoRoll( void ) :
"mode. You can also press 'M' on your keyboard to "
"activate this mode." ) );
m_cutButton = new toolButton( embed::getIconPixmap( "edit_cut" ),
tr( "Cut selected notes (Ctrl+X)" ),
this, SLOT( cutSelectedNotes() ),
m_toolBar );
m_cutButton = new crystalButton( embed::getIconPixmap( "pr_tool_bg" ),
embed::getIconPixmap(
"pr_edit_cut" ), this );
m_cutButton->move( 390, 1 );
m_cutButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_cutButton->setCheckable( FALSE );
m_copyButton = new crystalButton( embed::getIconPixmap( "pr_tool_bg" ),
embed::getIconPixmap(
"pr_edit_copy" ),
this );
m_copyButton->move( 440, 1 );
m_copyButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_copyButton->setCheckable( FALSE );
m_pasteButton = new crystalButton( embed::getIconPixmap( "pr_tool_bg" ),
embed::getIconPixmap(
"pr_edit_paste" ),
this );
m_pasteButton->move( 490, 1 );
m_pasteButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_pasteButton->setCheckable( FALSE );
m_copyButton = new toolButton( embed::getIconPixmap( "edit_copy" ),
tr( "Copy selected notes (Ctrl+C)" ),
this, SLOT( copySelectedNotes() ),
m_toolBar );
connect( m_cutButton, SIGNAL( clicked() ), this,
SLOT( cutSelectedNotes() ) );
connect( m_copyButton, SIGNAL( clicked() ), this,
SLOT( copySelectedNotes() ) );
connect( m_pasteButton, SIGNAL( clicked() ), this,
SLOT( pasteNotes() ) );
m_pasteButton = new toolButton( embed::getIconPixmap( "edit_paste" ),
tr( "Paste notes from clipboard "
"(Ctrl+V)" ),
this, SLOT( pasteNotes() ),
m_toolBar );
toolTip::add( m_cutButton, tr( "Cut selected notes (Ctrl+X)" ) );
toolTip::add( m_copyButton, tr( "Copy selected notes (Ctrl+C)" ) );
toolTip::add( m_pasteButton, tr( "Paste notes from clipboard "
"(Ctrl+V)" ) );
#ifdef QT4
m_cutButton->setWhatsThis(
#else
@@ -427,9 +376,10 @@ pianoRoll::pianoRoll( void ) :
// setup zooming-stuff
m_zoomingComboBox = new QComboBox( this );
m_zoomingComboBox->setGeometry( 580, 10, 60, 20 );
m_zoomingComboBox = new QComboBox( m_toolBar );
m_zoomingComboBox->setGeometry( 580, 4, 80, 24 );
for( int i = 0; i < 6; ++i )
{
m_zoomingComboBox->insertItem( QString::number( 25 *
@@ -441,6 +391,26 @@ pianoRoll::pianoRoll( void ) :
this, SLOT( zoomingChanged( const QString & ) ) );
tb_layout->addSpacing( 5 );
tb_layout->addWidget( m_playButton );
tb_layout->addWidget( m_recordButton );
tb_layout->addWidget( m_stopButton );
tb_layout->addSpacing( 10 );
tb_layout->addWidget( m_drawButton );
tb_layout->addWidget( m_eraseButton );
tb_layout->addWidget( m_selectButton );
tb_layout->addWidget( m_moveButton );
tb_layout->addSpacing( 10 );
tb_layout->addWidget( m_cutButton );
tb_layout->addWidget( m_copyButton );
tb_layout->addWidget( m_pasteButton );
tb_layout->addSpacing( 10 );
m_timeLine->addToolButtons( m_toolBar );
tb_layout->addSpacing( 10 );
tb_layout->addWidget( m_zoomingComboBox );
tb_layout->addStretch();
// setup our actual window
setWindowIcon( embed::getIconPixmap( "piano" ) );
resize( INITIAL_PIANOROLL_WIDTH, INITIAL_PIANOROLL_HEIGHT );
@@ -453,15 +423,6 @@ pianoRoll::pianoRoll( void ) :
hide();
// add time-line
m_timeLine = new timeLine( WHITE_KEY_WIDTH, 48, m_ppt,
songEditor::inst()->getPlayPos(
songEditor::PLAY_PATTERN ),
m_currentPosition, this );
connect( this, SIGNAL( positionChanged( const midiTime & ) ),
m_timeLine, SLOT( updatePosition( const midiTime & ) ) );
connect( m_timeLine, SIGNAL( positionChanged( const midiTime & ) ),
this, SLOT( updatePosition( const midiTime & ) ) );
}
@@ -785,7 +746,7 @@ void pianoRoll::paintEvent( QPaintEvent * )
// draw artwork-stuff
p.drawPixmap( 0, 0, *s_artwork1 );
/* p.drawPixmap( 0, 0, *s_artwork1 );
int artwork_x = s_artwork1->width();
@@ -793,10 +754,11 @@ void pianoRoll::paintEvent( QPaintEvent * )
{
p.drawPixmap( artwork_x, 0, *s_artwork2 );
artwork_x += s_artwork2->width();
}
}*/
// set clipping area, because we may not draw on keyboard...
// set clipping area, because we are not allowed to paint over
// keyboard...
p.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN, width()-WHITE_KEY_WIDTH,
height()-PR_TOP_MARGIN-PR_BOTTOM_MARGIN );
@@ -1027,6 +989,7 @@ void pianoRoll::resizeEvent( QResizeEvent * )
songEditor::inst()->getPlayPos( songEditor::PLAY_PATTERN
).m_timeLine->setFixedWidth( width() );
m_toolBar->setFixedWidth( width() );
}
@@ -1977,26 +1940,24 @@ void pianoRoll::play( void )
{
songEditor::inst()->stop();
songEditor::inst()->playPattern( m_pattern );
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "pause" ) );
m_playButton->setPixmap( embed::getIconPixmap(
"pause" ) );
}
else
{
songEditor::inst()->pause();
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "play" ) );
m_playButton->setPixmap( embed::getIconPixmap(
"play" ) );
}
}
else if( songEditor::inst()->paused() )
{
songEditor::inst()->resumeFromPause();
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "pause" ) );
m_playButton->setPixmap( embed::getIconPixmap( "pause" ) );
}
else
{
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "pause" ) );
m_playButton->setPixmap( embed::getIconPixmap( "pause" ) );
songEditor::inst()->playPattern( m_pattern );
}
}
@@ -2025,7 +1986,7 @@ void pianoRoll::record( void )
void pianoRoll::stop( void )
{
songEditor::inst()->stop();
m_playButton->setInactiveGraphic( embed::getIconPixmap( "play" ) );
m_playButton->setPixmap( embed::getIconPixmap( "play" ) );
m_playButton->update();
m_recording = FALSE;
m_scrollBack = TRUE;
@@ -2071,56 +2032,47 @@ void pianoRoll::verScrolled( int _new_pos )
void pianoRoll::drawButtonToggled( bool _on )
void pianoRoll::drawButtonToggled( void )
{
if( _on )
{
m_editMode = DRAW;
removeSelection();
update();
}
}
void pianoRoll::eraseButtonToggled( bool _on )
{
if( _on )
{
m_editMode = ERASE;
removeSelection();
update();
}
m_editMode = DRAW;
removeSelection();
update();
}
void pianoRoll::selectButtonToggled( bool _on )
void pianoRoll::eraseButtonToggled( void )
{
if( _on )
{
m_editMode = SELECT;
removeSelection();
update();
}
m_editMode = ERASE;
removeSelection();
update();
}
void pianoRoll::moveButtonToggled( bool _on )
void pianoRoll::selectButtonToggled( void )
{
if( _on )
{
m_editMode = MOVE;
m_selNotesForMove.clear();
getSelectedNotes( m_selNotesForMove );
update();
}
m_editMode = SELECT;
removeSelection();
update();
}
void pianoRoll::moveButtonToggled( void )
{
m_editMode = MOVE;
m_selNotesForMove.clear();
getSelectedNotes( m_selNotesForMove );
update();
}
void pianoRoll::selectAll( void )
{
if( validPattern() == FALSE )

View File

@@ -44,11 +44,12 @@
#include <QStatusBar>
#include <QKeyEvent>
#include <QLabel>
#include <QToolButton>
#include <QStatusBar>
#include <QAction>
#include <QToolBar>
#include <QComboBox>
#include <QLayout>
#include <QToolButton>
#else
@@ -60,9 +61,10 @@
#include <qdom.h>
#include <qslider.h>
#include <qlabel.h>
#include <qtoolbutton.h>
#include <qstatusbar.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <qtoolbutton.h>
#endif
@@ -87,13 +89,13 @@
#include "midi_file.h"
#include "lcd_spinbox.h"
#include "tooltip.h"
#include "tool_button.h"
#include "debug.h"
extern QString file_to_load;
extern QString file_to_render;
const int SCROLLBAR_SIZE = 16;
@@ -114,7 +116,6 @@ songEditor::songEditor() :
m_patternToPlay( NULL ),
m_loopPattern( FALSE ),
m_scrollBack( FALSE ),
m_epd( NULL ),
m_shiftPressed( FALSE ),
m_controlPressed( FALSE )
{
@@ -147,7 +148,7 @@ songEditor::songEditor() :
// create time-line
timeLine * tl = new timeLine( TRACK_OP_WIDTH +
DEFAULT_SETTINGS_WIDGET_WIDTH, 0,
DEFAULT_SETTINGS_WIDGET_WIDTH, 32,
pixelsPerTact(), m_playPos[PLAY_SONG],
m_currentPosition, cw );
connect( this, SIGNAL( positionChanged( const midiTime & ) ),
@@ -156,75 +157,41 @@ songEditor::songEditor() :
connect( tl, SIGNAL( positionChanged( const midiTime & ) ),
this, SLOT( updatePosition( const midiTime & ) ) );
// create toolbar
m_toolBar = new QWidget( cw );
m_toolBar->setFixedHeight( 32 );
m_toolBar->move( 0, 0 );
m_toolBar->setPaletteBackgroundPixmap( embed::getIconPixmap(
"toolbar_bg" ) );
QHBoxLayout * tb_layout = new QHBoxLayout( m_toolBar );
#ifdef QT4
containerWidget()->setParent( cw );
#else
containerWidget()->reparent( cw, 0, QPoint( 0, 0 ) );
#endif
containerWidget()->move( 0, tl->height() );
containerWidget()->move( 0, m_toolBar->height() + tl->height() );
QToolBar * song_control = new QToolBar( tr( "Song control" ), this );
#ifdef QT4
addToolBar( Qt::TopToolBarArea, song_control );
#else
addDockWindow( song_control, tr( "Song control" ), Qt::DockTop,
FALSE );
#endif
/* song_control->setPaletteBackgroundPixmap( embed::getIconPixmap(
"toolbar_bg" ) );
song_control->setErasePixmap( embed::getIconPixmap( "toolbar_bg" ) );*/
#ifdef QT4
QAction * a;
a = song_control->addAction( embed::getIconPixmap( "play" ),
tr( "Play song (Space)" ),
this, SLOT( play() ) );
a->setToolTip( tr( "Play/pause song (Space)" ) );
a->setWhatsThis( tr( "Click here, if you want to play your whole song. "
"Playing will be started at the song-position-"
"marker (green). You can also move it while "
"playing." ) );
#else
m_playButton = new QToolButton( embed::getIconPixmap( "play" ),
tr( "Play song (Space)" ),
QString::null, this, SLOT( play() ),
song_control );
#endif
#ifdef QT4
a = song_control->addAction( embed::getIconPixmap( "stop" ),
tr( "Stop song (Space)" ),
this, SLOT( stop() ) );
a->setToolTip( tr( "Stop song (Space)" ) );
a->setWhatsThis( tr( "Click here, if you want to stop playing of your "
"song. The song-position-marker will be set to "
"the start of your song." ) );
#else
m_stopButton = new QToolButton( embed::getIconPixmap( "stop" ),
tr( "Stop song (Space)" ),
QString::null, this, SLOT( stop() ),
song_control );
#endif
song_control->addSeparator();
QToolBar * main_tb = lmmsMainWin::inst()->mainToolBar();
// spacer-item
( new QWidget( song_control ) )->setFixedSize( 10, 1 );
( new QWidget( main_tb ) )->setFixedSize( 10, 1 );
QLabel * bpm_label = new QLabel( song_control );
QLabel * bpm_label = new QLabel( main_tb );
bpm_label->setPixmap( embed::getIconPixmap( "clock" ) );
// spacer-item
( new QWidget( song_control ) )->setFixedSize( 8, 1 );
( new QWidget( main_tb ) )->setFixedSize( 8, 1 );
m_bpmSpinBox = new lcdSpinBox( MIN_BPM, MAX_BPM, 3, song_control );
m_bpmSpinBox = new lcdSpinBox( MIN_BPM, MAX_BPM, 3, main_tb );
#ifdef QT4
song_control->addWidget( m_bpmSpinBox );
song_control->addWidget( bpm_label );
main_tb->addWidget( m_bpmSpinBox );
main_tb->addWidget( bpm_label );
#endif
m_bpmSpinBox->setLabel( tr( "TEMPO/BPM" ) );
connect( m_bpmSpinBox, SIGNAL( valueChanged( int ) ), this,
@@ -244,26 +211,26 @@ songEditor::songEditor() :
"should be played within four minutes)." ) );
// spacer-item
( new QWidget( song_control ) )->setFixedSize( 10, 1 );
( new QWidget( main_tb ) )->setFixedSize( 10, 1 );
song_control->addSeparator();
main_tb->addSeparator();
QLabel * master_vol_lbl = new QLabel( song_control );
QLabel * master_vol_lbl = new QLabel( main_tb );
master_vol_lbl->setPixmap( embed::getIconPixmap( "master_volume" ) );
#ifdef QT4
m_masterVolumeSlider = new QSlider( Qt::Vertical, song_control );
m_masterVolumeSlider = new QSlider( Qt::Vertical, main_tb );
m_masterVolumeSlider->setRange( 0, 200 );
m_masterVolumeSlider->setPageStep( 10 );
m_masterVolumeSlider->setValue( 100 );
m_masterVolumeSlider->setTickPosition( QSlider::TicksLeft );
song_control->addWidget( master_vol_lbl );
song_control->addWidget( m_masterVolumeSlider );
main_tb->addWidget( master_vol_lbl );
main_tb->addWidget( m_masterVolumeSlider );
#else
m_masterVolumeSlider = new QSlider( 0, 200, 10, 100, Qt::Vertical,
song_control );
main_tb );
m_masterVolumeSlider->setTickPosition( QSlider::Left );
#endif
m_masterVolumeSlider->setFixedSize( 26, 48 );
@@ -281,22 +248,22 @@ songEditor::songEditor() :
// spacer-item
( new QWidget( song_control ) )->setFixedSize( 10, 1 );
( new QWidget( main_tb ) )->setFixedSize( 10, 1 );
QLabel * master_pitch_lbl = new QLabel( song_control );
QLabel * master_pitch_lbl = new QLabel( main_tb );
master_pitch_lbl->setPixmap( embed::getIconPixmap( "master_pitch" ) );
#ifdef QT4
m_masterPitchSlider = new QSlider( Qt::Vertical, song_control );
m_masterPitchSlider = new QSlider( Qt::Vertical, main_tb );
m_masterPitchSlider->setRange( -12, 12 );
m_masterPitchSlider->setPageStep( 1 );
m_masterPitchSlider->setValue( 0 );
m_masterPitchSlider->setTickPosition( QSlider::TicksLeft );
song_control->addWidget( master_pitch_lbl );
song_control->addWidget( m_masterPitchSlider );
main_tb->addWidget( master_pitch_lbl );
main_tb->addWidget( m_masterPitchSlider );
#else
m_masterPitchSlider = new QSlider( -12, 12, 1, 0, Qt::Vertical,
song_control );
main_tb);
m_masterPitchSlider->setTickPosition( QSlider::Left );
#endif
m_masterPitchSlider->setFixedSize( 26, 48 );
@@ -312,28 +279,117 @@ songEditor::songEditor() :
SLOT( masterPitchReleased() ) );
// spacer-item
( new QWidget( song_control ) )->setFixedSize( 5, 1 );
( new QWidget( main_tb ) )->setFixedSize( 5, 1 );
song_control->addSeparator();
main_tb->addSeparator();
// spacer-item
( new QWidget( song_control ) )->setFixedSize( 5, 1 );
( new QWidget( main_tb ) )->setFixedSize( 5, 1 );
m_masterOutputGraph = new visualizationWidget( embed::getIconPixmap(
"output_graph" ), song_control );
"output_graph" ), main_tb );
#ifdef QT4
song_control->addWidget( m_masterOutputGraph );
main_tb->addWidget( m_masterOutputGraph );
#endif
// live high-quality mode switching is somewhat experimental so we don't
// offer it...
/* QToolButton * hq = new QToolButton(
embed::getIconPixmap( "presetfile" ),
// spacer-item
( new QWidget( main_tb ) )->setFixedSize( 5, 1 );
main_tb->addSeparator();
QToolButton * hq = new QToolButton(
embed::getIconPixmap( "hq_mode" ),
tr( "High quality mode" ),
QString::null, NULL, NULL,
song_control );
main_tb );
hq->setToggleButton( TRUE );
connect( hq, SIGNAL( toggled( bool ) ), mixer::inst(),
SLOT( setHighQuality( bool ) ) );*/
SLOT( setHighQuality( bool ) ) );
m_playButton = new toolButton( embed::getIconPixmap( "play" ),
tr( "Play song (Space)" ),
this, SLOT( play() ), m_toolBar );
m_stopButton = new toolButton( embed::getIconPixmap( "stop" ),
tr( "Stop song (Space)" ),
this, SLOT( stop() ), m_toolBar );
m_addBBTrackButton = new toolButton( embed::getIconPixmap(
"add_bb_track" ),
tr( "Add beat/bassline" ),
this, SLOT( addBBTrack() ),
m_toolBar );
m_addSampleTrackButton = new toolButton( embed::getIconPixmap(
"add_sample_track" ),
tr( "Add sample-track" ),
this, SLOT( addSampleTrack() ),
m_toolBar );
m_insertBarButton = new toolButton( embed::getIconPixmap(
"insert_bar" ),
tr( "Insert bar "
"(Shift+Insert)" ),
this, SLOT( insertBar() ),
m_toolBar );
m_removeBarButton = new toolButton( embed::getIconPixmap(
"remove_bar" ),
tr( "Remove bar (Shift+Delete)" ),
this, SLOT( removeBar() ),
m_toolBar );
#ifdef QT4
#else
QWhatsThis::add( m_playButton, tr( "Click here, if you want to play "
"your whole song. Playing will "
"be started at the "
"song-position-marker (green). "
"You can also move it while "
"playing." ) );
QWhatsThis::add( m_stopButton, tr ( "Click here, if you want to stop "
"playing of your song. The "
"song-position-marker will be "
"set to the start of your song."
) );
QWhatsThis::add( m_insertBarButton, tr( "If you click here, a "
"bar will "
"be inserted at the "
"current bar." ) );
QWhatsThis::add( m_removeBarButton, tr( "If you click here, the "
"current bar will be "
"removed." ) );
#endif
// setup zooming-stuff
m_zoomingComboBox = new QComboBox( m_toolBar );
m_zoomingComboBox->setGeometry( 580, 4, 80, 24 );
for( int i = 0; i < 7; ++i )
{
m_zoomingComboBox->insertItem( QString::number( 25 *
static_cast<int>( powf( 2.0f, i ) ) ) +
"%" );
}
m_zoomingComboBox->setCurrentText( "100%" );
connect( m_zoomingComboBox, SIGNAL( activated( const QString & ) ),
this, SLOT( zoomingChanged( const QString & ) ) );
tb_layout->addSpacing( 5 );
tb_layout->addWidget( m_playButton );
tb_layout->addWidget( m_stopButton );
tb_layout->addSpacing( 10 );
tb_layout->addWidget( m_addBBTrackButton );
tb_layout->addWidget( m_addSampleTrackButton );
tb_layout->addSpacing( 10 );
tb_layout->addWidget( m_insertBarButton );
tb_layout->addWidget( m_removeBarButton );
tb_layout->addSpacing( 10 );
tl->addToolButtons( m_toolBar );
tb_layout->addSpacing( 10 );
tb_layout->addWidget( m_zoomingComboBox );
tb_layout->addStretch();
m_leftRightScroll = new QScrollBar( Qt::Horizontal, cw );
@@ -349,112 +405,6 @@ songEditor::songEditor() :
SLOT( scrolled( int ) ) );
QToolBar * edit_tb = new QToolBar( tr( "Edit" ), this );
#ifdef QT4
addToolBar( Qt::TopToolBarArea, edit_tb );
#else
addDockWindow( edit_tb, tr( "Edit" ), Qt::DockTop, FALSE );
#endif
/* edit_tb->setPaletteBackgroundPixmap( embed::getIconPixmap(
"toolbar_bg" ) );
edit_tb->setErasePixmap( embed::getIconPixmap( "toolbar_bg" ) );*/
#ifdef QT4
a = edit_tb->addAction( embed::getIconPixmap( "add_bb_track" ), "",
this, SLOT( addBBTrack() ) );
a->setToolTip( tr( "Add beat/bassline" ) );
#else
m_addBBTrackButton = new QToolButton( embed::getIconPixmap(
"add_bb_track" ), "", "",
this, SLOT( addBBTrack() ),
edit_tb );
#endif
#ifdef QT4
a = edit_tb->addAction( embed::getIconPixmap( "add_sample_track" ), "",
this, SLOT( addSampleTrack() ) );
a->setToolTip( tr( "Add sample-track" ) );
#else
m_addSampleTrackButton = new QToolButton( embed::getIconPixmap(
"add_sample_track" ), "", "",
this, SLOT( addSampleTrack() ),
edit_tb );
#endif
edit_tb->addSeparator();
#ifdef QT4
a = edit_tb->addAction( embed::getIconPixmap( "se_insert_tact" ), "",
this, SLOT( insertTact() ) );
a->setToolTip( tr( "Insert bar at current tact (Shift+Insert)" ) );
a->setWhatsThis( tr( "If you click here, a tact will be inserted at "
"the current tact." ) );
#else
m_insertTactButton = new QToolButton( embed::getIconPixmap(
"se_insert_tact" ), "", "",
this, SLOT( insertTact() ),
edit_tb );
#endif
#ifdef QT4
a = edit_tb->addAction( embed::getIconPixmap( "se_remove_tact" ), "",
this, SLOT( removeTact() ) );
a->setToolTip( tr( "Remove bar at current tact (Shift+Delete)" ) );
a->setWhatsThis( tr( "If you click here, the tact at the current tact "
"will be removed." ) );
#else
m_removeTactButton = new QToolButton( embed::getIconPixmap(
"se_remove_tact" ), "", "",
this, SLOT( removeTact() ),
edit_tb );
#endif
// add tooltips and whats-this-texts to all buttons
toolTip::add( m_playButton, tr( "Play/pause song (Space)" ) );
toolTip::add( m_stopButton, tr( "Stop playing song (Space)" ) );
toolTip::add( m_addBBTrackButton, tr( "Add beat/bassline" ) );
toolTip::add( m_addSampleTrackButton, tr( "Add sample-track" ) );
toolTip::add( m_insertTactButton, tr( "Insert tact at current tact "
"(Shift+Insert)" ) );
toolTip::add( m_removeTactButton, tr( "Remove tact at current tact "
"(Shift+Delete)" ) );
#ifdef QT4
#else
QWhatsThis::add( m_playButton, tr( "Click here, if you want to play "
"your whole song. Playing will "
"be started at the "
"song-position-marker (green). "
"You can also move it while "
"playing." ) );
QWhatsThis::add( m_stopButton, tr ( "Click here, if you want to stop "
"playing of your song. The "
"song-position-marker will be "
"set to the start of your song."
) );
QWhatsThis::add( m_insertTactButton, tr( "If you click here, a "
"tact will "
"be inserted at the "
"current tact." ) );
QWhatsThis::add( m_removeTactButton, tr( "If you click here, the "
"tact at the "
"current tact will be "
"removed." ) );
#endif
edit_tb->addSeparator();
// setup zooming-stuff
m_zoomingComboBox = new QComboBox( edit_tb );
m_zoomingComboBox->setGeometry( 580, 10, 60, 20 );
for( int i = 0; i < 7; ++i )
{
m_zoomingComboBox->insertItem( QString::number( 25 *
static_cast<int>( powf( 2.0f, i ) ) ) +
"%" );
}
m_zoomingComboBox->setCurrentText( "100%" );
connect( m_zoomingComboBox, SIGNAL( activated( const QString & ) ),
this, SLOT( zoomingChanged( const QString & ) ) );
show();
@@ -524,6 +474,7 @@ void songEditor::resizeEvent( QResizeEvent * _re )
m_playPos[PLAY_SONG].m_timeLine->setFixedWidth(
centralWidget()->width() );
m_toolBar->setFixedWidth( centralWidget()->width() );
}
trackContainer::resizeEvent( _re );
}
@@ -553,12 +504,12 @@ void songEditor::keyPressEvent( QKeyEvent * _ke )
if( _ke->modifiers() & Qt::ShiftModifier &&
_ke->key() == Qt::Key_Insert )
{
insertTact();
insertBar();
}
else if( _ke->modifiers() & Qt::ShiftModifier &&
_ke->key() == Qt::Key_Delete )
{
removeTact();
removeBar();
}
else if( _ke->key() == Qt::Key_Left )
{
@@ -655,7 +606,7 @@ void songEditor::wheelEvent( QWheelEvent * _we )
void songEditor::masterVolumeChanged( int _new_val )
{
mixer::inst()->setMasterOutput( 2.0f - _new_val / 100.0f );
mixer::inst()->setMasterGain( 2.0f - _new_val / 100.0f );
setModified();
}
@@ -723,14 +674,6 @@ void songEditor::masterPitchReleased( void )
void songEditor::toggleHQMode( void )
{
//mixer::inst()->setHighQuality (hq_btn->isChecked());
}
void songEditor::updatePosition( const midiTime & _t )
{
if( ( m_playing && m_playMode == PLAY_SONG ) || m_scrollBack == TRUE )
@@ -953,7 +896,9 @@ void songEditor::processNextBuffer( void )
// check for looping-mode and act if neccessary
timeLine * tl = m_playPos[m_playMode].m_timeLine;
if( tl != NULL && m_exporting == FALSE && tl->loopPointsEnabled() )
if( tl != NULL && m_exporting == FALSE && tl->loopPointsEnabled() &&
!( m_playMode == PLAY_PATTERN &&
m_patternToPlay->freezing() == TRUE ) )
{
if( m_playPos[m_playMode] < tl->loopBegin() ||
m_playPos[m_playMode] >= tl->loopEnd() )
@@ -1056,33 +1001,6 @@ void songEditor::processNextBuffer( void )
{
m_playPos[m_playMode].m_timeLine->updatePosition();
}
if( m_exporting == TRUE )
{
tact tacts = lengthInTacts() + 1;
if( m_playPos[PLAY_SONG].getTact() >= tacts )
{
// now pause the mixer - method
// exportProjectDialog::redrawProgressBar() which is
// called every 100 ms will find out that export
// is done and will act according to this
mixer::inst()->pause();
}
else
{
m_epd->updateProgressBar(
( m_playPos[PLAY_SONG].getTact() * 64 +
m_playPos[PLAY_SONG].getTact64th() ) *
100 / ( tacts * 64 ) );
}
}
if( m_playMode == PLAY_PATTERN && m_loopPattern == FALSE &&
m_patternToPlay->isFreezing() == TRUE &&
m_playPos[PLAY_PATTERN] > m_patternToPlay->length() )
{
m_patternToPlay->finishFreeze();
}
}
@@ -1263,12 +1181,6 @@ void songEditor::stopExport( void )
{
stop();
m_exporting = FALSE;
// if we rendered file from cmd-line quit after export
if( file_to_render != "" )
{
qApp->quit();
}
}
@@ -1276,7 +1188,7 @@ void songEditor::stopExport( void )
void songEditor::insertTact( void )
void songEditor::insertBar( void )
{
trackVector tv = tracks();
for( trackVector::iterator it = tv.begin(); it != tv.end(); ++it )
@@ -1289,7 +1201,7 @@ void songEditor::insertTact( void )
void songEditor::removeTact( void )
void songEditor::removeBar( void )
{
trackVector tv = tracks();
for( trackVector::iterator it = tv.begin(); it != tv.end(); ++it )
@@ -1640,15 +1552,7 @@ void songEditor::exportProject( void )
if( m_fileName != "" )
{
#ifdef QT4
base_filename = QFileInfo( m_fileName ).absolutePath() + "/" +
QFileInfo( m_fileName
).completeBaseName();
#else
base_filename = QFileInfo( m_fileName ).dirPath() + "/" +
QFileInfo( m_fileName ).baseName(
TRUE );
#endif
base_filename = baseName( m_fileName );
}
else
{
@@ -1709,12 +1613,9 @@ void songEditor::exportProject( void )
{
return;
}
m_epd = new exportProjectDialog( export_file_name,
exportProjectDialog epd( export_file_name,
lmmsMainWin::inst() );
m_epd->exec();
delete m_epd;
m_epd = NULL;
epd.exec();
}
}

View File

@@ -31,11 +31,13 @@
#include <QPainter>
#include <QApplication>
#include <QMouseEvent>
#include <QLayout>
#else
#include <qpainter.h>
#include <qapplication.h>
#include <qlayout.h>
#endif
@@ -44,18 +46,23 @@
#include "nstate_button.h"
#include "embed.h"
#include "templates.h"
#include "nstate_button.h"
QPixmap * timeLine::s_timeLinePixmap = NULL;
QPixmap * timeLine::s_posMarkerPixmap = NULL;
QPixmap * timeLine::s_loopPointPixmap = NULL;
QPixmap * timeLine::s_loopPointDisabledPixmap = NULL;
timeLine::timeLine( const int _xoff, const int _yoff, const float _ppt,
songEditor::playPos & _pos, const midiTime & _begin,
QWidget * _parent ) :
QWidget( _parent ),
m_autoScroll( AUTOSCROLL_ENABLED ),
m_loopPoints( LOOP_POINTS_DISABLED ),
m_behaviourAtStop( BACK_TO_ZERO ),
m_xOffset( _xoff ),
m_posMarkerX( 0 ),
m_ppt( _ppt ),
@@ -84,41 +91,17 @@ timeLine::timeLine( const int _xoff, const int _yoff, const float _ppt,
"loop_point" ) );
}
if( s_loopPointDisabledPixmap == NULL)
{
s_loopPointDisabledPixmap = new QPixmap( embed::getIconPixmap(
"loop_point_disabled" ) );
}
move( 0, _yoff );
setFixedHeight( s_timeLinePixmap->height() );
m_xOffset -= s_posMarkerPixmap->width() / 2;
m_autoScroll = new nStateButton( this );
m_autoScroll->move( 3, 3 );
m_autoScroll->setGeneralToolTip( tr( "Enable/disable "
"auto-scrolling" ) );
m_autoScroll->addState( embed::getIconPixmap( "autoscroll_on" ) );
m_autoScroll->addState( embed::getIconPixmap( "autoscroll_off" ) );
m_loopPoints = new nStateButton( this );
m_loopPoints->move( 20, 3 );
m_loopPoints->setGeneralToolTip( tr( "Enable/disable loop-points" ) );
m_loopPoints->addState( embed::getIconPixmap( "loop_points_off" ) );
m_loopPoints->addState( embed::getIconPixmap( "loop_points_on" ) );
connect( m_loopPoints, SIGNAL( stateChanged( int ) ), this,
SLOT( toggleLoopPoints( int ) ) );
m_behaviourAtStop = new nStateButton( this );
m_behaviourAtStop ->move( 37, 3 );
m_behaviourAtStop ->addState( embed::getIconPixmap( "back_to_zero" ),
tr( "After stopping go back to begin" )
);
m_behaviourAtStop ->addState( embed::getIconPixmap(
"back_to_start" ),
tr( "After stopping go back to "
"position at which playing was "
"started" ) );
m_behaviourAtStop ->addState( embed::getIconPixmap(
"keep_stop_position" ),
tr( "After stopping keep position" ) );
#ifndef QT4
setBackgroundMode( Qt::NoBackground );
#endif
@@ -139,18 +122,45 @@ timeLine::~timeLine()
timeLine::behaviourAtStopStates timeLine::behaviourAtStop( void ) const
void timeLine::addToolButtons( QWidget * _tool_bar )
{
return( static_cast<behaviourAtStopStates>(
m_behaviourAtStop->state() ) );
}
nStateButton * m_autoScroll = new nStateButton( _tool_bar );
m_autoScroll->setPaletteBackgroundColor( QColor( 224, 224, 224 ) );
m_autoScroll->setGeneralToolTip( tr( "Enable/disable "
"auto-scrolling" ) );
m_autoScroll->addState( embed::getIconPixmap( "autoscroll_on" ) );
m_autoScroll->addState( embed::getIconPixmap( "autoscroll_off" ) );
connect( m_autoScroll, SIGNAL( changedState( int ) ), this,
SLOT( toggleAutoScroll( int ) ) );
nStateButton * m_loopPoints = new nStateButton( _tool_bar );
m_loopPoints->setPaletteBackgroundColor( QColor( 224, 224, 224 ) );
m_loopPoints->setGeneralToolTip( tr( "Enable/disable loop-points" ) );
m_loopPoints->addState( embed::getIconPixmap( "loop_points_off" ) );
m_loopPoints->addState( embed::getIconPixmap( "loop_points_on" ) );
connect( m_loopPoints, SIGNAL( changedState( int ) ), this,
SLOT( toggleLoopPoints( int ) ) );
nStateButton * m_behaviourAtStop = new nStateButton( _tool_bar );
m_behaviourAtStop->setPaletteBackgroundColor( QColor( 224, 224, 224 ) );
m_behaviourAtStop ->addState( embed::getIconPixmap( "back_to_zero" ),
tr( "After stopping go back to begin" )
);
m_behaviourAtStop ->addState( embed::getIconPixmap(
"back_to_start" ),
tr( "After stopping go back to "
"position at which playing was "
"started" ) );
m_behaviourAtStop ->addState( embed::getIconPixmap(
"keep_stop_position" ),
tr( "After stopping keep position" ) );
connect( m_behaviourAtStop, SIGNAL( changedState( int ) ), this,
SLOT( toggleBehaviourAtStop( int ) ) );
bool timeLine::loopPointsEnabled( void ) const
{
return( m_loopPoints->state() == LOOP_POINTS_ENABLED );
QBoxLayout * layout = dynamic_cast<QBoxLayout *>( _tool_bar->layout() );
layout->addWidget( m_autoScroll );
layout->addWidget( m_loopPoints );
layout->addWidget( m_behaviourAtStop );
}
@@ -170,7 +180,7 @@ void timeLine::updatePosition( const midiTime & )
#ifndef QT4
qApp->unlock();
#endif
if( m_autoScroll->state() == AUTOSCROLL_ENABLED )
if( m_autoScroll == AUTOSCROLL_ENABLED )
{
emit positionChanged( m_pos );
}
@@ -180,14 +190,31 @@ void timeLine::updatePosition( const midiTime & )
void timeLine::toggleAutoScroll( int _n )
{
m_autoScroll = static_cast<autoScrollStates>( _n );
}
void timeLine::toggleLoopPoints( int _n )
{
m_loopPoints = static_cast<loopPointStates>( _n );
update();
}
void timeLine::toggleBehaviourAtStop( int _n )
{
m_behaviourAtStop = static_cast<behaviourAtStopStates>( _n );
}
void timeLine::paintEvent( QPaintEvent * )
{
#ifdef QT4
@@ -205,13 +232,11 @@ void timeLine::paintEvent( QPaintEvent * )
p.setClipRect( m_xOffset, 0, width() - m_xOffset, height() );
p.setPen( QColor( 0, 0, 0 ) );
if( m_loopPoints->state() == LOOP_POINTS_ENABLED )
{
p.drawPixmap( markerX( m_loopPos[0] ), 7,
*s_loopPointPixmap );
p.drawPixmap( markerX( m_loopPos[1] ), 7,
*s_loopPointPixmap );
}
const QPixmap & lpoint = loopPointsEnabled() ?
*s_loopPointPixmap :
*s_loopPointDisabledPixmap;
p.drawPixmap( markerX( m_loopPos[0] ), 7, lpoint );
p.drawPixmap( markerX( m_loopPos[1] ), 7, lpoint );
tact tact_num = m_begin.getTact();
@@ -225,7 +250,11 @@ void timeLine::paintEvent( QPaintEvent * )
if( ( tact_num - 1 ) %
tMax( 1, static_cast<int>( 64.0f / m_ppt ) ) == 0 )
{
p.drawText( x + static_cast<int>( i * m_ppt ), 16,
p.setPen( QColor( 224, 224, 224 ) );
p.drawText( x + static_cast<int>( i * m_ppt ) + 1, 15,
QString::number( tact_num ) );
p.setPen( QColor( 0, 0, 0 ) );
p.drawText( x + static_cast<int>( i * m_ppt ), 14,
QString::number( tact_num ) );
}
}
@@ -249,10 +278,6 @@ void timeLine::mousePressEvent( QMouseEvent * _me )
}
if( _me->button() == Qt::RightButton )
{
if( m_loopPoints->state() != LOOP_POINTS_ENABLED )
{
return;
}
if( _me->x() >= markerX( loopBegin() ) &&
_me->x() <= markerX( loopBegin() ) +
s_loopPointPixmap->width() )
@@ -300,12 +325,12 @@ void timeLine::mouseMoveEvent( QMouseEvent * _me )
break;
case MOVE_LOOP_BEGIN:
m_loopPos[0] = t;
m_loopPos[0] = t.getTact() * 64;
update();
break;
case MOVE_LOOP_END:
m_loopPos[1] = t;
m_loopPos[1] = t.getTact() * 64;
update();
break;

View File

@@ -40,6 +40,8 @@
#include <qdom.h>
#include <qpopupmenu.h>
#include <qlayout.h>
#include <qcursor.h>
#include <qwhatsthis.h>
#endif
@@ -594,7 +596,7 @@ trackWidget::trackWidget( track * _track, QWidget * _parent ) :
QPushButton * clntr_btn = new QPushButton( embed::getIconPixmap(
"pr_edit_copy", 12, 12 ),
"edit_copy", 12, 12 ),
"",
&m_trackOperationsWidget );
clntr_btn->setGeometry( 1, 1, TRACK_OP_BTN_WIDTH, TRACK_OP_BTN_HEIGHT );

View File

@@ -48,7 +48,7 @@
midiALSARaw::midiALSARaw( void ) :
midiRawClient(),
midiClientRaw(),
QThread(),
m_inputp( &m_input ),
m_outputp( &m_output ),
@@ -200,7 +200,7 @@ void midiALSARaw::run( void )
midiALSARaw::setupWidget::setupWidget( QWidget * _parent ) :
midiRawClient::setupWidget( midiALSARaw::name(), _parent )
midiClientRaw::setupWidget( midiALSARaw::name(), _parent )
{
m_device = new QLineEdit( midiALSARaw::probeDevice(), this );
m_device->setGeometry( 10, 20, 160, 20 );

View File

@@ -74,7 +74,8 @@ midiALSASeq::midiALSASeq( void ) :
m_queueID = snd_seq_alloc_queue( m_seqHandle );
snd_seq_queue_tempo_t * tempo;
snd_seq_queue_tempo_alloca( &tempo );
snd_seq_queue_tempo_set_tempo( tempo, 6000000 / songEditor::inst()->getBPM() );
snd_seq_queue_tempo_set_tempo( tempo, 6000000 /
songEditor::inst()->getBPM() );
snd_seq_queue_tempo_set_ppq( tempo, 16 );
snd_seq_set_queue_tempo( m_seqHandle, m_queueID, tempo );
@@ -154,10 +155,10 @@ void midiALSASeq::processOutEvent( const midiEvent & _me,
break;
case NOTE_OFF:
snd_seq_ev_set_note( &ev,
snd_seq_ev_set_noteoff( &ev,
_port->outputChannel(),
_me.key() + NOTES_PER_OCTAVE,
_me.velocity(), 500 );
_me.velocity() );
break;
case KEY_PRESSURE:

View File

@@ -35,10 +35,6 @@
#include "midi_port.h"
#include "note.h"
/*#include "midi_alsa_raw.h"
#include "midi_alsa_seq.h"
#include "midi_oss.h"
#include "midi_dummy.h"*/
@@ -98,7 +94,7 @@ void midiClient::removePort( midiPort * _port )
midiRawClient::midiRawClient() :
midiClientRaw::midiClientRaw() :
midiClient()
{
}
@@ -106,14 +102,14 @@ midiRawClient::midiRawClient() :
midiRawClient::~midiRawClient()
midiClientRaw::~midiClientRaw()
{
}
void midiRawClient::parseData( const Uint8 _c )
void midiClientRaw::parseData( const Uint8 _c )
{
/*********************************************************************/
/* 'Process' system real-time messages */
@@ -248,7 +244,7 @@ void midiRawClient::parseData( const Uint8 _c )
void midiRawClient::processParsedEvent()
void midiClientRaw::processParsedEvent()
{
for( csize i = 0; i < m_midiPorts.size(); ++i )
{
@@ -260,7 +256,7 @@ void midiRawClient::processParsedEvent()
void midiRawClient::processOutEvent( const midiEvent & _me,
void midiClientRaw::processOutEvent( const midiEvent & _me,
const midiTime & ,
const midiPort * _port )
{
@@ -293,7 +289,7 @@ void midiRawClient::processOutEvent( const midiEvent & _me,
break;
default:
printf( "midiRawClient: unhandled MIDI-event %d\n",
printf( "midiClientRaw: unhandled MIDI-event %d\n",
(int) _me.m_type );
break;
}
@@ -331,7 +327,7 @@ const Uint8 REMAINS_80E0[] =
// Returns the length of the MIDI message starting with _event.
// Taken from Nagano Daisuke's USB-MIDI driver
Uint8 midiRawClient::eventLength( const Uint8 _event )
Uint8 midiClientRaw::eventLength( const Uint8 _event )
{
if ( _event < 0xF0 )
{

View File

@@ -54,7 +54,7 @@
midiOSS::midiOSS( void ) :
midiRawClient(),
midiClientRaw(),
QThread(),
m_midiDev( probeDevice() ),
m_quit( FALSE )
@@ -143,7 +143,7 @@ void midiOSS::run( void )
midiOSS::setupWidget::setupWidget( QWidget * _parent ) :
midiRawClient::setupWidget( midiOSS::name(), _parent )
midiClientRaw::setupWidget( midiOSS::name(), _parent )
{
m_device = new QLineEdit( midiOSS::probeDevice(), this );
m_device->setGeometry( 10, 20, 160, 20 );

View File

@@ -31,7 +31,6 @@
#include <QMenu>
#include <QProgressBar>
#include <QPushButton>
#include <QTimer>
#include <QMessageBox>
#include <QImage>
#include <QMouseEvent>
@@ -42,7 +41,6 @@
#include <qpopupmenu.h>
#include <qprogressbar.h>
#include <qpushbutton.h>
#include <qtimer.h>
#include <qmessagebox.h>
#include <qimage.h>
@@ -79,9 +77,8 @@ pattern::pattern ( channelTrack * _channel_track ) :
m_name( _channel_track->name() ),
m_frozenPatternMutex(),
m_frozenPattern( NULL ),
m_freezeRecorder( NULL ),
m_freezeStatusDialog( NULL ),
m_freezeStatusUpdateTimer( NULL )
m_freezing( FALSE ),
m_freezeAborted( FALSE )
{
initPixmaps();
@@ -118,7 +115,8 @@ pattern::pattern( const pattern & _pat_to_copy ) :
m_patternType( _pat_to_copy.m_patternType ),
m_name( "" ),
m_frozenPatternMutex(),
m_frozenPattern( NULL )
m_frozenPattern( NULL ),
m_freezeAborted( FALSE )
{
initPixmaps();
@@ -573,7 +571,8 @@ void pattern::freeze( void )
( 0, tr( "Channel muted" ),
tr( "The channel this pattern "
"belongs to is "
"currently muted, so "
"currently muted "
"therefore "
"freezing makes no "
"sense! Do you still "
"want to continue?" ),
@@ -594,15 +593,17 @@ void pattern::freeze( void )
unfreeze();
}
mixer::inst()->pause();
// create and install audio-sample-recorder
bool b;
m_freezeRecorder = new audioSampleRecorder(
mixer::inst()->sampleRate(),
DEFAULT_CHANNELS, b );
mixer::inst()->setAudioDevice( m_freezeRecorder,
// we cannot create local copy, because at a later stage
// mixer::restoreAudioDevice(...) deletes old audio-dev and thus
// audioSampleRecorder would be destroyed two times...
audioSampleRecorder * freeze_recorder = new audioSampleRecorder(
mixer::inst()->sampleRate(), DEFAULT_CHANNELS, b );
mixer::inst()->setAudioDevice( freeze_recorder,
mixer::inst()->highQuality() );
// prepare stuff for playing correct things later
songEditor::inst()->playPattern( this, FALSE );
songEditor::playPos & ppp = songEditor::inst()->getPlayPos(
songEditor::PLAY_PATTERN );
@@ -610,19 +611,41 @@ void pattern::freeze( void )
ppp.setTact64th( 0 );
ppp.setCurrentFrame( 0 );
ppp.m_timeLineUpdate = FALSE;
m_freezeStatusDialog = new patternFreezeStatusDialog;
connect( m_freezeStatusDialog, SIGNAL( aborted() ), this,
SLOT( abortFreeze() ) );
m_freezeStatusUpdateTimer = new QTimer( this );
connect( m_freezeStatusUpdateTimer, SIGNAL( timeout() ), this,
SLOT( updateFreezeStatusDialog() ) );
// create status-dialog
patternFreezeStatusDialog status_dlg;
status_dlg.show();
connect( &status_dlg, SIGNAL( aborted() ),
this, SLOT( abortFreeze() ) );
m_freezeStatusUpdateTimer->start( 50 );
m_freezeAborted = FALSE;
m_freezing = TRUE;
m_freezeStatusDialog->show();
// now render everything
while( ppp < length() && m_freezeAborted == FALSE )
{
freeze_recorder->processNextBuffer();
status_dlg.setProgress( ppp * 100 / length() );
qApp->processEvents();
}
mixer::inst()->play();
m_freezing = FALSE;
// reset song-editor settings
songEditor::inst()->stop();
songEditor::inst()->getPlayPos( songEditor::PLAY_PATTERN
).m_timeLineUpdate = TRUE;
// create final sample-buffer if freezing was successful
if( m_freezeAborted == FALSE )
{
m_frozenPatternMutex.lock();
freeze_recorder->createSampleBuffer( &m_frozenPattern );
m_frozenPatternMutex.unlock();
}
// restore original audio-device
mixer::inst()->restoreAudioDevice();
}
@@ -642,62 +665,9 @@ void pattern::unfreeze( void )
void pattern::updateFreezeStatusDialog( void )
{
m_freezeStatusDialog->setProgress( songEditor::inst()->getPlayPos(
songEditor::PLAY_PATTERN ) *
100 / length() );
m_frozenPatternMutex.lock();
// finishFreeze called?
if( m_freezeRecorder == NULL )
{
// then we're done and destroy the timer and the dialog
delete m_freezeStatusUpdateTimer;
delete m_freezeStatusDialog;
m_freezeStatusUpdateTimer = NULL;
m_freezeStatusDialog = NULL;
}
m_frozenPatternMutex.unlock();
}
void pattern::finishFreeze( void )
{
songEditor::inst()->stop();
m_frozenPatternMutex.lock();
m_freezeRecorder->createSampleBuffer( &m_frozenPattern );
mixer::inst()->restoreAudioDevice();
m_freezeRecorder = NULL;
songEditor::inst()->getPlayPos( songEditor::PLAY_PATTERN
).m_timeLineUpdate = TRUE;
m_frozenPatternMutex.unlock();
}
void pattern::abortFreeze( void )
{
songEditor::inst()->stop();
m_frozenPatternMutex.lock();
mixer::inst()->restoreAudioDevice();
m_freezeRecorder = NULL;
songEditor::inst()->getPlayPos( songEditor::PLAY_PATTERN
).m_timeLineUpdate = TRUE;
m_frozenPatternMutex.unlock();
m_freezeAborted = TRUE;
}
@@ -788,7 +758,7 @@ void pattern::removeNote( const note * _note_to_del )
noteVector::iterator it = m_notes.begin();
while( it != m_notes.end() )
{
if( ( *it ) == _note_to_del )
if( *it == _note_to_del )
{
delete *it;
m_notes.erase( it );
@@ -961,7 +931,8 @@ void pattern::loadSettings( const QDomElement & _this )
patternFreezeStatusDialog::patternFreezeStatusDialog( void )
patternFreezeStatusDialog::patternFreezeStatusDialog( void ) :
QDialog()
{
setWindowTitle( tr( "Freezing pattern..." ) );
#if QT_VERSION >= 0x030200
@@ -980,6 +951,7 @@ patternFreezeStatusDialog::patternFreezeStatusDialog( void )
m_cancelBtn = new QPushButton( embed::getIconPixmap( "cancel" ),
tr( "Cancel" ), this );
m_cancelBtn->setGeometry( 50, 38, 120, 28 );
m_cancelBtn->show();
connect( m_cancelBtn, SIGNAL( clicked() ), this,
SLOT( cancelBtnClicked() ) );
}

View File

@@ -44,13 +44,10 @@
nStateButton::nStateButton( QWidget * _parent ) :
QWidget( _parent ),
QPushButton( _parent ),
m_generalToolTip( "" ),
m_curState( -1 )
{
#ifndef QT4
setBackgroundMode( Qt::NoBackground );
#endif
}
@@ -75,7 +72,7 @@ void nStateButton::addState( const QPixmap & _pm, const QString & _tooltip )
if( m_states.size() == 1 )
{
// then resize ourself
resize( _pm.width(), _pm.height() );
setFixedSize( _pm.width() + 6, _pm.height() + 6 );
// and set state to first pixmap
changeState( 0 );
}
@@ -96,15 +93,17 @@ void nStateButton::changeState( int _n )
m_generalToolTip;
toolTip::add( this, _tooltip );
emit stateChanged( m_curState );
setPixmap( *m_states[m_curState].first );
update();
emit changedState( m_curState );
/* update();*/
}
}
/*
void nStateButton::paintEvent( QPaintEvent * )
{
#ifdef QT4
@@ -125,7 +124,7 @@ void nStateButton::paintEvent( QPaintEvent * )
bitBlt( this, rect().topLeft(), &draw_pm );
#endif
}
*/
@@ -135,6 +134,7 @@ void nStateButton::mousePressEvent( QMouseEvent * _me )
{
changeState( ( ++m_curState ) % m_states.size() );
}
QPushButton::mousePressEvent( _me );
}

View File

@@ -209,7 +209,7 @@ void tabWidget::paintEvent( QPaintEvent * _pe )
void tabWidget::wheelEvent( QWheelEvent * _we )
{
_we->accept();
int dir = ( _we->delta() > 0 ) ? 1 : -1;
int dir = ( _we->delta() < 0 ) ? 1 : -1;
int tab = m_activeTab;
while( tab > -1 && static_cast<csize>( tab ) < m_widgets.count() )
{

View File

@@ -129,7 +129,7 @@ void visualizationWidget::paintEvent( QPaintEvent * )
if( m_enabled )
{
float master_output = mixer::inst()->masterOutput();
float master_output = mixer::inst()->masterGain();
Uint16 w = width()-4;
float half_h = -( height() - 6 ) / 3.0 * master_output - 1;
Uint16 x_base = 2;