示例#1
0
        /// <summary>
        /// Creates a new ACM stream to convert one format to another. Note that
        /// not all conversions can be done in one step
        /// </summary>
        /// <param name="sourceFormat">The source audio format</param>
        /// <param name="destFormat">The destination audio format</param>
        public AcmStream(WaveFormat sourceFormat, WaveFormat destFormat)
        {
            try
            {
                streamHandle      = IntPtr.Zero;
                this.sourceFormat = sourceFormat;
                int sourceBufferSize = Math.Max(65536, sourceFormat.AverageBytesPerSecond);
                sourceBufferSize -= (sourceBufferSize % sourceFormat.BlockAlign);


                IntPtr sourceFormatPointer = WaveFormat.MarshalToPtr(sourceFormat);
                IntPtr destFormatPointer   = WaveFormat.MarshalToPtr(destFormat);
                try
                {
                    MmException.Try(AcmInterop.acmStreamOpen(out streamHandle, driverHandle,
                                                             sourceFormatPointer, destFormatPointer, null, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.None), "acmStreamOpen");
                }
                finally
                {
                    Marshal.FreeHGlobal(sourceFormatPointer);
                    Marshal.FreeHGlobal(destFormatPointer);
                }

                int destBufferSize = SourceToDest(sourceBufferSize);
                streamHeader = new AcmStreamHeader(streamHandle, sourceBufferSize, destBufferSize);
                driverHandle = IntPtr.Zero;
            }
            catch
            {
                // suppress the finalise and clean up resources
                Dispose();
                throw;
            }
        }
示例#2
0
        /// <summary>
        /// Frees resources associated with this ACM Stream
        /// </summary>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                // Free other state (managed objects).
                if (streamHeader != null)
                {
                    streamHeader.Dispose();
                    streamHeader = null;
                }
            }

            // Free your own state (unmanaged objects).

            if (streamHandle != IntPtr.Zero)
            {
                MmResult result = AcmInterop.acmStreamClose(streamHandle, 0);
                streamHandle = IntPtr.Zero;
                if (result != MmResult.NoError)
                {
                    throw new MmException(result, "acmStreamClose");
                }
            }
            // Set large fields to null.
            if (driverHandle != IntPtr.Zero)
            {
                AcmInterop.acmDriverClose(driverHandle, 0);
                driverHandle = IntPtr.Zero;
            }
        }
示例#3
0
 private unsafe void Prepare()
 {
     streamHeader.cbStruct            = Marshal.SizeOf(streamHeader);
     streamHeader.sourceBufferLength  = sourceBuffer.Length;
     streamHeader.sourceBufferPointer = (IntPtr)hSourceBuffer.Pointer;
     streamHeader.destBufferLength    = destBuffer.Length;
     streamHeader.destBufferPointer   = (IntPtr)hDestBuffer.Pointer;
     MmException.Try(AcmInterop.acmStreamPrepareHeader(streamHandle, streamHeader, 0), "acmStreamPrepareHeader");
 }
示例#4
0
        /// <summary>
        /// Returns the number of source bytes for a given number of destination bytes
        /// </summary>
        /// <param name="dest">Number of destination bytes</param>
        /// <returns>Number of source bytes</returns>
        public int DestToSource(int dest)
        {
            if (dest == 0) // zero is an invalid parameter to acmStreamSize
            {
                return(0);
            }
            int convertedBytes;

            MmException.Try(AcmInterop.acmStreamSize(streamHandle, dest, out convertedBytes, AcmStreamSizeFlags.Destination), "acmStreamSize");
            return(convertedBytes);
        }
示例#5
0
        /// <summary>
        /// Returns the number of output bytes for a given number of input bytes
        /// </summary>
        /// <param name="source">Number of input bytes</param>
        /// <returns>Number of output bytes</returns>
        public int SourceToDest(int source)
        {
            if (source == 0) // zero is an invalid parameter to acmStreamSize
            {
                return(0);
            }
            int convertedBytes;
            var mmResult = AcmInterop.acmStreamSize(streamHandle, source, out convertedBytes, AcmStreamSizeFlags.Source);

            MmException.Try(mmResult, "acmStreamSize");
            return(convertedBytes);
        }
示例#6
0
        private unsafe void Unprepare()
        {
            streamHeader.sourceBufferLength  = sourceBuffer.Length;
            streamHeader.sourceBufferPointer = (IntPtr)hSourceBuffer.Pointer;
            streamHeader.destBufferLength    = destBuffer.Length;
            streamHeader.destBufferPointer   = (IntPtr)hDestBuffer.Pointer;

            MmResult result = AcmInterop.acmStreamUnprepareHeader(streamHandle, streamHeader, 0);

            if (result != MmResult.NoError)
            {
                //if (result == MmResult.AcmHeaderUnprepared)
                throw new MmException(result, "acmStreamUnprepareHeader");
            }
        }
示例#7
0
        public int Convert(int bytesToConvert, out int sourceBytesConverted)
        {
            Prepare();
            try
            {
                streamHeader.sourceBufferLength     = bytesToConvert;
                streamHeader.sourceBufferLengthUsed = bytesToConvert;
                AcmStreamConvertFlags flags = firstTime ? (AcmStreamConvertFlags.Start | AcmStreamConvertFlags.BlockAlign) : AcmStreamConvertFlags.BlockAlign;
                MmException.Try(AcmInterop.acmStreamConvert(streamHandle, streamHeader, flags), "acmStreamConvert");
                firstTime = false;
                System.Diagnostics.Debug.Assert(streamHeader.destBufferLength == destBuffer.Length, "Codecs should not change dest buffer length");
                sourceBytesConverted = streamHeader.sourceBufferLengthUsed;
            }
            finally
            {
                Unprepare();
            }

            return(streamHeader.destBufferLengthUsed);
        }
示例#8
0
        /// <summary>
        /// Suggests an appropriate PCM format that the compressed format can be converted
        /// to in one step
        /// </summary>
        /// <param name="compressedFormat">The compressed format</param>
        /// <returns>The PCM format</returns>
        public static WaveFormat SuggestPcmFormat(WaveFormat compressedFormat)
        {
            // create a PCM format
            WaveFormat suggestedFormat = new WaveFormat(compressedFormat.SampleRate, 16, compressedFormat.Channels);
            //MmException.Try(AcmInterop.acmFormatSuggest(IntPtr.Zero, compressedFormat, suggestedFormat, Marshal.SizeOf(suggestedFormat), AcmFormatSuggestFlags.FormatTag), "acmFormatSuggest");

            IntPtr suggestedFormatPointer  = WaveFormat.MarshalToPtr(suggestedFormat);
            IntPtr compressedFormatPointer = WaveFormat.MarshalToPtr(compressedFormat);

            try
            {
                MmResult result = AcmInterop.acmFormatSuggest(IntPtr.Zero, compressedFormatPointer, suggestedFormatPointer, Marshal.SizeOf(suggestedFormat), AcmFormatSuggestFlags.FormatTag);
                suggestedFormat = WaveFormat.MarshalFromPtr(suggestedFormatPointer);
                MmException.Try(result, "acmFormatSuggest");
            }
            finally
            {
                Marshal.FreeHGlobal(suggestedFormatPointer);
                Marshal.FreeHGlobal(compressedFormatPointer);
            }

            return(suggestedFormat);
        }
示例#9
0
        /// <summary>
        /// Creates a new ACM stream to convert one format to another, using a
        /// specified driver identified and wave filter
        /// </summary>
        /// <param name="driverId">the driver identifier</param>
        /// <param name="sourceFormat">the source format</param>
        /// <param name="waveFilter">the wave filter</param>
        public AcmStream(IntPtr driverId, WaveFormat sourceFormat, WaveFilter waveFilter)
        {
            int sourceBufferSize = Math.Max(16384, sourceFormat.AverageBytesPerSecond);

            this.sourceFormat = sourceFormat;
            sourceBufferSize -= (sourceBufferSize % sourceFormat.BlockAlign);
            MmException.Try(AcmInterop.acmDriverOpen(out driverHandle, driverId, 0), "acmDriverOpen");

            IntPtr sourceFormatPointer = WaveFormat.MarshalToPtr(sourceFormat);

            try
            {
                MmException.Try(AcmInterop.acmStreamOpen(out streamHandle, driverHandle,
                                                         sourceFormatPointer, sourceFormatPointer, waveFilter, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.None), "acmStreamOpen");
            }
            finally
            {
                Marshal.FreeHGlobal(sourceFormatPointer);
            }

            //MmException.Try(AcmInterop.acmStreamOpen(out streamHandle, driverHandle,
            //              sourceFormat, sourceFormat, waveFilter, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.NonRealTime), "acmStreamOpen");
            streamHeader = new AcmStreamHeader(streamHandle, sourceBufferSize, SourceToDest(sourceBufferSize));
        }