bool Alsa9Buf::SetHWParams() { int err; if( dsnd_pcm_state(pcm) == SND_PCM_STATE_PREPARED ) dsnd_pcm_drop( pcm ); if( dsnd_pcm_state(pcm) != SND_PCM_STATE_OPEN ) { /* Reset the stream to SND_PCM_STATE_OPEN. */ err = dsnd_pcm_hw_free( pcm ); ALSA_ASSERT("dsnd_pcm_hw_free"); } // ASSERT_M( dsnd_pcm_state(pcm) == SND_PCM_STATE_OPEN, ssprintf("(%s)", dsnd_pcm_state_name(dsnd_pcm_state(pcm))) ); /* allocate the hardware parameters structure */ snd_pcm_hw_params_t *hwparams; dsnd_pcm_hw_params_alloca( &hwparams ); err = dsnd_pcm_hw_params_any(pcm, hwparams); ALSA_CHECK("dsnd_pcm_hw_params_any"); /* Set to interleaved mmap mode. */ err = dsnd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED); ALSA_CHECK("dsnd_pcm_hw_params_set_access"); /* Set the PCM format: signed 16bit, native endian. */ err = dsnd_pcm_hw_params_set_format(pcm, hwparams, SND_PCM_FORMAT_S16); ALSA_CHECK("dsnd_pcm_hw_params_set_format"); /* Set the number of channels. */ err = dsnd_pcm_hw_params_set_channels(pcm, hwparams, 2); ALSA_CHECK("dsnd_pcm_hw_params_set_channels"); /* Set the sample rate. */ err = dsnd_pcm_hw_params_set_rate_near(pcm, hwparams, &samplerate, 0); ALSA_CHECK("dsnd_pcm_hw_params_set_rate_near"); /* Set the buffersize to the writeahead, and then copy back the actual value * we got. */ writeahead = preferred_writeahead; err = dsnd_pcm_hw_params_set_buffer_size_near( pcm, hwparams, &writeahead ); ALSA_CHECK("dsnd_pcm_hw_params_set_buffer_size_near"); /* The period size is roughly equivalent to what we call the chunksize. */ int dir = 0; chunksize = preferred_chunksize; err = dsnd_pcm_hw_params_set_period_size_near( pcm, hwparams, &chunksize, &dir ); ALSA_CHECK("dsnd_pcm_hw_params_set_period_size_near"); // LOG->Info("asked for %i period, got %i", chunksize, period_size); /* write the hardware parameters to the device */ err = dsnd_pcm_hw_params( pcm, hwparams ); ALSA_CHECK("dsnd_pcm_hw_params"); return true; }
/* 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; }