Code cleanup; Reader classes renamed to Decoders, Writers to Encoders, every Decoder must have a corresponding Settings class now just like Encoders. UserDefinedEncoders renamed to CommandLineEncoders, etc.

This commit is contained in:
Grigory Chudov
2018-03-24 12:15:49 -04:00
parent ca8bb2fff6
commit e1f8906170
65 changed files with 1713 additions and 1798 deletions

View File

@@ -1000,8 +1000,8 @@ namespace CUERipper
private void resetEncoderModes(AudioEncoderSettingsViewModel encoder) private void resetEncoderModes(AudioEncoderSettingsViewModel encoder)
{ {
encoder.settings.PCM = AudioPCMConfig.RedBook; encoder.Settings.PCM = AudioPCMConfig.RedBook;
buttonEncoderSettings.Enabled = encoder.settings.HasBrowsableAttributes(); buttonEncoderSettings.Enabled = encoder.Settings.HasBrowsableAttributes();
string[] modes = encoder.SupportedModes; string[] modes = encoder.SupportedModes;
if (modes == null || modes.Length < 2) if (modes == null || modes.Length < 2)
{ {
@@ -1015,12 +1015,12 @@ namespace CUERipper
if (encoder.EncoderModeIndex == -1) if (encoder.EncoderModeIndex == -1)
{ {
string defaultMode; string defaultMode;
encoder.settings.GetSupportedModes(out defaultMode); encoder.Settings.GetSupportedModes(out defaultMode);
encoder.settings.EncoderMode = defaultMode; encoder.Settings.EncoderMode = defaultMode;
} }
trackBarEncoderMode.Maximum = modes.Length - 1; trackBarEncoderMode.Maximum = modes.Length - 1;
trackBarEncoderMode.Value = encoder.EncoderModeIndex == -1 ? modes.Length - 1 : encoder.EncoderModeIndex; trackBarEncoderMode.Value = encoder.EncoderModeIndex == -1 ? modes.Length - 1 : encoder.EncoderModeIndex;
labelEncoderMode.Text = encoder.settings.EncoderMode; labelEncoderMode.Text = encoder.Settings.EncoderMode;
labelEncoderMinMode.Text = modes[0]; labelEncoderMinMode.Text = modes[0];
labelEncoderMaxMode.Text = modes[modes.Length - 1]; labelEncoderMaxMode.Text = modes[modes.Length - 1];
trackBarEncoderMode.Visible = true; trackBarEncoderMode.Visible = true;
@@ -1048,8 +1048,8 @@ namespace CUERipper
{ {
var encoder = bnComboBoxEncoder.SelectedItem as AudioEncoderSettingsViewModel; var encoder = bnComboBoxEncoder.SelectedItem as AudioEncoderSettingsViewModel;
string[] modes = encoder.SupportedModes; string[] modes = encoder.SupportedModes;
encoder.settings.EncoderMode = modes[trackBarEncoderMode.Value]; encoder.Settings.EncoderMode = modes[trackBarEncoderMode.Value];
labelEncoderMode.Text = encoder.settings.EncoderMode; labelEncoderMode.Text = encoder.Settings.EncoderMode;
} }
private void trackBarSecureMode_Scroll(object sender, EventArgs e) private void trackBarSecureMode_Scroll(object sender, EventArgs e)
@@ -1129,7 +1129,7 @@ namespace CUERipper
data.Encoders.RaiseListChangedEvents = false; data.Encoders.RaiseListChangedEvents = false;
foreach (var encoder in _config.encoders) foreach (var encoder in _config.Encoders)
if (encoder.Extension == SelectedOutputAudioFmt.extension) if (encoder.Extension == SelectedOutputAudioFmt.extension)
{ {
if (SelectedOutputAudioType == AudioEncoderType.Lossless && !encoder.Lossless) if (SelectedOutputAudioType == AudioEncoderType.Lossless && !encoder.Lossless)
@@ -1572,7 +1572,7 @@ namespace CUERipper
var encoder = bnComboBoxEncoder.SelectedItem as AudioEncoderSettingsViewModel; var encoder = bnComboBoxEncoder.SelectedItem as AudioEncoderSettingsViewModel;
if (encoder == null) if (encoder == null)
return; return;
var form = new Options(encoder.settings); var form = new Options(encoder.Settings);
form.propertyGrid1.HelpVisible = true; form.propertyGrid1.HelpVisible = true;
form.ShowDialog(this); form.ShowDialog(this);
resetEncoderModes(encoder); resetEncoderModes(encoder);

View File

@@ -40,7 +40,6 @@ namespace CUETools.Codecs.ALAC
public DecoderSettings() : base() { } public DecoderSettings() : base() { }
} }
[AudioDecoderClass(typeof(DecoderSettings))]
public class AudioDecoder : IAudioSource public class AudioDecoder : IAudioSource
{ {
public AudioDecoder(DecoderSettings settings, string path, Stream IO = null) public AudioDecoder(DecoderSettings settings, string path, Stream IO = null)

View File

@@ -67,7 +67,6 @@ namespace CUETools.Codecs.ALAC
public bool DoVerify { get; set; } public bool DoVerify { get; set; }
} }
[AudioEncoderClass(typeof(EncoderSettings))]
public class AudioEncoder : IAudioDest public class AudioEncoder : IAudioDest
{ {
Stream _IO = null; Stream _IO = null;

View File

@@ -5,20 +5,6 @@ using System.IO;
namespace CUETools.Codecs.BDLPCM namespace CUETools.Codecs.BDLPCM
{ {
public class DecoderSettings : AudioDecoderSettings
{
public override string Extension => "m2ts";
public override string Name => "cuetools";
public override Type DecoderType => typeof(AudioDecoder);
public override int Priority => 2;
public DecoderSettings() : base() { }
}
[AudioDecoderClass(typeof(DecoderSettings))]
public class AudioDecoder : IAudioSource public class AudioDecoder : IAudioSource
{ {
public unsafe AudioDecoder(string path, Stream IO, ushort pid) public unsafe AudioDecoder(string path, Stream IO, ushort pid)
@@ -37,7 +23,7 @@ namespace CUETools.Codecs.BDLPCM
_samplePos = 0; _samplePos = 0;
_sampleLen = -1; _sampleLen = -1;
demux_ts_packets(null, 0); demux_ts_packets(null, 0);
settings = new BDLPCMDecoderSettings(); settings = new DecoderSettings();
} }
public AudioDecoderSettings Settings { get { return settings; } } public AudioDecoderSettings Settings { get { return settings; } }
@@ -749,6 +735,6 @@ namespace CUETools.Codecs.BDLPCM
int demuxer_channel; int demuxer_channel;
TsStream chosenStream; TsStream chosenStream;
long _samplePos, _sampleLen; long _samplePos, _sampleLen;
BDLPCMDecoderSettings settings; DecoderSettings settings;
} }
} }

View File

@@ -7,17 +7,25 @@ using Newtonsoft.Json;
namespace CUETools.Codecs.BDLPCM namespace CUETools.Codecs.BDLPCM
{ {
[JsonObject(MemberSerialization.OptIn)] [JsonObject(MemberSerialization.OptIn)]
public class BDLPCMDecoderSettings : AudioDecoderSettings public class DecoderSettings : AudioDecoderSettings
{ {
public BDLPCMDecoderSettings() public override string Extension => "m2ts";
{
IgnoreShortItems = true; public override string Name => "cuetools";
}
public override Type DecoderType => typeof(AudioDecoder);
public override int Priority => 2;
public bool IgnoreShortItems { get; set; } public bool IgnoreShortItems { get; set; }
public int? Stream { get; set; } public int? Stream { get; set; }
public ushort? Pid { get; set; } public ushort? Pid { get; set; }
public DecoderSettings() : base()
{
IgnoreShortItems = true;
}
} }
} }

View File

@@ -6,20 +6,6 @@ using System.Globalization;
namespace CUETools.Codecs.BDLPCM namespace CUETools.Codecs.BDLPCM
{ {
public class MPLSDecoderSettings : AudioDecoderSettings
{
public override string Extension => "mpls";
public override string Name => "cuetools";
public override Type DecoderType => typeof(MPLSDecoder);
public override int Priority => 2;
public MPLSDecoderSettings() : base() { }
}
[AudioDecoderClass(typeof(MPLSDecoderSettings))]
public class MPLSDecoder : IAudioSource public class MPLSDecoder : IAudioSource
{ {
public unsafe MPLSDecoder(string path, Stream IO, ushort pid) public unsafe MPLSDecoder(string path, Stream IO, ushort pid)
@@ -30,7 +16,7 @@ namespace CUETools.Codecs.BDLPCM
public unsafe MPLSDecoder(string path, Stream IO) public unsafe MPLSDecoder(string path, Stream IO)
{ {
settings = new BDLPCMDecoderSettings(); settings = new DecoderSettings();
_path = path; _path = path;
_IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000); _IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000);
int length = (int)_IO.Length; int length = (int)_IO.Length;
@@ -453,7 +439,7 @@ namespace CUETools.Codecs.BDLPCM
List<AudioDecoder> readers; List<AudioDecoder> readers;
AudioDecoder currentReader; AudioDecoder currentReader;
MPLSHeader hdr_m; MPLSHeader hdr_m;
BDLPCMDecoderSettings settings; DecoderSettings settings;
} }
public struct MPLSPlaylistMark public struct MPLSPlaylistMark

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using Newtonsoft.Json;
namespace CUETools.Codecs.MPLS
{
[JsonObject(MemberSerialization.OptIn)]
public class DecoderSettings : AudioDecoderSettings
{
public override string Extension => "mpls";
public override string Name => "cuetools";
public override Type DecoderType => typeof(BDLPCM.MPLSDecoder);
public override int Priority => 2;
public bool IgnoreShortItems { get; set; }
public int? Stream { get; set; }
public ushort? Pid { get; set; }
public DecoderSettings() : base()
{
IgnoreShortItems = true;
}
}
}

View File

@@ -279,7 +279,6 @@ namespace CUETools.Codecs.FLACCL
GPU = DeviceType.GPU GPU = DeviceType.GPU
} }
[AudioEncoderClass(typeof(EncoderSettings))]
public class AudioEncoder : IAudioDest public class AudioEncoder : IAudioDest
{ {
Stream _IO = null; Stream _IO = null;

View File

@@ -39,7 +39,6 @@ namespace CUETools.Codecs.FLAKE
public DecoderSettings() : base() { } public DecoderSettings() : base() { }
} }
[AudioDecoderClass(typeof(DecoderSettings))]
public class AudioDecoder: IAudioSource public class AudioDecoder: IAudioSource
{ {
int[] samplesBuffer; int[] samplesBuffer;

View File

@@ -272,8 +272,6 @@ namespace CUETools.Codecs.FLAKE
public string[] Tags { get; set; } public string[] Tags { get; set; }
} }
[AudioEncoderClass(typeof(EncoderSettings))]
//[AudioEncoderClass("libFlake nonsub", "flac", true, "9 10 11", "9", 3, typeof(FlakeWriterSettings))]
public class AudioEncoder : IAudioDest public class AudioEncoder : IAudioDest
{ {
Stream _IO = null; Stream _IO = null;

View File

@@ -12,7 +12,7 @@ namespace CUETools.Codecs.Icecast
{ {
private long _sampleOffset = 0; private long _sampleOffset = 0;
private AudioEncoderSettings m_settings; private AudioEncoderSettings m_settings;
private LAME.LAMEEncoderCBR encoder = null; private LAME.AudioEncoder encoder = null;
private HttpWebRequest req = null; private HttpWebRequest req = null;
private HttpWebResponse resp = null; private HttpWebResponse resp = null;
private Stream reqStream; private Stream reqStream;
@@ -80,12 +80,12 @@ namespace CUETools.Codecs.Icecast
resp = req.GetResponse() as HttpWebResponse; resp = req.GetResponse() as HttpWebResponse;
if (resp.StatusCode == HttpStatusCode.OK) if (resp.StatusCode == HttpStatusCode.OK)
{ {
var encoderSettings = new CUETools.Codecs.LAME.LAMEEncoderCBRSettings() { PCM = AudioPCMConfig.RedBook }; var encoderSettings = new CUETools.Codecs.LAME.CBREncoderSettings() { PCM = AudioPCMConfig.RedBook };
encoderSettings.StereoMode = settings.JointStereo ? //encoderSettings.StereoMode = settings.JointStereo ?
CUETools.Codecs.LAME.Interop.MpegMode.JOINT_STEREO : // CUETools.Codecs.LAME.Interop.MpegMode.JOINT_STEREO :
CUETools.Codecs.LAME.Interop.MpegMode.STEREO; // CUETools.Codecs.LAME.Interop.MpegMode.STEREO;
encoderSettings.CustomBitrate = settings.Bitrate; //encoderSettings.CustomBitrate = settings.Bitrate;
encoder = new CUETools.Codecs.LAME.LAMEEncoderCBR("", reqStream, encoderSettings); encoder = new CUETools.Codecs.LAME.AudioEncoder(encoderSettings, "", reqStream);
} }
} }
catch (WebException ex) catch (WebException ex)

View File

@@ -40,7 +40,6 @@ namespace CUETools.Codecs.WMA
public DecoderSettings() : base() { } public DecoderSettings() : base() { }
} }
[AudioDecoderClass(typeof(DecoderSettings))]
public class AudioDecoder : IAudioSource public class AudioDecoder : IAudioSource
{ {
IWMSyncReader m_syncReader; IWMSyncReader m_syncReader;

View File

@@ -276,8 +276,6 @@ namespace CUETools.Codecs.WMA
} }
} }
[AudioEncoderClass(typeof(LosslessEncoderSettings))]
[AudioEncoderClass(typeof(LossyEncoderSettings))]
public class AudioEncoder : IAudioDest public class AudioEncoder : IAudioDest
{ {
IWMWriter m_pEncoder; IWMWriter m_pEncoder;

View File

@@ -1,29 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net40;net20;netstandard2.0</TargetFrameworks> <TargetFrameworks>net40;net20;netstandard2.0</TargetFrameworks>
<Version>2.1.7.0</Version> <Version>2.1.7.0</Version>
<AssemblyName>CUETools.Codecs.LAME</AssemblyName> <AssemblyName>CUETools.Codecs.lame_enc</AssemblyName>
<RootNamespace>CUETools.Codecs.LAME</RootNamespace> <RootNamespace>CUETools.Codecs.lame_enc</RootNamespace>
<Product>CUETools</Product> <Product>CUETools</Product>
<Description>A library for encoding mp3 using LAME encoder.</Description> <Description>A library for encoding mp3 using LAME encoder.</Description>
<Copyright>Copyright (c) 2008-2018 Grigory Chudov</Copyright> <Copyright>Copyright (c) 2008-2018 Grigory Chudov</Copyright>
<Authors>Grigory Chudov</Authors> <Authors>Grigory Chudov</Authors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<OutputPath>..\bin\$(Configuration)\plugins\win32</OutputPath> <OutputPath>..\bin\$(Configuration)\plugins\win32</OutputPath>
<RepositoryUrl>https://github.com/gchudov/cuetools.net</RepositoryUrl> <RepositoryUrl>https://github.com/gchudov/cuetools.net</RepositoryUrl>
<RepositoryType>git</RepositoryType> <RepositoryType>git</RepositoryType>
<Company /> <Company />
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ProjectReference> <ProjectReference>
<Private>False</Private> <Private>False</Private>
</ProjectReference> </ProjectReference>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\CUETools.Codecs\CUETools.Codecs.csproj" /> <ProjectReference Include="..\CUETools.Codecs\CUETools.Codecs.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,14 +1,14 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CUETools.Codecs.LAME.Interop namespace CUETools.Codecs.LAME.Interop
{ {
[StructLayout(LayoutKind.Sequential), Serializable] [StructLayout(LayoutKind.Sequential), Serializable]
public struct ACC public struct ACC
{ {
public uint dwSampleRate; public uint dwSampleRate;
public byte byMode; public byte byMode;
public ushort wBitrate; public ushort wBitrate;
public byte byEncodingMethod; public byte byEncodingMethod;
} }
} }

View File

@@ -1,27 +1,27 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CUETools.Codecs.LAME.Interop namespace CUETools.Codecs.LAME.Interop
{ {
[StructLayout(LayoutKind.Sequential), Serializable] [StructLayout(LayoutKind.Sequential), Serializable]
public class BE_CONFIG public class BE_CONFIG
{ {
// encoding formats // encoding formats
public const uint BE_CONFIG_MP3 = 0; public const uint BE_CONFIG_MP3 = 0;
public const uint BE_CONFIG_LAME = 256; public const uint BE_CONFIG_LAME = 256;
public uint dwConfig; public uint dwConfig;
public Format format; public Format format;
public BE_CONFIG(AudioPCMConfig format, uint MpeBitRate, uint quality) public BE_CONFIG(AudioPCMConfig format, uint MpeBitRate, uint quality)
{ {
this.dwConfig = BE_CONFIG_LAME; this.dwConfig = BE_CONFIG_LAME;
this.format = new Format(format, MpeBitRate, quality); this.format = new Format(format, MpeBitRate, quality);
} }
public BE_CONFIG(AudioPCMConfig format) public BE_CONFIG(AudioPCMConfig format)
: this(format, 0, 5) : this(format, 0, 5)
{ {
} }
} }
} }

View File

@@ -1,34 +1,34 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CUETools.Codecs.LAME.Interop namespace CUETools.Codecs.LAME.Interop
{ {
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class BE_VERSION public class BE_VERSION
{ {
public const uint BE_MAX_HOMEPAGE = 256; public const uint BE_MAX_HOMEPAGE = 256;
public byte byDLLMajorVersion; public byte byDLLMajorVersion;
public byte byDLLMinorVersion; public byte byDLLMinorVersion;
public byte byMajorVersion; public byte byMajorVersion;
public byte byMinorVersion; public byte byMinorVersion;
// DLL Release date // DLL Release date
public byte byDay; public byte byDay;
public byte byMonth; public byte byMonth;
public ushort wYear; public ushort wYear;
//Homepage URL //Homepage URL
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257/*BE_MAX_HOMEPAGE+1*/)] [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257/*BE_MAX_HOMEPAGE+1*/)]
public string zHomepage; public string zHomepage;
public byte byAlphaLevel; public byte byAlphaLevel;
public byte byBetaLevel; public byte byBetaLevel;
public byte byMMXEnabled; public byte byMMXEnabled;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 125)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 125)]
public byte[] btReserved; public byte[] btReserved;
public BE_VERSION() public BE_VERSION()
{ {
btReserved = new byte[125]; btReserved = new byte[125];
} }
} }
} }

View File

@@ -1,21 +1,21 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CUETools.Codecs.LAME.Interop namespace CUETools.Codecs.LAME.Interop
{ {
[StructLayout(LayoutKind.Explicit), Serializable] [StructLayout(LayoutKind.Explicit), Serializable]
public class Format public class Format
{ {
[FieldOffset(0)] [FieldOffset(0)]
public MP3 mp3; public MP3 mp3;
[FieldOffset(0)] [FieldOffset(0)]
public LHV1 lhv1; public LHV1 lhv1;
[FieldOffset(0)] [FieldOffset(0)]
public ACC acc; public ACC acc;
public Format(AudioPCMConfig format, uint MpeBitRate, uint quality) public Format(AudioPCMConfig format, uint MpeBitRate, uint quality)
{ {
lhv1 = new LHV1(format, MpeBitRate, quality); lhv1 = new LHV1(format, MpeBitRate, quality);
} }
} }
} }

View File

@@ -1,34 +1,34 @@
namespace CUETools.Codecs.LAME.Interop namespace CUETools.Codecs.LAME.Interop
{ {
public enum LAME_QUALITY_PRESET : int public enum LAME_QUALITY_PRESET : int
{ {
LQP_NOPRESET = -1, LQP_NOPRESET = -1,
// QUALITY PRESETS // QUALITY PRESETS
LQP_NORMAL_QUALITY = 0, LQP_NORMAL_QUALITY = 0,
LQP_LOW_QUALITY = 1, LQP_LOW_QUALITY = 1,
LQP_HIGH_QUALITY = 2, LQP_HIGH_QUALITY = 2,
LQP_VOICE_QUALITY = 3, LQP_VOICE_QUALITY = 3,
LQP_R3MIX = 4, LQP_R3MIX = 4,
LQP_VERYHIGH_QUALITY = 5, LQP_VERYHIGH_QUALITY = 5,
LQP_STANDARD = 6, LQP_STANDARD = 6,
LQP_FAST_STANDARD = 7, LQP_FAST_STANDARD = 7,
LQP_EXTREME = 8, LQP_EXTREME = 8,
LQP_FAST_EXTREME = 9, LQP_FAST_EXTREME = 9,
LQP_INSANE = 10, LQP_INSANE = 10,
LQP_ABR = 11, LQP_ABR = 11,
LQP_CBR = 12, LQP_CBR = 12,
LQP_MEDIUM = 13, LQP_MEDIUM = 13,
LQP_FAST_MEDIUM = 14, LQP_FAST_MEDIUM = 14,
// NEW PRESET VALUES // NEW PRESET VALUES
LQP_PHONE = 1000, LQP_PHONE = 1000,
LQP_SW = 2000, LQP_SW = 2000,
LQP_AM = 3000, LQP_AM = 3000,
LQP_FM = 4000, LQP_FM = 4000,
LQP_VOICE = 5000, LQP_VOICE = 5000,
LQP_RADIO = 6000, LQP_RADIO = 6000,
LQP_TAPE = 7000, LQP_TAPE = 7000,
LQP_HIFI = 8000, LQP_HIFI = 8000,
LQP_CD = 9000, LQP_CD = 9000,
LQP_STUDIO = 10000 LQP_STUDIO = 10000
} }
} }

View File

@@ -1,130 +1,130 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CUETools.Codecs.LAME.Interop namespace CUETools.Codecs.LAME.Interop
{ {
[StructLayout(LayoutKind.Sequential, Size = 327), Serializable] [StructLayout(LayoutKind.Sequential, Size = 327), Serializable]
public struct LHV1 // BE_CONFIG_LAME LAME header version 1 public struct LHV1 // BE_CONFIG_LAME LAME header version 1
{ {
public const uint MPEG1 = 1; public const uint MPEG1 = 1;
public const uint MPEG2 = 0; public const uint MPEG2 = 0;
// STRUCTURE INFORMATION // STRUCTURE INFORMATION
public uint dwStructVersion; public uint dwStructVersion;
public uint dwStructSize; public uint dwStructSize;
// BASIC ENCODER SETTINGS // BASIC ENCODER SETTINGS
public uint dwSampleRate; // SAMPLERATE OF INPUT FILE public uint dwSampleRate; // SAMPLERATE OF INPUT FILE
public uint dwReSampleRate; // DOWNSAMPLERATE, 0=ENCODER DECIDES public uint dwReSampleRate; // DOWNSAMPLERATE, 0=ENCODER DECIDES
public MpegMode nMode; // STEREO, MONO public MpegMode nMode; // STEREO, MONO
public uint dwBitrate; // CBR bitrate, VBR min bitrate public uint dwBitrate; // CBR bitrate, VBR min bitrate
public uint dwMaxBitrate; // CBR ignored, VBR Max bitrate public uint dwMaxBitrate; // CBR ignored, VBR Max bitrate
public LAME_QUALITY_PRESET nPreset; // Quality preset public LAME_QUALITY_PRESET nPreset; // Quality preset
public uint dwMpegVersion; // MPEG-1 OR MPEG-2 public uint dwMpegVersion; // MPEG-1 OR MPEG-2
public uint dwPsyModel; // FUTURE USE, SET TO 0 public uint dwPsyModel; // FUTURE USE, SET TO 0
public uint dwEmphasis; // FUTURE USE, SET TO 0 public uint dwEmphasis; // FUTURE USE, SET TO 0
// BIT STREAM SETTINGS // BIT STREAM SETTINGS
public int bPrivate; // Set Private Bit (TRUE/FALSE) public int bPrivate; // Set Private Bit (TRUE/FALSE)
public int bCRC; // Insert CRC (TRUE/FALSE) public int bCRC; // Insert CRC (TRUE/FALSE)
public int bCopyright; // Set Copyright Bit (TRUE/FALSE) public int bCopyright; // Set Copyright Bit (TRUE/FALSE)
public int bOriginal; // Set Original Bit (TRUE/FALSE) public int bOriginal; // Set Original Bit (TRUE/FALSE)
// VBR STUFF // VBR STUFF
public int bWriteVBRHeader; // WRITE XING VBR HEADER (TRUE/FALSE) public int bWriteVBRHeader; // WRITE XING VBR HEADER (TRUE/FALSE)
public int bEnableVBR; // USE VBR ENCODING (TRUE/FALSE) public int bEnableVBR; // USE VBR ENCODING (TRUE/FALSE)
public int nVBRQuality; // VBR QUALITY 0..9 public int nVBRQuality; // VBR QUALITY 0..9
public uint dwVbrAbr_bps; // Use ABR in stead of nVBRQuality public uint dwVbrAbr_bps; // Use ABR in stead of nVBRQuality
public VBRMETHOD nVbrMethod; public VBRMETHOD nVbrMethod;
public int bNoRes; // Disable Bit resorvoir (TRUE/FALSE) public int bNoRes; // Disable Bit resorvoir (TRUE/FALSE)
// MISC SETTINGS // MISC SETTINGS
public int bStrictIso; // Use strict ISO encoding rules (TRUE/FALSE) public int bStrictIso; // Use strict ISO encoding rules (TRUE/FALSE)
public ushort nQuality; // Quality Setting, HIGH BYTE should be NOT LOW byte, otherwhise quality=5 public ushort nQuality; // Quality Setting, HIGH BYTE should be NOT LOW byte, otherwhise quality=5
// FUTURE USE, SET TO 0, align strucutre to 331 bytes // FUTURE USE, SET TO 0, align strucutre to 331 bytes
//[ MarshalAs( UnmanagedType.ByValArray, SizeConst=255-4*4-2 )] //[ MarshalAs( UnmanagedType.ByValArray, SizeConst=255-4*4-2 )]
//public byte[] btReserved;//[255-4*sizeof(DWORD) - sizeof( WORD )]; //public byte[] btReserved;//[255-4*sizeof(DWORD) - sizeof( WORD )];
public LHV1(AudioPCMConfig format, uint MpeBitRate, uint quality) public LHV1(AudioPCMConfig format, uint MpeBitRate, uint quality)
{ {
dwStructVersion = 1; dwStructVersion = 1;
dwStructSize = (uint)Marshal.SizeOf(typeof(BE_CONFIG)); dwStructSize = (uint)Marshal.SizeOf(typeof(BE_CONFIG));
switch (format.SampleRate) switch (format.SampleRate)
{ {
case 16000: case 16000:
case 22050: case 22050:
case 24000: case 24000:
dwMpegVersion = MPEG2; dwMpegVersion = MPEG2;
break; break;
case 32000: case 32000:
case 44100: case 44100:
case 48000: case 48000:
dwMpegVersion = MPEG1; dwMpegVersion = MPEG1;
break; break;
default: default:
throw new ArgumentOutOfRangeException("format", "Unsupported sample rate"); throw new ArgumentOutOfRangeException("format", "Unsupported sample rate");
} }
dwSampleRate = (uint)format.SampleRate; // INPUT FREQUENCY dwSampleRate = (uint)format.SampleRate; // INPUT FREQUENCY
dwReSampleRate = 0; // DON'T RESAMPLE dwReSampleRate = 0; // DON'T RESAMPLE
switch (format.ChannelCount) switch (format.ChannelCount)
{ {
case 1: case 1:
nMode = MpegMode.MONO; nMode = MpegMode.MONO;
break; break;
case 2: case 2:
nMode = MpegMode.STEREO; nMode = MpegMode.STEREO;
break; break;
default: default:
throw new ArgumentOutOfRangeException("format", "Invalid number of channels"); throw new ArgumentOutOfRangeException("format", "Invalid number of channels");
} }
switch (MpeBitRate) switch (MpeBitRate)
{ {
case 0: case 0:
case 32: case 32:
case 40: case 40:
case 48: case 48:
case 56: case 56:
case 64: case 64:
case 80: case 80:
case 96: case 96:
case 112: case 112:
case 128: case 128:
case 160: //Allowed bit rates in MPEG1 and MPEG2 case 160: //Allowed bit rates in MPEG1 and MPEG2
break; break;
case 192: case 192:
case 224: case 224:
case 256: case 256:
case 320: //Allowed only in MPEG1 case 320: //Allowed only in MPEG1
if (dwMpegVersion != MPEG1) if (dwMpegVersion != MPEG1)
{ {
throw new ArgumentOutOfRangeException("MpsBitRate", "Bit rate not compatible with input format"); throw new ArgumentOutOfRangeException("MpsBitRate", "Bit rate not compatible with input format");
} }
break; break;
case 8: case 8:
case 16: case 16:
case 24: case 24:
case 144: //Allowed only in MPEG2 case 144: //Allowed only in MPEG2
if (dwMpegVersion != MPEG2) if (dwMpegVersion != MPEG2)
{ {
throw new ArgumentOutOfRangeException("MpsBitRate", "Bit rate not compatible with input format"); throw new ArgumentOutOfRangeException("MpsBitRate", "Bit rate not compatible with input format");
} }
break; break;
default: default:
throw new ArgumentOutOfRangeException("MpsBitRate", "Unsupported bit rate"); throw new ArgumentOutOfRangeException("MpsBitRate", "Unsupported bit rate");
} }
dwBitrate = MpeBitRate; // MINIMUM BIT RATE dwBitrate = MpeBitRate; // MINIMUM BIT RATE
nPreset = LAME_QUALITY_PRESET.LQP_NORMAL_QUALITY; // QUALITY PRESET SETTING nPreset = LAME_QUALITY_PRESET.LQP_NORMAL_QUALITY; // QUALITY PRESET SETTING
dwPsyModel = 0; // USE DEFAULT PSYCHOACOUSTIC MODEL dwPsyModel = 0; // USE DEFAULT PSYCHOACOUSTIC MODEL
dwEmphasis = 0; // NO EMPHASIS TURNED ON dwEmphasis = 0; // NO EMPHASIS TURNED ON
bOriginal = 1; // SET ORIGINAL FLAG bOriginal = 1; // SET ORIGINAL FLAG
bWriteVBRHeader = 0; bWriteVBRHeader = 0;
bNoRes = 0; // No Bit resorvoir bNoRes = 0; // No Bit resorvoir
bCopyright = 0; bCopyright = 0;
bCRC = 0; bCRC = 0;
bEnableVBR = 0; bEnableVBR = 0;
bPrivate = 0; bPrivate = 0;
bStrictIso = 0; bStrictIso = 0;
dwMaxBitrate = 0; dwMaxBitrate = 0;
dwVbrAbr_bps = 0; dwVbrAbr_bps = 0;
nQuality = (ushort)(quality | ((~quality) << 8)); nQuality = (ushort)(quality | ((~quality) << 8));
nVbrMethod = VBRMETHOD.VBR_METHOD_NONE; nVbrMethod = VBRMETHOD.VBR_METHOD_NONE;
nVBRQuality = 0; nVBRQuality = 0;
} }
} }
} }

View File

@@ -1,161 +1,161 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CUETools.Codecs.LAME.Interop namespace CUETools.Codecs.LAME.Interop
{ {
/// <summary> /// <summary>
/// Lame_enc DLL functions /// Lame_enc DLL functions
/// </summary> /// </summary>
public class Lame_encDll public class Lame_encDll
{ {
//Error codes //Error codes
public const uint BE_ERR_SUCCESSFUL = 0; public const uint BE_ERR_SUCCESSFUL = 0;
public const uint BE_ERR_INVALID_FORMAT = 1; public const uint BE_ERR_INVALID_FORMAT = 1;
public const uint BE_ERR_INVALID_FORMAT_PARAMETERS = 2; public const uint BE_ERR_INVALID_FORMAT_PARAMETERS = 2;
public const uint BE_ERR_NO_MORE_HANDLES = 3; public const uint BE_ERR_NO_MORE_HANDLES = 3;
public const uint BE_ERR_INVALID_HANDLE = 4; public const uint BE_ERR_INVALID_HANDLE = 4;
/// <summary> /// <summary>
/// This function is the first to call before starting an encoding stream. /// This function is the first to call before starting an encoding stream.
/// </summary> /// </summary>
/// <param name="pbeConfig">Encoder settings</param> /// <param name="pbeConfig">Encoder settings</param>
/// <param name="dwSamples">Receives the number of samples (not bytes, each sample is a SHORT) to send to each beEncodeChunk() on return.</param> /// <param name="dwSamples">Receives the number of samples (not bytes, each sample is a SHORT) to send to each beEncodeChunk() on return.</param>
/// <param name="dwBufferSize">Receives the minimun number of bytes that must have the output(result) buffer</param> /// <param name="dwBufferSize">Receives the minimun number of bytes that must have the output(result) buffer</param>
/// <param name="phbeStream">Receives the stream handle on return</param> /// <param name="phbeStream">Receives the stream handle on return</param>
/// <returns>On success: BE_ERR_SUCCESSFUL</returns> /// <returns>On success: BE_ERR_SUCCESSFUL</returns>
[DllImport("Lame_enc.dll")] [DllImport("Lame_enc.dll")]
public static extern uint beInitStream(BE_CONFIG pbeConfig, ref uint dwSamples, ref uint dwBufferSize, ref uint phbeStream); public static extern uint beInitStream(BE_CONFIG pbeConfig, ref uint dwSamples, ref uint dwBufferSize, ref uint phbeStream);
/// <summary> /// <summary>
/// Encodes a chunk of samples. Please note that if you have set the output to /// Encodes a chunk of samples. Please note that if you have set the output to
/// generate mono MP3 files you must feed beEncodeChunk() with mono samples /// generate mono MP3 files you must feed beEncodeChunk() with mono samples
/// </summary> /// </summary>
/// <param name="hbeStream">Handle of the stream.</param> /// <param name="hbeStream">Handle of the stream.</param>
/// <param name="nSamples">Number of samples to be encoded for this call. /// <param name="nSamples">Number of samples to be encoded for this call.
/// This should be identical to what is returned by beInitStream(), /// This should be identical to what is returned by beInitStream(),
/// unless you are encoding the last chunk, which might be smaller.</param> /// unless you are encoding the last chunk, which might be smaller.</param>
/// <param name="pInSamples">Array of 16-bit signed samples to be encoded. /// <param name="pInSamples">Array of 16-bit signed samples to be encoded.
/// These should be in stereo when encoding a stereo MP3 /// These should be in stereo when encoding a stereo MP3
/// and mono when encoding a mono MP3</param> /// and mono when encoding a mono MP3</param>
/// <param name="pOutput">Buffer where to write the encoded data. /// <param name="pOutput">Buffer where to write the encoded data.
/// This buffer should be at least of the minimum size returned by beInitStream().</param> /// This buffer should be at least of the minimum size returned by beInitStream().</param>
/// <param name="pdwOutput">Returns the number of bytes of encoded data written. /// <param name="pdwOutput">Returns the number of bytes of encoded data written.
/// The amount of data written might vary from chunk to chunk</param> /// The amount of data written might vary from chunk to chunk</param>
/// <returns>On success: BE_ERR_SUCCESSFUL</returns> /// <returns>On success: BE_ERR_SUCCESSFUL</returns>
[DllImport("Lame_enc.dll")] [DllImport("Lame_enc.dll")]
public static extern uint beEncodeChunk(uint hbeStream, uint nSamples, short[] pInSamples, [In, Out] byte[] pOutput, ref uint pdwOutput); public static extern uint beEncodeChunk(uint hbeStream, uint nSamples, short[] pInSamples, [In, Out] byte[] pOutput, ref uint pdwOutput);
/// <summary> /// <summary>
/// Encodes a chunk of samples. Please note that if you have set the output to /// Encodes a chunk of samples. Please note that if you have set the output to
/// generate mono MP3 files you must feed beEncodeChunk() with mono samples /// generate mono MP3 files you must feed beEncodeChunk() with mono samples
/// </summary> /// </summary>
/// <param name="hbeStream">Handle of the stream.</param> /// <param name="hbeStream">Handle of the stream.</param>
/// <param name="nSamples">Number of samples to be encoded for this call. /// <param name="nSamples">Number of samples to be encoded for this call.
/// This should be identical to what is returned by beInitStream(), /// This should be identical to what is returned by beInitStream(),
/// unless you are encoding the last chunk, which might be smaller.</param> /// unless you are encoding the last chunk, which might be smaller.</param>
/// <param name="pSamples">Pointer at the 16-bit signed samples to be encoded. /// <param name="pSamples">Pointer at the 16-bit signed samples to be encoded.
/// InPtr is used to pass any type of array without need of make memory copy, /// InPtr is used to pass any type of array without need of make memory copy,
/// then gaining in performance. Note that nSamples is not the number of bytes, /// then gaining in performance. Note that nSamples is not the number of bytes,
/// but samples (is sample is a SHORT)</param> /// but samples (is sample is a SHORT)</param>
/// <param name="pOutput">Buffer where to write the encoded data. /// <param name="pOutput">Buffer where to write the encoded data.
/// This buffer should be at least of the minimum size returned by beInitStream().</param> /// This buffer should be at least of the minimum size returned by beInitStream().</param>
/// <param name="pdwOutput">Returns the number of bytes of encoded data written. /// <param name="pdwOutput">Returns the number of bytes of encoded data written.
/// The amount of data written might vary from chunk to chunk</param> /// The amount of data written might vary from chunk to chunk</param>
/// <returns>On success: BE_ERR_SUCCESSFUL</returns> /// <returns>On success: BE_ERR_SUCCESSFUL</returns>
[DllImport("Lame_enc.dll")] [DllImport("Lame_enc.dll")]
protected static extern uint beEncodeChunk(uint hbeStream, uint nSamples, IntPtr pSamples, IntPtr pOutput, ref uint pdwOutput); protected static extern uint beEncodeChunk(uint hbeStream, uint nSamples, IntPtr pSamples, IntPtr pOutput, ref uint pdwOutput);
/// <summary> /// <summary>
/// Encodes a chunk of samples. Samples are contained in a byte array /// Encodes a chunk of samples. Samples are contained in a byte array
/// </summary> /// </summary>
/// <param name="hbeStream">Handle of the stream.</param> /// <param name="hbeStream">Handle of the stream.</param>
/// <param name="buffer">Bytes to encode</param> /// <param name="buffer">Bytes to encode</param>
/// <param name="index">Position of the first byte to encode</param> /// <param name="index">Position of the first byte to encode</param>
/// <param name="nBytes">Number of bytes to encode (not samples, samples are two byte lenght)</param> /// <param name="nBytes">Number of bytes to encode (not samples, samples are two byte lenght)</param>
/// <param name="pOutput">Buffer where to write the encoded data. /// <param name="pOutput">Buffer where to write the encoded data.
/// This buffer should be at least of the minimum size returned by beInitStream().</param> /// This buffer should be at least of the minimum size returned by beInitStream().</param>
/// <param name="pdwOutput">Returns the number of bytes of encoded data written. /// <param name="pdwOutput">Returns the number of bytes of encoded data written.
/// The amount of data written might vary from chunk to chunk</param> /// The amount of data written might vary from chunk to chunk</param>
/// <returns>On success: BE_ERR_SUCCESSFUL</returns> /// <returns>On success: BE_ERR_SUCCESSFUL</returns>
public static unsafe uint EncodeChunk(uint hbeStream, byte* pSamples, uint nBytes, byte* pOutput, ref uint pdwOutput) public static unsafe uint EncodeChunk(uint hbeStream, byte* pSamples, uint nBytes, byte* pOutput, ref uint pdwOutput)
{ {
return beEncodeChunk(hbeStream, nBytes / 2/*Samples*/, (IntPtr)pSamples, (IntPtr)pOutput, ref pdwOutput); return beEncodeChunk(hbeStream, nBytes / 2/*Samples*/, (IntPtr)pSamples, (IntPtr)pOutput, ref pdwOutput);
} }
/// <summary> /// <summary>
/// Encodes a chunk of samples. Samples are contained in a byte array /// Encodes a chunk of samples. Samples are contained in a byte array
/// </summary> /// </summary>
/// <param name="hbeStream">Handle of the stream.</param> /// <param name="hbeStream">Handle of the stream.</param>
/// <param name="buffer">Bytes to encode</param> /// <param name="buffer">Bytes to encode</param>
/// <param name="index">Position of the first byte to encode</param> /// <param name="index">Position of the first byte to encode</param>
/// <param name="nBytes">Number of bytes to encode (not samples, samples are two byte lenght)</param> /// <param name="nBytes">Number of bytes to encode (not samples, samples are two byte lenght)</param>
/// <param name="pOutput">Buffer where to write the encoded data. /// <param name="pOutput">Buffer where to write the encoded data.
/// This buffer should be at least of the minimum size returned by beInitStream().</param> /// This buffer should be at least of the minimum size returned by beInitStream().</param>
/// <param name="pdwOutput">Returns the number of bytes of encoded data written. /// <param name="pdwOutput">Returns the number of bytes of encoded data written.
/// The amount of data written might vary from chunk to chunk</param> /// The amount of data written might vary from chunk to chunk</param>
/// <returns>On success: BE_ERR_SUCCESSFUL</returns> /// <returns>On success: BE_ERR_SUCCESSFUL</returns>
public static unsafe uint EncodeChunk(uint hbeStream, byte[] Samples, int index, uint nBytes, byte[] Output, ref uint pdwOutput) public static unsafe uint EncodeChunk(uint hbeStream, byte[] Samples, int index, uint nBytes, byte[] Output, ref uint pdwOutput)
{ {
fixed (byte* pSamples = &Samples[index], pOutput = Output) fixed (byte* pSamples = &Samples[index], pOutput = Output)
return beEncodeChunk(hbeStream, nBytes / 2/*Samples*/, (IntPtr)pSamples, (IntPtr)pOutput, ref pdwOutput); return beEncodeChunk(hbeStream, nBytes / 2/*Samples*/, (IntPtr)pSamples, (IntPtr)pOutput, ref pdwOutput);
} }
/// <summary> /// <summary>
/// Encodes a chunk of samples. Samples are contained in a byte array /// Encodes a chunk of samples. Samples are contained in a byte array
/// </summary> /// </summary>
/// <param name="hbeStream">Handle of the stream.</param> /// <param name="hbeStream">Handle of the stream.</param>
/// <param name="buffer">Bytes to encode</param> /// <param name="buffer">Bytes to encode</param>
/// <param name="pOutput">Buffer where to write the encoded data. /// <param name="pOutput">Buffer where to write the encoded data.
/// This buffer should be at least of the minimum size returned by beInitStream().</param> /// This buffer should be at least of the minimum size returned by beInitStream().</param>
/// <param name="pdwOutput">Returns the number of bytes of encoded data written. /// <param name="pdwOutput">Returns the number of bytes of encoded data written.
/// The amount of data written might vary from chunk to chunk</param> /// The amount of data written might vary from chunk to chunk</param>
/// <returns>On success: BE_ERR_SUCCESSFUL</returns> /// <returns>On success: BE_ERR_SUCCESSFUL</returns>
public static uint EncodeChunk(uint hbeStream, byte[] buffer, byte[] pOutput, ref uint pdwOutput) public static uint EncodeChunk(uint hbeStream, byte[] buffer, byte[] pOutput, ref uint pdwOutput)
{ {
return EncodeChunk(hbeStream, buffer, 0, (uint)buffer.Length, pOutput, ref pdwOutput); return EncodeChunk(hbeStream, buffer, 0, (uint)buffer.Length, pOutput, ref pdwOutput);
} }
/// <summary> /// <summary>
/// This function should be called after encoding the last chunk in order to flush /// This function should be called after encoding the last chunk in order to flush
/// the encoder. It writes any encoded data that still might be left inside the /// the encoder. It writes any encoded data that still might be left inside the
/// encoder to the output buffer. This function should NOT be called unless /// encoder to the output buffer. This function should NOT be called unless
/// you have encoded all of the chunks in your stream. /// you have encoded all of the chunks in your stream.
/// </summary> /// </summary>
/// <param name="hbeStream">Handle of the stream.</param> /// <param name="hbeStream">Handle of the stream.</param>
/// <param name="pOutput">Where to write the encoded data. This buffer should be /// <param name="pOutput">Where to write the encoded data. This buffer should be
/// at least of the minimum size returned by beInitStream().</param> /// at least of the minimum size returned by beInitStream().</param>
/// <param name="pdwOutput">Returns number of bytes of encoded data written.</param> /// <param name="pdwOutput">Returns number of bytes of encoded data written.</param>
/// <returns>On success: BE_ERR_SUCCESSFUL</returns> /// <returns>On success: BE_ERR_SUCCESSFUL</returns>
[DllImport("Lame_enc.dll")] [DllImport("Lame_enc.dll")]
public static extern uint beDeinitStream(uint hbeStream, [In, Out] byte[] pOutput, ref uint pdwOutput); public static extern uint beDeinitStream(uint hbeStream, [In, Out] byte[] pOutput, ref uint pdwOutput);
/// <summary> /// <summary>
/// Last function to be called when finished encoding a stream. /// Last function to be called when finished encoding a stream.
/// Should unlike beDeinitStream() also be called if the encoding is canceled. /// Should unlike beDeinitStream() also be called if the encoding is canceled.
/// </summary> /// </summary>
/// <param name="hbeStream">Handle of the stream.</param> /// <param name="hbeStream">Handle of the stream.</param>
/// <returns>On success: BE_ERR_SUCCESSFUL</returns> /// <returns>On success: BE_ERR_SUCCESSFUL</returns>
[DllImport("Lame_enc.dll")] [DllImport("Lame_enc.dll")]
public static extern uint beCloseStream(uint hbeStream); public static extern uint beCloseStream(uint hbeStream);
/// <summary> /// <summary>
/// Returns information like version numbers (both of the DLL and encoding engine), /// Returns information like version numbers (both of the DLL and encoding engine),
/// release date and URL for lame_enc's homepage. /// release date and URL for lame_enc's homepage.
/// All this information should be made available to the user of your product /// All this information should be made available to the user of your product
/// through a dialog box or something similar. /// through a dialog box or something similar.
/// </summary> /// </summary>
/// <param name="pbeVersion"Where version number, release date and URL for homepage /// <param name="pbeVersion"Where version number, release date and URL for homepage
/// is returned.</param> /// is returned.</param>
[DllImport("Lame_enc.dll")] [DllImport("Lame_enc.dll")]
public static extern void beVersion([Out] BE_VERSION pbeVersion); public static extern void beVersion([Out] BE_VERSION pbeVersion);
[DllImport("Lame_enc.dll", CharSet = CharSet.Ansi)] [DllImport("Lame_enc.dll", CharSet = CharSet.Ansi)]
public static extern void beWriteVBRHeader(string pszMP3FileName); public static extern void beWriteVBRHeader(string pszMP3FileName);
[DllImport("Lame_enc.dll")] [DllImport("Lame_enc.dll")]
public static extern uint beEncodeChunkFloatS16NI(uint hbeStream, uint nSamples, [In]float[] buffer_l, [In]float[] buffer_r, [In, Out]byte[] pOutput, ref uint pdwOutput); public static extern uint beEncodeChunkFloatS16NI(uint hbeStream, uint nSamples, [In]float[] buffer_l, [In]float[] buffer_r, [In, Out]byte[] pOutput, ref uint pdwOutput);
[DllImport("Lame_enc.dll")] [DllImport("Lame_enc.dll")]
public static extern uint beFlushNoGap(uint hbeStream, [In, Out]byte[] pOutput, ref uint pdwOutput); public static extern uint beFlushNoGap(uint hbeStream, [In, Out]byte[] pOutput, ref uint pdwOutput);
[DllImport("Lame_enc.dll", CharSet = CharSet.Ansi)] [DllImport("Lame_enc.dll", CharSet = CharSet.Ansi)]
public static extern uint beWriteInfoTag(uint hbeStream, string lpszFileName); public static extern uint beWriteInfoTag(uint hbeStream, string lpszFileName);
} }
} }

View File

@@ -1,25 +1,25 @@
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
PURPOSE. IT CAN BE DISTRIBUTED FREE OF CHARGE AS LONG AS THIS HEADER PURPOSE. IT CAN BE DISTRIBUTED FREE OF CHARGE AS LONG AS THIS HEADER
REMAINS UNCHANGED. REMAINS UNCHANGED.
Email: yetiicb@hotmail.com Email: yetiicb@hotmail.com
Copyright (C) 2002-2003 Idael Cardoso. Copyright (C) 2002-2003 Idael Cardoso.
LAME ( LAME Ain't an Mp3 Encoder ) LAME ( LAME Ain't an Mp3 Encoder )
You must call the fucntion "beVersion" to obtain information like version You must call the fucntion "beVersion" to obtain information like version
numbers (both of the DLL and encoding engine), release date and URL for numbers (both of the DLL and encoding engine), release date and URL for
lame_enc's homepage. All this information should be made available to the lame_enc's homepage. All this information should be made available to the
user of your product through a dialog box or something similar. user of your product through a dialog box or something similar.
You must see all information about LAME project and legal license infos at You must see all information about LAME project and legal license infos at
http://www.mp3dev.org/ The official LAME site http://www.mp3dev.org/ The official LAME site
About Thomson and/or Fraunhofer patents: About Thomson and/or Fraunhofer patents:
Any use of this product does not convey a license under the relevant Any use of this product does not convey a license under the relevant
intellectual property of Thomson and/or Fraunhofer Gesellschaft nor imply intellectual property of Thomson and/or Fraunhofer Gesellschaft nor imply
any right to use this product in any finished end user or ready-to-use final any right to use this product in any finished end user or ready-to-use final
product. An independent license for such use is required. product. An independent license for such use is required.
For details, please visit http://www.mp3licensing.com. For details, please visit http://www.mp3licensing.com.

View File

@@ -1,17 +1,17 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CUETools.Codecs.LAME.Interop namespace CUETools.Codecs.LAME.Interop
{ {
[StructLayout(LayoutKind.Sequential), Serializable] [StructLayout(LayoutKind.Sequential), Serializable]
public struct MP3 //BE_CONFIG_MP3 public struct MP3 //BE_CONFIG_MP3
{ {
public uint dwSampleRate; // 48000, 44100 and 32000 allowed public uint dwSampleRate; // 48000, 44100 and 32000 allowed
public byte byMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO public byte byMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO
public ushort wBitrate; // 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320 allowed public ushort wBitrate; // 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320 allowed
public int bPrivate; public int bPrivate;
public int bCRC; public int bCRC;
public int bCopyright; public int bCopyright;
public int bOriginal; public int bOriginal;
} }
} }

View File

@@ -1,13 +1,13 @@
namespace CUETools.Codecs.LAME.Interop namespace CUETools.Codecs.LAME.Interop
{ {
/* MPEG modes */ /* MPEG modes */
public enum MpegMode : uint public enum MpegMode : uint
{ {
STEREO = 0, STEREO = 0,
JOINT_STEREO, JOINT_STEREO,
DUAL_CHANNEL, /* LAME doesn't supports this! */ DUAL_CHANNEL, /* LAME doesn't supports this! */
MONO, MONO,
NOT_SET, NOT_SET,
MAX_INDICATOR /* Don't use this! It's used for sanity checks. */ MAX_INDICATOR /* Don't use this! It's used for sanity checks. */
} }
} }

View File

@@ -1,12 +1,12 @@
namespace CUETools.Codecs.LAME.Interop namespace CUETools.Codecs.LAME.Interop
{ {
public enum VBRMETHOD : int public enum VBRMETHOD : int
{ {
VBR_METHOD_NONE = -1, VBR_METHOD_NONE = -1,
VBR_METHOD_DEFAULT = 0, VBR_METHOD_DEFAULT = 0,
VBR_METHOD_OLD = 1, VBR_METHOD_OLD = 1,
VBR_METHOD_NEW = 2, VBR_METHOD_NEW = 2,
VBR_METHOD_MTRH = 3, VBR_METHOD_MTRH = 3,
VBR_METHOD_ABR = 4 VBR_METHOD_ABR = 4
} }
} }

View File

@@ -1,247 +1,247 @@
using System; using System;
using System.IO; using System.IO;
using System.Text; using System.Text;
using CUETools.Codecs.LAME.Interop; using CUETools.Codecs.LAME.Interop;
namespace CUETools.Codecs.LAME namespace CUETools.Codecs.LAME
{ {
public class LAMEEncoder : IAudioDest public class LAMEEncoder : IAudioDest
{ {
private bool closed = false; private bool closed = false;
private BE_CONFIG m_Mp3Config = null; private BE_CONFIG m_Mp3Config = null;
private uint m_hLameStream = 0; private uint m_hLameStream = 0;
private uint m_InputSamples = 0; private uint m_InputSamples = 0;
private uint m_OutBufferSize = 0; private uint m_OutBufferSize = 0;
private byte[] m_InBuffer = null; private byte[] m_InBuffer = null;
private int m_InBufferPos = 0; private int m_InBufferPos = 0;
private byte[] m_OutBuffer = null; private byte[] m_OutBuffer = null;
private AudioEncoderSettings m_settings; private AudioEncoderSettings m_settings;
private string _path; private string _path;
private Stream _IO; private Stream _IO;
private long position = 0, sample_count = -1; private long position = 0, sample_count = -1;
private long bytesWritten = 0; private long bytesWritten = 0;
private bool inited = false; private bool inited = false;
public virtual AudioEncoderSettings Settings public virtual AudioEncoderSettings Settings
{ {
get get
{ {
return m_settings; return m_settings;
} }
} }
public long Position public long Position
{ {
get { return position; } get { return position; }
} }
public long FinalSampleCount public long FinalSampleCount
{ {
set { sample_count = (int)value; } set { sample_count = (int)value; }
} }
public string Path { get { return _path; } } public string Path { get { return _path; } }
public long BytesWritten public long BytesWritten
{ {
get { return bytesWritten; } get { return bytesWritten; }
} }
public LAMEEncoder(string path, Stream IO, AudioEncoderSettings settings) public LAMEEncoder(string path, Stream IO, AudioEncoderSettings settings)
{ {
if (settings.PCM.BitsPerSample != 16)// && pcm.BitsPerSample != 32) if (settings.PCM.BitsPerSample != 16)// && pcm.BitsPerSample != 32)
throw new ArgumentOutOfRangeException("format", "Only 16 & 32 bits samples supported"); throw new ArgumentOutOfRangeException("format", "Only 16 & 32 bits samples supported");
m_settings = settings; m_settings = settings;
_path = path; _path = path;
_IO = IO; _IO = IO;
} }
public LAMEEncoder(string path, AudioEncoderSettings settings) public LAMEEncoder(string path, AudioEncoderSettings settings)
: this(path, null, settings) : this(path, null, settings)
{ {
} }
public void DeInit(bool flush) public void DeInit(bool flush)
{ {
if (!inited || closed) if (!inited || closed)
return; return;
try try
{ {
if (flush) if (flush)
{ {
uint EncodedSize = 0; uint EncodedSize = 0;
if (m_InBufferPos > 0) if (m_InBufferPos > 0)
{ {
if (Lame_encDll.EncodeChunk(m_hLameStream, m_InBuffer, 0, (uint)m_InBufferPos, m_OutBuffer, ref EncodedSize) == Lame_encDll.BE_ERR_SUCCESSFUL) if (Lame_encDll.EncodeChunk(m_hLameStream, m_InBuffer, 0, (uint)m_InBufferPos, m_OutBuffer, ref EncodedSize) == Lame_encDll.BE_ERR_SUCCESSFUL)
{ {
if (EncodedSize > 0) if (EncodedSize > 0)
{ {
_IO.Write(m_OutBuffer, 0, (int)EncodedSize); _IO.Write(m_OutBuffer, 0, (int)EncodedSize);
bytesWritten += EncodedSize; bytesWritten += EncodedSize;
} }
} }
} }
EncodedSize = 0; EncodedSize = 0;
if (Lame_encDll.beDeinitStream(m_hLameStream, m_OutBuffer, ref EncodedSize) == Lame_encDll.BE_ERR_SUCCESSFUL) if (Lame_encDll.beDeinitStream(m_hLameStream, m_OutBuffer, ref EncodedSize) == Lame_encDll.BE_ERR_SUCCESSFUL)
{ {
if (EncodedSize > 0) if (EncodedSize > 0)
{ {
_IO.Write(m_OutBuffer, 0, (int)EncodedSize); _IO.Write(m_OutBuffer, 0, (int)EncodedSize);
bytesWritten += EncodedSize; bytesWritten += EncodedSize;
} }
} }
} }
} }
finally finally
{ {
Lame_encDll.beCloseStream(m_hLameStream); Lame_encDll.beCloseStream(m_hLameStream);
_IO.Close(); _IO.Close();
closed = true; closed = true;
} }
} }
public void Close() public void Close()
{ {
bool needTag = !closed && _path != null && _path != ""; bool needTag = !closed && _path != null && _path != "";
DeInit(true); DeInit(true);
if (needTag) if (needTag)
{ {
bool utf8Required = Encoding.Default.GetString(Encoding.Default.GetBytes(_path)) != _path; bool utf8Required = Encoding.Default.GetString(Encoding.Default.GetBytes(_path)) != _path;
var tempDir = System.IO.Path.Combine(System.IO.Path.GetPathRoot(_path), "Temp"); var tempDir = System.IO.Path.Combine(System.IO.Path.GetPathRoot(_path), "Temp");
var tempName = utf8Required ? System.IO.Path.Combine(tempDir, Guid.NewGuid().ToString()) : _path; var tempName = utf8Required ? System.IO.Path.Combine(tempDir, Guid.NewGuid().ToString()) : _path;
try try
{ {
if (utf8Required && !Directory.Exists(tempDir)) Directory.CreateDirectory(tempDir); if (utf8Required && !Directory.Exists(tempDir)) Directory.CreateDirectory(tempDir);
if (utf8Required) File.Move(_path, tempName); if (utf8Required) File.Move(_path, tempName);
Lame_encDll.beWriteInfoTag(m_hLameStream, tempName); Lame_encDll.beWriteInfoTag(m_hLameStream, tempName);
if (utf8Required) File.Move(tempName, _path); if (utf8Required) File.Move(tempName, _path);
} }
catch catch
{ {
if (utf8Required) File.Move(tempName, _path); if (utf8Required) File.Move(tempName, _path);
} }
} }
} }
public void Delete() public void Delete()
{ {
if (!closed) if (!closed)
{ {
DeInit(false); DeInit(false);
if (_path != "") if (_path != "")
File.Delete(_path); File.Delete(_path);
} }
} }
protected virtual BE_CONFIG MakeConfig() protected virtual BE_CONFIG MakeConfig()
{ {
return new BE_CONFIG(Settings.PCM); return new BE_CONFIG(Settings.PCM);
} }
private void Init() private void Init()
{ {
if (inited) if (inited)
return; return;
m_Mp3Config = MakeConfig(); m_Mp3Config = MakeConfig();
uint LameResult = Lame_encDll.beInitStream(m_Mp3Config, ref m_InputSamples, ref m_OutBufferSize, ref m_hLameStream); uint LameResult = Lame_encDll.beInitStream(m_Mp3Config, ref m_InputSamples, ref m_OutBufferSize, ref m_hLameStream);
if (LameResult != Lame_encDll.BE_ERR_SUCCESSFUL) if (LameResult != Lame_encDll.BE_ERR_SUCCESSFUL)
throw new ApplicationException(string.Format("Lame_encDll.beInitStream failed with the error code {0}", LameResult)); throw new ApplicationException(string.Format("Lame_encDll.beInitStream failed with the error code {0}", LameResult));
m_InBuffer = new byte[m_InputSamples * 2]; //Input buffer is expected as short[] m_InBuffer = new byte[m_InputSamples * 2]; //Input buffer is expected as short[]
m_OutBuffer = new byte[Math.Max(65536, m_OutBufferSize)]; m_OutBuffer = new byte[Math.Max(65536, m_OutBufferSize)];
if (_IO == null) if (_IO == null)
_IO = new FileStream(_path, FileMode.Create, FileAccess.Write, FileShare.Read); _IO = new FileStream(_path, FileMode.Create, FileAccess.Write, FileShare.Read);
inited = true; inited = true;
} }
public unsafe void Write(AudioBuffer buff) public unsafe void Write(AudioBuffer buff)
{ {
buff.Prepare(this); buff.Prepare(this);
Init(); Init();
byte[] buffer = buff.Bytes; byte[] buffer = buff.Bytes;
int index = 0; int index = 0;
int count = buff.ByteLength; int count = buff.ByteLength;
int ToCopy = 0; int ToCopy = 0;
uint EncodedSize = 0; uint EncodedSize = 0;
uint LameResult; uint LameResult;
uint outBufferIndex = 0; uint outBufferIndex = 0;
fixed (byte* pBuffer = buffer, pOutBuffer = m_OutBuffer) fixed (byte* pBuffer = buffer, pOutBuffer = m_OutBuffer)
{ {
while (count > 0) while (count > 0)
{ {
if (m_InBufferPos > 0) if (m_InBufferPos > 0)
{ {
ToCopy = Math.Min(count, m_InBuffer.Length - m_InBufferPos); ToCopy = Math.Min(count, m_InBuffer.Length - m_InBufferPos);
Buffer.BlockCopy(buffer, index, m_InBuffer, m_InBufferPos, ToCopy); Buffer.BlockCopy(buffer, index, m_InBuffer, m_InBufferPos, ToCopy);
m_InBufferPos += ToCopy; m_InBufferPos += ToCopy;
index += ToCopy; index += ToCopy;
count -= ToCopy; count -= ToCopy;
if (m_InBufferPos >= m_InBuffer.Length) if (m_InBufferPos >= m_InBuffer.Length)
{ {
m_InBufferPos = 0; m_InBufferPos = 0;
if (outBufferIndex > 0) if (outBufferIndex > 0)
{ {
_IO.Write(m_OutBuffer, 0, (int)outBufferIndex); _IO.Write(m_OutBuffer, 0, (int)outBufferIndex);
bytesWritten += outBufferIndex; bytesWritten += outBufferIndex;
outBufferIndex = 0; outBufferIndex = 0;
} }
if ((LameResult = Lame_encDll.EncodeChunk(m_hLameStream, m_InBuffer, m_OutBuffer, ref EncodedSize)) == Lame_encDll.BE_ERR_SUCCESSFUL) if ((LameResult = Lame_encDll.EncodeChunk(m_hLameStream, m_InBuffer, m_OutBuffer, ref EncodedSize)) == Lame_encDll.BE_ERR_SUCCESSFUL)
{ {
outBufferIndex += EncodedSize; outBufferIndex += EncodedSize;
} }
else else
{ {
throw new ApplicationException(string.Format("Lame_encDll.EncodeChunk failed with the error code {0}", LameResult)); throw new ApplicationException(string.Format("Lame_encDll.EncodeChunk failed with the error code {0}", LameResult));
} }
} }
} }
else else
{ {
if (count >= m_InBuffer.Length) if (count >= m_InBuffer.Length)
{ {
if (outBufferIndex + m_OutBufferSize > m_OutBuffer.Length) if (outBufferIndex + m_OutBufferSize > m_OutBuffer.Length)
{ {
_IO.Write(m_OutBuffer, 0, (int)outBufferIndex); _IO.Write(m_OutBuffer, 0, (int)outBufferIndex);
bytesWritten += outBufferIndex; bytesWritten += outBufferIndex;
outBufferIndex = 0; outBufferIndex = 0;
} }
if ((LameResult = Lame_encDll.EncodeChunk(m_hLameStream, pBuffer + index, (uint)m_InBuffer.Length, pOutBuffer + outBufferIndex, ref EncodedSize)) == Lame_encDll.BE_ERR_SUCCESSFUL) if ((LameResult = Lame_encDll.EncodeChunk(m_hLameStream, pBuffer + index, (uint)m_InBuffer.Length, pOutBuffer + outBufferIndex, ref EncodedSize)) == Lame_encDll.BE_ERR_SUCCESSFUL)
{ {
outBufferIndex += EncodedSize; outBufferIndex += EncodedSize;
} }
else else
{ {
throw new ApplicationException(string.Format("Lame_encDll.EncodeChunk failed with the error code {0}", LameResult)); throw new ApplicationException(string.Format("Lame_encDll.EncodeChunk failed with the error code {0}", LameResult));
} }
count -= m_InBuffer.Length; count -= m_InBuffer.Length;
index += m_InBuffer.Length; index += m_InBuffer.Length;
} }
else else
{ {
Buffer.BlockCopy(buffer, index, m_InBuffer, 0, count); Buffer.BlockCopy(buffer, index, m_InBuffer, 0, count);
m_InBufferPos = count; m_InBufferPos = count;
index += count; index += count;
count = 0; count = 0;
} }
} }
} }
} }
if (outBufferIndex > 0) if (outBufferIndex > 0)
{ {
_IO.Write(m_OutBuffer, 0, (int)outBufferIndex); _IO.Write(m_OutBuffer, 0, (int)outBufferIndex);
bytesWritten += outBufferIndex; bytesWritten += outBufferIndex;
} }
} }
} }
} }

View File

@@ -1,40 +1,40 @@
using System; using System;
using System.IO; using System.IO;
using CUETools.Codecs.LAME.Interop; using CUETools.Codecs.LAME.Interop;
namespace CUETools.Codecs.LAME namespace CUETools.Codecs.LAME
{ {
//[AudioEncoderClass("lame CBR", "mp3", false, 2, typeof(LAMEEncoderCBRSettings))] //[AudioEncoderClass("lame CBR", "mp3", false, 2, typeof(LAMEEncoderCBRSettings))]
public class LAMEEncoderCBR : LAMEEncoder public class LAMEEncoderCBR : LAMEEncoder
{ {
private LAMEEncoderCBRSettings m_settings; private LAMEEncoderCBRSettings m_settings;
public override AudioEncoderSettings Settings public override AudioEncoderSettings Settings
{ {
get get
{ {
return m_settings; return m_settings;
} }
} }
public LAMEEncoderCBR(string path, Stream IO, AudioEncoderSettings settings) public LAMEEncoderCBR(string path, Stream IO, AudioEncoderSettings settings)
: base(path, IO, settings) : base(path, IO, settings)
{ {
} }
public LAMEEncoderCBR(string path, AudioEncoderSettings settings) public LAMEEncoderCBR(string path, AudioEncoderSettings settings)
: base(path, null, settings) : base(path, null, settings)
{ {
} }
protected override BE_CONFIG MakeConfig() protected override BE_CONFIG MakeConfig()
{ {
BE_CONFIG Mp3Config = new BE_CONFIG(Settings.PCM, m_settings.CustomBitrate > 0 ? (uint)m_settings.CustomBitrate : LAMEEncoderCBRSettings.bps_table[m_settings.EncoderModeIndex], 5); BE_CONFIG Mp3Config = new BE_CONFIG(Settings.PCM, m_settings.CustomBitrate > 0 ? (uint)m_settings.CustomBitrate : LAMEEncoderCBRSettings.bps_table[m_settings.EncoderModeIndex], 5);
Mp3Config.format.lhv1.bWriteVBRHeader = 1; Mp3Config.format.lhv1.bWriteVBRHeader = 1;
Mp3Config.format.lhv1.nMode = m_settings.StereoMode; Mp3Config.format.lhv1.nMode = m_settings.StereoMode;
//Mp3Config.format.lhv1.nVbrMethod = VBRMETHOD.VBR_METHOD_NONE; // --cbr //Mp3Config.format.lhv1.nVbrMethod = VBRMETHOD.VBR_METHOD_NONE; // --cbr
//Mp3Config.format.lhv1.nPreset = LAME_QUALITY_PRESET.LQP_NORMAL_QUALITY; //Mp3Config.format.lhv1.nPreset = LAME_QUALITY_PRESET.LQP_NORMAL_QUALITY;
return Mp3Config; return Mp3Config;
} }
} }
} }

View File

@@ -1,24 +1,24 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using CUETools.Codecs.LAME.Interop; using CUETools.Codecs.LAME.Interop;
namespace CUETools.Codecs.LAME namespace CUETools.Codecs.LAME
{ {
public class LAMEEncoderCBRSettings : AudioEncoderSettings public class LAMEEncoderCBRSettings : AudioEncoderSettings
{ {
public override Type EncoderType => typeof(LAMEEncoderCBR); public override Type EncoderType => typeof(LAMEEncoderCBR);
public static readonly uint[] bps_table = new uint[] { 96, 128, 192, 256, 320 }; public static readonly uint[] bps_table = new uint[] { 96, 128, 192, 256, 320 };
[DefaultValue(0)] [DefaultValue(0)]
public int CustomBitrate { get; set; } public int CustomBitrate { get; set; }
[DefaultValue(MpegMode.STEREO)] [DefaultValue(MpegMode.STEREO)]
public MpegMode StereoMode { get; set; } public MpegMode StereoMode { get; set; }
public LAMEEncoderCBRSettings() public LAMEEncoderCBRSettings()
: base("96 128 192 256 320", "256") : base("96 128 192 256 320", "256")
{ {
} }
} }
} }

View File

@@ -1,41 +1,41 @@
using System; using System;
using System.IO; using System.IO;
using CUETools.Codecs.LAME.Interop; using CUETools.Codecs.LAME.Interop;
namespace CUETools.Codecs.LAME namespace CUETools.Codecs.LAME
{ {
//[AudioEncoderClass("lame VBR", "mp3", false, 2, typeof(LAMEEncoderVBRSettings))] //[AudioEncoderClass("lame VBR", "mp3", false, 2, typeof(LAMEEncoderVBRSettings))]
public class LAMEEncoderVBR : LAMEEncoder public class LAMEEncoderVBR : LAMEEncoder
{ {
private LAMEEncoderVBRSettings m_settings; private LAMEEncoderVBRSettings m_settings;
public override AudioEncoderSettings Settings public override AudioEncoderSettings Settings
{ {
get get
{ {
return m_settings; return m_settings;
} }
} }
public LAMEEncoderVBR(string path, Stream IO, AudioEncoderSettings settings) public LAMEEncoderVBR(string path, Stream IO, AudioEncoderSettings settings)
: base(path, IO, settings) : base(path, IO, settings)
{ {
} }
public LAMEEncoderVBR(string path, AudioEncoderSettings settings) public LAMEEncoderVBR(string path, AudioEncoderSettings settings)
: base(path, null, settings) : base(path, null, settings)
{ {
} }
protected override BE_CONFIG MakeConfig() protected override BE_CONFIG MakeConfig()
{ {
BE_CONFIG Mp3Config = new BE_CONFIG(Settings.PCM, 0, (uint)m_settings.Quality); BE_CONFIG Mp3Config = new BE_CONFIG(Settings.PCM, 0, (uint)m_settings.Quality);
Mp3Config.format.lhv1.bWriteVBRHeader = 1; Mp3Config.format.lhv1.bWriteVBRHeader = 1;
Mp3Config.format.lhv1.nMode = MpegMode.JOINT_STEREO; Mp3Config.format.lhv1.nMode = MpegMode.JOINT_STEREO;
Mp3Config.format.lhv1.bEnableVBR = 1; Mp3Config.format.lhv1.bEnableVBR = 1;
Mp3Config.format.lhv1.nVBRQuality = 9 - m_settings.EncoderModeIndex; Mp3Config.format.lhv1.nVBRQuality = 9 - m_settings.EncoderModeIndex;
Mp3Config.format.lhv1.nVbrMethod = VBRMETHOD.VBR_METHOD_NEW; // --vbr-new Mp3Config.format.lhv1.nVbrMethod = VBRMETHOD.VBR_METHOD_NEW; // --vbr-new
return Mp3Config; return Mp3Config;
} }
} }
} }

View File

@@ -1,8 +1,8 @@
namespace CUETools.Codecs.LAME namespace CUETools.Codecs.LAME
{ {
public enum LAMEEncoderVBRProcessingQuality : uint public enum LAMEEncoderVBRProcessingQuality : uint
{ {
Best = 0, Best = 0,
Normal = 5, Normal = 5,
} }
} }

View File

@@ -1,18 +1,18 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
namespace CUETools.Codecs.LAME namespace CUETools.Codecs.LAME
{ {
public class LAMEEncoderVBRSettings : AudioEncoderSettings public class LAMEEncoderVBRSettings : AudioEncoderSettings
{ {
public override Type EncoderType => typeof(LAMEEncoderVBR); public override Type EncoderType => typeof(LAMEEncoderVBR);
[DefaultValue(LAMEEncoderVBRProcessingQuality.Normal)] [DefaultValue(LAMEEncoderVBRProcessingQuality.Normal)]
public LAMEEncoderVBRProcessingQuality Quality { get; set; } public LAMEEncoderVBRProcessingQuality Quality { get; set; }
public LAMEEncoderVBRSettings() public LAMEEncoderVBRSettings()
: base("V9 V8 V7 V6 V5 V4 V3 V2 V1 V0", "V2") : base("V9 V8 V7 V6 V5 V4 V3 V2 V1 V0", "V2")
{ {
} }
} }
} }

View File

@@ -21,7 +21,6 @@ namespace CUETools.Codecs.libFLAC
public Settings() : base() { } public Settings() : base() { }
} }
[AudioDecoderClass(typeof(Settings))]
public unsafe class Reader : IAudioSource public unsafe class Reader : IAudioSource
{ {
public Reader(string path, Stream IO) public Reader(string path, Stream IO)

View File

@@ -44,7 +44,6 @@ namespace CUETools.Codecs.libFLAC
public string Version => FLACDLL.GetVersion; public string Version => FLACDLL.GetVersion;
}; };
[AudioEncoderClass(typeof(EncoderSettings))]
public unsafe class Encoder : IAudioDest public unsafe class Encoder : IAudioDest
{ {
public Encoder(string path, Stream output, EncoderSettings settings) public Encoder(string path, Stream output, EncoderSettings settings)

View File

@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net40;net20;netstandard2.0</TargetFrameworks>
<Version>2.1.7.0</Version>
<AssemblyName>CUETools.Codecs.libmp3lame</AssemblyName>
<RootNamespace>CUETools.Codecs.libmp3lame</RootNamespace>
<Product>CUETools</Product>
<Description>A library for encoding mp3 using LAME encoder.</Description>
<Copyright>Copyright (c) 2008-2018 Grigory Chudov</Copyright>
<Authors>Grigory Chudov</Authors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<OutputPath>..\bin\$(Configuration)\plugins</OutputPath>
<RepositoryUrl>https://github.com/gchudov/cuetools.net</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Company />
</PropertyGroup>
<ItemDefinitionGroup>
<ProjectReference>
<Private>False</Private>
</ProjectReference>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\CUETools.Codecs\CUETools.Codecs.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,14 +1,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace CUETools.Codecs.LAME namespace CUETools.Codecs.libmp3lame
{ {
public class LameException : Exception public class LameException : Exception
{ {
public LameException(string message) public LameException(string message)
: base(message) : base(message)
{ {
} }
} }
} }

View File

@@ -1,300 +1,259 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using CUETools.Codecs; using CUETools.Codecs;
using System.IO; using System.IO;
namespace CUETools.Codecs.LAME namespace CUETools.Codecs.libmp3lame
{ {
[AudioEncoderClass(typeof(CBREncoderSettings))] public class AudioEncoder : IAudioDest
[AudioEncoderClass(typeof(VBREncoderSettings))] {
public class AudioEncoder : IAudioDest private string m_outputPath;
{ private Stream m_outputStream;
#region Unmanaged Functions
private bool m_closed = false, m_initialized = false;
private const string LameDll = "libmp3lame"; private IntPtr m_handle;
private const CallingConvention LameCallingConvention = CallingConvention.Cdecl; private uint m_finalSampleCount;
private byte[] m_outputBuffer;
[DllImport(LameDll, CallingConvention = LameCallingConvention)] private long m_bytesWritten;
internal static extern IntPtr lame_init();
[DllImport(LameDll, CallingConvention = LameCallingConvention)] public long FinalSampleCount
internal static extern int lame_close(IntPtr handle); {
[DllImport(LameDll, CallingConvention = LameCallingConvention)] set
internal static extern int lame_set_num_channels(IntPtr handle, int channels); {
[DllImport(LameDll, CallingConvention = LameCallingConvention)] if (value > uint.MaxValue)
internal static extern int lame_set_in_samplerate(IntPtr handle, int sampleRate); {
[DllImport(LameDll, CallingConvention = LameCallingConvention)] throw new ArgumentException("Input file too big.");
internal static extern int lame_set_quality(IntPtr handle, int quality); }
[DllImport(LameDll, CallingConvention = LameCallingConvention)] this.m_finalSampleCount = (uint)value;
internal static extern int lame_set_VBR(IntPtr handle, int vbrMode); }
[DllImport(LameDll, CallingConvention = LameCallingConvention)] }
internal static extern int lame_set_VBR_mean_bitrate_kbps(IntPtr handle, int meanBitrate);
[DllImport(LameDll, CallingConvention = LameCallingConvention)] public string Path
internal static extern int lame_init_params(IntPtr handle); {
[DllImport(LameDll, CallingConvention = LameCallingConvention)] get { return this.m_outputPath; }
internal static extern int lame_set_num_samples(IntPtr handle, uint numSamples); }
[DllImport(LameDll, CallingConvention = LameCallingConvention)]
internal static extern int lame_encode_buffer_interleaved(IntPtr handle, IntPtr pcm, int num_samples, IntPtr mp3buf, int mp3buf_size); private LameEncoderSettings m_settings;
[DllImport(LameDll, CallingConvention = LameCallingConvention)]
internal static extern int lame_encode_flush(IntPtr handle, IntPtr mp3buf, int size); public virtual AudioEncoderSettings Settings
[DllImport(LameDll, CallingConvention = LameCallingConvention)] {
internal static extern uint lame_get_lametag_frame(IntPtr handle, IntPtr buffer, uint size); get
[DllImport(LameDll, CallingConvention = LameCallingConvention)] {
internal static extern int lame_set_VBR_quality(IntPtr handle, float vbrQuality); return m_settings;
[DllImport(LameDll, CallingConvention = LameCallingConvention)] }
internal static extern int lame_set_brate(IntPtr handle, int bitrate); }
[DllImport(LameDll, CallingConvention = LameCallingConvention)]
internal static extern int lame_set_bWriteVbrTag(IntPtr handle, int writeVbrTag); public long BytesWritten => m_bytesWritten;
[DllImport(LameDll, CallingConvention = LameCallingConvention)]
internal static extern int lame_set_write_id3tag_automatic(IntPtr handle, int automaticWriteId3Tag); public AudioEncoder(LameEncoderSettings settings, string path, Stream output = null)
{
#endregion this.CheckPCMConfig(settings.PCM);
this.m_settings = settings;
private string m_outputPath; this.m_outputPath = path;
private Stream m_outputStream; this.m_outputStream = output != null ? output : File.Create(path);
this.m_bytesWritten = 0;
private bool m_closed = false, m_initialized = false; }
private IntPtr m_handle;
private uint m_finalSampleCount; private void CheckPCMConfig(AudioPCMConfig pcm)
private byte[] m_outputBuffer; {
if (pcm.BitsPerSample != 16)
public long FinalSampleCount {
{ throw new ArgumentException("LAME only supports 16 bits/sample.");
set }
{ }
if (value > uint.MaxValue)
{ private void FinalizeEncoding()
throw new ArgumentException("Input file too big."); {
} this.EnsureOutputBufferSize(7200);
this.m_finalSampleCount = (uint)value;
} int flushResult;
} unsafe
{
public string Path fixed (byte* outputBufferPtr = m_outputBuffer)
{ {
get { return this.m_outputPath; } flushResult = libmp3lamedll.lame_encode_flush(m_handle, (IntPtr)outputBufferPtr, m_outputBuffer.Length);
} }
}
private LameEncoderSettings m_settings; if (flushResult < 0)
{
public virtual AudioEncoderSettings Settings throw new LameException("Unknown flush error");
{ }
get if (flushResult > 0)
{ {
return m_settings; this.m_outputStream.Write(this.m_outputBuffer, 0, flushResult);
} m_bytesWritten += flushResult;
} }
public AudioEncoder(string path, Stream output, LameEncoderSettings settings) int lametagFrameSize = this.GetLametagFrame();
{ this.m_outputStream.Seek(0, SeekOrigin.Begin);
this.CheckPCMConfig(settings.PCM); this.m_outputStream.Write(this.m_outputBuffer, 0, lametagFrameSize);
this.m_settings = settings; }
this.m_outputPath = path;
this.m_outputStream = output != null ? output : File.Create(path); public void Close()
} {
if (!this.m_closed)
public AudioEncoder(string path, LameEncoderSettings settings) {
: this(path, null, settings) if (this.m_initialized)
{ {
} try
{
private void CheckPCMConfig(AudioPCMConfig pcm) try
{ {
if (pcm.BitsPerSample != 16) this.FinalizeEncoding();
{ }
throw new ArgumentException("LAME only supports 16 bits/sample."); finally
} {
} libmp3lamedll.lame_close(m_handle);
}
private void FinalizeEncoding() }
{ finally
this.EnsureOutputBufferSize(7200); {
m_handle = IntPtr.Zero;
int flushResult; if (this.m_outputPath != null)
unsafe {
{ this.m_outputStream.Close();
fixed (byte* outputBufferPtr = m_outputBuffer) }
{ }
flushResult = lame_encode_flush(m_handle, (IntPtr)outputBufferPtr, m_outputBuffer.Length); }
}
} this.m_closed = true;
if (flushResult < 0) }
{ }
throw new LameException("Unknown flush error");
} private int GetLametagFrame()
if (flushResult > 0) {
{ while (true)
this.m_outputStream.Write(this.m_outputBuffer, 0, flushResult); {
} uint lametagFrameResult;
unsafe
int lametagFrameSize = this.GetLametagFrame(); {
this.m_outputStream.Seek(0, SeekOrigin.Begin); fixed (byte* outputBufferPtr = m_outputBuffer)
this.m_outputStream.Write(this.m_outputBuffer, 0, lametagFrameSize); {
} lametagFrameResult = libmp3lamedll.lame_get_lametag_frame(this.m_handle, (IntPtr)outputBufferPtr, (uint)m_outputBuffer.Length);
}
public void Close() }
{ if (lametagFrameResult < 0)
if (!this.m_closed) {
{ throw new LameException("Error getting lametag frame.");
if (this.m_initialized) }
{ if (lametagFrameResult <= m_outputBuffer.Length)
try {
{ return (int)lametagFrameResult;
try }
{ this.EnsureOutputBufferSize((int)lametagFrameResult);
this.FinalizeEncoding(); }
} }
finally
{ public uint GetLametagFrame(byte[] outputBuffer)
lame_close(m_handle); {
} unsafe
} {
finally fixed (byte* outputBufferPtr = outputBuffer)
{ {
m_handle = IntPtr.Zero; return libmp3lamedll.lame_get_lametag_frame(m_handle, (IntPtr)outputBufferPtr, (uint)outputBuffer.Length);
if (this.m_outputPath != null) }
{ }
this.m_outputStream.Close(); }
}
} private void EnsureInitialized()
} {
if (!this.m_initialized)
this.m_closed = true; {
} m_handle = libmp3lamedll.lame_init();
}
libmp3lamedll.lame_set_bWriteVbrTag(m_handle, 1);
private int GetLametagFrame() libmp3lamedll.lame_set_write_id3tag_automatic(m_handle, 0);
{
while (true) libmp3lamedll.lame_set_num_channels(m_handle, this.Settings.PCM.ChannelCount);
{ libmp3lamedll.lame_set_in_samplerate(m_handle, this.Settings.PCM.SampleRate);
uint lametagFrameResult;
unsafe if (this.m_finalSampleCount != 0)
{ {
fixed (byte* outputBufferPtr = m_outputBuffer) libmp3lamedll.lame_set_num_samples(m_handle, this.m_finalSampleCount);
{ }
lametagFrameResult = lame_get_lametag_frame(this.m_handle, (IntPtr)outputBufferPtr, (uint)m_outputBuffer.Length);
} m_settings.Apply(m_handle);
}
if (lametagFrameResult < 0) if (libmp3lamedll.lame_init_params(m_handle) != 0)
{ {
throw new LameException("Error getting lametag frame."); throw new LameException("lame_init_params failed");
} }
if (lametagFrameResult <= m_outputBuffer.Length)
{ this.m_initialized = true;
return (int)lametagFrameResult; }
} }
this.EnsureOutputBufferSize((int)lametagFrameResult);
} public void Delete()
} {
if (this.m_outputPath == null)
public uint GetLametagFrame(byte[] outputBuffer) {
{ throw new InvalidOperationException("This writer was not created from file.");
unsafe }
{
fixed (byte* outputBufferPtr = outputBuffer) if (!m_closed)
{ {
return lame_get_lametag_frame(m_handle, (IntPtr)outputBufferPtr, (uint)outputBuffer.Length); this.Close();
} File.Delete(this.m_outputPath);
} }
} }
private void EnsureInitialized() private void EnsureOutputBufferSize(int requiredSize)
{ {
if (!this.m_initialized) if (this.m_outputBuffer == null || this.m_outputBuffer.Length < requiredSize)
{ {
m_handle = lame_init(); this.m_outputBuffer = new byte[requiredSize];
}
lame_set_bWriteVbrTag(m_handle, 1); }
lame_set_write_id3tag_automatic(m_handle, 0);
public void Write(AudioBuffer buffer)
lame_set_num_channels(m_handle, this.Settings.PCM.ChannelCount); {
lame_set_in_samplerate(m_handle, this.Settings.PCM.SampleRate); if (this.m_closed)
{
if (this.m_finalSampleCount != 0) throw new InvalidOperationException("Writer already closed.");
{ }
lame_set_num_samples(m_handle, this.m_finalSampleCount);
} buffer.Prepare(this);
m_settings.Apply(m_handle); this.EnsureInitialized();
if (lame_init_params(m_handle) != 0) this.EnsureOutputBufferSize(buffer.Length * 5 / 4 + 7200);
{
throw new LameException("lame_init_params failed"); byte[] bytes = buffer.Bytes;
}
int result;
this.m_initialized = true; unsafe
} {
} fixed (byte* bytesPtr = bytes)
{
public void Delete() fixed (byte* outputBufferPtr = this.m_outputBuffer)
{ {
if (this.m_outputPath == null) result = libmp3lamedll.lame_encode_buffer_interleaved(m_handle, (IntPtr)bytesPtr, buffer.Length, (IntPtr)outputBufferPtr, m_outputBuffer.Length);
{ }
throw new InvalidOperationException("This writer was not created from file."); }
} }
if (!m_closed) if (result < 0)
{ {
this.Close(); switch (result)
File.Delete(this.m_outputPath); {
} case -1:
} throw new LameException("Output buffer is too small");
case -2:
private void EnsureOutputBufferSize(int requiredSize) throw new LameException("malloc problem");
{ case -3:
if (this.m_outputBuffer == null || this.m_outputBuffer.Length < requiredSize) throw new LameException("lame_init_params was not called");
{ case -4:
this.m_outputBuffer = new byte[requiredSize]; throw new LameException("Psycho acoustic problems");
} default:
} throw new LameException("Unknown error");
}
public void Write(AudioBuffer buffer) }
{
if (this.m_closed) if (result > 0)
{ {
throw new InvalidOperationException("Writer already closed."); this.m_outputStream.Write(this.m_outputBuffer, 0, result);
} m_bytesWritten += result;
}
buffer.Prepare(this); }
}
this.EnsureInitialized(); }
this.EnsureOutputBufferSize(buffer.Length * 5 / 4 + 7200);
byte[] bytes = buffer.Bytes;
int result;
unsafe
{
fixed (byte* bytesPtr = bytes)
{
fixed (byte* outputBufferPtr = this.m_outputBuffer)
{
result = lame_encode_buffer_interleaved(m_handle, (IntPtr)bytesPtr, buffer.Length, (IntPtr)outputBufferPtr, m_outputBuffer.Length);
}
}
}
if (result < 0)
{
switch (result)
{
case -1:
throw new LameException("Output buffer is too small");
case -2:
throw new LameException("malloc problem");
case -3:
throw new LameException("lame_init_params was not called");
case -4:
throw new LameException("Psycho acoustic problems");
default:
throw new LameException("Unknown error");
}
}
if (result > 0)
{
this.m_outputStream.Write(this.m_outputBuffer, 0, result);
}
}
}
}

View File

@@ -1,36 +1,36 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Text; using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace CUETools.Codecs.LAME namespace CUETools.Codecs.libmp3lame
{ {
[JsonObject(MemberSerialization.OptIn)] [JsonObject(MemberSerialization.OptIn)]
public class CBREncoderSettings : LameEncoderSettings public class CBREncoderSettings : LameEncoderSettings
{ {
public override string Extension => "mp3"; public override string Extension => "mp3";
public override string Name => "libmp3lame-CBR"; public override string Name => "libmp3lame-CBR";
public override int Priority => 1; public override int Priority => 1;
public static readonly int[] bps_table = new int[] { 96, 128, 192, 256, 320 }; public static readonly int[] bps_table = new int[] { 96, 128, 192, 256, 320 };
[JsonProperty] [JsonProperty]
[DefaultValue(LameQuality.High)] [DefaultValue(LameQuality.High)]
public LameQuality Quality { get; set; } public LameQuality Quality { get; set; }
public CBREncoderSettings() public CBREncoderSettings()
: base("96 128 192 256 320", "256") : base("96 128 192 256 320", "256")
{ {
} }
public override void Apply(IntPtr lame) public override void Apply(IntPtr lame)
{ {
AudioEncoder.lame_set_VBR(lame, (int)LameVbrMode.Off); libmp3lamedll.lame_set_VBR(lame, (int)LameVbrMode.Off);
AudioEncoder.lame_set_brate(lame, CBREncoderSettings.bps_table[this.EncoderModeIndex]); libmp3lamedll.lame_set_brate(lame, CBREncoderSettings.bps_table[this.EncoderModeIndex]);
AudioEncoder.lame_set_quality(lame, (int)this.Quality); libmp3lamedll.lame_set_quality(lame, (int)this.Quality);
} }
} }
} }

View File

@@ -1,22 +1,22 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace CUETools.Codecs.LAME namespace CUETools.Codecs.libmp3lame
{ {
public enum LameQuality public enum LameQuality
{ {
High = 2, High = 2,
Normal = 5, Normal = 5,
Fast = 7, Fast = 7,
} }
public enum LameVbrMode public enum LameVbrMode
{ {
Off = 0, Off = 0,
Mt = 1, Mt = 1,
Rh = 2, Rh = 2,
Abr = 3, Abr = 3,
Default = 4, Default = 4,
} }
} }

View File

@@ -1,21 +1,21 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace CUETools.Codecs.LAME namespace CUETools.Codecs.libmp3lame
{ {
public class LameEncoderSettings : AudioEncoderSettings public class LameEncoderSettings : AudioEncoderSettings
{ {
public override Type EncoderType => typeof(AudioEncoder); public override Type EncoderType => typeof(AudioEncoder);
public LameEncoderSettings(string modes, string defaultMode) public LameEncoderSettings(string modes, string defaultMode)
: base(modes, defaultMode) : base(modes, defaultMode)
{ {
} }
public virtual void Apply(IntPtr lame) public virtual void Apply(IntPtr lame)
{ {
throw new MethodAccessException(); throw new MethodAccessException();
} }
} }
} }

View File

@@ -1,34 +1,34 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Text; using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace CUETools.Codecs.LAME namespace CUETools.Codecs.libmp3lame
{ {
[JsonObject(MemberSerialization.OptIn)] [JsonObject(MemberSerialization.OptIn)]
public class VBREncoderSettings : LameEncoderSettings public class VBREncoderSettings : LameEncoderSettings
{ {
public override string Extension => "mp3"; public override string Extension => "mp3";
public override string Name => "libmp3lame-VBR"; public override string Name => "libmp3lame-VBR";
public override int Priority => 2; public override int Priority => 2;
[JsonProperty] [JsonProperty]
[DefaultValue(LameQuality.High)] [DefaultValue(LameQuality.High)]
public LameQuality Quality { get; set; } public LameQuality Quality { get; set; }
public VBREncoderSettings() public VBREncoderSettings()
: base("V9 V8 V7 V6 V5 V4 V3 V2 V1 V0", "V2") : base("V9 V8 V7 V6 V5 V4 V3 V2 V1 V0", "V2")
{ {
} }
public override void Apply(IntPtr lame) public override void Apply(IntPtr lame)
{ {
AudioEncoder.lame_set_VBR(lame, (int)LameVbrMode.Default); libmp3lamedll.lame_set_VBR(lame, (int)LameVbrMode.Default);
AudioEncoder.lame_set_VBR_quality(lame, 9 - this.EncoderModeIndex); libmp3lamedll.lame_set_VBR_quality(lame, 9 - this.EncoderModeIndex);
AudioEncoder.lame_set_quality(lame, (int)this.Quality); libmp3lamedll.lame_set_quality(lame, (int)this.Quality);
} }
} }
} }

View File

@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace CUETools.Codecs.libmp3lame
{
class libmp3lamedll
{
private const string DllName = "libmp3lame";
private const CallingConvention LameCallingConvention = CallingConvention.Cdecl;
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern IntPtr lame_init();
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_close(IntPtr handle);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_set_num_channels(IntPtr handle, int channels);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_set_in_samplerate(IntPtr handle, int sampleRate);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_set_quality(IntPtr handle, int quality);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_set_VBR(IntPtr handle, int vbrMode);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_set_VBR_mean_bitrate_kbps(IntPtr handle, int meanBitrate);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_init_params(IntPtr handle);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_set_num_samples(IntPtr handle, uint numSamples);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_encode_buffer_interleaved(IntPtr handle, IntPtr pcm, int num_samples, IntPtr mp3buf, int mp3buf_size);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_encode_flush(IntPtr handle, IntPtr mp3buf, int size);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern uint lame_get_lametag_frame(IntPtr handle, IntPtr buffer, uint size);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_set_VBR_quality(IntPtr handle, float vbrQuality);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_set_brate(IntPtr handle, int bitrate);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_set_bWriteVbrTag(IntPtr handle, int writeVbrTag);
[DllImport(DllName, CallingConvention = LameCallingConvention)]
internal static extern int lame_set_write_id3tag_automatic(IntPtr handle, int automaticWriteId3Tag);
static libmp3lamedll()
{
var myPath = new Uri(typeof(libmp3lamedll).Assembly.CodeBase).LocalPath;
var myFolder = System.IO.Path.GetDirectoryName(myPath);
var is64 = IntPtr.Size == 8;
var subfolder = is64 ? "x64" : "win32";
#if NET40
IntPtr Dll = LoadLibrary(System.IO.Path.Combine(myFolder, subfolder, DllName + ".dll"));
#else
IntPtr Dll = LoadLibrary(System.IO.Path.Combine(System.IO.Path.Combine(myFolder, subfolder), DllName + ".dll"));
#endif
if (Dll == IntPtr.Zero)
Dll = LoadLibrary(DllName + ".dll");
if (Dll == IntPtr.Zero)
throw new DllNotFoundException();
}
}
}

View File

@@ -21,7 +21,6 @@ namespace CUETools.Codecs.libwavpack
public DecoderSettings() : base() { } public DecoderSettings() : base() { }
} }
[AudioDecoderClass(typeof(DecoderSettings))]
public unsafe class AudioDecoder : IAudioSource public unsafe class AudioDecoder : IAudioSource
{ {
private readonly void* IO_ID_WV = ((IntPtr)1).ToPointer(); private readonly void* IO_ID_WV = ((IntPtr)1).ToPointer();

View File

@@ -54,7 +54,6 @@ namespace CUETools.Codecs.libwavpack
private int m_extraMode; private int m_extraMode;
}; };
[AudioEncoderClass(typeof(EncoderSettings))]
public unsafe class AudioEncoder : IAudioDest public unsafe class AudioEncoder : IAudioDest
{ {
public AudioEncoder(EncoderSettings settings, string path, Stream output = null) public AudioEncoder(EncoderSettings settings, string path, Stream output = null)

View File

@@ -1,35 +0,0 @@
using System;
namespace CUETools.Codecs
{
/// <summary>
/// This class provides an attribute for marking
/// classes that provide <see cref="IAudioSource" />.
/// </summary>
/// <remarks>
/// When plugins with classes that provide <see cref="IAudioSource" /> are
/// registered, their <see cref="AudioDecoderClass" /> attributes are read.
/// </remarks>
/// <example>
/// <code lang="C#">using CUETools.Codecs;
///
///[AudioDecoderClass(typeof(MyDecoderSettings))]
///public class MyDecoder : IAudioSource {
/// ...
///}</code>
/// </example>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class AudioDecoderClassAttribute : Attribute
{
public Type Settings
{
get;
private set;
}
public AudioDecoderClassAttribute(Type settings)
{
Settings = settings;
}
}
}

View File

@@ -1,35 +0,0 @@
using System;
namespace CUETools.Codecs
{
/// <summary>
/// This class provides an attribute for marking
/// classes that provide <see cref="IAudioDest" />.
/// </summary>
/// <remarks>
/// When plugins with classes that provide <see cref="IAudioDest" /> are
/// registered, their <see cref="AudioEncoderClassAttribute" /> attributes are read.
/// </remarks>
/// <example>
/// <code lang="C#">using CUETools.Codecs;
///
///[AudioEncoderClass(typeof(MyEncoderSettings))]
///public class MyEncoder : IAudioDest {
/// ...
///}</code>
/// </example>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class AudioEncoderClassAttribute : Attribute
{
public Type Settings
{
get;
private set;
}
public AudioEncoderClassAttribute(Type settings)
{
Settings = settings;
}
}
}

View File

@@ -20,7 +20,7 @@ namespace CUETools.Codecs
} }
[JsonObject(MemberSerialization.OptIn)] [JsonObject(MemberSerialization.OptIn)]
public class AudioEncoderSettings public class AudioEncoderSettings : IAudioEncoderSettings
{ {
[Browsable(false)] [Browsable(false)]
public virtual string Name => null; public virtual string Name => null;

View File

@@ -1,4 +1,5 @@
using System; using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net; using System.Net;
@@ -11,83 +12,81 @@ namespace CUETools.Codecs
{ {
public class CUEToolsCodecsConfig public class CUEToolsCodecsConfig
{ {
[JsonIgnore]
public Dictionary<string, CUEToolsFormat> formats; public Dictionary<string, CUEToolsFormat> formats;
public EncoderListViewModel encoders; public List<AudioEncoderSettings> encoders;
public DecoderListViewModel decoders; public List<AudioDecoderSettings> decoders;
[JsonIgnore]
public EncoderListViewModel encodersViewModel;
[JsonIgnore]
public DecoderListViewModel decodersViewModel;
public CUEToolsCodecsConfig()
{
encoders = new List<AudioEncoderSettings>();
decoders = new List<AudioDecoderSettings>();
encodersViewModel = new EncoderListViewModel(encoders);
decodersViewModel = new DecoderListViewModel(decoders);
formats = new Dictionary<string, CUEToolsFormat>();
}
public CUEToolsCodecsConfig(CUEToolsCodecsConfig src) public CUEToolsCodecsConfig(CUEToolsCodecsConfig src)
{ {
encoders = new EncoderListViewModel(); encoders = new List<AudioEncoderSettings>();
foreach (var enc in src.encoders) decoders = new List<AudioDecoderSettings>();
encoders.Add(enc.Clone()); src.encoders.ForEach(item => encoders.Add(item.Clone()));
decoders = new DecoderListViewModel(); src.decoders.ForEach(item => decoders.Add(item.Clone()));
foreach (var dec in src.decoders) encodersViewModel = new EncoderListViewModel(encoders);
decoders.Add(dec.Clone()); decodersViewModel = new DecoderListViewModel(decoders);
formats = new Dictionary<string, CUEToolsFormat>(); formats = new Dictionary<string, CUEToolsFormat>();
foreach (var fmt in src.formats) foreach (var fmt in src.formats)
formats.Add(fmt.Key, fmt.Value.Clone(this)); formats.Add(fmt.Key, fmt.Value.Clone(this));
} }
public CUEToolsCodecsConfig(List<Type> encs, List<Type> decs) public void Init(List<AudioEncoderSettings> src_encoders, List<AudioDecoderSettings> src_decoders)
{ {
encoders = new EncoderListViewModel(); encoders = new List<AudioEncoderSettings>();
foreach (Type type in encs) decoders = new List<AudioDecoderSettings>();
foreach (AudioEncoderClassAttribute enc in Attribute.GetCustomAttributes(type, typeof(AudioEncoderClassAttribute))) src_encoders.ForEach(item => encoders.Add(item.Clone()));
try src_decoders.ForEach(item => decoders.Add(item.Clone()));
{
encoders.Add(new AudioEncoderSettingsViewModel(enc));
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
decoders = new DecoderListViewModel();
foreach (Type type in decs)
foreach (AudioDecoderClassAttribute dec in Attribute.GetCustomAttributes(type, typeof(AudioDecoderClassAttribute)))
try
{
decoders.Add(new AudioDecoderSettingsViewModel(Activator.CreateInstance(dec.Settings) as AudioDecoderSettings));
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
if (Type.GetType("Mono.Runtime", false) == null) if (Type.GetType("Mono.Runtime", false) == null)
{ {
encoders.Add(new AudioEncoderSettingsViewModel("flake", "flac", true, "0 1 2 3 4 5 6 7 8 9 10 11 12", "8", "flake.exe", "-%M - -o %O -p %P")); encoders.Add(new CommandLine.EncoderSettings("flake", "flac", true, "0 1 2 3 4 5 6 7 8 9 10 11 12", "8", "flake.exe", "-%M - -o %O -p %P"));
encoders.Add(new AudioEncoderSettingsViewModel("takc", "tak", true, "0 1 2 2e 2m 3 3e 3m 4 4e 4m", "2", "takc.exe", "-e -p%M -overwrite - %O")); encoders.Add(new CommandLine.EncoderSettings("takc", "tak", true, "0 1 2 2e 2m 3 3e 3m 4 4e 4m", "2", "takc.exe", "-e -p%M -overwrite - %O"));
encoders.Add(new AudioEncoderSettingsViewModel("ffmpeg alac", "m4a", true, "", "", "ffmpeg.exe", "-i - -f ipod -acodec alac -y %O")); encoders.Add(new CommandLine.EncoderSettings("ffmpeg alac", "m4a", true, "", "", "ffmpeg.exe", "-i - -f ipod -acodec alac -y %O"));
encoders.Add(new AudioEncoderSettingsViewModel("VBR (lame.exe)", "mp3", false, "V9 V8 V7 V6 V5 V4 V3 V2 V1 V0", "V2", "lame.exe", "--vbr-new -%M - %O")); encoders.Add(new CommandLine.EncoderSettings("VBR (lame.exe)", "mp3", false, "V9 V8 V7 V6 V5 V4 V3 V2 V1 V0", "V2", "lame.exe", "--vbr-new -%M - %O"));
encoders.Add(new AudioEncoderSettingsViewModel("CBR (lame.exe)", "mp3", false, "96 128 192 256 320", "256", "lame.exe", "-m s -q 0 -b %M --noreplaygain - %O")); encoders.Add(new CommandLine.EncoderSettings("CBR (lame.exe)", "mp3", false, "96 128 192 256 320", "256", "lame.exe", "-m s -q 0 -b %M --noreplaygain - %O"));
encoders.Add(new AudioEncoderSettingsViewModel("oggenc", "ogg", false, "-1 -0.5 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7 7.5 8", "3", "oggenc.exe", "-q %M - -o %O")); encoders.Add(new CommandLine.EncoderSettings("oggenc", "ogg", false, "-1 -0.5 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7 7.5 8", "3", "oggenc.exe", "-q %M - -o %O"));
encoders.Add(new AudioEncoderSettingsViewModel("opusenc", "opus", false, "6 16 32 48 64 96 128 192 256", "128", "opusenc.exe", "--bitrate %M - %O")); encoders.Add(new CommandLine.EncoderSettings("opusenc", "opus", false, "6 16 32 48 64 96 128 192 256", "128", "opusenc.exe", "--bitrate %M - %O"));
encoders.Add(new AudioEncoderSettingsViewModel("nero aac", "m4a", false, "0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9", "0.4", "neroAacEnc.exe", "-q %M -if - -of %O")); encoders.Add(new CommandLine.EncoderSettings("nero aac", "m4a", false, "0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9", "0.4", "neroAacEnc.exe", "-q %M -if - -of %O"));
encoders.Add(new AudioEncoderSettingsViewModel("qaac tvbr", "m4a", false, "10 20 30 40 50 60 70 80 90 100 110 127", "80", "qaac.exe", "-s -V %M -q 2 - -o %O")); encoders.Add(new CommandLine.EncoderSettings("qaac tvbr", "m4a", false, "10 20 30 40 50 60 70 80 90 100 110 127", "80", "qaac.exe", "-s -V %M -q 2 - -o %O"));
decoders.Add(new AudioDecoderSettingsViewModel(new CommandLine.DecoderSettings("takc", "tak", "takc.exe", "-d %I -"))); decoders.Add(new CommandLine.DecoderSettings("takc", "tak", "takc.exe", "-d %I -"));
decoders.Add(new AudioDecoderSettingsViewModel(new CommandLine.DecoderSettings("ffmpeg alac", "m4a", "ffmpeg.exe", "-v 0 -i %I -f wav -"))); decoders.Add(new CommandLine.DecoderSettings("ffmpeg alac", "m4a", "ffmpeg.exe", "-v 0 -i %I -f wav -"));
} }
else else
{ {
// !!! // !!!
} }
encodersViewModel = new EncoderListViewModel(encoders);
decodersViewModel = new DecoderListViewModel(decoders);
formats = new Dictionary<string, CUEToolsFormat>(); formats = new Dictionary<string, CUEToolsFormat>();
formats.Add("flac", new CUEToolsFormat("flac", CUEToolsTagger.TagLibSharp, true, false, true, true, encoders.GetDefault("flac", true), null, decoders.GetDefault("flac", true))); formats.Add("flac", new CUEToolsFormat("flac", CUEToolsTagger.TagLibSharp, true, false, true, true, encodersViewModel.GetDefault("flac", true), null, decodersViewModel.GetDefault("flac", true)));
formats.Add("wv", new CUEToolsFormat("wv", CUEToolsTagger.TagLibSharp, true, false, true, true, encoders.GetDefault("wv", true), null, decoders.GetDefault("wv", true))); formats.Add("wv", new CUEToolsFormat("wv", CUEToolsTagger.TagLibSharp, true, false, true, true, encodersViewModel.GetDefault("wv", true), null, decodersViewModel.GetDefault("wv", true)));
formats.Add("ape", new CUEToolsFormat("ape", CUEToolsTagger.TagLibSharp, true, false, true, true, encoders.GetDefault("ape", true), null, decoders.GetDefault("ape", true))); formats.Add("ape", new CUEToolsFormat("ape", CUEToolsTagger.TagLibSharp, true, false, true, true, encodersViewModel.GetDefault("ape", true), null, decodersViewModel.GetDefault("ape", true)));
formats.Add("tta", new CUEToolsFormat("tta", CUEToolsTagger.APEv2, true, false, false, true, encoders.GetDefault("tta", true), null, decoders.GetDefault("tta", true))); formats.Add("tta", new CUEToolsFormat("tta", CUEToolsTagger.APEv2, true, false, false, true, encodersViewModel.GetDefault("tta", true), null, decodersViewModel.GetDefault("tta", true)));
formats.Add("m2ts", new CUEToolsFormat("m2ts", CUEToolsTagger.APEv2, true, false, false, true, null, null, decoders.GetDefault("m2ts", true))); formats.Add("m2ts", new CUEToolsFormat("m2ts", CUEToolsTagger.APEv2, true, false, false, true, null, null, decodersViewModel.GetDefault("m2ts", true)));
formats.Add("mpls", new CUEToolsFormat("mpls", CUEToolsTagger.APEv2, true, false, false, true, null, null, decoders.GetDefault("mpls", true))); formats.Add("mpls", new CUEToolsFormat("mpls", CUEToolsTagger.APEv2, true, false, false, true, null, null, decodersViewModel.GetDefault("mpls", true)));
formats.Add("wav", new CUEToolsFormat("wav", CUEToolsTagger.TagLibSharp, true, false, false, true, encoders.GetDefault("wav", true), null, decoders.GetDefault("wav", true))); formats.Add("wav", new CUEToolsFormat("wav", CUEToolsTagger.TagLibSharp, true, false, false, true, encodersViewModel.GetDefault("wav", true), null, decodersViewModel.GetDefault("wav", true)));
formats.Add("m4a", new CUEToolsFormat("m4a", CUEToolsTagger.TagLibSharp, true, true, false, true, encoders.GetDefault("m4a", true), encoders.GetDefault("m4a", false), decoders.GetDefault("m4a", true))); formats.Add("m4a", new CUEToolsFormat("m4a", CUEToolsTagger.TagLibSharp, true, true, false, true, encodersViewModel.GetDefault("m4a", true), encodersViewModel.GetDefault("m4a", false), decodersViewModel.GetDefault("m4a", true)));
formats.Add("tak", new CUEToolsFormat("tak", CUEToolsTagger.APEv2, true, false, true, true, encoders.GetDefault("tak", true), null, decoders.GetDefault("tak", true))); formats.Add("tak", new CUEToolsFormat("tak", CUEToolsTagger.APEv2, true, false, true, true, encodersViewModel.GetDefault("tak", true), null, decodersViewModel.GetDefault("tak", true)));
formats.Add("wma", new CUEToolsFormat("wma", CUEToolsTagger.TagLibSharp, true, true, false, true, encoders.GetDefault("wma", true), encoders.GetDefault("wma", false), decoders.GetDefault("wma", true))); formats.Add("wma", new CUEToolsFormat("wma", CUEToolsTagger.TagLibSharp, true, true, false, true, encodersViewModel.GetDefault("wma", true), encodersViewModel.GetDefault("wma", false), decodersViewModel.GetDefault("wma", true)));
formats.Add("mp3", new CUEToolsFormat("mp3", CUEToolsTagger.TagLibSharp, false, true, false, true, null, encoders.GetDefault("mp3", false), null)); formats.Add("mp3", new CUEToolsFormat("mp3", CUEToolsTagger.TagLibSharp, false, true, false, true, null, encodersViewModel.GetDefault("mp3", false), null));
formats.Add("ogg", new CUEToolsFormat("ogg", CUEToolsTagger.TagLibSharp, false, true, false, true, null, encoders.GetDefault("ogg", false), null)); formats.Add("ogg", new CUEToolsFormat("ogg", CUEToolsTagger.TagLibSharp, false, true, false, true, null, encodersViewModel.GetDefault("ogg", false), null));
formats.Add("opus", new CUEToolsFormat("opus", CUEToolsTagger.TagLibSharp, false, true, false, true, null, encoders.GetDefault("opus", false), null)); formats.Add("opus", new CUEToolsFormat("opus", CUEToolsTagger.TagLibSharp, false, true, false, true, null, encodersViewModel.GetDefault("opus", false), null));
} }
} }
} }

View File

@@ -34,9 +34,9 @@
public CUEToolsFormat Clone(CUEToolsCodecsConfig cfg) public CUEToolsFormat Clone(CUEToolsCodecsConfig cfg)
{ {
var res = this.MemberwiseClone() as CUEToolsFormat; var res = this.MemberwiseClone() as CUEToolsFormat;
if (decoder != null) cfg.decoders.TryGetValue(decoder.decoderSettings.Extension, decoder.Lossless, decoder.decoderSettings.Name, out res.decoder); if (decoder != null) cfg.decodersViewModel.TryGetValue(decoder.Settings.Extension, decoder.Lossless, decoder.Settings.Name, out res.decoder);
if (encoderLossy != null) cfg.encoders.TryGetValue(encoderLossy.settings.Extension, encoderLossy.Lossless, encoderLossy.settings.Name, out res.encoderLossy); if (encoderLossy != null) cfg.encodersViewModel.TryGetValue(encoderLossy.Settings.Extension, encoderLossy.Lossless, encoderLossy.Settings.Name, out res.encoderLossy);
if (encoderLossless != null) cfg.encoders.TryGetValue(encoderLossless.settings.Extension, encoderLossless.Lossless, encoderLossless.settings.Name, out res.encoderLossless); if (encoderLossless != null) cfg.encodersViewModel.TryGetValue(encoderLossless.Settings.Extension, encoderLossless.Lossless, encoderLossless.Settings.Name, out res.encoderLossless);
return res; return res;
} }

View File

@@ -22,6 +22,25 @@ namespace CUETools.Codecs.CommandLine
{ {
} }
public EncoderSettings(
string _name,
string _extension,
bool _lossless,
string _supported_modes,
string _default_mode,
string _path,
string _parameters
)
{
name = _name;
extension = _extension;
lossless = _lossless;
SupportedModes = _supported_modes;
EncoderMode = _default_mode;
Path = _path;
Parameters = _parameters;
}
[JsonProperty] [JsonProperty]
public string name; public string name;

View File

@@ -8,7 +8,7 @@ namespace CUETools.Codecs
public class AudioDecoderSettingsViewModel : INotifyPropertyChanged public class AudioDecoderSettingsViewModel : INotifyPropertyChanged
{ {
[JsonProperty] [JsonProperty]
public AudioDecoderSettings decoderSettings = null; public AudioDecoderSettings Settings = null;
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
@@ -19,14 +19,7 @@ namespace CUETools.Codecs
public AudioDecoderSettingsViewModel(AudioDecoderSettings settings) public AudioDecoderSettingsViewModel(AudioDecoderSettings settings)
{ {
decoderSettings = settings; this.Settings = settings;
}
public AudioDecoderSettingsViewModel Clone()
{
var res = this.MemberwiseClone() as AudioDecoderSettingsViewModel;
if (decoderSettings != null) res.decoderSettings = decoderSettings.Clone();
return res;
} }
public override string ToString() public override string ToString()
@@ -40,14 +33,14 @@ namespace CUETools.Codecs
{ {
get get
{ {
if (decoderSettings is CommandLine.DecoderSettings) if (Settings is CommandLine.DecoderSettings)
return (decoderSettings as CommandLine.DecoderSettings).Path; return (Settings as CommandLine.DecoderSettings).Path;
return ""; return "";
} }
set set
{ {
if (decoderSettings is CommandLine.DecoderSettings) if (Settings is CommandLine.DecoderSettings)
(decoderSettings as CommandLine.DecoderSettings).Path = value; (Settings as CommandLine.DecoderSettings).Path = value;
else throw new InvalidOperationException(); else throw new InvalidOperationException();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Path")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Path"));
} }
@@ -56,14 +49,14 @@ namespace CUETools.Codecs
{ {
get get
{ {
if (decoderSettings is CommandLine.DecoderSettings) if (Settings is CommandLine.DecoderSettings)
return (decoderSettings as CommandLine.DecoderSettings).Parameters; return (Settings as CommandLine.DecoderSettings).Parameters;
return ""; return "";
} }
set set
{ {
if (decoderSettings is CommandLine.DecoderSettings) if (Settings is CommandLine.DecoderSettings)
(decoderSettings as CommandLine.DecoderSettings).Parameters = value; (Settings as CommandLine.DecoderSettings).Parameters = value;
else throw new InvalidOperationException(); else throw new InvalidOperationException();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Parameters")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Parameters"));
} }
@@ -79,11 +72,11 @@ namespace CUETools.Codecs
public string Name public string Name
{ {
get => decoderSettings.Name; get => Settings.Name;
set set
{ {
if (decoderSettings is CommandLine.DecoderSettings) if (Settings is CommandLine.DecoderSettings)
(decoderSettings as CommandLine.DecoderSettings).name = value; (Settings as CommandLine.DecoderSettings).name = value;
else throw new InvalidOperationException(); else throw new InvalidOperationException();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
} }
@@ -91,11 +84,11 @@ namespace CUETools.Codecs
public string Extension public string Extension
{ {
get => decoderSettings.Extension; get => Settings.Extension;
set set
{ {
if (decoderSettings is CommandLine.DecoderSettings) if (Settings is CommandLine.DecoderSettings)
(decoderSettings as CommandLine.DecoderSettings).extension = value; (Settings as CommandLine.DecoderSettings).extension = value;
else throw new InvalidOperationException(); else throw new InvalidOperationException();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Extension")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Extension"));
} }
@@ -103,10 +96,10 @@ namespace CUETools.Codecs
public string DotExtension => "." + Extension; public string DotExtension => "." + Extension;
public bool CanBeDeleted => decoderSettings is CommandLine.DecoderSettings; public bool CanBeDeleted => Settings is CommandLine.DecoderSettings;
public bool IsValid => public bool IsValid =>
(decoderSettings != null) (Settings != null)
&& (decoderSettings is CommandLine.DecoderSettings ? (decoderSettings as CommandLine.DecoderSettings).Path != "" : true); && (Settings is CommandLine.DecoderSettings ? (Settings as CommandLine.DecoderSettings).Path != "" : true);
} }
} }

View File

@@ -8,7 +8,7 @@ namespace CUETools.Codecs
public class AudioEncoderSettingsViewModel : INotifyPropertyChanged public class AudioEncoderSettingsViewModel : INotifyPropertyChanged
{ {
[JsonProperty] [JsonProperty]
public AudioEncoderSettings settings = null; public AudioEncoderSettings Settings = null;
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
@@ -17,31 +17,9 @@ namespace CUETools.Codecs
{ {
} }
public AudioEncoderSettingsViewModel( public AudioEncoderSettingsViewModel(AudioEncoderSettings settings)
string _name,
string _extension,
bool _lossless,
string _supported_modes,
string _default_mode,
string _path,
string _parameters
)
{ {
settings = new CommandLine.EncoderSettings() { name = _name, extension = _extension, SupportedModes = _supported_modes, EncoderMode = _default_mode, Path = _path, Parameters = _parameters, lossless = _lossless }; this.Settings = settings;
}
public AudioEncoderSettingsViewModel(AudioEncoderClassAttribute enc)
{
settings = Activator.CreateInstance(enc.Settings) as AudioEncoderSettings;
if (settings == null)
throw new InvalidOperationException("invalid codec");
}
public AudioEncoderSettingsViewModel Clone()
{
var res = this.MemberwiseClone() as AudioEncoderSettingsViewModel;
if (settings != null) res.settings = settings.Clone();
return res;
} }
public override string ToString() public override string ToString()
@@ -55,13 +33,13 @@ namespace CUETools.Codecs
{ {
get get
{ {
if (settings is CommandLine.EncoderSettings) if (Settings is CommandLine.EncoderSettings)
return (settings as CommandLine.EncoderSettings).Path; return (Settings as CommandLine.EncoderSettings).Path;
return ""; return "";
} }
set set
{ {
var settings = this.settings as CommandLine.EncoderSettings; var settings = this.Settings as CommandLine.EncoderSettings;
if (settings == null) throw new InvalidOperationException(); if (settings == null) throw new InvalidOperationException();
settings.Path = value; settings.Path = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Path")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Path"));
@@ -72,13 +50,13 @@ namespace CUETools.Codecs
{ {
get get
{ {
if (settings is CommandLine.EncoderSettings) if (Settings is CommandLine.EncoderSettings)
return (settings as CommandLine.EncoderSettings).Parameters; return (Settings as CommandLine.EncoderSettings).Parameters;
return ""; return "";
} }
set set
{ {
var settings = this.settings as CommandLine.EncoderSettings; var settings = this.Settings as CommandLine.EncoderSettings;
if (settings == null) throw new InvalidOperationException(); if (settings == null) throw new InvalidOperationException();
settings.Parameters = value; settings.Parameters = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Parameters")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Parameters"));
@@ -87,10 +65,10 @@ namespace CUETools.Codecs
public bool Lossless public bool Lossless
{ {
get => settings.Lossless; get => Settings.Lossless;
set set
{ {
var settings = this.settings as CommandLine.EncoderSettings; var settings = this.Settings as CommandLine.EncoderSettings;
if (settings == null) throw new InvalidOperationException(); if (settings == null) throw new InvalidOperationException();
settings.lossless = value; settings.lossless = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Lossless")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Lossless"));
@@ -100,10 +78,10 @@ namespace CUETools.Codecs
public string Name public string Name
{ {
get => settings.Name; get => Settings.Name;
set set
{ {
var settings = this.settings as CommandLine.EncoderSettings; var settings = this.Settings as CommandLine.EncoderSettings;
if (settings == null) throw new InvalidOperationException(); if (settings == null) throw new InvalidOperationException();
settings.name = value; settings.name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
@@ -112,10 +90,10 @@ namespace CUETools.Codecs
public string Extension public string Extension
{ {
get => settings.Extension; get => Settings.Extension;
set set
{ {
var settings = this.settings as CommandLine.EncoderSettings; var settings = this.Settings as CommandLine.EncoderSettings;
if (settings == null) throw new InvalidOperationException(); if (settings == null) throw new InvalidOperationException();
settings.extension = value; settings.extension = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Extension")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Extension"));
@@ -129,11 +107,11 @@ namespace CUETools.Codecs
get get
{ {
string defaultMode; string defaultMode;
return this.settings.GetSupportedModes(out defaultMode); return this.Settings.GetSupportedModes(out defaultMode);
} }
set set
{ {
var settings = this.settings as CommandLine.EncoderSettings; var settings = this.Settings as CommandLine.EncoderSettings;
if (settings == null) throw new InvalidOperationException(); if (settings == null) throw new InvalidOperationException();
settings.SupportedModes = value; settings.SupportedModes = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SupportedModesStr")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SupportedModesStr"));
@@ -150,16 +128,16 @@ namespace CUETools.Codecs
if (modes == null || modes.Length < 2) if (modes == null || modes.Length < 2)
return -1; return -1;
for (int i = 0; i < modes.Length; i++) for (int i = 0; i < modes.Length; i++)
if (modes[i] == this.settings.EncoderMode) if (modes[i] == this.Settings.EncoderMode)
return i; return i;
return -1; return -1;
} }
} }
public bool CanBeDeleted => settings is CommandLine.EncoderSettings; public bool CanBeDeleted => Settings is CommandLine.EncoderSettings;
public bool IsValid => public bool IsValid =>
(settings != null) (Settings != null)
&& (settings is CommandLine.EncoderSettings ? (settings as CommandLine.EncoderSettings).Path != "" : true); && (Settings is CommandLine.EncoderSettings ? (Settings as CommandLine.EncoderSettings).Path != "" : true);
} }
} }

View File

@@ -1,26 +1,33 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
namespace CUETools.Codecs namespace CUETools.Codecs
{ {
public class DecoderListViewModel : BindingList<AudioDecoderSettingsViewModel> public class DecoderListViewModel : BindingList<AudioDecoderSettingsViewModel>
{ {
public DecoderListViewModel() private List<AudioDecoderSettings> model;
public DecoderListViewModel(List<AudioDecoderSettings> model)
: base() : base()
{ {
this.model = model;
model.ForEach(item => Add(new AudioDecoderSettingsViewModel(item)));
AddingNew += OnAddingNew; AddingNew += OnAddingNew;
} }
private void OnAddingNew(object sender, AddingNewEventArgs e) private void OnAddingNew(object sender, AddingNewEventArgs e)
{ {
e.NewObject = new AudioDecoderSettingsViewModel(new CommandLine.DecoderSettings("new", "wav", "", "")); var item = new CommandLine.DecoderSettings("new", "wav", "", "");
model.Add(item);
e.NewObject = new AudioDecoderSettingsViewModel(item);
} }
public bool TryGetValue(string extension, bool lossless, string name, out AudioDecoderSettingsViewModel result) public bool TryGetValue(string extension, bool lossless, string name, out AudioDecoderSettingsViewModel result)
{ {
foreach (AudioDecoderSettingsViewModel udc in this) foreach (AudioDecoderSettingsViewModel udc in this)
{ {
if (udc.decoderSettings.Extension == extension && udc.decoderSettings.Lossless == lossless && udc.decoderSettings.Name == name) if (udc.Settings.Extension == extension && udc.Settings.Lossless == lossless && udc.Settings.Name == name)
{ {
result = udc; result = udc;
return true; return true;
@@ -35,7 +42,7 @@ namespace CUETools.Codecs
AudioDecoderSettingsViewModel result = null; AudioDecoderSettingsViewModel result = null;
foreach (AudioDecoderSettingsViewModel udc in this) foreach (AudioDecoderSettingsViewModel udc in this)
{ {
if (udc.decoderSettings.Extension == extension && udc.decoderSettings.Lossless == lossless && (result == null || result.decoderSettings.Priority < udc.decoderSettings.Priority)) if (udc.Settings.Extension == extension && udc.Settings.Lossless == lossless && (result == null || result.Settings.Priority < udc.Settings.Priority))
{ {
result = udc; result = udc;
} }

View File

@@ -1,19 +1,26 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
namespace CUETools.Codecs namespace CUETools.Codecs
{ {
public class EncoderListViewModel : BindingList<AudioEncoderSettingsViewModel> public class EncoderListViewModel : BindingList<AudioEncoderSettingsViewModel>
{ {
public EncoderListViewModel() private List<AudioEncoderSettings> model;
public EncoderListViewModel(List<AudioEncoderSettings> model)
: base() : base()
{ {
this.model = model;
model.ForEach(item => Add(new AudioEncoderSettingsViewModel(item)));
AddingNew += OnAddingNew; AddingNew += OnAddingNew;
} }
private void OnAddingNew(object sender, AddingNewEventArgs e) private void OnAddingNew(object sender, AddingNewEventArgs e)
{ {
e.NewObject = new AudioEncoderSettingsViewModel("new", "wav", true, "", "", "", ""); var item = new CommandLine.EncoderSettings("new", "wav", true, "", "", "", "");
model.Add(item);
e.NewObject = new AudioEncoderSettingsViewModel(item);
} }
public bool TryGetValue(string extension, bool lossless, string name, out AudioEncoderSettingsViewModel result) public bool TryGetValue(string extension, bool lossless, string name, out AudioEncoderSettingsViewModel result)
@@ -21,7 +28,7 @@ namespace CUETools.Codecs
//result = this.Where(udc => udc.settings.Extension == extension && udc.settings.Lossless == lossless && udc.settings.Name == name).First(); //result = this.Where(udc => udc.settings.Extension == extension && udc.settings.Lossless == lossless && udc.settings.Name == name).First();
foreach (AudioEncoderSettingsViewModel udc in this) foreach (AudioEncoderSettingsViewModel udc in this)
{ {
if (udc.settings.Extension == extension && udc.settings.Lossless == lossless && udc.settings.Name == name) if (udc.Settings.Extension == extension && udc.Settings.Lossless == lossless && udc.Settings.Name == name)
{ {
result = udc; result = udc;
return true; return true;
@@ -36,7 +43,7 @@ namespace CUETools.Codecs
AudioEncoderSettingsViewModel result = null; AudioEncoderSettingsViewModel result = null;
foreach (AudioEncoderSettingsViewModel udc in this) foreach (AudioEncoderSettingsViewModel udc in this)
{ {
if (udc.settings.Extension == extension && udc.settings.Lossless == lossless && (result == null || result.settings.Priority < udc.settings.Priority)) if (udc.Settings.Extension == extension && udc.Settings.Lossless == lossless && (result == null || result.Settings.Priority < udc.Settings.Priority))
{ {
result = udc; result = udc;
} }

View File

@@ -3,7 +3,6 @@ using System.IO;
namespace CUETools.Codecs.WAV namespace CUETools.Codecs.WAV
{ {
[AudioDecoderClass(typeof(DecoderSettings))]
public class AudioDecoder : IAudioSource public class AudioDecoder : IAudioSource
{ {
Stream _IO; Stream _IO;

View File

@@ -4,7 +4,6 @@ using System.IO;
namespace CUETools.Codecs.WAV namespace CUETools.Codecs.WAV
{ {
[AudioEncoderClass(typeof(EncoderSettings))]
public class AudioEncoder : IAudioDest public class AudioEncoder : IAudioDest
{ {
private Stream _IO; private Stream _IO;

View File

@@ -30,7 +30,7 @@ namespace CUETools.Converter
{ {
AudioEncoderSettingsViewModel tmpEncoder; AudioEncoderSettingsViewModel tmpEncoder;
return chosenEncoder != null ? return chosenEncoder != null ?
(config.encoders.TryGetValue(fmt.extension, lossless, chosenEncoder, out tmpEncoder) ? tmpEncoder : null) : (config.encodersViewModel.TryGetValue(fmt.extension, lossless, chosenEncoder, out tmpEncoder) ? tmpEncoder : null) :
(lossless ? fmt.encoderLossless : fmt.encoderLossy); (lossless ? fmt.encoderLossless : fmt.encoderLossy);
} }
@@ -47,16 +47,16 @@ namespace CUETools.Converter
throw new Exception("Unsupported audio type: " + path); throw new Exception("Unsupported audio type: " + path);
var decoder = fmt.decoder; var decoder = fmt.decoder;
if (chosenDecoder != null && !config.decoders.TryGetValue(fmt.extension, true, chosenDecoder, out decoder)) if (chosenDecoder != null && !config.decodersViewModel.TryGetValue(fmt.extension, true, chosenDecoder, out decoder))
throw new Exception("Unknown audio decoder " + chosenDecoder + " or unsupported audio type " + fmt.extension); throw new Exception("Unknown audio decoder " + chosenDecoder + " or unsupported audio type " + fmt.extension);
if (decoder == null) if (decoder == null)
throw new Exception("Unsupported audio type: " + path); throw new Exception("Unsupported audio type: " + path);
var settings = fmt.decoder.decoderSettings.Clone(); var settings = fmt.decoder.Settings.Clone();
try try
{ {
object src = Activator.CreateInstance(decoder.decoderSettings.DecoderType, settings, path, IO); object src = Activator.CreateInstance(decoder.Settings.DecoderType, settings, path, IO);
if (src == null || !(src is IAudioSource)) if (src == null || !(src is IAudioSource))
throw new Exception("Unsupported audio type: " + path + ": " + decoder.decoderSettings.DecoderType.FullName); throw new Exception("Unsupported audio type: " + path + ": " + decoder.Settings.DecoderType.FullName);
return src as IAudioSource; return src as IAudioSource;
} }
catch (System.Reflection.TargetInvocationException ex) catch (System.Reflection.TargetInvocationException ex)
@@ -133,7 +133,8 @@ namespace CUETools.Converter
DateTime start = DateTime.Now; DateTime start = DateTime.Now;
TimeSpan lastPrint = TimeSpan.FromMilliseconds(0); TimeSpan lastPrint = TimeSpan.FromMilliseconds(0);
CUEToolsCodecsConfig config = new CUEConfig(); var config = new CUEConfigAdvanced();
config.Init();
#if !DEBUG #if !DEBUG
try try
@@ -186,12 +187,12 @@ namespace CUETools.Converter
Program.GetEncoder(config, fmt, true, encoderName) ?? Program.GetEncoder(config, fmt, false, encoderName); Program.GetEncoder(config, fmt, true, encoderName) ?? Program.GetEncoder(config, fmt, false, encoderName);
if (encoder == null) if (encoder == null)
{ {
var lst = new List<AudioEncoderSettingsViewModel>(config.encoders).FindAll( var lst = new List<AudioEncoderSettingsViewModel>(config.encodersViewModel).FindAll(
e => e.Extension == fmt.extension && (audioEncoderType == AudioEncoderType.NoAudio || audioEncoderType == (e.Lossless ? AudioEncoderType.Lossless : AudioEncoderType.Lossy))). e => e.Extension == fmt.extension && (audioEncoderType == AudioEncoderType.NoAudio || audioEncoderType == (e.Lossless ? AudioEncoderType.Lossless : AudioEncoderType.Lossy))).
ConvertAll(e => e.Name + (e.Lossless ? " (lossless)" : " (lossy)")); ConvertAll(e => e.Name + (e.Lossless ? " (lossless)" : " (lossy)"));
throw new Exception("Encoders available for format " + fmt.extension + ": " + (lst.Count == 0 ? "none" : string.Join(", ", lst.ToArray()))); throw new Exception("Encoders available for format " + fmt.extension + ": " + (lst.Count == 0 ? "none" : string.Join(", ", lst.ToArray())));
} }
var settings = encoder.settings.Clone(); var settings = encoder.Settings.Clone();
settings.PCM = audioSource.PCM; settings.PCM = audioSource.PCM;
settings.Padding = padding; settings.Padding = padding;
settings.EncoderMode = encoderMode ?? settings.EncoderMode; settings.EncoderMode = encoderMode ?? settings.EncoderMode;

View File

@@ -25,12 +25,12 @@ namespace CUETools.Processor
throw new Exception("Unsupported audio type: " + path); throw new Exception("Unsupported audio type: " + path);
if (fmt.decoder == null) if (fmt.decoder == null)
throw new Exception("Unsupported audio type: " + path); throw new Exception("Unsupported audio type: " + path);
var settings = fmt.decoder.decoderSettings.Clone(); var settings = fmt.decoder.Settings.Clone();
try try
{ {
object src = Activator.CreateInstance(fmt.decoder.decoderSettings.DecoderType, settings, path, IO); object src = Activator.CreateInstance(fmt.decoder.Settings.DecoderType, settings, path, IO);
if (src == null || !(src is IAudioSource)) if (src == null || !(src is IAudioSource))
throw new Exception("Unsupported audio type: " + path + ": " + fmt.decoder.decoderSettings.DecoderType.FullName); throw new Exception("Unsupported audio type: " + path + ": " + fmt.decoder.Settings.DecoderType.FullName);
return src as IAudioSource; return src as IAudioSource;
} }
catch (System.Reflection.TargetInvocationException ex) catch (System.Reflection.TargetInvocationException ex)
@@ -60,7 +60,7 @@ namespace CUETools.Processor
null; null;
if (encoder == null) if (encoder == null)
throw new Exception("Unsupported audio type: " + path); throw new Exception("Unsupported audio type: " + path);
var settings = encoder.settings.Clone(); var settings = encoder.Settings.Clone();
settings.PCM = pcm; settings.PCM = pcm;
settings.Padding = padding; settings.Padding = padding;
object o; object o;

View File

@@ -12,7 +12,7 @@ using System.Linq;
namespace CUETools.Processor namespace CUETools.Processor
{ {
public class CUEConfig : CUEToolsCodecsConfig public class CUEConfig
{ {
public uint fixOffsetMinimumConfidence; public uint fixOffsetMinimumConfidence;
public uint fixOffsetMinimumTracksPercent; public uint fixOffsetMinimumTracksPercent;
@@ -71,11 +71,12 @@ namespace CUETools.Processor
public bool CopyAlbumArt { get; set; } public bool CopyAlbumArt { get; set; }
public string ArLogFilenameFormat { get; set; } public string ArLogFilenameFormat { get; set; }
public string AlArtFilenameFormat { get; set; } public string AlArtFilenameFormat { get; set; }
public EncoderListViewModel Encoders => encoders; public EncoderListViewModel Encoders => advanced.encodersViewModel;
public DecoderListViewModel Decoders => decoders; public DecoderListViewModel Decoders => advanced.decodersViewModel;
public Dictionary<string, CUEToolsFormat> formats => advanced.formats;
public CUEConfig() public CUEConfig()
: base(CUEProcessorPlugins.encs, CUEProcessorPlugins.decs) : base()
{ {
fixOffsetMinimumConfidence = 2; fixOffsetMinimumConfidence = 2;
fixOffsetMinimumTracksPercent = 51; fixOffsetMinimumTracksPercent = 51;
@@ -136,6 +137,7 @@ namespace CUETools.Processor
gapsHandling = CUEStyle.GapsAppended; gapsHandling = CUEStyle.GapsAppended;
advanced = new CUEConfigAdvanced(); advanced = new CUEConfigAdvanced();
advanced.Init();
language = Thread.CurrentThread.CurrentUICulture.Name; language = Thread.CurrentThread.CurrentUICulture.Name;
@@ -155,7 +157,6 @@ namespace CUETools.Processor
} }
public CUEConfig(CUEConfig src) public CUEConfig(CUEConfig src)
: base(src)
{ {
fixOffsetMinimumConfidence = src.fixOffsetMinimumConfidence; fixOffsetMinimumConfidence = src.fixOffsetMinimumConfidence;
fixOffsetMinimumTracksPercent = src.fixOffsetMinimumTracksPercent; fixOffsetMinimumTracksPercent = src.fixOffsetMinimumTracksPercent;
@@ -296,33 +297,13 @@ namespace CUETools.Processor
sw.Save("AlArtFilenameFormat", AlArtFilenameFormat); sw.Save("AlArtFilenameFormat", AlArtFilenameFormat);
sw.SaveText("Advanced", JsonConvert.SerializeObject(advanced, sw.SaveText("Advanced", JsonConvert.SerializeObject(advanced,
Newtonsoft.Json.Formatting.Indented,
new JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate
}));
sw.SaveText("Encoders", JsonConvert.SerializeObject(encoders,
Newtonsoft.Json.Formatting.Indented, Newtonsoft.Json.Formatting.Indented,
new JsonSerializerSettings new JsonSerializerSettings
{ {
DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate, DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate,
TypeNameHandling = TypeNameHandling.Auto TypeNameHandling = TypeNameHandling.Auto,
})); }));
int nDecoders = 0;
foreach (var decoder in decoders)
if (decoder.decoderSettings is Codecs.CommandLine.DecoderSettings)
{
var settings = decoder.decoderSettings as Codecs.CommandLine.DecoderSettings;
sw.Save(string.Format("ExternalDecoder{0}Name", nDecoders), settings.Name);
sw.Save(string.Format("ExternalDecoder{0}Extension", nDecoders), settings.Extension);
sw.Save(string.Format("ExternalDecoder{0}Path", nDecoders), settings.Path);
sw.Save(string.Format("ExternalDecoder{0}Parameters", nDecoders), settings.Parameters);
nDecoders++;
}
sw.Save("ExternalDecoders", nDecoders);
int nFormats = 0; int nFormats = 0;
foreach (KeyValuePair<string, CUEToolsFormat> format in formats) foreach (KeyValuePair<string, CUEToolsFormat> format in formats)
{ {
@@ -415,100 +396,56 @@ namespace CUETools.Processor
separateDecodingThread = sr.LoadBoolean("SeparateDecodingThread") ?? separateDecodingThread; separateDecodingThread = sr.LoadBoolean("SeparateDecodingThread") ?? separateDecodingThread;
try var jsonConfig = sr.Load("Advanced");
if (jsonConfig != null)
{ {
var jsonObject = JsonConvert.DeserializeObject(sr.Load("Advanced"), var backup = advanced;
typeof(CUEConfigAdvanced), try
new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate
});
if (jsonObject as CUEConfigAdvanced == null)
throw new Exception();
advanced = jsonObject as CUEConfigAdvanced;
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
var encodersBackup = encoders;
try
{
var jsonObject = JsonConvert.DeserializeObject(sr.Load("Encoders"),
typeof(EncoderListViewModel),
new JsonSerializerSettings {
DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate,
TypeNameHandling = TypeNameHandling.Auto
});
if (jsonObject as EncoderListViewModel == null)
throw new Exception();
encoders = jsonObject as EncoderListViewModel;
encoders.Where(x => !x.IsValid).ToList().ForEach(x => encoders.Remove(x));
AudioEncoderSettingsViewModel tmp;
encodersBackup.Where(x => !encoders.TryGetValue(x.Extension, x.Lossless, x.Name, out tmp)).ToList().ForEach(x => encoders.Add(x));
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
//int totalEncoders = sr.LoadInt32("ExternalEncoders", 0, null) ?? 0;
//for (int nEncoders = 0; nEncoders < totalEncoders; nEncoders++)
//{
// string name = sr.Load(string.Format("ExternalEncoder{0}Name", nEncoders));
// string extension = sr.Load(string.Format("ExternalEncoder{0}Extension", nEncoders));
// string settings = sr.Load(string.Format("ExternalEncoder{0}Settings", nEncoders));
// bool lossless = sr.LoadBoolean(string.Format("ExternalEncoder{0}Lossless", nEncoders)) ?? true;
// CUEToolsUDC encoder;
// if (name == null || extension == null) continue;
// if (!encoders.TryGetValue(extension, lossless, name, out encoder))
// {
// encoder = new CUEToolsUDC(name, extension, lossless, "", "", "", "");
// encoders.Add(encoder);
// }
// try
// {
// if (settings != null)
// {
// var encoderSettings = JsonConvert.DeserializeObject(settings,
// encoder.settings.GetType(),
// new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate });
// if (encoderSettings as AudioEncoderSettings == null)
// throw new Exception();
// encoder.settings = encoderSettings as AudioEncoderSettings;
// if (encoder.settings is UserDefinedEncoderSettings && (encoder.settings as UserDefinedEncoderSettings).Path == "")
// throw new Exception();
// }
// }
// catch (Exception ex)
// {
// System.Diagnostics.Trace.WriteLine(ex.Message);
// if (version == 203 && encoder.settings is UserDefinedEncoderSettings)
// {
// (encoder.settings as UserDefinedEncoderSettings).SupportedModes = sr.Load(string.Format("ExternalEncoder{0}Modes", nEncoders));
// (encoder.settings as UserDefinedEncoderSettings).EncoderMode = sr.Load(string.Format("ExternalEncoder{0}Mode", nEncoders));
// (encoder.settings as UserDefinedEncoderSettings).Path = sr.Load(string.Format("ExternalEncoder{0}Path", nEncoders));
// (encoder.settings as UserDefinedEncoderSettings).Parameters = sr.Load(string.Format("ExternalEncoder{0}Parameters", nEncoders));
// }
// else
// encoders.Remove(encoder);
// }
//}
int totalDecoders = sr.LoadInt32("ExternalDecoders", 0, null) ?? 0;
for (int nDecoders = 0; nDecoders < totalDecoders; nDecoders++)
{
string name = sr.Load(string.Format("ExternalDecoder{0}Name", nDecoders));
string extension = sr.Load(string.Format("ExternalDecoder{0}Extension", nDecoders));
string path = sr.Load(string.Format("ExternalDecoder{0}Path", nDecoders));
string parameters = sr.Load(string.Format("ExternalDecoder{0}Parameters", nDecoders));
AudioDecoderSettingsViewModel decoder;
if (!decoders.TryGetValue(extension, true, name, out decoder))
decoders.Add(new AudioDecoderSettingsViewModel(new Codecs.CommandLine.DecoderSettings(name, extension, path, parameters)));
else
{ {
decoder.Extension = extension; var jsonObject = JsonConvert.DeserializeObject(jsonConfig,
decoder.Path = path; typeof(CUEConfigAdvanced),
decoder.Parameters = parameters; new JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate,
TypeNameHandling = TypeNameHandling.Auto,
});
if (jsonObject as CUEConfigAdvanced == null)
throw new Exception();
advanced = jsonObject as CUEConfigAdvanced;
// Add missing codecs
backup.encoders.Where(x => advanced.encoders
.FindAll(y => y.Extension == x.Extension && y.Lossless == x.Lossless && y.Name == x.Name).Count == 0)
.ToList().ForEach(x => advanced.encoders.Add(x));
backup.decoders.Where(x => advanced.decoders
.FindAll(y => y.Extension == x.Extension && y.Lossless == x.Lossless && y.Name == x.Name).Count == 0)
.ToList().ForEach(x => advanced.decoders.Add(x));
// Reset the ViewModel
advanced.encodersViewModel = new EncoderListViewModel(advanced.encoders);
advanced.decodersViewModel = new DecoderListViewModel(advanced.decoders);
// Reset the links in formats
foreach (var extension in formats.Keys)
{
var format = formats[extension];
AudioEncoderSettingsViewModel encoderLossless, encoderLossy;
AudioDecoderSettingsViewModel decoder;
if (format.encoderLossless == null || !Encoders.TryGetValue(extension, true, format.encoderLossless.Name, out encoderLossless))
encoderLossless = Encoders.GetDefault(extension, true);
if (format.encoderLossy == null || !Encoders.TryGetValue(extension, false, format.encoderLossy.Name, out encoderLossy))
encoderLossy = Encoders.GetDefault(extension, false);
if (format.decoder == null || !Decoders.TryGetValue(extension, true, format.decoder.Name, out decoder))
decoder = Decoders.GetDefault(extension, true);
format.encoderLossless = encoderLossless;
format.encoderLossy = encoderLossy;
format.decoder = decoder;
}
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
advanced = backup;
} }
} }
@@ -526,12 +463,12 @@ namespace CUETools.Processor
CUEToolsFormat format; CUEToolsFormat format;
AudioEncoderSettingsViewModel udcLossless, udcLossy; AudioEncoderSettingsViewModel udcLossless, udcLossy;
AudioDecoderSettingsViewModel udcDecoder; AudioDecoderSettingsViewModel udcDecoder;
if (encoderLossless == "" || !encoders.TryGetValue(extension, true, encoderLossless, out udcLossless)) if (encoderLossless == "" || !Encoders.TryGetValue(extension, true, encoderLossless, out udcLossless))
udcLossless = encoders.GetDefault(extension, true); udcLossless = Encoders.GetDefault(extension, true);
if (encoderLossy == "" || !encoders.TryGetValue(extension, false, encoderLossy, out udcLossy)) if (encoderLossy == "" || !Encoders.TryGetValue(extension, false, encoderLossy, out udcLossy))
udcLossy = encoders.GetDefault(extension, false); udcLossy = Encoders.GetDefault(extension, false);
if (decoder == "" || !decoders.TryGetValue(extension, true, decoder, out udcDecoder)) if (decoder == "" || !Decoders.TryGetValue(extension, true, decoder, out udcDecoder))
udcDecoder = decoders.GetDefault(extension, true); udcDecoder = Decoders.GetDefault(extension, true);
if (!formats.TryGetValue(extension, out format)) if (!formats.TryGetValue(extension, out format))
formats.Add(extension, new CUEToolsFormat(extension, tagger, allowLossless, allowLossy, allowEmbed, false, udcLossless, udcLossy, udcDecoder)); formats.Add(extension, new CUEToolsFormat(extension, tagger, allowLossless, allowLossy, allowEmbed, false, udcLossless, udcLossy, udcDecoder));
else else

View File

@@ -1,10 +1,11 @@
using System; using CUETools.Codecs;
using System;
using System.ComponentModel; using System.ComponentModel;
namespace CUETools.Processor namespace CUETools.Processor
{ {
[Serializable] [Serializable]
public class CUEConfigAdvanced public class CUEConfigAdvanced : CUEToolsCodecsConfig
{ {
public enum ProxyMode public enum ProxyMode
{ {
@@ -38,6 +39,11 @@ namespace CUETools.Processor
} }
} }
public void Init()
{
Init(CUEProcessorPlugins.encs, CUEProcessorPlugins.decs);
}
[DefaultValue("i"), Category("Freedb"), DisplayName("Email user")] [DefaultValue("i"), Category("Freedb"), DisplayName("Email user")]
public string FreedbUser { get; set; } public string FreedbUser { get; set; }

View File

@@ -11,8 +11,8 @@ namespace CUETools.Processor
{ {
public static class CUEProcessorPlugins public static class CUEProcessorPlugins
{ {
public static List<Type> encs; public static List<AudioEncoderSettings> encs;
public static List<Type> decs; public static List<AudioDecoderSettings> decs;
public static List<Type> arcp; public static List<Type> arcp;
public static List<string> arcp_fmt; public static List<string> arcp_fmt;
public static Type hdcd; public static Type hdcd;
@@ -20,13 +20,13 @@ namespace CUETools.Processor
static CUEProcessorPlugins() static CUEProcessorPlugins()
{ {
encs = new List<Type>(); encs = new List<AudioEncoderSettings>();
decs = new List<Type>(); decs = new List<AudioDecoderSettings>();
arcp = new List<Type>(); arcp = new List<Type>();
arcp_fmt = new List<string>(); arcp_fmt = new List<string>();
encs.Add(typeof(CUETools.Codecs.WAV.AudioEncoder)); encs.Add(new Codecs.WAV.EncoderSettings());
decs.Add(typeof(CUETools.Codecs.WAV.AudioDecoder)); decs.Add(new Codecs.WAV.DecoderSettings());
//ApplicationSecurityInfo asi = new ApplicationSecurityInfo(AppDomain.CurrentDomain.ActivationContext); //ApplicationSecurityInfo asi = new ApplicationSecurityInfo(AppDomain.CurrentDomain.ActivationContext);
//string arch = asi.ApplicationId.ProcessorArchitecture; //string arch = asi.ApplicationId.ProcessorArchitecture;
@@ -67,14 +67,14 @@ namespace CUETools.Processor
{ {
try try
{ {
if (Attribute.GetCustomAttribute(type, typeof(AudioDecoderClassAttribute)) != null) if (!type.IsClass || type.IsAbstract) continue;
if (type.GetInterface(typeof(IAudioDecoderSettings).Name) != null && type != typeof(AudioDecoderSettings))
{ {
decs.Add(type); decs.Add(Activator.CreateInstance(type) as AudioDecoderSettings);
} }
//if (type.IsClass && !type.IsAbstract && typeof(IAudioDest).IsAssignableFrom(type)) if (type.GetInterface(typeof(IAudioEncoderSettings).Name) != null && type != typeof(AudioEncoderSettings))
if (Attribute.GetCustomAttributes(type, typeof(AudioEncoderClassAttribute)).Length > 0)
{ {
encs.Add(type); encs.Add(Activator.CreateInstance(type) as AudioEncoderSettings);
} }
CompressionProviderClass archclass = Attribute.GetCustomAttribute(type, typeof(CompressionProviderClass)) as CompressionProviderClass; CompressionProviderClass archclass = Attribute.GetCustomAttribute(type, typeof(CompressionProviderClass)) as CompressionProviderClass;
if (archclass != null) if (archclass != null)
@@ -87,7 +87,7 @@ namespace CUETools.Processor
{ {
hdcd = type; hdcd = type;
} }
if (type.IsClass && !type.IsAbstract && typeof(ICDRipper).IsAssignableFrom(type)) if (type.GetInterface(typeof(ICDRipper).Name) != null)
{ {
ripper = type; ripper = type;
} }

View File

@@ -788,7 +788,7 @@ namespace CUETools.Processor
else else
{ {
TagLib.File fileInfo; TagLib.File fileInfo;
TagLib.UserDefined.AdditionalFileTypes.Config = _config; TagLib.UserDefined.AdditionalFileTypes.Config = _config.advanced;
TagLib.File.IFileAbstraction file = new TagLib.File.LocalFileAbstraction(path); TagLib.File.IFileAbstraction file = new TagLib.File.LocalFileAbstraction(path);
fileInfo = TagLib.File.Create(file); fileInfo = TagLib.File.Create(file);
NameValueCollection tags = Tagging.Analyze(fileInfo); NameValueCollection tags = Tagging.Analyze(fileInfo);
@@ -2195,7 +2195,7 @@ namespace CUETools.Processor
} }
else else
{ {
TagLib.UserDefined.AdditionalFileTypes.Config = _config; TagLib.UserDefined.AdditionalFileTypes.Config = _config.advanced;
TagLib.File.IFileAbstraction file = _isArchive TagLib.File.IFileAbstraction file = _isArchive
? (TagLib.File.IFileAbstraction)new ArchiveFileAbstraction(this, path) ? (TagLib.File.IFileAbstraction)new ArchiveFileAbstraction(this, path)
: (TagLib.File.IFileAbstraction)new TagLib.File.LocalFileAbstraction(path); : (TagLib.File.IFileAbstraction)new TagLib.File.LocalFileAbstraction(path);
@@ -2668,9 +2668,9 @@ namespace CUETools.Processor
if (_audioEncoderType != AudioEncoderType.NoAudio) if (_audioEncoderType != AudioEncoderType.NoAudio)
{ {
NameValueCollection tags = GenerateAlbumTags(bestOffset, OutputStyle == CUEStyle.SingleFileWithCUE, _ripperLog ?? _eacLog); NameValueCollection tags = GenerateAlbumTags(bestOffset, OutputStyle == CUEStyle.SingleFileWithCUE, _ripperLog ?? _eacLog);
TagLib.UserDefined.AdditionalFileTypes.Config = _config; TagLib.UserDefined.AdditionalFileTypes.Config = _config.advanced;
TagLib.File fileInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(_destPaths[0])); TagLib.File fileInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(_destPaths[0]));
if (Tagging.UpdateTags(fileInfo, tags, _config, _config.advanced.UseId3v24)) if (Tagging.UpdateTags(fileInfo, tags, _config.advanced, _config.advanced.UseId3v24))
{ {
TagLib.File sourceFileInfo = _tracks[0]._fileInfo ?? _fileInfo; TagLib.File sourceFileInfo = _tracks[0]._fileInfo ?? _fileInfo;
@@ -2754,9 +2754,9 @@ namespace CUETools.Processor
{ {
string path = _destPaths[iTrack + (htoaToFile ? 1 : 0)]; string path = _destPaths[iTrack + (htoaToFile ? 1 : 0)];
NameValueCollection tags = GenerateTrackTags(iTrack, bestOffset); NameValueCollection tags = GenerateTrackTags(iTrack, bestOffset);
TagLib.UserDefined.AdditionalFileTypes.Config = _config; TagLib.UserDefined.AdditionalFileTypes.Config = _config.advanced;
TagLib.File fileInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(path)); TagLib.File fileInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(path));
if (Tagging.UpdateTags(fileInfo, tags, _config, _config.advanced.UseId3v24)) if (Tagging.UpdateTags(fileInfo, tags, _config.advanced, _config.advanced.UseId3v24))
{ {
TagLib.File sourceFileInfo = _tracks[iTrack]._fileInfo ?? _fileInfo; TagLib.File sourceFileInfo = _tracks[iTrack]._fileInfo ?? _fileInfo;
@@ -3033,7 +3033,7 @@ namespace CUETools.Processor
NameValueCollection tags = Tagging.Analyze(_fileInfo); NameValueCollection tags = Tagging.Analyze(_fileInfo);
CleanupTags(tags, "ACCURATERIP"); CleanupTags(tags, "ACCURATERIP");
GenerateAccurateRipTags(tags, bestOffset, -1); GenerateAccurateRipTags(tags, bestOffset, -1);
if (Tagging.UpdateTags(_fileInfo, tags, _config, _config.advanced.UseId3v24)) if (Tagging.UpdateTags(_fileInfo, tags, _config.advanced, _config.advanced.UseId3v24))
_fileInfo.Save(); _fileInfo.Save();
} }
else if (_hasTrackFilenames) else if (_hasTrackFilenames)
@@ -3043,7 +3043,7 @@ namespace CUETools.Processor
NameValueCollection tags = Tagging.Analyze(_tracks[iTrack]._fileInfo); NameValueCollection tags = Tagging.Analyze(_tracks[iTrack]._fileInfo);
CleanupTags(tags, "ACCURATERIP"); CleanupTags(tags, "ACCURATERIP");
GenerateAccurateRipTags(tags, bestOffset, iTrack); GenerateAccurateRipTags(tags, bestOffset, iTrack);
if (Tagging.UpdateTags(_tracks[iTrack]._fileInfo, tags, _config, _config.advanced.UseId3v24)) if (Tagging.UpdateTags(_tracks[iTrack]._fileInfo, tags, _config.advanced, _config.advanced.UseId3v24))
_tracks[iTrack]._fileInfo.Save(); _tracks[iTrack]._fileInfo.Save();
} }
} }
@@ -3059,7 +3059,7 @@ namespace CUETools.Processor
CleanupTags(tags, "CTDBDISCCONFIDENCE"); CleanupTags(tags, "CTDBDISCCONFIDENCE");
CleanupTags(tags, "CTDBTRACKCONFIDENCE"); CleanupTags(tags, "CTDBTRACKCONFIDENCE");
GenerateCTDBTags(tags, -1); GenerateCTDBTags(tags, -1);
if (Tagging.UpdateTags(_fileInfo, tags, _config, _config.advanced.UseId3v24)) if (Tagging.UpdateTags(_fileInfo, tags, _config.advanced, _config.advanced.UseId3v24))
_fileInfo.Save(); _fileInfo.Save();
} }
else if (_hasTrackFilenames) else if (_hasTrackFilenames)
@@ -3070,7 +3070,7 @@ namespace CUETools.Processor
CleanupTags(tags, "CTDBDISCCONFIDENCE"); CleanupTags(tags, "CTDBDISCCONFIDENCE");
CleanupTags(tags, "CTDBTRACKCONFIDENCE"); CleanupTags(tags, "CTDBTRACKCONFIDENCE");
GenerateCTDBTags(tags, iTrack); GenerateCTDBTags(tags, iTrack);
if (Tagging.UpdateTags(_tracks[iTrack]._fileInfo, tags, _config, _config.advanced.UseId3v24)) if (Tagging.UpdateTags(_tracks[iTrack]._fileInfo, tags, _config.advanced, _config.advanced.UseId3v24))
_tracks[iTrack]._fileInfo.Save(); _tracks[iTrack]._fileInfo.Save();
} }
} }
@@ -3687,7 +3687,7 @@ namespace CUETools.Processor
{ {
if (fileGroup.type == FileGroupInfoType.FileWithCUE) if (fileGroup.type == FileGroupInfoType.FileWithCUE)
{ {
TagLib.UserDefined.AdditionalFileTypes.Config = _config; TagLib.UserDefined.AdditionalFileTypes.Config = _config.advanced;
TagLib.File.IFileAbstraction fileAbsraction = new TagLib.File.LocalFileAbstraction(fileGroup.main.FullName); TagLib.File.IFileAbstraction fileAbsraction = new TagLib.File.LocalFileAbstraction(fileGroup.main.FullName);
TagLib.File fileInfo = TagLib.File.Create(fileAbsraction); TagLib.File fileInfo = TagLib.File.Create(fileAbsraction);
return Tagging.Analyze(fileInfo).Get("CUESHEET"); return Tagging.Analyze(fileInfo).Get("CUESHEET");
@@ -4199,7 +4199,7 @@ namespace CUETools.Processor
string cueFound = null; string cueFound = null;
CDImageLayout tocFound = null; CDImageLayout tocFound = null;
TimeSpan dur = TimeSpan.Zero; TimeSpan dur = TimeSpan.Zero;
TagLib.UserDefined.AdditionalFileTypes.Config = _config; TagLib.UserDefined.AdditionalFileTypes.Config = _config.advanced;
TagLib.File.IFileAbstraction fileAbsraction = new TagLib.File.LocalFileAbstraction(file.FullName); TagLib.File.IFileAbstraction fileAbsraction = new TagLib.File.LocalFileAbstraction(file.FullName);
try try
{ {

View File

@@ -36,7 +36,7 @@ namespace CUETools.eac3to
{ {
AudioEncoderSettingsViewModel tmpEncoder; AudioEncoderSettingsViewModel tmpEncoder;
return chosenEncoder != null ? return chosenEncoder != null ?
(config.encoders.TryGetValue(fmt.extension, lossless, chosenEncoder, out tmpEncoder) ? tmpEncoder : null) : (config.encodersViewModel.TryGetValue(fmt.extension, lossless, chosenEncoder, out tmpEncoder) ? tmpEncoder : null) :
(lossless ? fmt.encoderLossless : fmt.encoderLossy); (lossless ? fmt.encoderLossless : fmt.encoderLossy);
} }
@@ -115,7 +115,8 @@ namespace CUETools.eac3to
DateTime start = DateTime.Now; DateTime start = DateTime.Now;
TimeSpan lastPrint = TimeSpan.FromMilliseconds(0); TimeSpan lastPrint = TimeSpan.FromMilliseconds(0);
CUEToolsCodecsConfig config = new CUEConfig(); var config = new CUEConfigAdvanced();
config.Init();
#if !DEBUG #if !DEBUG
try try
@@ -314,7 +315,7 @@ namespace CUETools.eac3to
if (stream - chapterStreams - videos.Count > audios.Count) if (stream - chapterStreams - videos.Count > audios.Count)
throw new Exception(string.Format("The source file doesn't contain a track with the number {0}.", stream)); throw new Exception(string.Format("The source file doesn't contain a track with the number {0}.", stream));
ushort pid = audios[stream - chapterStreams - videos.Count - 1].pid; ushort pid = audios[stream - chapterStreams - videos.Count - 1].pid;
(audioSource.Settings as BDLPCMDecoderSettings).Pid = pid; (audioSource.Settings as Codecs.MPLS.DecoderSettings).Pid = pid;
} }
} }
@@ -353,13 +354,13 @@ namespace CUETools.eac3to
Program.GetEncoder(config, fmt, true, encoderName) ?? Program.GetEncoder(config, fmt, false, encoderName); Program.GetEncoder(config, fmt, true, encoderName) ?? Program.GetEncoder(config, fmt, false, encoderName);
if (encoder == null) if (encoder == null)
{ {
var lst = new List<AudioEncoderSettingsViewModel>(config.encoders).FindAll( var lst = new List<AudioEncoderSettingsViewModel>(config.encodersViewModel).FindAll(
e => e.Extension == fmt.extension && (audioEncoderType == AudioEncoderType.NoAudio || audioEncoderType == (e.Lossless ? AudioEncoderType.Lossless : AudioEncoderType.Lossy))). e => e.Extension == fmt.extension && (audioEncoderType == AudioEncoderType.NoAudio || audioEncoderType == (e.Lossless ? AudioEncoderType.Lossless : AudioEncoderType.Lossy))).
ConvertAll(e => e.Name + (e.Lossless ? " (lossless)" : " (lossy)")); ConvertAll(e => e.Name + (e.Lossless ? " (lossless)" : " (lossy)"));
throw new Exception("Encoders available for format " + fmt.extension + ": " + (lst.Count == 0 ? "none" : string.Join(", ", lst.ToArray()))); throw new Exception("Encoders available for format " + fmt.extension + ": " + (lst.Count == 0 ? "none" : string.Join(", ", lst.ToArray())));
} }
Console.Error.WriteLine("Output {0} : {1}", stream, destFile); Console.Error.WriteLine("Output {0} : {1}", stream, destFile);
var settings = encoder.settings.Clone(); var settings = encoder.Settings.Clone();
settings.PCM = audioSource.PCM; settings.PCM = audioSource.PCM;
settings.Padding = padding; settings.Padding = padding;
settings.EncoderMode = encoderMode ?? settings.EncoderMode; settings.EncoderMode = encoderMode ?? settings.EncoderMode;

View File

@@ -133,7 +133,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUEPlayer", "..\CUEPlayer\C
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CUETools.Codecs.CoreAudio", "..\CUETools.Codecs.CoreAudio\CUETools.Codecs.CoreAudio.csproj", "{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CUETools.Codecs.CoreAudio", "..\CUETools.Codecs.CoreAudio\CUETools.Codecs.CoreAudio.csproj", "{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CUETools.Codecs.LAME", "..\CUETools.Codecs.LAME\CUETools.Codecs.LAME.csproj", "{1AF02E2C-2CB2-44B5-B417-37653071FEC6}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CUETools.Codecs.libmp3lame", "..\CUETools.Codecs.libmp3lame\CUETools.Codecs.libmp3lame.csproj", "{1AF02E2C-2CB2-44B5-B417-37653071FEC6}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.Codecs.DirectSound", "..\CUETools.Codecs.DirectSound\CUETools.Codecs.DirectSound.csproj", "{5A9FB016-6388-475D-AB33-6F86AD49FDAD}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.Codecs.DirectSound", "..\CUETools.Codecs.DirectSound\CUETools.Codecs.DirectSound.csproj", "{5A9FB016-6388-475D-AB33-6F86AD49FDAD}"
EndProject EndProject
@@ -193,8 +193,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwavpack", "..\ThirdParty
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wavpackdll", "..\ThirdParty\WavPack\wavpackdll\wavpackdll.vcxproj", "{1A87F412-BA74-4DBB-9F77-FD55C042FB63}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wavpackdll", "..\ThirdParty\WavPack\wavpackdll\wavpackdll.vcxproj", "{1A87F412-BA74-4DBB-9F77-FD55C042FB63}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ttadll", "..\ThirdParty\libtta\ttaddl.vcxproj", "{083CE608-B3E8-4E3E-871E-1144F8F751FD}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -737,16 +735,6 @@ Global
{1A87F412-BA74-4DBB-9F77-FD55C042FB63}.Release|Win32.Build.0 = Release|Win32 {1A87F412-BA74-4DBB-9F77-FD55C042FB63}.Release|Win32.Build.0 = Release|Win32
{1A87F412-BA74-4DBB-9F77-FD55C042FB63}.Release|x64.ActiveCfg = Release|x64 {1A87F412-BA74-4DBB-9F77-FD55C042FB63}.Release|x64.ActiveCfg = Release|x64
{1A87F412-BA74-4DBB-9F77-FD55C042FB63}.Release|x64.Build.0 = Release|x64 {1A87F412-BA74-4DBB-9F77-FD55C042FB63}.Release|x64.Build.0 = Release|x64
{083CE608-B3E8-4E3E-871E-1144F8F751FD}.Debug|Any CPU.ActiveCfg = Debug|Win32
{083CE608-B3E8-4E3E-871E-1144F8F751FD}.Debug|Win32.ActiveCfg = Debug|Win32
{083CE608-B3E8-4E3E-871E-1144F8F751FD}.Debug|Win32.Build.0 = Debug|Win32
{083CE608-B3E8-4E3E-871E-1144F8F751FD}.Debug|x64.ActiveCfg = Debug|x64
{083CE608-B3E8-4E3E-871E-1144F8F751FD}.Debug|x64.Build.0 = Debug|x64
{083CE608-B3E8-4E3E-871E-1144F8F751FD}.Release|Any CPU.ActiveCfg = Release|Win32
{083CE608-B3E8-4E3E-871E-1144F8F751FD}.Release|Win32.ActiveCfg = Release|Win32
{083CE608-B3E8-4E3E-871E-1144F8F751FD}.Release|Win32.Build.0 = Release|Win32
{083CE608-B3E8-4E3E-871E-1144F8F751FD}.Release|x64.ActiveCfg = Release|x64
{083CE608-B3E8-4E3E-871E-1144F8F751FD}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -806,7 +794,6 @@ Global
{4D1B3411-F4F7-4E62-B7CB-A3AC3D530443} = {93B7AE1D-DEF6-4A04-A222-5CDE09DF262D} {4D1B3411-F4F7-4E62-B7CB-A3AC3D530443} = {93B7AE1D-DEF6-4A04-A222-5CDE09DF262D}
{5CCCB9CF-0384-458F-BA08-72B73866840F} = {8B179853-B7D6-479C-B8B2-6CBCE835D040} {5CCCB9CF-0384-458F-BA08-72B73866840F} = {8B179853-B7D6-479C-B8B2-6CBCE835D040}
{1A87F412-BA74-4DBB-9F77-FD55C042FB63} = {8B179853-B7D6-479C-B8B2-6CBCE835D040} {1A87F412-BA74-4DBB-9F77-FD55C042FB63} = {8B179853-B7D6-479C-B8B2-6CBCE835D040}
{083CE608-B3E8-4E3E-871E-1144F8F751FD} = {8B179853-B7D6-479C-B8B2-6CBCE835D040}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C634D169-5814-4203-94B6-6A11371DDA95} SolutionGuid = {C634D169-5814-4203-94B6-6A11371DDA95}

View File

@@ -2348,7 +2348,7 @@ namespace JDP
} }
case AudioEncoderType.Lossless: case AudioEncoderType.Lossless:
{ {
foreach (AudioEncoderSettingsViewModel encoder in _profile._config.encoders) foreach (AudioEncoderSettingsViewModel encoder in _profile._config.Encoders)
if (encoder.Extension == SelectedOutputAudioFmt.extension) if (encoder.Extension == SelectedOutputAudioFmt.extension)
if (encoder.Lossless) if (encoder.Lossless)
comboBoxEncoder.Items.Add(encoder); comboBoxEncoder.Items.Add(encoder);
@@ -2359,7 +2359,7 @@ namespace JDP
} }
case AudioEncoderType.Lossy: case AudioEncoderType.Lossy:
{ {
foreach (AudioEncoderSettingsViewModel encoder in _profile._config.encoders) foreach (AudioEncoderSettingsViewModel encoder in _profile._config.Encoders)
if (encoder.Extension == SelectedOutputAudioFmt.extension) if (encoder.Extension == SelectedOutputAudioFmt.extension)
if (!encoder.Lossless) if (!encoder.Lossless)
comboBoxEncoder.Items.Add(encoder); comboBoxEncoder.Items.Add(encoder);
@@ -2409,8 +2409,8 @@ namespace JDP
private void resetEncoderModes(AudioEncoderSettingsViewModel encoder) private void resetEncoderModes(AudioEncoderSettingsViewModel encoder)
{ {
// TODO: something cleverer than this hack... // TODO: something cleverer than this hack...
encoder.settings.PCM = AudioPCMConfig.RedBook; encoder.Settings.PCM = AudioPCMConfig.RedBook;
buttonEncoderSettings.Visible = encoder.settings.HasBrowsableAttributes(); buttonEncoderSettings.Visible = encoder.Settings.HasBrowsableAttributes();
string[] modes = encoder.SupportedModes; string[] modes = encoder.SupportedModes;
if (modes == null || modes.Length < 2) if (modes == null || modes.Length < 2)
{ {
@@ -2424,12 +2424,12 @@ namespace JDP
if (encoder.EncoderModeIndex == -1) if (encoder.EncoderModeIndex == -1)
{ {
string defaultMode; string defaultMode;
encoder.settings.GetSupportedModes(out defaultMode); encoder.Settings.GetSupportedModes(out defaultMode);
encoder.settings.EncoderMode = defaultMode; encoder.Settings.EncoderMode = defaultMode;
} }
trackBarEncoderMode.Maximum = modes.Length - 1; trackBarEncoderMode.Maximum = modes.Length - 1;
trackBarEncoderMode.Value = encoder.EncoderModeIndex == -1 ? modes.Length - 1 : encoder.EncoderModeIndex; trackBarEncoderMode.Value = encoder.EncoderModeIndex == -1 ? modes.Length - 1 : encoder.EncoderModeIndex;
labelEncoderMode.Text = encoder.settings.EncoderMode; labelEncoderMode.Text = encoder.Settings.EncoderMode;
labelEncoderMinMode.Text = modes[0]; labelEncoderMinMode.Text = modes[0];
labelEncoderMaxMode.Text = modes[modes.Length - 1]; labelEncoderMaxMode.Text = modes[modes.Length - 1];
trackBarEncoderMode.Visible = true; trackBarEncoderMode.Visible = true;
@@ -2461,8 +2461,8 @@ namespace JDP
{ {
var encoder = comboBoxEncoder.SelectedItem as AudioEncoderSettingsViewModel; var encoder = comboBoxEncoder.SelectedItem as AudioEncoderSettingsViewModel;
string[] modes = encoder.SupportedModes; string[] modes = encoder.SupportedModes;
encoder.settings.EncoderMode = modes[trackBarEncoderMode.Value]; encoder.Settings.EncoderMode = modes[trackBarEncoderMode.Value];
labelEncoderMode.Text = encoder.settings.EncoderMode; labelEncoderMode.Text = encoder.Settings.EncoderMode;
} }
//private void toolStripButton1_Click(object sender, EventArgs e) //private void toolStripButton1_Click(object sender, EventArgs e)

View File

@@ -316,11 +316,11 @@ namespace JDP
return; return;
} }
foreach (var encoder in _config.encoders) foreach (var encoder in _config.Encoders)
if (encoder.Extension == format.extension) if (encoder.Extension == format.extension)
encoder.Extension = e.Label; encoder.Extension = e.Label;
foreach (var decoder in _config.decoders) foreach (var decoder in _config.Decoders)
if (decoder.Extension == format.extension) if (decoder.Extension == format.extension)
decoder.Extension = e.Label; decoder.Extension = e.Label;
@@ -361,17 +361,17 @@ namespace JDP
if (format.builtin) if (format.builtin)
return; return;
var decodersToRemove = new List<AudioDecoderSettingsViewModel>(); var decodersToRemove = new List<AudioDecoderSettingsViewModel>();
foreach (var decoder in _config.decoders) foreach (var decoder in _config.Decoders)
if (decoder.Extension == format.extension) if (decoder.Extension == format.extension)
decodersToRemove.Add(decoder); decodersToRemove.Add(decoder);
foreach (var decoder in decodersToRemove) foreach (var decoder in decodersToRemove)
_config.decoders.Remove(decoder); _config.Decoders.Remove(decoder);
var encodersToRemove = new List<AudioEncoderSettingsViewModel>(); var encodersToRemove = new List<AudioEncoderSettingsViewModel>();
foreach (var encoder in _config.encoders) foreach (var encoder in _config.Encoders)
if (encoder.Extension == format.extension) if (encoder.Extension == format.extension)
encodersToRemove.Add(encoder); encodersToRemove.Add(encoder);
foreach (var encoder in encodersToRemove) foreach (var encoder in encodersToRemove)
_config.encoders.Remove(encoder); _config.Encoders.Remove(encoder);
comboBoxEncoderExtension.Items.Remove(format.extension); comboBoxEncoderExtension.Items.Remove(format.extension);
comboBoxDecoderExtension.Items.Remove(format.extension); comboBoxDecoderExtension.Items.Remove(format.extension);
_config.formats.Remove(format.extension); _config.formats.Remove(format.extension);
@@ -390,21 +390,21 @@ namespace JDP
return; return;
comboFormatLosslessEncoder.Items.Clear(); comboFormatLosslessEncoder.Items.Clear();
foreach (var encoder in _config.encoders) foreach (var encoder in _config.Encoders)
if (encoder.Extension == format.extension && encoder.Lossless) if (encoder.Extension == format.extension && encoder.Lossless)
comboFormatLosslessEncoder.Items.Add(encoder); comboFormatLosslessEncoder.Items.Add(encoder);
comboFormatLosslessEncoder.SelectedItem = format.encoderLossless; comboFormatLosslessEncoder.SelectedItem = format.encoderLossless;
comboFormatLosslessEncoder.Enabled = format.allowLossless; comboFormatLosslessEncoder.Enabled = format.allowLossless;
comboFormatLossyEncoder.Items.Clear(); comboFormatLossyEncoder.Items.Clear();
foreach (var encoder in _config.encoders) foreach (var encoder in _config.Encoders)
if (encoder.Extension == format.extension && !encoder.Lossless) if (encoder.Extension == format.extension && !encoder.Lossless)
comboFormatLossyEncoder.Items.Add(encoder); comboFormatLossyEncoder.Items.Add(encoder);
comboFormatLossyEncoder.SelectedItem = format.encoderLossy; comboFormatLossyEncoder.SelectedItem = format.encoderLossy;
comboFormatLossyEncoder.Enabled = format.allowLossy; comboFormatLossyEncoder.Enabled = format.allowLossy;
comboFormatDecoder.Items.Clear(); comboFormatDecoder.Items.Clear();
foreach (var decoder in _config.decoders) foreach (var decoder in _config.Decoders)
if (decoder.Extension == format.extension) if (decoder.Extension == format.extension)
comboFormatDecoder.Items.Add(decoder); comboFormatDecoder.Items.Add(decoder);
comboFormatDecoder.SelectedItem = format.decoder; comboFormatDecoder.SelectedItem = format.decoder;
@@ -466,8 +466,8 @@ namespace JDP
comboBoxEncoderExtension.Enabled = encoder.CanBeDeleted; comboBoxEncoderExtension.Enabled = encoder.CanBeDeleted;
groupBoxExternalEncoder.Visible = encoder.CanBeDeleted; groupBoxExternalEncoder.Visible = encoder.CanBeDeleted;
checkBoxEncoderLossless.Enabled = format != null && format.allowLossless && format.allowLossy; checkBoxEncoderLossless.Enabled = format != null && format.allowLossless && format.allowLossy;
propertyGridEncoderSettings.Visible = !encoder.CanBeDeleted && encoder.settings.HasBrowsableAttributes(); propertyGridEncoderSettings.Visible = !encoder.CanBeDeleted && encoder.Settings.HasBrowsableAttributes();
propertyGridEncoderSettings.SelectedObject = encoder.CanBeDeleted ? null : encoder.settings; propertyGridEncoderSettings.SelectedObject = encoder.CanBeDeleted ? null : encoder.Settings;
if (!checkBoxEncoderLossless.Enabled && format != null && encoder.Lossless != format.allowLossless) if (!checkBoxEncoderLossless.Enabled && format != null && encoder.Lossless != format.allowLossless)
encoder.Lossless = format.allowLossless; encoder.Lossless = format.allowLossless;
foreach (KeyValuePair<string, CUEToolsFormat> fmtEntry in _config.formats) foreach (KeyValuePair<string, CUEToolsFormat> fmtEntry in _config.formats)