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:
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <qdom.h>
|
||||
#include <qlabel.h>
|
||||
#include <qcombobox.h>
|
||||
#include <qwhatsthis.h>
|
||||
|
||||
#define setChecked setOn
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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" );
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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() ) );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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() )
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user