|
-
- from ctypes import *
- import string
- from Queue import Queue
-
- class jack_client_t(Structure):
- pass
-
- class jack_port_t(Structure):
- pass
-
- client_p = POINTER(jack_client_t)
- port_p = POINTER(jack_port_t)
-
- libjack = cdll.LoadLibrary( "libjack.so" )
- client_new = libjack.jack_client_new
- client_new.argtypes = [ c_char_p ]
- client_new.restype = client_p
-
- client_open = libjack.jack_client_open
- client_open.argtypes = [ c_char_p, c_uint, POINTER( c_uint ) ]
- client_open.restype = client_p
-
- client_close = libjack.jack_client_close
- client_close.argtypes = [ client_p ]
- client_close.restype = None
-
- activate = libjack.jack_activate
- activate.argtypes = [ client_p ]
- activate.restype = None
-
- deactivate = libjack.jack_deactivate
- deactivate.argtypes = [ client_p ]
- deactivate.restype = None
-
- get_ports = libjack.jack_get_ports
- get_ports.argtypes = [ client_p, c_char_p, c_char_p, c_ulong ]
- get_ports.restype = POINTER( c_char_p )
-
- port_by_name = libjack.jack_port_by_name
- port_by_name.argtypes = [ client_p, c_char_p ]
- port_by_name.restype = port_p
-
- port_get_all_connections = libjack.jack_port_get_all_connections
- port_get_all_connections.argtypes = [ client_p, port_p ]
- port_get_all_connections.restype = POINTER( c_char_p )
-
- jack_free = libjack.jack_free
- jack_free.argtypes = [ c_void_p ]
- jack_free.restype = None
-
- rename_client = libjack.jack_rename_client
- rename_client.argtypes = [ client_p, c_char_p, c_char_p ]
- rename_client.restype = c_int
-
- reserve_client_name = libjack.jack_reserve_client_name
- reserve_client_name.argtypes = [ client_p, c_char_p, c_char_p ]
- reserve_client_name.restype = c_int
-
- class jack_session_command_t( Structure ):
- _fields_ = [ ("uuid", 16*c_char ), ("clientname", 33*c_char), ("command", 256*c_char ) ]
-
- session_notify = libjack.jack_session_notify
- session_notify.argtypes = [ client_p, c_uint, c_char_p ]
- session_notify.restype = POINTER( jack_session_command_t )
-
- get_client_name_by_uuid = libjack.jack_get_client_name_by_uuid
- get_client_name_by_uuid.argtypes = [ client_p, c_char_p ]
- get_client_name_by_uuid.restype = c_char_p
-
- get_cookie_by_uuid = libjack.jack_get_cookie_by_uuid
- get_cookie_by_uuid.argtypes = [ client_p, c_char_p, c_char_p ]
- get_cookie_by_uuid.restype = c_char_p
-
- connect = libjack.jack_connect
- connect.argtypes = [ client_p, c_char_p, c_char_p ]
- connect.restype = c_int
-
- disconnect = libjack.jack_disconnect
- disconnect.argtypes = [ client_p, c_char_p, c_char_p ]
- disconnect.restype = c_int
-
- PortRegistrationCallback = CFUNCTYPE( None, c_uint, c_int, c_void_p )
-
- set_port_registration_callback = libjack.jack_set_port_registration_callback
- set_port_registration_callback.argtypes = [ client_p, PortRegistrationCallback, c_void_p ]
- set_port_registration_callback.restype = c_int
-
- port_by_id = libjack.jack_port_by_id
- port_by_id.argtypes = [ client_p, c_uint ]
- port_by_id.restype = port_p
-
- port_name = libjack.jack_port_name
- port_name.argtypes = [ port_p ]
- port_name.restype = c_char_p
-
- port_type = libjack.jack_port_type
- port_type.argtypes = [ port_p ]
- port_type.restype = c_char_p
-
- port_flags = libjack.jack_port_flags
- port_flags.argtypes = [ port_p ]
- port_flags.restype = c_int
-
- JACK_DEFAULT_AUDIO_TYPE="32 bit float mono audio"
- JACK_DEFAULT_MIDI_TYPE="8 bit raw midi"
-
- JackPortIsInput = 0x1
- JackPortIsOutput = 0x2
- JackPortIsPhysical = 0x4
- JackPortCanMonitor = 0x8
- JackPortIsTerminal = 0x10
-
- JackSessionSave = 1
- JackSessionQuit = 2
-
-
-
- class Port( object ):
- def __init__( self, client, name ):
- self.client = client
- self.name = name
- self.portname = name.split(':')[1]
- self.port_p = port_by_name( self.client, name )
- self.conns = self.get_live_connections()
-
- def get_connections( self ):
- return self.conns
-
- def get_live_connections( self ):
- conns = port_get_all_connections( self.client, self.port_p )
- if not conns:
- return []
-
- i=0
- retval = []
- while conns[i]:
- retval.append( conns[i] )
- i+=1
- jack_free(conns)
-
- return retval
-
- def connect( self, other ):
- connect( self.client, self.name, other )
-
- def disconnect( self, other ):
- disconnect( self.client, self.name, other )
-
- def is_input( self ):
- return (port_flags( self.port_p ) & JackPortIsInput) != 0
-
- def is_output( self ):
- return (port_flags( self.port_p ) & JackPortIsOutput) != 0
-
- def is_audio( self ):
- return (port_type( self.port_p ) == JACK_DEFAULT_AUDIO_TYPE)
-
- def is_midi( self ):
- return (port_type( self.port_p ) == JACK_DEFAULT_MIDI_TYPE)
-
-
- class Client( object ):
- def __init__( self, client, name ):
- self.client = client
- self.name = name
- self.ports = []
- self.commandline = None
- self.isinfra = False
- self.uuid = None
-
- def get_commandline( self ):
- if self.commandline:
- return self.commandline
- else:
- return ""
-
- def set_commandline( self, cmdline ):
- self.commandline = cmdline
-
- def get_uuid( self ):
- return self.uuid
-
- def set_uuid( self, uuid ):
- self.uuid = uuid
-
- def add_port( self, portname ):
- self.ports.append( Port( self.client, portname ) )
-
- def rename( self, newname ):
- rename_client( self.client, self.name, newname )
- self.ports = []
- ports = get_ports( self.client, newname+":.*", None, 0 )
- self.name = newname
-
- i=0
- while(ports[i]):
- self.add_port( ports[i] )
- i+=1
-
- jack_free( ports )
-
- def set_infra( self, cmdline ):
- self.isinfra = True
- self.commandline = cmdline
-
-
-
- class JackGraph( object ):
- def __init__( self, client, ports, uuids=[] ):
- self.client = client
- self.clients = {}
- self.reserved_names = []
-
- i=0
- while(ports[i]):
- port_split = ports[i].split(':')
- if not self.clients.has_key(port_split[0]):
- self.clients[port_split[0]] = Client( client, port_split[0] )
-
- self.clients[port_split[0]].add_port( ports[i] )
- i+=1
-
- def get_client( self, name ):
- return self.clients[name]
-
- def get_port_list( self ):
- retval = []
- for c in self.clients.values():
- for p in c.ports:
- retval.append( p.name )
- return retval
-
-
-
- def check_client_name( self, client ):
- if not client.name in self.reserved_names:
- return
-
- oldname = client.name
- newname = self.get_free_name( client.name )
-
- client.rename( newname )
- del self.clients[oldname]
- self.clients[newname] = client
-
- def get_free_name( self, oldname, other_names=[] ):
- cname_split = oldname.split('-')
- if len(cname_split) == 1:
- cname_prefix = cname_split[0]
- else:
- cname_prefix = string.join( cname_split[:-1], '-' )
-
- num = 1
- while ("%s-%d"%(cname_prefix,num)) in (self.clients.keys()+self.reserved_names+other_names):
- num+=1
-
- return ("%s-%d"%(cname_prefix,num))
-
-
-
- def remove_client( self, name ):
- del self.clients[name]
- for c in self.clients.values():
- for p in c.ports:
- for conn in p.get_connections():
- if conn.startswith(name+":"):
- p.conns.remove( conn )
-
- def remove_client_only( self, name ):
- del self.clients[name]
-
- def ensure_clientnames( self, names ):
- self.reserved_names = names
- for c in self.clients.values():
- self.check_client_name( c )
-
- def get_taken_names( self ):
- return self.clients.keys() + self.reserved_names
-
- def reserve_name( self, uuid, name ):
- if reserve_client_name( self.client, name, uuid ):
- raise Exception( "reservation failure" )
- self.reserved_names.append( name )
-
-
- class NotifyReply(object):
- def __init__( self, uuid, clientname, commandline ):
- self.uuid = uuid
- self.clientname = clientname
- self.commandline = commandline
-
-
- class JackClient(object):
- def __init__( self, name ):
- self.client = client_open( name, 0, None )
- if not self.client:
- raise Exception( "got no client name" )
- self.reg_cb = PortRegistrationCallback( self.port_registration_cb )
- set_port_registration_callback( self.client, self.reg_cb, None )
- self.port_queue = Queue()
-
- activate( self.client )
-
- def close( self ):
- client_close( self.client )
-
- def get_graph( self ):
- ports = get_ports( self.client, None, None, 0 )
- retval = JackGraph( self.client, ports )
- jack_free( ports )
- return retval
-
- def rename_client( self, old, new ):
- if rename_client( self.client, old, new ):
- raise Exception
-
- def port_registration_cb( self, port_id, reg, arg ):
- port_p = port_by_id( self.client, port_id )
- self.port_queue.put( (port_p,reg) )
-
-
- def session_save( self, path ):
- commands = session_notify( self.client, JackSessionSave, path )
- i=0
- retval = []
- while( commands[i].uuid != "" ):
- retval.append( NotifyReply( commands[i].uuid, commands[i].clientname, commands[i].command ) )
- i+=1
-
- jack_free( commands )
-
- return retval
-
- def connect( self, a, b ):
- portA_p = port_by_name( self.client, a )
-
- if( port_flags( portA_p ) & JackPortIsOutput ):
- connect( self.client, a, b )
- else:
- connect( self.client, b, a )
-
-
-
-
-
-
-
-
-
|