Skip to content

Instantly share code, notes, and snippets.

@jeanphix
Created July 14, 2012 07:10
Show Gist options
  • Save jeanphix/3109801 to your computer and use it in GitHub Desktop.
Save jeanphix/3109801 to your computer and use it in GitHub Desktop.
Creates waveform image from wave file.
import numpy
from PIL import Image, ImageDraw
import scikits.audiolab as audiolab
class Waveform(object):
"""Creates a waveform image for given wave audio file.
:param soundfile: The path to the wave file.
:param width: The output image width as an optional integer.
:param height: The output image height as an optional integer.
:param background: The output image background color as an optional
RGBA tupple.
:param line: The output image line color as an optional RGBA tupple.
"""
def __init__(self, soundfile, width=1000, height=200,
background=(255, 255, 255, 255), line=(0, 0, 0, 0)):
# Loads the wave file
self.snd = audiolab.Sndfile(soundfile, 'r')
self.width = width
self.height=height
self.background = background
self.line = line
# Reads all frames
self.frames = self.snd.read_frames(self.snd.nframes)
# Keep only one channel
if self.snd.channels == 2:
self.frames = self.frames[0::2]
# Frames to read for one pixel width
self.nframes_per_pixel = len(self.frames) / self.width
def draw(self):
"""Returns the waveform as PIL Image."""
image = Image.new("RGBA", (self.width, self.height), self.background)
draw = ImageDraw.Draw(image)
for x in range(0, self.width):
value = self.get_value_for_x(x)
draw.line([
x,
int(self.height) / 2 + value,
x,
int(self.height) / 2 - value
], self.line)
return image
def get_value_for_x(self, x):
"""Returns the max value for given `x`.
:param x: The x position in pixel.
"""
frames = self.frames[x * self.nframes_per_pixel: (x + 1) \
* self.nframes_per_pixel]
return int(numpy.abs(frames).max() * (self.height / 2))
def save(self, path):
"""Saves the waveform images.
:param path: The destination path.
"""
image = self.draw()
image.save(path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment