import sys import ctypes import _ctypes from ctypes import c_uint, \ c_int, \ c_float, \ CFUNCTYPE, \ c_char_p, \ POINTER, \ byref, \ c_char, \ c_double, \ c_short, \ memmove _libjack = ctypes.cdll.LoadLibrary('libjack.so') JACK_DEFAULT_AUDIO_TYPE = "32 bit float mono audio" # JackPortFlags JackPortIsInput = 0x1 JackPortIsOutput = 0x2 JackPortIsPhysical = 0x4 JackPortCanMonitor = 0x8 JackPortIsTerminal = 0x10 # JackOptions JackNullOption = 0x00 JackNoStartServer = 0x01 JackUseExactName = 0x02 JackServerName = 0x04 JackLoadName = 0x08 JackLoadInit = 0x10 JackOpenOptions = JackServerName|JackNoStartServer|JackUseExactName JackLoadOptions = JackLoadInit|JackLoadName|JackUseExactName # JackStatus JackFailure = 0x01 JackInvalidOption = 0x02 JackNameNotUnique = 0x04 JackServerStarted = 0x08 JackServerFailed = 0x10 JackServerError = 0x20 JackNoSuchClient = 0x40 JackLoadFailure = 0x80 JackInitFailure = 0x100 JackShmFailure = 0x200 JackVersionError = 0x400 def _jack_error_callback(msg): sys.stderr.write(msg) jack_error_callback = CFUNCTYPE(None,c_char_p) jack_error_callback_ptr = jack_error_callback(_jack_error_callback) _libjack.jack_set_error_function(jack_error_callback_ptr) _libjack.jack_port_get_buffer.restype = POINTER(c_float) _libjack.jack_cpu_load.restype = c_float class PortHandle: def __init__(self, client, port): self._client = client self._port = port class Port(PortHandle): def __init__(self, client, port_name, port_type, flags, buffer_size): PortHandle.__init__(self,client,_libjack.jack_port_register(client, port_name, port_type, flags, buffer_size)) def __del__(self): print 'passing' def get_buffer(self,frames): _libjack.jack_port_get_buffer.restype = POINTER(c_float) return _libjack.jack_port_get_buffer(self._port, frames).contents def set_buffer(self,arraydata): chardata = arraydata.tostring() size = len(chardata) _libjack.jack_port_get_buffer.restype = POINTER(c_float) memmove(_libjack.jack_port_get_buffer(self._port, size/4), chardata, size) JackShutdownCallback = CFUNCTYPE(None,POINTER(c_uint)) JackProcessCallback = CFUNCTYPE(c_int,c_uint,POINTER(c_uint)) JackThreadInitCallback = CFUNCTYPE(None,POINTER(c_uint)) JackGraphOrderCallback = CFUNCTYPE(c_int,POINTER(c_uint)) JackXRunCallback = CFUNCTYPE(c_int,POINTER(c_uint)) JackBufferSizeCallback = CFUNCTYPE(c_int,c_uint,POINTER(c_uint)) JackSampleRateCallback = CFUNCTYPE(c_int,c_uint,POINTER(c_uint)) JackPortRegistrationCallback = CFUNCTYPE(None,c_uint,c_int,POINTER(c_uint)) JackFreewheelCallback = CFUNCTYPE(None,c_int,POINTER(c_uint)) class Client: def __init__(self,client_name): self._client = _libjack.jack_client_new(client_name) self.ports = [] self._on_shutdown = JackShutdownCallback(self.on_shutdown) self._process = JackProcessCallback(self.process) self._thread_init = JackThreadInitCallback(self.thread_init) self._graph_order = JackGraphOrderCallback(self.graph_order) self._xrun = JackXRunCallback(self.xrun) self._buffer_size = JackBufferSizeCallback(self.buffer_size) self._sample_rate = JackSampleRateCallback(self.sample_rate) self._port_registration = JackPortRegistrationCallback(self.port_registration) self._freewheel = JackFreewheelCallback(self.freewheel) _libjack.jack_on_shutdown(self._client, self._on_shutdown, None) _libjack.jack_set_process_callback(self._client, self._process, None) _libjack.jack_set_thread_init_callback(self._client, self._thread_init, None) _libjack.jack_set_freewheel_callback(self._client, self._freewheel, None) _libjack.jack_set_buffer_size_callback(self._client, self._buffer_size, None) _libjack.jack_set_sample_rate_callback(self._client, self._sample_rate, None) _libjack.jack_set_port_registration_callback(self._client, self._port_registration, None) _libjack.jack_set_graph_order_callback(self._client, self._graph_order, None) _libjack.jack_set_xrun_callback(self._client, self._xrun, None) def on_shutdown(self, arg): pass def process(self, nframes, arg): return -1 def thread_init(self, arg): pass def graph_order(self, arg): return 0 def xrun(self, arg): return 0 def buffer_size(self, nframes, arg): return 0 def sample_rate(self, nframes, arg): return 0 def port_registration(self, port, i, arg): pass def freewheel(self, starting, arg): pass def __del__(self): for port in self.ports: port._client = None self._ports = None _libjack.jack_client_close(self._client) def new_port(self, port_name, port_type = JACK_DEFAULT_AUDIO_TYPE, flags = JackPortIsOutput, buffer_size = 0): port = Port(self._client, port_name, port_type, flags, buffer_size) self.ports.append(port) return port def new_audio_output(self, port_name): return self.new_port(port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0) def new_audio_input(self, port_name): return self.new_port(port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0) #~ char *get_client_name(); #~ bool is_realtime(); #~ virtual void on_shutdown(); #~ virtual int process(jack_nframes_t nframes); #~ virtual int buffer_size(jack_nframes_t nframes); #~ virtual void freewheel(int starting); #~ virtual int graph_order(); #~ virtual void port_registration(jack_port_id_t port, int i); #~ virtual int sample_rate(jack_nframes_t nframes); #~ virtual void thread_init(); #~ virtual int xrun(); #~ int set_freewheel(bool onoff); #~ int set_buffer_size(jack_nframes_t nframes); #~ int activate(); def activate(self): return _libjack.jack_activate(self._client) #~ int deactivate(); def deactivate(self): return _libjack.jack_deactivate(self._client) #~ int recompute_total_latencies(); #~ bool is_mine(const jack_port_t *port); #~ int request_monitor_by_name(const char *port_name, bool onoff); #~ int connect(const char *source_port, const char *destination_port); def connect(self,source_port,destination_port): return _libjack.jack_connect(self._client,source_port,destination_port) #~ int disconnect(const char *source_port, const char *destination_port); def disconnect(self,source_port,destination_port): return _libjack.jack_disconnect(self._client,source_port,destination_port) #~ const char **get_ports(const char *port_name_pattern, const char *type_name_pattern, unsigned long flags); #~ jack_port_t *port_by_name (const char *port_name); def port_by_name(self,port_name): return _libjack.jack_port_by_name(self._client,port_name) #~ jack_port_t *port_by_id (jack_port_id_t port_id); #~ jack_nframes_t get_sample_rate(); def get_sample_rate(self): return _libjack.jack_get_sample_rate(self._client) #~ jack_nframes_t get_buffer_size(); def get_buffer_size(self): return _libjack.jack_get_buffer_size(self._client) #~ int engine_takeover_timebase(); #~ jack_nframes_t frames_since_cycle_start(); #~ jack_nframes_t frame_time(); #~ jack_nframes_t last_frame_time(); #~ float cpu_load(); def cpu_load(self): return _libjack.jack_cpu_load(self._client) #~ pthread_t client_thread_id(); from Numeric import array, resize, arrayrange, sin as usin from math import sin class TestClient(Client): def __init__(self): import Queue Client.__init__(self,'Test') self.in0 = self.new_audio_input('in_0') self.out0 = self.new_audio_output('out_0') self.sample_rate = self.get_sample_rate() self.hz = 2 * 3.14159 * 440.0 / self.sample_rate self.phase = 0 self.amps = Queue.Queue() print self.sample_rate def __del__(self): self.in0 = None self.out0 = None Client.__del__(self) def native_mix(self,nframes): res = range(int(nframes)) for i in xrange(nframes): res[i] = sin((res[i]+self.phase) * self.hz) self.phase += 1 return array(res,'f') def mix(self,nframes): res = usin((arrayrange(float(nframes))+self.phase) * self.hz) self.phase = (self.phase + int(nframes)) return res.astype('f') def process(self, nframes, arg): amp = 0.0 self.out0.set_buffer(self.mix(nframes)) return 0 import psyco psyco.profile() def test(): from time import sleep,time client = TestClient() client.activate() client.connect('Test:out_0','alsa_pcm:playback_1') t = time() while (time() - t) < 30: print 'cpu:%.3f%%' % (client.cpu_load()) sleep(1) client.deactivate() del client print 'done.' if __name__ == '__main__': test()