/************************************************************ * Opens a PortAudio stream with default characteristics. * Allocates PABLIO_Stream structure. * */ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters, double sampleRate, PaStreamFlags streamFlags, long samples_per_packet, int do_dual) { long bytesPerSample = 2; PaError err; PABLIO_Stream *aStream; long numFrames; //long numBytes; int c = 0; int channels = 1; if (!(inputParameters || outputParameters)) { return -1; } /* Allocate PABLIO_Stream structure for caller. */ aStream = (PABLIO_Stream *) malloc(sizeof(PABLIO_Stream)); switch_assert(aStream); memset(aStream, 0, sizeof(PABLIO_Stream)); if (inputParameters) { channels = inputParameters->channelCount; } else if (outputParameters) { channels = outputParameters->channelCount; } numFrames = RoundUpToNextPowerOf2(samples_per_packet * 5); aStream->bytesPerFrame = bytesPerSample; aStream->channelCount = channels; /* Initialize Ring Buffers */ if (inputParameters) { for (c = 0; c < channels; c++) { err = PABLIO_InitFIFO(&aStream->inFIFOs[c], numFrames, aStream->bytesPerFrame); if (err != paNoError) { goto error; } } aStream->has_in = 1; } if (outputParameters) { for (c = 0; c < channels; c++) { err = PABLIO_InitFIFO(&aStream->outFIFOs[c], numFrames, aStream->bytesPerFrame); if (err != paNoError) { goto error; } } aStream->has_out = 1; } /* Open a PortAudio stream that we will use to communicate with the underlying * audio drivers. */ aStream->do_dual = do_dual; if (aStream->do_dual) { err = Pa_OpenStream(&aStream->istream, inputParameters, NULL, sampleRate, samples_per_packet, streamFlags, iblockingIOCallback, aStream); if (err != paNoError) { goto error; } err = Pa_OpenStream(&aStream->ostream, NULL, outputParameters, sampleRate, samples_per_packet, streamFlags, oblockingIOCallback, aStream); if (err != paNoError) { goto error; } } else { err = Pa_OpenStream(&aStream->iostream, inputParameters, outputParameters, sampleRate, samples_per_packet, streamFlags, ioblockingIOCallback, aStream); } if (err != paNoError) { goto error; } if (aStream->do_dual) { err = Pa_StartStream(aStream->istream); if (err != paNoError) { goto error; } err = Pa_StartStream(aStream->ostream); if (err != paNoError) { goto error; } } else { err = Pa_StartStream(aStream->iostream); } if (err != paNoError) { goto error; } *rwblPtr = aStream; switch_yield(500000); return paNoError; error: CloseAudioStream(aStream); *rwblPtr = NULL; return err; }
/************************************************************ * 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; }
/************************************************************ * 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 numFrames; PaStreamParameters instreamparams, outstreamparams; /* MSP */ /* 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... */ { indeviceno = Pa_GetDefaultInputDevice(); fprintf(stderr, "using default input device number: %d\n", indeviceno); } if (outdeviceno < 0) { outdeviceno = Pa_GetDefaultOutputDevice(); 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 ) { 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; 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 */ 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 ) goto error; } if(doWrite) { long numBytes; err = PABLIO_InitFIFO( &aStream->outFIFO, numFrames, aStream->outbytesPerFrame ); if( err != paNoError ) goto error; /* Make Write FIFO appear full initially. */ numBytes = sys_ringbuf_GetWriteAvailable( &aStream->outFIFO ); sys_ringbuf_AdvanceWriteIndex( &aStream->outFIFO, numBytes ); } /* Open a PortAudio stream that we will use to communicate with the underlying * audio drivers. */ 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 ); if( err != paNoError ) 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; }