-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspectrumanalyzer.py
More file actions
141 lines (118 loc) · 4.81 KB
/
spectrumanalyzer.py
File metadata and controls
141 lines (118 loc) · 4.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# Spectrum Analyzer Code Author: Caleb Wolfe
import time
import Adafruit_GPIO.SPI as SPI
import Adafruit_MCP3008
import numpy as np
class SpectrumAnalyzer:
def __init__(self, smprate=44100, senistivity=100.0, samplesize=1024):
self.__samplerate = smprate
self.__peaksample = senistivity
self.__samplesArraySize = (
samplesize # sample size for the audio batch to be analyzed
)
self.__buckets = []
# Hardware SPI configuration:
SPI_PORT = 0
SPI_DEVICE = 0
spid = SPI.SpiDev(SPI_PORT, SPI_DEVICE)
spid.set_clock_hz(self.__samplerate)
self.__mcp = Adafruit_MCP3008.MCP3008(spi=spid)
def __calculate_levels(self, inputarray):
darray = np.array(inputarray, dtype="float")
fourier = np.fft.rfft(darray) # apply discrete FFT
fftusable = fourier[
: self.__samplesArraySize - 1
] # Remove items past Nyquist limit
power = np.abs(fftusable) # convert the complex numbers to real numbers
nyqquistadjustment = (power * 2) / (
1024 * self.__samplesArraySize
) # Adjust the values to find actual amplitude (1024 is the max range of voltage)
result = nyqquistadjustment
self.__fft = result
def __readmicval(self):
value = self.__mcp.read_adc(0)
return value
def __getvals(self):
subbassbucket = []
bassbucketlow = []
bassbuckethigh = []
lowmid1bucket = []
lowmid2bucket = []
lowmid3bucket = []
lowmid4bucket = []
mid1bucket = []
mid2bucket = []
mid3bucket = []
mid4bucket = []
midbuckethigh = []
highbucketlow = []
highbuckethigh = []
amps = []
currentpos = 0
# find the values of the amplitudes to each bucket
for a in self.__fft: # append amplitudes to buckets
amp = (
a * 10000
) # make values more managable (Lower decible setting, changed to 10000 for experimentaion with quieter db levels
frq = self.__freqarray[currentpos] # get the current frequency
#
if (
amp > self.__peaksample
): # this applies senistivity levels to ignor non signifigant amplitudes
if frq > 20 and frq < 60: # and p in range(0,3) :
amp = (amp + 50) % 256
subbassbucket.append(amp)
elif frq >= 60 and frq < 155: # and p in range(3,5):
bassbucketlow.append(amp)
elif frq >= 155 and frq < 250:
bassbuckethigh.append(amp)
elif frq >= 250 and frq < 313:
lowmid1bucket.append(amp)
elif frq >= 313 and frq < 376: # and p in range(5,9):
lowmid2bucket.append(amp)
elif frq >= 376 and frq < 439: # and p in range(5,9):
lowmid3bucket.append(amp)
elif frq >= 439 and frq < 500: # and p in range(5,9):
lowmid4bucket.append(amp)
elif frq >= 500 and frq < 875:
mid1bucket.append(amp)
elif frq >= 875 and frq < 1250:
mid2bucket.append(amp)
elif frq >= 1250 and frq < 1625: # and p in range(9,12):
mid3bucket.append(amp)
elif frq >= 1625 and frq < 2000: # and p in range(9,12):
mid4bucket.append(amp)
elif frq >= 2000 and frq < 3000: # and p in range(12,15):
highbucketlow.append(amp)
elif frq >= 3000 and frq < 4000: # and p in range(12,15):
highbuckethigh.append(amp)
currentpos += 1
self.__buckets = [
np.mean(subbassbucket),
np.mean(bassbucketlow),
np.mean(bassbuckethigh),
np.mean(lowmid1bucket),
np.mean(lowmid2bucket),
np.mean(lowmid3bucket),
np.mean(lowmid4bucket),
np.mean(mid1bucket),
np.mean(mid2bucket),
np.mean(mid3bucket),
np.mean(mid4bucket),
np.mean(highbucketlow),
np.mean(highbuckethigh),
]
def getSpectrumBuckets(self):
return self.__buckets
def analyzeSpectrum(self):
tic = time.clock()
data = [self.__readmicval() for x in range(self.__samplesArraySize)]
toc = time.clock()
fft = self.__calculate_levels(data)
processtime = toc - tic
stimestep = processtime / self.__samplesArraySize # average step time
self.__freqarray = np.fft.fftfreq(
self.__samplesArraySize, stimestep
) # get freq steps
self.__getvals()
print("Reading MCP3008 values, press Ctrl-C to quit...")