private void ReduceBitsPerSample24Ns2(ConvertParams args, DataSubChunk toDsc) { var ns = new NoiseShaper2[mFsc.numChannels]; for (int ch = 0; ch < mFsc.numChannels; ++ch) { ns[ch] = new NoiseShaper2(args.order, args.filter, args.newQuantizationBitrate); } int bytesPerFrame = mFsc.numChannels * mFsc.bitsPerSample / 8; int numFrames = toDsc.data.Length / bytesPerFrame; int readPos = 0; int writePos = 0; for (int i = 0; i < numFrames; ++i) { for (int ch = 0; ch < mFsc.numChannels; ++ch) { int sample = 0; sample = ns[ch].Filter24(ReadSampleValue24(toDsc, readPos)); readPos += mFsc.bitsPerSample / 8; WriteSampleValue24(toDsc, writePos, sample); writePos += mFsc.bitsPerSample / 8; } } }
public void Convert(ConvertParams args, BinaryWriter bw) { var toDsc = new DataSubChunk(); toDsc.Setup(mDsc.subChunk2Size, mDsc.data); switch (args.ditherType) { case ConvertParams.DitherType.NoiseShaping: args.order = 1; args.filter = new double[] {1, -1}; ReduceBitsPerSample24Ns2(args, toDsc); break; case ConvertParams.DitherType.NoiseShaping2: args.order = 2; args.filter = new double[] {1, -2, 1}; ReduceBitsPerSample24Ns2(args, toDsc); break; case ConvertParams.DitherType.NoiseShapingMash2: ReduceBitsPerSample24Mash2(args, toDsc); break; default: ReduceBitsPerSample24Other(args, toDsc); break; } mRcd.Write(bw); mFsc.Write(bw); toDsc.Write(bw); }
public void Convert(ConvertParams args, BinaryWriter bw) { var toDsc = new DataSubChunk(); toDsc.Setup(mDsc.subChunk2Size, mDsc.data); switch (args.ditherType) { case ConvertParams.DitherType.NoiseShaping: args.order = 1; args.filter = new double[] { 1, -1 }; ReduceBitsPerSample24Ns2(args, toDsc); break; case ConvertParams.DitherType.NoiseShaping2: args.order = 2; args.filter = new double[] { 1, -2, 1 }; ReduceBitsPerSample24Ns2(args, toDsc); break; case ConvertParams.DitherType.NoiseShapingMash2: ReduceBitsPerSample24Mash2(args, toDsc); break; default: ReduceBitsPerSample24Other(args, toDsc); break; } mRcd.Write(bw); mFsc.Write(bw); toDsc.Write(bw); }
private int ReadSampleValue24(DataSubChunk fromDsc, int pos) { switch (mFsc.bitsPerSample) { case 16: return(256 * fromDsc.GetSampleValue16(pos)); case 24: return(fromDsc.GetSampleValue24(pos)); default: throw new NotImplementedException(); } }
private void WriteSampleValue24(DataSubChunk toDsc, int pos, int value24) { switch (mFsc.bitsPerSample) { case 16: toDsc.SetSampleValue16(pos, (short)(value24 / 256)); break; case 24: toDsc.SetSampleValue24(pos, value24); break; default: throw new NotImplementedException(); } }
public bool ReadFromFile(BinaryReader br) { mRcd = null; mFsc = null; mDsc = null; try { while (true) { var subChunk1Id = br.ReadInt32(); switch (subChunk1Id) { case ((int)('R')) + (((int)('I')) << 8) + (((int)('F')) << 16) + (((int)('F')) << 24): mRcd = new RiffChunkDescriptor(); if (!mRcd.Read(br)) { return(false); } break; case ((int)('f')) + (((int)('m')) << 8) + (((int)('t')) << 16) + (((int)(' ')) << 24): mFsc = new FmtSubChunk(); if (!mFsc.Read(br)) { return(false); } break; case ((int)('d')) + (((int)('a')) << 8) + (((int)('t')) << 16) + (((int)('a')) << 24): mDsc = new DataSubChunk(); if (!mDsc.Read(br)) { return(false); } break; default: SkipUnknownChunk(br); break; } } } catch (EndOfStreamException ex) { // 正常終了wwww } return(mRcd != null && mFsc != null && mDsc != null); }
private void ReduceBitsPerSample24Mash2(ConvertParams args, DataSubChunk toDsc) { var mash = new NoiseShaperMash[mFsc.numChannels]; for (int ch = 0; ch < mFsc.numChannels; ++ch) { mash[ch] = new NoiseShaperMash(args.newQuantizationBitrate); } int bytesPerFrame = mFsc.numChannels * mFsc.bitsPerSample / 8; int numFrames = toDsc.data.Length / bytesPerFrame; int readPos = 0; int writePos = 0; // 1サンプル遅延するので…。 for (int i = 0; i < numFrames + 1; ++i) { for (int ch = 0; ch < mFsc.numChannels; ++ch) { int sample = 0; if (i < numFrames) { sample = mash[ch].Filter24(ReadSampleValue24(toDsc, readPos)); readPos += mFsc.bitsPerSample / 8; } else { sample = mash[ch].Filter24(0); } if (1 <= i) { WriteSampleValue24(toDsc, writePos, sample); writePos += mFsc.bitsPerSample / 8; } } } }
public bool ReadFromFile(BinaryReader br) { mRcd = null; mFsc = null; mDsc = null; try { while (true) { var subChunk1Id = br.ReadInt32(); switch (subChunk1Id) { case ((int)('R')) + (((int)('I')) << 8) + (((int)('F')) << 16) + (((int)('F')) << 24): mRcd = new RiffChunkDescriptor(); if (!mRcd.Read(br)) { return false; } break; case ((int)('f')) + (((int)('m')) << 8) + (((int)('t')) << 16) + (((int)(' ')) << 24): mFsc = new FmtSubChunk(); if (!mFsc.Read(br)) { return false; } break; case ((int)('d')) + (((int)('a')) << 8) + (((int)('t')) << 16) + (((int)('a')) << 24): mDsc = new DataSubChunk(); if (!mDsc.Read(br)) { return false; } break; default: SkipUnknownChunk(br); break; } } } catch (EndOfStreamException ex) { // 正常終了wwww } return mRcd != null && mFsc != null && mDsc != null; }
private void ReduceBitsPerSample24Other(ConvertParams args, DataSubChunk toDsc) { uint mask = 0xffffffff << (24 - args.newQuantizationBitrate); uint maskError = ~mask; var gen = new RNGCryptoServiceProvider(); var gng = new GaussianNoiseGenerator(); var randomNumber = new byte[3]; int noiseMagnitude = (int)Math.Pow(2, (24 - args.newQuantizationBitrate)) / 2; Console.WriteLine("D: maskErr={0:X}", maskError); int bytesPerFrame = mFsc.numChannels * mFsc.bitsPerSample / 8; int numFrames = toDsc.data.Length / bytesPerFrame; int pos = 0; for (int i = 0; i < numFrames; ++i) { for (int ch = 0; ch < mFsc.numChannels; ++ch) { double sample = ReadSampleValue24(toDsc, pos); uint error = (uint)sample & maskError; sample -= error; switch (args.ditherType) { case ConvertParams.DitherType.Truncate: break; case ConvertParams.DitherType.RpdfDither: gen.GetBytes(randomNumber); int randDither = (int)((randomNumber[0]) + (randomNumber[1] << 8) + (randomNumber[2] << 16) & ~mask); sample += randDither; break; case ConvertParams.DitherType.GaussianDither: float noise = gng.NextFloat(); noise *= noiseMagnitude; sample += (int)noise; break; default: System.Diagnostics.Debug.Assert(false); break; } if (0x7fffff < sample) { sample = 0x7fffff; } if (sample < -0x800000) { sample = -0x800000; } WriteSampleValue24(toDsc, pos, (int)sample); pos += mFsc.bitsPerSample / 8; } } }
private int ReadSampleValue24(DataSubChunk fromDsc, int pos) { switch (mFsc.bitsPerSample) { case 16: return 256 * fromDsc.GetSampleValue16(pos); case 24: return fromDsc.GetSampleValue24(pos); default: throw new NotImplementedException(); } }
private void WriteSampleValue24(DataSubChunk toDsc, int pos, int value24) { switch (mFsc.bitsPerSample) { case 16: toDsc.SetSampleValue16(pos, (short)(value24 / 256)); break; case 24: toDsc.SetSampleValue24(pos, value24); break; default: throw new NotImplementedException(); } }
private void ReduceBitsPerSample24Other(ConvertParams args, DataSubChunk toDsc) { uint mask = 0xffffffff << (24 - args.newQuantizationBitrate); uint maskError = ~mask; var gen = new RNGCryptoServiceProvider(); var gng = new GaussianNoiseGenerator(); var randomNumber = new byte[3]; int noiseMagnitude = (int)Math.Pow(2, (24 - args.newQuantizationBitrate))/2; Console.WriteLine("D: maskErr={0:X}", maskError); int bytesPerFrame = mFsc.numChannels * mFsc.bitsPerSample / 8; int numFrames = toDsc.data.Length / bytesPerFrame; int pos = 0; for (int i=0; i < numFrames; ++i) { for (int ch=0; ch < mFsc.numChannels; ++ch) { double sample = ReadSampleValue24(toDsc, pos); uint error = (uint)sample & maskError; sample -= error; switch (args.ditherType) { case ConvertParams.DitherType.Truncate: break; case ConvertParams.DitherType.RpdfDither: gen.GetBytes(randomNumber); int randDither = (int)((randomNumber[0]) + (randomNumber[1] << 8) + (randomNumber[2]<<16) & ~mask); sample += randDither; break; case ConvertParams.DitherType.GaussianDither: float noise = gng.NextFloat(); noise *= noiseMagnitude; sample += (int)noise; break; default: System.Diagnostics.Debug.Assert(false); break; } if (0x7fffff < sample) { sample = 0x7fffff; } if (sample < -0x800000) { sample = -0x800000; } WriteSampleValue24(toDsc, pos, (int)sample); pos += mFsc.bitsPerSample / 8; } } }
private void ReduceBitsPerSample24Ns2(ConvertParams args, DataSubChunk toDsc) { var ns = new NoiseShaper2[mFsc.numChannels]; for (int ch=0; ch < mFsc.numChannels; ++ch) { ns[ch] = new NoiseShaper2(args.order, args.filter, args.newQuantizationBitrate); } int bytesPerFrame = mFsc.numChannels * mFsc.bitsPerSample / 8; int numFrames = toDsc.data.Length / bytesPerFrame; int readPos = 0; int writePos = 0; for (int i=0; i < numFrames; ++i) { for (int ch=0; ch < mFsc.numChannels; ++ch) { int sample = 0; sample = ns[ch].Filter24(ReadSampleValue24(toDsc, readPos)); readPos += mFsc.bitsPerSample / 8; WriteSampleValue24(toDsc, writePos, sample); writePos += mFsc.bitsPerSample / 8; } } }
private void ReduceBitsPerSample24Mash2(ConvertParams args, DataSubChunk toDsc) { var mash = new NoiseShaperMash[mFsc.numChannels]; for (int ch=0; ch < mFsc.numChannels; ++ch) { mash[ch] = new NoiseShaperMash(args.newQuantizationBitrate); } int bytesPerFrame = mFsc.numChannels * mFsc.bitsPerSample / 8; int numFrames = toDsc.data.Length / bytesPerFrame; int readPos = 0; int writePos = 0; // 1サンプル遅延するので…。 for (int i=0; i < numFrames + 1; ++i) { for (int ch=0; ch < mFsc.numChannels; ++ch) { int sample = 0; if (i < numFrames) { sample = mash[ch].Filter24(ReadSampleValue24(toDsc, readPos)); readPos += mFsc.bitsPerSample / 8; } else { sample = mash[ch].Filter24(0); } if (1 <= i) { WriteSampleValue24(toDsc, writePos, sample); writePos += mFsc.bitsPerSample / 8; } } } }