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); }
//------------------------------------------------------------------- // 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. }
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; }
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); }
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); }
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); }
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; }
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; }
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); }
//------------------------------------------------------------------- // 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; } }
/// <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); } }