/// <inheritdoc/> public void SaveMetadata(SettingDictionary settings = null) { if (settings == null) { settings = new SettingDictionary(); } var extension = IO.Path.GetExtension(Path); // Make sure the provided settings are clean AudioMetadataEncoderManager.GetSettingInfoByExtension(extension).ValidateSettings(settings); using (var fileStream = File.Open(Path, FileMode.Open)) { // Try each encoder that supports this file extension foreach (var factory in ExtensionProviderWrapper.GetFactories <IAudioMetadataEncoder>( "Extension", extension)) { using (var export = factory.CreateExport()) { if (_metadata == null) { _metadata = LoadMetadata(fileStream); } export.Value.WriteMetadata(fileStream, _metadata, settings); return; } } } throw new AudioUnsupportedException("No supporting extensions are available."); }
public void CreatesExpectedOutput( int index, [NotNull] string fileName, [NotNull] TestAudioMetadata metadata, [CanBeNull] string imageFileName, [CanBeNull] SettingDictionary settings, #if LINUX [NotNull] string expectedUbuntu1604Hash, [NotNull] string expectedUbuntu1804Hash)
public void Initialize(AudioInfo info, SettingDictionary settings, GroupToken groupToken) { _analyzer = new R128Analyzer((uint)info.Channels, (uint)info.SampleRate, settings.TryGetValue("PeakAnalysis", out string peakAnalysis) && peakAnalysis.Equals("Interpolated", StringComparison.Ordinal)); _groupState = (GroupState)groupToken.GetOrSetGroupState(new GroupState()); // ReSharper disable once PossibleNullReferenceException _groupState.Handles.Enqueue(_analyzer.Handle); }
void InitializeReplayGainFilter(AudioInfo info, AudioMetadata metadata, SettingDictionary settings) { var filterFactory = ExtensionProvider.GetFactories <IAudioFilter>("Name", "ReplayGain").FirstOrDefault(); if (filterFactory == null) { return; } _replayGainExport = filterFactory.CreateExport(); _replayGainExport.Value.Initialize(info, metadata, settings); }
public void Initialize(AudioInfo info, AudioMetadata metadata, SettingDictionary settings) { if (settings.TryGetValue("ApplyGain", out string applyGain)) { _scale = applyGain.Equals("Track", StringComparison.OrdinalIgnoreCase) ? CalculateScale(metadata.TrackGain, metadata.TrackPeak) : CalculateScale(metadata.AlbumGain, metadata.AlbumPeak); } // Adjust the metadata so that it remains valid metadata.TrackPeak = CalculatePeak(metadata.TrackPeak, _scale); metadata.AlbumPeak = CalculatePeak(metadata.AlbumPeak, _scale); metadata.TrackGain = CalculateGain(metadata.TrackGain, _scale); metadata.AlbumGain = CalculateGain(metadata.AlbumGain, _scale); }
public static SettingDictionary MergeWith(this SettingDictionary self, SettingDictionary other) { foreach (var sett in other) { try { self.Add(sett.Key, sett.Value); } catch (ArgumentException) { // ignore duplicate key errors. Just do not replace existing settings. } } return self; }
public void Initialize(Stream stream, AudioInfo info, AudioMetadata metadata, SettingDictionary settings) { _stream = stream; _metadata = metadata; _settings = settings; _bitsPerSample = info.BitsPerSample; // Pre-allocate the whole stream (estimate worst case compression, plus cover art) stream.SetLength(info.FrameCount * info.Channels * (long)Math.Ceiling(info.BitsPerSample / 8.0) + (metadata.CoverArt?.Data.Length ?? 0)); var inputDescription = GetInputDescription(info); _audioFile = new ExtendedAudioFile(GetOutputDescription(inputDescription), AudioFileType.M4A, stream); _audioFile.SetProperty(ExtendedAudioFilePropertyId.ClientDataFormat, inputDescription); }
public static SettingDictionary GetSettingDictionary(string settingKey) { var setting = SettingDictionary.Where(x => x.Name == settingKey).FirstOrDefault(); if (setting == null) { return new SettingDictionary() { Name = settingKey.ToString(), Value = string.Empty } } ; return(setting); }
void BindGrid() { SettingDictionary settingDictionary = SettingManager.GetAllSettings(); List <Setting> settings = new List <Setting>(); foreach (KeyValuePair <string, Setting> kvp in settingDictionary) { if (kvp.Value != null) { settings.Add(kvp.Value); } } gvSettings.DataSource = settings; gvSettings.DataBind(); }
private static SettingDictionary DBMapping(DBSettingCollection dbCollection) { if (dbCollection == null) { return(null); } var dictionary = new SettingDictionary(); foreach (var dbItem in dbCollection) { var item = DBMapping(dbItem); dictionary.Add(item.Name.ToLowerInvariant(), item); } return(dictionary); }
void InitializeReplayGainFilter( [NotNull] AudioInfo info, [NotNull] AudioMetadata metadata, [NotNull] SettingDictionary settings) { var filterFactory = ExtensionProvider.GetFactories <IAudioFilter>("Name", "ReplayGain").FirstOrDefault(); if (filterFactory == null) { return; } _replayGainExport = filterFactory.CreateExport(); // ReSharper disable once PossibleNullReferenceException _replayGainExport.Value.Initialize(info, metadata, settings); }
public void CreatesExpectedOutput( int index, string fileName, TestAudioMetadata metadata, string imageFileName, SettingDictionary settings, string[] validHashes) { var sourceDirectory = Path.Combine(PathUtility.GetTestFileRoot(), "Valid"); var path = Path.Combine("Output", "Save-AudioMetadata", "Valid", $"{index:000} - {fileName}"); Directory.CreateDirectory(Path.GetDirectoryName(path) !); File.Copy(Path.Combine(sourceDirectory, fileName), path, true); var audioFile = new TaggedAudioFile(path); _mapper.Map(metadata, audioFile.Metadata); if (!string.IsNullOrEmpty(imageFileName)) { audioFile.Metadata.CoverArt = CoverArtFactory.GetOrCreate(Path.Combine(sourceDirectory, imageFileName)); } using (var ps = PowerShell.Create()) { ps.Runspace = _moduleFixture.Runspace; ps.AddCommand("Save-AudioMetadata") .AddArgument(audioFile); foreach (var item in settings) { if (item.Value is bool boolValue) { if (boolValue) { ps.AddParameter(item.Key); } } else { ps.AddParameter(item.Key, item.Value); } } ps.Invoke(); } Assert.Contains(HashUtility.CalculateHash(audioFile.Path), validHashes); }
public IActionResult OnGet(int id, int pid) { if (id > 0) { Input = _settingManager.Find(id); if (Input == null) { return(NotFound()); } } else { Input = new SettingDictionary { ParentId = pid } }; return(Page()); }
internal static SettingDictionary?ParametersToSettings(RuntimeDefinedParameterDictionary?parameters) { if (parameters == null) { return(null); } var result = new SettingDictionary(); foreach (var parameter in parameters.Where(p => p.Value.IsSet)) { result.Add(parameter.Key, parameter.Value.ParameterType == typeof(SwitchParameter) ? true : parameter.Value.Value); } return(result); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var result = new SettingDictionary(); reader.Read(); while (reader.TokenType == JsonToken.PropertyName) { var propertyName = (string)reader.Value; reader.Read(); var value = reader.TokenType == JsonToken.Integer ? Convert.ToInt32(reader.Value, NumberFormatInfo.InvariantInfo) : serializer.Deserialize(reader); result.Add(propertyName, value); reader.Read(); } return(result); }
public void Initialize(Stream stream, AudioInfo info, AudioMetadata metadata, SettingDictionary settings) { InitializeReplayGainFilter(info, metadata, settings); if (!settings.TryGetValue("SerialNumber", out int serialNumber)) #if NETSTANDARD2_0 { using (var random = RandomNumberGenerator.Create()) { var buffer = new byte[sizeof(int)]; random.GetNonZeroBytes(buffer); serialNumber = BitConverter.ToInt32(buffer, 0); } } #else { serialNumber = RandomNumberGenerator.GetInt32(int.MaxValue); } #endif _oggStream = new(serialNumber); // Default to a quality setting of 5 if (settings.TryGetValue("BitRate", out int bitRate)) { if (settings.TryGetValue("ForceCBR", out bool cbr) && cbr) { _encoder = new(info.Channels, info.SampleRate, bitRate * 1000, bitRate * 1000, bitRate * 1000); } else { _encoder = new(info.Channels, info.SampleRate, -1, bitRate * 1000, -1); } } else { _encoder = new(info.Channels, info.SampleRate, settings.TryGetValue("Quality", out int quality) ? quality / 10f : 0.5f); } // Generate the header using (var comment = new MetadataToVorbisCommentAdapter(metadata)) { comment.HeaderOut(_encoder.DspState, out var first, out var second, out var third); _oggStream.PacketIn(first); _oggStream.PacketIn(second); _oggStream.PacketIn(third); } // Buffer the header in memory using (var tempStream = new MemoryStream()) { _outputStream = tempStream; while (_oggStream.Flush(out var page)) { WritePage(page); } // Pre-allocate the whole stream (estimate worst case of 500kbps, plus the header) stream.SetLength(0xFA00 * (long)info.PlayLength.TotalSeconds + tempStream.Length); // Flush the headers to the output stream tempStream.WriteTo(stream); } _outputStream = stream; }
public void Initialize(Stream stream, AudioInfo info, AudioMetadata metadata, SettingDictionary settings) { InitializeReplayGainFilter(info, metadata, settings); _oggStream = new OggStream(settings.TryGetValue("SerialNumber", out int serialNumber) ? serialNumber : new Random().Next()); // Default to a quality setting of 5 if (settings.TryGetValue("BitRate", out int bitRate)) { if (settings.TryGetValue("ForceCBR", out bool cbr) && cbr) { _encoder = new VorbisEncoder(info.Channels, info.SampleRate, bitRate * 1000, bitRate * 1000, bitRate * 1000); } else { _encoder = new VorbisEncoder(info.Channels, info.SampleRate, -1, bitRate * 1000, -1); } } else { _encoder = new VorbisEncoder(info.Channels, info.SampleRate, settings.TryGetValue("Quality", out int quality) ? quality / 10f : 0.5f); } // Generate the header using (var comment = new MetadataToVorbisCommentAdapter(metadata)) { comment.HeaderOut(_encoder.DspState, out var first, out var second, out var third); _oggStream.PacketIn(first); _oggStream.PacketIn(second); _oggStream.PacketIn(third); } // Buffer the header in memory using (var tempStream = new MemoryStream()) { _outputStream = tempStream; // ReSharper disable once PossibleNullReferenceException while (_oggStream.Flush(out var page)) { WritePage(page); } // Pre-allocate the whole stream (estimate worst case of 500kbps, plus the header) stream.SetLength(0xFA00 * (long)info.PlayLength.TotalSeconds + tempStream.Length); // Flush the headers to the output stream tempStream.WriteTo(stream); } _outputStream = stream; }
public void Initialize(Stream stream, AudioInfo info, AudioMetadata metadata, SettingDictionary settings) { _stream = stream; _metadata = metadata; _settings = settings; InitializeReplayGainFilter(info, metadata, settings); var inputDescription = GetInputDescription(info); _audioFile = new(GetOutputDescription(inputDescription), AudioFileType.M4A, stream); _audioFile.SetProperty(ExtendedAudioFilePropertyId.ClientDataFormat, inputDescription); var converter = _audioFile.GetProperty <IntPtr>(ExtendedAudioFilePropertyId.AudioConverter); var logger = LoggerManager.LoggerFactory.CreateLogger <AacAudioEncoder>(); // Enable high quality (defaults to medium, 0x40) SetConverterProperty(converter, AudioConverterPropertyId.CodecQuality, 0x60); if (settings.TryGetValue("BitRate", out int bitRate)) { switch (bitRate) { case > 256 when info.Channels == 1: logger.LogWarning("The maximum bitrate for 1-channel audio is 256 kbps."); bitRate = 256; break; case < 64 when info.Channels == 2: logger.LogWarning("The minimum bitrate for 2-channel audio is 64 kbps."); bitRate = 64; break; } SetConverterProperty(converter, AudioConverterPropertyId.BitRate, bitRate * 1000); // Set the control mode (constrained is the default) var controlMode = BitrateControlMode.VariableConstrained; if (settings.TryGetValue("ControlMode", out string?controlModeValue)) { if (controlModeValue !.Equals("Average", StringComparison.OrdinalIgnoreCase)) { controlMode = BitrateControlMode.LongTermAverage; } else if (controlModeValue.Equals("Constant", StringComparison.OrdinalIgnoreCase)) { controlMode = BitrateControlMode.Constant; } } SetConverterProperty(converter, AudioConverterPropertyId.BitRateControlMode, (uint)controlMode); }
public void Initialize(Stream stream, AudioInfo info, AudioMetadata metadata, SettingDictionary settings) { var gain = 0; if (settings.TryGetValue("ApplyGain", out string applyGain)) { var scale = applyGain.Equals("Track", StringComparison.OrdinalIgnoreCase) ? CalculateScale(metadata.TrackGain, metadata.TrackPeak) : CalculateScale(metadata.AlbumGain, metadata.AlbumPeak); // Adjust the metadata so that it remains valid metadata.TrackGain = CalculateGain(metadata.TrackGain, scale); metadata.AlbumGain = CalculateGain(metadata.AlbumGain, scale); gain = (int)Math.Round(Math.Log10(scale) * 5120); } _comments = new MetadataToOpusCommentAdapter(metadata); _encoder = new Encoder(stream, info.SampleRate, info.Channels, (int)info.PlayLength.TotalSeconds, _comments.Handle); if (info.BitsPerSample > 0) { _encoder.SetLsbDepth(Math.Min(Math.Max(info.BitsPerSample, 8), 24)); } _encoder.SetHeaderGain(gain); if (!settings.TryGetValue("SerialNumber", out int serialNumber)) { serialNumber = new Random().Next(); } _encoder.SetSerialNumber(serialNumber); // Default to full VBR if (settings.TryGetValue("ControlMode", out string vbrMode)) { switch (vbrMode) { case "Variable": _encoder.SetVbrConstraint(false); break; // 'Constrained' is the libopusenc default case "Constant": _encoder.SetVbr(false); break; } } else { _encoder.SetVbrConstraint(false); } if (settings.TryGetValue("BitRate", out int bitRate)) { _encoder.SetBitRate(bitRate); } if (settings.TryGetValue("SignalType", out string signalType)) { _encoder.SetSignal(signalType.Equals("Speech", StringComparison.OrdinalIgnoreCase) ? SignalType.Speech : SignalType.Music); } else { _encoder.SetSignal(SignalType.Music); } }
public unsafe void WriteMetadata(Stream stream, AudioMetadata metadata, SettingDictionary settings) { using (var tempStream = new TempFileStream()) { OggStream inputOggStream = null; OggStream outputOggStream = null; #if NETSTANDARD2_0 var buffer = ArrayPool <byte> .Shared.Rent(4096); #else Span <byte> buffer = stackalloc byte[4096]; #endif try { using (var sync = new OggSync()) { var headerWritten = false; OggPage page; var pagesWritten = 0u; do { // Read from the buffer into a page while (!sync.PageOut(out page)) { #if NETSTANDARD2_0 var bytesRead = stream.Read(buffer, 0, buffer.Length); #else var bytesRead = stream.Read(buffer); #endif if (bytesRead == 0) { throw new AudioInvalidException("No Ogg stream was found."); } var nativeBuffer = new Span <byte>(sync.Buffer(bytesRead).ToPointer(), bytesRead); #if NETSTANDARD2_0 buffer.AsSpan().Slice(0, bytesRead).CopyTo(nativeBuffer); #else buffer.Slice(0, bytesRead).CopyTo(nativeBuffer); #endif sync.Wrote(bytesRead); } if (inputOggStream == null) { inputOggStream = new OggStream(SafeNativeMethods.OggPageSerialNo(page)); } if (outputOggStream == null) { outputOggStream = new OggStream(inputOggStream.SerialNumber); } // Write new header page(s) using a modified comment packet if (!headerWritten) { inputOggStream.PageIn(page); while (inputOggStream.PacketOut(out var packet)) { switch (packet.PacketNumber) { case 0: outputOggStream.PacketIn(packet); break; // Substitute the new comment packet case 1: using (var adapter = new MetadataToOpusCommentAdapter(metadata)) { adapter.HeaderOut(out var commentPacket); outputOggStream.PacketIn(commentPacket); } headerWritten = true; break; default: throw new AudioInvalidException("Missing header packet."); } } // Flush at the end of each header while (outputOggStream.Flush(out var outPage)) { WritePage(outPage, tempStream); pagesWritten++; } } else { // Copy the existing data pages verbatim, with updated sequence numbers UpdateSequenceNumber(ref page, pagesWritten); WritePage(page, tempStream); pagesWritten++; } } while (!SafeNativeMethods.OggPageEos(page)); // Once the end of the input is reached, overwrite the original file and return stream.Position = 0; stream.SetLength(tempStream.Length); tempStream.Position = 0; tempStream.CopyTo(stream); } } finally { #if NETSTANDARD2_0 ArrayPool <byte> .Shared.Return(buffer); #endif inputOggStream?.Dispose(); outputOggStream?.Dispose(); } } }
public void Initialize(Stream stream, AudioInfo info, AudioMetadata metadata, SettingDictionary settings) { _stream = stream; InitializeReplayGainFilter(info, metadata, settings); // Call the external ID3 encoder, if available var metadataEncoderFactory = ExtensionProvider.GetFactories <IAudioMetadataEncoder>("Extension", FileExtension).FirstOrDefault(); if (metadataEncoderFactory != null) { using (var export = metadataEncoderFactory.CreateExport()) using (var tempStream = new MemoryStream()) { // Buffer the tag in memory export.Value.WriteMetadata(tempStream, metadata, settings); // Pre-allocate the whole stream (estimate worst case of 320kbps, plus the tag) stream.SetLength(0xA000 * (long)info.PlayLength.TotalSeconds + tempStream.Length); // Flush the tag to the output stream tempStream.WriteTo(stream); } } _encoder = new(stream); _encoder.SetChannels(info.Channels); _encoder.SetSampleRate(info.SampleRate); if (info.FrameCount > 0) { _encoder.SetSampleCount((uint)info.FrameCount); } if (settings.TryGetValue("BitRate", out int bitRate)) { // Use ABR, unless ForceCBR is set to true if (settings.TryGetValue("ForceCBR", out bool forceCbr) && forceCbr) { _encoder.SetBitRate(bitRate); } else { _encoder.SetVbrMeanBitRate(bitRate); _encoder.SetVbrMode(VbrMode.Abr); } } else { // Use VBR quality 3 if nothing else is specified _encoder.SetVbrQuality( settings.TryGetValue("VBRQuality", out int vbrQuality) ? vbrQuality : 3); _encoder.SetVbrMode(VbrMode.Mtrh); } _encoder.InitializeParameters(); }
internal ValidatingSettingDictionary([NotNull] SettingInfoDictionary settingInfos, [CanBeNull] SettingDictionary settings = null) { _settingInfos = settingInfos; if (settings == null) { return; } foreach (var setting in settings) { Add(setting); } }
public void Initialize(Stream stream, AudioInfo info, AudioMetadata metadata, SettingDictionary settings) { _stream = stream; _metadata = metadata; _settings = settings; InitializeReplayGainFilter(info, metadata, settings); var inputDescription = GetInputDescription(info); _audioFile = new ExtendedAudioFile(GetOutputDescription(inputDescription), AudioFileType.M4A, stream); _audioFile.SetProperty(ExtendedAudioFilePropertyId.ClientDataFormat, inputDescription); var converter = _audioFile.GetProperty <IntPtr>(ExtendedAudioFilePropertyId.AudioConverter); var logger = LoggerManager.LoggerFactory.CreateLogger <AacAudioEncoder>(); // Enable high quality (defaults to medium, 0x40) SetConverterProperty(converter, AudioConverterPropertyId.CodecQuality, 0x60); if (settings.TryGetValue("BitRate", out int bitRate)) { if (bitRate > 256 && info.Channels == 1) { logger.LogWarning("The maximum bitrate for 1-channel audio is 256 kbps."); bitRate = 256; } else if (bitRate < 64 && info.Channels == 2) { logger.LogWarning("The minimum bitrate for 2-channel audio is 64 kbps."); bitRate = 64; } SetConverterProperty(converter, AudioConverterPropertyId.BitRate, bitRate * 1000); // Set the control mode (constrained is the default) var controlMode = BitrateControlMode.VariableConstrained; if (settings.TryGetValue("ControlMode", out string controlModeValue)) { if (controlModeValue.Equals("Average", StringComparison.OrdinalIgnoreCase)) { controlMode = BitrateControlMode.LongTermAverage; } else if (controlModeValue.Equals("Constant", StringComparison.OrdinalIgnoreCase)) { controlMode = BitrateControlMode.Constant; } } SetConverterProperty(converter, AudioConverterPropertyId.BitRateControlMode, (uint)controlMode); } else { // Enable a true variable bitrate SetConverterProperty(converter, AudioConverterPropertyId.BitRateControlMode, (uint)BitrateControlMode.Variable); // Use a default VBR quality index of 9 SetConverterProperty(converter, AudioConverterPropertyId.VbrQuality, settings.TryGetValue("VBRQuality", out int quality) ? _vbrQualities[quality] : _vbrQualities[9]); } // Setting the ConverterConfig property to null resynchronizes the converter settings _audioFile.SetProperty(ExtendedAudioFilePropertyId.ConverterConfig, IntPtr.Zero); }
public void OnGet(int id = 0) { Current = _settingManager.Find(id); }
public void Initialize(Stream stream, AudioInfo info, AudioMetadata metadata, SettingDictionary settings) { _bitsPerSample = info.BitsPerSample; _bytesPerSample = (int)Math.Ceiling(info.BitsPerSample / 8.0); _writer = new RiffWriter(stream); // Pre-allocate the entire stream to avoid fragmentation var estimatedSize = 44 + info.FrameCount * info.Channels * _bytesPerSample; estimatedSize += estimatedSize % 2; stream.SetLength(estimatedSize); _writer.Initialize("WAVE"); WriteFmtChunk(info); // ReSharper disable once PossibleNullReferenceException _writer.BeginChunk("data"); }
public void Initialize(Stream stream, AudioInfo info, AudioMetadata metadata, SettingDictionary settings) { _stream = stream; _metadata = metadata; _settings = settings; if (info.BitsPerSample == 0) { var logger = LoggerManager.LoggerFactory.CreateLogger <AlacAudioEncoder>(); logger.LogWarning("Transcoding from a lossy to a lossless format."); _bitsPerSample = 16; } else { _bitsPerSample = info.BitsPerSample; } // Pre-allocate the whole stream (estimate worst case compression, plus cover art) stream.SetLength(info.FrameCount * info.Channels * (long)Math.Ceiling(_bitsPerSample / 8.0) + (metadata.CoverArt?.Data.Length ?? 0)); var inputDescription = GetInputDescription(info); _audioFile = new(GetOutputDescription(inputDescription), AudioFileType.M4A, stream); _audioFile.SetProperty(ExtendedAudioFilePropertyId.ClientDataFormat, inputDescription); }