# FFT_AMIGA.py
#
# From the Python prompt:
# >>> exec(open("[/full/path/to/]FFT_AMIGA.py").read())<ENTER>
#
# Very basic FFT code for the AMIGA A1200, with 68030, MMU, MPU, and 6MB RAM.
# This is designed to work on Python 2.0.x to 3.10.1 on any platform.
# The only module needed are the builtin 'cmath' and 'sys'.
# Slowish? Yes but better to have this facility than not.
# Licence is CC0, 2017-2021. Barry Walker, G0LCU.
# This works on just about any platform that has python 2.0.x to 3.10.1.

import sys
import cmath

def fft(DATA):
	N=len(DATA)
	if N<=1: return DATA
	# Check for powers of 2 and immediately exit if not.
	if N&(N-1)!=0:
		print("Power of 2 ERROR!")
		print("Padding or cropping is required to the nearest power of 2 elements.")
		print("Aborting with a return code of 1...")
		sys.exit(1)
	EVEN=fft([DATA[K] for K in range(0,N,2)])
	ODD=fft([DATA[K] for K in range(1,N,2)])
	return [EVEN[K]+cmath.exp(-2j*cmath.pi*K/N)*ODD[K] for K in range(int(N/2))]+[EVEN[K]-cmath.exp(-2j*cmath.pi*K/N)*ODD[K] for K in range(int(N/2))]

# FFT_LIST=[1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]
# [(4+0j), (1-2.414213562373095j), 0j, (1-0.4142135623730949j), 0j, (0.9999999999999999+0.4142135623730949j), 0j, (0.9999999999999997+2.414213562373095j)]
# ***********************
# For 1 cycle, 8 samples.
# ***********************
# 4.00000
# 2.61313
# 0.00000
# 1.08239
# 0.00000
# 1.08239
# 0.00000
# 2.61313

# *************** This is the DEFAULT listing. ***************
FFT_LIST=[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.5, 0.5, 0.5]
# [(8.5+0j), (3.6378211867292967-1.930714405542749j), (-1.7071067811865475-0.5000000000000001j), (0.05142521051217004-0.24146800830128268j), (1.5-1j),
# (-0.17274555407181275+0.4656387728852651j), (-0.29289321881345254+0.5j), (0.4834991568303464-1.2236076243562013j), (0.5+0j), (0.4834991568303464+1.2236076243562015j),
# (-0.29289321881345254-0.4999999999999999j), (-0.1727455540718124-0.465638772885265j), (1.5+1j), (0.05142521051216992+0.24146800830128226j),
# (-1.7071067811865475+0.49999999999999994j), (3.6378211867292958+1.9307144055427488j)]
# ***********************
# None power of 2, 0.5 used as centre padding, 16 samples.
# ***********************
# 8.50000
# 4.11842
# 1.77882
# 0.24688
# 1.80278
# 0.49665
# 0.57947
# 1.31567
# 0.50000
# 1.31567
# 0.57947
# 0.49665
# 1.80278
# 0.24688
# 1.77882
# 4.11842
#
# |*************************************************************
# |**************************
# |***
# |***************************
# |*******
# |********
# |*******************
# |*******
# |*******************
# |********
# |*******
# |***************************
# |***
# |**************************
# |*************************************************************
#
# **************** End of the DEFAULT listing. ***************

# FFT_LIST=[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# [(32+0j), 0j, (2.0000000000000004-20.306340775217716j), 0j, 0j, 0j, (2.000000000000001-6.59311641787664j), 0j, 0j, 0j, (2-3.7417368235787785j),
# 0j, 0j, 0j, (2.0000000000000004-2.4370070511759523j), 0j, 0j, 0j, (1.9999999999999998-1.6413575816573212j), 0j, 0j, 0j, (2.000000000000001-1.069022271901583j),
# 0j, 0j, 0j, (1.9999999999999993-0.6066933672146853j), 0j, 0j, 0j, (2.0000000000000027-0.19698280671432933j), 0j, 0j, 0j, (1.9999999999999996+0.19698280671432755j),
# 0j, 0j, 0j, (1.9999999999999998+0.6066933672146848j), 0j, 0j, 0j, (1.9999999999999996+1.069022271901583j), 0j, 0j, 0j, (1.9999999999999996+1.6413575816573212j),
# 0j, 0j, 0j, (2.0000000000000004+2.4370070511759523j), 0j, 0j, 0j, (1.9999999999999982+3.7417368235787793j), 0j, 0j, 0j, (2+6.59311641787664j),
# 0j, 0j, 0j, (1.999999999999994+20.30634077521772j), 0j]
# *************************
# For 2 cycles, 64 samples.
# *************************
# 32.00000
# 0.00000
# 20.40459
# 0.00000
# 0.00000
# 0.00000
# 6.88979
# 0.00000
# 0.00000
# 0.00000
# 4.24271
# 0.00000
# 0.00000
# 0.00000
# 3.15262
# 0.00000
# 0.00000
# 0.00000
# 2.58729
# 0.00000
# 0.00000
# 0.00000
# 2.26778
# 0.00000
# 0.00000
# 0.00000
# 2.08999
# 0.00000
# 0.00000
# 0.00000
# 2.00968
# 0.00000
# 0.00000
# 0.00000
# 2.00968
# 0.00000
# 0.00000
# 0.00000
# 2.08999
# 0.00000
# 0.00000
# 0.00000
# 2.26778
# 0.00000
# 0.00000
# 0.00000
# 2.58729
# 0.00000
# 0.00000
# 0.00000
# 3.15262
# 0.00000
# 0.00000
# 0.00000
# 4.24271
# 0.00000
# 0.00000
# 0.00000
# 6.88979
# 0.00000
# 0.00000
# 0.00000
# 20.40459
# 0.00000

FFT=fft(FFT_LIST)
print('')
print("FFT complex number list...")
print(FFT)
print('')

LENGTH=len(FFT)
print("Absolute FFT values...")
for FFT_LISTING in range(0,LENGTH,1): print("%.5f" %(abs(FFT[FFT_LISTING])))
print('')

print("Quick text mode uncalibrated spectrum display...")
for FFT_LISTING in range(1,len(FFT),1):
	# Change the current MULTIPLIER, 15.0, as required, this is for the DEFAULT FFT_LIST...
	# Value of MULTIPLIER for the 1 cycle, 8 sample mode is 20.0...
	# Value of MULTIPLIER for the 2 cycles, 64 samples mode is 3.0...
	MULTIPLIER=15.0
	CHAR='# |'
	HORIZ=(int(MULTIPLIER*(abs(FFT[FFT_LISTING]))))
	for DISPLAY in range(1,(HORIZ+1),1):
		CHAR=CHAR+'*'
	print(CHAR)

sys.exit(0)