示例#1
0
        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 CreateSecondaryBuffer()
        {
            uint error = DSERR.DS_OK;

            #region 创建默认音频流格式

            this.wfx = new WAVEFORMATEX()
            {
                nChannels       = this.Channel,
                nSamplesPerSec  = this.SamplesPerSec,
                wBitsPerSample  = this.BitsPerSample,
                nBlockAlign     = this.BlockAlign,
                nAvgBytesPerSec = this.BytesPerSec,
                cbSize          = 0,
                wFormatTag      = Win32API.WAVE_FORMAT_PCM
            };

            this.pwfx_free = PInvoke.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 Win32API.GUID(),
                dwBufferBytes   = this.BufferSize * NotifyEvents,
                dwReserved      = 0
            };

            #endregion

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

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

            return(true);
        }
示例#3
0
        public override bool Open(WaveFormat af)
        {
            this.windowHandle = GetDesktopWindow();

            this.audioFormat = af;

            #region 创建DirectSound对象

            int dsErr = DirectSoundHelper.DirectSoundCreate8(IntPtr.Zero, out this.pds8, IntPtr.Zero);
            if (dsErr != DSERR.DS_OK)
            {
                logger.ErrorFormat("DirectSoundCreate8失败, DSERR = {0}", dsErr);
                return(false);
            }

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

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

            #endregion

            #region 创建音频缓冲区对象

            this.wfx = new WAVEFORMATEX()
            {
                nChannels       = (short)this.audioFormat.Channel,
                nSamplesPerSec  = this.audioFormat.SamplesPerSec,
                wBitsPerSample  = (short)this.audioFormat.BitsPerSample,
                nBlockAlign     = (short)this.audioFormat.BlockAlign,
                nAvgBytesPerSec = this.audioFormat.AvgBytesPerSec,
                cbSize          = 0,
                wFormatTag      = DirectSoundHelper.WAVE_FORMAT_PCM
            };

            this.pwfx_free = Utils.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   = audioFormat.AvgBytesPerSec,
                dwReserved      = 0
            };
            this.buffer_size    = audioFormat.AvgBytesPerSec;
            this.min_free_space = this.wfx.nBlockAlign;

            IntPtr pdsb;
            dsErr = this.ds8.CreateSoundBuffer(ref this.dsbd, out pdsb, IntPtr.Zero);
            if (dsErr != DSERR.DS_OK)
            {
                logger.ErrorFormat("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;

            #endregion

            return(true);
        }