Advertisement
Guest User

Untitled

a guest
May 7th, 2023
398
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.20 KB | None | 0 0
  1.  
  2. import pyaudio
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. import math
  6. import time
  7. from rpi_ws281x import *
  8.  
  9. np.set_printoptions(suppress=True) # don't use scientific notation
  10.  
  11. class Masque:
  12.     def __init__(self, rate=44100, channel=1, width=2, chunk=256*2*2, index=2, ledCount = 111, ledPin = 10, ledFreqHZ = 800000, ledDMA = 10, ledBright = 255, ledInvert=False, ledChannel=0):
  13.  
  14.         # Stream
  15.         self.rate       = rate        
  16.         self.channel    = channel
  17.         self.index      = index
  18.         self.chunk      = chunk
  19.  
  20.         self.channel    = channel
  21.         self.width      = width
  22.        
  23.         self.p=pyaudio.PyAudio() # start the PyAudio class
  24.         self.stream = self.p.open(
  25.             rate=self.rate,
  26.             format=self.p.get_format_from_width(self.width),
  27.             channels=self.channel,
  28.             frames_per_buffer=self.chunk,
  29.             input=True,
  30.             input_device_index=self.index)
  31.  
  32.  
  33.         # Leds
  34.         self.ledCount       = ledCount          # Number of LED pixels.
  35.         self.ledPin         = ledPin            # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
  36.         self.ledFreqHZ      = ledFreqHZ         # LED signal frequency in hertz (usually 800khz)
  37.         self.ledDMA         = ledDMA            # DMA channel to use for generating signal (try 10)
  38.         self.ledBright      = ledBright         # Set to 0 for darkest and 255 for brightest
  39.         self.ledInvert      = ledInvert         # True to invert the signal (when using NPN transistor level shift)
  40.         self.ledChannel     = ledChannel        # set to '1' for GPIOs 13, 19, 41, 45 or 53
  41.  
  42.         # Create NeoPixel object with appropriate configuration.
  43.         self.strip = Adafruit_NeoPixel(self.ledCount, self.ledPin, self.ledFreqHZ, self.ledDMA, self.ledInvert, self.ledBright, self.ledChannel)
  44.        
  45.         # Intialize the library (must be called once before other functions).
  46.         self.strip.begin()
  47.        
  48.         #Gamma correction approximation
  49.         self.gamma8 = [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,  1,  1,  1,    1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,    2,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  5,  5,  5,    5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  9,  9,  9, 10,   10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,   17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,   25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,   37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,   51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,   69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,   90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,  115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,  144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,  177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,  215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 ]
  50.    
  51.         #Scale
  52.         minFreq = 20
  53.         maxFreq = 20000
  54.         self.chevauchement = 2
  55.         self.nbPixel = int((self.strip.numPixels() - 2  ) / 2)
  56.         #self.nbPixel = 10
  57.         self.scale =  np.logspace(np.log10(minFreq), np.log10(maxFreq),self.nbPixel+self.chevauchement+1)
  58.  
  59.         # FreqPeak
  60.         self.freqPeak = 10
  61.         self.freqPeakList = [1]*80
  62.  
  63.         # Volume
  64.         self.rmsList = [0] * 250
  65.         self.rmsListEyes = [0] * 12
  66.         self.rmsThreeshold = 280
  67.         self.rmsMedian = 0
  68.         self.rmsMedianEyes = 0
  69.  
  70.     def calculateFFT(self):
  71.         data = np.fromstring(self.stream.read(self.chunk, exception_on_overflow = False),dtype=np.int16)
  72.         data = data * np.hanning(len(data)) # smooth the FFT by windowing data
  73.  
  74.         fft = abs(np.fft.fft(data).real)
  75.         self.fft = fft[:int(len(fft)/2)] # keep only first half
  76.  
  77.         freq = np.fft.fftfreq(self.chunk,1.0/self.rate)
  78.         self.freq = freq[:int(len(freq)/2)] # keep only first half
  79.  
  80.         rms = np.sqrt(np.mean(np.square(data)))
  81.         self.rmsList.append(rms)
  82.         self.rmsList.pop(0)
  83.         self.rmsListEyes.append(rms)
  84.         self.rmsListEyes.pop(0)
  85.         self.rmsMedian= np.median(self.rmsList)
  86.         self.rmsMedianEyes= np.mean(self.rmsListEyes) - self.rmsMedian # Substracting the median of the 120 last to 20 last, in order to see variation
  87.         #print("rms eyes : ", self.rmsMedianEyes)
  88.  
  89.         freqPk = self.freq[np.where(self.fft[10:]==np.max(self.fft[10:]))[0][0]]+1 # We get the 20 first sample out, in order to not have the basses parasite the fondamental frequency
  90.         #print("where is max : ", np.where(self.fft[20:]==np.max(self.fft[20:]))[0][0])
  91.         #print("where is max 2 : ", np.where(self.fft==np.max(self.fft))[0][0])
  92.         if(freqPk>1):
  93.             self.freqPeakList.append(freqPk)
  94.             self.freqPeakList.pop(0)  
  95.             self.freqPeakValue = np.log10(np.mean(self.freqPeakList))
  96.  
  97.     def displayLed(self, dividor = 500000, debug=False):
  98.         for i in range(self.nbPixel):
  99.             idxBottom = (np.abs(self.freq-self.scale[i])).argmin()
  100.             idxUp= (np.abs(self.freq-self.scale[i+1])).argmin() +self.chevauchement
  101.  
  102.             mean = np.sum(self.fft[idxBottom:idxUp]) / (idxUp - idxBottom) / dividor
  103.  
  104.             if(self.rmsMedian > self.rmsThreeshold):
  105.                 colorIntensity = int(mean*255)
  106.                 if(colorIntensity > 255): colorIntensity=255
  107.             else:
  108.                 colorIntensity = 0
  109.                 self.strip.setPixelColor(109, Color(0,0,0))
  110.                 self.strip.setPixelColor(110, Color(0,0,0))
  111.                
  112.             self.strip.setPixelColor(i, Color( colorIntensity ,0,0))
  113.             self.strip.setPixelColor( self.nbPixel+(self.nbPixel-i), Color( 0,0,colorIntensity ))
  114.  
  115.             if(debug):
  116.                 print("\n\n\n")
  117.                 print("setting %d and %d" % (i,  self.nbPixel+(self.nbPixel-i)))
  118.                 print("self scale %f", self.scale)
  119.                 print("indx up %f, indx down %f" % (idxUp, idxBottom))
  120.                 print("i :", i, ", mean: ", mean, ", color intensity : ", colorIntensity)
  121.                
  122.         if(self.rmsMedian > self.rmsThreeshold):
  123.             self.strip.setPixelColor(109, self.eyes(self.freqPeakValue,self.rmsMedianEyes))
  124.             self.strip.setPixelColor(110, self.eyes(self.freqPeakValue,self.rmsMedianEyes))
  125.         else:
  126.             self.strip.setPixelColor(109, Color(0,0,0))
  127.             self.strip.setPixelColor(110, Color(0,0,0))
  128.  
  129.         self.strip.show()
  130.  
  131.    
  132.     def terminate(self):
  133.         for i in range(self.strip.numPixels()):
  134.             self.strip.setPixelColor(i, Color(0,0,0))
  135.         self.strip.show()
  136.         self.stream.stop_stream()
  137.         self.stream.close()
  138.         self.p.terminate()
  139.    
  140.     def eyes(self, pitch, energy):
  141.         """Generate rainbow colors for eyes"""
  142.         """Define intensity through fft variation"""
  143.         """Varies color through pitch"""
  144.  
  145.         print("pitch %f, energy %f" % (pitch, energy))
  146.  
  147.         # Pitch varies between 2 and 4
  148.         # We wants its to varies between 0 and 255
  149.         pitch -= 1.5
  150.         color = pitch / 2.0 * 255
  151.         if(color < 0): color = 0
  152.         if(color > 255): color = 255
  153.  
  154.         # Energy varies between -1000 and 1000
  155.         # We wants it to varies between 0 and 1
  156.         energy += 1000
  157.         energy -= 500
  158.         variation = energy / 2000.0
  159.         if(variation > 1): variation = 1
  160.         if(variation < 0.05): variation = 0.05
  161.  
  162.         #print("color %f, variation %f" % (color, variation))
  163.         #print("color eyes : ", Color(int((255-color)*variation), int(color*variation), 0))
  164.        
  165.         return Color(int((255-color)*variation), int(color*variation), 0)
  166.  
  167. if __name__ == "__main__":
  168.     instance = Masque()
  169.     try:
  170.         while True:
  171.             start = time.time()
  172.             instance.calculateFFT()
  173.             instance.displayLed()
  174.             end = time.time()
  175.             print("time elpased : ", end - start)
  176.             #print("new line")
  177.     except KeyboardInterrupt:
  178.         instance.terminate()
  179.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement