CVS commit by carewolf: Better state handling. Avoids initial XRUN. M +13 -10 alsa_sink.cpp 1.12 --- kdemultimedia/akode/plugins/alsa_sink/alsa_sink.cpp #1.11:1.12 @@ -32,5 +32,5 @@ extern "C" { ALSASinkPlugin alsa_sink; } struct ALSASink::private_data { - private_data() : pcm_playback(0), open(false), error(false) {}; + private_data() : pcm_playback(0), error(false) {}; snd_pcm_t *pcm_playback; @@ -41,5 +41,4 @@ struct ALSASink::private_data int sampleSize; void* buffer; - bool open; bool error; }; @@ -78,5 +77,4 @@ void ALSASink::close() } m_data->pcm_playback = 0; - m_data->open = false; m_data->error = false; } @@ -110,4 +108,5 @@ int ALSASink::setAudioConfiguration(cons // Try 16bit then m_data->config.sample_width = 16; + res = 1; } if (m_data->config.sample_width > 24 && m_data->config.sample_width <=32) { @@ -119,4 +118,5 @@ int ALSASink::setAudioConfiguration(cons // Try 24bit then m_data->config.sample_width = 24; + res = 1; } if (m_data->config.sample_width > 16 && m_data->config.sample_width <= 24) { @@ -150,5 +150,8 @@ found_format: unsigned int rate = config->sample_rate; snd_pcm_hw_params_set_rate_near(m_data->pcm_playback, hw, &rate, 0); + if (m_data->config.sample_rate != rate) { m_data->config.sample_rate = rate; + res = 1; + } snd_pcm_hw_params_set_channels(m_data->pcm_playback, hw, config->channels); @@ -163,5 +166,5 @@ found_format: } else - return 1; + return res; } @@ -186,5 +189,4 @@ void ALSASink::_writeFrame(AudioFrame* f if (status == -EPIPE) { snd_pcm_prepare(m_data->pcm_playback); - snd_pcm_start(m_data->pcm_playback); goto xrun; } @@ -198,4 +200,8 @@ void ALSASink::_writeFrame(AudioFrame* f i++; } + + if (snd_pcm_state( m_data->pcm_playback ) == SND_PCM_STATE_PREPARED) + snd_pcm_start(m_data->pcm_playback); + } @@ -212,9 +218,6 @@ bool ALSASink::writeFrame(AudioFrame* fr } - if (!m_data->open) { + if (snd_pcm_state( m_data->pcm_playback ) == SND_PCM_STATE_SETUP) snd_pcm_prepare(m_data->pcm_playback); - snd_pcm_start(m_data->pcm_playback); - m_data->open = true; - } if (frame->sample_width<0)