README for ScanJetPlay (c) Copyright 2005 by GanjaTron Music? On a Scanner??? ---------------------- That's right. The HP ScanJet 4c's SCL (Scanner Control Language) command set includes an unofficial "PLAY TUNE" command. I stumbled across this after reading an article in the feb. 1997 issue of HP Journal: "Design of a 600-Pixel-per-Inch, 30-Bit Color Scanner" by S.L. Webb, K.J. Youngers, M.J. Steinle, and J.A. Eccher. Available at http://www.hpl.hp.com/hpjournal/97feb/feb97a8.htm (see the sidebar "Sing to Me"). The PLAY TUNE command basically varies the stepping rate of the scanner motor to produce audible frequencies. All it needs is a series of note frequencies and durations previously written to its SCSI buffer. The ScanJetPlay utility resulted from my efforts in trying out this easter egg. Note that this is an old trick. "Music" from stepping motors also emanated from Commodore's 1541 floppy disk drive, and I'm sure there were others. Basically you just need direct access to the stepper motor, or, in the case of the ScanJet, a command in firmware which does that for you when direct access is not available. Terms of Use ------------ First things first: the obligatory disclaimer... This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; use at your own risk. The author assumes no liability for any damages incurred by its use, particularly to scanning hardware. Care has been taken to avoid potential damage, but if your scanner makes strange noises SHUT IT DOWN IMMEDIATELY! By using this software, you agree to these terms and conditions. Download -------- ScanJetPlay may be downloaded at http://www.ganjatron.net/misc/scanjet/scanjet.html Supported Hardware ------------------ This software is known to work on the Scanjet 4p and 4c. It should also work on the 3p and 3c, which are mechanically identical. It *may* work on later SCL-based models with SCSI interface (which I believe have long been discontinued), but this is untested. I'd appreciate user feedback on this. Installation ------------ ScanJetPlay requires libsane and libsanei (for SCSI access) from the SANE backends package (available at http://www.sane-project.org). Note that libsanei and its header files is not installed per default, and must be done manually. Edit the Makefile to reflect your C compiler's flags and the locations of the SANE libraries and header files, then run make. Chuck the resultant binaries in a convenient location (e.g. /usr/local/bin). SjetPlay -------- Uploads binary song files to the ScanJet and issues the PLAY TUNE command. The command line syntax is as follows: sjetplay , e.g. sjetplay /dev/sg0 song.sjn.bin The binary song file format consists of 3 bytes per note: ..., where the frequency specifies the number of 1.5 MHz clock cycles between motor half-steps, i.e. note frequency = 1.5 MHz / (freqMSB * 256 + freqLSB). The duration is specified as multiples of ca. 1/8 sec. SjetNAsm -------- The ScanJet Note Assembler (sounds fancy, huh?) is a utility to make the generation of binary song files more convenient, particularly when coding from sheet music. It takes a plain text file containing readable notation as input and outputs the associated stepper motor frequencies and durations as binary data for upload to the scanner via SjetPlay. SjetNAsm accepts no command line arguments, instead operating on stdin and stdout. A typical invocation looks like this: sjetnasm < song.sjn > song.sjn.bin Input files have the following text format: % Dees ees a comment, babee ... ... ..., where tempo is expressed in beats/sec (max 8). Anything following '%' is treated as a comment and ignored. Notes have the following format: = [duration], where: -- Note is one of {C, C#, D, D#, E, F, F#, G, G#, A, A#, B, P}, where P denotes a pause. -- Octave is in the range [0-2], with C1 denoting middle C. Octaves are omitted for pauses. -- Duration is in number of beats, or one beat if omitted. Floats are accepted for tempo and duration, but rounded to the nearest 1/8 sec. Notes are case insensitive and must lie in the ScanJet's tonal range D#0 - A3 (ca. 3 octaves). See elise.sjn for a sample input file. Bugs ---- The SCSI WRITE BUFFER command sometimes fails on the first invocation of sjetplay after powering up the scanner. A second attempt is usually successful. Notes at the extreme ends of the scanner's tonal range (i.e. D#0 and A3) may be clipped by the scanner's firmware and therefore sound off by a few Hz. Polyphonic performance is only possible with two or more scanners on separate SCSI channels, and the results are sobering at best. On a single channel, each scanner plays in turn while blocking all other activity on the channel. This is probably a firmware bug (or intentional to disourage such abuse). Even on separate channels, scanners drift out of sync resulting in total cacophony. This is presumably because the duration also depends on the note frequency, and there is no way to compensate for that. Everything was hacked together in about a week. Don't eggs-pect too much. :^) Feedback -------- The author may be contacted at -ganjatron-@-gmx-.-net- (remove hyphens). "Heff a lottof fun!" :^) --GanjaTron