Cuetools.Converter.exe: support for --decoder-option parameter.

Implemented "Stream" option in BDLPCM Reader to make it possible to select
the right stream in m2ts file.
This commit is contained in:
Grigory Chudov
2018-02-10 17:33:22 -05:00
parent 0e624d610d
commit 8cedc982a6
25 changed files with 179 additions and 33 deletions

View File

@@ -59,6 +59,8 @@ namespace CUETools.Codecs.ALAC
_framesBuffer = new byte[65536];
}
public AudioDecoderSettings Settings { get { return null; } }
private void InitTables()
{
if (_predicterror_buffer_a != null)

View File

@@ -230,6 +230,12 @@ namespace CUETools { namespace Codecs { namespace APE {
return buff->Length;
}
virtual property AudioDecoderSettings^ Settings {
AudioDecoderSettings^ get(void) {
return nullptr;
}
}
private:
IAPEDecompress * pAPEDecompress;

View File

@@ -14,13 +14,15 @@ namespace CUETools.Codecs.BDLPCM
_IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000);
streams = new Dictionary<ushort, TsStream>();
frameBuffer = new byte[192];
streamId = 0;
demuxer_channel = 0;
_samplePos = 0;
_sampleLen = -1;
demux_ts_packets(null, 0);
settings = new BDLPCMReaderSettings();
}
public AudioDecoderSettings Settings { get { return settings; } }
public void Close()
{
//if (_br != null)
@@ -47,31 +49,6 @@ namespace CUETools.Codecs.BDLPCM
}
}
public unsafe int StreamId
{
get
{
return streamId;
}
set
{
streamId = value;
chosenStream = null;
foreach (var s in streams)
{
if (s.Value.is_opened && s.Value.streamId == streamId)
{
chosenStream = s.Value;
if (chosenStream.pcm == null)
{
demux_ts_packets(null, 0);
}
break;
}
}
}
}
public unsafe int StreamIds
{
get
@@ -101,13 +78,37 @@ namespace CUETools.Codecs.BDLPCM
}
}
public AudioPCMConfig PCM { get { return chosenStream.pcm; } }
public unsafe AudioPCMConfig PCM
{
get {
if (chosenStream == null)
{
if (settings.Stream != null)
{
foreach (var s in streams)
{
if (s.Value.is_opened && s.Value.streamId.ToString() == settings.Stream)
{
chosenStream = s.Value;
if (chosenStream.pcm == null)
{
demux_ts_packets(null, 0);
}
return chosenStream.pcm;
}
}
}
throw new Exception("multiple streams present, please specify");
}
return chosenStream.pcm;
}
}
public string Path { get { return _path; } }
public unsafe int Read(AudioBuffer buff, int maxLength)
{
if (chosenStream == null) throw new InvalidOperationException("chosenStream == null");
buff.Prepare(this, maxLength);
int sampleCount;
fixed (byte* dest = &buff.Bytes[0])
@@ -164,7 +165,7 @@ namespace CUETools.Codecs.BDLPCM
TsStream s;
demux_ts_packet(fr, out s);
int dataLen = (int) fr.Length;
if (dataLen > 0 && s != null)
if (dataLen > 0 && s != null && (chosenStream == null || s == chosenStream))
{
int dataOffset = (int)(fr.Ptr - ptr);
if (s.savedBufferSize > 0)
@@ -687,7 +688,7 @@ namespace CUETools.Codecs.BDLPCM
// }
//}
if (s.is_opened && streamId == s.streamId)
if (s.is_opened)
{
if (s.at_packet_header)
{
@@ -706,8 +707,8 @@ namespace CUETools.Codecs.BDLPCM
byte[] frameBuffer;
int demuxer_channel;
int streamId;
TsStream chosenStream;
long _samplePos, _sampleLen;
BDLPCMReaderSettings settings;
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
namespace CUETools.Codecs.BDLPCM
{
public class BDLPCMReaderSettings : AudioDecoderSettings
{
public BDLPCMReaderSettings()
{
}
[Browsable(false)]
public string Stream { get; set; }
}
}

View File

@@ -60,6 +60,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="BDLPCMReader.cs" />
<Compile Include="BDLPCMReaderSettings.cs" />
<Compile Include="FrameReader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TsStream.cs" />

View File

@@ -284,6 +284,12 @@ namespace CUETools { namespace Codecs { namespace FLAC {
return buff->Length;
}
virtual property AudioDecoderSettings^ Settings {
AudioDecoderSettings^ get(void) {
return nullptr;
}
}
private:
DecoderWriteDelegate^ _writeDel;
DecoderMetadataDelegate^ _metadataDel;

View File

@@ -118,6 +118,8 @@ namespace CUETools.Codecs.FLAKE
framereader = new BitReader();
}
public AudioDecoderSettings Settings { get { return null; } }
public void Close()
{
_IO.Close();

View File

@@ -10,6 +10,8 @@ namespace CUETools.Codecs.LossyWAV
private AudioBuffer lwcdfBuffer;
private double scaling_factor;
public AudioDecoderSettings Settings { get { return null; } }
public long Length
{
get

View File

@@ -187,6 +187,12 @@ namespace TTA {
return buff->Length;
}
virtual property AudioDecoderSettings^ Settings {
AudioDecoderSettings^ get(void) {
return nullptr;
}
}
private:
Int64 _sampleCount, _sampleOffset;
AudioPCMConfig^ pcm;

View File

@@ -221,6 +221,8 @@ namespace CUETools.Codecs.WMA
//m_syncReader.GetMaxOutputSampleSize(m_dwAudioOutputNum, out cbMax);
}
public AudioDecoderSettings Settings { get { return null; } }
public void isValid(string filename)
{
int pdwDataSize = 0;

View File

@@ -185,6 +185,12 @@ namespace CUETools { namespace Codecs { namespace WavPack {
return sampleBuffer->Length;
}
virtual property AudioDecoderSettings^ Settings {
AudioDecoderSettings^ get(void) {
return nullptr;
}
}
private:
WavpackContext *_wpc;
Int32 _sampleCount, _sampleOffset;

View File

@@ -0,0 +1,39 @@
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Text;
namespace CUETools.Codecs
{
public class AudioDecoderSettings
{
public AudioDecoderSettings()
{
// Iterate through each property and call ResetValue()
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this))
property.ResetValue(this);
}
public AudioDecoderSettings Clone()
{
return this.MemberwiseClone() as AudioDecoderSettings;
}
public bool HasBrowsableAttributes()
{
bool hasBrowsable = false;
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this))
{
bool isBrowsable = true;
foreach (var attribute in property.Attributes)
{
var browsable = attribute as BrowsableAttribute;
isBrowsable &= browsable == null || browsable.Browsable;
}
hasBrowsable |= isBrowsable;
}
return hasBrowsable;
}
}
}

View File

@@ -18,6 +18,8 @@ namespace CUETools.Codecs
private bool own;
private ThreadPriority priority;
public AudioDecoderSettings Settings { get { return null; } }
public long Position
{
get

View File

@@ -64,6 +64,7 @@
<ItemGroup>
<Compile Include="AudioBuffer.cs" />
<Compile Include="AudioDecoderClass.cs" />
<Compile Include="AudioDecoderSettings.cs" />
<Compile Include="AudioEncoderSettings.cs" />
<Compile Include="AudioPCMConfig.cs" />
<Compile Include="AudioPipe.cs" />

View File

@@ -72,6 +72,7 @@ namespace CUETools.Codecs
formats.Add("wv", new CUEToolsFormat("wv", CUEToolsTagger.TagLibSharp, true, false, true, true, encoders.GetDefault("wv", true), null, decoders.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("tta", new CUEToolsFormat("tta", CUEToolsTagger.APEv2, true, false, false, true, encoders.GetDefault("tta", true), null, decoders.GetDefault("tta", true)));
formats.Add("m2ts", new CUEToolsFormat("m2ts", CUEToolsTagger.APEv2, true, false, false, true, null, null, decoders.GetDefault("m2ts", true)));
formats.Add("wav", new CUEToolsFormat("wav", CUEToolsTagger.TagLibSharp, true, false, false, true, encoders.GetDefault("wav", true), null, decoders.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("tak", new CUEToolsFormat("tak", CUEToolsTagger.APEv2, true, false, true, true, encoders.GetDefault("tak", true), null, decoders.GetDefault("tak", true)));

View File

@@ -2,6 +2,8 @@
{
public interface IAudioSource
{
AudioDecoderSettings Settings { get; }
AudioPCMConfig PCM { get; }
string Path { get; }

View File

@@ -6,6 +6,8 @@
private AudioPCMConfig pcm;
private int _sampleVal;
public AudioDecoderSettings Settings { get { return null; } }
public long Length
{
get { return _sampleCount; }

View File

@@ -10,6 +10,8 @@ namespace CUETools.Codecs
Process _decoderProcess;
WAVReader rdr;
public AudioDecoderSettings Settings { get { return null; } }
public long Position
{
get

View File

@@ -14,6 +14,8 @@ namespace CUETools.Codecs
bool _largeFile;
string _path;
public AudioDecoderSettings Settings { get { return null; } }
public long Position
{
get

View File

@@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.IO;
using CUETools.Codecs;
@@ -81,6 +82,7 @@ namespace CUETools.Converter
string encoderFormat = null;
bool ignore_chunk_sizes = false;
AudioEncoderType audioEncoderType = AudioEncoderType.NoAudio;
var decoderOptions = new Dictionary<string, string>();
for (int arg = 0; arg < args.Length; arg++)
{
@@ -90,6 +92,12 @@ namespace CUETools.Converter
ignore_chunk_sizes = true;
else if (args[arg] == "--decoder" && ++arg < args.Length)
decoderName = args[arg];
else if (args[arg] == "--decoder-option" && arg + 2 < args.Length)
{
var optionName = args[++arg];
var optionValue = args[++arg];
decoderOptions.Add(optionName, optionValue);
}
else if (args[arg] == "--encoder" && ++arg < args.Length)
encoderName = args[arg];
else if (args[arg] == "--encoder-format" && ++arg < args.Length)
@@ -143,6 +151,17 @@ namespace CUETools.Converter
try
{
audioSource = Program.GetAudioSource(config, sourceFile, decoderName, ignore_chunk_sizes);
foreach (var decOpt in decoderOptions)
{
var decoderSettings = audioSource.Settings;
if (decoderSettings == null)
throw new Exception(String.Format("{0} doesn't have any properties.", audioSource.GetType().Name));
var property = TypeDescriptor.GetProperties(decoderSettings).Find(decOpt.Key, true);
if (property == null)
throw new Exception(String.Format("{0} doesn't have a property named {1}.", audioSource.GetType().Name, decOpt.Key));
property.SetValue(decoderSettings, decOpt.Value);
}
AudioBuffer buff = new AudioBuffer(audioSource, 0x10000);
Console.Error.WriteLine("Filename : {0}", sourceFile);
Console.Error.WriteLine("File Info : {0}kHz; {1} channel; {2} bit; {3}", audioSource.PCM.SampleRate, audioSource.PCM.ChannelCount, audioSource.PCM.BitsPerSample, TimeSpan.FromSeconds(audioSource.Length * 1.0 / audioSource.PCM.SampleRate));

View File

@@ -17,6 +17,8 @@ namespace CUETools.DSP.Mixer
private int mixoffs = 0;
private int current = 0;
public AudioDecoderSettings Settings { get { return null; } }
public void Close()
{
}

View File

@@ -11,6 +11,8 @@ namespace CUETools.Processor
private long nextPos;
private long _samplePos, _sampleLen;
public AudioDecoderSettings Settings { get { return null; } }
public long Length
{
get { return _sampleLen; }

View File

@@ -77,6 +77,8 @@ namespace CUETools.Ripper.SCSI
private ReadProgressArgs progressArgs = new ReadProgressArgs();
public event EventHandler<ReadProgressArgs> ReadProgress;
public AudioDecoderSettings Settings { get { return null; } }
public CDImageLayout TOC
{
get

View File

@@ -49,6 +49,8 @@ namespace CUETools.TestHelpers
this.nextError = 0;
}
public AudioDecoderSettings Settings { get { return null; } }
public NoiseAndErrorsGenerator(long sampleCount)
: this(AudioPCMConfig.RedBook, sampleCount, 0, 0, 0)
{

View File

@@ -180,6 +180,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsMediaLib", "..\Windo
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.Codecs.WMA", "..\CUETools.Codecs.WMA\CUETools.Codecs.WMA.csproj", "{082D6B9E-326E-4D15-9798-DE70A6EDAE9E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.Codecs.BDLPCM", "..\CUETools.Codecs.BDLPCM\CUETools.Codecs.BDLPCM.csproj", "{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}"
EndProject
Global
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = CUETools1.vsmdi
@@ -1075,6 +1077,20 @@ Global
{082D6B9E-326E-4D15-9798-DE70A6EDAE9E}.Release|Win32.ActiveCfg = Release|Any CPU
{082D6B9E-326E-4D15-9798-DE70A6EDAE9E}.Release|x64.ActiveCfg = Release|Any CPU
{082D6B9E-326E-4D15-9798-DE70A6EDAE9E}.Release|x86.ActiveCfg = Release|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Debug|Win32.ActiveCfg = Debug|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Debug|x64.ActiveCfg = Debug|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Debug|x86.ActiveCfg = Debug|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Release|Any CPU.Build.0 = Release|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Release|Win32.ActiveCfg = Release|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Release|x64.ActiveCfg = Release|Any CPU
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1111,6 +1127,7 @@ Global
{1AF02E2C-2CB2-44B5-B417-37653071FEC6} = {93B7AE1D-DEF6-4A04-A222-5CDE09DF262D}
{DFE55765-564C-4B8F-993B-A94C4D1C212E} = {93B7AE1D-DEF6-4A04-A222-5CDE09DF262D}
{082D6B9E-326E-4D15-9798-DE70A6EDAE9E} = {93B7AE1D-DEF6-4A04-A222-5CDE09DF262D}
{E75F7CCD-4266-42E1-A039-DC7EB5EDD8F6} = {93B7AE1D-DEF6-4A04-A222-5CDE09DF262D}
{04945FB2-8410-4F14-8262-2ED18DCDACD6} = {D9D97BB6-002F-4858-8EF2-49B4C4C4DDB4}
{A430AD28-B76A-4ED0-AF7D-D13B8969297F} = {D9D97BB6-002F-4858-8EF2-49B4C4C4DDB4}
{5C8B61C0-BC3D-4316-B8A7-419D55BB5796} = {D9D97BB6-002F-4858-8EF2-49B4C4C4DDB4}