[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.&nbsp; The 1177 is a $125 unit =
that has=20
an auto and a manual mode.&nbsp; 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.&nbsp; The manual mode requires manually selecting =
the=20
changer, which obviously doesn't fly.</FONT></DIV>
<DIV>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</DIV>
<DIV><FONT size=3D2>The next two action items are software:</FONT></DIV>
<DIV>&nbsp;</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>&nbsp;</DIV>
<DIV><FONT size=3D2>4. Setting up an extensive map file in CDJ.&nbsp; =
Below I=20
share my map file that does it.&nbsp; 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&nbsp;11 that identifies the =
desired=20
changer, and then reads the parallel port.&nbsp; 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.&nbsp; =
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.&nbsp; This triggers a new returning par[] event which =
will=20
again identify the selected and desired inputs.</FONT><FONT =
size=3D2>&nbsp; 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>&nbsp;</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.&nbsp; It also uses a bit of the parallel port as a =
test bit=20
to allow a retry in one ambiguous condition.&nbsp; This slows the =
switching=20
slightly, but even so, at most it takes a second to switch inputs once =
the=20
process starts.&nbsp; I set a 1 second delay in the CDJ options to =
account for=20
this.</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>I've listed the relevant portion of my map file=20
below.</FONT></DIV>
<DIV>&nbsp;</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>&nbsp;{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>&nbsp;{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>&nbsp;{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>&nbsp;{lowlevel:parhs[0]=20
lowlevel:pardir[240] lowlevel:par[07] lowlevel:ir[-250000] =
lowlevel:par[03]=20
lowlevel:parread[]}</FONT></DIV>
<DIV>&nbsp;</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>&nbsp;# Either we arrived at the "auto" =
mode, or=20
are in a blink <BR>&nbsp;# Set test bit, wait 0.8 seconds (longer than =
blink),=20
&amp; re-read<BR>&nbsp;{lowlevel:ir[-800000] lowlevel:par[08]=20
lowlevel:parread[]}<BR>lowlevel:par[08]<BR>&nbsp;# Apparently, we are on =
"auto",=20
not in a blink<BR>&nbsp;{}<BR>lowlevel:par[20]<BR>&nbsp;# We want 0 but =
are at=20
1<BR>&nbsp;&nbsp;{lowlevel:par[04] lowlevel:ir[-250000] lowlevel:par[00] =

lowlevel:parread[]}<BR>lowlevel:par[28] # Same but with test bit =
set<BR>&nbsp;#=20
We want 0 but are at 1, clear test bit and =
move<BR>&nbsp;&nbsp;{lowlevel:par[04]=20
lowlevel:ir[-250000] lowlevel:par[00]=20
lowlevel:parread[]}<BR>lowlevel:par[40]<BR>&nbsp;# We want 0 but are at=20
2<BR>&nbsp;&nbsp;{lowlevel:par[04] lowlevel:ir[-250000] lowlevel:par[00] =

lowlevel:parread[]}<BR>lowlevel:par[48] # Same but with test bit =
set<BR>&nbsp;#=20
We want 0 but are at 2, clear test bit and =
move<BR>&nbsp;&nbsp;{lowlevel:par[04]=20
lowlevel:ir[-250000] lowlevel:par[00] =
lowlevel:parread[]}<BR>lowlevel:par[80]=20
<BR>&nbsp;# We want 0 but are at 3<BR>&nbsp;&nbsp;{lowlevel:par[04]=20
lowlevel:ir[-250000] lowlevel:par[00] =
lowlevel:parread[]}<BR>lowlevel:par[88] #=20
Same but with test bit set<BR>&nbsp;# We want 0 but are at 3, clear test =
bit and=20
move<BR>&nbsp;&nbsp;{lowlevel:par[04] lowlevel:ir[-250000] =
lowlevel:par[00]=20
lowlevel:parread[]}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>lowlevel:par[01]<BR>&nbsp;# We want 1 but are at =
0<BR>&nbsp;#=20
Still need to do a read in case caught at =
auto-select<BR>&nbsp;{lowlevel:par[05]=20
lowlevel:ir[-250000] lowlevel:par[01]=20
lowlevel:parread[]}<BR>lowlevel:par[21]<BR>&nbsp;# We are where we want =
to=20
be<BR>&nbsp;{}<BR>lowlevel:par[41]<BR>&nbsp;# We want 1 but are at=20
2<BR>&nbsp;&nbsp;{lowlevel:par[05] lowlevel:ir[-250000] lowlevel:par[01] =

lowlevel:parread[]}<BR>lowlevel:par[81]<BR>&nbsp;# We want 1 but are at=20
3<BR>&nbsp;&nbsp;{lowlevel:par[05] lowlevel:ir[-250000] lowlevel:par[01] =

lowlevel:parread[]}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>lowlevel:par[02]<BR>&nbsp;# We want 2 but are at=20
0<BR>&nbsp;&nbsp;{lowlevel:par[06] lowlevel:ir[-250000] lowlevel:par[02] =

lowlevel:parread[]}<BR>lowlevel:par[22] <BR>&nbsp;# We want 2 but are at =

1<BR>&nbsp;&nbsp;{lowlevel:par[06] lowlevel:ir[-250000] lowlevel:par[02] =

lowlevel:parread[]}<BR>lowlevel:par[42]<BR>&nbsp;# We are where we want =
to=20
be<BR>&nbsp;{}<BR>lowlevel:par[82]<BR>&nbsp;# We want 2 but are at=20
3<BR>&nbsp;&nbsp;{lowlevel:par[06] lowlevel:ir[-250000] lowlevel:par[02] =

lowlevel:parread[]}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>lowlevel:par[03]<BR>&nbsp;# We want 3 but are at=20
0<BR>&nbsp;&nbsp;{lowlevel:par[07] lowlevel:ir[-250000] lowlevel:par[03] =

lowlevel:parread[]}<BR>lowlevel:par[23]<BR>&nbsp;# We want 3 but are at=20
1<BR>&nbsp;&nbsp;{lowlevel:par[07] lowlevel:ir[-250000] lowlevel:par[03] =

lowlevel:parread[]}<BR>lowlevel:par[43]<BR>&nbsp;# We want 3 but are at=20
2<BR>&nbsp;&nbsp;{lowlevel:par[07] lowlevel:ir[-250000] lowlevel:par[03] =

lowlevel:parread[]}<BR>lowlevel:par[83]<BR>&nbsp;# We are where we want =
to=20
be<BR>&nbsp;{}<BR></FONT></DIV></BODY></HTML>

------=_NextPart_000_0122_01C0660C.088134E0--