diff --git a/CUETools.Codecs.FLACCL/FLACCLWriter.cs b/CUETools.Codecs.FLACCL/FLACCLWriter.cs index 0de51f0..ce21b16 100644 --- a/CUETools.Codecs.FLACCL/FLACCLWriter.cs +++ b/CUETools.Codecs.FLACCL/FLACCLWriter.cs @@ -1363,7 +1363,14 @@ namespace CUETools.Codecs.FLACCL fixed (int* coefs = task.frame.subframes[ch].best.coefs) { if (Settings.PCM.BitsPerSample > 16) - lpc.encode_residual_long(task.frame.subframes[ch].best.residual, task.frame.subframes[ch].samples, task.frame.blocksize, task.frame.subframes[ch].best.order, coefs, task.frame.subframes[ch].best.shift); + { + if (!lpc.encode_residual_long(task.frame.subframes[ch].best.residual, task.frame.subframes[ch].samples, task.frame.blocksize, task.frame.subframes[ch].best.order, coefs, task.frame.subframes[ch].best.shift)) + { + task.frame.subframes[ch].best.type = SubframeType.Verbatim; + task.frame.subframes[ch].best.size = (uint)(task.frame.subframes[ch].obits * task.frame.blocksize); + return; + } + } else lpc.encode_residual(task.frame.subframes[ch].best.residual, task.frame.subframes[ch].samples, task.frame.blocksize, task.frame.subframes[ch].best.order, coefs, task.frame.subframes[ch].best.shift); } diff --git a/CUETools.Codecs.FLAKE/FlakeWriter.cs b/CUETools.Codecs.FLAKE/FlakeWriter.cs index d8d1486..134c9ca 100644 --- a/CUETools.Codecs.FLAKE/FlakeWriter.cs +++ b/CUETools.Codecs.FLAKE/FlakeWriter.cs @@ -1156,7 +1156,10 @@ new int[] { // 30 fixed (int* coefs = frame.current.coefs) { if ((csum << frame.subframes[ch].obits) >= 1UL << 32) - lpc.encode_residual_long(frame.current.residual, frame.subframes[ch].samples, frame.blocksize, frame.current.order, coefs, frame.current.shift); + { + if (!lpc.encode_residual_long(frame.current.residual, frame.subframes[ch].samples, frame.blocksize, frame.current.order, coefs, frame.current.shift)) + continue; + } else lpc.encode_residual(frame.current.residual, frame.subframes[ch].samples, frame.blocksize, frame.current.order, coefs, frame.current.shift); } @@ -1274,7 +1277,10 @@ new int[] { // 30 csum += (ulong)Math.Abs(coefs[i - 1]); if ((csum << frame.subframes[ch].obits) >= 1UL << 32) - lpc.encode_residual_long(frame.current.residual, frame.subframes[ch].samples, frame.blocksize, frame.current.order, coefs, frame.current.shift); + { + if (!lpc.encode_residual_long(frame.current.residual, frame.subframes[ch].samples, frame.blocksize, frame.current.order, coefs, frame.current.shift)) + continue; + } else lpc.encode_residual(frame.current.residual, frame.subframes[ch].samples, frame.blocksize, frame.current.order, coefs, frame.current.shift); @@ -2270,15 +2276,33 @@ new int[] { // 30 if (verify != null) { - int decoded = verify.DecodeFrame(frame_buffer, 0, fs); - if (decoded != fs || verify.Remaining != bs) - throw new Exception(Properties.Resources.ExceptionValidationFailed); - fixed (int* s = verifyBuffer, r = verify.Samples) - { - for (int ch = 0; ch < channels; ch++) - if (AudioSamples.MemCmp(s + ch * Flake.MAX_BLOCKSIZE, r + ch * Flake.MAX_BLOCKSIZE, bs)) - throw new Exception(Properties.Resources.ExceptionValidationFailed); - } + try + { + int decoded = verify.DecodeFrame(frame_buffer, 0, fs); + if (decoded != fs || verify.Remaining != bs) + throw new Exception(Properties.Resources.ExceptionValidationFailed); + fixed (int* s = verifyBuffer, r = verify.Samples) + { + for (int ch = 0; ch < channels; ch++) + if (AudioSamples.MemCmp(s + ch * Flake.MAX_BLOCKSIZE, r + ch * Flake.MAX_BLOCKSIZE, bs)) + throw new Exception(Properties.Resources.ExceptionValidationFailed); + } + } + catch (Exception ex) + { + //if (channels == 2) + //{ + // var sw = new WAVWriter("verify.wav", new WAVWriterSettings(this.Settings.PCM)); + // sw.FinalSampleCount = this.frame.blocksize; + // var ab = new AudioBuffer(this.Settings.PCM, this.frame.blocksize); + // ab.Prepare(this.frame.blocksize); + // fixed (int* abs = ab.Samples, s = verifyBuffer) + // AudioSamples.Interlace(abs, s, s + Flake.MAX_BLOCKSIZE, this.frame.blocksize); + // sw.Write(ab); + // sw.Close(); + //} + throw ex; + } } if (bs < m_blockSize) diff --git a/CUETools.Codecs/LPC.cs b/CUETools.Codecs/LPC.cs index d5975b9..5724019 100644 --- a/CUETools.Codecs/LPC.cs +++ b/CUETools.Codecs/LPC.cs @@ -693,7 +693,7 @@ namespace CUETools.Codecs } } - public static unsafe void + public static unsafe bool encode_residual_long(int* res, int* smp, int n, int order, int* coefs, int shift) { @@ -704,13 +704,16 @@ namespace CUETools.Codecs int* r = res + order; int c0 = coefs[0]; int c1 = coefs[1]; + long overflows = 0L; switch (order) { case 1: for (int i = n - order; i > 0; i--) { long pred = c0 * (long)*(s++); - *(r++) = *s - (int)(pred >> shift); + pred = *s - (pred >> shift); + overflows += (pred ^ (pred >> 63)) >> 30; + *(r++) = (int)pred; } break; case 2: @@ -718,7 +721,9 @@ namespace CUETools.Codecs { long pred = c1 * (long)*(s++); pred += c0 * (long)*(s++); - *(r++) = *(s--) - (int)(pred >> shift); + pred = *(s--) - (pred >> shift); + overflows += (pred ^ (pred >> 63)) >> 30; + *(r++) = (int)pred; } break; case 3: @@ -727,7 +732,9 @@ namespace CUETools.Codecs long pred = coefs[2] * (long)*(s++); pred += c1 * (long)*(s++); pred += c0 * (long)*(s++); - *(r++) = *s - (int)(pred >> shift); + pred = *s - (pred >> shift); + overflows += (pred ^ (pred >> 63)) >> 30; + *(r++) = (int)pred; s -= 2; } break; @@ -738,7 +745,9 @@ namespace CUETools.Codecs pred += coefs[2] * (long)*(s++); pred += c1 * (long)*(s++); pred += c0 * (long)*(s++); - *(r++) = *s - (int)(pred >> shift); + pred = *s - (pred >> shift); + overflows += (pred ^ (pred >> 63)) >> 30; + *(r++) = (int)pred; s -= 3; } break; @@ -750,7 +759,9 @@ namespace CUETools.Codecs pred += coefs[2] * (long)*(s++); pred += c1 * (long)*(s++); pred += c0 * (long)*(s++); - *(r++) = *s - (int)(pred >> shift); + pred = *s - (pred >> shift); + overflows += (pred ^ (pred >> 63)) >> 30; + *(r++) = (int)pred; s -= 4; } break; @@ -763,7 +774,9 @@ namespace CUETools.Codecs pred += coefs[2] * (long)*(s++); pred += c1 * (long)*(s++); pred += c0 * (long)*(s++); - *(r++) = *s - (int)(pred >> shift); + pred = *s - (pred >> shift); + overflows += (pred ^ (pred >> 63)) >> 30; + *(r++) = (int)pred; s -= 5; } break; @@ -777,7 +790,9 @@ namespace CUETools.Codecs pred += coefs[2] * (long)*(s++); pred += c1 * (long)*(s++); pred += c0 * (long)*(s++); - *(r++) = *s - (int)(pred >> shift); + pred = *s - (pred >> shift); + overflows += (pred ^ (pred >> 63)) >> 30; + *(r++) = (int)pred; s -= 6; } break; @@ -792,7 +807,9 @@ namespace CUETools.Codecs pred += coefs[2] * (long)*(s++); pred += c1 * (long)*(s++); pred += c0 * (long)*(s++); - *(r++) = *s - (int)(pred >> shift); + pred = *s - (pred >> shift); + overflows += (pred ^ (pred >> 63)) >> 30; + *(r++) = (int)pred; s -= 7; } break; @@ -813,10 +830,13 @@ namespace CUETools.Codecs pred += coefs[2] * (long)*(s++); pred += c1 * (long)*(s++); pred += c0 * (long)*(s++); - *(r++) = *s - (int)(pred >> shift); + pred = *s - (pred >> shift); + overflows += (pred ^ (pred >> 63)) >> 30; + *(r++) = (int)pred; } break; } + return overflows == 0; } public static unsafe void