diff --git a/APEDotNet/APEDotNet.vcproj b/APEDotNet/APEDotNet.vcproj
index f474f1a..c35b71c 100644
--- a/APEDotNet/APEDotNet.vcproj
+++ b/APEDotNet/APEDotNet.vcproj
@@ -337,6 +337,10 @@
ReferencedProjectIdentifier="{CA200BCB-DFC6-4153-9BD4-785BC768B26B}"
RelativePathToProject="..\APETagDotNet\APETagDotNet.csproj"
/>
+
GetInfo (APE_INFO_BLOCK_ALIGN, 0, 0);
- pBuffer = new unsigned char [16384 * nBlockAlign];
+ _samplesBuffer = gcnew array (16384 * nBlockAlign);
// loop through the whole file
_sampleCount = pAPEDecompress->GetInfo (APE_DECOMPRESS_TOTAL_BLOCKS, 0, 0); // * ?
@@ -137,7 +140,6 @@ namespace APEDotNet {
~APEReader ()
{
- if (pBuffer) delete [] pBuffer;
if (_winFileIO)
delete _winFileIO;
if (_gchIO.IsAllocated)
@@ -146,50 +148,57 @@ namespace APEDotNet {
_gchReadBuffer.Free();
}
- property Int32 BitsPerSample {
+ virtual property Int32 BitsPerSample {
Int32 get() {
return _bitsPerSample;
}
}
- property Int32 ChannelCount {
+ virtual property Int32 ChannelCount {
Int32 get() {
return _channelCount;
}
}
- property Int32 SampleRate {
+ virtual property Int32 SampleRate {
Int32 get() {
return _sampleRate;
}
}
- property Int64 Length {
- Int64 get() {
+ virtual property UInt64 Length {
+ UInt64 get() {
return _sampleCount;
}
}
- property Int64 Position {
- Int64 get() {
- return _sampleOffset;
+ virtual property UInt64 Position
+ {
+ UInt64 get() {
+ return _sampleOffset - SamplesInBuffer;
}
- void set(Int64 offset) {
+ void set(UInt64 offset) {
_sampleOffset = offset;
+ _bufferOffset = 0;
+ _bufferLength = 0;
if (pAPEDecompress->Seek ((int) offset /*? */))
throw gcnew Exception("Unable to seek.");
}
}
- property Int64 Remaining {
- Int64 get() {
- return _sampleCount - _sampleOffset;
+ virtual property UInt64 Remaining {
+ UInt64 get() {
+ return _sampleCount - _sampleOffset + SamplesInBuffer;
}
}
- void Close() {
- if (pAPEDecompress) delete pAPEDecompress;
- pAPEDecompress = NULL;
+ virtual void Close()
+ {
+ if (pAPEDecompress)
+ {
+ delete pAPEDecompress;
+ pAPEDecompress = NULL;
+ }
if (_IO != nullptr)
{
_IO->Close ();
@@ -197,14 +206,15 @@ namespace APEDotNet {
}
}
- property String^ Path {
+ virtual property String^ Path {
String^ get() {
return _path;
}
}
- property NameValueCollection^ Tags {
- NameValueCollection^ get () {
+ virtual property NameValueCollection^ Tags {
+ NameValueCollection^ get ()
+ {
if (!_tags)
{
APETagDotNet^ apeTag = gcnew APETagDotNet (_IO, true);
@@ -213,33 +223,35 @@ namespace APEDotNet {
}
return _tags;
}
- void set (NameValueCollection ^tags) {
+ void set (NameValueCollection ^tags)
+ {
_tags = tags;
}
}
- Int32 Read([Out] array^% sampleBuffer) {
- int sampleCount;
-
- int nBlocksRetrieved;
- if (pAPEDecompress->GetData ((char *) pBuffer, 16384, &nBlocksRetrieved))
- throw gcnew Exception("An error occurred while decoding.");
-
- sampleCount = nBlocksRetrieved;
- array^ _sampleBuffer = gcnew array (nBlocksRetrieved, 2);
- interior_ptr pMyBuffer = &_sampleBuffer[0, 0];
-
- short * pAPEBuffer = (short *) pBuffer;
- short * pAPEBufferEnd = (short *) pBuffer + 2 * nBlocksRetrieved;
-
- while (pAPEBuffer < pAPEBufferEnd) {
- *(pMyBuffer++) = *(pAPEBuffer++);
- *(pMyBuffer++) = *(pAPEBuffer++);
- }
-
- sampleBuffer = _sampleBuffer;
- _sampleOffset += nBlocksRetrieved;
+ virtual UInt32 Read([Out] array^ buff, UInt32 sampleCount)
+ {
+ UInt32 buffOffset = 0;
+ UInt32 samplesNeeded = sampleCount;
+ while (samplesNeeded != 0)
+ {
+ if (SamplesInBuffer == 0)
+ {
+ int nBlocksRetrieved;
+ pin_ptr pSampleBuffer = &_samplesBuffer[0];
+ if (pAPEDecompress->GetData ((char *) pSampleBuffer, 16384, &nBlocksRetrieved))
+ throw gcnew Exception("An error occurred while decoding.");
+ _bufferOffset = 0;
+ _bufferLength = nBlocksRetrieved;
+ _sampleOffset += nBlocksRetrieved;
+ }
+ UInt32 copyCount = Math::Min(samplesNeeded, SamplesInBuffer);
+ AudioSamples::BytesToFLACSamples_16(_samplesBuffer, _bufferOffset*nBlockAlign, buff, buffOffset, copyCount, _channelCount);
+ samplesNeeded -= copyCount;
+ buffOffset += copyCount;
+ _bufferOffset += copyCount;
+ }
return sampleCount;
}
@@ -249,22 +261,33 @@ namespace APEDotNet {
NameValueCollection^ _tags;
Int64 _sampleCount, _sampleOffset;
Int32 _bitsPerSample, _channelCount, _sampleRate;
+ UInt32 _bufferOffset, _bufferLength;
int nBlockAlign;
- unsigned char * pBuffer;
+ array^ _samplesBuffer;
String^ _path;
Stream^ _IO;
array^ _readBuffer;
CWinFileIO* _winFileIO;
GCHandle _gchIO, _gchReadBuffer;
+
+ property UInt32 SamplesInBuffer
+ {
+ UInt32 get ()
+ {
+ return (UInt32) (_bufferLength - _bufferOffset);
+ }
+ }
};
- public ref class APEWriter {
+ public ref class APEWriter : IAudioDest
+ {
public:
- APEWriter(String^ path, Int32 bitsPerSample, Int32 channelCount, Int32 sampleRate) {
-
- if ((channelCount != 1) && (channelCount != 2)) {
+ APEWriter(String^ path, Int32 bitsPerSample, Int32 channelCount, Int32 sampleRate)
+ {
+ if (bitsPerSample != 16 && bitsPerSample != 24)
+ throw gcnew Exception("Bits per sample must be 16 or 24.");
+ if (channelCount != 1 && channelCount != 2)
throw gcnew Exception("Only stereo and mono audio formats are allowed.");
- }
_path = path;
_tags = gcnew NameValueCollection();
@@ -279,9 +302,8 @@ namespace APEDotNet {
int nRetVal;
pAPECompress = CreateIAPECompress (&nRetVal);
- if (!pAPECompress) {
- throw gcnew Exception("Unable to open file.");
- }
+ if (!pAPECompress)
+ throw gcnew Exception("Unable to open APE compressor.");
}
~APEWriter()
@@ -294,7 +316,8 @@ namespace APEDotNet {
_gchBuffer.Free();
}
- void Close() {
+ virtual void Close()
+ {
if (pAPECompress)
{
pAPECompress->Finish (NULL, 0, 0);
@@ -322,21 +345,47 @@ namespace APEDotNet {
}
}
- property Int32 FinalSampleCount {
- Int32 get() {
+ virtual property Int64 FinalSampleCount
+ {
+ Int64 get()
+ {
return _finalSampleCount;
}
- void set(Int32 value) {
- if (value < 0) {
+ void set(Int64 value)
+ {
+ if (value < 0)
throw gcnew Exception("Invalid final sample count.");
- }
- if (_initialized) {
+ if (_initialized)
throw gcnew Exception("Final sample count cannot be changed after encoding begins.");
- }
_finalSampleCount = value;
}
}
+ virtual void Write(array^ buff, UInt32 sampleCount)
+ {
+ if (_sampleBuffer == nullptr || _sampleBuffer.Length < sampleCount * _blockAlign)
+ _sampleBuffer = gcnew array(sampleCount * _blockAlign);
+ AudioSamples::FLACSamplesToBytes(buff, 0, _sampleBuffer, 0, sampleCount, _channelCount, _bitsPerSample);
+ if (!_initialized) Initialize();
+ pin_ptr pSampleBuffer = &_sampleBuffer[0];
+ if (pAPECompress->AddData (pSampleBuffer, sampleCount * _blockAlign))
+ throw gcnew Exception("An error occurred while encoding.");
+ _samplesWritten += sampleCount;
+ }
+
+ virtual property String^ Path
+ {
+ String^ get() {
+ return _path;
+ }
+ }
+
+ virtual bool SetTags (NameValueCollection^ tags)
+ {
+ _tags = tags;
+ return true;
+ }
+
property Int32 CompressionLevel {
Int32 get() {
return _compressionLevel;
@@ -349,24 +398,6 @@ namespace APEDotNet {
}
}
- void Write(array^ sampleBuffer, UInt32 sampleCount) {
- if (!_initialized) Initialize();
- pin_ptr pSampleBuffer = &sampleBuffer[0];
- if (pAPECompress->AddData (pSampleBuffer, sampleCount * _blockAlign))
- throw gcnew Exception("An error occurred while encoding.");
- _samplesWritten += sampleCount;
- }
-
- property String^ Path {
- String^ get() {
- return _path;
- }
- }
-
- void SetTags (NameValueCollection^ tags) {
- _tags = tags;
- }
-
private:
IAPECompress * pAPECompress;
bool _initialized;
@@ -379,6 +410,7 @@ namespace APEDotNet {
GCHandle _gchIO, _gchBuffer;
CWinFileIO* _winFileIO;
array^ _writeBuffer;
+ array^ _sampleBuffer;
void Initialize() {
_IO = gcnew FileStream (_path, FileMode::Create, FileAccess::ReadWrite, FileShare::Read);
@@ -408,7 +440,10 @@ namespace APEDotNet {
{
array^ buff = (array^) _gchBuffer.Target;
if (buff->Length < nBytesToRead)
+ {
Array::Resize (buff, nBytesToRead);
+ _gchBuffer.Target = buff;
+ }
int len = ((Stream^)_gchIO.Target)->Read (buff, 0, nBytesToRead);
if (len) Marshal::Copy (buff, 0, (IntPtr)pBuffer, len);
*pBytesRead = len;
@@ -419,7 +454,10 @@ namespace APEDotNet {
{
array^ buff = (array^) _gchBuffer.Target;
if (buff->Length < nBytesToWrite)
+ {
Array::Resize (buff, nBytesToWrite);
+ _gchBuffer.Target = buff;
+ }
Marshal::Copy ((IntPtr)(void*)pBuffer, buff, 0, nBytesToWrite);
((Stream^)_gchIO.Target)->Write (buff, 0, nBytesToWrite);
*pBytesWritten = nBytesToWrite;
diff --git a/AudioCodecsDotNet/AudioCodecsDotNet.cs b/AudioCodecsDotNet/AudioCodecsDotNet.cs
index 3be1f7f..59e5463 100644
--- a/AudioCodecsDotNet/AudioCodecsDotNet.cs
+++ b/AudioCodecsDotNet/AudioCodecsDotNet.cs
@@ -29,7 +29,7 @@ namespace AudioCodecsDotNet
string Path { get; }
}
- public class AudioCodecsDotNet
+ public class AudioSamples
{
public static unsafe void FLACSamplesToBytes_16(int[,] inSamples, uint inSampleOffset,
byte[] outSamples, uint outByteOffset, uint sampleCount, int channelCount)
@@ -92,9 +92,9 @@ namespace AudioCodecsDotNet
byte[] outSamples, uint outByteOffset, uint sampleCount, int channelCount, int bitsPerSample)
{
if (bitsPerSample == 16)
- AudioCodecsDotNet.FLACSamplesToBytes_16(inSamples, inSampleOffset, outSamples, outByteOffset, sampleCount, channelCount);
+ AudioSamples.FLACSamplesToBytes_16(inSamples, inSampleOffset, outSamples, outByteOffset, sampleCount, channelCount);
else if (bitsPerSample == 24)
- AudioCodecsDotNet.FLACSamplesToBytes_24(inSamples, inSampleOffset, outSamples, outByteOffset, sampleCount, channelCount);
+ AudioSamples.FLACSamplesToBytes_24(inSamples, inSampleOffset, outSamples, outByteOffset, sampleCount, channelCount);
else
throw new Exception("Unsupported bitsPerSample value");
}
@@ -483,7 +483,7 @@ namespace AudioCodecsDotNet
_sampleBuffer = new byte[byteCount];
if (_IO.Read(_sampleBuffer, 0, (int)byteCount) != byteCount)
throw new Exception("Incomplete file read.");
- AudioCodecsDotNet.BytesToFLACSamples_16 (_sampleBuffer, 0, buff, 0,
+ AudioSamples.BytesToFLACSamples_16(_sampleBuffer, 0, buff, 0,
sampleCount, _channelCount);
_samplePos += sampleCount;
return sampleCount;
@@ -596,7 +596,7 @@ namespace AudioCodecsDotNet
return;
if (_sampleBuffer == null || _sampleBuffer.Length < sampleCount * _blockAlign)
_sampleBuffer = new byte[sampleCount * _blockAlign];
- AudioCodecsDotNet.FLACSamplesToBytes(buff, 0, _sampleBuffer, 0,
+ AudioSamples.FLACSamplesToBytes(buff, 0, _sampleBuffer, 0,
sampleCount, _channelCount, _bitsPerSample);
_IO.Write(_sampleBuffer, 0, (int)sampleCount * _blockAlign);
_sampleLen += sampleCount;
diff --git a/CUEToolsLib/AudioReadWrite.cs b/CUEToolsLib/AudioReadWrite.cs
index e699c87..edea85d 100644
--- a/CUEToolsLib/AudioReadWrite.cs
+++ b/CUEToolsLib/AudioReadWrite.cs
@@ -53,500 +53,4 @@ namespace CUEToolsLib {
return dest;
}
}
-
-#if !MONO
- class FLACReader : IAudioSource {
- FLACDotNet.FLACReader _flacReader;
- int[,] _sampleBuffer;
- uint _bufferOffset, _bufferLength;
-
- public FLACReader(string path, Stream IO)
- {
- _flacReader = new FLACDotNet.FLACReader(path, IO);
- _bufferOffset = 0;
- _bufferLength = 0;
- }
-
- public void Close() {
- _flacReader.Close();
- }
-
- public NameValueCollection Tags
- {
- get { return _flacReader.Tags; }
- set { _flacReader.Tags = value; }
- }
-
- public bool UpdateTags(bool preserveTime)
- {
- return _flacReader.UpdateTags(preserveTime);
- }
-
- public ulong Length {
- get {
- return (ulong) _flacReader.Length;
- }
- }
-
- public ulong Remaining {
- get {
- return (ulong) _flacReader.Remaining + SamplesInBuffer;
- }
- }
-
- public ulong Position {
- get {
- return (ulong) _flacReader.Position - SamplesInBuffer;
- }
- set {
- _flacReader.Position = (long) value;
- _bufferOffset = 0;
- _bufferLength = 0;
- }
- }
-
- private uint SamplesInBuffer {
- get {
- return (uint) (_bufferLength - _bufferOffset);
- }
- }
-
- public int BitsPerSample {
- get {
- return _flacReader.BitsPerSample;
- }
- }
-
- public int ChannelCount {
- get {
- return _flacReader.ChannelCount;
- }
- }
-
- public int SampleRate {
- get {
- return _flacReader.SampleRate;
- }
- }
-
- public uint Read(int [,] buff, uint sampleCount) {
- if (_flacReader.BitsPerSample != 16) {
- throw new Exception("Reading is only supported for 16 bit sample depth.");
- }
- int chanCount = _flacReader.ChannelCount;
- uint copyCount;
- uint buffOffset = 0;
- uint samplesNeeded = sampleCount;
-
- while (samplesNeeded != 0) {
- if (SamplesInBuffer == 0) {
- _bufferOffset = 0;
- _bufferLength = (uint) _flacReader.Read(out _sampleBuffer);
- }
-
- copyCount = Math.Min(samplesNeeded, SamplesInBuffer);
- Array.Copy(_sampleBuffer, _bufferOffset * chanCount, buff, buffOffset * chanCount, copyCount * chanCount);
-
- samplesNeeded -= copyCount;
- buffOffset += copyCount;
- _bufferOffset += copyCount;
- }
-
- return sampleCount;
- }
-
- public string Path { get { return _flacReader.Path; } }
- }
-
- class FLACWriter : IAudioDest {
- FLACDotNet.FLACWriter _flacWriter;
- int _bitsPerSample;
- int _channelCount;
- int _sampleRate;
-
- public FLACWriter(string path, int bitsPerSample, int channelCount, int sampleRate) {
- if (bitsPerSample != 16 && bitsPerSample != 24) {
- throw new Exception("Bits per sample must be 16 or 24.");
- }
- _bitsPerSample = bitsPerSample;
- _channelCount = channelCount;
- _sampleRate = sampleRate;
- _flacWriter = new FLACDotNet.FLACWriter(path, bitsPerSample, channelCount, sampleRate);
- }
-
- public long FinalSampleCount {
- get {
- return _flacWriter.FinalSampleCount;
- }
- set {
- _flacWriter.FinalSampleCount = value;
- }
- }
-
- public int CompressionLevel {
- get {
- return _flacWriter.CompressionLevel;
- }
- set {
- _flacWriter.CompressionLevel = value;
- }
- }
-
- public bool Verify {
- get {
- return _flacWriter.Verify;
- }
- set {
- _flacWriter.Verify = value;
- }
- }
-
- public bool SetTags(NameValueCollection tags)
- {
- _flacWriter.SetTags (tags);
- return true;
- }
-
- public void Close() {
- _flacWriter.Close();
- }
-
- public void Write(int[,] buff, uint sampleCount)
- {
- _flacWriter.Write(buff, (int) sampleCount);
- }
-
- public string Path { get { return _flacWriter.Path; } }
- }
-#endif
-
-#if !MONO
- class APEReader : IAudioSource {
- APEDotNet.APEReader _apeReader;
- int[,] _sampleBuffer;
- uint _bufferOffset, _bufferLength;
-
- public APEReader(string path, Stream IO) {
- _apeReader = new APEDotNet.APEReader(path, IO);
- _bufferOffset = 0;
- _bufferLength = 0;
- }
-
- public void Close() {
- _apeReader.Close();
- }
-
- public ulong Length {
- get {
- return (ulong) _apeReader.Length;
- }
- }
-
- public ulong Remaining {
- get {
- return (ulong) _apeReader.Remaining + SamplesInBuffer;
- }
- }
-
- public ulong Position {
- get {
- return (ulong) _apeReader.Position - SamplesInBuffer;
- }
- set {
- _apeReader.Position = (long) value;
- _bufferOffset = 0;
- _bufferLength = 0;
- }
- }
-
- private uint SamplesInBuffer {
- get {
- return (uint) (_bufferLength - _bufferOffset);
- }
- }
-
- public int BitsPerSample {
- get {
- return _apeReader.BitsPerSample;
- }
- }
-
- public int ChannelCount {
- get {
- return _apeReader.ChannelCount;
- }
- }
-
- public int SampleRate {
- get {
- return _apeReader.SampleRate;
- }
- }
-
- public NameValueCollection Tags
- {
- get { return _apeReader.Tags; }
- set { _apeReader.Tags = value; }
- }
-
- private unsafe void APESamplesToFLACSamples(int[,] inSamples, uint inSampleOffset,
- int[,] outSamples, uint outSampleOffset, uint sampleCount, int channelCount)
- {
- uint loopCount = sampleCount * (uint) channelCount;
-
- if ((inSamples.GetLength(0) - inSampleOffset < sampleCount) ||
- (outSamples.GetLength(0) - outSampleOffset < sampleCount))
- {
- throw new IndexOutOfRangeException();
- }
-
- fixed (int* pInSamplesFixed = &inSamples[inSampleOffset, 0]) {
- fixed (int * pOutSamplesFixed = &outSamples[outSampleOffset, 0]) {
- int* pInSamples = pInSamplesFixed;
- int* pOutSamples = pOutSamplesFixed;
-
- for (int i = 0; i < loopCount; i++) {
- *(pOutSamples++) = *(pInSamples++);
- }
- }
- }
- }
-
- public uint Read(int[,] buff, uint sampleCount) {
- if (_apeReader.BitsPerSample != 16) {
- throw new Exception("Reading is only supported for 16 bit sample depth.");
- }
- int chanCount = _apeReader.ChannelCount;
- uint samplesNeeded, copyCount, buffOffset;
-
- buffOffset = 0;
- samplesNeeded = sampleCount;
-
- while (samplesNeeded != 0) {
- if (SamplesInBuffer == 0) {
- _bufferOffset = 0;
- _bufferLength = (uint) _apeReader.Read(out _sampleBuffer);
- }
-
- copyCount = Math.Min(samplesNeeded, SamplesInBuffer);
-
-
- Array.Copy(_sampleBuffer, _bufferOffset * chanCount, buff, buffOffset * chanCount, copyCount * chanCount);
- //APESamplesToFLACSamples(_sampleBuffer, _bufferOffset, buff, buffOffset,
- // copyCount, chanCount);
-
- samplesNeeded -= copyCount;
- buffOffset += copyCount;
- _bufferOffset += copyCount;
- }
-
- return sampleCount;
- }
-
- public string Path { get { return _apeReader.Path; } }
- }
-
- class APEWriter : IAudioDest
- {
- APEDotNet.APEWriter _apeWriter;
- byte[] _sampleBuffer;
- int _bitsPerSample;
- int _channelCount;
- int _sampleRate;
- int _blockAlign;
-
- public APEWriter(string path, int bitsPerSample, int channelCount, int sampleRate)
- {
- if (bitsPerSample != 16 && bitsPerSample != 24)
- {
- throw new Exception("Bits per sample must be 16 or 24.");
- }
- _bitsPerSample = bitsPerSample;
- _channelCount = channelCount;
- _sampleRate = sampleRate;
- _blockAlign = _channelCount * ((_bitsPerSample + 7) / 8);
- _apeWriter = new APEDotNet.APEWriter(path, bitsPerSample, channelCount, sampleRate);
- }
-
- public long FinalSampleCount
- {
- get { return _apeWriter.FinalSampleCount; }
- set { _apeWriter.FinalSampleCount = (int) value; }
- }
- public int CompressionLevel
- {
- get { return _apeWriter.CompressionLevel; }
- set { _apeWriter.CompressionLevel = value; }
- }
- public bool SetTags(NameValueCollection tags)
- {
- _apeWriter.SetTags(tags);
- return true;
- }
- public void Close()
- {
- _apeWriter.Close();
- }
- public void Write(int [,] buff, uint sampleCount)
- {
- if (_sampleBuffer == null || _sampleBuffer.Length < sampleCount * _blockAlign)
- _sampleBuffer = new byte[sampleCount * _blockAlign];
- AudioCodecsDotNet.AudioCodecsDotNet.FLACSamplesToBytes (buff, 0, _sampleBuffer, 0, sampleCount, _channelCount, _bitsPerSample);
- _apeWriter.Write(_sampleBuffer, sampleCount);
- }
- public string Path { get { return _apeWriter.Path; } }
- }
-#endif
-
-#if !MONO
- class WavPackReader : IAudioSource {
- WavPackDotNet.WavPackReader _wavPackReader;
-
- public WavPackReader(string path, Stream IO, Stream IO_WVC) {
- _wavPackReader = new WavPackDotNet.WavPackReader(path, IO, IO_WVC);
- }
-
- public void Close() {
- _wavPackReader.Close();
- }
-
- public ulong Length {
- get {
- return (ulong) _wavPackReader.Length;
- }
- }
-
- public ulong Remaining {
- get {
- return (ulong) _wavPackReader.Remaining;
- }
- }
-
- public ulong Position {
- get {
- return (ulong) _wavPackReader.Position;
- }
- set {
- _wavPackReader.Position = (int) value;
- }
- }
-
- public int BitsPerSample {
- get {
- return _wavPackReader.BitsPerSample;
- }
- }
-
- public int ChannelCount {
- get {
- return _wavPackReader.ChannelCount;
- }
- }
-
- public int SampleRate {
- get {
- return _wavPackReader.SampleRate;
- }
- }
-
- public NameValueCollection Tags
- {
- get { return _wavPackReader.Tags; }
- set { _wavPackReader.Tags = value; }
- }
-
- public uint Read(int[,] buff, uint sampleCount) {
- if (_wavPackReader.BitsPerSample != 16) {
- throw new Exception("Reading is only supported for 16 bit sample depth.");
- }
- _wavPackReader.Read(buff, (int) sampleCount);
- return sampleCount;
- }
-
- public string Path { get { return _wavPackReader.Path; } }
- }
-
- class WavPackWriter : IAudioDest {
- WavPackDotNet.WavPackWriter _wavPackWriter;
- int _bitsPerSample;
- int _channelCount;
- int _sampleRate;
- int _blockAlign;
- byte[] _sampleBuffer;
-
- public WavPackWriter(string path, int bitsPerSample, int channelCount, int sampleRate) {
- if (bitsPerSample != 16 && bitsPerSample != 24)
- {
- throw new Exception("Bits per sample must be 16 or 24.");
- }
- _bitsPerSample = bitsPerSample;
- _channelCount = channelCount;
- _sampleRate = sampleRate;
- _blockAlign = _channelCount * ((_bitsPerSample + 7) / 8);
- _wavPackWriter = new WavPackDotNet.WavPackWriter(path, bitsPerSample, channelCount, sampleRate);
- }
-
- public bool SetTags(NameValueCollection tags)
- {
- _wavPackWriter.SetTags(tags);
- return true;
- }
-
- public long FinalSampleCount {
- get {
- return _wavPackWriter.FinalSampleCount;
- }
- set {
- _wavPackWriter.FinalSampleCount = (int)value;
- }
- }
-
- public int CompressionMode {
- get {
- return _wavPackWriter.CompressionMode;
- }
- set {
- _wavPackWriter.CompressionMode = value;
- }
- }
-
- public int ExtraMode {
- get {
- return _wavPackWriter.ExtraMode;
- }
- set {
- _wavPackWriter.ExtraMode = value;
- }
- }
-
- public bool MD5Sum
- {
- get
- {
- return _wavPackWriter.MD5Sum;
- }
- set
- {
- _wavPackWriter.MD5Sum = value;
- }
- }
-
- public void Close() {
- _wavPackWriter.Close();
- }
-
- public void Write(int[,] sampleBuffer, uint sampleCount) {
- if (MD5Sum)
- {
- if (_sampleBuffer == null || _sampleBuffer.Length < sampleCount * _blockAlign)
- _sampleBuffer = new byte[sampleCount * _blockAlign];
- AudioCodecsDotNet.AudioCodecsDotNet.FLACSamplesToBytes(sampleBuffer, 0, _sampleBuffer, 0, sampleCount, _channelCount, _bitsPerSample);
- _wavPackWriter.UpdateHash(_sampleBuffer, (int) sampleCount * _blockAlign);
- }
- _wavPackWriter.Write(sampleBuffer, (int) sampleCount);
- }
-
- public string Path { get { return _wavPackWriter.Path; } }
- }
-#endif
}
\ No newline at end of file
diff --git a/CUEToolsLib/Main.cs b/CUEToolsLib/Main.cs
index 408984b..c306a83 100644
--- a/CUEToolsLib/Main.cs
+++ b/CUEToolsLib/Main.cs
@@ -31,6 +31,9 @@ using AudioCodecsDotNet;
using HDCDDotNet;
#if !MONO
using UnRarDotNet;
+using FLACDotNet;
+using APEDotNet;
+using WavPackDotNet;
#endif
namespace CUEToolsLib
diff --git a/FLACDotNet/FLACDotNet.vcproj b/FLACDotNet/FLACDotNet.vcproj
index cb73c9f..d11a418 100644
--- a/FLACDotNet/FLACDotNet.vcproj
+++ b/FLACDotNet/FLACDotNet.vcproj
@@ -328,6 +328,10 @@
RelativePath="System.XML.dll"
AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
/>
+
@@ -67,9 +68,11 @@ namespace FLACDotNet {
[UnmanagedFunctionPointer(CallingConvention::Cdecl)]
public delegate FLAC__bool DecoderEofDelegate (const FLAC__StreamDecoder *decoder, void *client_data);
- public ref class FLACReader {
+ public ref class FLACReader : public IAudioSource
+ {
public:
- FLACReader(String^ path, Stream^ IO) {
+ FLACReader(String^ path, Stream^ IO)
+ {
_tags = gcnew NameValueCollection();
_writeDel = gcnew DecoderWriteDelegate(this, &FLACReader::WriteCallback);
@@ -84,9 +87,10 @@ namespace FLACDotNet {
_decoderActive = false;
_sampleOffset = 0;
- _samplesWaiting = 0;
_sampleBuffer = nullptr;
_path = path;
+ _bufferOffset = 0;
+ _bufferLength = 0;
_IO = (IO != nullptr) ? IO : gcnew FileStream (path, FileMode::Open, FileAccess::Read, FileShare::Read);
@@ -122,50 +126,53 @@ namespace FLACDotNet {
Close ();
}
- property Int32 BitsPerSample {
+ virtual property Int32 BitsPerSample {
Int32 get() {
return _bitsPerSample;
}
}
- property Int32 ChannelCount {
+ virtual property Int32 ChannelCount {
Int32 get() {
return _channelCount;
}
}
- property Int32 SampleRate {
+ virtual property Int32 SampleRate {
Int32 get() {
return _sampleRate;
}
}
- property Int64 Length {
- Int64 get() {
+ virtual property UInt64 Length {
+ UInt64 get() {
return _sampleCount;
}
}
- property Int64 Position {
- Int64 get() {
- return _sampleOffset;
+ virtual property UInt64 Position {
+ UInt64 get()
+ {
+ return _sampleOffset - SamplesInBuffer;
}
- void set(Int64 offset) {
+ void set(UInt64 offset)
+ {
_sampleOffset = offset;
- _samplesWaiting = 0;
+ _bufferOffset = 0;
+ _bufferLength = 0;
if (!FLAC__stream_decoder_seek_absolute(_decoder, offset)) {
throw gcnew Exception("Unable to seek.");
}
}
}
- property String^ Path {
+ virtual property String^ Path {
String^ get() {
return _path;
}
}
- property NameValueCollection^ Tags {
+ virtual property NameValueCollection^ Tags {
NameValueCollection^ get () {
return _tags;
}
@@ -238,13 +245,13 @@ namespace FLACDotNet {
return 0 != res;
}
- property Int64 Remaining {
- Int64 get() {
- return _sampleCount - _sampleOffset;
+ virtual property UInt64 Remaining {
+ UInt64 get() {
+ return _sampleCount - _sampleOffset + SamplesInBuffer;
}
}
- void Close() {
+ virtual void Close() {
if (_decoderActive)
{
FLAC__stream_decoder_finish(_decoder);
@@ -258,18 +265,30 @@ namespace FLACDotNet {
}
}
- Int32 Read([Out] array^% sampleBuffer)
+ virtual UInt32 Read([Out] array^ buff, UInt32 sampleCount)
{
- while (_samplesWaiting == 0) {
- if (!FLAC__stream_decoder_process_single(_decoder)) {
- throw gcnew Exception("An error occurred while decoding.");
- }
- }
+ UInt32 buffOffset = 0;
+ UInt32 samplesNeeded = sampleCount;
- int sampleCount = _samplesWaiting;
- sampleBuffer = _sampleBuffer;
- _sampleOffset += sampleCount;
- _samplesWaiting = 0;
+ while (samplesNeeded != 0)
+ {
+ if (SamplesInBuffer == 0)
+ {
+ _bufferOffset = 0;
+ _bufferLength = 0;
+ do
+ {
+ if (!FLAC__stream_decoder_process_single(_decoder))
+ throw gcnew Exception("An error occurred while decoding.");
+ } while (_bufferLength == 0);
+ _sampleOffset += _bufferLength;
+ }
+ UInt32 copyCount = Math::Min(samplesNeeded, SamplesInBuffer);
+ Array::Copy(_sampleBuffer, _bufferOffset * _channelCount, buff, buffOffset * _channelCount, copyCount * _channelCount);
+ samplesNeeded -= copyCount;
+ buffOffset += copyCount;
+ _bufferOffset += copyCount;
+ }
return sampleCount;
}
@@ -287,18 +306,25 @@ namespace FLACDotNet {
Int32 _bitsPerSample, _channelCount, _sampleRate;
array^ _sampleBuffer;
array^ _readBuffer;
- int _samplesWaiting;
NameValueCollection^ _tags;
String^ _path;
bool _decoderActive;
Stream^ _IO;
+ UInt32 _bufferOffset, _bufferLength;
+
+ property UInt32 SamplesInBuffer {
+ UInt32 get ()
+ {
+ return (UInt32) (_bufferLength - _bufferOffset);
+ }
+ }
FLAC__StreamDecoderWriteStatus WriteCallback(const FLAC__StreamDecoder *decoder,
const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
{
Int32 sampleCount = frame->header.blocksize;
- if (_samplesWaiting > 0) {
+ if (_bufferLength > 0) {
throw gcnew Exception("Received unrequested samples.");
}
@@ -325,8 +351,7 @@ namespace FLACDotNet {
}
}
- _samplesWaiting = sampleCount;
-
+ _bufferLength = sampleCount;
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
@@ -425,9 +450,14 @@ namespace FLACDotNet {
}
};
- public ref class FLACWriter {
+ public ref class FLACWriter : IAudioDest
+ {
public:
- FLACWriter(String^ path, Int32 bitsPerSample, Int32 channelCount, Int32 sampleRate) {
+ FLACWriter(String^ path, Int32 bitsPerSample, Int32 channelCount, Int32 sampleRate)
+ {
+ if (bitsPerSample != 16 && bitsPerSample != 24)
+ throw gcnew Exception("Bits per sample must be 16 or 24.");
+
_initialized = false;
_path = path;
_finalSampleCount = 0;
@@ -447,7 +477,7 @@ namespace FLACDotNet {
FLAC__stream_encoder_set_sample_rate(_encoder, sampleRate);
}
- void Close() {
+ virtual void Close() {
FLAC__stream_encoder_finish(_encoder);
for (int i = 0; i < _metadataCount; i++) {
@@ -466,7 +496,7 @@ namespace FLACDotNet {
_tags->Clear ();
}
- property Int64 FinalSampleCount {
+ virtual property Int64 FinalSampleCount {
Int64 get() {
return _finalSampleCount;
}
@@ -481,6 +511,32 @@ namespace FLACDotNet {
}
}
+ virtual bool SetTags (NameValueCollection^ tags)
+ {
+ _tags = tags;
+ return true;
+ }
+
+ virtual property String^ Path {
+ String^ get() {
+ return _path;
+ }
+ }
+
+ virtual void Write(array^ sampleBuffer, UInt32 sampleCount) {
+ if (!_initialized) Initialize();
+
+ pin_ptr pSampleBuffer = &sampleBuffer[0, 0];
+
+ if (!FLAC__stream_encoder_process_interleaved(_encoder,
+ (const FLAC__int32*)pSampleBuffer, sampleCount))
+ {
+ throw gcnew Exception("An error occurred while encoding.");
+ }
+
+ _samplesWritten += sampleCount;
+ }
+
property Int32 CompressionLevel {
Int32 get() {
return _compressionLevel;
@@ -514,30 +570,6 @@ namespace FLACDotNet {
}
}
- void SetTags (NameValueCollection^ tags) {
- _tags = tags;
- }
-
- property String^ Path {
- String^ get() {
- return _path;
- }
- }
-
- void Write(array^ sampleBuffer, Int32 sampleCount) {
- if (!_initialized) Initialize();
-
- pin_ptr pSampleBuffer = &sampleBuffer[0, 0];
-
- if (!FLAC__stream_encoder_process_interleaved(_encoder,
- (const FLAC__int32*)pSampleBuffer, sampleCount))
- {
- throw gcnew Exception("An error occurred while encoding.");
- }
-
- _samplesWritten += sampleCount;
- }
-
private:
FLAC__StreamEncoder *_encoder;
bool _initialized;
diff --git a/HDCDDotNet/HDCDDotNet.cs b/HDCDDotNet/HDCDDotNet.cs
index 0465ef5..cbdf9c3 100644
--- a/HDCDDotNet/HDCDDotNet.cs
+++ b/HDCDDotNet/HDCDDotNet.cs
@@ -116,7 +116,7 @@ namespace HDCDDotNet
{
if (_inSampleBuffer == null || _inSampleBuffer.GetLength(0) < sampleCount)
_inSampleBuffer = new int[sampleCount, _channelCount];
- AudioCodecsDotNet.AudioCodecsDotNet.BytesToFLACSamples_16(buff, 0, _inSampleBuffer, 0, sampleCount, _channelCount);
+ AudioSamples.BytesToFLACSamples_16(buff, 0, _inSampleBuffer, 0, sampleCount, _channelCount);
Process(_inSampleBuffer, sampleCount);
}
diff --git a/MAC_SDK/Source/MACLib/Assembly/Assembly.obj b/MAC_SDK/Source/MACLib/Assembly/Assembly.obj
index 1535ff7..5424340 100644
Binary files a/MAC_SDK/Source/MACLib/Assembly/Assembly.obj and b/MAC_SDK/Source/MACLib/Assembly/Assembly.obj differ
diff --git a/WavPackDotNet/WavPackDotNet.cpp b/WavPackDotNet/WavPackDotNet.cpp
index 244c700..00727e6 100644
--- a/WavPackDotNet/WavPackDotNet.cpp
+++ b/WavPackDotNet/WavPackDotNet.cpp
@@ -35,6 +35,7 @@ using namespace System::Collections::Specialized;
using namespace System::Security::Cryptography;
using namespace System::IO;
using namespace APETagsDotNet;
+using namespace AudioCodecsDotNet;
#include
#include
@@ -59,9 +60,11 @@ namespace WavPackDotNet {
[UnmanagedFunctionPointer(CallingConvention::Cdecl)]
public delegate int DecoderCanSeekDelegate(void *id);
- public ref class WavPackReader {
+ public ref class WavPackReader : public IAudioSource
+ {
public:
- WavPackReader(String^ path, Stream^ IO, Stream^ IO_WVC) {
+ WavPackReader(String^ path, Stream^ IO, Stream^ IO_WVC)
+ {
char errorMessage[256];
_readDel = gcnew DecoderReadDelegate (this, &WavPackReader::ReadCallback);
@@ -89,14 +92,6 @@ namespace WavPackDotNet {
_IO = (IO != nullptr) ? IO : gcnew FileStream (path, FileMode::Open, FileAccess::Read, FileShare::Read);
_IO_WVC = (IO != nullptr) ? IO_WVC : System::IO::File::Exists (path+"c") ? gcnew FileStream (path+"c", FileMode::Open, FileAccess::Read, FileShare::Read) : nullptr;
- //IntPtr pathChars;
- //pathChars = Marshal::StringToHGlobalUni(path);
- //size_t pathLen = wcslen ((const wchar_t*)pathChars.ToPointer())+1;
- //wchar_t * pPath = new wchar_t[pathLen];
- //memcpy ((void*) pPath, (const wchar_t*)pathChars.ToPointer(), pathLen*sizeof(wchar_t));
- //Marshal::FreeHGlobal(pathChars);
- //_wpc = WavpackOpenFileInput (pPath, errorMessage, OPEN_WVC, 0);
-
_wpc = WavpackOpenFileInputEx (ioReader, "v", _IO_WVC != nullptr ? "c" : NULL, errorMessage, OPEN_WVC, 0);
if (_wpc == NULL) {
throw gcnew Exception("Unable to initialize the decoder.");
@@ -114,35 +109,35 @@ namespace WavPackDotNet {
delete ioReader;
}
- property Int32 BitsPerSample {
+ virtual property Int32 BitsPerSample {
Int32 get() {
return _bitsPerSample;
}
}
- property Int32 ChannelCount {
+ virtual property Int32 ChannelCount {
Int32 get() {
return _channelCount;
}
}
- property Int32 SampleRate {
+ virtual property Int32 SampleRate {
Int32 get() {
return _sampleRate;
}
}
- property Int32 Length {
- Int32 get() {
+ virtual property UInt64 Length {
+ UInt64 get() {
return _sampleCount;
}
}
- property Int32 Position {
- Int32 get() {
+ virtual property UInt64 Position {
+ UInt64 get() {
return _sampleOffset;
}
- void set(Int32 offset) {
+ void set(UInt64 offset) {
_sampleOffset = offset;
if (!WavpackSeekSample(_wpc, offset)) {
throw gcnew Exception("Unable to seek.");
@@ -150,19 +145,19 @@ namespace WavPackDotNet {
}
}
- property Int32 Remaining {
- Int32 get() {
+ virtual property UInt64 Remaining {
+ UInt64 get() {
return _sampleCount - _sampleOffset;
}
}
- property String^ Path {
+ virtual property String^ Path {
String^ get() {
return _path;
}
}
- property NameValueCollection^ Tags {
+ virtual property NameValueCollection^ Tags {
NameValueCollection^ get () {
if (!_tags)
{
@@ -177,7 +172,7 @@ namespace WavPackDotNet {
}
}
- void Close()
+ virtual void Close()
{
_wpc = WavpackCloseFile(_wpc);
if (_IO != nullptr)
@@ -192,16 +187,14 @@ namespace WavPackDotNet {
}
}
- void Read(array^ sampleBuffer, Int32 sampleCount) {
+ virtual UInt32 Read(array^ sampleBuffer, UInt32 sampleCount)
+ {
pin_ptr pSampleBuffer = &sampleBuffer[0, 0];
- int samplesRead;
-
- samplesRead = WavpackUnpackSamples(_wpc, pSampleBuffer, sampleCount);
+ int samplesRead = WavpackUnpackSamples(_wpc, pSampleBuffer, sampleCount);
_sampleOffset += samplesRead;
-
- if (samplesRead != sampleCount) {
+ if (samplesRead != sampleCount)
throw gcnew Exception("Decoder returned a different number of samples than requested.");
- }
+ return sampleCount;
}
private:
@@ -312,14 +305,17 @@ namespace WavPackDotNet {
}
};
- public ref class WavPackWriter {
+ public ref class WavPackWriter : IAudioDest
+ {
public:
- WavPackWriter(String^ path, Int32 bitsPerSample, Int32 channelCount, Int32 sampleRate) {
+ WavPackWriter(String^ path, Int32 bitsPerSample, Int32 channelCount, Int32 sampleRate)
+ {
IntPtr pathChars;
- if ((channelCount != 1) && (channelCount != 2)) {
+ if (channelCount != 1 && channelCount != 2)
throw gcnew Exception("Only stereo and mono audio formats are allowed.");
- }
+ if (bitsPerSample != 16 && bitsPerSample != 24)
+ throw gcnew Exception("Bits per sample must be 16 or 24.");
_path = path;
_tags = gcnew NameValueCollection();
@@ -330,6 +326,7 @@ namespace WavPackDotNet {
_bitsPerSample = bitsPerSample;
_channelCount = channelCount;
_sampleRate = sampleRate;
+ _blockAlign = _channelCount * ((_bitsPerSample + 7) / 8);
pathChars = Marshal::StringToHGlobalUni(path);
_hFile = _wfopen((const wchar_t*)pathChars.ToPointer(), L"w+b");
@@ -339,7 +336,8 @@ namespace WavPackDotNet {
}
}
- void Close() {
+ virtual void Close()
+ {
if (_md5Sum)
{
_md5hasher->TransformFinalBlock (gcnew array(1), 0, 0);
@@ -365,21 +363,56 @@ namespace WavPackDotNet {
}
}
- property Int32 FinalSampleCount {
- Int32 get() {
+ virtual property Int64 FinalSampleCount
+ {
+ Int64 get()
+ {
return _finalSampleCount;
}
- void set(Int32 value) {
- if (value < 0) {
+ void set(Int64 value)
+ {
+ if (value < 0)
throw gcnew Exception("Invalid final sample count.");
- }
- if (_initialized) {
+ if (_initialized)
throw gcnew Exception("Final sample count cannot be changed after encoding begins.");
- }
_finalSampleCount = value;
}
}
+ virtual void Write(array^ sampleBuffer, UInt32 sampleCount)
+ {
+ if (!_initialized)
+ Initialize();
+
+ if (MD5Sum)
+ {
+ if (_sampleBuffer == nullptr || _sampleBuffer.Length < sampleCount * _blockAlign)
+ _sampleBuffer = gcnew array(sampleCount * _blockAlign);
+ AudioSamples::FLACSamplesToBytes(sampleBuffer, 0, _sampleBuffer, 0, sampleCount, _channelCount, _bitsPerSample);
+ UpdateHash(_sampleBuffer, (int) sampleCount * _blockAlign);
+ }
+
+ pin_ptr pSampleBuffer = &sampleBuffer[0, 0];
+ if (!WavpackPackSamples(_wpc, (int32_t*)pSampleBuffer, sampleCount)) {
+ throw gcnew Exception("An error occurred while encoding.");
+ }
+
+ _samplesWritten += sampleCount;
+ }
+
+ virtual property String^ Path
+ {
+ String^ get() {
+ return _path;
+ }
+ }
+
+ virtual bool SetTags (NameValueCollection^ tags)
+ {
+ _tags = tags;
+ return true;
+ }
+
property Int32 CompressionMode {
Int32 get() {
return _compressionMode;
@@ -422,38 +455,18 @@ namespace WavPackDotNet {
_md5hasher->TransformBlock (buff, 0, len, buff, 0);
}
- void Write(array^ sampleBuffer, Int32 sampleCount) {
- if (!_initialized) Initialize();
-
- pin_ptr pSampleBuffer = &sampleBuffer[0, 0];
- if (!WavpackPackSamples(_wpc, (int32_t*)pSampleBuffer, sampleCount)) {
- throw gcnew Exception("An error occurred while encoding.");
- }
-
- _samplesWritten += sampleCount;
- }
-
- property String^ Path {
- String^ get() {
- return _path;
- }
- }
-
- void SetTags (NameValueCollection^ tags) {
- _tags = tags;
- }
-
private:
FILE *_hFile;
bool _initialized;
WavpackContext *_wpc;
Int32 _finalSampleCount, _samplesWritten;
- Int32 _bitsPerSample, _channelCount, _sampleRate;
+ Int32 _bitsPerSample, _channelCount, _sampleRate, _blockAlign;
Int32 _compressionMode, _extraMode;
NameValueCollection^ _tags;
String^ _path;
bool _md5Sum;
MD5^ _md5hasher;
+ array^ _sampleBuffer;
void Initialize() {
WavpackConfig config;
diff --git a/WavPackDotNet/WavPackDotNet.vcproj b/WavPackDotNet/WavPackDotNet.vcproj
index 8416406..de23456 100644
--- a/WavPackDotNet/WavPackDotNet.vcproj
+++ b/WavPackDotNet/WavPackDotNet.vcproj
@@ -92,81 +92,6 @@
Name="VCPostBuildEventTool"
/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+