Beispiel #1
0
// IDCTOrthogonal returns Inverse DCT (DCT-III) coefficients given a input
// signal.
func IDCTOrthogonal(dctCoef []float64) []float64 {
	n := len(dctCoef)
	nh := n / 2
	array := make([]complex128, n)

	theta := math.Pi / (2.0 * float64(n))

	c0 := math.Sqrt(1.0 / float64(n))
	c1 := math.Sqrt(2.0 / float64(n))

	// -1/4 Shift
	for k := 1; k < nh; k++ {
		w := cmplx.Exp(complex(0, float64(k)*theta))
		wCont := complex(imag(w), real(w))
		array[k] = w * complex(c1*dctCoef[k], 0)
		array[n-k] = wCont * complex(c1*dctCoef[n-k], 0)
	}
	array[0] = complex(c0*dctCoef[0], 0)
	array[nh] = complex(c1*dctCoef[nh], 0) *
		cmplx.Exp(complex(0, float64(nh)*theta))

	y := fft.IFFT(array)

	x := make([]float64, n)
	for i := 0; i < nh; i++ {
		x[2*i] = float64(n) * real(y[i])
		x[2*i+1] = float64(n) * real(y[n-1-i])
	}

	return x
}
Beispiel #2
0
func ExtIFFT_C(samples vlib.VectorC, N int) vlib.VectorC {

	y := vlib.VectorC(fft.IFFT(samples))
	y = y.Scale(math.Sqrt(1.0 / float64(N)))
	return y

}
Beispiel #3
0
// ISTFT performs invere STFT signal reconstruction and returns reconstructed
// signal.
func (s *STFT) ISTFT(spectrogram [][]complex128) []float64 {
	frameLen := len(spectrogram[0])
	numFrames := len(spectrogram)
	reconstructedSignal := make([]float64, frameLen+numFrames*s.FrameShift)

	// Griffin's method
	windowSum := make([]float64, len(reconstructedSignal))
	for i := 0; i < numFrames; i++ {
		buf := fft.IFFT(spectrogram[i])
		index := 0
		for t := i * s.FrameShift; t < i*s.FrameShift+frameLen; t++ {
			reconstructedSignal[t] += real(buf[index]) * s.Window[index]
			windowSum[t] += s.Window[index] * s.Window[index]
			index++
		}
	}

	// Normalize by window
	for n := range reconstructedSignal {
		if windowSum[n] > 1.0e-21 {
			reconstructedSignal[n] /= windowSum[n]
		}
	}

	return reconstructedSignal
}
Beispiel #4
0
func XCorrFFT(x1, x2 []float64, circular bool) []float64 {
	// zero padding.
	ftlength := len(x1)
	if !circular {
		length := len(x1) * 2
		var i uint32 = 1
		for ftlength < length {
			ftlength = 1 << i
			i++
		}
	}

	datax1 := make([]complex128, ftlength)
	datax2 := make([]complex128, ftlength)
	for i := 0; i < len(x1); i++ {
		datax1[i] = complex(x2[i%len(x2)], 0)
		datax2[i] = complex(x1[i%len(x1)], 0)
	}

	v1 := fft.FFT(datax1)
	v2 := fft.FFT(datax2)
	temp := []complex128{}
	for i := 0; i < len(v1); i++ {
		v := v1[i] * cmplx.Conj(v2[i])
		temp = append(temp, v)
	}
	v3 := fft.IFFT(temp)

	res := []float64{}
	for i := 0; i < len(x1); i++ {
		res = append(res, real(v3[i]))
	}
	return res
}
Beispiel #5
0
func (cqi *CQInverse) processOctaveColumn(octave int, column []complex128) {
	// 3. For each taller column, take the product with the inverse CQ
	// kernel (which is the conjugate of the forward kernel) and
	// perform an inverse FFT
	bpo := cqi.kernel.Properties.binsPerOctave
	apf := cqi.kernel.Properties.atomsPerFrame
	fftSize := cqi.kernel.Properties.fftSize

	if len(column) != bpo*apf {
		fmt.Printf("Error: column in octave %d has size %d, required = %d * %d = %d\n",
			octave, len(column), bpo, apf, bpo*apf)
		panic("Invalid argument to inverse processOctaveColumn")
	}

	transformed := cqi.kernel.ProcessInverse(column)

	// For inverse real transforms, force symmetric conjugate representation first.
	for i := fftSize/2 + 1; i < fftSize; i++ {
		transformed[i] = cmplx.Conj(transformed[fftSize-i])
	}

	inverse := fft.IFFT(transformed)
	cqi.overlapAddAndResample(octave, realParts(inverse))
}