Title: | Take my advice, you'd be better off DEAD |
Notice: | It's just a Box of Rain |
Moderator: | RDVAX::LEVY ::DEBESS |
Created: | Wed Jan 02 1991 |
Last Modified: | Fri Jun 06 1997 |
Last Successful Update: | Fri Jun 06 1997 |
Number of topics: | 580 |
Total number of notes: | 60238 |
Those doggone tape lists are getting out of hand! Keeping track, keeping them up to date - very time consuming. And labeling tapes, jeepers, I'm *months* behind! Seems like the perfect job for a computer! What a brilliant idea! :-) So who's got the code? What software do you use to keep up with your tape list? What about automated tape label programs? What do you use?
T.R | Title | User | Personal Name | Date | Lines |
---|---|---|---|---|---|
72.1 | 11SRUS::MARK | Waltzing with Bears | Tue Jan 15 1991 17:47 | 32 | |
Here's the LaTeX code I used to label my second NYE tape. If you don't have LaTeX on your system, you can find pointers to kits in VAXUUM::TEX. It looks a bit arcane, but the output is nice. Mark --------------------------------------------------------------------------- \documentstyle{article} \begin{document} \begin{tabular}{p{1.625in}p{1.625in}} \multicolumn{2}{c}{\Large New Year's Eve 1990-1991} \\ \multicolumn{2}{c}{Tape 2 - Set II} \\ \multicolumn{2}{c}{\hbox to 3.75in{}} \\ & \\ {\small\raggedright Side A\\ Not Fade Away$\hookleftarrow$\\ Eyes of the World$\hookleftarrow$\\ Dark Star$\hookleftarrow$\\ Jam$\hookleftarrow$\\ Drumz (abbreviated) } & {\small\raggedright Side B\\ Olin Agareed${}^1 \hookleftarrow$\\ Jam$\hookleftarrow$\\ The Other One$\hookleftarrow$\\ Wharf Rat$\hookleftarrow$\\ Not Fade Away } \\ & \\ \multicolumn{2}{l}{All with Branford Marsallis} \\ \multicolumn{2}{l}{${}^1$ with Hamza al Din} \\ \end{tabular} \end{document} | |||||
72.2 | Let's Trade tape list program | LESPE::WHITE | Without love in a dream... | Sun Jan 26 1992 19:47 | 47 |
The advertisement reproduced below (within the limits of an ASCII character cell display :-) came with my last order of tapes from Terrapin Tapes. It is posted here strictly as an FYI - no endorsement, explicit or implicit, is made in this posting. That said... The author had been discussing this on The WELL. It seems interesting. I may even scare up the $40 to check it out, although I have some doubts about the implied "one tape-one show" format. But I may be mistaken. Bob ----------------------------------------------------------------- TIRED OF FILLING OUT ALL OF THOSE CASSETTE LABELS? GET LET'S TRADE! Let's Trade is a computer program that keeps track of your GD tape list for you. It has every show's set list from 1972-1991. It keeps track of useful information about each tape, such as generation, quality, source, time and who you got it from. When you get a new tape all you have to do is add the date to your tape list and Let's Trade will do the rest. It prints cassette or DAT labels, and a complete listing of all your tapes. You can even serach for songs in your tape list and display or print just the tapes with that song. Let's Trade has a built in address book and can print mailing labels. It also has a built in memo pad to help keep track of all your trades. Let's Trade runs on an IBM PC or compatible computer with at least 640K RAM and a hard disk. Send a check or money order for $40 (tax, handling and shipping included) to: Terrapin Tapes P.O. Box 1408 Greenwich, CT 06836 For telephone orders call 1-800-677-8650, Visa and Master Card only Let's Trade Copyright (c) 1991 by Adam Robucci Distributed by Terrapin Tapes | |||||
72.5 | generic postscript label file ... | CUPTAY::BAILEY | A pirate looks at 40. | Tue Jun 23 1992 16:38 | 281 |
For those of you who don't have access to label programs, but do have access to a postscript printer, the template below is for generic tape labels. Just extract the reply, and delete everything above the line of asterisks. All the fields you have to fill in are identified with a double-asterisk (**). So all ya have to do is make a copy of the file for each set of labels you wanna make, do a search for **, and fill in the info it tells ya to. The file is set up to produce three labels, but you can customize it to one or two, as you need to. If ya have any blank fields, delete the "**label" tag in the field (in other words, don't leave anything identified with a ** in the file or it will print that way). I'm sure if ya diddle with it a bit you'll get the idea. ... Bobbb ************************************************************************ %!PS % % Label for **band_name % **venue % **date % /inch {72 mul} def /box { 0.1 inch 0.0 inch rlineto 0.0 inch 0.1 inch rlineto -0.1 inch 0.0 inch rlineto closepath } def /outline { 100 100 translate newpath 0 inch 0 inch moveto 3.94 inch 0 inch lineto 3.94 inch 3.63 inch lineto 0 inch 3.63 inch lineto closepath .9 setgray fill newpath 0 inch 0 inch moveto 3.94 inch 0 inch lineto 3.94 inch 3.63 inch lineto 0 inch 3.63 inch lineto closepath 0 setgray 3 setlinewidth stroke newpath 0 inch 2.97 inch moveto 3.94 inch 2.97 inch lineto stroke newpath 0 inch 2.47 inch moveto 3.94 inch 2.47 inch lineto stroke newpath 1.97 inch 2.47 inch moveto 1.97 inch 0 inch lineto stroke 1 setlinewidth /Times-Bold findfont 10 scalefont setfont newpath 0.13 inch 3.20 inch moveto box stroke 0.26 inch 3.20 inch moveto (Audience) show newpath 1.00 inch 3.20 inch moveto box stroke 1.13 inch 3.20 inch moveto (Board) show newpath 1.75 inch 3.20 inch moveto box stroke 1.88 inch 3.20 inch moveto (FM) show 2.40 inch 3.20 inch moveto (gen) show newpath 0.13 inch 3.05 inch moveto box stroke 0.26 inch 3.05 inch moveto (Dolby B) show newpath 1.00 inch 3.05 inch moveto box stroke 1.13 inch 3.05 inch moveto (Dolby C) show } def outline /Times-Bold findfont 12 scalefont setfont 0.13 inch 3.40 inch moveto (**band_name **date I ) show newpath 1.00 inch 3.20 inch moveto box /Times-Bold findfont 10 scalefont setfont 2.25 inch 3.20 inch moveto (**gen#) show newpath 1.00 inch 3.05 inch moveto box /Times-Bold findfont 10 scalefont setfont 1.75 inch 3.05 inch moveto (**donor&date ) show /Times-Bold findfont 14 scalefont setfont 0.13 inch 2.76 inch moveto (**band_name ) show 3.15 inch 2.76 inch moveto (**date) show 0.13 inch 2.55 inch moveto (**venue ) show 3.775 inch 2.55 inch moveto (I) show /Times-Bold findfont 10 scalefont setfont 0.13 inch 2.24 inch moveto (**song_title) show 0.13 inch 2.04 inch moveto (**song_title) show 0.13 inch 1.84 inch moveto (**song_title) show 0.13 inch 1.64 inch moveto (**song_title) show 0.13 inch 1.44 inch moveto (**song_title) show 0.13 inch 1.24 inch moveto (**song_title) show 0.13 inch 1.04 inch moveto (**song_title) show 0.13 inch 0.84 inch moveto (**song_title) show 0.13 inch 0.64 inch moveto (**song_title) show 0.13 inch 0.44 inch moveto (**song_title) show /Times-Bold findfont 10 scalefont setfont 2.10 inch 2.24 inch moveto (**song_title) show 2.10 inch 2.04 inch moveto (**song_title) show 2.10 inch 1.84 inch moveto (**song_title) show 2.10 inch 1.64 inch moveto (**song_title) show 2.10 inch 1.44 inch moveto (**song_title) show 2.10 inch 1.24 inch moveto (**song_title) show 2.10 inch 1.04 inch moveto (**song_title) show 2.10 inch 0.84 inch moveto (**song_title) show 2.10 inch 0.64 inch moveto (**song_title) show 2.10 inch 0.44 inch moveto (**song_title) show showpage outline /Times-Bold findfont 12 scalefont setfont 0.13 inch 3.40 inch moveto (**band_name **date II ) show newpath 1.00 inch 3.20 inch moveto box /Times-Bold findfont 10 scalefont setfont 2.25 inch 3.20 inch moveto (**gen#) show newpath 1.00 inch 3.05 inch moveto box /Times-Bold findfont 10 scalefont setfont 1.75 inch 3.05 inch moveto (**donor&date ) show /Times-Bold findfont 14 scalefont setfont 0.13 inch 2.76 inch moveto (**band_name ) show 3.15 inch 2.76 inch moveto (**date) show 0.13 inch 2.55 inch moveto (**venue ) show 3.725 inch 2.55 inch moveto (II) show /Times-Bold findfont 10 scalefont setfont 0.13 inch 2.24 inch moveto (**song_title) show 0.13 inch 2.04 inch moveto (**song_title) show 0.13 inch 1.84 inch moveto (**song_title) show 0.13 inch 1.64 inch moveto (**song_title) show 0.13 inch 1.44 inch moveto (**song_title) show 0.13 inch 1.24 inch moveto (**song_title) show 0.13 inch 1.04 inch moveto (**song_title) show 0.13 inch 0.84 inch moveto (**song_title) show 0.13 inch 0.64 inch moveto (**song_title) show 0.13 inch 0.44 inch moveto (**song_title) show /Times-Bold findfont 10 scalefont setfont 2.10 inch 2.24 inch moveto (**song_title) show 2.10 inch 2.04 inch moveto (**song_title) show 2.10 inch 1.84 inch moveto (**song_title) show 2.10 inch 1.64 inch moveto (**song_title) show 2.10 inch 1.44 inch moveto (**song_title) show 2.10 inch 1.24 inch moveto (**song_title) show 2.10 inch 1.04 inch moveto (**song_title) show 2.10 inch 0.84 inch moveto (**song_title) show 2.10 inch 0.64 inch moveto (**song_title) show 2.10 inch 0.44 inch moveto (**song_title) show showpage outline /Times-Bold findfont 12 scalefont setfont 0.13 inch 3.40 inch moveto (**band_name **date III ) show newpath 1.00 inch 3.20 inch moveto box /Times-Bold findfont 10 scalefont setfont 2.25 inch 3.20 inch moveto (**gen#) show newpath 1.00 inch 3.05 inch moveto box /Times-Bold findfont 10 scalefont setfont 1.75 inch 3.05 inch moveto (**donor&date ) show /Times-Bold findfont 14 scalefont setfont 0.13 inch 2.76 inch moveto (**band_name ) show 3.15 inch 2.76 inch moveto (**date) show 0.13 inch 2.55 inch moveto (**venue ) show 3.625 inch 2.55 inch moveto (III) show /Times-Bold findfont 10 scalefont setfont 0.13 inch 2.24 inch moveto (**song_title) show 0.13 inch 2.04 inch moveto (**song_title) show 0.13 inch 1.84 inch moveto (**song_title) show 0.13 inch 1.64 inch moveto (**song_title) show 0.13 inch 1.44 inch moveto (**song_title) show 0.13 inch 1.24 inch moveto (**song_title) show 0.13 inch 1.04 inch moveto (**song_title) show 0.13 inch 0.84 inch moveto (**song_title) show 0.13 inch 0.64 inch moveto (**song_title) show 0.13 inch 0.44 inch moveto (**song_title) show /Times-Bold findfont 10 scalefont setfont 2.10 inch 2.24 inch moveto (**song_title) show 2.10 inch 2.04 inch moveto (**song_title) show 2.10 inch 1.84 inch moveto (**song_title) show 2.10 inch 1.64 inch moveto (**song_title) show 2.10 inch 1.44 inch moveto (**song_title) show 2.10 inch 1.24 inch moveto (**song_title) show 2.10 inch 1.04 inch moveto (**song_title) show 2.10 inch 0.84 inch moveto (**song_title) show 2.10 inch 0.64 inch moveto (**song_title) show 2.10 inch 0.44 inch moveto (**song_title) show showpage | |||||
72.6 | hey...i've seen that code before! ;-) | DEDHED::Spine | Tom Spine | Tue Jun 23 1992 18:00 | 9 |
Ha! That PostScript code sure looks an aweful lot like the code that my tape label program produces. Glad ya like the design, Bobbb! Credit where credit is due department -- the PostScript code and the tape label design posted by Bobbb was written by me back in '86 or '87 or so. My inspriation for doing so can be traced to Mystery Hill's code and design. tms | |||||
72.7 | DOS label program | SSGV02::STROBEL | In this style 10/6 | Tue Jun 23 1992 18:03 | 4 |
I seem to recall in Grateful_Old someone have a DOS based program for labels. Is that available somewhere? Jeff_who_should_read_notes_more_often_so_that_he_doesn't_miss_northern_lunches | |||||
72.8 | what goes around, keeps going around ... ;^) | CUPTAY::BAILEY | A pirate looks at 40. | Wed Jun 24 1992 09:26 | 6 |
Hey now tms ... thanks for the code! I got it from Probz as a label for some Radiators tapes about a year ago. Been meaning to put it in here for a while now. Hope somebody finds it useful ... ... Bobbb | |||||
72.9 | NRSTA2::CLARK | Hour of Slack | Fri Feb 19 1993 11:04 | 85 | |
re <<< Note 72.7 by SSGV02::STROBEL "In this style 10/6" >>> > -< DOS label program >- > >I seem to recall in Grateful_Old someone have a DOS based program for labels. >Is that available somewhere? Here's one I just got from a guy in rec.music.gdead ... check out NRSTA2::USER03:[CLARK.PUBLIC]CASLINR3.ZIP Here's the readme file that came with it: CaseLinr Version 3.0 Ed Adasiewicz 764 Old Westbury Rd. Crystal Lake, IL 60012 CompuServe ID 71101,2744 CaseLinr is a Windows program which prints case liners (a.k.a. J-Cards) for audio cassettes. The image displayed on the CRT screen approximates what will actually be printed. The printed result is extremely accurate and can be cut, folded, and then inserted into an empty (preferably clear plastic) audio cassette box. To install CaseLinr, copy the files CASELINR.EXE and CASELINR.HLP to any directory and then use the New Program Item in the Files menu of the Program Manager to install CaseLinr within any group. For help about CaseLinr, read the online help available under the help menu. CaseLinr Version 3.0 is Shareware. It is NOT FREE SOFTWARE, but it is also NOT Crippleware. It is fully functional and does not contain any randomly appearing oversized dialog boxes with insulting messages, charge card graphics, and floating buttons. If you like CaseLinr and find it useful, you are requested to support it by sending me at least $10.00. Your donation will result in you receiving a warm feeling inside knowing that you are not abusing the shareware concept. Besides money, I also get a warm feeling knowing that someone appreciates my work. All suggestions, comments, criticisms, and modification requests are welcome -- those accompanied with donations will be acknowledged. This program is being made available on an "as is" basis, and carries no warranties, express or implied. The author shall in no way be held liable for any damages resulting from the use of this program or the media on which it is distributed, including, without limitation, loss of business profits, interruption of business, loss of information, damage to equipment, or any other incidental or consequential damages. Revision History: ---------------- 1.0 - Initial release (fixed various bugs in CLFREE). 1.1 - Added the Invert menu option. 1.2 - Added Bisect Side checkbox to global layouts. Changed the Invert menu option to Invert Image checkbox in global layouts so that it could be saved/reset and written to a cassette file. 2.0 - Insured that the program functioned correctly under Windows 3.0. The Ctrl-Enter key combination must now be used, instead of the Enter key, for entering multiple lines in Titles and Songs. Added an alternate icon. Added system menus to all of the dialog boxes. Default extensions (*.CAS) are now properly displayed in the Open... dialog box. OK in the global layout box only causes scrolling up or down if inversion was actually selected or deselected. 2.1 - Centered the liner, both horizintally and vertically, within the page specified in Control Panel prior to printing. Shrunk size of about box. J-card icon now blends in with background color. 3.0 - Started using private profile file (caselinr.ini) rather than win.ini. Provided automatic conversion from win.ini to caselinr.ini. Added online help. Modified file format slightly. Added Print Setup and Reset All Fonts. Added directory list boxes to Open and Save. Added top and left margins for printing. Split font handling into two dialog boxes and added more options. Added margins and indents for songs. Added title alignment, margins, and splitting. Modified features so that both the name and value are user settable. Changed a lotta radio buttons to combo boxes. | |||||
72.10 | ZENDIA::FERGUSON | I had one of those flashes | Fri Feb 19 1993 12:21 | 2 | |
Jeff, I wrote a program that does tape labels too. Runs on VMS. If anyone wants the executable + direx, send me mail. | |||||
72.11 | SSGV02::GPEACE::Strobel | expecting something witty? | Fri Feb 19 1993 13:25 | 7 | |
Thanks for the pointers and offers JC & DC. Actually, I've started playing around with Microsoft Access to see what type of label maker/db I can come up with. It's 90% there but until the developer's kit comes out to make runtime applications or unless you have an Access license (still under $100) it won't be much use to you. jeff | |||||
72.12 | DAT label program, VMS weeney can't deal with UNIX | CORA::65447::BELKIN | the slow one now will later be fast | Fri Apr 16 1993 15:12 | 92 |
I've just read the replies in this note. Does anyone have a tape label program for DAT tapes? I do not have a PC at home or in the office, so VMS (is VMS is VMS is forever) please only! I've extracted the generic cassette tape label.ps from a few replies back, but I don't know enough Postscript-ese to diddle with it. Also, I've tried looking with the decwrl::ftpmail thing in berkeley.dead.edu (?) for tape label programs, but I don't know anything about UNIX to know even how to interpret the mail I got back. I tried to 1) get a directory of tape label programs, I don't think it went to the right place 2) get a directory of the readme file ?? 3) copy the readme file, which didn't work (no such file or directory?). Maybe this string should be continued in the usenet note. thanks, Josh From: US1RMC::"[email protected]" To: wedoit::belkin Subj: part 001 of ls (@nemesis.berkeley.edu) [tape-labels] (ascii, last) total 5 d--------- 5 0 daemon 512 Mar 12 07:01 ...old -rwxr-xr-x 1 0 daemon 36 Feb 16 13:41 .cache d--x--x--x 2 0 wheel 512 Feb 17 09:43 bin d--x--x--x 2 0 wheel 512 Jun 12 1989 etc dr-xr-xr-x 4 ftp wheel 512 Feb 16 13:41 pub % ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ====== [headers deleted] % Reply-To: <[email protected]> From: US1RMC::"[email protected]" To: wedoit::belkin Subj: part 001 of ls (@gdead.berkeley.edu) [readme] (ascii, last) total 5 d--------- 5 0 daemon 512 Mar 12 07:01 ...old -rwxr-xr-x 1 0 daemon 36 Feb 16 13:41 .cache d--x--x--x 2 0 wheel 512 Feb 17 09:43 bin d--x--x--x 2 0 wheel 512 Jun 12 1989 etc dr-xr-xr-x 4 ftp wheel 512 Feb 16 13:41 pub % ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ====== [headers deleted] % Reply-To: <[email protected]> From: US1RMC::"[email protected]" to: wedoit::belkin Subj: results of ftpmail request 734724649.14200 [readme] Orig message-id: <[email protected]> Orig subject: readme Orig from: Josh Belkin 13-Apr-1993 1409 <"wedoit::belkin"@cora.ENET.dec.com> Orig date: Tue, 13 Apr 93 11:10:39 PDT --- connecting to gdead.berkeley.edu... Connecting to gdead.berkeley.edu 220 gdead FTP server ready. Complaints and questions should be sent to <[email protected]>. --- logging in as user=anonymous password=-ftpmail/wedoit::belkin account=... ---> USER anonymous 331 Guest login ok, send e-mail address as password. Begin your password entry with a - (dash) to suppress the helpful messages. ---> PASS <somestring> 230 Guest login ok, access restrictions apply. ---> TYPE A 200 Type set to A. ---> PORT 16,1,240,16,11,144 200 PORT command successful. ---> LIST 150 Opening ASCII mode data connection for /bin/ls. ls (@gdead.berkeley.edu) (1 part(s), 304 bytes) sent to wedoit::belkin 226 Transfer complete. === getting 'readme'... ---> PORT 16,1,240,16,11,146 200 PORT command successful. ---> RETR readme 550 readme: No such file or directory. Failure on RETR command !!! cannot initiate RETR ---> (end of ftpmail session) % ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ====== [headers deleted] % Reply-To: <[email protected]> | |||||
72.13 | CSCMA::M_PECKAR | Be kind: unwind | Fri Apr 16 1993 15:22 | 4 | |
Josh, I've been meaning to poke around that site for a while now. I'll try to find something for ya next time I ftp over there. MAy be a while, though... | |||||
72.14 | CORA::65447::BELKIN | the slow one now will later be fast | Fri Apr 16 1993 17:17 | 3 | |
Thanks, when I sent off the ftpmail it was 3 days before I got mail back. Josh | |||||
72.15 | SUBPAC::MAGGARD | Have YOU changed your logo lately??? | Wed Apr 21 1993 17:17 | 2583 | |
I got this from DAT-Heads ... but then you and the rest of the world probably did too... ;-) FWIW, it apparently puts a stealie in the background... directions are included. - jeff -------------- From: CRL::"[email protected]" "Digestifier" 17-APR-1993 01:04:18.90 To: [email protected] CC: Subj: DAT-Heads Digest #493 DAT-Heads Digest #493, Volume #1 Fri, 16 Apr 93 20:30:03 EDT Contents: PostScript label program (Bob Ramstad) ---------------------------------------------------------------------------- From: Bob Ramstad <[email protected]> Subject: PostScript label program Reply-To: boccibob%[email protected] Date: Fri, 16 Apr 93 16:46:31 PDT Here is a great little PostScript label program. Anyone want to put this at an FTP site? With a pointer in the FAQ? It's got two modifications I think are important from the source that Jamie puts out. 1) text on inside flap 2) nice SYF, corrected by Duane Day from the original inverted and wrong left/right for all those Dead labels. Enjoy! Bob %!PSAdobe-1 %%Creator: Jamie Zawinski <[email protected]> %%Title: audio-tape.ps %%CreationDate: 1-jun-91 %% %% PostScript code to generate tape labels, version 1.19. %% For audio-cassette, DAT, or 8mm video-cassette labels. %% Copyright (c) 1991 Jamie Zawinski <[email protected]>. %% %% Permission granted for non-commercial use and distribution %% so long as this notice of copyright remains intact. %% %% This version specially modified by [email protected] to allow %% printing of additional information on the inside flap. %% %% All five label formats, as well as all three tape sizes, support %% an optional last array. If you specify this array, you have to preceed %% the array with: %% %% /additional-information %% %% The text always appears across the song listings and is oriented %% horizontally. To orient the additional information the same as the %% songs, set /additional-information-follows-songs to true. %% %% The font name and size are: %% %% /additional-information-font %% /additional-information-font-height %% %% and their default values are: %% %% Helvetica %% 8 points %% %% The additional information font is scaled to fit the flap if the %% information is too large. %% %%EndComments %%BeginDocumentation %% %% There are a few examples at the end of this file; print this for a %% representative selection of what this code can do. Search for the %% string "example" to see how to do it. %% %% If you are using this code, send me mail, and I will send you updates %% as I improve it. %% And remember: PostScript programs don't senslessly destroy trees. %% People senslessly destroy trees. Print your labels on the backs of %% used sheets of paper, and preview your labels with an on-screen PS %% previewer such as GhostScript. %% ========================================================================= %% HOW TO USE THIS %% ========================================================================= %% %% To print a tape label, you construct a call to one of several PostScript %% procedures defined in this file. The calling syntax is fairly simple, %% and you don't need to know PostScript to do it. Just fill in the blanks. %% %% For a tape label with one album on each side, both albums by the same band, %% do this: %% %% (Band Name) (Album 1 Name) (Album 1 Date) %% (Album 2 Name) (Album 2 Date) %% [ <...album 1 songs....> ] [ <...album 2 songs....> ] %% two-albums %% %% For a tape label with one album on each side, both albums by different %% bands, do this: %% %% (Band 1 Name) (Album 1 Name) (Album 1 Date) %% [ <...album 1 songs....> ] %% (Band 2 Name) (Album 2 Name) (Album 2 Date) %% [ <...album 2 songs....> ] %% two-bands %% %% For a tape label with one double album consuming both sides, do this: %% %% (Band Name) (Album Name) (Album Date) %% [ <...songs, side 1....> ] %% [ <...songs, side 2....> ] %% double-album %% %% For a tape label with three or four albums/EPs by the same band, do this: %% %% (Band Name) (Album 1.1 Name) (Album 1.2 Name) (Album 1.* Date) %% (Album 2.1 Name) (Album 2.2 Name) (Album 2.* Date) %% [ <...songs, side 1....> ] %% [ <...songs, side 2....> ] %% N-albums %% %% (Either of the strings (Album 1.2 Name) or (Album 1.2 Name) may be %% an empty string; things will be positioned appropriately.) %% %% For a tape label with three or four albums/EPs by two different bands, %% do this: %% %% (Band 1 Name) (Album 1.1 Name) (Album 1.2 Name) (Album 1.* Date) %% [ <...songs, side 1...> ] %% (Band 2 Name) (Album 2.1 Name) (Album 2.2 Name) (Album 2.* Date) %% [ <...songs, side 2...> ] %% two-bands-N-albums %% %% %% In the above examples, [ <songs> ] should really be of the form %% %% [ (song 1) ... (song N) ] that is, an array of strings; or it %% may also be of the form %% %% [[ (song 1) (song 1 time) ] that is, an array of arrays, where %% [ (song 2) (song 2 time) ] each sub-array holds exactly two %% ... strings. The first string is the name %% [ (song N) (song N time) ]] of a song, and the second string is %% the start-time, length, counter, or %% whatever of the song. The song name is printed flushleft, and the song %% time is printed flushright. %% %% An entry in the song array may also be of the form %% [ (song N) (song N time) ...font... ] %% where ...font... is one of /B, /I, /BI, or /Title. This is explained a %% little later. %% ========================================================================= %% WHAT YOU WILL GET %% ========================================================================= %% %% The labels are printed two-per-page. You do not need to insert "showpage"s %% in this file; that happens automagically. %% %% The band-names and album-names are printed on the spine of the label. %% For the one-band-on-both-sides cases, the band-name is printed tall enough %% to fill the label. For the two-band cases, the band names are printed one %% atop the other. Album names are scaled so that all album names fit on %% one atop the other on the spine. %% %% In all cases (spine, song lists, etc) it is not possible for a string to %% be "too long" - font-widths are scaled so that the strings fit in the %% available space (taking into account adjascent strings of the same height; %% strings stacked above/next to each other are scaled as a unit. You'll %% see what I mean.) %% %% Songs are printed in one or two columns on the back of the tape label, or %% on the inside of the tape label (user-configurable). The name of the album %% is printed above the song lists. When there are more than two albums on a %% tape, the names of all three or four albums are printed on the spine, and %% the names of albums 1.1 and 2.1 are printed above the song listings on the %% inside. %% %% Labels for DATs and 8mm tapes look the same, except that they are smaller %% (of course...) %% %% It is possible to specify the font of individual lines in the song listings %% by placing a font-keyword in the third position of an element of the %% song-list array. Valid face-specifiers are /B (bold), /I (italic), /BI %% (bold italic), and /Title. If the font is unspecified, /B, /I, or /BI, %% then the font used for the song name is determined by one of the variables %% /song-font, /song-font-bold, /song-font-italic, or /song-font-bold-italic. %% The font will always be scaled to be /song-font-height points tall. %% %% If, however, the font is specified as /Title, then the font used will be %% the value of /title-font, and it will be /title-font-height tall; it will %% also be underlined. The intent here is that specifying the font as /Title %% makes an entry in the song listings look just like the album titles above %% the listings. That way, if you have more than one album on the same side %% of a tape, you can display a title for both of them, which was not possible %% in versions prior to 1.5. (Extra hack: [(song) /Title] is considered to %% be the same as [(song) () /Title], since the time is ignored for titles.) %% %% It is possible to include arbitrary graphics in place of the band-name %% on the spine, to duplicate the way a band normally renders its name, or %% whatever. It is also (as of v1.4) possible to include an arbitrary %% graphic on the inside flap, or printed (lightly) under the song listings. %% See below. %% %% If you want a Dolby logo printed, simply include a line containing only the %% word "DolbyB" or "DolbyC" (no quotes) before the band name(s). You must do %% this before each tape to get this logo; it is reset after printing each %% label. "dbx", "AAD", "ADD", and "DDD" print the appropriate logo as well. %% These logos go in the corner of the short back flap (where the signature %% string goes) because I couldn't think of a better place. Feel free to %% suggest one. %% %% ========================================================================= %% HOW TO USE THIS UNDER UNIX %% ========================================================================= %% %% Of course, it's possible to just edit this file and print it each time you %% want to print a label, but that's kind of a pain. And you don't want a %% copy of this file sitting around for every tape label you print, it's too %% big. This is the solution that I use: %% %% When you edit a new tape label, put it in its own file. Include in that %% file only what the "How to Use This" section had you type in. %% %% Add the following to your .cshrc file: %% %% alias tape_prolog awk '/^%.PS/,/^%%BeginDoc//^%%EndDoc/,/^%%EndPro/' %% alias tape_trailer awk '/^%%Trailer/,/^--eof--\$/' %% setenv TAPEPS ~/ps/audio-tape.ps %% alias catapes '(tape_prolog $TAPEPS;cat \!*; tape_trailer $TAPEPS)' %% alias printapes '(catapes \!*) | lpr' %% %% 'tape_prolog' and 'tape_trailer' are 'awk' programs that will extract %% the important part of this file. TAPEPS is a variable that points at %% the place your copy of the file is. 'catapes' takes one or more files %% as arguments, and splices their contents in with the PostScript code at %% the appropriate place. %% %% With the above aliases, the command "printapes tape1 tape2 tape3" will %% concatentate the PostScript code defined in this file, the definitions %% of your labels (which presumably are the contents of the files "tape1," %% "tape2," and "tape3"), and the necessary trailer together, and hand that %% as input to "lpr" (or whatever command it is that you use for printing). %% %% I also have some Common Lisp code which maintains a database of tapes, and %% can generate this PostScript code directly. It uses a simple textual file %% format for storing the song listings; if you want it, send me mail. If %% you use TI Explorer Lisp Machines, I have a totally whizzy menu-driven %% interface to editing, searching, and printing these labels. Again, just ask. %% ========================================================================= %% SIMPLE CUSTOMIZATION %% ========================================================================= %% %% To print labels for Digital Audio Tapes instead of normal cassette tapes, %% insert a line consisting of %% DAT-sizes %% in the file before the labels. To switch back to cassette sizes, include %% a line that says "cassette-sizes" instead of "DAT-sizes" (the default is %% to produce labels for normal cassettes.) %% %% To print labels for 8mm video cassettes, include a line that says %% (predictably enough) "8mm-sizes". %% %% To change the fonts of various things, change the values of the variables %% /song-font, /band-font, /album-font, /inner-album-font, or /date-font. %% It is not possible to change the height or aspect ratio of the fonts, as %% those are computed at runtime. %% %% If you prefer the labels to be printed in such a way that the song listings %% will appear on the inside of the tape box instead of the outside, set the %% variable /songs-go-inside to true. It defaults to false. %% %% If you prefer the labels to be printed so that a band's graphic goes on the %% inside of the tape box instead of the outside, set /icons-go-inside to %% true. It defaults to false. %% %% If you prefer to have the spine of the label wrong-side-up, set /flip-spine %% to true. It defaults to false. If you prefer to have the song listings %% wrong-side-up, set /flip-songs to true. It defaults to false. %% %% If you want the columns to follow the long edge of the tape rather than %% the short edge, set /columns-horizontally to true. You can change the %% orientation with /flip-songs. %% %% If you want the song-listings to be printed in one column instead of two, %% then set /one-column to true. The side1 songs and side2 songs will be %% appended together and printed in one column down the middle. This is %% most useful in conjunction with /columns-horizontally. %% %% If /songs-go-inside and /icons-go-inside have the same value (both inside %% or both outside) then the songs will be printed overlaying the icon. The %% icon will be printed at 20% intensity so that you can still read the songs %% on top of dark areas. This is customizable by changing the variable %% /icon-fade-factor. %% %% One problem I encountered with this code was that my co-worker's tapes all %% looked just like mine... I got around this by adding the parameter %% /signature - set this to a string of your name or something, and it will %% be printed on the back-spine of all of your labels. It can be multiple %% lines by specifying it as [ (line 1) (line 2) ... ] instead of as a string. %% (Embedding newlines in a string will not do what you want.) %% ========================================================================= %% SOPHISTICATED CUSTOMIZATION %% ========================================================================= %% %% Defining a new magic-name-printer is pretty simple. Just define a %% procedure for drawing the name, and index it in "magic-name-dict" under %% the string which is the band's name. There are some fairly sophisticated %% examples of this in this file. If you define any more, send them to me %% and I'll include them in the next distribution (whether I like the band %% or not :-)). %% %% Adding an icon-printer is similar - you use "magic-icon-dict" instead of %% "magic-name-dict". For magic-names, define the procedures to draw in %% a device-scale (1 unit = 1 point) space with origin at the upper left. %% For icons, define the procedure to be in a one-unit tall space - 1 unit %% will correspond to the entire height of the flap on which the icon is %% drawn. For icons, the origin is at the XY center instead of the upper %% left. This is all kind of arbitrary, but it doesn't matter too much, %% because the beauty of PostScript is that you can scale/translate within %% your procedure to work in the space that is most convenient to you. %% %% When you add something to magic-name-dict or magic-icon-dict, be sure to %% use "CIput" instead of "put" to insure case-insensitivity. %% %% If you associate an icon printer with the name (default-icon-printer), then %% this will be used for bands which do not have their own icons defined. %% %% When /songs-go-inside and /icons-go-inside have the same value, meaning %% that the songs will be printed overlaying the icon, we cause the icon to %% be printed at quarter-intensity by changing the transfer function. If %% your icon is written in such a way that this is not desirable, it's %% possible to defeat it within a given icon printer by doing something %% like "{} settransfer" within the scope of a "gsave". %% %% Note that magic-name and magic-icon printers are not used unless the label %% being printed is a double album, or the albums on both sides are by the %% same band. %% ========================================================================= %% WISHLIST %% ========================================================================= %% %% o Maybe the magic-name printers should be invoked even if both sides of %% the tape are not by the same band. %% %% o The magic-icon-printers should be used even if there are two different %% bands on one tape - print two of them side by side if necessary. %% %% o Maybe there should be a way to print arbitrary text on the inside flap, %% aside from defining a magic-icon printer. %% %% o A general font-change mechanism would be nice, for font changes in the %% signature as well as in the song listings. %% %% o Should have /3-bands-N-albums and /4-bands-N-albums commands. %% ========================================================================= %% WHAT THE CURRENTLY DEFINED MAGIC-NAME-PRINTERS DO %% ========================================================================= %% %% o Siouxsie and the Banshees is printed in an alternating sized, alternating %% cased font, with the "and" over the "the" like on many early albums. %% o Cabaret Voltaire is printed in a font that looks like the one on the %% cover of "Micro-Phonies." %% o New Order is printed with a black "New" overlapping a hollow "Order" as %% on "Low Life" etc. %% o OMD is printed on two lines, one font thicker than the other. The OE is %% printed with an OE character. %% o Front 242 is printed similarly. %% o Love and Rockets has an icon - a heart on a rocket in a circle. %% o Bauhaus has an icon - the Beggars' Banquet "face-in-circle" logo. %% o Nitzer Ebb has three icons: %% o If the album name is "That Total Age", the gear/star/hammer logo is %% printed. %% o If the album name is "Belief", a low-resolution bitmap of the angry %% looking eye from the cover of that album is printed. This is a fair %% example of how to incorperate such bitmaps, and it doesn't take up %% that much space, either. %% o Otherwise, the star-over-gear icon from the Warsaw Ghetto EP is used. %% o Nine Inch Nails has an icon - "NIN" in a box with the first N backwards. %% o Kate Bush has an icon. %% o Depeche Mode has a "some great reward"-like icon. %% %% Please send me more! %% ========================================================================= %% CHANGELOG %% ========================================================================= %% some time in 1988... created by Jamie Zawinski. %% some time in 1990... posted v1.1 to comp.lang.postscript %% 30 may 90 Jamie Zawinski %% fixed a bug which made it impossible to have the band-name and %% album-name in different fonts for double-albums. %% 27 jul 90 Jamie Zawinski %% fixed the above fix. %% 28 jul 90 Jamie Zawinski %% Modified the magic-name printers to work around a bug in version 1.1 %% of Adrian Aylward's Amiga postscript interpreter (post). In that %% implementation, 'get' doesn't work on dictionaries whose keys are %% string instead of names; so I added some calls to 'cvn' before %% storing into 'magic-name-dict'. %% 6 aug 90 Jamie Zawinski %% Implemented magic-icons for arbitrary graphics on the back. %% Improved auto-scaling a great deal. %% 9 aug 90 Jamie Zawinski %% Made songs able to be strings as well as [()()], and made the signature %% able to be multiple lines. Made sig able to be in a different font %% than the song listings. Made magic-name and magic-icon lookups happen %% case-insensitively. %% 17 oct 90 Jamie Zawinski %% Made it possible to change the fonts of individual song listings, and %% have album-titles embedded in the middle of the song listings. Fixed %% the auto-scaling of v1.5 to produce the exact same output as v1.4 %% except where v1.5 does better. %% 22 oct 90 Jamie Zawinski %% Made the fonts for /Title-type song listings be autscaled along with %% the titles at the top of the listing instead of with the songs %% themselves. (That is, long inline titles don't squash the song names, %% but they do squash the album names.) Also, /song-time-font was not %% being used. %% 15 dec 90 Jamie Zawinski %% Added support for Digital Audio Tapes. %% 20 dec 90 Jamie Zawinski %% Made dates auto-scale (for when they are used as footnotes). Fixed a %% bug that made auto-scaling not work for inner-album-titles. Tweaked %% sizes of DATs; made DATs fit 3-per-page. Added default-icon-printer. %% Added /flip-songs. Added /one-column and /columns-horizontally. Made %% the song-lists autoscale heightwise, for when there are too many songs. %% This doesn't completely work, and made the code much uglier... %% 16 jan 90 Jamie Zawinski %% Fixed a translation bug with songs inside and sideways columns. Took %% out the code that scales the height of the song font since it didn't %% really work. Adjusted the vertical placement of strings on the spine %% when there is only one string (as in double-albums). %% 22 feb 91 Jamie Zawinski %% Tested and fixed all permutations of the orientation variables. %% Made the song-lists autoscale heightwise, for when there are too many %% songs. And it works this time. %% 25 feb 91 Jamie Zawinski %% Spliced in Michael Brown's dolby-logo code -- thanks Michael. %% Fixed spurious comma when one-column and no dates. %% 27 feb 91 Jamie Zawinski %% Made icon orientations track song list orientations. Added logos for %% DDD, AAD, dbx, etc. %% 6 mar 91 Jamie Zawinski %% posted to comp.lang.postscript %% 14 mar 91 Jamie Zawinski %% Added code to print 8mm video cassette labels, from Allen Wade. %% 3 apr 91 Jamie Zawinski %% Put it in its own dictionary instead of userdict. %% 11 jun 91 Jamie Zawinski (who else?) %% Fixed a bug which caused inner-title width computations to have state %% beyond the current label (very bad...) %% ========================================================================= %% Questions? Comments? Suggestions? Improvements? Send them to me, %% [email protected]. "Please, no applause, just throw money." %% %%EndDocumentation /TapeDict 500 dict def TapeDict begin /bdef { bind readonly def } bind readonly def /box { 4 2 roll newpath moveto exch dup 0 rlineto exch 0 exch neg rlineto neg 0 rlineto closepath } bdef /rightshow {dup stringwidth pop neg 0 rmoveto show } bdef /centershow {dup stringwidth pop 2 div neg 0 rmoveto show } bdef /max { dup 3 -1 roll dup 3 -1 roll gt { exch pop } { pop } ifelse } bdef /max-stringwidth { stringwidth pop exch stringwidth pop max } bdef %% Default font-names and sizes. The widths (and sometimes heights) are %% stomped at runtime, but the names are the responsibility of the user. %% /song-font /Helvetica def /song-font-bold /Helvetica-Bold def /song-font-italic /Helvetica-Oblique def /song-font-bold-italic /Helvetica-BoldOblique def /song-time-font song-font def /song-font-height 8 def /signature-font /Helvetica def /signature-font-height 8 def /band-font /Helvetica def /band-font-height 13 def /album-font /Helvetica def /album-font-height 13 def /inner-album-font /Helvetica-Bold def /inner-album-font-height 13 def /date-font /Helvetica-Bold def /date-font-height 8 def /additional-information-font /Helvetica def /additional-information-font-height 8 def % if true, songs go inside the tape label, else outside. /songs-go-inside false def % if true, icons go inside the tape label, else outside. /icons-go-inside false def % If true, the spine will be printed with a nasty orientation. /flip-spine false def % If true, the song-listings will be printed other-side-up. /flip-songs false def % If true, the song-listings will be in one column instead of two. /one-column false def % If true, the song-listings will be horizontal instead of vertical. /columns-horizontally false def % if an icon and the song listings are being printed on the same flap, the % icon will be faded by this amount (so that the songs will be readable). % /icon-fade-factor 0.20 def /cassette-sizes { /margins 4 def /back-spine-height 40 def /spine-height 32 def /list-height 185 def /total-height margins back-spine-height add margins spine-height add add margins list-height add 2 mul add margins add def /inner-width 280 def /total-width inner-width margins dup add add def % if there are DATs or 8mms on the page already, force a page-break. DATp 8mmp or tick 0 ne and { showpage /tick 0 def } if /DATp false def /8mmp false def } bdef /DAT-sizes { % Length: 3 1/6 inches - 228.95 % Width: 2 7/8 in - 209.86 % Folds: % 7/16 in from bottom - 31.63 % 15/16 in from the bottom - 67.78 /margins 3 def /back-spine-height 27 def /spine-height 33 def /list-height 156 2 sub def /total-height margins back-spine-height add margins spine-height add add margins list-height add 2 mul add margins add def /inner-width 202 4 sub def /total-width inner-width margins dup add add def % if there are normal cassette tapes on the page already, force a page-break. DATp not tick 0 ne and { showpage /tick 0 def } if /DATp true def /8mmp false def } bdef /8mm-sizes { % by Allen Wade, 13 mar 91 % Length: 3 5/8 inches - 250 % Width: 3 11/16 inches - 279.86 % Folds: % 1/2 in from bottom - 32.63 % 1 1/8 in from the bottom - 77.78 /margins 4 def /back-spine-height 34 def /spine-height 40 def /list-height 175 def /total-height margins back-spine-height add margins spine-height add add margins list-height add 2 mul add margins add def /inner-width 260 def /total-width inner-width margins dup add add def % if there are normal cassette tapes on the page already, force a page-break. 8mmp not tick 0 ne and { showpage /tick 0 def } if /8mmp true def /DATp false def } bdef /tick 0 def % How many tapes have been dumped on this page. /DATp false def % don't change this. /8mmp false def % don't change this. /really-big false def % don't change this. cassette-sizes /extract-song-and-time-and-font-1 { dup type /stringtype eq { () /R } { dup length dup 0 eq { pop pop () () /R } { dup 1 eq { 0 get () /R } { 2 eq { dup 0 get exch 1 get /R } { dup 0 get exch dup 1 get exch 2 get } ifelse } ifelse } ifelse } ifelse % if the time is /Title or /title, set the font to % be the same. exch dup dup /Title eq exch /title eq or { pop pop /Title dup } if exch } bdef /extract-song-and-time-and-font { % takes a song spec and leaves three things % on the stack - (song) (time) <font>. extract-song-and-time-and-font-1 decode-song-font-name } bdef /song-fonts-w-scale 1 def /song-fonts-h-scale 1 def /song-fonts-title-w-scale 1 def /decode-song-font-name { % takes a name, one of /R, /B, /I, /BI, or /Title % and converts that to a font scaled appropriately. % Leaves the font on the stack. song-font-height exch % put the height on the stack under the name. /titlep false def % set the Hack flag... % convert the name to a font-name. dup /B eq { pop song-font-bold } { dup /I eq { pop song-font-italic } { dup /BI eq { pop song-font-bold-italic } { dup /Title eq exch /title eq or % if the code was /Title or /title, take the default height off the % stack and put the title-font-height there instead. { pop inner-album-font-height inner-album-font /titlep true def % hack hack... } { song-font } ifelse } ifelse } ifelse } ifelse % set FH to the font height, leaving the font-name. exch /FH exch def % then find and scale the font, leaving it on the stack. findfont [ FH titlep {song-fonts-title-w-scale} {song-fonts-w-scale} ifelse mul 0 0 titlep { FH } { FH song-fonts-h-scale mul } ifelse 0 0 ] makefont } bdef /compute-max-colheight { songs1 compute-max-colheight-1 songs1 compute-max-colheight-1 max } bdef /compute-max-colheight-1 { /total 0 def { extract-song-and-time-and-font-1 exch pop exch pop /Title eq { /total total inner-album-font-height add 5 add def } { /total total song-font-height add 2 add def } ifelse } forall total } bdef % songs1 length songs2 length max % song-font-height song-fonts-h-scale mul 2 add mul /print-one-column { % write one column of the song listings /songs exch def /h exch def /w exch def /y exch def /x exch def gsave /w w 10 sub def /x x 5 add def one-column double-album-p not and not { /y y inner-album-font-height sub def } if x y translate % -5 0 w h box clip newpath % -5 0 w h box stroke %debug /x 0 def /x2 x w add 5 sub def /y song-font-height neg def /maxh compute-max-colheight def maxh h y sub gt { 1 h y sub maxh div scale } if songs { extract-song-and-time-and-font setfont dup /Title eq { /y y inner-album-font-height song-font-height sub sub def pop x 5 sub y moveto show 0 -2 rmoveto x 5 sub y 2 sub lineto stroke % underline it /y y inner-album-font-height song-font-height sub 2 sub sub def % frob y. } { exch x y moveto show dup () ne { song-time-font findfont [ song-fonts-w-scale song-font-height mul 0 0 song-fonts-h-scale song-font-height mul 0 0 ] makefont setfont x2 y moveto rightshow } { pop } ifelse } ifelse /y y song-font-height song-fonts-h-scale mul sub 1 sub def } forall grestore } bdef /print-songs { % write a column of the song listings; 0=right. /left exch def gsave /x one-column { inner-width 20 sub max-songwidth sub 2 div 5 add } { 10 } ifelse def /y back-spine-height spine-height add margins 3 mul add neg def /w one-column { max-songwidth 20 add } { inner-width 2 div } ifelse def /h list-height one-column double-album-p not and not { inner-album-font-height sub } if () date1 eq () date2 eq and not { date-font-height sub } if margins 2 mul sub def songs-go-inside { flip-songs { /y y list-height margins add add def } { /y y list-height margins add sub def } ifelse } if 1 left eq { /songs songs1 def } { /x x w add def /songs songs2 def } ifelse x y w h songs print-one-column grestore } bdef /draw-icon { gsave total-width 2 div icons-go-inside { total-height list-height 2 div margins add sub neg } { total-height list-height 1.5 mul margins dup add add sub neg } ifelse translate list-height dup scale columns-horizontally { -90 rotate } if flip-songs { 180 rotate } if icons-go-inside songs-go-inside and icons-go-inside not songs-go-inside not and or { { 1 exch sub icon-fade-factor mul 1 exch sub } settransfer 0 setgray } % ..to work around bug in GhostScript 2.0's settransfer. if magic-icon grestore } bdef /set-songfont { % compute width-scale of fonts for song listings. /tfont song-time-font findfont song-font-height scalefont def /maxw 0 def /song-fonts-w-scale 1 def % set to 1 for width computation. songs1 { extract-song-and-time-and-font setfont dup /Title eq { pop pop () 0 } { stringwidth pop } %% oops, this isn't taking into account ifelse %% the /song-time-font. exch stringwidth pop add maxw max /maxw exch def } forall songs2 { extract-song-and-time-and-font setfont dup /Title eq { pop pop () 0 } { stringwidth pop } ifelse exch stringwidth pop add maxw max /maxw exch def } forall /w one-column { inner-width 20 sub } { inner-width 2 div 5 sub } ifelse def /max-songwidth maxw 20 add def max-songwidth w gt { /song-fonts-w-scale w max-songwidth div def /max-songwidth w def } if one-column double-album-p not and { /Imaxw inline-album-titles-max-stringwidth def /song-fonts-title-w-scale Imaxw max-songwidth gt { max-songwidth Imaxw div } { 1 } ifelse def } if } bdef /inline-album-titles-max-stringwidth { /Imaxw 0 def /Imaxh 0 def /ofsws song-fonts-w-scale def /ofshs song-fonts-h-scale def /song-fonts-w-scale 1 def % set to 1 for width computation. songs1 { extract-song-and-time-and-font setfont /Title eq { stringwidth pop Imaxw max /Imaxw exch def /Imaxh Imaxh inner-album-font-height add 4 add def } { pop } ifelse } forall songs2 { extract-song-and-time-and-font setfont /Title eq { stringwidth pop Imaxw max /Imaxw exch def /Imaxh Imaxh inner-album-font-height add 4 add def } { pop } ifelse } forall /song-fonts-w-scale ofsws def /song-fonts-h-scale ofshs def Imaxw } bdef /print-two-inner-album-titles { % write album titles above the song listings gsave /x 10 def /y back-spine-height spine-height add margins 3 mul add neg def /w inner-width 2 div 10 sub def /x2 w 20 add def one-column { /w2 w def } if songs-go-inside { flip-songs { /y y list-height margins add add def } { /y y list-height margins add sub def } ifelse } if /font inner-album-font findfont inner-album-font-height scalefont def font setfont /maxw albumname1 albumname2 max-stringwidth def /maxw maxw inline-album-titles-max-stringwidth max def /song-fonts-title-w-scale maxw w gt { w maxw div } { 1 } ifelse def font [ song-fonts-title-w-scale 0 0 1 0 0 ] makefont setfont gsave x y w inner-album-font-height 1.5 add box clip newpath x y inner-album-font-height sub 2 add moveto albumname1 show 0 -2 rmoveto x y inner-album-font-height sub lineto stroke % underline it. grestore gsave x2 y w inner-album-font-height 1.5 add box clip newpath x2 y inner-album-font-height sub 2 add moveto albumname2 show 0 -2 rmoveto x y inner-album-font-height sub lineto stroke % underline it. grestore grestore } bdef /print-one-inner-album-title { % write album title centered above songs. gsave /x 10 def /y back-spine-height spine-height add margins 3 mul add neg def /w inner-width x sub def /w2 inner-width 2 div x sub def one-column { /w2 w def } if songs-go-inside { flip-songs { /y y list-height margins add add def } { /y y list-height margins add sub def } ifelse } if /font inner-album-font findfont inner-album-font-height scalefont def font setfont /maxw albumname1 stringwidth pop def /innerw inline-album-titles-max-stringwidth def /maxw maxw innerw max def /w3 innerw 0 eq { w } { w2 } ifelse def /song-fonts-title-w-scale maxw w3 gt { w3 maxw div } { 1 } ifelse def font [ song-fonts-title-w-scale 0 0 1 0 0 ] makefont setfont gsave x y w inner-album-font-height 1.5 add box clip newpath x w 2 div add y inner-album-font-height sub 2 add moveto albumname1 centershow newpath x y inner-album-font-height sub moveto % w 10 sub 0 rlineto stroke w 0 rlineto stroke grestore grestore } bdef /print-inner-album-titles { double-album-p { print-one-inner-album-title } { print-two-inner-album-titles } ifelse } bdef /print-one-date { % write a date centered below the song listings gsave /x 10 def /y back-spine-height spine-height add list-height add margins 2 mul add inner-album-font-height sub neg def /w inner-width x sub def songs-go-inside { flip-songs { /y y list-height margins add add def } { /y y list-height margins add sub def } ifelse } if date-font findfont date-font-height scalefont setfont x y w inner-album-font-height 1.5 add box clip newpath x w 2 div add y inner-album-font-height sub 2 add moveto /datew date1 stringwidth pop def datew w gt { currentfont [ w datew div 0 0 1 0 0 ] makefont setfont } if date1 centershow grestore } bdef /print-two-dates { % write the dates below the song listings gsave /x 25 def /y back-spine-height spine-height add list-height add margins 2 mul add inner-album-font-height sub neg def /w inner-width 2 div def /x2 w x add def songs-go-inside { flip-songs { /y y list-height margins add add def } { /y y list-height margins add sub def } ifelse } if date-font findfont date-font-height scalefont setfont /datew date1 date2 max-stringwidth def gsave x y w inner-album-font-height box clip newpath x y inner-album-font-height sub 2 add moveto datew w x sub gt { currentfont [ w x sub datew div 0 0 1 0 0 ] makefont setfont } if date1 show grestore gsave x2 y w inner-album-font-height box clip newpath x2 y inner-album-font-height sub 2 add moveto datew w x sub gt { currentfont [ w x sub datew div 0 0 1 0 0 ] makefont setfont } if date2 show grestore grestore } bdef /print-dates { one-column double-album-p not and { () date1 eq { /date1 date2 def /date2 () def } { () date2 eq not { /l1 date1 length def /l2 date2 length def /s l1 l2 add 2 add string def 0 1 l1 1 sub { s exch dup date1 exch get put } for s l1 (,) 0 get put s l1 1 add ( ) 0 get put 0 1 l2 1 sub { s exch dup date2 exch get exch l1 2 add add exch put } for /date1 s def /date2 () def } if } ifelse } if double-album-p one-column or { print-one-date } { print-two-dates } ifelse } bdef /print-additional-information { % write the additional information gsave /x 10 def /y back-spine-height spine-height add margins 3 mul add neg additional-information-font-height sub def columns-horizontally { /x x list-height songs-go-inside flip-songs xor { sub } { add } ifelse def songs-go-inside flip-songs not and { /y y inner-width margins add sub def } if songs-go-inside flip-songs and { /y y inner-width margins add add def } if } { songs-go-inside not flip-songs not and { /y y list-height margins add sub def } if songs-go-inside not flip-songs and { /y y list-height margins add add def } if } ifelse additional-information-font findfont additional-information-font-height scalefont setfont 0 1 additional-information length 1 sub { x y moveto additional-information exch get show /y y additional-information-font-height sub def } for grestore } bdef /compute-spine-font-xscale { % compute horizontal size of largest band name string... magic-name-p { magic-name-width } { band-font findfont band-font-height scalefont setfont bandname1 bandname2 max-stringwidth } ifelse % compute horizontal size of largest album name string... album-font findfont album-font-height scalefont setfont albumname1 albumname2 max-stringwidth albumname3 albumname4 max-stringwidth max add % add them and divide inner-width by them to get spine-height mul % the ratio to scale the fonts by. If this is inner-width % less than 1, don't do any scaling. 10 sub % subtract 10 from inner-width to account for the 5 point margin % between the text and the right and left edges. % if the two fonts are the same height, insert an additional 10 point gap. % band-font-height album-font-height eq { 10 sub } if % no, always insert it. 10 sub exch div dup 1 ge { pop 1 } if } bdef /box-name-printers-p false def % For debugging. You don't want this. /draw-spine { % draw the spine of the tape gsave margins margins margins add back-spine-height add neg translate flip-spine not { 180 rotate inner-width neg spine-height translate } if 0 0 inner-width spine-height box stroke % the box around the spine 0 0 inner-width spine-height box clip newpath margins spine-height neg translate /xscale compute-spine-font-xscale def gsave 0 0 moveto spine-height xscale mul spine-height scale magic-name-p { box-name-printers-p % debugging magic-name-printer sizing. { 0 setgray 0 0 magic-name-width -1 box fill { 1 exch sub } settransfer 0.01 setlinewidth 0 setgray 0 1 9 { 0 moveto 0 1 rlineto stroke } for } if % bandname2 () eq not % { % 0 0.6 translate % 0.45 0.45 scale % gsave magic-name grestore % 0 -1 translate % magic-name2 % } % { 0 0.2222 translate 0.9 0.9 scale magic-name % } ifelse } { band-font findfont band-font-height scalefont setfont 0 1 band-font-height sub moveto same-band-p { 0 -0.1 rmoveto } if bandname1 show 0 1 band-font-height dup add sub moveto bandname2 show } ifelse grestore inner-width margins sub margins sub 0 translate gsave spine-height xscale mul spine-height scale /afh album-font-height def album-font findfont afh scalefont setfont 1 afh sub dup 0 exch moveto double-album-p { 0 -0.1 rmoveto } if % albumname1 and albumname2 are the first album on each side. % albumname3 and albumname4 are the second album on each side. albumname1 () eq not { albumname1 rightshow afh sub }if albumname3 () eq not {dup 0 exch moveto albumname3 rightshow afh sub }if albumname2 () eq not {dup 0 exch moveto albumname2 rightshow afh sub }if albumname4 () eq not {dup 0 exch moveto albumname4 rightshow }if pop grestore grestore } bdef /coerce-to-array-of-strings { % if given a string, puts it in an array. dup type /stringtype eq { 1 array astore } if } bdef /draw-back-spine { % draw the short flap on the back. /x margins def /y margins neg def /w inner-width def /h back-spine-height def gsave x y w h box stroke x y w h box clip newpath x w add y h add neg translate 180 rotate signature-font findfont signature-font-height scalefont setfont /s signature coerce-to-array-of-strings def /sx margins def /sy h margins 3 mul sub neg s length 1 sub signature-font-height mul add def s { sx sy moveto show /sy sy signature-font-height sub def } forall grestore } bdef /reset { % resets all the tape-specific parameters. /bandname1 () def /bandname2 () def /albumname1 () def /albumname2 () def /albumname3 () def /albumname4 () def /date1 () def /date2 () def /magic-name-p false def /magic-icon-p false def /double-album-p false def /same-band-p false def /dolby false def /additional-information false def %% This shouldn't be necessary, but it seems to be. %% This program is way outta control... %/song-fonts-w-scale 1 def %/song-fonts-h-scale 1 def /song-fonts-title-w-scale 1 def } bdef reset % do it now to give them their initial values. /signature () def % probably redefined later. /draw-tape-label { % draw one. Assumes all variables have been filled in. % Takes X and Y on the stack. /tty exch def /ttx exch def % save % ** Comment this out if your PS interpreter doesn't like it. really-big { /ttx 0 def /tty 0 def } if gsave 90 rotate ttx tty translate really-big { % This is a hack for debugging on screen... 90 rotate 2 2 scale total-width neg 0 translate } if 0 0 total-width total-height box stroke margins total-height neg list-height 2 mul add margins 2 mul add inner-width list-height box stroke % draw a box around the back. magic-icon-p { draw-icon } if margins total-height neg list-height add margins add inner-width list-height box stroke % draw a box around the listings. draw-back-spine draw-spine 0 0 total-width total-height box % draw the outermost box. % You are not expected to understand this. % flip-songs { 180 rotate total-width neg list-height spine-height back-spine-height add margins 3 mul add 2 mul add translate } if /frobbed-columns false def columns-horizontally { /frobbed-columns true def -90 rotate 0 inner-width translate back-spine-height spine-height add 3 margins mul add dup margins sub exch translate flip-songs { columns-horizontally not { 0 total-width neg margins add translate } if songs-go-inside { list-height margins add neg total-width neg margins add translate } if } { songs-go-inside { list-height margins add total-width translate } if } ifelse one-column { margins 0 translate } if % hack /iw inner-width def /inner-width list-height def /list-height iw def /total-width inner-width margins dup add add def } if one-column { double-album-p not { [ albumname1 /Title ] } if songs1 aload pop double-album-p not { () albumname2 () eq not { [ albumname2 /Title ] } if } if songs2 aload pop songs1 length songs2 length add double-album-p not { albumname2 () eq not {3} {2} ifelse add } if array astore /songs1 exch def /songs2 [] def double-album-p { print-inner-album-titles } if set-songfont 1 print-songs } { print-inner-album-titles set-songfont 0 print-songs 1 print-songs } ifelse print-dates frobbed-columns % fix up the sizes we've screwed with { DATp {DAT-sizes} { 8mmp {8mm-sizes} {cassette-sizes} ifelse } ifelse } if additional-information false eq not { print-additional-information } if grestore gsave 90 rotate ttx tty translate really-big { % This is a hack for debugging on screen... 90 rotate 2 2 scale total-width neg 0 translate } if -90 rotate margins 2 add dup translate dolby false eq not { draw-dolby } if grestore reset % restore % ** Comment this out if your PS interpreter doesn't like it. } bdef %% Dolby symbols. This code is derived from code written by Michael L. Brown. %% /draw-dolby-internal { gsave dup () eq { pop } { % text /Helvetica-Bold findfont 36 scalefont setfont 92 12 moveto dup stringwidth pop /dolbytextw exch def show % from stack 4 setlinewidth 82 2 moveto 0 46 rlineto dolbytextw 20 add 0 rlineto 0 -46 rlineto closepath stroke % Trademark % aaah, who needs this. % /Helvetica-Bold findfont 28 scalefont setfont % dolbytextw 110 add 29.5 moveto % (TM) show } ifelse % left D box 0 0 moveto 0 50 rlineto 32 0 rlineto 0 -50 rlineto closepath fill % right D box 38 0 moveto 0 50 rlineto 32 0 rlineto 0 -50 rlineto closepath fill 1.0 setgray 4 setlinewidth % left D 10 8 moveto 0 34 rlineto stroke gsave newpath 1.0 1.2142857 scale 12 20.588236 14 270 90 arc fill grestore % right D 60 8 moveto 0 34 rlineto stroke gsave newpath 1.0 1.2142857 scale 58 20.588236 14 90 270 arc fill grestore 0.0 setgray grestore } bdef /draw-dolby { % stack: x y % draw a dolby symbol at x,y, with a boxed string next to it. % if string=(), don't draw box. DD symbol is 1 point square. gsave 0.0143 9 mul dup scale dolby type /stringtype eq { dolby draw-dolby-internal } { /Helvetica-Bold findfont 36 scalefont setfont gsave 5 setlinewidth /d dolby 3 string cvs def 0 0 d stringwidth pop 12 add -36 box stroke 7 7 translate 0 0 moveto d show grestore } ifelse grestore } bdef /Dolby { /dolby () def } def /DolbyB { /dolby (DOLBY B) def } def /DolbyC { /dolby (DOLBY C) def } def /AAD { /dolby /AAD def } def /DAD { /dolby /DAD def } def /ADD { /dolby /ADD def } def /DDD { /dolby /DDD def } def /dbx { /dolby /dbx def } def %%% Case-insensitive dictionary lookup. Yowza. /nsdc-buf 255 string def /nstring-downcase { % target-string source-string % convert a string to lowercase; copies source-string % into target-string, doing the conversion. The two % strings may be the same, and the source-string may % be a 'name'. dup type /nametype eq { nsdc-buf cvs } if 0 exch { dup dup 65 ge exch 90 le and { 32 add } if exch dup 4 1 roll exch 2 index 5 1 roll put 1 add } forall pop } bdef /CIget { % like get, but uses a lowercase version of the string. dup length string exch nstring-downcase get } bdef /CIput { % like put, but uses a lowercase version of the string. exch dup length string exch nstring-downcase exch put } bdef /CIknown { % like known, but uses a lowercase version of the string. dup length string exch nstring-downcase known } bdef % Dictionaries for storing magic band-name-and-icon-rendering functions. % /magic-name-dict 200 dict def /magic-icon-dict 200 dict def % Invoke the magic band-name-rendering function for the current band. % /magic-icon { magic-icon-dict bandname1 CIknown { magic-icon-dict bandname1 CIget exec } { magic-icon-dict /default-icon-printer known { magic-icon-dict /default-icon-printer get exec } if } ifelse } bdef /magic-name { magic-name-dict bandname1 CIget 0 get exec } bdef /magic-name2 { magic-name-dict bandname2 CIget 0 get exec } bdef /magic-name-width { magic-name-dict bandname1 CIget 1 get } bdef % Decide whether this band has a magic rendering function. % /check-magic { /magic-name-p magic-name-dict bandname1 CIknown def /magic-icon-p magic-icon-dict bandname1 CIknown magic-icon-dict /default-icon-printer known or def } bdef % Define a new magic-name printer. /define-magic-name-printer { % arguments: bandname procedure width 2 array astore magic-name-dict % stack: band [proc w] dict 3 1 roll % stack: dict band [proc w] CIput } bdef /dump-internal { DATp { tick 2 eq {550} { tick 1 eq {300} {50} ifelse } ifelse } { tick 1 eq {360} {50} ifelse } ifelse -100 draw-tape-label tick DATp { 2 } { 1 } ifelse eq really-big or { showpage } if /tick tick 1 add DATp { 3 } { 2 } ifelse mod def really-big { /tick 0 def } if reset } bdef %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%% %%%%%%%% %%%%%%% The user-level functions. %%%%%%%% %%%%%%% %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /two-albums { % arguments: bandname album1 date1 album2 date2 songs1 songs2 % /additional-information info (both optional) 1 index /additional-information eq { def } if /songs2 exch def /songs1 exch def /date2 exch def /albumname2 exch def /date1 exch def /albumname1 exch def /bandname1 exch def /same-band-p true def /band-font-height 0.6 def /album-font-height 0.4 def check-magic dump-internal } bdef /two-bands { %args: bandname1 album1 date1 songs1 bandname2 album2 date2 songs2 % /additional-information info (both optional) 1 index /additional-information eq { def } if /songs2 exch def /date2 exch def /albumname2 exch def /bandname2 exch def /songs1 exch def /date1 exch def /albumname1 exch def /bandname1 exch def /band-font-height 0.4 def /album-font-height 0.4 def /magic-name-p false def /magic-icon-p false def % check-magic dump-internal } bdef /double-album { % arguments: bandname album date songs1 songs2 % /additional-information info (both optional) 1 index /additional-information eq { def } if /songs2 exch def /songs1 exch def /date1 exch def /albumname1 exch def /bandname1 exch def /band-font-height 0.6 def /album-font-height 0.6 def /double-album-p true def /same-band-p true def check-magic dump-internal } bdef /N-albums { %args: bandname album1.1 album1.2 date1 album2.1 album2.2 date2 songs1 songs2 % /additional-information info (both optional) 1 index /additional-information eq { def } if /songs2 exch def /songs1 exch def /date2 exch def /albumname4 exch def /albumname2 exch def /date1 exch def /albumname3 exch def /albumname1 exch def /bandname1 exch def /band-font-height 0.6 def () albumname3 eq () albumname4 eq and { /album-font-height 0.4 def } { () albumname3 eq () albumname4 eq or { /album-font-height 0.3125 def } { /album-font-height 0.21875 def } ifelse } /same-band-p band-font-height 0.6 eq def ifelse check-magic dump-internal } bdef /two-bands-N-albums { % arguments: band1 album1.1 album1.2 date1 songs1 band2 album2.1 album2.2 date2 songs2 % /additional-information info (both optional) 1 index /additional-information eq { def } if /songs2 exch def /date2 exch def /albumname4 exch def /albumname2 exch def /bandname2 exch def /songs1 exch def /date1 exch def /albumname3 exch def /albumname1 exch def /bandname1 exch def /band-font-height 0.4 def () albumname3 eq () albumname4 eq and { /album-font-height 0.4 def } { () albumname3 eq () albumname4 eq or { /album-font-height 0.3125 def } { /album-font-height 0.21875 def } ifelse } ifelse /magic-name-p false def /magic-icon-p false def dump-internal } bdef %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%% %%%%%%%% %%%%%%% The Magic-Name Printers. %%%%%%%% %%%%%%% %%%%%%%% %%%%%%% These routines will be automatically invoked to %%%%%%%% %%%%%%% draw certain band-names, so that you can have %%%%%%%% %%%%%%% really hi-tech tape-labels. Add more! %%%%%%%% %%%%%%% %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Draw "Front 242" as a long, thin "front" over a long, tall "242". %%% (Front 242) { gsave 0 -0.1 translate 0.95 1 scale /Helvetica-Bold findfont [ 1.35 0 0 0.4 0 0 ] makefont setfont 0 0.58 moveto (FRONT) show /Helvetica-Bold findfont [ 2.85 0 0 0.7 0 0 ] makefont setfont 0 0 moveto (242) show grestore } bind 4 define-magic-name-printer %%% Draw "Orchestral Manoeuveres in the Dark" on two lines; use the %%% "oe" character. %%% (Orchestral Manoeuveres in the Dark) { gsave 0 -0.1 translate 0.7 1 scale /Helvetica-Bold findfont [0.45 0 0 0.65 0 0] makefont setfont 0.1 0.35 moveto (ORCHESTRAL MAN\352UVRES) show /Helvetica findfont [1 0 0 0.3 0 0] makefont setfont 0.1 0.05 moveto (IN THE DARK) show grestore } bind 4.2 define-magic-name-printer %%% Draw "OMD" in the same way as "Orchestral Manoeuveres in the Dark". %%% magic-name-dict (OMD) cvn magic-name-dict (Orchestral Manoeuveres in the Dark) cvn CIget CIput %%% Draw "New Order" as a dark "New" over an outlined "Order", staggered. %%% (New Order) { gsave 0 -0.1 translate 0.02 setlinewidth 1.5 setmiterlimit /Helvetica-Bold findfont setfont 0 0.1 moveto (Order) true charpath stroke 1.57 0.1 moveto (new) show grestore } bind 3.2 define-magic-name-printer %%% Draw "Siouxsie and the Banshees" with varying-height letters, %%% like on the early albums. %%% (Siouxsie and the Banshees) { gsave 0 -0.1 translate 0.7 0.4 scale 0.1 0.25 translate /big-font /Helvetica findfont [ 0.5 0 0 2.2 0 0 ] makefont def /med-font /Helvetica findfont [ 0.5 0 0 1.1 0 0 ] makefont def /small-font /Helvetica findfont [ 0.5 0 0 1.5 0 0 ] makefont def 0 -0.1 5.9 -1.8 box clip newpath 0 0 moveto big-font setfont (SI) show 0 0.8 rmoveto small-font setfont (o) show 0 -0.8 rmoveto big-font setfont (UXSIE) show med-font setfont currentpoint /y exch def /x exch def .07 0.85 rmoveto (and) show x y moveto (THE) show big-font setfont (BANSHE) show 0 0.8 rmoveto small-font setfont (e) show 0 -0.8 rmoveto big-font setfont (S) show grestore } bind 4 define-magic-name-printer %%% Draw "Cabaret Voltaire" in their font. I should probably have %%% implemented this as a font, instead of as a set of procedures, %%% but life's too short. %%% (Cabaret Voltaire) { gsave 0 -0.1 translate 0.5 0.5 scale 1.8 setmiterlimit 0.1 setlinewidth 0.2 0.3 moveto cabaret-c 0.5 0 rmoveto cabaret-a 0.7 0 rmoveto cabaret-b 0.6 0 rmoveto cabaret-a 0.7 0 rmoveto cabaret-R 0.6 0 rmoveto cabaret-e 0.4 0 rmoveto cabaret-T 1.0 0 rmoveto cabaret-v 0.6 0 rmoveto cabaret-o 0.7 0 rmoveto cabaret-L 0.6 0 rmoveto cabaret-t 0.4 0 rmoveto cabaret-A 0.45 0 rmoveto cabaret-I 0.45 0 rmoveto cabaret-r 0.5 0 rmoveto cabaret-e grestore } bind 4.1 define-magic-name-printer %% Internal procedures to the "Cabaret Voltaire" printer. %% /cabaret-c { gsave currentpoint translate newpath 0.5 0.25 moveto 0.25 0 lineto 0 0.5 lineto 0.25 1 lineto 0.5 0.75 lineto stroke grestore } bdef /cabaret-a { gsave currentpoint translate newpath 0.25 0.75 moveto 0.5 1 lineto 0.5 0 lineto 0 0.5 lineto 0.5 0.5 lineto stroke grestore } bdef /cabaret-b { gsave currentpoint translate newpath 0 1 moveto 0 0 lineto 0.5 0.5 lineto 0 0.5 lineto stroke grestore } bdef /cabaret-R { gsave currentpoint translate newpath 0 0 moveto 0 1 lineto 0.5 0.5 lineto 0 0.5 lineto 0.25 0.5 moveto 0.5 0 lineto stroke grestore } bdef /cabaret-e { gsave currentpoint translate newpath 0.375 0.25 moveto 0.25 0 lineto 0 0.5 lineto 0.25 1 lineto 0.5 0.5 lineto 0 0.5 lineto stroke grestore } bdef /cabaret-T { gsave currentpoint translate newpath 0 1 moveto 0.5 1 lineto 0.25 1 moveto 0.25 0 lineto stroke grestore } bdef /cabaret-v { gsave currentpoint translate newpath 0 1 moveto 0.25 0 lineto 0.5 1 lineto stroke grestore } bdef /cabaret-o { gsave currentpoint translate newpath 0.25 1 moveto 0.5 0.5 lineto 0.25 0 lineto 0 0.5 lineto closepath stroke grestore } bdef /cabaret-L { gsave currentpoint translate newpath 0 1 moveto 0 0.10 lineto 0.5 0.10 lineto stroke grestore } bdef /cabaret-t { gsave currentpoint translate newpath 0 1 moveto 0 0 lineto 0.275 0.25 lineto stroke 0 0.75 moveto 0.25 0.75 lineto stroke grestore } bdef /cabaret-A { gsave currentpoint translate newpath 0 0 moveto 0.25 1 lineto 0.5 0 lineto stroke 0.125 0.5 moveto 0.375 0.5 lineto stroke grestore } bdef /cabaret-I { gsave currentpoint translate newpath 0.25 0 moveto 0.25 1 lineto stroke grestore } bdef /cabaret-r { gsave currentpoint translate newpath 0 0 moveto 0 1 lineto stroke 0 0.75 moveto 0.25 1 lineto 0.5 0.75 lineto stroke grestore } bdef (Nine Inch Nails) { gsave 0 0 moveto /Helvetica findfont [ 1 0 0 1 0 0] makefont /Helvetica findfont [-1 0 0 1 0 0] makefont dup setfont gsave 90 rotate 0.3 -0.2 translate 0.7 0.7 scale NiNbox grestore /nw (n)stringwidth pop neg def 0.6 0 moveto nw 0 rmoveto (n)show nw 0 rmoveto exch dup setfont (i)show nw 0 rmoveto exch dup setfont (n)show nw 0 rmoveto exch dup setfont (e i)show nw 0 rmoveto exch dup setfont (n)show nw 0 rmoveto exch dup setfont (ch )show nw 0 rmoveto exch dup setfont (n)show nw 0 rmoveto exch dup setfont (ails)show pop pop grestore } bind 6.3 define-magic-name-printer %% Draw "Depeche Mode" as on their "Some Great Reward" %% "depeche" (in lower case) over a larger "MODE" %% By Roderick Lee <[email protected]>. %% (Depeche Mode) { gsave 0 -0.1 translate 0.95 1 scale /Helvetica-Bold findfont [ 0.60 0 0 0.50 0 0 ] makefont setfont 0.05 0.51 moveto (depeche) show /Helvetica-Bold findfont [ 0.84 0 0 0.70 0 0 ] makefont setfont 0 -0.05 moveto (MODE) show grestore } bind 2 define-magic-name-printer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%% %%%%%%%% %%%%%%% The Magic-Icon Printers. %%%%%%%% %%%%%%% %%%%%%%% %%%%%%% These routines will be automatically invoked to %%%%%%%% %%%%%%% draw icons for tapes of certain band, again for %%%%%%%% %%%%%%% added whizziness. Add more! %%%%%%%% %%%%%%% %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% magic-icon-dict (Love and Rockets) cvn { L&R } CIput /L&R { % Love and Rockets logo. gsave 0.005 setlinewidth gsave newpath 0.5 0 moveto 0 0 0.5 0 360 arc clip newpath -0.5 -0.5 1 -1 box fill 1 setgray -0.1875 -0.5 0.375 -1 box fill grestore newpath 0.5 0 moveto 0 0 0.5 0 360 arc stroke L&R-rocket L&R-heart grestore } bdef /L&R-rocket { -0.0625 0.3125 0.125 0.625 box fill % shaft -0.0625 0.3125 moveto 0.125 0 rlineto % head 0 0.5 lineto closepath fill -0.0625 -0.2 moveto -0.03 -0.03 rlineto % lfin 0 -0.25 rlineto 0 -0.3125 lineto fill 0.0625 -0.2 moveto 0.03 -0.03 rlineto % rfin 0 -0.25 rlineto 0 -0.3125 lineto fill } bdef /L&R-heart-path { newpath 0 0.125 moveto -0.0625 0.125 0.0625 0 180 arc 0 -0.125 lineto 0.125 0.125 lineto 0.0625 0.125 0.0625 0 180 arc closepath } bdef /L&R-heart { 0.5 setgray L&R-heart-path fill 0 setgray L&R-heart-path stroke } bdef magic-icon-dict (Bauhaus) cvn { BEGA } CIput /BEGA { % Beggars Banquet logo. gsave 0.005 setlinewidth newpath 0.5 0 moveto 0 0 0.5 0 360 arc stroke newpath 0.5 0 moveto 0 0 0.5 0 360 arc clip newpath 0 0.3333 moveto 0.25 0 rlineto 0 -0.25 rlineto stroke % eye 0.083 0.3333 0.1666 0.1666 box fill 0.3125 0.5 0.02 0.5 box fill % nose v 0.2125 0 moveto 0.3125 0 lineto stroke % nose h 0.2725 0 0.04 0.3 box fill % mouth v 0.2125 -0.125 0.1 0.03 box fill % mouth h 0.125 -0.3 0.155 0.25 box fill % chin v 0.0625 -0.3 moveto 0.28 -0.3 lineto stroke % chin h grestore } bdef magic-icon-dict (Nitzer Ebb) cvn { NE-dispatch } CIput /NE-dispatch { % draw one of three nitzer ebb logos, depending on albumname. albumname1 (That Total Age) eq { NE3 } { albumname1 (Belief) eq { NE-belief } { NE-star-and-gear } ifelse } ifelse } bdef /NE3 { % Nitzer Ebb "That Total Age" logo. gsave -0.175 0.5 0.35 1 box fill 0.5 setgray /s 0.3 def gsave 0 -0.3333 translate s s scale NE-hammer grestore gsave s s scale starpath fill grestore gsave 0 0.3333 translate s s scale NE-gear grestore grestore } bdef /NE-gear { gsave 0.1 setlinewidth 0 0 0.375 0 360 arc stroke 0 1 8 { -0.075 0.5 0.15 0.1 box fill 45 rotate } for grestore } bdef /NE-hammer { gsave 0.05 0 translate 45 rotate -0.1 0.4 0.2 0.85 box fill -0.3 0.4 0.45 0.2 box fill 0.15 0.4 moveto 0.35 0.2 lineto 0.15 0.2 lineto closepath fill grestore } bdef /starpath { newpath 0 0.5 moveto 0 1 4 { 144 rotate 0 0.5 lineto } for closepath } bdef /NE-star-and-gear { % Nitzer Ebb "Warsaw Ghetto" logo. gsave 0.8 0.8 scale NE-split-gear grestore NE-split-star } bdef /NE-split-star { gsave 0.02 setlinewidth 0 setgray starpath stroke starpath clip newpath 0 setgray 0 0.5 0.5 1 box fill 1 setgray -0.5 0.5 0.5 1 box fill grestore } bdef /NE-gear-path { 0 0.5 moveto 0 1 11 { -0.075 0.5 lineto -0.075 0.45 lineto 30 rotate 0.075 0.45 lineto % ## make this a curveto!! 0.075 0.45 lineto 0.075 0.5 lineto } for closepath } bdef /NE-split-gear { gsave % I tried doing this with eopath, but it doesn't work in Amiga Post 1.1. 0.005 setlinewidth 0 setgray NE-gear-path stroke NE-gear-path clip newpath -0.5 0.5 0.5 1 box fill 1 setgray 0.4 0 moveto 0 0 0.4 0 360 arc fill 0 setgray 0.4 0 moveto 0 0 0.4 0 360 arc stroke grestore } bdef %% What follows is a bitmap of the "grainy eye" image from "Belief". %% Digitized on an Amiga, converted to PS with Jef Poskanzer's PBM toolkit. %% I would have stored the bitmap run-length encoded, but that would have %% taken some work, as the only rle-decoders I have expect to draw the image %% as they decode, and not store it away for future use as we do here. %% /NE-belief { gsave 0.8 0.8 scale -0.5 -0.5 translate 82 71 1 [ 82 0 0 -71 0 71 ] %% 28 lines of bitmap data... pinhead representation (tm). {<000000000000000000003f000000000000000000003f000000000000000000003f00000000 0000000000003f000000000000000000003f03ffffffffffeffff0003f03ffffffdf3fffffb 0003f03fffff800002ff661003f03ffffe00000060ffb003f03ffff8000000001fc003f007f fc00000000067c003f007fe000000000001d803f001f00000000000008203f0000000000000 00006003f000000000000000004003f0000000000001e0000003f0000000000003f8000003f 0000000000007d0000003f000000000000390000003f000000000000000000003f000000000 000000000003f000000000000000000003f000000000000000000003f000000002000000000 003f0000000ff000000000003f0000001fe006000000003f0000003f8046000000003f02000 07fc1c6000000003f0200007fb780000000403f0300007fc70800000f803f0300003ff03040 0008883f030001ffffff800018003f0380004ffffe0001f8003f03800007fffc0003fc003f0 380001780000053f4003f03800001c8000197f7003f03800001f80001fffe003f03800046c0 0037ffbf003f03800007f801ffffff803f0380000ffffffffff0003f03800003fffffffffe0 03f03800002fffffffffe003f03c00000fffffffff8003f03c00000fffffffff8003f03c000 01fffffffff0003f03c000007ffffffff0003f03c000001ffffffff0003f03c000007ffffff fe0003f03c00000ffffffffe0003f03e000007fffffffe0003f03e000003fffffff40003f03 e000001fffffff80003f03e000001ffffffd80003f03f0000003fffffe00003f03f0000001f ffffc00003f03f0000001fffffc00003f03f0000000fffffc00003f03f00000017ffff80000 3f03f0000001fffffc00003f03f0000000fffff800003f03e0000000fffff800003f03e0000 0003ffff000003f03e000000017fff000003f0300000000179fe000003f02000000001f0ae0 00003f000000000001000000003f0000000000007f0000003f000000000000000000003f000 000000000000000003f000000000000000000003f000000000000000000003f000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000>} image grestore } bdef magic-icon-dict (Nine Inch Nails) cvn { NiNbox } CIput /NiNbox { gsave 0.7 0.7 scale /Helvetica-Bold findfont [ 1 0 0 1 0 0] makefont /Helvetica-Bold findfont [-1 0 0 1 0 0] makefont dup setfont (NIN)stringwidth pop 2 div -0.3 translate 0 0 moveto /Nw (N)stringwidth pop neg def Nw 0 rmoveto (N)show Nw 0 rmoveto exch dup setfont (IN)show exch 0.1 setlinewidth -0.1 -0.15 Nw (IN)stringwidth pop add 0.2 add -1.05 box stroke pop pop grestore } bdef %% Kate Bush logo by Christer Lindh <[email protected]>. %% This draws the old-style KB logo. If it goes on the outside %% but songs go inside, it is rotates 90 degrees. %% /KB { gsave .87 .87 scale % songs-go-inside icons-go-inside not and % { -0.5 0.54 translate -90 rotate } % { -0.5 -0.5 translate } % ifelse -0.5 -0.5 translate 0.5 0.5 0.5 0 360 arc fill stroke 1 setgray 0.3 setlinewidth 0.14 0.68 moveto 0.14 0 lineto stroke 0.08 setlinewidth 0 0.80 moveto 1 0.80 lineto 0.45 0.80 moveto 0.45 0 lineto stroke 0.06 setlinewidth 0.45 0.45 moveto 1 0.875 lineto 0.60 0.55 moveto 0.9 0.1 lineto stroke grestore } bdef magic-icon-dict (Kate Bush) cvn { KB } CIput systemdict /statusdict known { systemdict /statusdict get /product known { systemdict /statusdict get /product get (Ghostscript) eq { /really-big true def } if } if } if %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Dead bitmap from [email protected] (Fish) %% courtesy of boccibob%[email protected] (Bob Ramstad). %% Doubly inverted version (black<->white) and (left<->right) %% by Duane Day ([email protected]). %% The bitmap of the skull is from rec.music.gdead, it is %% presumed to be in the public domain. magic-icon-dict (Dead) cvn { SYF } CIput magic-icon-dict (Grateful Dead) cvn { SYF } CIput /SYF { % Steal Your Face Logo. gsave 0.8 0.8 scale -0.5 -0.5 translate 96 100 1 [96 0 0 -100 0 100] % data: {<ffffffffffffffffffffffff ffffffffffffffffffffffff ffffffffffffffffffffffff ffffffffff8001ffffffffff fffffffff03ffc07ffffffff ffffffff81ffffc0ffffffff fffffffc0fc007f83fffffff fffffff03e0001fe0fffffff ffffffe0f800000f81ffffff ffffff83c0000001c0ffffff fffffe0700000000f07fffff fffff81e00000004381fffff ffffe0380000003c1c07ffff ffffe070000001f80e03ffff ffff80e0000000300701ffff ffff01c00000007003807fff fffe0380000001e001c07fff fffc0700000007c200e03fff fff8070000001fde00601fff fff80c000000fffc00700fff fff01c000001fff0003007ff ffe0180000000fe0001803ff ffc03800000007c0001803ff ffc0300000001f00001801ff ff80600000003c00000c00ff ff0060000000ff80000c00ff ff0060000003fffe0006007f fe00c000000ffffc0006007f fe00c000003ffff80006003f fe00c00000fc7fc00006003f fc01c0000000ff800003001f f80180000003fe000003001f f8018000000ffc000003000f f0018000001ff0000003000f f0018000003fc0080003000f f0018000007ffff80003000f e001800001ffffc000030007 e001800007ffff8000030007 e00180000ffffe0000030007 e00180003e1ff80000030007 c0018000003ff00000060007 c0018000007fc00000060007 c001800001ff000000060003 c001400003feff8000060003 c000c00007fffe00000c0003 c000a0000ffff000000c0007 c000a0003fffe000001c0007 c000a00060ff800000180007 c000500001fe000000180007 c000500003f0000000300007 c000280003e0000000700007 c000280007fe000000700007 c00014000ff8000000e0000f c0001a000fe0000001e0000f c0000a001f8000000340000f c0000d001e0000000740000f e0000d003f8000000ec0000f e00005403e0000001e80001f e0000960700000003e80001f e00000f800000000fc80001f f00002fc00000001fc80003f f00002ff00000017fc80003f f00002ffc000003ffd00003f f8000a7ff800007ffe80007f f800093fff001ff3f28000ff f800090f07f8fc01c50000ff fc00020001fdf0000f0000ff fc000900007de000080001ff fe000200001fc000180003ff fe000060000f800ff00003ff ff00000a7fefbffe200007ff ff8000017fef7fff50000fff ff800040ffef7fff50001fff ffc00055fff6ffff50001fff ffe00055fff4fffea0003fff fff00029fff0fffc00007fff fff80000ffe0fff00000ffff fffc00001fe07ff00001ffff fffe000021e47c400003ffff ffff000029f6ff400007ffff ffff80002dffff00000fffff ffffe0000dffff00001fffff fffff00008fff88000ffffff fffff800099ff58001ffffff fffffe001b42050003ffffff ffffff800369b4000fffffff ffffffe0035db4003fffffff fffffff80159b000ffffffff ffffffff0009a007ffffffff ffffffffe000003fffffffff ffffffffff000fffffffffff ffffffffffffffffffffffff ffffffffffffffffffffffff ffffffffffffffffffffffff ffffffffffffffffffffffff ffffffffffffffffffffffff ffffffffffffffffffffffff ffffffffffffffffffffffff ffffffffffffffffffffffff ffffffffffffffffffffffff>} image grestore } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% old version: non-inverted, and not flipped left / right either. %% Dead bitmap from [email protected] (Fish) %% courtesy of [email protected] (Bob Ramstad). %% The bitmap of the skull is from rec.music.gdead, it is %% presumed to be in the public domain. % % magic-icon-dict (Dead) cvn { SYF } CIput % % magic-icon-dict (Grateful Dead) cvn { SYF } CIput % % /SYF { % Steal Your Face Logo. % gsave % 0.8 0.8 scale % -0.5 -0.5 translate % 96 100 1 % [96 0 0 -100 0 100] % % data: % % {<000000000000000000000000 %000000000000000000000000 %000000000000000000000000 %00000000007ffe0000000000 %000000001fc003f000000000 %00000000fc00007e00000000 %00000003e01ffc0fc0000000 %0000000f807fff83f0000000 %0000007e0fffffe0f8000000 %000000fc7ffffffc3e000000 %000001f0ffffffff1f800000 %000007e3dfffffff87e00000 %00001fc7c3ffffffe3f80000 %00003f8fe07ffffff1f80000 %00007f1ff3fffffff8fe0000 %0001fe3ff1fffffffc7f0000 %0001fc7ff87ffffffe3f8000 %0003f8ffbc1fffffff1fc000 %0007f9ff8407ffffff1fe000 %000ff1ffc000ffffffcfe000 %001ff3fff0007fffffc7f000 %003fe7fff80fffffffe7f800 %003fe7fffc1fffffffe3fc00 %007fe7ffff07fffffff3fc00 %00ffcfffffc3fffffff9fe00 %00ffcffffe00fffffff9ff00 %01ff9fff80003ffffff9ff00 %01ff9fffc0000ffffffcff80 %03ff9fffe00003fffffcff80 %03ff9ffffc01c0fffffcff80 %07ff3ffffe00fffffffc7fc0 %07ff3fffff803ffffffe7fe0 %0fff3fffffc00ffffffe7fe0 %0fff3ffffff007fffffe7ff0 %0fff3fffeffc03fffffe7ff0 %0fff3fffe00001fffffe7ff0 %1fff3ffffc00007ffffe7ff8 %1fff3ffffe00001ffffe7ff8 %1fff3fffff80000ffffe7ff8 %1fff3fffffe00783fffe7ff8 %1fff9ffffff003fffffe7ffc %1fff9ffffffc01fffffe7ffc %3fff9fffffff007ffffe7ffc %3fff9ffffe00803ffffd7ffc %3fffcfffff80001ffffcfffc %1fffcffffff0000ffffafffc %1fffc7fffff80003fffafffc %1fffe7fffffe00f9fffafffc %1fffe7ffffff807ffff5fffc %1ffff3fffffff03ffff5fffc %1ffff1fffffff83fffebfffc %1ffff1ffffff801fffebfffc %0ffff8ffffffe00fffd7fffc %0ffff87ffffff80fffa7fffc %0ffffd3ffffffe07ffaffffc %0ffffd1fffffff87ff4ffffc %0ffffc8ffffffe03ff4ffff8 %07fffe87ffffff83fd5ffff8 %07fffe83fffffff1f96ffff8 %07fffec0ffffffffe0fffff8 %03fffec07fffffffc0bffff0 %03fffec017ffffff00bffff0 %03ffff4003fffffc00bffff0 %01fffe8001ffffe001afffe0 %00fffeb03007ff00036fffe0 %00ffff5c7fc0e01f0f6fffe0 %00ffff0ffff0407fffbfffc0 %007fffeffff841ffff6fffc0 %003fffe7fffc07ffffbfff80 %003ffff00ffe0ffff9ffff80 %001ffffb80020801afffff00 %000ffff5000108017ffffe00 %0007fff500010800fdfffe00 %0007fff50000900055fffc00 %0003fffa8000d00055fff800 %0001ffffc000f0006bfff000 %0000fffff000f800ffffe000 %00007ffff001f807ffffc000 %00003ffffdc1d87bffff8000 %00001ffffd00906bffff0000 %00000fffff00004bfffe0000 %000007ffff00004ffff80000 %000000fffee000effff00000 %0000007ffe50066fffe00000 %0000003fff5fbd27ff800000 %0000000fffd2693ffe000000 %00000003ffd2453ff8000000 %00000000fff2657fe0000000 %000000001ffa6fff00000000 %0000000003fffff800000000 %00000000000fff0000000000 %000000000000000000000000 %000000000000000000000000 %000000000000000000000000 %000000000000000000000000 %000000000000000000000000 %000000000000000000000000 %000000000000000000000000 %000000000000000000000000 %000000000000000000000000>} % image % grestore % } def % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /signature [ (From the private collection of Robert Ramstad.) (Recorded with Dolby B unless otherwise noted.) ] def /flip-spine true def /band-font /Helvetica def /album-font /Helvetica def %%EndProlog %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%% %%%%%%%% %%%%%%% Begin Example-Land. %%%%%%%% %%%%%%% Modify what lies after this point. %%%%%%%% %%%%%%% %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Set this string to what you want printed on the back flap, or an array %% of strings (one string per line). %% /band-font /Helvetica def % The font for band-names. /album-font /Helvetica def % The font for album-names. % Uncomment the next line to produce labels for Digital Audio Tapes. %DAT-sizes % Uncomment the next line to produce labels for 8mm video cassettes. %8mm-sizes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%% An example of the normal case: two albums by one band, %%%%%%%% %%%%%% with one album on each side of the tape. %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% (Gang of 4) (Entertainment) (1979) (Solid Gold) (1981) [(Ether) (Natural's not in it) (Not Great Men) (Damaged Goods) (Return the Gift) (Guns before Butter) () (I Found that Essence Rare) (Glass) (Contract) (At Home He's a Tourist) (5:45) (Anthrax) () (To Hell With Poverty) (Capital it Fails Us Now) ] [(Paralysed) (What we All Want) (Why Theory) (If I could keep it for myself) (Outside the trains don't run on time) () (Cheeseburger) (The Republic) (In the Ditch) (A Hole in the Wallet) (He'd send in the Army) ] /additional-information [(Arbitrary text line 1. This may be excessively long. Well maybe not!) (Arbitrary text line 2) () (Arbitrary text line 4) ] two-albums %%Trailer %% This form should always be here at the end, to make sure that the %% final page is dumped even if there are an odd number of labels %% being printed. %% tick 0 ne { showpage } if end % pop the TapeDict ------------------------------ ** FOR YOUR REFERENCE ** Requests to be added to or deleted from the DAT-heads mailing list, questions about the list, and requests for the current version of the Frequently Asked Questions file must be sent to one of the following service addresses: Internet: [email protected] [email protected] BITNET: DATH-Req@Virginia UUCP: ...!uunet!virginia!dat-heads-request You can send mail to the entire list via one of these addresses: Internet: [email protected] [email protected] BITNET: DATHeads@Virginia UUCP: ...!uunet!virginia!dat-heads End of DAT-Heads Digest ****************************** % ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ====== % Received: by easynet.crl.dec.com; id AA21142; Sat, 17 Apr 93 01:04:26 -0400 % Received: by crl.dec.com; id AA15518; Sat, 17 Apr 93 01:04:22 -0400 % Message-Id: <[email protected]> % Received: from fuggles.acc.Virginia.EDU by fuggles.acc.Virginia.EDU id aa27883; 16 Apr 93 20:32 EDT % From: Digestifier <[email protected]> % To: [email protected] % Date: Fri, 16 Apr 93 20:30:03 EDT % Subject: DAT-Heads Digest #493 | |||||
72.16 | Now, how to use it for Dead TAPES? | CORA::65447::BELKIN | the slow one now will later be fast | Thu Apr 22 1993 11:48 | 30 |
So, I'm trying to use CDA to view the .PS files so I can screw around with this and get things right for using it with typical Dead tapes. For example, for a Dead tape, I think you wanna use "double-album" ? and the 'album-name' would be the venue/date of show? Also, the area of the the label that has the 'signature' is IMHO better used for info like Date the tape was recorded: Owner: Type: SCMS: Notes: (history) as I've seen on a Mystery Hill Productions tape label. Now, this can be easily done with this program, but, problem is, it comes out upside-down. Anyone have a clue how make the .signature 'flip' ? (Guess I'll ask the DAT-heads.) I'm having problems with CDA - it draws the .ps file rotated 90 degrees. Its easy enough to change that with the print options 'rotate' button, BUT HOW TO I PUT THIS IN A FREAKIN' .CDA$OPTIONS FILE???? I read the help on creating the .cda$options file, but _nowhere_ in there does it say precisely how to specify something like the option to rotate the page!!! ARRGGHH!!!! I also looked at the CDA stuff in Bookreader and couldn't find anything in there about the View that was more than a 2 paragraph description. thanks, Josh | |||||
72.17 | CSCMA::M_PECKAR | Be kind: unwind | Thu Apr 22 1993 11:57 | 2 | |
Well, you might try playing with the vms command convert/document first??? | |||||
72.18 | closer but still no cigar | CORA::65447::BELKIN | the slow one now will later be fast | Thu Apr 22 1993 12:56 | 15 |
Well, I don't want to have zillions of extra files around, and its also an extra step to have to do. However the help in convert/document was a little usefull in describing how to make a .cda$options file, it gave the keywords, but its still not working. I have in file dat.cda$options: PS LANDSCAPE PS WATCH and I set up CDA to use this options file, but it still either ignores the options or something still isn't right. thanks, Josh | |||||
72.19 | EBBV03::SMITH | So many roads tease my soul | Thu May 27 1993 17:02 | 4 | |
Where might I be able to obtain the tape labeler that puts the big white GD in the background of the place where the song list is? | |||||
72.20 | NRSTA2::CLARK | Electric Music for the Mind and Body | Thu May 27 1993 17:16 | 1 | |
Deane, I think that might be JC's labeller ... send him mail .... | |||||
72.21 | AKOCOA::DMITCHELL | or just another pretty face | Thu May 27 1993 17:20 | 6 | |
.19 Deane, yes, Check w/ JC. Don | |||||
72.22 | ZENDIA::FERGUSON | Your recipe is so tasty | Fri May 28 1993 11:43 | 1 | |
both these guys are correct, that one be mine... send me mail. | |||||
72.23 | Grateful T.E.D. v2.0 Taper's Electronic Database | NRSTA2::CLARK | Wed Jun 30 1993 14:22 | 55 | |
Hey folks; I ftp'd the Grateful T.E.D. software that's been mentioned in rec.music.gdead, and put it in NRSTA2::USER03:[CLARK.PUBLIC]G_TED20.ZIP ... description is below. Ignore the bit about the self-extracting archive, I put the files into a .ZIP file instead. I scanned the files for viruses and they're clean. - DC p.s. Only problem I've found so far is that you'll have to edit the .PIF file if you want to use it from Windows, to change the pathspec to whatever directory you choose to contain the software. Subj: G_TED20.EXE Grateful T.E.D. v2.0 Taper's Electronic Database AUTHOR: Michael E. Carver EQUIPMENT: IBM compatible, Hard Drive recommended (or high-density floppy) NEEDS: Deadicated tape collection Type: Shareware Grateful T.E.D. (Taper's Electronic Database) version 2.0 is a DOS based database programmed specifically for DEALing with HARD TO HANDLE Dead tape collections. Features: - Space for 22 song titles per entry - Pull Down Menus - Fast Entry of song titles (maintains a separate database of readily available Dead tunes) - Multiple supported indexes (Date, City, Venue, Source, Recording Quality, Performance Quality, & Overall Quality) -- providing quick retrieval of particular tape(s) - Quickly locate tape(s) with a particular song title - Ability to print out tape lists (all or selected tapes) -- 4 different formats - Ability to print out to file or printer - Quickly calculates statistics on average quality of collection + total time G_TED20.EXE is a self extracting file. To install from a floppy disk (720k or greater), copy file to disk and log to drive, enter: G_TED20 To install, log to drive/directory that contains extracted files and enter: INSTALL Documentation: README.TXT and G_TED.DOC | |||||
72.24 | VXTST6::BOURDESS | Wed Jun 30 1993 14:38 | 5 | ||
does anyone have an unzipper I could copy? thanx much, Mike | |||||
72.25 | gzip/gunzip | LANDO::HAPGOOD | Wed Jun 30 1993 14:40 | 8 | |
<<< Note 72.24 by VXTST6::BOURDESS >>> > does anyone have an unzipper I could copy? I have a tar file with gzip/gunzip (gnu zip and unzip). It's unix. let me know and i'll make it available... bob | |||||
72.26 | VXTST6::BOURDESS | Wed Jun 30 1993 14:46 | 8 | ||
I'm kinda confused on this matter. If the software is meant for DOS, does it have to be unzipped in a DOS environment? Right now I have the zip file in a vms area. Can I unzip it and copy to a dos machine, or do I have to copy it to a DOS machine *then* unzip it. If the first method will work, then I can copy it to unix and use the unzipper mentioned in -.1...right? Mike | |||||
72.27 | you can unpack it anywhere if your unzippers work | NRSTA2::CLARK | Wed Jun 30 1993 14:56 | 6 | |
I have unzippers that work for both DOS and VMS, but I usually find the one on DOS to be more reliable ... the DOS versions are updated more frequently. Let me know if you want it and I can copy the DOS version to my public dir. - DC | |||||
72.28 | CSCMA::M_PECKAR | Two pints make one cavort | Wed Jun 30 1993 15:57 | 21 | |
> I'm kinda confused on this matter. If the software is meant for DOS, > does it have to be unzipped in a DOS environment? Right now I have the > zip file in a vms area. Can I unzip it and copy to a dos machine, or > do I have to copy it to a DOS machine *then* unzip it. If the first > method will work, then I can copy it to unix and use the unzipper > mentioned in -.1...right? You can do either, but the prefered method would be to unzip it on the local machine to decrease the chances of data corruption (the more data you xfer between different machines, the more chances for corruption). This program would be great if it came with a data entry operator. I figure it would take me, oh, one man-year to load YADB (yet another database) with all my tapes. Also, if I understand it correcty, it has no cross reference to a Deadbase-like database of all setlists, so you can't make any queries like "how many of all known Cosmic Charlies do I have on tape", or "Is this tape I just entered a complete show or not", or even "The playin' on this tape is 23 minutes long, which show is it from". :-) Fog_staying_tuned_for_the_DB_software_from_the_deadbase_folks... | |||||
72.29 | works on DOS | NRSTA2::CLARK | Wed Jun 30 1993 16:14 | 3 | |
I copied PKUNZIP.EXE to NRSTA2::USER03:[CLARK.PUBLIC] - dc | |||||
72.30 | ZENDIA::FERGUSON | Your recipe is so tasty | Thu Jul 01 1993 10:01 | 4 | |
DC, you might wanna just use ZIP2EXE and make that sucker into a self-extracting zip file. this way, you don't even need PKUNZIP | |||||
72.31 | NRSTA2::CLARK | Thu Jul 01 1993 10:22 | 6 | ||
Ah, I was *wondering* what that ZIP2EXE.EXE program was in my applications directory! :^} Done ... NRSTA2::USER03:[CLARK.PUBLIC]G_TED20.EXE - dc | |||||
72.32 | MR4MI2::REHILL | Tree's Name Here - Call 226-6165 | Fri Jul 02 1993 09:15 | 4 | |
I've heard that there is a Dancing Bears Screen Saver out on the internet. Anyone got a copy of that? | |||||
72.33 | NRSTA2::CLARK | Tue Jul 06 1993 10:34 | 5 | ||
I have it in NRSTA2::USER03:[CLARK.PUBLIC]DBEAR.EXE (self-extracting archive). Unfortunately it needs a VBRUN200.DLL ... I'm tracking that down now (unless someone has it on his/her PC already hint hint) .... - DC | |||||
72.34 | MR4MI2::REHILL | Tree's Name Here - Call 226-6165 | Tue Jul 06 1993 13:26 | 3 | |
Kevin Flannagan mailed me a copy, I have it running now! | |||||
72.35 | zipped vbrun available | SSGV01::STROBEL | & now for something completely different... | Tue Jul 06 1993 18:03 | 8 |
I've put a zipped copy of VBRUN200.DLL in a public account for those who want/need it. Copy from: ssgv02::disk$user09:[strobel.public]vbrun200.ZIP enjoy jeff | |||||
72.36 | warning: 200 block CD_PLAYER.C (that I can't link!) | PONDA::64423::BELKIN | the slow one now will later be fast | Tue Jan 18 1994 10:19 | 2718 |
I'm still dinking around with the RRD-42 CD player programs. I found the following program CD_PLAYER.C in the CDROM notes file. It has volume and balance, which the one in the DEC$examples area (DECW$CDPLAYER.C) does not. However I'm having major problems linking it! I make a link_CD.com that looks like: $!------------------------------------------- $ define/nolog c$include decw$examples,decw$include,sys$library $ define/nolog vaxc$include c$include $ $! cc CD_PLAYER $ $ link CD_PLAYER, sys$input/opt, sys$share:decw$dxmlibshr/share, - sys$share:decw$xmlibshr/share, sys$share:decw$xlibshr/share, sys$share:vaxcrtl/share $ $!------------------------------------------- which is just from the CD_PLAYER.C (a few lines down in the comments). However when I try to link, this bombs out because we don't have .OBJs in the sys$share area, only .EXEs. How does this work? I have: 12X5> dir sys$share:decw$dxmlibshr* Directory SYS$COMMON:[SYSLIB] DECW$DXMLIBSHR.EXE;2 948 19-MAY-1992 23:04:32.57 So how can I link this? Also, there was mention in the CDROM notes file that you really didn't need privs (PHY_IO and DIAGNOSE are needed for DECW$CDPLAYER.C) for the CD_PLAYER.C, that you can just go ahead and run it. Does anyone have such a program? thanks, Josh --------------------------------------------------------------------------- /* <<< CDROM::DISK$LAYERED:[NOTES$LIBRARY]CD_READER.NOTE;1 >>> -< CD Reader Technology >- ================================================================================ Note 237.14 how to play audio on RRD42 14 of 16 DENVER::BOYLES 2671 lines 20-JUL-1992 17:38 -< CD-player (VMS) with volume. >- -------------------------------------------------------------------------------- */ /* Below is a VMS audio CD_PLAYER I wrote, which provides volume and balance controls to the CD display. It does require a minimum of VMS V5.4-2, though. */ #define CONVENIENCE_ROUTINES 0 /* Compile routines = 1, else 0 */ /*============================================================================= ! Program: CD_PLAYER.C (Version 1.0 revision 20) ! Author: Gary Boyles (Englewood, CO USA) ! Date: 15-JUN-1992 17:00 ! ! ! Modification History: ! Revision Reason Date ! -------- ------------------------------------- -------- ! V1.0 -17 Initially finished (gpb) 11/21/91 ! -18 Plugged some memory-leaks (gpb) 01/03/92 ! -19 Modularized things a bit more (gpb) 06/05/92 ! -20 Added the following: (gpb) 06/15/92 ! a) Descending time-remaining scale. ! b) track-max label to "Track Now Playing" ! c) Total play-time printf statement. ! d) MSF-related convenience routines ! (present for example -- not used). ! ! ! Description: ! This program acts as a control panel for a SCSI audio CD player. It ! creates a workstation window panel with buttons for: ! eject = stop playing/enable-eject/eject-caddy from player ! stop = stop the player from playing & enable-eject ! play = start playing CD on current track & disable-eject ! pause = pause/resume the CD-player ! replay = replay the current selection ! shuffle = play random selections ! exit = stop playing/enable eject(but don't)/exit program ! incr = increment track playing ! decr = decrement track playing ! ! The program also creates the following scales/sliders/displays: ! current-track playing ! track-time display ! track-time remaining display ! volume control/display ! channel-balance control/display ! ! Note that the volume thumb-wheel should be on full-volume, because ! the slider will only control volume upto what the thumb-wheel is ! set to. ! ! The program uses MOTIF toolkit routines to create and manage the ! display and its widgets. This program was tested with an RRD42 ! on a VMS workstation running VMS DECW MOTIF V1.0 & VMS V5.4-2 ! and VMS V5.5 ! ! Currently the following improvements are necessary: ! 1) Better random # generator (currently not so random) ! 2) Some error-trapping code (currently quite minimal) ! ! In the program listing (frontend) refers for the most part to MOTIF ! routines, and (backend) refers to CD-control routines. Routines ! starting with "handle_" are the button/arrow/slider callback ! routines. ! ! In regard to routines getting executed... it happens via two methods: ! 1) Pushing a button or moving the slider (activating a callback) ! 2) Via the timer routine "the_timer". ! ! Commands to build this program are (VMS): ! ======================================== ! $ define/nolog c$include decw$examples,decw$include,sys$library ! $ define/nolog vaxc$include c$include ! $ ! $ cc CD_PLAYER ! $ ! $ link CD_PLAYER, sys$input/opt ! sys$share:decw$dxmlibshr/share ! sys$share:decw$xmlibshr/share ! sys$share:decw$xlibshr/share ! sys$share:vaxcrtl/share ! $ ! ! The program interfaces to the CD player through the SCSI disk driver. ! If you assume that the CD-player is device DKB400 then you would ! have to do the following before running the program (with privs): ! ! $ DEFINE DECW$CD_PLAYER DKB400: ! ! Note: ! To change the icon resources for the CD-player, edit your ! "mwm" file (on VMS this is DECW$MWM.DAT). For example: ! ! Mwm*CD*iconImageForeground: Firebrick ! Mwm*CD*iconImageBackground: Yellow ! ! ! Thanks goes to Stephen N. Davis for his help. !===========================================================================*/ #include <stdio.h> #include <Xm/MainW.h> /* MainWindow Class */ #include <Xm/BulletinB.h> /* BulletinBoard Class */ #include <Xm/Frame.h> /* Frame widget class */ #include <Xm/Label.h> /* Label class */ #include <Xm/PushB.h> /* Push-button Class */ #include <Xm/RowColumn.h> /* RowColumn Class */ #include <Xm/Scale.h> /* Scale class */ /*===============================(Frontend)=================================== ! Symbolic Constants !====================*/ #define SHOW_CD_TIME 1 /* 1 = show ttl play time on CD */ #define ICON_LABEL "Audio" /* Cd-player Icon label */ #define TIMER_INTERVAL 1000 /* How often? 1000 = 1/second */ #define CD_TRACK_MIN 0 /* Lower limit for track select */ #define CD_TRACK_MAX 99 /* Upper limit for track select */ #define BALANCE_SCALE_MAX 10 /* Balance max (min = -max) */ #define VOLUME_OFF 0 /* Volume Completely Off */ #define VOLUME_DEFAULT 200 /* Initial volume-setting */ #define VOLUME_MINIMUM 155 /* Lower limit for volume level */ #define VOLUME_MAXIMUM 255 /* Upper limit for volume level */ #define PUSH_BUTTON 0 /* Used in Create_Button */ #define ARROW_LEFT 1 /* Used in Create_Button */ #define ARROW_RIGHT 2 /* Used in Create_Button */ #define SHADOW_THICKNESS 4 #define BOTTOM_SHADOW_COLOR "DimGrey" #define TOP_SHADOW_COLOR "White" #define DEFAULT_FOREGROUND "Firebrick" #define DEFAULT_BACKGROUND "AntiqueWhite3" #define DEF_PUSHBUTTON_BACKGROUND "Black" /* Defaults */ #define DEF_PUSHBUTTON_FOREGROUND "White" #define BUTTON_HEIGHT 40 #define BUTTON_WIDTH 100 #define ALT_PUSHBUTTON_BACKGROUND "Firebrick" /* Alternate */ #define ALT_PUSHBUTTON_FOREGROUND "Yellow" #define ARROW_FOREGROUND "Chocolate" #define ARROW_BACKGROUND "IndianRed4" #define SCALE_FOREGROUND DEFAULT_FOREGROUND #define SCALE_BACKGROUND DEFAULT_BACKGROUND #define SCALE_TOP_SHADOW DEFAULT_FOREGROUND #define SCALE_BOTTOM_SHADOW DEFAULT_FOREGROUND #define TRACK_TIME_FOREGROUND DEF_PUSHBUTTON_FOREGROUND #define TRACK_TIME_BACKGROUND "NavyBlue" #define FALSE 0 #define TRUE 1 #define NOT_USED -1 #define VERTICAL_SCALE 1 #define HORIZONTAL_SCALE 2 /*=========================================================================== ! Define bitmap for the icon used for the cd-player. !===========================================================================*/ #define SMALL_ICON_WIDTH 32 #define SMALL_ICON_HEIGHT 32 static char small_icon_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xf8, 0x00, 0x00, 0x01, 0x08, 0x01, 0x80, 0x00, 0x08, 0x02, 0x80, 0x00, 0x08, 0x04, 0x80, 0x00, 0x08, 0x04, 0x80, 0x00, 0x08, 0x04, 0x80, 0x00, 0x08, 0x04, 0x80, 0x00, 0x08, 0x04, 0x80, 0x00, 0x08, 0x04, 0x80, 0x00, 0x08, 0x04, 0x80, 0x00, 0x08, 0x04, 0x80, 0x00, 0x08, 0x02, 0x00, 0x01, 0x08, 0x01, 0x00, 0x7e, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x87, 0x00, 0x00, 0x88, 0x8f, 0x00, 0x00, 0xc8, 0x9f, 0x00, 0x00, 0xc8, 0x9f, 0x00, 0x00, 0xc8, 0x9f, 0x00, 0x00, 0x88, 0x8f, 0x00, 0x00, 0x08, 0x87, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00}; #define MEDIUM_ICON_WIDTH 50 #define MEDIUM_ICON_HEIGHT 50 static char medium_icon_bits[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x7c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x7c, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x7f, 0x8e, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x7f, 0x9e, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x7f, 0x9e, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x7f, 0x9e, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x7f, 0x9e, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x7f, 0x9e, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x7f, 0x8e, 0xff, 0xff, 0xff, 0xff, 0x07, 0x7c, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x7c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xc9, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xcc, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x7f, 0xce, 0xff, 0x9f, 0xff, 0xff, 0xff, 0x3f, 0xcf, 0xff, 0xcf, 0xff, 0xff, 0xff, 0x9f, 0xcf, 0xff, 0x07, 0x00, 0x00, 0x00, 0xc0, 0xcf, 0xff, 0x07, 0x00, 0x00, 0x00, 0xe0, 0xcf, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xe7, 0xcf, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xe7, 0xcf, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xe7, 0xcf, 0xff, 0x67, 0x00, 0x00, 0x00, 0xe7, 0xcf, 0xff, 0x67, 0xff, 0xff, 0x7f, 0xe7, 0xcf, 0xff, 0x67, 0xff, 0xff, 0x7f, 0xe7, 0xcf, 0xff, 0x67, 0x00, 0x00, 0x00, 0xe7, 0xcf, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xe7, 0xe7, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xff, 0xe7, 0xf9, 0xff, 0x1f, 0xe7, 0xf9, 0xff, 0xe7, 0xf9, 0xff, 0x1c, 0xe7, 0xfc, 0xff, 0xe7, 0xff, 0xff, 0xff, 0x67, 0xfe, 0xff, 0xe7, 0xff, 0xff, 0xff, 0x27, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; #define LARGE_ICON_WIDTH 75 #define LARGE_ICON_HEIGHT 75 static char large_icon_bits[] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xfd, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xfd, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xfd, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xfd, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xfa, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xfd, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x65, 0xfd, 0xaa, 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xfa, 0xd5, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x64, 0xfd, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0xfa, 0xd5, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x64, 0xfd, 0xaa, 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xfa, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x65, 0xfd, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x65, 0xfd, 0xaa, 0x0a, 0xaa, 0xaa, 0xaa, 0xaa, 0x02, 0x80, 0xaa, 0xfa, 0xd5, 0x65, 0x05, 0x40, 0x55, 0x55, 0x05, 0x00, 0x65, 0xfd, 0xaa, 0x6a, 0x0a, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0xd5, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x65, 0xfd, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0xd5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfd, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xfa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xfd, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xfd, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xfd, 0xaa, 0xaa, 0xfe, 0xff, 0x01, 0xf0, 0xff, 0xaf, 0xaa, 0xfa, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x55, 0xfd, 0xaa, 0xaa, 0x9f, 0xaa, 0xaa, 0xaa, 0xaa, 0xbe, 0xaa, 0xfa, 0x55, 0x55, 0x4f, 0x55, 0x01, 0x50, 0x55, 0x3d, 0x55, 0xfd, 0xaa, 0xaa, 0xa7, 0x2a, 0xbe, 0x82, 0xaa, 0xba, 0xaa, 0xfa, 0x55, 0x55, 0x53, 0x85, 0x5f, 0x15, 0x54, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0xab, 0xea, 0xbf, 0xaa, 0xaa, 0xba, 0xaa, 0xfa, 0x55, 0x55, 0x57, 0xf1, 0x5f, 0x55, 0x51, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0xab, 0xfa, 0xbf, 0xaa, 0xaa, 0xba, 0xaa, 0xfa, 0x55, 0x55, 0x57, 0xfc, 0x5f, 0x55, 0x45, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0x2b, 0xfe, 0xbf, 0xaa, 0xaa, 0xba, 0xaa, 0xfa, 0x55, 0x55, 0x57, 0xff, 0x5f, 0x55, 0x55, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0x2b, 0xff, 0xbf, 0xaa, 0x8a, 0xba, 0xaa, 0xfa, 0x55, 0x55, 0x97, 0xff, 0x5f, 0x55, 0x15, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0xab, 0xff, 0x07, 0xa8, 0x2a, 0xba, 0xaa, 0xfa, 0x55, 0x55, 0x97, 0xff, 0xf3, 0x51, 0x55, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0xcb, 0xff, 0xf9, 0xa3, 0x2a, 0xba, 0xaa, 0xfa, 0x55, 0x54, 0xd7, 0xff, 0xfc, 0x47, 0x55, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0xcb, 0xff, 0xfe, 0xaf, 0x2a, 0xba, 0xaa, 0xfa, 0x55, 0x54, 0xd7, 0xff, 0xfe, 0x4f, 0x55, 0x35, 0x55, 0xfd, 0xaa, 0xa8, 0x8b, 0xaa, 0xfe, 0xaf, 0x3f, 0xba, 0xaa, 0xfa, 0x55, 0x40, 0x57, 0x55, 0xfe, 0xcf, 0x7f, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0x8b, 0xaa, 0xfe, 0xef, 0x7f, 0xba, 0xaa, 0xfa, 0x55, 0x54, 0x57, 0x55, 0xfc, 0xe7, 0x7f, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0x8b, 0xaa, 0xf8, 0xf3, 0x7f, 0xba, 0xaa, 0xfa, 0x55, 0x54, 0x17, 0x55, 0xf1, 0xf9, 0x7f, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0xab, 0xaa, 0x02, 0xfc, 0xbf, 0xba, 0xaa, 0xfa, 0x05, 0x54, 0x17, 0x55, 0x55, 0xff, 0x3f, 0x35, 0x55, 0xfd, 0x02, 0xaa, 0x2b, 0xaa, 0xaa, 0xff, 0x9f, 0xba, 0xaa, 0xfa, 0x01, 0x54, 0x57, 0x55, 0x55, 0xff, 0x5f, 0x35, 0x55, 0xfd, 0x02, 0xaa, 0x2b, 0xaa, 0xaa, 0xff, 0xaf, 0xba, 0xaa, 0xfa, 0x05, 0x55, 0x57, 0x55, 0x55, 0xff, 0x47, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0xab, 0xa8, 0xaa, 0xff, 0xab, 0xba, 0xaa, 0xfa, 0x55, 0x55, 0x57, 0x51, 0x55, 0xff, 0x55, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0xab, 0xa2, 0xaa, 0xfe, 0xa8, 0xba, 0xaa, 0xfa, 0x55, 0x55, 0x57, 0x15, 0x55, 0x3f, 0x55, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0xab, 0x2a, 0xa8, 0x82, 0xaa, 0xba, 0xaa, 0xfa, 0x55, 0x55, 0x57, 0x55, 0x01, 0x50, 0x55, 0x35, 0x55, 0xfd, 0xaa, 0xaa, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xba, 0xaa, 0xfa, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x55, 0xfd, 0xaa, 0xaa, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xaa, 0xfa, 0x55, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xfd, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xfd}; Pixmap /* The CD-player icon */ cd_icon; globalvalue IO$_AVAILABLE, IO$_PACKACK, IO$_DIAGNOSE; /*================================(Backend)=================================== ! SCSI Generic Class Driver #Defines & Variables !===============================================*/ static char gk_device [] = {"DECW$CD_PLAYER"}; short gk_chan; /*------------------------------------ ! CD-ROM SCSI operation command codes !-------------------------------------*/ #define SCSI_STATUS_MASK 0X3E #define MEDIA_OPCODE 0x1E #define MODE_SELECT_OPCODE 0X15 #define PAUSE_OPCODE 0X4B #define RESUME_OPCODE 0X4B #define STOP_OPCODE 0x1B #define READ_SUBCHAN_OPCODE 0X42 #define READ_TOC_OPCODE 0X43 #define PLAY_TRACK_OPCODE 0X48 #define PLAYBACK_CONTROL_OPCODE 0XC9 #define PLAYBACK_STATUS_OPCODE 0XC4 #define READ 1 #define WRITE 0 /* Varibles for saving CD-player state !======================================*/ static int saved_track_time_sec, track_time_sec, /* Playing time for this track */ total_tracks = 0, /* Total track read off this CD */ saved_total_tracks = 0, current_track = 0, /* Track now playing */ saved_current_track = 0, /* Track we thought was playing */ random_track = 0, /* Track # generated for SHUFFLE*/ old_random_track= 0, /* Saved (old) random_track */ random_total = 0, /* # of random tracks to SHUFFLE*/ current_volume = 0, /* Current volume-level */ left_volume = 0, /* Current left-channel setting */ right_volume = 0, /* Current right-channel setting*/ play_flag = FALSE, /* Flags set/reset by pressing */ cd_paused = FALSE, /* the various pushbuttons */ saved_cd_paused = FALSE, shuffle_flag = FALSE; static unsigned int Track_Address[CD_TRACK_MAX]; /* Save the start address of each CD track */ static int Track_Seconds [CD_TRACK_MAX]; /* Track time (seconds) for each track on CD */ /*============================================================================ ! (Frontend) Routines !=====================*/ void init_icon(); /* Setup CD icon */ int String_To_Pixel(), /* String to Pixel Conversion */ get_icon_size(); /* Which icon-size is needed */ Widget Create_Button(), /* Create button or arrow */ Create_Scale(), /* Create a horizontal scale */ Create_Label(); /* Create a label */ /*=========================================================================== ! (Frontend to Backend) Routines !================================*/ void handle_eject_button(), /* EJECT button callback */ handle_stop_button(), /* STOP button callback */ handle_play_button(), /* START button callback */ handle_pause_button(), /* PAUSE button callback */ handle_replay_button(), /* REPLAY button callback */ handle_shuffle_button(), /* SHUFFLE botton callback */ handle_exit_button(), /* EXIT button callback */ handle_track_decr(), /* DECRement CD track callback */ handle_track_incr(), /* INCRement CD track callback */ handle_track_scale(), /* Track-input slider callback */ handle_time_scale(), /* Track-time slider callback */ handle_volume_scale(), /* Volume-input slider callback */ handle_balance_scale(); /* Balance-input slider callback*/ /*=========================================================================== ! Backend Routines !==================*/ void the_timer(), /* Master program timer */ update_track_time(), /* Update Track-Time Display */ update_time_scale_max(), /* Size time-scale to tracktime */ update_track_info(), /* Update track scale and data */ update_track_max(), /* Update track-max label */ init_track_scale(), /* Init track-scale display */ init_volume_and_balance(), /* Init volume/balance display */ set_volume_and_balance(), /* Set CD volume/balance levels */ reset_pause_button(), /* Reset label to PAUSE */ toggle_pause_label(), /* Toggle label PAUSE/RESUME */ do_shuffle(); /* Do the actual track shuffle */ int get_random_track(); /* Random number generator */ /*=========================================================================== ! (Backend) CD-player specific Routines !=======================================*/ unsigned int read_CD_capacity(), /* # of blocks on current CD */ read_toc_track(); /* Returns start-addr for track */ int read_toc(), /* Get CD table-of-contents */ setup_default_block_size(), /* Set block size = 512 */ play_track(char track_num), /* Play a track on the CD */ play_MSF(), /* Mins/sec/frame format play */ play_partial_track(), /* Plays portion of a track */ pause_cd(), /* Suspend playing */ resume_cd(), /* Resume playing */ stop_unit(), /* Stop the CD player */ eject_cd(), /* Eject the CD */ enable_eject(), /* Allow manual removal of CD */ disable_eject(); /* Don't allow manual removal */ void get_volume(), /* Get current volume of player */ set_volume(), /* Set the volume of the player */ get_status(), /* Read CD table-of-contents */ save_track_time(), /* Save track-time of CD tracks */ bpt(); /* Null Routine */ /*=========================================================================== ! VMS specific routines !======================*/ int execute_command(); /* Sends the actual SCSI cmds */ /* to the CD-player */ void exit_handler(), /* Stop CD/Deassign Channel/etc */ alloc_cd_channel(), /* Assigns a channel to CD */ dealloc_cd_channel(); /* Deassign CD channel */ /*=========================================================================== ! List of Widgets (Frontend) !============================*/ Widget toplevel, main_window, work_area, rc, eject_button, stop_button, play_button, pause_button, replay_button, shuffle_button, exit_button, decrArrow, incrArrow, volume_scale, balance_scale, track_scale, time_scale, trackMax, trackTime, trackFrame, trackLabel, arrowsLabel; /*===========================================================================*/ /*===========================================================================*/ /* Other Declarations !====================*/ static Display *display; /* Holds display id */ XtAppContext ctx; Pixel color; Arg args[20]; int n; /* Generic arg counter */ unsigned long int random_number = 1; /* Holds random numbers required*/ /* for SHUFFLE operation */ /*===========================================================================*/ /*===========================================================================*/ /*===========================================================================*/ /*===========================================================================*/ /* BEGIN MAIN ROUTINE */ main(argc, argv) int argc; char **argv; { /*======================================================================= ! Create our application shell, and our main window. !=======================================================================*/ toplevel = XtInitialize( /* Create ApplicationShell */ "Audio", /* Name */ "CD", /* Class */ NULL, /* Options */ 0, /* Number of options */ &argc, /* Address of argc */ argv); /* Arg value */ main_window = XmCreateMainWindow ( /* Create main-window */ toplevel, /* Parent */ "Main", /* name */ args, 0); /* args, # of args */ XtManageChild(main_window); display = XtDisplay(toplevel); /*======================================================================= ! Create a bulletin-board as our work-area, and manage via a row-column !=======================================================================*/ n = 0; /* Set bulletin-board resources */ XtSetArg( args[n], XmNwidth, 580); ++n; XtSetArg( args[n], XmNheight, 100); ++n; XtSetArg( args[n], XmNresizePolicy, XmRESIZE_NONE); ++n; color = String_To_Pixel (DEFAULT_BACKGROUND); XtSetArg( args[n], XmNbackground, color); ++n; work_area = XmCreateBulletinBoard ( /* Create bulletin-board */ main_window, /* Parent */ "Work", /* name */ args, n); /* args, # of args. */ XtManageChild(work_area); n = 0; /* Init arg count */ XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n; /* Lay it flat */ XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n; /* How to pack */ XtSetArg( args[n], XmNspacing, 5); ++n; XtSetArg( args[n], XmNx, 150); ++n; XtSetArg( args[n], XmNy, 85); ++n; color = String_To_Pixel (DEFAULT_BACKGROUND); XtSetArg( args[n], XmNbackground, color); ++n; rc = XmCreateRowColumn ( /* Create row-col widget inst */ work_area, /* Parent */ "RowCol", /* Name */ args, n); /* Arglist, Arg count */ XtManageChild(rc); /*======================================================================= ! Now create a EJECT (i.e. EJECT the CD) pushbutton. ! Inputs: parent, name/label, PUSH_BUTTON/ARROW_LEFT/ARROW_RIGHT, ! X, Y, height, width, foreground, background, display-id !=======================================================================*/ eject_button = Create_Button (rc, " EJECT ", PUSH_BUTTON, NOT_USED, NOT_USED, BUTTON_HEIGHT, BUTTON_WIDTH, DEF_PUSHBUTTON_FOREGROUND, DEF_PUSHBUTTON_BACKGROUND, display); XtManageChild(eject_button); XtAddCallback(eject_button, XmNactivateCallback, handle_eject_button, NULL); /*======================================================================= ! Now create a STOP (i.e. STOP the CD) pushbutton. ! Inputs: parent, name/label, PUSH_BUTTON/ARROW_LEFT/ARROW_RIGHT, ! X, Y, height, width, foreground, background, display-id !=======================================================================*/ stop_button = Create_Button (rc, " STOP ", PUSH_BUTTON, NOT_USED, NOT_USED, BUTTON_HEIGHT, BUTTON_WIDTH, DEF_PUSHBUTTON_FOREGROUND, DEF_PUSHBUTTON_BACKGROUND, display); XtManageChild(stop_button); XtAddCallback(stop_button, XmNactivateCallback, handle_stop_button, NULL); /*======================================================================= ! Now create a PLAY CD pushbutton. !=======================================================================*/ play_button = Create_Button (rc, " PLAY ", PUSH_BUTTON, NOT_USED, NOT_USED, BUTTON_HEIGHT, BUTTON_WIDTH, DEF_PUSHBUTTON_FOREGROUND, DEF_PUSHBUTTON_BACKGROUND, display); XtManageChild(play_button); XtAddCallback(play_button, XmNactivateCallback, handle_play_button, NULL); /*======================================================================= ! Now create a PAUSE (i.e. pause/resume selection) pushbutton. !=======================================================================*/ pause_button = Create_Button (rc, "PAUSE ", PUSH_BUTTON, NOT_USED, NOT_USED, BUTTON_HEIGHT, BUTTON_WIDTH, DEF_PUSHBUTTON_FOREGROUND, DEF_PUSHBUTTON_BACKGROUND, display); XtManageChild(pause_button); XtAddCallback(pause_button, XmNactivateCallback, handle_pause_button, NULL); /*======================================================================= ! Now create a REPLAY (i.e. play last song) pushbutton. !=======================================================================*/ replay_button = Create_Button (rc, "REPLAY", PUSH_BUTTON, NOT_USED, NOT_USED, BUTTON_HEIGHT, BUTTON_WIDTH, DEF_PUSHBUTTON_FOREGROUND, DEF_PUSHBUTTON_BACKGROUND, display); XtManageChild(replay_button); XtAddCallback(replay_button, XmNactivateCallback, handle_replay_button, NULL); /*======================================================================= ! Add in SHUFFLE pushbutton. !=======================================================================*/ shuffle_button = Create_Button (rc, "SHUFFLE", PUSH_BUTTON, NOT_USED, NOT_USED, BUTTON_HEIGHT, BUTTON_WIDTH, DEF_PUSHBUTTON_FOREGROUND, DEF_PUSHBUTTON_BACKGROUND, display); XtManageChild(shuffle_button); XtAddCallback(shuffle_button,XmNactivateCallback,handle_shuffle_button, NULL); /*======================================================================= ! Add in EXIT pushbutton. !=======================================================================*/ exit_button = Create_Button (rc, " EXIT ", PUSH_BUTTON, NOT_USED, NOT_USED, BUTTON_HEIGHT, BUTTON_WIDTH, ALT_PUSHBUTTON_FOREGROUND, ALT_PUSHBUTTON_BACKGROUND, display); XtManageChild(exit_button); XtAddCallback(exit_button, XmNactivateCallback, handle_exit_button, NULL); /*======================================================================= ! Add decrement-track Arrow button. !=======================================================================*/ decrArrow = Create_Button (work_area, "DECR", ARROW_LEFT, 170, 15, 40, 60, ARROW_FOREGROUND, ARROW_BACKGROUND, display); XtManageChild(decrArrow); XtAddCallback(decrArrow, XmNactivateCallback, handle_track_decr, NULL); /*======================================================================= ! Add increment-track Arrow button. !=======================================================================*/ incrArrow = Create_Button (work_area, "INCR", ARROW_RIGHT, 240, 15, 40, 60, ARROW_FOREGROUND, ARROW_BACKGROUND, display); XtManageChild(incrArrow); XtAddCallback(incrArrow, XmNactivateCallback, handle_track_incr, NULL); /*======================================================================= ! Add a scale widget to show current volume-level set on the CD. ! Inputs: parent, name/label, X, Y, scale-size, ! scale-min, scale-max, initial scale value, ! foreground color, background color, ! bottom shadow color, top shadow color, ! display-id ! ! Note: Start scale at 0, no matter what the actual volume-level min ! value is. !=======================================================================*/ volume_scale = Create_Scale (work_area, "Volume", " Volume Level", 0, 1, 130, VOLUME_MINIMUM - VOLUME_MINIMUM, VOLUME_MAXIMUM - VOLUME_MINIMUM, VOLUME_DEFAULT - VOLUME_MINIMUM, DEFAULT_FOREGROUND, DEFAULT_BACKGROUND, BOTTOM_SHADOW_COLOR, TOP_SHADOW_COLOR, HORIZONTAL_SCALE, display); XtManageChild(volume_scale); XtAddCallback(volume_scale,XmNvalueChangedCallback,handle_volume_scale, NULL); balance_scale = Create_Scale (work_area, "Balance", "(L) Balance (R)", 0, 70, 130, -BALANCE_SCALE_MAX, BALANCE_SCALE_MAX, 0, DEFAULT_FOREGROUND, DEFAULT_BACKGROUND, BOTTOM_SHADOW_COLOR, TOP_SHADOW_COLOR, HORIZONTAL_SCALE, display); XtManageChild(balance_scale); XtAddCallback(balance_scale , XmNvalueChangedCallback, handle_balance_scale, NULL); /*======================================================================= ! Add a scale widget to show current TRACK-SELECTED on the CD. ! Inputs: parent, name/label, X, Y, scale-size, ! scale-min, scale-max, initial scale value, ! foreground color, background color, ! bottom shadow color, top shadow color, ! display-id ! ! Note: Scale can also be used to change track #. !=======================================================================*/ track_scale = Create_Scale (work_area, "This_Track", " Track Now Playing", 320, 1, 180, CD_TRACK_MIN, CD_TRACK_MAX, CD_TRACK_MIN, DEFAULT_FOREGROUND, DEFAULT_BACKGROUND, BOTTOM_SHADOW_COLOR, TOP_SHADOW_COLOR, HORIZONTAL_SCALE, display); XtManageChild(track_scale); XtAddCallback(track_scale,XmNvalueChangedCallback,handle_track_scale, NULL); /*======================================================================= ! Add a scale widget to show track-time !=======================================================================*/ time_scale = Create_Scale (work_area, "Time_Scale", "", 625, 20, 20, 0, 999, 0, DEFAULT_FOREGROUND, DEFAULT_BACKGROUND, BOTTOM_SHADOW_COLOR, TOP_SHADOW_COLOR, VERTICAL_SCALE, display); XtManageChild(time_scale); XtAddCallback(time_scale, XmNvalueChangedCallback, handle_time_scale, NULL); /*======================================================================= ! Add label widgets to display highest track. ! Inputs: Parent, Name, Actual Label, x,Y, height, width, ! foreground color, background color, display id. !=======================================================================*/ n = 0; trackMax = Create_Label (work_area, "TM", "99", 500, 25, 30, 30, DEFAULT_FOREGROUND, DEFAULT_BACKGROUND, display); XtManageChild(trackMax); /*======================================================================= ! Add Frame widget to frame the TRACK-TIME. ! Inputs: Parent, Name, Actual Label, x,Y, height, width, ! foreground color, background color, display id. !=======================================================================*/ n = 0; /* Init arg count */ XtSetArg( args[n], XmNx, 550); ++n; /* X Location */ XtSetArg( args[n], XmNy, 20); ++n; /* Y Location */ XtSetArg( args[n], XmNshadowType, /* Type of frame effect */ XmSHADOW_ETCHED_IN); ++n; color = String_To_Pixel (TOP_SHADOW_COLOR); /* Frame shadow colors */ XtSetArg( args[n], XmNtopShadowColor, color); ++n; color = String_To_Pixel (BOTTOM_SHADOW_COLOR); XtSetArg( args[n], XmNbottomShadowColor, color); ++n; XtSetArg( args[n], XmNshadowThickness, SHADOW_THICKNESS+2); ++n; trackFrame = XmCreateFrame ( /* Create Frame widget inst */ work_area, /* Parent */ "tFrame", /* Name */ args, n); /* Arglist, Arg count */ XtManageChild(trackFrame); /*======================================================================= ! Add label widgets to display TRACK-TIME. ! Inputs: Parent, Name, Actual Label, x,Y, height, width, ! foreground color, background color, display id. !=======================================================================*/ n = 0; trackTime = Create_Label (trackFrame, "L1", "00:00", 0, 0, 30, 60, TRACK_TIME_FOREGROUND, TRACK_TIME_BACKGROUND, display); XtManageChild(trackTime); /*======================================================================= ! Add label widget to add label to track-time display. !=======================================================================*/ trackLabel = Create_Label (work_area, "L2", "Track Time", 540, 55, 30, 70, DEFAULT_FOREGROUND, DEFAULT_BACKGROUND, display); XtManageChild(trackLabel); /*======================================================================= ! Add label widget to add label to Incr/Decr Arrows. !=======================================================================*/ arrowsLabel = Create_Label (work_area, "L3", "Select Track", 165, 55, 30, 140, DEFAULT_FOREGROUND, DEFAULT_BACKGROUND, display); XtManageChild(arrowsLabel); /*======================================================================= ! Now lets realize everything, allocate the CD, setup our timer ! (typically to run once per second), and go into our event loop !=======================================================================*/ XtRealizeWidget (toplevel); /* Lets bring all the widgets up */ init_icon(); /* Setup the Cd-player icon */ alloc_cd_channel(); /* Allocate a channel for the CD */ setup_default_block_size(); the_timer (); /* And start the clock timer */ update_time_scale_max(); /* Make sure time_scale is correct */ enable_eject (); /* Allow eject until unit is started */ init_volume_and_balance (); /* Get current volume-levels from CD */ /* And set the balance/volume sliders */ XtMainLoop (); } /* END MAIN ROUTINE */ /*==========================================================================*/ /*==========================================================================*/ /*==========================================================================*/ /*==========================================================================*/ /*============================================================================ ! init_icon Routine. ! Initialize/select the CD-reader icon. The icons that have been included ! in this program are of equal width and height, and the code assumes this ! (i.e. if icon changes are made, then coding changes may also have to ! be made). !============================================================================*/ void init_icon() { int i, icon_size; Arg ArgL [2]; Window icon_window_id = XtWindow(main_window); icon_size = get_icon_size(); /* 0=none set */ if (icon_size == 0 || icon_size < MEDIUM_ICON_WIDTH) /* Use smallest icon */ { cd_icon = XCreateBitmapFromData(display, icon_window_id, small_icon_bits, SMALL_ICON_WIDTH, SMALL_ICON_HEIGHT); } else { if (icon_size < LARGE_ICON_WIDTH) /* Use medium icon */ { cd_icon = XCreateBitmapFromData(display, icon_window_id, medium_icon_bits, MEDIUM_ICON_WIDTH, MEDIUM_ICON_HEIGHT); } else /* Use largest icon */ { cd_icon = XCreateBitmapFromData(display, icon_window_id, large_icon_bits, LARGE_ICON_WIDTH, LARGE_ICON_HEIGHT); } } i = 0; XtSetArg (ArgL[i], XmNiconPixmap, cd_icon); i++; /* Set PIXMAP */ XtSetArg (ArgL[i], XmNiconName, ICON_LABEL); i++; /* And label */ XtSetValues (toplevel, ArgL, i); } /*============================================================================ ! get_icon_size Routine. ! Get the size of the icon in-use. Return the largest dimension. !============================================================================*/ int get_icon_size () { XIconSize *size_list; int num_sizes, status; Window root_window = XDefaultRootWindow (display); status = XGetIconSizes (display, root_window, &size_list, &num_sizes); if (status == 0) /* If no icon-size set then */ { /* return 0. Otherwise return */ return 0; /* the greater dimension... */ } /* icon-width or icon-height */ else { if (size_list->max_width > size_list->max_height) { return size_list->max_width; } else { return size_list->max_height; } } } /*============================================================================ ! Create_Button Routine. ! Routine to create the Push or Arrow Buttons on the CD. The widget-name ! is returned. Note that X & Y locations are only used if > 0. !============================================================================*/ Widget Create_Button ( Widget theParent, /* Name of parent */ char theName[], /* Name of the button */ int button_type, /* Push or Arrow left/right */ int xLoc, /* X location in window */ int yLoc, /* Y location in window */ int height, /* Height (in pixels) of button */ int width, /* Width (in pixels) of button */ char f_color[], /* Foreground color */ char b_color[], /* Background color */ Display *dpy) /* Display id */ { Widget wgt; /* Widget instance produced */ Pixel color; /* Pixel color fore/back ground */ Arg ArgL[20]; /* Argument list */ int i; i = 0; /* Init arg count */ if (xLoc > NOT_USED) { XtSetArg( ArgL[i], XmNx, xLoc); ++i; /* X position for button*/ } if (yLoc > NOT_USED) { XtSetArg( ArgL[i], XmNy, yLoc); ++i; /* Y position for button*/ } XtSetArg( ArgL[i], XmNheight, height); ++i; /* Height (in pixels) */ XtSetArg( ArgL[i], XmNwidth, width); ++i; /* Width (in pixels) */ color = String_To_Pixel (f_color); /* Get (pixel) color */ XtSetArg( ArgL[i], XmNforeground,color); ++i; /* Set foreground color */ color = String_To_Pixel (b_color); /* Get (pixel) color */ XtSetArg( ArgL[i], XmNbackground,color); ++i; /* Set background color */ color = String_To_Pixel (BOTTOM_SHADOW_COLOR); XtSetArg( ArgL[i], XmNbottomShadowColor, color); ++i; color = String_To_Pixel (TOP_SHADOW_COLOR); XtSetArg( ArgL[i], XmNtopShadowColor, color); ++i; XtSetArg( ArgL[i], XmNshadowThickness, SHADOW_THICKNESS); ++i; XtSetArg( ArgL[i], XmNrecomputeSize, True); ++i; if (button_type == PUSH_BUTTON) /* Standard PushButton? */ { /* (Yes) */ wgt = XmCreatePushButton( /* Create Pushbutton */ theParent, /* Parent */ theName, /* Name */ ArgL, i); /* Arglist, Arg count */ } else /* (No) */ { /* Must be an Arrow Button. */ if (button_type == ARROW_RIGHT) /* set RIGHT direction */ { XtSetArg( ArgL[i], XmNarrowDirection, XmARROW_RIGHT); ++i; } else /* (or) */ { /* set LEFT direction */ XtSetArg( ArgL[i], XmNarrowDirection, XmARROW_LEFT); ++i; } /* (Now) */ wgt = XmCreateArrowButton( /* Create Arrow Button */ theParent, /* Parent */ theName, /* Name */ ArgL, i); /* Arglist, Arg count */ } return(wgt); /* Return pushbutton/widget. */ } /*============================================================================ ! Create_Scale Routine. ! Add a scale widget to show current TRACK-SELECTED on the CD. ! Inputs: parent, name, title/label, X, Y, scale-size, ! scale-min, scale-max, initial scale value, ! bg color, fg color, ! bottom shadow color, top shadow color, ! display-id !============================================================================*/ Widget Create_Scale ( Widget theParent, /* Name of parent */ char theLabel[], /* Name of the scale */ char theTitle[], /* Title/label of the scale */ int xLoc, /* X location in window */ int yLoc, /* Y location in window */ int sSize, /* Size of the scale (pixels) */ int sMin, /* Scale minimum value */ int sMax, /* Scale maximum value */ int sInit, /* Scale initial value */ char sf_color[], /* Foreground color */ char sb_color[], /* Background color */ char bs_color[], /* Bottom shadow color */ char ts_color[], /* Top shadow color */ int s_orientation, /* vertical or horizontal */ Display *dpy) /* Display id */ { Widget wgt; /* Widget instance produced */ Pixel color; /* Pixel color */ XmString Ctitle; /* Compound-string for title */ Arg ArgL[20]; /* Argument list */ int i; i = 0; /* Init arg count */ XtSetArg( ArgL[i], XmNsensitive, True); ++i; /* Allow input */ XtSetArg( ArgL[i], XmNx, xLoc); ++i; /* X position for scale. */ XtSetArg( ArgL[i], XmNy, yLoc); ++i; /* Y position for scale. */ XtSetArg( ArgL[i], XmNscaleWidth, sSize); ++i;/* How big is scale */ XtSetArg( ArgL[i], XmNshowValue, True); ++i; /* Do show value */ XtSetArg( ArgL[i], XmNminimum, sMin); ++i; /* Min scale */ XtSetArg( ArgL[i], XmNmaximum, sMax); ++i; /* Max scale */ XtSetArg( ArgL[i], XmNvalue, sInit); ++i; /* Initital scale value */ color = String_To_Pixel (sf_color); /* Get (pixel) color */ XtSetArg( ArgL[i], XmNforeground,color); ++i; /* Set foreground color */ color = String_To_Pixel (sb_color); /* Get (pixel) color */ XtSetArg( ArgL[i], XmNbackground,color); ++i; /* Set background color */ color = String_To_Pixel (bs_color); /* Get (pixel) color */ XtSetArg( ArgL[i], XmNbottomShadowColor,color); ++i; color = String_To_Pixel (ts_color); /* Get (pixel) color */ XtSetArg( ArgL[i], XmNtopShadowColor,color); ++i; XtSetArg( ArgL[i], XmNshadowThickness, SHADOW_THICKNESS); ++i; Ctitle = XmStringCreateSimple (theTitle); /* Compound-str title */ XtSetArg( ArgL[i], XmNtitleString, Ctitle); ++i; /* Set Scale title */ if (s_orientation == VERTICAL_SCALE) { XtSetArg( ArgL[i], XmNorientation, XmVERTICAL); ++i; } else { XtSetArg( ArgL[i], XmNorientation, XmHORIZONTAL); ++i; } wgt = XmCreateScale( /* Create Scale */ theParent, /* Parent */ theLabel, /* Name */ ArgL, i); /* Arglist, Arg count */ XmStringFree (Ctitle); /* Free up memory for title */ return(wgt); /* Return scale/widget */ } /*============================================================================ ! Create_Label Routine. ! Add a label widget. Inputs to this routine are: ! Parent, Name of widget, Label, X, Y, height, width, colors & display-id. !============================================================================*/ Widget Create_Label ( Widget theParent, /* Name of parent */ char theName[], /* Name of the label */ char theLabel[], /* Text for the label */ int xLoc, /* X location in window */ int yLoc, /* Y location in window */ int height, /* height of label. */ int width, /* width of the label */ char f_color[], /* Foreground color */ char b_color[], /* Background color */ Display *dpy) /* Display id */ { Widget wgt; /* Widget instance produced */ Pixel color; /* Pixel color */ XmString Clabel; /* Compound-string label */ Arg ArgL[10]; /* Argument list */ int i; i = 0; color = String_To_Pixel (f_color); XtSetArg( ArgL[i], XmNforeground, color); ++i; color = String_To_Pixel (b_color); XtSetArg( ArgL[i], XmNbackground, color); ++i; XtSetArg( ArgL[i], XmNx, xLoc); ++i; /* X position */ XtSetArg( ArgL[i], XmNy, yLoc); ++i; /* Y position */ XtSetArg( ArgL[i], XmNheight, height);++i; /* Height (in pixels) */ XtSetArg( ArgL[i], XmNwidth, width); ++i; /* Width (in pixels) */ XtSetArg( ArgL[i], XmNlabelType, XmSTRING); ++i; Clabel = XmStringCreateSimple (theLabel); /* Compound-str label */ XtSetArg( ArgL[i], XmNlabelString, Clabel); ++i; /* Set string */ wgt = XmCreateLabel( /* Create Label Widget instance */ theParent, /* Parent */ theName, /* Name */ ArgL, i); /* Arglist, Arg count */ XmStringFree (Clabel); /* Free up memory from string */ return(wgt); /* Return Label widget */ } /*============================================================================ ! String_To_Pixel Routine. ! This routine returns a pixel value when passed a named color. ! Note: Variable "display" has been previously declared. !============================================================================*/ String_To_Pixel(char *spec) { int i; Colormap cmap; XColor color_struct; cmap = XDefaultColormap(display, DefaultScreen(display)); i = XParseColor(display, cmap, spec, &color_struct); i = XAllocColor(display, cmap, &color_struct); return(color_struct.pixel); } /*============================================================================ ! handle_eject_button Routine. Eject the current cd playing. !============================================================================*/ void handle_eject_button( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { play_flag = FALSE; /* Set flag to show not started */ cd_paused = FALSE; /* CD is not paused */ shuffle_flag = FALSE; /* Not in shuffle mode */ enable_eject(); /* Allow the CD to program-eject */ stop_unit(); /* Spin down the CD (if playing) */ eject_cd(); /* Eject the CD */ reset_pause_button(); /* Set label to PAUSE & flag = FALSE */ init_track_scale(); /* Init "track now playing" display */ } /*============================================================================ ! handle_stop_button Routine. Stop the current cd playing. !============================================================================*/ void handle_stop_button( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { play_flag = FALSE; /* Set flag to show not started */ cd_paused = FALSE; /* CD is not paused */ shuffle_flag = FALSE; /* Not in shuffle mode */ stop_unit(); /* Spin down the CD (if playing) */ reset_pause_button(); /* Set label to PAUSE & flag = FALSE */ enable_eject(); /* Allow removal of CD */ } /*============================================================================ ! handle_play_button Routine. Start CD on track 1. !============================================================================*/ void handle_play_button( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { play_flag = TRUE; /* Set flag to show now-playing */ cd_paused = FALSE; /* CD is not paused */ shuffle_flag = FALSE; /* Not in shuffle mode */ reset_pause_button(); /* Make sure CD is not paused */ get_status(); /* Get information about current CD */ XmScaleGetValue (track_scale, ¤t_track); /* Get track # */ play_track(current_track); /* Start the CD playing */ set_volume_and_balance(); /* Set volume and balance levels on CD */ disable_eject(); /* Disable CD eject. */ update_time_scale_max(); /* Set time-scale to correct setting */ } /*============================================================================ ! handle_pause_button Routine. ! Pause the current CD, and change the button label from "PAUSE" to "RESUME" ! (or) if on "RESUME" then start CD and change button label to "PAUSE". !============================================================================*/ void handle_pause_button( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { if (play_flag == TRUE) { if (cd_paused == FALSE) /* Were we paused already? */ { /* (No) */ cd_paused = TRUE; /* Set Flag */ toggle_pause_label(); /* Change the button label */ pause_cd(); /* Send PAUSE command to CD */ } else { /* (Yes -- we were paused already) */ cd_paused = FALSE; /* Reset the flag */ toggle_pause_label(); /* Change the button label */ resume_cd(); /* Send RESUME command to CD */ } } } /*============================================================================ ! handle_replay_button Routine. Replay the current track on the CD. !============================================================================*/ void handle_replay_button( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { shuffle_flag = FALSE; /* Not in shuffle mode */ if (play_flag = TRUE && cd_paused == FALSE) { play_track(current_track); /* Play the current track again */ set_volume_and_balance(); /* Set volume and balance levels on CD */ disable_eject(); /* Disable removal of CD */ } } /*============================================================================ ! handle_shuffle_button Routine. ! Play tracks in a random order. Keep playing in a random order until some ! other button is pushed, or until total_tracks * n are played. !===========================================================================*/ void handle_shuffle_button( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { if (play_flag == TRUE && cd_paused == FALSE) { shuffle_flag = TRUE; do_shuffle(); /* Play a random track */ } } /*=========================================================================== ! handle_exit_button Routine. Used to exit the program. !===========================================================================*/ void handle_exit_button( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { XtCloseDisplay(XtDisplay(wgt)); /* Get rid of CD panel display */ enable_eject(); /* Allow the CD to eject */ dealloc_cd_channel(); /* Deassign the channel */ exit(0); /* Bye-Bye */ } /*============================================================================ ! handle_track_decr Routine. ! Callback for the << arrow button. Decrement the track count by one, and ! update the display. If track count is less than track-min, then set to ! track-max. !============================================================================*/ void handle_track_decr ( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { int this_track, next_track; shuffle_flag = FALSE; /* Not in shuffle-mode */ if (play_flag == TRUE && cd_paused == FALSE) { XmScaleGetValue (track_scale, &this_track); next_track = --this_track; if (next_track < 1) { next_track = total_tracks; } play_track (next_track); /* Start track playing */ set_volume_and_balance(); /* Set vol & bal levels on CD */ } } /*============================================================================ ! handle_track_incr Routine. ! Callback for the >> arrow button. Increment the track count by one, and ! update the select-track display. If track count is greater than track-max, ! then set to track-min. !============================================================================*/ void handle_track_incr ( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { int this_track, next_track; shuffle_flag = FALSE; /* Hot in shuffle-mode */ if (play_flag == TRUE && cd_paused == FALSE) { XmScaleGetValue (track_scale, &this_track); next_track = this_track + 1; if (next_track > total_tracks) { next_track = 1; } play_track (next_track); /* Start track playing */ set_volume_and_balance(); /* Set vol & bal levels on CD */ } } /*============================================================================ ! handle_time_scale Routine. ! Callback for track-time slider input. !============================================================================*/ void handle_time_scale ( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { } /*============================================================================ ! handle_track_scale Routine. ! Callback for track-slider input. Get new slider value, and update the ! CD playing. This allows the slider to be used for input, as well as output. !============================================================================*/ void handle_track_scale ( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { int this_track; shuffle_flag = FALSE; /* Hot in shuffle-mode */ if (play_flag == TRUE && cd_paused == FALSE) { XmScaleGetValue (track_scale, &this_track); play_track (this_track); /* Start track playing */ set_volume_and_balance(); /* Set vol & bal levels on CD */ } } /*============================================================================ ! handle_volume_scale Routine. ! Callback for volume-slider input. Get the slider-value from the display ! panel, and update the actual volume-level in the cd-player. Note that ! the volume-slider starts at 0 (i.e. VOLUME_DEFAULT - VOLUME_MINIMUM) while ! the actual volume-level put into the CD starts at VOLUME_MINIMUM. !============================================================================*/ void handle_volume_scale ( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { set_volume_and_balance(); /* Set vol & bal levels on CD */ } /*============================================================================ ! handle_balance_scale Routine. ! Callback for balance-slider input. Get the slider-value from the display ! panel, and set the balance between the left and right channels ! (i.e. channels 0 & 1). !============================================================================*/ void handle_balance_scale ( Widget wgt, caddr_t client_data, XmAnyCallbackStruct *call_data) { set_volume_and_balance(); /* Set vol & bal levels on CD */ } /*============================================================================ ! the_timer Routine. ! This routine is a timer which runs, gets the track-time status, updates ! the track-time, and then registers itself as a timeout callback to be ! called again. This routine is executed once every TIMER_INTERVAL, which ! is typically every one second. ! ! The routine also handles automatic track SHUFFLE after the initial ! button-press. ! ! Note: The CD-player will automatically go to the next track after the ! current track is finished playing. !============================================================================*/ void the_timer () { if (shuffle_flag == TRUE) /* Are we shuffling CD */ { /* (yes)... did the CD */ if (current_track != random_track) /* player shift to next */ { /* track? (yes)... get */ do_shuffle(); /* another random one */ random_total = random_total + 1; /* BUT... let's not */ if (random_total >= total_tracks*4) /* play on forever */ { shuffle_flag = FALSE; random_total = 0; stop_unit(); } } } get_status(); /* Get CD status */ update_track_info(); /* Inc track/time scale */ update_track_time(); /* and track-time clock*/ get_volume(); /* Get current volume */ XtAddTimeOut (TIMER_INTERVAL, the_timer); /* & reset timeout */ } /*============================================================================ ! update_track_time Routine. ! This is the common routine for updating the track-time display. ! It is called by the one second timer routine as well as by the button ! callback routines. If the player state has changed, then update the ! appropriate button/slider on the display. !============================================================================*/ void update_track_time () { Arg ArgL[5]; char track_time_char[6]; XmString the_track_time; int track_time_min, time_remaining, max_time, i = 0; /*===================================================================== ! 1st lets update the track-time display !====================================================================*/ track_time_min = track_time_sec / 60; /* Figure out time */ track_time_char [0] = track_time_min / 10 + '0'; track_time_char [1] = track_time_min % 10 + '0'; track_time_char [2] = ':'; track_time_char [3] = (track_time_sec % 60) / 10 + '0'; track_time_char [4] = (track_time_sec % 60) % 10 + '0'; track_time_char [5] = '\0'; the_track_time = XmStringCreateSimple (track_time_char); /* cvt to compound str */ XtSetArg( ArgL[i], XmNlabelString, the_track_time); ++i; /* Set arg for new time */ XtSetValues(trackTime, ArgL, i); /* Update time-display */ XmStringFree (the_track_time); /* Recover memory */ /*===================================================================== ! And now the track-time scale !====================================================================*/ time_remaining = Track_Seconds [current_track] - track_time_sec ; XmScaleGetValue (time_scale, &max_time); /* Get scale-max */ if (time_remaining > max_time) /* Make sure we don't */ { /* exceed scale */ i = 0; XtSetArg( ArgL[i], XmNmaximum, time_remaining); i++; XtSetValues(time_scale, ArgL, i); /* Do display update */ } XmScaleSetValue (time_scale, time_remaining); } /*============================================================================ ! update_time_scale_max Routine. ! Update/reset the maximum value on the time_scale. !============================================================================*/ void update_time_scale_max() { int i = 0; Arg ArgL[5]; XtSetArg( ArgL[i], XmNminimum, 0); ++i; XtSetArg( ArgL[i], XmNvalue, 0); ++i; if (Track_Seconds[current_track] > 0 && current_track > 0) { XtSetArg( ArgL[i], XmNmaximum, Track_Seconds[current_track]); ++i; } else { XtSetArg( ArgL[i], XmNmaximum, 999); ++i; } XtSetValues(time_scale, ArgL, i); /* Do display update */ } /*============================================================================ ! update_track_max Routine. ! Update the label that shows the max track # on the current CD. !============================================================================*/ void update_track_max() { int i; Arg ArgL[5]; char track_max_char[3]; XmString the_track_max; track_max_char[0] = (total_tracks/10) + '0'; /* Stuff into string */ track_max_char[1] = total_tracks % 10 + '0'; track_max_char[2] = '\0'; the_track_max = XmStringCreateSimple (track_max_char); /* cvt to compound str */ i = 0; XtSetArg( ArgL[i], XmNlabelString, the_track_max); ++i; /* Set arg for new time */ XtSetValues(trackMax, ArgL, i); /* Update track-max dpy */ XmStringFree (the_track_max); /* Recover memory */ } /*============================================================================ ! update_track_info Routine. ! This is the common routine that does the following: ! 1) Updates display if necessary. ! 2) Check to see if old CD has been removed (and updates display). ! 3) If there is a new CD... we save the track time for each track. !============================================================================*/ void update_track_info() { Arg ArgL[5]; /* Argument list */ int i = 0, /* Argument counter */ this_track; /* Track # from track_scale */ /* Make sure track_scale reflects the current track playing !==========================================================*/ XmScaleGetValue (track_scale, &this_track); if (this_track != current_track) { XmScaleSetValue (track_scale, current_track); } /* If the old CD is gone then make sure track-scale max is still ok !==================================================================*/ if (saved_total_tracks != total_tracks) /* We've removed old CD */ { if (total_tracks == 0) /* No CD */ { saved_total_tracks = 0; init_track_scale(); update_track_max(); } else /* New CD */ { saved_total_tracks = total_tracks; i = 0; XtSetArg( ArgL[i], XmNmaximum, total_tracks); ++i; XtSetValues(track_scale, ArgL, i); /* Do display update */ save_track_time (); /* Save track-time for each */ /* track on CD (Track_Time[]) */ update_track_max(); /* Display total-tracks on CD */ } } } /*============================================================================ ! init_track_scale Routine. ! Initialize the scale (i.e. set track-slider to initial values). !============================================================================*/ void init_track_scale () { Arg ArgL[5]; /* Argument list */ int i, /* Argument counter */ track_max; /* Top-end for the scale. */ i = 0; if (total_tracks > CD_TRACK_MIN) /* If there's a CD mounted... */ { /* then use its track-count */ track_max = total_tracks; /* to define the scale */ } else { track_max = CD_TRACK_MAX; } /* Update scale */ /*====================*/ XtSetArg( ArgL[i], XmNminimum, CD_TRACK_MIN); ++i; XtSetArg( ArgL[i], XmNvalue, CD_TRACK_MIN); ++i; XtSetArg( ArgL[i], XmNmaximum, track_max); ++i; XtSetValues (track_scale, ArgL, i); current_track = CD_TRACK_MIN; } /*============================================================================ ! init_volume_and_balance routine ! Initialize the balance and volume sliders. Try and use the current settings ! off of the cd-player itself. Note: get_volume() modifies the variables ! current_volume, left_volume, and right_volume. !============================================================================*/ void init_volume_and_balance () { int L_volume, R_volume, C_volume, balance_setting; get_volume (); /* Get values off of cd-player */ L_volume = left_volume; R_volume = right_volume; C_volume = current_volume; if (L_volume < VOLUME_MINIMUM) /* We need default values for */ L_volume = VOLUME_DEFAULT; /* slider calculations */ if (R_volume < VOLUME_MINIMUM) R_volume = VOLUME_DEFAULT; if (C_volume < VOLUME_MINIMUM) C_volume = VOLUME_DEFAULT; /*--------------------------------------------------- ! Calculate the correct balance-slider setting from ! the actual volume levels gotten from the cd-player. !----------------------------------------------------*/ if (L_volume > R_volume) { balance_setting = -BALANCE_SCALE_MAX + (BALANCE_SCALE_MAX * (R_volume - VOLUME_MINIMUM))/ (L_volume - VOLUME_MINIMUM); } else { if (L_volume < R_volume) { balance_setting = BALANCE_SCALE_MAX - (BALANCE_SCALE_MAX * (L_volume - VOLUME_MINIMUM))/ (R_volume - VOLUME_MINIMUM); } else { balance_setting = 0; } } /*--------------------------------------------------- ! Now set the balance and volume sliders. !----------------------------------------------------*/ XmScaleSetValue (balance_scale, balance_setting); XmScaleSetValue (volume_scale, C_volume - VOLUME_MINIMUM ); } /*============================================================================ ! set_volume_and_balance Routine. ! Get the balance-level, and the volume-level, and set the CD accordingly. ! Note that the volume is set to (VOLUME_MINIMUM + volume_scale), unless ! scale is zero, and then volume is set to zero. ! (i.e. channels 0 & 1). !============================================================================*/ void set_volume_and_balance() { int new_balance, new_volume, L_volume, R_volume; XmScaleGetValue (volume_scale, &new_volume); /* Get volume */ if (new_volume == 0) /* If scale is 0... then turn */ { /* volume all the way off */ current_volume = VOLUME_OFF; left_volume = VOLUME_OFF; right_volume = VOLUME_OFF; } else /* Else set to minimum + scale */ { current_volume = new_volume + VOLUME_MINIMUM; XmScaleGetValue (balance_scale, &new_balance); /* Get balance */ if (new_balance <= 0) /* Convert to volume levels for */ { /* left and right channels */ L_volume = current_volume; R_volume = current_volume + (((current_volume - VOLUME_MINIMUM) * new_balance)/ BALANCE_SCALE_MAX ); } else { L_volume = current_volume - (((current_volume - VOLUME_MINIMUM) * new_balance)/ BALANCE_SCALE_MAX ); R_volume = current_volume; } left_volume = L_volume; /* Save left-channel volume */ right_volume= R_volume; /* Save right-channel volume */ } set_volume(left_volume, right_volume);/* Go out and actually change */ /* the volume on the CD-player */ } /*============================================================================ ! reset_pause_button Routine. ! Reset the PAUSE button (i.e. make sure it says PAUSE, and make sure that ! "cd_paused" is set to FALSE. !============================================================================*/ void reset_pause_button () { Pixel color; /* Needed for changing bg color */ XmString Cpause; /* Compound-str for pause label */ Arg ArgL[5]; /* Argument list */ int i; /* Arg count */ i = 0; /* Init arg count */ cd_paused = FALSE; /* Reset flag */ color = String_To_Pixel ("Black"); /* Get (pixel) color */ XtSetArg( ArgL[i], XmNbackground,color); ++i; /* Reset color */ Cpause = XmStringCreateSimple ("PAUSE "); /* Cvt to compound-str */ XtSetArg( ArgL[i], XmNlabelString, Cpause); ++i; /* Reset to "PAUSE" */ XtSetValues (pause_button, ArgL, i); /* Actually do changes */ XmStringFree (Cpause); /* Free memory for str */ } /*============================================================================ ! toggle_pause_label Routine. ! Change the pause button from PAUSE to RESUME, or RESUME to PAUSE. !============================================================================*/ void toggle_pause_label () { Pixel color; /* Needed for changing bg color */ XmString Clabel; /* Compound string for label */ Arg ArgL[5]; /* Argument list */ int i; /* Arg count */ i = 0; /* Init arg count */ if (cd_paused == FALSE) { color = String_To_Pixel ("Black"); /* Get (pixel) color */ XtSetArg( ArgL[i], XmNbackground,color); ++i; /* Set color */ Clabel = XmStringCreateSimple ("PAUSE "); /* Create str */ XtSetArg( ArgL[i], XmNlabelString, Clabel); ++i; /* Set label */ } else { color = String_To_Pixel (DEFAULT_FOREGROUND); /* Get color */ XtSetArg( ArgL[i], XmNbackground,color); ++i; /* Set color */ Clabel = XmStringCreateSimple ("RESUME"); /* Create str */ XtSetArg( ArgL[i], XmNlabelString, Clabel); ++i; /* Set label */ } XtSetValues (pause_button, ArgL, i); /* Actually do changes */ XmStringFree (Clabel); /* Free memory for str */ } /*============================================================================ ! do_shuffle Routine. ! Get a random track between 1 and total_tracks. Set the current track # ! to that track, and then play the current_track. Only do a shuffle if a ! CD in the player. !============================================================================*/ void do_shuffle () { if (total_tracks > 0) /* Is CD present? */ { random_track = get_random_track(); /* Get any track # */ while (random_track == old_random_track) /* Make sure it's not */ { /* the one we just */ random_track = get_random_track(); /* played */ } play_track (random_track); /* Play the track */ set_volume_and_balance(); /* Set vol & bal levels on CD */ old_random_track = random_track; /* Save track # */ current_track = random_track; /* Set current-track # */ } } /*============================================================================ ! get_random_track Routine. ! Routine which returns a random track number between 1 and ! total_tracks. Note: We need a better random # generator (but not now). !============================================================================*/ int get_random_track() { random_number = (random_number/(current_track+1)) * 1103515245 + 12345; return (((unsigned int) (random_number/65536) % total_tracks)+1); } /*============================================================================ ! setup_default_block_size Routine. ! This routine changes the default block size of the CD player ! to 512 bytes and is required for correct callibration of ! the track time. The mode select command is tried three times ! because if the device has just been reset, the first two will ! fail. !============================================================================*/ int setup_default_block_size() { char mode_select_command [6] = {MODE_SELECT_OPCODE, 0x10, 0, 0, 12, 0}, mode_select_data [12] = {0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 2, 0}; int i, status; for (i=0; i<3; i++) { status = execute_command (mode_select_command, 6, mode_select_data, 12, WRITE); if (status) return status; bpt (); } return status; } /*============================================================================ ! read_toc Routine. ! This routine reads the table of contents on the CD to determine the ! total number of tracks. !============================================================================*/ int read_toc () { int TTL_tracks = 0, status; char read_toc_command [10] = {READ_TOC_OPCODE, 0, 0, 0, 0, 0, 0, 0, 4, 0}; char toc_data[4]; if (!execute_command (read_toc_command, 10, toc_data, 4, READ)) { TTL_tracks = 0; /* No CD is present */ } else TTL_tracks = toc_data[3] - toc_data[2] + 1; return TTL_tracks; } /*============================================================================ ! read_toc_track Routine. ! This routine reads the table of contents on the CD for the specified track ! and returns the block/address for the start of that track. !============================================================================*/ unsigned int read_toc_track (int track_num) #define READ_THE_TOC 0X43 { unsigned char read_toc_track_command [12] = {READ_THE_TOC, 0, 0, 0, 0, 0, 0, 0, 12, 0}; unsigned char toc_track_data[12]; int track, status; unsigned int addr1, addr2, addr3, addr4, the_addr; read_toc_track_command[6] = track_num; if (!execute_command (read_toc_track_command, 12, toc_track_data, 12, READ)) return FALSE; addr4 = toc_track_data[8]; addr3 = toc_track_data[9]; addr2 = toc_track_data[10]; addr1 = toc_track_data[11]; addr4 = addr4 << 24; /* Do all necessary byte-shifts */ addr3 = addr3 << 16; addr2 = addr2 << 8; the_addr = addr4 + addr3 + addr2 + addr1; /* Final address */ return the_addr; /* And return the block # */ } /*============================================================================ ! save_track_time Routine. ! This routine saves the track-time for each track of the CD in the array ! Track_Seconds []. !============================================================================*/ void save_track_time () { unsigned int track_address[CD_TRACK_MAX], end_of_CD, track_units; int last_track, track, ttl_CD_secs, CD_secs, CD_mins, x; last_track = read_toc(); /* Get total # of tracks on CD */ /* Save track address for each track on current CD */ /*====================================================*/ for (track = 1; track <= last_track; track++) { track_address [track] = read_toc_track (track); } /* Now compute track-time (seconds) for each track) */ /*====================================================*/ for (track = 1; track <= (last_track - 1); track++) /* Except last */ { track_units = track_address[track+1] - track_address[track]; Track_Seconds[track] = track_units / (75 * 4); } end_of_CD = read_CD_capacity (); /* Now last */ if (SHOW_CD_TIME == 1) { ttl_CD_secs = end_of_CD / (75 * 4); CD_mins = ttl_CD_secs / 60; CD_secs = ttl_CD_secs - (CD_mins * 60); printf ("=========================== \n"); printf ("Total CD Play Time = %d:%d \n", CD_mins, CD_secs); } Track_Seconds[last_track] = (end_of_CD - track_address[last_track]) / (75 * 4); } /*============================================================================ ! read_CD_capacity Routine. !============================================================================*/ unsigned int read_CD_capacity () #define CD_CAPACITY 0X25 { unsigned char CD_capacity [10] = {CD_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char CD_capacity_data[12]; unsigned int addr1, addr2, addr3, addr4, the_addr; int x; if (!execute_command (CD_capacity, 10, CD_capacity_data, 12, READ)) { return FALSE; } addr4 = CD_capacity_data[0]; /* Extract the necessary data */ addr3 = CD_capacity_data[1]; addr2 = CD_capacity_data[2]; addr1 = CD_capacity_data[3]; addr4 = addr4 << 24; /* Do byte-shifts */ addr3 = addr3 << 16; addr2 = addr2 << 8; the_addr = addr4 + addr3 + addr2 + addr1; /* Compute address */ return the_addr; /* return the block # */ } /*============================================================================ ! play_track Routine. ! This routine plays the specified track on the CD. !============================================================================*/ int play_track (char track_num) { int status; char play_track_command [10] = {PLAY_TRACK_OPCODE, 0, 0, 0, 0, 1, 0, 0, 1, 0}; play_track_command [4] = track_num; play_track_command [7] = total_tracks; status = execute_command(play_track_command, 10, 0, 0, READ); disable_eject(); return status; } /*============================================================================ ! pause_cd Routine. ! This routine sends a PAUSE command to the CD-player. !============================================================================*/ int pause_cd () { char pause_command [10] = {PAUSE_OPCODE , 0, 0, 0, 0, 0, 0, 0, 0, 0}; return execute_command (pause_command, 10, 0, 0, READ); } /*============================================================================ ! resume_cd Routine. ! This routine sends a RESUME command to the CD-player. !============================================================================*/ int resume_cd () { char resume_command [10] = {RESUME_OPCODE, 0, 0, 0, 0, 0, 0, 0, 1, 0}; return execute_command (resume_command, 10, 0, 0, READ); } /*============================================================================ ! stop_unit Routine. ! This routine sends a stop command the the CD player. !============================================================================*/ int stop_unit() { char stop_command [6] = {STOP_OPCODE , 0, 0, 0, 0, 0}; return execute_command (stop_command, 6, 0, 0, READ); } /*============================================================================ ! eject_cd Routine. ! This routine sends an eject-cd command the the CD player. !============================================================================*/ int eject_cd() { char eject_command [6] = {STOP_OPCODE , 0, 0, 0, 2, 0}; return execute_command (eject_command, 6, 0, 0, READ); } /*============================================================================ ! enable_eject Routine. ! This routine enables the manual removal of a CD. !============================================================================*/ int enable_eject() { char media_enable [6] = {MEDIA_OPCODE , 0, 0, 0, 0, 0}; return execute_command (media_enable, 6, 0, 0, READ); } /*============================================================================ ! disable_eject Routine. ! This routine disables the manual removal of a CD. !============================================================================*/ int disable_eject() { char media_disable [6] = {MEDIA_OPCODE , 0, 0, 0, 1, 0}; return execute_command (media_disable, 6, 0, 0, READ); } /*============================================================================ ! get_volume Routine. ! This routine gets the volume-level from the cd. !============================================================================*/ void get_volume() { int audio_stat = 0, volume_level = 0, volume_ch0 = 0, volume_ch1 = 0, status = 0; char cd_data [14]; char playback_status [10] = {PLAYBACK_STATUS_OPCODE, 0, 0, 0, 0, 0, 0, 0, 14, 0}; status = execute_command (playback_status, 10, cd_data, 14, READ); audio_stat = cd_data[4] & 0377; /* Play/Eject=0, Stop/Pause=1 */ volume_ch0 = cd_data[11] & 0377; /* Volume ch0 (low-order 8 bits)*/ volume_ch1 = cd_data[13] & 0377; /* Volume ch1 (low-order 8 bits)*/ if (volume_ch0 > volume_ch1) /* Make sure the volume-level */ { /* returned is the highest of */ volume_level = volume_ch0; /* the two channels */ } else { volume_level = volume_ch1; } left_volume = volume_ch0; /* Save left-channel volume */ right_volume = volume_ch1; /* Save right-channel volume */ current_volume = volume_level; /* And the higher of the two */ if (volume_level > 0 && audio_stat == 0) { /* Assume we are playing a CD */ play_flag = TRUE; /* if status is 0, and volume */ } /* is not 0 (if volume was 0, */ /* then we could be ejected) */ /* printf ("L= %d R= %d Max = %d Stat= %d\n", left_volume, right_volume, volume_level, audio_stat); */ } /*============================================================================ ! set_volume Routine. ! This routine changes the volume of the cd-player in both channels 0 & 1. !============================================================================*/ void set_volume(int volume_ch0, int volume_ch1) { int status; char playback_control [10] = {PLAYBACK_CONTROL_OPCODE, 0, 0, 0, 0, 0, 0, 0, 14, 0}; char cd_data [14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}; cd_data [10] = 1; cd_data [11] = volume_ch0; cd_data [12] = 2; cd_data [13] = volume_ch1; status = execute_command (playback_control, 10, cd_data, 14, WRITE); } /*============================================================================ ! get_status Routine. ! This routine reads the current status of the CD player to determine the ! total number of tracks, whether the player is playing, and, if so, the ! current track number being played. If any of this information has changed ! since the last time the screen was updated, then the screen is updated ! again. !============================================================================*/ void get_status() { char read_subchan_command [10] = {READ_SUBCHAN_OPCODE, 0, 0x40, 1, 0, 0, 0, 0, 48, 0}; char subchan_data [48]; int i, track_time_units; total_tracks = read_toc(); /* Get total tracks on this CD */ if (total_tracks == 0 || execute_command (read_subchan_command, 10, subchan_data, 48, READ) == FALSE) { current_track = 0; track_time_sec = 0; } else { current_track = subchan_data[6]; /* if (subchan_data[1] == 0x12) cd_paused = TRUE; printf ("Subchannel data: "); for (i=0; i<20; i++) printf (" %02x", subchan_data[i] & 0xff); printf ("\n"); */ track_time_units = (subchan_data[13] & 0xff) * 0x10000 + (subchan_data[14] & 0xff) * 0x100 + (subchan_data[15] & 0xff); /*================================================================== ! The following operation converts the units (blocks from ! beginning of track) in the subchan_data [13], subchan_data [14], ! and subchan_data [15] fields into units of seconds. !==================================================================*/ track_time_sec = track_time_units / (75 * 4); if ((track_time_sec != saved_track_time_sec) && (track_time_sec != (saved_track_time_sec-1))) { saved_track_time_sec = track_time_sec; } if (subchan_data[1] == 0x13) { stop_unit (); } } if (current_track != saved_current_track) { update_time_scale_max(); saved_current_track = current_track; } } /*============================================================================ ! bpt Routine. ! This is a null routine (spin-wheels). !============================================================================*/ void bpt () { } /*============================================================================ ! exit_handler Routine. ! Callback routine for exit button. Stop the CD from playing, deassign ! the channel to the player, and exit. !============================================================================*/ void exit_handler () { stop_unit (); /* spin down the unit */ dealloc_cd_channel(); /* blow away the channel */ exit(1); /* go away */ } /*============================================================================ !============================================================================= !============================================================================= ! Below are the only VMS-SPECIFIC routines in the program: !============================================================================*/ /*============================================================================ ! execute_command Routine. ! This routine sends the specified command to the CD player. It does ! so by filling in the generic class driver descriptor and issuing ! an IO$_DIAGNOSE QIO to GKDRIVER. !============================================================================*/ int execute_command ( int *command_addr, int command_len, int data_addr, int data_len, int rw_flag) /*===================================== ! SCSI Generic Class Driver Constants !=====================================*/ #define FLAGS_READ 1 #define FLAGS_DISCONNECT 2 #define FLAGS_DISCONNECT 2 #define GOOD_SCSI_STATUS 0 #define OPCODE 0 #define FLAGS 1 #define COMMAND_ADDRESS 2 #define COMMAND_LENGTH 3 #define DATA_ADDRESS 4 #define DATA_LENGTH 5 #define PAD_LENGTH 6 #define PHASE_TIMEOUT 7 #define DISCONNECT_TIMEOUT 8 { char request_sense_command [6] = {3, 0, 0, 0, 18, 0}, request_sense_data [18], scsi_status; int gk_iosb[2], gk_desc[15], i, status; gk_desc[OPCODE] = 1; gk_desc[FLAGS] = rw_flag + FLAGS_DISCONNECT; gk_desc[COMMAND_ADDRESS] = command_addr; gk_desc[COMMAND_LENGTH] = command_len; gk_desc[DATA_ADDRESS] = data_addr; gk_desc[DATA_LENGTH] = data_len; gk_desc[PAD_LENGTH] = 0; gk_desc[PHASE_TIMEOUT] = 0; gk_desc[DISCONNECT_TIMEOUT] = 60; for (i=9; i<15; i++) gk_desc[i] = 0; /* Clear reserved fields */ /*====================================================================== ! Issue the QIO to send the inquiry command and receive the inquiry data !=======================================================================*/ status = sys$qiow (1, gk_chan, IO$_DIAGNOSE, gk_iosb, 0, 0, &gk_desc[0], 15*4, 0, 0, 0, 0); /*========================================== ! Check the various returned status values !===========================================*/ if (!(status & 1)) sys$exit (status); if (!(gk_iosb[0] & 1)) sys$exit (gk_iosb[0] & 0xffff); scsi_status = (gk_iosb[1] >> 24) & SCSI_STATUS_MASK; if (scsi_status == GOOD_SCSI_STATUS) return TRUE; if (scsi_status == 2) { bpt (); gk_desc[OPCODE] = 1; gk_desc[FLAGS] = FLAGS_READ + FLAGS_DISCONNECT; gk_desc[COMMAND_ADDRESS] = request_sense_command; gk_desc[COMMAND_LENGTH] = 6; gk_desc[DATA_ADDRESS] = request_sense_data; gk_desc[DATA_LENGTH] = 18; gk_desc[PAD_LENGTH] = 0; gk_desc[PHASE_TIMEOUT] = 0; gk_desc[DISCONNECT_TIMEOUT] = 60; for (i=9; i<15; i++) gk_desc[i] = 0; /* Clear reserved fields */ status = sys$qiow (1, gk_chan, IO$_DIAGNOSE, gk_iosb, 0, 0, &gk_desc[0], 15*4, 0, 0, 0, 0); } return FALSE; } /*============================================================================ ! alloc_cd_channel Routine. ! This routine assigns a channel to the CD player. !============================================================================*/ void alloc_cd_channel () { int status, gk_device_desc[2]; gk_device_desc[0] = strlen (gk_device); gk_device_desc[1] = &gk_device[0]; status = sys$assign (&gk_device_desc[0], &gk_chan, 0, 0); if (!(status & 1)) { printf ("Unable to assign channel to %s", &gk_device[0]); exit (status); } } /*============================================================================ ! dealloc_cd_channel Routine. ! This routine deassigns a channel to the CD player !============================================================================*/ void dealloc_cd_channel () { int status; status = sys$dassgn (gk_chan); if (!(status & 1)) { printf ("Unable to deassign channel from %s", &gk_device[0]); exit (status); } } /*===========================================================================*/ /*===============================(END PROGRAM)===============================*/ /*===========================================================================*/ /*===========================================================================*/ /* Convenience Routines */ #if CONVENIENCE_ROUTINES /*============================================================================ ! play_MSF Routine. ! This routine plays a segment starting at "sm" minutes and "ss" seconds, ! and goes to "em" minutes and "es" seconds. ! ! Note: The program doesn't use this routine -- It is presented as an FYI ! in case the user wants to utilize the MSF calls for the CD. !============================================================================*/ int play_MSF ( int sm, int ss, int em, int es) #define PLAY_MSF_OPCODE 0X47 { unsigned char play_MSF_command [10] = {PLAY_MSF_OPCODE, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int status; if (sm == 0 && ss < 3) ss = 3; /* Play starts at 3 sec */ play_MSF_command [3] = sm; /* Start minutes */ play_MSF_command [4] = ss; /* start seconds */ play_MSF_command [5] = 0; /* start frame */ play_MSF_command [6] = em; /* end minutes */ play_MSF_command [7] = es; /* end seconds */ play_MSF_command [8] = 0; /* end frame */ status = execute_command(play_MSF_command, 10, 0, 0, READ); return status; } /*============================================================================ ! play_partial_track Routine. ! This routine starts at "x" minutes into the current track, and plays for ! "y" minutes. Note that if you try and play for more minutes than are ! remaining on the CD (from your start)... that nothing will happen! ! (we call that... being feature-rich) ! ! Note: The program doesn't use this routine -- It is presented as an FYI ! to illustrate the use of the MSF format for playing a CD. !============================================================================*/ int play_partial_track ( int track_num, int start_at_minutes, int start_at_seconds, int duration_minutes, int duration_seconds) { int track_minutes = 0, track_seconds = 0, begin_minutes = 0, begin_seconds = 0, end_minutes = 0, end_seconds = 0; unsigned int total_seconds = 0, start_here = 0, stop_here = 0, actual_CD_stop = 0; total_seconds = read_toc_track (track_num) / (75*4); /* Calcuate track start (in seconds) */ track_minutes = total_seconds / 60; track_seconds = total_seconds - (track_minutes * 60); begin_minutes = track_minutes + start_at_minutes; begin_seconds = track_seconds + start_at_seconds; /* Now add in start offset - mins/sec */ end_minutes = begin_minutes + duration_minutes; end_seconds = begin_seconds + duration_seconds; /* And compute the end - mins/sec */ start_here = (begin_minutes*60) + begin_seconds; stop_here = (end_minutes*60) + end_seconds; actual_CD_stop = read_CD_capacity() / (75*4); if (start_here > actual_CD_stop) /* If start is greater */ { /* than CD capacity */ return FALSE; /* exit on error */ } if (stop_here > actual_CD_stop) /* If end is greater... */ { /* then set to actual */ end_minutes = actual_CD_stop/60; /* end */ end_seconds = actual_CD_stop - (end_minutes*60); } printf ("play_MSF min=%d sec=%d min=%d sec=%d \n", begin_minutes, begin_seconds, end_minutes, end_seconds); play_MSF (begin_minutes, begin_seconds, end_minutes, end_seconds); /* Now play the segment */ } #endif /*===========================================================================*/ /*=================================(END ALL)=================================*/ /*===========================================================================*/ | |||||
72.37 | fooey | PONDA::64423::BELKIN | the slow one now will later be fast | Tue Jan 18 1994 10:46 | 27 |
I was just able to link the .c program in -.1 with: $ define/nolog c$include decw$examples,decw$include,sys$library $ define/nolog vaxc$include c$include $ $! cc CD_PLAYER $ $ link CD_PLAYER, sys$input/opt sys$share:decw$dxmlibshr.exe/share sys$share:decw$xmlibshr.exe/share sys$share:decw$xlibshr.exe/share sys$share:vaxcrtl.exe/share $ exit then I did: $DEFINE DECW$CD_PLAYER 12X5$DKA400: but when I run CD_PLAYER.EXE I get: %SYSTEM-F-NOPRIV, no privilege for attempted operation :-( josh | |||||
72.38 | TOOK::PECKAR | That would be something | Tue Jan 18 1994 12:54 | 3 | |
fwiw, there's a cd player for alpha osf which comes with the operating system as part of the motif examples. Its called xcd. | |||||
72.39 | PONDA::64423::BELKIN | the slow one now will later be fast | Tue Jan 18 1994 13:16 | 8 | |
Yabut I don't have an alpha (keep dreamin'! :-) I think that maybe the cdplayer I found does not require you to reboot your werkstation to make sure the default scsi driver does not get loaded. This means that I wouldn't have to reboot to go from playing audio to reading cdroms - unlike the version in decw$examples. thanks anyway, Josh | |||||
72.40 | ROCK::FROMM | It's hard to care about a don't care. | Tue Jan 18 1994 13:27 | 5 | |
josh, what happened when you tried the cd player i sent to you - rich | |||||
72.41 | no joy | PONDA::64423::BELKIN | the slow one now will later be fast | Tue Jan 18 1994 15:39 | 19 |
re <<< Note 72.40 by ROCK::FROMM "It's hard to care about a don't care." >>> >what happened when you tried the cd player i sent to you I haven't tried that one yet. It needs privs and to have my workstation rebooted, with futzing with the sysgen params for SCSI generic class drivers. I don't have privs since my workstation boots into a big cluster. Any progress with the cdplayer is a result of the sysman's good will (of which he has, but he's also busy). I just got him to install (with privs) the version I posted back a few notes but when I run it I get %SYSTEM-F-CTRLERR, fatal controller error. This version says its OK with Motif 1.0 and VMS V5.5. We're running Motif 1.1 and VMS 5.5 - so for all I know, its a Motif problem. My RRD-42 works fine for reading CD-ROMS of VMS docs. Maybe I have to punt this cdplayer version and go with the newer ones (either Rich's or the one in decw$examples). But then I have to mess with sysgen and I lose use of the RRD42 for CD ROMS. josh | |||||
72.42 | does chmod work on VMS ??? | QUARRY::petert | rigidly defined areas of doubt and uncertainty | Tue Jan 18 1994 15:45 | 11 |
Josh, while not familiar with the VMS side of things, typically in order to use the cd-rom for an audio player, you need read-write access to the CDROM device. This is so you can change the volume from the software window. I would expect if you are just reading documents, read-only is OK. I know how to do this in ODSF land, but don't know if you need to reboot or whatever after setting things up. Of course, in the strange way you describe it, it sounds almost like you need the sysadmin person to set up the device for you. Strange.... PeterT | |||||
72.43 | TOOK::PECKAR | That would be something | Tue Jan 18 1994 17:10 | 3 | |
rebooting seems a bit severe. Both Unix and vms devices can be mounted/unmounted/dismounted | |||||
72.44 | BIODTL::JC | Just one thing I ask of you | Wed Jan 19 1994 10:16 | 11 | |
re <<< Note 72.43 by TOOK::PECKAR "That would be something" >>> >rebooting seems a bit severe. Both Unix and vms devices can be >mounted/unmounted/dismounted true, but if you change non-dyn sysgen pars or need to load a different driver, you need to reboot. josh, can you see the cd drive doing a "show dev" ? | |||||
72.45 | the thick plottens... | PONDA::64423::BELKIN | the slow one now will later be fast | Wed Jan 19 1994 12:15 | 11 |
>josh, can you see the cd drive doing a "show dev" ? Hmmm.. well I could see the drive reading CDroms and I'd like to see it play audio CDs... not sure I could see that RRD042 doing a "show dev". :-)))) kinda thick today, ain't I? ;-) Yes, I can see the drive with a show dev dk. I can use it perfectly well to mount bookreader VMS docs. Josh | |||||
72.46 | labeling program ? | AWECIM::HANNAN | Beyond description... | Fri May 03 1996 16:36 | 5 |
Is there a tape label program for the PC out there ? A friend is looking for something like this. Thanks, Ken | |||||
72.47 | AWECIM::RUSSO | claimin! | Fri May 03 1996 16:48 | 6 | |
>>A friend is looking for something like this. Hmmmmm....Ken just got a pc this week, too......hmmmmm ;^) Hogan | |||||
72.48 | MKOTS3::JOLLIMORE | Always stop at the top | Fri May 03 1996 16:55 | 4 | |
ken, have you checked WinTaper (Note 455) ? it's more than a label program though. | |||||
72.49 | AWECIM::HANNAN | Beyond description... | Mon May 06 1996 09:52 | 8 | |
> Hmmmmm....Ken just got a pc this week, too......hmmmmm ;^) Correction: I've had a pc @ HLO for about a year now... And I don't need a tape label maker when I have the old trusty postscript program to hack at when needed. ;-) /Ken |