Skip to content

Instantly share code, notes, and snippets.

@notalentgeek
Created December 22, 2016 09:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save notalentgeek/bbeae8a736a001d2cb87d536ab3a67c6 to your computer and use it in GitHub Desktop.
Save notalentgeek/bbeae8a736a001d2cb87d536ab3a67c6 to your computer and use it in GitHub Desktop.
Simple proof of concept to stream audio from main microphone and then extract its pitch and volume properties on the fly.
# Only works with operating system that uses
# AlsaAudio as audio driver. Most Linux distros
# are using this (Debian, Ubuntu). Does not work
# any where else (MacOS or Windows).
#
# This is a class to stream audio data from
# computer microphone then extract the pitch
# and the volume from it. This is done using
# AlsaAudio and Aubio Python library. The
# AlsaAudio is used to turn on the computer
# microphone and then stream the data. While
# the Aubio is used to process the streamed
# data into its pitch detector object to get
# the pitch and the volume.
import alsaaudio as alsa
import aubio
# The NumPy library is used to convert data
# from AlsaAudio into format that Aubio understand.
import numpy as num
import sys
# Some constants for setting the PyAudio and the
# Aubio.
BUFFER_SIZE = 2048
CHANNELS = 1
FORMAT = alsa.PCM_FORMAT_FLOAT_LE
METHOD = "default"
SAMPLE_RATE = 44100
TYPE = alsa.PCM_CAPTURE
HOP_SIZE = BUFFER_SIZE//2
PERIOD_SIZE_IN_FRAME = HOP_SIZE
def main(args):
# Audio input from microphone. Determine the PCM
# (pulse code modulation) device. The default type
# is for play backing audio file. Hence, for this
# case set the mode into alsa
# (type=alsa.PCM_CAPTURE) instead of the default
# one that for voice capturing. The microphone that
# will be used to stream the voice is the microphone
# that is set in the alsamixer (Linux default driver
# and sound manager). Hence, this AlsaAudio library
# is only for Linux operating system.
# Here is the main recorder object.
mic = alsa.PCM(type=TYPE)
# The other properties that I do not know
# what it does :D :D :D :D :D.
mic.setchannels(CHANNELS)
mic.setformat(FORMAT)
mic.setperiodsize(PERIOD_SIZE_IN_FRAME)
mic.setrate(SAMPLE_RATE)
# Finally create the main pitch detection object.
# This object is from Aubio library.
pDetection = aubio.pitch(METHOD, BUFFER_SIZE,
HOP_SIZE, SAMPLE_RATE)
# Set the output unit. This can be "cent",
# "midi", "Hz".
pDetection.set_unit("Hz")
# Ignore frames under this level.
pDetection.set_silence(-40)
# Starting the infinite loop!
while True:
# Keep reading data from the audio input.
length, data = mic.read()
# Convert data from the microphone of
# AlsaAudio library into Aubio format samples.
samples = num.fromstring(data,
dtype=aubio.float_type)
# Pitch of the current frame.
pitch = pDetection(samples)[0]
# Compute the energy (volume) of the
# current frame.
volume = num.sum(samples**2)/len(samples)
# Format the volume output so that at most
# it has six decimal numbers.
volume = "{:.6f}".format(volume)
# Finally print the pitch and the volume.
print(str(pitch) + " " + str(volume))
if __name__ == "__main__": main(sys.argv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment