"""
//=========================================================
// MusE
// Linux Music Editor
// (C) Copyright 2009 Mathias Gyllengahm (lunar_shuttle@users.sf.net)
//=========================================================
This file is used by MusE for launching a Pyro name service and connecting a remote object to the global Python functions
"""
import Pyro.naming
import Pyro.core
from Pyro.errors import PyroError,NamingError
import sys, time
import threading
#
# Note: this module, 'muse' is activated from within MusE - thus it is not possible to execute the scripts without a running
# MusE instance
#
import muse
#
# Class which implements the functionality that is used remotely.
# In short just repeating the global functions in the muse-module
#
# TODO: It should be better to skip this class completely by implementing
# functionality as a class in pyapi.cpp instead of global functions
# that need to be wrapped like this
#
class MusE:
def getCPos(self): # Get current position
return muse.getCPos()
def startPlay(self): # Start playback
return muse.startPlay()
def stopPlay(self): # Stop playback
return muse.stopPlay()
def rewindStart(self): # Rewind current position to start
return muse.rewindStart()
def getLPos(self): # Get position of left locator
return muse.getLPos()
def getRPos(self): # Get position of right locator
return muse.getRPos()
def getTempo(self, tick): #Get tempo at particular tick
return muse.getTempo(tick)
def getTrackNames(self): # get track names
return muse.getTrackNames()
def getParts(self, trackname): # get parts in a particular track
return muse.getParts(trackname)
def createPart(self, trackname, starttick, lenticks, part): # create part in track
return muse.createPart(trackname, starttick, lenticks, part)
def modifyPart(self, part): # modify a part (the part to be modified is specified by its id
return muse.modifyPart((part))
def deletePart(self, part): # delete a part
return muse.deletePart((part))
def getSelectedTrack(self): # get first selected track in arranger window
return muse.getSelectedTrack()
def importPart(self, trackname, filename, tick): # import part file to a track at a given position
return muse.importPart(trackname, filename, tick)
def setCPos(self, tick): # set current position
return muse.setPos(0, tick)
def setLPos(self, tick): # set left locator
return muse.setPos(1, tick)
def setRPos(self, tick): # set right locator
return muse.setPos(2, tick)
def setSongLen(self, ticks): # set song length
return muse.setSongLen(ticks)
def getSongLen(self): # get song length
return muse.getSongLen()
def getDivision(self): # get division (ticks per 1/4, or per beat?)
return muse.getDivision()
def setMidiTrackParameter(self, trackname, paramname, value): # set midi track parameter (velocity, compression, len, transpose)
return muse.setMidiTrackParameter(trackname, paramname, value);
def getLoop(self): # get loop flag
return muse.getLoop()
def setLoop(self, loopFlag): # set loop flag
return muse.setLoop(loopFlag)
def getMute(self, trackname): # get track mute parameter
return muse.getMute(trackname)
def setMute(self, trackname, enabled): # set track mute parameter
return muse.setMute(trackname, enabled)
def setVolume(self, trackname, volume): # set mixer volume
return muse.setVolume(trackname, volume)
def getMidiControllerValue(self, trackname, ctrlno): # get a particular midi controller value for a track
return muse.getMidiControllerValue(trackname, ctrlno)
def setMidiControllerValue(self, trackname, ctrlno, value): # set a particular midi controller value for a track
return muse.setMidiControllerValue(trackname, ctrlno, value)
def setAudioTrackVolume(self, trackname, dvol): # set volume for audio track
return muse.setAudioTrackVolume(trackname, dvol)
def getAudioTrackVolume(self, trackname): # get volume for audio track
return muse.getAudioTrackVolume(trackname)
def getTrackEffects(self, trackname): # get effect names for an audio track
return muse.getTrackEffects(trackname)
def toggleTrackEffect(self, trackname, effectno, onoff): # toggle specific effect on/off
return muse.toggleTrackEffect(trackname, effectno, onoff)
def findNewTrack(self, oldtracknames): #internal function
tracknames = muse.getTrackNames()
for trackname in tracknames:
if trackname in oldtracknames:
continue
return trackname
def changeTrackName(self, trackname, newname): #change track name
return muse.changeTrackName(trackname, newname)
def nameNewTrack(self, newname, oldtracknames):# Internal function, wait until new track shows up in tracknames, then rename it
tmpname = None
for i in range(0,100):
tmpname = self.findNewTrack(oldtracknames)
if tmpname == None:
time.sleep(0.1)
continue
else:
self.changeTrackName(tmpname, newname)
time.sleep(0.1) # Ouch!!
break
def addMidiTrack(self, trackname): # add midi track
oldtracknames = muse.getTrackNames()
if trackname in oldtracknames:
return None
muse.addMidiTrack()
self.nameNewTrack(trackname, oldtracknames)
def addWaveTrack(self, trackname): # add wave track
oldtracknames = muse.getTrackNames()
if trackname in oldtracknames:
return None
muse.addWaveTrack()
self.nameNewTrack(trackname, oldtracknames)
def addInput(self, trackname): # add audio input
oldtracknames = muse.getTrackNames()
if trackname in oldtracknames:
return None
muse.addInput()
self.nameNewTrack(trackname, oldtracknames)
def addOutput(self, trackname): # add audio output
oldtracknames = muse.getTrackNames()
if trackname in oldtracknames:
return None
muse.addOutput()
self.nameNewTrack(trackname, oldtracknames)
def addGroup(self, trackname): # add audio group
oldtracknames = muse.getTrackNames()
if trackname in oldtracknames:
return None
muse.addGroup()
self.nameNewTrack(trackname, oldtracknames)
def deleteTrack(self, trackname): # delete a track
tracknames = muse.getTrackNames()
if trackname not in tracknames:
return False
muse.deleteTrack(trackname)
# def getOutputRoute(self, trackname):
# return muse.getOutputRoute(trackname)
class NameServiceThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.starter = Pyro.naming.NameServerStarter()
def run(self):
self.starter.start()
def verifyRunning(self):
return self.starter.waitUntilStarted(10)
#
# museclass Pyro object
#
class museclass(Pyro.core.ObjBase, MusE):
pass
#
# main server program
#
def main():
Pyro.core.initServer()
nsthread = NameServiceThread()
nsthread.start()
if (nsthread.verifyRunning() == False):
print "Failed to launch name service..."
sys.exit(1)
daemon = Pyro.core.Daemon()
# locate the NS
locator = Pyro.naming.NameServerLocator()
#print 'searching for Name Server...'
ns = locator.getNS()
daemon.useNameServer(ns)
# connect a new object implementation (first unregister previous one)
try:
# 'test' is the name by which our object will be known to the outside world
ns.unregister('muse')
except NamingError:
pass
# connect new object implementation
daemon.connect(museclass(),'muse')
# enter the server loop.
print 'Muse remote object published'
daemon.requestLoop()
if __name__=="__main__":
main()
main()