| 
				
			 | 
			
			
				
				@@ -0,0 +1,86 @@ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				1
			 | 
			
			
				
				+# The MIT License (MIT) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2
			 | 
			
			
				
				+# 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3
			 | 
			
			
				
				+# Copyright (c) 2019 Tom Schucker for Tea and Tech Time 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				4
			 | 
			
			
				
				+# 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				5
			 | 
			
			
				
				+# Permission is hereby granted, free of charge, to any person obtaining a copy 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				6
			 | 
			
			
				
				+# of this software and associated documentation files (the "Software"), to deal 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				7
			 | 
			
			
				
				+# in the Software without restriction, including without limitation the rights 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				8
			 | 
			
			
				
				+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				9
			 | 
			
			
				
				+# copies of the Software, and to permit persons to whom the Software is 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				10
			 | 
			
			
				
				+# furnished to do so, subject to the following conditions: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				11
			 | 
			
			
				
				+# 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				12
			 | 
			
			
				
				+# The above copyright notice and this permission notice shall be included in 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				13
			 | 
			
			
				
				+# all copies or substantial portions of the Software. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				14
			 | 
			
			
				
				+# 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				15
			 | 
			
			
				
				+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				16
			 | 
			
			
				
				+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				17
			 | 
			
			
				
				+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				18
			 | 
			
			
				
				+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				19
			 | 
			
			
				
				+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				20
			 | 
			
			
				
				+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				21
			 | 
			
			
				
				+# THE SOFTWARE. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				22
			 | 
			
			
				
				+""" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				23
			 | 
			
			
				
				+`teaandtechtime_fft` 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				24
			 | 
			
			
				
				+================================================================================ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				25
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				26
			 | 
			
			
				
				+CircuitPython FFT Library 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				27
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				28
			 | 
			
			
				
				+* Author(s): Tom Schucker 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				29
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				30
			 | 
			
			
				
				+Implementation Notes 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				31
			 | 
			
			
				
				+--------------------- 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				32
			 | 
			
			
				
				+This variant comes from @thedod's `no-itertools` fork: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				33
			 | 
			
			
				
				+https://github.com/thedod/CircuitPython_FFT/tree/no-itertools 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				34
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				35
			 | 
			
			
				
				+**Hardware:** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				36
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				37
			 | 
			
			
				
				+**Software and Dependencies:** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				38
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				39
			 | 
			
			
				
				+* Adafruit CircuitPython firmware for the supported boards: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				40
			 | 
			
			
				
				+  https://github.com/adafruit/circuitpython/releases 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				41
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				42
			 | 
			
			
				
				+""" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				43
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				44
			 | 
			
			
				
				+# imports 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				45
			 | 
			
			
				
				+from math import pi, sin, cos, sqrt, pow, log 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				46
			 | 
			
			
				
				+import array 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				47
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				48
			 | 
			
			
				
				+__version__ = "0.0.0-auto.0" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				49
			 | 
			
			
				
				+__repo__ = "https://github.com/tschucker/Teaandtechtime_CircuitPython_FFT.git" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				50
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				51
			 | 
			
			
				
				+#Computes the complex fft of the input array needs to be power of 2 length to work. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				52
			 | 
			
			
				
				+def fft(x): 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				53
			 | 
			
			
				
				+    N = len(x) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				54
			 | 
			
			
				
				+    if N <= 1: return x 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				55
			 | 
			
			
				
				+    even = fft([x[i] for i in range(0, N, 2)]) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				56
			 | 
			
			
				
				+    odd =  fft([x[i] for i in range(1, N, 2)]) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				57
			 | 
			
			
				
				+    T = [cos(2*pi*k/N)*odd[k].real+sin(2*pi*k/N)*odd[k].imag + (cos(2*pi*k/N)*odd[k].imag-sin(2*pi*k/N)*odd[k].real)*1j for k in range(N//2)] 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				58
			 | 
			
			
				
				+    return [even[k].real + T[k].real + (even[k].imag + T[k].imag)*1j for k in range(N//2)] + \ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				59
			 | 
			
			
				
				+           [even[k].real - T[k].real + (even[k].imag - T[k].imag)*1j for k in range(N//2)] 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				60
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				61
			 | 
			
			
				
				+#Computes the complex inverse fft of the input array needs to be power of 2 length to work 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				62
			 | 
			
			
				
				+#not the most efficiant but uses the same fft code. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				63
			 | 
			
			
				
				+def ifft(x): 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				64
			 | 
			
			
				
				+    fft_len = float(len(x)) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				65
			 | 
			
			
				
				+    x_swap = [] 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				66
			 | 
			
			
				
				+    for s in x: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				67
			 | 
			
			
				
				+        x_swap.append(s.imag + s.real*1j) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				68
			 | 
			
			
				
				+    temp = fft(x_swap) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				69
			 | 
			
			
				
				+    temp_swap = [] 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				70
			 | 
			
			
				
				+    for s in temp: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				71
			 | 
			
			
				
				+        temp_swap.append((s.imag/fft_len) + (s.real/fft_len)*1j) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				72
			 | 
			
			
				
				+    return temp_swap 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				73
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				74
			 | 
			
			
				
				+#Computes the double sided spectrogram of the input array needs to be a power of 2 to work 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				75
			 | 
			
			
				
				+def spectrogram(x): 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				76
			 | 
			
			
				
				+    freq = fft(x) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				77
			 | 
			
			
				
				+    temp_list = [] 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				78
			 | 
			
			
				
				+    for f in freq: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				79
			 | 
			
			
				
				+        abs_val = abs(f) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				80
			 | 
			
			
				
				+        if  abs_val != 0.0: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				81
			 | 
			
			
				
				+            temp_list.append(int(log(abs_val))) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				82
			 | 
			
			
				
				+        else: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				83
			 | 
			
			
				
				+            temp_list.append(0) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				84
			 | 
			
			
				
				+    return temp_list 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				85
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				86
			 | 
			
			
				
				+ 
			 |