simplify stream configuration

This commit is contained in:
Glenn Maynard
2006-12-16 22:45:44 +00:00
parent 3f3e6cd480
commit 59b35c19bb
3 changed files with 30 additions and 92 deletions
+19 -74
View File
@@ -11,24 +11,6 @@
#define ALSA_ASSERT(x) \
if (err < 0) { LOG->Warn("ALSA: %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 )
{
if( rate == 0 )
rate = 44100;
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;
@@ -64,13 +46,9 @@ bool Alsa9Buf::SetHWParams()
ALSA_CHECK("dsnd_pcm_hw_params_set_channels");
/* Set the sample rate. */
unsigned int rate = samplerate;
err = dsnd_pcm_hw_params_set_rate_near(pcm, hwparams, &rate, 0);
err = dsnd_pcm_hw_params_set_rate_near(pcm, hwparams, &samplerate, 0);
ALSA_CHECK("dsnd_pcm_hw_params_set_rate_near");
if( samplerate_set_explicitly && (int) rate != samplerate )
LOG->Warn("Alsa9Buf::SetHWParams: Couldn't get %ihz (got %ihz instead)", samplerate, rate);
/* Set the buffersize to the writeahead, and then copy back the actual value
* we got. */
writeahead = preferred_writeahead;
@@ -92,14 +70,6 @@ bool Alsa9Buf::SetHWParams()
return true;
}
void Alsa9Buf::LogParams()
{
if( preferred_writeahead != writeahead )
LOG->Info( "ALSA: writeahead adjusted from %u to %u", (unsigned) preferred_writeahead, (unsigned) writeahead );
if( preferred_chunksize != chunksize )
LOG->Info( "ALSA: chunksize adjusted from %u to %u", (unsigned) preferred_chunksize, (unsigned) chunksize );
}
bool Alsa9Buf::SetSWParams()
{
snd_pcm_sw_params_t *swparams;
@@ -240,16 +210,24 @@ Alsa9Buf::Alsa9Buf()
samplerate = 44100;
samplebits = 16;
last_cursor_pos = 0;
samplerate_set_explicitly = false;
preferred_writeahead = 8192;
preferred_chunksize = 1024;
pcm = NULL;
}
RString Alsa9Buf::Init( int channels_ )
RString Alsa9Buf::Init( int channels_,
int iWriteahead,
int iChunkSize,
int iSampleRate )
{
channels = channels_;
preferred_writeahead = iWriteahead;
preferred_chunksize = iChunkSize;
if( iSampleRate == 0 )
samplerate = 44100;
else
samplerate = iSampleRate;
GetSoundCardDebugInfo();
InitializeErrorHandler();
@@ -268,6 +246,13 @@ RString Alsa9Buf::Init( int channels_ )
SetSWParams();
LOG->Info( "ALSA: Mixing at %ihz", samplerate );
if( preferred_writeahead != writeahead )
LOG->Info( "ALSA: writeahead adjusted from %u to %u", (unsigned) preferred_writeahead, (unsigned) writeahead );
if( preferred_chunksize != chunksize )
LOG->Info( "ALSA: chunksize adjusted from %u to %u", (unsigned) preferred_chunksize, (unsigned) chunksize );
return "";
}
@@ -419,32 +404,6 @@ void Alsa9Buf::Stop()
last_cursor_pos = 0;
}
void Alsa9Buf::SetSampleRate(int hz)
{
samplerate = hz;
samplerate_set_explicitly = true;
if( !SetHWParams() )
{
/*
* If this fails, we're no longer set up; if we call SW param calls,
* ALSA will assert out on us (instead of gracefully returning an error).
*
* If we fail here, it means we set up the initial stream, but can't
* configure it to the sample rate we want. This happened on a CS46xx
* with an old ALSA version, at least: snd_pcm_hw_params failed
* with ENOMEM. It set up only 10 44.1khz streams; it may have been
* trying to increase one to 48khz and, for some reason, that needed
* more card memory. (I've tried to work around that by setting up
* streams as 48khz to begin with, so we set it up as the maximum
* to begin with.)
*/
FAIL_M( ssprintf("SetHWParams(%i) failed", hz) );
}
SetSWParams();
}
RString Alsa9Buf::GetHardwareID( RString name )
{
InitializeErrorHandler();
@@ -470,20 +429,6 @@ RString Alsa9Buf::GetHardwareID( RString name )
return ret;
}
void Alsa9Buf::SetWriteahead( snd_pcm_sframes_t frames )
{
preferred_writeahead = frames;
SetHWParams();
SetSWParams();
}
void Alsa9Buf::SetChunksize( snd_pcm_sframes_t frames )
{
preferred_chunksize = frames;
SetHWParams();
SetSWParams();
}
/*
* (c) 2002-2004 Glenn Maynard, Aaron VonderHaar
+6 -10
View File
@@ -8,10 +8,10 @@
class Alsa9Buf
{
private:
int channels, samplerate, samplebits;
int channels, samplebits;
unsigned samplerate;
int buffersize;
int64_t last_cursor_pos;
bool samplerate_set_explicitly;
snd_pcm_uframes_t preferred_writeahead, preferred_chunksize;
snd_pcm_uframes_t writeahead, chunksize;
@@ -29,26 +29,22 @@ public:
static void GetSoundCardDebugInfo();
static RString GetHardwareID( RString name="" );
/* Call SetSampleRate before you use the sample. */
Alsa9Buf();
RString Init( int channels );
RString Init( int channels,
int iWriteahead,
int iChunkSize,
int iSampleRate );
~Alsa9Buf();
int GetNumFramesToFill();
bool WaitUntilFramesCanBeFilled( int timeout_ms );
void Write( const int16_t *buffer, int frames );
unsigned FindSampleRate( unsigned rate );
void Play();
void Stop();
void SetVolume(float vol);
void SetSampleRate(int hz);
int GetSampleRate() const { return samplerate; }
void SetWriteahead( snd_pcm_sframes_t frames );
void SetChunksize( snd_pcm_sframes_t frames );
void LogParams();
int64_t GetPosition() const;
int64_t GetPlayPos() const { return last_cursor_pos; }
};
@@ -102,17 +102,14 @@ RString RageSoundDriver_ALSA9_Software::Init()
g_iMaxWriteahead = PREFSMAN->m_iSoundWriteAhead;
m_pPCM = new Alsa9Buf();
sError = m_pPCM->Init( channels );
sError = m_pPCM->Init( channels,
g_iMaxWriteahead,
g_iMaxWriteahead / num_chunks,
PREFSMAN->m_iSoundPreferredSampleRate );
if( sError != "" )
return sError;
m_iSampleRate = m_pPCM->FindSampleRate( PREFSMAN->m_iSoundPreferredSampleRate );
m_pPCM->SetSampleRate( m_iSampleRate );
LOG->Info( "ALSA: Software mixing at %ihz", m_iSampleRate );
m_pPCM->SetWriteahead( g_iMaxWriteahead );
m_pPCM->SetChunksize( g_iMaxWriteahead / num_chunks );
m_pPCM->LogParams();
m_iSampleRate = m_pPCM->GetSampleRate();
StartDecodeThread();