Tweaking the delay a bit... 0,050 s for output seems too little; it results in choppy audio and ultimately, a heap of errors. 0,100 seems ok for the output buffer. But the input buffer needs to be much larger else it overflows. Also, an extra stop stream before terminating to make sure all audio from the audio buffer is played.

This commit is contained in:
Jiri Wichern 2014-06-07 20:49:35 +02:00
parent 5dd236ec96
commit 74fa117850
3 changed files with 42 additions and 13 deletions

9
dsd.h
View File

@ -45,10 +45,17 @@
#define SAMPLE_RATE_IN 48000
#define SAMPLE_RATE_OUT 8000
#define PA_FRAMES_PER_BUFFER 64
#ifdef USE_PORTAUDIO
#include "portaudio.h"
#define PA_FRAMES_PER_BUFFER 64
//Buffer needs to be large enough to prevent input buffer overruns while DSD is doing other struff (like outputting voice)
//else you get skipped samples which result in incomplete/erronous decodes and a mountain of error messages.
#define PA_LATENCY_IN 0.500
//Buffer needs to be large enough to prevent output buffer underruns while DSD is doing other stuff (like decoding input)
//else you get choppy audio and in 'extreme' cases errors.
//Buffer also needs to be as small as possible so we don't have a lot of audio delay.
#define PA_LATENCY_OUT 0.100
#endif
/*

View File

@ -235,8 +235,11 @@ playSynthesizedVoice (dsd_opts * opts, dsd_state * state)
//printf("Frames available: %d\n", available);
if( err != paNoError )
break;
if(available > SAMPLE_RATE_OUT / 2)
if(available > SAMPLE_RATE_OUT * PA_LATENCY_OUT)
{
//It looks like this might not be needed for very small latencies. However, it's definitely needed for a bit larger ones.
//When PA_LATENCY_OUT == 0.500 I get output buffer underruns if I don't use this. With PA_LATENCY_OUT <= 0.100 I don't see those happen.
//But with PA_LATENCY_OUT < 0.100 I run the risk of choppy audio and stream errors.
printf("\nSyncing voice output stream\n");
err = Pa_StopStream( opts->audio_out_pa_stream );
if( err != paNoError )
@ -335,7 +338,7 @@ int getPADevice(char* dev, int input, PaStream** stream)
parameters.device = devnum;
parameters.channelCount = 1; /* mono */
parameters.sampleFormat = paInt16; //Shorts
parameters.suggestedLatency = 0.500; //0.050; // Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
parameters.suggestedLatency = (input == 1) ? PA_LATENCY_IN : PA_LATENCY_OUT;
parameters.hostApiSpecificStreamInfo = NULL;
//Open stream

View File

@ -98,8 +98,14 @@ initOpts (dsd_opts * opts)
opts->scoperate = 15;
sprintf (opts->audio_in_dev, "/dev/audio");
opts->audio_in_fd = -1;
#ifdef USE_PORTAUDIO
opts->audio_in_pa_stream = NULL;
#endif
sprintf (opts->audio_out_dev, "/dev/audio");
opts->audio_out_fd = -1;
#ifdef USE_PORTAUDIO
opts->audio_out_pa_stream = NULL;
#endif
opts->split = 0;
opts->playoffset = 0;
opts->mbe_out_dir[0] = 0;
@ -364,20 +370,33 @@ cleanupAndExit (dsd_opts * opts, dsd_state * state)
printf("Terminating portaudio.\n");
PaError err = paNoError;
if(opts->audio_in_pa_stream != NULL)
err = Pa_CloseStream( opts->audio_in_pa_stream );
if( err != paNoError )
{
fprintf( stderr, "An error occured while closing the portaudio input stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
err = Pa_CloseStream( opts->audio_in_pa_stream );
if( err != paNoError )
{
fprintf( stderr, "An error occured while closing the portaudio input stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
}
}
if(opts->audio_out_pa_stream != NULL)
err = Pa_CloseStream( opts->audio_out_pa_stream );
if( err != paNoError )
{
fprintf( stderr, "An error occured while closing the portaudio output stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
err = Pa_IsStreamActive( opts->audio_out_pa_stream );
if(err == 1)
err = Pa_StopStream( opts->audio_out_pa_stream );
if( err != paNoError )
{
fprintf( stderr, "An error occured while closing the portaudio output stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
}
err = Pa_CloseStream( opts->audio_out_pa_stream );
if( err != paNoError )
{
fprintf( stderr, "An error occured while closing the portaudio output stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
}
}
err = Pa_Terminate();
if( err != paNoError )