Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
Index: src/Makefile.am =================================================================== --- src/Makefile.am (revision 28129) +++ 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 \ Index: src/arch/arch_default.h =================================================================== --- src/arch/arch_default.h (revision 28129) +++ 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? #endif Index: 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,66 @@ +#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: configure.ac =================================================================== --- configure.ac (revision 28129) +++ configure.ac (working copy) @@ -208,6 +208,14 @@ AC_CHECK_HEADER(stdint.h, , [AC_DEFINE(MISSING_STDINT_H, 1, [stdint.h is missing])]) AC_CHECK_HEADERS([inttypes.h endian.h machine/endian.h alloca.h]) +have_pulse=no +AC_CHECK_LIB(pulse, pa_stream_new, have_pulse=yes) +if test x$have_pulse = xyes; then + AC_DEFINE(HAVE_PULSE, 1, [pulseaudio support available]) + AC_SUBST(PULSE_LIBS) + AC_SUBST(PULSE_CFLAGS) +fi + AC_MSG_CHECKING(if cstdlib breaks llabs) AC_LANG_PUSH(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h> @@ -227,6 +234,7 @@ AM_CONDITIONAL(HAVE_ALSA, test x$alsa != xfalse ) AM_CONDITIONAL(HAVE_GTK, test "$enable_gtk2" != "no" ) AM_CONDITIONAL(HAVE_OSS, test x$ac_cv_header_sys_soundcard_h = xyes ) +AM_CONDITIONAL(HAVE_PULSE, test x$have_pulse = xyes) AM_CONDITIONAL(USE_CRASH_HANDLER, test "$use_crash_handler" = "yes" ) if test x$force_oss = xyes && test x$ac_cv_header_sys_soundcard_h = xyes; then
This paste will be private.
From the Design Piracy series on my blog: