annotate src/portaudio_20161030/test/patest_write_stop_hang_illegal.c @ 56:af97cad61ff0

Add updated build of PortAudio for OSX
author Chris Cannam <cannam@all-day-breakfast.com>
date Tue, 03 Jan 2017 15:10:52 +0000
parents 284acf908dcd
children
rev   line source
Chris@55 1 /** @file patest_write_stop_threads.c
Chris@55 2 @brief Call Pa_StopStream() from another thread to see if PortAudio hangs.
Chris@55 3 @author Bjorn Roche of XO Audio (www.xoaudio.com)
Chris@55 4 @author Ross Bencina
Chris@55 5 @author Phil Burk
Chris@55 6 */
Chris@55 7 /*
Chris@55 8 * $Id$
Chris@55 9 *
Chris@55 10 * This program uses the PortAudio Portable Audio Library.
Chris@55 11 * For more information see: http://www.portaudio.com/
Chris@55 12 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
Chris@55 13 *
Chris@55 14 * Permission is hereby granted, free of charge, to any person obtaining
Chris@55 15 * a copy of this software and associated documentation files
Chris@55 16 * (the "Software"), to deal in the Software without restriction,
Chris@55 17 * including without limitation the rights to use, copy, modify, merge,
Chris@55 18 * publish, distribute, sublicense, and/or sell copies of the Software,
Chris@55 19 * and to permit persons to whom the Software is furnished to do so,
Chris@55 20 * subject to the following conditions:
Chris@55 21 *
Chris@55 22 * The above copyright notice and this permission notice shall be
Chris@55 23 * included in all copies or substantial portions of the Software.
Chris@55 24 *
Chris@55 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@55 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@55 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Chris@55 28 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
Chris@55 29 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@55 30 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@55 31 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@55 32 */
Chris@55 33
Chris@55 34 /*
Chris@55 35 * The text above constitutes the entire PortAudio license; however,
Chris@55 36 * the PortAudio community also makes the following non-binding requests:
Chris@55 37 *
Chris@55 38 * Any person wishing to distribute modifications to the Software is
Chris@55 39 * requested to send the modifications to the original developer so that
Chris@55 40 * they can be incorporated into the canonical version. It is also
Chris@55 41 * requested that these non-binding requests be included along with the
Chris@55 42 * license above.
Chris@55 43 */
Chris@55 44
Chris@55 45 #include <stdio.h>
Chris@55 46 #include <unistd.h>
Chris@55 47 #include <math.h>
Chris@55 48 #include <memory.h>
Chris@55 49 /* pthread may only be available on Mac and Linux. */
Chris@55 50 #include <pthread.h>
Chris@55 51 #include "portaudio.h"
Chris@55 52
Chris@55 53 #define SAMPLE_RATE (44100)
Chris@55 54 #define FRAMES_PER_BUFFER (2048)
Chris@55 55
Chris@55 56 static float s_buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */
Chris@55 57
Chris@55 58 /**
Chris@55 59 * WARNING: PortAudio is NOT thread safe. DO NOT call PortAudio
Chris@55 60 * from multiple threads without synchronization. This test uses
Chris@55 61 * PA in an ILLEGAL WAY in order to try to flush out potential hang bugs.
Chris@55 62 * The test calls Pa_WriteStream() and Pa_StopStream() simultaneously
Chris@55 63 * from separate threads in order to try to cause Pa_StopStream() to hang.
Chris@55 64 * In the main thread we write to the stream in a loop.
Chris@55 65 * Then try stopping PA from another thread to see if it hangs.
Chris@55 66 *
Chris@55 67 * @note: Do not expect this test to pass. The test is only here
Chris@55 68 * as a debugging aid for hang bugs. Since this test uses PA in an
Chris@55 69 * illegal way, it may fail for reasons that are not PA bugs.
Chris@55 70 */
Chris@55 71
Chris@55 72 /* Wait for awhile then abort the stream. */
Chris@55 73 void *stop_thread_proc(void *arg)
Chris@55 74 {
Chris@55 75 PaStream *stream = (PaStream *)arg;
Chris@55 76 PaTime time;
Chris@55 77 for (int i = 0; i < 20; i++)
Chris@55 78 {
Chris@55 79 /* ILLEGAL unsynchronised call to PA, see comment above */
Chris@55 80 time = Pa_GetStreamTime( stream );
Chris@55 81 printf("Stream time = %f\n", time);
Chris@55 82 fflush(stdout);
Chris@55 83 usleep(100 * 1000);
Chris@55 84 }
Chris@55 85 printf("Call Pa_StopStream()\n");
Chris@55 86 fflush(stdout);
Chris@55 87 /* ILLEGAL unsynchronised call to PA, see comment above */
Chris@55 88 PaError err = Pa_StopStream( stream );
Chris@55 89 printf("Pa_StopStream() returned %d\n", err);
Chris@55 90 fflush(stdout);
Chris@55 91
Chris@55 92 return stream;
Chris@55 93 }
Chris@55 94
Chris@55 95 int main(void);
Chris@55 96 int main(void)
Chris@55 97 {
Chris@55 98 PaStreamParameters outputParameters;
Chris@55 99 PaStream *stream;
Chris@55 100 PaError err;
Chris@55 101 int result;
Chris@55 102 pthread_t thread;
Chris@55 103
Chris@55 104 printf( "PortAudio Test: output silence and stop from another thread. SR = %d, BufSize = %d\n",
Chris@55 105 SAMPLE_RATE, FRAMES_PER_BUFFER);
Chris@55 106
Chris@55 107 err = Pa_Initialize();
Chris@55 108 if( err != paNoError ) goto error;
Chris@55 109
Chris@55 110 outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
Chris@55 111 outputParameters.channelCount = 2; /* stereo output */
Chris@55 112 outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
Chris@55 113 outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency * 5;
Chris@55 114 outputParameters.hostApiSpecificStreamInfo = NULL;
Chris@55 115
Chris@55 116 /* open the stream */
Chris@55 117 err = Pa_OpenStream(
Chris@55 118 &stream,
Chris@55 119 NULL, /* no input */
Chris@55 120 &outputParameters,
Chris@55 121 SAMPLE_RATE,
Chris@55 122 FRAMES_PER_BUFFER,
Chris@55 123 paClipOff, /* we won't output out of range samples so don't bother clipping them */
Chris@55 124 NULL, /* no callback, use blocking API */
Chris@55 125 NULL ); /* no callback, so no callback userData */
Chris@55 126 if( err != paNoError ) goto error;
Chris@55 127
Chris@55 128 result = pthread_create(&thread, NULL /* attributes */, stop_thread_proc, stream);
Chris@55 129
Chris@55 130 /* start the stream */
Chris@55 131 err = Pa_StartStream( stream );
Chris@55 132 if( err != paNoError ) goto error;
Chris@55 133
Chris@55 134 /* clear buffer */
Chris@55 135 memset( s_buffer, 0, sizeof(s_buffer) );
Chris@55 136
Chris@55 137 /* play the silent buffer many times */
Chris@55 138 while( Pa_IsStreamActive(stream) > 0 )
Chris@55 139 {
Chris@55 140 err = Pa_WriteStream( stream, s_buffer, FRAMES_PER_BUFFER );
Chris@55 141 printf("Pa_WriteStream returns %d = %s\n", err, Pa_GetErrorText( err ));
Chris@55 142 if( err != paNoError )
Chris@55 143 {
Chris@55 144 err = paNoError;
Chris@55 145 break;
Chris@55 146 };
Chris@55 147 }
Chris@55 148
Chris@55 149 printf("Try to join the thread that called Pa_StopStream().\n");
Chris@55 150 result = pthread_join( thread, NULL );
Chris@55 151 printf("pthread_join returned %d\n", result);
Chris@55 152
Chris@55 153 /* close, and terminate */
Chris@55 154 printf("Call Pa_CloseStream\n");
Chris@55 155 err = Pa_CloseStream( stream );
Chris@55 156 if( err != paNoError ) goto error;
Chris@55 157
Chris@55 158 Pa_Terminate();
Chris@55 159 printf("Test finished.\n");
Chris@55 160
Chris@55 161 return err;
Chris@55 162 error:
Chris@55 163 Pa_Terminate();
Chris@55 164 fprintf( stderr, "An error occured while using the portaudio stream\n" );
Chris@55 165 fprintf( stderr, "Error number: %d\n", err );
Chris@55 166 fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
Chris@55 167 return err;
Chris@55 168 }