예제 #1
0
#
#	PulseEqualizerGui is free software; you can redistribute it and/or modify
#	it under the terms of the GNU Lesser General Public License as published
#	by the Free Software Foundation; either version 3 of the License,
#	or (at your option) any later version.

import sys

sys.path.append('./resources/lib/')
sys.path.append('./fakekodi')

from helper import SocketCom

#sc = SocketCom("sound")
sc = SocketCom("server")
if not sc.is_server_running():
    print("server is not running")
    sys.exit(0)

try:
    func = sys.argv[1]

    if func == "exit":
        sc.stop_server()
        sys.exit(0)

    target = sys.argv[2]
    try:
        args = []
        for arg in sys.argv[3:]:
            args.append(float(arg))
예제 #2
0
class PaMonitor( xbmc.Monitor ):
	def __init__( self ):
		#strat process
		xbmc.Monitor.__init__( self )
		xbmc.log("eq: start PulesEqualizer service",xbmc.LOGDEBUG)

		self.server_sock = SocketCom("kodi")
		if not self.server_sock.is_server_running():
			self.server_sock.start_func_server(self)
		else: self.server_sock = None

		launcher = Launcher("menu")
		launcher.start()

		self.sock = SocketCom("server")

		ps = PulseService()
		ps.start()

		self.sock.call_func("set","device",[self.get_device()])

		while not self.abortRequested():
			if self.waitForAbort( 10 ):
				break

		launcher.stop()

		ps.stop()
		if self.server_sock:
			self.server_sock.stop_server()

	@staticmethod
	def get_device():
		device = ""
		r_dict = json.loads(xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Settings.GetSettings", "params":{ "filter": {"section":"system", "category":"audio"}}, "id":1}'))
		for s in r_dict["result"]["settings"]:
			if s["id"] == "audiooutput.audiodevice":
				device = s["value"]
				break
		return device

	def on_device_get(self):
		result = self.get_device()
		xbmc.log("eq: kodi service: on_device_get %s" % result,xbmc.LOGDEBUG)
		return result

	@staticmethod
	def on_player_get():
		r_dict = json.loads(xbmc.executeJSONRPC('{"jsonrpc":"2.0","method":"Player.GetActivePlayers","id":0}'))
		try: return r_dict["result"]
		except Exception: return None

	@staticmethod
	def on_log_write(message, level):
		xbmc.log(message, level)

	def on_service_up(self):
		self.sock.call_func("set","device",[self.get_device()])

	def onNotification( self, _sender, method, _data ):
		target,func = method.lower().replace("on","").split(".")
		if target in ["system", "player"]:
			self.sock.call_func(func, target)
예제 #3
0
class PulseInterfaceService():
    def __init__(self, gid=0):
        self.service_owner = False
        self.running = False
        self.pulseloop = False

        self.gid = gid
        self.sock = SocketCom("server")

        self.q = Queue()
        self.mc = MessageCentral()

        #allow only one instance of the server
        if not self.sock.is_server_running():
            self.start_event_loop()
            self.service_owner = True
        else:
            log("pase: server alreay running, don't start")

    #start all message loops
    def start_event_loop(self):
        self.running = True
        Thread(target=self.message_forward).start()
        Thread(target=self.start_pulse_loop).start()
        self.sock.start_server(self.on_socket_message)

    #stop all message loops
    def stop_event_loop(self):
        if self.running:
            self.running = False
            self.pulseloop = True
            self.q.put(('exit', '', '', None))

            self.sock.stop_server()

            self.send_message_to_central('message', 'exit')
            self.pulse_event.close()

    #
    #	support functions
    #

    def send_message_to_central(self, target, func, param='', conn=None):
        # create a new thread per message. So message_forward thread will not crash in case of message handling crash
        th = Thread(target=self.mc.on_message,
                    args=(target, func, param, conn))
        th.start()
        th.join()
        if conn: conn.close()

    #
    #	message loops
    #

    def on_socket_message(self, conn, msg):
        try:
            func, target, args = json.loads(msg)
            log("pase: receive from socket: %s" % repr([func, target, args]))

            if target == "service" and func == "stop" and args[0] == self.gid:
                log("pase: stop_service received - stopping service")
                conn.close()
                self.stop_event_loop()

            self.q.put((target, func, args, conn))

        except Exception as e:
            handle(e)

    #messages from pulse audio
    def pulse_event_receive(self, event):
        if event.facility._value in ["server", "source", "source_output"]:
            return
        self.q.put(
            (event.facility._value, event.t._value, [event.index], None))

    #start message loop for pulse audio
    def start_pulse_loop(self):
        log("pase: start pulse loop")
        cnt = 1
        while True:
            try:
                self.pulse_event = pulsectl.Pulse('Event Manager')

                log("pase: connected to pulse")
                cnt = 1

                self.pulse_event.event_mask_set('all')
                self.pulse_event.event_callback_set(self.pulse_event_receive)
                self.send_message_to_central('pulse', 'connect')
                self.pulse_event.event_listen()

            except pulsectl.PulseDisconnected:
                log("pase: pulse disconnected")
                if not self.running:
                    self.pulseloop = False
                    log("pase: stop pulse loop")
                    return
            except Exception as e:
                if cnt > 0:
                    handle(e)
                    logerror("pase: in event manager")
                    cnt = cnt - 1

            if not self.running: return

            time.sleep(0.5)

    #
    #	message forward
    #
    #	message from pulse may arrive to late/ quick for our message handling.
    #	therefore collect them and process them 100ms after the last message.

    def message_forward(self):
        log("pase: start message_dispatch")

        timeout = None
        while True:
            try:
                try:
                    target, func, param, conn = self.q.get(timeout=timeout)

                except Empty:
                    # we did not receive any message since 100 ms. Send this info to
                    # message collector. Message collector will then process the previouse
                    # collected messages

                    t = time.time()

                    self.send_message_to_central('pa', 'update')
                    timeout = None

                    log("pase: pa_updated: time needed {:2f} ms".format(
                        (time.time() - t) * 1000))
                    continue
                except Exception as e:
                    handle(e)

                if target == "exit": break

                if conn is None: timeout = 0.1

                self.send_message_to_central(target, func, param, conn)

                self.q.task_done()

            except Exception as e:
                handle(e)

        log("pase: stop message_dispatch")
예제 #4
0
    def sweep_play_loop(self, count, channel, vol):
        if not self.player_proc:
            if not self.on_pulseplayer_start(channel): return False

        self.playing = True
        self.stop = False

        log("soge: sweep start")

        socket = SocketCom("sweep")
        sock_up = socket.is_server_running()
        if sock_up: log("soge: sweep server is up")

        sampleRate = float(self.cur_eq.sample_spec["rate"])
        chunk = int(sampleRate / 4)
        chunk_duration = float(0.25)

        #
        # prepare Sound
        #

        total_chunk = 20 * count
        cur_chunk = 0

        chunk_list = []
        pos = 0
        for c in range(20):
            base = c * chunk
            samples = array('f', [])
            for f in range(chunk):
                step = float((base + f)) / (sampleRate * 10)
                samples.append(float(sin(2 * pos * pi) * vol))
                pos = pos + step
            chunk_list.append(samples)
        cur_chunk = 0

        #
        # play Sound
        #

        for cnt in range(count):
            if sock_up: socket.send("play", "sound", [count - cnt])
            c = 0

            for samples in chunk_list:
                if sock_up:
                    socket.send("play", "chunk",
                                [c, 20, cur_chunk, total_chunk])
                self.player_proc.stdin.write(samples)

                if self.stop: break
                cur_chunk = cur_chunk + 1
                c = c + 1
                if cur_chunk > 2: sleep(chunk_duration)
            if self.stop: break

        sleep(4 * chunk_duration)

        log("soge: sweep has finished")
        self.stop = False
        self.playing = False
        if sock_up: socket.send("stop", "sound")
        self.on_pulseplayer_stop()