Skip to content

Instantly share code, notes, and snippets.

@Melanpan

Melanpan/udp_vu.py

Last active Feb 7, 2020
Embed
What would you like to do?
import socket
import struct
import pyaudio
import wave
import audioop
import math
UDP_IP = "192.168.3.4"
UDP_PORT = 5000
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
def db_level(data, samplewidth=2, rms_mode=False):
"""
Returns the average audio volume level measured in dB (range -60 db to 0 db)
If the sample is stereo, you get back a tuple: (left_level, right_level)
If the sample is mono, you still get a tuple but both values will be the same.
This method is probably only useful if processed on very short sample fragments in sequence,
so the db levels could be used to show a level meter for the duration of the sample.
"""
maxvalue = 2**(8*samplewidth-1)
left_frames = audioop.tomono(data, samplewidth, 1, 0)
right_frames = audioop.tomono(data, samplewidth, 0, 1)
if rms_mode:
peak_left = (audioop.rms(left_frames, samplewidth)+1)/maxvalue
peak_right = (audioop.rms(right_frames, samplewidth)+1)/maxvalue
else:
peak_left = (audioop.max(left_frames, samplewidth)+1)/maxvalue
peak_right = (audioop.max(right_frames, samplewidth)+1)/maxvalue
# cut off at the bottom at -60 instead of all the way down to -infinity
return peak_left, peak_right #max(20.0*math.log(peak_left, 10), -60.0), max(20.0*math.log(peak_right, 10), -60.0)
def valmap(value, istart, istop, ostart, ostop):
return ostart + (ostop - ostart) * ((value - istart) / (istop - istart))
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16,
channels=2,
rate=44100,
input=True,
frames_per_buffer=104)
while True:
data = stream.read(1024)
dbs = db_level(data, rms_mode=True)
left_channel = round(dbs[0] * 1000)
data = struct.pack("hh", left_channel, 1024)
sock.sendto(data, (UDP_IP, UDP_PORT))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment