Пример #1
0
        private void InitializeDirectSound()
        {
            // Open DirectSound
            lock (this.m_LockObject)
            {
                directSound = null;
                DirectSoundCreate(ref device, out directSound, IntPtr.Zero);

                if (directSound != null)
                {
                    // Set Cooperative Level to PRIORITY (priority level can call the SetFormat and Compact methods)
                    directSound.SetCooperativeLevel(GetDesktopWindow(), DirectSoundCooperativeLevel.DSSCL_PRIORITY);

                    // -------------------------------------------------------------------------------------
                    // Create PrimaryBuffer
                    // -------------------------------------------------------------------------------------

                    // Fill BufferDescription for PrimaryBuffer
                    BufferDescription bufferDesc = new BufferDescription();
                    bufferDesc.dwSize = Marshal.SizeOf(bufferDesc);
                    bufferDesc.dwBufferBytes = 0;
                    bufferDesc.dwFlags = DirectSoundBufferCaps.DSBCAPS_PRIMARYBUFFER;
                    bufferDesc.dwReserved = 0;
                    bufferDesc.lpwfxFormat = IntPtr.Zero;
                    bufferDesc.guidAlgo = Guid.Empty;

                    object soundBufferObj;
                    // Create PrimaryBuffer
                    directSound.CreateSoundBuffer(bufferDesc, out soundBufferObj, IntPtr.Zero);
                    primarySoundBuffer = (IDirectSoundBuffer)soundBufferObj;

                    // Play & Loop on the PrimarySound Buffer
                    primarySoundBuffer.Play(0, 0, DirectSoundPlayFlags.DSBPLAY_LOOPING);

                    // -------------------------------------------------------------------------------------
                    // Create SecondaryBuffer
                    // -------------------------------------------------------------------------------------

                    // A frame of samples equals to Desired Latency
                    samplesFrameSize = MsToBytes(desiredLatency);

                    // Fill BufferDescription for SecondaryBuffer
                    BufferDescription bufferDesc2 = new BufferDescription();
                    bufferDesc2.dwSize = Marshal.SizeOf(bufferDesc2);
                    bufferDesc2.dwBufferBytes = (uint)(samplesFrameSize * 2);
                    bufferDesc2.dwFlags = DirectSoundBufferCaps.DSBCAPS_GETCURRENTPOSITION2
                        | DirectSoundBufferCaps.DSBCAPS_CTRLPOSITIONNOTIFY
                        | DirectSoundBufferCaps.DSBCAPS_GLOBALFOCUS
                        | DirectSoundBufferCaps.DSBCAPS_CTRLVOLUME
                        | DirectSoundBufferCaps.DSBCAPS_STICKYFOCUS
                        | DirectSoundBufferCaps.DSBCAPS_GETCURRENTPOSITION2;
                    bufferDesc2.dwReserved = 0;
                    GCHandle handleOnWaveFormat = GCHandle.Alloc(waveFormat, GCHandleType.Pinned); // Ptr to waveFormat
                    bufferDesc2.lpwfxFormat = handleOnWaveFormat.AddrOfPinnedObject(); // set Ptr to waveFormat
                    bufferDesc2.guidAlgo = Guid.Empty;

                    // Create SecondaryBuffer
                    directSound.CreateSoundBuffer(bufferDesc2, out soundBufferObj, IntPtr.Zero);
                    secondaryBuffer = (IDirectSoundBuffer)soundBufferObj;
                    handleOnWaveFormat.Free();

                    // Get effective SecondaryBuffer size
                    BufferCaps dsbCaps = new BufferCaps();
                    dsbCaps.dwSize = Marshal.SizeOf(dsbCaps);
                    secondaryBuffer.GetCaps(dsbCaps);

                    nextSamplesWriteIndex = 0;
                    samplesTotalSize = dsbCaps.dwBufferBytes;
                    samples = new byte[samplesTotalSize];
                    System.Diagnostics.Debug.Assert(samplesTotalSize == (2 * samplesFrameSize), "Invalid SamplesTotalSize vs SamplesFrameSize");

                    // -------------------------------------------------------------------------------------
                    // Create double buffering notification.
                    // Use DirectSoundNotify at Position [0, 1/2] and Stop Position (0xFFFFFFFF)
                    // -------------------------------------------------------------------------------------
                    IDirectSoundNotify notify = (IDirectSoundNotify)soundBufferObj;

                    frameEventWaitHandle1 = new EventWaitHandle(false, EventResetMode.AutoReset);
                    frameEventWaitHandle2 = new EventWaitHandle(false, EventResetMode.AutoReset);
                    endEventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);

                    DirectSoundBufferPositionNotify[] notifies = new DirectSoundBufferPositionNotify[3];
                    notifies[0] = new DirectSoundBufferPositionNotify();
                    notifies[0].dwOffset = 0;
                    notifies[0].hEventNotify = frameEventWaitHandle1.SafeWaitHandle.DangerousGetHandle();

                    notifies[1] = new DirectSoundBufferPositionNotify();
                    notifies[1].dwOffset = (uint)samplesFrameSize;
                    notifies[1].hEventNotify = frameEventWaitHandle2.SafeWaitHandle.DangerousGetHandle();

                    notifies[2] = new DirectSoundBufferPositionNotify();
                    notifies[2].dwOffset = 0xFFFFFFFF;
                    notifies[2].hEventNotify = endEventWaitHandle.SafeWaitHandle.DangerousGetHandle();

                    notify.SetNotificationPositions(3, notifies);
                }
            }
        }
        private void InitializeDirectSound()
        {
            // Open DirectSound
            lock (this.m_LockObject)
            {
                directSound = null;
                DirectSoundCreate(ref device, out directSound, IntPtr.Zero);

                if (directSound != null)
                {
                    // Set Cooperative Level to PRIORITY (priority level can call the SetFormat and Compact methods)
                    directSound.SetCooperativeLevel(GetDesktopWindow(), DirectSoundCooperativeLevel.DSSCL_PRIORITY);

                    // -------------------------------------------------------------------------------------
                    // Create PrimaryBuffer
                    // -------------------------------------------------------------------------------------

                    // Fill BufferDescription for PrimaryBuffer
                    BufferDescription bufferDesc = new BufferDescription();
                    bufferDesc.dwSize        = Marshal.SizeOf(bufferDesc);
                    bufferDesc.dwBufferBytes = 0;
                    bufferDesc.dwFlags       = DirectSoundBufferCaps.DSBCAPS_PRIMARYBUFFER;
                    bufferDesc.dwReserved    = 0;
                    bufferDesc.lpwfxFormat   = IntPtr.Zero;
                    bufferDesc.guidAlgo      = Guid.Empty;

                    object soundBufferObj;
                    // Create PrimaryBuffer
                    directSound.CreateSoundBuffer(bufferDesc, out soundBufferObj, IntPtr.Zero);
                    primarySoundBuffer = (IDirectSoundBuffer)soundBufferObj;

                    // Play & Loop on the PrimarySound Buffer
                    primarySoundBuffer.Play(0, 0, DirectSoundPlayFlags.DSBPLAY_LOOPING);

                    // -------------------------------------------------------------------------------------
                    // Create SecondaryBuffer
                    // -------------------------------------------------------------------------------------

                    // A frame of samples equals to Desired Latency
                    samplesFrameSize = MsToBytes(desiredLatency);

                    // Fill BufferDescription for SecondaryBuffer
                    BufferDescription bufferDesc2 = new BufferDescription();
                    bufferDesc2.dwSize        = Marshal.SizeOf(bufferDesc2);
                    bufferDesc2.dwBufferBytes = (uint)(samplesFrameSize * 2);
                    bufferDesc2.dwFlags       = DirectSoundBufferCaps.DSBCAPS_GETCURRENTPOSITION2
                                                | DirectSoundBufferCaps.DSBCAPS_CTRLPOSITIONNOTIFY
                                                | DirectSoundBufferCaps.DSBCAPS_GLOBALFOCUS
                                                | DirectSoundBufferCaps.DSBCAPS_CTRLVOLUME
                                                | DirectSoundBufferCaps.DSBCAPS_STICKYFOCUS;
                    bufferDesc2.dwReserved = 0;
                    GCHandle handleOnWaveFormat = GCHandle.Alloc(waveFormat, GCHandleType.Pinned); // Ptr to waveFormat
                    bufferDesc2.lpwfxFormat = handleOnWaveFormat.AddrOfPinnedObject();             // set Ptr to waveFormat
                    bufferDesc2.guidAlgo    = Guid.Empty;

                    // Create SecondaryBuffer
                    directSound.CreateSoundBuffer(bufferDesc2, out soundBufferObj, IntPtr.Zero);
                    secondaryBuffer = (IDirectSoundBuffer)soundBufferObj;
                    handleOnWaveFormat.Free();

                    // Get effective SecondaryBuffer size
                    BufferCaps dsbCaps = new BufferCaps();
                    dsbCaps.dwSize = Marshal.SizeOf(dsbCaps);
                    secondaryBuffer.GetCaps(dsbCaps);

                    nextSamplesWriteIndex = 0;
                    samplesTotalSize      = dsbCaps.dwBufferBytes;
                    samples = new byte[samplesTotalSize];
                    System.Diagnostics.Debug.Assert(samplesTotalSize == (2 * samplesFrameSize), "Invalid SamplesTotalSize vs SamplesFrameSize");

                    // -------------------------------------------------------------------------------------
                    // Create double buffering notification.
                    // Use DirectSoundNotify at Position [0, 1/2] and Stop Position (0xFFFFFFFF)
                    // -------------------------------------------------------------------------------------
                    IDirectSoundNotify notify = (IDirectSoundNotify)soundBufferObj;

                    frameEventWaitHandle1 = new EventWaitHandle(false, EventResetMode.AutoReset);
                    frameEventWaitHandle2 = new EventWaitHandle(false, EventResetMode.AutoReset);
                    endEventWaitHandle    = new EventWaitHandle(false, EventResetMode.AutoReset);

                    DirectSoundBufferPositionNotify[] notifies = new DirectSoundBufferPositionNotify[3];
                    notifies[0]              = new DirectSoundBufferPositionNotify();
                    notifies[0].dwOffset     = 0;
                    notifies[0].hEventNotify = frameEventWaitHandle1.SafeWaitHandle.DangerousGetHandle();

                    notifies[1]              = new DirectSoundBufferPositionNotify();
                    notifies[1].dwOffset     = (uint)samplesFrameSize;
                    notifies[1].hEventNotify = frameEventWaitHandle2.SafeWaitHandle.DangerousGetHandle();

                    notifies[2]              = new DirectSoundBufferPositionNotify();
                    notifies[2].dwOffset     = 0xFFFFFFFF;
                    notifies[2].hEventNotify = endEventWaitHandle.SafeWaitHandle.DangerousGetHandle();

                    notify.SetNotificationPositions(3, notifies);
                }
            }
        }