Created
April 3, 2014 20:15
-
-
Save hihihippp/9962030 to your computer and use it in GitHub Desktop.
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
| 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