예제 #1
0
 private static bool FormatListContainsFormatTag(IList<SoundFormat> formats, SoundFormatTag tag)
 {
     foreach (var format in formats) {
     if (format.Tag == tag) {
        return true;
     }
      }
      return false;
 }
예제 #2
0
 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;
 }
예제 #3
0
 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;
 }
예제 #4
0
 private static bool FormatListContainsFormatTag(IList <SoundFormat> formats, SoundFormatTag tag)
 {
     foreach (var format in formats)
     {
         if (format.Tag == tag)
         {
             return(true);
         }
     }
     return(false);
 }
예제 #5
0
        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);
            }
        }
예제 #6
0
 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);
      }
 }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
 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;
 }
예제 #10
0
        // 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));
        }
예제 #11
0
        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;
        }