コード例 #1
0
ファイル: DirectSound.cs プロジェクト: zxmak/ZXMAK2
        public DirectSound(
            Form form,
            int sampleRate,
            int bufferCount)
        {
            if ((sampleRate % 50) != 0)
            {
                throw new ArgumentOutOfRangeException("sampleRate", "Sample rate must be a multiple of 50!");
            }
            _sampleRate = sampleRate;
            var bufferSize = sampleRate / 50;

            for (int i = 0; i < bufferCount; i++)
            {
                _fillQueue.Enqueue(new uint[bufferSize]);
            }
            _bufferSize  = bufferSize;
            _bufferCount = bufferCount;
            _zeroValue   = 0;

            var hWnd = form != null ? form.Handle : IntPtr.Zero;

            _device = new DirectSound8();
            _device.SetCooperativeLevel(hWnd, DSSCL.PRIORITY);

            // we always use 16 bit stereo (uint per sample)
            const short channels      = 2;
            const short bitsPerSample = 16;
            const int   sampleSize    = 4; // channels * (bitsPerSample / 8);
            var         wf            = new WaveFormat(_sampleRate, bitsPerSample, channels);

            // Create a buffer
            var bufferDesc = new DSBUFFERDESC();

            bufferDesc.dwBufferBytes = _bufferSize * sampleSize * _bufferCount;
            bufferDesc.dwFlags       =
                DSBCAPS_FLAGS.CTRLVOLUME |
                DSBCAPS_FLAGS.CTRLPOSITIONNOTIFY |
                DSBCAPS_FLAGS.GLOBALFOCUS |
                DSBCAPS_FLAGS.GETCURRENTPOSITION2;
            bufferDesc.Format = wf;
            _soundBuffer      = new SecondarySoundBuffer(_device, bufferDesc);

            var posNotify = new DSBPOSITIONNOTIFY[_bufferCount];

            for (int i = 0; i < posNotify.Length; i++)
            {
                posNotify[i]            = new DSBPOSITIONNOTIFY();
                posNotify[i].dwOffset   = i * _bufferSize * sampleSize;
                posNotify[i].WaitHandle = _fillEvent;
            }
            _soundBuffer.SetNotificationPositions(posNotify);

            _wavePlayThread = new Thread(WavePlayThreadProc);
            _wavePlayThread.IsBackground = true;
            _wavePlayThread.Name         = "WavePlay";
            _wavePlayThread.Priority     = ThreadPriority.Highest;
            _wavePlayThread.Start();
        }
コード例 #2
0
        private bool CreateBufferNotifications()
        {
            uint error = DSERR.DS_OK;

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

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

            try
            {
                WAVEFORMATEX wfx;
                int          pdwSizeWritten;
                if ((error = this.dscb8.GetFormat(out wfx, Marshal.SizeOf(typeof(WAVEFORMATEX)), out pdwSizeWritten)) != DSERR.DS_OK)
                {
                    logger.ErrorFormat("GetFormat失败, DSERROR = {0}", error);
                    return(false);
                }

                DSBPOSITIONNOTIFY[] rgdsbpn = new DSBPOSITIONNOTIFY[this.NotifyEvents];
                this.notifyHandle_close = new IntPtr[this.NotifyEvents];
                for (int i = 0; i < this.NotifyEvents; i++)
                {
                    this.notifyHandle_close[i] = Win32API.CreateEvent(IntPtr.Zero, true, false, null);
                }

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

                rgdsbpn[1].dwOffset     = Win32API.DSBPN_OFFSETSTOP;
                rgdsbpn[1].hEventNotify = this.notifyHandle_close[1];

                if ((error = dsNotify8.SetNotificationPositions(this.NotifyEvents, Marshal.UnsafeAddrOfPinnedArrayElement(rgdsbpn, 0))) != DSERR.DS_OK)
                {
                    logger.ErrorFormat("SetNotificationPositions失败, DSERROR = {0}", error);
                    return(false);
                }
            }
            finally
            {
                Marshal.Release(pdsNotify8);
            }

            return(true);
        }