Ring buffer solution attached. It uses spin locks to check if the
buffer has sufficient data available before reading from it.
There is a define called RING_BUFFER_SIZE_MULTIPLIER which defaults to
4 and sets the ring buffer size to 4 times that of what it would be if
it was the original buffer fifo implementation. I found that 4x, 8x,
or higher gave most smooth audio playback results. Ultimately, this
define should go and the size should be set dynamically.
This is just a draft, so please give me feedback if you try it!
- Carmelo
On Thu, Apr 1, 2010 at 5:46 PM, Tobias Doerffel
<[email protected]> wrote:
> Hi,
>
> Am Mittwoch, 31. März 2010 14:34:43 schrieb Carmelo Piccione:
>> I reached the same solution as you with the RT safe ring buffer. Sadly I
>> moronically misunderstood the implementation in AudioJack.cpp and ended up
>> using the read / write ring buffer in reverse of how it was intended (I
>> copy the space given by jack in the processing thread to write audio, then
>> write to the copy in the ring buffer on a RT qthread. )
>>
>> Instead I need to copy the audio buffer from lmms into jack using a similar
>> mechanism. I'm hoping I can patch the code I wrote some time this week to
>> do just that.
> Please also have a look at the jack-fixes branch at
> http://lmms.git.sourceforge.net/git/gitweb.cgi?p=lmms/lmms;a=shortlog;h=refs/heads/jack-
> fixes - it does not work very well yet but includes some fixes for better RT
> safety.
>
> Toby
>
> ------------------------------------------------------------------------------
> Download Intel® Parallel Studio Eval
> Try the new software tools for yourself. Speed compiling, find bugs
> proactively, and fine-tune applications for parallel performance.
> See why Intel Parallel Studio got high marks during beta.
> http://p.sf.net/sfu/intel-sw-dev
> _______________________________________________
> LMMS-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/lmms-devel
>
>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bd13070..6078d36 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -69,6 +69,12 @@ OPTION(WANT_VST_NOWINE "Include partial VST support (without wine)" OFF)
OPTION(WANT_WINMM "Include WinMM MIDI support" OFF)
OPTION(WANT_ZIP "Include zip support" ON)
OPTION(WANT_FLAC "Include flac support" ON)
+OPTION(WANT_JACK_RING_BUFFERS "Enable jack ring buffers" ON)
+
+IF(WANT_JACK_RING_BUFFERS)
+ADD_DEFINITIONS("-DUSE_JACK_RING_BUFFERS")
+ELSE(WANT_JACK_RING_BUFFERS)
+ENDIF(WANT_JACK_RING_BUFFERS)
IF(LMMS_BUILD_WIN32)
SET(WANT_ALSA OFF)
diff --git a/include/AudioOutputContext.h b/include/AudioOutputContext.h
index f8847ca..93646db 100644
--- a/include/AudioOutputContext.h
+++ b/include/AudioOutputContext.h
@@ -32,6 +32,11 @@
class AudioBackend;
+#ifdef USE_JACK_RING_BUFFERS
+#include "RingBufferFifo.h"
+#endif
+
+
/*! \brief The AudioOutputContext class centralizes all functionality
* and data related to output of audio data.
*
@@ -70,22 +75,22 @@ public:
/*! Lists all supported oversampling ratios. */
enum Oversampling
- {
+ {
Oversampling_None, /*!< No oversampling - fast */
Oversampling_2x, /*!< 2x oversampling - good quality */
Oversampling_4x, /*!< 4x oversampling - better quality */
- Oversampling_8x /*!< 8x oversampling - best quality but might break some filters */
+ Oversampling_8x, /*!< 8x oversampling - best quality but might break some filters */
} ;
-
+
/*! \brief Constructs a QualitySettings object based on a given preset. */
QualitySettings( Preset m )
{
switch( m )
{
case Preset_Draft:
- m_interpolation = Interpolation_Linear;
- m_oversampling = Oversampling_None;
- m_sampleExactControllers = false;
+ m_interpolation = Interpolation_Linear;
+ m_oversampling = Oversampling_None;
+ m_sampleExactControllers = false;
m_aliasFreeOscillators = false;
break;
case Preset_HighQuality:
@@ -109,7 +114,7 @@ public:
QualitySettings( Interpolation _i, Oversampling _o, bool _sec,
bool _afo ) :
m_interpolation( _i ),
- m_oversampling( _o ),
+ m_oversampling( _o ),
m_sampleExactControllers( _sec ),
m_aliasFreeOscillators( _afo )
{
@@ -119,7 +124,7 @@ public:
int sampleRateMultiplier() const
{
switch( oversampling() )
- {
+ {
case Oversampling_None: return 1;
case Oversampling_2x: return 2;
case Oversampling_4x: return 4;
@@ -127,7 +132,7 @@ public:
}
return 1;
}
-
+
/*! \brief Maps interpolation setting to libsamplerate constants. */
int libsrcInterpolation() const
{
@@ -162,13 +167,13 @@ public:
{
return m_oversampling;
}
-
+
/*! \brief Sets a new oversampling factor. */
void setOversampling( Oversampling oversampling )
{
m_oversampling = oversampling;
}
-
+
/*! \brief Returns whether to use sample exact controllers. */
bool sampleExactControllers() const
{
@@ -183,7 +188,7 @@ public:
private:
Interpolation m_interpolation;
- Oversampling m_oversampling;
+ Oversampling m_oversampling;
bool m_sampleExactControllers;
bool m_aliasFreeOscillators;
@@ -218,7 +223,7 @@ public:
* \param bufferSize The size of each buffer in the FIFO
*/
BufferFifo( int size, int bufferSize );
- ~BufferFifo();
+ virtual ~BufferFifo();
/*! \brief Enable or disable support for realtime reading */
void setRealtimeReading( bool enabled )
@@ -259,7 +264,7 @@ public:
return m_fillState == 0;
}
-
+
private:
bool m_realtimeReading;
volatile int m_fillState;
@@ -274,6 +279,12 @@ public:
} ;
+ #ifdef USE_JACK_RING_BUFFERS
+ typedef RingBufferFifo BufferFifoType;
+ #else
+ typedef BufferFifo BufferFifoType;
+ #endif
+
/*! \brief The FifoWriter class provides an internal thread for feeding
* the FIFO read by the active AudioBackend */
class FifoWriter : public QThread
@@ -334,7 +345,7 @@ public:
}
/*! \brief Returns BufferFifo object used by this context. */
- BufferFifo * fifo()
+ BufferFifoType * fifo()
{
return m_fifo;
}
@@ -366,12 +377,12 @@ public:
int getCurrentOutputBuffer( sampleFrameA * destBuffer,
sample_rate_t destSampleRate );
-
private:
Mixer * m_mixer;
QualitySettings m_qualitySettings;
AudioBackend * m_audioBackend;
- BufferFifo * m_fifo;
+
+ BufferFifoType * m_fifo;
FifoWriter * m_fifoWriter;
// resample data
diff --git a/src/core/audio/AudioOutputContext.cpp b/src/core/audio/AudioOutputContext.cpp
index 664453c..91e946d 100644
--- a/src/core/audio/AudioOutputContext.cpp
+++ b/src/core/audio/AudioOutputContext.cpp
@@ -29,6 +29,9 @@
#include "config_mgr.h"
#include "engine.h"
+#ifdef USE_JACK_RING_BUFFERS
+#include "RingBufferFifo.h"
+#endif
AudioOutputContext::BufferFifo::BufferFifo( int _size, int _bufferSize ) :
m_realtimeReading( false ),
@@ -173,7 +176,7 @@ AudioOutputContext::AudioOutputContext( Mixer * mixer,
// just rendering?
if( !engine::hasGUI() )
{
- m_fifo = new BufferFifo( 1, framesPerPeriod );
+ m_fifo = new BufferFifoType( 1, framesPerPeriod );
}
else if( configManager::inst()->value( "mixer", "framesperaudiobuffer"
).toInt() >= 32 )
@@ -184,12 +187,12 @@ AudioOutputContext::AudioOutputContext( Mixer * mixer,
if( framesPerPeriod > DEFAULT_BUFFER_SIZE )
{
- m_fifo = new BufferFifo( framesPerPeriod / DEFAULT_BUFFER_SIZE,
- DEFAULT_BUFFER_SIZE );
+ m_fifo = new BufferFifoType( framesPerPeriod / DEFAULT_BUFFER_SIZE,
+ DEFAULT_BUFFER_SIZE );
}
else
{
- m_fifo = new BufferFifo( 1, framesPerPeriod );
+ m_fifo = new BufferFifoType( 1, framesPerPeriod );
}
}
else
@@ -197,7 +200,7 @@ AudioOutputContext::AudioOutputContext( Mixer * mixer,
configManager::inst()->setValue( "mixer",
"framesperaudiobuffer",
QString::number( framesPerPeriod ) );
- m_fifo = new BufferFifo( 1, framesPerPeriod );
+ m_fifo = new BufferFifoType( 1, framesPerPeriod );
}
}
@@ -265,7 +268,7 @@ int AudioOutputContext::getCurrentOutputBuffer( sampleFrameA * _destBuf,
{
int frames = mixer()->framesPerPeriod();
m_fifo->startRead();
- if( m_fifo->currentReadBufferState() == BufferFifo::NullBuffer )
+ if( m_fifo->currentReadBufferState() == BufferFifoType::NullBuffer )
{
m_fifo->finishRead();
return 0;
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
LMMS-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/lmms-devel