PaError IPortAudio::configure_InputDevice(long FrameSize) { #if defined(TARGET_WINDOWS) // configure HostAPI audio channels if(m_UsedInputHostAPI == paASIO) { // Configure ASIO device m_InputParameters.hostApiSpecificStreamInfo = new PaAsioStreamInfo; memset(m_InputParameters.hostApiSpecificStreamInfo, 0, sizeof(PaAsioStreamInfo)); ((PaAsioStreamInfo*)m_InputParameters.hostApiSpecificStreamInfo)->size = sizeof(PaAsioStreamInfo); ((PaAsioStreamInfo*)m_InputParameters.hostApiSpecificStreamInfo)->hostApiType = paASIO; ((PaAsioStreamInfo*)m_InputParameters.hostApiSpecificStreamInfo)->version = 1; ((PaAsioStreamInfo*)m_InputParameters.hostApiSpecificStreamInfo)->flags = paAsioUseChannelSelectors; ((PaAsioStreamInfo*)m_InputParameters.hostApiSpecificStreamInfo)->channelSelectors = new int[m_InputParameters.channelCount]; for(int ch = 0; ch < m_InputParameters.channelCount; ch++) { ((PaAsioStreamInfo*)m_InputParameters.hostApiSpecificStreamInfo)->channelSelectors[ch] = ch; } } else if(m_UsedInputHostAPI == paWASAPI) { if(m_InputParameters.channelCount < m_InputDeviceInfo.deviceInfo->maxInputChannels) { // try to set WASAPI exclusive mode m_InputParameters.hostApiSpecificStreamInfo = new PaWasapiStreamInfo; memset(m_InputParameters.hostApiSpecificStreamInfo, 0, sizeof(PaWasapiStreamInfo)); ((PaWasapiStreamInfo*)m_InputParameters.hostApiSpecificStreamInfo)->hostApiType = paWASAPI; ((PaWasapiStreamInfo*)m_InputParameters.hostApiSpecificStreamInfo)->version = 1; ((PaWasapiStreamInfo*)m_InputParameters.hostApiSpecificStreamInfo)->size = sizeof(PaWasapiStreamInfo); ((PaWasapiStreamInfo*)m_InputParameters.hostApiSpecificStreamInfo)->flags = paWinWasapiExclusive; PaWinWaveFormat waveFormat; if(PaWasapi_GetDeviceDefaultFormat(&waveFormat, sizeof(PaWinWaveFormat), m_InputDeviceInfo.paDeviceIdx) < 0) { return paIncompatibleHostApiSpecificStreamInfo; } // TODO: check how to set channelMask and how to use waveFormat information //((PaWasapiStreamInfo*)m_InputParameters.hostApiSpecificStreamInfo)->channelMask = } else { m_InputParameters.hostApiSpecificStreamInfo = NULL; } } else { m_InputParameters.hostApiSpecificStreamInfo = NULL; } // configure device latency/bufferSize if(m_UsedInputHostAPI == paASIO) { long minBufferSizeFrames; long maxBufferSizeFrames; long preferredBufferSizeFrames; long granularity; PaError paErr = PaAsio_GetAvailableBufferSizes(m_InputParameters.device, &minBufferSizeFrames, &maxBufferSizeFrames, &preferredBufferSizeFrames, &granularity); if(paErr != paNoError) { return paErr; } cout << "ASIO minimum buffer size " << minBufferSizeFrames << endl; cout << "ASIO maximum buffer size " << maxBufferSizeFrames << endl; cout << "ASIO preferred buffer size " << preferredBufferSizeFrames << endl; if(granularity == -1) { cout << "ASIO buffer granularity is power of 2" << endl; } else { cout << "ASIO buffer granularity: " << granularity << endl; } if(FrameSize < 0) { m_InputFrameSize = (unsigned long)preferredBufferSizeFrames; } else if(FrameSize > maxBufferSizeFrames) { m_InputFrameSize = (unsigned long)maxBufferSizeFrames; } else { m_InputFrameSize = (unsigned long)FrameSize; } } else { if(FrameSize <= 0) { FrameSize = 2048; } else { m_InputFrameSize = FrameSize; } } #endif return paNoError; }
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; }