Microsoft Audio Compression Manager (ACM) in C#.NET

最近需要用到Microsoft Audio Compression Manager (ACM), 鉴于C#.NET没有直接的ACM的API,自己写了pinvoke:

 

public const string msacm = "msacm32.dll";

[DllImport(msacm, CharSet = CharSet.Unicode)]

public static extern MMRESULT acmStreamOpen(out IntPtr phas, IntPtr had,

         ref WAVEFORMATEX pwfxSrc, ref WAVEFORMATEX pwfxDest, IntPtr pwFltr/*WAVEFILTER pwFltr*/, IntPtr

      callBack, IntPtr dwInstance, [MarshalAs(UnmanagedType.U4)] uint dwOpen);

 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

      public struct WAVEFORMATEX

      {

         public UInt16 wFormatTag;          /* format type */

         public UInt16 nChannels;           /* number of channels (i.e. mono, stereo...) */

         public UInt32 nSamplesPerSec;      /* sample rate */

         public UInt32 nAvgBytesPerSec;     /* for buffer estimation */

         public UInt16 nBlockAlign;         /* block size of data */

         public UInt16 wBitsPerSample;      /* number of bits per sample of mono data */

         public UInt16 cbSize;              /* the count in bytes of the size of */

         /* extra information (after cbSize) */

      }

[StructLayout(LayoutKind.Sequential, Pack = 1)]

      public class WAVEFILTER

      {

         public UInt32 cbStruct;                   /* Size, in bytes, of the WAVEFILTER structure */

         public UInt32 pcdwFilterTag;              /* Waveform-audio filter type */

         public UInt32 fdwFilter;                  /* Flags for the dwFilterTag member. */

         [MarshalAs(UnmanagedType.SysUInt, SizeConst = 5)]

         public UInt32 dwReserved;                 /* Reserved for system use */

      }

 

Some tips about using ACM:

1. 有些ACM Driver支持有回调函数也就是异步转换,有些不支持,在使用acmStreamOpen函数的时候要注意。

2. 只有ACM Driver支持的格式间才可以相互转换,否则acmStreamOpen 会返回 512。

3. 使用acmStreamOpen 的例子: 

ACMController.MMRESULT Result = ACMController.acmStreamOpen(out _hACMStream, _hACMDriver, ref F.Wfx, ref _DestWaveFormat, IntPtr.Zero, IntPtr.Zero, //_Window.Handle       IntPtr.Zero,       0 /* ACMController.ACM_STREAMOPENF_ASYNC | ACMController.CALLBACK_WINDOW */);

如果_DestWaveFormat 是WAVE-PCM 格式的话可以按如下设置:

_DestWaveFormat.wFormatTag = ACMController.WAVE_FORMAT_PCM; _DestWaveFormat.nChannels = f.Wfx.nChannels; (depend on ACM Driver) _DestWaveFormat.nSamplesPerSec = f.Wfx.nSamplesPerSec; (depend on ACM Driver)

_DestWaveFormat.wBitsPerSample = 16; (depend on ACM Driver)

_DestWaveFormat.nBlockAlign = (ushort)(_DestWaveFormat.nChannels * Math.Ceiling((double)_DestWaveFormat.wBitsPerSample / 8)); _DestWaveFormat.nAvgBytesPerSec = _DestWaveFormat.nSamplesPerSec * _DestWaveFormat.nBlockAlign; _DestWaveFormat.cbSize = 0;

4. 一些查看ACM Driver 的例子:

      pInvoke:

      [DllImport(msacm)] public static extern MMRESULT acmDriverEnum(AcmDriverEnumCallback fnCallback, int dwInstance, AcmDriverEnumFlags flags); [DllImport(msacm)] public static extern MMRESULT acmDriverDetails(int hAcmDriver, ref AcmDriverDetails driverDetails, int reserved); [DllImport(msacm)] public static extern MMRESULT acmDriverID(IntPtr has, int hAcmDriver, int reserved);

public delegate bool AcmDriverEnumCallback(int hAcmDriverId, int instance, AcmDriverDetailsSupportFlags flags);

      使用:

_ACMdrivers = new List<ACMController.AcmDriverDetails>(); Result = ACMController.acmDriverEnum(new ACMController.AcmDriverEnumCallback(DriverEnumCallback), 0, 0); foreach (ACMController.AcmDriverDetails mdriver in _ACMdrivers) { int n = 0; }

private bool DriverEnumCallback(int hAcmDriver, int dwInstance, ACMController.AcmDriverDetailsSupportFlags flags) { ACMController.AcmDriverDetails details = new ACMController.AcmDriverDetails(); details.structureSize = System.Runtime.InteropServices.Marshal.SizeOf(details); ACMController.MMRESULT R= ACMController.acmDriverDetails(hAcmDriver, ref details, 0); _ACMdrivers.Add(details); return true; }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值