WAV can also be read from RAR archive

This commit is contained in:
chudov
2008-11-10 09:31:14 +00:00
parent e028a4d1e8
commit df34997334
3 changed files with 104 additions and 40 deletions

View File

@@ -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;
} }

View File

@@ -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);

View File

@@ -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);
}
} }
} }
} }