public override WWUtil.LargeArray <double> FilterDo(WWUtil.LargeArray <double> inPcm) { WWUtil.LargeArray <double> outPcm = new WWUtil.LargeArray <double>(inPcm.LongLength); for (long i = 0; i < outPcm.LongLength; ++i) { outPcm.Set(i, inPcm.At(inPcm.LongLength - i - 1)); } return(outPcm); }
/// <summary> /// Returns jitter added resample position /// retval unit is sample, difference from the ideal resample position of no jitter /// </summary> private double GenerateJitter2() { // 以下のsineJitterの計算、offsを掛けるのではなくて、前回の計算結果にcoeffを足してから // -π ≦ mSineArg < +π にする。 double sineJitter = mSineJitterAmp * Math.Sin(mSineArg); double tpdfJitter = 0.0; double rpdfJitter = 0.0; double timingErrFromFile = 0.0; if (0.0 < mTpdfJitterAmp) { double r = GenRandom0to1(mRand) + GenRandom0to1(mRand) - 1.0; tpdfJitter = mTpdfJitterAmp * r; } if (0.0 < mRpdfJitterAmp) { rpdfJitter = mRpdfJitterAmp * (GenRandom0to1(mRand) * 2.0 - 1.0); } if (mTimingErrorFromAudioFile != null) { timingErrFromFile = 1.0e-9 * TimingErrorFileNanosec * mSampleRate * mTimingErrorFromAudioFile.At(mOffs); } double jitter = sineJitter + tpdfJitter + rpdfJitter + timingErrFromFile; mSineArg += mSineJitterThetaCoefficient; while (Math.PI < mSineArg) { mSineArg -= 2.0 * Math.PI; } ++mOffs; return(jitter); }
Add(WWUtil.LargeArray <double> a, WWUtil.LargeArray <double> b) { if (a.LongLength != b.LongLength) { return(null); } var result = new WWUtil.LargeArray <double>(a.LongLength); for (long i = 0; i < a.LongLength; ++i) { result.Set(i, a.At(i) + b.At(i)); } return(result); }
Mul(WWUtil.LargeArray <WWComplex> a, WWUtil.LargeArray <WWComplex> b) { if (a.LongLength != b.LongLength) { return(null); } var result = new WWUtil.LargeArray <WWComplex>(a.LongLength); for (long i = 0; i < a.LongLength; ++i) { var t = a.At(i); result.Set(i, WWComplex.Mul(t, b.At(i))); } return(result); }
public override WWUtil.LargeArray<double> FilterDo(WWUtil.LargeArray<double> inPcmLA) { System.Diagnostics.Debug.Assert(inPcmLA.LongLength == NumOfSamplesNeeded()); var inPcm = inPcmLA.ToArray(); int inputSamples = (int)((UpsampledWindowLen + 1) / Factor + PROCESS_SLICE); if (mFirst) { var silence = new double[(UpsampledWindowLen + 1) / Factor / 2]; mInputDelay.AddRange(silence); } mInputDelay.AddRange(inPcm); if (inputSamples < mInputDelay.Count) { int count = mInputDelay.Count - inputSamples; mInputDelay.RemoveRange(0, count); } var fromPcm = mInputDelay.ToArray(); var toPcm = new double[PROCESS_SLICE * Factor]; #if false for (int i=0; i<PROCESS_SLICE; ++i) { #else Parallel.For(0, PROCESS_SLICE, i => { #endif for (int f = 0; f < Factor; ++f) { double sampleValue = 0; for (long offs = 0; offs + Factor - f < mCoeffs.LongLength; offs += Factor) { double input = mInputDelay[(int)(offs / Factor + i)]; if (input != 0.0) { sampleValue += mCoeffs.At(offs + Factor - f) * input; } } toPcm[i * Factor + f] = sampleValue; } #if false } #else }); #endif mFirst = false; return new WWUtil.LargeArray<double>(toPcm); } }
private WWUtil.LargeArray <double> FFTFir(WWUtil.LargeArray <double> inPcm, double[] coef, long fftLength) { var fft = new WWMath.WWRadix2FftLargeArray(fftLength); var inTime = new WWUtil.LargeArray <WWComplex>(fftLength); for (long i = 0; i < mNumSamples; ++i) { inTime.Set(i, new WWComplex(inPcm.At(i), 0)); } var inFreq = fft.ForwardFft(inTime); inTime = null; var coefTime = new WWUtil.LargeArray <WWComplex>(fftLength); for (long i = 0; i < mCoeffs[mChannelId * 2].Length; ++i) { coefTime.Set(i, new WWComplex(coef[i], 0)); } var coefFreq = fft.ForwardFft(coefTime); coefTime = null; var mulFreq = Mul(inFreq, coefFreq); inFreq = null; coefFreq = null; var mulTime = fft.InverseFft(mulFreq); mulFreq = null; var result = new WWUtil.LargeArray <double>(inPcm.LongLength); for (int i = 0; i < inPcm.LongLength; ++i) { result.Set(i, mulTime.At(i).real); } mulTime = null; return(result); }
public override WWUtil.LargeArray <double> FilterDo(WWUtil.LargeArray <double> inPcmLA) { var y = new WWUtil.LargeArray <double>(inPcmLA.LongLength); for (long pos = 0; pos < inPcmLA.LongLength; ++pos) { double x = inPcmLA.At(pos); x = mScale * x; foreach (var f in mF) { x = f.Filter(x); } y.Set(pos, x); } return(y); }
private void SetupCoeffs() { var window = WWMath.WWWindowFunc.BlackmanWindow(UpsampledWindowLen); // ループ処理を簡単にするため最初と最後に0を置く。 mCoeffs = new WWUtil.LargeArray<double>(1 + UpsampledWindowLen + 1); long center = UpsampledWindowLen / 2; for (long i = 0; i < UpsampledWindowLen / 2 + 1; ++i) { long numerator = i; int denominator = Factor; int numeratorReminder = (int)(numerator % (denominator*2)); if (numerator == 0) { mCoeffs.Set(1 + center + i, 1.0f); } else if (numerator % denominator == 0) { // sinc(180 deg) == 0, sinc(360 deg) == 0, ... mCoeffs.Set(1 + center + i, 0.0f); } else { mCoeffs.Set(1 + center + i, Math.Sin(Math.PI * numeratorReminder / denominator) / (Math.PI * numerator / denominator) * window.At(center + i)); } mCoeffs.Set(1 + center - i, mCoeffs.At(1 + center + i)); } }
public int GetSampleValueInInt32(int ch, long pos) { Debug.Assert(0 <= ch && ch < NumChannels); if (pos < 0 || NumFrames <= pos) { return(0); } long offset = pos * BitsPerFrame / 8 + ch * BitsPerSample / 8; switch (BitsPerSample) { case 16: return((mSampleLargeArray.At(offset) << 16) + (mSampleLargeArray.At(offset + 1) << 24)); case 24: return((mSampleLargeArray.At(offset) << 8) + (mSampleLargeArray.At(offset + 1) << 16) + (mSampleLargeArray.At(offset + 2) << 24)); case 32: if (SampleValueRepresentationType == PcmDataLib.PcmData.ValueRepresentationType.SFloat) { var buff = new byte[4]; buff[0] = mSampleLargeArray.At(offset + 0); buff[1] = mSampleLargeArray.At(offset + 1); buff[2] = mSampleLargeArray.At(offset + 2); buff[3] = mSampleLargeArray.At(offset + 3); float f = BitConverter.ToSingle(buff, 0); int v = (int)(f * 0x80000000L); return(v); } switch (ValidBitsPerSample) { case 24: return((mSampleLargeArray.At(offset + 1) << 8) + (mSampleLargeArray.At(offset + 2) << 16) + (mSampleLargeArray.At(offset + 3) << 24)); case 32: return((mSampleLargeArray.At(offset)) + (mSampleLargeArray.At(offset + 1) << 8) + (mSampleLargeArray.At(offset + 2) << 16) + (mSampleLargeArray.At(offset + 3) << 24)); default: System.Diagnostics.Debug.Assert(false); return(0); } default: System.Diagnostics.Debug.Assert(false); return(0); } }
/// <summary> /// double[]を戻すバージョン。 /// </summary> /// <param name="count">取得する要素数。範囲外の領域は0が入る。</param> /// <returns></returns> public double[] GetPcmInDoublePcm(int count) { // 確保するサイズはcount個。 if (mTotalSamples <= mOffsBytes / (mBitsPerSample / 8) || count == 0) { // 完全に範囲外。 return(new double[count]); } var result = new double[count]; // コピーするデータの個数はcount個よりも少ないことがある。 int copyCount = result.Length; if (mTotalSamples < mOffsBytes / (mBitsPerSample / 8) + copyCount) { copyCount = (int)(mTotalSamples - mOffsBytes / (mBitsPerSample / 8)); } switch (mBitsPerSample) { case 16: for (int i = 0; i < copyCount; ++i) { short v = (short)((mData.At(mOffsBytes)) + (mData.At(mOffsBytes + 1) << 8)); result[i] = v * (1.0 / 32768.0); mOffsBytes += 2; } break; case 24: for (int i = 0; i < copyCount; ++i) { int v = (int)((mData.At(mOffsBytes) << 8) + (mData.At(mOffsBytes + 1) << 16) + (mData.At(mOffsBytes + 2) << 24)); result[i] = v * (1.0 / 2147483648.0); mOffsBytes += 3; } break; case 32: switch (mValueRepresentationType) { case PcmData.ValueRepresentationType.SInt: for (int i = 0; i < copyCount; ++i) { // 32bit int. int v = (int)( (mData.At(mOffsBytes + 0) << 0) + (mData.At(mOffsBytes + 1) << 8) + (mData.At(mOffsBytes + 2) << 16) + (mData.At(mOffsBytes + 3) << 24)); result[i] = v * (1.0 / 2147483648.0); mOffsBytes += 4; } break; case PcmData.ValueRepresentationType.SFloat: for (int i = 0; i < copyCount; ++i) { // 32bit float. byte [] buff = new byte[4]; for (int j = 0; j < 4; ++j) { buff[j] = mData.At(mOffsBytes + j); } float v = BitConverter.ToSingle(buff, 0); result[i] = v; mOffsBytes += 4; } break; } break; case 64: switch (mValueRepresentationType) { case PcmData.ValueRepresentationType.SInt: for (int i = 0; i < copyCount; ++i) { // 16.48 fixed point number long v = (long)( ((ulong)mData.At(mOffsBytes + 0) << 0) + ((ulong)mData.At(mOffsBytes + 1) << 8) + ((ulong)mData.At(mOffsBytes + 2) << 16) + ((ulong)mData.At(mOffsBytes + 3) << 24) + ((ulong)mData.At(mOffsBytes + 4) << 32) + ((ulong)mData.At(mOffsBytes + 5) << 40) + ((ulong)mData.At(mOffsBytes + 6) << 48) + ((ulong)mData.At(mOffsBytes + 7) << 56)); result[i] = v * (1.0 / 65536.0 / 65536.0 / 65536.0); mOffsBytes += 8; } break; case PcmData.ValueRepresentationType.SFloat: for (int i = 0; i < copyCount; ++i) { // 64bit float. byte[] buff = new byte[8]; for (int j = 0; j < 8; ++j) { buff[j] = mData.At(mOffsBytes + j); } double v = BitConverter.ToDouble(buff, 0); result[i] = v; mOffsBytes += 8; } break; } break; default: System.Diagnostics.Debug.Assert(false); break; } return(result); }