2008-12-07 23:38:00 +00:00
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using CUETools.Codecs;
|
|
|
|
|
using CUETools.Codecs.ALAC;
|
2009-08-21 03:26:12 +00:00
|
|
|
using CUETools.Codecs.FLAKE;
|
2009-01-17 04:09:38 +00:00
|
|
|
#if !MONO
|
2008-12-09 07:25:48 +00:00
|
|
|
using CUETools.Codecs.FLAC;
|
|
|
|
|
using CUETools.Codecs.WavPack;
|
|
|
|
|
using CUETools.Codecs.APE;
|
2009-01-17 04:09:38 +00:00
|
|
|
using CUETools.Codecs.TTA;
|
|
|
|
|
#endif
|
2008-12-07 23:38:00 +00:00
|
|
|
using CUETools.Codecs.LossyWAV;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Collections.Specialized;
|
|
|
|
|
|
|
|
|
|
namespace CUETools.Processor
|
|
|
|
|
{
|
|
|
|
|
public static class AudioReadWrite {
|
2009-02-19 04:09:59 +00:00
|
|
|
public static IAudioSource GetAudioSource(string path, Stream IO, string extension, CUEConfig config)
|
2008-12-07 23:38:00 +00:00
|
|
|
{
|
2009-05-01 15:16:26 +00:00
|
|
|
CUEToolsFormat fmt;
|
|
|
|
|
if (!extension.StartsWith(".") || !config.formats.TryGetValue(extension.Substring(1), out fmt))
|
|
|
|
|
throw new Exception("Unsupported audio type: " + path);
|
|
|
|
|
CUEToolsUDC decoder;
|
|
|
|
|
if (fmt.decoder == null || !config.decoders.TryGetValue(fmt.decoder, out decoder))
|
|
|
|
|
throw new Exception("Unsupported audio type: " + path);
|
|
|
|
|
switch (decoder.className)
|
2008-12-07 23:38:00 +00:00
|
|
|
{
|
2009-05-01 15:16:26 +00:00
|
|
|
case "WAVReader":
|
2008-12-07 23:38:00 +00:00
|
|
|
return new WAVReader(path, IO);
|
2009-05-01 15:16:26 +00:00
|
|
|
case "ALACReader":
|
2008-12-07 23:38:00 +00:00
|
|
|
return new ALACReader(path, IO);
|
2009-08-21 03:26:12 +00:00
|
|
|
case "FlakeReader":
|
|
|
|
|
return new FlakeReader(path, IO);
|
2008-12-07 23:38:00 +00:00
|
|
|
#if !MONO
|
2009-05-01 15:16:26 +00:00
|
|
|
case "FLACReader":
|
2009-03-04 21:30:56 +00:00
|
|
|
return new FLACReader(path, IO, config.disableAsm);
|
2009-05-01 15:16:26 +00:00
|
|
|
case "WavPackReader":
|
2008-12-07 23:38:00 +00:00
|
|
|
return new WavPackReader(path, IO, null);
|
2009-05-01 15:16:26 +00:00
|
|
|
case "APEReader":
|
2008-12-07 23:38:00 +00:00
|
|
|
return new APEReader(path, IO);
|
2009-05-01 15:16:26 +00:00
|
|
|
case "TTAReader":
|
2009-01-17 04:09:38 +00:00
|
|
|
return new TTAReader(path, IO);
|
2008-12-07 23:38:00 +00:00
|
|
|
#endif
|
|
|
|
|
default:
|
2009-05-01 15:16:26 +00:00
|
|
|
if (decoder.path == null)
|
|
|
|
|
throw new Exception("Unsupported audio type: " + path);
|
|
|
|
|
return new UserDefinedReader(path, IO, decoder.path, decoder.parameters);
|
2008-12-07 23:38:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-19 04:09:59 +00:00
|
|
|
public static IAudioSource GetAudioSource(string path, Stream IO, CUEConfig config)
|
2008-12-07 23:38:00 +00:00
|
|
|
{
|
|
|
|
|
string extension = Path.GetExtension(path).ToLower();
|
|
|
|
|
string filename = Path.GetFileNameWithoutExtension(path);
|
|
|
|
|
string secondExtension = Path.GetExtension(filename).ToLower();
|
|
|
|
|
if (secondExtension != ".lossy" && secondExtension != ".lwcdf")
|
2009-02-19 04:09:59 +00:00
|
|
|
return GetAudioSource(path, IO, extension, config);
|
2008-12-07 23:38:00 +00:00
|
|
|
|
|
|
|
|
string lossyPath = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(filename) + ".lossy" + extension);
|
|
|
|
|
string lwcdfPath = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(filename) + ".lwcdf" + extension);
|
2009-02-19 04:09:59 +00:00
|
|
|
IAudioSource lossySource = GetAudioSource(lossyPath, null, extension, config);
|
2009-01-17 04:09:38 +00:00
|
|
|
IAudioSource lwcdfSource = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
2009-02-19 04:09:59 +00:00
|
|
|
lwcdfSource = GetAudioSource(lwcdfPath, null, extension, config);
|
2009-01-17 04:09:38 +00:00
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
return lossySource;
|
|
|
|
|
}
|
2008-12-07 23:38:00 +00:00
|
|
|
return new LossyWAVReader(lossySource, lwcdfSource);
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-08 16:14:06 +00:00
|
|
|
public static IAudioDest GetAudioDest(AudioEncoderType audioEncoderType, string path, int bitsPerSample, int channelCount, int sampleRate, long finalSampleCount, int padding, string extension, CUEConfig config)
|
2009-05-01 15:16:26 +00:00
|
|
|
{
|
2008-12-07 23:38:00 +00:00
|
|
|
IAudioDest dest;
|
2009-05-01 15:16:26 +00:00
|
|
|
if (audioEncoderType == AudioEncoderType.NoAudio || extension == ".dummy")
|
|
|
|
|
{
|
|
|
|
|
dest = new DummyWriter(path, bitsPerSample, channelCount, sampleRate);
|
|
|
|
|
dest.FinalSampleCount = finalSampleCount;
|
|
|
|
|
return dest;
|
|
|
|
|
}
|
|
|
|
|
CUEToolsFormat fmt;
|
|
|
|
|
if (!extension.StartsWith(".") || !config.formats.TryGetValue(extension.Substring(1), out fmt))
|
|
|
|
|
throw new Exception("Unsupported audio type: " + path);
|
2009-08-06 13:03:02 +00:00
|
|
|
CUEToolsUDC encoder = audioEncoderType == AudioEncoderType.Lossless ? fmt.encoderLossless :
|
2009-05-01 15:16:26 +00:00
|
|
|
audioEncoderType == AudioEncoderType.Lossy ? fmt.encoderLossy :
|
|
|
|
|
null;
|
2009-08-06 13:03:02 +00:00
|
|
|
if (encoder == null)
|
2009-05-01 15:16:26 +00:00
|
|
|
throw new Exception("Unsupported audio type: " + path);
|
|
|
|
|
switch (encoder.className)
|
|
|
|
|
{
|
|
|
|
|
case "WAVWriter":
|
2008-12-07 23:38:00 +00:00
|
|
|
dest = new WAVWriter(path, bitsPerSample, channelCount, sampleRate, null);
|
|
|
|
|
break;
|
|
|
|
|
#if !MONO
|
2009-05-01 15:16:26 +00:00
|
|
|
case "FLACWriter":
|
2008-12-07 23:38:00 +00:00
|
|
|
dest = new FLACWriter(path, bitsPerSample, channelCount, sampleRate);
|
2009-08-08 16:14:06 +00:00
|
|
|
((FLACWriter)dest).PaddingLength = padding;
|
2009-06-24 19:40:23 +00:00
|
|
|
((FLACWriter)dest).CompressionLevel = encoder.DefaultModeIndex;
|
2008-12-07 23:38:00 +00:00
|
|
|
((FLACWriter)dest).Verify = config.flacVerify;
|
2009-03-04 21:30:56 +00:00
|
|
|
((FLACWriter)dest).DisableAsm = config.disableAsm;
|
2008-12-07 23:38:00 +00:00
|
|
|
break;
|
2009-08-21 03:26:12 +00:00
|
|
|
case "FlakeWriter":
|
|
|
|
|
dest = new FlakeWriter(path, bitsPerSample, channelCount, sampleRate, null);
|
|
|
|
|
((FlakeWriter)dest).PaddingLength = padding;
|
|
|
|
|
((FlakeWriter)dest).CompressionLevel = encoder.DefaultModeIndex;
|
|
|
|
|
dest = new BufferedWriter(dest, 128 * 1024);
|
|
|
|
|
break;
|
2009-05-01 15:16:26 +00:00
|
|
|
case "WavPackWriter":
|
2008-12-07 23:38:00 +00:00
|
|
|
dest = new WavPackWriter(path, bitsPerSample, channelCount, sampleRate);
|
2009-06-24 19:40:23 +00:00
|
|
|
((WavPackWriter)dest).CompressionMode = encoder.DefaultModeIndex;
|
2008-12-07 23:38:00 +00:00
|
|
|
((WavPackWriter)dest).ExtraMode = config.wvExtraMode;
|
|
|
|
|
((WavPackWriter)dest).MD5Sum = config.wvStoreMD5;
|
|
|
|
|
break;
|
2009-05-01 15:16:26 +00:00
|
|
|
case "APEWriter":
|
2008-12-07 23:38:00 +00:00
|
|
|
dest = new APEWriter(path, bitsPerSample, channelCount, sampleRate);
|
2009-06-24 19:40:23 +00:00
|
|
|
((APEWriter)dest).CompressionLevel = encoder.DefaultModeIndex;
|
2008-12-07 23:38:00 +00:00
|
|
|
break;
|
2009-05-01 15:16:26 +00:00
|
|
|
case "TTAWriter":
|
2009-01-17 04:09:38 +00:00
|
|
|
dest = new TTAWriter(path, bitsPerSample, channelCount, sampleRate);
|
|
|
|
|
break;
|
2008-12-07 23:38:00 +00:00
|
|
|
#endif
|
|
|
|
|
default:
|
2009-05-01 15:16:26 +00:00
|
|
|
if (encoder.path == null)
|
|
|
|
|
throw new Exception("Unsupported audio type: " + path);
|
2009-08-08 16:14:06 +00:00
|
|
|
dest = new UserDefinedWriter(path, bitsPerSample, channelCount, sampleRate, null, encoder.path, encoder.parameters, encoder.default_mode, padding);
|
2009-05-01 15:16:26 +00:00
|
|
|
break;
|
2008-12-07 23:38:00 +00:00
|
|
|
}
|
|
|
|
|
dest.FinalSampleCount = finalSampleCount;
|
|
|
|
|
return dest;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-08 16:14:06 +00:00
|
|
|
public static IAudioDest GetAudioDest(AudioEncoderType audioEncoderType, string path, long finalSampleCount, int bitsPerSample, int sampleRate, int padding, CUEConfig config)
|
2008-12-07 23:38:00 +00:00
|
|
|
{
|
|
|
|
|
string extension = Path.GetExtension(path).ToLower();
|
|
|
|
|
string filename = Path.GetFileNameWithoutExtension(path);
|
2009-05-01 15:16:26 +00:00
|
|
|
if (audioEncoderType == AudioEncoderType.NoAudio || audioEncoderType == AudioEncoderType.Lossless || Path.GetExtension(filename).ToLower() != ".lossy")
|
2009-08-08 16:14:06 +00:00
|
|
|
return GetAudioDest(audioEncoderType, path, bitsPerSample, 2, sampleRate, finalSampleCount, padding, extension, config);
|
2008-12-07 23:38:00 +00:00
|
|
|
|
|
|
|
|
string lwcdfPath = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(filename) + ".lwcdf" + extension);
|
|
|
|
|
int lossyBitsPerSample = (config.detectHDCD && config.decodeHDCD && !config.decodeHDCDtoLW16) ? 24 : 16;
|
2009-08-08 16:14:06 +00:00
|
|
|
IAudioDest lossyDest = GetAudioDest(AudioEncoderType.Lossless, path, lossyBitsPerSample, 2, sampleRate, finalSampleCount, padding, extension, config);
|
|
|
|
|
IAudioDest lwcdfDest = audioEncoderType == AudioEncoderType.Hybrid ? GetAudioDest(AudioEncoderType.Lossless, lwcdfPath, bitsPerSample, 2, sampleRate, finalSampleCount, padding, extension, config) : null;
|
2009-01-28 04:53:13 +00:00
|
|
|
return new LossyWAVWriter(lossyDest, lwcdfDest, bitsPerSample, 2, sampleRate, config.lossyWAVQuality);
|
2008-12-07 23:38:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|