* 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:
Tobias Doerffel
2008-05-11 23:21:33 +00:00
parent e32eed940f
commit 7598cd7a8e
17 changed files with 157 additions and 81 deletions

View File

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

View File

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

View File

@@ -162,6 +162,8 @@ protected:
return( m_mixer );
}
bool hqAudio( void ) const;
private:
sample_rate_t m_sampleRate;

View File

@@ -412,7 +412,7 @@ private:
private:
mixer * m_mixer;
fifo * m_fifo;
bool m_writing;
volatile bool m_writing;
virtual void run( void );

View File

@@ -76,6 +76,7 @@ private:
audioFileDevice * m_fileDev;
mixer::qualitySettings m_qualitySettings;
mixer::qualitySettings m_oldQualitySettings;
volatile bool m_abort;

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 ) );
}
}
}

View File

@@ -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 );
}
}
}

View File

@@ -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() );
}
}
}

View File

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

View File

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

View File

@@ -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();
}
}

View File

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

View File

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