All pastes #1397357 Raw Edit

StepMania PulseAudio

public diff v1 · immutable
#1397357 ·published 2009-04-20 15:48 UTC
rendered paste body
Index: configure.ac===================================================================--- configure.ac    (revision 28031)+++ configure.ac    (working copy)@@ -254,6 +254,16 @@ AC_ARG_ENABLE(lua-binaries, AS_HELP_STRING([--enable-lua-binaries],[Build lua and luac]), enable_lua_binaries=$enableval, enable_lua_binaries=no) AM_CONDITIONAL(BUILD_LUA_BINARIES, test "$enable_lua_binaries" = "yes" ) +AC_ARG_ENABLE(pulse, AS_HELP_STRING([--enable-pulse],[enable PulseAudio output]), enable_pulse=$enableval, enable_pulse=no)+have_pulse=no+if test "x$enable_pulse" = "xyes"; then+    PKG_CHECK_MODULES(PULSE, [ libpulse-simple >= 0.9 ],+        [have_pulse=yes],[have_pulse=no])+    AC_SUBST(PULSE_LIBS)+    AC_SUBST(PULSE_CFLAGS)+fi+AM_CONDITIONAL(HAVE_PULSE, test "x$have_pulse" = "xyes" )+ AC_CONFIG_FILES(Makefile) AC_CONFIG_FILES(src/Makefile) AC_OUTPUTIndex: src/arch/Sound/RageSoundDriver_Pulse.cpp===================================================================--- src/arch/Sound/RageSoundDriver_Pulse.cpp    (revision 0)+++ src/arch/Sound/RageSoundDriver_Pulse.cpp    (revision 0)@@ -0,0 +1,166 @@+#include "global.h"+#include "RageSoundDriver_Pulse.h"++#include "RageLog.h"+#include "RageSound.h"+#include "RageSoundManager.h"+#include "RageUtil.h"+#include "PrefsManager.h"++#include <errno.h>+#include <string.h>+#include <pulse/error.h>++REGISTER_SOUND_DRIVER_CLASS( Pulse );++/* samples */+const int channels = 2;+const int bytes_per_frame = channels*2;        /* 16-bit */+const int chunk_order = 12;+const int num_chunks = 2; //4;+const int buffersize = num_chunks * (1 << (chunk_order-1)); /* in bytes */+const int buffersize_frames = buffersize/bytes_per_frame;    /* in frames */++int RageSoundDriver_Pulse::MixerThread_start(void *p)+{+    ((RageSoundDriver_Pulse *) p)->MixerThread();+    return 0;+}++void RageSoundDriver_Pulse::MixerThread()+{+    /* We want to set a higher priority, but Unix only lets root renice+     * < 0, which is silly.  Give it a try, anyway. */+    int status = nice( -10 );+    if( status != -1 )+        LOG->Trace( "Set MixerThread nice value to %d", status );++    while( !shutdown )+    {+        GetData();++        usleep( 10000 );+    }+}++void RageSoundDriver_Pulse::SetupDecodingThread()+{+    int status = nice( -5 );+    if( status != -1 )+        LOG->Trace( "Set DecodingThread nice value to %d", status );+}++bool RageSoundDriver_Pulse::GetData()+{+    const int chunksize = buffersize;++    static int16_t *buf = NULL;+    if(!buf)+        buf = new int16_t[chunksize / sizeof(int16_t)];++    this->Mix( buf, chunksize/bytes_per_frame, last_cursor_pos, GetPosition() );++    if (pa_simple_write( s, buf, chunksize, &err ) < 0)+        return true;    // need more data++    /* Increment last_cursor_pos. */+    last_cursor_pos += chunksize / bytes_per_frame;++    return false;    // have enough data+}++int64_t RageSoundDriver_Pulse::GetPosition() const+{+    return last_cursor_pos - (buffersize / bytes_per_frame);+    //return last_cursor_pos;+}++RageSoundDriver_Pulse::RageSoundDriver_Pulse()+{+    s = NULL;+    shutdown = false;+    last_cursor_pos = 0;+}++RString RageSoundDriver_Pulse::Init()+{+    samplerate = PREFSMAN->m_iSoundPreferredSampleRate;+    if( samplerate == 0 )+        samplerate = 44100;++    spec.format = PA_SAMPLE_S16LE;+    spec.channels = channels;+    spec.rate = samplerate;++    //bufattr.maxlength = 4096;+    bufattr.maxlength = buffersize * 2;++    s = pa_simple_new(+        NULL,            // default server+        "StepMania",        // app name+        PA_STREAM_PLAYBACK,    // playback+        NULL,            // default device+        "Audio",        // stream description+        &spec,            // sample spec+        NULL,            // default channel map+        &bufattr,        // h4xed buffering+        &err            // error code+    );+    if (s == NULL)+        return ssprintf( "RageSoundDriver_Pulse: Couldn't connect to Pulse server: %s", pa_strerror(err) );++    StartDecodeThread();++    MixingThread.SetName( "RageSoundDriver_Pulse" );+    MixingThread.Create( MixerThread_start, this );++    return "";+}++RageSoundDriver_Pulse::~RageSoundDriver_Pulse()+{+    if( MixingThread.IsCreated() )+    {+        /* Signal the mixing thread to quit. */+        shutdown = true;+        LOG->Trace("Shutting down mixer thread ...");+        MixingThread.Wait();+        LOG->Trace("Mixer thread shut down.");+    }++    if (s != NULL)+        pa_simple_free(s);+}++float RageSoundDriver_Pulse::GetPlayLatency() const+{+    //return (1.0f / samplerate) * (buffersize_frames - chunksize_frames);+    return pa_simple_get_latency(s, NULL) / 1000000.0f;+    //return 0;+}++/*+ * (c) 2002-2004 Glenn Maynard+ * (c) 2009 Ondrej Hosek+ * All rights reserved.+ * + * Permission is hereby granted, free of charge, to any person obtaining a+ * copy of this software and associated documentation files (the+ * "Software"), to deal in the Software without restriction, including+ * without limitation the rights to use, copy, modify, merge, publish,+ * distribute, and/or sell copies of the Software, and to permit persons to+ * whom the Software is furnished to do so, provided that the above+ * copyright notice(s) and this permission notice appear in all copies of+ * the Software and that both the above copyright notice(s) and this+ * permission notice appear in supporting documentation.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS+ * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT+ * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR+ * PERFORMANCE OF THIS SOFTWARE.+ */Index: src/arch/Sound/RageSoundDriver_Pulse.h===================================================================--- src/arch/Sound/RageSoundDriver_Pulse.h    (revision 0)+++ src/arch/Sound/RageSoundDriver_Pulse.h    (revision 0)@@ -0,0 +1,65 @@+#ifndef RAGE_SOUND_PULSE+#define RAGE_SOUND_PULSE++#include "RageSoundDriver.h"+#include "RageThreads.h"+#include "RageTimer.h"++#include <pulse/simple.h>++class RageSoundDriver_Pulse: public RageSoundDriver+{+    pa_simple *s;+    pa_sample_spec spec;+    pa_buffer_attr bufattr;++    bool shutdown;+    int last_cursor_pos;+    int samplerate;++    static int MixerThread_start(void *p);+    void MixerThread();+    RageThread MixingThread;++    int err;+    +public:+    bool GetData();+    int GetSampleRate() const { return samplerate; }++    /* virtuals: */+    int64_t GetPosition() const;+    float GetPlayLatency() const;+    void SetupDecodingThread();++    RageSoundDriver_Pulse();+    RString Init();+    ~RageSoundDriver_Pulse();+};++#endif++/*+ * (c) 2002-2004 Glenn Maynard+ * (c) 2009 Ondrej Hosek+ * All rights reserved.+ * + * Permission is hereby granted, free of charge, to any person obtaining a+ * copy of this software and associated documentation files (the+ * "Software"), to deal in the Software without restriction, including+ * without limitation the rights to use, copy, modify, merge, publish,+ * distribute, and/or sell copies of the Software, and to permit persons to+ * whom the Software is furnished to do so, provided that the above+ * copyright notice(s) and this permission notice appear in all copies of+ * the Software and that both the above copyright notice(s) and this+ * permission notice appear in supporting documentation.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS+ * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT+ * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR+ * PERFORMANCE OF THIS SOFTWARE.+ */Index: src/arch/arch_default.h===================================================================--- src/arch/arch_default.h    (revision 28031)+++ src/arch/arch_default.h    (working copy)@@ -49,7 +49,7 @@ #define DEFAULT_INPUT_DRIVER_LIST "X11" #endif #define DEFAULT_MOVIE_DRIVER_LIST "Theora,FFMpeg,Null"-#define DEFAULT_SOUND_DRIVER_LIST "ALSA-sw,OSS,Null"+#define DEFAULT_SOUND_DRIVER_LIST "Pulse,ALSA-sw,OSS,Null" #else #error Which arch? #endifIndex: src/Makefile.am===================================================================--- src/Makefile.am    (revision 28031)+++ src/Makefile.am    (working copy)@@ -198,6 +198,12 @@ Sound += arch/Sound/RageSoundDriver_OSS.cpp arch/Sound/RageSoundDriver_OSS.h endif +if HAVE_PULSE+Sound += arch/Sound/RageSoundDriver_Pulse.cpp arch/Sound/RageSoundDriver_Pulse.h+AM_CXXFLAGS += $(PULSE_CFLAGS)+AM_LDFLAGS += $(PULSE_LIBS)+endif+ if HAVE_ALSA Sound += arch/Sound/ALSA9Dynamic.cpp arch/Sound/ALSA9Dynamic.h arch/Sound/ALSA9Functions.h \      arch/Sound/ALSA9Helpers.cpp arch/Sound/ALSA9Helpers.h \