예제 #1
0
int jtaudio_(int *ndevin, int *ndevout, short y1[], short y2[], 
	     int *nbuflen, int *iwrite, short iwave[], 
	     int *nwave, int *nfsample, int *nsamperbuf,
	     int *TRPeriod, int *TxOK, int *ndebug,
 	     int *Transmitting, double *Tsec, int *ngo, int *nmode,
	     double tbuf[], int *ibuf, int *ndsec)
{
  paTestData data;
  PaStream *outstream;
  PaStreamParameters outputParameters;

  int nfs,ndin,ndout;
  PaError err1,err2,err2a,err3,err3a;
  double dnfs;

  data.Tsec = Tsec;
  data.tbuf = tbuf;
  data.iwrite = iwrite;
  data.ibuf = ibuf;
  data.TxOK = TxOK;
  data.ndebug = ndebug;
  data.ndsec = ndsec;
  data.Transmitting = Transmitting;
  data.y1 = y1;
  data.y2 = y2;
  data.nbuflen = *nbuflen;
  data.nmode = nmode;
  data.nwave = nwave;
  data.iwave = iwave;
  data.nfs = *nfsample;
  data.trperiod = TRPeriod;

  nfs=*nfsample;
  err1=Pa_Initialize();                      // Initialize PortAudio
  if(err1) {
    printf("Error initializing PortAudio.\n");
    printf("%s\n",Pa_GetErrorText(err1));
    goto error;
  }

  ndin=*ndevin;
  ndout=*ndevout;
  dnfs=(double)nfs;
  printf("Opening device %d for output.\n",ndout);

  outputParameters.device=*ndevout;
  outputParameters.channelCount=2;
  outputParameters.sampleFormat=paInt16;
  outputParameters.suggestedLatency=1.0;
  outputParameters.hostApiSpecificStreamInfo=NULL;
  err2a=Pa_OpenStream(
		       &outstream,      //address of stream
		       NULL,
		       &outputParameters,
		       dnfs,            //Sample rate
		       2048,            //Frames per buffer
		       paNoFlag,
		       SoundOut,        //Callback routine
		       &data);          //address of data structure
  if(err2a) {
    printf("Error opening Audio stream for output.\n");
    printf("%s\n",Pa_GetErrorText(err2a));
    goto error;
  }

  err3a=Pa_StartStream(outstream);             //Start output stream
  if(err3a) {
    printf("Error starting output Audio stream\n");
    printf("%s\n",Pa_GetErrorText(err3a));
    goto error;
  }

  printf("Audio output stream running normally.\n******************************************************************\n");

  while(Pa_IsStreamActive(outstream))  {
    if(*ngo==0) goto StopStream;
    Pa_Sleep(200);
  }

 StopStream:
  Pa_AbortStream(outstream);              // Abort stream
  Pa_CloseStream(outstream);             // Close stream, we're done.
  Pa_Terminate();
  return(0);

error:
  printf("%d  %f  %d  %d  %d\n",ndout,dnfs,err1,err2a,err3a);
  Pa_Terminate();
  return(1);
}
예제 #2
0
파일: rc_test.c 프로젝트: mayrit/crrcsim
int main(void)
{
  //    PortAudioStream *stream;
  //    int inputDevice = Pa_GetDefaultInputDeviceID();
  //    int        i,numDevices;
  //    PaDeviceInfo pdi;


  //    printf("Channel data acquisition configuration test\n");
  //    printf("\n"); fflush(stdout);

  //    numDevices = Pa_CountDevices();
  //    printf(    "Number of total devices : Pa_CountDevices()\t: %d.\n", numDevices );
  //    for( i=0; i<numDevices; i++ ) {
  //        pdi = *Pa_GetDeviceInfo( i );
  //        printf("Device(%d) name  \t: %s.\n", i, pdi.name);
  //        printf("\tMax Inputs   = %d\n", pdi.maxInputChannels  );
  //        printf("\tMax Outputs  = %d\n", pdi.maxOutputChannels  );
  //    }
  //    printf("Default Devic id : %d.\n", Pa_GetDefaultInputDeviceID() );
  int i,numDevices;
  PaDeviceInfo pdi;
  PaError    err;

  err = Pa_Initialize();
  if( err != paNoError )
    goto error;

  numDevices = Pa_CountDevices();
  printf(    "Number of total devices : Pa_CountDevices()\t: %d.\n", numDevices );
  for( i=0; i<numDevices; i++ )
  {
    pdi = *Pa_GetDeviceInfo( i );
    printf("Device(%d) name  \t: %s.\n", i, pdi.name);
    printf("\tMax Inputs   = %d\n", pdi.maxInputChannels  );
    printf("\tMax Outputs  = %d\n", pdi.maxOutputChannels  );
  }
  printf("Default Devic id : %d.\n", Pa_GetDefaultInputDeviceID() );

  Pa_Terminate();
  printf("\n");


  audio_rc_open();

  printf("\nNow display channel acquisition 0 up to 9 during 10seconds!!\n");
  fflush(stdout);


  for( i=0; i<100; i++ )
  {
    Pa_Sleep(100);
    /* launch test */
    audio_rc_test();
    fflush(stdout);
  }

  audio_rc_close();




  return 0;

error:
  Pa_Terminate();
  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 ) );

  return -1;
}
예제 #3
0
int main(int argc, char* argv[])
{
    PaStreamParameters outputParameters;
    PaWinMmeStreamInfo wmmeStreamInfo;
    PaStream *stream;
    PaError err;
    paTestData data;
    int i;
    int deviceIndex;

    printf("PortAudio Test: output a sine blip on each channel. SR = %d, BufSize = %d, Chans = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER, CHANNEL_COUNT);

    err = Pa_Initialize();
    if( err != paNoError ) goto error;

	deviceIndex = Pa_GetDefaultOutputDevice();
	if( argc == 2 ){
		sscanf( argv[1], "%d", &deviceIndex );
	}

	printf( "using device id %d (%s)\n", deviceIndex, Pa_GetDeviceInfo(deviceIndex)->name );

    /* initialise sinusoidal wavetable */
    for( i=0; i<TABLE_SIZE; i++ )
    {
        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
    }

	data.phase = 0;
	data.currentChannel = 0;
	data.cycleCount = 0;

    outputParameters.device = deviceIndex;
    outputParameters.channelCount = CHANNEL_COUNT;
    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;

    /* it's not strictly necessary to provide a channelMask for surround sound
       output. But if you want to be sure which channel mask PortAudio will use
       then you should supply one */
    wmmeStreamInfo.size = sizeof(PaWinMmeStreamInfo);
    wmmeStreamInfo.hostApiType = paMME; 
    wmmeStreamInfo.version = 1;
    wmmeStreamInfo.flags = paWinMmeUseChannelMask;
    wmmeStreamInfo.channelMask = PAWIN_SPEAKER_5POINT1_SURROUND; /* request 5.1 output format */
    outputParameters.hostApiSpecificStreamInfo = &wmmeStreamInfo;


	if( Pa_IsFormatSupported( 0, &outputParameters, SAMPLE_RATE ) == paFormatIsSupported  ){
		printf( "Pa_IsFormatSupported reports device will support %d channels.\n", CHANNEL_COUNT );
	}else{
		printf( "Pa_IsFormatSupported reports device will not support %d channels.\n", CHANNEL_COUNT );
	}

    err = Pa_OpenStream(
              &stream,
              NULL, /* no input */
              &outputParameters,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              patestCallback,
              &data );
    if( err != paNoError ) goto error;

    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;

    printf("Play for %d seconds.\n", NUM_SECONDS );
    Pa_Sleep( NUM_SECONDS * 1000 );

    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;

    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;

    Pa_Terminate();
    printf("Test finished.\n");
    
    return err;
error:
    Pa_Terminate();
    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 ) );
    return err;
}
예제 #4
0
PaError WriteStream( PaStream* stream,
                            const void *buffer,
                            unsigned long framesRequested )
{
    PaMacCoreStream *macStream = (PaMacCoreStream*)stream;
    PaMacBlio *blio = &macStream->blio;
    char *cbuf = (char *) buffer;
    PaError ret = paNoError;
    VVDBUG(("WriteStream()\n"));

    while( framesRequested > 0 && macStream->state != STOPPING ) {
        ring_buffer_size_t framesAvailable;
        ring_buffer_size_t framesToTransfer;
        ring_buffer_size_t framesTransferred;

       do {
          framesAvailable = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
/*
          printf( "Write Buffer is %%%g full: %ld of %ld.\n",
                  100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize,
                  framesAvailable, blio->outputRingBuffer.bufferSize );
*/
          if( framesAvailable == 0 ) {
#ifdef PA_MAC_BLIO_MUTEX
             /*block while full*/
             ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) );
             if( ret )
                return ret;
             while( blio->isOutputFull ) {
                ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) );
                if( ret )
                   return ret;
             }
             ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) );
             if( ret )
                return ret;
#else
             Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
#endif
          }
       } while( framesAvailable == 0 && macStream->state != STOPPING );

       if( macStream->state == STOPPING )
       {
           break;
       }

       framesToTransfer = MIN( framesAvailable, framesRequested );
       framesTransferred = PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, framesToTransfer );
       cbuf += framesTransferred * blio->outputSampleSizeActual * blio->outChan;
       framesRequested -= framesTransferred;

#ifdef PA_MAC_BLIO_MUTEX
       if( framesToTransfer == framesAvailable ) {
          /* we just filled up the buffer, so we need to mark it as filled. */
          ret = blioSetIsOutputFull( blio, true );
          if( ret )
             return ret;
          /* of course, in the meantime, we may have emptied the buffer, so
             so check for that, too, to avoid a race condition. */
          if( PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) ) {
             blioSetIsOutputFull( blio, false );
              /* FIXME remove or review this code, does not fix race, ret not set! */
             if( ret )
                return ret;
          }
       }
#endif
    }

    if ( macStream->state == STOPPING )
    {
        ret = paInternalError;
    }
    else if (ret == paNoError )
    {
        /*   Test for underflow. */
        ret = blio->statusFlags & paOutputUnderflow;

        /* report underflow only once: */
        if( ret )
        {
            OSAtomicAnd32( (uint32_t)(~paOutputUnderflow), &blio->statusFlags );
            ret = paOutputUnderflowed;
        }
    }

    return ret;
}
예제 #5
0
int main(void)
{	    
	//printf("InfiniteLooper--based on patest_record.c\n"); //fflush(stdout);
	//Record for a few seconds. 
	data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; 
	data.frameIndex = 0;
	numSamples = totalFrames * NUM_CHANNELS;
	numBytes = numSamples * sizeof(SAMPLE);
	// From now on, recordedSamples is initialised.
	// 5 minutes of record buffer allocated 5% of free
	// on rPi zero. could record 90 minutes on rPi 0  
	//++++++++++++++++++++++++++++++++++++++++++++++++++++
	data.recordedSamples = (SAMPLE*) malloc( numBytes ); 
	//++++++++++++++++++++++++++++++++++++++++++++++++++++
	if( data.recordedSamples == NULL )
	{
		//printf("Could not allocate record array.\n");
		goto done;
	}
	else
	{
		//printf("allocated %d bytes\n", numBytes );
	}
		
	ringbufferWPTR = 0;
	ringbufferRPTR = 0;
    all_complete = FALSE;
    // ******************************************
    doState(S_INIT, data.recordedSamples);	
    // ******************************************
		
	// we do the recording set-up just once and cycle power
	// to do it again. This initialization should be moved to
	// ilooper_audio if multiple recordings are implemented
	
	err = Pa_Initialize();
	if( err != paNoError ) goto done;
	// default input device 
	inputParameters.device = Pa_GetDefaultInputDevice(); 
	if (inputParameters.device == paNoDevice) {
		fprintf(stderr,"Error: No default input device.\n");
		goto done;
	}
	inputParameters.channelCount = 2;                    //stereo input 
	inputParameters.sampleFormat = PA_SAMPLE_TYPE;
	inputParameters.suggestedLatency = 
	Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
	inputParameters.hostApiSpecificStreamInfo = NULL;
	
	//Record some audio. -------------------------------------------- 
	err = Pa_OpenStream
	(
	 &stream,
	 &inputParameters,
	 NULL,                  // &outputParameters, 
	 SAMPLE_RATE,           // ADC sample rate is a constant
	 FRAMES_PER_BUFFER,
	 //we won't output out of range samples so 
	 //don't bother clipping them 
	 //paClipOff, 
	 // ***wm6h for this app, let's clip
	 paNoFlag,
	 recordCallback,
	 &data 
	 );
	
	if( err != paNoError ) goto done;
	
	// the output sample rate is checked in playback()
	err = Pa_IsFormatSupported( &inputParameters, NULL, SAMPLE_RATE );
	if( err == paFormatIsSupported )
	{
		//printf("\n ADC samplerate is supported %d, FPB %d\n", \
		//         SAMPLE_RATE, FRAMES_PER_BUFFER);
	}
	else
	{
		//printf("\n ADC samplerate is NOT supported\n");
		goto done;
	}
	
	//printf(" %s\n", Pa_GetVersionText());	
	
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
	//GPIO-0 access for Green LED and test
    //rPi J8-11 and gnd J8-6
    if(wiringPiSetup () < 0 )
    {
		fprintf(stderr, "Unable to setup wiringPi: %s\n", strerror(errno));
		return 1;
    }
    pinMode (LED_PIN, OUTPUT) ;
    digitalWrite (LED_PIN,  OFF) ;
    pinMode (BUTTON_PIN, INPUT) ;
    //pullUpDnControl(BUTTON_PIN, PUD_OFF);
    pullUpDnControl(BUTTON_PIN, PUD_UP);
    pinMode (DIRECTION_PIN, INPUT) ;
    pullUpDnControl(DIRECTION_PIN, PUD_UP); 
    pinMode (REBOOT_PIN, INPUT) ;
    pullUpDnControl(REBOOT_PIN, PUD_UP);
    
    
    pinMode (ERROR_PIN, OUTPUT) ;
    digitalWrite (ERROR_PIN, OFF) ;
   
    sync();
   
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
	
	// underway--shift ship's colors--all ahead 8K sps
	// 
	err = Pa_StartStream( stream );
	if( err != paNoError ) goto done;

// =============================================================================	
// =============================================================================	
// collecting samples phase
    // ******************************************
    doState(S_COLLECTING, data.recordedSamples);	
    // ******************************************
	
	// we are running the callbacks
	while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
	{
		Pa_Sleep(500);
						
		if(buttonPress == TRUE)
		{
			Pa_Sleep(100);
			all_complete = TRUE; //stop the sample interrupt, exit while loop
		}
		else
		{	
		    // no button press
		    // give the state machine a chance to run	 
        // ******************************************
			doState(currentSTATE, (void*) NULL);	
	    // ******************************************		
		}
	}
// =============================================================================	
// =============================================================================	
	
	if( err < 0 ) goto done;
	// all stop
	err = Pa_CloseStream( stream );
	if( err != paNoError ) goto done;
	
	buttonValue = digitalRead(BUTTON_PIN);
	//printf("button = %d\n", buttonValue); 
	
	if(buttonValue == 0)
	{ 
		//if button still pressed, it's a hold
		buttonHold = TRUE;        
		//printf("button hold\n"); //fflush(stdout);
	}
	else
	{  //else, it's a button press
		buttonPress = FALSE; //acknowledged, reset flag
		//printf("button pressed\n"); //fflush(stdout);					 			
	}
	
	
	// Measure maximum peak amplitude. 
	// we could indicate over-driving/clipping the audio
	// or AGC it
	max = 0;
	average = 0.0;
	for( i=0; i<numSamples; i++ )
	{
		val = data.recordedSamples[i];
		if( val < 0 ) val = -val; // ABS 
		if( val > max )
		{
			max = val;
		}
		average += val;
	}
	
	average = average / (double)numSamples;
	
	//printf("sample max amplitude = "PRINTF_S_FORMAT"\n", max );
	//printf("sample average = %lf\n", average );
	
	
	// Write recorded data to a file. 
#if WRITE_TO_FILE
	{   // the file size should be 5 minutes of 8K samples * 2
	    // the entire ring buffer is recorded without regard to the 
	    // read/write pointers. Make sense of the file by editing it in
	    // Audacity
	    // todo: write the file in correct time order using rd/wr pointers
		FILE  *fid;				
		fid = fopen("recorded.raw", "wb");
		if( fid == NULL )
		{
			//printf("Could not open file.");
		}
		else
		{
			fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), 
				   totalFrames, fid );
			fclose( fid );
			//printf("Wrote data to 'recorded.raw'\n");
		}
	}
#endif
	

// initial state after recording
// all future state changes from within state machine
    if(buttonHold == FALSE)
    {
        // ******************************************
		doState(S_REWIND_10, (void*) NULL);
		// ******************************************	   
    }
    else
    {
        // ******************************************
		doState(S_REWIND_PLAYBACK, (void*) NULL);	
		// ******************************************    
    }
// |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||	
// |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||	
    while (1)
    {
        // advance state in the state machine
        // ******************************************
		doState(currentSTATE, (void*) NULL);    
		// ******************************************	
		Pa_Sleep(100);
		if(terminate != FALSE)
		 goto done;
		 
    }
// |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||	
// |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
	
	
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 ) );
		
		fatalError();
		
		err = 1;          // Always return 0 or 1, but no other return codes. 
	}
	return err;
}
int main(void)
{
    PaStreamParameters outputParameters;
    PaStream *stream;
    PaError err;
    TestData data;
    int i, j;


    printf( "PortAudio Test: output sine wave. SR = %d, BufSize = %d\n",
            SAMPLE_RATE, FRAMES_PER_BUFFER );

    /* initialise sinusoidal wavetable */
    for( i=0; i<TABLE_SIZE; i++ )
    {
        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
    }

    err = Pa_Initialize();
    if( err != paNoError ) goto error;

    outputParameters.device                    = Pa_GetDefaultOutputDevice();
    outputParameters.channelCount              = 2;               /* stereo output */
    outputParameters.sampleFormat              = paFloat32;       /* 32 bit floating point output */
    outputParameters.suggestedLatency          = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;

    err = Pa_OpenStream(
              &stream,
              NULL, /* no input */
              &outputParameters,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,      /* output will be in-range, so no need to clip */
              TestCallback,
              &data );
    if( err != paNoError ) goto error;

    printf("Repeating test %d times.\n", NUM_LOOPS );

    for( i=0; i < NUM_LOOPS; ++i )
    {
        data.phase = 0;
        data.generatedFramesCount = 0;
        data.callbackReturnedPaComplete = 0;
        data.callbackInvokedAfterReturningPaComplete = 0;

        err = Pa_StartStream( stream );
        if( err != paNoError ) goto error;

        printf("Play for %d seconds.\n", NUM_SECONDS );

        /* wait for the callback to complete generating NUM_SECONDS of tone */

        do
        {
            Pa_Sleep( 500 );
        }
        while( !data.callbackReturnedPaComplete );

        printf( "Callback returned paComplete.\n" );
        printf( "Waiting for buffers to finish playing...\n" );

        /* wait for stream to become inactive,
           or for a timeout of approximately NUM_SECONDS
         */

        j = 0;
        while( (err = Pa_IsStreamActive( stream )) == 1 && j < NUM_SECONDS * 2 )
        {
            printf(".\n" );
            Pa_Sleep( 500 );
            ++j;
        }

        if( err < 0 )
        {
            goto error;
        }
        else if( err == 1 )
        {
            printf( "TEST FAILED: Timed out waiting for buffers to finish playing.\n" );
        }
        else
        {
            printf("Buffers finished.\n" );
        }

        if( data.callbackInvokedAfterReturningPaComplete )
        {
            printf( "TEST FAILED: Callback was invoked after returning paComplete.\n" );
        }


        err = Pa_StopStream( stream );
        if( err != paNoError ) goto error;
    }

    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;

    Pa_Terminate();
    printf("Test finished.\n");

    return err;
error:
    Pa_Terminate();
    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 ) );
    return err;
}
예제 #7
0
PaError WriteStream( PaStream* stream,
                            const void *buffer,
                            unsigned long frames )
{
    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
    char *cbuf = (char *) buffer;
    PaError ret = paNoError;
    VVDBUG(("WriteStream()\n"));

    while( frames > 0 ) {
       long avail = 0;
       long toWrite;

       do {
          avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
/*
          printf( "Write Buffer is %%%g full: %ld of %ld.\n",
                  100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize,
                  avail, blio->outputRingBuffer.bufferSize );
*/
          if( avail == 0 ) {
#ifdef PA_MAC_BLIO_MUTEX
             /*block while full*/
             ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) );
             if( ret )
                return ret;
             while( blio->isOutputFull ) {
                ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) );
                if( ret )
                   return ret;
             }
             ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) );
             if( ret )
                return ret;
#else
             Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
#endif
          }
       } while( avail == 0 );

       toWrite = MIN( avail, frames * blio->outputSampleSizeActual * blio->outChan );
       toWrite -= toWrite % blio->outputSampleSizeActual * blio->outChan ;
       PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, toWrite );
       cbuf += toWrite;
       frames -= toWrite / ( blio->outputSampleSizeActual * blio->outChan );

#ifdef PA_MAC_BLIO_MUTEX
       if( toWrite == avail ) {
          /* we just filled up the buffer, so we need to mark it as filled. */
          ret = blioSetIsOutputFull( blio, true );
          if( ret )
             return ret;
          /* of course, in the meantime, we may have emptied the buffer, so
             so check for that, too, to avoid a race condition. */
          if( PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) ) {
             blioSetIsOutputFull( blio, false );
             if( ret )
                return ret;
          }
       }
#endif
    }

    /*   Report either paNoError or paOutputUnderflowed. */
    /*   may also want to report other errors, but this is non-standard. */
    ret = blio->statusFlags & paOutputUnderflow;

    /* report underflow only once: */
    if( ret ) {
      OSAtomicAnd32( (uint32_t)(~paOutputUnderflow), &blio->statusFlags );
      ret = paOutputUnderflowed;
    }

    return ret;
}
예제 #8
0
int main(void)
{
    PaStreamParameters outputParameters;
    PaStream *stream;
    PaError err;
    paTestData data;
    int i;

    
    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
    
    /* initialise sinusoidal wavetable */
    for( i=0; i<TABLE_SIZE; i++ )
    {
        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
    }
    data.left_phase = data.right_phase = 0;
    
    err = Pa_Initialize();
    if( err != paNoError ) goto error;

    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
    outputParameters.channelCount = 2;       /* stereo output */
    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;

    err = Pa_OpenStream(
              &stream,
              NULL, /* no input */
              &outputParameters,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              patestCallback,
              &data );
    if( err != paNoError ) goto error;

    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;

    printf("Play for %d seconds.\n", NUM_SECONDS );
    Pa_Sleep( NUM_SECONDS * 1000 );

    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;

    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;

    Pa_Terminate();
    printf("Test finished.\n");
    
    return err;
error:
    Pa_Terminate();
    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 ) );
    return err;
}
예제 #9
0
파일: jpa.c 프로젝트: rjeschke/jpa
JNIEXPORT void JNICALL Java_com_github_rjeschke_jpa_JPA_sleep(JNIEnv *env, jclass clazz, jlong msec)
{
    Pa_Sleep((long int)msec);
}
예제 #10
0
int main(void)
{
	PortAudioStream *stream;
	PaError    err;
	mute=false;

	bool quit;
	char ch;

	printf("A sample on how to use RakVoice. You need a microphone for this sample.\n");
	printf("RakVoice relies on Speex for voice encoding and decoding.\n");
	printf("See DependentExtensions/RakVoice/speex-1.1.12 for speex projects.\n");
	printf("For windows, I had to define HAVE_CONFIG_H, include win32/config.h,\n");
	printf("and include the files under libspeex, except those that start with test.\n");
	printf("PortAudio is also included and is used to read and write audio data.  You\n");
	printf("can substitute whatever you want if you do not want to use portaudio.\n");
	printf("Difficulty: Advanced\n\n");

	// Since voice is peer to peer, we give the option to use the nat punchthrough client if desired.
	RakNet::NatPunchthroughClient natPunchthroughClient;
	char port[256];
	rakPeer = RakNet::RakPeerInterface::GetInstance();
	printf("Enter local port (enter for default): ");
	Gets(port, sizeof(port));
	if (port[0]==0)
		strcpy(port, "60000");
	RakNet::SocketDescriptor socketDescriptor(atoi(port),0);
	rakPeer->Startup(4, &socketDescriptor, 1);
	rakPeer->SetMaximumIncomingConnections(4);
	rakPeer->AttachPlugin(&rakVoice);
	rakPeer->AttachPlugin(&natPunchthroughClient);
	rakVoice.Init(SAMPLE_RATE, FRAMES_PER_BUFFER*sizeof(SAMPLE));

	err = Pa_Initialize();
	if( err != paNoError ) goto error;
	
	err = Pa_OpenStream(
		&stream,
		Pa_GetDefaultInputDeviceID(),
		1, // Num channels, whatever that means
		PA_SAMPLE_TYPE,
		NULL,
		Pa_GetDefaultOutputDeviceID(),
		1, // Num channels
		PA_SAMPLE_TYPE,
		NULL,
		SAMPLE_RATE,
		FRAMES_PER_BUFFER,            /* frames per buffer */
		0,               /* number of buffers, if zero then use default minimum */
		0, /* paDitherOff, // flags */
		PACallback,
		0 );

	if( err != paNoError ) goto error;

	err = Pa_StartStream( stream );
	if( err != paNoError ) goto error;

	printf("Support NAT punchthrough? (y/n)? ");
	bool useNatPunchthrough;
	useNatPunchthrough=(getche()=='y');
	printf("\n");
	char facilitatorIP[256];
	{//Linux fix. Won't compile without it. Because of the goto error above, the scope is ambigious. Make it a block to define that it will not be used after the jump.
	//Doesn't change current logic
	RakNet::SystemAddress facilitator;
	if (useNatPunchthrough)
	{
		printf("My GUID is %s\n", rakPeer->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString());

		printf("Enter IP of facilitator (enter for default): ");
		Gets(facilitatorIP,sizeof(facilitatorIP));
		if (facilitatorIP[0]==0)
			strcpy(facilitatorIP, "natpunch.jenkinssoftware.com");
		facilitator.FromString(facilitatorIP);
		facilitator.SetPortHostOrder(NAT_PUNCHTHROUGH_FACILITATOR_PORT);
		rakPeer->Connect(facilitatorIP, NAT_PUNCHTHROUGH_FACILITATOR_PORT, 0, 0);
		printf("Connecting to facilitator...\n");
	}
	else
	{
		printf("Not supporting NAT punchthrough.\n");
	}


    
	RakNet::Packet *p;
	quit=false;
	if (useNatPunchthrough==false)
		printf("(Q)uit. (C)onnect. (D)isconnect. C(l)ose voice channels. (M)ute. ' ' for stats.\n");

	while (!quit)
	{
		if (kbhit())
		{
			ch=getch();
			if (ch=='y')
			{
				quit=true;
			}
			else if (ch=='c')
			{
				if (useNatPunchthrough)
				{
					RakNet::RakNetGUID destination;
					printf("Enter GUID of destination: ");
					char guidStr[256];
					while (1)
					{
						Gets(guidStr,sizeof(guidStr));
						if (!destination.FromString(guidStr))
							printf("Invalid GUID format. Try again.\nEnter GUID of destination: ");
						else
							break;
					}
					printf("Starting NAT punch. Please wait...\n");
					natPunchthroughClient.OpenNAT(destination,facilitator);
				}
				else
				{
					char ip[256];
					printf("Enter IP of remote system: ");
					Gets(ip, sizeof(ip));
					if (ip[0]==0)
						strcpy(ip, "127.0.0.1");
					printf("Enter port of remote system: ");
					Gets(port, sizeof(port));
					if (port[0]==0)
						strcpy(port, "60000");
					rakPeer->Connect(ip, atoi(port), 0,0);

				}
			}
			else if (ch=='m')
			{
				mute=!mute;
				if (mute)
					printf("Now muted.\n");
				else
					printf("No longer muted.\n");
			}
			else if (ch=='d')
			{
				rakPeer->Shutdown(100,0);
			}
			else if (ch=='l')
			{
				rakVoice.CloseAllChannels();
			}
			else if (ch==' ')
			{
				char message[2048];
				RakNet::RakNetStatistics *rss=rakPeer->GetStatistics(rakPeer->GetSystemAddressFromIndex(0));
				StatisticsToString(rss, message, 2);
				printf("%s", message);
			}
			else if (ch=='q')
				quit=true;
			ch=0;
		}

		p=rakPeer->Receive();
		while (p)
		{
			if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED)
			{
				if (p->systemAddress==facilitator)
				{
					printf("Connection to facilitator completed\n");
					printf("(Q)uit. (C)onnect. (D)isconnect. (M)ute. ' ' for stats.\n");
				}
				else
				{
					printf("ID_CONNECTION_REQUEST_ACCEPTED from %s\n", p->systemAddress.ToString());
					rakVoice.RequestVoiceChannel(p->guid);
				}
			}
			else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED)
			{
				if (p->systemAddress==facilitator)
				{
					printf("Connection to facilitator failed. Using direct connections\n");
					useNatPunchthrough=false;
					printf("(Q)uit. (C)onnect. (D)isconnect. (M)ute. ' ' for stats.\n");
				}
				else
				{
					printf("ID_CONNECTION_ATTEMPT_FAILED\n");
				}
			}
			else if (p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REQUEST || p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REPLY)
			{
				printf("Got new channel from %s\n", p->systemAddress.ToString());
			}
			else if (p->data[0]==ID_NAT_TARGET_NOT_CONNECTED)
			{
				RakNet::RakNetGUID g;
				RakNet::BitStream b(p->data, p->length, false);
				b.IgnoreBits(8); // Ignore the ID_...
				b.Read(g);
				printf("ID_NAT_TARGET_NOT_CONNECTED for %s\n", g.ToString());
			}
			else if (p->data[0]==ID_NAT_TARGET_UNRESPONSIVE)
			{
				RakNet::RakNetGUID g;
				RakNet::BitStream b(p->data, p->length, false);
				b.IgnoreBits(8); // Ignore the ID_...
				b.Read(g);
				printf("ID_NAT_TARGET_UNRESPONSIVE for %s\n", g.ToString());
			}
			else if (p->data[0]==ID_NAT_CONNECTION_TO_TARGET_LOST)
			{
				RakNet::RakNetGUID g;
				RakNet::BitStream b(p->data, p->length, false);
				b.IgnoreBits(8); // Ignore the ID_...
				b.Read(g);
				printf("ID_NAT_CONNECTION_TO_TARGET_LOST for %s\n", g.ToString());
			}
			else if (p->data[0]==ID_NAT_ALREADY_IN_PROGRESS)
			{
				RakNet::RakNetGUID g;
				RakNet::BitStream b(p->data, p->length, false);
				b.IgnoreBits(8); // Ignore the ID_...
				b.Read(g);
				printf("ID_NAT_ALREADY_IN_PROGRESS for %s\n", g.ToString());
			}
			else if (p->data[0]==ID_NAT_PUNCHTHROUGH_FAILED)
			{
				printf("ID_NAT_PUNCHTHROUGH_FAILED for %s\n", p->guid.ToString());
			}
			else if (p->data[0]==ID_NAT_PUNCHTHROUGH_SUCCEEDED)
			{
				printf("ID_NAT_PUNCHTHROUGH_SUCCEEDED for %s. Connecting...\n", p->guid.ToString());
				rakPeer->Connect(p->systemAddress.ToString(false),p->systemAddress.GetPort(),0,0);
			}
			else if (p->data[0]==ID_ALREADY_CONNECTED)
			{
				printf("ID_ALREADY_CONNECTED\n");
			}
			else if (p->data[0]==ID_RAKVOICE_CLOSE_CHANNEL)
			{
				printf("ID_RAKVOICE_CLOSE_CHANNEL\n");
			}
			else if (p->data[0]==ID_DISCONNECTION_NOTIFICATION)
			{
				printf("ID_DISCONNECTION_NOTIFICATION\n");
			}
			else if (p->data[0]==ID_NEW_INCOMING_CONNECTION)
			{
				printf("ID_NEW_INCOMING_CONNECTION\n");
			}
			else
			{
				printf("Unknown packet ID %i\n", p->data[0]);
			}


			rakPeer->DeallocatePacket(p);
			p=rakPeer->Receive();
		}


		Pa_Sleep( 30 );
	}
	}

	err = Pa_CloseStream( stream );
	if( err != paNoError ) goto error;

	Pa_Terminate();

	rakPeer->Shutdown(300);
	RakNet::RakPeerInterface::DestroyInstance(rakPeer);

	return 0;

error:
	Pa_Terminate();
	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 ) );
	return -1;
}
예제 #11
0
int audioPlayRec( int playdevID, SAMPLE * playbuffer, int playbuflen, int playbuffirstchannel, int playbuflastchannel, int recdevID, SAMPLE * recbuffer, int recbuflen, int recbuffirstchannel, int recbuflastchannel, char * recCallbackName, int samplerate )
{
    paAudioData audio;
    mxArray * precRingArray = NULL;

    audio.recMode = PLAYREC_NONE;

    audio.playBuffer = NULL;
    audio.playBufLen = 0;
    audio.playBufPos = 0;
    audio.playFirstChannel = 0;
    audio.playChannels = 0;
    audio.playDevChannels = 0;

    audio.recBuffer = NULL;
    audio.recBufLen = 0;
    audio.recBufWritePos = 0;
    audio.recBufReadPos = 0;
    audio.recFirstChannel = 0;
    audio.recChannels = 0;
    audio.recDevChannels = 0;

    if( playdevID != paNoDevice && playbuffer != NULL && playbuflen > 0 && playbuffirstchannel >= 0 && playbuflastchannel >= playbuffirstchannel )
    {
        int playChannels = playbuflastchannel - playbuffirstchannel + 1;

        audio.recMode |= PLAYREC_PLAY;

        audio.playBuffer = playbuffer;
        audio.playBufLen = playbuflen / playChannels;		// just only one channel samples
        audio.playFirstChannel = playbuffirstchannel;
        audio.playChannels = playChannels;
    }

    if( recdevID != paNoDevice && playbuffirstchannel >= 0 && recbuflastchannel >= recbuffirstchannel )
    {
        int recChannels = recbuflastchannel - recbuffirstchannel + 1;

        if( recbuffer != NULL && recbuflen > 0 )
        {
            audio.recMode |= PLAYREC_REC;

            audio.recBuffer = recbuffer;
            audio.recBufLen = recbuflen / recChannels;		// just only one channel samples
            audio.recFirstChannel = recbuffirstchannel;
            audio.recChannels = recChannels;
        }
        else if( recCallbackName != NULL )
        {
            int recBufferLength = samplerate * 2;			// 2 seconds ring buffer

            precRingArray = mxCreateNumericMatrix( recBufferLength, recChannels, SAMPLE_CLASSID, mxREAL );
            SAMPLE * recBuf = (SAMPLE *)mxGetData( precRingArray );
            if( recBuf != NULL )
            {
                audio.recMode |= PLAYREC_REC;

                audio.recBuffer = recBuf;
                audio.recBufLen = recBufferLength;			// just only one channel samples
                audio.recFirstChannel = recbuffirstchannel;
                audio.recChannels = recChannels;
            }
        }
    }

    if( audio.recMode == PLAYREC_NONE )
    {
        errorPrintf( ( "Playback and Recording parameters is wrong!\n" ) );
        return paNoError;
    }

    PaStreamParameters inputParameters, outputParameters;
    PaStreamParameters *pinputParameters, *poutputParameters;
    PaStream *stream;
    PaError err;

    err = Pa_Initialize();
    if( err != paNoError )
        goto error;

    if( audio.recMode & PLAYREC_PLAY )
    {
        poutputParameters = &outputParameters;

        outputParameters.device = playdevID;
        outputParameters.channelCount = Pa_GetDeviceInfo( outputParameters.device )->maxOutputChannels;
        outputParameters.sampleFormat = SAMPLE_FORMAT;
        outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
        outputParameters.hostApiSpecificStreamInfo = NULL;

        audio.playDevChannels = outputParameters.channelCount;
    }
    else
        poutputParameters = NULL;

    if( audio.recMode & PLAYREC_REC )
    {
        pinputParameters = &inputParameters;

        inputParameters.device = recdevID;
        inputParameters.channelCount = Pa_GetDeviceInfo( inputParameters.device )->maxInputChannels;
        inputParameters.sampleFormat = SAMPLE_FORMAT;
        inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
        inputParameters.hostApiSpecificStreamInfo = NULL;

        audio.recDevChannels = inputParameters.channelCount;
    }
    else
        pinputParameters = NULL;

    err = Pa_OpenStream( &stream,
                        pinputParameters,
                        poutputParameters,
                        samplerate,
                        FRAMES_PER_BUFFER,
                        paNoFlag,
                        paCallback,
                        &audio );
    if( err != paNoError )
        goto error;

    err = Pa_StartStream( stream );
    if( err != paNoError )
        goto error;

    while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
    {
        if( recCallbackName != NULL )
        {
            bool stop = false;

            while( getRecDataLen( &audio ) >= FRAMES_PER_BUFFER )	// recording data is more than FRAMES_PER_BUFFER
            {
                mxArray * pdataArray = mxCreateNumericMatrix( FRAMES_PER_BUFFER, audio.recChannels, SAMPLE_CLASSID, mxREAL );
                mxArray * presultArray = NULL;

                SAMPLE * dataBuf = (SAMPLE *)mxGetData( pdataArray );
                if( dataBuf != NULL )
                {
                    for( int index = 0; index < FRAMES_PER_BUFFER; index++ )	// frame
                    {
                        for( int channel = 0; channel < audio.recChannels; channel++ )	// channel
                        {
                            *(dataBuf + FRAMES_PER_BUFFER * channel + index) = *(audio.recBuffer + audio.recBufLen * channel + audio.recBufReadPos);
                        }
                        if( nextReadPos( &audio ) == -1 )
                            break;
                    }

                    mexCallMATLAB( 1, &presultArray, 1, &pdataArray, recCallbackName );

                    if( !mxIsDouble( presultArray ) || mxGetPr( presultArray ) == NULL || ((int)*mxGetPr( presultArray )) != 0 )	// return 0 should be continue, others should be stop
                        stop = true;
                }

                if( presultArray != NULL )
                    mxDestroyArray( presultArray );
                if( pdataArray != NULL )
                    mxDestroyArray( pdataArray );

                if( stop )	break;	// recording stop
            }

            if( stop )	break;	// recording stop

            Pa_Sleep( (FRAMES_PER_BUFFER * 1000) / samplerate );
        }
        else
            Pa_Sleep( 50 );
    }
    if( err < 0 )
        goto error;

    err = Pa_StopStream( stream );
    if( err != paNoError )
        goto error;

    err = Pa_CloseStream( stream );
    if( err != paNoError )
        goto error;

    Pa_Terminate();

    if( precRingArray != NULL )
        mxDestroyArray( precRingArray );

    return err;

error:
    Pa_Terminate();

    errorPrintf( ( "Error number: %d\n", err ) );
    errorPrintf( ( "Error message: %s\n", Pa_GetErrorText(err) ) );

    if( precRingArray != NULL )
        mxDestroyArray( precRingArray );

    return err;
}
예제 #12
0
int main(void)
{
    PaError err;
    PortAudioStream *stream1;
    PortAudioStream *stream2;
    paTestData data1 = {0};
    paTestData data2 = {0};
    printf("PortAudio Test: two rates.\n" );

    err = Pa_Initialize();
    if( err != paNoError ) goto error;

    /* Start first stream. **********************/
    err = Pa_OpenStream(
              &stream1,
              paNoDevice, /* default input device */
              0,              /* no input */
              paFloat32,  /* 32 bit floating point input */
              NULL,
              OUTPUT_DEVICE,
              2,          /* Stereo */
              paFloat32,  /* 32 bit floating point output */
              NULL,
              SAMPLE_RATE_1,
              FRAMES_PER_BUFFER,  /* frames per buffer */
              0,    /* number of buffers, if zero then use default minimum */
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              patestCallback,
              &data1 );
    if( err != paNoError ) goto error;

    err = Pa_StartStream( stream1 );
    if( err != paNoError ) goto error;

    Pa_Sleep( 3 * 1000 );

    /* Start second stream. **********************/
    err = Pa_OpenStream(
              &stream2,
              paNoDevice, /* default input device */
              0,              /* no input */
              paFloat32,  /* 32 bit floating point input */
              NULL,
              OUTPUT_DEVICE,
              2,          /* Stereo */
              paFloat32,  /* 32 bit floating point output */
              NULL,
              SAMPLE_RATE_2,
              FRAMES_PER_BUFFER,  /* frames per buffer */
              0,    /* number of buffers, if zero then use default minimum */
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              patestCallback,
              &data2 );
    if( err != paNoError ) goto error;

    err = Pa_StartStream( stream2 );
    if( err != paNoError ) goto error;

    Pa_Sleep( 3 * 1000 );

    err = Pa_StopStream( stream2 );
    if( err != paNoError ) goto error;

    Pa_Sleep( 3 * 1000 );

    err = Pa_StopStream( stream1 );
    if( err != paNoError ) goto error;

    Pa_CloseStream( stream2 );
    Pa_CloseStream( stream1 );

    Pa_Terminate();
    printf("Test finished.\n");
    return err;
error:
    Pa_Terminate();
    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 ) );
    return err;
}
예제 #13
0
int main(void)
{
    PortAudioStream *stream;
    PaError err;
    paTestData data;
    int i;
    int timeout;
    
    printf("Play different tone sine waves that alternate between left and right channel.\n");
    printf("The low tone should be on the left channel.\n");
    
    /* initialise sinusoidal wavetable */
    for( i=0; i<TABLE_SIZE; i++ )
    {
        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
    }
    data.left_phase = data.right_phase = data.toggle = 0;
    data.countDown = SAMPLE_RATE;

    err = Pa_Initialize();
    if( err != paNoError ) goto error;
    
    err = Pa_OpenStream(
              &stream,
              paNoDevice,/* default input device */
              0,              /* no input */
              paFloat32,  /* 32 bit floating point input */
              NULL,
              Pa_GetDefaultOutputDeviceID(), /* default output device */
              2,          /* stereo output */
              paFloat32,      /* 32 bit floating point output */
              NULL,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,            /* frames per buffer */
              0,              /* number of buffers, if zero then use default minimum */
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              patestCallback,
              &data );
    if( err != paNoError ) goto error;
    
    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;
    
    printf("Play for several seconds.\n");
    timeout = NUM_SECONDS * 4;
    while( timeout > 0 )
    {
        Pa_Sleep( 300 );
        timeout -= 1;
    }

    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;
    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;
    Pa_Terminate();
    printf("Test finished.\n");
    return err;
error:
    Pa_Terminate();
    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 ) );
    return err;
}
예제 #14
0
int main(void)
{
    PaStreamParameters outputParameters;
    PaStream *stream;
    PaError err;
    TestData data;
    float writeBuffer[ FRAMES_PER_BUFFER * 2 ];
    
    printf("PortAudio Test: check that stopping stream plays out all queued samples. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);

    InitTestSignalGenerator( &data );
    
    err = Pa_Initialize();
    if( err != paNoError ) goto error;

    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
    outputParameters.channelCount = 2;       /* stereo output */
    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;

/* test paComplete ---------------------------------------------------------- */

    ResetTestSignalGenerator( &data );

    err = Pa_OpenStream(
              &stream,
              NULL, /* no input */
              &outputParameters,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              TestCallback1,
              &data );
    if( err != paNoError ) goto error;

    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;


    printf("\nPlaying 'tone-blip' %d times using callback, stops by returning paComplete from callback.\n", NUM_REPEATS );
    printf("If final blip is not intact, callback+paComplete implementation may be faulty.\n\n" );

    while( (err = Pa_IsStreamActive( stream )) == 1 )
        Pa_Sleep( 5 );

    if( err != 0 ) goto error;

    
    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;

    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;

    Pa_Sleep( 500 );

/* test Pa_StopStream() with callback --------------------------------------- */

    ResetTestSignalGenerator( &data );

    testCallback2Finished = 0;
    
    err = Pa_OpenStream(
              &stream,
              NULL, /* no input */
              &outputParameters,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              TestCallback2,
              &data );
    if( err != paNoError ) goto error;

    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;


    printf("\nPlaying 'tone-blip' %d times using callback, stops by calling Pa_StopStream.\n", NUM_REPEATS );
    printf("If final blip is not intact, callback+Pa_StopStream implementation may be faulty.\n\n" );

    /* note that polling a volatile flag is not a good way to synchronise with
        the callback, but it's the best we can do portably. */
    while( !testCallback2Finished )
        Pa_Sleep( 2 );

    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;
    

    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;

    Pa_Sleep( 500 );

/* test Pa_StopStream() with Pa_WriteStream --------------------------------- */

    ResetTestSignalGenerator( &data );

    err = Pa_OpenStream(
              &stream,
              NULL, /* no input */
              &outputParameters,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              NULL, /* no callback, use blocking API */
              NULL ); /* no callback, so no callback userData */
    if( err != paNoError ) goto error;

    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;


    printf("\nPlaying 'tone-blip' %d times using Pa_WriteStream, stops by calling Pa_StopStream.\n", NUM_REPEATS );
    printf("If final blip is not intact, Pa_WriteStream+Pa_StopStream implementation may be faulty.\n\n" );

    do{
        GenerateTestSignal( &data, writeBuffer, FRAMES_PER_BUFFER );
        err = Pa_WriteStream( stream, writeBuffer, FRAMES_PER_BUFFER );
        if( err != paNoError ) goto error;
        
    }while( !IsTestSignalFinished( &data ) );

    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;
    

    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;

/* -------------------------------------------------------------------------- */
    
    Pa_Terminate();
    printf("Test finished.\n");
    
    return err;
    
error:
    Pa_Terminate();
    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 ) );
    return err;
}
예제 #15
0
int main(void)
{
    PortAudioStream *stream;
    PaError err;
    int numStress;
    paTestData data = {0};
    double load;
    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
        SAMPLE_RATE, FRAMES_PER_BUFFER, MAX_LOAD );

    err = Pa_Initialize();
    if( err != paNoError ) goto error;
    err = Pa_OpenStream(
              &stream,
              paNoDevice,/* default input device */
              0,              /* no input */
              paFloat32,  /* 32 bit floating point input */
              NULL,
              Pa_GetDefaultOutputDeviceID(), /* default output device */
              1,          /* mono output */
              paFloat32,      /* 32 bit floating point output */
              NULL,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,            /* frames per buffer */
              0,              /* number of buffers, if zero then use default minimum */
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              patestCallback,
              &data );
    if( err != paNoError ) goto error;
    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;

    /* Determine number of sines required to get to 50% */
    do
    {
        data.numSines++;
        Pa_Sleep( 100 );

        load = Pa_GetCPULoad( stream );
        printf("numSines = %d, CPU load = %f\n", data.numSines, load );
    }
    while( load < 0.5 );
    
    /* Calculate target stress value then ramp up to that level*/
    numStress = (int) (2.0 * data.numSines * MAX_LOAD );
    for( ; data.numSines < numStress; data.numSines++ )
    {
        Pa_Sleep( 200 );
        load = Pa_GetCPULoad( stream );
        printf("STRESSING: numSines = %d, CPU load = %f\n", data.numSines, load );
    }
    
    printf("Suffer for 5 seconds.\n");
    Pa_Sleep( 5000 );
    
    printf("Stop stream.\n");
    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;
    
    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;
    
    Pa_Terminate();
    printf("Test finished.\n");
    return err;
error:
    Pa_Terminate();
    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 ) );
    return err;
}
예제 #16
0
int main(void)
{
    PortAudioStream *stream;
    PaError    err;
    paTestData data;
    int        i;
    int        totalFrames;
    int        numSamples;
    int        numBytes;
    SAMPLE     max, average, val;
    printf("patest_record.c\n"); fflush(stdout);

    data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
    data.frameIndex = 0;
    numSamples = totalFrames * NUM_CHANNELS;

    numBytes = numSamples * sizeof(SAMPLE);
    data.recordedSamples = (SAMPLE *) malloc( numBytes );
    if( data.recordedSamples == NULL )
    {
        printf("Could not allocate record array.\n");
        exit(1);
    }
    for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0;

    err = Pa_Initialize();
    if( err != paNoError ) goto error;

    /* Record some audio. -------------------------------------------- */
    err = Pa_OpenStream(
              &stream,
              Pa_GetDefaultInputDeviceID(),
              NUM_CHANNELS,
              PA_SAMPLE_TYPE,
              NULL,
              paNoDevice,
              0,
              PA_SAMPLE_TYPE,
              NULL,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,            /* frames per buffer */
              0,               /* number of buffers, if zero then use default minimum */
              0, /* paDitherOff, // flags */
              recordCallback,
              &data );
    if( err != paNoError ) goto error;

    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;
    printf("Now recording!!\n"); fflush(stdout);

    while( Pa_StreamActive( stream ) )
    {
        Pa_Sleep(1000);
        printf("index = %d\n", data.frameIndex ); fflush(stdout);
    }

    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;

    /* Measure maximum peak amplitude. */
    max = 0;
    average = 0;
    for( i=0; i<numSamples; i++ )
    {
        val = data.recordedSamples[i];
        if( val < 0 ) val = -val; /* ABS */
        if( val > max )
        {
            max = val;
        }
        average += val;
    }
    
    average = average / numSamples;

    if( PA_SAMPLE_TYPE == paFloat32 )   /* This should be done at compile-time with "#if" ?? */
    {                                   /* MIPS-compiler warns at the int-version below.     */
        printf("sample max amplitude = %f\n", max );
        printf("sample average = %f\n", average );
    }
    else
    {
        printf("sample max amplitude = %d\n", max );    /* <-- This IS compiled anyhow. */
        printf("sample average = %d\n", average );
    }
    
    /* Write recorded data to a file. */
#if 0
    {
        FILE  *fid;
        fid = fopen("recorded.raw", "wb");
        if( fid == NULL )
        {
            printf("Could not open file.");
        }
        else
        {
            fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
            fclose( fid );
            printf("Wrote data to 'recorded.raw'\n");
        }
    }
#endif

    /* Playback recorded data.  -------------------------------------------- */
    data.frameIndex = 0;
    printf("Begin playback.\n"); fflush(stdout);
    err = Pa_OpenStream(
              &stream,
              paNoDevice,
              0,               /* NO input */
              PA_SAMPLE_TYPE,
              NULL,
              Pa_GetDefaultOutputDeviceID(),
              NUM_CHANNELS,
              PA_SAMPLE_TYPE,
              NULL,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,            /* frames per buffer */
              0,               /* number of buffers, if zero then use default minimum */
              paClipOff,       /* we won't output out of range samples so don't bother clipping them */
              playCallback,
              &data );
    if( err != paNoError ) goto error;

    if( stream )
    {
        err = Pa_StartStream( stream );
        if( err != paNoError ) goto error;
        printf("Waiting for playback to finish.\n"); fflush(stdout);

        while( Pa_StreamActive( stream ) ) Pa_Sleep(100);

        err = Pa_CloseStream( stream );
        if( err != paNoError ) goto error;
        printf("Done.\n"); fflush(stdout);
    }
    free( data.recordedSamples );

    Pa_Terminate();
    return 0;

error:
    Pa_Terminate();
    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 ) );
    return -1;
}
예제 #17
0
int main(void)
{
    PortAudioStream *stream;
    PaError err;
    paTestData data;
    int i;
    int totalSamps;
#if TEST_UNSIGNED
    printf("PortAudio Test: output UNsigned 8 bit sine wave.\n");
#else
    printf("PortAudio Test: output signed 8 bit sine wave.\n");
#endif
    /* initialise sinusoidal wavetable */
    for( i=0; i<TABLE_SIZE; i++ )
    {
        data.sine[i] = (char) (127.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
#if TEST_UNSIGNED
        data.sine[i] += (unsigned char) 0x80;
#endif

    }
    data.left_phase = data.right_phase = 0;
    data.framesToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
    err = Pa_Initialize();
    if( err != paNoError ) goto error;
    err = Pa_OpenStream(
              &stream,
              paNoDevice,/* default input device */
              0,              /* no input */
              TEST_FORMAT,
              NULL,
              Pa_GetDefaultOutputDeviceID(), /* default output device */
              2,          /* stereo output */
              TEST_FORMAT,
              NULL,
              SAMPLE_RATE,
              256,            /* frames per buffer */
              0,              /* number of buffers, if zero then use default minimum */
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              patestCallback,
              &data );
    if( err != paNoError ) goto error;
    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;
    /* Watch until sound is halfway finished. */
    while( Pa_StreamTime( stream ) < (totalSamps/2) ) Pa_Sleep(10);
    /* Stop sound until ENTER hit. */
    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;
    printf("Pause for 2 seconds.\n");
    Pa_Sleep( 2000 );

    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;
    printf("Waiting for sound to finish.\n");
    while( Pa_StreamActive( stream ) ) Pa_Sleep(10);
    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;
    Pa_Terminate();
    printf("Test finished.\n");
    return err;
error:
    Pa_Terminate();
    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 ) );
    return err;
}
예제 #18
0
int main(void)
{
    PaStreamParameters outputParameters;
    PaStream *stream;
    PaError err;
    paTestData data;
#ifdef __APPLE__
    PaMacCoreStreamInfo macInfo;
    const SInt32 channelMap[4] = { -1, -1, 0, 1 };
#endif
    int i;


    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
    printf("Output will be mapped to channels 2 and 3 instead of 0 and 1.\n");

    /* initialise sinusoidal wavetable */
    for( i=0; i<TABLE_SIZE; i++ )
    {
        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
    }
    data.left_phase = data.right_phase = 0;

    err = Pa_Initialize();
    if( err != paNoError ) goto error;

    /** setup host specific info */
#ifdef __APPLE__
    PaMacCore_SetupStreamInfo( &macInfo, paMacCorePlayNice );
    PaMacCore_SetupChannelMap( &macInfo, channelMap, 4 );

    for( i=0; i<4; ++i )
        printf( "channel %d name: %s\n", i, PaMacCore_GetChannelName( Pa_GetDefaultOutputDevice(), i, false ) );
#else
    printf( "Channel mapping not supported on this platform. Reverting to normal sine test.\n" );
#endif

    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
    if (outputParameters.device == paNoDevice) {
        fprintf(stderr,"Error: No default output device.\n");
        goto error;
    }
    outputParameters.channelCount = 2;       /* stereo output */
    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
#ifdef __APPLE__
    outputParameters.hostApiSpecificStreamInfo = &macInfo;
#else
    outputParameters.hostApiSpecificStreamInfo = NULL;
#endif

    err = Pa_OpenStream(
              &stream,
              NULL, /* no input */
              &outputParameters,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              patestCallback,
              &data );
    if( err != paNoError ) goto error;

    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;

    printf("Play for %d seconds.\n", NUM_SECONDS );
    Pa_Sleep( NUM_SECONDS * 1000 );

    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;

    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;

    Pa_Terminate();
    printf("Test finished.\n");

    return err;
error:
    Pa_Terminate();
    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 ) );
    return err;
}
예제 #19
0
PaError ReadStream( PaStream* stream,
                           void *buffer,
                           unsigned long frames )
{
    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
    char *cbuf = (char *) buffer;
    PaError ret = paNoError;
    VVDBUG(("ReadStream()\n"));

    while( frames > 0 ) {
       long avail;
       long toRead;
       do {
          avail = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer );
/*
          printf( "Read Buffer is %%%g full: %ld of %ld.\n",
                  100 * (float)avail / (float) blio->inputRingBuffer.bufferSize,
                  avail, blio->inputRingBuffer.bufferSize );
*/
          if( avail == 0 ) {
#ifdef PA_MAC_BLIO_MUTEX
             /**block when empty*/
             ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) );
             if( ret )
                return ret;
             while( blio->isInputEmpty ) {
                ret = UNIX_ERR( pthread_cond_wait( &blio->inputCond, &blio->inputMutex ) );
                if( ret )
                   return ret;
             }
             ret = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) );
             if( ret )
                return ret;
#else
             Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
#endif
          }
       } while( avail == 0 );
       toRead = MIN( avail, frames * blio->inputSampleSizeActual * blio->inChan );
       toRead -= toRead % blio->inputSampleSizeActual * blio->inChan ;
       PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, toRead );
       cbuf += toRead;
       frames -= toRead / ( blio->inputSampleSizeActual * blio->inChan );

       if( toRead == avail ) {
#ifdef PA_MAC_BLIO_MUTEX
          /* we just emptied the buffer, so we need to mark it as empty. */
          ret = blioSetIsInputEmpty( blio, true );
          if( ret )
             return ret;
          /* of course, in the meantime, the callback may have put some sats
             in, so
             so check for that, too, to avoid a race condition. */
          if( PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) ) {
             blioSetIsInputEmpty( blio, false );
             if( ret )
                return ret;
          }
#endif
       }
    }

    /*   Report either paNoError or paInputOverflowed. */
    /*   may also want to report other errors, but this is non-standard. */
    ret = blio->statusFlags & paInputOverflow;

    /* report underflow only once: */
    if( ret ) {
       OSAtomicAnd32( (uint32_t)(~paInputOverflow), &blio->statusFlags );
       ret = paInputOverflowed;
    }

    return ret;
}
예제 #20
0
PaError TestRecording( paTestData *dataPtr )
{
    PortAudioStream *stream;
    PaError    err;
    int        i;

    /* Record some audio. */
    err = Pa_OpenStream(
              &stream,
              Pa_GetDefaultInputDeviceID(),
              dataPtr->samplesPerFrame,               /* stereo input */
              PA_SAMPLE_TYPE,
              NULL,
              paNoDevice,
              0,
              PA_SAMPLE_TYPE,
              NULL,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,            /* frames per buffer */
              NUM_REC_BUFS,               /* number of buffers, if zero then use default minimum */
              paClipOff,       /* we won't output out of range samples so don't bother clipping them */
              recordCallback,
              dataPtr );
    if( err != paNoError ) goto error;
    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;

    printf("Now recording!\n"); fflush(stdout);
    for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
    {
        if( Pa_StreamActive( stream ) <= 0)
        {
            printf("Stream inactive!\n");
            break;
        }
        if( dataPtr->maxFrameIndex <= dataPtr->frameIndex )
        {
            printf("Buffer recording complete.\n");
            break;
        }
        Pa_Sleep(100);
        printf("index = %d\n", dataPtr->frameIndex ); fflush(stdout);
    }

    printf("Finished loop. Close stream.\n"); fflush(stdout);

    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;

    printf("Done.\n"); fflush(stdout);
    {
        SAMPLE max = 0;
        SAMPLE posVal;
        int i;
        for( i=0; i<dataPtr->numSamples; i++ )
        {
            posVal = dataPtr->recordedSamples[i];
            if( posVal < 0 ) posVal = -posVal;
            if( posVal > max ) max = posVal;
        }
        printf("Largest recorded sample = %d\n", max );
    }
    /* Write recorded data to a file. */
#if 0
    {
        FILE  *fid;
        fid = fopen("recorded.raw", "wb");
        if( fid == NULL )
        {
            printf("Could not open file.");
        }
        else
        {
            fwrite( dataPtr->recordedSamples, dataPtr->samplesPerFrame * sizeof(SAMPLE), totalFrames, fid );
            fclose( fid );
            printf("Wrote data to 'recorded.raw'\n");
        }
    }
#endif

error:
    return err;
}
예제 #21
0
PaError ReadStream( PaStream* stream,
                           void *buffer,
                           unsigned long framesRequested )
{
    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
    char *cbuf = (char *) buffer;
    PaError ret = paNoError;
    VVDBUG(("ReadStream()\n"));

    while( framesRequested > 0 ) {
       ring_buffer_size_t framesAvailable;
       ring_buffer_size_t framesToTransfer;
       ring_buffer_size_t framesTransferred;
       do {
          framesAvailable = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer );
/*
          printf( "Read Buffer is %%%g full: %ld of %ld.\n",
                  100 * (float)avail / (float) blio->inputRingBuffer.bufferSize,
                  framesAvailable, blio->inputRingBuffer.bufferSize );
*/
          if( framesAvailable == 0 ) {
#ifdef PA_MAC_BLIO_MUTEX
             /**block when empty*/
             ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) );
             if( ret )
                return ret;
             while( blio->isInputEmpty ) {
                ret = UNIX_ERR( pthread_cond_wait( &blio->inputCond, &blio->inputMutex ) );
                if( ret )
                   return ret;
             }
             ret = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) );
             if( ret )
                return ret;
#else
             Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
#endif
          }
       } while( framesAvailable == 0 );
       framesToTransfer = (ring_buffer_size_t) MIN( framesAvailable, framesRequested );
       framesTransferred = PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, framesToTransfer );
       cbuf += framesTransferred * blio->inputSampleSizeActual * blio->inChan;
       framesRequested -= framesTransferred;

       if( framesToTransfer == framesAvailable ) {
#ifdef PA_MAC_BLIO_MUTEX
          /* we just emptied the buffer, so we need to mark it as empty. */
          ret = blioSetIsInputEmpty( blio, true );
          if( ret )
             return ret;
          /* of course, in the meantime, the callback may have put some sats
             in, so
             so check for that, too, to avoid a race condition. */
          /* FIXME - this does not seem to fix any race condition. */
          if( PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) ) {
             blioSetIsInputEmpty( blio, false );
             /* FIXME - why check? ret has not been set? */
             if( ret )
                return ret;
          }
#endif
       }
    }

    /*   Report either paNoError or paInputOverflowed. */
    /*   may also want to report other errors, but this is non-standard. */
    /* FIXME should not clobber ret, use if(blio->statusFlags & paInputOverflow) */
    ret = blio->statusFlags & paInputOverflow;

    /* report underflow only once: */
    if( ret ) {
       OSAtomicAnd32( (uint32_t)(~paInputOverflow), &blio->statusFlags );
       ret = paInputOverflowed;
    }

    return ret;
}
예제 #22
0
static void wait_for_restart_signal() {
	Pa_Sleep(5000);
}
예제 #23
0
int main(void)
{
    PaStreamParameters  inputParameters,
                        outputParameters;
    PaStream*           stream;
    PaError             err = paNoError;
    paTestData          data;
    int                 i;
    int                 totalFrames;
    int                 numSamples;
    int                 numBytes;
    SAMPLE              max, val;
    double              average;

    printf("patest_record.c\n"); fflush(stdout);

    data.maxFrameIndex = totalFrames = NUM_SECONDS * 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; i<numSamples; i++ ) data.recordedSamples[i] = 0;

    err = Pa_Initialize();
    if( err != paNoError ) goto done;

    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
    inputParameters.channelCount = 2;                    /* stereo input */
    inputParameters.sampleFormat = PA_SAMPLE_TYPE;
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
    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("Now recording!!\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;

    /* Measure maximum peak amplitude. */
    max = 0;
    average = 0.0;
    for( i=0; i<numSamples; i++ )
    {
        val = data.recordedSamples[i];
        if( val < 0 ) val = -val; /* ABS */
        if( val > max )
        {
            max = val;
        }
        average += val;
    }

    average = average / (double)numSamples;

    printf("sample max amplitude = "PRINTF_S_FORMAT"\n", max );
    printf("sample average = %lf\n", average );

    /* Write recorded data to a file. */
#if 0
    {
        FILE  *fid;
        fid = fopen("recorded.raw", "wb");
        if( fid == NULL )
        {
            printf("Could not open file.");
        }
        else
        {
            fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
            fclose( fid );
            printf("Wrote data to 'recorded.raw'\n");
        }
    }
#endif

    /* Playback recorded data.  -------------------------------------------- */
    data.frameIndex = 0;

    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
    outputParameters.channelCount = 2;                     /* stereo output */
    outputParameters.sampleFormat =  PA_SAMPLE_TYPE;
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;

    printf("Begin playback.\n"); fflush(stdout);
    err = Pa_OpenStream(
              &stream,
              NULL, /* no input */
              &outputParameters,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              playCallback,
              &data );
    if( err != paNoError ) goto done;

    if( stream )
    {
        err = Pa_StartStream( stream );
        if( err != paNoError ) goto done;
        
        printf("Waiting for playback to finish.\n"); fflush(stdout);

        while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
        if( err < 0 ) goto done;
        
        err = Pa_CloseStream( stream );
        if( err != paNoError ) goto done;
        
        printf("Done.\n"); fflush(stdout);
    }

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;
}
예제 #24
0
int main(int argc, char *argv[]) {
	int exit_code = 0;
	slimproto_t slimproto;
	slimaudio_t slimaudio;

	PaDeviceIndex output_device_id = PA_DEFAULT_DEVICE;
	char *output_device_name = NULL;
	char *hostapi_name = NULL;

	unsigned int output_predelay = 0;
	unsigned int output_predelay_amplitude = 0;
#ifdef EMPEG
	bool power_bypass = false, power_last = false;
	bool geteq = false;
	long key, ir;
#endif
#ifdef EMPEG
	slimaudio_volume_t volume_control = VOLUME_DRIVER;
#else
	slimaudio_volume_t volume_control = VOLUME_SOFTWARE;
#endif
	unsigned int retry_interval = RETRY_DEFAULT;

	char macaddress[6] = { 0, 0, 0, 0, 0, 1 };

	int keepalive_interval = -1;

	bool listdevs = false;
	bool listservers = false;
	bool discover_server = false;
	unsigned int json_port;

#ifdef ZONES
	bool default_macaddress = true;
	unsigned int zone = 0;
	unsigned int num_zones = 1;
#endif
#ifdef DAEMONIZE
	bool should_daemonize = false;
	char *logfile = NULL;
#endif
	char slimserver_address[INET_FQDNSTRLEN] = "127.0.0.1";

	char getopt_options[OPTLEN] = "a:FId:Y:e:f:hk:Lm:n:o:P:p:Rr:TO:Vv:";

	static struct option long_options[] = {
		{"predelay_amplitude", required_argument, 0, 'a'},
		{"discover",           no_argument,       0, 'F'},
		{"debug",              required_argument, 0, 'd'},
		{"debuglog",           required_argument, 0, 'Y'},
		{"help",               no_argument,       0, 'h'},
		{"keepalive",          required_argument, 0, 'k'},
		{"list",               no_argument,       0, 'L'},
		{"findservers",        no_argument,       0, 'I'},
		{"mac",	               required_argument, 0, 'm'},
		{"name",               required_argument, 0, 'n'},
		{"output",             required_argument, 0, 'o'},
		{"playerid",           required_argument, 0, 'e'},
		{"firmware",           required_argument, 0, 'f'},
		{"port",               required_argument, 0, 'P'},
		{"predelay",           required_argument, 0, 'p'},
		{"threshold_override", no_argument,       0, 'T'},
		{"output_threshold",   required_argument, 0, 'O'},
#ifdef EMPEG
		{"puteq",              no_argument,       0, 'Q'},
		{"geteq",              no_argument,       0, 'q'},
#endif
		{"retry",              no_argument,       0, 'R'},
		{"intretry",           required_argument, 0, 'r'},
		{"version",            no_argument,       0, 'V'},
		{"volume",             required_argument, 0, 'v'},
		{"zone",               required_argument, 0, 'z'},
#ifdef PORTAUDIO_DEV
		{"latency",            required_argument, 0, 'y'},
		{"audiotype",          required_argument, 0, 't'},
#else
		{"paframes",           required_argument, 0, 'g'},
		{"pabuffers",          required_argument, 0, 'j'},
#endif
#ifdef DAEMONIZE
		{"daemonize",          required_argument, 0, 'M'},
#endif
#ifdef __WIN32__
		{"highpriority",       no_argument,       0, 'H'},
#ifdef PADEV_WASAPI
		{"shared",             no_argument,       0, 'S'},
#endif
#endif
#ifdef INTERACTIVE
		{"lircrc",             required_argument, 0, 'c'},
		{"lirc",               no_argument,       0, 'i'},
		{"lcd",                no_argument,       0, 'l'},
		{"lcdc",               no_argument,       0, 'C'},
		{"display",            no_argument,       0, 'D'},
		{"width",              required_argument, 0, 'w'},
#endif
#ifdef RENICE
		{"renice",             no_argument,       0, 'N'},
#endif
#ifdef ZONES
		{"zone",               required_argument, 0, 'z'},
#endif
		{0, 0, 0, 0}
	};

#ifdef INTERACTIVE
        fd_set read_fds;
        fd_set write_fds;
        int key = 0;
        unsigned long ir = 0;
	int maxfd = 0;
	char *home;
	struct timeval timeout;
	timeout.tv_usec = 0;

#ifdef __WIN32__
	int WSAerrno;
	int ptw32_processInitialize (void);
	ptw32_processInitialize();
#endif /* __WIN32__ */
        /* default lircrc file ($HOME/.lircrc) */
	home = getenv("HOME");
	if (home == NULL) home = "";
	lircrc = (char *)malloc((strlen(home) + strlen("/.lircrc") + 1) * sizeof(char));
	strcpy(lircrc,home);
	strcat(lircrc,"/.lircrc");
#endif /* INTERACTIVE */

#ifdef EMPEG
	strcat (getopt_options, "Qq");
#endif
#ifdef PORTAUDIO_DEV
	strcat (getopt_options, "y:t:");
#else
	strcat (getopt_options, "g:j:");
#endif	
#ifdef DAEMONIZE	
	strcat (getopt_options, "M:");
#endif
#ifdef INTERACTIVE
	strcat (getopt_options, "c:CDilw:");
#endif
#ifdef __WIN32__
	strcat (getopt_options, "H");
#ifdef PADEV_WASAPI
	strcat (getopt_options, "S");
#endif
#endif
#ifdef RENICE
	strcat (getopt_options, "N");
#endif
#ifdef ZONES
	strcat (getopt_options, "z:");
#endif
#ifdef EMPEG
	empeg_getmac(macaddress);
#endif

	while (true) {
		const char shortopt =
			getopt_long_only(argc, argv, getopt_options, long_options, NULL);

		if (shortopt == (char) -1) {
			break;
		}

		switch (shortopt) {
		case 'a':
			output_predelay_amplitude = strtoul(optarg, NULL, 0);
			break;
		case 'F':
			discover_server = true;
			break;
		case 'd':
#ifdef SLIMPROTO_DEBUG
			if (strcmp(optarg, "all") == 0)
			{
				slimproto_debug = true;
				slimaudio_debug = true;
				slimaudio_buffer_debug = true;
				slimaudio_buffer_debug_v = true;
				slimaudio_decoder_debug = true;
				slimaudio_decoder_debug_r = true;
				slimaudio_decoder_debug_v = true;
				slimaudio_http_debug = true;
				slimaudio_http_debug_v = true;
				slimaudio_output_debug = true;
				slimaudio_output_debug_v = true;
			}
			else if (strcmp(optarg, "slimproto") == 0)
				slimproto_debug = true;
			else if (strcmp(optarg, "slimaudio") == 0)
				slimaudio_debug = true;
			else if (strcmp(optarg, "slimaudio_buffer") == 0)
				slimaudio_buffer_debug = true;
			else if (strcmp(optarg, "slimaudio_buffer_v") == 0)
				slimaudio_buffer_debug_v = true;
			else if (strcmp(optarg, "slimaudio_decoder") == 0)
				slimaudio_decoder_debug = true;
			else if (strcmp(optarg, "slimaudio_decoder_r") == 0)
				slimaudio_decoder_debug_r = true;
			else if (strcmp(optarg, "slimaudio_decoder_v") == 0)
				slimaudio_decoder_debug_v = true;
			else if (strcmp(optarg, "slimaudio_http") == 0)
				slimaudio_http_debug = true;
			else if (strcmp(optarg, "slimaudio_http_v") == 0)
				slimaudio_http_debug_v = true;
			else if (strcmp(optarg, "slimaudio_output") == 0)
				slimaudio_output_debug = true;
			else if (strcmp(optarg, "slimaudio_output_v") == 0)
				slimaudio_output_debug_v = true;
			else
				fprintf(stderr, "%s: Unknown debug option %s\n", argv[0], optarg);
#else
				fprintf(stderr, "%s: Recompile with -DSLIMPROTO_DEBUG to enable debugging.\n", argv[0]);
#endif
			break;
		case 'Y':
#ifdef SLIMPROTO_DEBUG
                        if ( optarg == NULL )
                        {
                                fprintf(stderr, "%s: Cannot parse debug log filename %s\n", argv[0], optarg);
                                exit(-1);
                        } else
                        {
				debuglog = freopen( optarg, "a", stderr);
				if ( debuglog )
					debug_logfile = true;
				else
					fprintf(stderr, "%s: Redirection of stderr to %s failed.\n", argv[0], optarg);
                        }
#endif
			break;

/* From server/Slim/Networking/Slimproto.pm from 7.5r28596
** squeezebox(2)
** softsqueeze(3)
** squeezebox2(4)
** transporter(5)
** softsqueeze3(6)
** receiver(7)
** squeezeslave(8)
** controller(9)
** boom(10)
** softboom(11)
** squeezeplay(12)
** radio(13)
** touch(14)
*/
		case 'e':
			player_type = strtoul(optarg, NULL, 0);
			if ( (player_type < 2) || (player_type > 14) )
			{
				player_type = PLAYER_TYPE;
				fprintf(stderr, "%s: Unknown player type, using (%d)\n", argv[0], player_type);
			}
			break;
		case 'f':
			firmware = strtoul(optarg, NULL, 0);
			if ( (firmware < 0) || (firmware > 254) )
			{
				firmware = FIRMWARE_VERSION;
				fprintf(stderr, "%s: Invalid firmware value, using (%d)\n", argv[0], firmware);
			}
			break;
		case 'h':
			print_help();
			exit(0);	
		case 'k':
			keepalive_interval = strtoul(optarg, NULL, 0);
			break;
		case 'T':
			threshold_override = true;
			break;
		case 'O':
			output_threshold = strtoul(optarg, NULL, 0);
			if ( (output_threshold < 0) || (output_threshold > 1000000) )
			{
				output_threshold = OUTPUT_THRESHOLD;
				fprintf(stderr, "%s: Invalid output threshold, using (%d)\n",
					argv[0], output_threshold);
			}
			break;
		case 'm':
			if (parse_macaddress(macaddress, optarg) != 0) {
				fprintf(stderr, "%s: Cannot parse mac address %s\n", argv[0], optarg);
				exit(-1);	
			}
#ifdef ZONES
			default_macaddress = false;
#endif
			break;
#ifdef DAEMONIZE
		case 'M':
			if ( optarg == NULL )
			{
				fprintf(stderr, "%s: Cannot parse log filename %s\n", argv[0], optarg);
				exit(-1);	
			} else
			{
				logfile = optarg;
			}
			should_daemonize = true;
			break;
#endif

#ifdef __WIN32__
		case 'H':
			/* Change Window process priority class to HIGH */
			if ( !SetPriorityClass ( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) )
			{
				int dwError = GetLastError();
				fprintf(stderr, "%s: Failed to set priority (%d), using default.\n", argv[0],
					dwError);
			} 
			break;
#ifdef PADEV_WASAPI
		case 'S':
			wasapi_exclusive = false;
			break;
#endif
#endif
#ifdef RENICE
		case 'N':
			renice = true;
			break;
#endif
		case 'n':
			output_device_name = optarg;
			output_change = true;
			break;
		case 'o':
			output_device_id = strtoul(optarg, NULL, 0);
			output_change = true;
			break;
		case 'p':
			output_predelay = strtoul(optarg, NULL, 0);
			break;
		case 'P':
			port = strtoul(optarg, NULL, 0);
			if ( (port < 0) || (port > 65535) )
			{
				port = SLIMPROTOCOL_PORT;
				fprintf(stderr, "%s: Invalid port number, using %d.\n", argv[0], port);
			}
			break;
			break;
#ifdef EMPEG
		case 'Q':
			empeg_puteq_tofile();
			exit(0);
			break;
		case 'q':
			geteq = true;
			break;
#endif
		case 'R':
			retry_connection = true;
			break;
		case 'r':
			retry_connection = true;
			retry_interval = strtoul(optarg, NULL, 0);
			if ( ( retry_interval < 1 ) || ( retry_interval > 120 ) )
			{
				retry_interval = RETRY_DEFAULT;
				fprintf (stderr, "Invalid retry interval, using %d seconds.\n", retry_interval );
			}
			break;
#ifdef INTERACTIVE
		case 'c':
		        free(lircrc);
			lircrc = optarg;
			break;
#ifndef __WIN32__
		case 'i':
			using_lirc = true;
			break;
		case 'l':
			use_lcdd_menu = true;
			break;
		case 'C':
			use_lcdd_menu = true;
			lcdd_compat = true;
			break;
#endif
		case 'D':
			using_curses = 1;
			break;
		case 'w':
			linelen = strtoul(optarg, NULL, 0);
			break;
#endif
		case 'L':
			listdevs = true;
			break;
		case 'I':
			listservers = true;
			break;
		case 'V':
			print_version();
			exit(0);
			break;
		case 'v':
		 	if (strcmp(optarg, "sw") == 0) {
				volume_control = VOLUME_SOFTWARE;
			}
#ifndef PORTAUDIO_DEV
			else if (strcmp(optarg, "on") == 0 ) {
				volume_control = VOLUME_DRIVER;
			}
#endif
			else if (strcmp(optarg, "off") == 0 ) {
				volume_control = VOLUME_NONE;
			}
			break;
#ifdef PORTAUDIO_DEV
		case 'y':
			modify_latency = true;
			user_latency = strtoul(optarg, NULL, 0);

			if ( user_latency > 1000 )
			{
				fprintf (stderr, "Suggested latency invalid, using device default.\n");
				modify_latency = false;
			}
			break;
		case 't':
			hostapi_name = optarg;
			break;
#else
		case 'g':
			pa_framesPerBuffer = strtoul(optarg, NULL, 0);

			if ( (pa_framesPerBuffer > 65536) || (pa_framesPerBuffer < 64) )
			{
				fprintf (stderr,
					"Portaudio frames per buffer invalid, using default (%d).\n",
					PA_FRAMES_PER_BUFFER);
				pa_framesPerBuffer = PA_FRAMES_PER_BUFFER ;
			}
			break;
		case 'j':
			pa_numberOfBuffers = strtoul(optarg, NULL, 0);

			if ( (pa_numberOfBuffers > 64) || (pa_numberOfBuffers < 0) )
			{
				fprintf (stderr,
					"Number of Portaudio buffers invalid, using default (%d).\n",
					PA_NUM_BUFFERS);
				pa_numberOfBuffers = PA_NUM_BUFFERS;
			}
			break;
#endif
#ifdef ZONES
		case 'z':
			if (sscanf(optarg, "%u/%u", &zone, &num_zones) != 2)
			{
				fprintf (stderr, "Invalid zone specification, using default.\n");
			}
			if (num_zones > MAX_ZONES)
			{
				fprintf(stderr, "Number of zones > %d not supported\n", MAX_ZONES);
				zone=0;
				num_zones=1;
			}
			if (num_zones <= zone)
			{
				fprintf (stderr, "Invalid zone specification, using default.\n");
				zone = 0;
				num_zones = 1;
			}
			break;
#endif
		default:
			break;
		}
	}

	if (listdevs) {
		GetAudioDevices(output_device_id, output_device_name, hostapi_name, output_change, true);
		exit(0);
	}

	if (listservers) {
		slimproto_discover(slimserver_address, sizeof(slimserver_address), port, &json_port, true);
		exit(0);
	}

	if (optind < argc)
		strncpy(slimserver_address, argv[optind], sizeof(slimserver_address));

#ifdef DAEMONIZE
	if ( should_daemonize ) {
#ifdef INTERACTIVE
		if ( using_curses || use_lcdd_menu )
		{
			fprintf(stderr, "Daemonize not supported with display modes.\n");
			exit(-1);
		}
		else
#endif
			init_daemonize();
	}
#endif
	signal(SIGTERM, &exit_handler);
	signal(SIGINT, &exit_handler);
	install_restart_handler();

#ifdef INTERACTIVE
	install_toggle_handler();  /*SIGUSR2 to toggle IR/LCD on and off */
#endif
	if (slimproto_init(&slimproto) < 0) {
		fprintf(stderr, "Failed to initialize slimproto\n");
		exit(-1);	
	}

#ifdef ZONES
	if (slimaudio_init(&slimaudio, &slimproto, output_device_id, output_device_name,
		hostapi_name, output_change, zone, num_zones) < 0)
#else
	if (slimaudio_init(&slimaudio, &slimproto, output_device_id, output_device_name,
		hostapi_name, output_change) < 0)
#endif
	{
		fprintf(stderr, "Failed to initialize slimaudio\n");
		exit(-1);
	}
#ifdef ZONES
	if (default_macaddress)
		macaddress[5] += zone;
#endif
	slimproto_add_connect_callback(&slimproto, connect_callback, macaddress);

#ifdef INTERACTIVE
	/* Process VFD (display) commands */
	if ( using_curses || using_lirc || use_lcdd_menu )
		slimproto_add_command_callback(&slimproto, "vfdc", vfd_callback, macaddress);
#endif
#ifdef EMPEG
	slimproto_add_command_callback(&slimproto, "grfe", empeg_vfd_callback, macaddress);
	slimproto_add_command_callback(&slimproto, "grfb", empeg_vfdbrt_callback, macaddress);
	slimproto_add_command_callback(&slimproto, "aude", empeg_aude_callback, macaddress);
#endif

	slimaudio_set_volume_control(&slimaudio, volume_control);
	slimaudio_set_output_predelay(&slimaudio, output_predelay, output_predelay_amplitude);

	if (keepalive_interval >= 0) {
		slimaudio_set_keepalive_interval(&slimaudio, keepalive_interval);
	}

#ifdef INTERACTIVE
	init_lcd();
#endif
#ifdef EMPEG
	empeg_init();
	if (geteq)
	   empeg_geteq_fromfile();
	power_last = empeg_state.power_on;
	empeg_state.power_on = false;
#endif

	if (slimaudio_open(&slimaudio) < 0) {
		fprintf(stderr, "Failed to open slimaudio\n");
		exit_code = -1;
		goto exit;
	}

#ifdef SLIMPROTO_DEBUG
	if (slimaudio_debug)
		fprintf ( stderr, "Using audio device index: %d\n", slimaudio.output_device_id );
#endif

#ifdef INTERACTIVE
        init_lirc();

	setlocale(LC_ALL, "");
	initcurses();
#endif
#ifdef DAEMONIZE
	if ( should_daemonize ) {
		daemonize(logfile);
	}
#endif
	/* When retry_connection is true, retry connecting to Squeezebox Server 
	** until we succeed, unless the signal handler tells us to give up.
	*/
	do {
		if (signal_restart_flag) { 
#ifdef INTERACTIVE
			exitcurses();
#endif
			fprintf(stderr,"Retry in %d seconds.\n", retry_interval);
			Pa_Sleep(1000 * retry_interval);
#ifdef INTERACTIVE
	   	        initcurses();
#endif
		}
#ifdef EMPEG
		if (discover_server && empeg_state.last_server[0] != '\0')
		{
			strcpy(slimserver_address, (char *)empeg_state.last_server);
			empeg_state.last_server[0] = '\0';
		}
		else
#endif
		if (discover_server && slimproto_discover(slimserver_address,
			sizeof(slimserver_address), port, &json_port, false) < 0)
		{
			fprintf(stderr,"Discover failed.\n");
			if (!retry_connection) {
				exit_code = -1;
				goto exit;
			}
			signal_restart_flag = true;
			continue;
		}

		if (slimproto_connect(
			&slimproto, slimserver_address, port) < 0) {
			fprintf(stderr, "Connection to Squeezebox Server %s failed.\n", slimserver_address);
			if (!retry_connection) {
				exit_code = -1;
				goto exit;
			}
			signal_restart_flag = true;
			continue;
		}
		signal_restart_flag = false;
		discover_server = false;
#ifdef EMPEG
		strcpy((char *)empeg_state.last_server, slimserver_address);
		if (power_last)
			while (!empeg_state.power_on)
			{
				Pa_Sleep(100);
				slimproto_ir(&slimproto, 1, 1, 0x76898F70);
			}
#endif
                while (!signal_exit_flag && !signal_restart_flag) {
#ifdef EMPEG
		   int rc = empeg_idle();
		   if (power_bypass)
		   {
		      if (rc == 0 || !empeg_state.power_on)
		      {
		         power_last = false;
		         power_bypass = false;
		      }
		   }
		   else if (rc == -1)
		   {
		      fprintf(stderr, "Power loss detected.\n");
		      power_last = empeg_state.power_on;
                      slimproto_ir(&slimproto, 1, 1, 0x76898778);
		      while (empeg_state.power_on)
		         Pa_Sleep(250);
		   }
		   else if (rc == -2 && empeg_state.power_on)
		   {
		      fprintf(stderr, "Manual override, aborting power down.\n");
		      power_bypass = true;
		   }
		   else if (rc == -3)
		   {
		      fprintf(stderr, "Power restored.\n");
		      if (power_last)
                         slimproto_ir(&slimproto, 1, 1, 0x76898F70);
		   }
		   else if (rc == -4)
		   {
		      fprintf(stderr, "Powering down.\n");
		      slimproto_goodbye(&slimproto, 0x00);
		      Pa_Sleep(400);
		      slimproto_close(&slimproto);
		      empeg_state.power_on = power_last;
		      empeg_poweroff();
		      signal_restart_flag = true;
		   }
#endif
#ifdef INTERACTIVE
                   if (using_curses == 1 || use_lcdd_menu || using_lirc) {
                      FD_ZERO(&read_fds);
                      FD_ZERO(&write_fds);
		      if (using_curses == 1)
     	                 FD_SET(0, &read_fds); /* watch stdin */
   	              if  (use_lcdd_menu) {
		         FD_SET(lcd_fd, &read_fds); 
		         maxfd = lcd_fd;
		      }
   	              if (using_lirc) {
		         FD_SET(lirc_fd, &read_fds); 
                         if (lirc_fd > maxfd) 
		            maxfd = lirc_fd;
                      }
		      timeout.tv_sec = 5;
                      if(select(maxfd + 1, &read_fds, NULL, NULL, &timeout) == -1) {
#ifndef __WIN32__
    	                 if (errno != EINTR)
			 {
		           fprintf(stderr,"Select Error:%d\n", errno);
#else
			 WSAerrno = WSAGetLastError();
			 if ( (WSAerrno != WSAEINTR) && (WSAerrno != WSAENOTSOCK) )
			 {	
		           fprintf(stderr,"Select Error:%d\n", WSAerrno);
#endif
   	                   abort();
	                 }
#ifdef __WIN32__
			 else
				 WaitForSingleObject( GetStdHandle(STD_INPUT_HANDLE), 5000 );
#endif
                      }
		      if (FD_ISSET(0, &read_fds)) {
                         while ((key = getch()) != ERR) {
                            ir = getircode(key);
	                    if (ir == (unsigned long) 0x01) {
  		               signal_exit_flag = 1;
                            }else{
			       if (ir != 0) slimproto_ir(&slimproto, 1, 1, ir);
			    }
		         }
		      } 
		      if (using_lirc && FD_ISSET(lirc_fd, &read_fds)) {
                         while((key = read_lirc()) != 0 ) { 
                            ir = getircode(key);
	                    if (ir == 0x01) { 
  		               signal_exit_flag = 1;
                            } else {
			       if (ir != 0) slimproto_ir(&slimproto, 1, 1, ir);
			    }
		         }
		      } 
		      if (use_lcdd_menu && FD_ISSET(lcd_fd, &read_fds)) {
                         while(read_lcd()); 
		      }
		   } else {
                      wait_for_restart_signal();
		   }
#else
#ifdef EMPEG
                   while ((key = empeg_getkey()) != -1)
                   {
                      ir = empeg_getircode(key);
                      if (ir != 0)
                         slimproto_ir(&slimproto, 1, 1, ir);
                   }
#else
                   wait_for_restart_signal();
#endif
#endif
		}
#ifdef INTERACTIVE
                FD_ZERO(&read_fds);
                FD_ZERO(&write_fds);
#endif
        } while (signal_restart_flag && !signal_exit_flag);

exit:
	slimaudio_close(&slimaudio);

	slimproto_goodbye(&slimproto, 0x00);

	/* Wait 200ms for BYE! message send to complete */
	Pa_Sleep(200);

	slimproto_close(&slimproto);

#ifdef INTERACTIVE
	exitcurses();
	close_lirc();
#endif

#if defined(EMPEG) || defined(INTERACTIVE)
	close_lcd();
#endif

#ifdef SLIMPROTO_DEBUG
	if (debug_logfile)
	{
		fclose (debuglog);
	}
#endif

	slimproto_destroy(&slimproto);
	slimaudio_destroy(&slimaudio);

	return exit_code;
} 
int main(void)
{
    PaStreamParameters outputParameters;
    PaStream *stream;
    PaError err;
    int safeSineCount, stressedSineCount;
    int safeUnderflowCount, stressedUnderflowCount;
    paTestData data = {0};
    double load;


    printf("PortAudio Test: output sine waves, count underflows. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
        SAMPLE_RATE, FRAMES_PER_BUFFER, (float)MAX_LOAD );

    err = Pa_Initialize();
    if( err != paNoError ) goto error;
    
    outputParameters.device = Pa_GetDefaultOutputDevice();  /* default output device */
    if (outputParameters.device == paNoDevice) {
      fprintf(stderr,"Error: No default output device.\n");
      goto error;
    }
    outputParameters.channelCount = 1;                      /* mono output */
    outputParameters.sampleFormat = paFloat32;              /* 32 bit floating point output */
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;

    err = Pa_OpenStream(
              &stream,
              NULL,         /* no input */
              &outputParameters,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,    /* we won't output out of range samples so don't bother clipping them */
              patestCallback,
              &data );    
    if( err != paNoError ) goto error;
    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;

    printf("Establishing load conditions...\n" );

    /* Determine number of sines required to get to 50% */
    do
    {
        Pa_Sleep( 100 );

        load = Pa_GetStreamCpuLoad( stream );
        printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
		
		if( load < 0.3 )
		{
			data.sineCount += 10;
    }
		else if( load < 0.4 )
		{
			data.sineCount += 2;
		}
		else
		{
			data.sineCount += 1;
		}
		
    }
    while( load < 0.5 && data.sineCount < (MAX_SINES-1));

    safeSineCount = data.sineCount;

    /* Calculate target stress value then ramp up to that level*/
    stressedSineCount = (int) (2.0 * data.sineCount * MAX_LOAD );
    if( stressedSineCount > MAX_SINES )
        stressedSineCount = MAX_SINES;
    for( ; data.sineCount < stressedSineCount; data.sineCount+=4 )
    {
        Pa_Sleep( 100 );
        load = Pa_GetStreamCpuLoad( stream );
        printf("STRESSING: sineCount = %d, CPU load = %f\n", data.sineCount, load );
    }
    
    printf("Counting underflows for 5 seconds.\n");
    data.countUnderflows = 1;
    Pa_Sleep( 5000 );

    stressedUnderflowCount = data.outputUnderflowCount;

    data.countUnderflows = 0;
    data.sineCount = safeSineCount;

    printf("Resuming safe load...\n");
    Pa_Sleep( 1500 );
    data.outputUnderflowCount = 0;
    Pa_Sleep( 1500 );
    load = Pa_GetStreamCpuLoad( stream );
    printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );

    printf("Counting underflows for 5 seconds.\n");
    data.countUnderflows = 1;
    Pa_Sleep( 5000 );

    safeUnderflowCount = data.outputUnderflowCount;
    
    printf("Stop stream.\n");
    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;
    
    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;
    
    Pa_Terminate();

    if( stressedUnderflowCount == 0 )
        printf("Test failed, no output underflows detected under stress.\n");
    else if( safeUnderflowCount != 0 )
        printf("Test failed, %d unexpected underflows detected under safe load.\n", safeUnderflowCount);
    else
        printf("Test passed, %d expected output underflows detected under stress, 0 unexpected underflows detected under safe load.\n", stressedUnderflowCount );

    return err;
error:
    Pa_Terminate();
    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 ) );
    return err;
}
예제 #26
0
int main(void)
{
    PaStreamParameters outputParameters;
    PaStream *stream;
    PaError err;
    float buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */
    float sine[TABLE_SIZE]; /* sine wavetable */
    int left_phase = 0;
    int right_phase = 0;
    int left_inc = 1;
    int right_inc = 3; /* higher pitch so we can distinguish left and right. */
    int i, j, k;
    int bufferCount;

    
    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
    
    /* initialise sinusoidal wavetable */
    for( i=0; i<TABLE_SIZE; i++ )
    {
        sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
    }

    
    err = Pa_Initialize();
    if( err != paNoError ) goto error;

    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
    outputParameters.channelCount = 2;       /* stereo output */
    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;

    err = Pa_OpenStream(
              &stream,
              NULL, /* no input */
              &outputParameters,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              NULL, /* no callback, use blocking API */
              NULL ); /* no callback, so no callback userData */
    if( err != paNoError ) goto error;


    printf( "Play 3 times, higher each time.\n" );
    
    for( k=0; k < 3; ++k )
    {
        err = Pa_StartStream( stream );
        if( err != paNoError ) goto error;

        printf("Play for %d seconds.\n", NUM_SECONDS );

        bufferCount = ((NUM_SECONDS * SAMPLE_RATE) / FRAMES_PER_BUFFER);

        for( i=0; i < bufferCount; i++ )
        {
            for( j=0; j < FRAMES_PER_BUFFER; j++ )
            {
                buffer[j][0] = sine[left_phase];  /* left */
                buffer[j][1] = sine[right_phase];  /* right */
                left_phase += left_inc;
                if( left_phase >= TABLE_SIZE ) left_phase -= TABLE_SIZE;
                right_phase += right_inc;
                if( right_phase >= TABLE_SIZE ) right_phase -= TABLE_SIZE;
            }

            err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER );
            if( err != paNoError ) goto error;
        }   

        err = Pa_StopStream( stream );
        if( err != paNoError ) goto error;

        ++left_inc;
        ++right_inc;

        Pa_Sleep( 1000 );
    }

    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;

    Pa_Terminate();
    printf("Test finished.\n");
    
    return err;
error:
    Pa_Terminate();
    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 ) );
    return err;
}
예제 #27
0
PaError TestRecording( paTestData *dataPtr )
{
    PaError    err;
    int        i;
    int        lastIndex = 0;

/* Open input stream if not already open. */
    if( dataPtr->inputStream == NULL )
    {
        /* Record some audio. */
        err = Pa_OpenStream(
                  &dataPtr->inputStream,
                  Pa_GetDefaultInputDeviceID(),
                  dataPtr->samplesPerFrame,               /* stereo input */
                  PA_SAMPLE_TYPE,
                  NULL,
                  paNoDevice,
                  0,
                  PA_SAMPLE_TYPE,
                  NULL,
                  SAMPLE_RATE,
                  FRAMES_PER_BUFFER,            /* frames per buffer */
                  NUM_REC_BUFS,               /* number of buffers, if zero then use default minimum */
                  paClipOff,       /* we won't output out of range samples so don't bother clipping them */
                  recordCallback,
                  dataPtr );
        if( err != paNoError ) goto error;
    }

    dataPtr->frameIndex = 0;

    err = Pa_StartStream( dataPtr->inputStream );
    if( err != paNoError ) goto error;

    printf("Now recording!\n"); fflush(stdout);
    for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
    {
        int frameIndex, delta;
        Pa_Sleep(SLEEP_DUR_MSEC);

        frameIndex = dataPtr->frameIndex;
        if( Pa_StreamActive( dataPtr->inputStream ) <= 0)
        {
            printf("Stream inactive!\n");
            break;
        }
        if( dataPtr->maxFrameIndex <= frameIndex )
        {
            printf("Buffer recording complete.\n");
            break;
        }

        delta = frameIndex - lastIndex;
        lastIndex = frameIndex;
        printf("index = %d, delta = %d\n", frameIndex, delta ); fflush(stdout);
    }

    err = Pa_StopStream( dataPtr->inputStream );
    if( err != paNoError ) goto error;

    printf("Done.\n"); fflush(stdout);

error:
    return err;
}
예제 #28
0
파일: pa_unix_util.c 프로젝트: Crisil/praat
static void *WatchdogFunc( void *userData )
{
    PaError result = paNoError, *pres = NULL;
    int err;
    PaAlsaThreading *th = (PaAlsaThreading *) userData;
    unsigned intervalMsec = 500;
    const PaTime maxSeconds = 3.;   /* Max seconds between callbacks */
    PaTime timeThen = PaUtil_GetTime(), timeNow, timeElapsed, cpuTimeThen, cpuTimeNow, cpuTimeElapsed;
    double cpuLoad, avgCpuLoad = 0.;
    int throttled = 0;

    assert( th );

    /* Execute OnWatchdogExit when exiting */
    pthread_cleanup_push( &OnWatchdogExit, th );

    /* Boost priority of callback thread */
    PA_ENSURE( result = BoostPriority( th ) );
    if( !result )
    {
        /* Boost failed, might as well exit */
        pthread_exit( NULL );
    }

    cpuTimeThen = th->callbackCpuTime;
    {
        int policy;
        struct sched_param spm = { 0 };
        pthread_getschedparam( pthread_self(), &policy, &spm );
        PA_DEBUG(( "%s: Watchdog priority is %d\n", __FUNCTION__, spm.sched_priority ));
    }

    while( 1 )
    {
        double lowpassCoeff = 0.9, lowpassCoeff1 = 0.99999 - lowpassCoeff;
        
        /* Test before and after in case whatever underlying sleep call isn't interrupted by pthread_cancel */
        pthread_testcancel();
        Pa_Sleep( intervalMsec );
        pthread_testcancel();

        if( PaUtil_GetTime() - th->callbackTime > maxSeconds )
        {
            PA_DEBUG(( "Watchdog: Terminating callback thread\n" ));
            /* Tell thread to terminate */
            err = pthread_kill( th->callbackThread, SIGKILL );
            pthread_exit( NULL );
        }

        PA_DEBUG(( "%s: PortAudio reports CPU load: %g\n", __FUNCTION__, PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) ));

        /* Check if we should throttle, or unthrottle :P */
        cpuTimeNow = th->callbackCpuTime;
        cpuTimeElapsed = cpuTimeNow - cpuTimeThen;
        cpuTimeThen = cpuTimeNow;

        timeNow = PaUtil_GetTime();
        timeElapsed = timeNow - timeThen;
        timeThen = timeNow;
        cpuLoad = cpuTimeElapsed / timeElapsed;
        avgCpuLoad = avgCpuLoad * lowpassCoeff + cpuLoad * lowpassCoeff1;
        /*
        if( throttled )
            PA_DEBUG(( "Watchdog: CPU load: %g, %g\n", avgCpuLoad, cpuTimeElapsed ));
            */
        if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) > .925 )
        {
            static int policy;
            static struct sched_param spm = { 0 };
            static const struct sched_param defaultSpm = { 0 };
            PA_DEBUG(( "%s: Throttling audio thread, priority %d\n", __FUNCTION__, spm.sched_priority ));

            pthread_getschedparam( th->callbackThread, &policy, &spm );
            if( !pthread_setschedparam( th->callbackThread, SCHED_OTHER, &defaultSpm ) )
            {
                throttled = 1;
            }
            else
                PA_DEBUG(( "Watchdog: Couldn't lower priority of audio thread: %s\n", strerror( errno ) ));

            /* Give other processes a go, before raising priority again */
            PA_DEBUG(( "%s: Watchdog sleeping for %lu msecs before unthrottling\n", __FUNCTION__, th->throttledSleepTime ));
            Pa_Sleep( th->throttledSleepTime );

            /* Reset callback priority */
            if( pthread_setschedparam( th->callbackThread, SCHED_FIFO, &spm ) != 0 )
            {
                PA_DEBUG(( "%s: Couldn't raise priority of audio thread: %s\n", __FUNCTION__, strerror( errno ) ));
            }

            if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) >= .99 )
                intervalMsec = 50;
            else
                intervalMsec = 100;

            /*
            lowpassCoeff = .97;
            lowpassCoeff1 = .99999 - lowpassCoeff;
            */
        }
        else if( throttled && avgCpuLoad < .8 )
        {
            intervalMsec = 500;
            throttled = 0;

            /*
            lowpassCoeff = .9;
            lowpassCoeff1 = .99999 - lowpassCoeff;
            */
        }
    }

    pthread_cleanup_pop( 1 );   /* Execute cleanup on exit */

error:
    /* Shouldn't get here in the normal case */

    /* Pass on error code */
    pres = malloc( sizeof (PaError) );
    *pres = result;
    
    pthread_exit( pres );
}
예제 #29
0
int main(void)
{
    PaStream *stream;
    PaStreamParameters outputParameters;
    PaError err;
    paTestData data;
    int i;
    int timeout;
    
    printf("Play different tone sine waves that alternate between left and right channel.\n");
    printf("The low tone should be on the left channel.\n");
    
    /* initialise sinusoidal wavetable */
    for( i=0; i<TABLE_SIZE; i++ )
    {
        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
    }
    data.left_phase = data.right_phase = data.toggle = 0;
    data.countDown = SAMPLE_RATE;

    err = Pa_Initialize();
    if( err != paNoError ) goto error;

    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
    if (outputParameters.device == paNoDevice) {
      fprintf(stderr,"Error: No default output device.\n");
      goto error;
    }
    outputParameters.channelCount = 2;       /* stereo output */
    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;

    err = Pa_OpenStream( &stream,
                         NULL,                  /* No input. */
                         &outputParameters,     /* As above. */
                         SAMPLE_RATE,
                         FRAMES_PER_BUFFER,
                         paClipOff,      /* we won't output out of range samples so don't bother clipping them */
                         patestCallback,
                         &data );
    if( err != paNoError ) goto error;
    
    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;
    
    printf("Play for several seconds.\n");
    timeout = NUM_SECONDS * 4;
    while( timeout > 0 )
    {
        Pa_Sleep( 300 );        /*(Irix very much likes sleeps <= 1000 ms.)*/
        timeout -= 1;
    }

    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;
    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;
    Pa_Terminate();
    printf("Test finished.\n");
    return err;
error:
    Pa_Terminate();
    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 ) );
    return err;
}
int main(int argc, char* argv[])
{
    PaStreamParameters outputParameters;
    PaWinMmeStreamInfo wmmeStreamInfo;
    PaStream *stream;
    PaError err;
    paTestData data;
    int i;
    int deviceIndex;

    printf("PortAudio Test: output a sine blip on each channel. SR = %d, BufSize = %d, Chans = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER, CHANNEL_COUNT);

    err = Pa_Initialize();
    if( err != paNoError ) goto error;

	deviceIndex = Pa_GetHostApiInfo( Pa_HostApiTypeIdToHostApiIndex( paMME ) )->defaultOutputDevice;
	if( argc == 2 ){
		sscanf( argv[1], "%d", &deviceIndex );
	}

	printf( "using device id %d (%s)\n", deviceIndex, Pa_GetDeviceInfo(deviceIndex)->name );

    /* initialise sinusoidal wavetable */
    for( i=0; i<TABLE_SIZE; i++ )
    {
        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
    }

	data.phase = 0;

    outputParameters.device = deviceIndex;
    outputParameters.channelCount = CHANNEL_COUNT;
    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */
    outputParameters.suggestedLatency = 0; /*Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;*/
    outputParameters.hostApiSpecificStreamInfo = NULL;

    wmmeStreamInfo.size = sizeof(PaWinMmeStreamInfo);
    wmmeStreamInfo.hostApiType = paMME; 
    wmmeStreamInfo.version = 1;
    wmmeStreamInfo.flags = paWinMmeUseLowLevelLatencyParameters | paWinMmeDontThrottleOverloadedProcessingThread;
    wmmeStreamInfo.framesPerBuffer = WMME_FRAMES_PER_BUFFER;
    wmmeStreamInfo.bufferCount = WMME_BUFFER_COUNT;
    outputParameters.hostApiSpecificStreamInfo = &wmmeStreamInfo;
   

	if( Pa_IsFormatSupported( 0, &outputParameters, SAMPLE_RATE ) == paFormatIsSupported  ){
		printf( "Pa_IsFormatSupported reports device will support %d channels.\n", CHANNEL_COUNT );
	}else{
		printf( "Pa_IsFormatSupported reports device will not support %d channels.\n", CHANNEL_COUNT );
	}

    err = Pa_OpenStream(
              &stream,
              NULL, /* no input */
              &outputParameters,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              patestCallback,
              &data );
    if( err != paNoError ) goto error;

    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;

    printf("Play for %d seconds.\n", NUM_SECONDS );
    Pa_Sleep( NUM_SECONDS * 1000 );

    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;

    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;

    Pa_Terminate();
    printf("Test finished.\n");
    
    return err;
error:
    Pa_Terminate();
    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 ) );
    return err;
}