aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2023-12-19 22:19:50 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2023-12-19 22:19:50 +0300
commitd845d87e2c7fa7afb2ac0ecb239ae1cc0b341937 (patch)
treea883e4bb20e21ce6180b63a8456909bcdd76c681 /examples
parent7059fffa6e55cb0fc406307122dd0688f34ee4fc (diff)
downloadapplause2-d845d87e2c7fa7afb2ac0ecb239ae1cc0b341937.tar.gz
added example for pitch tracking via FFT
Diffstat (limited to 'examples')
-rw-r--r--examples/fft.ipynb62
-rw-r--r--examples/fft.lua17
-rw-r--r--examples/opera.flacbin0 -> 895467 bytes
3 files changed, 77 insertions, 2 deletions
diff --git a/examples/fft.ipynb b/examples/fft.ipynb
index d38cda3..0ac3e96 100644
--- a/examples/fft.ipynb
+++ b/examples/fft.ipynb
@@ -2145,9 +2145,67 @@
]
},
{
+ "cell_type": "markdown",
+ "id": "178a3734-815b-44fa-bd1f-ecc4b45d567b",
+ "metadata": {},
+ "source": [
+ "Pitch Tracking. This however is [not so easy to get right](http://blog.bjornroche.com/2012/07/frequency-detection-using-fft-aka-pitch.html)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "eb6f6047-c6f0-4155-9029-2f643cdc9c04",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "WARNING: Buffer underrun detected\n"
+ ]
+ }
+ ],
+ "source": [
+ "opera = SndfileStream(\"examples/opera.flac\")\n",
+ "opera:play()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "a11139f5-bb3e-4dc1-aa04-eede12abe0d3",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "WARNING: Buffer underrun detected\n",
+ "WARNING: Buffer underrun detected\n"
+ ]
+ }
+ ],
+ "source": [
+ "opera:LPF(10000):FFT(1024, Hanning):map(function(spectrum)\n",
+ "\tlocal size = (#spectrum-1)*2\n",
+ "\tlocal peak_i, peak_val\n",
+ "\tfor i = 1, #spectrum do\n",
+ "\t\t-- We don't have to take the square root to find the peak\n",
+ "\t\tlocal val = spectrum[i].re^2 + spectrum[i].im^2\n",
+ "\t\tif not peak_val or val > peak_val then\n",
+ "\t\t\tpeak_i, peak_val = i, val\n",
+ "\t\tend\n",
+ "\tend\n",
+ "\t-- Return peak as frequency\n",
+ "\treturn tostream((peak_i-1)*samplerate/size):sub(1, size)\n",
+ "end):ravel():div(10000):crush(7):mul(10000):SqrOsc():crush():play()"
+ ]
+ },
+ {
"cell_type": "code",
"execution_count": null,
- "id": "fc38550e-835c-47a8-a792-7164109dafee",
+ "id": "7f43540f-2b92-4e7f-ac8d-160223518a08",
"metadata": {},
"outputs": [],
"source": []
@@ -2163,7 +2221,7 @@
"file_extension": ".lua",
"mimetype": "text/x-lua",
"name": "lua",
- "version": "5.1"
+ "version": "n/a"
}
},
"nbformat": 4,
diff --git a/examples/fft.lua b/examples/fft.lua
index 5930f46..1f8687d 100644
--- a/examples/fft.lua
+++ b/examples/fft.lua
@@ -36,3 +36,20 @@ noisy:FFT(1024, Hamming):map(function(spectrum)
end
return spectrum
end):IFFT(1024):play()
+
+-- Pitch Tracking
+-- See also: http://blog.bjornroche.com/2012/07/frequency-detection-using-fft-aka-pitch.html
+opera = SndfileStream("examples/opera.flac")
+opera:LPF(10000):FFT(1024, Hanning):map(function(spectrum)
+ local size = (#spectrum-1)*2
+ local peak_i, peak_val
+ for i = 1, #spectrum do
+ -- We don't have to take the square root to find the peak
+ local val = spectrum[i].re^2 + spectrum[i].im^2
+ if not peak_val or val > peak_val then
+ peak_i, peak_val = i, val
+ end
+ end
+ -- Return peak as frequency
+ return tostream((peak_i-1)*samplerate/size):sub(1, size)
+end):ravel():div(10000):crush(7):mul(10000):SqrOsc():crush():play()
diff --git a/examples/opera.flac b/examples/opera.flac
new file mode 100644
index 0000000..e4bce4c
--- /dev/null
+++ b/examples/opera.flac
Binary files differ