Skip to content

Commit ba5ec87

Browse files
committed
pulseaudio: Rework stopping code that it should prevent artifacts
Rework stopping and stream closing code as it should prevent artifacts when closing or stopping stream. Correctly handle stream termination from callback
1 parent 57aa393 commit ba5ec87

File tree

1 file changed

+48
-25
lines changed

1 file changed

+48
-25
lines changed

src/hostapi/pulseaudio/pa_linux_pulseaudio_cb.c

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,37 @@ void _PaPulseAudio_Read( PaPulseAudio_Stream *stream,
219219

220220
}
221221

222+
static int _PaPulseaudio_WriteZero(PaPulseAudio_Stream *stream,
223+
int32_t length)
224+
{
225+
size_t tmpSize = length;
226+
int ret = paContinue;
227+
void *bufferData = NULL;
228+
229+
if( length <= 0)
230+
{
231+
return ret;
232+
}
233+
234+
/* Allocate memory to make it faster to output stuff */
235+
if( pa_stream_begin_write( stream->outputStream, &bufferData, &tmpSize ) )
236+
{
237+
PA_DEBUG( ("Portaudio %s: Can't output to stream!\n",
238+
__FUNCTION__) );
239+
return paInsufficientMemory;
240+
}
241+
242+
memset( bufferData, 0x00, tmpSize);
243+
244+
pa_stream_write( stream->outputStream,
245+
bufferData,
246+
tmpSize,
247+
NULL,
248+
0,
249+
PA_SEEK_RELATIVE );
250+
return ret;
251+
}
252+
222253
static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
223254
size_t length)
224255
{
@@ -233,6 +264,7 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
233264
int ret = paContinue;
234265
void *bufferData = NULL;
235266
size_t pulseaudioOutputWritten = 0;
267+
size_t pulseaudioLength = length;
236268

237269
/* If there is no specified per host buffer then
238270
* just generate one or but correct one in place
@@ -293,19 +325,10 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
293325
pulseaudioInputBytes /= 2;
294326
}
295327

296-
if( !stream->isActive && stream->pulseaudioIsActive && stream->outputStream)
328+
if( !stream->isActive && stream->outputStream)
297329
{
298-
bufferData = pulseaudioSampleBuffer;
299-
memset( bufferData, 0x00, length);
300-
301-
pa_stream_write( stream->outputStream,
302-
bufferData,
303-
length,
304-
NULL,
305-
0,
306-
PA_SEEK_RELATIVE );
307-
308-
return paContinue;
330+
return _PaPulseaudio_WriteZero( stream,
331+
pulseaudioLength );
309332
}
310333

311334

@@ -388,13 +411,10 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
388411
size_t tmpSize = pulseaudioOutputBytes;
389412

390413
/* Allocate memory to make it faster to output stuff */
391-
pa_stream_begin_write( stream->outputStream, &bufferData, &tmpSize );
392-
393-
/* If bufferData is NULL then output is not ready
394-
* and we have to wait for it
395-
*/
396-
if(!bufferData)
414+
if( pa_stream_begin_write( stream->outputStream, &bufferData, &tmpSize ) )
397415
{
416+
PA_DEBUG( ("Portaudio %s: Can't output to stream!\n",
417+
__FUNCTION__) )
398418
return paNotInitialized;
399419
}
400420

@@ -426,6 +446,13 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
426446

427447
PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer,
428448
hostFrameCount );
449+
450+
if( ret )
451+
{
452+
stream->isActive = 0;
453+
return _PaPulseaudio_WriteZero( stream,
454+
(length - pulseaudioOutputWritten) );
455+
}
429456
}
430457

431458
return ret;
@@ -518,8 +545,6 @@ PaError PaPulseAudio_CloseStreamCb( PaStream * s )
518545
/* Wait for stream to be stopped */
519546
stream->isActive = 0;
520547
stream->isStopped = 1;
521-
stream->pulseaudioIsActive = 0;
522-
stream->pulseaudioIsStopped = 1;
523548

524549
if( stream->outputStream != NULL
525550
&& PA_STREAM_IS_GOOD( pa_stream_get_state( stream->outputStream ) ) )
@@ -536,7 +561,6 @@ PaError PaPulseAudio_CloseStreamCb( PaStream * s )
536561
&pulseaudioOperation );
537562

538563
PaPulseAudio_Lock(stream->mainloop);
539-
540564
pa_stream_disconnect( stream->outputStream );
541565
PaPulseAudio_UnLock( stream->mainloop );
542566
}
@@ -598,6 +622,9 @@ PaError PaPulseAudio_CloseStreamCb( PaStream * s )
598622
usleep(10000);
599623
}
600624

625+
stream->pulseaudioIsActive = 0;
626+
stream->pulseaudioIsStopped = 1;
627+
601628
PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
602629
PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
603630

@@ -917,8 +944,6 @@ static PaError RequestStop( PaPulseAudio_Stream * stream,
917944
/* Wait for stream to be stopped */
918945
stream->isActive = 0;
919946
stream->isStopped = 1;
920-
stream->pulseaudioIsActive = 0;
921-
stream->pulseaudioIsStopped = 1;
922947

923948
stream->missedBytes = 0;
924949

@@ -941,8 +966,6 @@ static PaError RequestStop( PaPulseAudio_Stream * stream,
941966

942967
requeststop_error:
943968
PaPulseAudio_UnLock( pulseaudioHostApi->mainloop );
944-
stream->isActive = 0;
945-
stream->isStopped = 1;
946969
stream->pulseaudioIsActive = 0;
947970
stream->pulseaudioIsStopped = 1;
948971

0 commit comments

Comments
 (0)