Exemple #1
0
 /// <summary>
 /// Opens this driver
 /// </summary>
 public void Open()
 {
     if (driverHandle == IntPtr.Zero)
     {
         MmException.Try(AcmInterop.acmDriverOpen(out driverHandle, DriverId, 0), "acmDriverOpen");
     }
 }
Exemple #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;
            }
        }
Exemple #3
0
        /// <summary>
        /// Attempts to add a new ACM driver from a file
        /// </summary>
        /// <param name="driverFile">Full path of the .acm or dll file containing the driver</param>
        /// <returns>Handle to the driver</returns>
        public static AcmDriver AddLocalDriver(string driverFile)
        {
            IntPtr handle = NativeMethods.LoadLibrary(driverFile);

            if (handle == IntPtr.Zero)
            {
                throw new ArgumentException("Failed to load driver file");
            }
            var driverProc = NativeMethods.GetProcAddress(handle, "DriverProc");

            if (driverProc == IntPtr.Zero)
            {
                NativeMethods.FreeLibrary(handle);
                throw new ArgumentException("Failed to discover DriverProc");
            }
            IntPtr driverHandle;
            var    result = AcmInterop.acmDriverAdd(out driverHandle,
                                                    handle, driverProc, 0, AcmDriverAddFlags.Function);

            if (result != MmResult.NoError)
            {
                NativeMethods.FreeLibrary(handle);
                throw new MmException(result, "acmDriverAdd");
            }
            var driver = new AcmDriver(driverHandle);

            // long name seems to be missing when we use acmDriverAdd
            if (string.IsNullOrEmpty(driver.details.longName))
            {
                driver.details.longName = "Local driver: " + Path.GetFileName(driverFile);
                driver.localDllHandle   = handle;
            }
            return(driver);
        }
Exemple #4
0
 /// <summary>
 /// Creates a new ACM Driver object
 /// </summary>
 /// <param name="hAcmDriver">Driver handle</param>
 private AcmDriver(IntPtr hAcmDriver)
 {
     driverId = hAcmDriver;
     details  = new AcmDriverDetails();
     details.structureSize = Marshal.SizeOf(details);
     MmException.Try(AcmInterop.acmDriverDetails(hAcmDriver, ref details, 0), "acmDriverDetails");
 }
Exemple #5
0
 /// <summary>
 /// Closes this driver
 /// </summary>
 public void Close()
 {
     if (driverHandle != IntPtr.Zero)
     {
         MmException.Try(AcmInterop.acmDriverClose(driverHandle, 0), "acmDriverClose");
         driverHandle = IntPtr.Zero;
     }
 }
Exemple #6
0
 private void Prepare()
 {
     streamHeader.cbStruct            = Marshal.SizeOf(streamHeader);
     streamHeader.sourceBufferLength  = sourceBuffer.Length;
     streamHeader.sourceBufferPointer = hSourceBuffer.AddrOfPinnedObject();
     streamHeader.destBufferLength    = destBuffer.Length;
     streamHeader.destBufferPointer   = hDestBuffer.AddrOfPinnedObject();
     MmException.Try(AcmInterop.acmStreamPrepareHeader(streamHandle, streamHeader, 0), "acmStreamPrepareHeader");
 }
Exemple #7
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");
            MmException.Try(AcmInterop.acmStreamOpen(out streamHandle, driverHandle,
                                                     sourceFormat, sourceFormat, waveFilter, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.NonRealTime), "acmStreamOpen");
            streamHeader = new AcmStreamHeader(streamHandle, sourceBufferSize, SourceToDest(sourceBufferSize));
        }
Exemple #8
0
        /// <summary>
        /// Removes a driver previously added using AddLocalDriver
        /// </summary>
        /// <param name="localDriver">Local driver to remove</param>
        public static void RemoveLocalDriver(AcmDriver localDriver)
        {
            if (localDriver.localDllHandle == IntPtr.Zero)
            {
                throw new ArgumentException("Please pass in the AcmDriver returned by the AddLocalDriver method");
            }
            var removeResult = AcmInterop.acmDriverRemove(localDriver.driverId, 0); // gets stored as a driver Id

            NativeMethods.FreeLibrary(localDriver.localDllHandle);
            MmException.Try(removeResult, "acmDriverRemove");
        }
Exemple #9
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);
        }
Exemple #10
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);
        }
Exemple #11
0
        /// <summary>
        /// Show Format Choose Dialog
        /// </summary>
        /// <param name="ownerWindowHandle">Owner window handle, can be null</param>
        /// <param name="windowTitle">Window title</param>
        /// <param name="enumFlags">Enumeration flags. None to get everything</param>
        /// <param name="enumFormat">Enumeration format. Only needed with certain enumeration flags</param>
        /// <param name="selectedFormat">The selected format</param>
        /// <param name="selectedFormatDescription">Textual description of the selected format</param>
        /// <param name="selectedFormatTagDescription">Textual description of the selected format tag</param>
        /// <returns>True if a format was selected</returns>
        public static bool ShowFormatChooseDialog(
            IntPtr ownerWindowHandle,
            string windowTitle,
            AcmFormatEnumFlags enumFlags,
            WaveFormat enumFormat,
            out WaveFormat selectedFormat,
            out string selectedFormatDescription,
            out string selectedFormatTagDescription)
        {
            AcmFormatChoose formatChoose = new AcmFormatChoose();

            formatChoose.structureSize     = Marshal.SizeOf(formatChoose);
            formatChoose.styleFlags        = AcmFormatChooseStyleFlags.None;
            formatChoose.ownerWindowHandle = ownerWindowHandle;
            int maxFormatSize = 200; // guess

            formatChoose.selectedWaveFormatPointer  = Marshal.AllocHGlobal(maxFormatSize);
            formatChoose.selectedWaveFormatByteSize = maxFormatSize;
            formatChoose.title                 = windowTitle;
            formatChoose.name                  = null;
            formatChoose.formatEnumFlags       = enumFlags;//AcmFormatEnumFlags.None;
            formatChoose.waveFormatEnumPointer = IntPtr.Zero;
            if (enumFormat != null)
            {
                IntPtr enumPointer = Marshal.AllocHGlobal(Marshal.SizeOf(enumFormat));
                Marshal.StructureToPtr(enumFormat, enumPointer, false);
                formatChoose.waveFormatEnumPointer = enumPointer;
            }
            formatChoose.instanceHandle = IntPtr.Zero;
            formatChoose.templateName   = null;

            MmResult result = AcmInterop.acmFormatChoose(ref formatChoose);

            selectedFormat               = null;
            selectedFormatDescription    = null;
            selectedFormatTagDescription = null;
            if (result == MmResult.NoError)
            {
                selectedFormat               = WaveFormat.MarshalFromPtr(formatChoose.selectedWaveFormatPointer);
                selectedFormatDescription    = formatChoose.formatDescription;
                selectedFormatTagDescription = formatChoose.formatTagDescription;
            }

            Marshal.FreeHGlobal(formatChoose.waveFormatEnumPointer);
            Marshal.FreeHGlobal(formatChoose.selectedWaveFormatPointer);
            if (result != MmResult.AcmCancelled && result != MmResult.NoError)
            {
                throw new MmException(result, "acmFormatChoose");
            }
            return(result == MmResult.NoError);
        }
Exemple #12
0
        private void Unprepare()
        {
            streamHeader.sourceBufferLength  = sourceBuffer.Length;
            streamHeader.sourceBufferPointer = hSourceBuffer.AddrOfPinnedObject();
            streamHeader.destBufferLength    = destBuffer.Length;
            streamHeader.destBufferPointer   = hDestBuffer.AddrOfPinnedObject();

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

            if (result != MmResult.NoError)
            {
                //if (result == MmResult.AcmHeaderUnprepared)
                throw new MmException(result, "acmStreamUnprepareHeader");
            }
        }
Exemple #13
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);
             * MmResult result = AcmInterop.acmFormatSuggest2(IntPtr.Zero, compressedFormatPointer, suggestedFormatPointer, Marshal.SizeOf(suggestedFormat), AcmFormatSuggestFlags.FormatTag);
             * suggestedFormat = WaveFormat.MarshalFromPtr(suggestedFormatPointer);
             * Marshal.FreeHGlobal(suggestedFormatPointer);
             * Marshal.FreeHGlobal(compressedFormatPointer);
             * MmException.Try(result, "acmFormatSuggest");*/


            return(suggestedFormat);
        }
Exemple #14
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);
        }
Exemple #15
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);
                MmException.Try(AcmInterop.acmStreamOpen(out streamHandle, IntPtr.Zero, sourceFormat, destFormat, null, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.NonRealTime), "acmStreamOpen");

                int destBufferSize = SourceToDest(sourceBufferSize);
                streamHeader = new AcmStreamHeader(streamHandle, sourceBufferSize, destBufferSize);
                driverHandle = IntPtr.Zero;
            }
            catch
            {
                // suppress the finalise and clean up resources
                Dispose();
                throw;
            }
        }
Exemple #16
0
        /// <summary>
        /// Gets all the supported formats for a given format tag
        /// </summary>
        /// <param name="formatTag">Format tag</param>
        /// <returns>Supported formats</returns>
        public IEnumerable <AcmFormat> GetFormats(AcmFormatTag formatTag)
        {
            if (driverHandle == IntPtr.Zero)
            {
                throw new InvalidOperationException("Driver must be opened first");
            }
            tempFormatsList = new List <AcmFormat>();
            var formatDetails = new AcmFormatDetails();

            formatDetails.structSize = Marshal.SizeOf(formatDetails);
            // need to make sure we have enough space for a waveFormat. formatTag.FormatSize isn't reliable,
            // and some codecs MaxFormatSize isn't either
            formatDetails.waveFormatByteSize = 1024;
            formatDetails.waveFormatPointer  = Marshal.AllocHGlobal(formatDetails.waveFormatByteSize);
            formatDetails.formatTag          = (int)formatTag.FormatTag; // (int)WaveFormatEncoding.Unknown
            var result = AcmInterop.acmFormatEnum(driverHandle,
                                                  ref formatDetails, AcmFormatEnumCallback, IntPtr.Zero,
                                                  AcmFormatEnumFlags.None);

            Marshal.FreeHGlobal(formatDetails.waveFormatPointer);
            MmException.Try(result, "acmFormatEnum");
            return(tempFormatsList);
        }
Exemple #17
0
 /// <summary>
 /// Gets a list of the ACM Drivers installed
 /// </summary>
 public static IEnumerable <AcmDriver> EnumerateAcmDrivers()
 {
     drivers = new List <AcmDriver>();
     MmException.Try(AcmInterop.acmDriverEnum(new AcmInterop.AcmDriverEnumCallback(DriverEnumCallback), IntPtr.Zero, 0), "acmDriverEnum");
     return(drivers);
 }