private static bool FormatEnumCallback(IntPtr had, ref AcmInterop.ACMFORMATDETAILS pafd, UIntPtr dwInstance, int fdwSupport) { if (pafd.cbwfx >= Marshal.SizeOf(typeof(MMInterop.WAVEFORMATEX))) { SoundFormat soundFormat = new SoundFormat(pafd.pwfx); callbackFormats.Add(soundFormat); } return(true); }
public static AcmConvertionMap GetConvertionMap(SoundFormat[] inputFormats, SoundFormatTag tagFilter) { // First, we enumerate convertion formats AcmConvertionMap initConvertionMap = new AcmConvertionMap(); int maxFormatSize = GetMaxFormatSize(); // Enumerate acm drivers foreach (int driverId in GetDriverIds()) { // Open driver IntPtr phDriver; int mmr = AcmInterop.acmDriverOpen(out phDriver, driverId, 0); if (mmr != 0) { continue; } // For each input format, we do enumeration foreach (SoundFormat inputFormat in inputFormats) { // Fill format details struct AcmInterop.ACMFORMATDETAILS fmtDetails = new AcmInterop.ACMFORMATDETAILS(); IntPtr pwfxFormat = inputFormat.ToPtr(maxFormatSize); fmtDetails.cbStruct = Marshal.SizeOf(fmtDetails); fmtDetails.pwfx = pwfxFormat; fmtDetails.cbwfx = maxFormatSize; // Enumerate convertion formats callbackFormats = new List <SoundFormat>(); IntPtr pwfxInput = inputFormat.ToPtr(); mmr = AcmInterop.acmFormatEnum(phDriver, ref fmtDetails, FormatEnumCallback, IntPtr.Zero, AcmInterop.ACM_FORMATENUMF_CONVERT); Marshal.FreeHGlobal(pwfxInput); // Add formats to the map (if succeed) if (mmr == 0) { initConvertionMap.Add(inputFormat, callbackFormats); } callbackFormats = null; } // Close driver mmr = AcmInterop.acmDriverClose(phDriver, 0); } // Now we query ACM to make sure each convertion is supported AcmConvertionMap finalConvertionMap = new AcmConvertionMap(); SoundFormat[] inputs = initConvertionMap.GetInputs(); foreach (SoundFormat inputFormat in inputs) { IntPtr pwfxSrc = inputFormat.ToPtr(); foreach (SoundFormat outputFormat in initConvertionMap.GetOutputs(inputFormat)) { // Filter tags if (tagFilter != SoundFormatTag.UNKNOWN && outputFormat.Tag != tagFilter) { continue; } IntPtr phs; IntPtr pwfxDst = outputFormat.ToPtr(); // Open acm stream using the query flag int mmr = AcmInterop.acmStreamOpen(out phs, IntPtr.Zero, pwfxSrc, pwfxDst, IntPtr.Zero, IntPtr.Zero, UIntPtr.Zero, AcmInterop.ACM_STREAMOPENF_QUERY); Marshal.FreeHGlobal(pwfxDst); // Add format to the final map if succeed if (mmr == 0) { finalConvertionMap.Add(inputFormat, outputFormat); } } Marshal.FreeHGlobal(pwfxSrc); } return(finalConvertionMap); }
public static AcmConvertionMap GetConvertionMap(SoundFormat[] inputFormats, SoundFormatTag tagFilter) { // First, we enumerate convertion formats AcmConvertionMap initConvertionMap = new AcmConvertionMap(); int maxFormatSize = GetMaxFormatSize(); // Enumerate acm drivers foreach (int driverId in GetDriverIds()) { // Open driver IntPtr phDriver; int mmr = AcmInterop.acmDriverOpen(out phDriver, driverId, 0); if (mmr != 0) { continue; } // For each input format, we do enumeration foreach (SoundFormat inputFormat in inputFormats) { // Fill format details struct AcmInterop.ACMFORMATDETAILS fmtDetails = new AcmInterop.ACMFORMATDETAILS(); IntPtr pwfxFormat = inputFormat.ToPtr(maxFormatSize); fmtDetails.cbStruct = Marshal.SizeOf(fmtDetails); fmtDetails.pwfx = pwfxFormat; fmtDetails.cbwfx = maxFormatSize; // Enumerate convertion formats callbackFormats = new List<SoundFormat>(); IntPtr pwfxInput = inputFormat.ToPtr(); mmr = AcmInterop.acmFormatEnum(phDriver, ref fmtDetails, FormatEnumCallback, IntPtr.Zero, AcmInterop.ACM_FORMATENUMF_CONVERT); Marshal.FreeHGlobal(pwfxInput); // Add formats to the map (if succeed) if (mmr == 0) { initConvertionMap.Add(inputFormat, callbackFormats); } callbackFormats = null; } // Close driver mmr = AcmInterop.acmDriverClose(phDriver, 0); } // Now we query ACM to make sure each convertion is supported AcmConvertionMap finalConvertionMap = new AcmConvertionMap(); SoundFormat[] inputs = initConvertionMap.GetInputs(); foreach (SoundFormat inputFormat in inputs) { IntPtr pwfxSrc = inputFormat.ToPtr(); foreach (SoundFormat outputFormat in initConvertionMap.GetOutputs(inputFormat)) { // Filter tags if (tagFilter != SoundFormatTag.UNKNOWN && outputFormat.Tag != tagFilter) { continue; } IntPtr phs; IntPtr pwfxDst = outputFormat.ToPtr(); // Open acm stream using the query flag int mmr = AcmInterop.acmStreamOpen(out phs, IntPtr.Zero, pwfxSrc, pwfxDst, IntPtr.Zero, IntPtr.Zero, UIntPtr.Zero, AcmInterop.ACM_STREAMOPENF_QUERY); Marshal.FreeHGlobal(pwfxDst); // Add format to the final map if succeed if (mmr == 0) { finalConvertionMap.Add(inputFormat, outputFormat); } } Marshal.FreeHGlobal(pwfxSrc); } return finalConvertionMap; }