Skip to content

ascpixi/hftnn

Repository files navigation

Harmonic Fourier Transform for Neural Networks (HFTNN)

An HFTNN is a filtered version of a Fourier transform, suitable for training neural networks on content that is harmonic in nature. The resulting transforms may greatly reduce the required size of the input layer of a NN. For data such as e.g. piano performances or synthesizer pads, an HFTNN removes redundant information, as well as removing any inharmonic noise that might have been present in the dataset.

For example usage, you may refer to the demo contained in the repository. The demo is also hosted on https://ascpixi.dev/hftnn.

Theory of Operation

In an HFTNN forward transform, the following steps are performed:

  1. Given a discrete signal x [ n ] , the signal is partitioned into non-overlapping, windowed segments of length N . Each segment is denoted as x chunk [ k ] , where k is the segment index.

x chunk [ k ] = x [ n ] , for  n = k N  to  ( k + 1 ) N βˆ’ 1

  1. The Fourier transform of each segment x chunk [ k ] is denoted as X chunk [ k ] .

X chunk [ k ] = F ( x chunk [ k ] )

  1. For each Fourier transform bin, harmonics are selected within a specified range of octaves, including neighboring bins. Let HFT be the resulting array.

HFT [ j ] = [ magnitude , phase ]

Here, j represents the index iterating over the selected harmonics and neighboring bins.

  1. The frequency corresponding to each harmonic is calculated using the function freq ( j ) . The corresponding FFT bin index is denoted as binIdx ( j ) .

freq ( j ) = intervalToFreq ( j , fundamental , frequenciesInOctave )

binIdx ( j ) = freqToFftBin ( freq ( j ) , sampleRate , signalLength )

  1. To handle edge cases where the computed bin index binIdx and neighboring indices idx may exceed array bounds, a conditional statement is used.

HFT [ j ] = { [ 0 , 0 ] , if  idx < 0  or  idx β‰₯ bins.length [ magnitude , phase ] , otherwise

A similar algorithm is employed for the inverse temporal transform.

✨ Usage

You can use the library as a regular npm package. For example usage, see /demo/src/app/HftnnDemo.tsx.

import { hftnnForwardTemporal } from "hftnn";

const output = hftnnForwardTemporal(signal, {
   sampleRate: 44100,
   octaveRange: 11,
   extraBins: 2,
   interpolatedChunks: 0,
   dftSize: 2048,
   fundamental: 16.351597831287414,
   frequenciesInOctave: 12
});

// output is a [number, number][][] - i.e., an array of arrays of arrays that always hold two numbers

If you want to use the library out-right in a browser in vanilla JS, with all dependencies attached, use npm run build. This will create a ./build/hftnn-build.js file, which you can then import in a browser.

<script src="./build/hftnn-bundle.js"></script>

<script>
   console.log(HFTNN.hftnnForward(/* insert params here */));
</script>