Esempio n. 1
0
PaError CloseAudioStream(PABLIO_Stream * aStream)
{
	int bytesEmpty;
	int byteSize;
	int c = 0;


	if (aStream->has_out) {

		for (c = 0; c < aStream->channelCount; c++) {
			byteSize = aStream->outFIFOs[c].bufferSize;

			/* If we are writing data, make sure we play everything written. */
			if (byteSize > 0) {
				bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[c]);
				while (bytesEmpty < byteSize) {
					Pa_Sleep(10);
					bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[c]);
				}
			}
		}
	}

	if (aStream->do_dual) {
		if (aStream->has_in && aStream->istream) {
			if (Pa_IsStreamActive(aStream->istream)) {
				Pa_StopStream(aStream->istream);
			}

			Pa_CloseStream(aStream->istream);
			aStream->istream = NULL;
		}

		if (aStream->has_out && aStream->ostream) {
			if (Pa_IsStreamActive(aStream->ostream)) {
				Pa_StopStream(aStream->ostream);
			}

			Pa_CloseStream(aStream->ostream);
			aStream->ostream = NULL;
		}

	} else {
		if (aStream->iostream) {
			if (Pa_IsStreamActive(aStream->iostream)) {
				Pa_StopStream(aStream->iostream);
			}

			Pa_CloseStream(aStream->iostream);
			aStream->iostream = NULL;
		}
	}

	if (aStream->has_in) {
		for (c = 0; c < aStream->channelCount; c++) {
			PABLIO_TermFIFO(&aStream->inFIFOs[c]);
		}
	}

	if (aStream->has_out) {
		for (c = 0; c < aStream->channelCount; c++) {
			PABLIO_TermFIFO(&aStream->outFIFOs[c]);
		}
	}

	free(aStream);
	switch_yield(500000);

	return paNoError;
}
Esempio n. 2
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 */
    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,
              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 */
    if (outputParameters.device == paNoDevice) {
        fprintf(stderr,"Error: No default output device.\n");
        goto done;
    }
    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;
}
Esempio n. 3
0
static int wave_open_sound()
{
  ENTER("wave_open_sound");

  PaError err=paNoError;
  PaError active;

#if USE_PORTAUDIO == 18
  active = Pa_StreamActive(pa_stream);
#else
  active = Pa_IsStreamActive(pa_stream);
#endif

  if(active == 1)
    {
      SHOW_TIME("wave_open_sound > already active");
      return(0);
    }
  if(active < 0)
    {
      out_channels = 1;

#if USE_PORTAUDIO == 18
      //      err = Pa_OpenDefaultStream(&pa_stream,0,1,paInt16,wave_samplerate,FRAMES_PER_BUFFER,N_WAV_BUF,pa_callback,(void *)userdata);

   PaDeviceID playbackDevice = Pa_GetDefaultOutputDeviceID();

   PaError err = Pa_OpenStream( &pa_stream,
				/* capture parameters */
				paNoDevice,
				0,
				paInt16,
				NULL,
				/* playback parameters */
				playbackDevice,
				out_channels,
				paInt16,
				NULL,
				/* general parameters */
				wave_samplerate, FRAMES_PER_BUFFER, 0,
				//paClipOff | paDitherOff,
				paNoFlag,
				pa_callback, (void *)userdata);
   
      SHOW("wave_open_sound > Pa_OpenDefaultStream(1): err=%d (%s)\n",err, Pa_GetErrorText(err));      

      if(err == paInvalidChannelCount)
	{
	  SHOW_TIME("wave_open_sound > try stereo");
	  // failed to open with mono, try stereo
	  out_channels = 2;
	  //	  myOutputParameters.channelCount = out_channels;
	  PaError err = Pa_OpenStream( &pa_stream,
				       /* capture parameters */
				       paNoDevice,
				       0,
				       paInt16,
				       NULL,
				       /* playback parameters */
				       playbackDevice,
				       out_channels,
				       paInt16,
				       NULL,
				       /* general parameters */
				       wave_samplerate, FRAMES_PER_BUFFER, 0,
				       //paClipOff | paDitherOff,
				       paNoFlag,
				       pa_callback, (void *)userdata);
// 	  err = Pa_OpenDefaultStream(&pa_stream,0,2,paInt16,
// 				     wave_samplerate,
// 				     FRAMES_PER_BUFFER,
// 				     N_WAV_BUF,pa_callback,(void *)userdata);
	  SHOW("wave_open_sound > Pa_OpenDefaultStream(2): err=%d (%s)\n",err, Pa_GetErrorText(err));
	  err=0; // avoid warning
	}
   mInCallbackFinishedState = false; // v18 only
#else
      myOutputParameters.channelCount = out_channels;
      unsigned long framesPerBuffer = paFramesPerBufferUnspecified;
      err = Pa_OpenStream(
			  &pa_stream,
			  NULL, /* no input */
			  &myOutputParameters,
			  wave_samplerate,
			  framesPerBuffer,
			  paNoFlag,
			  //			  paClipOff | paDitherOff,
			  pa_callback,
			  (void *)userdata);
      if ((err!=paNoError) 
	  && (err!=paInvalidChannelCount)) //err==paUnanticipatedHostError
	{
	  fprintf(stderr, "wave_open_sound > Pa_OpenStream : err=%d (%s)\n",err,Pa_GetErrorText(err));
	  framesPerBuffer = FRAMES_PER_BUFFER;
	  err = Pa_OpenStream(
			      &pa_stream,
			      NULL, /* no input */
			      &myOutputParameters,
			      wave_samplerate,
			      framesPerBuffer,
			      paNoFlag,
			      //			  paClipOff | paDitherOff,
			      pa_callback,
			      (void *)userdata);
	}
      if(err == paInvalidChannelCount)
	{
	  SHOW_TIME("wave_open_sound > try stereo");
	  // failed to open with mono, try stereo
	  out_channels = 2;
	  myOutputParameters.channelCount = out_channels;
	  err = Pa_OpenStream(
			       &pa_stream,
			       NULL, /* no input */
			       &myOutputParameters,
			       wave_samplerate,
			       framesPerBuffer,
			       paNoFlag,
			       //			       paClipOff | paDitherOff,
			       pa_callback,
			       (void *)userdata);

	  //	  err = Pa_OpenDefaultStream(&pa_stream,0,2,paInt16,(double)wave_samplerate,FRAMES_PER_BUFFER,pa_callback,(void *)userdata);
	}
      mInCallbackFinishedState = false;
#endif
    }

  SHOW("wave_open_sound > %s\n","LEAVE");

  return (err != paNoError);
}
Esempio n. 4
0
static int output_data(char *buf, int32 nbytes)
{
	unsigned int i;
	int32 samplesToGo;
	char *bufepoint;

    if(pa_active == 0) return -1; 
	
	while((pa_active==1) && (pa_data.samplesToGo > bytesPerInBuffer)){ Pa_Sleep(1);};
	
//	if(pa_data.samplesToGo > DATA_BLOCK_SIZE){ 
//		Sleep(  (pa_data.samplesToGo - DATA_BLOCK_SIZE)/dpm.rate/4  );
//	}
	samplesToGo=pa_data.samplesToGo;
	bufepoint=pa_data.bufepoint;

	if (pa_data.buf+bytesPerInBuffer*2 >= bufepoint + nbytes){
		memcpy(bufepoint, buf, nbytes);
		bufepoint += nbytes;
		//buf += nbytes;
	}else{
		int32 send = pa_data.buf+bytesPerInBuffer*2 - bufepoint;
		if (send != 0) memcpy(bufepoint, buf, send);
		buf += send;
		memcpy(pa_data.buf, buf, nbytes - send);
		bufepoint = pa_data.buf + nbytes - send;
		//buf += nbytes-send;
	}
	samplesToGo += nbytes;

	pa_data.samplesToGo=samplesToGo;
	pa_data.bufepoint=bufepoint;

/*
	if(firsttime==1){
		err = Pa_StartStream( stream );

		if( err != paNoError ) goto error;
		firsttime=0;
	}
*/
#if PORTAUDIO_V19
	if( 0==Pa_IsStreamActive(stream)){
#else
	if( 0==Pa_StreamActive(stream)){
#endif
		err = Pa_StartStream( stream );

		if( err != paNoError ) goto error;
	}
		
//	if(ctl->id_character != 'r' && ctl->id_character != 'A' && ctl->id_character != 'W' && ctl->id_character != 'P')
//	    while((pa_active==1) && (pa_data.samplesToGo > bytesPerInBuffer)){ Pa_Sleep(1);};
//	Pa_Sleep( (pa_data.samplesToGo - bytesPerInBuffer)/dpm.rate * 1000);
	return 0;

error:
	Pa_Terminate(); pa_active=0;
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "PortAudio error: %s\n", Pa_GetErrorText( err ) );
	return -1;
}

static void close_output(void)
{	
	if( pa_active==0) return;
#ifdef PORTAUDIO_V19
	if(Pa_IsStreamActive(stream)){
#else
	if(Pa_StreamActive(stream)){
#endif
		Pa_Sleep(  bytesPerInBuffer/dpm.rate*1000  );
	}	
	err = Pa_AbortStream( stream );
    if( (err!=paStreamIsStopped) && (err!=paNoError) ) goto error;
	err = Pa_CloseStream( stream );
//	if( err != paNoError ) goto error;
	Pa_Terminate(); 
	pa_active=0;

#ifdef AU_PORTAUDIO_DLL
#ifndef PORTAUDIO_V19
  free_portaudio_dll();
#endif
#endif

	return;

error:
	Pa_Terminate(); pa_active=0;
#ifdef AU_PORTAUDIO_DLL
#ifndef PORTAUDIO_V19
  free_portaudio_dll();
#endif
#endif
	ctl->cmsg(  CMSG_ERROR, VERB_NORMAL, "PortAudio error: %s\n", Pa_GetErrorText( err ) );
	return;
}


static int acntl(int request, void *arg)
{
    switch(request)
    {
 
      case PM_REQ_GETQSIZ:
		 *(int *)arg = bytesPerInBuffer*2;
    	return 0;
		//break;
      case PM_REQ_GETFILLABLE:
		 *(int *)arg = bytesPerInBuffer*2-pa_data.samplesToGo;
    	return 0;
		//break;
      case PM_REQ_GETFILLED:
		 *(int *)arg = pa_data.samplesToGo;
    	return 0;
		//break;

    	
   	case PM_REQ_DISCARD:
    case PM_REQ_FLUSH:
    	pa_data.samplesToGo=0;
    	pa_data.bufpoint=pa_data.bufepoint;
    	err = Pa_AbortStream( stream );
    	if( (err!=paStreamIsStopped) && (err!=paNoError) ) goto error;
    	err = Pa_StartStream( stream );
    	if(err!=paNoError) goto error;
		return 0;

		//break;

    case PM_REQ_RATE:  
    	{
    		int i;
    		double sampleRateBack;
    		i = *(int *)arg; //* sample rate in and out *
    		close_output();
    		sampleRateBack=dpm.rate;
    		dpm.rate=i;
    		if(0==open_output()){
    			return 0;
    		}else{    		
    			dpm.rate=sampleRateBack;
    			open_output();
    			return -1;
    		}
    	}
    	//break;

//    case PM_REQ_RATE: 
//          return -1;
    	
    case PM_REQ_PLAY_START: //* Called just before playing *
    case PM_REQ_PLAY_END: //* Called just after playing *
        return 0;
      
	default:
    	return -1;

    }
	return -1;
error:
/*
	Pa_Terminate(); pa_active=0;
#ifdef AU_PORTAUDIO_DLL
  free_portaudio_dll();
#endif
*/
	ctl->cmsg(  CMSG_ERROR, VERB_NORMAL, "PortAudio error in acntl : %s\n", Pa_GetErrorText( err ) );
	return -1;
}


static void print_device_list(void){
	PaDeviceIndex maxDeviceIndex, i;
	PaHostApiIndex HostApiIndex;
	const PaDeviceInfo* DeviceInfo;

#if PORTAUDIO_V19
	HostApiIndex=Pa_HostApiTypeIdToHostApiIndex(HostApiTypeId);
#endif
	
	maxDeviceIndex=Pa_GetDeviceCount();
	
	for( i = 0; i < maxDeviceIndex; i++){
		DeviceInfo=Pa_GetDeviceInfo(i);
#if PORTAUDIO_V19
		if( DeviceInfo->hostApi == HostApiIndex){
#endif
			if( DeviceInfo->maxOutputChannels > 0){
				ctl->cmsg(  CMSG_ERROR, VERB_NORMAL, "%2d %s",i,DeviceInfo->name);
			}
#if PORTAUDIO_V19
		}
#endif
	}
}
Esempio n. 5
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");
        ;
    }
    for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0;

    err = Pa_Initialize();
    if( err != paNoError ) {};

    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
    if (inputParameters.device == paNoDevice) {
        fprintf(stderr,"Error: No default input device.\n");
        ;
    }
    inputParameters.channelCount = NUM_CHANNELS;
    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 ) {};
//
//    err = Pa_StartStream( stream );
//    if( err != paNoError ) {};
//    printf("\n=== Sprawdzam poziom szumów. Nie mów nic. ===\n"); fflush(stdout);
//
//    while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
//    {
//        Pa_Sleep(1000);
//        printf("index = %d\n", data.frameIndex ); fflush(stdout);
//    }
//    if( err < 0 ){};
//
//    err = Pa_CloseStream( stream );
//    if( err != paNoError ) {};




    data.frameIndex = 0;
    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 ) {};

    err = Pa_StartStream( stream );
        if( err != paNoError ) {};
        printf("\n=== Teraz nagrywam powiedź coś. ===\n"); fflush(stdout);

        while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
        {
            Pa_Sleep(1000);
            printf("index = %d\n", data.frameIndex ); fflush(stdout);
        }
        if( err < 0 ){};

        err = Pa_CloseStream( stream );
        if( err != paNoError ) {};

        /* 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("maksymalna amplituda  = "PRINTF_S_FORMAT"\n", max );
           printf("srednia = %lf\n", average );
    zapiszWykres(numSamples, data);
    zapiszHistogram(numSamples, data);
    //przejsciaPrzezZero(numSamples, data, 0);
    przejsciaPrzezZero(numSamples, data, average);

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

    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
    if (outputParameters.device == paNoDevice) {
        fprintf(stderr,"Error: No default output device.\n");

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

    printf("\n=== Now playing back. ===\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 ) {};

    if( stream )
    {
        err = Pa_StartStream( stream );
        if( err != paNoError ) {};

        printf("Waiting for playback to finish.\n"); fflush(stdout);

        while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
        if( err < 0 ) {};

        err = Pa_CloseStream( stream );
        if( err != paNoError ) {};

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


    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;
}
Esempio n. 6
0
int main(void) {
    PaStreamParameters  outputParameters;
    PaStream*           stream;
    PaError             err = paNoError;
    paTestData          data;
    int                 totalFrames;
    int                 numSamples;
    int                 numBytes;


    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;
    }

    if( err != paNoError ) goto done;

    FILE * pFile;
    long lSize;
    size_t result;

    pFile = fopen ( "recorded.raw" , "rb" );
    if (pFile==NULL) {
        fputs ("Error opening file!",stderr);
        exit (1);
    }

    // obtain file size:
    fseek (pFile , 0 , SEEK_END);
    lSize = ftell (pFile);
    rewind (pFile);

    // copy the file into the buffer:
    result = fread( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), lSize / (NUM_CHANNELS * sizeof(SAMPLE)), pFile );
    if (result != lSize / (NUM_CHANNELS * sizeof(SAMPLE))) {
        fputs ("Reading error, file may be corrupted\n",stderr);
        exit (3);
    }
    fclose (pFile);





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

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

    printf("\n=== Now playing back. ===\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;
}
Esempio n. 7
0
int main(int argc, char* argv[])
{
    PaStream                *stream;
    PaError                 err;
    patest1data             data;
    int                     i;
    PaStreamParameters      inputParameters, outputParameters;
    const PaHostErrorInfo*  herr;

    printf("patest1.c\n"); fflush(stdout);
    printf("Ring modulate input for 20 seconds.\n"); fflush(stdout);
    
    /* initialise sinusoidal wavetable */
    for( i=0; i<100; i++ )
        data.sine[i] = sin( ((double)i/100.) * M_PI * 2. );
    data.phase = 0;
    data.sampsToGo = SAMPLE_RATE * 20;        /* 20 seconds. */

    /* initialise portaudio subsytem */
    err = Pa_Initialize();

    inputParameters.device = Pa_GetDefaultInputDevice();    /* default input device */
    if (inputParameters.device == paNoDevice) {
      fprintf(stderr,"Error: No input default device.\n");
      goto done;
    }
    inputParameters.channelCount = 2;                       /* stereo input */
    inputParameters.sampleFormat = paFloat32;               /* 32 bit floating point input */
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
    inputParameters.hostApiSpecificStreamInfo = NULL;

    outputParameters.device = Pa_GetDefaultOutputDevice();  /* default output device */
    if (outputParameters.device == paNoDevice) {
      fprintf(stderr,"Error: No default output device.\n");
      goto done;
    }
    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,
                        &inputParameters,
                        &outputParameters,
                        (double)SAMPLE_RATE, /* Samplerate in Hertz. */
                        512,                 /* Small buffers */
                        paClipOff,           /* We won't output out of range samples so don't bother clipping them. */
                        patest1Callback,
                        &data );
    if( err != paNoError ) goto done;

    err = Pa_StartStream( stream );
    if( err != paNoError ) goto done;
    
    printf( "Press any key to end.\n" ); fflush(stdout);
         
    getc( stdin ); /* wait for input before exiting */

    err = Pa_AbortStream( stream );
    if( err != paNoError ) goto done;
    
    printf( "Waiting for stream to complete...\n" );

    /* sleep until playback has finished */
    while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(1000);
    if( err < 0 ) goto done;

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

done:
    Pa_Terminate();

    if( err != paNoError )
    {
        fprintf( stderr, "An error occured while using portaudio\n" );
        if( err == paUnanticipatedHostError )
        {
            fprintf( stderr, " unanticipated host error.\n");
            herr = Pa_GetLastHostErrorInfo();
            if (herr)
            {
                fprintf( stderr, " Error number: %ld\n", herr->errorCode );
                if (herr->errorText)
                    fprintf( stderr, " Error text: %s\n", herr->errorText );
            }
            else
                fprintf( stderr, " Pa_GetLastHostErrorInfo() failed!\n" );
        }
        else
        {
            fprintf( stderr, " Error number: %d\n", err );
            fprintf( stderr, " Error text: %s\n", Pa_GetErrorText( err ) );
        }

        err = 1;          /* Always return 0 or 1, but no other return codes. */
    }

    printf( "bye\n" );

    return err;
}
Esempio n. 8
0
int pa_wavplayrec(SAMPLE *buffer, int buflen, int bufchannels, SAMPLE *recbuffer, int recbuffirstchannel, int recbufflastchannel, int recbuflen, int deviceID, int recdevID, int samplerate)
{
	//mexPrintf("buflen=%i bufchannels=%i samplerate=%i\n", buflen, bufchannels, samplerate);

	// Make our wavData object, to pass to OpenStream. This gets given to us again in the
	// callback. I guess you could just have a global variable instead...
	paWavData wav;
	wav.buffer = buffer;
	wav.recbuffer = recbuffer;
	wav.buflen = buflen;
	wav.recbuflen = recbuflen;
	wav.bufchannels = bufchannels;
	wav.recbuffirstchan = recbuffirstchannel;
	wav.recbufflastchan = recbufflastchannel;
	wav.bufpos = 0;
	wav.recbufpos = 0;
	
	if (recbuffer == NULL)
		if (buffer == NULL)
			mexErrMsgTxt("recbuffer && buffer NULL in pa_wavplay");
		else
		{
			mexPrintf("Playing on device %i\n", deviceID);
			wav.recmode = play;
		}
	else
		if (buffer == NULL)
		{
			mexPrintf("Recording on device %i\n", recdevID);
			wav.recmode = record;
		}
		else
		{
			mexPrintf("Recording on device %i\n", recdevID);
			mexPrintf("Playing on device %i\n", deviceID);

			wav.recmode = playrecord;
		}

	PaStream *stream;
    PaError err;

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

	int dev_type_indx = -1;
	const PaHostApiInfo* Api_Info;
	int num_APIs = (int )Pa_GetHostApiCount();
	for (int i=0; i<num_APIs; i++) {
 		Api_Info = Pa_GetHostApiInfo(i);
		if (strcmp(Api_Info->name,API_NAME)==0)
			dev_type_indx = i;
	}
	if (dev_type_indx == -1) {
		goto error;
	}
	Api_Info = Pa_GetHostApiInfo(dev_type_indx);
	if (recdevID != -1)
		recdevID = Pa_HostApiDeviceIndexToDeviceIndex(dev_type_indx, recdevID);
	if (deviceID != -1)
		deviceID = Pa_HostApiDeviceIndexToDeviceIndex(dev_type_indx, deviceID);
	
	// Open an audio I/O stream. 
	PaWasapiStreamInfo api_info;
	api_info.size = sizeof(PaWasapiStreamInfo);
	api_info.version = 1;
	api_info.hostApiType = paWASAPI;
	api_info.flags = paWinWasapiExclusive;
	void *p_api_info;
	if ((strcmp(API_NAME, "Windows WASAPI")== 0)) {
		p_api_info = &api_info;
	} else {
		p_api_info = NULL;
	}
    PaStreamParameters inputParameters;		// Parameters governing portaudio input stream
	PaStreamParameters outputParameters;	// Parameters governing portaudio output stream
    inputParameters.channelCount = recbufflastchannel;
    inputParameters.device = recdevID;
    inputParameters.hostApiSpecificStreamInfo = p_api_info;
    inputParameters.sampleFormat = paFloat32;	// Input data returned as floating point
	if (recdevID != -1)
	    inputParameters.suggestedLatency = Pa_GetDeviceInfo(recdevID)->defaultLowInputLatency ;
	outputParameters.channelCount = bufchannels;
    outputParameters.device = deviceID;
    outputParameters.hostApiSpecificStreamInfo = p_api_info;
    outputParameters.sampleFormat = paFloat32;	// Output data returned as floating point
	if (deviceID != -1)
	    outputParameters.suggestedLatency = Pa_GetDeviceInfo(deviceID)->defaultLowInputLatency ;

	err = Pa_IsFormatSupported(NULL, &outputParameters, (double )samplerate);

	if (recbuffer == NULL)
		err = Pa_OpenStream(
			  &stream,
			  NULL,
			  &outputParameters,
			  samplerate,     // stream sample rate
			  BLOCK,            // frames per buffer 
			  paNoFlag,       // stream flag
			  (PaStreamCallback (__cdecl *))paWavCallback,  // callback function
			  &wav);          // user data
	else
		if (buffer == NULL)
			err = Pa_OpenStream(
				  &stream,
				  &inputParameters,
				  NULL,
				  samplerate,     // stream sample rate
				  BLOCK,            // frames per buffer 
				  paNoFlag,       // stream flag
				  (PaStreamCallback (__cdecl *))paWavCallback,  // callback function
				  &wav);          // user data
		else
			err = Pa_OpenStream(
				  &stream,
				  &inputParameters,
				  &outputParameters,
				  samplerate,     // stream sample rate
				  BLOCK,            // frames per buffer 
				  paNoFlag,       // stream flag
				  (PaStreamCallback (__cdecl *))paWavCallback,  // callback function
				  &wav);          // user data


    if( err != paNoError ) 
		goto error;

    err = Pa_StartStream( stream );
    
	if( err != paNoError ) 
		goto error;
    
	// sleep while stream's active
	while( Pa_IsStreamActive(stream) )
		Pa_Sleep( 50 );

	if (err = Pa_IsStreamStopped( stream ) == 0) {
	    err = Pa_StopStream( stream );
	    if( err != paNoError ) 
			goto error;
	} else if (err != paNoError )
		goto error;

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

	return err;

	// wtf? A goto? Yeah, that's leftover from the portaudio example code
error:
    Pa_Terminate();
    mexPrintf( "An error occured while using the portaudio stream\n" );
    mexPrintf( "Error number: %d\n", err );
    mexPrintf( "Error message: %s\n", Pa_GetErrorText( err ) );
    return err;
	
}
Esempio n. 9
0
int main(void)
{
    PaStreamParameters  outputParameters;
    PaStream*           stream;
    PaError             err;
    paTestData          data;
    PaTime              streamOpened;
    int                 i, 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;

    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 = TEST_FORMAT;
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;
    err = Pa_OpenStream( &stream,
                         NULL,      /* No input. */
                         &outputParameters,
                         SAMPLE_RATE,
                         256,       /* 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;

    streamOpened = Pa_GetStreamTime( stream ); /* Time in seconds when stream was opened (approx). */

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

    /* Watch until sound is halfway finished. */
    /* (Was ( Pa_StreamTime( stream ) < (totalSamps/2) ) in V18. */
    while( (Pa_GetStreamTime( stream ) - streamOpened) < (PaTime)NUM_SECONDS / 2.0 )
        Pa_Sleep(10);

    /* Stop sound. */
    printf("Stopping Stream.\n");
    err = Pa_StopStream( stream );
    if( err != paNoError )
        goto error;

    printf("Pause for 2 seconds.\n");
    Pa_Sleep( 2000 );

    printf("Starting again.\n");
    err = Pa_StartStream( stream );
    if( err != paNoError )
        goto error;

    printf("Waiting for sound to finish.\n");

    while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
        Pa_Sleep(100);
    if( err < 0 )
        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 selectDevice()
{
    int     			i, 
						numDevices, 
						defaultDisplayed;
    const PaDeviceInfo 	*deviceInfo;
    PaStreamParameters 	inputParameters, 
						outputParameters;
	PaStream*			stream;
    PaError 			err;
	
    paTestData          data;
    int                 totalFrames;
    int                 numSamples;
    int                 numBytes;
	char 				devSelection[4];
	int					devSelectInt;

    
    err = Pa_Initialize();
    if( err != paNoError )
    {
        printf( "ERROR: Pa_Initialize returned 0x%x\n", err );
        goto error;
    }
    
    printf( "PortAudio version: 0x%08X\n", Pa_GetVersion());
    printf( "Version text: '%s'\n", Pa_GetVersionInfo()->versionText );

    numDevices = Pa_GetDeviceCount();
    if( numDevices < 0 )
    {
        printf( "ERROR: Pa_GetDeviceCount returned 0x%x\n", numDevices );
        err = numDevices;
        goto error;
    }
    
    printf( "Number of devices = %d\n", numDevices );
    for( i=0; i<numDevices; i++ )
    {
        deviceInfo = Pa_GetDeviceInfo( i );
        printf( "--------------------------------------- device #%d\n", i );
                
    /* Mark global and API specific default devices */
        defaultDisplayed = 0;
        if( i == Pa_GetDefaultInputDevice() )
        {
            printf( "[ Default Input" );
            defaultDisplayed = 1;
        }
        else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultInputDevice )
        {
            const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
            printf( "[ Default %s Input", hostInfo->name );
            defaultDisplayed = 1;
        }
        
        if( i == Pa_GetDefaultOutputDevice() )
        {
            printf( (defaultDisplayed ? "," : "[") );
            printf( " Default Output" );
            defaultDisplayed = 1;
        }
        else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultOutputDevice )
        {
            const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
            printf( (defaultDisplayed ? "," : "[") );                
            printf( " Default %s Output", hostInfo->name );
            defaultDisplayed = 1;
        }

        if( defaultDisplayed )
            printf( " ]\n" );

    /* print device info fields */
#ifdef WIN32
        {   /* Use wide char on windows, so we can show UTF-8 encoded device names */
            wchar_t wideName[MAX_PATH];
            MultiByteToWideChar(CP_UTF8, 0, deviceInfo->name, -1, wideName, MAX_PATH-1);
            wprintf( L"Name                        = %s\n", wideName );
        }
#else
        printf( "Name                        = %s\n", deviceInfo->name );
#endif
        printf( "Host API                    = %s\n",  Pa_GetHostApiInfo( deviceInfo->hostApi )->name );
        printf( "Max inputs = %d", deviceInfo->maxInputChannels  );
        printf( ", Max outputs = %d\n", deviceInfo->maxOutputChannels  );

        printf( "Default low input latency   = %8.4f\n", deviceInfo->defaultLowInputLatency  );
        printf( "Default low output latency  = %8.4f\n", deviceInfo->defaultLowOutputLatency  );
        printf( "Default high input latency  = %8.4f\n", deviceInfo->defaultHighInputLatency  );
        printf( "Default high output latency = %8.4f\n", deviceInfo->defaultHighOutputLatency  );

#ifdef WIN32
#if PA_USE_ASIO
/* ASIO specific latency information */
        if( Pa_GetHostApiInfo( deviceInfo->hostApi )->type == paASIO ){
            long minLatency, maxLatency, preferredLatency, granularity;

            err = PaAsio_GetAvailableLatencyValues( i,
		            &minLatency, &maxLatency, &preferredLatency, &granularity );

            printf( "ASIO minimum buffer size    = %ld\n", minLatency  );
            printf( "ASIO maximum buffer size    = %ld\n", maxLatency  );
            printf( "ASIO preferred buffer size  = %ld\n", preferredLatency  );

            if( granularity == -1 )
                printf( "ASIO buffer granularity     = power of 2\n" );
            else
                printf( "ASIO buffer granularity     = %ld\n", granularity  );
        }
#endif /* PA_USE_ASIO */
#endif /* WIN32 */

        printf( "Default sample rate         = %8.2f\n", deviceInfo->defaultSampleRate );

    /* poll for standard sample rates */
        inputParameters.device = i;
        inputParameters.channelCount = deviceInfo->maxInputChannels;
        inputParameters.sampleFormat = paInt16;
        inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
        inputParameters.hostApiSpecificStreamInfo = NULL;
        
        outputParameters.device = i;
        outputParameters.channelCount = deviceInfo->maxOutputChannels;
        outputParameters.sampleFormat = paInt16;
        outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
        outputParameters.hostApiSpecificStreamInfo = NULL;

        if( inputParameters.channelCount > 0 )
        {
            printf("Supported standard sample rates\n for half-duplex 16 bit %d channel input = \n",
                    inputParameters.channelCount );
            PrintSupportedStandardSampleRates( &inputParameters, NULL );
        }

        if( outputParameters.channelCount > 0 )
        {
            printf("Supported standard sample rates\n for half-duplex 16 bit %d channel output = \n",
                    outputParameters.channelCount );
            PrintSupportedStandardSampleRates( NULL, &outputParameters );
        }

        if( inputParameters.channelCount > 0 && outputParameters.channelCount > 0 )
        {
            printf("Supported standard sample rates\n for full-duplex 16 bit %d channel input, %d channel output = \n",
                    inputParameters.channelCount, outputParameters.channelCount );
            PrintSupportedStandardSampleRates( &inputParameters, &outputParameters );
        }
    } /* for numDevices */
	
	
	printf("What input device would you like to use? ");	
	fgets(devSelection, 4, stdin);
	devSelectInt	= atoi(devSelection);
	
	if(devSelectInt < numDevices)
	{
		printf("Hooray!  You chose device %s, which is within bounds.\n", devSelection);
		
		inputParameters.device	= devSelectInt;
		if(inputParameters.device == paNoDevice)
		{
			fprintf(stderr,"Error: input device at that device number.\n");
			goto error;
		} // if - no device
		
		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 error;
		}
		for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0;
		
		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 error;

		err = Pa_StartStream( stream );
		if( err != paNoError ) goto error;
		printf("\n=== Now recording!! Please speak into the microphone. ===\n"); fflush(stdout);

		while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
		{
			Pa_Sleep(100);
			printf("index = %d; amplitude = %f\n", data.frameIndex, data.recordedSamples[data.frameIndex] ); fflush(stdout);
		}
		if( err < 0 ) goto error;

		err = Pa_CloseStream( stream );
		if( err != paNoError ) goto error;
			
	} // if - device number within bounds

    Pa_Terminate();

    printf("----------------------------------------------\n");
    return 0;

error:
    Pa_Terminate();
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return err;
} /* selectDevice */
Esempio n. 11
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 */
	if (inputParameters.device == paNoDevice) {
		fprintf(stderr, "Error: No default input device.\n");
		goto done;
	}
	inputParameters.channelCount = 1;                    /* stereo input */
	inputParameters.sampleFormat = PA_SAMPLE_TYPE;
	inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
	inputParameters.hostApiSpecificStreamInfo = NULL;

	//set a keyboard hit to start recording. Added by Yao Canwu
	printf("Press any key to start recording\n");
	while (!kbhit()){}

	/* Record some audio. -------------------------------------------- */
	err = Pa_OpenStream(
		&stream,
		&inputParameters,
		NULL,                  /* &outputParameters, */
		SAMPLE_RATE,
		FRAMES_PER_BUFFER,
		paClipOff,      /* we won't output out of range samples so don't bother clipping them */
		recordCallback,
		&data);
	if (err != paNoError) goto done;

	err = Pa_StartStream(stream);
	if (err != paNoError) goto done;
	printf("\n=== Now start recording!!\n"); fflush(stdout);
	/* Pa_IsStreamActive: Determine whether the stream is active. A stream
	is active after a successful call to Pa_StartStream(), until it becomes
	inactive either as a result of a call to Pa_StopStream() or Pa_AbortStream(),
	or as a result of a return value other than paContinue from the stream callback.
	In the latter case, the stream is considered inactive after the last buffer has finished playing. */
	while ((err = Pa_IsStreamActive(stream)) == 1)
	{
		Pa_Sleep(1000);
		printf("index = %d\n", data.frameIndex); fflush(stdout);
	}
	if (err < 0) goto done;

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

	//Write wave to file in wav formate. Added by Yao Canwu
	printf("Waiting to save into file...\n");
	char *path = "audio.wav";
	WriteWave(path, data.recordedSamples, data.maxFrameIndex, SAMPLE_RATE);
	printf("Save successfully!\n");

	/* Write recorded data to a file. */
#if WRITE_TO_FILE
	{
		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 */
	if (outputParameters.device == paNoDevice) {
		fprintf(stderr, "Error: No default output device.\n");
		goto done;
	}
	outputParameters.channelCount = 1;                     /* stereo output */
	outputParameters.sampleFormat = PA_SAMPLE_TYPE;
	outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
	outputParameters.hostApiSpecificStreamInfo = NULL;

	printf("\n=== Now playing back. ===\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. */
	}
	system("pause");
	return err;
}
Esempio n. 12
0
void
playSynthesizedVoice (dsd_opts * opts, dsd_state * state)
{
    ssize_t result;

    if (state->audio_out_idx > opts->delay)
    {
        // output synthesized speech to sound card
        if(opts->audio_out_type == 2)
        {
#ifdef USE_PORTAUDIO
            PaError err = paNoError;
            do
            {
                long available = Pa_GetStreamWriteAvailable( opts->audio_out_pa_stream );
                if(available < 0)
                    err = available;
                //printf("Frames available: %d\n", available);
                if( err != paNoError )
                    break;
                if(available > SAMPLE_RATE_OUT * PA_LATENCY_OUT)
                {
                    //It looks like this might not be needed for very small latencies. However, it's definitely needed for a bit larger ones.
                    //When PA_LATENCY_OUT == 0.500 I get output buffer underruns if I don't use this. With PA_LATENCY_OUT <= 0.100 I don't see those happen.
                    //But with PA_LATENCY_OUT < 0.100 I run the risk of choppy audio and stream errors.
                    printf("\nSyncing voice output stream\n");
                    err = Pa_StopStream( opts->audio_out_pa_stream );
                    if( err != paNoError )
                        break;
                }

                err = Pa_IsStreamActive( opts->audio_out_pa_stream );
                if(err == 0)
                {
                    printf("Start voice output stream\n");
                    err = Pa_StartStream( opts->audio_out_pa_stream );
                }
                else if(err == 1)
                {
                    err = paNoError;
                }
                if( err != paNoError )
                    break;

                //printf("write stream %d\n", state->audio_out_idx);
                err = Pa_WriteStream( opts->audio_out_pa_stream, (state->audio_out_buf_p - state->audio_out_idx), state->audio_out_idx );
                if( err != paNoError )
                    break;
            } while(0);

            if( err != paNoError )
            {
                fprintf( stderr, "An error occured while using the portaudio output stream\n" );
                fprintf( stderr, "Error number: %d\n", err );
                fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
            }

#endif
        }
        else if (opts->audio_out_fd == -1)
        {
            memcpy(state->output_buffer + state->output_offset, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2));
            state->output_offset += state->audio_out_idx;
        }
        else
        {
            result = write (opts->audio_out_fd, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2));
        }
        state->audio_out_idx = 0;
    }

    if (state->audio_out_idx2 >= 800000)
    {
        state->audio_out_float_buf_p = state->audio_out_float_buf + 100;
        state->audio_out_buf_p = state->audio_out_buf + 100;
        memset (state->audio_out_float_buf, 0, 100 * sizeof (float));
        memset (state->audio_out_buf, 0, 100 * sizeof (short));
        state->audio_out_idx2 = 0;
    }
}
Esempio n. 13
0
JNIEXPORT jboolean JNICALL Java_org_jpab_PortAudio_isStreamActive(JNIEnv *env, jclass paClass, jlong stream_id) {
    PaError error = (UINT32) Pa_IsStreamActive((PaStream *) stream_id);
    if (error < 0) org_jpab_throw_exception(env, (PaError *) &error);
	return error == 1 ? JNI_TRUE : JNI_FALSE;
}
bool PortAudioHelper::isRecording() const {
    return Pa_IsStreamActive( stream );
}
Esempio n. 15
0
int AudioDevice_isActive(AudioDevice *self)
{
	return AudioDevice_isOpen(self) ? Pa_IsStreamActive( self->stream ) : 0;
}
Esempio n. 16
0
int patestMain(void) {
    PaError err;
    PaStream *stream;
    paTestData data;
    // int totalFrames;
    int numSamples;
    int totalBytes;
    int i;
    PaStreamParameters inputParameters;
    int targetDevId = 0;
    float currEnergy = 0.0;

    FILE  *fid;
    fid = fopen("recorded.raw", "ab");
    if( fid == NULL )
    {
        fprintf(stderr, "Could not open file.\n");
        return 3;
    }

    // preparing the buffer
    data.maxFrameIndex = numSamples = BUF_SECONDS * SAMPLE_RATE;
    // totalBytes = numSamples * sizeof(C_DATA_TYPE);

    data.recordedSamples = (C_DATA_TYPE *) malloc (numSamples * sizeof(C_DATA_TYPE));
    for (i = 0; i < numSamples; i++) {
        data.recordedSamples[i] = 0;
    }

    // check device
    // targetDevId = patestCheckDevice();
    targetDevId = Pa_GetDefaultInputDevice();
    fprintf(stderr, "Using device ID %d\n", targetDevId);

    // preparing the parameters
    inputParameters.device = targetDevId;
    inputParameters.channelCount = NUM_CHANNELS;
    inputParameters.sampleFormat = PA_DATA_TYPE;
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
    inputParameters.hostApiSpecificStreamInfo = NULL;
    fprintf(stderr, "\n=== Now recording!! Please speak into the microphone. ===\n");
    fflush(stderr);


    while (1) {
        data.frameIndex = 0;

        // Opens stream
        err = Pa_OpenStream(
                  &stream,
                  &inputParameters,
                  NULL,                  /*  &outputParameters, */
                  SAMPLE_RATE,
                  // FRAMES_PER_BUFFER,
                  paFramesPerBufferUnspecified,
                  paClipOff,      /*  we won't output out of range samples so don't bother clipping them */
                  recordCallback,
                  &data );

        if (err != paNoError) {
            fprintf(stderr, "Error: %s\n", Pa_GetErrorText(err));
        }

        // start the stream
        err = Pa_StartStream( stream );

        if (Pa_IsStreamActive(stream) != 1) {
            fprintf(stderr, "Stream not active ... \n");
        }

        while((err = Pa_IsStreamActive(stream)) == 1)
        {
            Pa_Sleep(100);
            fprintf(stderr, "index = %d\n", data.frameIndex );
            fflush(stderr);
        }

        // write the recorded audio to file
        fwrite(data.recordedSamples, sizeof(C_DATA_TYPE), data.maxFrameIndex, fid);
        fprintf(stderr, "Wrote %d bytes to 'recorded.raw'\n", data.maxFrameIndex * sizeof(C_DATA_TYPE));

        // compute the energy of each frame
        // for (i = 0; i < numSamples; i+=100) {
        // float frameEnergy(C_DATA_TYPE *samples, long sampleLen, long frameIdx, int frameSpan) {
        // currEnergy = frameEnergy(data.recordedSamples, numSamples, i, 10);
        // fprintf(stderr, "Energy at frame %d: %f\n", i, currEnergy);
        // }
    }

    fclose( fid );
    err = Pa_StopStream(stream);
    err = Pa_CloseStream(stream);
    free(data.recordedSamples);

    return 0;
}
Esempio n. 17
0
static int wave_open_sound()
{
	PaError err = paNoError;
	PaError active;

#if USE_PORTAUDIO == 18
	active = Pa_StreamActive(pa_stream);
#else
	active = Pa_IsStreamActive(pa_stream);
#endif

	if (active == 1)
		return 0;
	if (active < 0) {
		out_channels = 1;

#if USE_PORTAUDIO == 18
		err = Pa_OpenStream(&pa_stream,
		                    // capture parameters
		                    paNoDevice,
		                    0,
		                    paInt16,
		                    NULL,
		                    // playback parameters
		                    myOutputDevice,
		                    out_channels,
		                    paInt16,
		                    NULL,
		                    // general parameters
		                    wave_samplerate, FRAMES_PER_BUFFER, 0,
		                    paNoFlag,
		                    pa_callback, (void *)userdata);

		if (err == paInvalidChannelCount) {
			// failed to open with mono, try stereo
			out_channels = 2;
			err = Pa_OpenStream(&pa_stream,
			                    // capture parameters
			                    paNoDevice,
			                    0,
			                    paInt16,
			                    NULL,
			                    // playback parameters
			                    myOutputDevice,
			                    out_channels,
			                    paInt16,
			                    NULL,
			                    // general parameters
			                    wave_samplerate, FRAMES_PER_BUFFER, 0,
			                    paNoFlag,
			                    pa_callback, (void *)userdata);
		}
		mInCallbackFinishedState = false; // v18 only
#else
		myOutputParameters.channelCount = out_channels;
		unsigned long framesPerBuffer = paFramesPerBufferUnspecified;
		err = Pa_OpenStream(&pa_stream,
		                    NULL, // no input
		                    &myOutputParameters,
		                    wave_samplerate,
		                    framesPerBuffer,
		                    paNoFlag,
		                    pa_callback,
		                    (void *)userdata);
		if ((err != paNoError)
		    && (err != paInvalidChannelCount)) {
			fprintf(stderr, "wave_open_sound > Pa_OpenStream : err=%d (%s)\n", err, Pa_GetErrorText(err));
			framesPerBuffer = FRAMES_PER_BUFFER;
			err = Pa_OpenStream(&pa_stream,
			                    NULL, // no input
			                    &myOutputParameters,
			                    wave_samplerate,
			                    framesPerBuffer,
			                    paNoFlag,
			                    pa_callback,
			                    (void *)userdata);
		}
		if (err == paInvalidChannelCount) {
			// failed to open with mono, try stereo
			out_channels = 2;
			myOutputParameters.channelCount = out_channels;
			err = Pa_OpenStream(&pa_stream,
			                    NULL, // no input
			                    &myOutputParameters,
			                    wave_samplerate,
			                    framesPerBuffer,
			                    paNoFlag,
			                    pa_callback,
			                    (void *)userdata);
		}
		mInCallbackFinishedState = false;
#endif
	}

	return err != paNoError;
}
Esempio n. 18
0
int main(int argc, char* argv[])
{
    PaStream *stream;
    PaError err;
    patest1data data;
    int i;
    int inputDevice = Pa_GetDefaultInputDevice();
    int outputDevice = Pa_GetDefaultOutputDevice();
    /* initialise sinusoidal wavetable */
    for( i=0; i<100; i++ )
        data.sine[i] = sin( ((double)i/100.) * M_PI * 2. );
    data.phase = 0;
    data.sampsToGo = 44100 * 20;   // 20 seconds
    /* initialise portaudio subsytem */
    Pa_Initialize();
    err = Pa_OpenStream(
              &stream,
              inputDevice,
              2,              /* stereo input */
              paFloat32,  /* 32 bit floating point input */
              NULL,
              outputDevice,
              2,              /* stereo output */
              paFloat32,      /* 32 bit floating point output */
              NULL,
              44100.,
              512,            /* small buffers */
              0,              /* let PA determine number of buffers */
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              patest1Callback,
              &data );
    if( err == paNoError )
    {
        err = Pa_StartStream( stream );
        printf( "Press any key to end.\n" );
        getc( stdin ); //wait for input before exiting
        Pa_AbortStream( stream );

        printf( "Waiting for stream to complete...\n" );

        while( Pa_IsStreamActive( stream ) )
            Pa_Sleep(1000); /* sleep until playback has finished */

        err = Pa_CloseStream( stream );
    }
    else
    {
        fprintf( stderr, "An error occured while opening the portaudio stream\n" );
        if( err == paHostError )
        {
            fprintf( stderr, "Host error number: %d\n", Pa_GetHostError() );
        }
        else
        {
            fprintf( stderr, "Error number: %d\n", err );
            fprintf( stderr, "Error text: %s\n", Pa_GetErrorText( err ) );
        }
    }
    Pa_Terminate();
    printf( "bye\n" );

    return 0;
}
Esempio n. 19
0
int main(void)
{
  PaStreamParameters  inputParameters,
                      outputParameters;
  PaStream*           stream;
  PaError             err = paNoError;
  paTestData          data;
  int                 totalFrames;
  int                 numSamples;
  int                 numBytes;
  SAMPLE              max, val;
  double              average;
	struct sockaddr_in myaddr, remaddr;
	int fd, i, slen=sizeof(remaddr);
	char buf[BUFLEN];	/* message buffer */
	int recvlen;		/* # bytes in acknowledgement message */
	char *server = "127.0.0.1";	/* change this to use a different server */

	/* create a socket */

	if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1)
		printf("socket created\n");

	/* bind it to all local addresses and pick any port number */

	memset((char *)&myaddr, 0, sizeof(myaddr));
	myaddr.sin_family = AF_INET;
	myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	myaddr.sin_port = htons(0);

	if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
		perror("bind failed");
		return 0;
	}       

	/* now define remaddr, the address to whom we want to send messages */
	/* For convenience, the host address is expressed as a numeric IP address */
	/* that we will convert to a binary format via inet_aton */

	memset((char *) &remaddr, 0, sizeof(remaddr));
	remaddr.sin_family = AF_INET;
	remaddr.sin_port = htons(SERVICE_PORT);
	if (inet_aton(server, &remaddr.sin_addr)==0) {
		fprintf(stderr, "inet_aton() failed\n");
		exit(1);
	}

  data.fd = fd;
  data.remaddr = (struct sockaddr *)  &remaddr;
  data.slen = slen;

  err = Pa_Initialize();
  if( err != paNoError ) exit(1);

  inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
  if (inputParameters.device == paNoDevice) {
      fprintf(stderr,"Error: No default input device.\n");
      exit(1);
  }
  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 */
            sendCallback,
            &data );
  if( err != paNoError ) exit(1);

  err = Pa_StartStream( stream );
  if( err != paNoError ) exit(1);
  printf("\n=== Now listenning!! Please speak into the microphone. ===\n"); fflush(stdout);

  while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
  {
    Pa_Sleep(1000);
    printf("index = \n"); fflush(stdout);
  }
  if( err < 0 ) exit(1);

  err = Pa_CloseStream( stream );
  if( err != paNoError ) exit(1);
	/* now let's send the messages */

	//close(fd);
	return 0;
}
Esempio n. 20
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 *instream, *outstream;
  PaStreamParameters inputParameters, outputParameters;
  //  PaStreamInfo *streamInfo;

  int nSampleRate = *nfsample;
  int ndevice_in = *ndevin;
  int ndevice_out = *ndevout;
  double dSampleRate = (double) *nfsample;
  PaError err_init, err_open_in, err_open_out, err_start_in, err_start_out;
  PaError err = 0;

  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 = nSampleRate;
  data.trperiod = TRPeriod;

  err_init = Pa_Initialize();                      // Initialize PortAudio

  if(err_init) {
    printf("Error initializing PortAudio.\n");
    printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_init), err_init);

    Pa_Terminate();  // I don't think we need this but...

    return(-1);
  }

  //  printf("Opening device %d for input, %d for output...\n",ndevice_in,ndevice_out);

  inputParameters.device = ndevice_in;
  inputParameters.channelCount = 2;
  inputParameters.sampleFormat = paInt16;
  inputParameters.suggestedLatency = 1.0;
  inputParameters.hostApiSpecificStreamInfo = NULL;

// Test if this configuration actually works, so we do not run into an ugly assertion
  err_open_in = Pa_IsFormatSupported(&inputParameters, NULL, dSampleRate);

  if (err_open_in == 0) {
    err_open_in = Pa_OpenStream(
		       &instream,       //address of stream
		       &inputParameters,
		       NULL,
		       dSampleRate,            //Sample rate
		       2048,            //Frames per buffer
		       paNoFlag,
		       (PaStreamCallback *)SoundIn,  //Callback routine
		       (void *)&data);  //address of data structure

    if(err_open_in) {   // We should have no error here usually
      printf("Error opening input audio stream:\n");
      printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_in), err_open_in);

      err = 1;
    } else {
      //      printf("Successfully opened audio input.\n");
    }
  } else {
    printf("Error opening input audio stream.\n");
    printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_in), err_open_in);

    err = 1;
  }

  outputParameters.device = ndevice_out;
  outputParameters.channelCount = 2;
  outputParameters.sampleFormat = paInt16;
  outputParameters.suggestedLatency = 1.0;
  outputParameters.hostApiSpecificStreamInfo = NULL;

// Test if this configuration actually works, so we do not run into an ugly assertion
  err_open_out = Pa_IsFormatSupported(NULL, &outputParameters, dSampleRate);

  if (err_open_out == 0) {
    err_open_out = Pa_OpenStream(
		       &outstream,      //address of stream
		       NULL,
		       &outputParameters,
		       dSampleRate,            //Sample rate
		       2048,            //Frames per buffer
		       paNoFlag,
		       (PaStreamCallback *)SoundOut,  //Callback routine
		       (void *)&data);  //address of data structure

    if(err_open_out) {     // We should have no error here usually
      printf("Error opening output audio stream!\n");
      printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_out), err_open_out);

      err += 2;
    } else {
      //      printf("Successfully opened audio output.\n");
    }
  } else {
    printf("Error opening output audio stream.\n");
    printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_out), err_open_out);

    err += 2;
  }

  // if there was no error in opening both streams start them
  if (err == 0) {
    err_start_in = Pa_StartStream(instream);             //Start input stream

    if(err_start_in) {
      printf("Error starting input audio stream!\n");
      printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_start_in), err_start_in);

      err += 4;
    }

    err_start_out = Pa_StartStream(outstream);             //Start output stream

    if(err_start_out) {
      printf("Error starting output audio stream!\n");
      printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_start_out), err_start_out);

      err += 8;
    } 
  }

  if (err == 0) printf("Audio streams running normally.\n******************************************************************\n");

  while( Pa_IsStreamActive(instream) && (*ngo != 0) && (err == 0) )  {
    //    printf("CPU: %.1f\%\n",100*Pa_GetStreamCpuLoad(instream));
    Pa_Sleep(200);
  }

  Pa_AbortStream(instream);              // Abort stream
  Pa_CloseStream(instream);             // Close stream, we're done.
  Pa_AbortStream(outstream);              // Abort stream
  Pa_CloseStream(outstream);             // Close stream, we're done.

  Pa_Terminate();

  return(err);
}
Esempio n. 21
0
static void *output_thread(void *ptr) {
	int err;
	int output_buffer_size;
#ifndef PORTAUDIO_DEV
	int num_mixers, nbVolumes, volumeIdx;
#endif
	struct timeval  now;
	struct timespec timeout;
	
	slimaudio_t *audio = (slimaudio_t *) ptr;
	audio->output_STMs = false;
	audio->output_STMu = false;

        err = Pa_Initialize();
        if (err != paNoError) {
                printf("PortAudio error4: %s Could not open any audio devices.\n", Pa_GetErrorText(err) );
                exit(-1);
        }

	if ( audio->renice )
		if ( slimproto_renice_thread (-5) ) /* Increase priority */
			fprintf(stderr, "output_thread: renice failed. Got Root?\n");

#ifndef PORTAUDIO_DEV
	DEBUGF("output_thread: output_device_id  : %i\n", audio->output_device_id );
	DEBUGF("output_thread: pa_framesPerBuffer: %lu\n", pa_framesPerBuffer );
	DEBUGF("output_thread: pa_numberOfBuffers: %lu\n", pa_numberOfBuffers );

	err = Pa_OpenStream(	&audio->pa_stream,	/* stream */
				paNoDevice,		/* input device */
				0,			/* input channels */
				0,			/* input sample format */
				NULL,			/* input driver info */
				audio->output_device_id,/* output device */
				2,			/* output channels */
				paInt16,		/* output sample format */
				NULL,			/* output driver info */
				44100.0,		/* sample rate */
				pa_framesPerBuffer,	/* frames per buffer */
				pa_numberOfBuffers,	/* number of buffers */
				paNoFlag,		/* stream flags */
				pa_callback,		/* callback */
				audio);			/* user data */
#else
	PaStreamParameters outputParameters;
	const PaDeviceInfo * paDeviceInfo;
	float newLatency;

#ifdef PADEV_WASAPI
	PaWasapiStreamInfo streamInfo;
	const PaHostApiInfo *paHostApiInfo;
#endif

	paDeviceInfo = Pa_GetDeviceInfo(audio->output_device_id);
	/* Device is not stereo or better, abort */
	if (paDeviceInfo->maxOutputChannels < 2)
	{
		printf("output_thread: PortAudio device does not support 44.1KHz, 16-bit, stereo audio.\n");
		printf("output_thread: Use -L for a list of supported audio devices, then use -o followed\n");
		printf("output_thread: by the device number listed before the colon.  See -h for details.\n");
		exit(-2);
	}
	outputParameters.device = audio->output_device_id;
#ifdef SLIMPROTO_ZONES
	outputParameters.channelCount = 2 * audio->output_num_zones;
#else
	outputParameters.channelCount = 2;
#endif
	outputParameters.sampleFormat = paInt16;
	outputParameters.suggestedLatency = paDeviceInfo->defaultHighOutputLatency;

	if ( audio->modify_latency )
	{
		newLatency = (float) audio->user_latency / 1000.0;
		if ( ( newLatency > 1.0 ) || ( newLatency <= paDeviceInfo->defaultLowOutputLatency ) )
		{
			fprintf (stderr, "User defined latency %f out of range %f-1.0, using default.\n",
					newLatency, paDeviceInfo->defaultLowOutputLatency );
			newLatency = paDeviceInfo->defaultHighOutputLatency;
		}
		outputParameters.suggestedLatency = newLatency ;
	}

#ifdef PADEV_WASAPI
	/* Use exclusive mode for WASAPI device, default is shared */

	paHostApiInfo = Pa_GetHostApiInfo ( paDeviceInfo->hostApi );
	if ( paHostApiInfo != NULL )
	{
		if ( paHostApiInfo->type == paWASAPI )
		{
			/* Use exclusive mode for WasApi device, default is shared */
			if (wasapi_exclusive)
			{
				streamInfo.size = sizeof(PaWasapiStreamInfo);
				streamInfo.hostApiType = paWASAPI;
				streamInfo.version = 1;
				streamInfo.flags = paWinWasapiExclusive;
				outputParameters.hostApiSpecificStreamInfo = &streamInfo;

				DEBUGF("WASAPI: Exclusive\n");
			}
			else
			{
				outputParameters.hostApiSpecificStreamInfo = NULL;

				DEBUGF("WASAPI: Shared\n");
			}
		}
	}
#else
	outputParameters.hostApiSpecificStreamInfo = NULL;
#endif

	DEBUGF("paDeviceInfo->deviceid %d\n", outputParameters.device);
	DEBUGF("paDeviceInfo->maxOutputChannels %i\n", paDeviceInfo->maxOutputChannels);
	DEBUGF("outputParameters.suggestedLatency %f\n", outputParameters.suggestedLatency);
	DEBUGF("paDeviceInfo->defaultHighOutputLatency %f\n", (float) paDeviceInfo->defaultHighOutputLatency);
	DEBUGF("paDeviceInfo->defaultLowOutputLatency %f\n", (float) paDeviceInfo->defaultLowOutputLatency);
	DEBUGF("paDeviceInfo->defaultSampleRate %f\n", paDeviceInfo->defaultSampleRate);

	err = Pa_OpenStream (	&audio->pa_stream,				/* stream */
				NULL,						/* inputParameters */
				&outputParameters,				/* outputParameters */
				44100.0,					/* sample rate */
				paFramesPerBufferUnspecified,			/* framesPerBuffer */
				paPrimeOutputBuffersUsingStreamCallback,	/* streamFlags */
				pa_callback,					/* streamCallback */
				audio);						/* userData */
#endif

#ifdef BSD_THREAD_LOCKING
	pthread_mutex_lock(&audio->output_mutex);
#endif

	if (err != paNoError) {
		printf("output_thread: PortAudio error1: %s\n", Pa_GetErrorText(err) );	
		exit(-1);
	}

#ifndef PORTAUDIO_DEV
	num_mixers = Px_GetNumMixers(audio->pa_stream);
	while (--num_mixers >= 0) {
		DEBUGF("Mixer: %s\n", Px_GetMixerName(audio->pa_stream, num_mixers));
	}
	
	if (audio->volume_control == VOLUME_DRIVER) {
		DEBUGF("Opening mixer.\n" );
		audio->px_mixer = Px_OpenMixer(audio->pa_stream, 0);
	}

	if (audio->px_mixer != NULL) {
		DEBUGF("Px_mixer = %p\n", audio->px_mixer);
		DEBUGF("PCM volume supported: %d.\n", 
		       Px_SupportsPCMOutputVolume(audio->px_mixer));

		nbVolumes = Px_GetNumOutputVolumes(audio->px_mixer);
		DEBUGF("Nb volumes supported: %d.\n", nbVolumes);
		for (volumeIdx=0; volumeIdx<nbVolumes; ++volumeIdx) {
			DEBUGF("Volume %d: %s\n", volumeIdx, 
				Px_GetOutputVolumeName(audio->px_mixer, volumeIdx));
		}
	}
#endif

	while (audio->output_state != QUIT) {

		switch (audio->output_state) {
			case STOPPED:
				audio->decode_num_tracks_started = 0L;
				audio->stream_samples = 0UL;
				audio->pa_streamtime_offset = audio->stream_samples;

				DEBUGF("output_thread STOPPED: %llu\n",audio->pa_streamtime_offset);

				slimaudio_buffer_set_readopt(audio->output_buffer, BUFFER_BLOCKING);

			case PAUSED:
				/* We report ourselves to the server every few seconds
				** as a keep-alive.  This is required for Squeezebox Server
				** v6.5.x although technically, "stat" is not a valid event 
				** code for the STAT Client->Server message.  This was 
				** lifted by observing how a Squeezebox3 reports itself to 
				** the server using Squeezebox Server's d_slimproto and 
				** d_slimproto_v tracing services.  Note that Squeezebox3
				** seems to report every 1 second or so, but the server only
				** drops the connection after 15-20 seconds of inactivity.
				*/
				DEBUGF("output_thread PAUSED: %llu\n",audio->pa_streamtime_offset);

			  	if (audio->keepalive_interval <= 0) {
					pthread_cond_wait(&audio->output_cond, &audio->output_mutex);
				}
				else {
					gettimeofday(&now, NULL);
					timeout.tv_sec = now.tv_sec + audio->keepalive_interval;
					timeout.tv_nsec = now.tv_usec * 1000;				
					err = pthread_cond_timedwait(&audio->output_cond,
								     &audio->output_mutex, &timeout);
					if (err == ETIMEDOUT) {
						DEBUGF("Sending keepalive. Interval=%ds.\n", audio->keepalive_interval);
						output_thread_stat(audio, "stat");
					}
				}

				break;

			case PLAY:
				audio->output_predelay_frames = audio->output_predelay_msec * 44.100;

				DEBUGF("output_thread PLAY: output_predelay_frames: %i\n",
					audio->output_predelay_frames);

				output_buffer_size = slimaudio_buffer_available(audio->output_buffer);

				DEBUGF("output_thread BUFFERING: output_buffer_size: %i output_threshold: %i",
					output_buffer_size, audio->output_threshold);
				DEBUGF(" buffering_timeout: %i\n", audio->buffering_timeout);

				if ( (output_buffer_size < audio->output_threshold) && (audio->buffering_timeout > 0) )
				{
					pthread_mutex_unlock(&audio->output_mutex);
					pthread_cond_broadcast(&audio->output_cond);

					Pa_Sleep(100);

					pthread_mutex_lock(&audio->output_mutex);
					audio->buffering_timeout--;
				}
				else
				{
					DEBUGF("output_thread PLAY: start stream: %llu\n",
						audio->pa_streamtime_offset);

					audio->buffering_timeout = BUFFERING_TIMEOUT;

					err = Pa_StartStream(audio->pa_stream);
					if (err != paNoError)
					{
						printf("output_thread: PortAudio error2: %s\n", Pa_GetErrorText(err));
						exit(-1);
					}

					audio->output_state = PLAYING;

					pthread_cond_broadcast(&audio->output_cond);
				}

				break;

			case BUFFERING:
				DEBUGF("output_thread BUFFERING: %llu\n",audio->pa_streamtime_offset);

			case PLAYING:			
				gettimeofday(&now, NULL);
				timeout.tv_sec = now.tv_sec + 1;
				timeout.tv_nsec = now.tv_usec * 1000;
				err = pthread_cond_timedwait(&audio->output_cond, &audio->output_mutex, &timeout);

				if (err == ETIMEDOUT)
				{
					DEBUGF("output_thread ETIMEDOUT-PLAYING: %llu\n",audio->pa_streamtime_offset);
					output_thread_stat(audio, "STMt");
				}

				/* Track started */				
				if (audio->output_STMs)
				{
					audio->output_STMs = false;
					audio->decode_num_tracks_started++;

					audio->replay_gain = audio->start_replay_gain;
					slimaudio_output_vol_adjust(audio);

					audio->pa_streamtime_offset = audio->stream_samples;

					DEBUGF("output_thread STMs-PLAYING: %llu\n",audio->pa_streamtime_offset);
					output_thread_stat(audio, "STMs");
				}

				/* Data underrun
				** On buffer underrun causes the server to switch to the next track.
				*/
				if (audio->output_STMu)
				{
					audio->output_STMu = false;

					audio->output_state = STOP;

					DEBUGF("output_thread STMu-PLAYING: %llu\n",audio->pa_streamtime_offset);
					output_thread_stat(audio, "STMu");

					pthread_cond_broadcast(&audio->output_cond);
				}

				break;
		
			case STOP:
#ifndef PORTAUDIO_DEV
				if ( (err = Pa_StreamActive(audio->pa_stream) ) > 0)
				{
					err = Pa_StopStream(audio->pa_stream);
					if (err != paNoError)
					{
						printf("output_thread: PortAudio error3: %s\n", Pa_GetErrorText(err) );	
						exit(-1);
					}
				}
				else
				{
					if ( err != paNoError)
					{
						printf("output_thread: PortAudio error9: %s\n",
						Pa_GetErrorText(err) );
						exit(-1);
					}
				}
#else
				if ( (err = Pa_IsStreamActive(audio->pa_stream)) > 0) {
					err = Pa_StopStream(audio->pa_stream);
					if (err != paNoError) {
						printf("output_thread[STOP]: PortAudio error3: %s\n",
									Pa_GetErrorText(err) );
						exit(-1);
					}
				} else if ( err != paNoError) {
					printf("output_thread[STOP ISACTIVE]: PortAudio error3: %s\n",
									Pa_GetErrorText(err) );
					exit(-1);
				}
#endif
				audio->output_state = STOPPED;

				DEBUGF("output_thread STOP: %llu\n",audio->pa_streamtime_offset);
				pthread_cond_broadcast(&audio->output_cond);

				break;
				
			case PAUSE:
#ifndef PORTAUDIO_DEV
				if ( (err = Pa_StreamActive(audio->pa_stream) ) > 0)
				{
					err = Pa_StopStream(audio->pa_stream);
					if (err != paNoError)
					{
						printf("output_thread: PortAudio error10: %s\n", Pa_GetErrorText(err));	
						exit(-1);
					}
				}
				else
				{
					if ( err != paNoError)
					{
						printf("output_thread: PortAudio error11: %s\n",
						Pa_GetErrorText(err) );
						exit(-1);
					}
				}
#else
				if ( (err = Pa_IsStreamActive(audio->pa_stream)) > 0) {
					err = Pa_StopStream(audio->pa_stream);
					if (err != paNoError) {
						printf("output_thread[PAUSE]: PortAudio error3: %s\n",
								Pa_GetErrorText(err) );
						exit(-1);
					}
				} else if ( err != paNoError) {
					printf("output_thread[PAUSE ISACTIVE]: PortAudio error3: %s\n",
							Pa_GetErrorText(err) );
					exit(-1);
				}
#endif
				audio->output_state = PAUSED;

				DEBUGF("output_thread PAUSE: %llu\n",audio->pa_streamtime_offset);
				pthread_cond_broadcast(&audio->output_cond);

				break;

			case QUIT:
				DEBUGF("output_thread QUIT: %llu\n",audio->pa_streamtime_offset);
				break;

		}		
	}
	pthread_mutex_unlock(&audio->output_mutex);

#ifndef PORTAUDIO_DEV	
	if (audio->px_mixer != NULL) {
		Px_CloseMixer(audio->px_mixer);
		audio->px_mixer = NULL;
	}
#endif

	err = Pa_CloseStream(audio->pa_stream);

	if (err != paNoError) {
		printf("output_thread[exit]: PortAudio error3: %s\n", Pa_GetErrorText(err) );
		exit(-1);
	}

	audio->pa_stream = NULL;
	Pa_Terminate();

	DEBUGF("output_thread: PortAudio terminated\n");

	return 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;
}
Esempio n. 23
0
int run_filter(AudioOptions audio_options)
{
    PaStreamParameters input_parameters, output_parameters;
    PaStream *input_stream = NULL, *output_stream = NULL;
    PaError err = paNoError;
    CircularBuffer * output_buffer = CircularBuffer_create(audio_options.buffer_size);
    CircularBuffer * input_buffer = NULL;
    CircularBuffer * decoder_input = NULL;
    DecodingBuffer * decoder_buffer = NULL;

    int live_stream = !audio_options.wav_path || !strlen(audio_options.wav_path);

    OSFilter * filter =
        OSFilter_create(
                        audio_options.filters,
                        audio_options.num_filters,
                        2,
                        audio_options.filter_size,
                        audio_options.conv_multiple * (audio_options.filter_size - 1),
                        audio_options.input_scale
                        );
    if (!filter) {
        goto done;
    }

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

    int step_size = audio_options.filter_size - 1;

    RecordCallbackMetadata record_data = {
        NULL,
        0,
        0,
        audio_options.number_of_channels,
        audio_options.enabled_channels,
        0
    };

    {
        int num_enabled_channels = 0;

        for (int i = 0; i < audio_options.number_of_channels; ++i) {
            if (audio_options.enabled_channels & (1 << i)) {
                num_enabled_channels++;
            }
        }
        if (num_enabled_channels != audio_options.enabled_channels) {
            record_data.stripe_input = 1;
        }
        if (num_enabled_channels == 0) {
            record_data.stripe_input = 0;
        }
    }

    if (record_data.stripe_input) {
        printf("striping record_data: %d channels with %d enabled flag\n",
               record_data.number_of_channels,
               record_data.enabled_channels
               );
    } else {
        printf("NOT striping record_data: %d channels with %d enabled flag\n",
               record_data.number_of_channels,
               record_data.enabled_channels
               );
    }

    if (live_stream) {
        input_buffer = CircularBuffer_create(audio_options.buffer_size);

        if (audio_options.decode_input) {
            decoder_input = CircularBuffer_create(audio_options.buffer_size);
            decoder_buffer = Decoding_new(decoder_input, input_buffer);
            record_data.buffer = decoder_input;
            if (!Decoding_start_ac3(decoder_buffer)) {
                printf("Failed to start ac3 decoder thread.\n");
                goto done;
            }
        } else {
            record_data.buffer = input_buffer;
        }

        input_parameters.device = audio_options.input_device;
        input_parameters.channelCount = 2;
        input_parameters.sampleFormat = PA_SAMPLE_TYPE;
        input_parameters.suggestedLatency = Pa_GetDeviceInfo(input_parameters.device)->defaultHighInputLatency;
        input_parameters.hostApiSpecificStreamInfo = NULL;

        err = Pa_OpenStream(
                            &input_stream,
                            &input_parameters,
                            NULL,
                            audio_options.sample_rate,
                            step_size,
                            paNoFlag,
                            recordCallback,
                            &record_data
                            );

        if (err != paNoError) {
            goto done;
        }

        record_data.start_time = currentTimeMillis();


#ifdef LINUX_ALSA
        PaAlsa_EnableRealtimeScheduling(input_stream, 1);
#endif

        if ((err = Pa_StartStream(input_stream)) != paNoError) {
            goto done;
        }
    } else {
        input_buffer = __read_audio_file(audio_options);
    }

    output_parameters.device = audio_options.output_device;
    if (audio_options.output_channels >= 6) {
        output_parameters.channelCount = audio_options.output_channels + 2;
    } else {
        output_parameters.channelCount = audio_options.output_channels;
    }
    output_parameters.sampleFormat = PA_SAMPLE_TYPE;
    output_parameters.suggestedLatency = Pa_GetDeviceInfo(output_parameters.device)->defaultLowOutputLatency;
    output_parameters.hostApiSpecificStreamInfo = NULL;

    PlaybackCallbackData playback_data = {
        output_buffer,
        output_parameters.channelCount
    };

    printf("output channels: %d\n", output_parameters.channelCount);

    err = Pa_OpenStream(
                        &output_stream,
                        NULL,
                        &output_parameters,
                        audio_options.sample_rate,
                        step_size,
                        paNoFlag,
                        playCallback,
                        &playback_data
                        );

    if (err != paNoError) {
        goto done;
    }

#ifdef LINUX_ALSA
    PaAlsa_EnableRealtimeScheduling(output_stream, 1);
#endif

    if ((err = Pa_StartStream(output_stream)) != paNoError) {
        goto done;
    }

    int output_scale = output_parameters.channelCount / 2;
    int frame_print_interval = DEBUG_PRINT_INTERVAL_MILLIS * audio_options.sample_rate / 1000;
    int current_frame = 0;

    while (true) {
        if ((err = Pa_IsStreamActive(output_stream)) != 1) {
            break;
        }
        if (input_stream && (err = Pa_IsStreamActive(input_stream)) != 1) {
            break;
        }
        current_frame += OSFilter_execute(filter, input_buffer, output_buffer);
        if (audio_options.print_debug && current_frame > frame_print_interval) {
            current_frame -= frame_print_interval;

            if (!is_parent_running(audio_options.parent_thread_ident)) {
                printf("Parent thread is dead. Shutting down now.\n");
                fflush(stdout);
                goto done;
            }

            if (!audio_options.print_debug) {
                continue;
            }
            long frame_difference = (CircularBuffer_lag(input_buffer) + CircularBuffer_lag(output_buffer) / output_scale) / 2;
            float lag = (float)(frame_difference) / audio_options.sample_rate * 1000;
            printf("%lu\t%lu\t%lu\t%fms\n",
                   input_buffer->offset_producer,
                   output_buffer->offset_consumer / output_scale,
                   frame_difference, lag
                   );

            if (live_stream && (lag > audio_options.lag_reset_limit * 1000)) {
                printf("Resetting to latest due to high lag.\n");
                CircularBuffer_fastforward(input_buffer, audio_options.filter_size * 2);
                CircularBuffer_fastforward(output_buffer, 0);
            }
            fflush(stdout);
        }
    }
    if (err < 0) {
        goto done;
    }

done:
    if (output_stream) {
        Pa_CloseStream(output_stream);
    }
    if (input_stream) {
        Pa_CloseStream(input_stream);
    }
    Pa_Terminate();
    if (input_buffer) {
        CircularBuffer_destroy(input_buffer);
    }
    CircularBuffer_destroy(output_buffer);
    if (decoder_input) {
        CircularBuffer_destroy(decoder_input);
    }
    if (decoder_buffer) {
        Decoding_free(decoder_buffer);
    }

    OSFilter_destroy(filter);

    if (err != paNoError) {
        fprintf(stdout, "An error occured while using the portaudio stream\n");
        fprintf(stdout, "Error number: %d\n", err);
        fprintf(stdout, "Error message: %s\n", Pa_GetErrorText(err));
        fflush(stdout);
        err = 1;
    }
    return err;
}
bool isPlayed()
{
    return (Pa_IsStreamActive(stream) == 1);
}
Esempio n. 25
0
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;
}
void PA_AudioIO::terminate(){
        if( Pa_IsStreamActive(m_Stream) ) Pa_StopStream(m_Stream);
        Pa_Terminate();
        std::cout << "PA terminated" << std::endl;
}
Esempio n. 27
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);
   
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
	
	// 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;
}
PA_AudioIO::~PA_AudioIO(){
    if( Pa_IsStreamActive(m_Stream) ) Pa_StopStream(m_Stream);
    Pa_Terminate();
}
Esempio n. 29
0
int main (int argc, char ** argv) {
int buffersize;
int stereo;
int samplerate;
int numBytes;
int numSample;
int maxnumchannel_input;

// state of keypress
int state, oldstate;

// vars for portaudio
char * portaudiodevice;
int exact=0;
PaStreamParameters inputParameters;
PaStream * stream;
PaError pa_ret;

const PaDeviceInfo *devinfo;

// vars for networking
char * ipaddrtxtin;
int udpport;
struct sockaddr_in * udp_aiaddr_in = NULL;
struct sockaddr_in6 * udp_aiaddr_in6 = NULL;
struct sockaddr * sendto_aiaddr = NULL; // structure used for sendto
int sendto_sizeaiaddr=0; // size of structed used for sendto
int udpsd;
int udp_family;

char ipaddrtxt[INET6_ADDRSTRLEN];

// vars for getaddrinfo
struct addrinfo * hint;
struct addrinfo * info;

// for SAMPLE RATE CONVERSION
SRC_STATE *src=NULL;
SRC_DATA src_data;
int src_error;

// vars for codec2
void *codec2;
unsigned char *c2_buff;
int mode, nc2byte;

// vars for audio
int16_t * audiobuffer;
float * inaudiobuffer_f = NULL;
float * outaudiobuffer_f = NULL;

// other vars
int ret;

// structure for c2encap data
c2encap c2_voice;
c2encap c2_begin, c2_end;

// "audio in" posix thread
pthread_t thr_keypress;

// init data
stereo=-1;
global.transmit=0;

// We need at least 3 arguments: IP-address, udpport and samplerate
if (argc < 4) {
	fprintf(stderr,"Error: at least 3 arguments needed. \n");
	fprintf(stderr,"Usage: %s <ip-addr> <udp port> <samplerate> [ <audiodevice> [exact] ] \n",argv[0]);
	fprintf(stderr,"Note: allowed audio samplerate are 8000, 44100 or 48000 samples/second.\n");
	fprintf(stderr,"Note: use device \"\" to get list of devices.\n");
	exit(-1);
}; // end if

ipaddrtxtin=argv[1];
udpport=atoi(argv[2]);
samplerate=atoi(argv[3]);


// if 1st argument exists, use it as capture device
if (argc >= 5) {
	portaudiodevice = argv[4];

	// is there the "exact" statement?
	if (argc >= 6) {
		if (!strcmp(argv[5],"exact")) {
			exact=1;
		} else {
			fprintf(stderr,"Error: parameter \"exact\" expected. Got %s. Ignoring! \n",argv[5]);
		}; // end else - if
	}; // end if
} else {
	// no argument given
	portaudiodevice = NULL;
}; // end else - if



// create network structure
if ((udpport < 0) || (udpport > 65535)) {
	fprintf(stderr,"Error: UDPport number must be between 0 and 65535! \n");
	exit(-1);
}; // end if


if ((IPV4ONLY) && (IPV6ONLY)) {
	fprintf(stderr,"Error: internal configuration error: ipv4only and ipv6only are mutually exclusive! \n");
	exit(-1);
}; // end if


// sample rates below 8Ksamples/sec or above 48Ksamples/sec do not make sence
if (samplerate == 8000) {
	numSample = 320;
} else if (samplerate == 44100) {
	numSample = 1764;
} else if (samplerate == 48000) {
	numSample = 1920;
} else {
	fprintf(stderr,"Error: audio samplerate should be 8000, 44100 or 48000 samples/sec! \n");
	exit(-1);
}; // end if


// DO DNS query for ipaddress
hint=malloc(sizeof(struct addrinfo));

if (!hint) {
	fprintf(stderr,"Error: could not allocate memory for hint!\n");
	exit(-1);
}; // end if

// clear hint
memset(hint,0,sizeof(hint));

hint->ai_socktype = SOCK_DGRAM;

// resolve hostname, use function "getaddrinfo"
// set address family of hint if ipv4only or ipv6only
if (IPV4ONLY) {
	hint->ai_family = AF_INET;
} else if (IPV6ONLY) {
	hint->ai_family = AF_INET6;
} else {
	hint->ai_family = AF_UNSPEC;
}; // end else - elsif - if

// do DNS-query, use getaddrinfo for both ipv4 and ipv6 support
ret=getaddrinfo(ipaddrtxtin, NULL, hint, &info);

if (ret < 0) {
	fprintf(stderr,"Error: resolving hostname %s failed: (%s)\n",ipaddrtxtin,gai_strerror(ret));
	exit(-1);
}; // end if


udp_family=info->ai_family;

// open UDP socket + set udp port
if (udp_family == AF_INET) {
	udpsd=socket(AF_INET,SOCK_DGRAM,0);
	
	// getaddrinfo returns pointer to generic "struct sockaddr" structure.
	// 		Cast to "struct sockaddr_in" to be able to fill in destination port
	udp_aiaddr_in=(struct sockaddr_in *)info->ai_addr;
	udp_aiaddr_in->sin_port=htons((unsigned short int) udpport);

	// set pointer to be used for "sendto" ipv4 structure
	// sendto uses generic "struct sockaddr" just like the information
	// 		returned from getaddrinfo, so no casting needed here
	sendto_aiaddr=info->ai_addr;
	sendto_sizeaiaddr=sizeof(struct sockaddr);

	// get textual version of returned ip-address
	inet_ntop(AF_INET,&udp_aiaddr_in->sin_addr,ipaddrtxt,INET6_ADDRSTRLEN);
	
} else if (udp_family == AF_INET6) {
	udpsd=socket(AF_INET6,SOCK_DGRAM,0);

	// getaddrinfo returns pointer to generic "struct sockaddr" structure.
	// 		Cast to "struct sockaddr_in6" to be able to fill in destination port
	udp_aiaddr_in6=(struct sockaddr_in6 *)info->ai_addr;
	udp_aiaddr_in6->sin6_port=htons((unsigned short int) udpport);

	// set pointer to be used for "sendto" ipv4 structure
	// sendto uses generic "struct sockaddr" just like the information
	// 		returned from getaddrinfo, so no casting needed here
	sendto_aiaddr=info->ai_addr;
	sendto_sizeaiaddr=sizeof(struct sockaddr_in6);

	// get textual version of returned ip-address
	inet_ntop(AF_INET6,&udp_aiaddr_in6->sin6_addr,ipaddrtxt,INET6_ADDRSTRLEN);
	
} else {
	fprintf(stderr,"Error: DNS query for %s returned an unknown network-family: %d \n",ipaddrtxtin,udp_family);
	exit(-1);
}; // end if



// getaddrinfo can return multiple results, we only use the first one
// give warning is more then one result found.
// Data is returned in info as a linked list
// If the "next" pointer is not NULL, there is more then one
// element in the chain

if (info->ai_next != NULL) {
	fprintf(stderr,"Warning. getaddrinfo returned multiple entries. Using %s\n",ipaddrtxt);
}; // end if


if (udpsd < 0) {
	fprintf(stderr,"Error: could not create socket for UDP! \n");
	exit(-1);
}; // end if

// init c2encap structures
memcpy(c2_begin.header,C2ENCAP_HEAD,sizeof(C2ENCAP_HEAD));
c2_begin.header[3]=C2ENCAP_MARK_BEGIN;
memcpy(c2_begin.c2data.c2data_text3,"BEG",3);

memcpy(c2_end.header,C2ENCAP_HEAD,sizeof(C2ENCAP_HEAD));
c2_end.header[3]=C2ENCAP_MARK_END;
memcpy(c2_end.c2data.c2data_text3,"END",3);

memcpy(c2_voice.header,C2ENCAP_HEAD,sizeof(C2ENCAP_HEAD));
c2_voice.header[3]=C2ENCAP_DATA_VOICE1400;



// PORTAUDIO STUFF

fprintf(stderr,"INITIALISING PORTAUDIO    (this can take some time, please ignore any errors below) .... \n");
// open portaudio device
pa_ret=Pa_Initialize();
fprintf(stderr,".... DONE\n");

if (pa_ret != paNoError) {
	Pa_Terminate();
	fprintf(stderr,"Error: Could not initialise Portaudio: %s(%d) \n",Pa_GetErrorText(pa_ret),pa_ret);
	exit(-1);
}; // end if

if (portaudiodevice == NULL) {
	// portaudio device = NULL -> use portaudio "get default input device"
	inputParameters.device = Pa_GetDefaultInputDevice();

	if (inputParameters.device == paNoDevice) {
		fprintf(stderr,"Error: no portaudio default input device!\n");
		exit(-1);
	}; // end if

	if (inputParameters.device >= Pa_GetDeviceCount()) {
		fprintf(stderr,"Internal Error: portaudio \"GetDefaultInputDevice\" returns device number %d while possible devices go from 0 to %d \n,",inputParameters.device, (Pa_GetDeviceCount() -1) );
		exit(-1);
	}; // end if


	// check if device supports samplerate:
	inputParameters.sampleFormat = paInt16;
	inputParameters.suggestedLatency = 0; // not used in Pa_IsFormatSupported
	inputParameters.hostApiSpecificStreamInfo = NULL;

	devinfo = Pa_GetDeviceInfo (inputParameters.device);

   maxnumchannel_input = devinfo->maxInputChannels;
	printf("Audio device = %d (%s %s)\n",inputParameters.device,Pa_GetHostApiInfo(devinfo->hostApi)->name,devinfo->name);

	if (maxnumchannel_input >= 1) {
		// first check if samplerate is supported in mono
		inputParameters.channelCount = 1;
		pa_ret = Pa_IsFormatSupported(NULL,&inputParameters,(double) samplerate);

		if (pa_ret == paFormatIsSupported) {
			printf("Samplerate %d supported in mono.\n",samplerate);
			stereo=0;
		} else {
			// try again using stereo
			inputParameters.channelCount = 2;

			if (maxnumchannel_input >= 2) {
				pa_ret = Pa_IsFormatSupported(NULL,&inputParameters,(double) samplerate);

				if (pa_ret == paFormatIsSupported) {
					printf("Samplerate %d supported in stereo.\n",samplerate);
					stereo=1;
				} else {
					printf("Error: Samplerate %d not supported in mono or stereo!\n",samplerate);
					exit(-1);
				}; // end if
			} else {
				// stereo not supported on this device
				printf("Error: Samplerate %d not supported in mono. Stereo not supported on this device!\n",samplerate);
				exit(-1);
			}; // end if
		}; // end else - if
	} else {
		printf("Error: input not supported on this device!\n");
		exit(-1);
	}; // end if
	
	printf("\n");
	fflush(stdout);


} else {
	// CLI option "device" contains text, look throu list of all devices if there are
	// devices that match that name and support the particular requested samplingrate
	int loop;
	int numdevice;

	int numdevicefound=0;
	int devicenr=0;
	int devicestereo=0;



	// init some vars
	numdevice=Pa_GetDeviceCount();

	inputParameters.sampleFormat = paInt16;
	inputParameters.suggestedLatency = 0; // not used in Pa_IsFormatSupported
	inputParameters.hostApiSpecificStreamInfo = NULL;

	for (loop=0; loop<numdevice;loop++) {
		int devnamematch=0;

		// get name of device
		devinfo = Pa_GetDeviceInfo (loop);

		// only do check if searchstring is smaller or equal is size of device name
		if (strlen(devinfo->name) >= strlen(portaudiodevice)) {
			int numcheck;
			int devnamesize;
			int loop;
			char *p;

			// init pointer to beginning of string
			p=(char *)devinfo->name;
			devnamesize = strlen(portaudiodevice);

			if (exact) {
				// exact match, only check once: at the beginning
				numcheck=1;
			} else {
				numcheck=strlen(p) - strlen(portaudiodevice) +1;
			}; // end if

			// loop until text found or end-of-string
			for (loop=0; (loop<numcheck && devnamematch == 0); loop++) {
				if (strncmp(portaudiodevice,p,devnamesize) ==0) {
					devnamematch=1;
				}; // end if

				// move up pointer
				p++;
			};
		}; // end if

		if (devnamematch) {
			printf("Audio device: %d (API: %s ,NAME: %s)\n",loop,Pa_GetHostApiInfo(devinfo->hostApi)->name,devinfo->name);

   		maxnumchannel_input = devinfo->maxInputChannels;

			if (maxnumchannel_input >= 1) {
				// next step: check if this device supports the particular requested samplerate
				inputParameters.device = loop;

				inputParameters.channelCount = 1;
				pa_ret = Pa_IsFormatSupported(NULL,&inputParameters,(double) samplerate);

				if (pa_ret == paFormatIsSupported) {
					printf("Samplerate %d supported in mono.\n",samplerate);
					numdevicefound++;
					devicenr=loop;
					devicestereo=0;
				} else {
					if (maxnumchannel_input >= 2) {
						inputParameters.channelCount = 2;
						pa_ret = Pa_IsFormatSupported(NULL,&inputParameters,(double) samplerate);

						if (pa_ret == paFormatIsSupported) {
							printf("Samplerate %d supported in stereo.\n",samplerate);
							numdevicefound++;
							devicenr=loop;
							devicestereo=1;
						} else {
							printf("Error: Samplerate %d not supported in mono or stereo.\n",samplerate);
						}; // end else - if
					} else {
						// stereo not supported on this device
						printf("Error: Samplerate %d not supported in mono. Stereo not supported on this device!\n",samplerate);
					}; // end if
				}; // end else - if
			} else {
				printf("Error: Input not supported on device.\n");
			}; // end if

			printf("\n");
			fflush(stdout);
		};// end if
	}; // end for

	// did we find any device
	if (numdevicefound == 0) {
		fprintf(stderr,"Error: did not find any audio-device supporting that audio samplerate\n");
		fprintf(stderr,"       Try again with other samplerate of devicename \"\" to get list of all devices\n");
		exit(-1);
	} else if (numdevicefound > 1) {
		fprintf(stderr,"Error: Found multiple devices matching devicename supporting that audio samplerate\n");
		fprintf(stderr,"       Try again with a more strict devicename or use \"exact\" clause!\n");
		exit(-1);
	} else {
		// OK, we have exactly one device: copy its parameters
		inputParameters.device=devicenr;
		stereo=devicestereo;

		if (devicestereo) {
			inputParameters.channelCount = 2;
		} else {
			inputParameters.channelCount = 1;
		}; // end else - if

		// get name info from device
		devinfo = Pa_GetDeviceInfo (inputParameters.device);

		fprintf(stderr,"Selected Audio device = (API: %s ,NAME: %s)\n",Pa_GetHostApiInfo(devinfo->hostApi)->name,devinfo->name);
	};
}; // end else - if

// set other parameters of inputParameters structure
inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;

// configure portaudio global data
if (samplerate == 8000) {
	numSample = 320;
} else if (samplerate == 44100) {
	numSample = 1764;
} else if (samplerate == 48000) {
	numSample = 1920;
} else {
	fprintf(stderr,"Error: invalid value for samplerate in funct_audioout: %d !\n",samplerate);
	exit(-1);
}; // end if


// configure portaudio global data
if (stereo) {
	numBytes = (numSample << 2);
} else {
	numBytes = (numSample << 1); 
}; // end if

// create memory for audiobuffer
audiobuffer = malloc(numBytes); // allow memory for buffer 0
if (!audiobuffer) {
	// memory could not be allocated
	fprintf(stderr,"Error: could not allocate memory for portaudio buffer 0!\n");
	exit(-1);
}; // end if


// some network debug info
fprintf(stderr,"Sending CODEC2 DV stream to ip-address %s udp port %d\n",ipaddrtxt,udpport);


// open PortAudio stream
// do not start stream yet, will be done further down
pa_ret = Pa_OpenStream (
	&stream,
	&inputParameters,
	NULL, // output Parameters, not used here 
	samplerate, // sample rate
	numSample, // frames per buffer: 40 ms @ 8000 samples/sec
	paClipOff, // we won't output out of range samples,
					// so don't bother clipping them
	NULL, // no callback function, syncronous read
	&global // parameters passed to callback function (not used here)
);

if (pa_ret != paNoError) {
	Pa_Terminate();
	fprintf(stderr,"Error in Pa_OpenStream: %s(%d) \n",Pa_GetErrorText(pa_ret),pa_ret);
	exit(-1);
}; // end if

// init codec2
mode = CODEC2_MODE_1400;
codec2 = codec2_create (mode);

nc2byte = (codec2_bits_per_frame(codec2) + 7) >> 3; // ">>3" is same as "/8"

if (nc2byte != 7) {
	fprintf(stderr,"Error: number of bytes for codec2 frames should be 7. We got %d \n",nc2byte);
}; // end if

if (codec2_samples_per_frame(codec2) != 320) {
	fprintf(stderr,"Error: number of samples for codec2 frames should be 320. We got %d \n",codec2_samples_per_frame(codec2));
}; // end if

c2_buff = (unsigned char *)&c2_voice.c2data.c2data_data7;


// allocate audiobuffer
if (stereo) {
	buffersize= numSample << 2; // = number of samples  * 4 (stereo and 16 bit/sample)
} else {
	// mono
	buffersize= numSample << 1; // = number of samples * 2 (16 bit/sample)
}; // end else - if
audiobuffer=malloc(buffersize);

if (!audiobuffer) {
	fprintf(stderr,"Error: malloc audiobuffer: %s",strerror(errno));
	exit(-1);
}; // end if


// init samplerate conversion
if (samplerate != 8000) {

// allocate memory for audio sample buffers (only needed when audio rate conversion is used)
	inaudiobuffer_f=malloc(numSample * sizeof(float));
	if (!inaudiobuffer_f) {
		fprintf(stderr,"Error in malloc for inaudiobuffer_f! \n");
		exit(-1);
	}; // end if

	outaudiobuffer_f=malloc(320 * sizeof(float)); // output buffer is 320 samples (40 ms @ 8000 samples/sec)
	if (!outaudiobuffer_f) {
		fprintf(stderr,"Error in malloc for outaudiobuffer_f! \n");
		exit(-1);
	}; // end if

	src = src_new(SRC_SINC_FASTEST,1,&src_error);

	if (!src) {
		fprintf(stderr,"src_new failed! \n");
		exit(-1);
	}; // end if

	src_data.data_in = inaudiobuffer_f;
	src_data.data_out = outaudiobuffer_f;
	src_data.input_frames = numSample;
	src_data.output_frames = 320; // 40 ms @ 8000 samples / sec
	src_data.end_of_input = 0; // no further data, every 40 ms frame is concidered to be a seperate unit

	if (samplerate == 48000) {
		src_data.src_ratio = (float) 8000/48000;
	} else {
		src_data.src_ratio = (float) 8000/44100;
	}; // end else - if
}; // end if


// start thread to read detect keypress (used to switch transmitting)
pthread_create (&thr_keypress, NULL, funct_keypress, (void *) &global);


// Start stream
pa_ret=Pa_StartStream(stream);

if (pa_ret != paNoError) {
	Pa_Terminate();
	fprintf(stderr,"Error in Pa_StartStream: %s(%d) \n",Pa_GetErrorText(pa_ret),pa_ret);
	exit(-1);
}; // end if


// init some vars;
oldstate=0;


while (( pa_ret = Pa_IsStreamActive (stream)) == 1) {
// get audio

	pa_ret = Pa_ReadStream(stream, audiobuffer, numSample);

	if (pa_ret != paNoError) {
		Pa_Terminate();
		fprintf(stderr,"Error in Pa_ReadStream: %s(%d) \n",Pa_GetErrorText(pa_ret),pa_ret);
		exit(-1);
	}; // end if


	// get state from subthread
	state=global.transmit;

	if (state) {
		// State = 1: write audio

		// first check old state, if we go from oldstate=0 to state=1, this is
		// the beginning of a new stream; so send start packe
		if (oldstate == 0) {
			// start "start" marker
			// fwrite((void *) &c2_begin,C2ENCAP_SIZE_MARK,1,stdout);
			// fflush(stdout);

			// send start 3 times, just to be sure
			sendto(udpsd,&c2_begin,C2ENCAP_SIZE_MARK,0,sendto_aiaddr, sendto_sizeaiaddr);
			sendto(udpsd,&c2_begin,C2ENCAP_SIZE_MARK,0,sendto_aiaddr, sendto_sizeaiaddr);
			sendto(udpsd,&c2_begin,C2ENCAP_SIZE_MARK,0,sendto_aiaddr, sendto_sizeaiaddr);

//			putc('B',stderr);
		}


		// if stereo, only use left channel
		if (stereo) {
			int loop;

			int16_t *p1, *p2;

			// start at 2th element (in stereo format); which is 3th (in mono format)
			p1=&audiobuffer[1];
			p2=&audiobuffer[2];
	
			for (loop=1; loop < numSample; loop++) {
				*p1=*p2;
				p1++; p2 += 2;
			}; // end for
		}; // end if


		// if not 8000 samples / second: convert
		if (samplerate != 8000) {
fprintf(stderr,"2!!! \n");
			if (!inaudiobuffer_f) {
				fprintf(stderr,"Internal Error: inaudiobuffer_f not initialised \n");
				exit(-1);
			}; // end if

			if (!outaudiobuffer_f) {
				fprintf(stderr,"Internal Error: outaudiobuffer_f not initialised \n");
				exit(-1);
			}; // end if

			// convert int16 to float
			src_short_to_float_array(audiobuffer,inaudiobuffer_f,numSample);

			// convert
			ret=src_process(src,&src_data);

			if (ret) {
				fprintf(stderr,"Warning: samplerate conversion error %d (%s)\n",ret,src_strerror(ret));
			}; // end if

			// some error checking
			if (src_data.output_frames_gen != 320) {
				fprintf(stderr,"Warning: number of frames generated by samplerateconvert should be %d, got %ld. \n",numSample,src_data.output_frames_gen);
			}; // end if

			// convert back from float to int
			src_float_to_short_array(outaudiobuffer_f,audiobuffer,320); // 40 ms @ 8000 samples/sec = 320 samples

fprintf(stderr,"3!!! \n");
		}; // end if

		// do codec2 encoding
		codec2_encode(codec2, c2_buff, audiobuffer);

		//fwrite((void *)&c2_voice,C2ENCAP_SIZE_VOICE1400,1,stdout);
		//fflush(stdout);

		sendto(udpsd,&c2_voice,C2ENCAP_SIZE_VOICE1400,0,sendto_aiaddr, sendto_sizeaiaddr);

//		putc('T',stderr);
	} else {
		// state = 0, do not send
		// however, if we go from "oldstate = 1 - > state = 0", this is
		// the end of a stream

		if (oldstate) {
			// send "end" marker
			//fwrite((void *)&c2_end,C2ENCAP_SIZE_MARK,1,stdout);
			//fflush(stdout);

			// send end 3 times, just to be sure
			sendto(udpsd,&c2_end,C2ENCAP_SIZE_MARK,0,sendto_aiaddr, sendto_sizeaiaddr);
			sendto(udpsd,&c2_end,C2ENCAP_SIZE_MARK,0,sendto_aiaddr, sendto_sizeaiaddr);
			sendto(udpsd,&c2_end,C2ENCAP_SIZE_MARK,0,sendto_aiaddr, sendto_sizeaiaddr);

//			putc('E',stderr);
		}; // end if 
	}; // end else - if

	oldstate=state;

	
}; // end while
// dropped out of endless loop. Should not happen

if (pa_ret < 0) {
	Pa_Terminate();
	fprintf(stderr,"Error in Pa_isStreamActive: %s(%d) \n",Pa_GetErrorText(pa_ret),pa_ret);
	exit(-1);
}; // end if

fprintf(stderr,"Error: audiocap dropped out of audiocapturing loop. Should not happen!\n");

pa_ret=Pa_CloseStream(stream);

if (pa_ret != paNoError) {
	Pa_Terminate();
	fprintf(stderr,"Error in Pa_CloseStream: %s(%d) \n",Pa_GetErrorText(pa_ret),pa_ret);
	exit(-1);
}; // end if

// Done!!!

Pa_Terminate();

exit(0);


}; // end main applicion
Esempio n. 30
0
void* AudioThread::Entry()
{
	GlobalConfig* config = GlobalConfig::getInstance();
    config->Log( "AudioThread::Entry();" );

    m_Done = false;

    m_PaStreamIsActive = false;

    int cnt=0;

    while( not m_Done )
    {
        // Check Audio-Device-State every 100 ms
        switch( m_AudioState )
        {
            case STATE_CLOSED:
            {
                config->Log( "Audiothread-STATE: CLOSED" );
                // closed ?!? Then try to configure it...
                Configure();
                break;
            }
            case STATE_OPEN:
            {
                config->Log( "Audiothread-STATE: OPEN" );

                // Open, but not running? Then start it by all means...
                int err=Pa_StartStream( m_PaStream );
                int cnt=0;
                while( err != paNoError && cnt<5 )
                {
                    err = Pa_StartStream( m_PaStream );
                    cnt++;
                }

                if( err == paNoError )
                {
                    m_PaStreamIsActive = true;
                    config->Log( "Audiothread-STATE: OPEN and Portaudio-Stream successfully started." );
                    config->Log( "                   Portaudio-Error-Code: %i ", err );
                    config->Log( "                   Portaudio-Error-Text: %s ", Pa_GetErrorText( err ) );
                    m_AudioState = STATE_RUNNING;
                }
                else
                {
                    m_AudioState = STATE_ERROR;
                    config->Log( "Audiothread-STATE: OPEN and Portaudio-Stream *NOT* successfully started." );
                    config->Log( "                   Portaudio-Error-Code: %i ", err );
                    config->Log( "                   Portaudio-Error-Text: %s ", Pa_GetErrorText( err ) );
                }

                // change audio-state to running...
                break;
            }
            case STATE_ERROR:
            {
				// close all active streams ...
                if( m_PaStreamIsActive )
                {
                    Pa_CloseStream( m_PaStream );
                    m_PaStreamIsActive = false;
                }

                // send an event, so the user can notice that there is something
                // going wrong badly...
                //wxWindow* statusWindow = Config->getStatusWindow();
                //wxCommandEvent event(wxEVT_COMMAND_MIXER_ERROR);
                //statusWindow->AddPendingEvent( event );

                // now wait here(!) until the user changes the configuration
                // again
                while( m_AudioState == STATE_ERROR )
                {
                    config->Log( "Audiothread-STATE: *** ERROR ***" );

                    // Check for reconfiguration-request...
                    m_ReconfigureLock.Lock();
                    if( m_ReconfigureFlag )
                    {
                        // reset flag
                        m_ReconfigureFlag = false;

                        // change AudioState
                        m_AudioState = STATE_CLOSED;
                    }
                    m_ReconfigureLock.Unlock();
                    Sleep( 1000 ); // wait a second
                }
                break;
            }
            case STATE_RUNNING:
            default:
            {
                // do nothing but wait for reconfigure-flag... and check that
                // all audio-streams are up and running...

                cnt = (cnt+1)%80;
                if( cnt==0 )
                {
                    double cpuLoad = Pa_GetStreamCpuLoad( m_PaStream );

                    config->Log( "Audiothread-STATE: RUNNING (%f)",
                                 floor(cpuLoad*1000.0+0.5)/10.0 );
                }

                // Check for reconfiguration-request...
                m_ReconfigureLock.Lock();
                if( m_ReconfigureFlag )
                {
                    // close all active streams and change state...
                    if( m_PaStreamIsActive )
                    {
                        Pa_CloseStream( m_PaStream );
                        m_PaStreamIsActive = false;
                    }

                    // reset flag
                    m_ReconfigureFlag = false;

                    // change AudioState
                    m_AudioState = STATE_CLOSED;
                }
                m_ReconfigureLock.Unlock();

                // Check that everything is OK with the streams...

                if( m_PaStreamIsActive )
                {
                    if( Pa_IsStreamActive( m_PaStream ) != 1 )
                    {
                        // flag error
                        m_AudioState = STATE_ERROR;
                        // try to get some information on the
                        // error...
                        const PaHostErrorInfo* errorInfo = Pa_GetLastHostErrorInfo();
                        config->Log( "PaGetLastErrorInfo: %i %i %s", (int)errorInfo->hostApiType, errorInfo->errorCode, errorInfo->errorText );
                    }
                }
            }
        }
        Sleep( 100 ); // wait for 100 ms
    }

	// close all active streams ...
    if( m_PaStreamIsActive )
    {
        Pa_StopStream( m_PaStream );
        Pa_CloseStream( m_PaStream );
        m_PaStreamIsActive = false;
    }

    // all finished here...
    return( 0 );
}