diff --git a/NEWS b/NEWS index b372b697..91d9573c 100644 --- a/NEWS +++ b/NEWS @@ -84,6 +84,8 @@ -- Fixed out_play() abortion logic to better detect fatal situations (broken pipe). Needed on FreeBSD, while Linux buffers the issue away. Should resolve bug 283. +-- Limit size of buffer block being written in out123_play to 16K, avoiding + unnecessary failure with ALSA at least. -- Using SDL2 now if found. Output module code unchanged. -- Added hex and txt (plain text) printout. -- Eliminated a spots where error messages would still be printed diff --git a/src/libout123/libout123.c b/src/libout123/libout123.c index 99a34256..25b284a5 100644 --- a/src/libout123/libout123.c +++ b/src/libout123/libout123.c @@ -691,13 +691,19 @@ out123_play(out123_handle *ao, void *bytes, size_t count) else #endif { + // Write 16K in a piece as maximum, as I've seen random short + // writes of big blocks with ALSA. + int maxcount = 1<<14; + maxcount -= maxcount % ao->framesize; + if(maxcount < 1) + maxcount = ao->framesize; if(ao->flags & OUT123_MUTE) mute_block( bytes, count, ao->zerosample , MPG123_SAMPLESIZE(ao->format) ); do /* Playback in a loop to be able to continue after interruptions. */ { errno = 0; - int block = count > INT_MAX ? INT_MAX : count; + int block = count > maxcount ? maxcount : count; written = ao->write(ao, bytes, block); debug4( "written: %d errno: %i (%s), keep_on=%d" , written, errno, strerror(errno) @@ -707,7 +713,8 @@ out123_play(out123_handle *ao, void *bytes, size_t count) { ao->errcode = OUT123_DEV_PLAY; if(!AOQUIET) - error1("Error in writing audio (%s?)!", strerror(errno)); + merror( "Error in writing audio, wrote only %d of %d (%s?)!" + , written, block, strerror(errno) ); /* This is a serious issue ending this playback round. */ break; }