JNIEXPORT jint JNICALL Java_com_github_rjeschke_jpa_JPA_paOpenDefaultStream(JNIEnv *env, jclass clazz, jlong jPtr, jint numInputChannels, jint numOutputChannels, jint sampleFormat, jdouble sampleRate, jint frames) { JPA_DATA *j = (JPA_DATA*)long2Ptr(jPtr); j->iFrameSize = (uint32_t)Pa_GetSampleSize((PaSampleFormat)sampleFormat) * (uint32_t)numInputChannels; j->oFrameSize = (uint32_t)Pa_GetSampleSize((PaSampleFormat)sampleFormat) * (uint32_t)numOutputChannels; return Pa_OpenDefaultStream(&(j->stream), (int)numInputChannels, (int)numOutputChannels, (PaSampleFormat)sampleFormat, sampleRate, frames, jpaStreamCallback, j); }
JNIEXPORT jint JNICALL Java_com_github_rjeschke_jpa_JPA_paOpenStream(JNIEnv *env, jclass clazz, jlong jPtr, jobject jInput, jobject jOutput, jdouble sampleRate, jint frames, jint flags) { JPA_DATA *j = (JPA_DATA*)long2Ptr(jPtr); PaStreamParameters *i, *o; i = jInput ? toStreamParameters(env, jInput, &(j->inputParameters)) : 0; o = jOutput ? toStreamParameters(env, jOutput, &(j->outputParameters)) : 0; j->iFrameSize = i ? (uint32_t)Pa_GetSampleSize(i->sampleFormat) * (uint32_t)i->channelCount : 0; j->oFrameSize = o ? (uint32_t)Pa_GetSampleSize(o->sampleFormat) * (uint32_t)o->channelCount : 0; return Pa_OpenStream(&(j->stream), i, o, (double)sampleRate, frames, (PaStreamFlags)flags, jpaStreamCallback, j); }
static OSStatus CopyOutputData(AudioBufferList* destination, PaMacClientData *source, unsigned long frameCount) { int frameSpacing, channelSpacing; if (source->outputSampleFormat & paNonInterleaved) { frameSpacing = 1; channelSpacing = source->outputChannelCount; } else { frameSpacing = source->outputChannelCount; channelSpacing = 1; } AudioBuffer *outputBuffer = &destination->mBuffers[0]; void *coreAudioBuffer = outputBuffer->mData; void *portAudioBuffer = source->outputBuffer; UInt32 i, streamNumber, streamChannel; for (i = streamNumber = streamChannel = 0; i < source->outputChannelCount; ++i, ++streamChannel) { if (streamChannel >= outputBuffer->mNumberChannels) { ++streamNumber; outputBuffer = &destination->mBuffers[streamNumber]; coreAudioBuffer = outputBuffer->mData; streamChannel = 0; } source->outputConverter(coreAudioBuffer, outputBuffer->mNumberChannels, portAudioBuffer, frameSpacing, frameCount, NULL); coreAudioBuffer += sizeof(Float32); portAudioBuffer += Pa_GetSampleSize(source->outputSampleFormat) * channelSpacing; } return noErr; }
static OSStatus CopyInputData(PaMacClientData* destination, const AudioBufferList *source, unsigned long frameCount) { int frameSpacing, channelSpacing; if (destination->inputSampleFormat & paNonInterleaved) { frameSpacing = 1; channelSpacing = destination->inputChannelCount; } else { frameSpacing = destination->inputChannelCount; channelSpacing = 1; } AudioBuffer const *inputBuffer = &source->mBuffers[0]; void *coreAudioBuffer = inputBuffer->mData; void *portAudioBuffer = destination->inputBuffer; UInt32 i, streamNumber, streamChannel; for (i = streamNumber = streamChannel = 0; i < destination->inputChannelCount; ++i, ++streamChannel) { if (streamChannel >= inputBuffer->mNumberChannels) { ++streamNumber; inputBuffer = &source->mBuffers[streamNumber]; coreAudioBuffer = inputBuffer->mData; streamChannel = 0; } destination->inputConverter(portAudioBuffer, frameSpacing, coreAudioBuffer, inputBuffer->mNumberChannels, frameCount, destination->ditherGenerator); coreAudioBuffer += sizeof(Float32); portAudioBuffer += Pa_GetSampleSize(destination->inputSampleFormat) * channelSpacing; } return noErr; }
void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate, PaWinWaveFormatChannelMask channelMask ) { WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat; int bytesPerSample = Pa_GetSampleSize(sampleFormat); unsigned long bytesPerFrame = numChannels * bytesPerSample; GUID guid; waveFormatEx->wFormatTag = WAVE_FORMAT_EXTENSIBLE; waveFormatEx->nChannels = (WORD)numChannels; waveFormatEx->nSamplesPerSec = (DWORD)sampleRate; waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame; waveFormatEx->nBlockAlign = (WORD)bytesPerFrame; waveFormatEx->wBitsPerSample = bytesPerSample * 8; waveFormatEx->cbSize = 22; *((WORD*)&waveFormat->fields[PAWIN_INDEXOF_WVALIDBITSPERSAMPLE]) = waveFormatEx->wBitsPerSample; *((DWORD*)&waveFormat->fields[PAWIN_INDEXOF_DWCHANNELMASK]) = channelMask; guid = pawin_ksDataFormatSubtypeGuidBase; guid.Data1 = (USHORT)waveFormatTag; *((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = guid; }
static bool init_stream(MyStream *v, PaStreamParameters *in, PaStreamParameters *out, long size) { memset(v, 0, sizeof(MyStream)); if (in) { long bufsize = round_pow2(Pa_GetSampleSize(in->sampleFormat)* in->channelCount*size); if (!init_buf(&v->in_buf, &v->in_data, bufsize)) return false; } if (out) { long bufsize = round_pow2(Pa_GetSampleSize(out->sampleFormat)* out->channelCount*size); if (!init_buf(&v->out_buf, &v->out_data, bufsize)) { if (in) fini_buf(&v->in_buf, &v->in_data); return false; } #if 0 { /* fake a full write buffer */ long bytes = MyRingBuffer_GetWriteAvailable(&v->out_buf); MyRingBuffer_AdvanceWriteIndex(&v->out_buf, bytes); } #endif } v->time = 0.0; #ifdef TIMER_KLUDGE v->delta = 0.0; #endif pthread_mutex_init(&v->data_mutex, NULL); if (in) { pthread_mutex_init(&v->in_mutex, NULL); pthread_cond_init(&v->in_cond, NULL); } if (out) { pthread_mutex_init(&v->out_mutex, NULL); pthread_cond_init(&v->out_cond, NULL); } if (current) current->prev = v; v->prev = NULL; v->next = current; current = v; return true; }
static long PortAudio_getFrameSize(PaStreamParameters *streamParameters) { if (streamParameters) { PaError sampleSize = Pa_GetSampleSize(streamParameters->sampleFormat); if (paSampleFormatNotSupported != sampleSize) return sampleSize * streamParameters->channelCount; } return 0; }
static unsigned long PortAudio_getSampleSizeInBits(PaStreamParameters *streamParameters) { if (streamParameters) { PaError sampleSize = Pa_GetSampleSize(streamParameters->sampleFormat); if (paSampleFormatNotSupported != sampleSize) return sampleSize * 8; } return 0; }
JNIEXPORT jint JNICALL Java_org_jpab_PortAudio_openStream(JNIEnv *env, jclass paClass, jobject byte_buffer) { StreamConfiguration * stream_configuration = (StreamConfiguration *) env->GetDirectBufferAddress(byte_buffer); PaStreamParameters * input_parameters, * output_parameters; switch (stream_configuration->mode) { case 1: input_parameters = parameters(stream_configuration->input_channels, stream_configuration->input_device, stream_configuration->input_format, stream_configuration->input_latency); output_parameters = NULL; break; case 2: input_parameters = NULL; output_parameters = parameters(stream_configuration->output_channels, stream_configuration->output_device, stream_configuration->output_format, stream_configuration->output_latency); break; case 3: input_parameters = parameters(stream_configuration->input_channels, stream_configuration->input_device, stream_configuration->input_format, stream_configuration->input_latency); output_parameters = parameters(stream_configuration->output_channels, stream_configuration->output_device, stream_configuration->output_format, stream_configuration->output_latency); break; } PaStream * stream; UserData * data = (UserData *)malloc(sizeof(UserData)); data->input_frame_size = (input_parameters != NULL) ? Pa_GetSampleSize(input_parameters->sampleFormat) * input_parameters->channelCount : 0; data->output_frame_size = (output_parameters != NULL) ? Pa_GetSampleSize(output_parameters->sampleFormat) * output_parameters->channelCount : 0; data->attached = 0; fprintf(stderr, "[JNI] opening stream with frame size: %d. Sample rate: %f\n", data->input_frame_size, stream_configuration->sample_rate); PaError error = Pa_OpenStream(& stream, input_parameters, output_parameters, stream_configuration->sample_rate, paFramesPerBufferUnspecified, stream_configuration->flags, org_jpab_callback, data); if (error != paNoError) { org_jpab_throw_exception(env, & error); return -1; } error = Pa_SetStreamFinishedCallback(stream, org_jpab_hook); if (error != paNoError) { org_jpab_throw_exception(env, & error); return -1; } data->id = (long long) stream; return data->id; }
void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate ) { WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat; int bytesPerSample = Pa_GetSampleSize(sampleFormat); unsigned long bytesPerFrame = numChannels * bytesPerSample; waveFormatEx->wFormatTag = waveFormatTag; waveFormatEx->nChannels = (WORD)numChannels; waveFormatEx->nSamplesPerSec = (DWORD)sampleRate; waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame; waveFormatEx->nBlockAlign = (WORD)bytesPerFrame; waveFormatEx->wBitsPerSample = bytesPerSample * 8; waveFormatEx->cbSize = 0; }
/************************************************************ * 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; }
static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError err = paNoError; PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation *)hostApi; PaMacCoreStream *stream = PaUtil_AllocateMemory(sizeof(PaMacCoreStream)); stream->isActive = 0; stream->isStopped = 1; stream->inputDevice = kAudioDeviceUnknown; stream->outputDevice = kAudioDeviceUnknown; PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, ( (streamCallback) ? &macCoreHostApi->callbackStreamInterface : &macCoreHostApi->blockingStreamInterface ), streamCallback, userData ); PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); *s = (PaStream*)stream; PaMacClientData *clientData = PaUtil_AllocateMemory(sizeof(PaMacClientData)); clientData->stream = stream; clientData->callback = streamCallback; clientData->userData = userData; clientData->inputBuffer = 0; clientData->outputBuffer = 0; clientData->ditherGenerator = PaUtil_AllocateMemory(sizeof(PaUtilTriangularDitherGenerator)); PaUtil_InitializeTriangularDitherState(clientData->ditherGenerator); if (inputParameters != NULL) { stream->inputDevice = macCoreHostApi->macCoreDeviceIds[inputParameters->device]; clientData->inputConverter = PaUtil_SelectConverter(paFloat32, inputParameters->sampleFormat, streamFlags); clientData->inputBuffer = PaUtil_AllocateMemory(Pa_GetSampleSize(inputParameters->sampleFormat) * framesPerBuffer * inputParameters->channelCount); clientData->inputChannelCount = inputParameters->channelCount; clientData->inputSampleFormat = inputParameters->sampleFormat; err = SetUpUnidirectionalStream(stream->inputDevice, sampleRate, framesPerBuffer, 1); } if (err == paNoError && outputParameters != NULL) { stream->outputDevice = macCoreHostApi->macCoreDeviceIds[outputParameters->device]; clientData->outputConverter = PaUtil_SelectConverter(outputParameters->sampleFormat, paFloat32, streamFlags); clientData->outputBuffer = PaUtil_AllocateMemory(Pa_GetSampleSize(outputParameters->sampleFormat) * framesPerBuffer * outputParameters->channelCount); clientData->outputChannelCount = outputParameters->channelCount; clientData->outputSampleFormat = outputParameters->sampleFormat; err = SetUpUnidirectionalStream(stream->outputDevice, sampleRate, framesPerBuffer, 0); } if (inputParameters == NULL || outputParameters == NULL || stream->inputDevice == stream->outputDevice) { AudioDeviceID device = (inputParameters == NULL) ? stream->outputDevice : stream->inputDevice; AudioDeviceAddIOProc(device, AudioIOProc, clientData); } else { // using different devices for input and output AudioDeviceAddIOProc(stream->inputDevice, AudioInputProc, clientData); AudioDeviceAddIOProc(stream->outputDevice, AudioOutputProc, clientData); } return err; }
JNIEXPORT jint JNICALL Java_com_github_rjeschke_jpa_JPA_paGetSampleSize(JNIEnv *env, jclass clazz, jint format) { return (jint)Pa_GetSampleSize((PaSampleFormat)format); }
JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_portaudio_PortAudio_Pa_1GetSampleSize (JNIEnv *env, jclass clazz, jlong format) { return Pa_GetSampleSize(format); }
/************************************************************ * 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; }
pure_expr *open_audio_stream(int *in, int *out, double sr, long size, int flags) { PaStreamParameters inparams, outparams, *inptr = NULL, *outptr = NULL; MyStream *v; PaError err; int in_bps = 0, out_bps = 0; const PaStreamInfo* info; #ifdef HAVE_POSIX_SIGNALS sigset_t sigset, oldset; #endif if (!init_ok) return 0; if (size <= 0) size = 512; /* Initialize parameters. */ if (in && in[1]>0) { memset(&inparams, 0, sizeof(inparams)); inparams.device = in[0]; inparams.channelCount = in[1]; inparams.sampleFormat = in[2]; inparams.suggestedLatency = in[3] ? Pa_GetDeviceInfo(in[0])->defaultLowInputLatency : Pa_GetDeviceInfo(in[0])->defaultHighInputLatency; inparams.hostApiSpecificStreamInfo = 0; inptr = &inparams; in_bps = Pa_GetSampleSize(inparams.sampleFormat); if (in_bps <= 0) return 0; } else in = 0; if (out && out[1]>0) { memset(&outparams, 0, sizeof(outparams)); outparams.device = out[0]; outparams.channelCount = out[1]; outparams.sampleFormat = out[2]; outparams.suggestedLatency = out[3] ? Pa_GetDeviceInfo(out[0])->defaultLowOutputLatency : Pa_GetDeviceInfo(out[0])->defaultHighOutputLatency; outparams.hostApiSpecificStreamInfo = 0; outptr = &outparams; out_bps = Pa_GetSampleSize(outparams.sampleFormat); if (out_bps <= 0) return 0; } else out = 0; /* Initialize the Pure stream descriptor. This is passed to the callback data and also to the sentry on the stream object, so that we can perform proper cleanup when a stream is closed or gets garbage-collected. */ if (!(v = malloc(sizeof(MyStream)))) return 0; if (!init_stream(v, inptr, outptr, size)) { free(v); return 0; } /* Open the PortAudio stream. */ err = Pa_OpenStream(&v->as, inptr, outptr, sr, size, flags, audio_cb, v); if (err != paNoError) { destroy_stream(v); free(v); return pure_int(err); } /* Fill in needed information about the stream. */ info = Pa_GetStreamInfo(v->as); v->in = in?inparams.device:paNoDevice; v->out = out?outparams.device:paNoDevice; v->sample_rate = info?info->sampleRate:sr; v->size = size; /* Looks like these are sometimes bogus for some drivers and devices, but we store them anyway. */ v->in_latency = info?info->inputLatency:0; v->out_latency = info?info->outputLatency:0; v->in_channels = in?inparams.channelCount:0; v->out_channels = out?outparams.channelCount:0; v->in_format = in?inparams.sampleFormat:0; v->out_format = out?outparams.sampleFormat:0; v->in_bps = in_bps; v->out_bps = out_bps; v->in_bpf = in_bps*v->in_channels; v->out_bpf = out_bps*v->out_channels; /* Start the stream. */ #ifdef HAVE_POSIX_SIGNALS /* temporarily block some signals to make sure that they are blocked in the PortAudio threads created by Pa_StartStream */ sigemptyset(&sigset); sigaddset(&sigset, SIGINT); sigaddset(&sigset, SIGQUIT); sigaddset(&sigset, SIGTSTP); sigaddset(&sigset, SIGTERM); sigaddset(&sigset, SIGHUP); sigprocmask(SIG_BLOCK, &sigset, &oldset); #endif Pa_StartStream(v->as); #ifdef HAVE_POSIX_SIGNALS sigprocmask(SIG_SETMASK, &oldset, NULL); #endif /* Note that we return the real PortAudio stream here, so that it can be passed to other (low-level) PortAudio operations. Our own stream data is kept in the sentry we set on the stream so that we can perform the necessary cleanup. */ return pure_sentry (pure_app(pure_symbol(pure_sym("audio::audio_sentry")), pure_pointer(v)), pure_pointer(v->as)); }
/************************************************************ * 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; }
RTC::ReturnCode_t PortAudioInput::onActivated(RTC::UniqueId ec_id) { RTC_DEBUG(("onActivated start")); PaStreamParameters inputParameters; // PaWasapiStreamInfo wasapiinfo; try { //m_pa_mutex.lock(); //by Irie Seisho m_format = getFormat(m_formatstr); m_totalframes = FRAMES_PER_BUFFER * m_channels; m_err = Pa_GetSampleSize(m_format); if( m_err > 0 ) { m_totalframes *= m_err; } #if 0 /* Find all WASAPI devices */ const PaDeviceInfo *device; for ( int i = 0; i < Pa_GetDeviceCount(); ++i ) { device = Pa_GetDeviceInfo(i); if ( Pa_GetDeviceInfo(i)->hostApi == Pa_HostApiTypeIdToHostApiIndex(paWASAPI) ) { std::cout << "Device Index " << i << " : " << device->name << ", inch " << device->maxInputChannels << ", outch " << device->maxOutputChannels << std::endl; } } //#if 0 PaDeviceIndex dnum = Pa_GetDeviceCount(); for (int i = 0; i < (int)dnum; i++) { std::cout << "Device Index " << i << " : " << Pa_GetDeviceInfo(i)->name << ", inch " << Pa_GetDeviceInfo(i)->maxInputChannels << ", outch " << Pa_GetDeviceInfo(i)->maxOutputChannels << std::endl; } //#endif void *pFormat; unsigned int nFormatSize; PaDeviceIndex nDevice; int r = PaWasapi_GetDeviceDefaultFormat(pFormat, nFormatSize, nDevice); #endif inputParameters.device = Pa_GetDefaultInputDevice(); //!< default input device if ( inputParameters.device < 0 ) { throw (paNotInitialized); } if ( m_channels > Pa_GetDeviceInfo(inputParameters.device)->maxInputChannels ) m_channels = Pa_GetDeviceInfo(inputParameters.device)->maxInputChannels; inputParameters.channelCount = m_channels; inputParameters.sampleFormat = m_format; inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; /* wasapiinfo.size = sizeof(PaWasapiStreamInfo); wasapiinfo.hostApiType = paWASAPI; wasapiinfo.version = 1; wasapiinfo.flags = paWasapiUseChannelSelectors; wasapiinfo.hostProcessorInput wasapiinfo.threadPriority wasapiinfo.channelMask = outputChannelSelectors; inputParameters.hostApiSpecificStreamInfo = wasapiinfo; */ inputParameters.hostApiSpecificStreamInfo = NULL; m_err = Pa_OpenStream( &m_stream, //!< PortAudioStream &inputParameters, //!< InputParameters NULL, //!< outputParameters m_samplerate, //!< sampleRate FRAMES_PER_BUFFER, //!< framesPerBuffer paClipOff, //!< streamFlags:we won't output out of range samples so don't bother clipping // StreamCB, //!< streamCallback // this ); //!< callback userData NULL, //!< streamCallback:no callback, use blocking API NULL ); //!< no callback, so no callback userData if( m_err != paNoError ) { throw m_err; } #ifdef HAVE_LIBPORTMIXER m_mixer = Px_OpenMixer( m_stream, 0 ); m_volume = Px_GetInputVolume( m_mixer ); #else #if defined(_WIN32) if ( InitMixer() == true ) { DWORD vol; GetMicrophoneLevel(&vol); } else { CloseMixer(); } #elif defined(__linux) const char* sound_device_names[] = SOUND_DEVICE_NAMES; m_device = -1; m_fd = -1; for ( int i = 0; i < SOUND_MIXER_NRDEVICES; i ++ ) { std::cout << " device name : " << sound_device_names[i] << std::endl; if ( strcmp( "mic", sound_device_names[i] ) == 0 ) { m_device = i; break; } } if ( ( m_fd = open( "/dev/mixer", O_RDONLY ) ) == -1 ) { perror( "open" ); } #endif #endif m_err = Pa_StartStream( m_stream ); if( m_err != paNoError ) { throw m_err; } //m_pa_mutex.unlock(); //by Irie Seisho } catch (...) { std::string error_str = Pa_GetErrorText(m_err); RTC_WARN(("PortAudio failed onActivated:%s", error_str.c_str())); return RTC::RTC_ERROR; } syncflg = true; is_active = true; RTC_DEBUG(("onActivated finish")); return RTC::RTC_OK; }