import pyaudio import serial from serial import SerialException import _thread import struct import numpy as np import math import time import random import paho.mqtt.client as mqtt from beatDetection import SimpleBeatDetection nFFT = 512 CHUNKSIZE = nFFT * 4 # fixed chunk size SAMPLERATE = 44100 FORMAT = pyaudio.paInt16 # initialize portaudio p = pyaudio.PyAudio() MAX_y = 2.0 ** (p.get_sample_size(pyaudio.paInt16) * 8 - 1) ser = None portName="COM7" while not ser: try: ser = serial.Serial(portName, 115200) except serial.SerialException: print(portName, " not available") portName="COM" + input("COM") print("Connected to ", ser.name) info = p.get_host_api_info_by_index(0) numdevices = info.get('deviceCount') #for each audio device, determine if is an input or an output and add it to the appropriate list and dictionary DEVICE = -1 for i in range (0,numdevices): info = p.get_device_info_by_host_api_device_index(0,i) if info.get('maxInputChannels')>0: print ("Input Device id ", i, " - ", info.get('name')) if "High" in info.get('name'): DEVICE = i #if p.get_device_info_by_host_api_device_index(0,i).get('maxOutputChannels')>0: # print ("Output Device id ", i, " - ", p.get_device_info_by_host_api_device_index(0,i).get('name')) if DEVICE == -1: DEVICE = int(input("Device? ")) stream = p.open(format=pyaudio.paInt16, channels=2, rate=SAMPLERATE, input=True,input_device_index=DEVICE, frames_per_buffer=CHUNKSIZE) devinfo = p.get_device_info_by_index(DEVICE) print ("Selected device is ",devinfo.get('name'), " at ", SAMPLERATE, " Hz") if p.is_format_supported(SAMPLERATE, # Sample rate input_device=devinfo["index"], input_channels=devinfo['maxInputChannels'], input_format=pyaudio.paInt16): print ('Audio seems to be ok!') def read(): while 1: if ser.inWaiting()>0: print(ser.read(ser.inWaiting()).decode("utf-8")) time.sleep(.1) _thread.start_new_thread( read, () ) def write(val): ser.write((int(val)&0xFF).to_bytes(1, byteorder='big', signed=False)) def writeInt(val): ser.write((int(val)&0xFFFF).to_bytes(2, byteorder='big', signed=False)) def writeLng(val): ser.write((int(val)&0xFFFFFFFF).to_bytes(4, byteorder='big', signed=False)) def on_message(mqttc, obj, msg): print(msg) def on_log(mqttc, obj, level, string): print(string) def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) mqttc.subscribe("Timer/#", 2) mqttc.subscribe("Pc/#", 2) # If you want to use a specific client id, use # mqttc = mqtt.Client("client-id") # but note that the client id must be unique on the broker. Leaving the client # id parameter empty will generate a random id for you. mqttc = mqtt.Client() mqttc.on_message = on_message mqttc.on_connect = on_connect # Uncomment to enable debug messages #mqttc.on_log = on_log mqttc.connect_async("192.168.0.2", 1883, 60) mqttc.loop_start() sbd = SimpleBeatDetection(100) val=[0]*64 ser.write(b'~u~t~c ') timeout = 0 oldBeat = False tBeat = 0 nBeat = 0 while 1: #start = time.time() N = int(max(stream.get_read_available() / nFFT, 1) * nFFT) data = stream.read(N) y = np.array(struct.unpack("%dh" % (N * 2), data)) / MAX_y y_L = y[::2] y_R = y[1::2] Y_L = np.fft.fft(y_L, nFFT) Y_R = np.fft.fft(y_R, nFFT) Y = abs(np.hstack((Y_L[int(-nFFT / 2):-1], Y_R[0:int(nFFT / 2)]))) buf = [] for z in range(4): for y in range(4): for x in range(4): if x in [1,2]: if y == 0: a=np.sum(Y[259:266])/30*16 - z*4 + 32 #right channel elif y == 1: a=np.sum(Y[256:259])/40*16 - z*4 + 32 elif y == 2: a=np.sum(Y[252:256])/40*16 - z*4 + 32 #left channel else: a=np.sum(Y[240:247])/30*16 - z*4 + 32 else: if y == 0: a=np.sum(Y[264:270])/20*16 - z*4 + 32 #right channel elif y == 1: a=np.sum(Y[258:264])/40*16 - z*4 + 32 elif y == 2: a=np.sum(Y[247:253])/40*16 - z*4 + 32 #left channel else: a=np.sum(Y[236:242])/20*16 - z*4 + 32 if a>val[x+y*4+z*16]: val[x+y*4+z*16]=a else: a=val[x+y*4+z*16]=val[x+y*4+z*16] * 0.8 + a * 0.2 if a<32 : a = 32 elif a>47 : a = 47 buf.append(int(a)) ser.write(b'~a') ser.write(bytearray(buf)) s = sum(buf) if s == 32*64: timeout += 1 else: timeout = 0 signal = np.frombuffer(data, np.int16) beat = sbd.detect_beat(signal) if beat == 0: tBeat += 1 if beat == True and timeout == 0 and tBeat > 3: tBeat = 0 nBeat += 1 json = "{\"spot\":[{\"color\":" + str(256*256-1) + ",\"radius\":" + str(int(s/64-32)*3+2) + ",\"pos\":" + str(10 + nBeat%4 * 10) + ",\"keep\":0}],\"speed\":40}" #print(" ------------------ " + json) mqttc.publish("RgbLamp/spot", json) oldBeat = beat if timeout > 1000: time.sleep(0.3) else: time.sleep(0.015) # close stream stream.stop_stream() stream.close() p.terminate() ser.close()