static IntPtr InitializeMagicCookie(NativeAudioFile audioFile, NativeAudioConverter converter) { Contract.Requires(audioFile != null); Contract.Requires(converter != null); uint dataSize; uint isWritable; AudioFileStatus getStatus = audioFile.GetPropertyInfo(AudioFilePropertyId.MagicCookieData, out dataSize, out isWritable); if (getStatus != AudioFileStatus.Ok) { throw new IOException(string.Format(CultureInfo.CurrentCulture, Resources.LosslessSampleDecoderGetCookieInfoError, getStatus)); } if (dataSize == 0) { return(IntPtr.Zero); } IntPtr cookie = audioFile.GetProperty(AudioFilePropertyId.MagicCookieData, dataSize); AudioConverterStatus setStatus = converter.SetProperty(AudioConverterPropertyId.DecompressionMagicCookie, dataSize, cookie); if (setStatus != AudioConverterStatus.Ok) { throw new IOException(string.Format(CultureInfo.CurrentCulture, Resources.LosslessSampleDecoderSetCookieError, setStatus)); } return(cookie); }
public SampleCollection DecodeSamples() { Contract.Ensures(_buffer != null); Contract.Ensures(Contract.Result <SampleCollection>() != null); uint sampleCount = 4096; if (_buffer == null) { _buffer = new int[sampleCount * _inputDescription.ChannelsPerFrame]; } GCHandle handle = GCHandle.Alloc(_buffer, GCHandleType.Pinned); try { var bufferList = new AudioBufferList { NumberBuffers = 1, Buffers = new AudioBuffer[1] }; bufferList.Buffers[0].NumberChannels = _inputDescription.ChannelsPerFrame; bufferList.Buffers[0].DataByteSize = (uint)(_buffer.Length); bufferList.Buffers[0].Data = handle.AddrOfPinnedObject(); AudioConverterStatus status = _converter.FillBuffer(ref sampleCount, ref bufferList, null); if (status != AudioConverterStatus.Ok) { throw new IOException(string.Format(CultureInfo.CurrentCulture, Resources.LosslessSampleDecoderFillBufferError, status)); } SampleCollection result = SampleCollectionFactory.Instance.Create((int)_inputDescription.ChannelsPerFrame, (int)sampleCount); // De-interlace the output buffer into the new sample collection, converting to floating point values: var index = 0; for (var sample = 0; sample < result.SampleCount; sample++) { for (var channel = 0; channel < result.Channels; channel++) { result[channel][sample] = _buffer[index++] / _divisor; } } return(result); } finally { handle.Free(); } }
static void ConfigureConverterForBitRate(SettingsDictionary settings, int channels, IntPtr converter) { Contract.Requires(settings != null); Contract.Requires(converter != IntPtr.Zero); uint minBitRate = channels == 1 ? 32u : 64u; uint maxBitRate = channels == 1 ? 256u : 320u; uint bitRate; if (!uint.TryParse(settings["BitRate"], out bitRate) || bitRate <minBitRate || bitRate> maxBitRate) { throw new InvalidSettingException(string.Format(CultureInfo.CurrentCulture, Resources.AacSampleEncoderBadBitRate, settings["BitRate"], minBitRate, maxBitRate)); } AudioConverterStatus status = SetConverterProperty(converter, AudioConverterPropertyId.BitRate, bitRate * 1000); if (status != AudioConverterStatus.Ok) { throw new IOException(string.Format(CultureInfo.CurrentCulture, Resources.SampleEncoderConverterBitRateError, status)); } BitrateControlMode controlMode; if (string.IsNullOrEmpty(settings["ControlMode"]) || string.Compare(settings["ControlMode"], "Constrained", StringComparison.OrdinalIgnoreCase) == 0) { controlMode = BitrateControlMode.VariableConstrained; } else if (string.Compare(settings["ControlMode"], "Average", StringComparison.OrdinalIgnoreCase) == 0) { controlMode = BitrateControlMode.LongTermAverage; } else if (string.Compare(settings["ControlMode"], "Constant", StringComparison.OrdinalIgnoreCase) == 0) { controlMode = BitrateControlMode.Constant; } else { throw new InvalidSettingException(string.Format(CultureInfo.CurrentCulture, Resources.AacSampleEncoderBadBitRateControlMode, settings["ControlMode"])); } status = SetConverterProperty(converter, AudioConverterPropertyId.BitRateControlMode, (uint)controlMode); if (status != AudioConverterStatus.Ok) { throw new InvalidSettingException(string.Format(CultureInfo.CurrentCulture, Resources.SampleEncoderConverterControlModeError, status)); } }
static void ConfigureConverter(SettingsDictionary settings, int channels, IntPtr converter) { Contract.Requires(settings != null); Contract.Requires(converter != IntPtr.Zero); // Set the quality if specified, otherwise select "High": Quality quality; if (string.IsNullOrEmpty(settings["Quality"]) || string.Compare(settings["Quality"], "High", StringComparison.OrdinalIgnoreCase) == 0) { quality = Quality.High; } else if (string.Compare(settings["Quality"], "Medium", StringComparison.OrdinalIgnoreCase) == 0) { quality = Quality.Medium; } else if (string.Compare(settings["Quality"], "Low", StringComparison.OrdinalIgnoreCase) == 0) { quality = Quality.Low; } else { throw new InvalidSettingException(string.Format(CultureInfo.CurrentCulture, Resources.AacSampleEncoderBadQuality, settings["Quality"])); } AudioConverterStatus status = SetConverterProperty(converter, AudioConverterPropertyId.CodecQuality, (uint)quality); if (status != AudioConverterStatus.Ok) { throw new IOException(string.Format(CultureInfo.CurrentCulture, Resources.SampleEncoderConverterQualityError, status)); } // Set a bitrate only if specified. Otherwise, default to a variable bitrate: if (!string.IsNullOrEmpty(settings["BitRate"])) { ConfigureConverterForBitRate(settings, channels, converter); } else { ConfigureConverterForQuality(settings, converter); } }
static void ConfigureConverterForQuality(SettingsDictionary settings, IntPtr converter) { Contract.Requires(settings != null); Contract.Requires(converter != IntPtr.Zero); if (!string.IsNullOrEmpty(settings["ControlMode"]) && string.Compare(settings["ControlMode"], "Variable", StringComparison.OrdinalIgnoreCase) != 0) { throw new InvalidSettingException(Resources.AacSampleEncoderBadQualityControlMode); } AudioConverterStatus status = SetConverterProperty(converter, AudioConverterPropertyId.BitRateControlMode, (uint)BitrateControlMode.Variable); if (status != AudioConverterStatus.Ok) { throw new IOException(string.Format(CultureInfo.CurrentCulture, Resources.SampleEncoderConverterControlModeError, status)); } // There are only 15 distinct settings actually available: uint vbrQualityIndex; if (string.IsNullOrEmpty(settings["VBRQuality"])) { vbrQualityIndex = 9; } else if (!uint.TryParse(settings["VBRQuality"], out vbrQualityIndex) || vbrQualityIndex >= _vbrQualities.Length) { throw new InvalidSettingException(string.Format(CultureInfo.CurrentCulture, Resources.AacSampleEncoderBadVbrQuality, settings["VBRQuality"])); } status = SetConverterProperty(converter, AudioConverterPropertyId.VbrQuality, _vbrQualities[vbrQualityIndex]); if (status != AudioConverterStatus.Ok) { throw new IOException(string.Format(CultureInfo.CurrentCulture, Resources.SampleEncoderConverterQualityError, status)); } }
internal NativeAudioConverter(ref AudioStreamBasicDescription inputDescription, ref AudioStreamBasicDescription outputDescription, NativeAudioFile audioFile) { Contract.Requires(audioFile != null); Contract.Ensures(_handle != null); Contract.Ensures(!_handle.IsClosed); Contract.Ensures(_inputCallback != null); Contract.Ensures(_audioFile != null); Contract.Ensures(_audioFile == audioFile); AudioConverterStatus status = SafeNativeMethods.AudioConverterNew(ref inputDescription, ref outputDescription, out _handle); if (status != AudioConverterStatus.Ok) { throw new IOException(string.Format(CultureInfo.CurrentCulture, Resources.NativeAudioConverterInitializationError, status)); } _inputCallback = InputCallback; _audioFile = audioFile; }