Beispiel #1
0
        public int Release()
        {
            Marshal.FreeHGlobal(this.pwfx_free);
            Marshal.Release(this.pdscb8);
            Marshal.Release(this.pdsc8);
            //Marshal.ReleaseComObject(this.dscb8);
            //Marshal.ReleaseComObject(this.dsc8);
            Marshal.FinalReleaseComObject(this.dscb8);
            Marshal.FinalReleaseComObject(this.dsc8);

            this.pwfx_free = IntPtr.Zero;

            this.pdscb8 = IntPtr.Zero;
            this.pdsc8  = IntPtr.Zero;

            this.dscb8 = null;
            this.dsc8  = null;

            foreach (var hwnd in this.notifyHwnd_close)
            {
                LibNatives.CloseHandle(hwnd);
            }
            this.notifyHwnd_close = null;

            return(LibErrors.SUCCESS);
        }
Beispiel #2
0
        public int Stop()
        {
            if (!this.isInit)
            {
                return(LibErrors.NOT_INITIALIZED);
            }

            if (this.stream == null)
            {
                return(LibErrors.STREAM_NOT_OPENED);
            }

            this.isPlaying = false;

            uint dsErr = this.dsb8.Stop();

            if (dsErr != DSERR.DS_OK)
            {
                LibUtils.PrintLog("Stop失败, DSERR = {0}", dsErr);
            }

            this.stream.Seek(0);

            LibNatives.SetEvent(this.notifyHwnd_close[0]);

            return(LibErrors.SUCCESS);
        }
Beispiel #3
0
        public int Release()
        {
            if (!this.isInit)
            {
                return(LibErrors.SUCCESS);
            }

            this.isInit = false;

            Marshal.FreeHGlobal(this.pwfx_free);
            Marshal.Release(this.pdsb8);
            Marshal.Release(this.pds8);
            //Marshal.ReleaseComObject(this.dsb8);
            //Marshal.ReleaseComObject(this.ds8);
            Marshal.FinalReleaseComObject(this.dsb8);
            Marshal.FinalReleaseComObject(this.ds8);

            this.pwfx_free = IntPtr.Zero;

            this.pdsb8 = IntPtr.Zero;
            this.pds8  = IntPtr.Zero;

            this.dsb8 = null;
            this.ds8  = null;

            foreach (var item in notifyHwnd_close)
            {
                LibNatives.CloseHandle(item);
            }
            this.notifyHwnd_close = null;
            this.rgdsbpn          = null;

            return(LibErrors.SUCCESS);
        }
Beispiel #4
0
        private bool CreateBufferNotifications()
        {
            uint dsErr = DSERR.DS_OK;

            // 获取IDirectSoundNotify8接口
            Guid   iid_dsNotify8 = new Guid(IID.IID_IDirectSoundNotify8);
            IntPtr pdsNotify8;
            IDirectSoundNotify8 dsNotify8;

            Marshal.QueryInterface(this.pdscb8, ref iid_dsNotify8, out pdsNotify8);
            dsNotify8 = Marshal.GetObjectForIUnknown(pdsNotify8) as IDirectSoundNotify8;

            try
            {
                tWAVEFORMATEX wfx;
                int           pdwSizeWritten;
                dsErr = this.dscb8.GetFormat(out wfx, Marshal.SizeOf(typeof(tWAVEFORMATEX)), out pdwSizeWritten);
                if (dsErr != DSERR.DS_OK)
                {
                    LibUtils.PrintLog("GetFormat失败, DSERROR = {0}", dsErr);
                    return(false);
                }

                _DSBPOSITIONNOTIFY[] rgdsbpn = new _DSBPOSITIONNOTIFY[LibConsts.NotifyEvents];
                this.notifyHwnd_close = new IntPtr[LibConsts.NotifyEvents];
                for (int i = 0; i < LibConsts.NotifyEvents; i++)
                {
                    this.notifyHwnd_close[i] = LibNatives.CreateEvent(IntPtr.Zero, true, false, null);
                }

                rgdsbpn[0].dwOffset     = (uint)(wfx.nAvgBytesPerSec - 1);
                rgdsbpn[0].hEventNotify = this.notifyHwnd_close[0];

                rgdsbpn[1].dwOffset     = LibNatives.DSBPN_OFFSETSTOP;
                rgdsbpn[1].hEventNotify = this.notifyHwnd_close[1];

                dsErr = dsNotify8.SetNotificationPositions(LibConsts.NotifyEvents, Marshal.UnsafeAddrOfPinnedArrayElement(rgdsbpn, 0));
                if (dsErr != DSERR.DS_OK)
                {
                    LibUtils.PrintLog("SetNotificationPositions失败, DSERROR = {0}", dsErr);
                    return(false);
                }
            }
            finally
            {
                Marshal.Release(pdsNotify8);
            }

            return(true);
        }
Beispiel #5
0
        private bool CreateIDirectSoundCapture8()
        {
            uint dsErr = DSERR.DS_OK;

            dsErr = LibNatives.DirectSoundCaptureCreate8(IntPtr.Zero, out this.pdsc8, IntPtr.Zero);
            if (dsErr != DSERR.DS_OK)
            {
                LibUtils.PrintLog("DirectSoundCaptureCreate8失败, DSERROR = {0}", dsErr);
                return(false);
            }

            this.dsc8 = Marshal.GetObjectForIUnknown(this.pdsc8) as IDirectSoundCapture8;

            return(true);
        }
Beispiel #6
0
        private bool CreateBufferNotifications()
        {
            uint dsErr = DSERR.DS_OK;

            // 获取IDirectSoundNotify8接口
            Guid   iid_dsNotify8 = new Guid(IID.IID_IDirectSoundNotify8);
            IntPtr pdsNotify8;
            IDirectSoundNotify8 dsNotify8;

            Marshal.QueryInterface(this.pdsb8, ref iid_dsNotify8, out pdsNotify8);
            dsNotify8 = Marshal.GetObjectForIUnknown(pdsNotify8) as IDirectSoundNotify8;

            try
            {
                uint          written;
                tWAVEFORMATEX wfx;
                dsErr = this.dsb8.GetFormat(out wfx, (uint)Marshal.SizeOf(typeof(tWAVEFORMATEX)), out written);
                if (dsErr != DSERR.DS_OK)
                {
                    LibUtils.PrintLog("GetFormat失败, DSERR = {0}", dsErr);
                    return(false);
                }

                this.rgdsbpn          = new _DSBPOSITIONNOTIFY[LibConsts.BUFF_NOTIFY_TIMES];
                this.notifyHwnd_close = new IntPtr[LibConsts.BUFF_NOTIFY_TIMES];
                for (int idx = 0; idx < LibConsts.BUFF_NOTIFY_TIMES; idx++)
                {
                    IntPtr pHandle = LibNatives.CreateEvent(IntPtr.Zero, false, false, null);
                    this.notifyHwnd_close[idx]     = pHandle;
                    this.rgdsbpn[idx].dwOffset     = (uint)(LibConsts.BUFF_NOTIFY_SIZE * idx);
                    this.rgdsbpn[idx].hEventNotify = pHandle;
                }

                dsErr = dsNotify8.SetNotificationPositions(LibConsts.BUFF_NOTIFY_TIMES, Marshal.UnsafeAddrOfPinnedArrayElement(rgdsbpn, 0));
                if (dsErr != DSERR.DS_OK)
                {
                    LibUtils.PrintLog("SetNotificationPositions失败, DSERROR = {0}", dsErr);
                    return(false);
                }
            }
            finally
            {
                Marshal.Release(pdsNotify8);
            }

            return(true);
        }
Beispiel #7
0
        //public int Pause()
        //{
        //    return DSERR.DS_OK;
        //}

        //public int Restore()
        //{
        //    return DSERR.DS_OK;
        //}

        #endregion

        #region 实例方法

        private bool CreateIDirectSound8(IntPtr hwnd)
        {
            uint dsErr = LibNatives.DirectSoundCreate8(IntPtr.Zero, out this.pds8, IntPtr.Zero);

            if (dsErr != DSERR.DS_OK)
            {
                LibUtils.PrintLog("DirectSoundCreate8失败, DSERR = {0}", dsErr);
                return(false);
            }

            this.ds8 = Marshal.GetObjectForIUnknown(this.pds8) as IDirectSound8;

            dsErr = this.ds8.SetCooperativeLevel(hwnd, DSSCL.DSSCL_NORMAL);
            if (dsErr != DSERR.DS_OK)
            {
                LibUtils.PrintLog("SetCooperativeLevel失败, DSERR = {0}", dsErr);
                return(false);
            }

            return(true);
        }
Beispiel #8
0
        public int Play()
        {
            if (!this.isInit)
            {
                return(LibErrors.NOT_INITIALIZED);
            }

            if (this.stream == null)
            {
                return(LibErrors.STREAM_NOT_OPENED);
            }

            this.dsb8.SetCurrentPosition(0);
            uint dsErr = this.dsb8.Play(0, 0, DSBPLAY.DSBPLAY_LOOPING);

            if (dsErr != DSERR.DS_OK)
            {
                LibUtils.PrintLog("Play失败, DSERR = {0}", dsErr);
                return(LibErrors.DS_ERROR);
            }

            this.isPlaying = true;

            this.NotifyStatusChanged(DSLibPlayerStatus.Playing, 0);

            uint offset = (uint)LibConsts.BUFF_NOTIFY_SIZE;

            Task.Factory.StartNew((state) =>
            {
                while (this.isPlaying)
                {
                    IntPtr lpHandles = Marshal.UnsafeAddrOfPinnedArrayElement(this.notifyHwnd_close, 0);

                    uint notifyIdx = LibNatives.WaitForMultipleObjects(LibConsts.BUFF_NOTIFY_TIMES, lpHandles, false, LibNatives.INFINITE);
                    if ((notifyIdx >= LibNatives.WAIT_OBJECT_0) && (notifyIdx <= LibNatives.WAIT_OBJECT_0 + LibConsts.BUFF_NOTIFY_TIMES))
                    {
                        if (!this.isPlaying)
                        {
                            // 通知是异步的,在调用了Stop之后, 如果收到通知的速度比音频流Seek(0)的速度慢(也就是说先重置了音频流,然后又收到了一次通知), 有可能会再次读取一次数据
                            break;
                        }

                        this.HandleNotification(offset, LibConsts.BUFF_NOTIFY_SIZE, state as SynchronizationContext);

                        offset += (uint)LibConsts.BUFF_NOTIFY_SIZE;
                        offset %= (uint)(LibConsts.BUFF_NOTIFY_SIZE * LibConsts.BUFF_NOTIFY_TIMES);

                        //Console.WriteLine("dwOffset = {0}, offset = {1}", this.rgdsbpn[notifyIdx].dwOffset, offset);
                    }
                    else if (notifyIdx == LibNatives.WAIT_FAILED)
                    {
                        int winErr = Marshal.GetLastWin32Error();

                        LibUtils.PrintLog("等待信号失败, LastWin32Error = {0}", winErr);
                        (state as SynchronizationContext).Send((o) =>
                        {
                            this.Stop();
                        }, null);
                        this.NotifyStatusChanged(DSLibPlayerStatus.Error, winErr);
                    }
                }

                LibUtils.PrintLog("跳出循环");
            }, SynchronizationContext.Current);

            return(LibErrors.SUCCESS);
        }
Beispiel #9
0
        public int Start()
        {
            uint dsErr = this.dscb8.Start(LibNatives.DSCBSTART_LOOPING);

            if (dsErr != DSERR.DS_OK)
            {
                LibUtils.PrintLog("开始录音失败, DSERROR = {0}", dsErr);
                return(LibErrors.DS_ERROR);
            }

            this.isRunning = true;

            Task.Factory.StartNew((state) =>
            {
                while (this.isRunning)
                {
                    // 这里需要实时获取通知对象的指针, 因为这个指针的值每隔一段时间会改变。。。
                    IntPtr lpHandles = Marshal.UnsafeAddrOfPinnedArrayElement(this.notifyHwnd_close, 0);

                    // DSLibNatives.WaitForSingleObject(this.close_notifyHwnd[0], DSLibNatives.INFINITE);
                    switch (LibNatives.WaitForMultipleObjects(LibConsts.NotifyEvents, lpHandles, false, LibNatives.INFINITE))
                    {
                    case LibNatives.WAIT_OBJECT_0:
                        {
                            (state as SynchronizationContext).Send((o) =>
                            {
                                try
                                {
                                    byte[] audioData = null;
                                    if (this.RecordCapturedData(0, (uint)this.wfx.nAvgBytesPerSec, out audioData) == DSERR.DS_OK)
                                    {
                                        if (this.OnCaptured != null)
                                        {
                                            this.OnCaptured(audioData);
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    LibUtils.PrintLog("保存音频流异常, Exception = {0}", ex);
                                }
                            }, null);

                            LibNatives.ResetEvent(this.notifyHwnd_close[0]);
                        }
                        break;

                    case LibNatives.WAIT_OBJECT_0 + 1:
                        {
                            // 录音结束
                            LibNatives.ResetEvent(this.notifyHwnd_close[1]);

                            this.isRunning = false;
                        }
                        break;

                    case LibNatives.WAIT_FAILED:
                        {
                            int error = Marshal.GetLastWin32Error();

                            // 失败, 句柄已经被销毁
                            LibUtils.PrintLog("WAIT_FAILED, LastWin32Error = {0}", error);

                            this.isRunning = false;

                            this.Stop();

                            if (this.OnError != null)
                            {
                                this.OnError(error);
                            }
                        }
                        break;
                    }
                }
            }, SynchronizationContext.Current);

            return(LibErrors.SUCCESS);
        }
Beispiel #10
0
 public override int StartTask()
 {
     return(LibNatives.ElevateProcessHandles(processID, handles.Count, handles.ToArray(),
                                             newAccessMasks.ToArray(), fnErrorOccured));
 }
Beispiel #11
0
 public override int StartTask()
 {
     return(LibNatives.GetProcessHandles(processID, fnHandleFound, fnErrorOccured));
 }