From: drowe67 Date: Mon, 15 Oct 2012 02:51:56 +0000 (+0000) Subject: added fifo buffering to account for mysterious change in framesPerBuf from portaudio X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=b6fbeb9bc2edf9ae8d09f4fd11508b7348829007;p=freetel-svn-tracking.git added fifo buffering to account for mysterious change in framesPerBuf from portaudio git-svn-id: https://svn.code.sf.net/p/freetel/code@749 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/portaudio/Makefile b/codec2-dev/portaudio/Makefile index a1876de9..39255b6c 100644 --- a/codec2-dev/portaudio/Makefile +++ b/codec2-dev/portaudio/Makefile @@ -3,7 +3,7 @@ CFLAGS = -g -Wall -I../src LIBS = -lm -lportaudio -pthread -SRC = ../src/fdmdv.c ../src/kiss_fft.c +SRC = ../src/fdmdv.c ../src/kiss_fft.c ../src/fifo.c all: pa_rec pa_play pa_recplay pa_impresp diff --git a/codec2-dev/portaudio/pa_rec.c b/codec2-dev/portaudio/pa_rec.c index 79366621..00023b02 100644 --- a/codec2-dev/portaudio/pa_rec.c +++ b/codec2-dev/portaudio/pa_rec.c @@ -81,7 +81,7 @@ static int recordCallback( const void *inputBuffer, void *outputBuffer, paTestData *data = (paTestData*)userData; FILE *fout = data->fout; int framesToCopy; - int i, n8; + int i; int finished; short *rptr = (short*)inputBuffer; float out8k[N8]; @@ -130,8 +130,7 @@ static int recordCallback( const void *inputBuffer, void *outputBuffer, int main(int argc, char *argv[]) { - PaStreamParameters inputParameters, - outputParameters; + PaStreamParameters inputParameters; PaStream* stream; PaError err = paNoError; paTestData data; @@ -158,6 +157,9 @@ int main(int argc, char *argv[]) err = Pa_Initialize(); if( err != paNoError ) goto done; + printf( "PortAudio version number = %d\nPortAudio version text = '%s'\n", + Pa_GetVersion(), Pa_GetVersionText() ); + inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */ if (inputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default input device.\n"); diff --git a/codec2-dev/portaudio/pa_recplay.c b/codec2-dev/portaudio/pa_recplay.c index f745396f..6bfcd08b 100644 --- a/codec2-dev/portaudio/pa_recplay.c +++ b/codec2-dev/portaudio/pa_recplay.c @@ -44,6 +44,7 @@ #include #include "portaudio.h" #include "fdmdv.h" +#include "fifo.h" #define SAMPLE_RATE 48000 /* 48 kHz sampling rate rec. as we can trust accuracy of sound @@ -54,12 +55,15 @@ #define NUM_CHANNELS 2 /* I think most sound cards prefer stereo, we will convert to mono as we sample */ +#define MAX_FPB 2048 /* maximum value of framesPerBuffer */ /* state information passed to call back */ typedef struct { float in48k[FDMDV_OS_TAPS + N48]; float in8k[MEM8 + N8]; + struct FIFO *infifo; + struct FIFO *outfifo; } paTestData; @@ -85,43 +89,95 @@ static int callback( const void *inputBuffer, void *outputBuffer, float out8k[N8]; float out48k[N48]; short out48k_short[N48]; + short in48k_short[N48]; + short indata[MAX_FPB]; + short outdata[MAX_FPB]; (void) timeInfo; (void) statusFlags; assert(inputBuffer != NULL); + assert(outputBuffer != NULL); + + /* + framesPerBuffer is portaudio-speak for number of samples we + actually get from the record side and need to provide to the + play side. On Linux (at least) it was found that + framesPerBuffer may not always be what we ask for in the + framesPerBuffer field of Pa_OpenStream. For example a request + for 960 sample buffers lead to framesPerBuffer = 1024. + + To perform the 48 to 8 kHz conversion we need an integer + multiple of FDMDV_OS samples to support the interpolation and + decimation. As we can't guarantee the size of framesPerBuffer + we do a little FIFO buffering. + */ - /* just use left channel */ + //printf("framesPerBuffer: %d N48 %d\n", framesPerBuffer, N48); + /* assemble a mono buffer (just use left channel) and write to FIFO */ + + assert(framesPerBuffer < MAX_FPB); for(i=0; iin48k[i+FDMDV_OS_TAPS] = *rptr; + indata[i] = *rptr; + fifo_write(data->infifo, indata, framesPerBuffer); - /* downsample and update filter memory */ + /* while we have enough samples available ... */ - fdmdv_48_to_8(out8k, &in48k[FDMDV_OS_TAPS], N8); - for(i=0; iinfifo)); + while (fifo_read(data->infifo, in48k_short, N48) == 0) { - /* play side, back up to 8k */ + /* convert to float */ - for(i=0; ioutfifo, out48k_short, N48); + } + //printf("infifo after: %d\n", fifo_n(data->infifo)); + //printf("outfifo : %d\n", fifo_n(data->outfifo)); + + + /* OK now set up output samples */ + + if (fifo_read(data->outfifo, outdata, framesPerBuffer) == 0) { + + /* write signal to both channels */ + + for(i=0; i