Created
August 20, 2018 18:38
-
-
Save lclibardi/a08079f642917fcc0e786614eaa3bb42 to your computer and use it in GitHub Desktop.
Animate objects in Maya using sound from the microphone
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# This script opens an ALSA pcm for sound capture, and keyframes the | |
# object's 'radius' attribute while looping through the sound input. | |
import sys | |
import time | |
import maya.cmds as cmds | |
# If not installed, install alsa audio by running `pip install pyalsaaudio` | |
sys.path.append('/usr/local/lib/python2.7/dist-packages') | |
import alsaaudio | |
import audioop | |
def mapValue(rawValue): | |
oldMin, oldMax = 3072, 32100 | |
newMin, newMax = 1, 20 | |
oldRange = (oldMax - oldMin) | |
newRange = (newMax - newMin) | |
newValue = (((rawValue - oldMin) * newRange) / oldRange) + newMin | |
return newValue | |
# Open the device in nonblocking capture mode. The last argument could | |
# just as well have been zero for blocking mode. Then we could have | |
# left out the sleep call in the bottom of the loop | |
inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NONBLOCK) | |
# Set attributes: Mono, 8000 Hz, 16 bit little endian samples | |
inp.setchannels(1) | |
inp.setrate(8000) | |
inp.setformat(alsaaudio.PCM_FORMAT_S16_LE) | |
# The period size controls the internal number of frames per period. | |
# The significance of this parameter is documented in the ALSA api. | |
# For our purposes, it is suficcient to know that reads from the device | |
# will return this many frames. Each frame being 2 bytes long. | |
# This means that the reads below will return either 320 bytes of data | |
# or 0 bytes of data. The latter is possible because we are in nonblocking | |
# mode. | |
inp.setperiodsize(160) | |
# Iterate over 48 frames (2 seconds) | |
for n in range(0, 48): | |
# Read data from device | |
l, data = inp.read() | |
if l: | |
# Return the maximum of the absolute value of all samples in a fragment. | |
rawValue = audioop.max(data, 2) | |
# Map value to a smaller range in order to limit the object's animation | |
mappedValue = mapValue(rawValue) | |
# Keyframe object | |
cmds.setAttr('polySphere1.radius', mappedValue) | |
cmds.setKeyframe('polySphere1.radius') | |
# Step to next frame in the timeline | |
cmds.currentTime(cmds.currentTime(query=True) + 1) | |
time.sleep(0.04166) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment