void _pa_open(void) { PaStreamParameters outputParameters; PaError err = paNoError; int device_id; if (pa.stream) { if ((err = Pa_CloseStream(pa.stream)) != paNoError) { LOG_WARN("error closing stream: %s", Pa_GetErrorText(err)); } } if (output.state == OUTPUT_OFF) { // we get called when transitioning to OUTPUT_OFF to create the probe thread // set err to avoid opening device and logging messages err = 1; } else if ((device_id = pa_device_id(output.device)) == -1) { LOG_INFO("device %s not found", output.device); err = 1; } else { outputParameters.device = device_id; outputParameters.channelCount = 2; outputParameters.sampleFormat = paInt32; outputParameters.suggestedLatency = output.latency ? (double)output.latency/(double)1000 : Pa_GetDeviceInfo(outputParameters.device)->defaultHighOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; #if OSX // enable pro mode which aims to avoid resampling if possible // see http://code.google.com/p/squeezelite/issues/detail?id=11 & http://code.google.com/p/squeezelite/issues/detail?id=37 // command line controls osx_playnice which is -1 if not specified, 0 or 1 - choose playnice if -1 or 1 PaMacCoreStreamInfo macInfo; unsigned long streamInfoFlags; if (output.osx_playnice) { LOG_INFO("opening device in PlayNice mode"); streamInfoFlags = paMacCorePlayNice; } else { LOG_INFO("opening device in Pro mode"); streamInfoFlags = paMacCorePro; } PaMacCore_SetupStreamInfo(&macInfo, streamInfoFlags); outputParameters.hostApiSpecificStreamInfo = &macInfo; #endif } if (!err && (err = Pa_OpenStream(&pa.stream, NULL, &outputParameters, (double)output.current_sample_rate, paFramesPerBufferUnspecified, paPrimeOutputBuffersUsingStreamCallback | paDitherOff, pa_callback, NULL)) != paNoError) { LOG_WARN("error opening device %i - %s : %s", outputParameters.device, Pa_GetDeviceInfo(outputParameters.device)->name, Pa_GetErrorText(err)); } if (!err) { LOG_INFO("opened device %i - %s at %u latency %u ms", outputParameters.device, Pa_GetDeviceInfo(outputParameters.device)->name, (unsigned int)Pa_GetStreamInfo(pa.stream)->sampleRate, (unsigned int)(Pa_GetStreamInfo(pa.stream)->outputLatency * 1000)); pa.rate = output.current_sample_rate; if ((err = Pa_SetStreamFinishedCallback(pa.stream, pa_stream_finished)) != paNoError) { LOG_WARN("error setting finish callback: %s", Pa_GetErrorText(err)); } if ((err = Pa_StartStream(pa.stream)) != paNoError) { LOG_WARN("error starting stream: %s", Pa_GetErrorText(err)); } } if (err && !monitor_thread_running) { vis_stop(); // create a thread to check for output state change or device return #if LINUX || OSX pthread_create(&monitor_thread, NULL, pa_monitor, NULL); #endif #if WIN monitor_thread = CreateThread(NULL, OUTPUT_THREAD_STACK_SIZE, (LPTHREAD_START_ROUTINE)&pa_monitor, NULL, 0, NULL); #endif } output.error_opening = !err; }
bool open() { if(stream) close(); assert(stream == NULL); PaStreamParameters outputParameters; #if defined(__APPLE__) PaMacCoreStreamInfo macInfo; PaMacCore_SetupStreamInfo( &macInfo, paMacCorePlayNice | paMacCorePro ); outputParameters.hostApiSpecificStreamInfo = &macInfo; #elif defined(__LINUX__) // TODO: if we have PaAlsa_EnableRealtimeScheduling in portaudio, // we can call that to enable RT priority with ALSA. // We could check dynamically via dsym. outputParameters.hostApiSpecificStreamInfo = NULL; #else outputParameters.hostApiSpecificStreamInfo = NULL; #endif outputParameters.device = Pa_GetDefaultOutputDevice(); if (outputParameters.device == paNoDevice) { PyErr_SetString(PyExc_RuntimeError, "Pa_GetDefaultOutputDevice didn't returned a device"); return false; } outputParameters.channelCount = player->outNumChannels; outputParameters.sampleFormat = OutPaSampleFormat<OUTSAMPLE_t>::format; unsigned long bufferSize = (player->outSamplerate * player->outNumChannels / 1000) * LATENCY_IN_MS / 4; if(bufferSize == paFramesPerBufferUnspecified) outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency; else outputParameters.suggestedLatency = LATENCY_IN_MS / 1000.0; // Note about framesPerBuffer: // Earlier, we used (2048 * 5 * OUTSAMPLEBYTELEN) which caused // some random more or less rare cracking noises. // See here: https://github.com/albertz/music-player/issues/35 // This doesn't seem to happen with paFramesPerBufferUnspecified. PaError ret = Pa_OpenStream( &stream, NULL, // no input &outputParameters, player->outSamplerate, // sampleRate bufferSize, paClipOff | paDitherOff, #if USE_PORTAUDIO_CALLBACK &paStreamCallback, #else NULL, #endif this //void *userData ); if(ret != paNoError) { PyErr_Format(PyExc_RuntimeError, "Pa_OpenStream failed: (err %i) %s", ret, Pa_GetErrorText(ret)); if(stream) close(); return false; } needRealtimeReset = true; Pa_StartStream(stream); #if !USE_PORTAUDIO_CALLBACK audioThread.func = boost::bind(&OutStream::audioThreadProc, this, _1, _2); audioThread.start(); #endif return true; }
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; }
PaStream *setupAudioStream(PartConvMax *pc) { PaStream *stream; PaStreamParameters outputParameters,inputParameters; Pa_Initialize(); //outputParameters.device = Pa_GetDefaultOutputDevice(); outputParameters.device = 6; //Aggregate Device if(outputParameters.device == paNoDevice) { printf("\nno output device available\n"); Pa_Terminate(); exit(-1); } outputParameters.channelCount = pc->numOutputChannels; outputParameters.sampleFormat = paFloat32; //outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; //outputParameters.suggestedLatency = (64.0f / 44100.0f); outputParameters.suggestedLatency = ((float)(pc->buffer_size) / 44100.0f); //inputParameters.device = Pa_GetDefaultInputDevice(); inputParameters.device = 6; //Aggregate Device if(inputParameters.device == paNoDevice) { printf("\nno input device available\n"); Pa_Terminate(); exit(-1); } inputParameters.channelCount = pc->numInputChannels; inputParameters.sampleFormat = paFloat32; inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; //inputParameters.suggestedLatency = (64.0f / 44100.0f); inputParameters.suggestedLatency = ((float)(pc->buffer_size) / 44100.0f); PaStreamFlags streamFlags; PaMacCoreStreamInfo coreInfo; /*This setting is tuned for pro audio apps. It allows SR conversion on input and output, but it tries to set the appropriate SR on the device.*/ //#define paMacCorePro (0x01) /*This is a setting to minimize CPU usage, even if that means interrupting the device. */ //#define paMacCoreMinimizeCPU (0x0101) unsigned long flags = (0x0101); PaMacCore_SetupStreamInfo(&coreInfo, flags); inputParameters.hostApiSpecificStreamInfo = &coreInfo; outputParameters.hostApiSpecificStreamInfo = &coreInfo; streamFlags = paNoFlag; PaError error = Pa_OpenStream( &stream, &inputParameters, &outputParameters, pc->FS, pc->buffer_size, streamFlags, Callback, (void*)pc // user data in callback ); if (error) { printf("\nError opening stream, error code = %i\n",error); printf("%s\n", Pa_GetErrorText(error)); Pa_Terminate(); exit(-1); } const PaStreamInfo* stream_info = Pa_GetStreamInfo(stream); printf("\nOutput Stream:\n"); printf("sample rate: %g \n",stream_info->sampleRate); printf("device: %u\n",outputParameters.device); printf("channels: %u\n",outputParameters.channelCount); printf("suggested latency: %g ms\n", outputParameters.suggestedLatency*1000); printf("stream latency: %g ms\n", stream_info->outputLatency*1000); printf("\nInput Stream:\n"); printf("sample rate: %g \n",stream_info->sampleRate); printf("device: %u\n",inputParameters.device); printf("channels: %u\n",inputParameters.channelCount); printf("suggested latency: %g ms\n", inputParameters.suggestedLatency*1000); printf("stream latency: %g ms\n", stream_info->inputLatency*1000); return stream; }
int main(void) { PaStreamParameters outputParameters; PaStream *stream; PaError err; paTestData data; #ifdef __APPLE__ PaMacCoreStreamInfo macInfo; #endif int i; /* 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; for( i=0; i<2; ++i ) { const float sr = i ? SAMPLE_RATE2 : SAMPLE_RATE1; printf("PortAudio Test: output sine wave. SR = %g, BufSize = %d\n", sr, FRAMES_PER_BUFFER); 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; /** setup host specific info */ #ifdef __APPLE__ PaMacCore_SetupStreamInfo( &macInfo, paMacCorePro ); outputParameters.hostApiSpecificStreamInfo = &macInfo; #else printf( "Hardware SR changing not being tested on this platform.\n" ); outputParameters.hostApiSpecificStreamInfo = NULL; #endif err = Pa_OpenStream( &stream, NULL, /* no input */ &outputParameters, sr, 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; }