예제 #1
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);
        }
예제 #2
0
        /// <summary>
        /// 打开音频源
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public int Open(IAudioSource source)
        {
            if (this.stream != null)
            {
                this.Close();
            }

            this.stream = IAudioStream.Create(source);
            if (this.stream == null)
            {
                LibUtils.PrintLog("不支持的音频源:{0}", source);
                return(LibErrors.NOT_SUPPORTED);
            }

            int ret = this.stream.Open();

            if (ret != LibErrors.SUCCESS)
            {
                return(ret);
            }

            this.stream.PlaybackProgressChanged += this.Stream_PlaybackProgressChanged;
            this.stream.DownloadProgressChanged += this.Stream_DownloadProgressChanged;

            return(LibErrors.SUCCESS);
        }
예제 #3
0
        private int RecordCapturedData(uint offset, uint dataSize, out byte[] audioData)
        {
            audioData = null;
            IntPtr pbCaptureData;
            int    dwCaptureLength;
            IntPtr pbCaptureData2;
            int    dwCaptureLength2;
            uint   dsErr = DSERR.DS_OK;

            dsErr = this.dscb8.Lock(offset, dataSize, out pbCaptureData, out dwCaptureLength, out pbCaptureData2, out dwCaptureLength2, 0);
            if (dsErr != DSERR.DS_OK)
            {
                LibUtils.PrintLog("Lock失败, DSERROR = {0}", dsErr);
                return(LibErrors.DS_ERROR);
            }

            // Unlock the capture buffer.
            this.dscb8.Unlock(pbCaptureData, dwCaptureLength, pbCaptureData2, dwCaptureLength2);

            // 拷贝音频数据
            int audioLength = dwCaptureLength + dwCaptureLength2;

            audioData = new byte[audioLength];
            Marshal.Copy(pbCaptureData, audioData, 0, dwCaptureLength);
            if (pbCaptureData2 != IntPtr.Zero)
            {
                Marshal.Copy(pbCaptureData2, audioData, dwCaptureLength, dwCaptureLength2);
            }

            return(LibErrors.SUCCESS);
        }
예제 #4
0
        static Library()
        {
            utils = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
                           ? (LibUtils) new WindowsLibUtils()
                           : (LibUtils) new UnixLibUtils();

            filename = Environment.GetEnvironmentVariable("YOGI_CORE_LIBRARY");
            if (filename == null)
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    string architecture = System.Environment.Is64BitProcess ? "x64" : "x86";
                    filename = $"yogi-core-{architecture}.dll";
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    filename = "libyogi-core.dylib";
                }
                else
                {
                    filename = "libyogi-core.so";
                }
            }

            dll = utils.LoadLibrary(filename);
            CheckVersionCompatibility();
        }
예제 #5
0
        public async Task <string> ExtractTextAsync(string fileName)
        {
            var temp = LibUtils.RandomTempFile("txt");
            var args = ParseParameters();

            args.Add(LibUtils.QuotedStr(fileName));
            args.Add(LibUtils.QuotedStr(temp));

            var programName = LibUtils.GetProgramName(ProgramBaseName);
            var fullArgs    = LibUtils.ParseParameters(args);
            var workDir     = LibUtils.WorkDirectory;

            await CustomProcess.RunProcessAsync(programName, fullArgs, workDir);

            if (!File.Exists(temp))
            {
                return(string.Empty);
            }

            var text = await File.ReadAllTextAsync(temp);

            File.Delete(temp);

            return(text);
        }
예제 #6
0
        public int Initialize()
        {
            #region waveInOpen

            WAVEFORMATEX wfx = new WAVEFORMATEX()
            {
                nChannels       = Channels,
                nSamplesPerSec  = SamplesPerSec,
                wBitsPerSample  = BitsPerSample,
                nBlockAlign     = BlockAlign,
                nAvgBytesPerSec = (uint)(BlockAlign * SamplesPerSec),
                cbSize          = 0,
                wFormatTag      = 1
            };
            this.free_pwfx     = LibUtils.StructureToPtr(wfx);
            this.waveInProcDlg = new waveNatives.waveInProcDlg(this.waveInProc);
            int retValue = waveNatives.waveInOpen(out this.hwi, waveNatives.WAVE_MAPPER, this.free_pwfx, this.waveInProcDlg, 0, waveNatives.WAVE_FORMAT_DIRECT | waveNatives.CALLBACK_FUNCTION);
            if (retValue != MMSYSERR.MMSYSERR_NOERROR)
            {
                LibUtils.PrintLog("waveInOpen失败, MMSYSERROR = {0}", retValue);
                return(retValue);
            }

            #endregion

            #region waveInPrepareHeader

            wavehdr_tag wh = new wavehdr_tag()
            {
                lpData         = this.free_pAudioData = Marshal.AllocHGlobal((int)(BlockAlign * SamplesPerSec)),
                dwBufferLength = (BlockAlign * SamplesPerSec),
                dwFlags        = 0x00000002
            };
            this.whSize   = Marshal.SizeOf(typeof(wavehdr_tag));
            this.free_pwh = LibUtils.StructureToPtr(wh);
            retValue      = waveNatives.waveInPrepareHeader(hwi, this.free_pwh, (uint)this.whSize);
            if (retValue != MMSYSERR.MMSYSERR_NOERROR)
            {
                LibUtils.PrintLog("waveInPrepareHeader失败, MMSYSERROR = {0}", retValue);
                return(retValue);
            }

            #endregion

            #region waveInAddBuffer

            retValue = waveNatives.waveInAddBuffer(hwi, this.free_pwh, (uint)this.whSize);
            if (retValue != MMSYSERR.MMSYSERR_NOERROR)
            {
                LibUtils.PrintLog("waveInAddBuffer失败, MMSYSERROR = {0}", retValue);
                return(retValue);
            }

            #endregion

            return(MMSYSERR.MMSYSERR_NOERROR);
        }
예제 #7
0
 /// <summary>
 /// Initialisiert das Singletonanwendungsobjekt. Dies ist die erste Zeile von erstelltem Code
 /// und daher das logische Äquivalent von main() bzw. WinMain().
 /// </summary>
 public App()
 {
     SignalFileLoggerProvider.ForceAddUILog(LibUtils.GetAppStartMessage());
     Instance = this;
     SignalLogging.SetupLogging(true);
     this.InitializeComponent();
     this.UnhandledException += OnUnhandledException;
     this.Suspending         += App_Suspending;
     this.Resuming           += App_Resuming;
 }
예제 #8
0
        public int Stop()
        {
            uint dsErr = this.dscb8.Stop();

            if (dsErr != DSERR.DS_OK)
            {
                LibUtils.PrintLog("停止录音失败, DSERR = {0}", dsErr);
            }

            return(LibErrors.SUCCESS);
        }
예제 #9
0
        public int Stop()
        {
            this.isStop = true;

            int retValue = waveNatives.waveInStop(this.hwi);

            if (retValue != MMSYSERR.MMSYSERR_NOERROR)
            {
                LibUtils.PrintLog("waveInStop失败, MMSYSERROR = {0}", retValue);
            }

            return(MMSYSERR.MMSYSERR_NOERROR);
        }
예제 #10
0
        private bool CreateCaptureBuffer()
        {
            uint dsErr = DSERR.DS_OK;

            #region 创建默认音频流格式

            this.wfx = new tWAVEFORMATEX()
            {
                nChannels       = LibConsts.Channels,
                nSamplesPerSec  = LibConsts.SamplesPerSec,
                wBitsPerSample  = LibConsts.BitsPerSample,
                nBlockAlign     = LibConsts.BlockAlign,
                nAvgBytesPerSec = LibConsts.Bps,
                cbSize          = 0,
                wFormatTag      = LibNatives.WAVE_FORMAT_PCM
            };

            this.pwfx_free = LibUtils.StructureToPtr(this.wfx);

            this.dsbd = new _DSCBUFFERDESC()
            {
                dwFlags       = 0,
                dwSize        = Marshal.SizeOf(typeof(_DSCBUFFERDESC)),
                dwReserved    = 0,
                dwFXCount     = 0,
                dwBufferBytes = LibConsts.BufferSize,
                lpwfxFormat   = this.pwfx_free,
                lpDSCFXDesc   = IntPtr.Zero
            };

            #endregion

            IntPtr pdscb;
            Guid   iid_dscb8;
            dsErr = this.dsc8.CreateCaptureBuffer(ref this.dsbd, out pdscb, IntPtr.Zero); //TestInvoke2(this.free_bufferDesc, out ppDSCBuff);
            if (dsErr == DSERR.DS_OK)
            {
                // 获取IDirectSoundCaptureBuffer8接口实例
                iid_dscb8 = new Guid(IID.IID_IDirectSoundCaptureBuffer8);
                Marshal.QueryInterface(pdscb, ref iid_dscb8, out this.pdscb8);
                Marshal.Release(pdscb);
                this.dscb8 = Marshal.GetObjectForIUnknown(this.pdscb8) as IDirectSoundCaptureBuffer8;
            }
            else
            {
                LibUtils.PrintLog("CreateCaptureBuffer失败, DSERROR = {0}", dsErr);
                return(false);
            }

            return(true);
        }
예제 #11
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);
        }
예제 #12
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);
        }
예제 #13
0
        public override tWAVEFORMATEX GetFormat()
        {
            short blockAlign = LibUtils.GetBlockAlign(this.source.ChannelCount, this.source.BitsPerSample);

            return(new tWAVEFORMATEX()
            {
                nChannels = (short)this.source.ChannelCount,
                nSamplesPerSec = this.source.SamplesPerSec,
                wBitsPerSample = (short)this.source.BitsPerSample,
                nBlockAlign = blockAlign,
                nAvgBytesPerSec = LibUtils.GetBytesPerSec(blockAlign, this.source.SamplesPerSec),
                cbSize = 0,
                wFormatTag = LibNatives.WAVE_FORMAT_PCM
            });
        }
예제 #14
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);
        }
예제 #15
0
        private bool CreateSecondaryBuffer()
        {
            uint dsErr = DSERR.DS_OK;

            #region 创建默认音频流格式

            this.wfx = new tWAVEFORMATEX()
            {
                nChannels       = LibConsts.Channels,
                nSamplesPerSec  = LibConsts.SamplesPerSec,
                wBitsPerSample  = LibConsts.BitsPerSample,
                nBlockAlign     = LibConsts.BlockAlign,
                nAvgBytesPerSec = LibConsts.Bps,
                cbSize          = 0,
                wFormatTag      = LibNatives.WAVE_FORMAT_PCM
            };

            this.pwfx_free = LibUtils.StructureToPtr(this.wfx);

            this.dsbd = new _DSBUFFERDESC()
            {
                dwSize          = Marshal.SizeOf(typeof(_DSBUFFERDESC)),
                dwFlags         = DSBCAPS.DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS.DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS.DSBCAPS_GLOBALFOCUS | DSBCAPS.DSBCAPS_CTRLVOLUME,
                lpwfxFormat     = this.pwfx_free,
                guid3DAlgorithm = new _GUID(),
                dwBufferBytes   = LibConsts.PLAY_BUFF_SIZE,
                dwReserved      = 0
            };

            #endregion

            IntPtr pdsb;
            dsErr = this.ds8.CreateSoundBuffer(ref this.dsbd, out pdsb, IntPtr.Zero);
            if (dsErr != DSERR.DS_OK)
            {
                LibUtils.PrintLog("CreateSoundBuffer失败, DSERR = {0}", dsErr);
                return(false);
            }

            Guid iid_dsb8 = new Guid(IID.IID_IDirectSoundBuffer8);
            Marshal.QueryInterface(pdsb, ref iid_dsb8, out this.pdsb8);
            Marshal.Release(pdsb);
            this.dsb8 = Marshal.GetObjectForIUnknown(this.pdsb8) as IDirectSoundBuffer8;

            return(true);
        }
예제 #16
0
        private bool WriteDataToBuffer(uint offset, byte[] data)
        {
            IntPtr audioPtr1, audioPtr2;
            uint   audioBytes1, audioBytes2, dataLength = (uint)data.Length;

            uint dsErr = this.dsb8.Lock(offset, dataLength, out audioPtr1, out audioBytes1, out audioPtr2, out audioBytes2, 0);

            if (dsErr == DSERR.DSERR_BUFFERLOST)
            {
                this.dsb8.Restore();
                dsErr = this.dsb8.Lock(offset, dataLength, out audioPtr1, out audioBytes1, out audioPtr2, out audioBytes2, 0);
                if (dsErr != DSERR.DS_OK)
                {
                    LibUtils.PrintLog("Lock失败, DSERR = {0}", dsErr);
                    return(false);
                }
            }

            if (data != null && data.Length > 0)
            {
                Marshal.Copy(data, 0, audioPtr1, (int)audioBytes1);
                if (audioBytes2 > 0 && audioPtr2 != IntPtr.Zero)
                {
                    Marshal.Copy(data, (int)audioBytes1, audioPtr2, (int)audioBytes2);
                }
            }
            else
            {
                // 填充空数据
                //DSLibNatives.memset(audioPtr1, 0, audioBytes1);
                //if (audioPtr2 != IntPtr.Zero)
                //{
                //    DSLibNatives.memset(audioPtr2, 0, audioBytes2);
                //}
            }

            dsErr = this.dsb8.Unlock(audioPtr1, audioBytes1, audioPtr2, audioBytes2);
            if (dsErr != DSERR.DS_OK)
            {
                LibUtils.PrintLog("Unlock失败, DSERR = {0}", dsErr);
                return(false);
            }

            return(true);
        }
예제 #17
0
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            SignalFileLoggerProvider.ForceAddBGLog(LibUtils.GetBGStartMessage());
            SignalLogging.SetupLogging(false);
            Deferral               = taskInstance.GetDeferral();
            ToastNotifier          = ToastNotificationManager.CreateToastNotifier();
            taskInstance.Canceled += OnCanceled;
            bool locked = LibUtils.Lock(5000);

            Logger.LogTrace("Locking global finished, locked = {0}", locked);
            if (!locked)
            {
                Logger.LogWarning("App is running, background task shutting down");
                Deferral.Complete();
                return;
            }
            GlobalResetEvent = LibUtils.OpenResetEventUnset();
            Task.Run(() =>
            {
                GlobalResetEvent.WaitOne();
                Logger.LogInformation("Background task received app startup signal");
                ResetEvent.Set();
            });
            try
            {
                Handle = SignalHelper.CreateSignalLibHandle(true);
                Handle.SignalMessageEvent += Handle_SignalMessageEvent;
                Handle.BackgroundAcquire();
                ResetEvent.WaitOne();
            }
            catch (Exception e)
            {
                Logger.LogError("Background task failed: {0}\n{1}", e.Message, e.StackTrace);
            }
            finally
            {
                Logger.LogInformation("Background task shutting down");
                Handle.BackgroundRelease();
                LibUtils.Unlock();
                Deferral.Complete();
            }
        }
예제 #18
0
        private void HandleNotification(uint offset, int playSize, SynchronizationContext ctx)
        {
            byte[] buffer;
            int    ret = this.stream.Read(playSize, out buffer);

            if (ret == LibErrors.SUCCESS)
            {
                #region 读取音频流成功

                ctx.Send((o) =>
                {
                    //DSLibUtils.PrintLog("播放缓冲区数据, 大小:{0}字节", buffer.Length);

                    try
                    {
                        if (this.WriteDataToBuffer(offset, buffer))
                        {
                        }
                    }
                    catch (Exception ex)
                    {
                        LibUtils.PrintLog("播放音频流异常, Exception = {0}", ex);
                    }
                }, null);

                #endregion
            }
            else if (ret == LibErrors.NO_DATA)
            {
                #region 没数据了, 播放完毕

                ctx.Send((o) =>
                {
                    LibUtils.PrintLog("缓冲区播放完毕, 停止播放");
                    this.Stop();
                    this.NotifyStatusChanged(DSLibPlayerStatus.Stopped, 0);
                }, null);

                #endregion
            }
        }
예제 #19
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);
        }
예제 #20
0
        private void waveInProc(IntPtr hwi, uint uMsg, uint dwInstance, uint dwParam1, uint dwParam2)
        {
            switch (uMsg)
            {
            case (uint)waveNatives.uMsgEnum.WIM_OPEN:
                LibUtils.PrintLog("OPEN");
                break;

            case (uint)waveNatives.uMsgEnum.WIM_DATA:
                if (this.isStop)
                {
                    break;
                }

                wavehdr_tag hdr = (wavehdr_tag)Marshal.PtrToStructure(this.free_pwh, typeof(wavehdr_tag));

                // 处理音频数据
                {
                    byte[] buffer = new byte[hdr.dwBytesRecorded];
                    Marshal.Copy(hdr.lpData, buffer, 0, buffer.Length);

                    if (this.AudioCaptured != null)
                    {
                        this.AudioCaptured(buffer);
                    }
                }

                int retValue = waveNatives.waveInAddBuffer(hwi, this.free_pwh, (uint)this.whSize);
                if (retValue != MMSYSERR.MMSYSERR_NOERROR)
                {
                    LibUtils.PrintLog("waveInAddBuffer失败, MMSYSERROR = {0}", retValue);
                }

                break;

            case (uint)waveNatives.uMsgEnum.WIM_CLOSE:
                LibUtils.PrintLog("CLOSE");
                break;
            }
        }
예제 #21
0
        public override int Open()
        {
            if (!File.Exists(this.source.Path))
            {
                LibUtils.PrintLog("AudioSource.Open失败, 文件不存在, Uri = {0}", this.source.Path);
                return(LibErrors.FILE_NOT_EXISTS);
            }

            base.isDownloading = true;

            try
            {
                this.stream = File.Open(this.source.Path, FileMode.Open);
            }
            catch (Exception ex)
            {
                LibUtils.PrintLog("AudioSource.Open失败, 打开文件失败, 异常信息:{0}", ex);
                return(LibErrors.OPEN_FILE_FAILED);
            }

            base.isDownloading = false;

            return(LibErrors.SUCCESS);
        }
예제 #22
0
        /// <summary>
        /// 向DirectSound缓冲区Put音频数据
        /// </summary>
        /// <param name="buffer">要Put的数据</param>
        /// <param name="type">Put的数据类型</param>
        public void PutBuffer(byte[] buffer)
        {
            LibUtils.PrintLog("PutBuffer, Size = {0}", buffer.Length);

            this.audioStream.PutBuffer(buffer);
        }
예제 #23
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);
        }
예제 #24
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);
        }