private static bool FormatListContainsFormatTag(IList<SoundFormat> formats, SoundFormatTag tag) { foreach (var format in formats) { if (format.Tag == tag) { return true; } } return false; }
public SoundFormat(SoundFormatTag tag, int bitsPerSample, int channels, int samplesPerSecond) { this.avgBytesPerSecond = (bitsPerSample / 8) * samplesPerSecond * channels; this.bitsPerSample = bitsPerSample; this.blockAlign = (bitsPerSample / 8) * channels; this.channels = channels; this.samplesPerSecond = samplesPerSecond; this.tag = tag; }
private static bool FormatListContainsFormatTag(IList <SoundFormat> formats, SoundFormatTag tag) { foreach (var format in formats) { if (format.Tag == tag) { return(true); } } return(false); }
static SoundFormatConverter() { // Convert soundformat tags to string values Array tagsArray = Enum.GetValues(typeof(SoundFormatTag)); supportedTags = new string[tagsArray.Length - 1]; for (int i = 1; i < tagsArray.Length; i++) { SoundFormatTag tag = (SoundFormatTag)tagsArray.GetValue(i); supportedTags.SetValue(tag.ToString(), i - 1); } }
public SoundFormat(IntPtr ptr) { MMInterop.WAVEFORMATEX wfx = (MMInterop.WAVEFORMATEX)Marshal.PtrToStructure(ptr, typeof(MMInterop.WAVEFORMATEX)); this.avgBytesPerSecond = (int)wfx.nAvgBytesPerSec; this.blockAlign = wfx.nBlockAlign; this.channels = wfx.nChannels; this.samplesPerSecond = (int)wfx.nSamplesPerSec; this.bitsPerSample = wfx.wBitsPerSample; this.tag = (SoundFormatTag)wfx.wFormatTag; this.cbSize = wfx.cbSize; int extraBytes = wfx.cbSize; if (extraBytes > 0) { this.extra = new byte[extraBytes]; Marshal.Copy(new IntPtr(ptr.ToInt64() + fixedSize), this.extra, 0, extraBytes); } }
public SoundFormat(IntPtr ptr, int totalBytes) { MMInterop.WAVEFORMATEX wfx = (MMInterop.WAVEFORMATEX)Marshal.PtrToStructure(ptr, typeof(MMInterop.WAVEFORMATEX)); this.avgBytesPerSecond = (int)wfx.nAvgBytesPerSec; this.blockAlign = wfx.nBlockAlign; this.channels = wfx.nChannels; this.samplesPerSecond = (int)wfx.nSamplesPerSec; this.bitsPerSample = wfx.wBitsPerSample; this.tag = (SoundFormatTag)wfx.wFormatTag; this.cbSize = wfx.cbSize; int extraBytes = Math.Max(wfx.cbSize, totalBytes - fixedSize); if (extraBytes > 0) { this.extra = new byte[extraBytes]; Marshal.Copy(new IntPtr(ptr.ToInt64() + fixedSize), this.extra, 0, extraBytes); } }
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 SoundFormat SuggestFormat(string deviceId, SoundFormatTag? tag, int? samplesPerSecond, int? channels) { if (string.IsNullOrEmpty(deviceId)) { throw new ArgumentNullException("deviceId"); } if (tag == null) { tag = preferredFormat.Tag; } if (samplesPerSecond == null) { samplesPerSecond = preferredFormat.SamplesPerSecond; } if (channels == null) { channels = preferredFormat.Channels; } SoundFormat[] availableFormats = GetFormats(deviceId, true); // Find the closest format to the specified paramters // Priorities: 1) Tag 2) Sample Rate 3) Channels SoundFormat suggestedFormat = null; float suggestedMatchValue = int.MinValue; foreach (SoundFormat format in availableFormats) { float matchValue = 0; if (tag != null && format.Tag == tag.Value) { matchValue += 4.0f; } if (samplesPerSecond != null) { float diffRatio = 2.0f - (Math.Abs(format.SamplesPerSecond - samplesPerSecond.Value) / (samplesPerSecond.Value + format.SamplesPerSecond + 1.0f)); matchValue += diffRatio; } if (channels != null && channels.Value == format.Channels) { matchValue += 1.0f; } if (matchValue > suggestedMatchValue) { suggestedFormat = format; suggestedMatchValue = matchValue; } } return suggestedFormat; }
// Overrides the ConvertFrom method of TypeConverter. public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (!(value is string)) { return(base.ConvertFrom(context, culture, value)); } SoundFormatTag tag = SoundFormatTag.UNKNOWN; int bytesPerSecond = 0; int bitsPerSample = 0; int blockAlign = 0; int channels = 0; int samplesPerSecond = 0; string[] properties = ((string)value).Split(new char[] { ',' }); // Read properties... foreach (var property in properties) { string tproperty = property.Trim(); if (tproperty.EndsWith(bit, StringComparison.InvariantCultureIgnoreCase)) { string bitsString = tproperty.Substring(0, tproperty.Length - bit.Length).Trim(); if (!int.TryParse(bitsString, NumberStyles.Any, culture, out bitsPerSample)) { throw new NotSupportedException(); } } else if (tproperty.EndsWith(block, StringComparison.InvariantCultureIgnoreCase)) { string blockAlignString = tproperty.Substring(0, tproperty.Length - block.Length).Trim(); if (!int.TryParse(blockAlignString, NumberStyles.Any, culture, out blockAlign)) { throw new NotSupportedException(); } } else if (tproperty.EndsWith(bps, StringComparison.InvariantCultureIgnoreCase)) { string bpsString = tproperty.Substring(0, tproperty.Length - bps.Length).Trim(); int bitsPerSecond; if (!TryParseNumber(bpsString, bytesPow, NumberStyles.Any, culture, out bitsPerSecond)) { throw new NotSupportedException(); } bytesPerSecond = bitsPerSecond / 8; } else if (tproperty.Equals(mono, StringComparison.InvariantCultureIgnoreCase)) { channels = 1; } else if (tproperty.Equals(stereo, StringComparison.InvariantCultureIgnoreCase)) { channels = 2; } else if (tproperty.EndsWith(hz, StringComparison.InvariantCultureIgnoreCase)) { string samplesPerSecondString = tproperty.Substring(0, tproperty.Length - hz.Length).Trim(); if (!TryParseNumber(samplesPerSecondString, hertzPow, NumberStyles.Any, culture, out samplesPerSecond)) { throw new NotSupportedException(); } } else if (tproperty.EndsWith(bps, StringComparison.InvariantCultureIgnoreCase)) { // } else { bool isTag = false; foreach (var supportedTag in supportedTags) { if (string.Equals(supportedTag, tproperty, StringComparison.InvariantCultureIgnoreCase)) { tag = (SoundFormatTag)Enum.Parse(typeof(SoundFormatTag), supportedTag); isTag = true; break; } } if (!isTag) { throw new NotSupportedException(); } } } if (bytesPerSecond != 0 && blockAlign != 0) { return(new SoundFormat(tag, bitsPerSample, blockAlign, channels, samplesPerSecond, bytesPerSecond)); } return(new SoundFormat(tag, bitsPerSample, channels, samplesPerSecond)); }
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; }