mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
WAV can also be read from RAR archive
This commit is contained in:
@@ -251,7 +251,7 @@ namespace AudioCodecsDotNet
|
|||||||
|
|
||||||
public class WAVReader : IAudioSource
|
public class WAVReader : IAudioSource
|
||||||
{
|
{
|
||||||
FileStream _fs;
|
Stream _IO;
|
||||||
BinaryReader _br;
|
BinaryReader _br;
|
||||||
ulong _dataOffset, _dataLen;
|
ulong _dataOffset, _dataLen;
|
||||||
ulong _samplePos, _sampleLen;
|
ulong _samplePos, _sampleLen;
|
||||||
@@ -260,12 +260,11 @@ namespace AudioCodecsDotNet
|
|||||||
string _path;
|
string _path;
|
||||||
private byte[] _sampleBuffer;
|
private byte[] _sampleBuffer;
|
||||||
|
|
||||||
public WAVReader(string path)
|
public WAVReader(string path, Stream IO)
|
||||||
{
|
{
|
||||||
_path = path;
|
_path = path;
|
||||||
//_fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
_IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000, FileOptions.SequentialScan);
|
||||||
_fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000, FileOptions.SequentialScan);
|
_br = new BinaryReader(_IO);
|
||||||
_br = new BinaryReader(_fs);
|
|
||||||
|
|
||||||
ParseHeaders();
|
ParseHeaders();
|
||||||
|
|
||||||
@@ -274,11 +273,13 @@ namespace AudioCodecsDotNet
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
|
{
|
||||||
|
if (_br != null)
|
||||||
{
|
{
|
||||||
_br.Close();
|
_br.Close();
|
||||||
|
|
||||||
_br = null;
|
_br = null;
|
||||||
_fs = null;
|
}
|
||||||
|
_IO = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ParseHeaders()
|
private void ParseHeaders()
|
||||||
@@ -310,7 +311,7 @@ namespace AudioCodecsDotNet
|
|||||||
foundFormat = false;
|
foundFormat = false;
|
||||||
foundData = false;
|
foundData = false;
|
||||||
|
|
||||||
while (_fs.Position < fileEnd)
|
while (_IO.Position < fileEnd)
|
||||||
{
|
{
|
||||||
uint ckID, ckSize, ckSizePadded;
|
uint ckID, ckSize, ckSizePadded;
|
||||||
long ckEnd;
|
long ckEnd;
|
||||||
@@ -318,7 +319,7 @@ namespace AudioCodecsDotNet
|
|||||||
ckID = _br.ReadUInt32();
|
ckID = _br.ReadUInt32();
|
||||||
ckSize = _br.ReadUInt32();
|
ckSize = _br.ReadUInt32();
|
||||||
ckSizePadded = (ckSize + 1U) & ~1U;
|
ckSizePadded = (ckSize + 1U) & ~1U;
|
||||||
ckEnd = _fs.Position + (long)ckSizePadded;
|
ckEnd = _IO.Position + (long)ckSizePadded;
|
||||||
|
|
||||||
if (ckID == fccFormat)
|
if (ckID == fccFormat)
|
||||||
{
|
{
|
||||||
@@ -338,15 +339,15 @@ namespace AudioCodecsDotNet
|
|||||||
{
|
{
|
||||||
foundData = true;
|
foundData = true;
|
||||||
|
|
||||||
_dataOffset = (ulong)_fs.Position;
|
_dataOffset = (ulong)_IO.Position;
|
||||||
if (_fs.Length <= maxFileSize)
|
if (_IO.Length <= maxFileSize)
|
||||||
{
|
{
|
||||||
_dataLen = ckSize;
|
_dataLen = ckSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_largeFile = true;
|
_largeFile = true;
|
||||||
_dataLen = ((ulong)_fs.Length) - _dataOffset;
|
_dataLen = ((ulong)_IO.Length) - _dataOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +356,7 @@ namespace AudioCodecsDotNet
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_fs.Seek(ckEnd, SeekOrigin.Begin);
|
_IO.Seek(ckEnd, SeekOrigin.Begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((foundFormat & foundData) == false)
|
if ((foundFormat & foundData) == false)
|
||||||
@@ -401,7 +402,7 @@ namespace AudioCodecsDotNet
|
|||||||
}
|
}
|
||||||
|
|
||||||
seekPos = _dataOffset + (_samplePos * (uint)_blockAlign);
|
seekPos = _dataOffset + (_samplePos * (uint)_blockAlign);
|
||||||
_fs.Seek((long)seekPos, SeekOrigin.Begin);
|
_IO.Seek((long)seekPos, SeekOrigin.Begin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,7 +481,7 @@ namespace AudioCodecsDotNet
|
|||||||
int byteCount = (int) sampleCount * _blockAlign;
|
int byteCount = (int) sampleCount * _blockAlign;
|
||||||
if (_sampleBuffer == null || _sampleBuffer.Length < byteCount)
|
if (_sampleBuffer == null || _sampleBuffer.Length < byteCount)
|
||||||
_sampleBuffer = new byte[byteCount];
|
_sampleBuffer = new byte[byteCount];
|
||||||
if (_fs.Read(_sampleBuffer, 0, (int)byteCount) != byteCount)
|
if (_IO.Read(_sampleBuffer, 0, (int)byteCount) != byteCount)
|
||||||
throw new Exception("Incomplete file read.");
|
throw new Exception("Incomplete file read.");
|
||||||
AudioCodecsDotNet.BytesToFLACSamples_16 (_sampleBuffer, 0, buff, 0,
|
AudioCodecsDotNet.BytesToFLACSamples_16 (_sampleBuffer, 0, buff, 0,
|
||||||
sampleCount, _channelCount);
|
sampleCount, _channelCount);
|
||||||
@@ -493,7 +494,7 @@ namespace AudioCodecsDotNet
|
|||||||
|
|
||||||
public class WAVWriter : IAudioDest
|
public class WAVWriter : IAudioDest
|
||||||
{
|
{
|
||||||
FileStream _fs;
|
FileStream _IO;
|
||||||
BinaryWriter _bw;
|
BinaryWriter _bw;
|
||||||
int _bitsPerSample, _channelCount, _sampleRate, _blockAlign;
|
int _bitsPerSample, _channelCount, _sampleRate, _blockAlign;
|
||||||
long _sampleLen;
|
long _sampleLen;
|
||||||
@@ -508,8 +509,8 @@ namespace AudioCodecsDotNet
|
|||||||
_sampleRate = sampleRate;
|
_sampleRate = sampleRate;
|
||||||
_blockAlign = _channelCount * ((_bitsPerSample + 7) / 8);
|
_blockAlign = _channelCount * ((_bitsPerSample + 7) / 8);
|
||||||
|
|
||||||
_fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read);
|
_IO = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read);
|
||||||
_bw = new BinaryWriter(_fs);
|
_bw = new BinaryWriter(_IO);
|
||||||
|
|
||||||
WriteHeaders();
|
WriteHeaders();
|
||||||
}
|
}
|
||||||
@@ -571,7 +572,7 @@ namespace AudioCodecsDotNet
|
|||||||
_bw.Close();
|
_bw.Close();
|
||||||
|
|
||||||
_bw = null;
|
_bw = null;
|
||||||
_fs = null;
|
_IO = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long Position
|
public long Position
|
||||||
@@ -597,7 +598,7 @@ namespace AudioCodecsDotNet
|
|||||||
_sampleBuffer = new byte[sampleCount * _blockAlign];
|
_sampleBuffer = new byte[sampleCount * _blockAlign];
|
||||||
AudioCodecsDotNet.FLACSamplesToBytes(buff, 0, _sampleBuffer, 0,
|
AudioCodecsDotNet.FLACSamplesToBytes(buff, 0, _sampleBuffer, 0,
|
||||||
sampleCount, _channelCount, _bitsPerSample);
|
sampleCount, _channelCount, _bitsPerSample);
|
||||||
_fs.Write(_sampleBuffer, 0, (int)sampleCount * _blockAlign);
|
_IO.Write(_sampleBuffer, 0, (int)sampleCount * _blockAlign);
|
||||||
_sampleLen += sampleCount;
|
_sampleLen += sampleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ namespace CUEToolsLib {
|
|||||||
public static IAudioSource GetAudioSource(string path) {
|
public static IAudioSource GetAudioSource(string path) {
|
||||||
switch (Path.GetExtension(path).ToLower()) {
|
switch (Path.GetExtension(path).ToLower()) {
|
||||||
case ".wav":
|
case ".wav":
|
||||||
return new WAVReader(path);
|
return new WAVReader(path, null);
|
||||||
#if !MONO
|
#if !MONO
|
||||||
case ".flac":
|
case ".flac":
|
||||||
return new FLACReader(path);
|
return new FLACReader(path, null);
|
||||||
case ".wv":
|
case ".wv":
|
||||||
return new WavPackReader(path);
|
return new WavPackReader(path);
|
||||||
case ".ape":
|
case ".ape":
|
||||||
@@ -32,6 +32,8 @@ namespace CUEToolsLib {
|
|||||||
{
|
{
|
||||||
switch (Path.GetExtension(path).ToLower())
|
switch (Path.GetExtension(path).ToLower())
|
||||||
{
|
{
|
||||||
|
case ".wav":
|
||||||
|
return new WAVReader(path, IO);
|
||||||
#if !MONO
|
#if !MONO
|
||||||
case ".flac":
|
case ".flac":
|
||||||
return new FLACReader(path, IO);
|
return new FLACReader(path, IO);
|
||||||
@@ -70,12 +72,6 @@ namespace CUEToolsLib {
|
|||||||
int[,] _sampleBuffer;
|
int[,] _sampleBuffer;
|
||||||
uint _bufferOffset, _bufferLength;
|
uint _bufferOffset, _bufferLength;
|
||||||
|
|
||||||
public FLACReader(string path) {
|
|
||||||
_flacReader = new FLACDotNet.FLACReader(path, null);
|
|
||||||
_bufferOffset = 0;
|
|
||||||
_bufferLength = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FLACReader(string path, Stream IO)
|
public FLACReader(string path, Stream IO)
|
||||||
{
|
{
|
||||||
_flacReader = new FLACDotNet.FLACReader(path, IO);
|
_flacReader = new FLACDotNet.FLACReader(path, IO);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace UnRarDotNet
|
|||||||
_buffer = null;
|
_buffer = null;
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
_length = 0;
|
_length = 0;
|
||||||
|
_pos = 0;
|
||||||
_unrar.PasswordRequired += new PasswordRequiredHandler(unrar_PasswordRequired);
|
_unrar.PasswordRequired += new PasswordRequiredHandler(unrar_PasswordRequired);
|
||||||
_unrar.DataAvailable += new DataAvailableHandler(unrar_DataAvailable);
|
_unrar.DataAvailable += new DataAvailableHandler(unrar_DataAvailable);
|
||||||
_unrar.Open(archive, Unrar.OpenMode.Extract);
|
_unrar.Open(archive, Unrar.OpenMode.Extract);
|
||||||
@@ -35,7 +36,7 @@ namespace UnRarDotNet
|
|||||||
}
|
}
|
||||||
public override bool CanSeek
|
public override bool CanSeek
|
||||||
{
|
{
|
||||||
get { return false; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
public override bool CanWrite
|
public override bool CanWrite
|
||||||
{
|
{
|
||||||
@@ -43,11 +44,21 @@ namespace UnRarDotNet
|
|||||||
}
|
}
|
||||||
public override long Length
|
public override long Length
|
||||||
{
|
{
|
||||||
get { throw new NotSupportedException(); }
|
get
|
||||||
|
{
|
||||||
|
lock (this)
|
||||||
|
{
|
||||||
|
while (_size == null && !_stop)
|
||||||
|
Monitor.Wait(this);
|
||||||
|
}
|
||||||
|
if (_size == null)
|
||||||
|
throw new NotSupportedException();
|
||||||
|
return _size.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public override long Position
|
public override long Position
|
||||||
{
|
{
|
||||||
get { throw new NotSupportedException(); }
|
get { return _pos; }
|
||||||
set { Seek(value, SeekOrigin.Begin); }
|
set { Seek(value, SeekOrigin.Begin); }
|
||||||
}
|
}
|
||||||
public override void Close()
|
public override void Close()
|
||||||
@@ -57,9 +68,16 @@ namespace UnRarDotNet
|
|||||||
_stop = true;
|
_stop = true;
|
||||||
Monitor.Pulse(this);
|
Monitor.Pulse(this);
|
||||||
}
|
}
|
||||||
|
if (_workThread != null)
|
||||||
|
{
|
||||||
_workThread.Join();
|
_workThread.Join();
|
||||||
_workThread = null;
|
_workThread = null;
|
||||||
|
}
|
||||||
|
if (_unrar != null)
|
||||||
|
{
|
||||||
_unrar.Close();
|
_unrar.Close();
|
||||||
|
_unrar = null;
|
||||||
|
}
|
||||||
base.Close();
|
base.Close();
|
||||||
}
|
}
|
||||||
public override void Flush()
|
public override void Flush()
|
||||||
@@ -81,16 +99,34 @@ namespace UnRarDotNet
|
|||||||
Monitor.Wait(this);
|
Monitor.Wait(this);
|
||||||
if (_buffer == null)
|
if (_buffer == null)
|
||||||
return total;
|
return total;
|
||||||
|
if (_seek_to != null)
|
||||||
|
{
|
||||||
|
if (_seek_to.Value < _pos)
|
||||||
|
throw new NotSupportedException();
|
||||||
|
if (_length <= _seek_to.Value - _pos)
|
||||||
|
{
|
||||||
|
_pos += _length;
|
||||||
|
_buffer = null;
|
||||||
|
Monitor.Pulse(this);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_offset += (int)(_seek_to.Value - _pos);
|
||||||
|
_length -= (int)(_seek_to.Value - _pos);
|
||||||
|
_pos = _seek_to.Value;
|
||||||
|
_seek_to = null;
|
||||||
|
}
|
||||||
if (_length > count)
|
if (_length > count)
|
||||||
{
|
{
|
||||||
Array.Copy(_buffer, _offset, array, offset, count);
|
Array.Copy(_buffer, _offset, array, offset, count);
|
||||||
total += count;
|
total += count;
|
||||||
|
_pos += count;
|
||||||
_offset += count;
|
_offset += count;
|
||||||
_length -= count;
|
_length -= count;
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
Array.Copy(_buffer, _offset, array, offset, _length);
|
Array.Copy(_buffer, _offset, array, offset, _length);
|
||||||
total += _length;
|
total += _length;
|
||||||
|
_pos += _length;
|
||||||
offset += _length;
|
offset += _length;
|
||||||
count -= _length;
|
count -= _length;
|
||||||
_buffer = null;
|
_buffer = null;
|
||||||
@@ -101,7 +137,31 @@ namespace UnRarDotNet
|
|||||||
}
|
}
|
||||||
public override long Seek(long offset, SeekOrigin origin)
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
{
|
{
|
||||||
|
lock (this)
|
||||||
|
{
|
||||||
|
while (_size == null && !_stop)
|
||||||
|
Monitor.Wait(this);
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public override void Write(byte[] array, int offset, int count)
|
public override void Write(byte[] array, int offset, int count)
|
||||||
{
|
{
|
||||||
@@ -114,6 +174,9 @@ namespace UnRarDotNet
|
|||||||
private bool _stop;
|
private bool _stop;
|
||||||
private byte[] _buffer;
|
private byte[] _buffer;
|
||||||
int _offset, _length;
|
int _offset, _length;
|
||||||
|
long? _size;
|
||||||
|
long? _seek_to;
|
||||||
|
long _pos;
|
||||||
|
|
||||||
private void unrar_PasswordRequired(object sender, PasswordRequiredEventArgs e)
|
private void unrar_PasswordRequired(object sender, PasswordRequiredEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -149,13 +212,12 @@ namespace UnRarDotNet
|
|||||||
{
|
{
|
||||||
if (_unrar.CurrentFile.FileName == _fileName)
|
if (_unrar.CurrentFile.FileName == _fileName)
|
||||||
{
|
{
|
||||||
// unrar.CurrentFile.UnpackedSize;
|
|
||||||
_unrar.Test();
|
|
||||||
lock (this)
|
lock (this)
|
||||||
{
|
{
|
||||||
_stop = true;
|
_size = _unrar.CurrentFile.UnpackedSize;
|
||||||
Monitor.Pulse(this);
|
Monitor.Pulse(this);
|
||||||
}
|
}
|
||||||
|
_unrar.Test();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -165,6 +227,11 @@ namespace UnRarDotNet
|
|||||||
//catch (StopExtractionException)
|
//catch (StopExtractionException)
|
||||||
//{
|
//{
|
||||||
//}
|
//}
|
||||||
|
lock (this)
|
||||||
|
{
|
||||||
|
_stop = true;
|
||||||
|
Monitor.Pulse(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user