mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
ALAC can also be read from RAR archive
This commit is contained in:
@@ -28,16 +28,16 @@ namespace ALACDotNet
|
|||||||
{
|
{
|
||||||
public class ALACReader : IAudioSource
|
public class ALACReader : IAudioSource
|
||||||
{
|
{
|
||||||
public ALACReader(string path)
|
public ALACReader(string path, Stream IO)
|
||||||
{
|
{
|
||||||
_path = path;
|
_path = path;
|
||||||
m_spIO = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
_IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
_buff = new byte[512];
|
_buff = new byte[512];
|
||||||
_tags = new NameValueCollection();
|
_tags = new NameValueCollection();
|
||||||
qtmovie_read();
|
qtmovie_read();
|
||||||
if (!_formatRead || _bitsPerSample != 16 || _channelCount != 2 || _sampleRate != 44100)
|
if (!_formatRead || _bitsPerSample != 16 || _channelCount != 2 || _sampleRate != 44100)
|
||||||
throw new Exception("Invalid ALAC file.");
|
throw new Exception("Invalid ALAC file.");
|
||||||
_saved_mdat_pos = m_spIO.Position;
|
_saved_mdat_pos = _IO.Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint Read(int[,] buff, uint sampleCount)
|
public uint Read(int[,] buff, uint sampleCount)
|
||||||
@@ -83,7 +83,7 @@ namespace ALACDotNet
|
|||||||
if ((int) _iSample >= _sample_byte_size.Length)
|
if ((int) _iSample >= _sample_byte_size.Length)
|
||||||
return (uint)offset;
|
return (uint)offset;
|
||||||
get_sample_info(_iSample, out sampleDuration, out sampleSize);
|
get_sample_info(_iSample, out sampleDuration, out sampleSize);
|
||||||
m_spIO.Read(_framesBuffer, 0, (int) sampleSize);
|
_IO.Read(_framesBuffer, 0, (int) sampleSize);
|
||||||
decodeFrame(sampleDuration, sampleSize);
|
decodeFrame(sampleDuration, sampleSize);
|
||||||
if (sampleDuration != _samplesInBuffer)
|
if (sampleDuration != _samplesInBuffer)
|
||||||
throw new Exception("sample count mismatch");
|
throw new Exception("sample count mismatch");
|
||||||
@@ -102,7 +102,7 @@ namespace ALACDotNet
|
|||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
m_spIO.Close();
|
_IO.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ulong Length
|
public ulong Length
|
||||||
@@ -142,7 +142,7 @@ namespace ALACDotNet
|
|||||||
{
|
{
|
||||||
if (durOffs == value)
|
if (durOffs == value)
|
||||||
{
|
{
|
||||||
m_spIO.Position = _saved_mdat_pos + fileOffs;
|
_IO.Position = _saved_mdat_pos + fileOffs;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
get_sample_info(_iSample, out sampleDuration, out sampleSize);
|
get_sample_info(_iSample, out sampleDuration, out sampleSize);
|
||||||
@@ -150,7 +150,7 @@ namespace ALACDotNet
|
|||||||
fileOffs += sampleSize;
|
fileOffs += sampleSize;
|
||||||
_iSample++;
|
_iSample++;
|
||||||
} while (durOffs <= value);
|
} while (durOffs <= value);
|
||||||
m_spIO.Position = _saved_mdat_pos + fileOffs - sampleSize;
|
_IO.Position = _saved_mdat_pos + fileOffs - sampleSize;
|
||||||
_samplesBufferOffset = (uint) (value + sampleDuration - durOffs);
|
_samplesBufferOffset = (uint) (value + sampleDuration - durOffs);
|
||||||
_iSample--;
|
_iSample--;
|
||||||
}
|
}
|
||||||
@@ -218,7 +218,7 @@ namespace ALACDotNet
|
|||||||
{
|
{
|
||||||
if (len > 512)
|
if (len > 512)
|
||||||
throw new Exception("Decoding failed.");
|
throw new Exception("Decoding failed.");
|
||||||
if (m_spIO.Read(_buff, 0, len) != len)
|
if (_IO.Read(_buff, 0, len) != len)
|
||||||
throw new Exception("Decoding failed.");
|
throw new Exception("Decoding failed.");
|
||||||
return _buff;
|
return _buff;
|
||||||
}
|
}
|
||||||
@@ -255,7 +255,7 @@ namespace ALACDotNet
|
|||||||
|
|
||||||
private void stream_skip (UInt32 skip)
|
private void stream_skip (UInt32 skip)
|
||||||
{
|
{
|
||||||
m_spIO.Position += skip;
|
_IO.Position += skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* supports reading 1 to 24 bits, in big endian format */
|
/* supports reading 1 to 24 bits, in big endian format */
|
||||||
@@ -834,7 +834,7 @@ namespace ALACDotNet
|
|||||||
_codecData[0] = 0; _codecData[1] = 0; _codecData[2] = 0; _codecData[3] = 0x0C;
|
_codecData[0] = 0; _codecData[1] = 0; _codecData[2] = 0; _codecData[3] = 0x0C;
|
||||||
_codecData[4] = (byte)'f'; _codecData[5] = (byte)'r'; _codecData[6] = (byte)'m'; _codecData[7] = (byte)'a';
|
_codecData[4] = (byte)'f'; _codecData[5] = (byte)'r'; _codecData[6] = (byte)'m'; _codecData[7] = (byte)'a';
|
||||||
_codecData[8] = (byte)'a'; _codecData[9] = (byte)'l'; _codecData[10] = (byte)'a'; _codecData[11] = (byte)'c';
|
_codecData[8] = (byte)'a'; _codecData[9] = (byte)'l'; _codecData[10] = (byte)'a'; _codecData[11] = (byte)'c';
|
||||||
m_spIO.Read(_codecData, 12, (int)entry_remaining);
|
_IO.Read(_codecData, 12, (int)entry_remaining);
|
||||||
entry_remaining -= entry_remaining;
|
entry_remaining -= entry_remaining;
|
||||||
|
|
||||||
//#endif
|
//#endif
|
||||||
@@ -957,7 +957,7 @@ namespace ALACDotNet
|
|||||||
/* name */
|
/* name */
|
||||||
UInt32 strlen = stream_read_uint8();
|
UInt32 strlen = stream_read_uint8();
|
||||||
byte[] str = new byte[strlen];
|
byte[] str = new byte[strlen];
|
||||||
m_spIO.Read(str, 0, (int)strlen);
|
_IO.Read(str, 0, (int)strlen);
|
||||||
size_remaining -= 1 + strlen;
|
size_remaining -= 1 + strlen;
|
||||||
|
|
||||||
if (size_remaining > 0)
|
if (size_remaining > 0)
|
||||||
@@ -989,7 +989,7 @@ namespace ALACDotNet
|
|||||||
return;
|
return;
|
||||||
if (skip_mdat)
|
if (skip_mdat)
|
||||||
{
|
{
|
||||||
_saved_mdat_pos = m_spIO.Position;
|
_saved_mdat_pos = _IO.Position;
|
||||||
stream_skip(size_remaining);
|
stream_skip(size_remaining);
|
||||||
}
|
}
|
||||||
//#if 0
|
//#if 0
|
||||||
@@ -1049,7 +1049,7 @@ namespace ALACDotNet
|
|||||||
if (str_size <= 0) return;
|
if (str_size <= 0) return;
|
||||||
if (tag_format != 0) throw new Exception(path + " not a binary");
|
if (tag_format != 0) throw new Exception(path + " not a binary");
|
||||||
byte[] value = new byte[str_size];
|
byte[] value = new byte[str_size];
|
||||||
if (m_spIO.Read(value, 0, str_size) != str_size)
|
if (_IO.Read(value, 0, str_size) != str_size)
|
||||||
throw new Exception("Decoding failed.");
|
throw new Exception("Decoding failed.");
|
||||||
if (path.EndsWith(".trkn.data"))
|
if (path.EndsWith(".trkn.data"))
|
||||||
{
|
{
|
||||||
@@ -1189,7 +1189,7 @@ namespace ALACDotNet
|
|||||||
qtmovie_read_lst("top.moov", chunk_len - 8, null);
|
qtmovie_read_lst("top.moov", chunk_len - 8, null);
|
||||||
if (found_mdat)
|
if (found_mdat)
|
||||||
{
|
{
|
||||||
m_spIO.Position = _saved_mdat_pos;
|
_IO.Position = _saved_mdat_pos;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
found_moov = true;
|
found_moov = true;
|
||||||
@@ -1216,7 +1216,7 @@ namespace ALACDotNet
|
|||||||
}
|
}
|
||||||
|
|
||||||
string _path;
|
string _path;
|
||||||
FileStream m_spIO;
|
Stream _IO;
|
||||||
|
|
||||||
byte[] _codecData;
|
byte[] _codecData;
|
||||||
uint[] _time_to_sample_count, _time_to_sample_duration, _sample_byte_size;
|
uint[] _time_to_sample_count, _time_to_sample_duration, _sample_byte_size;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace CUEToolsLib {
|
|||||||
case ".ape":
|
case ".ape":
|
||||||
return new APEReader(path);
|
return new APEReader(path);
|
||||||
case ".m4a":
|
case ".m4a":
|
||||||
return new ALACReader(path);
|
return new ALACReader(path, null);
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
throw new Exception("Unsupported audio type.");
|
throw new Exception("Unsupported audio type.");
|
||||||
@@ -37,6 +37,8 @@ namespace CUEToolsLib {
|
|||||||
#if !MONO
|
#if !MONO
|
||||||
case ".flac":
|
case ".flac":
|
||||||
return new FLACReader(path, IO);
|
return new FLACReader(path, IO);
|
||||||
|
case ".m4a":
|
||||||
|
return new ALACReader(path, IO);
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
throw new Exception("Unsupported audio type in archive.");
|
throw new Exception("Unsupported audio type in archive.");
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace UnRarDotNet
|
|||||||
}
|
}
|
||||||
public override long Position
|
public override long Position
|
||||||
{
|
{
|
||||||
get { return _pos; }
|
get { return _seek_to == null ? _pos : _seek_to.Value; }
|
||||||
set { Seek(value, SeekOrigin.Begin); }
|
set { Seek(value, SeekOrigin.Begin); }
|
||||||
}
|
}
|
||||||
public override void Close()
|
public override void Close()
|
||||||
@@ -143,25 +143,30 @@ namespace UnRarDotNet
|
|||||||
Monitor.Wait(this);
|
Monitor.Wait(this);
|
||||||
if (_size == null)
|
if (_size == null)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
switch (origin)
|
|
||||||
{
|
|
||||||
case SeekOrigin.Begin:
|
|
||||||
_seek_to = offset;
|
|
||||||
break;
|
|
||||||
case SeekOrigin.Current:
|
|
||||||
_seek_to = _pos + offset;
|
|
||||||
break;
|
|
||||||
case SeekOrigin.End:
|
|
||||||
_seek_to = _size.Value + offset;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (_seek_to.Value == _pos)
|
|
||||||
{
|
|
||||||
_seek_to = null;
|
|
||||||
return _pos;
|
|
||||||
}
|
|
||||||
return _seek_to.Value;
|
|
||||||
}
|
}
|
||||||
|
switch (origin)
|
||||||
|
{
|
||||||
|
case SeekOrigin.Begin:
|
||||||
|
_seek_to = offset;
|
||||||
|
break;
|
||||||
|
case SeekOrigin.Current:
|
||||||
|
_seek_to = Position + offset;
|
||||||
|
break;
|
||||||
|
case SeekOrigin.End:
|
||||||
|
_seek_to = _size.Value + offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (_seek_to.Value == _pos)
|
||||||
|
{
|
||||||
|
_seek_to = null;
|
||||||
|
return _pos;
|
||||||
|
}
|
||||||
|
if (_seek_to.Value < _pos)
|
||||||
|
{
|
||||||
|
_seek_to = null;
|
||||||
|
throw new NotSupportedException("cannot seek backwards");
|
||||||
|
}
|
||||||
|
return _seek_to.Value;
|
||||||
}
|
}
|
||||||
public override void Write(byte[] array, int offset, int count)
|
public override void Write(byte[] array, int offset, int count)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user