Skip to content

Instantly share code, notes, and snippets.

@benstigsen
Last active January 14, 2021 17:55
Show Gist options
  • Save benstigsen/99aab03023df79cedd5be02d1114a560 to your computer and use it in GitHub Desktop.
Save benstigsen/99aab03023df79cedd5be02d1114a560 to your computer and use it in GitHub Desktop.
Small Python script to animate character depending on voice volume (used with OBS virtual cam in school calls)
from PIL import Image
import aubio
import pygame
import pyaudio
import numpy as np
import glob
PATH = "happyboy1"
METHOD = "default"
PERIOD_SIZE_IN_FRAME = 2048 // 2
pA = pyaudio.PyAudio()
mic = pA.open(
format = pyaudio.paFloat32, channels = 1,
rate = 44100, input = True,
frames_per_buffer = PERIOD_SIZE_IN_FRAME
)
img_size = 0, 0
with Image.open(glob.glob(f"{PATH}/*.png")[0]) as img:
img_size = img.size
pygame.init()
size = width, height = img_size
clock = pygame.time.Clock()
screen = pygame.display.set_mode(size)
avatars = []
for image in glob.glob(f"{PATH}/*.png"):
avatars.append(pygame.image.load(image))
step_prev = 0
step = 0
steps = len(avatars) - 1
running = True
screen.fill((255, 255, 255))
screen.blit(avatars[0], (0, 0))
pygame.display.update()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
break
# READ MIC
data = mic.read(PERIOD_SIZE_IN_FRAME)
samples = np.frombuffer(data, dtype = aubio.float_type)
volume = (np.sum(samples * samples) / len(samples)) * 1000
if (volume > 25):
step = 4
elif (volume > 19):
step = 3
elif (volume > 12):
step = 2
elif (volume > 6):
step = 1
elif (volume <= 6):
step = 0
#print(volume)
# Only draw if something needs to be updated
if (step_prev != step):
step_prev = step
screen.blit(avatars[step], (0, 0))
pygame.display.update((260, 370, 470, 210))
clock.tick(50)
pygame.quit()
quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment