Skip to content

Instantly share code, notes, and snippets.

@hihihippp
Created April 3, 2014 20:15
Show Gist options
  • Select an option

  • Save hihihippp/9962030 to your computer and use it in GitHub Desktop.

Select an option

Save hihihippp/9962030 to your computer and use it in GitHub Desktop.
import base64
import struct
from io import BytesIO
import wave
import numpy as np
from IPython.core.display import DisplayObject
class Sound(DisplayObject):
"""Create a WAV object given raw data.
When this object is returned by an input cell or passed to the
display function, it will result in Audio controls being displayed
in the frontend (only works in the notebook).
Parameters
----------
data : array, unicode, str or bytes
A numpy array containing the desired waveform, the raw WAV data
or a URL or filename to load the data from. If the array option
is used the waveform will be normalized before display.
framerate : int
Framerate of the audio. Only used if the data is input as an array.
Examples
--------
# Generate a cool sound
import numpy as np
framerate = 44100
t = np.linspace(0,5,framerate*5)
data = np.sin(2*np.pi*440*np.sin(10*t**2))
Sound(data,framerate=framerate)
Sound("http://www.nch.com.au/acm/8k16bitpcm.wav")
Sound('/path/to/sound.wav')
Sound(b'RAW_WAV_DATA..)
"""
def __init__(self,data=None,framerate=None):
if data is None:
raise ValueError("No audio data found. Expecting filename, url or data.")
super(Sound, self).__init__(data=data)
if not isinstance(self.data, bytes):
data = np.array(data)
self.data = self._make_wav(data,framerate)
def _make_wav(self,data,framerate):
""" Transform a numpy arrray to a wav bytestring """
scaled = np.int16(data/np.max(np.abs(data)) * 32767)
fp = BytesIO()
waveobj = wave.open(fp,mode='wb')
waveobj.setnchannels(1)
waveobj.setframerate(framerate)
waveobj.setsampwidth(2)
waveobj.setcomptype('NONE','NONE')
waveobj.writeframes(b''.join([struct.pack('<h',x) for x in scaled]))
val = fp.getvalue()
waveobj.close()
return val
def _repr_html_(self):
res = '<audio controls="controls" style="width:600px" >\n'
res += ' <source controls src="data:audio/wav;base64,{data}" type="audio/wav" />\n'
res += ' Your browser does not support the audio element.\n'
res += '</audio>\n'
return res.format(data=base64.encodestring(self.data))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment