Beispiel #1
0
static int PAOpenStream( aout_instance_t *p_aout )
{
    aout_sys_t *p_sys = p_aout->output.p_sys;
    const PaHostErrorInfo* paLastHostErrorInfo = Pa_GetLastHostErrorInfo();
    PaStreamParameters paStreamParameters;
    vlc_value_t val;
    int i_channels, i_err;
    uint32_t i_channel_mask;

    if( var_Get( p_aout, "audio-device", &val ) < 0 )
    {
        return VLC_EGENERIC;
    }

    if( val.i_int == AOUT_VAR_5_1 )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
              | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
              | AOUT_CHAN_LFE;
    }
    else if( val.i_int == AOUT_VAR_3F2R )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
            | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
    }
    else if( val.i_int == AOUT_VAR_2F2R )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
            | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
    }
    else if( val.i_int == AOUT_VAR_MONO )
    {
        p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER;
    }
    else
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
    }

    i_channels = aout_FormatNbChannels( &p_aout->output.output );
    msg_Dbg( p_aout, "nb_channels requested = %d", i_channels );
    i_channel_mask = p_aout->output.output.i_physical_channels;

    /* Calculate the frame size in bytes */
    p_sys->i_sample_size = 4 * i_channels;
    p_aout->output.i_nb_samples = FRAME_SIZE;
    aout_FormatPrepare( &p_aout->output.output );
    aout_VolumeSoftInit( p_aout );

    /* Check for channel reordering */
    p_aout->output.p_sys->i_channel_mask = i_channel_mask;
    p_aout->output.p_sys->i_bits_per_sample = 32; /* forced to paFloat32 */
    p_aout->output.p_sys->i_channels = i_channels;

    p_aout->output.p_sys->b_chan_reorder =
        aout_CheckChannelReorder( NULL, pi_channels_out,
                                  i_channel_mask, i_channels,
                                  p_aout->output.p_sys->pi_chan_table );

    if( p_aout->output.p_sys->b_chan_reorder )
    {
        msg_Dbg( p_aout, "channel reordering needed" );
    }

    paStreamParameters.device = p_sys->i_device_id;
    paStreamParameters.channelCount = i_channels;
    paStreamParameters.sampleFormat = paFloat32;
    paStreamParameters.suggestedLatency =
        p_sys->deviceInfo->defaultLowOutputLatency;
    paStreamParameters.hostApiSpecificStreamInfo = NULL;

    i_err = Pa_OpenStream( &p_sys->p_stream, NULL /* no input */,
                &paStreamParameters, (double)p_aout->output.output.i_rate,
                FRAME_SIZE, paClipOff, paCallback, p_sys );
    if( i_err != paNoError )
    {
        msg_Err( p_aout, "Pa_OpenStream returns %d : %s", i_err,
                 Pa_GetErrorText( i_err ) );
        if( i_err == paUnanticipatedHostError )
        {
            msg_Err( p_aout, "type %d code %ld : %s",
                     paLastHostErrorInfo->hostApiType,
                     paLastHostErrorInfo->errorCode,
                     paLastHostErrorInfo->errorText );
        }
        p_sys->p_stream = 0;
        return VLC_EGENERIC;
    }

    i_err = Pa_StartStream( p_sys->p_stream );
    if( i_err != paNoError )
    {
        msg_Err( p_aout, "Pa_StartStream() failed" );
        Pa_CloseStream( p_sys->p_stream );
        return VLC_EGENERIC;
    }

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


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

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

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

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

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

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

    safeSineCount = data.sineCount;

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

    stressedUnderflowCount = data.outputUnderflowCount;

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

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

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

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

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

    return err;
error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return err;
}
int main(void)
{
    PaError    err;
    paTestData data = { 0 };
    long       totalFrames;
    long       numBytes;
    long       i;
    printf("patest_record.c\n"); fflush(stdout);

/* Set up test data structure and sample array. */
    data.frameIndex = 0;
    data.samplesPerFrame = 2;
    data.maxFrameIndex = totalFrames = NUM_SECONDS*SAMPLE_RATE;

    printf("totalFrames = %d\n", totalFrames ); fflush(stdout);
    data.numSamples = totalFrames * data.samplesPerFrame;

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

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

/* Record and playback multiple times. */
    for( i=0; i<2; i++ )
    {
        err = TestRecording( &data );
        if( err != paNoError ) goto error;

        err = TestPlayback( &data );
        if( err != paNoError ) goto error;
    }

/* Clean up. */
    err = Pa_CloseStream( data.inputStream );
    if( err != paNoError ) goto error;

    err = Pa_CloseStream( data.outputStream );
    if( err != paNoError ) goto error;

    if( err != paNoError ) goto error;

    free( data.recordedSamples );
    Pa_Terminate();
    
    printf("Test complete.\n"); fflush(stdout);
    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 ) );
    if( err == paHostError )
    {
        fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() );
    }
    return -1;
}
Beispiel #4
0
PaError OpenStream(PaStream **mStream, PaDeviceIndex Device, double Rate, void* Sound, double &dLatency, PaStreamCallback Callback)
{
	PaStreamParameters outputParams;

	outputParams.device = Device;
	outputParams.channelCount = 2;
	outputParams.sampleFormat = paFloat32;

	if (!Configuration::GetConfigf("UseHighLatency", "Audio"))
		outputParams.suggestedLatency = Pa_GetDeviceInfo(outputParams.device)->defaultLowOutputLatency;
	else
		outputParams.suggestedLatency = Pa_GetDeviceInfo(outputParams.device)->defaultHighOutputLatency;


#ifndef WIN32

	outputParams.hostApiSpecificStreamInfo = NULL;

#else
	PaWasapiStreamInfo StreamInfo;
	PaWinDirectSoundStreamInfo DSStreamInfo;
	if (UseWasapi)
	{
		outputParams.hostApiSpecificStreamInfo = &StreamInfo;
		StreamInfo.hostApiType = paWASAPI;
		StreamInfo.size = sizeof(PaWasapiStreamInfo);
		StreamInfo.version = 1;
		if (!Configuration::GetConfigf("WasapiDontUseExclusiveMode", "Audio"))
		{
			StreamInfo.threadPriority = eThreadPriorityProAudio;
			StreamInfo.flags = paWinWasapiExclusive;
		}
		else
		{
			StreamInfo.threadPriority = eThreadPriorityAudio;
			StreamInfo.flags = 0;
		}

		StreamInfo.hostProcessorOutput = NULL;
		StreamInfo.hostProcessorInput = NULL;
	}
	else
	{
		outputParams.hostApiSpecificStreamInfo = &DSStreamInfo;

		DSStreamInfo.size = sizeof(PaWinDirectSoundStreamInfo);
		DSStreamInfo.hostApiType = paDirectSound;
		DSStreamInfo.version = 2;
		DSStreamInfo.flags = 0;
	}
#endif

	dLatency = outputParams.suggestedLatency;

	// fire up portaudio
	PaError Err = Pa_OpenStream(mStream, NULL, &outputParams, Rate, 0, paClipOff, Callback, (void*)Sound);

	if (Err)
	{
		Log::Logf("%ls\n", Utility::Widen(Pa_GetErrorText(Err)).c_str());
		Log::Logf("Device Selected %d\n", Device);
	}
#ifdef LINUX
	else
	{
		Log::Logf("Audio: Enabling real time scheduling\n");
		PaAlsa_EnableRealtimeScheduling( mStream, true );
	}	
#endif

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

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

// initial state after recording
// all future state changes from within state machine
    if(buttonHold == FALSE)
    {
        // ******************************************
		doState(S_REWIND_10, (void*) NULL);
		// ******************************************	   
    }
    else
    {
        // ******************************************
		doState(S_REWIND_PLAYBACK, (void*) NULL);	
		// ******************************************    
    }
// |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||	
// |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||	
    while (1)
    {
        // advance state in the state machine
        // ******************************************
		doState(currentSTATE, (void*) NULL);    
		// ******************************************	
		Pa_Sleep(100);
		if(terminate != FALSE)
		 goto done;
		 
    }
// |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||	
// |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
	
	
done:
	Pa_Terminate();
	if( data.recordedSamples )       // Sure it is NULL or valid. 
		free( data.recordedSamples );
	if( err != paNoError )
	{
		fprintf( stderr, 
				"An error occured while using the portaudio stream\n" );
		fprintf( stderr, "Error number: %d\n", err );
		fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
		
		fatalError();
		
		err = 1;          // Always return 0 or 1, but no other return codes. 
	}
	return err;
}
Beispiel #6
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;
}
Beispiel #7
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;
	}
Beispiel #8
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;
}
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;
}
Beispiel #10
0
static ALCenum pa_open_capture(ALCdevice *device, const ALCchar *deviceName)
{
    PaStreamParameters inParams;
    ALuint frame_size;
    pa_data *data;
    PaError err;

    if(!deviceName)
        deviceName = pa_device;
    else if(strcmp(deviceName, pa_device) != 0)
        return ALC_INVALID_VALUE;

    data = (pa_data*)calloc(1, sizeof(pa_data));
    if(data == NULL)
        return ALC_OUT_OF_MEMORY;

    frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
    data->ring = CreateRingBuffer(frame_size, device->UpdateSize*device->NumUpdates);
    if(data->ring == NULL)
        goto error;

    inParams.device = -1;
    if(!ConfigValueInt("port", "capture", &inParams.device) || inParams.device < 0)
        inParams.device = Pa_GetDefaultOutputDevice();
    inParams.suggestedLatency = 0.0f;
    inParams.hostApiSpecificStreamInfo = NULL;

    switch(device->FmtType)
    {
        case DevFmtByte:
            inParams.sampleFormat = paInt8;
            break;
        case DevFmtUByte:
            inParams.sampleFormat = paUInt8;
            break;
        case DevFmtShort:
            inParams.sampleFormat = paInt16;
            break;
        case DevFmtFloat:
            inParams.sampleFormat = paFloat32;
            break;
        case DevFmtUShort:
            ERR("Unsigned short samples not supported\n");
            goto error;
    }
    inParams.channelCount = ChannelsFromDevFmt(device->FmtChans);

    err = Pa_OpenStream(&data->stream, &inParams, NULL, device->Frequency,
                        paFramesPerBufferUnspecified, paNoFlag, pa_capture_cb, device);
    if(err != paNoError)
    {
        ERR("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err));
        goto error;
    }

    device->szDeviceName = strdup(deviceName);

    device->ExtraData = data;
    return ALC_NO_ERROR;

error:
    DestroyRingBuffer(data->ring);
    free(data);
    return ALC_INVALID_VALUE;
}
Beispiel #11
0
int main(void)
{
    PortAudioStream *stream;
    PaError    err;
    paTestData data;
    int        i;
    int        totalFrames;
    int        numSamples;
    int        numBytes;
    SAMPLE     max, average, val;
    printf("patest_record.c\n"); fflush(stdout);

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

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

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

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

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

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

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

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

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

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

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

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

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

    Pa_Terminate();
    return 0;

error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return -1;
}
Beispiel #12
0
static ALCenum pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
    PaStreamParameters outParams;
    pa_data *data;
    PaError err;

    if(!deviceName)
        deviceName = pa_device;
    else if(strcmp(deviceName, pa_device) != 0)
        return ALC_INVALID_VALUE;

    data = (pa_data*)calloc(1, sizeof(pa_data));
    data->update_size = device->UpdateSize;

    device->ExtraData = data;

    outParams.device = -1;
    if(!ConfigValueInt("port", "device", &outParams.device) || outParams.device < 0)
        outParams.device = Pa_GetDefaultOutputDevice();
    outParams.suggestedLatency = (device->UpdateSize*device->NumUpdates) /
                                 (float)device->Frequency;
    outParams.hostApiSpecificStreamInfo = NULL;

    switch(device->FmtType)
    {
        case DevFmtByte:
            outParams.sampleFormat = paInt8;
            break;
        case DevFmtUByte:
            outParams.sampleFormat = paUInt8;
            break;
        case DevFmtUShort:
            device->FmtType = DevFmtShort;
            /* fall-through */
        case DevFmtShort:
            outParams.sampleFormat = paInt16;
            break;
        case DevFmtFloat:
            outParams.sampleFormat = paFloat32;
            break;
    }
    outParams.channelCount = ((device->FmtChans == DevFmtMono) ? 1 : 2);

    SetDefaultChannelOrder(device);

    err = Pa_OpenStream(&data->stream, NULL, &outParams, device->Frequency,
                        device->UpdateSize, paNoFlag, pa_callback, device);
    if(err != paNoError)
    {
        ERR("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err));
        device->ExtraData = NULL;
        free(data);
        return ALC_INVALID_VALUE;
    }

    device->szDeviceName = strdup(deviceName);

    if((ALuint)outParams.channelCount != ChannelsFromDevFmt(device->FmtChans))
    {
        if(outParams.channelCount != 1 && outParams.channelCount != 2)
        {
            ERR("Unhandled channel count: %u\n", outParams.channelCount);
            Pa_CloseStream(data->stream);
            device->ExtraData = NULL;
            free(data);
            return ALC_INVALID_VALUE;
        }
        if((device->Flags&DEVICE_CHANNELS_REQUEST))
            ERR("Failed to set %s, got %u channels instead\n", DevFmtChannelsString(device->FmtChans), outParams.channelCount);
        device->Flags &= ~DEVICE_CHANNELS_REQUEST;
        device->FmtChans = ((outParams.channelCount==1) ? DevFmtMono : DevFmtStereo);
    }

    return ALC_NO_ERROR;
}
Beispiel #13
0
JNIEXPORT jstring JNICALL Java_com_github_rjeschke_jpa_JPA_paGetErrorText(JNIEnv *env, jclass clazz, jint error)
{
    return makeString(env, (char*)Pa_GetErrorText((PaError)error));
}
Beispiel #14
0
/*****************************************************************************
 * PORTAUDIOThread: all interactions with libportaudio.a are handled
 * in this single thread.  Otherwise libportaudio.a is _not_ happy :-(
 *****************************************************************************/
static void* PORTAUDIOThread( vlc_object_t *p_this )
{
    pa_thread_t *pa_thread = (pa_thread_t*)p_this;
    aout_instance_t *p_aout;
    aout_sys_t *p_sys;
    int i_err;
    int canc = vlc_savecancel ();

    while( vlc_object_alive (pa_thread) )
    {
        /* Wait for start of stream */
        vlc_mutex_lock( &pa_thread->lock_signal );
        if( !pa_thread->b_signal )
            vlc_cond_wait( &pa_thread->signal, &pa_thread->lock_signal );
        vlc_mutex_unlock( &pa_thread->lock_signal );
        pa_thread->b_signal = false;

        p_aout = pa_thread->p_aout;
        p_sys = p_aout->output.p_sys;

        if( PAOpenDevice( p_aout ) != VLC_SUCCESS )
        {
            msg_Err( p_aout, "cannot open portaudio device" );
            pa_thread->b_error = true;
        }

        if( !pa_thread->b_error && PAOpenStream( p_aout ) != VLC_SUCCESS )
        {
            msg_Err( p_aout, "cannot open portaudio device" );
            pa_thread->b_error = true;

            i_err = Pa_Terminate();
            if( i_err != paNoError )
            {
                msg_Err( p_aout, "Pa_Terminate: %d (%s)", i_err,
                         Pa_GetErrorText( i_err ) );
            }
        }

        /* Tell the main thread that we are ready */
        vlc_mutex_lock( &pa_thread->lock_wait );
        pa_thread->b_wait = true;
        vlc_cond_signal( &pa_thread->wait );
        vlc_mutex_unlock( &pa_thread->lock_wait );

        /* Wait for end of stream */
        vlc_mutex_lock( &pa_thread->lock_signal );
        if( !pa_thread->b_signal )
            vlc_cond_wait( &pa_thread->signal, &pa_thread->lock_signal );
        vlc_mutex_unlock( &pa_thread->lock_signal );
        pa_thread->b_signal = false;

        if( pa_thread->b_error ) continue;

        i_err = Pa_StopStream( p_sys->p_stream );
        if( i_err != paNoError )
        {
            msg_Err( p_aout, "Pa_StopStream: %d (%s)", i_err,
                     Pa_GetErrorText( i_err ) );
        }
        i_err = Pa_CloseStream( p_sys->p_stream );
        if( i_err != paNoError )
        {
            msg_Err( p_aout, "Pa_CloseStream: %d (%s)", i_err,
                     Pa_GetErrorText( i_err ) );
        }
        i_err = Pa_Terminate();
        if( i_err != paNoError )
        {
            msg_Err( p_aout, "Pa_Terminate: %d (%s)", i_err,
                     Pa_GetErrorText( i_err ) );
        }

        /* Tell the main thread that we are ready */
        vlc_mutex_lock( &pa_thread->lock_wait );
        pa_thread->b_wait = true;
        vlc_cond_signal( &pa_thread->wait );
        vlc_mutex_unlock( &pa_thread->lock_wait );
    }
    vlc_restorecancel (canc);
    return NULL;
}
Beispiel #15
0
int main(int argc, char *argv[])
{
    QString         cfg_file;
    std::string     conf;
    std::string     style;
    bool            clierr = false;
    bool            edit_conf = false;
    int             return_code;

    QApplication app(argc, argv);
    QCoreApplication::setOrganizationName(GQRX_ORG_NAME);
    QCoreApplication::setOrganizationDomain(GQRX_ORG_DOMAIN);
    QCoreApplication::setApplicationName(GQRX_APP_NAME);
    QCoreApplication::setApplicationVersion(VERSION);

    // setup controlport via environment variables
    // see http://lists.gnu.org/archive/html/discuss-gnuradio/2013-05/msg00270.html
    // Note: tried using gr::prefs().save() but that doesn't have effect until the next time
    if (qputenv("GR_CONF_CONTROLPORT_ON", "False"))
        qDebug() << "Controlport disabled";
    else
        qDebug() << "Failed to disable controlport";

    // setup the program options
    po::options_description desc("Command line options");
    desc.add_options()
            ("help,h", "This help message")
            ("style,s", po::value<std::string>(&style), "Use the give style (fusion, windows)")
            ("list,l", "List existing configurations")
            ("conf,c", po::value<std::string>(&conf), "Start with this config file")
            ("edit,e", "Edit the config file before using it")
            ("reset,r", "Reset configuration file")
    ;

    po::variables_map vm;
    try
    {
        po::store(po::parse_command_line(argc, argv, desc), vm);
    }
    catch(const boost::program_options::invalid_command_line_syntax& ex)
    {
        /* happens if e.g. -c without file name */
        clierr = true;
    }
    catch(const boost::program_options::unknown_option& ex)
    {
        /* happens if e.g. -c without file name */
        clierr = true;
    }

    po::notify(vm);

    // print the help message
    if (vm.count("help") || clierr)
    {
        std::cout << "Gqrx software defined radio receiver " << VERSION << std::endl;
        std::cout << desc << std::endl;
        return 1;
    }

    if (vm.count("style"))
        QApplication::setStyle(QString::fromStdString(style));

    if (vm.count("list"))
    {
        list_conf();
        return 0;
    }

    // check whether audio backend is functional
#ifdef WITH_PORTAUDIO
    PaError     err = Pa_Initialize();
    if (err != paNoError)
    {
        QString message = QString("Portaudio error: %1").arg(Pa_GetErrorText(err));
        qCritical() << message;
        QMessageBox::critical(0, "Audio Error", message,
                              QMessageBox::Abort, QMessageBox::NoButton);
        return 1;
    }
#endif

#ifdef WITH_PULSEAUDIO
    int         error = 0;
    pa_simple  *test_sink;
    pa_sample_spec ss;

    ss.format = PA_SAMPLE_FLOAT32LE;
    ss.rate = 48000;
    ss.channels = 2;
    test_sink =  pa_simple_new(NULL, "Gqrx Test", PA_STREAM_PLAYBACK, NULL,
                               "Test stream", &ss, NULL, NULL, &error);
    if (!test_sink)
    {
        QString message = QString("Pulseaudio error: %1").arg(pa_strerror(error));
        qCritical() << message;
        QMessageBox::critical(0, "Audio Error", message,
                              QMessageBox::Abort, QMessageBox::NoButton);
        return 1;
    }
    pa_simple_free(test_sink);
#endif


    if (!conf.empty())
    {
        cfg_file = QString::fromStdString(conf);
        qDebug() << "User specified config file:" << cfg_file;
    }
    else
    {
        cfg_file = "default.conf";
        qDebug() << "No user supplied config file. Using" << cfg_file;
    }

    if (vm.count("reset"))
        reset_conf(cfg_file);
    else if (vm.count("edit"))
        edit_conf = true;

    // Mainwindow will check whether we have a configuration
    // and open the config dialog if there is none or the specified
    // file does not exist.
    MainWindow w(cfg_file, edit_conf);

    if (w.configOk)
    {
        w.show();
        return_code = app.exec();
    }
    else
    {
        return_code = 1;
    }

#ifdef WITH_PORTAUDIO
    Pa_Terminate();
#endif

    return  return_code;
}
Beispiel #16
0
Datei: twatc.c Projekt: vrld/twat
int main(int argc, char** argv)
{
    struct sockaddr_in server;
    int chan;
    PaStream *stream;
    PaStreamParameters output_parameters;
    PaError err;

    voice = NULL;
    srand(time(NULL));
    atexit(at_exit);
    set_signal_handlers();
    init();

    if (argc != 4)
        return usage(argv[0]);

    set_output_parameters(&output_parameters, atoi(argv[3]));

    /* connect to server */
    sock = udp_create_socket(&server, sizeof(server), inet_addr(argv[1]), atoi(argv[2]), WAIT_FOR_RECEIVE);
    if (sock < 0)
        error_and_exit("Cannot create socket", __FILE__, __LINE__);
    
    /* create speech thingies */
    si.w          = malloc(sizeof(cst_wave) * si.channel_count);
    si.pos        = malloc(sizeof(long) * si.channel_count);
    si.done       = malloc(sizeof(int) * si.channel_count);
    si.cur_delay  = malloc(sizeof(double) * si.channel_count);
    si.rate_delay = malloc(sizeof(double) * si.channel_count);
    for (chan = 0; chan < si.channel_count; ++chan) {
        si.w[chan] = NULL;
        next_tweet(&server, chan);
    }

    err = Pa_OpenStream(&stream, NULL, &output_parameters,
            44100., 0, paNoFlag, say_text_callback, &si);
    if (paNoError != err) {
        fprintf(stderr, "Cannot open stream: %s\n", Pa_GetErrorText(err));
        exit(-1);
    }
/*        Pa_OpenDefaultStream(&stream, 0, si.channel_count, paInt16,
            si.w->sample_rate, 0, say_text_callback, &si); */
    err = Pa_StartStream(stream);
    if (paNoError != err) {
        fprintf(stderr, "Cannot start stream: %s\n", Pa_GetErrorText(err));
        exit(-1);
    }
    
    while (1)
    {
        usleep(100);
        for (chan = 0; chan < si.channel_count; ++chan) 
        {
            if (si.done[chan])
                next_tweet(&server, chan);
        }
    }
    //Pa_StopStream(stream);

    return 0;
}
Beispiel #17
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;
}
Beispiel #18
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;
}
Beispiel #19
0
/*
 * pjmedia_strerror()
 */
PJ_DEF(pj_str_t) pjmedia_strerror( pj_status_t statcode, 
				   char *buf, pj_size_t bufsize )
{
    pj_str_t errstr;

#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)

    /* See if the error comes from PortAudio. */
#if PJMEDIA_SOUND_IMPLEMENTATION==PJMEDIA_SOUND_PORTAUDIO_SOUND
    if (statcode >= PJMEDIA_ERRNO_FROM_PORTAUDIO(paNotInitialized) &&
	statcode <  PJMEDIA_ERRNO_FROM_PORTAUDIO(paNotInitialized + 10000))
    {

	int pa_err = statcode - PJMEDIA_ERRNO_FROM_PORTAUDIO(0);
	pj_str_t msg;
	
	msg.ptr = (char*)Pa_GetErrorText(pa_err);
	msg.slen = pj_ansi_strlen(msg.ptr);

	errstr.ptr = buf;
	pj_strncpy_with_null(&errstr, &msg, bufsize);
	return errstr;

    } else 
#endif	/* PJMEDIA_SOUND_IMPLEMENTATION */
    if (statcode >= PJMEDIA_ERRNO_START && 
	       statcode < PJMEDIA_ERRNO_START + PJ_ERRNO_SPACE_SIZE)
    {
	/* Find the error in the table.
	 * Use binary search!
	 */
	int first = 0;
	int n = PJ_ARRAY_SIZE(err_str);

	while (n > 0) {
	    int half = n/2;
	    int mid = first + half;

	    if (err_str[mid].code < statcode) {
		first = mid+1;
		n -= (half+1);
	    } else if (err_str[mid].code > statcode) {
		n = half;
	    } else {
		first = mid;
		break;
	    }
	}


	if (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {
	    pj_str_t msg;
	    
	    msg.ptr = (char*)err_str[first].msg;
	    msg.slen = pj_ansi_strlen(err_str[first].msg);

	    errstr.ptr = buf;
	    pj_strncpy_with_null(&errstr, &msg, bufsize);
	    return errstr;

	} 
    }

#endif	/* PJ_HAS_ERROR_STRING */

    /* Error not found. */
    errstr.ptr = buf;
    errstr.slen = pj_ansi_snprintf(buf, bufsize, 
				   "Unknown pjmedia error %d",
				   statcode);

    return errstr;
}
Beispiel #20
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;
}
Beispiel #21
0
int main(void)
{
    PaStreamParameters  inputParameters,
                        outputParameters;
    PaStream*           stream;
    PaError             err = paNoError;
    paTestData          data;
    int                 i;
    int                 totalFrames;
    int                 numSamples;
    int                 numBytes;
    SAMPLE              max, val;
    double              average;

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

    data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
    data.frameIndex = 0;
    numSamples = totalFrames * NUM_CHANNELS;
    numBytes = numSamples * sizeof(SAMPLE);
    data.recordedSamples = (SAMPLE *) malloc( numBytes ); /* From now on, recordedSamples is initialised. */
    if( data.recordedSamples == NULL )
    {
        printf("Could not allocate record array.\n");
        goto done;
    }
    for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0;

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

    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
    inputParameters.channelCount = 2;                    /* stereo input */
    inputParameters.sampleFormat = PA_SAMPLE_TYPE;
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
    inputParameters.hostApiSpecificStreamInfo = NULL;

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

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

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

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

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

    average = average / (double)numSamples;

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

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

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

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

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

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

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

done:
    Pa_Terminate();
    if( data.recordedSamples )       /* Sure it is NULL or valid. */
        free( data.recordedSamples );
    if( err != paNoError )
    {
        fprintf( stderr, "An error occured while using the portaudio stream\n" );
        fprintf( stderr, "Error number: %d\n", err );
        fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
        err = 1;          /* Always return 0 or 1, but no other return codes. */
    }
    return err;
}
Beispiel #22
0
int main(void)
{
    PortAudioStream *stream;
    PaError err;
    int numStress;
    paTestData data = {0};
    double load;
    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
        SAMPLE_RATE, FRAMES_PER_BUFFER, MAX_LOAD );

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

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

        load = Pa_GetCPULoad( stream );
        printf("numSines = %d, CPU load = %f\n", data.numSines, load );
    }
    while( load < 0.5 );
    
    /* Calculate target stress value then ramp up to that level*/
    numStress = (int) (2.0 * data.numSines * MAX_LOAD );
    for( ; data.numSines < numStress; data.numSines++ )
    {
        Pa_Sleep( 200 );
        load = Pa_GetCPULoad( stream );
        printf("STRESSING: numSines = %d, CPU load = %f\n", data.numSines, load );
    }
    
    printf("Suffer for 5 seconds.\n");
    Pa_Sleep( 5000 );
    
    printf("Stop stream.\n");
    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;
    
    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;
    
    Pa_Terminate();
    printf("Test finished.\n");
    return err;
error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return err;
}
Beispiel #23
0
int main(void)
{
    PaStreamParameters inputParameters, outputParameters;
    PaStream *stream;
    PaError err;
    
    err = Pa_Initialize();
    if( err != paNoError ) goto error;
    
    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
    if (inputParameters.device == paNoDevice) {
        fprintf(stderr,"Error: No default input device.\n");
        goto error;
    }
    inputParameters.channelCount = 2;       /* stereo input */
    inputParameters.sampleFormat = PA_SAMPLE_TYPE;
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
    inputParameters.hostApiSpecificStreamInfo = NULL;
    
    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
    if (outputParameters.device == paNoDevice) {
        fprintf(stderr,"Error: No default output device.\n");
        goto error;
    }
    outputParameters.channelCount = 2;       /* stereo output */
    outputParameters.sampleFormat = PA_SAMPLE_TYPE;
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;
    
    /* Instantiate FFT */
    fft_new(&fft, FRAMES_PER_BUFFER);
    spectrum = malloc(FRAMES_PER_BUFFER * sizeof(double));
    
    /* Instantiate Spectral Features */
    spectralFeatures_new(&features, FRAMES_PER_BUFFER);
    
    err = Pa_OpenStream(
                        &stream,
                        &inputParameters,
                        &outputParameters,
                        SAMPLE_RATE,
                        FRAMES_PER_BUFFER,
                        0, /* paClipOff, */  /* we won't output out of range samples so don't bother clipping them */
                        onsetCallback,
                        NULL );
    if( err != paNoError ) goto error;
    
    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;
    
    printf("Hit ENTER to stop program.\n");
    getchar();
    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;
    
    printf("Finished. gNumNoInputs = %d\n", gNumNoInputs );
    Pa_Terminate();
    return 0;
    
error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return -1;
}
Beispiel #24
0
/* -- 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;
}
int main(void)
{
    PaStreamParameters inputParameters, outputParameters;
    PaStream *stream;
    PaError err;
    SAMPLE *recordedSamples;
    int i;
    int totalFrames;
    int numSamples;
    int numBytes;
    SAMPLE max, average, val;
    
    
    printf("patest_read_record.c\n"); fflush(stdout);

    totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
    numSamples = totalFrames * NUM_CHANNELS;

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

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

    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
    if (inputParameters.device == paNoDevice) {
      fprintf(stderr,"Error: No default input device.\n");
      goto error;
    }
    inputParameters.channelCount = NUM_CHANNELS;
    inputParameters.sampleFormat = PA_SAMPLE_TYPE;
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
    inputParameters.hostApiSpecificStreamInfo = NULL;

    /* Record some audio. -------------------------------------------- */
    err = Pa_OpenStream(
              &stream,
              &inputParameters,
              NULL,                  /* &outputParameters, */
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              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("Now recording!!\n"); fflush(stdout);

    err = Pa_ReadStream( stream, recordedSamples, totalFrames );
    if( err != paNoError ) goto error;
    
    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;

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

    average = average / numSamples;

    printf("Sample max amplitude = "PRINTF_S_FORMAT"\n", max );
    printf("Sample average = "PRINTF_S_FORMAT"\n", average );
/*  Was as below. Better choose at compile time because this
    keeps generating compiler-warnings:
    if( PA_SAMPLE_TYPE == paFloat32 )
    {
        printf("sample max amplitude = %f\n", max );
        printf("sample average = %f\n", average );
    }
    else
    {
        printf("sample max amplitude = %d\n", max );
        printf("sample average = %d\n", average );
    }
*/
    /* Write recorded data to a file. */
#if 0
    {
        FILE  *fid;
        fid = fopen("recorded.raw", "wb");
        if( fid == NULL )
        {
            printf("Could not open file.");
        }
        else
        {
            fwrite( recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
            fclose( fid );
            printf("Wrote data to 'recorded.raw'\n");
        }
    }
#endif

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

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

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

        err = Pa_WriteStream( stream, recordedSamples, totalFrames );
        if( err != paNoError ) goto error;

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

    Pa_Terminate();
    return 0;

error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return -1;
}
Beispiel #26
0
int main(void)
{
    PortAudioStream *stream;
    PaError err;
    paTestData data;
    int i;
    int totalSamps;
#if TEST_UNSIGNED
    printf("PortAudio Test: output UNsigned 8 bit sine wave.\n");
#else
    printf("PortAudio Test: output signed 8 bit sine wave.\n");
#endif
    /* initialise sinusoidal wavetable */
    for( i=0; i<TABLE_SIZE; i++ )
    {
        data.sine[i] = (char) (127.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
#if TEST_UNSIGNED
        data.sine[i] += (unsigned char) 0x80;
#endif

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

    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;
    printf("Waiting for sound to finish.\n");
    while( Pa_StreamActive( stream ) ) Pa_Sleep(10);
    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;
    Pa_Terminate();
    printf("Test finished.\n");
    return err;
error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return err;
}
Beispiel #27
0
int main(void)
{
  //    PortAudioStream *stream;
  //    int inputDevice = Pa_GetDefaultInputDeviceID();
  //    int        i,numDevices;
  //    PaDeviceInfo pdi;


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

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

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

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

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


  audio_rc_open();

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


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

  audio_rc_close();




  return 0;

error:
  Pa_Terminate();
  fprintf( stderr, "An error occured while using the portaudio stream\n" );
  fprintf( stderr, "Error number: %d\n", err );
  fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );

  return -1;
}
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;
}
Beispiel #29
0
static void pa_checkerror(lua_State *L, PaError err)
{
  if(err != paNoError)
    luaL_error(L, "An error occured while using the portaudio stream: %s", Pa_GetErrorText(err));
}
Beispiel #30
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;
}