release v0.18.9
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJTEwdzAAoJECNuiljG20USkFYP/i1PaM7O20e2EPE7ELhffk1I PEL6WiuCxfEHP+JbH/RPy/CdyKIqx3TTeaktXzOJmCcU+5fAgbpIwfK689ZjpE7Y U+7aPfGudfjYTxM/bigEo+1XAIYWJCJ2IlopN0lRIZSquUm8rfxosqsNzJFrhwsK 40Ps36XdpYUA3z9dugyJjeKQETkjJa5Y55C1yml5RRUz+yPqyiPelm0dSlx3Ggce KpmNZfp8g8/stwb08iw+qk+cNKP75eJwPdFmQrsc91QxP1oW7ERWhiICA0ZtqaNe T0Ld5+wZ6uTJSztQiUsWrJYS1yKix5q1Za8tyFr3a9NPI+iIjsALXqU9k7zmZ6Id GK0Xr9Noo1o80QeGkd60nJyCQXbEU/V0p9D/QiDVei+IvK6mbxF3y2gPA7wobgrC KEDgsJZ+0fjmgdx+eb8ydg0uIwHrk04u0YKukUqA3bkNS/PUEICPqblcg8Spf89I RMdjq2HFcpkaIwGvryfHIbTNUbonAziMzmiJ0WQA1FCD3x1WELvBf09GzAsUEoFX Be0Co15rODOByo5ryZvSJv5BCr2RuCPwzNF+V26nMaKK7EloQWmbO0rpkRLVRk81 qo1JmElm6SyeE3kHqVW/NyrPxLtd7VngV+z9hXr95szUjCjMv/MK169r4jumLTex RLyPDkhkQLDIijamhjfZ =nX0n -----END PGP SIGNATURE----- Merge tag 'release-0.18.9'
This commit is contained in:
commit
503ed9c331
7
NEWS
7
NEWS
@ -39,13 +39,18 @@ ver 0.19 (not yet released)
|
||||
* install systemd unit for socket activation
|
||||
* Android port
|
||||
|
||||
ver 0.18.9 (not yet released)
|
||||
ver 0.18.9 (2014/03/02)
|
||||
* protocol
|
||||
- "findadd" requires the "add" permission
|
||||
* output
|
||||
- alsa: improved workaround for noise after manual song change
|
||||
* decoder
|
||||
- vorbis: fix linker failure when libvorbis/libogg are static
|
||||
* encoder
|
||||
- vorbis: fix another linker failure
|
||||
* output
|
||||
- pipe: fix hanging child process due to blocked signals
|
||||
* fix build failure due to missing signal.h include
|
||||
|
||||
ver 0.18.8 (2014/02/07)
|
||||
* decoder
|
||||
|
@ -99,7 +99,7 @@ static const struct command commands[] = {
|
||||
{ "enableoutput", PERMISSION_ADMIN, 1, 1, handle_enableoutput },
|
||||
#ifdef ENABLE_DATABASE
|
||||
{ "find", PERMISSION_READ, 2, -1, handle_find },
|
||||
{ "findadd", PERMISSION_READ, 2, -1, handle_findadd},
|
||||
{ "findadd", PERMISSION_ADD, 2, -1, handle_findadd},
|
||||
#endif
|
||||
{ "idle", PERMISSION_READ, 0, -1, handle_idle },
|
||||
{ "kill", PERMISSION_ADMIN, -1, -1, handle_kill },
|
||||
|
@ -105,12 +105,16 @@ struct AlsaOutput {
|
||||
snd_pcm_uframes_t period_position;
|
||||
|
||||
/**
|
||||
* Set to non-zero when the Raspberry Pi workaround has been
|
||||
* activated in alsa_recover(); decremented by each write.
|
||||
* This will avoid activating it again, leading to an endless
|
||||
* loop. This problem was observed with a "RME Digi9636/52".
|
||||
* Do we need to call snd_pcm_prepare() before the next write?
|
||||
* It means that we put the device to SND_PCM_STATE_SETUP by
|
||||
* calling snd_pcm_drop().
|
||||
*
|
||||
* Without this flag, we could easily recover after a failed
|
||||
* optimistic write (returning -EBADFD), but the Raspberry Pi
|
||||
* audio driver is infamous for generating ugly artefacts from
|
||||
* this.
|
||||
*/
|
||||
unsigned pi_workaround;
|
||||
bool must_prepare;
|
||||
|
||||
/**
|
||||
* This buffer gets allocated after opening the ALSA device.
|
||||
@ -671,8 +675,6 @@ alsa_open(AudioOutput *ao, AudioFormat &audio_format, Error &error)
|
||||
{
|
||||
AlsaOutput *ad = (AlsaOutput *)ao;
|
||||
|
||||
ad->pi_workaround = 0;
|
||||
|
||||
int err = snd_pcm_open(&ad->pcm, alsa_device(ad),
|
||||
SND_PCM_STREAM_PLAYBACK, ad->mode);
|
||||
if (err < 0) {
|
||||
@ -694,6 +696,8 @@ alsa_open(AudioOutput *ao, AudioFormat &audio_format, Error &error)
|
||||
ad->in_frame_size = audio_format.GetFrameSize();
|
||||
ad->out_frame_size = ad->pcm_export->GetFrameSize(audio_format);
|
||||
|
||||
ad->must_prepare = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -731,29 +735,6 @@ alsa_recover(AlsaOutput *ad, int err)
|
||||
case SND_PCM_STATE_XRUN:
|
||||
ad->period_position = 0;
|
||||
err = snd_pcm_prepare(ad->pcm);
|
||||
|
||||
if (err == 0 && ad->pi_workaround == 0) {
|
||||
/* this works around a driver bug observed on
|
||||
the Raspberry Pi: after snd_pcm_drop(), the
|
||||
whole ring buffer must be invalidated, but
|
||||
the snd_pcm_prepare() call above makes the
|
||||
driver play random data that just happens
|
||||
to be still in the buffer; by adding and
|
||||
cancelling some silence, this bug does not
|
||||
occur */
|
||||
alsa_write_silence(ad, ad->period_frames);
|
||||
|
||||
/* cancel the silence data right away to avoid
|
||||
increasing latency; even though this
|
||||
function call invalidates the portion of
|
||||
silence, the driver seems to avoid the
|
||||
bug */
|
||||
snd_pcm_reset(ad->pcm);
|
||||
|
||||
/* disable the workaround for some time */
|
||||
ad->pi_workaround = 8;
|
||||
}
|
||||
|
||||
break;
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
break;
|
||||
@ -796,6 +777,7 @@ alsa_cancel(AudioOutput *ao)
|
||||
AlsaOutput *ad = (AlsaOutput *)ao;
|
||||
|
||||
ad->period_position = 0;
|
||||
ad->must_prepare = true;
|
||||
|
||||
snd_pcm_drop(ad->pcm);
|
||||
}
|
||||
@ -817,6 +799,16 @@ alsa_play(AudioOutput *ao, const void *chunk, size_t size,
|
||||
|
||||
assert(size % ad->in_frame_size == 0);
|
||||
|
||||
if (ad->must_prepare) {
|
||||
ad->must_prepare = false;
|
||||
|
||||
int err = snd_pcm_prepare(ad->pcm);
|
||||
if (err < 0) {
|
||||
error.Set(alsa_output_domain, err, snd_strerror(-err));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
chunk = ad->pcm_export->Export(chunk, size, size);
|
||||
|
||||
assert(size % ad->out_frame_size == 0);
|
||||
@ -829,9 +821,6 @@ alsa_play(AudioOutput *ao, const void *chunk, size_t size,
|
||||
ad->period_position = (ad->period_position + ret)
|
||||
% ad->period_frames;
|
||||
|
||||
if (ad->pi_workaround > 0)
|
||||
--ad->pi_workaround;
|
||||
|
||||
size_t bytes_written = ret * ad->out_frame_size;
|
||||
return ad->pcm_export->CalcSourceSize(bytes_written);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user