[slinkelist] Hacking the Audio Authority 1177 for Slink-e control
Thomas W. Humphrey
TWHumphrey@fuse.net
Thu, 14 Dec 2000 20:25:42 -0500
This is a multi-part message in MIME format.
------=_NextPart_000_0122_01C0660C.088134E0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
I suspected my post would generate interest from people interested in =
replicating my 1177 hack. The 1177 is a $125 unit that has an auto and =
a manual mode. It can't be used as is in either mode with CDJ, because =
when CDJ is running the changers, they are always all on, so in the auto =
mode the 1177 will always select the highest priority changer and never =
provide audio from any others. The manual mode requires manually =
selecting the changer, which obviously doesn't fly.
My hack basically involved:
1. Adding a transistor-relay circuit to the 1177 in parallel with the =
manual selection button on the front so that I could use an output =
signal from the Slink-e parallel port to "manually" move the 1177 input =
from one input to the next.
2. Soldering wires to the digital outputs from the 1177 processor that =
drive the lights on the front so that I could detect which input was =
currently selected.
I would be happy to document what is soldered to what for parts (1) and =
(2) for anyone interested.
The next two action items are software:
3. Setting up the lowlevel device in CDJ so that CDJ could read and =
write to the parallel port.
4. Setting up an extensive map file in CDJ. Below I share my map file =
that does it. In essence, it works as follows: when a using_player =
event occurs, CDJ sets two unconnected output bits on the Slink-e =
parallel ports to a value between 00 and 11 that identifies the desired =
changer, and then reads the parallel port. The bits of the returning =
par[] event then indicate what input is desired and (from the signals =
driving the lights on the front of the 1177) what input is currently =
selected. For each case where the two don't match, the map file creates =
par[] events that set and reset the parallel port bit driving the =
transistor-relay circuit (which has the effect of pushing and releasing =
the manual control button once), and then a parread[] event. This =
triggers a new returning par[] event which will again identify the =
selected and desired inputs. The process will continue until the =
selected and desired inputs match, at which point no further events are =
generated.
My map file also includes short delays to work around the "blink" that =
the 1177 generates on lights for inputs that are selected but receiving =
no signal. It also uses a bit of the parallel port as a test bit to =
allow a retry in one ambiguous condition. This slows the switching =
slightly, but even so, at most it takes a second to switch inputs once =
the process starts. I set a 1 second delay in the CDJ options to =
account for this.
I've listed the relevant portion of my map file below.
# When we start using a player, shift to next input, set bits
# to indicate desired player number, then check 1177 status bits
# Set no handshaking, using bottom four bits for output, remainder for =
input
cdjr:using_player[cd1]
{lowlevel:parhs[0] lowlevel:pardir[240] lowlevel:par[04] =
lowlevel:ir[-250000] lowlevel:par[00] lowlevel:parread[]}
cdjr:using_player[cd2]
{lowlevel:parhs[0] lowlevel:pardir[240] lowlevel:par[05] =
lowlevel:ir[-250000] lowlevel:par[01] lowlevel:parread[]}
cdjr:using_player[cd3]
{lowlevel:parhs[0] lowlevel:pardir[240] lowlevel:par[06] =
lowlevel:ir[-250000] lowlevel:par[02] lowlevel:parread[]}
cdjr:using_player[cd4]
{lowlevel:parhs[0] lowlevel:pardir[240] lowlevel:par[07] =
lowlevel:ir[-250000] lowlevel:par[03] lowlevel:parread[]}
# When we get 1177 status bits back, compare to desired player
# number, and shift to next input if no match
lowlevel:par[00]
# Either we arrived at the "auto" mode, or are in a blink=20
# Set test bit, wait 0.8 seconds (longer than blink), & re-read
{lowlevel:ir[-800000] lowlevel:par[08] lowlevel:parread[]}
lowlevel:par[08]
# Apparently, we are on "auto", not in a blink
{}
lowlevel:par[20]
# We want 0 but are at 1
{lowlevel:par[04] lowlevel:ir[-250000] lowlevel:par[00] =
lowlevel:parread[]}
lowlevel:par[28] # Same but with test bit set
# We want 0 but are at 1, clear test bit and move
{lowlevel:par[04] lowlevel:ir[-250000] lowlevel:par[00] =
lowlevel:parread[]}
lowlevel:par[40]
# We want 0 but are at 2
{lowlevel:par[04] lowlevel:ir[-250000] lowlevel:par[00] =
lowlevel:parread[]}
lowlevel:par[48] # Same but with test bit set
# We want 0 but are at 2, clear test bit and move
{lowlevel:par[04] lowlevel:ir[-250000] lowlevel:par[00] =
lowlevel:parread[]}
lowlevel:par[80]=20
# We want 0 but are at 3
{lowlevel:par[04] lowlevel:ir[-250000] lowlevel:par[00] =
lowlevel:parread[]}
lowlevel:par[88] # Same but with test bit set
# We want 0 but are at 3, clear test bit and move
{lowlevel:par[04] lowlevel:ir[-250000] lowlevel:par[00] =
lowlevel:parread[]}
lowlevel:par[01]
# We want 1 but are at 0
# Still need to do a read in case caught at auto-select
{lowlevel:par[05] lowlevel:ir[-250000] lowlevel:par[01] =
lowlevel:parread[]}
lowlevel:par[21]
# We are where we want to be
{}
lowlevel:par[41]
# We want 1 but are at 2
{lowlevel:par[05] lowlevel:ir[-250000] lowlevel:par[01] =
lowlevel:parread[]}
lowlevel:par[81]
# We want 1 but are at 3
{lowlevel:par[05] lowlevel:ir[-250000] lowlevel:par[01] =
lowlevel:parread[]}
lowlevel:par[02]
# We want 2 but are at 0
{lowlevel:par[06] lowlevel:ir[-250000] lowlevel:par[02] =
lowlevel:parread[]}
lowlevel:par[22]=20
# We want 2 but are at 1
{lowlevel:par[06] lowlevel:ir[-250000] lowlevel:par[02] =
lowlevel:parread[]}
lowlevel:par[42]
# We are where we want to be
{}
lowlevel:par[82]
# We want 2 but are at 3
{lowlevel:par[06] lowlevel:ir[-250000] lowlevel:par[02] =
lowlevel:parread[]}
lowlevel:par[03]
# We want 3 but are at 0
{lowlevel:par[07] lowlevel:ir[-250000] lowlevel:par[03] =
lowlevel:parread[]}
lowlevel:par[23]
# We want 3 but are at 1
{lowlevel:par[07] lowlevel:ir[-250000] lowlevel:par[03] =
lowlevel:parread[]}
lowlevel:par[43]
# We want 3 but are at 2
{lowlevel:par[07] lowlevel:ir[-250000] lowlevel:par[03] =
lowlevel:parread[]}
lowlevel:par[83]
# We are where we want to be
{}
------=_NextPart_000_0122_01C0660C.088134E0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=3D"text/html; charset=3Diso-8859-1" =
http-equiv=3DContent-Type>
<META content=3D"MSHTML 5.00.3019.2500" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT size=3D2>I suspected my post would generate interest from =
people=20
interested in replicating my 1177 hack. The 1177 is a $125 unit =
that has=20
an auto and a manual mode. It can't be used as is in either mode =
with CDJ,=20
because when CDJ is running the changers, they are always all on, so in =
the auto=20
mode the 1177 will always select the highest priority changer and never =
provide=20
audio from any others. The manual mode requires manually selecting =
the=20
changer, which obviously doesn't fly.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=3D2>My hack basically involved:</FONT></DIV>
<DIV><FONT size=3D2>1. Adding a transistor-relay circuit to the 1177 in =
parallel=20
with the manual selection button on the front so that I could use an =
output=20
signal from the Slink-e parallel port to "manually" move the 1177 input =
from one=20
input to the next.</FONT></DIV>
<DIV><FONT size=3D2></FONT> </DIV>
<DIV><FONT size=3D2>2. Soldering wires to the digital outputs from the =
1177=20
processor that drive the lights on the front so that I could detect =
which input=20
was currently selected.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=3D2>I would be happy to document what is soldered to =
what for=20
parts (1) and (2) for anyone interested.</FONT></DIV>
<DIV><FONT size=3D2></FONT> </DIV>
<DIV><FONT size=3D2>The next two action items are software:</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=3D2>3. Setting up the lowlevel device in CDJ so that CDJ =
could=20
read and write to the parallel port.</FONT></DIV>
<DIV><FONT size=3D2></FONT> </DIV>
<DIV><FONT size=3D2>4. Setting up an extensive map file in CDJ. =
Below I=20
share my map file that does it. In essence, it works as follows: =
when a=20
using_player event occurs, CDJ sets two unconnected output bits on the =
Slink-e=20
parallel ports to a value between 00 and 11 that identifies the =
desired=20
changer, and then reads the parallel port. The bits of the =
returning par[]=20
event then indicate what input is desired and (from the signals driving =
the=20
lights on the front of the 1177) what input is currently selected. =
For=20
each case where the two don't match, the map file creates par[] events =
that set=20
and reset the parallel port bit driving the transistor-relay circuit =
(which has=20
the effect of pushing and releasing the manual control button once), and =
then a=20
parread[] event. This triggers a new returning par[] event which =
will=20
again identify the selected and desired inputs.</FONT><FONT =
size=3D2> The=20
process will continue until the selected and desired inputs match, at =
which=20
point no further events are generated.</FONT></DIV>
<DIV><FONT size=3D2></FONT> </DIV>
<DIV><FONT size=3D2>My map file also includes short delays to work =
around the=20
"blink" that the 1177 generates on lights for inputs that are selected =
but=20
receiving no signal. It also uses a bit of the parallel port as a =
test bit=20
to allow a retry in one ambiguous condition. This slows the =
switching=20
slightly, but even so, at most it takes a second to switch inputs once =
the=20
process starts. I set a 1 second delay in the CDJ options to =
account for=20
this.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=3D2>I've listed the relevant portion of my map file=20
below.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=3D2># When we start using a player, shift to next input, =
set=20
bits<BR># to indicate desired player number, then check 1177 status =
bits<BR>#=20
Set no handshaking, using bottom four bits for output, remainder for=20
input<BR>cdjr:using_player[cd1]<BR> {lowlevel:parhs[0] =
lowlevel:pardir[240]=20
lowlevel:par[04] lowlevel:ir[-250000] lowlevel:par[00]=20
lowlevel:parread[]}<BR></FONT></DIV>
<DIV><FONT size=3D2>cdjr:using_player[cd2]<BR> {lowlevel:parhs[0]=20
lowlevel:pardir[240] lowlevel:par[05] lowlevel:ir[-250000] =
lowlevel:par[01]=20
lowlevel:parread[]}<BR></FONT></DIV>
<DIV><FONT size=3D2>cdjr:using_player[cd3]<BR> {lowlevel:parhs[0]=20
lowlevel:pardir[240] lowlevel:par[06] lowlevel:ir[-250000] =
lowlevel:par[02]=20
lowlevel:parread[]}<BR></FONT></DIV>
<DIV><FONT size=3D2>cdjr:using_player[cd4]<BR> {lowlevel:parhs[0]=20
lowlevel:pardir[240] lowlevel:par[07] lowlevel:ir[-250000] =
lowlevel:par[03]=20
lowlevel:parread[]}</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=3D2># When we get 1177 status bits back, compare to =
desired=20
player<BR># number, and shift to next input if no=20
match<BR>lowlevel:par[00]<BR> # Either we arrived at the "auto" =
mode, or=20
are in a blink <BR> # Set test bit, wait 0.8 seconds (longer than =
blink),=20
& re-read<BR> {lowlevel:ir[-800000] lowlevel:par[08]=20
lowlevel:parread[]}<BR>lowlevel:par[08]<BR> # Apparently, we are on =
"auto",=20
not in a blink<BR> {}<BR>lowlevel:par[20]<BR> # We want 0 but =
are at=20
1<BR> {lowlevel:par[04] lowlevel:ir[-250000] lowlevel:par[00] =
lowlevel:parread[]}<BR>lowlevel:par[28] # Same but with test bit =
set<BR> #=20
We want 0 but are at 1, clear test bit and =
move<BR> {lowlevel:par[04]=20
lowlevel:ir[-250000] lowlevel:par[00]=20
lowlevel:parread[]}<BR>lowlevel:par[40]<BR> # We want 0 but are at=20
2<BR> {lowlevel:par[04] lowlevel:ir[-250000] lowlevel:par[00] =
lowlevel:parread[]}<BR>lowlevel:par[48] # Same but with test bit =
set<BR> #=20
We want 0 but are at 2, clear test bit and =
move<BR> {lowlevel:par[04]=20
lowlevel:ir[-250000] lowlevel:par[00] =
lowlevel:parread[]}<BR>lowlevel:par[80]=20
<BR> # We want 0 but are at 3<BR> {lowlevel:par[04]=20
lowlevel:ir[-250000] lowlevel:par[00] =
lowlevel:parread[]}<BR>lowlevel:par[88] #=20
Same but with test bit set<BR> # We want 0 but are at 3, clear test =
bit and=20
move<BR> {lowlevel:par[04] lowlevel:ir[-250000] =
lowlevel:par[00]=20
lowlevel:parread[]}</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=3D2>lowlevel:par[01]<BR> # We want 1 but are at =
0<BR> #=20
Still need to do a read in case caught at =
auto-select<BR> {lowlevel:par[05]=20
lowlevel:ir[-250000] lowlevel:par[01]=20
lowlevel:parread[]}<BR>lowlevel:par[21]<BR> # We are where we want =
to=20
be<BR> {}<BR>lowlevel:par[41]<BR> # We want 1 but are at=20
2<BR> {lowlevel:par[05] lowlevel:ir[-250000] lowlevel:par[01] =
lowlevel:parread[]}<BR>lowlevel:par[81]<BR> # We want 1 but are at=20
3<BR> {lowlevel:par[05] lowlevel:ir[-250000] lowlevel:par[01] =
lowlevel:parread[]}</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=3D2>lowlevel:par[02]<BR> # We want 2 but are at=20
0<BR> {lowlevel:par[06] lowlevel:ir[-250000] lowlevel:par[02] =
lowlevel:parread[]}<BR>lowlevel:par[22] <BR> # We want 2 but are at =
1<BR> {lowlevel:par[06] lowlevel:ir[-250000] lowlevel:par[02] =
lowlevel:parread[]}<BR>lowlevel:par[42]<BR> # We are where we want =
to=20
be<BR> {}<BR>lowlevel:par[82]<BR> # We want 2 but are at=20
3<BR> {lowlevel:par[06] lowlevel:ir[-250000] lowlevel:par[02] =
lowlevel:parread[]}</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=3D2>lowlevel:par[03]<BR> # We want 3 but are at=20
0<BR> {lowlevel:par[07] lowlevel:ir[-250000] lowlevel:par[03] =
lowlevel:parread[]}<BR>lowlevel:par[23]<BR> # We want 3 but are at=20
1<BR> {lowlevel:par[07] lowlevel:ir[-250000] lowlevel:par[03] =
lowlevel:parread[]}<BR>lowlevel:par[43]<BR> # We want 3 but are at=20
2<BR> {lowlevel:par[07] lowlevel:ir[-250000] lowlevel:par[03] =
lowlevel:parread[]}<BR>lowlevel:par[83]<BR> # We are where we want =
to=20
be<BR> {}<BR></FONT></DIV></BODY></HTML>
------=_NextPart_000_0122_01C0660C.088134E0--