Hey
I've been away from this for a bit... I've just gotten my mythtv set
top with an a2dp headset*
can avrcp be used to drive mythtv? I've got a setup where the myth
frontend is rarely the foreground app, so it wouldn't work to deliver
keystrokes to the foreground app. I'm not sure how lirc does this but
it delivers messages to myth even if it doesn't have x11 focus.
Is there anything in place to fix latency automatically? Can I
calibrate the delay for a headset and have pulse fix it for me? The
wired audio sync also needs to be adjusted fwiw... pulse delivers
audio about 300ms too soon in the wired case.
* for the record, what I had to do under ubuntu 10.04 was tell myth to
use the pulse device and add this line to /etc/pulse/default.pa:
load-module module-alsa-sink device=plug:dmix
then I click the headset button to connect it and use pavucontrol to
move the myth stream over to the headset (a bit of a pain)
--
Brad Midgley
Sander
> I suppose this has to be enabled in the kernel, or loaded as a module, then udev will pick
> it up. On my Ubuntu 10.10 it is enabled in the kernel.
ok, so this is a bug in ubuntu before 10.10. for now I put uinput in
/etc/modules. see
https://bugs.launchpad.net/ubuntu/+source/bluez/+bug/584812
the key names coming through now as reported by irw:
a3 0 KEY_NEXTSONG event9
a5 0 KEY_PREVIOUSSONG event9
c9 0 KEY_PAUSECD event9
c8 0 KEY_PLAYCD event9
unfortunately there isn't a clear way to merge a udp/hdhomerun remote
coming in on lircd with avrcp events from inputlircd. I'll take it up
with the lirc folks and summarize here later. There is also eventlirc
that can deal with dynamic devices better but it still can't do udp.
Wouldn't it be nice if lirc simply used d-bus?
--
Brad Midgley
On Wednesday 29 September 2010 17:01:06 Brad Midgley wrote:
> Sander,
>
> >> Control is enabled by default in 4.60, is there anything I can check
> >> to see why I don't see any log messages about avrcp, no input device
> >> appear, nothing logged, etc?
> >
> > Currently there is support in bluez to act as a AVRCP target, and it will deliver
these
> > events through the input layer. No new input device will appear, it will go through
> > /dev/uinput (which I think you can open for reading then)
>
> Thanks for the tip. I didn't have /dev/uinput or /dev/input/uinput so
> I mknod'd it temporarily (mknod /dev/input/uinput c 10 233). Trying to
> get anything out of it while streaming gives me "No such device".
I suppose this has to be enabled in the kernel, or loaded as a module, then udev will pick
it up. On my Ubuntu 10.10 it is enabled in the kernel.
--
Sander
Sander,
>> Control is enabled by default in 4.60, is there anything I can check
>> to see why I don't see any log messages about avrcp, no input device
>> appear, nothing logged, etc?
>
> Currently there is support in bluez to act as a AVRCP target, and it will deliver these
> events through the input layer. No new input device will appear, it will go through
> /dev/uinput (which I think you can open for reading then)
Thanks for the tip. I didn't have /dev/uinput or /dev/input/uinput so
I mknod'd it temporarily (mknod /dev/input/uinput c 10 233). Trying to
get anything out of it while streaming gives me "No such device". Is
there somewhere else I can look to debug what bluez is doing to see if
it's trying to handle avrcp events? Is there any d-bus api for
examining them? hcidump shows avrcp messages going across, I just
don't know what bluetoothd is doing with them.
thanks all
--
Brad Midgley
On Tuesday 28 September 2010 09:05:18 Brad Midgley wrote:
> Hey
>
> > can avrcp be used to drive mythtv? I've got a setup where the myth
> > frontend is rarely the foreground app
>
> So if avrcp were to present events in a /dev/input/eventX device, I
> could use inputlircd to connect those events to lirc clients. It might
> make it easier if a udev rule created something like /dev/input/avrcp0
> so we could find it more easily for the inputlircd config.
>
> And I see now that it is by virtue of the use of liblirc that myth can
> get remote events even if it's not the foreground app.
>
> Control is enabled by default in 4.60, is there anything I can check
> to see why I don't see any log messages about avrcp, no input device
> appear, nothing logged, etc? The main connection is initiated by the
> headset and the audio connection is initiated by the computer. If I
> remember tinkering with this stuff, bluez would need to initiate the
> control connection in this case.
Currently there is support in bluez to act as a AVRCP target, and it will deliver these
events through the input layer. No new input device will appear, it will go through
/dev/uinput (which I think you can open for reading then)
The Control connection is ONLY (implicitly) established when an audio connection
(HS,HF,A2DP) is succesfully started, so you should be able to control myth (through lirc
perhaps) with a headset that has some controls. If this is done, you should be able to see
some debug logging w.r.t. RCP. You probably need to run bluetoothd using -d -n.
--
Sander
Hey
> can avrcp be used to drive mythtv? I've got a setup where the myth
> frontend is rarely the foreground app
So if avrcp were to present events in a /dev/input/eventX device, I
could use inputlircd to connect those events to lirc clients. It might
make it easier if a udev rule created something like /dev/input/avrcp0
so we could find it more easily for the inputlircd config.
And I see now that it is by virtue of the use of liblirc that myth can
get remote events even if it's not the foreground app.
Control is enabled by default in 4.60, is there anything I can check
to see why I don't see any log messages about avrcp, no input device
appear, nothing logged, etc? The main connection is initiated by the
headset and the audio connection is initiated by the computer. If I
remember tinkering with this stuff, bluez would need to initiate the
control connection in this case.
hcidump -X -V shows messages going across when I tap avrcp buttons...
> ACL data: handle 42 flags 0x02 dlen 12
L2CAP(d): cid 0x0043 len 8 [psm 0]
0000: a0 11 0e 00 48 7c 4b 00 ....H|K.
< ACL data: handle 42 flags 0x02 dlen 12
L2CAP(d): cid 0x0053 len 8 [psm 0]
0000: a2 11 0e 09 48 7c 4b 00 ....H|K.
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 42 packets 1
> HCI Event: Mode Change (0x14) plen 6
status 0x00 handle 42 mode 0x00 interval 0
Mode: Active
> ACL data: handle 42 flags 0x02 dlen 12
L2CAP(d): cid 0x0043 len 8 [psm 0]
0000: b0 11 0e 00 48 7c cb 00 ....H|..
< ACL data: handle 42 flags 0x02 dlen 12
L2CAP(d): cid 0x0053 len 8 [psm 0]
0000: b2 11 0e 09 48 7c cb 00 ....H|..
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 42 packets 1
> HCI Event: Mode Change (0x14) plen 6
status 0x00 handle 42 mode 0x02 interval 200
Mode: Sniff
--
Brad Midgley
sorry guys, you can crash mythtv if you don't drain the socket...
#***
#*********************************************************************
#*************************************************************************
#***
#*** GizmoDaemon Config Script
#*** AVRCP controls for MythTV
#***
#*****************************************
#*****************************************
#***
from GizmoDaemon import *
from GizmoScriptEnableChecker import *
import sys
import telnetlib
import time
ENABLED = True
VERSION_NEEDED = 3.2
class AVRCPMythTV(GizmoScriptEnableChecker):
"""
CatchAll Event Mapping for Testing
"""
def msend(self, msg):
telnet = telnetlib.Telnet("localhost", 6546)
telnet.read_until("# ")
time.sleep(0.1)
telnet.write(msg + "\n")
time.sleep(0.1)
telnet.read_eager()
telnet.write("quit\n")
time.sleep(0.1)
telnet.read_all()
telnet.close
def onEvent(self, Event, Gizmo = None):
"""
See GizmodDispatcher.onEvent documention for an explanation of this function
"""
if Event.Remote:
return False
if Event.Class != GizmoEventClass.Standard:
return False
if Event.Type != GizmoEventType.EV_KEY:
return False
if Event.Value != 1:
return False
name = str(Event.Code)
if name == "KEY_NEXTSONG":
self.msend("key right")
return True
elif name == "KEY_PLAYCD" or name == "KEY_PAUSECD":
self.msend("key p")
return True
elif name == "KEY_STOPCD":
self.msend("key escape")
return True
elif name == "KEY_PREVIOUSSONG":
self.msend("key left")
return True
return False
def __init__(self):
"""
Default Constructor
"""
GizmoScriptEnableChecker.__init__(self, ENABLED, VERSION_NEEDED)
AVRCPMythTV()
Guys
> unfortunately there isn't a clear way to merge a udp/hdhomerun remote
> coming in on lircd with avrcp events from inputlircd. I'll take it up
> with the lirc folks and summarize here later.
lirc should be used to inject input events and probably nothing else.
There are three different lirc daemon flavors, each one missing key
features. If you need to merge multiple sources, you have to do a
confusing dance with tcp sockets, master servers, etc. Unfortunately,
the event driver interface is one thing in lirc that apparently
doesn't work at all.
I made it work instead with gizmod talking to the mythtv telnet
control connection, see script.
Gizmod does have a problem with its compile prefix, see
https://bugs.launchpad.net/ubuntu/+source/gizmod/+bug/645058
So, the complete hack under ubuntu 10.04...
* add uinput to /etc/modules
* tell myth to use the pulse device
* add to /etc/pulse/default.pa: load-module module-alsa-sink device=plug:dmix
* click the headset button to connect it
* use pavucontrol to move the myth stream over to the headset
* install the script below in ~/.gizmod/modules.d/001-AVRCP-MythTV.py
* sudo ln -s /etc /usr/etc
* sudo gizmod
--
Brad Midgley
from GizmoDaemon import *
from GizmoScriptEnableChecker import *
import sys
import telnetlib
ENABLED = True
VERSION_NEEDED = 3.2
class AVRCPMythTV(GizmoScriptEnableChecker):
def msend(self, msg):
telnet = telnetlib.Telnet("localhost", 6546)
telnet.read_until("# ")
telnet.write(msg + "\n")
telnet.close
def onEvent(self, Event, Gizmo = None):
if Event.Remote:
return False
if Event.Class != GizmoEventClass.Standard:
return False
if Event.Type != GizmoEventType.EV_KEY:
return False
if Event.Value != 1:
return False
name = str(Event.Code)
if name == "KEY_NEXTSONG":
self.msend("key right")
return True
elif name == "KEY_PLAYCD" or name == "KEY_PAUSECD":
self.msend("key p")
return True
elif name == "KEY_STOPCD":
self.msend("key escape")
return True
elif name == "KEY_PREVIOUSSONG":
self.msend("key left")
return True
return False
def __init__(self):
GizmoScriptEnableChecker.__init__(self, ENABLED, VERSION_NEEDED)