mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
Merge branch 'master' of https://github.com/gchudov/cuetools.net
This commit is contained in:
@@ -165,7 +165,9 @@ namespace CUETools.Codecs.ALAC
|
||||
_IO.Close();
|
||||
}
|
||||
|
||||
public long Length
|
||||
public TimeSpan Duration => Length < 0 ? TimeSpan.Zero : TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -127,7 +127,9 @@ namespace CUETools.Codecs.Flake
|
||||
_IO.Close();
|
||||
}
|
||||
|
||||
public long Length
|
||||
public TimeSpan Duration => Length < 0 ? TimeSpan.Zero : TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -12,13 +12,9 @@ namespace CUETools.Codecs.LossyWAV
|
||||
|
||||
public IAudioDecoderSettings Settings => null;
|
||||
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return _audioSource.Length;
|
||||
}
|
||||
}
|
||||
public TimeSpan Duration => _audioSource.Duration;
|
||||
|
||||
public long Length => _audioSource.Length;
|
||||
|
||||
public long Position
|
||||
{
|
||||
@@ -33,29 +29,11 @@ namespace CUETools.Codecs.LossyWAV
|
||||
}
|
||||
}
|
||||
|
||||
public long Remaining
|
||||
{
|
||||
get
|
||||
{
|
||||
return _audioSource.Remaining;
|
||||
}
|
||||
}
|
||||
public long Remaining => _audioSource.Remaining;
|
||||
|
||||
public AudioPCMConfig PCM
|
||||
{
|
||||
get
|
||||
{
|
||||
return _audioSource.PCM;
|
||||
}
|
||||
}
|
||||
public AudioPCMConfig PCM => _audioSource.PCM;
|
||||
|
||||
public string Path
|
||||
{
|
||||
get
|
||||
{
|
||||
return _audioSource.Path;
|
||||
}
|
||||
}
|
||||
public string Path => _audioSource.Path;
|
||||
|
||||
public LossyWAVReader(IAudioSource audioSource, IAudioSource lwcdfSource)
|
||||
{
|
||||
|
||||
@@ -74,6 +74,8 @@ namespace CUETools.Codecs.MACLib
|
||||
|
||||
public string Path => _path;
|
||||
|
||||
public TimeSpan Duration => Length < 0 ? TimeSpan.Zero : TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length => _sampleCount;
|
||||
|
||||
internal long SamplesInBuffer => _bufferLength - _bufferOffset;
|
||||
|
||||
1043
CUETools.Codecs.MPEG/ATSI/AudioDecoder.cs
Normal file
1043
CUETools.Codecs.MPEG/ATSI/AudioDecoder.cs
Normal file
File diff suppressed because it is too large
Load Diff
48
CUETools.Codecs.MPEG/ATSI/DecoderSettings.cs
Normal file
48
CUETools.Codecs.MPEG/ATSI/DecoderSettings.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace CUETools.Codecs.MPEG.ATSI
|
||||
{
|
||||
[JsonObject(MemberSerialization.OptIn)]
|
||||
public class DecoderSettings : IAudioDecoderSettings
|
||||
{
|
||||
#region IAudioDecoderSettings implementation
|
||||
[Browsable(false)]
|
||||
public string Extension => "ifo";
|
||||
|
||||
[Browsable(false)]
|
||||
public string Name => "cuetools";
|
||||
|
||||
[Browsable(false)]
|
||||
public Type DecoderType => typeof(AudioDecoder);
|
||||
|
||||
[Browsable(false)]
|
||||
public int Priority => 2;
|
||||
|
||||
public IAudioDecoderSettings Clone()
|
||||
{
|
||||
return MemberwiseClone() as IAudioDecoderSettings;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public DecoderSettings()
|
||||
{
|
||||
this.Init();
|
||||
}
|
||||
|
||||
[DefaultValue(true)]
|
||||
public bool IgnoreShortItems { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public int? Stream { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public int? StreamId { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public int? Title { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,6 @@ namespace CUETools.Codecs.MPEG.BDLPCM
|
||||
{
|
||||
public class AudioDecoder : IAudioSource
|
||||
{
|
||||
public unsafe AudioDecoder(string path, Stream IO, int pid)
|
||||
: this(new DecoderSettings() { StreamId = pid }, path, IO)
|
||||
{
|
||||
}
|
||||
|
||||
public unsafe AudioDecoder(DecoderSettings settings, string path, Stream IO)
|
||||
{
|
||||
_path = path;
|
||||
@@ -38,6 +33,8 @@ namespace CUETools.Codecs.MPEG.BDLPCM
|
||||
_IO = null;
|
||||
}
|
||||
|
||||
public TimeSpan Duration => Length < 0 ? TimeSpan.Zero : TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
|
||||
@@ -5,19 +5,15 @@ using System.IO;
|
||||
|
||||
namespace CUETools.Codecs.MPEG.MPLS
|
||||
{
|
||||
public class AudioDecoder : IAudioSource
|
||||
public class AudioDecoder : IAudioSource, IAudioTitleSet
|
||||
{
|
||||
public unsafe AudioDecoder(string path, Stream IO, ushort pid)
|
||||
: this(new DecoderSettings() { StreamId = pid }, path, IO)
|
||||
{
|
||||
}
|
||||
|
||||
public unsafe AudioDecoder(DecoderSettings settings, string path, Stream IO)
|
||||
{
|
||||
m_settings = settings;
|
||||
_path = path;
|
||||
_IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000);
|
||||
int length = (int)_IO.Length;
|
||||
if (length > 0x100000) throw new Exception("File too big");
|
||||
contents = new byte[length];
|
||||
if (_IO.Read(contents, 0, length) != length) throw new Exception("");
|
||||
fixed (byte* ptr = &contents[0])
|
||||
@@ -33,7 +29,7 @@ namespace CUETools.Codecs.MPEG.MPLS
|
||||
|
||||
void openEntries()
|
||||
{
|
||||
readers = new List<BDLPCM.AudioDecoder>();
|
||||
readers = new List<IAudioSource>();
|
||||
var pids = new List<int>();
|
||||
foreach (var item in hdr_m.play_item)
|
||||
foreach (var audio in item.audio)
|
||||
@@ -67,7 +63,8 @@ namespace CUETools.Codecs.MPEG.MPLS
|
||||
var m2ts = System.IO.Path.Combine(
|
||||
System.IO.Path.Combine(parent.FullName, "STREAM"),
|
||||
item.clip_id + ".m2ts");
|
||||
var entry = new BDLPCM.AudioDecoder(m2ts, null, chosenPid);
|
||||
var settings = new BDLPCM.DecoderSettings() { StreamId = chosenPid };
|
||||
var entry = settings.Open(m2ts);
|
||||
readers.Add(entry);
|
||||
break;
|
||||
}
|
||||
@@ -387,15 +384,30 @@ namespace CUETools.Codecs.MPEG.MPLS
|
||||
}
|
||||
}
|
||||
|
||||
public List<uint> Chapters
|
||||
public List<IAudioTitle> AudioTitles
|
||||
{
|
||||
get
|
||||
{
|
||||
var titles = new List<IAudioTitle>();
|
||||
foreach (var item in hdr_m.play_item)
|
||||
foreach (var audio in item.audio)
|
||||
{
|
||||
//if (audio.coding_type != 0x80 /* LPCM */) continue;
|
||||
titles.Add(new AudioTitle(this, audio.pid));
|
||||
}
|
||||
return titles;
|
||||
}
|
||||
}
|
||||
|
||||
public List<TimeSpan> Chapters
|
||||
{
|
||||
get
|
||||
{
|
||||
//settings.IgnoreShortItems
|
||||
var res = new List<uint>();
|
||||
var res = new List<TimeSpan>();
|
||||
if (hdr_m.play_mark.Count < 1) return res;
|
||||
if (hdr_m.play_item.Count < 1) return res;
|
||||
res.Add(0);
|
||||
res.Add(TimeSpan.Zero);
|
||||
for (int i = 0; i < hdr_m.mark_count; i++)
|
||||
{
|
||||
ushort mark_item = hdr_m.play_mark[i].play_item_ref;
|
||||
@@ -410,7 +422,7 @@ namespace CUETools.Codecs.MPEG.MPLS
|
||||
if (m_settings.IgnoreShortItems && item_duration < shortItemDuration) continue;
|
||||
item_offset += item_duration;
|
||||
}
|
||||
res.Add(hdr_m.play_mark[i].time - item_in_time + item_offset);
|
||||
res.Add(TimeSpan.FromSeconds((hdr_m.play_mark[i].time - item_in_time + item_offset) / 45000.0));
|
||||
}
|
||||
uint end_offset = 0;
|
||||
for (int j = 0; j < hdr_m.play_item.Count; j++)
|
||||
@@ -420,9 +432,9 @@ namespace CUETools.Codecs.MPEG.MPLS
|
||||
if (m_settings.IgnoreShortItems && item_duration < shortItemDuration) continue;
|
||||
end_offset += hdr_m.play_item[j].out_time - hdr_m.play_item[j].in_time;
|
||||
}
|
||||
res.Add(end_offset);
|
||||
while (res.Count > 1 && res[1] - res[0] < 45000) res.RemoveAt(1);
|
||||
while (res.Count > 1 && res[res.Count - 1] - res[res.Count - 2] < 45000) res.RemoveAt(res.Count - 2);
|
||||
res.Add(TimeSpan.FromSeconds(end_offset / 45000.0));
|
||||
while (res.Count > 1 && res[1] - res[0] < TimeSpan.FromSeconds(1.0)) res.RemoveAt(1);
|
||||
while (res.Count > 1 && res[res.Count - 1] - res[res.Count - 2] < TimeSpan.FromSeconds(1.0)) res.RemoveAt(res.Count - 2);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -434,12 +446,64 @@ namespace CUETools.Codecs.MPEG.MPLS
|
||||
byte[] contents;
|
||||
|
||||
AudioPCMConfig pcm;
|
||||
List<BDLPCM.AudioDecoder> readers;
|
||||
BDLPCM.AudioDecoder currentReader;
|
||||
List<IAudioSource> readers;
|
||||
IAudioSource currentReader;
|
||||
MPLSHeader hdr_m;
|
||||
DecoderSettings m_settings;
|
||||
}
|
||||
|
||||
public class AudioTitle : IAudioTitle
|
||||
{
|
||||
public AudioTitle(AudioDecoder source, int pid)
|
||||
{
|
||||
this.source = source;
|
||||
this.pid = pid;
|
||||
}
|
||||
|
||||
public List<TimeSpan> Chapters => source.Chapters;
|
||||
public AudioPCMConfig PCM
|
||||
{
|
||||
get
|
||||
{
|
||||
var s = FirstStream;
|
||||
int channelCount = s.format == 1 ? 1 : s.format == 3 ? 2 : s.format == 6 ? 5 : 0;
|
||||
int sampleRate = s.rate == 1 ? 48000 : s.rate == 4 ? 96000 : s.rate == 5 ? 192000 : s.rate == 12 ? 192000 : s.rate == 14 ? 96000 : 0;
|
||||
int bitsPerSample = 0;
|
||||
return new AudioPCMConfig(bitsPerSample, channelCount, sampleRate);
|
||||
}
|
||||
}
|
||||
public string Codec
|
||||
{
|
||||
get
|
||||
{
|
||||
var s = FirstStream;
|
||||
return s != null ? s.CodecString : "?";
|
||||
}
|
||||
}
|
||||
public string Language
|
||||
{
|
||||
get
|
||||
{
|
||||
var s = FirstStream;
|
||||
return s != null ? s.LanguageString : "?";
|
||||
}
|
||||
}
|
||||
public int StreamId => pid;
|
||||
|
||||
MPLSStream FirstStream
|
||||
{
|
||||
get
|
||||
{
|
||||
MPLSStream result = null;
|
||||
source.MPLSHeader.play_item.ForEach(i => i.audio.FindAll(a => a.pid == pid).ForEach(x => result = x));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
AudioDecoder source;
|
||||
int pid;
|
||||
}
|
||||
|
||||
public struct MPLSPlaylistMark
|
||||
{
|
||||
public byte mark_id;
|
||||
@@ -450,7 +514,7 @@ namespace CUETools.Codecs.MPEG.MPLS
|
||||
public uint duration;
|
||||
}
|
||||
|
||||
public struct MPLSStream
|
||||
public class MPLSStream
|
||||
{
|
||||
public byte stream_type;
|
||||
public byte coding_type;
|
||||
|
||||
@@ -127,6 +127,11 @@ namespace TTA {
|
||||
}
|
||||
}
|
||||
|
||||
virtual property TimeSpan Duration {
|
||||
TimeSpan get() {
|
||||
return Length < 0 ? TimeSpan::Zero : TimeSpan::FromSeconds((double)Length / PCM->SampleRate);
|
||||
}
|
||||
}
|
||||
virtual property Int64 Length {
|
||||
Int64 get() {
|
||||
return _sampleCount;
|
||||
|
||||
@@ -252,6 +252,8 @@ namespace CUETools.Codecs.WMA
|
||||
m_syncReader = null;
|
||||
}
|
||||
|
||||
public TimeSpan Duration => Length < 0 ? TimeSpan.Zero : TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
|
||||
@@ -191,7 +191,7 @@ namespace CUETools.Codecs.ffmpegdll
|
||||
//if (stream->duration > 0)
|
||||
// _sampleCount = stream->duration;
|
||||
//else
|
||||
_sampleCount = -1;
|
||||
_sampleCount = -1;
|
||||
|
||||
int bps = stream->codecpar->bits_per_raw_sample != 0 ?
|
||||
stream->codecpar->bits_per_raw_sample :
|
||||
@@ -279,6 +279,21 @@ namespace CUETools.Codecs.ffmpegdll
|
||||
|
||||
public string Path => _path;
|
||||
|
||||
public TimeSpan Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
// Sadly, duration is unreliable for most codecs.
|
||||
if (stream->codecpar->codec_id == AVCodecID.AV_CODEC_ID_MLP)
|
||||
return TimeSpan.Zero;
|
||||
if (stream->duration > 0)
|
||||
return TimeSpan.FromSeconds((double)stream->duration / stream->codecpar->sample_rate);
|
||||
if (fmt_ctx->duration > 0)
|
||||
return TimeSpan.FromSeconds((double)fmt_ctx->duration / ffmpeg.AV_TIME_BASE);
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public long Length => _sampleCount;
|
||||
|
||||
public long Position
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace CUETools.Codecs.ffmpegdll
|
||||
#region IAudioDecoderSettings implementation
|
||||
|
||||
[Browsable(false)]
|
||||
public string Name => "ffmpeg";
|
||||
public string Name => "ffmpeg.dll";
|
||||
|
||||
[Browsable(false)]
|
||||
public Type DecoderType => typeof(AudioDecoder);
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace CUETools.Codecs.libFLAC
|
||||
public string Name => "libFLAC";
|
||||
|
||||
[Browsable(false)]
|
||||
public Type DecoderType => typeof(Reader);
|
||||
public Type DecoderType => typeof(AudioDecoder);
|
||||
|
||||
[Browsable(false)]
|
||||
public int Priority => 1;
|
||||
@@ -37,9 +37,9 @@ namespace CUETools.Codecs.libFLAC
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe class Reader : IAudioSource
|
||||
public unsafe class AudioDecoder : IAudioSource
|
||||
{
|
||||
public Reader(DecoderSettings settings, string path, Stream IO)
|
||||
public AudioDecoder(DecoderSettings settings, string path, Stream IO)
|
||||
{
|
||||
m_settings = settings;
|
||||
|
||||
@@ -306,6 +306,8 @@ namespace CUETools.Codecs.libFLAC
|
||||
|
||||
public string Path => m_path;
|
||||
|
||||
public TimeSpan Duration => Length < 0 ? TimeSpan.Zero : TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length => m_sampleCount;
|
||||
|
||||
private int SamplesInBuffer => m_bufferLength - m_bufferOffset;
|
||||
|
||||
@@ -99,6 +99,8 @@ namespace CUETools.Codecs.libwavpack
|
||||
|
||||
public string Path => _path;
|
||||
|
||||
public TimeSpan Duration => Length < 0 ? TimeSpan.Zero : TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length => _sampleCount;
|
||||
|
||||
public long Position
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
|
||||
namespace CUETools.Codecs
|
||||
{
|
||||
@@ -44,5 +45,10 @@ namespace CUETools.Codecs
|
||||
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(settings))
|
||||
property.ResetValue(settings);
|
||||
}
|
||||
|
||||
public static IAudioSource Open(this IAudioDecoderSettings settings, string path, Stream IO = null)
|
||||
{
|
||||
return Activator.CreateInstance(settings.DecoderType, settings, path, IO) as IAudioSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,51 @@
|
||||
KSAUDIO_SPEAKER_5POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT),
|
||||
KSAUDIO_SPEAKER_5POINT1_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT),
|
||||
KSAUDIO_SPEAKER_7POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER),
|
||||
KSAUDIO_SPEAKER_7POINT1_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT)
|
||||
KSAUDIO_SPEAKER_7POINT1_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT),
|
||||
|
||||
DVDAUDIO_GR1_0 = SPEAKER_FRONT_CENTER,
|
||||
DVDAUDIO_GR1_1 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
|
||||
DVDAUDIO_GR1_2 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
|
||||
DVDAUDIO_GR1_3 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
|
||||
DVDAUDIO_GR1_4 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
|
||||
DVDAUDIO_GR1_5 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
|
||||
DVDAUDIO_GR1_6 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
|
||||
DVDAUDIO_GR1_7 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
|
||||
DVDAUDIO_GR1_8 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
|
||||
DVDAUDIO_GR1_9 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
|
||||
DVDAUDIO_GR1_10 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
|
||||
DVDAUDIO_GR1_11 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
|
||||
DVDAUDIO_GR1_12 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
|
||||
DVDAUDIO_GR1_13 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER,
|
||||
DVDAUDIO_GR1_14 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER,
|
||||
DVDAUDIO_GR1_15 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER,
|
||||
DVDAUDIO_GR1_16 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER,
|
||||
DVDAUDIO_GR1_17 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER,
|
||||
DVDAUDIO_GR1_18 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
|
||||
DVDAUDIO_GR1_19 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
|
||||
DVDAUDIO_GR1_20 = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
|
||||
|
||||
DVDAUDIO_GR2_0 = 0,
|
||||
DVDAUDIO_GR2_1 = 0,
|
||||
DVDAUDIO_GR2_2 = SPEAKER_BACK_CENTER,
|
||||
DVDAUDIO_GR2_3 = SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
|
||||
DVDAUDIO_GR2_4 = SPEAKER_LOW_FREQUENCY,
|
||||
DVDAUDIO_GR2_5 = SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_CENTER,
|
||||
DVDAUDIO_GR2_6 = SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
|
||||
DVDAUDIO_GR2_7 = SPEAKER_FRONT_CENTER,
|
||||
DVDAUDIO_GR2_8 = SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER,
|
||||
DVDAUDIO_GR2_9 = SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
|
||||
DVDAUDIO_GR2_10 = SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY,
|
||||
DVDAUDIO_GR2_11 = SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_CENTER,
|
||||
DVDAUDIO_GR2_12 = SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
|
||||
DVDAUDIO_GR2_13 = SPEAKER_BACK_CENTER,
|
||||
DVDAUDIO_GR2_14 = SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
|
||||
DVDAUDIO_GR2_15 = SPEAKER_LOW_FREQUENCY,
|
||||
DVDAUDIO_GR2_16 = SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_CENTER,
|
||||
DVDAUDIO_GR2_17 = SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
|
||||
DVDAUDIO_GR2_18 = SPEAKER_LOW_FREQUENCY,
|
||||
DVDAUDIO_GR2_19 = SPEAKER_FRONT_CENTER,
|
||||
DVDAUDIO_GR2_20 = SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY,
|
||||
}
|
||||
|
||||
private int _bitsPerSample;
|
||||
@@ -46,6 +90,17 @@
|
||||
public int BlockAlign { get { return _channelCount * ((_bitsPerSample + 7) / 8); } }
|
||||
public SpeakerConfig ChannelMask { get { return _channelMask; } }
|
||||
public bool IsRedBook { get { return _bitsPerSample == 16 && _channelCount == 2 && _sampleRate == 44100; } }
|
||||
public static int ChannelsInMask(SpeakerConfig mask)
|
||||
{
|
||||
int count = 0;
|
||||
while (mask != 0)
|
||||
{
|
||||
count++;
|
||||
mask &= (mask - 1);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static SpeakerConfig GetDefaultChannelMask(int channelCount)
|
||||
{
|
||||
switch (channelCount)
|
||||
|
||||
@@ -54,6 +54,8 @@ namespace CUETools.Codecs
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan Duration => Length < 0 ? TimeSpan.Zero : TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
|
||||
@@ -52,18 +52,18 @@ namespace CUETools.Codecs
|
||||
|
||||
if (Type.GetType("Mono.Runtime", false) == null)
|
||||
{
|
||||
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 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 CommandLine.EncoderSettings("ffmpeg alac", "m4a", true, "", "", "ffmpeg.exe", "-i - -f ipod -acodec alac -y %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 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 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 CommandLine.EncoderSettings("opusenc", "opus", false, "6 16 32 48 64 96 128 192 256", "128", "opusenc.exe", "--bitrate %M - %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 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"));
|
||||
encoders.Add(new CommandLine.EncoderSettings("flake.exe", "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("takc.exe", "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("ffmpeg.exe", "m4a", true, "", "", "ffmpeg.exe", "-i - -f ipod -acodec alac -y %O"));
|
||||
encoders.Add(new CommandLine.EncoderSettings("lame.exe (VBR)", "mp3", false, "V9 V8 V7 V6 V5 V4 V3 V2 V1 V0", "V2", "lame.exe", "--vbr-new -%M - %O"));
|
||||
encoders.Add(new CommandLine.EncoderSettings("lame.exe (CBR)", "mp3", false, "96 128 192 256 320", "256", "lame.exe", "-m s -q 0 -b %M --noreplaygain - %O"));
|
||||
encoders.Add(new CommandLine.EncoderSettings("oggenc.exe", "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("opusenc.exe", "opus", false, "6 16 32 48 64 96 128 192 256", "128", "opusenc.exe", "--bitrate %M - %O"));
|
||||
encoders.Add(new CommandLine.EncoderSettings("neroAacEnc.exe", "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("qaac.exe (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 CommandLine.DecoderSettings("takc", "tak", "takc.exe", "-d %I -"));
|
||||
decoders.Add(new CommandLine.DecoderSettings("ffmpeg alac", "m4a", "ffmpeg.exe", "-v 0 -i %I -f wav -"));
|
||||
decoders.Add(new CommandLine.DecoderSettings("takc.exe", "tak", "takc.exe", "-d %I -"));
|
||||
decoders.Add(new CommandLine.DecoderSettings("ffmpeg.exe", "m4a", "ffmpeg.exe", "-v 0 -i %I -f wav -"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -27,6 +27,15 @@ namespace CUETools.Codecs.CommandLine
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
Initialize();
|
||||
return rdr.Duration;
|
||||
}
|
||||
}
|
||||
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
namespace CUETools.Codecs
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CUETools.Codecs
|
||||
{
|
||||
public interface IAudioSource
|
||||
{
|
||||
@@ -7,11 +10,73 @@
|
||||
AudioPCMConfig PCM { get; }
|
||||
string Path { get; }
|
||||
|
||||
long Length { get; }
|
||||
TimeSpan Duration { get; }
|
||||
long Length { get; }
|
||||
long Position { get; set; }
|
||||
long Remaining { get; }
|
||||
|
||||
int Read(AudioBuffer buffer, int maxLength);
|
||||
void Close();
|
||||
}
|
||||
|
||||
public interface IAudioTitle
|
||||
{
|
||||
List<TimeSpan> Chapters { get; }
|
||||
AudioPCMConfig PCM { get; }
|
||||
string Codec { get; }
|
||||
string Language { get; }
|
||||
int StreamId { get; }
|
||||
//IAudioSource Open { get; }
|
||||
}
|
||||
|
||||
public interface IAudioTitleSet
|
||||
{
|
||||
List<IAudioTitle> AudioTitles { get; }
|
||||
}
|
||||
|
||||
public static class IAudioTitleExtensions
|
||||
{
|
||||
public static TimeSpan GetDuration(this IAudioTitle title)
|
||||
{
|
||||
var chapters = title.Chapters;
|
||||
return chapters[chapters.Count - 1];
|
||||
}
|
||||
|
||||
|
||||
public static string GetRateString(this IAudioTitle title)
|
||||
{
|
||||
var sr = title.PCM.SampleRate;
|
||||
if (sr % 1000 == 0) return $"{sr / 1000}KHz";
|
||||
if (sr % 100 == 0) return $"{sr / 100}.{(sr / 100) % 10}KHz";
|
||||
return $"{sr}Hz";
|
||||
}
|
||||
|
||||
public static string GetFormatString(this IAudioTitle title)
|
||||
{
|
||||
switch (title.PCM.ChannelCount)
|
||||
{
|
||||
case 1: return "mono";
|
||||
case 2: return "stereo";
|
||||
default: return "multi-channel";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SingleAudioTitle : IAudioTitle
|
||||
{
|
||||
public SingleAudioTitle(IAudioSource source) { this.source = source; }
|
||||
public List<TimeSpan> Chapters => new List<TimeSpan> { TimeSpan.Zero, source.Duration };
|
||||
public AudioPCMConfig PCM => source.PCM;
|
||||
public string Codec => source.Settings.Extension;
|
||||
public string Language => "";
|
||||
public int StreamId => 0;
|
||||
IAudioSource source;
|
||||
}
|
||||
|
||||
public class SingleAudioTitleSet : IAudioTitleSet
|
||||
{
|
||||
public SingleAudioTitleSet(IAudioSource source) { this.source = source; }
|
||||
public List<IAudioTitle> AudioTitles => new List<IAudioTitle> { new SingleAudioTitle(source) };
|
||||
IAudioSource source;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace CUETools.Codecs.NULL
|
||||
using System;
|
||||
|
||||
namespace CUETools.Codecs.NULL
|
||||
{
|
||||
public class AudioDecoder : IAudioSource
|
||||
{
|
||||
@@ -8,6 +10,8 @@
|
||||
|
||||
public IAudioDecoderSettings Settings => null;
|
||||
|
||||
public TimeSpan Duration => TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length
|
||||
{
|
||||
get { return _sampleCount; }
|
||||
|
||||
@@ -55,6 +55,8 @@ namespace CUETools.Codecs.WAV
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan Duration => Length < 0 ? TimeSpan.Zero : TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace CUETools.Converter
|
||||
|
||||
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));
|
||||
Console.Error.WriteLine("File Info : {0}kHz; {1} channel; {2} bit; {3}", audioSource.PCM.SampleRate, audioSource.PCM.ChannelCount, audioSource.PCM.BitsPerSample, audioSource.Duration);
|
||||
|
||||
CUEToolsFormat fmt;
|
||||
if (encoderFormat == null)
|
||||
@@ -226,15 +226,16 @@ namespace CUETools.Converter
|
||||
TimeSpan elapsed = DateTime.Now - start;
|
||||
if ((elapsed - lastPrint).TotalMilliseconds > 60)
|
||||
{
|
||||
long length = audioSource.Length;
|
||||
if (length < 0 && sourceInfo != null) length = (long)(sourceInfo.Properties.Duration.TotalMilliseconds * audioSource.PCM.SampleRate / 1000);
|
||||
if (length < audioSource.Position) length = audioSource.Position;
|
||||
if (length < 1) length = 1;
|
||||
var duration = audioSource.Duration;
|
||||
var position = TimeSpan.FromSeconds((double)audioSource.Position / audioSource.PCM.SampleRate);
|
||||
if (duration == TimeSpan.Zero && sourceInfo != null) duration = sourceInfo.Properties.Duration;
|
||||
if (duration < position) duration = position;
|
||||
if (duration < TimeSpan.FromSeconds(1)) duration = TimeSpan.FromSeconds(1);
|
||||
Console.Error.Write("\rProgress : {0:00}%; {1:0.00}x; {2}/{3}",
|
||||
100.0 * audioSource.Position / length,
|
||||
audioSource.Position / elapsed.TotalSeconds / audioSource.PCM.SampleRate,
|
||||
100.0 * position.TotalSeconds / duration.TotalSeconds,
|
||||
position.TotalSeconds / elapsed.TotalSeconds,
|
||||
elapsed,
|
||||
TimeSpan.FromMilliseconds(elapsed.TotalMilliseconds / audioSource.Position * length)
|
||||
TimeSpan.FromSeconds(elapsed.TotalSeconds / position.TotalSeconds * duration.TotalSeconds)
|
||||
);
|
||||
lastPrint = elapsed;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,11 @@ namespace CUETools.DSP.Mixer
|
||||
set { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
public TimeSpan Duration
|
||||
{
|
||||
get { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
public long Length
|
||||
{
|
||||
get { throw new NotSupportedException(); }
|
||||
|
||||
@@ -13,6 +13,8 @@ namespace CUETools.Processor
|
||||
|
||||
public IAudioDecoderSettings Settings => null;
|
||||
|
||||
public TimeSpan Duration => Length < 0 ? TimeSpan.Zero : TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length
|
||||
{
|
||||
get { return _sampleLen; }
|
||||
|
||||
@@ -1149,7 +1149,9 @@ namespace CUETools.Ripper.SCSI
|
||||
return buff.Length;
|
||||
}
|
||||
|
||||
public long Length
|
||||
public TimeSpan Duration => TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -56,7 +56,9 @@ namespace CUETools.TestHelpers
|
||||
{
|
||||
}
|
||||
|
||||
public long Length
|
||||
public TimeSpan Duration => Length < 0 ? TimeSpan.Zero : TimeSpan.FromSeconds((double)Length / PCM.SampleRate);
|
||||
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ using CUETools.CTDB;
|
||||
using CUETools.Processor;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
@@ -49,6 +50,7 @@ namespace CUETools.eac3to
|
||||
string encoderName = null;
|
||||
string encoderFormat = null;
|
||||
AudioEncoderType audioEncoderType = AudioEncoderType.NoAudio;
|
||||
var decoderOptions = new Dictionary<string, string>();
|
||||
bool queryMeta = false;
|
||||
|
||||
for (int arg = 0; arg < args.Length; arg++)
|
||||
@@ -61,14 +63,20 @@ namespace CUETools.eac3to
|
||||
encoderFormat = args[arg];
|
||||
else if ((args[arg] == "-p" || args[arg] == "--padding") && ++arg < args.Length)
|
||||
ok = int.TryParse(args[arg], out padding);
|
||||
else if ((args[arg] == "-m" || args[arg] == "--mode") && ++arg < args.Length)
|
||||
encoderMode = args[arg];
|
||||
else if ((args[arg] == "-m" || args[arg] == "--mode") && arg + 1 < args.Length)
|
||||
encoderMode = args[++arg];
|
||||
else if (args[arg] == "--lossy")
|
||||
audioEncoderType = AudioEncoderType.Lossy;
|
||||
else if (args[arg] == "--lossless")
|
||||
audioEncoderType = AudioEncoderType.Lossless;
|
||||
else if (args[arg] == "--ctdb")
|
||||
queryMeta = true;
|
||||
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][0] != '-' || args[arg] == "-") && sourceFile == null)
|
||||
sourceFile = args[arg];
|
||||
else if ((args[arg][0] != '-' || args[arg] == "-") && sourceFile != null && destFile == null)
|
||||
@@ -122,11 +130,11 @@ namespace CUETools.eac3to
|
||||
#endif
|
||||
{
|
||||
IAudioSource audioSource = null;
|
||||
IAudioTitleSet audioContainer = null;
|
||||
IAudioDest audioDest = null;
|
||||
var videos = new List<Codecs.MPEG.MPLS.MPLSStream>();
|
||||
var audios = new List<Codecs.MPEG.MPLS.MPLSStream>();
|
||||
List<uint> chapters;
|
||||
TimeSpan duration;
|
||||
List<IAudioTitle> audios = null;
|
||||
List<TimeSpan> chapters = null;
|
||||
TagLib.UserDefined.AdditionalFileTypes.Config = config;
|
||||
|
||||
#if !DEBUG
|
||||
@@ -135,19 +143,43 @@ namespace CUETools.eac3to
|
||||
{
|
||||
if (true)
|
||||
{
|
||||
var mpls = new Codecs.MPEG.MPLS.AudioDecoder(new Codecs.MPEG.MPLS.DecoderSettings(), sourceFile, null);
|
||||
audioSource = mpls;
|
||||
IAudioDecoderSettings decoderSettings = null;
|
||||
if (Path.GetExtension(sourceFile) == ".mpls")
|
||||
{
|
||||
decoderSettings = new Codecs.MPEG.MPLS.DecoderSettings();
|
||||
} else
|
||||
{
|
||||
decoderSettings = new Codecs.MPEG.ATSI.DecoderSettings();
|
||||
}
|
||||
foreach (var decOpt in decoderOptions)
|
||||
{
|
||||
var property = TypeDescriptor.GetProperties(decoderSettings).Find(decOpt.Key, true);
|
||||
if (property == null)
|
||||
throw new Exception($"{decoderSettings.Name} {decoderSettings.Extension} decoder settings object (of type {decoderSettings.GetType().FullName}) doesn't have a property named {decOpt.Key}.");
|
||||
property.SetValue(decoderSettings,
|
||||
TypeDescriptor.GetConverter(property.PropertyType).ConvertFromString(decOpt.Value));
|
||||
}
|
||||
audioSource = decoderSettings.Open(sourceFile);
|
||||
audioContainer = audioSource as IAudioTitleSet;
|
||||
if (audioContainer == null) audioContainer = new SingleAudioTitleSet(audioSource);
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
int frameRate = 0;
|
||||
bool interlaced = false;
|
||||
chapters = mpls.Chapters;
|
||||
mpls.MPLSHeader.play_item.ForEach(i => i.video.ForEach(v => { if (!videos.Exists(v1 => v1.pid == v.pid)) videos.Add(v); }));
|
||||
mpls.MPLSHeader.play_item.ForEach(i => i.audio.ForEach(v => { if (!audios.Exists(v1 => v1.pid == v.pid)) audios.Add(v); }));
|
||||
audios = audioContainer.AudioTitles;
|
||||
audios.ForEach(t => chapters = t.Chapters);
|
||||
if (audioSource is Codecs.MPEG.MPLS.AudioDecoder)
|
||||
{
|
||||
var mpls = audioSource as Codecs.MPEG.MPLS.AudioDecoder;
|
||||
mpls.MPLSHeader.play_item.ForEach(i => i.video.ForEach(v => { if (!videos.Exists(v1 => v1.pid == v.pid)) videos.Add(v); }));
|
||||
}
|
||||
videos.ForEach(v => { frameRate = v.FrameRate; interlaced = v.Interlaced; });
|
||||
Console.Error.WriteLine("M2TS, {0} video track{1}, {2} audio track{3}, {4}, {5}{6}",
|
||||
videos.Count, videos.Count > 1 ? "s" : "",
|
||||
audios.Count, audios.Count > 1 ? "s" : "",
|
||||
CDImageLayout.TimeToString(mpls.Duration, "{0:0}:{1:00}:{2:00}"), frameRate * (interlaced ? 2 : 1), interlaced ? "i" : "p");
|
||||
Console.Error.Write($@"M2TS, {
|
||||
videos.Count} video track{(videos.Count != 1 ? "s" : "")}, {
|
||||
audios.Count} audio track{(audios.Count != 1 ? "s" : "")}, {
|
||||
CDImageLayout.TimeToString(audios[0].GetDuration(), "{0:0}:{1:00}:{2:00}")}, {
|
||||
(frameRate * (interlaced ? 2 : 1))}{
|
||||
(interlaced ? "i" : "p")}");
|
||||
Console.Error.WriteLine();
|
||||
//foreach (var item in mpls.MPLSHeader.play_item)
|
||||
//Console.Error.WriteLine("{0}.m2ts", item.clip_id);
|
||||
{
|
||||
@@ -175,11 +207,9 @@ namespace CUETools.eac3to
|
||||
Console.Error.Write(id++);
|
||||
Console.Error.Write(": ");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Console.Error.WriteLine("{0}, {1}, {2}, {3}", audio.CodecString, audio.LanguageString, audio.FormatString, audio.RateString);
|
||||
Console.Error.WriteLine("{0}, {1}, {2}, {3}", audio.Codec, audio.Language, audio.GetFormatString(), audio.GetRateString());
|
||||
}
|
||||
}
|
||||
|
||||
duration = mpls.Duration;
|
||||
}
|
||||
|
||||
if (destFile == null)
|
||||
@@ -187,7 +217,7 @@ namespace CUETools.eac3to
|
||||
|
||||
string strtoc = "";
|
||||
for (int i = 0; i < chapters.Count; i++)
|
||||
strtoc += string.Format(" {0}", chapters[i] / 600);
|
||||
strtoc += string.Format(" {0}", (int)Math.Round((chapters[i].TotalSeconds * 75)));
|
||||
strtoc = strtoc.Substring(1);
|
||||
CDImageLayout toc = new CDImageLayout(strtoc);
|
||||
CTDBResponseMeta meta = null;
|
||||
@@ -238,9 +268,9 @@ namespace CUETools.eac3to
|
||||
for (int i = 0; i < chapters.Count - 1; i++)
|
||||
{
|
||||
sw.WriteLine("CHAPTER{0:00}={1}", i + 1,
|
||||
CDImageLayout.TimeToString(TimeSpan.FromSeconds(chapters[i] / 45000.0)));
|
||||
if (meta != null && meta.track.Length >= toc[i+1].Number)
|
||||
sw.WriteLine("CHAPTER{0:00}NAME={1}", i + 1, meta.track[(int)toc[i+1].Number - 1].name);
|
||||
CDImageLayout.TimeToString(chapters[i]));
|
||||
if (meta != null && meta.track.Length >= toc[i + 1].Number)
|
||||
sw.WriteLine("CHAPTER{0:00}NAME={1}", i + 1, meta.track[(int)toc[i + 1].Number - 1].name);
|
||||
else
|
||||
sw.WriteLine("CHAPTER{0:00}NAME=", i + 1);
|
||||
}
|
||||
@@ -309,21 +339,21 @@ namespace CUETools.eac3to
|
||||
|
||||
throw new Exception("Unknown encoder format: " + destFile);
|
||||
}
|
||||
if (stream - chapterStreams <= videos.Count)
|
||||
throw new Exception("Video extraction not supported.");
|
||||
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));
|
||||
int streamId = audios[stream - chapterStreams - videos.Count - 1].StreamId;
|
||||
if (audioSource is Codecs.MPEG.MPLS.AudioDecoder)
|
||||
{
|
||||
if (stream - chapterStreams <= videos.Count)
|
||||
throw new Exception("Video extraction not supported.");
|
||||
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));
|
||||
int pid = audios[stream - chapterStreams - videos.Count - 1].pid;
|
||||
(audioSource.Settings as Codecs.MPEG.MPLS.DecoderSettings).StreamId = pid;
|
||||
(audioSource.Settings as Codecs.MPEG.MPLS.DecoderSettings).StreamId = streamId;
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
duration);
|
||||
audioSource.Duration);
|
||||
|
||||
CUEToolsFormat fmt;
|
||||
if (encoderFormat == null)
|
||||
@@ -397,14 +427,15 @@ namespace CUETools.eac3to
|
||||
TimeSpan elapsed = DateTime.Now - start;
|
||||
if ((elapsed - lastPrint).TotalMilliseconds > 60)
|
||||
{
|
||||
long length = (long)(duration.TotalSeconds * audioSource.PCM.SampleRate);
|
||||
if (length < audioSource.Position) length = audioSource.Position;
|
||||
if (length < 1) length = 1;
|
||||
var duration = audioSource.Duration;
|
||||
var position = TimeSpan.FromSeconds((double)audioSource.Position / audioSource.PCM.SampleRate);
|
||||
if (duration < position) duration = position;
|
||||
if (duration < TimeSpan.FromSeconds(1)) duration = TimeSpan.FromSeconds(1);
|
||||
Console.Error.Write("\rProgress : {0:00}%; {1:0.00}x; {2}/{3}",
|
||||
100.0 * audioSource.Position / length,
|
||||
audioSource.Position / elapsed.TotalSeconds / audioSource.PCM.SampleRate,
|
||||
100.0 * position.TotalSeconds / duration.TotalSeconds,
|
||||
position.TotalSeconds / elapsed.TotalSeconds,
|
||||
elapsed,
|
||||
TimeSpan.FromMilliseconds(elapsed.TotalMilliseconds / audioSource.Position * length)
|
||||
TimeSpan.FromSeconds(elapsed.TotalSeconds / position.TotalSeconds * duration.TotalSeconds)
|
||||
);
|
||||
lastPrint = elapsed;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace BluTools
|
||||
{
|
||||
string strtoc = "";
|
||||
for (int i = 0; i < chapters.Count; i++)
|
||||
strtoc += string.Format(" {0}", chapters[i] / 600);
|
||||
strtoc += string.Format(" {0}", (int) Math.Round((chapters[i].TotalSeconds * 75)));
|
||||
strtoc = strtoc.Substring(1);
|
||||
CDImageLayout toc = new CDImageLayout(strtoc);
|
||||
ctdb = new CUEToolsDB(toc, null);
|
||||
@@ -228,10 +228,11 @@ namespace BluTools
|
||||
|
||||
void workerExtract_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
CUETools.Codecs.MPEG.MPLS.AudioDecoder reader = null;
|
||||
IAudioSource reader = null;
|
||||
try
|
||||
{
|
||||
reader = new CUETools.Codecs.MPEG.MPLS.AudioDecoder(chosenReader.Path, null, pid);
|
||||
var decoderSettings = new CUETools.Codecs.MPEG.MPLS.DecoderSettings() { StreamId = pid };
|
||||
reader = decoderSettings.Open(chosenReader.Path);
|
||||
Directory.CreateDirectory(outputFolderPath);
|
||||
if (File.Exists(outputCuePath)) throw new Exception(string.Format("File \"{0}\" already exists", outputCuePath));
|
||||
if (File.Exists(outputAudioPath)) throw new Exception(string.Format("File \"{0}\" already exists", outputAudioPath));
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace CUETools.TestCodecs
|
||||
[TestMethod()]
|
||||
public void SeekTest()
|
||||
{
|
||||
var r = new CUETools.Codecs.libFLAC.Reader(new Codecs.libFLAC.DecoderSettings(), "test.flac", null);
|
||||
var r = new Codecs.libFLAC.DecoderSettings().Open("test.flac", null);
|
||||
var buff1 = new AudioBuffer(r, 16536);
|
||||
var buff2 = new AudioBuffer(r, 16536);
|
||||
Assert.AreEqual(0, r.Position);
|
||||
|
||||
Reference in New Issue
Block a user