From 8c2e1b7e540e93757d04bdb4af7618c87ad31741 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Fri, 6 Jul 2012 00:01:57 +0000 Subject: [PATCH] first pass at port audio record program git-svn-id: https://svn.code.sf.net/p/freetel/code@580 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/unittest/Makefile.am | 6 +- codec2-dev/unittest/pa_rec.c | 218 ++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 codec2-dev/unittest/pa_rec.c diff --git a/codec2-dev/unittest/Makefile.am b/codec2-dev/unittest/Makefile.am index 77c72028..26856c27 100644 --- a/codec2-dev/unittest/Makefile.am +++ b/codec2-dev/unittest/Makefile.am @@ -3,7 +3,7 @@ AUTOMAKE_OPTS = gnu NAME = libcodec2 AM_CPPFLAGS = $(AM_CFLAGS) -noinst_PROGRAMS = genres genlsp extract vqtrain vqtrainjnd tnlp tinterp tquant vq_train_jvm scalarlsptest tfdmdv t48_8 lspsync create_interleaver tlspsens +noinst_PROGRAMS = genres genlsp extract vqtrain vqtrainjnd tnlp tinterp tquant vq_train_jvm scalarlsptest tfdmdv t48_8 lspsync create_interleaver tlspsens pa_rec genres_SOURCES = genres.c ../src/lpc.c genres_LDADD = $(lib_LTLIBRARIES) @@ -68,3 +68,7 @@ tlspsens_SOURCES = tlspsens.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src tlspsens_LDADD = $(lib_LTLIBRARIES) tlspsens_LDFLAGS = $(LIBS) +pa_rec_SOURCES = pa_rec.c +pa_rec_LDADD = $(lib_LTLIBRARIES) +pa_rec_LDFLAGS = $(LIBS) + diff --git a/codec2-dev/unittest/pa_rec.c b/codec2-dev/unittest/pa_rec.c new file mode 100644 index 00000000..514098d3 --- /dev/null +++ b/codec2-dev/unittest/pa_rec.c @@ -0,0 +1,218 @@ +/* + pa_rec.c + David Rowe + July 6 2012 + + Modified from paex_record.c Portaudio example + + Original author author Phil Burk http://www.softsynth.com + + To Build: + + gcc paex_rec.c -o paex_rec -lm -lrt -lportaudio -pthread +*/ + +/* + * $Id: paex_record.c 1752 2011-09-08 03:21:55Z philburk $ + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.portaudio.com + * Copyright (c) 1999-2000 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "portaudio.h" + +#define SAMPLE_RATE 48000 +#define FRAMES_PER_BUFFER 512 +#define NUM_CHANNELS 2 /* I think most sound cards like stereo, we will + convert to mono as we sample */ +#define SAMPLE_SILENCE 0 + +typedef short SAMPLE; + +typedef struct +{ + int frameIndex; /* Index into sample array. */ + int maxFrameIndex; + SAMPLE *recordedSamples; +} +paTestData; + +/* This routine will be called by the PortAudio engine when audio is available. +** It may be called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int recordCallback( const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void *userData ) +{ + paTestData *data = (paTestData*)userData; + const SAMPLE *rptr = (const SAMPLE*)inputBuffer; + SAMPLE *wptr = &data->recordedSamples[data->frameIndex /** NUM_CHANNELS*/]; + long framesToCalc; + long i; + int finished; + unsigned long framesLeft = data->maxFrameIndex - data->frameIndex; + + (void) outputBuffer; /* Prevent unused variable warnings. */ + (void) timeInfo; + (void) statusFlags; + (void) userData; + + if( framesLeft < framesPerBuffer ) + { + framesToCalc = framesLeft; + finished = paComplete; + } + else + { + framesToCalc = framesPerBuffer; + finished = paContinue; + } + + if( inputBuffer == NULL ) + { + for( i=0; iframeIndex += framesToCalc; + return finished; +} + +int main(int argc, char *argv[]) +{ + PaStreamParameters inputParameters, + outputParameters; + PaStream* stream; + PaError err = paNoError; + paTestData data; + int i; + int totalFrames; + int numSamples; + int numBytes; + SAMPLE max, val; + double average; + int numSecs; + FILE *fout; + + if (argc != 3) { + printf("usage: %s rawFile time(s)\n", argv[0]); + exit(0); + } + + fout = fopen(argv[1], "wt"); + if (fout == NULL) { + printf("Error opening output raw file %s\n", argv[1]); + exit(1); + } + + numSecs = atoi(argv[2]); + printf("patest_record.c\n"); fflush(stdout); + + data.maxFrameIndex = totalFrames = numSecs * SAMPLE_RATE; /* Record for a few seconds. */ + data.frameIndex = 0; + numSamples = totalFrames/* * NUM_CHANNELS*/; + numBytes = numSamples * sizeof(SAMPLE); + data.recordedSamples = (SAMPLE *) malloc( numBytes ); /* From now on, recordedSamples is initialised. */ + if( data.recordedSamples == NULL ) + { + printf("Could not allocate record array.\n"); + goto done; + } + for( i=0; idefaultLowInputLatency; + inputParameters.hostApiSpecificStreamInfo = NULL; + + /* Record some audio. -------------------------------------------- */ + + err = Pa_OpenStream( + &stream, + &inputParameters, + NULL, /* &outputParameters, */ + SAMPLE_RATE, + FRAMES_PER_BUFFER, + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + recordCallback, + &data ); + if( err != paNoError ) goto done; + + err = Pa_StartStream( stream ); + if( err != paNoError ) goto done; + printf("\n=== Now recording!! Please speak into the microphone. ===\n"); fflush(stdout); + + while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) + { + Pa_Sleep(1000); + printf("index = %d\n", data.frameIndex ); fflush(stdout); + } + if( err < 0 ) goto done; + + err = Pa_CloseStream( stream ); + if( err != paNoError ) goto done; + + /* Write recorded data to a file. */ + + fwrite( data.recordedSamples, /*NUM_CHANNELS * */sizeof(SAMPLE), totalFrames, fout ); + fclose( fout ); + + +done: + Pa_Terminate(); + if( data.recordedSamples ) /* Sure it is NULL or valid. */ + free( data.recordedSamples ); + if( err != paNoError ) + { + fprintf( stderr, "An error occured while using the portaudio stream\n" ); + fprintf( stderr, "Error number: %d\n", err ); + fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + err = 1; /* Always return 0 or 1, but no other return codes. */ + } + return err; +} + -- 2.25.1