* sf2Player: retrieve resampling-interpolation from current mixer quality settings
* mixer: made m_writing-variable in fifoWriter volatile * projectRenderer: change audio-device to file-device from within GUI-thread in order to make slots being connected to sampleRateChanged()-signal being called immediately * audioDevice: made HQ-mode for audio-devices optional git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@959 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
29
ChangeLog
29
ChangeLog
@@ -1,5 +1,34 @@
|
||||
2008-05-1 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
|
||||
|
||||
* plugins/sf2_player/sf2_player.cpp:
|
||||
retrieve resampling-interpolation from current mixer quality settings
|
||||
|
||||
* include/mixer.h:
|
||||
made m_writing-variable in fifoWriter volatile
|
||||
|
||||
* include/project_renderer.h:
|
||||
* src/core/project_renderer.cpp:
|
||||
change audio-device to file-device from within GUI-thread in order to
|
||||
make slots being connected to sampleRateChanged()-signal being called
|
||||
immediately
|
||||
|
||||
* src/tracks/instrument_track.cpp:
|
||||
cleanups
|
||||
|
||||
* src/core/mixer.cpp:
|
||||
initialize quality with draft-preset
|
||||
|
||||
* include/setup_dialog.h:
|
||||
* include/audio_device.h:
|
||||
* src/gui/main_window.cpp:
|
||||
* src/gui/setup_dialog.cpp:
|
||||
* src/core/audio/audio_device.cpp:
|
||||
* src/core/audio/audio_alsa.cpp:
|
||||
* src/core/audio/audio_sdl.cpp:
|
||||
* src/core/audio/audio_oss.cpp:
|
||||
* src/core/audio/audio_jack.cpp:
|
||||
made HQ-mode for audio-devices optional
|
||||
|
||||
* include/controller.h:
|
||||
* include/song.h:
|
||||
* include/audio_file_device.h:
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(lmms, 0.4.0-svn20080504, lmms-devel/at/lists/dot/sf/dot/net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.4.0-svn20080504)
|
||||
AC_INIT(lmms, 0.4.0-svn20080511, lmms-devel/at/lists/dot/sf/dot/net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.4.0-svn20080511)
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
|
||||
@@ -162,6 +162,8 @@ protected:
|
||||
return( m_mixer );
|
||||
}
|
||||
|
||||
bool hqAudio( void ) const;
|
||||
|
||||
|
||||
private:
|
||||
sample_rate_t m_sampleRate;
|
||||
|
||||
@@ -412,7 +412,7 @@ private:
|
||||
private:
|
||||
mixer * m_mixer;
|
||||
fifo * m_fifo;
|
||||
bool m_writing;
|
||||
volatile bool m_writing;
|
||||
|
||||
virtual void run( void );
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ private:
|
||||
|
||||
audioFileDevice * m_fileDev;
|
||||
mixer::qualitySettings m_qualitySettings;
|
||||
mixer::qualitySettings m_oldQualitySettings;
|
||||
|
||||
volatile bool m_abort;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* setup_dialog.h - dialog for setting up LMMS
|
||||
*
|
||||
* Copyright (c) 2005-2007 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -45,13 +45,16 @@ class setupDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum configTabs
|
||||
enum ConfigTabs
|
||||
{
|
||||
GENERAL_SETTINGS, DIRECTORY_SETTINGS, PERFORMANCE_SETTINGS,
|
||||
AUDIO_SETTINGS, MIDI_SETTINGS
|
||||
GeneralSettings,
|
||||
DirectorySettings,
|
||||
PerformanceSettings,
|
||||
AudioSettings,
|
||||
MidiSettings
|
||||
} ;
|
||||
|
||||
setupDialog( configTabs _tab_to_open = GENERAL_SETTINGS );
|
||||
setupDialog( ConfigTabs _tab_to_open = GeneralSettings );
|
||||
virtual ~setupDialog();
|
||||
|
||||
|
||||
@@ -89,6 +92,7 @@ private slots:
|
||||
void toggleWarnAfterSetup( bool _enabled );
|
||||
void toggleDisplaydBV( bool _enabled );
|
||||
void toggleMMPZ( bool _enabled );
|
||||
void toggleHQAudioDev( bool _enabled );
|
||||
|
||||
void openWorkingDir( void );
|
||||
void openVSTDir( void );
|
||||
@@ -115,6 +119,7 @@ private:
|
||||
bool m_warnAfterSetup;
|
||||
bool m_displaydBV;
|
||||
bool m_MMPZ;
|
||||
bool m_hqAudioDev;
|
||||
|
||||
|
||||
QLineEdit * m_wdLineEdit;
|
||||
|
||||
@@ -423,7 +423,8 @@ void sf2Instrument::updateSampleRate( void )
|
||||
src_delete( m_srcState );
|
||||
}
|
||||
int error;
|
||||
m_srcState = src_new( SRC_SINC_MEDIUM_QUALITY,
|
||||
m_srcState = src_new( engine::getMixer()->
|
||||
currentQualitySettings().libsrcInterpolation(),
|
||||
DEFAULT_CHANNELS, &error );
|
||||
if( m_srcState == NULL || error )
|
||||
{
|
||||
@@ -452,7 +453,7 @@ void sf2Instrument::playNote( notePlayHandle * _n, bool, sampleFrame * )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( tfp == 0 )
|
||||
if( tfp == 0 )
|
||||
{
|
||||
_n->m_pluginData = new int( midiNote );
|
||||
|
||||
@@ -464,11 +465,6 @@ void sf2Instrument::playNote( notePlayHandle * _n, bool, sampleFrame * )
|
||||
++m_notesRunning[midiNote];
|
||||
m_notesRunningMutex.unlock();
|
||||
}
|
||||
else if( _n->released() )
|
||||
{
|
||||
// Doesn't happen with release frames = 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -187,35 +187,39 @@ void audioALSA::stopProcessing( void )
|
||||
|
||||
void audioALSA::applyQualitySettings( void )
|
||||
{
|
||||
setSampleRate( engine::getMixer()->processingSampleRate() );
|
||||
|
||||
if( m_handle != NULL )
|
||||
if( hqAudio() )
|
||||
{
|
||||
snd_pcm_close( m_handle );
|
||||
}
|
||||
setSampleRate( engine::getMixer()->processingSampleRate() );
|
||||
|
||||
int err;
|
||||
if( ( err = snd_pcm_open( &m_handle,
|
||||
if( m_handle != NULL )
|
||||
{
|
||||
snd_pcm_close( m_handle );
|
||||
}
|
||||
|
||||
int err;
|
||||
if( ( err = snd_pcm_open( &m_handle,
|
||||
probeDevice().toAscii().constData(),
|
||||
SND_PCM_STREAM_PLAYBACK,
|
||||
0 ) ) < 0 )
|
||||
{
|
||||
printf( "Playback open error: %s\n", snd_strerror( err ) );
|
||||
return;
|
||||
}
|
||||
0 ) ) < 0 )
|
||||
{
|
||||
printf( "Playback open error: %s\n",
|
||||
snd_strerror( err ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( ( err = setHWParams( channels(),
|
||||
if( ( err = setHWParams( channels(),
|
||||
SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
|
||||
{
|
||||
printf( "Setting of hwparams failed: %s\n",
|
||||
{
|
||||
printf( "Setting of hwparams failed: %s\n",
|
||||
snd_strerror( err ) );
|
||||
return;
|
||||
}
|
||||
if( ( err = setSWParams() ) < 0 )
|
||||
{
|
||||
printf( "Setting of swparams failed: %s\n",
|
||||
return;
|
||||
}
|
||||
if( ( err = setSWParams() ) < 0 )
|
||||
{
|
||||
printf( "Setting of swparams failed: %s\n",
|
||||
snd_strerror( err ) );
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
|
||||
#include "audio_device.h"
|
||||
#include "config_mgr.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
@@ -166,7 +167,7 @@ void audioDevice::resample( const surroundSampleFrame * _src,
|
||||
m_srcData.output_frames = _frames;
|
||||
m_srcData.data_in = (float *) _src[0];
|
||||
m_srcData.data_out = _dst[0];
|
||||
m_srcData.src_ratio = (float) _dst_sr / _src_sr;
|
||||
m_srcData.src_ratio = (double) _dst_sr / _src_sr;
|
||||
|
||||
int error;
|
||||
if( ( error = src_process( m_srcState, &m_srcData ) ) )
|
||||
@@ -235,4 +236,11 @@ void audioDevice::clearS16Buffer( int_sample_t * _outbuf, const fpp_t _frames )
|
||||
|
||||
|
||||
|
||||
bool audioDevice::hqAudio( void ) const
|
||||
{
|
||||
return( configManager::inst()->value( "mixer", "hqaudio" ).toInt() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -234,11 +234,14 @@ void audioJACK::stopProcessing( void )
|
||||
|
||||
void audioJACK::applyQualitySettings( void )
|
||||
{
|
||||
setSampleRate( engine::getMixer()->processingSampleRate() );
|
||||
|
||||
if( jack_get_sample_rate( m_client ) != sampleRate() )
|
||||
if( hqAudio() )
|
||||
{
|
||||
setSampleRate( jack_get_sample_rate( m_client ) );
|
||||
setSampleRate( engine::getMixer()->processingSampleRate() );
|
||||
|
||||
if( jack_get_sample_rate( m_client ) != sampleRate() )
|
||||
{
|
||||
setSampleRate( jack_get_sample_rate( m_client ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -270,25 +270,28 @@ void audioOSS::stopProcessing( void )
|
||||
|
||||
void audioOSS::applyQualitySettings( void )
|
||||
{
|
||||
setSampleRate( engine::getMixer()->processingSampleRate() );
|
||||
if( hqAudio() )
|
||||
{
|
||||
setSampleRate( engine::getMixer()->processingSampleRate() );
|
||||
|
||||
unsigned int value = sampleRate();
|
||||
if ( ioctl( m_audioFD, SNDCTL_DSP_SPEED, &value ) < 0 )
|
||||
{
|
||||
perror( "SNDCTL_DSP_SPEED" );
|
||||
printf( "Couldn't set audio frequency\n" );
|
||||
return;
|
||||
}
|
||||
if( value != sampleRate() )
|
||||
{
|
||||
value = getMixer()->baseSampleRate();
|
||||
unsigned int value = sampleRate();
|
||||
if ( ioctl( m_audioFD, SNDCTL_DSP_SPEED, &value ) < 0 )
|
||||
{
|
||||
perror( "SNDCTL_DSP_SPEED" );
|
||||
printf( "Couldn't set audio frequency\n" );
|
||||
return;
|
||||
}
|
||||
setSampleRate( value );
|
||||
if( value != sampleRate() )
|
||||
{
|
||||
value = getMixer()->baseSampleRate();
|
||||
if ( ioctl( m_audioFD, SNDCTL_DSP_SPEED, &value ) < 0 )
|
||||
{
|
||||
perror( "SNDCTL_DSP_SPEED" );
|
||||
printf( "Couldn't set audio frequency\n" );
|
||||
return;
|
||||
}
|
||||
setSampleRate( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,18 +131,22 @@ void audioSDL::stopProcessing( void )
|
||||
|
||||
void audioSDL::applyQualitySettings( void )
|
||||
{
|
||||
SDL_CloseAudio();
|
||||
|
||||
setSampleRate( engine::getMixer()->processingSampleRate() );
|
||||
|
||||
m_audioHandle.freq = sampleRate();
|
||||
|
||||
SDL_AudioSpec actual;
|
||||
|
||||
// open the audio device, forcing the desired format
|
||||
if( SDL_OpenAudio( &m_audioHandle, &actual ) < 0 )
|
||||
if( hqAudio() )
|
||||
{
|
||||
printf( "Couldn't open SDL-audio: %s\n", SDL_GetError() );
|
||||
SDL_CloseAudio();
|
||||
|
||||
setSampleRate( engine::getMixer()->processingSampleRate() );
|
||||
|
||||
m_audioHandle.freq = sampleRate();
|
||||
|
||||
SDL_AudioSpec actual;
|
||||
|
||||
// open the audio device, forcing the desired format
|
||||
if( SDL_OpenAudio( &m_audioHandle, &actual ) < 0 )
|
||||
{
|
||||
printf( "Couldn't open SDL-audio: %s\n",
|
||||
SDL_GetError() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,8 +125,9 @@ public:
|
||||
done( FALSE )
|
||||
{
|
||||
}
|
||||
|
||||
JobTypes type;
|
||||
|
||||
|
||||
union
|
||||
{
|
||||
playHandle * playHandleJob;
|
||||
@@ -254,11 +255,7 @@ mixer::mixer( void ) :
|
||||
m_workers(),
|
||||
m_numWorkers( m_multiThreaded ? QThread::idealThreadCount() : 0 ),
|
||||
m_workerSem( m_numWorkers ),
|
||||
m_qualitySettings( qualitySettings::Interpolation_Linear,
|
||||
qualitySettings::Oversampling_None,
|
||||
FALSE, // sample-exact controllers
|
||||
FALSE // alias-free oscillators
|
||||
),
|
||||
m_qualitySettings( qualitySettings::Mode_Draft ),
|
||||
m_masterGain( 1.0f ),
|
||||
m_audioDev( NULL ),
|
||||
m_oldAudioDev( NULL ),
|
||||
@@ -1057,9 +1054,9 @@ void mixer::fifoWriter::finish( void )
|
||||
|
||||
void mixer::fifoWriter::run( void )
|
||||
{
|
||||
const fpp_t frames = m_mixer->framesPerPeriod();
|
||||
while( m_writing )
|
||||
{
|
||||
fpp_t frames = m_mixer->framesPerPeriod();
|
||||
surroundSampleFrame * buffer = new surroundSampleFrame[frames];
|
||||
const surroundSampleFrame * b = m_mixer->renderNextBuffer();
|
||||
memcpy( buffer, b, frames * sizeof( surroundSampleFrame ) );
|
||||
|
||||
@@ -69,6 +69,7 @@ projectRenderer::projectRenderer( const mixer::qualitySettings & _qs,
|
||||
const QString & _out_file ) :
|
||||
QThread( engine::getMixer() ),
|
||||
m_qualitySettings( _qs ),
|
||||
m_oldQualitySettings( engine::getMixer()->currentQualitySettings() ),
|
||||
m_abort( FALSE )
|
||||
{
|
||||
int idx = 0;
|
||||
@@ -141,6 +142,11 @@ projectRenderer::ExportFileTypes projectRenderer::getFileTypeFromExtension(
|
||||
|
||||
void projectRenderer::startProcessing( void )
|
||||
{
|
||||
// have to do mixer stuff with GUI-thread-affinity in order to make
|
||||
// slots connected to sampleRateChanged()-signals being called
|
||||
// immediately
|
||||
engine::getMixer()->setAudioDevice( m_fileDev, m_qualitySettings );
|
||||
|
||||
start( QThread::HighestPriority );
|
||||
}
|
||||
|
||||
@@ -149,15 +155,10 @@ void projectRenderer::startProcessing( void )
|
||||
|
||||
void projectRenderer::run( void )
|
||||
{
|
||||
const mixer::qualitySettings qs =
|
||||
engine::getMixer()->currentQualitySettings();
|
||||
|
||||
engine::getMixer()->setAudioDevice( m_fileDev, m_qualitySettings );
|
||||
engine::getSong()->startExport();
|
||||
|
||||
song::playPos & pp = engine::getSong()->getPlayPos(
|
||||
song::Mode_PlaySong );
|
||||
|
||||
int progress = 0;
|
||||
while( engine::getSong()->isExportDone() == FALSE &&
|
||||
engine::getSong()->isExporting() == TRUE
|
||||
@@ -178,7 +179,7 @@ void projectRenderer::run( void )
|
||||
const QString f = m_fileDev->outputFile();
|
||||
|
||||
engine::getMixer()->restoreAudioDevice(); // also deletes audio-dev
|
||||
engine::getMixer()->changeQuality( qs );
|
||||
engine::getMixer()->changeQuality( m_oldQualitySettings );
|
||||
|
||||
// if the user aborted export-process, the file has to be deleted
|
||||
if( m_abort )
|
||||
|
||||
@@ -475,7 +475,7 @@ void mainWindow::finalize( void )
|
||||
else if( engine::getMixer()->audioDevName() == audioDummy::name() )
|
||||
{
|
||||
// no, so we offer setup-dialog with audio-settings...
|
||||
setupDialog sd( setupDialog::AUDIO_SETTINGS );
|
||||
setupDialog sd( setupDialog::AudioSettings );
|
||||
sd.exec();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ inline void labelWidget( QWidget * _w, const QString & _txt )
|
||||
|
||||
|
||||
|
||||
setupDialog::setupDialog( configTabs _tab_to_open ) :
|
||||
setupDialog::setupDialog( ConfigTabs _tab_to_open ) :
|
||||
m_bufferSize( configManager::inst()->value( "mixer",
|
||||
"framesperaudiobuffer" ).toInt() ),
|
||||
m_toolTips( !configManager::inst()->value( "tooltips",
|
||||
@@ -98,6 +98,8 @@ setupDialog::setupDialog( configTabs _tab_to_open ) :
|
||||
m_displaydBV( configManager::inst()->value( "app",
|
||||
"displaydbv" ).toInt() ),
|
||||
m_MMPZ( !configManager::inst()->value( "app", "nommpz" ).toInt() ),
|
||||
m_hqAudioDev( configManager::inst()->value( "mixer",
|
||||
"hqaudio" ).toInt() ),
|
||||
m_workingDir( configManager::inst()->workingDir() ),
|
||||
m_vstDir( configManager::inst()->vstDir() ),
|
||||
m_artworkDir( configManager::inst()->artworkDir() ),
|
||||
@@ -175,7 +177,7 @@ setupDialog::setupDialog( configTabs _tab_to_open ) :
|
||||
|
||||
|
||||
tabWidget * misc_tw = new tabWidget( tr( "MISC" ), general );
|
||||
misc_tw->setFixedHeight( 150 );
|
||||
misc_tw->setFixedHeight( 164 );
|
||||
|
||||
ledCheckBox * enable_tooltips = new ledCheckBox(
|
||||
tr( "Enable tooltips" ),
|
||||
@@ -239,6 +241,15 @@ setupDialog::setupDialog( configTabs _tab_to_open ) :
|
||||
connect( mmpz, SIGNAL( toggled( bool ) ),
|
||||
this, SLOT( toggleMMPZ( bool ) ) );
|
||||
|
||||
ledCheckBox * hqaudio = new ledCheckBox(
|
||||
tr( "HQ-mode for output audio-device" ),
|
||||
misc_tw );
|
||||
hqaudio->move( 10, 144 );
|
||||
hqaudio->setChecked( m_hqAudioDev );
|
||||
connect( hqaudio, SIGNAL( toggled( bool ) ),
|
||||
this, SLOT( toggleHQAudioDev( bool ) ) );
|
||||
|
||||
|
||||
|
||||
gen_layout->addWidget( bufsize_tw );
|
||||
gen_layout->addSpacing( 10 );
|
||||
@@ -678,6 +689,8 @@ void setupDialog::accept( void )
|
||||
QString::number( m_displaydBV ) );
|
||||
configManager::inst()->setValue( "app", "nommpz",
|
||||
QString::number( !m_MMPZ ) );
|
||||
configManager::inst()->setValue( "mixer", "hqaudio",
|
||||
QString::number( m_hqAudioDev ) );
|
||||
configManager::inst()->setValue( "ui",
|
||||
"disablechannelactivityindicators",
|
||||
QString::number( m_disableChActInd ) );
|
||||
@@ -834,6 +847,14 @@ void setupDialog::toggleMMPZ( bool _enabled )
|
||||
|
||||
|
||||
|
||||
void setupDialog::toggleHQAudioDev( bool _enabled )
|
||||
{
|
||||
m_hqAudioDev = _enabled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void setupDialog::toggleDisableChActInd( bool _disabled )
|
||||
{
|
||||
m_disableChActInd = _disabled;
|
||||
|
||||
@@ -181,6 +181,8 @@ void instrumentTrack::processAudioBuffer( sampleFrame * _buf,
|
||||
}
|
||||
float v_scale = (float) getVolume() / DefaultVolume;
|
||||
|
||||
// if effects "went to sleep" because there was no input, wake them up
|
||||
// now
|
||||
m_audioPort.getEffects()->startRunning();
|
||||
|
||||
// instruments using instrument-play-handles will call this method
|
||||
@@ -517,7 +519,7 @@ bool FASTCALL instrumentTrack::play( const midiTime & _start,
|
||||
}
|
||||
else
|
||||
{
|
||||
getTCOsInRange( tcos, _start, _start + static_cast<Sint32>(
|
||||
getTCOsInRange( tcos, _start, _start + static_cast<int>(
|
||||
_frames / frames_per_tick ) );
|
||||
bb_track = NULL;
|
||||
sendMidiTime( _start );
|
||||
|
||||
Reference in New Issue
Block a user