예제 #1
0
 private void FillWave(WaveFormatEx w1, short iOffset)
 {
     w1.nBlockAlign = (short)(iOffset + 3);
     w1.nAvgBytesPerSec = (short)(iOffset + 4);
     w1.nChannels = (short)(iOffset + 5);
     w1.nSamplesPerSec = (short)(iOffset + 6);
     w1.wBitsPerSample = (short)(iOffset + 7);
     w1.wFormatTag = (short)(iOffset + 8);
 }
예제 #2
0
        //-------------------------------------------------------------------
        // Name: ValidateWaveFormat
        // Description: Validates a WAVEFORMATEX structure.
        //
        // Just to keep the sample as simple as possible, we only accept
        // uncompressed PCM formats.
        //-------------------------------------------------------------------
        void ValidateWaveFormat(WaveFormatEx pWav, int cbSize)
        {
            if (pWav.wFormatTag != 1)
            {
                throw new COMException("wFormatTag", MFError.MF_E_INVALIDMEDIATYPE);
            }

            if (pWav.nChannels != 1 && pWav.nChannels != 2)
            {
                throw new COMException("nChannels", MFError.MF_E_INVALIDMEDIATYPE);
            }

            if (pWav.wBitsPerSample != 8 && pWav.wBitsPerSample != 16)
            {
                throw new COMException("wBitsPerSample", MFError.MF_E_INVALIDMEDIATYPE);
            }

            if (pWav.cbSize != 0)
            {
                throw new COMException("cbSize", MFError.MF_E_INVALIDMEDIATYPE);
            }

            // Make sure block alignment was calculated correctly.
            if (pWav.nBlockAlign != pWav.nChannels * (pWav.wBitsPerSample / 8))
            {
                throw new COMException("nBlockAlign", MFError.MF_E_INVALIDMEDIATYPE);
            }

            // Make sure average bytes per second was calculated correctly.
            if (pWav.nAvgBytesPerSec != pWav.nSamplesPerSec * pWav.nBlockAlign)
            {
                throw new COMException("nAvgBytesPerSec", MFError.MF_E_INVALIDMEDIATYPE);
            }

            // Everything checked out.
        }
예제 #3
0
        void InitializePCMWaveFormat(out WaveFormatEx pWav, PCM_Audio_Format_Params param)
        {
            pWav = new WaveFormatEx();

            pWav.wFormatTag = 1;
            pWav.cbSize = 0;

            pWav.nChannels = param.nChannels;
            pWav.nSamplesPerSec = param.nSamplesPerSec;
            pWav.wBitsPerSample = param.wBitsPerSample;

            // Derived values
            pWav.nBlockAlign = (short)(pWav.nChannels * (pWav.wBitsPerSample / 8));
            pWav.nAvgBytesPerSec = pWav.nSamplesPerSec * pWav.nBlockAlign;
        }
예제 #4
0
        private void TestEqual()
        {
            WaveFormatEx a1 = new WaveFormatEx();
            WaveFormatEx a2 = new WaveFormatEx();
            WaveFormatEx a3 = new WaveFormatEx();
            WaveFormatEx a4 = null;

            WaveFormatExWithData b1 = new WaveFormatExWithData();
            WaveFormatExWithData b2 = new WaveFormatExWithData();
            WaveFormatExWithData b3 = new WaveFormatExWithData();
            WaveFormatEx b4 = null;

            WaveFormatExtensible c1 = new WaveFormatExtensible();
            WaveFormatExtensible c2 = new WaveFormatExtensible();
            WaveFormatExtensible c3 = new WaveFormatExtensible();
            WaveFormatEx c4 = null;

            WaveFormatExtensibleWithData d1 = new WaveFormatExtensibleWithData();
            WaveFormatExtensibleWithData d2 = new WaveFormatExtensibleWithData();
            WaveFormatExtensibleWithData d3 = new WaveFormatExtensibleWithData();
            WaveFormatEx d4 = null;

            FillWave(a1, 1);
            FillWave(a2, 1);
            FillWave(a3, 2);

            FillWave(b1, 1);
            FillWave(b2, 1);
            FillWave(b3, 2);

            FillWave(c1, 1);
            FillWave(c2, 1);
            FillWave(c3, 2);

            FillWave(d1, 1);
            FillWave(d2, 1);
            FillWave(d3, 2);

            b1.byteData = new byte[3];
            b2.byteData = new byte[3];

            d1.byteData = new byte[3];
            d2.byteData = new byte[3];

            FillByteData(b1.byteData, 2);
            FillByteData(b2.byteData, 2);

            FillByteData(d1.byteData, 2);
            FillByteData(d2.byteData, 2);

            Debug.Assert(!a1.Equals(null));
            Debug.Assert(!a1.Equals(this));
            Debug.Assert(a1.Equals(a1));
            Debug.Assert(a1.Equals(a2));
            Debug.Assert(!a1.Equals(a3));
            Debug.Assert(!a1.Equals(a4));
            Debug.Assert(a1 != null);
            Debug.Assert(null != a1);
            Debug.Assert(a1 == a2);
            Debug.Assert(a2 == a1);
            Debug.Assert(a1 != a3);
            Debug.Assert(a3 != a1);
            Debug.Assert(a4 != a1);
            Debug.Assert(a1 != a4);

            Debug.Assert(!b1.Equals(null));
            Debug.Assert(!b1.Equals(this));
            Debug.Assert(b1.Equals(b1));
            Debug.Assert(b1.Equals(b2));
            Debug.Assert(!b1.Equals(b3));
            Debug.Assert(!b1.Equals(b4));
            Debug.Assert(b1 != null);
            Debug.Assert(null != b1);
            Debug.Assert(b1 == b2);
            Debug.Assert(b2 == b1);
            Debug.Assert(b1 != b3);
            Debug.Assert(b3 != b1);
            Debug.Assert(b4 != b1);
            Debug.Assert(b1 != b4);

            Debug.Assert(!c1.Equals(null));
            Debug.Assert(!c1.Equals(this));
            Debug.Assert(c1.Equals(c1));
            Debug.Assert(c1.Equals(c2));
            Debug.Assert(!c1.Equals(c3));
            Debug.Assert(!c1.Equals(c4));
            Debug.Assert(c1 != null);
            Debug.Assert(null != c1);
            Debug.Assert(c1 == c2);
            Debug.Assert(c2 == c1);
            Debug.Assert(c1 != c3);
            Debug.Assert(c3 != c1);
            Debug.Assert(c4 != c1);
            Debug.Assert(c1 != c4);

            Debug.Assert(!d1.Equals(null));
            Debug.Assert(!d1.Equals(this));
            Debug.Assert(d1.Equals(d1));
            Debug.Assert(d1.Equals(d2));
            Debug.Assert(!d1.Equals(d3));
            Debug.Assert(!d1.Equals(d4));
            Debug.Assert(d1 != null);
            Debug.Assert(null != d1);
            Debug.Assert(d1 == d2);
            Debug.Assert(d2 == d1);
            Debug.Assert(d1 != d3);
            Debug.Assert(d3 != d1);
            Debug.Assert(d4 != d1);
            Debug.Assert(d1 != d4);

            Debug.Assert(!a1.Equals(b1));
            Debug.Assert(!a1.Equals(c1));
            Debug.Assert(!a1.Equals(d1));

            Debug.Assert(!b1.Equals(a1));
            Debug.Assert(!b1.Equals(c1));
            Debug.Assert(!b1.Equals(d1));

            Debug.Assert(!c1.Equals(a1));
            Debug.Assert(!c1.Equals(b1));
            Debug.Assert(!c1.Equals(d1));

            Debug.Assert(!d1.Equals(a1));
            Debug.Assert(!d1.Equals(b1));
            Debug.Assert(!d1.Equals(c1));

            Debug.Assert(a1 != b1);
            Debug.Assert(a1 != c1);
            Debug.Assert(a1 != d1);

            Debug.Assert(b1 != a1);
            Debug.Assert(b1 != c1);
            Debug.Assert(b1 != d1);

            Debug.Assert(c1 != a1);
            Debug.Assert(c1 != b1);
            Debug.Assert(c1 != d1);

            Debug.Assert(d1 != a1);
            Debug.Assert(d1 != b1);
            Debug.Assert(d1 != c1);
        }
예제 #5
0
        private void TestWaveFormatEx()
        {
            WaveFormatEx w1 = new WaveFormatEx();
            FillWave(w1, 0);

            IntPtr ip = w1.GetPtr();
            WaveFormatEx w2 = WaveFormatEx.PtrToWave(ip);

            Marshal.FreeCoTaskMem(ip);

            Debug.Assert(w1 == w2);
        }
예제 #6
0
        private void TestWaveFormatExPCM()
        {
            int iDataSize = 5;

            WaveFormatEx w1 = new WaveFormatEx();
            FillWave(w1, 0);

            w1.cbSize = (short)(iDataSize);
            w1.wFormatTag = 1;

            IntPtr ip = w1.GetPtr();
            WaveFormatEx w2 = WaveFormatEx.PtrToWave(ip) as WaveFormatEx;

            Marshal.FreeCoTaskMem(ip);

            // Equals won't work cuz of the cbSize issue
            //Debug.Assert(w1 == w2);
        }
예제 #7
0
        public static WaveFormatEx PtrToWave(IntPtr pNativeData)
        {
            short wFormatTag = Marshal.ReadInt16(pNativeData);
            WaveFormatEx wfe;

            // WAVE_FORMAT_EXTENSIBLE == -2
            if (wFormatTag != -2)
            {
                short cbSize;

                // By spec, PCM has no cbSize element
                if (wFormatTag != 1)
                {
                    cbSize = Marshal.ReadInt16(pNativeData, 16);
                }
                else
                {
                    cbSize = 0;
                }

                // Does the structure contain extra data?
                if (cbSize == 0)
                {
                    // Create a simple WaveFormatEx struct
                    wfe = new WaveFormatEx();
                    Marshal.PtrToStructure(pNativeData, wfe);

                    // It probably already has the right value, but there is a special case
                    // where it might not, so, just to be safe...
                    wfe.cbSize = 0;
                }
                else
                {
                    WaveFormatExWithData dat = new WaveFormatExWithData();

                    // Manually parse the data into the structure
                    dat.wFormatTag = wFormatTag;
                    dat.nChannels = Marshal.ReadInt16(pNativeData, 2);
                    dat.nSamplesPerSec = Marshal.ReadInt32(pNativeData, 4);
                    dat.nAvgBytesPerSec = Marshal.ReadInt32(pNativeData, 8);
                    dat.nBlockAlign = Marshal.ReadInt16(pNativeData, 12);
                    dat.wBitsPerSample = Marshal.ReadInt16(pNativeData, 14);
                    dat.cbSize = cbSize;

                    dat.byteData = new byte[dat.cbSize];
                    IntPtr ip2 = new IntPtr(pNativeData.ToInt64() + 18);
                    Marshal.Copy(ip2, dat.byteData, 0, dat.cbSize);

                    wfe = dat as WaveFormatEx;
                }
            }
            else
            {
                short cbSize;
                int extrasize = Marshal.SizeOf(typeof(WaveFormatExtensible)) - Marshal.SizeOf(typeof(WaveFormatEx));

                cbSize = Marshal.ReadInt16(pNativeData, 16);
                if (cbSize == extrasize)
                {
                    WaveFormatExtensible ext = new WaveFormatExtensible();
                    Marshal.PtrToStructure(pNativeData, ext);
                    wfe = ext as WaveFormatEx;
                }
                else
                {
                    WaveFormatExtensibleWithData ext = new WaveFormatExtensibleWithData();
                    int iExtraBytes = cbSize - extrasize;

                    ext.wFormatTag = wFormatTag;
                    ext.nChannels = Marshal.ReadInt16(pNativeData, 2);
                    ext.nSamplesPerSec = Marshal.ReadInt32(pNativeData, 4);
                    ext.nAvgBytesPerSec = Marshal.ReadInt32(pNativeData, 8);
                    ext.nBlockAlign = Marshal.ReadInt16(pNativeData, 12);
                    ext.wBitsPerSample = Marshal.ReadInt16(pNativeData, 14);
                    ext.cbSize = cbSize;

                    ext.wValidBitsPerSample = Marshal.ReadInt16(pNativeData, 18);
                    ext.dwChannelMask = (WaveMask)Marshal.ReadInt16(pNativeData, 20);

                    // Read the Guid
                    byte[] byteGuid = new byte[16];
                    Marshal.Copy(new IntPtr(pNativeData.ToInt64() + 24), byteGuid, 0, 16);
                    ext.SubFormat = new Guid(byteGuid);

                    ext.byteData = new byte[iExtraBytes];
                    IntPtr ip2 = new IntPtr(pNativeData.ToInt64() + Marshal.SizeOf(typeof(WaveFormatExtensible)));
                    Marshal.Copy(ip2, ext.byteData, 0, iExtraBytes);

                    wfe = ext as WaveFormatEx;
                }
            }

            return wfe;
        }
예제 #8
0
        private long BufferSizeFromAudioDuration(WaveFormatEx pWav, long duration)
        {
            long cbSize = duration * pWav.nAvgBytesPerSec / ONE_SECOND;

            int ulRemainder = (int)(cbSize % pWav.nBlockAlign);

            // Round up to the next block.
            if (ulRemainder > 0)
            {
                cbSize += pWav.nBlockAlign - ulRemainder;
            }

            return cbSize;
        }
예제 #9
0
        public static long AudioDurationFromBufferSize(WaveFormatEx pWav, int cbAudioDataSize)
        {
            Debug.Assert(pWav != null);

            if (pWav.nAvgBytesPerSec == 0)
            {
                return 0;
            }
            return Utils.MulDiv(cbAudioDataSize, 10000000, pWav.nAvgBytesPerSec);
        }
예제 #10
0
        //-------------------------------------------------------------------
        // Name: ReadFormatBlock
        // Description: Reads the WAVEFORMATEX structure from the file header.
        //-------------------------------------------------------------------
        private void ReadFormatBlock()
        {
            Debug.Assert(Chunk().FourCC() == new FourCC("fmt "));
            Debug.Assert(m_pWaveFormat == null);

            try
            {
                int iWaveFormatExSize = Marshal.SizeOf(typeof(WaveFormatEx));

                // Some .wav files do not include the cbSize field of the WAVEFORMATEX
                // structure. For uncompressed PCM audio, field is always zero.
                int cbMinFormatSize = iWaveFormatExSize - Marshal.SizeOf(typeof(short));

                int cbFormatSize = 0;       // Size of the actual format block in the file.

                // Validate the size
                if (Chunk().DataSize() < cbMinFormatSize)
                {
                    throw new COMException("chunk too small", MFError.MF_E_INVALID_FILE_FORMAT);
                }

                // Allocate a buffer for the WAVEFORMAT structure.
                cbFormatSize = Chunk().DataSize();

                // We store a WAVEFORMATEX structure, so our format block must be at
                // least sizeof(WAVEFORMATEX) even if the format block in the file
                // is smaller. See note above about cbMinFormatSize.
                m_cbWaveFormat = Math.Max(cbFormatSize, iWaveFormatExSize);

                IntPtr ip = Marshal.AllocCoTaskMem(m_cbWaveFormat);

                try
                {
                    // Zero our structure, in case cbFormatSize < m_cbWaveFormat.
                    for (int x = 0; x < m_cbWaveFormat; x++)
                    {
                        Marshal.WriteByte(ip, x, 0);
                    }

                    // Now read cbFormatSize bytes from the file.
                    ReadDataFromChunk(ip, cbFormatSize);
                    m_pWaveFormat = new WaveFormatEx();

                    Marshal.PtrToStructure(ip, m_pWaveFormat);
                    Debug.Assert(m_pWaveFormat.cbSize == 0);
                }
                finally
                {
                    Marshal.FreeCoTaskMem(ip);
                }

            }
            catch
            {
                m_pWaveFormat = null;
                m_cbWaveFormat = 0;

                throw;
            }
        }
예제 #11
0
        /// <summary>
        /// ValidateWaveFormat - Validates a WAVEFORMATEX structure.
        /// </summary>
        /// <remarks>
        /// This method is called when the byte stream handler opens the
        /// source. The WAVEFORMATEX structure is copied directly from the
        /// .wav file. Therefore the source should not trust any of the
        /// values in the format header.
        ///
        /// Just to keep the sample as simple as possible, we only accept
        /// uncompressed PCM formats in this media source.
        /// </remarks>
        /// <param name="pWav"></param>
        /// <param name="cbSize"></param>
        /// <returns></returns>
        private void ValidateWaveFormat(WaveFormatEx pWav, int cbSize)
        {
            m_Log.WriteLine("ValidateWaveFormat");

            if (pWav.wFormatTag != WAVE_FORMAT_PCM)
            {
                throw new COMException("bad wFormatTag", MFError.MF_E_INVALIDMEDIATYPE);
            }

            if (pWav.nChannels != 1 && pWav.nChannels != 2)
            {
                throw new COMException("bad # channels", MFError.MF_E_INVALIDMEDIATYPE);
            }

            if (pWav.wBitsPerSample != 8 && pWav.wBitsPerSample != 16)
            {
                throw new COMException("bad bitspersample", MFError.MF_E_INVALIDMEDIATYPE);
            }

            if (pWav.cbSize != 0)
            {
                throw new COMException("bad cbsize", MFError.MF_E_INVALIDMEDIATYPE);
            }

            // Make sure block alignment was calculated correctly.
            if (pWav.nBlockAlign != pWav.nChannels * (pWav.wBitsPerSample / 8))
            {
                throw new COMException("bad align", MFError.MF_E_INVALIDMEDIATYPE);
            }

            // Check possible overflow...
            if (pWav.nSamplesPerSec > (int)(int.MaxValue / pWav.nBlockAlign))        // Is (nSamplesPerSec * nBlockAlign > MAXDWORD) ?
            {
                throw new COMException("overflow", MFError.MF_E_INVALIDMEDIATYPE);
            }

            // Make sure average bytes per second was calculated correctly.
            if (pWav.nAvgBytesPerSec != pWav.nSamplesPerSec * pWav.nBlockAlign)
            {
                throw new COMException("bad AvgBytesPerSec", MFError.MF_E_INVALIDMEDIATYPE);
            }
        }