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(); }
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); }
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); }