@@ -309,8 +309,20 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
309309
310310 if ( !stream -> isActive && stream -> pulseaudioIsActive && stream -> outputStream )
311311 {
312- bufferData = pulseaudioSampleBuffer ;
313- memset ( bufferData , 0x00 , length );
312+ size_t tmpSize = length ;
313+
314+ /* Allocate memory to make it faster to output stuff */
315+ pa_stream_begin_write ( stream -> outputStream , & bufferData , & tmpSize );
316+
317+ /* If bufferData is NULL then output is not ready
318+ * and we have to wait for it
319+ */
320+ if (!bufferData )
321+ {
322+ return paNotInitialized ;
323+ }
324+
325+ memset ( bufferData , 0x00 , tmpSize );
314326
315327 pa_stream_write ( stream -> outputStream ,
316328 bufferData ,
@@ -323,8 +335,16 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
323335 }
324336
325337
326- while ( 1 )
338+ do
327339 {
340+ /* Make sure that bufferData is NULL that marks there
341+ * is nothing to output
342+ */
343+ if ( isOutputCb )
344+ {
345+ bufferData = NULL ;
346+ }
347+
328348 /*
329349 * If everything fail like stream vanish or mainloop
330350 * is in error state try to handle error
@@ -396,6 +416,9 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
396416 hostFramesPerBuffer );
397417 }
398418
419+ /* Is output is enable and buffer data is not NULL
420+ * then crap pointer to output ringbuffer
421+ */
399422 if ( isOutputCb )
400423 {
401424
@@ -404,14 +427,6 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
404427 /* Allocate memory to make it faster to output stuff */
405428 pa_stream_begin_write ( stream -> outputStream , & bufferData , & tmpSize );
406429
407- /* If bufferData is NULL then output is not ready
408- * and we have to wait for it
409- */
410- if (!bufferData )
411- {
412- return paNotInitialized ;
413- }
414-
415430 PaUtil_SetInterleavedOutputChannels ( & stream -> bufferProcessor ,
416431 0 ,
417432 bufferData ,
@@ -420,6 +435,31 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
420435 PaUtil_SetOutputFrameCount ( & stream -> bufferProcessor ,
421436 hostFramesPerBuffer );
422437
438+ }
439+
440+ hostFrameCount =
441+ PaUtil_EndBufferProcessing ( & stream -> bufferProcessor ,
442+ & ret );
443+
444+ PaUtil_EndCpuLoadMeasurement ( & stream -> cpuLoadMeasurer ,
445+ hostFrameCount );
446+
447+ /*
448+ * pa_stream_begin_write gives pointer to ring
449+ * buffer in Pulseaudio. WhenPaUtil_EndBufferProcessing
450+ * returns paContinue then is ok to write output.
451+ *
452+ * When it's something else than paContinue
453+ * then we have to cancel writing with
454+ * with pa_stream_cancel_write.
455+ *
456+ * If there is no space in output ringbuffer or for
457+ * example USB device has dissapiered and pointer
458+ * is NULL then we just get out of loop as there is not much
459+ * we can't do
460+ */
461+ if ( ret == paContinue && isOutputCb && bufferData )
462+ {
423463 if ( pa_stream_write ( stream -> outputStream ,
424464 bufferData ,
425465 pulseaudioOutputBytes ,
@@ -433,14 +473,19 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
433473
434474 pulseaudioOutputWritten += pulseaudioOutputBytes ;
435475 }
476+ else if ( ret != paContinue && isOutputCb && bufferData )
477+ {
478+ pa_stream_cancel_write ( stream -> outputStream );
479+ bufferData = NULL ;
480+ }
481+ else if ( isOutputCb && !bufferData )
482+ {
483+ ret = -1 ;
484+ }
485+ }
486+ while ( ret == paContinue );
436487
437- hostFrameCount =
438- PaUtil_EndBufferProcessing ( & stream -> bufferProcessor ,
439- & ret );
440488
441- PaUtil_EndCpuLoadMeasurement ( & stream -> cpuLoadMeasurer ,
442- hostFrameCount );
443- }
444489
445490 return ret ;
446491}
0 commit comments