예제 #1
0
 private void _DoFree()
 {
     if (_PaHandle != null)
     {
         if (_Stream != IntPtr.Zero)
         {
             _PaHandle.CloseStream(_Stream);
         }
         _PaHandle.Close();
         _PaHandle = null;
     }
     if (_DecoderThread != null)
     {
         if (Thread.CurrentThread.ManagedThreadId != _DecoderThread.ManagedThreadId)
         {
             throw new Exception("Another thread should never free the decoder thread!");
         }
         _DecoderThread = null;
     }
     if (_Decoder != null)
     {
         _Decoder.Close();
         _Decoder = null;
     }
     if (_EventDecode != null)
     {
         _EventDecode.Close();
         _EventDecode = null;
     }
     if (_CloseStreamListener != null)
     {
         _CloseStreamListener.OnCloseStream(this);
     }
 }
예제 #2
0
        /// <summary>
        ///     Stop all voice capturing streams and terminate PortAudio
        /// </summary>
        public override void Close()
        {
            if (_RecHandle != null)
            {
                foreach (IntPtr handle in _RecHandle)
                {
                    if (handle != IntPtr.Zero)
                    {
                        _PaHandle.CloseStream(handle);
                    }
                }
            }
            if (_PaHandle != null)
            {
                _PaHandle.Close();
                _PaHandle = null;
            }

            _Initialized = false;

            base.Close();
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <summary>
        ///     Stop all voice capturing streams and terminate PortAudio
        /// </summary>
        public override void Close()
        {
            if (_RecHandle != null && _RecHandle.Length > 0)
            {
                foreach (IntPtr handle in _RecHandle)
                {
                    if (handle != IntPtr.Zero)
                    {
                        _PaHandle.CloseStream(handle);
                    }
                }

                _RecHandle = new IntPtr[_Devices.Count];
            }
            if (_PaHandle != null)
            {
                _PaHandle.Close();
                _PaHandle = null;
            }

            _Initialized = false;

            base.Close();
        }
예제 #5
0
        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);
        }