/** * Device initialization: check device capability and open for recording. * * @param sfreq [in] required sampling frequency. * @param dummy [in] a dummy data * * @return TRUE on success, FALSE on failure. */ boolean adin_mic_standby(int sfreq, void *dummy) { PaError err; int frames_per_buffer, num_buffer; int latency; char *p; /* set cycle buffer length */ cycle_buffer_len = INPUT_DELAY_SEC * sfreq; j_printerr("Audio cycle buffer length: %d bytes\n", cycle_buffer_len * sizeof(SP16)); /* for safety... */ if (sizeof(SP16) != paInt16) { j_error("SP16 != paInt16\n"); } /* allocate and init */ current = processed = 0; speech = (SP16 *)mymalloc(sizeof(SP16) * cycle_buffer_len); buffer_overflowed = FALSE; /* set buffer parameter*/ if ((p = getenv("LATENCY_MSEC")) != NULL) { j_printerr("adin_mic_standby: get LATENCY_MSEC=%s\n", p); latency = atoi(p); } else { latency = MAX_FRAGMENT_MSEC; } frames_per_buffer = 256; num_buffer = sfreq * latency / (frames_per_buffer * 1000); j_printf("framesPerBuffer=%d, NumBuffers(guess)=%d (%d)\n", frames_per_buffer, num_buffer, Pa_GetMinNumBuffers(frames_per_buffer, sfreq)); j_printf("Audio I/O Latency = %d msec (data fragment = %d frames)\n", (frames_per_buffer * num_buffer) * 1000 / sfreq, (frames_per_buffer * num_buffer)); /* initialize device and open stream */ err = Pa_Initialize(); if (err != paNoError) { j_printerr("Error: %s\n", Pa_GetErrorText(err)); return(FALSE); } err = Pa_OpenDefaultStream(&stream, 1, 0, paInt16, sfreq, frames_per_buffer, num_buffer, Callback, NULL); if (err != paNoError) { j_printerr("Error: %s\n", Pa_GetErrorText(err)); return(FALSE); } return(TRUE); }
void Gear_AudioInput::initPortAudio() { std::cout << "Opening PortAudio Stream..." << std::endl; if (_stream) { Pa_AbortStream(_stream); Pa_CloseStream(_stream); } std::cout << Engine::signalInfo().sampleRate() << "hz " << std::endl; int framesPerBuffer = _settings.get(SETTING_FRAMES_PER_BUFFER)->valueInt(); std::cout << "Frames per buffer: " << framesPerBuffer << std::endl; int nbBuffers = _settings.get(SETTING_NB_BUFFERS)->valueInt(); //if nbBuffers is 0, let portaudio set the value if (!nbBuffers) { nbBuffers = Pa_GetMinNumBuffers(framesPerBuffer, Engine::signalInfo().sampleRate()); _settings.get(SETTING_NB_BUFFERS)->valueInt(nbBuffers); } std::cout << "Number of buffers: " << nbBuffers << std::endl; _ringBufferSize = framesPerBuffer; _lBuffer.resize(_ringBufferSize); PaError err = Pa_OpenStream(&_stream, Pa_GetDefaultInputDeviceID(),/* default input device*/ 1, //input paFloat32, NULL, paNoDevice, //no output 0, //mono paFloat32, NULL, Engine::signalInfo().sampleRate(), framesPerBuffer, nbBuffers, /* number of buffers, if zero then use default minimum*/ paClipOff, /* we won't output out of range samples so don't bother clipping them*/ portAudioCallback, this); if (err != paNoError) std::cout << Pa_GetErrorText(err) << std::endl; else std::cout << "Opening PortAudio Stream...done" << std::endl; }
static int open_audio(){ /* this will open one circular audio stream */ /* build on top of portaudio routines */ /* implementation based on file pastreamio.c */ int numSamples; int numBytes; int minNumBuffers; int numFrames; minNumBuffers = 2 * Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, vi.rate ); numFrames = minNumBuffers * FRAMES_PER_BUFFER; numFrames = RoundUpToNextPowerOf2( numFrames ); numSamples = numFrames * vi.channels; numBytes = numSamples * sizeof(SAMPLE); samples = (SAMPLE *) malloc( numBytes ); /* store our latency calculation here */ latency_sec = (double) numFrames / vi.rate / vi.channels; printf( "Latency: %.04f\n", latency_sec ); err = OpenAudioStream( &aOutStream, vi.rate, PA_SAMPLE_TYPE, (PASTREAMIO_WRITE | PASTREAMIO_STEREO) ); if( err != paNoError ) goto error; return err; error: CloseAudioStream( aOutStream ); printf( "An error occured while opening the portaudio stream\n" ); printf( "Error number: %d\n", err ); printf( "Error message: %s\n", Pa_GetErrorText( err ) ); return err; }
PaError PaHost_OpenStream( internalPortAudioStream *past ) { PaError result = paNoError; PaHostSoundControl *pahsc; unsigned int minNumBuffers; internalPortAudioDevice *pad; DBUG(("PaHost_OpenStream() called.\n" )); /* Allocate and initialize host data. */ pahsc = (PaHostSoundControl *) malloc(sizeof(PaHostSoundControl)); if( pahsc == NULL ) { result = paInsufficientMemory; goto error; } memset( pahsc, 0, sizeof(PaHostSoundControl) ); past->past_DeviceData = (void *) pahsc; pahsc->pahsc_OutputHandle = BAD_DEVICE_ID; /* No device currently opened. */ pahsc->pahsc_InputHandle = BAD_DEVICE_ID; pahsc->pahsc_IsAudioThreadValid = 0; pahsc->pahsc_IsWatchDogThreadValid = 0; /* Allocate native buffers. */ pahsc->pahsc_BytesPerInputBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels * sizeof(short); if( past->past_NumInputChannels > 0) { pahsc->pahsc_NativeInputBuffer = (short *) malloc(pahsc->pahsc_BytesPerInputBuffer); if( pahsc->pahsc_NativeInputBuffer == NULL ) { result = paInsufficientMemory; goto error; } } pahsc->pahsc_BytesPerOutputBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels * sizeof(short); if( past->past_NumOutputChannels > 0) { pahsc->pahsc_NativeOutputBuffer = (short *) malloc(pahsc->pahsc_BytesPerOutputBuffer); if( pahsc->pahsc_NativeOutputBuffer == NULL ) { result = paInsufficientMemory; goto error; } } /* DBUG(("PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\n", pahsc->pahsc_MinFramesPerHostBuffer )); */ minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate ); past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers; pahsc->pahsc_InverseMicrosPerBuffer = past->past_SampleRate / (1000000.0 * past->past_FramesPerUserBuffer); DBUG(("past_SampleRate = %g\n", past->past_SampleRate )); DBUG(("past_FramesPerUserBuffer = %d\n", past->past_FramesPerUserBuffer )); DBUG(("pahsc_InverseMicrosPerBuffer = %g\n", pahsc->pahsc_InverseMicrosPerBuffer )); /* ------------------------- OPEN DEVICE -----------------------*/ /* just output */ if (past->past_OutputDeviceID == past->past_InputDeviceID) { if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0) ) { pad = Pa_GetInternalDevice( past->past_OutputDeviceID ); DBUG(("PaHost_OpenStream: attempt to open %s for O_RDWR\n", pad->pad_DeviceName )); /* dmazzoni: test it first in nonblocking mode to make sure the device is not busy */ pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDWR|O_NONBLOCK); if(pahsc->pahsc_InputHandle==-1) { ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDWR\n", pad->pad_DeviceName )); result = paHostError; goto error; } close(pahsc->pahsc_InputHandle); pahsc->pahsc_OutputHandle = pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDWR); if(pahsc->pahsc_InputHandle==-1) { ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDWR\n", pad->pad_DeviceName )); result = paHostError; goto error; } Pa_SetLatency( pahsc->pahsc_OutputHandle, past->past_NumUserBuffers, past->past_FramesPerUserBuffer, past->past_NumOutputChannels ); result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle, past->past_NumOutputChannels, (int)past->past_SampleRate ); } } else { if (past->past_NumOutputChannels > 0) { pad = Pa_GetInternalDevice( past->past_OutputDeviceID ); DBUG(("PaHost_OpenStream: attempt to open %s for O_WRONLY\n", pad->pad_DeviceName )); /* dmazzoni: test it first in nonblocking mode to make sure the device is not busy */ pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY|O_NONBLOCK); if(pahsc->pahsc_OutputHandle==-1) { ERR_RPT(("PaHost_OpenStream: could not open %s for O_WRONLY\n", pad->pad_DeviceName )); result = paHostError; goto error; } close(pahsc->pahsc_OutputHandle); pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY); if(pahsc->pahsc_OutputHandle==-1) { ERR_RPT(("PaHost_OpenStream: could not open %s for O_WRONLY\n", pad->pad_DeviceName )); result = paHostError; goto error; } Pa_SetLatency( pahsc->pahsc_OutputHandle, past->past_NumUserBuffers, past->past_FramesPerUserBuffer, past->past_NumOutputChannels ); result = Pa_SetupOutputDeviceFormat( pahsc->pahsc_OutputHandle, past->past_NumOutputChannels, (int)past->past_SampleRate ); } if (past->past_NumInputChannels > 0) { pad = Pa_GetInternalDevice( past->past_InputDeviceID ); DBUG(("PaHost_OpenStream: attempt to open %s for O_RDONLY\n", pad->pad_DeviceName )); /* dmazzoni: test it first in nonblocking mode to make sure the device is not busy */ pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY|O_NONBLOCK); if(pahsc->pahsc_InputHandle==-1) { ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDONLY\n", pad->pad_DeviceName )); result = paHostError; goto error; } close(pahsc->pahsc_InputHandle); pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY); if(pahsc->pahsc_InputHandle==-1) { ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDONLY\n", pad->pad_DeviceName )); result = paHostError; goto error; } Pa_SetLatency( pahsc->pahsc_InputHandle, /* DH20010115 - was OutputHandle! */ past->past_NumUserBuffers, past->past_FramesPerUserBuffer, past->past_NumInputChannels ); result = Pa_SetupInputDeviceFormat( pahsc->pahsc_InputHandle, past->past_NumInputChannels, (int)past->past_SampleRate ); } } DBUG(("PaHost_OpenStream: SUCCESS - result = %d\n", result )); return result; error: ERR_RPT(("PaHost_OpenStream: ERROR - result = %d\n", result )); PaHost_CloseStream( past ); return result; }
PaError PaHost_OpenStream( internalPortAudioStream *past ) { HRESULT hr; PaError result = paNoError; PaHostSoundControl *pahsc; int numBytes, maxChannels; unsigned int minNumBuffers; internalPortAudioDevice *pad; DSoundWrapper *dsw; /* Allocate and initialize host data. */ pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); /* MEM */ if( pahsc == NULL ) { result = paInsufficientMemory; goto error; } memset( pahsc, 0, sizeof(PaHostSoundControl) ); past->past_DeviceData = (void *) pahsc; pahsc->pahsc_TimerID = 0; dsw = &pahsc->pahsc_DSoundWrapper; DSW_Init( dsw ); /* Allocate native buffer. */ maxChannels = ( past->past_NumOutputChannels > past->past_NumInputChannels ) ? past->past_NumOutputChannels : past->past_NumInputChannels; pahsc->pahsc_BytesPerBuffer = past->past_FramesPerUserBuffer * maxChannels * sizeof(short); if( maxChannels > 0 ) { pahsc->pahsc_NativeBuffer = (short *) PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerBuffer); /* MEM */ if( pahsc->pahsc_NativeBuffer == NULL ) { result = paInsufficientMemory; goto error; } } else { result = paInvalidChannelCount; goto error; } DBUG(("PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\n", pahsc->pahsc_MinFramesPerHostBuffer )); minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate ); past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers; numBytes = pahsc->pahsc_BytesPerBuffer * past->past_NumUserBuffers; if( numBytes < DSBSIZE_MIN ) { result = paBufferTooSmall; goto error; } if( numBytes > DSBSIZE_MAX ) { result = paBufferTooBig; goto error; } pahsc->pahsc_FramesPerDSBuffer = past->past_FramesPerUserBuffer * past->past_NumUserBuffers; { int msecLatency = (int) ((pahsc->pahsc_FramesPerDSBuffer * 1000) / past->past_SampleRate); PRINT(("PortAudio on DirectSound - Latency = %d frames, %d msec\n", pahsc->pahsc_FramesPerDSBuffer, msecLatency )); } /* ------------------ OUTPUT */ if( (past->past_OutputDeviceID >= 0) && (past->past_NumOutputChannels > 0) ) { DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", past->past_OutputDeviceID)); pad = Pa_GetInternalDevice( past->past_OutputDeviceID ); hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound, NULL ); /* If this fails, then try each output device until we find one that works. */ if( hr != DS_OK ) { int i; ERR_RPT(("Creation of requested Audio Output device '%s' failed.\n", ((pad->pad_lpGUID == NULL) ? "Default" : pad->pad_Info.name) )); for( i=0; i<Pa_CountDevices(); i++ ) { pad = Pa_GetInternalDevice( i ); if( pad->pad_Info.maxOutputChannels >= past->past_NumOutputChannels ) { DBUG(("Try device '%s' instead.\n", pad->pad_Info.name )); hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound, NULL ); if( hr == DS_OK ) { ERR_RPT(("Using device '%s' instead.\n", pad->pad_Info.name )); break; } } } } if( hr != DS_OK ) { ERR_RPT(("PortAudio: DirectSoundCreate() failed!\n")); result = paHostError; sPaHostError = hr; goto error; } hr = DSW_InitOutputBuffer( dsw, (unsigned long) (past->past_SampleRate + 0.5), past->past_NumOutputChannels, numBytes ); DBUG(("DSW_InitOutputBuffer() returns %x\n", hr)); if( hr != DS_OK ) { result = paHostError; sPaHostError = hr; goto error; } past->past_FrameCount = pahsc->pahsc_DSoundWrapper.dsw_FramesWritten; } #if SUPPORT_AUDIO_CAPTURE /* ------------------ INPUT */ if( (past->past_InputDeviceID >= 0) && (past->past_NumInputChannels > 0) ) { pad = Pa_GetInternalDevice( past->past_InputDeviceID ); hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture, NULL ); /* If this fails, then try each input device until we find one that works. */ if( hr != DS_OK ) { int i; ERR_RPT(("Creation of requested Audio Capture device '%s' failed.\n", ((pad->pad_lpGUID == NULL) ? "Default" : pad->pad_Info.name) )); for( i=0; i<Pa_CountDevices(); i++ ) { pad = Pa_GetInternalDevice( i ); if( pad->pad_Info.maxInputChannels >= past->past_NumInputChannels ) { PRINT(("Try device '%s' instead.\n", pad->pad_Info.name )); hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture, NULL ); if( hr == DS_OK ) break; } } } if( hr != DS_OK ) { ERR_RPT(("PortAudio: DirectSoundCaptureCreate() failed!\n")); result = paHostError; sPaHostError = hr; goto error; } hr = DSW_InitInputBuffer( dsw, (unsigned long) (past->past_SampleRate + 0.5), past->past_NumInputChannels, numBytes ); DBUG(("DSW_InitInputBuffer() returns %x\n", hr)); if( hr != DS_OK ) { ERR_RPT(("PortAudio: DSW_InitInputBuffer() returns %x\n", hr)); result = paHostError; sPaHostError = hr; goto error; } } #endif /* SUPPORT_AUDIO_CAPTURE */ /* Calculate scalar used in CPULoad calculation. */ { LARGE_INTEGER frequency; if( QueryPerformanceFrequency( &frequency ) == 0 ) { pahsc->pahsc_InverseTicksPerUserBuffer = 0.0; } else { pahsc->pahsc_InverseTicksPerUserBuffer = past->past_SampleRate / ( (double)frequency.QuadPart * past->past_FramesPerUserBuffer ); DBUG(("pahsc_InverseTicksPerUserBuffer = %g\n", pahsc->pahsc_InverseTicksPerUserBuffer )); } } return result; error: PaHost_CloseStream( past ); return result; }
static int open_output(void) { double rate; int n, nrates, include_enc, exclude_enc, ret; PaSampleFormat SampleFormat, nativeSampleFormats; if( dpm.name != NULL) ret = sscanf(dpm.name, "%d", &opt_pa_device_id); if (dpm.name == NULL || ret == 0 || ret == EOF) opt_pa_device_id = -2; #ifdef AU_PORTAUDIO_DLL #if PORTAUDIO_V19 { if(&dpm == &portaudio_asio_play_mode){ HostApiTypeId = paASIO; } else if(&dpm == &portaudio_win_ds_play_mode){ HostApiTypeId = paDirectSound; } else if(&dpm == &portaudio_win_wmme_play_mode){ HostApiTypeId = paMME; } else { return -1; } if(load_portaudio_dll(0)) return -1; } #else { if(&dpm == &portaudio_asio_play_mode){ if(load_portaudio_dll(PA_DLL_ASIO)) return -1; } else if(&dpm == &portaudio_win_ds_play_mode){ if(load_portaudio_dll(PA_DLL_WIN_DS)) return -1; } else if(&dpm == &portaudio_win_wmme_play_mode){ if(load_portaudio_dll(PA_DLL_WIN_WMME)) return -1; } else { return -1; } } #endif #endif /* if call twice Pa_OpenStream causes paDeviceUnavailable error */ if(pa_active == 1) return 0; if(pa_active == 0){ err = Pa_Initialize(); if( err != paNoError ) goto error; pa_active = 1; } if (opt_pa_device_id == -1){ print_device_list(); goto error2; } #ifdef PORTAUDIO_V19 #ifdef AU_PORTAUDIO_DLL { PaHostApiIndex i, ApiCount; i = 0; ApiCount = Pa_GetHostApiCount(); do{ HostApiInfo=Pa_GetHostApiInfo(i); if( HostApiInfo->type == HostApiTypeId ) break; i++; }while ( i < ApiCount ); if ( i == ApiCount ) goto error; DeviceIndex = HostApiInfo->defaultOutputDevice; if(DeviceIndex==paNoDevice) goto error; } #else DeviceIndex = Pa_GetDefaultOutputDevice(); if(DeviceIndex==paNoDevice) goto error; #endif DeviceInfo = Pa_GetDeviceInfo( DeviceIndex); if(DeviceInfo==NULL) goto error; if(opt_pa_device_id != -2){ const PaDeviceInfo *id_DeviceInfo; id_DeviceInfo=Pa_GetDeviceInfo((PaDeviceIndex)opt_pa_device_id); if(id_DeviceInfo==NULL) goto error; if( DeviceInfo->hostApi == id_DeviceInfo->hostApi){ DeviceIndex=(PaDeviceIndex)opt_pa_device_id; DeviceInfo = id_DeviceInfo; } } if (dpm.encoding & PE_24BIT) { SampleFormat = paInt24; }else if (dpm.encoding & PE_16BIT) { SampleFormat = paInt16; }else { SampleFormat = paInt8; } stereo = (dpm.encoding & PE_MONO) ? 1 : 2; data_nbyte = (dpm.encoding & PE_16BIT) ? 2 : 1; data_nbyte = (dpm.encoding & PE_24BIT) ? 3 : data_nbyte; pa_data.samplesToGo = 0; pa_data.bufpoint = pa_data.buf; pa_data.bufepoint = pa_data.buf; // firsttime = 1; numBuffers = 1; //Pa_GetMinNumBuffers( framesPerBuffer, dpm.rate ); framesPerInBuffer = numBuffers * framesPerBuffer; if (framesPerInBuffer < 4096) framesPerInBuffer = 4096; bytesPerInBuffer = framesPerInBuffer * data_nbyte * stereo; /* set StreamParameters */ StreamParameters.device = DeviceIndex; StreamParameters.channelCount = stereo; if(ctl->id_character != 'r' && ctl->id_character != 'A' && ctl->id_character != 'W' && ctl->id_character != 'P'){ StreamParameters.suggestedLatency = DeviceInfo->defaultHighOutputLatency; }else{ StreamParameters.suggestedLatency = DeviceInfo->defaultLowOutputLatency; } StreamParameters.hostApiSpecificStreamInfo = NULL; if( SampleFormat == paInt16){ StreamParameters.sampleFormat = paInt16; if( paFormatIsSupported != Pa_IsFormatSupported( NULL , &StreamParameters,(double) dpm.rate )){ StreamParameters.sampleFormat = paInt32; conv16_32 = 1; } else { StreamParameters.sampleFormat = paInt16; conv16_32 = 0; } }else{ StreamParameters.sampleFormat = SampleFormat; } err = Pa_IsFormatSupported( NULL , &StreamParameters, (double) dpm.rate ); if ( err != paNoError) goto error; err = Pa_OpenStream( & stream, /* passes back stream pointer */ NULL, /* inputStreamParameters */ &StreamParameters, /* outputStreamParameters */ (double) dpm.rate, /* sample rate */ paFramesPerBufferUnspecified, /* frames per buffer */ paFramesPerBufferUnspecified, /* PaStreamFlags */ paCallback, /* specify our custom callback */ &pa_data /* pass our data through to callback */ ); // Pa_Sleeep(1); if ( err != paNoError) goto error; return 0; #else if(opt_pa_device_id == -2){ DeviceID = Pa_GetDefaultOutputDeviceID(); if(DeviceID==paNoDevice) goto error2; }else{ DeviceID = opt_pa_device_id; } DeviceInfo = Pa_GetDeviceInfo( DeviceID); if(DeviceInfo==NULL) goto error2; nativeSampleFormats = DeviceInfo->nativeSampleFormats; exclude_enc = PE_ULAW | PE_ALAW | PE_BYTESWAP; include_enc = PE_SIGNED; if (!(nativeSampleFormats & paInt16) && !(nativeSampleFormats & paInt32)) {exclude_enc |= PE_16BIT;} if (!(nativeSampleFormats & paInt24)) {exclude_enc |= PE_24BIT;} dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc); if (dpm.encoding & PE_24BIT) { SampleFormat = paInt24; }else if (dpm.encoding & PE_16BIT) { if(nativeSampleFormats & paInt16) SampleFormat = paInt16; else{ SampleFormat = paInt32; conv16_32 = 1; } }else { SampleFormat = paInt8; } stereo = (dpm.encoding & PE_MONO) ? 1 : 2; data_nbyte = (dpm.encoding & PE_16BIT) ? 2 : 1; data_nbyte = (dpm.encoding & PE_24BIT) ? 3 : data_nbyte; nrates = DeviceInfo->numSampleRates; if (nrates == -1) { /* range supported */ rate = dpm.rate; if (dpm.rate < DeviceInfo->sampleRates[0]) rate = DeviceInfo->sampleRates[0]; if (dpm.rate > DeviceInfo->sampleRates[1]) rate = DeviceInfo->sampleRates[1]; } else { rate = DeviceInfo->sampleRates[nrates-1]; for (n = nrates - 1; n >= 0; n--) { /* find nearest sample rate */ if (dpm.rate <= DeviceInfo->sampleRates[n]) rate=DeviceInfo->sampleRates[n]; } } dpm.rate = (int32)rate; pa_data.samplesToGo = 0; pa_data.bufpoint = pa_data.buf; pa_data.bufepoint = pa_data.buf; // firsttime = 1; numBuffers = Pa_GetMinNumBuffers( framesPerBuffer, dpm.rate ); framesPerInBuffer = numBuffers * framesPerBuffer; if (framesPerInBuffer < 4096) framesPerInBuffer = 4096; bytesPerInBuffer = framesPerInBuffer * data_nbyte * stereo; // printf("%d\n",framesPerInBuffer); // printf("%d\n",dpm.rate); err = Pa_OpenDefaultStream( &stream, /* passes back stream pointer */ 0, /* no input channels */ stereo, /* 2:stereo 1:mono output */ SampleFormat, /* 24bit 16bit 8bit output */ (double)dpm.rate, /* sample rate */ framesPerBuffer, /* frames per buffer */ numBuffers, /* number of buffers, if zero then use default minimum */ paCallback, /* specify our custom callback */ &pa_data); /* pass our data through to callback */ if ( err != paNoError && err != paHostError) goto error; return 0; #endif error: ctl->cmsg( CMSG_ERROR, VERB_NORMAL, "PortAudio error: %s\n", Pa_GetErrorText( err ) ); error2: Pa_Terminate(); pa_active = 0; #ifdef AU_PORTAUDIO_DLL #ifndef PORTAUDIO_V19 free_portaudio_dll(); #endif #endif return -1; }
/************************************************************ * Opens a PortAudio stream with default characteristics. * Allocates PABLIO_Stream structure. * * flags parameter can be an ORed combination of: * PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE */ PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate, PaSampleFormat format, int inchannels, int outchannels, int framesperbuf, int nbuffers, int indeviceno, int outdeviceno) /* MSP */ { long bytesPerSample; long doRead = 0; long doWrite = 0; PaError err; PABLIO_Stream *aStream; long minNumBuffers; long numFrames; //#ifdef PA19 // PaStreamParameters instreamparams, outstreamparams; /* MSP */ //#endif /* fprintf(stderr, "open %lf fmt %d flags %d ch: %d fperbuf: %d nbuf: %d devs: %d %d\n", sampleRate, format, flags, nchannels, framesperbuf, nbuffers, indeviceno, outdeviceno); */ if (indeviceno < 0) /* MSP... */ { //#ifdef PA19 // indeviceno = Pa_GetDefaultInputDevice(); //#else indeviceno = Pa_GetDefaultInputDeviceID(); //#endif fprintf(stderr, "using default input device number: %d\n", indeviceno); } if (outdeviceno < 0) { //#ifdef PA19 // outdeviceno = Pa_GetDefaultOutputDevice(); //#else outdeviceno = Pa_GetDefaultOutputDeviceID(); //#endif fprintf(stderr, "using default output device number: %d\n", outdeviceno); } /* fprintf(stderr, "nchan %d, flags %d, bufs %d, framesperbuf %d\n", nchannels, flags, nbuffers, framesperbuf); */ /* ...MSP */ /* Allocate PABLIO_Stream structure for caller. */ aStream = (PABLIO_Stream *) malloc( sizeof(PABLIO_Stream) ); if( aStream == NULL ) return paInsufficientMemory; memset( aStream, 0, sizeof(PABLIO_Stream) ); /* Determine size of a sample. */ bytesPerSample = Pa_GetSampleSize( format ); if( bytesPerSample < 0 ) { fprintf(stderr, "error bytes per sample: %i\n", bytesPerSample); err = (PaError) bytesPerSample; goto error; } aStream->insamplesPerFrame = inchannels; /* MSP */ aStream->inbytesPerFrame = bytesPerSample * aStream->insamplesPerFrame; aStream->outsamplesPerFrame = outchannels; aStream->outbytesPerFrame = bytesPerSample * aStream->outsamplesPerFrame; /* Initialize PortAudio */ err = Pa_Initialize(); if( err != paNoError ) goto error; //#ifdef PA19 // numFrames = nbuffers * framesperbuf; /* ...MSP */ // instreamparams.device = indeviceno; /* MSP... */ // instreamparams.channelCount = inchannels; // instreamparams.sampleFormat = format; // instreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate; // instreamparams.hostApiSpecificStreamInfo = 0; // outstreamparams.device = outdeviceno; // outstreamparams.channelCount = outchannels; // outstreamparams.sampleFormat = format; // outstreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate; // outstreamparams.hostApiSpecificStreamInfo = 0; /* ... MSP */ //#else /* Warning: numFrames must be larger than amount of data processed per interrupt inside PA to prevent glitches. */ /* MSP */ minNumBuffers = Pa_GetMinNumBuffers(framesperbuf, sampleRate); if (minNumBuffers > nbuffers) fprintf(stderr, "warning: number of buffers %d less than recommended minimum %d\n", (int)nbuffers, (int)minNumBuffers); //#endif numFrames = nbuffers * framesperbuf; /* fprintf(stderr, "numFrames %d\n", numFrames); */ /* Initialize Ring Buffers */ doRead = (inchannels != 0); doWrite = (outchannels != 0); if(doRead) { err = PABLIO_InitFIFO( &aStream->inFIFO, numFrames, aStream->inbytesPerFrame ); if( err != paNoError ) { fprintf(stderr, "error doRead PABLIO_InitFIFO \n"); goto error; } } if(doWrite) { long numBytes; err = PABLIO_InitFIFO( &aStream->outFIFO, numFrames, aStream->outbytesPerFrame ); if( err != paNoError ) { fprintf(stderr, "error doWrite PABLIO_InitFIFO \n"); goto error; } /* Make Write FIFO appear full initially. */ numBytes = RingBuffer_GetWriteAvailable( &aStream->outFIFO ); RingBuffer_AdvanceWriteIndex( &aStream->outFIFO, numBytes ); } /* Open a PortAudio stream that we will use to communicate with the underlying * audio drivers. */ //#ifdef PA19 // err = Pa_OpenStream( // &aStream->stream, // (doRead ? &instreamparams : 0), /* MSP */ // (doWrite ? &outstreamparams : 0), /* MSP */ // sampleRate, // framesperbuf, /* MSP */ // paNoFlag, /* MSP -- portaudio will clip for us */ // blockingIOCallback, // aStream ); //#else // err = Pa_OpenStream( // &aStream->stream, // (doRead ? indeviceno : paNoDevice), /* MSP */ // (doRead ? aStream->insamplesPerFrame : 0 ), // format, // NULL, // (doWrite ? outdeviceno : paNoDevice), /* MSP */ // (doWrite ? aStream->outsamplesPerFrame : 0 ), // format, // NULL, // sampleRate, // framesperbuf, /* MSP */ // nbuffers, /* MSP */ // paNoFlag, /* MSP -- portaudio will clip for us */ // blockingIOCallback, // aStream ); // #endif PortAudioStream *stream; err = Pa_OpenDefaultStream( stream, 0, 2, paFloat32, 44100, 256, 0, blockingIOCallback, stream ); if( err != paNoError ){ fprintf(stderr, "error Pa_OpenStream \n"); goto error; } err = Pa_StartStream( aStream->stream ); if( err != paNoError ) /* MSP */ { fprintf(stderr, "Pa_StartStream failed; closing audio stream...\n"); CloseAudioStream( aStream ); goto error; } *rwblPtr = aStream; return paNoError; error: *rwblPtr = NULL; return err; }
void main( int argc, char **argv ) { PortAudioStream *stream; PaError err; paTestData data; int i; int go; int numBuffers = 0; int minBuffers = 0; int framesPerBuffer; double sampleRate = 44100.0; char str[256]; printf("paminlat - Determine minimum latency for your computer.\n"); printf(" usage: paminlat {framesPerBuffer}\n"); printf(" for example: paminlat 256\n"); printf("Adjust your stereo until you hear a smooth tone in each speaker.\n"); printf("Then try to find the smallest number of buffers that still sounds smooth.\n"); printf("Note that the sound will stop momentarily when you change the number of buffers.\n"); /* Get bufferSize from command line. */ framesPerBuffer = ( argc > 1 ) ? atol( argv[1] ) : DEFAULT_BUFFER_SIZE; printf("Frames per buffer = %d\n", framesPerBuffer ); /* 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; /* Ask PortAudio for the recommended minimum number of buffers. */ numBuffers = minBuffers = Pa_GetMinNumBuffers( framesPerBuffer, sampleRate ); printf("NumBuffers set to %d based on a call to Pa_GetMinNumBuffers()\n", numBuffers ); /* Try different numBuffers in a loop. */ go = 1; while( go ) { printf("Latency = framesPerBuffer * numBuffers = %d * %d = %d frames = %d msecs.\n", framesPerBuffer, numBuffers, framesPerBuffer*numBuffers, (int)((1000 * framesPerBuffer * numBuffers) / sampleRate) ); err = Pa_OpenStream( &stream, paNoDevice, 0, /* no input */ paFloat32, /* 32 bit floating point input */ NULL, Pa_GetDefaultOutputDeviceID(), /* default output device */ 2, /* stereo output */ paFloat32, /* 32 bit floating point output */ NULL, sampleRate, framesPerBuffer,/* 46 msec buffers */ numBuffers, /* number of buffers */ paClipOff, /* we won't output out of range samples so don't bother clipping them */ paminlatCallback, &data ); if( err != paNoError ) goto error; if( stream == NULL ) goto error; /* Start audio. */ err = Pa_StartStream( stream ); if( err != paNoError ) goto error; /* Ask user for a new number of buffers. */ printf("\nMove windows around to see if the sound glitches.\n"); printf("NumBuffers currently %d, enter new number, or 'q' to quit: ", numBuffers ); gets( str ); if( str[0] == 'q' ) go = 0; else { numBuffers = atol( str ); if( numBuffers < minBuffers ) { printf( "numBuffers below minimum of %d! Set to minimum!!!\n", minBuffers ); numBuffers = minBuffers; } } /* Stop sound until ENTER hit. */ err = Pa_StopStream( stream ); if( err != paNoError ) goto error; err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; } printf("A good setting for latency would be somewhat higher than\n"); printf("the minimum latency that worked.\n"); printf("PortAudio: Test finished.\n"); Pa_Terminate(); return; 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 ) ); }
static int TestAdvance( int mode, PaDeviceID deviceID, double sampleRate, int numChannels, PaSampleFormat format ) { PortAudioStream *stream = NULL; PaError result; PaQaData myData; #define FRAMES_PER_BUFFER (64) printf("------ TestAdvance: %s, device = %d, rate = %g, numChannels = %d, format = %d -------\n", ( mode == MODE_INPUT ) ? "INPUT" : "OUTPUT", deviceID, sampleRate, numChannels, format); fflush(stdout); /* Setup data for synthesis thread. */ myData.framesLeft = (unsigned long) (sampleRate * 100); /* 100 seconds */ myData.numChannels = numChannels; myData.mode = mode; myData.format = format; switch( format ) { case paFloat32: case paInt32: case paInt24: myData.bytesPerSample = 4; break; case paPackedInt24: myData.bytesPerSample = 3; break; default: myData.bytesPerSample = 2; break; } EXPECT( ((result = Pa_OpenStream( &stream, ( mode == MODE_INPUT ) ? deviceID : paNoDevice, ( mode == MODE_INPUT ) ? numChannels : 0, format, NULL, ( mode == MODE_OUTPUT ) ? deviceID : paNoDevice, ( mode == MODE_OUTPUT ) ? numChannels : 0, format, NULL, sampleRate, 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 */ QaCallback, &myData ) ) == 0) ); if( stream ) { PaTimestamp oldStamp, newStamp; unsigned long oldFrames; int minDelay = ( mode == MODE_INPUT ) ? 1000 : 400; int minNumBuffers = Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, sampleRate ); int msec = (int) ((minNumBuffers * 3 * 1000.0 * FRAMES_PER_BUFFER) / sampleRate); if( msec < minDelay ) msec = minDelay; printf("msec = %d\n", msec); /**/ EXPECT( ((result=Pa_StartStream( stream )) == 0) ); /* Check to make sure PortAudio is advancing timeStamp. */ result = paNoError; oldStamp = Pa_StreamTime(stream); fflush(stdout); Pa_Sleep(msec); newStamp = Pa_StreamTime(stream); printf("oldStamp = %g,newStamp = %g\n", oldStamp, newStamp ); /**/ EXPECT( (oldStamp < newStamp) ); /* Check to make sure callback is decrementing framesLeft. */ oldFrames = myData.framesLeft; Pa_Sleep(msec); printf("oldFrames = %d, myData.framesLeft = %d\n", oldFrames, myData.framesLeft ); /**/ EXPECT( (oldFrames > myData.framesLeft) ); EXPECT( ((result=Pa_CloseStream( stream )) == 0) ); stream = NULL; } error: if( stream != NULL ) Pa_CloseStream( stream ); fflush(stdout); return result; }
bool AudioIO::OpenDevice() { PaError error; int numPortAudioBuffers; int recDeviceNum; int playDeviceNum; PaSampleFormat paFormat; wxString recDevice; wxString playDevice; numPortAudioBuffers = Pa_GetMinNumBuffers(mBufferSize, mRate); if (mNumInChannels>0) numPortAudioBuffers *= 2; recDeviceNum = Pa_GetDefaultInputDeviceID(); playDeviceNum = Pa_GetDefaultOutputDeviceID(); recDevice = gPrefs->Read("/AudioIO/RecordingDevice", ""); playDevice = gPrefs->Read("/AudioIO/PlaybackDevice", ""); mFormat = (sampleFormat)gPrefs->Read("/AudioIO/SampleFormat", floatSample); switch(mFormat) { case floatSample: paFormat = paFloat32; break; case int16Sample: paFormat = paInt16; break; default: // Debug message only printf("Cannot output this sample format using PortAudio\n"); return false; } for(int j=0; j<Pa_CountDevices(); j++) { const PaDeviceInfo* info = Pa_GetDeviceInfo(j); if (info->name == playDevice && info->maxOutputChannels > 0) playDeviceNum = j; if (info->name == recDevice && info->maxInputChannels > 0) recDeviceNum = j; } if (mNumOutChannels<=0) playDeviceNum = paNoDevice; if (mNumInChannels<=0) recDeviceNum = paNoDevice; error = Pa_OpenStream(&mPortStream, recDeviceNum, mNumInChannels, paFormat, NULL, /* inputDriverInfo */ playDeviceNum, mNumOutChannels, paFormat, NULL, mRate, (unsigned long)mBufferSize, (unsigned long)numPortAudioBuffers, paClipOff | paDitherOff, audacityAudioCallback, NULL); return (mPortStream != NULL && error == paNoError); }
/************************************************************ * Opens a PortAudio stream with default characteristics. * Allocates PASTREAMIO_Stream structure. * * flags parameter can be an ORed combination of: * PABLIO_WRITE, * and either PABLIO_MONO or PABLIO_STEREO */ PaError OpenAudioStream( PASTREAMIO_Stream **rwblPtr, double sampleRate, PaSampleFormat format, long flags ) { long bytesPerSample; long doWrite = 0; PaError err; PASTREAMIO_Stream *aStream; long minNumBuffers; long numFrames; /* Allocate PASTREAMIO_Stream structure for caller. */ aStream = (PASTREAMIO_Stream *) malloc( sizeof(PASTREAMIO_Stream) ); if( aStream == NULL ) return paInsufficientMemory; memset( aStream, 0, sizeof(PASTREAMIO_Stream) ); /* Determine size of a sample. */ bytesPerSample = Pa_GetSampleSize( format ); if( bytesPerSample < 0 ) { err = (PaError) bytesPerSample; goto error; } aStream->samplesPerFrame = ((flags&PASTREAMIO_MONO) != 0) ? 1 : 2; aStream->bytesPerFrame = bytesPerSample * aStream->samplesPerFrame; /* Initialize PortAudio */ err = Pa_Initialize(); if( err != paNoError ) goto error; /* Warning: numFrames must be larger than amount of data processed per interrupt * inside PA to prevent glitches. Just to be safe, adjust size upwards. */ minNumBuffers = 2 * Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, sampleRate ); numFrames = minNumBuffers * FRAMES_PER_BUFFER; numFrames = RoundUpToNextPowerOf2( numFrames ); /* Initialize Ring Buffer */ doWrite = ((flags & PASTREAMIO_WRITE) != 0); if(doWrite) { err = PASTREAMIO_InitFIFO( &aStream->outFIFO, numFrames, aStream->bytesPerFrame ); if( err != paNoError ) goto error; /* Make Write FIFO appear full initially. numBytes = RingBuffer_GetWriteAvailable( &aStream->outFIFO ); RingBuffer_AdvanceWriteIndex( &aStream->outFIFO, numBytes );*/ } /* Open a PortAudio stream that we will use to communicate with the underlying * audio drivers. */ err = Pa_OpenStream( &aStream->stream, paNoDevice, 0 , format, NULL, Pa_GetDefaultOutputDeviceID() , aStream->samplesPerFrame , format, NULL, sampleRate, FRAMES_PER_BUFFER, minNumBuffers, paClipOff, /* we won't output out of range samples so don't bother clipping them */ audioIOCallback, aStream ); if( err != paNoError ) goto error; *rwblPtr = aStream; return paNoError; error: CloseAudioStream( aStream ); *rwblPtr = NULL; return err; }