Example #1
0
        /// <summary>
        /// Determines whether or not the device supports a given format.
        /// </summary>
        /// <param name="waveFormat">The format to check.</param>
        /// <returns>true, if the format is supported; false, otherwise.</returns>
        public bool SupportsFormat(WaveFormat waveFormat)
        {
            NativeMethods.WAVEFORMATEX wfx = new NativeMethods.WAVEFORMATEX();
            wfx.nAvgBytesPerSec = waveFormat.AverageBytesPerSecond;
            wfx.wBitsPerSample  = waveFormat.BitsPerSample;
            wfx.nBlockAlign     = waveFormat.BlockAlign;
            wfx.nChannels       = waveFormat.Channels;
            wfx.wFormatTag      = (short)(int)waveFormat.FormatTag;
            wfx.nSamplesPerSec  = waveFormat.SamplesPerSecond;
            wfx.cbSize          = 0;

            IntPtr dummy = new IntPtr(0);

            NativeMethods.MMSYSERROR ret = NativeMethods.waveOutOpen(
                ref dummy,
                (uint)this.deviceId,
                ref wfx,
                null,
                (IntPtr)0,
                NativeMethods.WAVEOPENFLAGS.WAVE_FORMAT_QUERY);

            if (ret == NativeMethods.MMSYSERROR.MMSYSERR_NOERROR)
            {
                return(true);
            }
            else if (ret == NativeMethods.MMSYSERROR.WAVERR_BADFORMAT)
            {
                return(false);
            }
            else
            {
                NativeMethods.Throw(ret, NativeMethods.ErrorSource.WaveOut);
                return(false);
            }
        }
Example #2
0
        /// <summary>
        /// Opens the device for writing with the specified format.
        /// </summary>
        /// <param name="waveFormat">The format of the device to open.</param>
        public void Open(WaveFormat waveFormat)
        {
            lock (this.startStopLock)
            {
                if (this.handle != null)
                {
                    throw new InvalidOperationException("The device is already open.");
                }

                NativeMethods.WAVEFORMATEX wfx = new NativeMethods.WAVEFORMATEX
                {
                    nAvgBytesPerSec = waveFormat.AverageBytesPerSecond,
                    wBitsPerSample  = waveFormat.BitsPerSample,
                    nBlockAlign     = waveFormat.BlockAlign,
                    nChannels       = waveFormat.Channels,
                    wFormatTag      = (short)(int)waveFormat.FormatTag,
                    nSamplesPerSec  = waveFormat.SamplesPerSecond,
                    cbSize          = 0
                };

                this.recordingFormat = waveFormat.Clone();

                IntPtr tempHandle = new IntPtr();
                NativeMethods.Throw(
                    NativeMethods.waveInOpen(
                        ref tempHandle,
                        (uint)this.deviceId,
                        ref wfx,
                        this.callback,
                        (IntPtr)0,
                        NativeMethods.WAVEOPENFLAGS.CALLBACK_FUNCTION | NativeMethods.WAVEOPENFLAGS.WAVE_FORMAT_DIRECT),
                    NativeMethods.ErrorSource.WaveOut);
                this.handle = new WaveInSafeHandle(tempHandle);
            }
        }
Example #3
0
        /// <summary>
        /// Opens the device for writing with the specified format.
        /// </summary>
        /// <param name="waveFormat">The format of the device to open.</param>
        public void Open(WaveFormat waveFormat)
        {
            lock (this.startStopLock)
            {
                if (this.handle != null)
                {
                    throw new InvalidOperationException("The device is already open.");
                }

                NativeMethods.WAVEFORMATEX wfx = new NativeMethods.WAVEFORMATEX();
                wfx.nAvgBytesPerSec = waveFormat.AverageBytesPerSecond;
                wfx.wBitsPerSample  = waveFormat.BitsPerSample;
                wfx.nBlockAlign     = waveFormat.BlockAlign;
                wfx.nChannels       = waveFormat.Channels;
                wfx.wFormatTag      = (short)(int)waveFormat.FormatTag;
                wfx.nSamplesPerSec  = waveFormat.SamplesPerSecond;
                wfx.cbSize          = 0;

                IntPtr tempHandle = new IntPtr();
                NativeMethods.Throw(
                    NativeMethods.waveOutOpen(
                        ref tempHandle,
                        (uint)this.deviceId,
                        ref wfx,
                        this.callback,
                        (IntPtr)0,
                        NativeMethods.WAVEOPENFLAGS.CALLBACK_FUNCTION | NativeMethods.WAVEOPENFLAGS.WAVE_FORMAT_DIRECT),
                    NativeMethods.ErrorSource.WaveOut);
                this.handle = new WaveOutSafeHandle(tempHandle);

                lock (this.bufferingLock)
                {
                    this.buffering = true;
                    Monitor.Pulse(this.bufferingLock);
                }

                this.bufferMaintainerThread = new Thread(new ThreadStart(this.MaintainBuffers));
                this.bufferMaintainerThread.IsBackground = true;
                this.bufferMaintainerThread.Name         = "WaveOut MaintainBuffers thread. (DeviceID = " + this.deviceId + ")";
                this.bufferMaintainerThread.Start();
            }
        }
Example #4
0
        public static void Play(double[] signal, int samplingRate)
        {
            // Dies ist noch sehr unsauber!
            // TODO: auf Fehler reagieren; Speicherlecks vermeiden
            // TODO: Iterator statt komplettem Array benutzen

            short[] buffer = new short[signal.Length];
            for (int i = 0; i < signal.Length; i++)
            {
                buffer[i] = (short)(short.MaxValue * signal[i]);
            }
            GCHandle hBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);

            IntPtr hWaveOut = IntPtr.Zero;

            NativeMethods.WAVEFORMATEX format = new NativeMethods.WAVEFORMATEX();
            format.wFormatTag      = 1;
            format.nChannels       = 1;
            format.nSamplesPerSec  = (uint)samplingRate;
            format.nAvgBytesPerSec = (uint)(samplingRate * sizeof(short));
            format.nBlockAlign     = sizeof(short);
            format.wBitsPerSample  = 16;
            format.cbSize          = 0;
            NativeMethods.waveOutOpen(ref hWaveOut, new IntPtr(-1), ref format, IntPtr.Zero, IntPtr.Zero, 0);
            NativeMethods.WAVEHDR header = new NativeMethods.WAVEHDR();
            header.lpData         = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0);
            header.dwBufferLength = (uint)(buffer.Length * sizeof(short));
            NativeMethods.waveOutPrepareHeader(hWaveOut, ref header, (uint)Marshal.SizeOf(header));
            NativeMethods.waveOutWrite(hWaveOut, ref header, (uint)Marshal.SizeOf(header));
            while ((header.dwFlags & 1) == 0)
            {
                System.Threading.Thread.Sleep(100);
            }
            NativeMethods.waveOutUnprepareHeader(hWaveOut, ref header, (uint)Marshal.SizeOf(header));
            NativeMethods.waveOutClose(hWaveOut);

            hBuffer.Free();
        }
Example #5
0
        private unsafe void ValidateSoundFile(string fileName)
        {
            NativeMethods.MMCKINFO     ckRIFF     = new NativeMethods.MMCKINFO();
            NativeMethods.MMCKINFO     ck         = new NativeMethods.MMCKINFO();
            NativeMethods.WAVEFORMATEX waveFormat = null;
            int dw;

            IntPtr hMIO = UnsafeNativeMethods.mmioOpen(fileName, IntPtr.Zero, NativeMethods.MMIO_READ | NativeMethods.MMIO_ALLOCBUF);

            if (hMIO == IntPtr.Zero)
            {
                throw new FileNotFoundException(SR.GetString(SR.SoundAPIFileDoesNotExist), this.soundLocation);
            }

            try {
                ckRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E');
                if (UnsafeNativeMethods.mmioDescend(hMIO, ckRIFF, null, NativeMethods.MMIO_FINDRIFF) != 0)
                {
                    throw new InvalidOperationException(SR.GetString(SR.SoundAPIInvalidWaveFile, this.soundLocation));
                }

                while (UnsafeNativeMethods.mmioDescend(hMIO, ck, ckRIFF, 0) == 0)
                {
                    if (ck.dwDataOffset + ck.cksize > ckRIFF.dwDataOffset + ckRIFF.cksize)
                    {
                        throw new InvalidOperationException(SR.GetString(SR.SoundAPIInvalidWaveHeader));
                    }

                    if (ck.ckID == mmioFOURCC('f', 'm', 't', ' '))
                    {
                        if (waveFormat == null)
                        {
                            dw = ck.cksize;
                            if (dw < Marshal.SizeOf(typeof(NativeMethods.WAVEFORMATEX)))
                            {
                                dw = Marshal.SizeOf(typeof(NativeMethods.WAVEFORMATEX));
                            }

                            waveFormat = new NativeMethods.WAVEFORMATEX();
                            byte[] data = new byte[dw];
                            if (UnsafeNativeMethods.mmioRead(hMIO, data, dw) != dw)
                                throw new InvalidOperationException(SR.GetString(SR.SoundAPIReadError, this.soundLocation));
                            fixed(byte *pdata = data)
                            {
                                Marshal.PtrToStructure((IntPtr)pdata, waveFormat);
                            }
                        }
                        else
                        {
                            //
                            // multiple formats?
                            //
                        }
                    }
                    UnsafeNativeMethods.mmioAscend(hMIO, ck, 0);
                }

                if (waveFormat == null)
                {
                    throw new InvalidOperationException(SR.GetString(SR.SoundAPIInvalidWaveHeader));
                }

                if (waveFormat.wFormatTag != NativeMethods.WAVE_FORMAT_PCM &&
                    waveFormat.wFormatTag != NativeMethods.WAVE_FORMAT_ADPCM &&
                    waveFormat.wFormatTag != NativeMethods.WAVE_FORMAT_IEEE_FLOAT)
                {
                    throw new InvalidOperationException(SR.GetString(SR.SoundAPIFormatNotSupported));
                }
            } finally {
                if (hMIO != IntPtr.Zero)
                {
                    UnsafeNativeMethods.mmioClose(hMIO, 0);
                }
            }
        }
        private unsafe void ValidateSoundFile(string fileName)
        {
            NativeMethods.MMCKINFO     lpck      = new NativeMethods.MMCKINFO();
            NativeMethods.MMCKINFO     mmckinfo2 = new NativeMethods.MMCKINFO();
            NativeMethods.WAVEFORMATEX structure = null;
            IntPtr hMIO = UnsafeNativeMethods.mmioOpen(fileName, IntPtr.Zero, 0x10000);

            if (hMIO == IntPtr.Zero)
            {
                throw new FileNotFoundException(SR.GetString("SoundAPIFileDoesNotExist"), this.soundLocation);
            }
            try
            {
                lpck.fccType = mmioFOURCC('W', 'A', 'V', 'E');
                if (UnsafeNativeMethods.mmioDescend(hMIO, lpck, null, 0x20) == 0)
                {
                    goto Label_0179;
                }
                throw new InvalidOperationException(SR.GetString("SoundAPIInvalidWaveFile", new object[] { this.soundLocation }));
Label_008B:
                if ((mmckinfo2.dwDataOffset + mmckinfo2.cksize) > (lpck.dwDataOffset + lpck.cksize))
                {
                    throw new InvalidOperationException(SR.GetString("SoundAPIInvalidWaveHeader"));
                }
                if ((mmckinfo2.ckID == mmioFOURCC('f', 'm', 't', ' ')) && (structure == null))
                {
                    int cksize = mmckinfo2.cksize;
                    if (cksize < Marshal.SizeOf(typeof(NativeMethods.WAVEFORMATEX)))
                    {
                        cksize = Marshal.SizeOf(typeof(NativeMethods.WAVEFORMATEX));
                    }
                    structure = new NativeMethods.WAVEFORMATEX();
                    byte[] wf = new byte[cksize];
                    if (UnsafeNativeMethods.mmioRead(hMIO, wf, cksize) != cksize)
                    {
                        throw new InvalidOperationException(SR.GetString("SoundAPIReadError", new object[] { this.soundLocation }));
                    }
                    try
                    {
                        fixed(byte *numRef = wf)
                        {
                            Marshal.PtrToStructure((IntPtr)numRef, structure);
                        }
                    }
                    finally
                    {
                        numRef = null;
                    }
                }
                UnsafeNativeMethods.mmioAscend(hMIO, mmckinfo2, 0);
Label_0179:
                if (UnsafeNativeMethods.mmioDescend(hMIO, mmckinfo2, lpck, 0) == 0)
                {
                    goto Label_008B;
                }
                if (structure == null)
                {
                    throw new InvalidOperationException(SR.GetString("SoundAPIInvalidWaveHeader"));
                }
                if (((structure.wFormatTag != 1) && (structure.wFormatTag != 2)) && (structure.wFormatTag != 3))
                {
                    throw new InvalidOperationException(SR.GetString("SoundAPIFormatNotSupported"));
                }
            }
            finally
            {
                if (hMIO != IntPtr.Zero)
                {
                    UnsafeNativeMethods.mmioClose(hMIO, 0);
                }
            }
        }
        private unsafe void ValidateSoundFile(string fileName) {
            NativeMethods.MMCKINFO ckRIFF = new NativeMethods.MMCKINFO();
            NativeMethods.MMCKINFO ck = new NativeMethods.MMCKINFO();
            NativeMethods.WAVEFORMATEX waveFormat = null;
            int dw;

            IntPtr hMIO = UnsafeNativeMethods.mmioOpen(fileName, IntPtr.Zero, NativeMethods.MMIO_READ | NativeMethods.MMIO_ALLOCBUF);

            if (hMIO == IntPtr.Zero)
                throw new FileNotFoundException(SR.GetString(SR.SoundAPIFileDoesNotExist), this.soundLocation);

            try {
                ckRIFF.fccType = mmioFOURCC('W', 'A','V','E');
                if (UnsafeNativeMethods.mmioDescend(hMIO, ckRIFF, null, NativeMethods.MMIO_FINDRIFF) != 0)
                    throw new InvalidOperationException(SR.GetString(SR.SoundAPIInvalidWaveFile, this.soundLocation));

                while (UnsafeNativeMethods.mmioDescend(hMIO, ck, ckRIFF, 0) == 0) {
                    if (ck.dwDataOffset + ck.cksize > ckRIFF.dwDataOffset + ckRIFF.cksize)
                        throw new InvalidOperationException(SR.GetString(SR.SoundAPIInvalidWaveHeader));

                    if (ck.ckID == mmioFOURCC('f','m','t',' ')) {
                            if (waveFormat == null) {
                                dw = ck.cksize;
                                if (dw < Marshal.SizeOf(typeof(NativeMethods.WAVEFORMATEX)))
                                    dw =  Marshal.SizeOf(typeof(NativeMethods.WAVEFORMATEX));

                                waveFormat = new NativeMethods.WAVEFORMATEX();
                                byte[] data = new byte[dw];
                                if (UnsafeNativeMethods.mmioRead(hMIO, data, dw) != dw)
                                    throw new InvalidOperationException(SR.GetString(SR.SoundAPIReadError, this.soundLocation));
                                fixed(byte* pdata = data) {
                                    Marshal.PtrToStructure((IntPtr) pdata, waveFormat);
                                }
                            } else {
                                //
                                // multiple formats?
                                //
                            }
                    }
                    UnsafeNativeMethods.mmioAscend(hMIO, ck, 0);
                }

                if (waveFormat == null)
                    throw new InvalidOperationException(SR.GetString(SR.SoundAPIInvalidWaveHeader));

                if (waveFormat.wFormatTag != NativeMethods.WAVE_FORMAT_PCM &&
                    waveFormat.wFormatTag != NativeMethods.WAVE_FORMAT_ADPCM &&
                    waveFormat.wFormatTag != NativeMethods.WAVE_FORMAT_IEEE_FLOAT)
                    throw new InvalidOperationException(SR.GetString(SR.SoundAPIFormatNotSupported));

            } finally {
                    if (hMIO != IntPtr.Zero)
                        UnsafeNativeMethods.mmioClose(hMIO, 0);
            }
        }
 private unsafe void ValidateSoundFile(string fileName)
 {
     NativeMethods.MMCKINFO lpck = new NativeMethods.MMCKINFO();
     NativeMethods.MMCKINFO mmckinfo2 = new NativeMethods.MMCKINFO();
     NativeMethods.WAVEFORMATEX structure = null;
     IntPtr hMIO = UnsafeNativeMethods.mmioOpen(fileName, IntPtr.Zero, 0x10000);
     if (hMIO == IntPtr.Zero)
     {
         throw new FileNotFoundException(SR.GetString("SoundAPIFileDoesNotExist"), this.soundLocation);
     }
     try
     {
         lpck.fccType = mmioFOURCC('W', 'A', 'V', 'E');
         if (UnsafeNativeMethods.mmioDescend(hMIO, lpck, null, 0x20) == 0)
         {
             goto Label_0179;
         }
         throw new InvalidOperationException(SR.GetString("SoundAPIInvalidWaveFile", new object[] { this.soundLocation }));
     Label_008B:
         if ((mmckinfo2.dwDataOffset + mmckinfo2.cksize) > (lpck.dwDataOffset + lpck.cksize))
         {
             throw new InvalidOperationException(SR.GetString("SoundAPIInvalidWaveHeader"));
         }
         if ((mmckinfo2.ckID == mmioFOURCC('f', 'm', 't', ' ')) && (structure == null))
         {
             int cksize = mmckinfo2.cksize;
             if (cksize < Marshal.SizeOf(typeof(NativeMethods.WAVEFORMATEX)))
             {
                 cksize = Marshal.SizeOf(typeof(NativeMethods.WAVEFORMATEX));
             }
             structure = new NativeMethods.WAVEFORMATEX();
             byte[] wf = new byte[cksize];
             if (UnsafeNativeMethods.mmioRead(hMIO, wf, cksize) != cksize)
             {
                 throw new InvalidOperationException(SR.GetString("SoundAPIReadError", new object[] { this.soundLocation }));
             }
             try
             {
                 fixed (byte* numRef = wf)
                 {
                     Marshal.PtrToStructure((IntPtr) numRef, structure);
                 }
             }
             finally
             {
                 numRef = null;
             }
         }
         UnsafeNativeMethods.mmioAscend(hMIO, mmckinfo2, 0);
     Label_0179:
         if (UnsafeNativeMethods.mmioDescend(hMIO, mmckinfo2, lpck, 0) == 0)
         {
             goto Label_008B;
         }
         if (structure == null)
         {
             throw new InvalidOperationException(SR.GetString("SoundAPIInvalidWaveHeader"));
         }
         if (((structure.wFormatTag != 1) && (structure.wFormatTag != 2)) && (structure.wFormatTag != 3))
         {
             throw new InvalidOperationException(SR.GetString("SoundAPIFormatNotSupported"));
         }
     }
     finally
     {
         if (hMIO != IntPtr.Zero)
         {
             UnsafeNativeMethods.mmioClose(hMIO, 0);
         }
     }
 }