diff --git a/ALACDotNet/ALACDotNet.cs b/ALACDotNet/ALACDotNet.cs index ef691fd..5bc6641 100644 --- a/ALACDotNet/ALACDotNet.cs +++ b/ALACDotNet/ALACDotNet.cs @@ -40,7 +40,7 @@ namespace ALACDotNet _saved_mdat_pos = m_spIO.Position; } - public uint Read(byte[] buff, uint sampleCount) + public uint Read(int[,] buff, uint sampleCount) { if (_predicterror_buffer_a == null) { @@ -62,24 +62,23 @@ namespace ALACDotNet _outputsamples_buffer_b = new int[setinfo_max_samples_per_frame]; _samplesInBuffer = 0; - _samplesBuffer = new byte[setinfo_max_samples_per_frame*4]; _framesBuffer = new byte[65536]; } - ulong offset = 0; + uint offset = 0; while (_samplesInBuffer < sampleCount) { if (_samplesInBuffer > 0) { - Array.Copy(_samplesBuffer, (long) _samplesBufferOffset * 4, buff, (long)offset * 4, (long)_samplesInBuffer * 4); + deinterlace(buff, offset); sampleCount -= (uint) _samplesInBuffer; offset += _samplesInBuffer; _samplesInBuffer = 0; _samplesBufferOffset = 0; } - ulong sampleDuration; + uint sampleDuration; uint sampleSize; if ((int) _iSample >= _sample_byte_size.Length) return (uint)offset; @@ -93,7 +92,7 @@ namespace ALACDotNet _iSample++; } - Array.Copy(_samplesBuffer, (long) _samplesBufferOffset * 4, buff, (long)offset * 4, (long)sampleCount * 4); + deinterlace(buff, offset); _samplesInBuffer -= sampleCount; _samplesBufferOffset += sampleCount; if (_samplesInBuffer == 0) @@ -136,7 +135,7 @@ namespace ALACDotNet _iSample = 0; ulong durOffs = 0; - ulong sampleDuration; + uint sampleDuration; long fileOffs = 0; uint sampleSize; do @@ -152,7 +151,7 @@ namespace ALACDotNet _iSample++; } while (durOffs <= value); m_spIO.Position = _saved_mdat_pos + fileOffs - sampleSize; - _samplesBufferOffset = sampleDuration - durOffs + value; + _samplesBufferOffset = (uint) (value + sampleDuration - durOffs); _iSample--; } } @@ -201,7 +200,7 @@ namespace ALACDotNet } } - private void get_sample_info(ulong iSample, out ulong sampleDuration, out uint sampleSize) + private void get_sample_info(ulong iSample, out uint sampleDuration, out uint sampleSize) { // if (iSample >= _sample_byte_size.Length) uint duration_index_accum = 0; @@ -590,43 +589,39 @@ namespace ALACDotNet } } - private unsafe void deinterlace(uint numsamples, byte interlacing_shift, byte interlacing_leftweight) + private unsafe void deinterlace(int [,] samplesBuffer, uint offset) { - if (numsamples <= 0) + if (_samplesInBuffer <= 0) return; int i; - fixed (int* buf_a = &_outputsamples_buffer_a[0], buf_b = _outputsamples_buffer_b) - fixed (byte* buf_s = &_samplesBuffer[0]) + fixed (int* buf_a = &_outputsamples_buffer_a[_samplesBufferOffset], buf_b = &_outputsamples_buffer_b[_samplesBufferOffset]) + fixed (int* buf_s = &samplesBuffer[offset, 0]) { /* weighted interlacing */ - if (interlacing_leftweight != 0) + if (_interlacing_leftweight != 0) { - for (i = 0; i < numsamples; i++) + for (i = 0; i < _samplesInBuffer; i++) { int a = buf_a[i]; int b = buf_b[i]; - a -= (b * interlacing_leftweight) >> interlacing_shift; + a -= (b * _interlacing_leftweight) >> _interlacing_shift; b += a; - buf_s[i * 4] = (byte)(b & 0xff); - buf_s[i * 4 + 1] = (byte)((b >> 8) & 0xff); - buf_s[i * 4 + 2] = (byte)(a & 0xff); - buf_s[i * 4 + 3] = (byte)((a >> 8) & 0xff); + buf_s[i * 2] = b; + buf_s[i * 2 + 1] = a; } return; } /* otherwise basic interlacing took place */ - for (i = 0; i < numsamples; i++) + for (i = 0; i < _samplesInBuffer; i++) { int a = buf_a[i]; int b = buf_b[i]; - buf_s[i * 4] = (byte)(a & 0xff); - buf_s[i * 4 + 1] = (byte)((a >> 8) & 0xff); - buf_s[i * 4 + 2] = (byte)(b & 0xff); - buf_s[i * 4 + 3] = (byte)((b >> 8) & 0xff); + buf_s[i * 2] = a; + buf_s[i * 2 + 1] = b; } } } @@ -640,8 +635,6 @@ namespace ALACDotNet if (channels != 1) throw new Exception("Not stereo"); - byte interlacing_shift; - byte interlacing_leftweight; readbits(_framesBuffer, ref pos, 4); readbits(_framesBuffer, ref pos, 12); /* unknown, skip 12 bits */ bool hassize = 0 != readbits(_framesBuffer, ref pos, 1); /* the output sample size is stored soon */ @@ -654,8 +647,8 @@ namespace ALACDotNet { /* compressed */ - interlacing_shift = (byte)readbits(_framesBuffer, ref pos, 8); - interlacing_leftweight = (byte)readbits(_framesBuffer, ref pos, 8); + _interlacing_shift = (byte)readbits(_framesBuffer, ref pos, 8); + _interlacing_leftweight = (byte)readbits(_framesBuffer, ref pos, 8); if (wasted_bytes != 0) throw new Exception("FIXME: unimplemented, unhandling of wasted_bytes"); @@ -684,15 +677,13 @@ namespace ALACDotNet _outputsamples_buffer_b[i] = extend_sign32((int)readbits(_framesBuffer, ref pos, _bitsPerSample), _bitsPerSample); } /* wasted_bytes = 0; */ - interlacing_shift = 0; - interlacing_leftweight = 0; + _interlacing_shift = 0; + _interlacing_leftweight = 0; } if (_bitsPerSample != 16) throw new Exception("Not 16 bit"); - deinterlace(outputSamples, interlacing_shift, interlacing_leftweight); - _samplesInBuffer = outputSamples; } @@ -1245,16 +1236,16 @@ namespace ALACDotNet predictor_t predictor_info_b; NameValueCollection _tags; - ulong _samplesInBuffer; - byte[] _samplesBuffer; + uint _samplesInBuffer, _samplesBufferOffset; byte[] _framesBuffer; byte[] _buff; + byte _interlacing_shift; + byte _interlacing_leftweight; int _sampleRate; int _channelCount; int _bitsPerSample; ulong _sampleCount; ulong _sampleOffset; - ulong _samplesBufferOffset; ulong _iSample; Dictionary _qtmovie_parsers; diff --git a/AudioCodecsDotNet/AudioCodecsDotNet.cs b/AudioCodecsDotNet/AudioCodecsDotNet.cs index 46b4520..2791038 100644 --- a/AudioCodecsDotNet/AudioCodecsDotNet.cs +++ b/AudioCodecsDotNet/AudioCodecsDotNet.cs @@ -8,7 +8,7 @@ namespace AudioCodecsDotNet { public interface IAudioSource { - uint Read(byte[] buff, uint sampleCount); + uint Read(int[,] buff, uint sampleCount); ulong Length { get; } ulong Position { get; set; } NameValueCollection Tags { get; set; } @@ -228,24 +228,17 @@ namespace AudioCodecsDotNet } } - public uint Read(byte[] buff, uint sampleCount) + public uint Read(int [,] buff, uint sampleCount) { - uint samplesRemaining, byteCount, i; - - samplesRemaining = (uint)(_sampleCount - _sampleOffset); + uint samplesRemaining = (uint)(_sampleCount - _sampleOffset); if (sampleCount > samplesRemaining) - { sampleCount = samplesRemaining; - } - byteCount = sampleCount * 2 * 2; - for (i = 0; i < byteCount; i++) - { - buff[i] = 0; - } + for (uint i = 0; i < sampleCount; i++) + for (int j = 0; j < buff.GetLength(1); j++) + buff[i,j] = 0; _sampleOffset += sampleCount; - return sampleCount; } @@ -265,6 +258,7 @@ namespace AudioCodecsDotNet int _bitsPerSample, _channelCount, _sampleRate, _blockAlign; bool _largeFile; string _path; + private byte[] _sampleBuffer; public WAVReader(string path) { @@ -476,22 +470,21 @@ namespace AudioCodecsDotNet values = new List(); } - public uint Read(byte[] buff, uint sampleCount) + public uint Read(int[,] buff, uint sampleCount) { if (sampleCount > Remaining) sampleCount = (uint)Remaining; - uint byteCount = sampleCount * (uint)_blockAlign; - - if (sampleCount != 0) - { - if (_fs.Read(buff, 0, (int)byteCount) != byteCount) - { - throw new Exception("Incomplete file read."); - } - _samplePos += sampleCount; - } - + if (sampleCount == 0) + return 0; + int byteCount = (int) sampleCount * _blockAlign; + if (_sampleBuffer == null || _sampleBuffer.Length < byteCount) + _sampleBuffer = new byte[byteCount]; + if (_fs.Read(_sampleBuffer, 0, (int)byteCount) != byteCount) + throw new Exception("Incomplete file read."); + AudioCodecsDotNet.BytesToFLACSamples_16 (_sampleBuffer, 0, buff, 0, + sampleCount, _channelCount); + _samplePos += sampleCount; return sampleCount; } @@ -600,7 +593,7 @@ namespace AudioCodecsDotNet { if (sampleCount == 0) return; - if (_sampleBuffer == null || _sampleBuffer.Length < sampleCount * _channelCount) + if (_sampleBuffer == null || _sampleBuffer.Length < sampleCount * _blockAlign) _sampleBuffer = new byte[sampleCount * _blockAlign]; AudioCodecsDotNet.FLACSamplesToBytes(buff, 0, _sampleBuffer, 0, sampleCount, _channelCount, _bitsPerSample); diff --git a/CUETools/frmBatch.cs b/CUETools/frmBatch.cs index da4f9ed..16a0244 100644 --- a/CUETools/frmBatch.cs +++ b/CUETools/frmBatch.cs @@ -130,6 +130,7 @@ namespace JDP progressBar2.Value = 0; }); } +#if !DEBUG catch (Exception ex) { this.Invoke((MethodInvoker)delegate() @@ -141,6 +142,7 @@ namespace JDP textBox1.Select(0, 0); }); } +#endif if (_batchPaths.Count != 0) { diff --git a/CUEToolsLib/AudioReadWrite.cs b/CUEToolsLib/AudioReadWrite.cs index 3246242..dd3815c 100644 --- a/CUEToolsLib/AudioReadWrite.cs +++ b/CUEToolsLib/AudioReadWrite.cs @@ -126,7 +126,7 @@ namespace CUEToolsLib { } } - public uint Read(byte[] buff, uint sampleCount) { + public uint Read(int [,] buff, uint sampleCount) { if (_flacReader.BitsPerSample != 16) { throw new Exception("Reading is only supported for 16 bit sample depth."); } @@ -142,12 +142,10 @@ namespace CUEToolsLib { } copyCount = Math.Min(samplesNeeded, SamplesInBuffer); - - AudioCodecsDotNet.AudioCodecsDotNet.FLACSamplesToBytes_16(_sampleBuffer, _bufferOffset, buff, buffOffset, - copyCount, chanCount); + Array.Copy(_sampleBuffer, _bufferOffset * chanCount, buff, buffOffset * chanCount, copyCount * chanCount); samplesNeeded -= copyCount; - buffOffset += copyCount * (uint) chanCount * 2; + buffOffset += copyCount; _bufferOffset += copyCount; } @@ -288,30 +286,30 @@ namespace CUEToolsLib { set { _apeReader.Tags = value; } } - private unsafe void APESamplesToBytes_16(int[,] inSamples, uint inSampleOffset, - byte[] outSamples, uint outByteOffset, uint sampleCount, int channelCount) + 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.Length - outByteOffset < loopCount * 2)) + (outSamples.GetLength(0) - outSampleOffset < sampleCount)) { throw new IndexOutOfRangeException(); } fixed (int* pInSamplesFixed = &inSamples[inSampleOffset, 0]) { - fixed (byte* pOutSamplesFixed = &outSamples[outByteOffset]) { + fixed (int * pOutSamplesFixed = &outSamples[outSampleOffset, 0]) { int* pInSamples = pInSamplesFixed; - short* pOutSamples = (short*)pOutSamplesFixed; + int* pOutSamples = pOutSamplesFixed; for (int i = 0; i < loopCount; i++) { - *(pOutSamples++) = (short)*(pInSamples++); + *(pOutSamples++) = *(pInSamples++); } } } } - public uint Read(byte[] buff, uint sampleCount) { + public uint Read(int[,] buff, uint sampleCount) { if (_apeReader.BitsPerSample != 16) { throw new Exception("Reading is only supported for 16 bit sample depth."); } @@ -329,11 +327,11 @@ namespace CUEToolsLib { copyCount = Math.Min(samplesNeeded, SamplesInBuffer); - APESamplesToBytes_16(_sampleBuffer, _bufferOffset, buff, buffOffset, + APESamplesToFLACSamples(_sampleBuffer, _bufferOffset, buff, buffOffset, copyCount, chanCount); samplesNeeded -= copyCount; - buffOffset += copyCount * (uint) chanCount * 2; + buffOffset += copyCount; _bufferOffset += copyCount; } @@ -452,16 +450,11 @@ namespace CUEToolsLib { set { _wavPackReader.Tags = value; } } - public uint Read(byte[] buff, uint sampleCount) { + public uint Read(int[,] buff, uint sampleCount) { if (_wavPackReader.BitsPerSample != 16) { throw new Exception("Reading is only supported for 16 bit sample depth."); } - int chanCount = _wavPackReader.ChannelCount; - int[,] sampleBuffer; - - sampleBuffer = new int[sampleCount * 2, chanCount]; - _wavPackReader.Read(sampleBuffer, (int) sampleCount); - AudioCodecsDotNet.AudioCodecsDotNet.FLACSamplesToBytes_16(sampleBuffer, 0, buff, 0, sampleCount, chanCount); + _wavPackReader.Read(buff, (int) sampleCount); return sampleCount; } diff --git a/CUEToolsLib/Main.cs b/CUEToolsLib/Main.cs index 5aee33b..04ff28d 100644 --- a/CUEToolsLib/Main.cs +++ b/CUEToolsLib/Main.cs @@ -628,6 +628,7 @@ namespace CUEToolsLib } } } + sr.Close(); } if (trackNumber == 0) { @@ -1179,7 +1180,7 @@ namespace CUEToolsLib } } - unsafe private void CalculateAccurateRipCRCsSemifast(UInt32* samples, uint count, int iTrack, uint currentOffset, uint previousOffset, uint trackLength) + unsafe private void CalculateAccurateRipCRCsSemifast(int* samples, uint count, int iTrack, uint currentOffset, uint previousOffset, uint trackLength) { fixed (uint* CRCsA = iTrack != 0 ? _tracks[iTrack - 1].OffsetedCRC : null, CRCsB = _tracks[iTrack].OffsetedCRC, @@ -1187,7 +1188,7 @@ namespace CUEToolsLib { for (uint si = 0; si < count; si++) { - uint sampleValue = samples[si]; + uint sampleValue = (uint) ((samples[2 * si] & 0xffff) + (samples[2 * si + 1] << 16)); int i; int iB = Math.Max(0, _arOffsetRange - (int)(currentOffset + si)); int iC = Math.Min(2 * _arOffsetRange + 1, _arOffsetRange + (int)trackLength - (int)(currentOffset + si)); @@ -1215,41 +1216,44 @@ namespace CUEToolsLib } } - unsafe private void CalculateAccurateRipCRCs(UInt32* samples, uint count, int iTrack, uint currentOffset, uint previousOffset, uint trackLength) + unsafe private void CalculateAccurateRipCRCs(int* samples, uint count, int iTrack, uint currentOffset, uint previousOffset, uint trackLength) { for (int si = 0; si < count; si++) + { + uint sampleValue = (uint)((samples[2 * si] & 0xffff) + (samples[2 * si + 1] << 16)); for (int oi = -_arOffsetRange; oi <= _arOffsetRange; oi++) { int iTrack2 = iTrack; - int currentOffset2 = (int) currentOffset + si - oi; + int currentOffset2 = (int)currentOffset + si - oi; if (currentOffset2 < 5 * 588 - 1 && iTrack == 0) - // we are in the skipped area at the start of the disk + // we are in the skipped area at the start of the disk { continue; } - else if (currentOffset2 < 0) - // offset takes us to previous track + else if (currentOffset2 < 0) + // offset takes us to previous track { iTrack2--; - currentOffset2 += (int) previousOffset; + currentOffset2 += (int)previousOffset; } else if (currentOffset2 >= trackLength - 5 * 588 && iTrack == TrackCount - 1) - // we are in the skipped area at the end of the disc + // we are in the skipped area at the end of the disc { continue; } else if (currentOffset2 >= trackLength) - // offset takes us to the next track + // offset takes us to the next track { iTrack2++; - currentOffset2 -= (int) trackLength; + currentOffset2 -= (int)trackLength; } - _tracks[iTrack2].OffsetedCRC[_arOffsetRange - oi] += (uint)(samples [si] * (currentOffset2 + 1)); + _tracks[iTrack2].OffsetedCRC[_arOffsetRange - oi] += sampleValue * (uint) (currentOffset2 + 1); } + } } - unsafe private void CalculateAccurateRipCRCsFast(UInt32* samples, uint count, int iTrack, uint currentOffset) + unsafe private void CalculateAccurateRipCRCsFast(int* samples, uint count, int iTrack, uint currentOffset) { int s1 = (int) Math.Min(count, Math.Max(0, 450 * 588 - _arOffsetRange - (int)currentOffset)); int s2 = (int) Math.Min(count, Math.Max(0, 451 * 588 + _arOffsetRange - (int)currentOffset)); @@ -1260,8 +1264,9 @@ namespace CUEToolsLib int magicFrameOffset = (int)currentOffset + sj - 450 * 588 + 1; int firstOffset = Math.Max(-_arOffsetRange, magicFrameOffset - 588); int lastOffset = Math.Min(magicFrameOffset - 1, _arOffsetRange); + uint sampleValue = (uint)((samples[2 * sj] & 0xffff) + (samples[2 * sj + 1] << 16)); for (int oi = firstOffset; oi <= lastOffset; oi++) - FrameCRCs[_arOffsetRange - oi] += (uint)(samples[sj] * (magicFrameOffset - oi)); + FrameCRCs[_arOffsetRange - oi] += sampleValue * (uint)(magicFrameOffset - oi); } fixed (uint* CRCs = _tracks[iTrack].OffsetedCRC) { @@ -1269,7 +1274,7 @@ namespace CUEToolsLib currentOffset += (uint) _arOffsetRange + 1; for (uint si = 0; si < count; si++) { - uint sampleValue = samples[si]; + uint sampleValue = (uint)((samples[2 * si] & 0xffff) + (samples[2 * si + 1] << 16)); stepSum += sampleValue; baseSum += sampleValue * (uint)(currentOffset + si); } @@ -1747,6 +1752,7 @@ namespace CUEToolsLib destTags.Remove("CUESHEET"); destTags.Remove("TITLE"); + destTags.Remove("TRACKNUMBER"); CleanupTags(destTags, "ACCURATERIP"); CleanupTags(destTags, "REPLAYGAIN"); @@ -1781,7 +1787,7 @@ namespace CUEToolsLib { const int buffLen = 16384; int iTrack, iIndex; - byte[] buff = new byte[buffLen * 2 * 2]; + int[,] sampleBuffer = new int[buffLen, 2]; TrackInfo track; IAudioSource audioSource = null; IAudioDest audioDest = null; @@ -1854,8 +1860,6 @@ namespace CUEToolsLib } } - int[,] sampleBuffer = null; - if (_accurateRip && noOutput) for (iTrack = 0; iTrack < TrackCount; iTrack++) for (int iCRC = 0; iCRC < 10 * 588; iCRC++) @@ -1966,10 +1970,7 @@ namespace CUEToolsLib lastTrackPercent = trackPercent; } - audioSource.Read(buff, copyCount); - if (sampleBuffer == null || sampleBuffer.GetLength(0) < copyCount) - sampleBuffer = new int[copyCount, audioSource.ChannelCount]; - AudioCodecsDotNet.AudioCodecsDotNet.BytesToFLACSamples_16(buff, 0, sampleBuffer, 0, copyCount, audioSource.ChannelCount); + audioSource.Read(sampleBuffer, copyCount); if (!discardOutput) audioDest.Write(sampleBuffer, copyCount); if (_config.detectHDCD && hdcdDecoder != null) { @@ -1987,23 +1988,22 @@ namespace CUEToolsLib } if (_accurateRip && noOutput && (iTrack != 0 || iIndex != 0)) unsafe { - fixed (byte * pBuff = &buff[0]) + fixed (int *pSampleBuff = &sampleBuffer[0,0]) { - UInt32 * samples = (UInt32*) pBuff; int iTrack2 = iTrack - (iIndex == 0 ? 1 : 0); uint si1 = (uint) Math.Min(copyCount, Math.Max(0, 588*(iTrack2 == 0?10:5) - (int) currentOffset)); uint si2 = (uint) Math.Min(copyCount, Math.Max(si1, trackLength - (int) currentOffset - 588 * (iTrack2 == TrackCount - 1?10:5))); if (iTrack2 == 0) - CalculateAccurateRipCRCs (samples, si1, iTrack2, currentOffset, previousOffset, trackLength); + CalculateAccurateRipCRCs (pSampleBuff, si1, iTrack2, currentOffset, previousOffset, trackLength); else - CalculateAccurateRipCRCsSemifast (samples, si1, iTrack2, currentOffset, previousOffset, trackLength); + CalculateAccurateRipCRCsSemifast(pSampleBuff, si1, iTrack2, currentOffset, previousOffset, trackLength); if (si2 > si1) - CalculateAccurateRipCRCsFast (samples+si1, (uint)(si2 - si1), iTrack2, currentOffset + si1); + CalculateAccurateRipCRCsFast(pSampleBuff + si1 * 2, (uint)(si2 - si1), iTrack2, currentOffset + si1); if (iTrack2 == TrackCount - 1) - CalculateAccurateRipCRCs (samples+si2, copyCount-si2, iTrack2, currentOffset+si2, previousOffset, trackLength); + CalculateAccurateRipCRCs(pSampleBuff + si2*2, copyCount - si2, iTrack2, currentOffset + si2, previousOffset, trackLength); else - CalculateAccurateRipCRCsSemifast (samples + si2, copyCount - si2, iTrack2, currentOffset + si2, previousOffset, trackLength); + CalculateAccurateRipCRCsSemifast(pSampleBuff + si2*2, copyCount - si2, iTrack2, currentOffset + si2, previousOffset, trackLength); } } currentOffset += copyCount; diff --git a/FLACDotNet/flacdotnet.cpp b/FLACDotNet/flacdotnet.cpp index 2a5a56e..eefdba2 100644 --- a/FLACDotNet/flacdotnet.cpp +++ b/FLACDotNet/flacdotnet.cpp @@ -70,7 +70,7 @@ namespace FLACDotNet { _decoderActive = false; _sampleOffset = 0; - _samplesWaiting = false; + _samplesWaiting = 0; _sampleBuffer = nullptr; _path = path; @@ -138,7 +138,7 @@ namespace FLACDotNet { } void set(Int64 offset) { _sampleOffset = offset; - _samplesWaiting = false; + _samplesWaiting = 0; if (!FLAC__stream_decoder_seek_absolute(_decoder, offset)) { throw gcnew Exception("Unable to seek."); } @@ -237,20 +237,18 @@ namespace FLACDotNet { _decoderActive = false; } - Int32 Read([Out] array^% sampleBuffer) { - int sampleCount; - - while (!_samplesWaiting) { + Int32 Read([Out] array^% sampleBuffer) + { + while (_samplesWaiting == 0) { if (!FLAC__stream_decoder_process_single(_decoder)) { throw gcnew Exception("An error occurred while decoding."); } } - sampleCount = _sampleBuffer->GetLength(0); + int sampleCount = _samplesWaiting; sampleBuffer = _sampleBuffer; _sampleOffset += sampleCount; - _samplesWaiting = false; - + _samplesWaiting = 0; return sampleCount; } @@ -262,7 +260,7 @@ namespace FLACDotNet { Int64 _sampleCount, _sampleOffset; Int32 _bitsPerSample, _channelCount, _sampleRate; array^ _sampleBuffer; - bool _samplesWaiting; + int _samplesWaiting; NameValueCollection^ _tags; String^ _path; bool _decoderActive; @@ -272,7 +270,7 @@ namespace FLACDotNet { { Int32 sampleCount = frame->header.blocksize; - if (_samplesWaiting) { + if (_samplesWaiting > 0) { throw gcnew Exception("Received unrequested samples."); } @@ -283,7 +281,7 @@ namespace FLACDotNet { throw gcnew Exception("Format changes within a file are not allowed."); } - if ((_sampleBuffer == nullptr) || (_sampleBuffer->GetLength(0) != sampleCount)) { + if ((_sampleBuffer == nullptr) || (_sampleBuffer->GetLength(0) < sampleCount)) { _sampleBuffer = gcnew array(sampleCount, _channelCount); } @@ -299,7 +297,7 @@ namespace FLACDotNet { } } - _samplesWaiting = true; + _samplesWaiting = sampleCount; return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; }