/// <summary> /// Init PortAudio and list record devices /// </summary> /// <returns>true if success</returns> public override bool Init() { if (!base.Init()) { return(false); } try { _PaHandle = new CPortAudioHandle(); int hostAPI = _PaHandle.GetHostApi(); int numDevices = PortAudioSharp.PortAudio.Pa_GetDeviceCount(); for (int i = 0; i < numDevices; i++) { PortAudioSharp.PortAudio.PaDeviceInfo info = PortAudioSharp.PortAudio.Pa_GetDeviceInfo(i); if (info.hostApi == hostAPI && info.maxInputChannels > 0) { var dev = new CRecordDevice(i, info.name, info.name + i, info.maxInputChannels); _Devices.Add(dev); } } _RecHandle = new IntPtr[_Devices.Count]; _MyRecProc = _MyPaStreamCallback; _Initialized = true; } catch (Exception e) { _Initialized = false; CLog.LogError("Error initializing PortAudio: " + e.Message); Close(); return(false); } return(true); }
public override bool Open(bool prescan) { Debug.Assert(!_FileOpened); if (_FileOpened) { return(false); } if (!File.Exists(_Medium)) { Dispose(); return(false); } try { _PaHandle = new CPortAudioHandle(); int hostApi = _PaHandle.GetHostApi(); _ApiInfo = PortAudioSharp.PortAudio.Pa_GetHostApiInfo(hostApi); _OutputDeviceInfo = PortAudioSharp.PortAudio.Pa_GetDeviceInfo(_ApiInfo.defaultOutputDevice); if (_OutputDeviceInfo.defaultLowOutputLatency < 0.1) { _OutputDeviceInfo.defaultLowOutputLatency = 0.1; } _PaStreamCallback = _ProcessNewData; } catch (Exception) { Dispose(); CLog.Error("Error Init PortAudio Playback"); return(false); } _Decoder = new CAudioDecoderFFmpeg(); if (!_Decoder.Open(_Medium)) { Dispose(); CLog.Error("Error opening audio file: " + _Medium); return(false); } SFormatInfo format = _Decoder.GetFormatInfo(); if (format.SamplesPerSecond == 0) { Dispose(); CLog.Error("Error Init PortAudio Playback (samples=0)"); return(false); } Length = _Decoder.GetLength(); _ByteCount = 2 * format.ChannelCount; _BytesPerSecond = format.SamplesPerSecond * _ByteCount; _SyncTimer.Pause(); _SyncTimer.Time = 0f; PortAudioSharp.PortAudio.PaStreamParameters?outputParams = new PortAudioSharp.PortAudio.PaStreamParameters { channelCount = format.ChannelCount, device = _ApiInfo.defaultOutputDevice, sampleFormat = PortAudioSharp.PortAudio.PaSampleFormat.paInt16, suggestedLatency = _OutputDeviceInfo.defaultLowOutputLatency, hostApiSpecificStreamInfo = IntPtr.Zero }; if (!_PaHandle.OpenOutputStream( out _Stream, ref outputParams, format.SamplesPerSecond, (uint)CConfig.Config.Sound.AudioBufferSize / 2, PortAudioSharp.PortAudio.PaStreamFlags.paNoFlag, _PaStreamCallback, IntPtr.Zero) || _Stream == IntPtr.Zero) { Dispose(); return(false); } _Latency = CConfig.Config.Sound.AudioLatency / 1000f + (float)PortAudioSharp.PortAudio.Pa_GetStreamInfo(_Stream).outputLatency; //From now on closing the driver and the decoder is handled by the thread ONLY! _Paused = true; _FileOpened = true; _Data = new CRingBuffer(_Bufsize); _NoMoreData = false; _DecoderThread = new Thread(_Execute) { Priority = ThreadPriority.Normal, Name = Path.GetFileName(_Medium) }; _DecoderThread.Start(); return(true); }