diff --git a/stepmania/src/arch/Sound/RageSoundDriver_Linux.cpp b/stepmania/src/arch/Sound/RageSoundDriver_Linux.cpp deleted file mode 100644 index 795db0a61e..0000000000 --- a/stepmania/src/arch/Sound/RageSoundDriver_Linux.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/* Rage Sound Driver for Linux using ALSA - * (C) 2003 Tim Hentenaar - */ - -#include -#include -#include -#include -#include -#include - -#define ALSA_PCM_NEW_HW_PARAMS_API -#include - -#include "RageSoundDriver_Linux.h" -#include "RageTimer.h" -#include "RageLog.h" -#include "RageSound.h" -#include "RageUtil.h" -#include "RageException.h" -#include "SDL_utils.h" -#include "SDL/SDL_thread.h" -#include "global.h" - -#include -using namespace std; - -/* Get the chunk size */ -#define CHUNKSIZE(x,y) y = x / 8; - -/* Buffer size in frames */ -#define BUFSIZE_F(x,y) y = x / 2; - -/* Minimum Buffer Size (bytes) */ -#define BUFSIZE(x) x ? 1024 : 1024*16; - -void RageSound_Linux::OpenAudio() { - /* Open Device [default hardware sound device] (non-blocking) */ - snd_pcm_open(&playback_handle, "hw", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); - - /* Set up the device parameter struct */ - snd_pcm_hw_params_t *hw_params; - snd_pcm_hw_params_malloc(&hw_params); - snd_pcm_hw_params_any(playback_handle,hw_params); - - /* Non-Interleaved Access (since we hold the samples in a buffer) */ - snd_pcm_hw_params_set_access(playback_handle,hw_params,SND_PCM_ACCESS_RW_NONINTERLEAVED); - - /* Set the audio format */ - - /* 16-bit signed CPU-Endian */ - snd_pcm_hw_params_set_format(playback_handle,hw_params,SND_PCM_FORMAT_S16); - - /* 44100 Hz Rate (or closest supported match) */ - unsigned int rate = 44100; - snd_pcm_hw_params_set_rate_near(playback_handle,hw_params,&rate,0); - - /* 2 channels (stereo) */ - snd_pcm_hw_params_set_channels(playback_handle,hw_params,2); - - /* Set Sample Size (channels * 2) */ - snd_pcm_uframes_t z = 4; - snd_pcm_hw_params_set_period_size_near(playback_handle,hw_params,&z,NULL); - - /* Get hardware Buffer Size and allocate buffer - * It should be as big as the hardware buffer or 8K whichever - * is larger - */ - snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size); - BUFSIZE(buffer_size); - sbuffer = (Sint16 *)malloc(buffer_size); /* snd_pcm_sframes_t = long */ - - /* Apply the settings to the device */ - snd_pcm_hw_params(playback_handle,hw_params); - - /* free hw_params struct */ - snd_pcm_hw_params_free(hw_params); -} - -void RageSound_Linux::CloseAudio() { - /* close the PCM */ - snd_pcm_close(playback_handle); - - if (sbuffer) free(sbuffer); /* free sound buffer */ - sbuffer = NULL; -} - -void RageSound_Linux::RecoverState(long state) { - /* Revcover from suspended/overflowed state - * by re-preparing the device for use - */ - - int err = 0; - - switch((int)state) { - case -EPIPE: /* buffer under-run */ - if (snd_pcm_prepare(playback_handle) < 0) - LOG->Trace("RageSound_Linux::RecoverState(): Unable to recover from sound buffer underrun!"); - break; - case -ESTRPIPE: /* suspend */ - if (err = snd_pcm_resume(playback_handle) == -EAGAIN) sleep(1); - err = snd_pcm_resume(playback_handle); - if (err < 0) RageException::Throw("RageSound_Linux::RecoverState(): Unable To recover from suspend!"); - break; - }; - - snd_pcm_prepare(playback_handle); -} - -void RageSound_Linux::StartMixing(RageSound *snd) { - sound *s = new sound; - s->snd = snd; - - SDL_LockAudio(); - sounds.push_back(s); - SDL_UnlockAudio(); -} - -void RageSound_Linux::StopMixing(RageSound *snd) { - LockMutex L(SOUNDMAN->lock); - - int i = 0; - /* Find the sound. */ - for(i = 0; i < sounds.size(); ++i) if(sounds[i]->snd == snd) break; - - if(i == sounds.size()) { - LOG->Trace("RageSound_Linux::StopMixing(): not stopping a sound because it's not playing"); - return; - } - - delete sounds[i]; - sounds.erase(sounds.begin()+i, sounds.begin()+i+1); -} - - -bool RageSound_Linux::GetData() { - - LockMutex L(SOUNDMAN->lock); - - Sint16 *buf = NULL; - - /* Find a free chunk */ - - for (int b = 0; b<8; b++) { - if (chunks[b] != NULL) break; - if (b == 8) return false; - - int bufsiz = 0; - BUFSIZE_F(buffer_size,bufsiz); - bufsiz *= 16; - if (!buf) buf = (Sint16 *)malloc(bufsiz); - - int cs = 0; - CHUNKSIZE(buffer_size,cs); - - memset(buf,0,sizeof(buf)); - memset(chunks[b],0,sizeof(chunks[b])); - - SoundMixBuffer mix; - - for (int i = 0; istopping) continue; - /* Call the Callback */ - char *d = (char *)malloc(sizeof(buf)); - memcpy(d,buf,sizeof(buf)); - int got = sounds[i]->snd->GetPCM((char *)d,(int)cs,(int)last_pos); - memmove(buf,d,sizeof(buf)); - free(d); - - mix.write(buf,got/2); - - if (got < cs) { - /* sound is finishing */ - sounds[i]->stopping = true; - sounds[i]->flush_pos = last_pos + (got / 16); - } - - } - - mix.read(chunks[b]); /* Get the sound */ - - snd_pcm_prepare(playback_handle); /* Prepare for write */ - - /* Non-Interleaved Write */ - long ret = snd_pcm_writen(playback_handle,(void **)&chunks[b],sizeof(chunks[b])); - RecoverState(ret); /* Check for an error and recover */ - last_pos += cs; - } - - if (buf) free(buf); - return true; -} - -void RageSound_Linux::Update(float delta) { - LockMutex L(SOUNDMAN->lock); - - /* SoundStopped might erase sounds out from under us, so make a copy - * of the sound list. */ - vector snds = sounds; - for(unsigned i = 0; i < snds.size(); ++i) - { - if(!sounds[i]->stopping) continue; - - if(GetPosition(snds[i]->snd) < sounds[i]->flush_pos) continue; /* stopping but still flushing */ - - /* This sound is done. */ - snds[i]->snd->StopPlaying(); - } - -} - -int RageSound_Linux::GetPosition(const RageSound *snd) const { - LockMutex L(SOUNDMAN->lock); - - /* Get a timestamp from the stream's status */ - int err; - snd_pcm_status_t *status; - snd_timestamp_t *x; - - snd_pcm_status_alloca(&status); - if ((err = snd_pcm_status(playback_handle, status)) < 0) { - char errstr[100]; - memset(errstr,0,100); - sprintf(errstr,"RageSound_Linux::GetPosition(): Stream status error: %s\n", snd_strerror(err)); - RageException::Throw(errstr); - return 0; - } - snd_pcm_status_get_trigger_tstamp(status, x); - - /* Convert it to samples - * To be exact, we should get the rate from the - * hardware, but this should do. (The rate will - * be 44100 Hz anyway :P) - */ - - return (x->tv_usec / 1000) * 44100; -} - -float RageSound_Linux::GetPlayLatency() const { - int bufsize_frames = 1; - BUFSIZE_F(buffer_size,bufsize_frames); - return (float)((1.0f / 44100) * ( bufsize_frames - (bufsize_frames / 8))); -} - -RageSound_Linux::RageSound_Linux() { - last_pos = 0; - shutdown = false; - MixerThreadPtr = SDL_CreateThread(MixerThread_start,this); -} - -RageSound_Linux::~RageSound_Linux() { - LOG->Trace("RageSoundDriver_Linux::~RageSoundDriver_Linux(): Shutting down mixer thread ..."); - shutdown = true; - SDL_WaitThread(MixerThreadPtr, NULL); - LOG->Trace("Mixer thread shut down."); - CloseAudio(); -} - -int RageSound_Linux::MixerThread_start(void *p) { - ((RageSound_Linux *) p)->MixerThread(); - return 0; -} - - -void RageSound_Linux::MixerThread() { - /* SOUNDMAN will be set once RageSoundManager's ctor returns and - * assigns it; we might get here before that happens, though. */ - while(!SOUNDMAN && !shutdown) SDL_Delay(10); - while(!shutdown) { while (GetData()); } -} - - - - - - - diff --git a/stepmania/src/arch/Sound/RageSoundDriver_Linux.h b/stepmania/src/arch/Sound/RageSoundDriver_Linux.h deleted file mode 100644 index c64ea1a11d..0000000000 --- a/stepmania/src/arch/Sound/RageSoundDriver_Linux.h +++ /dev/null @@ -1,58 +0,0 @@ -/* (C) 2003 Tim Hentenaar */ - -#ifndef RAGE_SOUND_LINUX -#define RAGE_SOUND_LINUX - -#include -using namespace std; - -#include "RageSoundDriver.h" -#include "SDL_thread.h" -#include "global.h" -#include - - -/* A lot of this is from Glenn's RageSoundDriver_WaveOut */ - -struct sound { - RageSound *snd; - bool stopping; - int flush_pos; /* state == STOPPING only */ - sound() { snd = NULL; stopping = false; } -}; - -typedef struct sound sound_t; - -class RageSound_Linux : public RageSoundDriver { - public: - - - /* Currently Playing Sounds */ - vector sounds; - SDL_Thread *MixerThreadPtr; - snd_pcm_uframes_t buffer_size; - Sint16 *sbuffer; /* Sound Buffer */ - Sint16 *chunks[8]; /* chunks of sound buffer */ - snd_pcm_t *playback_handle; /* Handle for PCM device */ - int last_pos; - bool shutdown; - - void RecoverState(long state); /* Recover from various states */ - - void MixerThread(); - static int MixerThread_start(void *p); - bool GetData(); - void OpenAudio(); - void CloseAudio(); - void StartMixing(RageSound *snd); - void StopMixing(RageSound *snd); - int GetPosition(const RageSound *snd) const; - float GetPlayLatency() const; - - void Update(float delta); - RageSound_Linux(); - ~RageSound_Linux(); -}; - -#endif -