Mac: test adjustable number of channels.

This commit is contained in:
Phil Burk 2016-05-21 17:25:18 -07:00
commit 315309f60e
5 changed files with 74 additions and 74 deletions

View file

@ -49,56 +49,40 @@
#include "portaudio.h" #include "portaudio.h"
/* #define SAMPLE_RATE (17932) // Test failure to open with this value. */ /* #define SAMPLE_RATE (17932) // Test failure to open with this value. */
#define SAMPLE_RATE (44100) #define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (1024) #define FRAMES_PER_BUFFER (512)
#define NUM_CHANNELS (6) #define NUM_SECONDS (10)
#define NUM_SECONDS (15)
/* #define DITHER_FLAG (paDitherOff) */ /* #define DITHER_FLAG (paDitherOff) */
#define DITHER_FLAG (0) /**/ #define DITHER_FLAG (0)
/* @todo Underflow and overflow is disabled until we fix priming of blocking write. */
#define CHECK_OVERFLOW (0)
#define CHECK_UNDERFLOW (0)
/* Select sample format. */ /* Select sample format. */
#if 0 #if 1
#define PA_SAMPLE_TYPE paFloat32 #define PA_SAMPLE_TYPE paFloat32
#define SAMPLE_SIZE (4) #define SAMPLE_SIZE (4)
#define SAMPLE_SILENCE (0.0f) #define SAMPLE_SILENCE (0.0f)
#define CLEAR(a) memset( (a), 0, FRAMES_PER_BUFFER * NUM_CHANNELS * SAMPLE_SIZE )
#define PRINTF_S_FORMAT "%.8f" #define PRINTF_S_FORMAT "%.8f"
#elif 0 #elif 0
#define PA_SAMPLE_TYPE paInt16 #define PA_SAMPLE_TYPE paInt16
#define SAMPLE_SIZE (2) #define SAMPLE_SIZE (2)
#define SAMPLE_SILENCE (0) #define SAMPLE_SILENCE (0)
#define CLEAR(a) memset( (a), 0, FRAMES_PER_BUFFER * NUM_CHANNELS * SAMPLE_SIZE )
#define PRINTF_S_FORMAT "%d" #define PRINTF_S_FORMAT "%d"
#elif 1 #elif 0
#define PA_SAMPLE_TYPE paInt24 #define PA_SAMPLE_TYPE paInt24
#define SAMPLE_SIZE (3) #define SAMPLE_SIZE (3)
#define SAMPLE_SILENCE (0) #define SAMPLE_SILENCE (0)
#define CLEAR(a) memset( (a), 0, FRAMES_PER_BUFFER * NUM_CHANNELS * SAMPLE_SIZE )
#define PRINTF_S_FORMAT "%d" #define PRINTF_S_FORMAT "%d"
#elif 0 #elif 0
#define PA_SAMPLE_TYPE paInt8 #define PA_SAMPLE_TYPE paInt8
#define SAMPLE_SIZE (1) #define SAMPLE_SIZE (1)
#define SAMPLE_SILENCE (0) #define SAMPLE_SILENCE (0)
#define CLEAR(a) memset( (a), 0, FRAMES_PER_BUFFER * NUM_CHANNELS * SAMPLE_SIZE )
#define PRINTF_S_FORMAT "%d" #define PRINTF_S_FORMAT "%d"
#else #else
#define PA_SAMPLE_TYPE paUInt8 #define PA_SAMPLE_TYPE paUInt8
#define SAMPLE_SIZE (1) #define SAMPLE_SIZE (1)
#define SAMPLE_SILENCE (128) #define SAMPLE_SILENCE (128)
#define CLEAR( a ) { \
int i; \
for( i=0; i<FRAMES_PER_BUFFER*NUM_CHANNELS; i++ ) \
((unsigned char *)a)[i] = (SAMPLE_SILENCE); \
}
#define PRINTF_S_FORMAT "%d" #define PRINTF_S_FORMAT "%d"
#endif #endif
/*******************************************************************/ /*******************************************************************/
int main(void); int main(void);
int main(void) int main(void)
@ -106,46 +90,50 @@ int main(void)
PaStreamParameters inputParameters, outputParameters; PaStreamParameters inputParameters, outputParameters;
PaStream *stream = NULL; PaStream *stream = NULL;
PaError err; PaError err;
char *sampleBlock; const PaDeviceInfo* inputInfo;
const PaDeviceInfo* outputInfo;
char *sampleBlock = NULL;
int i; int i;
int numBytes; int numBytes;
printf("patest_read_write_wire.c\n"); fflush(stdout); printf("patest_read_write_wire.c\n"); fflush(stdout);
printf("sizeof(int) = %lu\n", sizeof(int)); fflush(stdout);
numBytes = FRAMES_PER_BUFFER * NUM_CHANNELS * SAMPLE_SIZE ; printf("sizeof(long) = %lu\n", sizeof(long)); fflush(stdout);
sampleBlock = (char *) malloc( numBytes );
if( sampleBlock == NULL )
{
printf("Could not allocate record array.\n");
exit(1);
}
CLEAR( sampleBlock );
err = Pa_Initialize(); err = Pa_Initialize();
if( err != paNoError ) goto error; if( err != paNoError ) goto error2;
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */ inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
printf( "Input device # %d.\n", inputParameters.device ); printf( "Input device # %d.\n", inputParameters.device );
printf( "Input LL: %g s\n", Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency ); inputInfo = Pa_GetDeviceInfo( inputParameters.device );
printf( "Input HL: %g s\n", Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency ); printf( " Name: %s\n", inputInfo->name );
inputParameters.channelCount = NUM_CHANNELS; printf( " LL: %g s\n", inputInfo->defaultLowInputLatency );
inputParameters.sampleFormat = PA_SAMPLE_TYPE; printf( " HL: %g s\n", inputInfo->defaultHighInputLatency );
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency ;
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
printf( "Output device # %d.\n", outputParameters.device ); printf( "Output device # %d.\n", outputParameters.device );
printf( "Output LL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency ); outputInfo = Pa_GetDeviceInfo( outputParameters.device );
printf( "Output HL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency ); printf( " Name: %s\n", outputInfo->name );
outputParameters.channelCount = NUM_CHANNELS; printf( " LL: %g s\n", outputInfo->defaultLowOutputLatency );
printf( " HL: %g s\n", outputInfo->defaultHighOutputLatency );
int numChannels = inputInfo->maxInputChannels < outputInfo->maxOutputChannels
? inputInfo->maxInputChannels : outputInfo->maxOutputChannels;
printf( "Num channels = %d.\n", numChannels );
inputParameters.channelCount = numChannels;
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = inputInfo->defaultHighInputLatency ;
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.channelCount = numChannels;
outputParameters.sampleFormat = PA_SAMPLE_TYPE; outputParameters.sampleFormat = PA_SAMPLE_TYPE;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency; outputParameters.suggestedLatency = outputInfo->defaultHighOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL; outputParameters.hostApiSpecificStreamInfo = NULL;
/* -- setup -- */ /* -- setup -- */
err = Pa_OpenStream( err = Pa_OpenStream(
&stream, &stream,
&inputParameters, &inputParameters,
&outputParameters, &outputParameters,
@ -154,21 +142,33 @@ int main(void)
paClipOff, /* we won't output out of range samples so don't bother clipping them */ paClipOff, /* we won't output out of range samples so don't bother clipping them */
NULL, /* no callback, use blocking API */ NULL, /* no callback, use blocking API */
NULL ); /* no callback, so no callback userData */ NULL ); /* no callback, so no callback userData */
if( err != paNoError ) goto error; if( err != paNoError ) goto error2;
numBytes = FRAMES_PER_BUFFER * numChannels * SAMPLE_SIZE ;
sampleBlock = (char *) malloc( numBytes );
if( sampleBlock == NULL )
{
printf("Could not allocate record array.\n");
goto error1;
}
memset( sampleBlock, SAMPLE_SILENCE, numBytes );
err = Pa_StartStream( stream ); err = Pa_StartStream( stream );
if( err != paNoError ) goto error; if( err != paNoError ) goto error1;
printf("Wire on. Will run %d seconds.\n", NUM_SECONDS); fflush(stdout); printf("Wire on. Will run %d seconds.\n", NUM_SECONDS); fflush(stdout);
for( i=0; i<(NUM_SECONDS*SAMPLE_RATE)/FRAMES_PER_BUFFER; ++i ) for( i=0; i<(NUM_SECONDS*SAMPLE_RATE)/FRAMES_PER_BUFFER; ++i )
{ {
err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER ); // You may get underruns or overruns if the output is not primed by PortAudio.
if( err && CHECK_UNDERFLOW ) goto xrun; err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER );
err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER ); if( err ) goto xrun;
if( err && CHECK_OVERFLOW ) goto xrun; err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
if( err ) goto xrun;
} }
printf("Wire off.\n"); fflush(stdout);
err = Pa_StopStream( stream ); err = Pa_StopStream( stream );
if( err != paNoError ) goto error; if( err != paNoError ) goto error1;
free( sampleBlock ); free( sampleBlock );
@ -176,6 +176,7 @@ int main(void)
return 0; return 0;
xrun: xrun:
printf("err = %d\n", err); fflush(stdout);
if( stream ) { if( stream ) {
Pa_AbortStream( stream ); Pa_AbortStream( stream );
Pa_CloseStream( stream ); Pa_CloseStream( stream );
@ -187,13 +188,13 @@ xrun:
if( err & paOutputUnderflow ) if( err & paOutputUnderflow )
fprintf( stderr, "Output Underflow.\n" ); fprintf( stderr, "Output Underflow.\n" );
return -2; return -2;
error1:
error: free( sampleBlock );
error2:
if( stream ) { if( stream ) {
Pa_AbortStream( stream ); Pa_AbortStream( stream );
Pa_CloseStream( stream ); Pa_CloseStream( stream );
} }
free( sampleBlock );
Pa_Terminate(); Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" ); fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err ); fprintf( stderr, "Error number: %d\n", err );

View file

@ -231,7 +231,7 @@ static void TestDevices( int mode )
88200.0, 96000.0, 88200.0, 96000.0,
-1.0 }; /* Negative terminated list. */ -1.0 }; /* Negative terminated list. */
int numDevices = Pa_GetDeviceCount(); int numDevices = Pa_GetDeviceCount();
for( id=0; id<numDevices; id++ ) /* Iterate through all devices. */ for( id=3; id<numDevices; id++ ) /* Iterate through all devices. */
{ {
pdi = Pa_GetDeviceInfo( id ); pdi = Pa_GetDeviceInfo( id );
/* Try 1 to maxChannels on each device. */ /* Try 1 to maxChannels on each device. */
@ -239,13 +239,13 @@ static void TestDevices( int mode )
if( maxChannels > MAX_TEST_CHANNELS ) if( maxChannels > MAX_TEST_CHANNELS )
maxChannels = MAX_TEST_CHANNELS; maxChannels = MAX_TEST_CHANNELS;
for( jc=1; jc<=maxChannels; jc++ ) for( jc=4; jc<=maxChannels; jc++ )
{ {
printf("\n========================================================================\n"); printf("\n========================================================================\n");
printf(" Device = %s\n", pdi->name ); printf(" Device = %s\n", pdi->name );
printf("========================================================================\n"); printf("========================================================================\n");
/* Try each standard sample rate. */ /* Try each standard sample rate. */
for( i=0; standardSampleRates[i] > 0; i++ ) for( i=9; standardSampleRates[i] > 0; i++ )
{ {
TestFormats( mode, (PaDeviceIndex)id, standardSampleRates[i], jc ); TestFormats( mode, (PaDeviceIndex)id, standardSampleRates[i], jc );
} }
@ -258,8 +258,8 @@ static void TestFormats( int mode, PaDeviceIndex deviceID, double sampleRate,
int numChannels ) int numChannels )
{ {
TestAdvance( mode, deviceID, sampleRate, numChannels, paFloat32 ); TestAdvance( mode, deviceID, sampleRate, numChannels, paFloat32 );
TestAdvance( mode, deviceID, sampleRate, numChannels, paInt16 ); // TestAdvance( mode, deviceID, sampleRate, numChannels, paInt16 );
TestAdvance( mode, deviceID, sampleRate, numChannels, paInt32 ); // TestAdvance( mode, deviceID, sampleRate, numChannels, paInt32 );
/* TestAdvance( mode, deviceID, sampleRate, numChannels, paInt24 ); */ /* TestAdvance( mode, deviceID, sampleRate, numChannels, paInt24 ); */
} }

View file

@ -456,9 +456,9 @@ PaError ReadStream( PaStream* stream,
} }
} while( framesAvailable == 0 ); } while( framesAvailable == 0 );
framesToTransfer = MIN( framesAvailable, framesRequested ); framesToTransfer = MIN( framesAvailable, framesRequested );
PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, framesToTransfer ); framesTransferred = PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, framesToTransfer );
cbuf += framesToTransfer * blio->inputSampleSizeActual * blio->inChan; cbuf += framesTransferred * blio->inputSampleSizeActual * blio->inChan;
framesRequested -= framesToTransfer; framesRequested -= framesTransferred;
if( framesToTransfer == framesAvailable ) { if( framesToTransfer == framesAvailable ) {
#ifdef PA_MAC_BLIO_MUTEX #ifdef PA_MAC_BLIO_MUTEX
@ -509,7 +509,6 @@ PaError WriteStream( PaStream* stream,
ring_buffer_size_t framesToTransfer; ring_buffer_size_t framesToTransfer;
ring_buffer_size_t framesTransferred; ring_buffer_size_t framesTransferred;
do { do {
framesAvailable = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); framesAvailable = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
/* /*
@ -538,9 +537,9 @@ PaError WriteStream( PaStream* stream,
} while( framesAvailable == 0 ); } while( framesAvailable == 0 );
framesToTransfer = MIN( framesAvailable, framesRequested ); framesToTransfer = MIN( framesAvailable, framesRequested );
PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, framesToTransfer ); framesTransferred = PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, framesToTransfer );
cbuf += framesToTransfer * blio->outputSampleSizeActual * blio->outChan; cbuf += framesTransferred * blio->outputSampleSizeActual * blio->outChan;
framesRequested -= framesToTransfer; framesRequested -= framesTransferred;
#ifdef PA_MAC_BLIO_MUTEX #ifdef PA_MAC_BLIO_MUTEX
if( framesToTransfer == framesAvailable ) { if( framesToTransfer == framesAvailable ) {

View file

@ -46,8 +46,8 @@
#include <math.h> #include <math.h>
#include "portaudio.h" #include "portaudio.h"
#define MAX_SINES (500) #define MAX_SINES (2000)
#define MAX_USAGE (0.8) #define MAX_USAGE (0.5)
#define SAMPLE_RATE (44100) #define SAMPLE_RATE (44100)
#define FREQ_TO_PHASE_INC(freq) (freq/(float)SAMPLE_RATE) #define FREQ_TO_PHASE_INC(freq) (freq/(float)SAMPLE_RATE)
@ -60,7 +60,7 @@
#endif #endif
#define TWOPI (M_PI * 2.0) #define TWOPI (M_PI * 2.0)
#define TABLE_SIZE (512) #define TABLE_SIZE (1024)
typedef struct paTestData typedef struct paTestData
{ {
@ -70,7 +70,7 @@ typedef struct paTestData
} }
paTestData; paTestData;
/* Convert phase between and 1.0 to sine value /* Convert phase between 0.0 and 1.0 to sine value
* using linear interpolation. * using linear interpolation.
*/ */
float LookupSine( paTestData *data, float phase ); float LookupSine( paTestData *data, float phase );
@ -187,14 +187,14 @@ int main(void)
/* Play an increasing number of sine waves until we hit MAX_USAGE */ /* Play an increasing number of sine waves until we hit MAX_USAGE */
do { do {
data.numSines++; data.numSines += 10;
Pa_Sleep(200); Pa_Sleep(200);
load = Pa_GetStreamCpuLoad(stream); load = Pa_GetStreamCpuLoad(stream);
printf("numSines = %d, CPU load = %f\n", data.numSines, load ); printf("numSines = %d, CPU load = %f\n", data.numSines, load );
fflush(stdout); fflush(stdout);
} while((load < MAX_USAGE) && (data.numSines < MAX_SINES)); } while((load < MAX_USAGE) && (data.numSines < MAX_SINES));
Pa_Sleep(2000); /* Stay for 2 seconds around 80% CPU. */ Pa_Sleep(2000); /* Stay for 2 seconds at max CPU. */
err = Pa_StopStream( stream ); err = Pa_StopStream( stream );
if( err != paNoError ) if( err != paNoError )

View file

@ -47,7 +47,7 @@
#include "portaudio.h" #include "portaudio.h"
#define SAMPLE_RATE (44100) #define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (256) #define FRAMES_PER_BUFFER (128)
#define FREQ_INCR (300.0 / SAMPLE_RATE) #define FREQ_INCR (300.0 / SAMPLE_RATE)
#define MAX_CHANNELS (64) #define MAX_CHANNELS (64)