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;
}
Example #2
0
PaStream *pa_dev_open(phastream_t *as, int output, char *name, int rate, int framesize, int latencymsecs)
{
  PaStreamParameters inputParameters, outputParameters;
  PaStream *stream;
  PaError err;
  char *in, *out;
  static double standardSampleRates[] = {
        8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
        44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1 /* negative terminated  list */
  };
  int i;
  int rateIndex;
  double drate = (double) rate;

  DBG_DYNA_AUDIO_DRV("phad_pa - pa_dev_open: asking for (name: \"%s\", rate: %d, framesize: %d)\n", name, rate, framesize);

  if (!strncasecmp(name, "pa:", 3))
  {
    name += 3;
  }

  if ((in = strstr(name,"IN=")) != NULL)
  {
    inputParameters.device = atoi(in + 3);
  }
  else
  {
    inputParameters.device = Pa_GetDefaultInputDevice();
    if (inputParameters.device == paNoDevice)
    {
      return 0;
    }
  }

  if ((out = strstr(name,"OUT=")))
  {
    outputParameters.device = atoi(out + 4);
  }
  else
  {
    outputParameters.device = Pa_GetDefaultOutputDevice();
    if (outputParameters.device == paNoDevice)
    {
      return 0;
    }
  }

  DBG_DYNA_AUDIO_DRV("pa_dev_open: PA Input %d, PA Output %d\n", inputParameters.device, outputParameters.device);

  inputParameters.channelCount = 1;
  inputParameters.sampleFormat = paInt16;

  inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency; // latencymsecs / 1000.0;
  //  if (inputParameters.suggestedLatency == 0.0)
  inputParameters.suggestedLatency = latencymsecs / 1000.0;
  inputParameters.hostApiSpecificStreamInfo = 0;

  outputParameters.channelCount = 1;
  outputParameters.sampleFormat = paInt16;
  outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
  //  if (outputParameters.suggestedLatency == 0.0)
  outputParameters.suggestedLatency = latencymsecs / 1000.0;

  outputParameters.hostApiSpecificStreamInfo = 0;

  DBG_DYNA_AUDIO_DRV("pa_dev_open: using latencies  in = %d ms, out = %d ms\n",  (int) (inputParameters.suggestedLatency * 1000.0),
    (int) (outputParameters.suggestedLatency * 1000.0));

  /* find the nearest matching entry in the table */
  rateIndex = -1;
  for (i = 0; standardSampleRates[i] > 0; i++ )
  {
    if (drate <= standardSampleRates[i])
    {
      rateIndex = i;
      break;
    }
  }

  if (rateIndex == -1)
  {
      return 0;
  }

  /* check if the initial match is accepted */
  err = Pa_IsFormatSupported( &inputParameters, &outputParameters, standardSampleRates[rateIndex] );
  if ( err == paFormatIsSupported )
  {
    as->actual_rate = (int) standardSampleRates[rateIndex];
  }
  else
  {
    /* find a sampling rate that IS accepted */
    i = rateIndex + 1;
    rateIndex = -1;
    for (i = 0; standardSampleRates[i] > 0; i++ )
    {
      err = Pa_IsFormatSupported( &inputParameters, &outputParameters, standardSampleRates[i] );
      if ( err == paFormatIsSupported )
      {
        rateIndex = i;
        break;
      }
    }

    if (rateIndex == -1)
    {
      return 0;
    }
  }

  as->actual_rate = (int) standardSampleRates[rateIndex];

  /* we need to recalculate the frame size? */
  if (rate !=  as->actual_rate)
  {
    int frameDuration =  1000 * (framesize / 2) / rate;
    framesize = frameDuration * as->actual_rate / 1000 * 2;
  }

  DBG_DYNA_AUDIO_DRV("pa_dev_open: chosen rate (freq, framesize)=(%d,%d)\n",
    as->actual_rate,
    framesize);

  if (output)
  {
    err = Pa_OpenStream(
              &stream,
              (output == PH_PA_INOUT) ? &inputParameters : 0,
              &outputParameters,
              standardSampleRates[rateIndex],
              framesize / 2,
              0, /* paClipOff, */  /* we won't output out of range samples so don't bother clipping them */
              (output == PH_PA_INOUT) ? ph_pa_callback : ph_pa_ocallback,
              as );
  }
  else
  {
    err = Pa_OpenStream(
              &stream,
              &inputParameters,
              0,
              standardSampleRates[rateIndex],
              framesize / 2,
              0, /* paClipOff, */  /* we won't output out of range samples so don't bother clipping them */
              ph_pa_icallback,
              as );
  }
  if( err != paNoError )
  {
    return 0;
  }

  return stream;
}
Example #3
0
int main(void)
{
    char  pad[256];
    PortAudioStream *stream;
    PaError err;
    const PaDeviceInfo *pdi;
    paTestData data = {0};
    printf("PortAudio Test: output sine wave on each channel.\n" );

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

    pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE );
    data.numChannels = pdi->maxOutputChannels;
    if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS;
    printf("Number of Channels = %d\n", data.numChannels );
    data.amplitude = 1.0;
    
    err = Pa_OpenStream(
              &stream,
              paNoDevice, /* default input device */
              0,              /* no input */
              paFloat32,  /* 32 bit floating point input */
              NULL,
              OUTPUT_DEVICE,
              data.numChannels,
              paFloat32,  /* 32 bit floating point output */
              NULL,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,  /* frames per buffer */
              0,    /* number of buffers, if zero then use default minimum */
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              patestCallback,
              &data );
    if( err != paNoError ) goto error;

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

    do
    {
        printf("Current amplitude = %f\n", data.amplitude );
        printf("Enter new amplitude or 'q' to quit.\n");
        fflush(stdout);
        gets( pad );
        if( pad[0] != 'q' )
        {
        // I tried to use atof but it seems to be broken on Mac OS X 10.1
            float amp;
            sscanf( pad, "%f", &amp );
            data.amplitude = amp;
        }
    } while( pad[0] != 'q' );

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

    Pa_CloseStream( stream );
    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;
}
Example #4
0
bool audio_init(audio_t *a, size_t sample_rate, size_t n_channels, size_t samples_per_chunk)
{
    //***Initialize PA internal data structures******
    if(Pa_Initialize() != paNoError)
        return false;

    size_t frames_per_buffer = samples_per_chunk / n_channels;

    //******Initialize input device*******
    PaStreamParameters inparams;
    PaDeviceIndex dev;
    PaTime lat;

    dev = Pa_GetDefaultInputDevice();
    if(dev == paNoDevice)
        return false;
    lat = Pa_GetDeviceInfo(dev)->defaultLowInputLatency;

    inparams = (PaStreamParameters) {
        .device = dev,
         .channelCount = n_channels,
          .sampleFormat = paInt16,
           .suggestedLatency = lat,
            .hostApiSpecificStreamInfo = NULL
    };

    //******Initialize output device*******
    PaStreamParameters outparams;
    //**************
    dev = Pa_GetDefaultOutputDevice();
    if(dev == paNoDevice)
        return false;
    lat = Pa_GetDeviceInfo(dev)->defaultLowInputLatency;

    outparams = (PaStreamParameters) {
        .device = dev,
         .channelCount = n_channels,
          .sampleFormat = paInt16,
           .suggestedLatency = lat,
            .hostApiSpecificStreamInfo = NULL
    };

    //********Open play stream*******
    PaStream *pstream=NULL;
    if(Pa_OpenStream(
                &pstream,
                NULL,
                &outparams,
                sample_rate,
                frames_per_buffer,
                paClipOff,
                playCallback,
                a) != paNoError) return false; //**************

    //********Open record and listen stream*******
    PaStream *rstream=NULL;
    if(Pa_OpenStream(
                &rstream,
                &inparams,
                NULL,
                sample_rate,
                frames_per_buffer,
                paClipOff,
                recordCallback,
                a) != paNoError) return false;

    //*****Initialize communication ring buffers********************
    PaUtilRingBuffer rb;
    void *rb_data;
    size_t rb_size;

    rb_size = 1 << (sizeof(samples_per_chunk) * CHAR_BIT - __builtin_clz(samples_per_chunk * RB_MULTIPLIER));
    rb_data = malloc(sizeof(audio_sample_t) * rb_size);
    PaUtil_InitializeRingBuffer(&rb, sizeof(audio_sample_t), rb_size, rb_data);

    *a = (audio_t) {
        .sample_rate = sample_rate,
         .n_channels = n_channels,
          .samples_per_chunk = samples_per_chunk,

           .pstream = pstream,
            .rstream = rstream,

             .wakeup = false,
              .wakeup_sig   = PTHREAD_COND_INITIALIZER,
               .wakeup_mutex  = PTHREAD_MUTEX_INITIALIZER,

                .flags = DEFAULT,

                 .prbuf = NULL,
                  .prbuf_size = 0,
                   .prbuf_offset = 0,

                    .rb = rb,
                     .rb_data = rb_data
    };

    return true;
}

void audio_destroy(audio_t *a)
{
    Pa_CloseStream(a->pstream);
    Pa_CloseStream(a->rstream);
    Pa_Terminate();

    pthread_cond_destroy(&a->wakeup_sig);
    pthread_mutex_destroy(&a->wakeup_mutex);

    audio_clear(a);
    free(a->rb_data);
}
Example #5
0
File: main.c Project: jake-g/tuner
/* -- main function -- */
int main( int argc, char **argv ) {
    PaStreamParameters inputParameters;
    float a[2], b[3], mem1[4], mem2[4];
    float data[FFT_SIZE];
    float datai[FFT_SIZE];
    float window[FFT_SIZE];
    float freqTable[FFT_SIZE];
    char * noteNameTable[FFT_SIZE];
    float notePitchTable[FFT_SIZE];
    void * fft = NULL;
    PaStream *stream = NULL;
    PaError err = 0;
    struct sigaction action;

    // add signal listen so we know when to exit:
    action.sa_handler = signalHandler;
    sigemptyset (&action.sa_mask);
    action.sa_flags = 0;

    sigaction (SIGINT, &action, NULL);
    sigaction (SIGHUP, &action, NULL);
    sigaction (SIGTERM, &action, NULL);

    // build the window, fft, etc
    /*
       buildHanWindow( window, 30 );
       for( int i=0; i<30; ++i ) {
          for( int j=0; j<window[i]*50; ++j )
             printf( "*" );
          printf("\n");
       }
       exit(0);
    */
    buildHanWindow( window, FFT_SIZE );
    fft = initfft( FFT_EXP_SIZE );
    computeSecondOrderLowPassParameters( SAMPLE_RATE, 330, a, b );
    mem1[0] = 0;
    mem1[1] = 0;
    mem1[2] = 0;
    mem1[3] = 0;
    mem2[0] = 0;
    mem2[1] = 0;
    mem2[2] = 0;
    mem2[3] = 0;
    //freq/note tables
    for( int i=0; i<FFT_SIZE; ++i ) {
        freqTable[i] = ( SAMPLE_RATE * i ) / (float) ( FFT_SIZE );
    }
    for( int i=0; i<FFT_SIZE; ++i ) {
        noteNameTable[i] = NULL;
        notePitchTable[i] = -1;
    }
    for( int i=0; i<127; ++i ) {
        float pitch = ( 440.0 / 32.0 ) * pow( 2, (i-9.0)/12.0 ) ;
        if( pitch > SAMPLE_RATE / 2.0 )
            break;
        //find the closest frequency using brute force.
        float min = 1000000000.0;
        int index = -1;
        for( int j=0; j<FFT_SIZE; ++j ) {
            if( fabsf( freqTable[j]-pitch ) < min ) {
                min = fabsf( freqTable[j]-pitch );
                index = j;
            }
        }
        noteNameTable[index] = NOTES[i%12];
        notePitchTable[index] = pitch;
        //printf( "%f %d %s\n", pitch, index, noteNameTable[index] );
    }



    // initialize portaudio
    err = Pa_Initialize();
    if( err != paNoError ) goto error;

    inputParameters.device = Pa_GetDefaultInputDevice();
    inputParameters.channelCount = 1;
    inputParameters.sampleFormat = paFloat32;
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency ;
    inputParameters.hostApiSpecificStreamInfo = NULL;

    printf( "Opening %s\n",
            Pa_GetDeviceInfo( inputParameters.device )->name );

    err = Pa_OpenStream( &stream,
                         &inputParameters,
                         NULL, //no output
                         SAMPLE_RATE,
                         FFT_SIZE,
                         paClipOff,
                         NULL,
                         NULL );
    if( err != paNoError ) goto error;

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

    // this is the main loop where we listen to and
    // process audio.
    while( running )
    {
        // read some data
        err = Pa_ReadStream( stream, data, FFT_SIZE );
        if( err ) goto error; //FIXME: we don't want to err on xrun

        // low-pass
        //for( int i=0; i<FFT_SIZE; ++i )
        //   printf( "in %f\n", data[i] );
        for( int j=0; j<FFT_SIZE; ++j ) {
            data[j] = processSecondOrderFilter( data[j], mem1, a, b );
            data[j] = processSecondOrderFilter( data[j], mem2, a, b );
        }
        // window
        applyWindow( window, data, FFT_SIZE );

        // do the fft
        for( int j=0; j<FFT_SIZE; ++j )
            datai[j] = 0;
        applyfft( fft, data, datai, false );

        //find the peak
        float maxVal = -1;
        int maxIndex = -1;
        for( int j=0; j<FFT_SIZE/2; ++j ) {
            float v = data[j] * data[j] + datai[j] * datai[j] ;
            /*
                     printf( "%d: ", j*SAMPLE_RATE/(2*FFT_SIZE) );
                     for( int i=0; i<sqrt(v)*100000000; ++i )
                        printf( "*" );
                     printf( "\n" );
            */
            if( v > maxVal ) {
                maxVal = v;
                maxIndex = j;
            }
        }
        float freq = freqTable[maxIndex];
        //find the nearest note:
        int nearestNoteDelta=0;
        while( true ) {
            if( nearestNoteDelta < maxIndex && noteNameTable[maxIndex-nearestNoteDelta] != NULL ) {
                nearestNoteDelta = -nearestNoteDelta;
                break;
            } else if( nearestNoteDelta + maxIndex < FFT_SIZE && noteNameTable[maxIndex+nearestNoteDelta] != NULL ) {
                break;
            }
            ++nearestNoteDelta;
        }
        char * nearestNoteName = noteNameTable[maxIndex+nearestNoteDelta];
        float nearestNotePitch = notePitchTable[maxIndex+nearestNoteDelta];
        float centsSharp = 1200 * log( freq / nearestNotePitch ) / log( 2.0 );

        // now output the results:
        printf("\033[2J\033[1;1H"); //clear screen, go to top left
        fflush(stdout);

        printf( "Tuner listening. Control-C to exit.\n" );
        printf( "%f Hz, %d : %f\n", freq, maxIndex, maxVal*1000 );
        printf( "Nearest Note: %s\n", nearestNoteName );
        if( nearestNoteDelta != 0 ) {
            if( centsSharp > 0 )
                printf( "%f cents sharp.\n", centsSharp );
            if( centsSharp < 0 )
                printf( "%f cents flat.\n", -centsSharp );
        } else {
            printf( "in tune!\n" );
        }
        printf( "\n" );
        int chars = 30;
        if( nearestNoteDelta == 0 || centsSharp >= 0 ) {
            for( int i=0; i<chars; ++i )
                printf( " " );
        } else {
            for( int i=0; i<chars+centsSharp; ++i )
                printf( " " );
            for( int i=chars+centsSharp<0?0:chars+centsSharp; i<chars; ++i )
                printf( "=" );
        }
        printf( " %2s ", nearestNoteName );
        if( nearestNoteDelta != 0 )
            for( int i=0; i<chars && i<centsSharp; ++i )
                printf( "=" );
        printf("\n");
    }
    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;

    // cleanup
    destroyfft( fft );
    Pa_Terminate();

    return 0;
error:
    if( stream ) {
        Pa_AbortStream( stream );
        Pa_CloseStream( stream );
    }
    destroyfft( fft );
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return 1;
}
Example #6
0
int main(void)
{
    PaStream *stream;
    PaStreamParameters outputParameters;
    PaError err;
    paTestData data;
    int i;    
    printf("Play different tone sine waves that alternate between left and right channel.\n");
    printf("The low tone should be on the left channel.\n");
    
    /* initialise sinusoidal wavetable */
    for( i=0; i<TABLE_SIZE; i++ )
    {
        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
    }
    data.left_phase = data.right_phase = 0;
    data.currentBalance = 0.0;
    data.targetBalance = 0.0;

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

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

    err = Pa_OpenStream( &stream,
                         NULL,                  /* No input. */
                         &outputParameters,     /* As above. */
                         SAMPLE_RATE,
                         FRAMES_PER_BUFFER,
                         paClipOff,      /* we won't output out of range samples so don't bother clipping them */
                         patestCallback,
                         &data );
    if( err != paNoError ) goto error;
    
    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;
    
    printf("Play for several seconds.\n");
    for( i=0; i<4; i++ )
	{
		printf("Hear low sound on left side.\n");
		data.targetBalance = 0.01;
        Pa_Sleep( 1000 );
		
		printf("Hear high sound on right side.\n");
		data.targetBalance = 0.99;
        Pa_Sleep( 1000 ); 
	}

    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;
    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;
    Pa_Terminate();
    printf("Test finished.\n");
    return err;
error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return err;
}
Example #7
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("\n=== Now recording!! Please speak into the microphone. ===\n"); fflush(stdout);
 
     while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
     {
         Pa_Sleep(1000);
         printf("index = %d\n", data.frameIndex ); fflush(stdout);
     }
     if( err < 0 ) goto done;
 
     err = Pa_CloseStream( stream );
     if( err != paNoError ) goto done;
 
     /* 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 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 = 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;
 }
Example #8
0
// print the audio device to stdout.
static void printDeviceInfo( int device )
{
    const PaDeviceInfo *pdi;
    bool defaultDisplayed = false;

    pdi = Pa_GetDeviceInfo( device );

    if( pdi != NULL )
    {
        messagePrintf( ( "\n" ) );

        if( device == Pa_GetDefaultInputDevice() )
        {
            messagePrintf( ( "[ Default Input" ) );
            defaultDisplayed = true;
        }
        else if( device == Pa_GetHostApiInfo( pdi->hostApi )->defaultInputDevice )
        {
            const PaHostApiInfo *phai = Pa_GetHostApiInfo( pdi->hostApi );
            messagePrintf( ( "[ Default %s Input", phai->name ) );
            defaultDisplayed = true;
        }

        if( device == Pa_GetDefaultOutputDevice() )
        {
            messagePrintf( ( ( defaultDisplayed ? "," : "[") ) );
            messagePrintf( ( " Default Output" ) );
            defaultDisplayed = true;
        }
        else if( device == Pa_GetHostApiInfo( pdi->hostApi )->defaultOutputDevice )
        {
            const PaHostApiInfo *phai = Pa_GetHostApiInfo( pdi->hostApi );
            messagePrintf( ( ( defaultDisplayed ? "," : "[") ) );
            messagePrintf( ( " Default %s Output", phai->name ) );
            defaultDisplayed = true;
        }

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

        messagePrintf( ( ""
            "Device %d name: %s\n"
            "Host API name: %s\n"
            "Max input channels: %d, Max output channels: %d\n"
            "Default input latency:  %8.4f(low) - %8.4f(high)\n"
            "Default output latency: %8.4f(low) - %8.4f(high)\n"
            "Default sample rate: %8.2f\n",
            device, pdi->name,
            Pa_GetHostApiInfo( pdi->hostApi )->name,
            pdi->maxInputChannels, pdi->maxOutputChannels,
            pdi->defaultLowInputLatency, pdi->defaultHighInputLatency,
            pdi->defaultLowOutputLatency, pdi->defaultHighOutputLatency,
            pdi->defaultSampleRate ) );

        if( true )	// Print supported standard sample rates
        {
            PaStreamParameters inputParameters, outputParameters;

            inputParameters.device = device;
            inputParameters.channelCount = pdi->maxInputChannels;
            inputParameters.sampleFormat = paInt16;					// default only
            inputParameters.suggestedLatency = 0;
            inputParameters.hostApiSpecificStreamInfo = NULL;

            outputParameters.device = device;
            outputParameters.channelCount = pdi->maxOutputChannels;
            outputParameters.sampleFormat = paInt16;				// default only
            outputParameters.suggestedLatency = 0;
            outputParameters.hostApiSpecificStreamInfo = NULL;

            if( inputParameters.channelCount > 0 )
            {
                messagePrintf( ( "Supported standard sample rates input.\n" ) );
                printSupportedStandardSampleRates( &inputParameters, NULL );
            }

            if( outputParameters.channelCount > 0 )
            {
                messagePrintf( ( "Supported standard sample rates output.\n" ) );
                printSupportedStandardSampleRates( NULL, &outputParameters );
            }

            if( inputParameters.channelCount > 0 && outputParameters.channelCount > 0 )
            {
                messagePrintf( ( "Supported standard sample rates input/output.\n" ) );
                printSupportedStandardSampleRates( &inputParameters, &outputParameters );
            }
        }
    }
}
Example #9
0
Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples) :
    _stream(NULL),
    _ringBuffer(true),
    _scope(scope),
    _averagedLatency(0.0),
    _measuredJitter(0),
    _jitterBufferSamples(initialJitterBufferSamples),
    _wasStarved(0),
    _numStarves(0),
    _lastInputLoudness(0),
    _lastVelocity(0),
    _lastAcceleration(0),
    _totalPacketsReceived(0),
    _firstPacketReceivedTime(),
    _packetsReceivedThisPlayback(0),
    _echoSamplesLeft(NULL),
    _isSendingEchoPing(false),
    _pingAnalysisPending(false),
    _pingFramesToRecord(0),
    _samplesLeftForFlange(0),
    _lastYawMeasuredMaximum(0),
    _flangeIntensity(0.0f),
    _flangeRate(0.0f),
    _flangeWeight(0.0f),
    _collisionSoundMagnitude(0.0f),
    _collisionSoundFrequency(0.0f),
    _collisionSoundNoise(0.0f),
    _collisionSoundDuration(0.0f),
    _proceduralEffectSample(0),
    _heartbeatMagnitude(0.0f),
    _listenMode(AudioRingBuffer::NORMAL),
    _listenRadius(0.0f)
{
    outputPortAudioError(Pa_Initialize());
    
    //  NOTE:  Portaudio documentation is unclear as to whether it is safe to specify the
    //         number of frames per buffer explicitly versus setting this value to zero.
    //         Possible source of latency that we need to investigate further.
    // 
    unsigned long FRAMES_PER_BUFFER = BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
    
    //  Manually initialize the portaudio stream to ask for minimum latency
    PaStreamParameters inputParameters, outputParameters;
    
    inputParameters.device = Pa_GetDefaultInputDevice();
    outputParameters.device = Pa_GetDefaultOutputDevice();

    if (inputParameters.device == -1 || outputParameters.device == -1) {
        qDebug("Audio: Missing device.\n");
        outputPortAudioError(Pa_Terminate());
        return;
    }

    inputParameters.channelCount = 2;                    //  Stereo input
    inputParameters.sampleFormat = (paInt16 | paNonInterleaved);
    inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
    inputParameters.hostApiSpecificStreamInfo = NULL;

    outputParameters.channelCount = 2;                    //  Stereo output
    outputParameters.sampleFormat = (paInt16 | paNonInterleaved);
    outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;
    
    outputPortAudioError(Pa_OpenStream(&_stream, 
                                       &inputParameters,
                                       &outputParameters,
                                       SAMPLE_RATE,
                                       FRAMES_PER_BUFFER,
                                       paNoFlag,
                                       audioCallback,
                                       (void*) this));
        
    if (! _stream) {
        return;
    }
 
    _echoSamplesLeft = new int16_t[AEC_BUFFERED_SAMPLES + AEC_TMP_BUFFER_SIZE];
    memset(_echoSamplesLeft, 0, AEC_BUFFERED_SAMPLES * sizeof(int16_t));
    
    // start the stream now that sources are good to go
    outputPortAudioError(Pa_StartStream(_stream));
    
    // Uncomment these lines to see the system-reported latency
    //qDebug("Default low input, output latency (secs): %0.4f, %0.4f\n",
    //         Pa_GetDeviceInfo(Pa_GetDefaultInputDevice())->defaultLowInputLatency,
    //         Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice())->defaultLowOutputLatency);
    
    const PaStreamInfo* streamInfo = Pa_GetStreamInfo(_stream);
    qDebug("Started audio with reported latency msecs In/Out: %.0f, %.0f\n", streamInfo->inputLatency * 1000.f,
             streamInfo->outputLatency * 1000.f);

    gettimeofday(&_lastReceiveTime, NULL);
}
Example #10
0
bool Portaudio::init()
      {
      PaError err = Pa_Initialize();
      if (err != paNoError) {
            qDebug("Portaudio initialize failed: %s", Pa_GetErrorText(err));
            return false;
            }
      initialized = true;
      if (MScore::debugMode)
            qDebug("using PortAudio Version: %s", Pa_GetVersionText());

      PaDeviceIndex idx = preferences.portaudioDevice;
      if (idx < 0)
            idx = Pa_GetDefaultOutputDevice();

      const PaDeviceInfo* di = Pa_GetDeviceInfo(idx);
      
      if (di == nullptr)
            di = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice());
            
      _sampleRate = int(di->defaultSampleRate);

      /* Open an audio I/O stream. */
      struct PaStreamParameters out;
      memset(&out, 0, sizeof(out));

      out.device           = idx;
      out.channelCount     = 2;
      out.sampleFormat     = paFloat32;
#ifdef Q_OS_MAC
      out.suggestedLatency = 0.020;
#else // on windows, this small latency causes some problem
      out.suggestedLatency = 0.100;
#endif
      out.hostApiSpecificStreamInfo = 0;

      err = Pa_OpenStream(&stream, 0, &out, double(_sampleRate), 0, 0, paCallback, (void*)this);
      if (err != paNoError) {
            // fall back to default device:
            out.device = Pa_GetDefaultOutputDevice();
            err = Pa_OpenStream(&stream, 0, &out, double(_sampleRate), 0, 0, paCallback, (void*)this);
            if (err != paNoError) {
                  qDebug("Portaudio open stream %d failed: %s", idx, Pa_GetErrorText(err));
                  return false;
                  }
            }
      const PaStreamInfo* si = Pa_GetStreamInfo(stream);
      if (si)
            _sampleRate = int(si->sampleRate);
#ifdef USE_ALSA
      midiDriver = new AlsaMidiDriver(seq);
#endif
#ifdef USE_PORTMIDI
      midiDriver = new PortMidiDriver(seq);
#endif
      if (midiDriver && !midiDriver->init()) {
            qDebug("Init midi driver failed");
            delete midiDriver;
            midiDriver = 0;
#ifdef USE_PORTMIDI
            return true;                  // return OK for audio driver; midi is only input
#else
            return false;
#endif
            }
      return true;
      }
Example #11
0
int audioPlayRec( int playdevID, SAMPLE * playbuffer, int playbuflen, int playbuffirstchannel, int playbuflastchannel, int recdevID, SAMPLE * recbuffer, int recbuflen, int recbuffirstchannel, int recbuflastchannel, char * recCallbackName, int samplerate )
{
    paAudioData audio;
    mxArray * precRingArray = NULL;

    audio.recMode = PLAYREC_NONE;

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

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

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

        audio.recMode |= PLAYREC_PLAY;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                if( stop )	break;	// recording stop
            }

            if( stop )	break;	// recording stop

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

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

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

    Pa_Terminate();

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

    return err;

error:
    Pa_Terminate();

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

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

    return err;
}
Example #12
0
int main(void)
{
    PortAudioStream *stream;
    PaError err;
    paTestData data;
    int i;
    PaDeviceID inputDevice;
    const PaDeviceInfo *pdi;
    printf("PortAudio Test: input signal from each channel. %d buffers\n", NUM_BUFFERS );
    data.liveChannel = 0;
    err = Pa_Initialize();
    if( err != paNoError ) goto error;
#ifdef INPUT_DEVICE_NAME
    printf("Try to use device: %s\n", INPUT_DEVICE_NAME );
    inputDevice = PaFindDeviceByName(INPUT_DEVICE_NAME);
    if( inputDevice == paNoDevice )
    {
        printf("Could not find %s. Using default instead.\n", INPUT_DEVICE_NAME );
        inputDevice = Pa_GetDefaultInputDeviceID();
    }
#else
    printf("Using default input device.\n");
    inputDevice = Pa_GetDefaultInputDeviceID();
#endif
    pdi = Pa_GetDeviceInfo( inputDevice );
    if( pdi == NULL )
    {
        printf("Could not get device info!\n");
        goto error;
    }
    data.numChannels = pdi->maxInputChannels;
    printf("Input Device name is %s\n", pdi->name );
    printf("Input Device has %d channels.\n", pdi->maxInputChannels);
    err = Pa_OpenStream(
              &stream,
              inputDevice,
              pdi->maxInputChannels,
              paFloat32,  /* 32 bit floating point input */
              NULL,
              OUTPUT_DEVICE,
              2,
              paFloat32,  /* 32 bit floating point output */
              NULL,
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,  /* frames per buffer */
              NUM_BUFFERS,    /* number of buffers, if zero then use default minimum */
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              patestCallback,
              &data );
    if( err != paNoError ) goto error;
    data.liveChannel = 0;
    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;
    for( i=0; i<data.numChannels; i++ )
    {
        data.liveChannel = i;
        printf("Channel %d being sent to output. Hit ENTER for next channel.", i );
        fflush(stdout);
        getchar();
    }
    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;

    err = Pa_CloseStream( stream );
    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;
}
Example #13
0
int openPA(Synth* synth, Vocoder* vc) {
    printf("PortAudio Test: output sawtooth wave.\n"); fflush(stdout);

    PaStreamParameters inputParameters, outputParameters;

    paData* data = (paData*) malloc(sizeof(paData));
    data->synth  = synth;
    data->vc     = vc;

    /* Initialize library before making any other calls. */
    err = Pa_Initialize();
    if( err != paNoError ) goto error;

    /* Set up input parameters */
    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
    if (inputParameters.device == paNoDevice) {
        fprintf(stderr,"Error: No default input device.\n");
        goto error;
    }
    printf( "Input device # %d.\n", inputParameters.device );
    printf( "Input LL: %g s\n", Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency );
    printf( "Input HL: %g s\n", Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency );
    inputParameters.channelCount = NUM_CHANNELS;
    inputParameters.sampleFormat = FORMAT;
    inputParameters.suggestedLatency = 
        Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
    inputParameters.hostApiSpecificStreamInfo = NULL;

    /* Set up output parameters */
    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
    if (outputParameters.device == paNoDevice) {
        fprintf(stderr,"Error: No default output device.\n");
        goto error;
    }
    printf( "Output device # %d.\n", outputParameters.device );
    printf( "Output LL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency );
    printf( "Output HL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency );
    outputParameters.channelCount = NUM_CHANNELS;
    outputParameters.sampleFormat = FORMAT;
    outputParameters.suggestedLatency = 
        Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;
    
    /* Open an audio I/O stream. */
    err = Pa_OpenStream( 
            &stream,
            &inputParameters,
            &outputParameters,
            SAMPLE_RATE,
            FRAMES_PER_BUFFER,
            paClipOff,
            paCallback,
            data );
    if( err != paNoError ) goto error;

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

    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 ) );
    synth_free(data->synth);
    vc_free(data->vc);
    free(data);
    return err;
}
SoundDriver_PortAudio::SoundDriver_PortAudio() {
	
	mixing_frequency=1;
	

	driver_name="PortAudio v19";
	
	active=false;

	
	int devices=Pa_GetDeviceCount();
		
	int current_input=0;
	int current_output=0;
	
	std::vector<String> output_names;
	std::vector<String> input_names;
	
	for (int i=0;i<devices;i++) {
		const PaDeviceInfo * dinfo=Pa_GetDeviceInfo (i);
		
		
		if (dinfo->maxOutputChannels) {
			
			if (i==Pa_GetDefaultOutputDevice())
				current_output=output_device_index.size();
			output_device_index.push_back(i);
			output_names.push_back(dinfo->name);
		}
		if (dinfo->maxInputChannels) {
			
			if (i==Pa_GetDefaultInputDevice())
				current_input=input_device_index.size();
			input_device_index.push_back(i);
			input_names.push_back(dinfo->name);
		}

	}	
	
	input_devices.set_all("input_devices","Input Devices",input_names,current_input);
	output_devices.set_all("output_devices","Output Devices",output_names,current_output);

	
	std::vector<String> buffer_sizes_text;
	for (int i=0;i<MAX_BUFFER_SIZES;i++) {
		
		buffer_sizes_text.push_back( String::num(buffer_sizes[i]) );
	}
	
	buffer_size.set_all("buffer_size","Buffer Size",buffer_sizes_text,6,"frames");
	
	
	sampling_rate_values.push_back(4000);
	sampling_rate_values.push_back(5512);
	sampling_rate_values.push_back(8000);
	sampling_rate_values.push_back(9600);
	sampling_rate_values.push_back(11025);
	sampling_rate_values.push_back(16000);
	sampling_rate_values.push_back(22050);
	sampling_rate_values.push_back(22050);
	sampling_rate_values.push_back(32000);
	sampling_rate_values.push_back(44100);
	sampling_rate_values.push_back(48000);
	sampling_rate_values.push_back(88200);
	sampling_rate_values.push_back(96000);
	sampling_rate_values.push_back(192000);
	
	std::vector<String> sampling_rates_text;
	for (int i=0;i<sampling_rate_values.size();i++) {
		
		sampling_rates_text.push_back( String::num(sampling_rate_values[i]) );
	}
	
	int default_sampling_rate=0;
	for (int i=0;i<sampling_rate_values.size();i++) {
		default_sampling_rate=i;
		if (sampling_rate_values[i]>=48000)
			break;
		
		
	}
	
	mix_rate.set_all("sampling_rate","Sampling Rate",sampling_rates_text,default_sampling_rate,"hz");

	
	settings.push_back(&input_devices);
	settings.push_back(&output_devices);
	settings.push_back(&buffer_size);
	settings.push_back(&mix_rate);
	
	stream=NULL;
	
}
Example #15
0
/* Internal: create playback stream */
static pj_status_t create_play_stream(struct pa_aud_factory *pa,
				      const pjmedia_aud_param *param,
				      pjmedia_aud_play_cb play_cb,
				      void *user_data,
				      pjmedia_aud_stream **p_snd_strm)
{
    pj_pool_t *pool;
    pjmedia_aud_dev_index play_id;
    struct pa_aud_stream *stream;
    PaStreamParameters outputParam;
    int sampleFormat;
    const PaDeviceInfo *paDevInfo = NULL;
    const PaHostApiInfo *paHostApiInfo = NULL;
    const PaStreamInfo *paSI;
    unsigned paFrames, paRate, paLatency;
    PaError err;

    PJ_ASSERT_RETURN(play_cb && p_snd_strm, PJ_EINVAL);

    play_id = param->play_id;
    if (play_id < 0) {
	play_id = pa_get_default_output_dev(param->channel_count);
	if (play_id < 0) {
	    /* No such device. */
	    return PJMEDIA_EAUD_NODEFDEV;
	}
    } 

    paDevInfo = Pa_GetDeviceInfo(play_id);
    if (!paDevInfo) {
	/* Assumed it is "No such device" error. */
	return PJMEDIA_EAUD_INVDEV;
    }

    if (param->bits_per_sample == 8)
	sampleFormat = paUInt8;
    else if (param->bits_per_sample == 16)
	sampleFormat = paInt16;
    else if (param->bits_per_sample == 32)
	sampleFormat = paInt32;
    else
	return PJMEDIA_EAUD_SAMPFORMAT;
    
    pool = pj_pool_create(pa->pf, "playstrm", 1024, 1024, NULL);
    if (!pool)
	return PJ_ENOMEM;

    stream = PJ_POOL_ZALLOC_T(pool, struct pa_aud_stream);
    stream->pool = pool;
    pj_strdup2_with_null(pool, &stream->name, paDevInfo->name);
    stream->dir = PJMEDIA_DIR_PLAYBACK;
    stream->play_id = play_id;
    stream->rec_id = -1;
    stream->user_data = user_data;
    stream->samples_per_sec = param->clock_rate;
    stream->samples_per_frame = param->samples_per_frame;
    stream->bytes_per_sample = param->bits_per_sample / 8;
    stream->channel_count = param->channel_count;
    stream->play_cb = play_cb;

    stream->play_buf = (pj_int16_t*)pj_pool_alloc(pool, 
					    stream->samples_per_frame * 
					    stream->bytes_per_sample);
    stream->play_buf_count = 0;

    pj_bzero(&outputParam, sizeof(outputParam));
    outputParam.device = play_id;
    outputParam.channelCount = param->channel_count;
    outputParam.hostApiSpecificStreamInfo = NULL;
    outputParam.sampleFormat = sampleFormat;
    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY)
	outputParam.suggestedLatency=param->output_latency_ms / 1000.0;
    else
	outputParam.suggestedLatency=PJMEDIA_SND_DEFAULT_PLAY_LATENCY/1000.0;

    paHostApiInfo = Pa_GetHostApiInfo(paDevInfo->hostApi);

    /* Frames in PortAudio is number of samples in a single channel */
    paFrames = param->samples_per_frame / param->channel_count;

    err = Pa_OpenStream( &stream->play_strm, NULL, &outputParam,
			 param->clock_rate,  paFrames, 
			 paClipOff, &PaPlayerCallback, stream );
    if (err != paNoError) {
	pj_pool_release(pool);
	return PJMEDIA_AUDIODEV_ERRNO_FROM_PORTAUDIO(err);
    }

    paSI = Pa_GetStreamInfo(stream->play_strm);
    paRate = (unsigned)(paSI->sampleRate);
    paLatency = (unsigned)(paSI->outputLatency * 1000);

    PJ_LOG(5,(THIS_FILE, "Opened device %d: %s(%s) for playing, sample rate=%d"
			 ", ch=%d, "
			 "bits=%d, %d samples per frame, latency=%d ms",
			 play_id, paDevInfo->name, paHostApiInfo->name, 
			 paRate, param->channel_count,
		 	 param->bits_per_sample, param->samples_per_frame, 
			 paLatency));

    *p_snd_strm = &stream->base;

    return PJ_SUCCESS;
}
Example #16
0
int softrock_open(void) {
#ifdef DIRECTAUDIO  
    int arg;
    int status;
#endif
#ifdef PORTAUDIO
		int rc;
    int status;
#endif
#ifdef PULSEAUDIO
    int error;
    pa_sample_spec params; 
    pa_buffer_attr attrs;
#endif
#ifdef PORTAUDIO
    PaStreamParameters inputParameters;
    PaStreamParameters outputParameters;
    PaStreamInfo *info;
    int devices;
    int i;
    PaDeviceInfo* deviceInfo;
	if (softrock_get_verbose())  fprintf(stderr,"softrock_open: portaudio\n");
#endif
#ifdef DIRECTAUDIO
	if (softrock_get_verbose())  fprintf(stderr,"softrock_open: %s\n",softrock_get_device());
#endif

    if(softrock_get_playback()) {
        return 0;
    }

#ifdef PULSEAUDIO
    if (softrock_get_verbose())  fprintf(stderr,"Using PulseAudio\n");

    params.format=PA_SAMPLE_FLOAT32LE;
    params.rate=softrock_get_sample_rate();
    params.channels=2;


    attrs.maxlength=attrs.minreq=attrs.prebuf=attrs.tlength=(uint32_t)-1;
    attrs.fragsize=attrs.maxlength=attrs.minreq=attrs.prebuf=(uint32_t)-1;
    attrs.fragsize=SAMPLES_PER_BUFFER*2 * sizeof(float);
    attrs.tlength=SAMPLES_PER_BUFFER*2 * sizeof(float);

    if (softrock_get_verbose())  fprintf(stderr,"params.rate=%d\n",params.rate);

    stream=pa_simple_new("localhost","Softrock", PA_STREAM_RECORD, NULL, "IQ", &params, NULL, &attrs, &error);
    if(stream==NULL) {
        if (softrock_get_verbose())  fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
        exit(0);
    }
    playback_stream=pa_simple_new("localhost","Softrock", PA_STREAM_PLAYBACK, NULL, "IQ", &params, NULL, &attrs, &error);
    if(playback_stream==NULL) {
        if (softrock_get_verbose())  fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
        exit(0);
    }


    ftime(&start_time);
#endif
#ifdef PORTAUDIO
    if (softrock_get_verbose())  fprintf(stderr,"Using PortAudio\n");

    rc=Pa_Initialize();
    if(rc!=paNoError) {
        if (softrock_get_verbose())  fprintf(stderr,"Pa_Initialize failed: %s\n",Pa_GetErrorText(rc));
        exit(1);
    }

    devices=Pa_GetDeviceCount();
    if(devices<0) {
        if (softrock_get_verbose())  fprintf(stderr,"Px_GetDeviceCount failed: %s\n",Pa_GetErrorText(devices));
    } else {
        if (softrock_get_verbose())  fprintf(stderr,"default input=%d output=%d devices=%d\n",Pa_GetDefaultInputDevice(),Pa_GetDefaultOutputDevice(),devices);

        for(i=0;i<devices;i++) {
            deviceInfo=Pa_GetDeviceInfo(i);
            if (softrock_get_verbose())  fprintf(stderr,"%d - %s\n",i,deviceInfo->name);
                if (softrock_get_verbose())  fprintf(stderr,"maxInputChannels: %d\n",deviceInfo->maxInputChannels);
                if (softrock_get_verbose())  fprintf(stderr,"maxOututChannels: %d\n",deviceInfo->maxOutputChannels);
                //if (softrock_get_verbose())  fprintf(stderr,"defaultLowInputLatency: %f\n",deviceInfo->defaultLowInputLatency);
                //if (softrock_get_verbose())  fprintf(stderr,"defaultLowOutputLatency: %f\n",deviceInfo->defaultLowOutputLatency);
                //if (softrock_get_verbose())  fprintf(stderr,"defaultHighInputLatency: %f\n",deviceInfo->defaultHighInputLatency);
                //if (softrock_get_verbose())  fprintf(stderr,"defaultHighOutputLatency: %f\n",deviceInfo->defaultHighOutputLatency);
                //if (softrock_get_verbose())  fprintf(stderr,"defaultSampleRate: %f\n",deviceInfo->defaultSampleRate);
        }
    }

    inputParameters.device=atoi(softrock_get_input());
    inputParameters.channelCount=2;
    inputParameters.sampleFormat=paFloat32;
    inputParameters.suggestedLatency=Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
    inputParameters.hostApiSpecificStreamInfo=NULL;

    outputParameters.device=atoi(softrock_get_output());
    outputParameters.channelCount=2;
    outputParameters.sampleFormat=paFloat32;
    outputParameters.suggestedLatency=Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo=NULL;

	if (softrock_get_verbose()) fprintf(stderr,"input device=%d output device=%d\n",inputParameters.device,outputParameters.device);
    rc=Pa_OpenStream(&stream,&inputParameters,&outputParameters,(double)softrock_get_sample_rate(),(unsigned long)SAMPLES_PER_BUFFER,paNoFlag,NULL,NULL);
    if(rc!=paNoError) {
        if (softrock_get_verbose()) fprintf(stderr,"Pa_OpenStream failed: %s\n",Pa_GetErrorText(rc));
        exit(1);
    }

    rc=Pa_StartStream(stream);
    if(rc!=paNoError) {
        if (softrock_get_verbose()) fprintf(stderr,"Pa_StartStream failed: %s\n",Pa_GetErrorText(rc));
        exit(1);
    }

    info=Pa_GetStreamInfo(stream);
    if(info!=NULL) {
        if (softrock_get_verbose()) fprintf(stderr,"stream.sampleRate=%f\n",info->sampleRate);
        if (softrock_get_verbose()) fprintf(stderr,"stream.inputLatency=%f\n",info->inputLatency);
        if (softrock_get_verbose()) fprintf(stderr,"stream.outputLatency=%f\n",info->outputLatency);
    } else {
        if (softrock_get_verbose()) fprintf(stderr,"Pa_GetStreamInfo returned NULL\n");
    }
#endif
#ifdef DIRECTAUDIO

    if (softrock_get_verbose()) fprintf(stderr,"Using direct audio\n");
    /* open sound device */
    fd = open(softrock_get_device(), O_RDWR);
    if (fd < 0) {
        perror("open of audio device failed");
        exit(1);
    }

    /* set sampling parameters */
    arg = SAMPLE_SIZE;      /* sample size */
    status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
    if (status == -1)
        perror("SOUND_PCM_WRITE_BITS ioctl failed");
    if (arg != SAMPLE_SIZE)
        perror("unable to set write sample size");

    status = ioctl(fd, SOUND_PCM_READ_BITS, &arg);
    if (status == -1)
        perror("SOUND_PCM_READ_BITS ioctl failed");
    if (arg != SAMPLE_SIZE)
        perror("unable to set read sample size");

    arg = CHANNELS;  /* mono or stereo */
    status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
    if (status == -1)
        perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
    if (arg != CHANNELS)
        perror("unable to set number of channels");

    arg = softrock_get_sample_rate();      /* sampling rate */
	if (softrock_get_verbose()) fprintf(stderr,"sample_rate: %d\n",arg);
    status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
    if (status == -1)
        perror("SOUND_PCM_WRITE_WRITE ioctl failed");

    arg = AFMT_S16_LE;       /* signed little endian */
    status = ioctl(fd, SOUND_PCM_SETFMT, &arg);
    if (status == -1)
        perror("SOUND_PCM_SETFMTS ioctl failed");

#endif

	InitBuf(&rx_r, "RX_R");
	InitBuf(&rx_l, "RX_R");
	printf("my ring buffers are set\n");
    return 0;
}
Example #17
0
/* Internal: Create both player and recorder stream */
static pj_status_t create_bidir_stream(struct pa_aud_factory *pa,
				       const pjmedia_aud_param *param,
				       pjmedia_aud_rec_cb rec_cb,
				       pjmedia_aud_play_cb play_cb,
				       void *user_data,
				       pjmedia_aud_stream **p_snd_strm)
{
    pj_pool_t *pool;
    pjmedia_aud_dev_index rec_id, play_id;
    struct pa_aud_stream *stream;
    PaStream *paStream = NULL;
    PaStreamParameters inputParam;
    PaStreamParameters outputParam;
    int sampleFormat;
    const PaDeviceInfo *paRecDevInfo = NULL;
    const PaDeviceInfo *paPlayDevInfo = NULL;
    const PaHostApiInfo *paRecHostApiInfo = NULL;
    const PaHostApiInfo *paPlayHostApiInfo = NULL;
    const PaStreamInfo *paSI;
    unsigned paFrames, paRate, paInputLatency, paOutputLatency;
    PaError err;

    PJ_ASSERT_RETURN(play_cb && rec_cb && p_snd_strm, PJ_EINVAL);

    rec_id = param->rec_id;
    if (rec_id < 0) {
	rec_id = pa_get_default_input_dev(param->channel_count);
	if (rec_id < 0) {
	    /* No such device. */
	    return PJMEDIA_EAUD_NODEFDEV;
	}
    }

    paRecDevInfo = Pa_GetDeviceInfo(rec_id);
    if (!paRecDevInfo) {
	/* Assumed it is "No such device" error. */
	return PJMEDIA_EAUD_INVDEV;
    }

    play_id = param->play_id;
    if (play_id < 0) {
	play_id = pa_get_default_output_dev(param->channel_count);
	if (play_id < 0) {
	    /* No such device. */
	    return PJMEDIA_EAUD_NODEFDEV;
	}
    } 

    paPlayDevInfo = Pa_GetDeviceInfo(play_id);
    if (!paPlayDevInfo) {
	/* Assumed it is "No such device" error. */
	return PJMEDIA_EAUD_INVDEV;
    }


    if (param->bits_per_sample == 8)
	sampleFormat = paUInt8;
    else if (param->bits_per_sample == 16)
	sampleFormat = paInt16;
    else if (param->bits_per_sample == 32)
	sampleFormat = paInt32;
    else
	return PJMEDIA_EAUD_SAMPFORMAT;
    
    pool = pj_pool_create(pa->pf, "sndstream", 1024, 1024, NULL);
    if (!pool)
	return PJ_ENOMEM;

    stream = PJ_POOL_ZALLOC_T(pool, struct pa_aud_stream);
    stream->pool = pool;
    pj_strdup2_with_null(pool, &stream->name, paRecDevInfo->name);
    stream->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
    stream->play_id = play_id;
    stream->rec_id = rec_id;
    stream->user_data = user_data;
    stream->samples_per_sec = param->clock_rate;
    stream->samples_per_frame = param->samples_per_frame;
    stream->bytes_per_sample = param->bits_per_sample / 8;
    stream->channel_count = param->channel_count;
    stream->rec_cb = rec_cb;
    stream->play_cb = play_cb;

    stream->rec_buf = (pj_int16_t*)pj_pool_alloc(pool, 
		      stream->samples_per_frame * stream->bytes_per_sample);
    stream->rec_buf_count = 0;

    stream->play_buf = (pj_int16_t*)pj_pool_alloc(pool, 
		       stream->samples_per_frame * stream->bytes_per_sample);
    stream->play_buf_count = 0;

    pj_bzero(&inputParam, sizeof(inputParam));
    inputParam.device = rec_id;
    inputParam.channelCount = param->channel_count;
    inputParam.hostApiSpecificStreamInfo = NULL;
    inputParam.sampleFormat = sampleFormat;
    if (param->flags & PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY)
	inputParam.suggestedLatency = param->input_latency_ms / 1000.0;
    else
	inputParam.suggestedLatency = PJMEDIA_SND_DEFAULT_REC_LATENCY / 1000.0;

    paRecHostApiInfo = Pa_GetHostApiInfo(paRecDevInfo->hostApi);

    pj_bzero(&outputParam, sizeof(outputParam));
    outputParam.device = play_id;
    outputParam.channelCount = param->channel_count;
    outputParam.hostApiSpecificStreamInfo = NULL;
    outputParam.sampleFormat = sampleFormat;
    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY)
	outputParam.suggestedLatency=param->output_latency_ms / 1000.0;
    else
	outputParam.suggestedLatency=PJMEDIA_SND_DEFAULT_PLAY_LATENCY/1000.0;

    paPlayHostApiInfo = Pa_GetHostApiInfo(paPlayDevInfo->hostApi);

    /* Frames in PortAudio is number of samples in a single channel */
    paFrames = param->samples_per_frame / param->channel_count;

    /* If both input and output are on the same device, open a single stream
     * for both input and output.
     */
    if (rec_id == play_id) {
	err = Pa_OpenStream( &paStream, &inputParam, &outputParam,
			     param->clock_rate, paFrames, 
			     paClipOff, &PaRecorderPlayerCallback, stream );
	if (err == paNoError) {
	    /* Set play stream and record stream to the same stream */
	    stream->play_strm = stream->rec_strm = paStream;
	}
    } else {
	err = -1;
    }

    /* .. otherwise if input and output are on the same device, OR if we're
     * unable to open a bidirectional stream, then open two separate
     * input and output stream.
     */
    if (paStream == NULL) {
	/* Open input stream */
	err = Pa_OpenStream( &stream->rec_strm, &inputParam, NULL,
			     param->clock_rate, paFrames, 
			     paClipOff, &PaRecorderCallback, stream );
	if (err == paNoError) {
	    /* Open output stream */
	    err = Pa_OpenStream( &stream->play_strm, NULL, &outputParam,
				 param->clock_rate, paFrames, 
				 paClipOff, &PaPlayerCallback, stream );
	    if (err != paNoError)
		Pa_CloseStream(stream->rec_strm);
	}
    }

    if (err != paNoError) {
	pj_pool_release(pool);
	return PJMEDIA_AUDIODEV_ERRNO_FROM_PORTAUDIO(err);
    }

    paSI = Pa_GetStreamInfo(stream->rec_strm);
    paRate = (unsigned)(paSI->sampleRate);
    paInputLatency = (unsigned)(paSI->inputLatency * 1000);
    paSI = Pa_GetStreamInfo(stream->play_strm);
    paOutputLatency = (unsigned)(paSI->outputLatency * 1000);

    PJ_LOG(5,(THIS_FILE, "Opened device %s(%s)/%s(%s) for recording and "
			 "playback, sample rate=%d, ch=%d, "
			 "bits=%d, %d samples per frame, input latency=%d ms, "
			 "output latency=%d ms",
			 paRecDevInfo->name, paRecHostApiInfo->name,
			 paPlayDevInfo->name, paPlayHostApiInfo->name,
			 paRate, param->channel_count,
			 param->bits_per_sample, param->samples_per_frame,
			 paInputLatency, paOutputLatency));

    *p_snd_strm = &stream->base;

    return PJ_SUCCESS;
}
Example #18
0
_JATTA_EXPORT Jatta::PortAudio::Device Jatta::PortAudio::HostApi::GetDefaultOutputDevice()
{
    return Device(host->defaultOutputDevice, Pa_GetDeviceInfo(host->defaultOutputDevice));
}
int main(void)
{
    PaStreamParameters outputParameters;
    PaStream *stream;
    PaError err;
    paTestData data;
#ifdef __APPLE__
    PaMacCoreStreamInfo macInfo;
    const SInt32 channelMap[4] = { -1, -1, 0, 1 };
#endif
    int i;


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

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

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

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

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

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

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

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

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

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

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

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

    return err;
error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return err;
}
int main(void)
{
    PaStreamParameters outputParameters;
    PaStream *stream;
    PaError err;
    int safeSineCount, stressedSineCount;
    int safeUnderflowCount, stressedUnderflowCount;
    paTestData data = {0};
    double load;


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

    err = Pa_Initialize();
    if( err != paNoError ) goto error;
    
    outputParameters.device = Pa_GetDefaultOutputDevice();  /* default output device */
    outputParameters.channelCount = 1;                      /* mono output */
    outputParameters.sampleFormat = paFloat32;              /* 32 bit floating point output */
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;

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

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

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

        load = Pa_GetStreamCpuLoad( stream );
        printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
    }
    while( load < 0.5 && data.sineCount < (MAX_SINES-1));

    safeSineCount = data.sineCount;

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

    stressedUnderflowCount = data.outputUnderflowCount;

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

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

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

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

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

    return err;
error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return err;
}
Example #21
0
int main(void)
{
    PaStreamParameters outputParameters;
    PaStream *stream;
    PaError err;
    float buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */
    float sine[TABLE_SIZE]; /* sine wavetable */
    int left_phase = 0;
    int right_phase = 0;
    int left_inc = 1;
    int right_inc = 3; /* higher pitch so we can distinguish left and right. */
    int i, j, k;
    int bufferCount;

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

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

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

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


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

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

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

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

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

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

        ++left_inc;
        ++right_inc;

        Pa_Sleep( 1000 );
    }

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

    Pa_Terminate();
    printf("Test finished.\n");
    
    return err;
error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return err;
}
Example #22
0
int main(void)
{
    PaStreamParameters outputParameters;
    PaStream *stream;
    PaError err;
    paTestData data;
    int i;

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

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

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

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

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

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

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

    Pa_Terminate();
    printf("Test finished.\n");
    
    return err;
error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return err;
}
Example #23
0
int sdr1000_open(void) {
    int arg;
    int status;
    int rc;
#ifdef PORTAUDIO
    PaStreamParameters inputParameters;
    PaStreamParameters outputParameters;
    const PaStreamInfo *info;
    int devices;
    int i;
    const PaDeviceInfo* deviceInfo;

fprintf(stderr,"sdr1000_open: portaudio\n");
#else
fprintf(stderr,"sdr1000_open: %s\n",sdr1000_get_device());
#endif


#ifdef PORTAUDIO
    rc=Pa_Initialize();
    if(rc!=paNoError) {
        fprintf(stderr,"Pa_Initialize failed: %s\n",Pa_GetErrorText(rc));
        exit(1);
    }

    devices=Pa_GetDeviceCount();
    if(devices<0) {
        fprintf(stderr,"Px_GetDeviceCount failed: %s\n",Pa_GetErrorText(devices));
    } else {
        fprintf(stderr,"default input=%d output=%d devices=%d\n",Pa_GetDefaultInputDevice(),Pa_GetDefaultOutputDevice(),devices);

        for(i=0;i<devices;i++) {
            deviceInfo=Pa_GetDeviceInfo(i);
            fprintf(stderr,"%d - %s\n",i,deviceInfo->name);
                fprintf(stderr,"maxInputChannels: %d\n",deviceInfo->maxInputChannels);
                fprintf(stderr,"maxOututChannels: %d\n",deviceInfo->maxOutputChannels);
                //fprintf(stderr,"defaultLowInputLatency: %f\n",deviceInfo->defaultLowInputLatency);
                //fprintf(stderr,"defaultLowOutputLatency: %f\n",deviceInfo->defaultLowOutputLatency);
                //fprintf(stderr,"defaultHighInputLatency: %f\n",deviceInfo->defaultHighInputLatency);
                //fprintf(stderr,"defaultHighOutputLatency: %f\n",deviceInfo->defaultHighOutputLatency);
                //fprintf(stderr,"defaultSampleRate: %f\n",deviceInfo->defaultSampleRate);
        }
    }

    inputParameters.device=atoi(sdr1000_get_input());
    inputParameters.channelCount=2;
    inputParameters.sampleFormat=paFloat32;
    inputParameters.suggestedLatency=Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
    inputParameters.hostApiSpecificStreamInfo=NULL;

    outputParameters.device=atoi(sdr1000_get_output());
    outputParameters.channelCount=2;
    outputParameters.sampleFormat=paFloat32;
    outputParameters.suggestedLatency=Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo=NULL;

fprintf(stderr,"input device=%d output device=%d\n",inputParameters.device,outputParameters.device);
    rc=Pa_OpenStream(&stream,&inputParameters,&outputParameters,(double)sdr1000_get_sample_rate(),(unsigned long)SAMPLES_PER_BUFFER,paNoFlag,NULL,NULL);
    if(rc!=paNoError) {
        fprintf(stderr,"Pa_OpenStream failed: %s\n",Pa_GetErrorText(rc));
        exit(1);
    }

    rc=Pa_StartStream(stream);
    if(rc!=paNoError) {
        fprintf(stderr,"Pa_StartStream failed: %s\n",Pa_GetErrorText(rc));
        exit(1);
    }

    info=Pa_GetStreamInfo(stream);
    if(info!=NULL) {
        fprintf(stderr,"stream.sampleRate=%f\n",info->sampleRate);
        fprintf(stderr,"stream.inputLatency=%f\n",info->inputLatency);
        fprintf(stderr,"stream.outputLatency=%f\n",info->outputLatency);
    } else {
        fprintf(stderr,"Pa_GetStreamInfo returned NULL\n");
    }

#else
    /* open sound device */
    fd = open(sdr1000_get_device(), O_RDWR);
    if (fd < 0) {
        perror("open of audio device failed");
        exit(1);
    }

    /* set sampling parameters */
    arg = SAMPLE_SIZE;      /* sample size */
    status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
    if (status == -1)
        perror("SOUND_PCM_WRITE_BITS ioctl failed");
    if (arg != SAMPLE_SIZE)
        perror("unable to set write sample size");

    status = ioctl(fd, SOUND_PCM_READ_BITS, &arg);
    if (status == -1)
        perror("SOUND_PCM_READ_BITS ioctl failed");
    if (arg != SAMPLE_SIZE)
        perror("unable to set read sample size");

    arg = CHANNELS;  /* mono or stereo */
    status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
    if (status == -1)
        perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
    if (arg != CHANNELS)
        perror("unable to set number of channels");

    arg = sdr1000_get_sample_rate();      /* sampling rate */
fprintf(stderr,"sample_rate: %d\n",arg);
    status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
    if (status == -1)
        perror("SOUND_PCM_WRITE_WRITE ioctl failed");

    arg = AFMT_S16_LE;       /* signed little endian */
    status = ioctl(fd, SOUND_PCM_SETFMT, &arg);
    if (status == -1)
        perror("SOUND_PCM_SETFMTS ioctl failed");

#endif

    return 0;
}
Example #24
0
static int PAOpenDevice( aout_instance_t *p_aout )
{
    aout_sys_t *p_sys = p_aout->output.p_sys;
    const PaDeviceInfo *p_pdi;
    PaError i_err;
    vlc_value_t val, text;
    int i;

    /* Initialize portaudio */
    i_err = Pa_Initialize();
    if( i_err != paNoError )
    {
        msg_Err( p_aout, "Pa_Initialize returned %d : %s",
                 i_err, Pa_GetErrorText( i_err ) );

        return VLC_EGENERIC;
    }

    p_sys->i_devices = Pa_GetDeviceCount();
    if( p_sys->i_devices < 0 )
    {
        i_err = p_sys->i_devices;
        msg_Err( p_aout, "Pa_GetDeviceCount returned %d : %s", i_err,
                 Pa_GetErrorText( i_err ) );

        goto error;
    }

    /* Display all devices info */
    msg_Dbg( p_aout, "number of devices = %d", p_sys->i_devices );
    for( i = 0; i < p_sys->i_devices; i++ )
    {
        p_pdi = Pa_GetDeviceInfo( i );
        msg_Dbg( p_aout, "------------------------------------- #%d", i );
        msg_Dbg( p_aout, "Name         = %s", p_pdi->name );
        msg_Dbg( p_aout, "Max Inputs   = %d, Max Outputs = %d",
                  p_pdi->maxInputChannels, p_pdi->maxOutputChannels );
    }
    msg_Dbg( p_aout, "-------------------------------------" );

    msg_Dbg( p_aout, "requested device is #%d", p_sys->i_device_id );
    if( p_sys->i_device_id >= p_sys->i_devices )
    {
        msg_Err( p_aout, "device %d does not exist", p_sys->i_device_id );
        goto error;
    }
    p_sys->deviceInfo = Pa_GetDeviceInfo( p_sys->i_device_id );

    if( p_sys->deviceInfo->maxOutputChannels < 1 )
    {
        msg_Err( p_aout, "no channel available" );
        goto error;
    }

    if( var_Type( p_aout, "audio-device" ) == 0 )
    {
        var_Create( p_aout, "audio-device", VLC_VAR_INTEGER|VLC_VAR_HASCHOICE);
        text.psz_string = _("Audio Device");
        var_Change( p_aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL );

        if( p_sys->deviceInfo->maxOutputChannels >= 1 )
        {
            val.i_int = AOUT_VAR_MONO;
            text.psz_string = _("Mono");
            var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE,
                        &val, &text );
            msg_Dbg( p_aout, "device supports 1 channel" );
        }
        if( p_sys->deviceInfo->maxOutputChannels >= 2 )
        {
            val.i_int = AOUT_VAR_STEREO;
            text.psz_string = _("Stereo");
            var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE,
                        &val, &text );
            var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT,
                        &val, NULL );
            var_Set( p_aout, "audio-device", val );
            msg_Dbg( p_aout, "device supports 2 channels" );
        }
        if( p_sys->deviceInfo->maxOutputChannels >= 4 )
        {
            val.i_int = AOUT_VAR_2F2R;
            text.psz_string = _("2 Front 2 Rear");
            var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE,
                        &val, &text );
            msg_Dbg( p_aout, "device supports 4 channels" );
        }
        if( p_sys->deviceInfo->maxOutputChannels >= 5 )
        {
            val.i_int = AOUT_VAR_3F2R;
            text.psz_string = _("3 Front 2 Rear");
            var_Change( p_aout, "audio-device",
                        VLC_VAR_ADDCHOICE, &val, &text );
            msg_Dbg( p_aout, "device supports 5 channels" );
        }
        if( p_sys->deviceInfo->maxOutputChannels >= 6 )
        {
            val.i_int = AOUT_VAR_5_1;
            text.psz_string = "5.1";
            var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE,
                        &val, &text );
            msg_Dbg( p_aout, "device supports 5.1 channels" );
        }

        var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL );
        var_SetBool( p_aout, "intf-change", true );
    }

    /* Audio format is paFloat32 (always supported by portaudio v19) */
    p_aout->output.output.i_format = VLC_CODEC_FL32;

    return VLC_SUCCESS;

 error:
    if( ( i_err = Pa_Terminate() ) != paNoError )
    {
        msg_Err( p_aout, "Pa_Terminate returned %d", i_err );
    }
    return VLC_EGENERIC;
}
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;
}
Example #26
0
File: jpa.c Project: rjeschke/jpa
JNIEXPORT jobject JNICALL Java_com_github_rjeschke_jpa_JPA_getDeviceInfo(JNIEnv *env, jclass clazz, jint index)
{
    const PaDeviceInfo *inf = Pa_GetDeviceInfo((PaDeviceIndex)index);
    return inf ? toPaDeviceInfo(env, inf) : 0;
}
Example #27
0
int main(void)
{
    int     i, numDevices, defaultDisplayed;
    const   PaDeviceInfo *deviceInfo;
    PaStreamParameters inputParameters, outputParameters;
    PaError err;

    
    Pa_Initialize();

    printf( "PortAudio version number = %d\nPortAudio version text = '%s'\n",
            Pa_GetVersion(), Pa_GetVersionText() );

            
    numDevices = Pa_GetDeviceCount();
    if( numDevices < 0 )
    {
        printf( "ERROR: Pa_CountDevices 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 */
        printf( "Name                        = %s\n", deviceInfo->name );
        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.3f\n", deviceInfo->defaultLowInputLatency  );
        printf( "Default low output latency  = %8.3f\n", deviceInfo->defaultLowOutputLatency  );
        printf( "Default high input latency  = %8.3f\n", deviceInfo->defaultHighInputLatency  );
        printf( "Default high output latency = %8.3f\n", deviceInfo->defaultHighOutputLatency  );

#ifdef WIN32
#ifndef PA_NO_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_NO_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 );
        }
    }

    Pa_Terminate();

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

error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return err;
}
Example #28
0
/*-------------------------------------------------------------------------------------------------*/
static int TestBadOpens( void )
{
    PaStream*           stream = NULL;
    PaError             result;
    PaQaData            myData;
    PaStreamParameters  ipp, opp;
    
    /* Setup data for synthesis thread. */
    myData.framesLeft = (unsigned long) (SAMPLE_RATE * 100); /* 100 seconds */
    myData.numChannels = 1;
    myData.mode = MODE_OUTPUT;

    /*----------------------------- No devices specified: */
    ipp.device                    = opp.device                    = paNoDevice;
    ipp.channelCount              = opp.channelCount              = 0; /* Also no channels. */
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
    /* Take the low latency of the default device for all subsequent tests. */
    ipp.suggestedLatency          = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice())->defaultLowInputLatency;
    opp.suggestedLatency          = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice())->defaultLowOutputLatency;
    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp,
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));

    /*----------------------------- No devices specified #2: */
    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, NULL,
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));

    /*----------------------------- Out of range input device specified: */
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
    ipp.channelCount = 0;           ipp.device = Pa_GetDeviceCount(); /* And no output device, and no channels. */
    opp.channelCount = 0;           opp.device = paNoDevice;
    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL,
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));

    /*----------------------------- Out of range output device specified: */
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
    ipp.channelCount = 0;           ipp.device = paNoDevice; /* And no input device, and no channels. */
    opp.channelCount = 0;           opp.device = Pa_GetDeviceCount();
    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));

    /*----------------------------- Zero input channels: */
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
    ipp.channelCount = 0;           ipp.device = Pa_GetDefaultInputDevice();
    opp.channelCount = 0;           opp.device = paNoDevice;    /* And no output device, and no output channels. */   
    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL,
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
                                     paClipOff, QaCallback, &myData )) == paInvalidChannelCount));

    /*----------------------------- Zero output channels: */
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
    ipp.channelCount = 0;           ipp.device = paNoDevice; /* And no input device, and no input channels. */
    opp.channelCount = 0;           opp.device = Pa_GetDefaultOutputDevice();
    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
                                     paClipOff, QaCallback, &myData )) == paInvalidChannelCount));

    /*----------------------------- Nonzero input and output channels but no output device: */
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
    ipp.channelCount = 2;           ipp.device = Pa_GetDefaultInputDevice();        /* Both stereo. */
    opp.channelCount = 2;           opp.device = paNoDevice;
    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp,
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));

    /*----------------------------- Nonzero input and output channels but no input device: */
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
    ipp.channelCount = 2;           ipp.device = paNoDevice;
    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp,
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));

    /*----------------------------- NULL stream pointer: */
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
    ipp.channelCount = 0;           ipp.device = paNoDevice;           /* Output is more likely than input. */
    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();    /* Only 2 output channels. */
    HOPEFOR(((result = Pa_OpenStream(NULL, &ipp, &opp,
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
                                     paClipOff, QaCallback, &myData )) == paBadStreamPtr));

    /*----------------------------- Low sample rate: */
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
    ipp.channelCount = 0;           ipp.device = paNoDevice;
    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
                                     1.0, FRAMES_PER_BUFFER, /* 1 cycle per second (1 Hz) is too low. */
                                     paClipOff, QaCallback, &myData )) == paInvalidSampleRate));

    /*----------------------------- High sample rate: */
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
    ipp.channelCount = 0;           ipp.device = paNoDevice;
    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
                                     10000000.0, FRAMES_PER_BUFFER, /* 10^6 cycles per second (10 MHz) is too high. */
                                     paClipOff, QaCallback, &myData )) == paInvalidSampleRate));

    /*----------------------------- NULL callback: */
    /* NULL callback is valid in V19 -- it means use blocking read/write stream
    
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
    ipp.channelCount = 0;           ipp.device = paNoDevice;
    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
                                     paClipOff,
                                     NULL,
                                     &myData )) == paNullCallback));
    */

    /*----------------------------- Bad flag: */
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
    ipp.channelCount = 0;           ipp.device = paNoDevice;
    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
                                     255,                      /* Is 8 maybe legal V19 API? */
                                     QaCallback, &myData )) == paInvalidFlag));

    /*----------------------------- using input device as output device: */
    if( FindInputOnlyDevice() != paNoDevice )
    {
        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
        ipp.channelCount = 0;           ipp.device = paNoDevice; /* And no input device, and no channels. */
        opp.channelCount = 2;           opp.device = FindInputOnlyDevice();
        HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
                                         SAMPLE_RATE, FRAMES_PER_BUFFER,
                                         paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
    }

    /*----------------------------- using output device as input device: */
    if( FindOutputOnlyDevice() != paNoDevice )
    {
        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
        ipp.channelCount = 2;           ipp.device = FindOutputOnlyDevice();
        opp.channelCount = 0;           opp.device = paNoDevice;  /* And no output device, and no channels. */
        HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL,
                                         SAMPLE_RATE, FRAMES_PER_BUFFER,
                                         paClipOff, QaCallback, &myData )) == paInvalidChannelCount));

    }

    if( stream != NULL ) Pa_CloseStream( stream );
    return result;
}
Example #29
0
	s32 Init()
	{
		started=false;
		stream=NULL;

		ReadSettings();

		PaError err = Pa_Initialize();
		if( err != paNoError )
		{
			fprintf(stderr,"* SPU2-X: PortAudio error: %s\n", Pa_GetErrorText( err ) );
			return -1;
		}
		started=true;

		int deviceIndex = -1;

		fprintf(stderr,"* SPU2-X: Enumerating PortAudio devices:");
		for(int i=0;i<Pa_GetDeviceCount();i++)
		{
			const PaDeviceInfo * info = Pa_GetDeviceInfo(i);

			const PaHostApiInfo * apiinfo = Pa_GetHostApiInfo(info->hostApi);

			fprintf(stderr," *** Device %d: '%s' (%s)", i, info->name, apiinfo->name);

			if(apiinfo->type == m_ApiId)
			{
				static wchar_t buffer [1000];
				mbstowcs(buffer,info->name,1000);
				buffer[999]=0;

				if(m_Device == buffer)
				{
					deviceIndex = i;
					fprintf(stderr," (selected)");
				}

			}
			fprintf(stderr,"\n");
		}

		if(deviceIndex<0 && m_ApiId>=0)
		{
			for(int i=0;i<Pa_GetHostApiCount();i++)
			{
				const PaHostApiInfo * apiinfo = Pa_GetHostApiInfo(i);
				if(apiinfo->type == m_ApiId)
				{
					deviceIndex = apiinfo->defaultOutputDevice;
				}
			}
		}

		if(deviceIndex>=0)
		{
			void* infoPtr = NULL;

#ifdef __WIN32__
			PaWasapiStreamInfo info = {
				sizeof(PaWasapiStreamInfo),
				paWASAPI,
				1,
				paWinWasapiExclusive
			};

			if((m_ApiId == paWASAPI) && m_WasapiExclusiveMode)
			{
				// Pass it the Exclusive mode enable flag
				infoPtr = &info;
			}
#endif

			PaStreamParameters outParams = {

			//	PaDeviceIndex device;
			//	int channelCount;
			//	PaSampleFormat sampleFormat;
			//	PaTime suggestedLatency;
			//	void *hostApiSpecificStreamInfo;
				deviceIndex,
				2,
				paInt32,
				0.2f,
				infoPtr
			};

			err = Pa_OpenStream(&stream,
				NULL, &outParams, SampleRate,
				SndOutPacketSize,
				paNoFlag,
#ifndef __LINUX__
				PaCallback,
#else
				PaLinuxCallback,
#endif
				NULL);
		}
		else
		{
			err = Pa_OpenDefaultStream( &stream,
				0, 2, paInt32, 48000,
				SndOutPacketSize,
#ifndef __LINUX__
				PaCallback,
#else
				PaLinuxCallback,
#endif
				NULL );
		}
		if( err != paNoError )
		{
			fprintf(stderr,"* SPU2-X: PortAudio error: %s\n", Pa_GetErrorText( err ) );
			Pa_Terminate();
			return -1;
		}

		err = Pa_StartStream( stream );
		if( err != paNoError )
		{
			fprintf(stderr,"* SPU2-X: PortAudio error: %s\n", Pa_GetErrorText( err ) );
			Pa_CloseStream(stream);
			stream=NULL;
			Pa_Terminate();
			return -1;
		}

		return 0;
	}
Example #30
0
void* RecieveClientThread(void* data) // recieve udp packets containing message/voice to the other client
{
	struct thread* new_data = data;	

	printf("you are recieving from %s IP address\n", new_data->IPaddr);
	PaStreamParameters outputParam;
	PaStream *stream = NULL;
	char *sampleBlock;
	int i, sockfd, numBytes;
	PaError error;
	struct sockaddr_in servaddr, cliaddr;

	sockfd = socket(AF_INET, SOCK_DGRAM, 0); // make udp socket
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = inet_addr(new_data->IPaddr);
	servaddr.sin_port = htons(new_data->Port);

	bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
	fflush(stdout); 
	numBytes = FRAMES_BUFFER * SAMPLE_SIZE * 2;
	sampleBlock = (char *) malloc(numBytes);
	if(sampleBlock == NULL){
		printf("Could not allocate record array.\n");
		exit(1);
	}
	CLEAR(sampleBlock);
 
	printf("Initializing the devices...\n"); 
	error = Pa_Initialize();
	if(error != paNoError) 
		goto errorState;
 
	outputParam.device = Pa_GetDefaultOutputDevice();
  	printf( "Output device # %d.\n", outputParam.device );
	outputParam.channelCount = 2;
	outputParam.sampleFormat = paFloat32;
	outputParam.suggestedLatency = Pa_GetDeviceInfo( outputParam.device )->defaultHighOutputLatency;
	outputParam.hostApiSpecificStreamInfo = NULL;	
 
	error = Pa_OpenStream(&stream, NULL, &outputParam, SAMPLE_RATE, FRAMES_BUFFER, paClipOff, NULL, NULL );
  
	if( error != paNoError ) 
		goto errorState;
 
	error = Pa_StartStream( stream );
	if( error != paNoError ) 
		goto errorState;

	printf("The client is talking to you\n"); 
	fflush(stdout);

	while(1){
		recvfrom(sockfd, sampleBlock, 4096, 0, NULL, NULL); // recieve packet containing voice data from the other client
		error = Pa_WriteStream(stream, sampleBlock, FRAMES_BUFFER);
 		if(error && UNDERFLOW) 
			goto exitState;
	}

	error = Pa_StopStream(stream);
	if(error != paNoError) 
		goto errorState;
 
	CLEAR(sampleBlock);
	free(sampleBlock);
	Pa_Terminate();
	return 0;
 
exitState:
	if(stream){
		Pa_AbortStream(stream);
		Pa_CloseStream(stream);
	}
	free(sampleBlock);
	Pa_Terminate();
	if(error & paOutputUnderflow)
		fprintf(stderr, "Output Underflow.\n");
	return (void*)-2;
 
errorState:
	if(stream) {
		Pa_AbortStream(stream);
		Pa_CloseStream(stream);
	}
	free(sampleBlock);
	Pa_Terminate();
	fprintf(stderr, "An error occured while using the portaudio stream\n");
	fprintf(stderr, "Error number: %d\n", error);
	fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(error));
	return (void*)-1;

}