From a27620a32dae031436bf3b9a3efa67426c43f572 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Sat, 3 Jan 2004 02:35:47 +0000 Subject: [PATCH] Handle hardware that only supports 48khz output (eg. Intel8x0, on nForce boards). Allow drivers to tell whether specific sample rates are supported (instead of "all or nothing"). Warning: this will break the Windows (and possibly OS X) drivers for a few minutes until I update them. --- stepmania/src/arch/Sound/ALSA9Helpers.cpp | 29 +++++++++++++------ stepmania/src/arch/Sound/ALSA9Helpers.h | 9 +++--- stepmania/src/arch/Sound/RageSoundDriver.h | 2 +- .../src/arch/Sound/RageSoundDriver_ALSA9.cpp | 10 ++++++- .../src/arch/Sound/RageSoundDriver_ALSA9.h | 2 +- .../Sound/RageSoundDriver_ALSA9_Software.cpp | 12 ++++++-- .../Sound/RageSoundDriver_ALSA9_Software.h | 3 +- .../src/arch/Sound/RageSoundDriver_OSS.h | 2 +- 8 files changed, 48 insertions(+), 21 deletions(-) diff --git a/stepmania/src/arch/Sound/ALSA9Helpers.cpp b/stepmania/src/arch/Sound/ALSA9Helpers.cpp index a0aa987e06..6f5be02eb8 100644 --- a/stepmania/src/arch/Sound/ALSA9Helpers.cpp +++ b/stepmania/src/arch/Sound/ALSA9Helpers.cpp @@ -11,6 +11,21 @@ #define ALSA_ASSERT(x) \ if (err < 0) { LOG->Warn("ALSA9: %s: %s", x, dsnd_strerror(err)); } +/* If the given sample rate can be used, return it. Otherwise, return the + * samplerate to use instead. */ +unsigned Alsa9Buf::FindSampleRate( unsigned rate ) +{ + snd_pcm_hw_params_t *testhw; + dsnd_pcm_hw_params_alloca( &testhw ); + dsnd_pcm_hw_params_any( pcm, testhw ); + + int err = dsnd_pcm_hw_params_set_rate_near(pcm, testhw, &rate, 0); + if( err >= 0 ) + return rate; + + return 0; +} + bool Alsa9Buf::SetHWParams() { int err; @@ -45,11 +60,7 @@ bool Alsa9Buf::SetHWParams() err = dsnd_pcm_hw_params_set_channels(pcm, hwparams, 2); ALSA_CHECK("dsnd_pcm_hw_params_set_channels"); - /* Set the sample rate. We shouldn't need to set it if rate is DYNAMIC_SAMPLERATE, - * but I've had alsalib crashes if I don't. */ - if( samplerate == Alsa9Buf::DYNAMIC_SAMPLERATE ) - samplerate = 44100; - + /* Set the sample rate. */ unsigned int rate = samplerate; err = dsnd_pcm_hw_params_set_rate_near(pcm, hwparams, &rate, 0); ALSA_CHECK("dsnd_pcm_hw_params_set_rate_near"); @@ -139,21 +150,21 @@ void Alsa9Buf::ErrorHandler(const char *file, int line, const char *function, in /* NOP */ } -Alsa9Buf::Alsa9Buf( hw hardware, int channels_, int samplerate_ ) +Alsa9Buf::Alsa9Buf( hw hardware, int channels_ ) { GetSoundCardDebugInfo(); dsnd_lib_error_set_handler( ErrorHandler ); channels = channels_; - samplerate = samplerate_; + samplerate = 44100; samplebits = 16; last_cursor_pos = 0; /* Open the device. */ int err; // err = dsnd_pcm_open( &pcm, "dmix", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ); - err = dsnd_pcm_open( &pcm, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ); + err = dsnd_pcm_open( &pcm, "hw:0", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ); if (err < 0) RageException::ThrowNonfatal("dsnd_pcm_open: %s", dsnd_strerror(err)); @@ -251,7 +262,7 @@ void Alsa9Buf::Write( const Sint16 *buffer, int frames ) last_cursor_pos += wrote; if( wrote < frames ) - LOG->Trace("Couldn't write whole buffer? (%i < %i)\n", wrote, frames ); + LOG->Trace("Couldn't write whole buffer? (%i < %i)", wrote, frames ); } diff --git a/stepmania/src/arch/Sound/ALSA9Helpers.h b/stepmania/src/arch/Sound/ALSA9Helpers.h index ed18e61b0a..0dcfa78d8e 100644 --- a/stepmania/src/arch/Sound/ALSA9Helpers.h +++ b/stepmania/src/arch/Sound/ALSA9Helpers.h @@ -28,15 +28,14 @@ public: enum hw { HW_HARDWARE, HW_SOFTWARE, HW_DONT_CARE }; - /* If samplerate is DYNAMIC_SAMPLERATE, then call SetSampleRate before - * you use the sample. */ - enum { DYNAMIC_SAMPLERATE = -1 }; - Alsa9Buf( hw hardware, int channels, int samplerate ); + /* Call SetSampleRate before you use the sample. */ + Alsa9Buf( hw hardware, int channels ); ~Alsa9Buf(); int GetNumFramesToFill( int writeahead ); void Write( const Sint16 *buffer, int frames ); - + unsigned FindSampleRate( unsigned rate ); + void Reset(); void Play(); void Stop(); diff --git a/stepmania/src/arch/Sound/RageSoundDriver.h b/stepmania/src/arch/Sound/RageSoundDriver.h index db25a0c7dc..0bf010dfe3 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver.h +++ b/stepmania/src/arch/Sound/RageSoundDriver.h @@ -37,7 +37,7 @@ protected: * get it. */ virtual void VolumeChanged() { } - virtual int GetSampleRate() const { return 44100; } + virtual int GetSampleRate( int rate ) const { return 44100; } public: virtual ~RageSoundDriver() { } diff --git a/stepmania/src/arch/Sound/RageSoundDriver_ALSA9.cpp b/stepmania/src/arch/Sound/RageSoundDriver_ALSA9.cpp index c73764e6ac..e3706c6756 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_ALSA9.cpp +++ b/stepmania/src/arch/Sound/RageSoundDriver_ALSA9.cpp @@ -208,6 +208,14 @@ int RageSound_ALSA9::GetPosition(const RageSound *snd) const return stream_pool[i]->pcm->GetPosition(); } +int RageSound_ALSA9::GetSampleRate( int rate ) const +{ + LockMutex L(SOUNDMAN->lock); + + stream *str = stream_pool[0]; + return str->pcm->FindSampleRate( rate ); +} + RageSound_ALSA9::RageSound_ALSA9() { @@ -222,7 +230,7 @@ try { { Alsa9Buf *newbuf; try { - newbuf = new Alsa9Buf( Alsa9Buf::HW_HARDWARE, channels, Alsa9Buf::DYNAMIC_SAMPLERATE ); + newbuf = new Alsa9Buf( Alsa9Buf::HW_HARDWARE, channels ); } catch(const RageException &e) { /* If we didn't get at least 8, fail. */ if(i >= 8) break; /* OK */ diff --git a/stepmania/src/arch/Sound/RageSoundDriver_ALSA9.h b/stepmania/src/arch/Sound/RageSoundDriver_ALSA9.h index 7d214afdd6..17b9cf9ccf 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_ALSA9.h +++ b/stepmania/src/arch/Sound/RageSoundDriver_ALSA9.h @@ -51,7 +51,7 @@ public: void StartMixing(RageSound *snd); void StopMixing(RageSound *snd); int GetPosition(const RageSound *snd) const; - int GetSampleRate() const { return -1; } + int GetSampleRate( int rate ) const; void Update(float delta); diff --git a/stepmania/src/arch/Sound/RageSoundDriver_ALSA9_Software.cpp b/stepmania/src/arch/Sound/RageSoundDriver_ALSA9_Software.cpp index 7571eb65cf..d700976fc7 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_ALSA9_Software.cpp +++ b/stepmania/src/arch/Sound/RageSoundDriver_ALSA9_Software.cpp @@ -15,7 +15,7 @@ #include const int channels = 2; -const int samplerate = 44100; +int samplerate = 44100; const int samples_per_frame = channels; const int bytes_per_frame = sizeof(Sint16) * samples_per_frame; @@ -176,7 +176,10 @@ try { if( PREFSMAN->m_iSoundWriteAhead ) max_writeahead = PREFSMAN->m_iSoundWriteAhead; - pcm = new Alsa9Buf( Alsa9Buf::HW_DONT_CARE, channels, samplerate ); + pcm = new Alsa9Buf( Alsa9Buf::HW_DONT_CARE, channels ); + + samplerate = pcm->FindSampleRate( samplerate ); + pcm->SetSampleRate( samplerate ); MixingThread.SetName( "RageSound_ALSA9_Software" ); MixingThread.Create( MixerThread_start, this ); @@ -205,6 +208,11 @@ float RageSound_ALSA9_Software::GetPlayLatency() const return float(max_writeahead)/samplerate; } +int RageSound_ALSA9_Software::GetSampleRate( int rate ) const +{ + return samplerate; +} + /* * Copyright (c) 2002 by the person(s) listed below. All rights reserved. * diff --git a/stepmania/src/arch/Sound/RageSoundDriver_ALSA9_Software.h b/stepmania/src/arch/Sound/RageSoundDriver_ALSA9_Software.h index ed5934d23a..332477e1c2 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_ALSA9_Software.h +++ b/stepmania/src/arch/Sound/RageSoundDriver_ALSA9_Software.h @@ -37,7 +37,8 @@ public: void StopMixing(RageSound *snd); int GetPosition(const RageSound *snd) const; float GetPlayLatency() const; - + int GetSampleRate( int rate ) const; + void Update(float delta); RageSound_ALSA9_Software(); diff --git a/stepmania/src/arch/Sound/RageSoundDriver_OSS.h b/stepmania/src/arch/Sound/RageSoundDriver_OSS.h index 7f9a66e734..54950d5ef2 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_OSS.h +++ b/stepmania/src/arch/Sound/RageSoundDriver_OSS.h @@ -32,7 +32,7 @@ class RageSound_OSS: public RageSoundDriver public: bool GetData(); void Update(float delta); - int GetSampleRate() const { return samplerate; } + int GetSampleRate( int rate ) const { return samplerate; } /* virtuals: */ void StartMixing(RageSound *snd); /* used by RageSound */