示例#1
0
        /// <summary>
        /// Stop playback
        /// </summary>
        private void StopPlayback()
        {
            lock (this.m_LockObject)
            {
                if (secondaryBuffer != null)
                {
                    CleanUpSecondaryBuffer();

                    secondaryBuffer.Stop();
                    Marshal.ReleaseComObject(secondaryBuffer);
                    secondaryBuffer = null;
                }
                if (primarySoundBuffer != null)
                {
                    primarySoundBuffer.Stop();
                    Marshal.ReleaseComObject(primarySoundBuffer);
                    primarySoundBuffer = null;
                }
                if (directSound != null)
                {
                    Marshal.ReleaseComObject(directSound);
                    directSound = null;
                }
            }
        }
示例#2
0
 public void Dispose()
 {
     // This doesn't follow the Microsoft Dispose pattern because that one sucks (http://nitoprograms.blogspot.com/2009/08/how-to-implement-idisposable-and.html)
     // This also doesn't follow the Cleary's pattern because it's too much work.
     // If an IDisposable field were added to this class, this code would need further work because of that, but until then this is acceptable.
     if (soundBufferDescription.lpwfxFormat != IntPtr.Zero)
     {
         Marshal.FreeHGlobal(soundBufferDescription.lpwfxFormat);
         soundBufferDescription.lpwfxFormat = IntPtr.Zero;
     }
     if (directSoundDevice != null)
     {
         Marshal.ReleaseComObject(directSoundDevice);
         directSoundDevice = null;
     }
 }
示例#3
0
        public Beeper()
        {
            // Silently fail DirectSound creation

            if (!WinAPI.ModuleContainsFunction(DirectSoundModuleName, "DirectSoundCreate", true, true))
            {
                return;
            }

            if (DirectSoundCreate(IntPtr.Zero, out directSoundDevice, IntPtr.Zero) < 0)
            {
                return;
            }

            if (directSoundDevice.SetCooperativeLevel(GetDesktopWindow(), DSSCL_NORMAL) < 0)
            {
                Marshal.ReleaseComObject(directSoundDevice);
                directSoundDevice = null;
                return;
            }

            WAVEFORMATEX waveFormat;

            waveFormat.cbSize          = (short)Marshal.SizeOf(typeof(WAVEFORMATEX));
            waveFormat.wFormatTag      = WAVE_FORMAT_PCM;
            waveFormat.nChannels       = NumberOfChannels;
            waveFormat.wBitsPerSample  = BitsPerSamplePerChannel;
            waveFormat.nSamplesPerSec  = SamplingRate;
            waveFormat.nBlockAlign     = (short)(waveFormat.nChannels * waveFormat.wBitsPerSample / 8);
            waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;

            // The wave format never changes so we marshal it to unmanaged memory and reuse it in calls
            //  to CreateSoundBuffer.
            IntPtr unmanagedWaveFormat = Marshal.AllocHGlobal(waveFormat.cbSize);

            Marshal.StructureToPtr(waveFormat, unmanagedWaveFormat, false);

            // These fields never change
            soundBufferDescription.dwSize      = Marshal.SizeOf(typeof(DSBUFFERDESC));
            soundBufferDescription.dwReserved  = 0;
            soundBufferDescription.dwFlags     = DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS;
            soundBufferDescription.lpwfxFormat = unmanagedWaveFormat;
        }
示例#4
0
文件: Sound.cs 项目: Timwi/CsNibbles
        public Beeper()
        {
            // Silently fail DirectSound creation

            if (!WinAPI.ModuleContainsFunction(DirectSoundModuleName, "DirectSoundCreate", true, true))
                return;

            if (DirectSoundCreate(IntPtr.Zero, out directSoundDevice, IntPtr.Zero) < 0)
                return;

            if (directSoundDevice.SetCooperativeLevel(GetDesktopWindow(), DSSCL_NORMAL) < 0)
            {
                Marshal.ReleaseComObject(directSoundDevice);
                directSoundDevice = null;
                return;
            }

            WAVEFORMATEX waveFormat;
            waveFormat.cbSize = (short) Marshal.SizeOf(typeof(WAVEFORMATEX));
            waveFormat.wFormatTag = WAVE_FORMAT_PCM;
            waveFormat.nChannels = NumberOfChannels;
            waveFormat.wBitsPerSample = BitsPerSamplePerChannel;
            waveFormat.nSamplesPerSec = SamplingRate;
            waveFormat.nBlockAlign = (short) (waveFormat.nChannels * waveFormat.wBitsPerSample / 8);
            waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;

            // The wave format never changes so we marshal it to unmanaged memory and reuse it in calls
            //  to CreateSoundBuffer.
            IntPtr unmanagedWaveFormat = Marshal.AllocHGlobal(waveFormat.cbSize);
            Marshal.StructureToPtr(waveFormat, unmanagedWaveFormat, false);

            // These fields never change
            soundBufferDescription.dwSize = Marshal.SizeOf(typeof(DSBUFFERDESC));
            soundBufferDescription.dwReserved = 0;
            soundBufferDescription.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS;
            soundBufferDescription.lpwfxFormat = unmanagedWaveFormat;
        }
示例#5
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);
                }
            }
        }
 static extern void DirectSoundCreate(ref Guid GUID, [Out, MarshalAs(UnmanagedType.Interface)] out IDirectSound directSound, IntPtr pUnkOuter);
        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);
                }
            }
        }
示例#8
0
 extern static int DirectSoundCreate(IntPtr pcGuidDevice, out IDirectSound ppDS, IntPtr pUnkOuter);
示例#9
0
 public static extern int DirectSoundCreate(IntPtr pcGuidDevice, [MarshalAs(UnmanagedType.Interface)] out IDirectSound pDS, IntPtr pUnkOuter);
示例#10
0
文件: Sound.cs 项目: Timwi/CsNibbles
 static extern int DirectSoundCreate(IntPtr pcGuidDevice, out IDirectSound ppDS, IntPtr pUnkOuter);
示例#11
0
文件: Sound.cs 项目: Timwi/CsNibbles
 public void Dispose()
 {
     // This doesn't follow the Microsoft Dispose pattern because that one sucks (http://nitoprograms.blogspot.com/2009/08/how-to-implement-idisposable-and.html)
     // This also doesn't follow the Cleary's pattern because it's too much work.
     // If an IDisposable field were added to this class, this code would need further work because of that, but until then this is acceptable.
     if (soundBufferDescription.lpwfxFormat != IntPtr.Zero)
     {
         Marshal.FreeHGlobal(soundBufferDescription.lpwfxFormat);
         soundBufferDescription.lpwfxFormat = IntPtr.Zero;
     }
     if (directSoundDevice != null)
     {
         Marshal.ReleaseComObject(directSoundDevice);
         directSoundDevice = null;
     }
 }