changeset 1:1c027151f7ec

Beginnings of a test script
author Chris Cannam
date Thu, 01 Oct 2015 16:56:01 +0100
parents d7c216b6a84f
children 44f670784d5f
files .hgignore fft/test.html
diffstat 2 files changed, 97 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Thu Oct 01 16:56:01 2015 +0100
@@ -0,0 +1,2 @@
+syntax: glob
+*~
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fft/test.html	Thu Oct 01 16:56:01 2015 +0100
@@ -0,0 +1,95 @@
+    <html>
+    <body>
+    <p>If 2150 iterations of real-to-complex FFT of size 2048 takes less than 10 seconds, then we may be able to make a high quality real-time phase vocoder (just).</p>
+
+<p>A phase-vocoder of course must use overlapped
+windowed FFT (although you can choose the size, within limits), IFFT,
+and cartesian-polar conversion to calculate the phase for the
+instantaneous frequency.</p>
+
+<p>A reasonable estimate of CPU cost for the whole thing is somewhere
+around 10x the cost of simple non-overlapping short-time forward
+Fourier transforms across the signal. </p>
+
+<p>2150 iterations corresponds to 100 seconds of audio non-overlapped at
+44.1kHz, so if that takes less than 10 second, then in theory we might
+be OK.</p>
+    <pre>
+<script src="nayuki/fft.js"></script>
+<script>
+
+/* for a phase vocoder, we probably want 2048-point real-to-complex
+ * FFTs (if available) */
+
+function inputReals(size) {
+    var result = new Array(size);
+    for (var i = 0; i < result.length; i++)
+	result[i] = (i % 20) / 10.0 - 1.0;
+    return result;
+}
+
+function zeroReals(size) {
+    var result = new Array(size);
+    for (var i = 0; i < result.length; i++)
+	result[i] = 0.0;
+    return result;
+}
+
+function inputReal64s(size) {
+    var result = new Float64Array(size);
+    for (var i = 0; i < result.length; i++)
+	result[i] = (i % 20) / 10.0 - 1.0;
+    return result;
+}
+
+var iterations = 2150;
+var size = 2048;
+
+var start = performance.now();
+
+var total = 0.0;
+
+for (var i = 0; i < iterations; ++i) {
+    var real = inputReals(size);
+    var imag = zeroReals(size);
+    transform(real, imag);
+    for (var j = 0; j < size; ++j) {
+	total += real[j] + imag[j];
+    }
+}
+
+document.write("total = " + total + "<br>");
+
+var end = performance.now();
+
+document.write("nayuki fft.js: " + iterations + " iterations at size " + size + " took " + (end - start) + "ms (" + (1000.0 / ((end - start) / iterations)) + " iterations/sec)<br>");
+
+</script>
+<script src="fft.js/lib/complex.js"></script>
+<script>
+    
+var fft = new FFT.complex(size, false);
+    
+start = performance.now();
+
+total = 0.0;
+
+for (var i = 0; i < iterations; ++i) {
+    var ri = inputReal64s(size);
+    var co = new Float64Array(2 * size);
+    fft.simple(co, ri, 'real');
+    for (var j = 0; j < 2 * size; ++j) {
+	total += co[j];
+    }
+}
+
+document.write("total = " + total + "<br>");
+
+var end = performance.now();
+
+document.write("nockert fft.js: " + iterations + " iterations at size " + size + " took " + (end - start) + "ms (" + (1000.0 / ((end - start) / iterations)) + " iterations/sec)<br>");
+
+    </script>
+</pre>
+    </body>
+