from objc_util import * import ctypes import numpy as np import matplotlib.image import io,ui AVAudioEngine=ObjCClass('AVAudioEngine') AVAudioSession=ObjCClass('AVAudioSession') def setup(): error=ctypes.c_void_p(0) session=AVAudioSession.sharedInstance() category=session.setCategory('AVAudioSessionCategoryPlayAndRecord',error=ctypes.pointer(error)) if error: raise Exception('error setting up category') session.setActive(True, error=ctypes.pointer(error)) if error: raise Exception('error setting up session active') engine=AVAudioEngine.new() return engine class fftview(ui.View): def __init__(self,*args,**kwargs): ui.View.__init__(self,*args,**kwargs) self.i=ui.ImageView() self.i.frame=self.bounds self.i.flex='wh' self.add_subview(self.i) self.fps=ui.Label() self.add_subview(self.fps) self.fps.text='' def update(self,im): self.i.image=im @ui.in_background def will_close(self): print('stopping engine') engine.pause() v=fftview(frame=(0,0,500,500)) '''setup a tap block''' buf=[] #for debugging bIO=io.BytesIO() lastt=0 def processBuffer(self,buffer,when, cmd): global buf, lastt buf=ObjCInstance(buffer ) t=ObjCInstance(when).sampleTime()/44100. fps=1./(t-lastt) lastt=t v.fps.text='fps{}'.format(fps) A=np.ctypeslib.as_array(buf.floatChannelData()[0],(128,128)) B=np.transpose(np.log10(np.fft.fftshift(abs(np.fft.fft(A,512))))) matplotlib.image.imsave(bIO,B,format='png',vmin=-3,vmax=1) v.update(ui.Image.from_data(bIO.getvalue())) bIO.seek(0) process_block=ObjCBlock(processBuffer,restype=None,argtypes=[c_void_p,c_void_p,c_void_p,c_void_p]) '''set up audio engine, and install tap, and start''' engine=setup() engine.connect_to_format_(engine.inputNode(), engine.outputNode(), engine.inputNode().inputFormatForBus_(0)) engine.inputNode().installTapOnBus(0, bufferSize=64*256, format=None, block=process_block) v.present('sheet') engine.startAndReturnError_(None)