################################################################### # Minidisc Toc Editor # Copyright (C) 2001 Uwe Rathmann # # $Id: Sony-Modern-Decks.tcl,v 1.1 2002/02/18 15:01:11 rathmann Exp $ # # Tcl plugin for modern Sony decks. It uses the commands of # the rm-d29m, rm-d10p remote controls. Most modern Sony decks # understand them, even if they are shipped with other remotes. # It was reported to work with MDS-JE330, MDS-JE530, MDS-JE640 # but others should work as well. # ################################################################### proc pluginName {} { return "Modern Sony Decks" } proc delay {} { return 20 } proc timing {} { return 40 } proc eraseName { what } { ircmd rm-d29m menu ircmd delay 8 # The main(=edit) menu consists of maximum # 8 entries, where the "Name' menu is the first one. # So when we scroll 7 times left, we can be sure # that the name menu is active for { set i 0 } { $i < 7 } { incr i 1 } { ircmd rm-d29m skip_back ircmd delay 5 } ircmd rm-d29m yes ircmd delay 40 # the "Name" menu consists of 4 entries # where TrackErase is 2. and AllErase is 3. if { $what == "All" } { for { set i 0 } { $i < 3 } { incr i 1 } { ircmd rm-d29m skip_forw } ircmd rm-d29m skip_back } if { $what == "Selected" } { for { set i 0 } { $i < 3 } { incr i 1 } { ircmd rm-d29m skip_back } ircmd rm-d29m skip_forw } ircmd rm-d29m yes ircmd delay 80 ircmd rm-d29m yes ircmd delay 80 } proc selectTrack {track} { if { $track <= 0 } return; if { $track >= 100 } return; if { $track < 10 } { ircmd rm-d29m $track } else { # Better Sony remotes offer buttons for trackno 1-25. # If we'd like to optimze, we could use these commands. ircmd rm-d29m >10 ircmd rm-d29m [ expr $track / 10 ] ircmd delay 10 ircmd rm-d29m [ expr $track % 10 ] } } proc setName { title } { ircmd rm-d29m name ircmd delay 80 # we split the string into a list of characters # and map each of them into a single rm-d10p command. # rm-d10p is a IR-keyboard, made for the purpose # of md-titeling with Sony decks only. set charList [ split $title {} ] set previousCmd "" foreach c $charList { # According manuals, Sony decks seem to differ in what # charcters are supported. (Implementation missing) switch -regexp -- $c { [0-9] { set cmd $c } [a-z] { set cmd $c } [A-Z] { set cmd cap_[ string tolower $c] } default { switch -- $c { @ { set cmd at } ` { set cmd grave } ^ { set cmd asciicircum } ! { set cmd exclamation } \" { set cmd doublequote } # { set cmd hash } $ { set cmd dollar } % { set cmd percent } & { set cmd ampersand } ' { set cmd apostrophe } ( { set cmd open_parenthesis } ) { set cmd close_parenthesis } \{ { set cmd open_parenthesis } \} { set cmd close_parenthesis } * { set cmd asterick } + { set cmd plus } , { set cmd comma } - { set cmd dash } - { set cmd underscore } . { set cmd period } / { set cmd slash } \\ { set cmd slash } : { set cmd colon } ; { set cmd semicolon } < { set cmd lessthan } = { set cmd equal } > { set cmd greaterthan } ? { set cmd question } " " { set cmd space } default { set cmd asterick } } } } if { $previousCmd == $cmd } { # The deck seems to interprete 2 identical commands # as 1 command if they follow to close, and swallows the # second one. ircmd delay 4 } set previousCmd $cmd ircmd rm-d10p $cmd } ircmd delay 1 ircmd rm-d29m yes ircmd delay 20 return 0 } proc rescueDisc {} { # there is a backdoor in most modern Sony decks how to prevent # the deck from synchronizing memory and disc. The trick is to # set the deck into "Retry Cause Display Mode" and do an # operation that would sync to disc normally. ircmd rm-d29m stop 12s ircmd rm-d29m eject ircmd delay 80 # now we can leave "Retry Cause Display Mode" # by turning the deck off/on ircmd rm-d29m power ircmd delay 10 ircmd rm-d29m power ircmd delay 10 } proc writeToDisc {} { # power off and eject are operations, when the deck # syncs the TOC to disc. We use 'power off' ircmd rm-d29m power ircmd delay 10s ircmd rm-d29m power ircmd delay 10 } proc power {} { ircmd rm-d29m power } proc eject {} { ircmd rm-d29m eject } proc play {track} { if { $track <= 0 } { ircmd rm-d29m play } else { # selecting a track starts the track selectTrack [ expr $track + 1 ] } } proc stop {} { ircmd rm-d29m stop } proc pause {} { ircmd rm-d29m pause } proc forward {} { ircmd rm-d29m forw 1s } proc backward {} { ircmd rm-d29m back 1s } proc nextTrack {} { ircmd rm-d29m skip_forw } proc previousTrack {} { ircmd rm-d29m skip_back } proc setTitle {track title} { ircmd rm-d29m stop ircmd delay 40 if { $track >= 0 } { ircmd rm-d29m pause ircmd delay 40 if { $track > 0 } { # "pause" activates the first track, so we don't have # to select track 0 selectTrack [ expr $track + 1 ] } } eraseName Selected setName $title if { $track >= 0 } { ircmd rm-d29m stop ircmd delay 40 } } proc setToc args { # There are several situations, where the deck displays the # current name. Because the display has only 11 chars, longer names # have to be scrolled through the display. This scrolling # needs some time, and even worse, it needs an unknown # amount of time, as it depends on the length of the name. # So setToc is written avoiding all situations where scrolling # would happen. ircmd rm-d29m stop ircmd delay 40 # we erase all names first. This is faster than deleting # name by name and helps us as with an well defined initial # state where we can avoid the scrolling problem. eraseName All # After entering a title, scrolling of the new title would happen. # We can avoid it, using the stop command. But using # stop, we also loose the pause state. # But when we reenter the pause state, the first # track will be activated and its title will be scrolled. # To avoid this problem we enter the title of the first # track at last. for { set i [ expr [ llength $args ] - 1 ] } { $i >= 0 } { incr i -1 } { # i == 0: disc title # otherwise: title of track i if { $i > 0 } { ircmd rm-d29m pause selectTrack $i } setName [ lindex $args $i ] if { $i > 0 } { # stop the scrolling display and leaving pause state ircmd rm-d29m stop } } ircmd rm-d29m stop }