#!/usr/bin/env python # coding: utf-8 # In[1]: from IPython.display import DisplayObject class Audio(DisplayObject): _read_flags = 'rb' def __init__(self, data=None, filename=None, url=None, embed=None, rate=None, autoplay=False, maxvalue=None): if filename is None and url is None and data is None: raise ValueError("No image data found. Expecting filename, url, or data.") if embed is False and url is None: raise ValueError("No url found. Expecting url when embed=False") if url is not None and embed is not True: self.embed = False else: self.embed = True self.autoplay = autoplay self.maxvalue = maxvalue super(Audio, self).__init__(data=data, url=url, filename=filename) if self.data is not None and not isinstance(self.data, bytes): self.data = self._make_wav(data,rate) def reload(self): """Reload the raw data from file or URL.""" import mimetypes if self.embed: super(Audio, self).reload() if self.filename is not None: self.mimetype = mimetypes.guess_type(self.filename)[0] elif self.url is not None: self.mimetype = mimetypes.guess_type(self.url)[0] else: self.mimetype = "audio/wav" def _make_wav(self, data, rate): """ Transform a numpy array to a PCM bytestring """ import struct from io import BytesIO import wave try: import numpy as np data = np.array(data, dtype=float) if len(data.shape) == 1: nchan = 1 elif len(data.shape) == 2: # In wave files,channels are interleaved. E.g., # "L1R1L2R2..." for stereo. See # http://msdn.microsoft.com/en-us/library/windows/hardware/dn653308(v=vs.85).aspx # for channel ordering nchan = data.shape[0] data = data.T.ravel() else: raise ValueError('Array audio input must be a 1D or 2D array') if self.maxvalue is None: maxvalue = np.max(np.abs(data)) else: maxvalue = self.maxvalue scaled = np.int16(data/maxvalue * 32767).tolist() except ImportError: # check that it is a "1D" list idata = iter(data) # fails if not an iterable try: iter(idata.next()) raise TypeError('Only lists of mono audio are ' 'supported if numpy is not installed') except TypeError: # this means it's not a nested list, which is what we want pass if self.maxvalue is None: maxvalue = float(max([abs(x) for x in data])) else: maxvalue = self.maxvalue scaled = [int(x/maxvalue * 32767) for x in data] nchan = 1 fp = BytesIO() waveobj = wave.open(fp,mode='wb') waveobj.setnchannels(nchan) waveobj.setframerate(rate) waveobj.setsampwidth(2) waveobj.setcomptype('NONE','NONE') waveobj.writeframes(b''.join([struct.pack(' Your browser does not support the audio element. """ return src.format(src=self.src_attr(),type=self.mimetype, autoplay=self.autoplay_attr()) def src_attr(self): import base64 if self.embed and (self.data is not None): data = base64=base64.b64encode(self.data).decode('ascii') return """data:{type};base64,{base64}""".format(type=self.mimetype, base64=data) elif self.url is not None: return self.url else: return "" def autoplay_attr(self): if(self.autoplay): return 'autoplay="autoplay"' else: return '' print("This cell defines the Audio class.") # In[28]: 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)) data= np.sin(2*np.pi*440*t) # In[29]: import wave import struct scaled = np.int16(data/np.max(np.abs(data)) * 32767) waveobj = wave.open("funky.wav",mode='wb') waveobj.setnchannels(1) waveobj.setframerate(framerate) waveobj.setsampwidth(2) waveobj.setcomptype('NONE','NONE') waveobj.writeframes(b''.join([struct.pack('