refactor: improve comments and variable names for clarity.

This commit is contained in:
Chigozirim Igweamaka 2025-03-08 07:43:24 +01:00
parent 1e5e42e1dc
commit 5411913a98
4 changed files with 12 additions and 17 deletions

View file

@ -4,20 +4,20 @@ import (
"math" "math"
) )
// Fft performs the Fast Fourier Transform on the input signal. // FFT computes the Fast Fourier Transform (FFT) of the input data,
// converting the signal from the time domain to the frequency domain.
// For better understanding, refer to this video: https://www.youtube.com/watch?v=spUNpyF58BY
func FFT(input []float64) []complex128 { func FFT(input []float64) []complex128 {
// Convert input to complex128
complexArray := make([]complex128, len(input)) complexArray := make([]complex128, len(input))
for i, v := range input { for i, v := range input {
complexArray[i] = complex(v, 0) complexArray[i] = complex(v, 0)
} }
fftResult := make([]complex128, len(complexArray)) fftResult := make([]complex128, len(complexArray))
copy(fftResult, complexArray) // Copy input to result buffer copy(fftResult, complexArray)
return recursiveFFT(fftResult) return recursiveFFT(fftResult)
} }
// recursiveFFT performs the recursive FFT algorithm.
func recursiveFFT(complexArray []complex128) []complex128 { func recursiveFFT(complexArray []complex128) []complex128 {
N := len(complexArray) N := len(complexArray)
if N <= 1 { if N <= 1 {

View file

@ -11,7 +11,6 @@ const (
) )
// Fingerprint generates fingerprints from a list of peaks and stores them in an array. // Fingerprint generates fingerprints from a list of peaks and stores them in an array.
// The fingerprints are encoded using a 32-bit integer format and stored in an array.
// Each fingerprint consists of an address and a couple. // Each fingerprint consists of an address and a couple.
// The address is a hash. The couple contains the anchor time and the song ID. // The address is a hash. The couple contains the anchor time and the song ID.
func Fingerprint(peaks []Peak, songID uint32) map[uint32]models.Couple { func Fingerprint(peaks []Peak, songID uint32) map[uint32]models.Couple {

View file

@ -11,11 +11,9 @@ import (
// ConvertSpectrogramToImage converts a spectrogram to a heat map image // ConvertSpectrogramToImage converts a spectrogram to a heat map image
func SpectrogramToImage(spectrogram [][]complex128, outputPath string) error { func SpectrogramToImage(spectrogram [][]complex128, outputPath string) error {
// Determine dimensions of the spectrogram
numWindows := len(spectrogram) numWindows := len(spectrogram)
numFreqBins := len(spectrogram[0]) numFreqBins := len(spectrogram[0])
// Create a new grayscale image
img := image.NewGray(image.Rect(0, 0, numFreqBins, numWindows)) img := image.NewGray(image.Rect(0, 0, numFreqBins, numWindows))
// Scale the values in the spectrogram to the range [0, 255] // Scale the values in the spectrogram to the range [0, 255]
@ -38,7 +36,6 @@ func SpectrogramToImage(spectrogram [][]complex128, outputPath string) error {
} }
} }
// Save the image to a PNG file
file, err := os.Create(outputPath) file, err := os.Create(outputPath)
if err != nil { if err != nil {
return err return err

View file

@ -14,19 +14,18 @@ const (
hopSize = freqBinSize / 32 hopSize = freqBinSize / 32
) )
func Spectrogram(samples []float64, sampleRate int) ([][]complex128, error) { func Spectrogram(sample []float64, sampleRate int) ([][]complex128, error) {
lpf := NewLowPassFilter(maxFreq, float64(sampleRate)) lpf := NewLowPassFilter(maxFreq, float64(sampleRate))
filteredSamples := lpf.Filter(samples) filteredSample := lpf.Filter(sample)
downsampledSamples, err := Downsample(filteredSamples, sampleRate, sampleRate/dspRatio) downsampledSample, err := Downsample(filteredSample, sampleRate, sampleRate/dspRatio)
if err != nil { if err != nil {
return nil, fmt.Errorf("couldn't downsample audio samples: %v", err) return nil, fmt.Errorf("couldn't downsample audio sample: %v", err)
} }
numOfWindows := len(downsampledSamples) / (freqBinSize - hopSize) numOfWindows := len(downsampledSample) / (freqBinSize - hopSize)
spectrogram := make([][]complex128, numOfWindows) spectrogram := make([][]complex128, numOfWindows)
// Apply Hamming window function
window := make([]float64, freqBinSize) window := make([]float64, freqBinSize)
for i := range window { for i := range window {
window[i] = 0.54 - 0.46*math.Cos(2*math.Pi*float64(i)/(float64(freqBinSize)-1)) window[i] = 0.54 - 0.46*math.Cos(2*math.Pi*float64(i)/(float64(freqBinSize)-1))
@ -36,12 +35,12 @@ func Spectrogram(samples []float64, sampleRate int) ([][]complex128, error) {
for i := 0; i < numOfWindows; i++ { for i := 0; i < numOfWindows; i++ {
start := i * hopSize start := i * hopSize
end := start + freqBinSize end := start + freqBinSize
if end > len(downsampledSamples) { if end > len(downsampledSample) {
end = len(downsampledSamples) end = len(downsampledSample)
} }
bin := make([]float64, freqBinSize) bin := make([]float64, freqBinSize)
copy(bin, downsampledSamples[start:end]) copy(bin, downsampledSample[start:end])
// Apply Hamming window // Apply Hamming window
for j := range window { for j := range window {