diff --git a/ChangeLog b/ChangeLog index a848ad647..7d9cfd3a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,34 @@ 2008-05-1 Tobias Doerffel + * 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: diff --git a/configure.in b/configure.in index c028de5bc..483a55fc6 100644 --- a/configure.in +++ b/configure.in @@ -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) diff --git a/include/audio_device.h b/include/audio_device.h index f638ce0bb..4921236a6 100644 --- a/include/audio_device.h +++ b/include/audio_device.h @@ -162,6 +162,8 @@ protected: return( m_mixer ); } + bool hqAudio( void ) const; + private: sample_rate_t m_sampleRate; diff --git a/include/mixer.h b/include/mixer.h index c2b1abbe4..31f86c3a0 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -412,7 +412,7 @@ private: private: mixer * m_mixer; fifo * m_fifo; - bool m_writing; + volatile bool m_writing; virtual void run( void ); diff --git a/include/project_renderer.h b/include/project_renderer.h index 786e18739..1f956b2fa 100644 --- a/include/project_renderer.h +++ b/include/project_renderer.h @@ -76,6 +76,7 @@ private: audioFileDevice * m_fileDev; mixer::qualitySettings m_qualitySettings; + mixer::qualitySettings m_oldQualitySettings; volatile bool m_abort; diff --git a/include/setup_dialog.h b/include/setup_dialog.h index 0be11647d..0286d3cdd 100644 --- a/include/setup_dialog.h +++ b/include/setup_dialog.h @@ -1,7 +1,7 @@ /* * setup_dialog.h - dialog for setting up LMMS * - * Copyright (c) 2005-2007 Tobias Doerffel + * Copyright (c) 2005-2008 Tobias Doerffel * * 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; diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 0235e7487..12959e594 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -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 - } - } diff --git a/src/core/audio/audio_alsa.cpp b/src/core/audio/audio_alsa.cpp index 0f11998f2..8ec37b4de 100644 --- a/src/core/audio/audio_alsa.cpp +++ b/src/core/audio/audio_alsa.cpp @@ -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; + } } } diff --git a/src/core/audio/audio_device.cpp b/src/core/audio/audio_device.cpp index 79d9994ff..95b77d3f5 100644 --- a/src/core/audio/audio_device.cpp +++ b/src/core/audio/audio_device.cpp @@ -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 diff --git a/src/core/audio/audio_jack.cpp b/src/core/audio/audio_jack.cpp index 7601cdd06..64919d44b 100644 --- a/src/core/audio/audio_jack.cpp +++ b/src/core/audio/audio_jack.cpp @@ -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 ) ); + } } } diff --git a/src/core/audio/audio_oss.cpp b/src/core/audio/audio_oss.cpp index a055d7b0c..cee247627 100644 --- a/src/core/audio/audio_oss.cpp +++ b/src/core/audio/audio_oss.cpp @@ -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 ); + } } } diff --git a/src/core/audio/audio_sdl.cpp b/src/core/audio/audio_sdl.cpp index c4144a405..e7f439368 100644 --- a/src/core/audio/audio_sdl.cpp +++ b/src/core/audio/audio_sdl.cpp @@ -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() ); + } } } diff --git a/src/core/mixer.cpp b/src/core/mixer.cpp index 0cf46f690..0bc252ba7 100644 --- a/src/core/mixer.cpp +++ b/src/core/mixer.cpp @@ -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 ) ); diff --git a/src/core/project_renderer.cpp b/src/core/project_renderer.cpp index 05fd6aef0..3f74d83e3 100644 --- a/src/core/project_renderer.cpp +++ b/src/core/project_renderer.cpp @@ -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 ) diff --git a/src/gui/main_window.cpp b/src/gui/main_window.cpp index 99a64b4d2..51cc8f1c1 100644 --- a/src/gui/main_window.cpp +++ b/src/gui/main_window.cpp @@ -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(); } } diff --git a/src/gui/setup_dialog.cpp b/src/gui/setup_dialog.cpp index 0caf79f26..00ccc8b62 100644 --- a/src/gui/setup_dialog.cpp +++ b/src/gui/setup_dialog.cpp @@ -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; diff --git a/src/tracks/instrument_track.cpp b/src/tracks/instrument_track.cpp index 38e1aa2a2..f30dfd8f1 100644 --- a/src/tracks/instrument_track.cpp +++ b/src/tracks/instrument_track.cpp @@ -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( + getTCOsInRange( tcos, _start, _start + static_cast( _frames / frames_per_tick ) ); bb_track = NULL; sendMidiTime( _start );