Difference between revisions of "SCORE in Linux/X-Windows using Dosemu"
(75 intermediate revisions by the same user not shown) | |||
Line 7: | Line 7: | ||
=== Installing and setting up dosemu === | === Installing and setting up dosemu === | ||
− | Dosemu is one of the DOS/Windows emulators in which SCORE can run. First you will have to install dosemu for your particular operating system and configuration. In Gentoo this is easy to do (as root): | + | Dosemu is one of the DOS/Windows emulators in which SCORE can run. First you will have to install dosemu for your particular operating system and configuration. In Gentoo this is easy to do (as root or with [http://en.wikipedia.org/wiki/Sudo sudo]): |
emerge dosemu | emerge dosemu | ||
− | On other linux systems, you can try "yum install dosemu", "rpm -Uvh dosemu" or "apt-get install dosemu", or download and compile the source code manually from the [http://sourceforge.net/projects/dosemu dosemu website]. [http://www.freedos.org/ Freedos] was installed at the same time as dosemu when "emerge dosemu" was run, but you may also need to install that before running dosemu, particularly if you are installing manually. | + | On other linux systems, you can try "yum install dosemu", "rpm -Uvh [http://www.dosemu.org/stable/ dosemu*.rpm]" or "apt-get install dosemu" (Ubuntu), or download and compile the source code manually from the [http://sourceforge.net/projects/dosemu dosemu website]. [http://www.freedos.org/ Freedos] was installed at the same time as dosemu when "emerge dosemu" was run, but you may also need to install that before running dosemu, particularly if you are installing manually. |
Once dosemu is installed, type: | Once dosemu is installed, type: | ||
Line 49: | Line 49: | ||
[[File:dosemu-gounod.png|500px||center]] | [[File:dosemu-gounod.png|500px||center]] | ||
+ | |||
+ | |||
+ | === SCORE startup script === | ||
+ | |||
+ | The PERL program at the bottom of this section can be used to automate the processes of starting SCORE from the linux command-line. Place the script in a file called "<tt>scor4</tt>" within your search path (such as <tt>/usr/local/bin</tt>) and then set the executable permission for the script: | ||
+ | chmod 0755 scor4 | ||
+ | Then you can use the linux "scor4" command to start the actual DOS SCOR4.EXE program in one step. | ||
+ | |||
+ | The "scor4" script found below will automatically determine which DOS directory maps to your current working directory. If you are somewhere in your home directory, the script will move to that equivalent location on the <tt>D:</tt> drive in DOS before starting SCOR4.EXE. If you are located in <tt>~/.dosemu/drive_c</tt> when you run the "scor4" script, the DOS directory will be set to the <tt>C:</tt> drive (similar for any <tt>~/.dosemu/drive_?</tt> directory). An optional filename to start editing can be given to the "scor4" script as well. | ||
+ | |||
+ | For example, suppose you are in a subdirectory of your home directory called "score". Then if you type: | ||
+ | scor4 test.mus | ||
+ | the scor4 script will open dosemu, change directory to <tt>D:\score</tt> and then run SCOR4.EXE, loading test.mus into the score editor. All in a single step. | ||
+ | |||
+ | You can specify a different directory other than your current working directory in linux by using the -d option. The given directory can be a linux directory (which should be mappable to a DOS drive location), or can be a dos drive:directory pathname. For example to start editing the file "test.mus" in the D:\score directory from any linux location: | ||
+ | scor4 test.mus -w d:/score | ||
+ | Alternatively the directory name can be given at the same time as the filename: | ||
+ | scor4 d:/score/test.mus | ||
+ | Backslashes can be used for the pathname, but will have to be doubled in order to be first parsed by the linux terminal: | ||
+ | scor4 d:\\score\\test.mus | ||
+ | |||
+ | |||
+ | <pre> | ||
+ | #!/usr/bin/perl | ||
+ | # Program name: scor4 | ||
+ | # Usage: scor4 [.pmx or .mus file] | ||
+ | use strict; | ||
+ | |||
+ | use Getopt::Mixed; # command-line options parsing | ||
+ | use vars qw/ $opt_d /; # used to override current working directory | ||
+ | my $options = 'd=s w>d dir>d directory>d'; | ||
+ | Getopt::Mixed::getOptions($options); | ||
+ | |||
+ | my ($dosdrive, $dosdir, $filename)=getDosDriveDirAndFilename($opt_d, $ARGV[0]); | ||
+ | |||
+ | my $input = "\\P1;"; | ||
+ | $input .= "$dosdrive:\\r"; | ||
+ | $input .= "cd $dosdir\\r"; | ||
+ | $input .= "c:\\\\scor4\\\\scor4.exe $filename\\r"; | ||
+ | $input .= "\\r"; | ||
+ | |||
+ | my $command = "dosemu -X -quiet -input '$input'"; | ||
+ | |||
+ | print "Type \"exitemu\" to leave DOS\n"; | ||
+ | print "DOS_DIRECTORY: $dosdrive:$dosdir\n"; | ||
+ | print "COMMAND: $command\n"; | ||
+ | |||
+ | system($command); | ||
+ | exit(0); | ||
+ | |||
+ | |||
+ | sub getDosDriveDirAndFilename { | ||
+ | my ($directory, $filename) = @_; | ||
+ | |||
+ | $filename =~ s/\/+/\\/g; | ||
+ | $filename =~ s/\\+/\\\\/g; | ||
+ | if ($filename =~ /\\/) { | ||
+ | if ($filename =~ /^(.*\\)([^\\]*)/) { | ||
+ | $directory = $1; | ||
+ | $filename = $2; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | my $cwd = ""; | ||
+ | my $homedir = $ENV{'HOME'}; | ||
+ | if ($directory =~ /^\s*$/) { | ||
+ | $cwd = $ENV{'PWD'}; | ||
+ | $directory = $cwd; | ||
+ | } | ||
+ | my $dosdrive = "c"; | ||
+ | my $dosdir = "/"; | ||
+ | if ($directory =~ /^([a-zA-Z]):(.*)/) { | ||
+ | $dosdrive = $1; | ||
+ | $dosdir = $2; | ||
+ | } elsif ($directory =~ /^$homedir/) { | ||
+ | if ($directory =~ /^$homedir\/.dosemu\/drive_([a-zA-Z])\/?(.*)/) { | ||
+ | $dosdrive = "$1"; | ||
+ | $dosdir = "/$2"; | ||
+ | } elsif ($directory =~ /^$homedir\/?(.*)/) { | ||
+ | $dosdrive = "d"; | ||
+ | $dosdir = "/$1"; | ||
+ | } | ||
+ | } elsif ($directory !~ /^\s*$/) { | ||
+ | $dosdir = "/$directory"; | ||
+ | } | ||
+ | $dosdir =~ s/\/+/\\/g; | ||
+ | $dosdir =~ s/\\+/\\\\/g; | ||
+ | $dosdir =~ s/\\+$//; | ||
+ | |||
+ | return ($dosdrive, $dosdir, $filename); | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | To run this program, you may need the PERL module Getopt::Mixed (or delete the options processing code in the above program). To install, type as root: | ||
+ | perl -MCPAN -e shell | ||
+ | If you have not used this command before there will be some setup questions. After initialization, type the command: | ||
+ | install Getopt::Mixed | ||
+ | If you have run the perl -MCPAN command before, then you can also type this from the command-line: | ||
+ | perl -MCPAN -e "install Getopt::Mixed" | ||
== Useful dosemu commands == | == Useful dosemu commands == | ||
+ | |||
+ | Dosemu stores the default executable programs on the read-only <tt>Z:</tt> drive. You can see a list of the search path for commands by typing: | ||
+ | echo %PATH% | ||
+ | which should reply: | ||
+ | z:\bin;z:\gnu;z:\dosemu | ||
=== exitemu === | === exitemu === | ||
Line 64: | Line 168: | ||
Linux hostname 2.6.32-gentoo-r7 #1 SMP Mon Jul 12 05:51:36 PDT 2010 i686 Intel(R) | Linux hostname 2.6.32-gentoo-r7 #1 SMP Mon Jul 12 05:51:36 PDT 2010 i686 Intel(R) | ||
Core(TM)2 Duo CPU E6750 @ 2.66GHz GenuineIntel GNU/Linux | Core(TM)2 Duo CPU E6750 @ 2.66GHz GenuineIntel GNU/Linux | ||
+ | |||
+ | === long filenames === | ||
+ | |||
+ | To view long filenames (rather than 8+3 length names), use the /LFN option for dir: | ||
+ | dir/lfn | ||
+ | |||
+ | Alternatively, you can use the <tt>Z:\GNU\LS.EXE</tt> program to view a list of files in a unix style: | ||
+ | ls -asCF | ||
== Useful dosemu options == | == Useful dosemu options == | ||
Line 80: | Line 192: | ||
* <tt>\\P1;</tt> == set the keypress rate to 1/100th of a second. This will type the characters in the input string as fast as possible into dosemu. | * <tt>\\P1;</tt> == set the keypress rate to 1/100th of a second. This will type the characters in the input string as fast as possible into dosemu. | ||
− | * <tt>c:\\\\score4\\\\score4.exe</tt> == this is full DOS path name of the score4 program. Four backslash characters are needed to generate a single | + | * <tt>c:\\\\score4\\\\score4.exe</tt> == this is full DOS path name of the score4 program. Four backslash characters are needed to generate a single backslash in the path name. The unix terminal first converts "\\" pairs into single backslashes. Then the dosemu will take "\\" pairs and generate a single backslash which is finally sent to DOS as a keypress. So the final command typed into DOS with this string is: <pre>c:\scor4\scor4.exe</pre> |
* <tt>\\r</tt> == this is the enter key in DOS. The second "<tt>\\r</tt>" in the input string is used to skip the SCORE editor without pausing at the splash screen. | * <tt>\\r</tt> == this is the enter key in DOS. The second "<tt>\\r</tt>" in the input string is used to skip the SCORE editor without pausing at the splash screen. | ||
− | This command can be used more conveniently in a shell script, or as an alias. To use as an alias in the bash shell, you can type or permanently add this line to ~/.bashrc | + | This command can be used more conveniently in a shell script, or as an alias (The [[SCORE in X-Windows#SCORE startup script|SCORE startup script]] section describes a more generalized solution and the alias method of starting SCORE). To use as an alias in the bash shell, you can type or permanently add this line to the <tt>~/.bashrc</tt> file: |
alias scor4="dosemu -quiet -input '\\P1;c:\\\\scor4\\\\scor4.exe\\r\\r'" | alias scor4="dosemu -quiet -input '\\P1;c:\\\\scor4\\\\scor4.exe\\r\\r'" | ||
− | Log out and in again or type this command to activate the alias within the ~/.bashrc file: | + | Log out and in again or type this command to activate the alias within the <tt>~/.bashrc</tt> file: |
. ~/.bashrc | . ~/.bashrc | ||
Line 114: | Line 226: | ||
The <tt>-s</tt> option is used to access the hardware (video, keyboard, mouse) directly. This might give the most realistic emulation of DOS for SCORE (but untested). | The <tt>-s</tt> option is used to access the hardware (video, keyboard, mouse) directly. This might give the most realistic emulation of DOS for SCORE (but untested). | ||
+ | |||
+ | |||
== Dosemu configuration == | == Dosemu configuration == | ||
The dosemu configuration file is found in <tt>/etc/dosemu/dosemu.conf</tt>. Useful settings are given below. | The dosemu configuration file is found in <tt>/etc/dosemu/dosemu.conf</tt>. Useful settings are given below. | ||
+ | |||
+ | |||
+ | === Low-memory access === | ||
+ | |||
+ | In some configurations of dosemu (1.4.0.0 and earlier) and versions of linux (about 3.0.0 and later), you will get the following message caused by the operating system preventing access of dosemu to lower addresses in memory (to minimize security risks to the operating system): | ||
+ | |||
+ | EXPERIMENTAL: using non-zero memory base address 0x110000. | ||
+ | You can use the better-tested zero based setup using | ||
+ | sysctl -w vm.mmap_min_addr=0 | ||
+ | as root, or by changing the vm.mmap_min_addr setting in | ||
+ | /etc/sysctl.conf or a file in /etc/sysctl.d/ to 0. | ||
+ | |||
+ | Installing dosemu 1.4.0.1 or higher will prevent this warning message from being printed. Or you can allow dosemu to access low-addressed memory. For example, on Ubuntu computers in the file <tt>/etc/sysctl.d/10-zeropage.conf</tt>, change the line: | ||
+ | vm.mmap_min_addr = 65536 | ||
+ | to | ||
+ | vm.mmap_min_addr = 0 | ||
+ | Then reboot-the computer to activate the newer setting. | ||
=== Keyboard layout === | === Keyboard layout === | ||
Line 142: | Line 273: | ||
to | to | ||
rem lredir e: linux\fs/media/cdrom c | rem lredir e: linux\fs/media/cdrom c | ||
+ | |||
+ | == Other DOS emulators == | ||
+ | |||
+ | * On Apple OS X: | ||
+ | ** [http://boxerapp.com boxer] | ||
+ | * On Windows: | ||
+ | ** [http://www.dosbox.com dosbox] — see [https://web.archive.org/web/20151002085936/http://home.comcast.net/~tom.brodhead/dosbox.htm Tom Broadhead's instructions] for running SCORE in dosbox. | ||
+ | ** [http://scummvm.org ScummVM] | ||
+ | |||
+ | == Converting SCORE EPS into PDF, PNG or SVG files == | ||
+ | |||
+ | === EPS to PDF === | ||
+ | |||
+ | The Encapsulated PostScript files generated by SCORE can be converted to a pdf file with the command-line program [http://pages.cs.wisc.edu/~ghost/doc/AFPL/6.50/Ps2pdf.htm ps2pdf] which is a front-end to GhostScript: | ||
+ | ps2pdf mytest.eps | ||
+ | which will automatically create <i>mytest.pdf</i>. Or used in a pipeline: | ||
+ | cat mytest.eps | ps2pdf - - > [[Media:dosemu-ps2pdfdefault.pdf|mytest.pdf]] | ||
+ | |||
+ | Using the default settings, ps2pdf will generate a PDF file of the entire page of music: [[Media:dosemu-ps2pdfdefault.pdf|fullpage.pdf]]. In this case the music was placed in the default position at the bottom of the page when created in SCORE (so you may have to scroll down in the PDF viewer to see it). | ||
+ | |||
+ | You can give the <tt>-dEPSCrop</tt> option to ps2pdf so that the bounding box region of the EPS is used as the margins in the output PDF file: | ||
+ | cat mytest.eps | ps2pdf -dEPSCrop - - > [[Media:doseum-ps2pdfbbox.pdf|boundingbox.pdf]] | ||
+ | |||
+ | To produce a PDF file which does not contain any font information (more portable): | ||
+ | gs -q -dNOPAUSE -dBATCH -dSAFER -dNOCACHE -sDEVICE=epswrite \ | ||
+ | -sOutputFile=output.eps input.eps | ||
+ | ps2pdf -dEPSCrop output.eps [[Media:dosemu-ps2pdfbbox-nofonts.pdf|output.pdf]] | ||
+ | |||
+ | Other important options for ps2pdf/gs: | ||
+ | -sPAPERSIZE=letter | ||
+ | Use this option if the music is printed to U.S. letter size of 8.5" by 11". By default the ps2pdf program is usually set up to generate pages in the A4 size. | ||
+ | -dPDFSETTINGS=/prepress | ||
+ | This is useful to make [http://en.wikipedia.org/wiki/PDF/X PDF/X] conformant (with embedded fonts). | ||
+ | -dCompatibilityLevel=1.4 | ||
+ | The compatibility level of 1.4 makes the PDF compatible with older PDF viewing programs. | ||
+ | |||
+ | === EPS to PNG === | ||
+ | |||
+ | Here is an example of converting the EPS file into a PNG image using [http://netpbm.sourceforge.net/doc/pstopnm.html pstopnm] and ImageMagick's [http://www.imagemagick.org/script/convert.php convert] program: | ||
+ | cat mytest.eps | pstopnm -dpi=300 | convert - -trim -resize '40%' mytest.png | ||
+ | which results in this image: | ||
+ | |||
+ | [[File:dosemu-mytest.png|500px||center]] | ||
+ | |||
+ | The pstopnm program uses GhostScript to extract a bitmap from the EPS file. You can also directly call the gs command to convert the EPS file into a PNG file. The following example will also anti-alias the image, which is done above using the <i>convert</i> command after <i>pstopnm</i> extracts a higher-resolution 2-color image. | ||
+ | gs -sDEVICE=pnggray -dEPSCrop -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -r91 -o output.png input.eps | ||
+ | |||
+ | which results in this image: | ||
+ | |||
+ | [[File:dosemu-mytestgspng.png|500px||center]] | ||
+ | |||
+ | The second method of extracting PNG image from EPS files is faster (80 ms compared to 616 ms for this test image). The <tt>-r 91</tt> option samples the EPS image at 91 pixels per inch. The <tt>-dEPSCrop</tt> option causes the output image region to match the bounding box information within the EPS file, rather than the entire page. The <Tt>-dGraphicsAlphaBits=4</tt> option controls the anti-aliasing amount. Use 2 for a coarser anti-aliasing amount, or 1 (or omit the Alpha options) for no anti-aliasing. See the [http://www.ghostscript.com/doc/current/Use.htm GhostScript options] for more conversion controls. For colored images, use the [http://www.ghostscript.com/doc/current/Devices.htm#PNG device option] <tt>-sDEVICE=png16m</tt>. | ||
+ | |||
+ | |||
+ | |||
+ | === EPS to SVG === | ||
+ | |||
+ | To generate an SVG graphic from EPS, the EPS file should be processed in two steps. The first step is optional if the EPS file does not contain text: | ||
+ | gs -q -dNOPAUSE -dBATCH -dSAFER -dNOCACHE -sDEVICE=epswrite \ | ||
+ | -sOutputFile=nofonts.eps input.eps | ||
+ | |||
+ | The above GhostScript command will convert text from fonts to character outlines in the EPS data which is written to nofonts.eps (primarily caused by adding the <tt>-dNOCACHE</tt> option). After fonts have been removed from the EPS file (or there were no fonts to begin with), use this command to create the SVG file: | ||
+ | |||
+ | inkscape `pwd`/nofonts.eps -T -l output.svg | ||
+ | which generates this image: | ||
+ | |||
+ | [[File:dosemu-mytest.svg|505px||center]] | ||
+ | |||
+ | The above image is actually a PNG file, since WikiMedia automatically converts SVG files (vector graphics) into PNG files (bitmap graphics) so that the image can be viewed on any browser. Click on the above image twice to view the raw SVG image in the browser. | ||
+ | |||
+ | The options to [http://www.inkscape.org inkscape] used for this conversion from EPS into SVG: | ||
+ | * <tt>`pwd`/file.eps</tt> → Inkscape (v0.48) cannot read EPS files unless they are given with absolute path names. [http://en.wikipedia.org/wiki/Pwd Pwd] is the unix command which displays the <i>present working directory</i>. | ||
+ | * <tt>-l</tt> → Set the output type to plain SVG (as opposed to Inkscape SVG). | ||
+ | * <tt>-T</tt> → convert text characters into outlines. This is needed for portable display of text since necessary fonts may not be available on client browsers. The <tt>gs</tt> command above must be used first to convert the fonts to outlines in the EPS file for this option to work. | ||
+ | |||
+ | The above image is automatically converted into a PNG file in mediawiki (click twice on the image to see the raw SVG image). Here is a raw display of the same SVG graphic directly on this webpage (which will not display on older Internet Explorer versions and has scaling problems in recent IE versions) with a size carefully chosen to minimize anti-aliasing: | ||
+ | |||
+ | <center><htmlet>svgexample</htmlet></center> | ||
+ | |||
+ | If this page is printed to a 600 dpi printer, then the above raw SVG image will be printed at 600 dpi (even though it is displayed on the screen around 100 dpi). | ||
+ | |||
+ | Here is a PERL script which can be used to automatically convert from EPS to SVG files in one step: | ||
+ | |||
+ | <pre> | ||
+ | #!/usr/bin/perl | ||
+ | # Program name: eps2svg | ||
+ | # Usage: eps2svg [eps file(s)] | ||
+ | # Converts EPS files into SVG files, converting | ||
+ | # text into outlines. | ||
+ | |||
+ | my $ext; | ||
+ | my $base; | ||
+ | my $file; | ||
+ | my $command1; | ||
+ | my $command2; | ||
+ | my $tempfile = "temp"; | ||
+ | $tempfile .= int(rand(1000000)); | ||
+ | $tempfile .= ".eps"; | ||
+ | |||
+ | foreach $file (@ARGV) { | ||
+ | $base = $file; | ||
+ | $base =~ s/\.[^.]*//; | ||
+ | $ext = $file; | ||
+ | $ext =~ s/^$base\.//; | ||
+ | next if $ext !~ /[e]ps/i; | ||
+ | |||
+ | # first embed fonts in file | ||
+ | $command1 = "gs -q -dNOPAUSE -dBATCH -dSAFER -dNOCACHE"; | ||
+ | $command1 .= " -sDEVICE=epswrite"; | ||
+ | $command1 .= " -sOutputFile=$tempfile"; | ||
+ | $command1 .= " $file"; | ||
+ | |||
+ | # then convert to SVG | ||
+ | $command2 = " inkscape `pwd`/$tempfile -T -l $base.svg"; | ||
+ | |||
+ | print "Processing $file...\n"; | ||
+ | `$command1`; | ||
+ | `$command2`; | ||
+ | `rm -f $tempfile`; | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | Underlying software packages used to generate SVG graphics from PDF files: | ||
+ | * [http://en.wikipedia.org/wiki/Poppler_%28software%29 Poppler]: a free software library used to render PDF documents. | ||
+ | * [http://en.wikipedia.org/wiki/Cairo_%28graphics%29 Cairo]: a software library used to provide a vector graphics-based, device-independent API for software developers. | ||
== SCORE in batch mode using dosemu == | == SCORE in batch mode using dosemu == | ||
Line 203: | Line 459: | ||
For more information on the non-interactive modes of dosemu see: http://www.dosemu.org/docs/HOWTO/x304.html#AEN309 | For more information on the non-interactive modes of dosemu see: http://www.dosemu.org/docs/HOWTO/x304.html#AEN309 | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== Conversion scripts == | == Conversion scripts == | ||
Line 253: | Line 466: | ||
Where <i>program</i> is the name of the file with the PERL script, and 0755 set the permissions so that anyone can run the program. To run the program, you may have to add "./" (without the quotes) before the command name, such as: | Where <i>program</i> is the name of the file with the PERL script, and 0755 set the permissions so that anyone can run the program. To run the program, you may have to add "./" (without the quotes) before the command name, such as: | ||
./score2eps *.pmx *.mus | ./score2eps *.pmx *.mus | ||
+ | |||
+ | To run the following programs, you may need the PERL module Getopt::Mixed (or delete the options processing code in the above program). To install, type as root: | ||
+ | perl -MCPAN -e shell | ||
+ | If you have not used this command before there will be some setup questions. After initialization, type the command: | ||
+ | install Getopt::Mixed | ||
+ | If you have run the perl -MCPAN command before, then you can also type this from the command-line: | ||
+ | perl -MCPAN -e "install Getopt::Mixed" | ||
=== <tt>score2eps</tt>: Converting MUS or PMX data into EPS files === | === <tt>score2eps</tt>: Converting MUS or PMX data into EPS files === | ||
− | + | Below is a PERL script which converts PMX files or MUS files into EPS files. Multiple PMX/MUS files can be given as arguments. This automatic method of converting SCORE data into EPS images is not so great because time delays proportional to the amount of data on the page are required (or always use a long delay before starting to print so that music can be drawn on the screen). A more generalized version of the program which solves this problem and also converts [[ScoreXML]] files to EPS can be found on [[score2eps|this page]]. | |
+ | |||
+ | The <tt>score2eps</tt> script has two options. The <tt>-d</tt> option can be used to debug. If there is a problem converting a file, you can run the debug mode to watch the various automated steps to see where the problem might be occurring in the process. The <tt>-w</tt> option can be used to process all files in a directory which is not the one which you are running the program from (but the directory must be accessible to dosemu). | ||
+ | |||
+ | A caveat is that you should not type any characters on the computer keyboard while this program (or any other conversion script given further below) is running, since the characters will be sent to dosemu and interleave with the automatic feed of characters which are part of the conversion processing. This problem does not occur if you change window focus from the terminal in which you are running the program. | ||
<pre> | <pre> | ||
Line 266: | Line 490: | ||
use strict; | use strict; | ||
− | my $debug = | + | use Getopt::Mixed; # command-line options parsing |
+ | use vars qw/ $opt_d /; # run in debug mode if -d is given on command line | ||
+ | use vars qw/ $opt_w /; # set the default directory if not current one | ||
+ | my $options = 'd debug>d'; | ||
+ | $options .= ' w=s dir>w'; | ||
+ | Getopt::Mixed::getOptions($options); | ||
+ | my $debug = int($opt_d); | ||
+ | my $directory = $opt_w; | ||
− | my $file; | + | my ($file, $filename, $drive, $dir, $basename, $extension); |
− | foreach $ | + | foreach $filename (@ARGV) { |
− | + | ($drive, $dir, $file) = getDosDriveDirAndFilename($directory, $filename); | |
− | $basename =~ s/\.[^.]*//; | + | $basename = $file; |
− | + | $basename =~ s/\.[^.]*//; | |
+ | $extension = $file; | ||
$extension =~ s/^$basename\.//; | $extension =~ s/^$basename\.//; | ||
− | + | print "Processing file $file in $drive:$dir\n"; | |
− | + | createEPS($basename, $extension, $drive, $dir); | |
− | |||
− | |||
} | } | ||
sub createEPS { | sub createEPS { | ||
− | my ($base, $ext) = @_; | + | my ($base, $ext, $drive, $dir) = @_; |
my $keystrokes = "\\P3;"; # set keypress speed | my $keystrokes = "\\P3;"; # set keypress speed | ||
if ($debug != 0) { | if ($debug != 0) { | ||
Line 289: | Line 519: | ||
} | } | ||
+ | $keystrokes .= "$drive:\\r" if $drive !~ /^\s*$/; | ||
+ | $keystrokes .= "cd $dir\\r" if $dir !~ /^\s*$/; | ||
# Run the SCORE program: | # Run the SCORE program: | ||
$keystrokes .= "c:\\\\\\\\scor4\\\\\\\\scor4.exe\\r"; | $keystrokes .= "c:\\\\\\\\scor4\\\\\\\\scor4.exe\\r"; | ||
Line 296: | Line 528: | ||
$keystrokes .= "g"; # Get binary data (.mus files) | $keystrokes .= "g"; # Get binary data (.mus files) | ||
} else { | } else { | ||
− | $keystrokes .= " | + | $keystrokes .= "res"; # REad ASCII data (.pmx files) |
} | } | ||
$keystrokes .= " $base.$ext\\r"; # the file to read | $keystrokes .= " $base.$ext\\r"; # the file to read | ||
Line 323: | Line 555: | ||
$keystrokes .= "exit\\r"; # exit from SCORE | $keystrokes .= "exit\\r"; # exit from SCORE | ||
− | $keystrokes .= "y\\r"; | + | if (($ext !~ /mus/i) and ($ext !~ /pag/i)) { |
+ | $keystrokes .= "y\\r"; # don't save pmx data to binary file | ||
+ | } | ||
$keystrokes .= "exitemu\\r"; # exit from dosemu | $keystrokes .= "exitemu\\r"; # exit from dosemu | ||
− | if ( | + | my $command = "LANG=none dosemu -quiet"; |
− | + | if ($debug == 0) { | |
− | + | $command .= " -t"; | |
− | + | } | |
+ | $command .= " -input \"$keystrokes\""; | ||
+ | if ($debug == 0) { | ||
+ | $command .= " &> /dev/null"; | ||
+ | } | ||
+ | print "$command\n" if $debug != 0; | ||
+ | `$command`; # run the command | ||
+ | } | ||
+ | |||
+ | |||
+ | sub getDosDriveDirAndFilename { | ||
+ | my ($directory, $filename) = @_; | ||
+ | |||
+ | $filename =~ s/\/+/\\/g; | ||
+ | $filename =~ s/\\+/\\\\/g; | ||
+ | if ($filename =~ /\\/) { | ||
+ | if ($filename =~ /^(.*\\)([^\\]*)/) { | ||
+ | $directory = $1; | ||
+ | $filename = $2; | ||
} | } | ||
− | $ | + | } |
− | + | ||
− | $ | + | my $cwd = ""; |
+ | my $homedir = $ENV{'HOME'}; | ||
+ | if ($directory =~ /^\s*$/) { | ||
+ | $cwd = $ENV{'PWD'}; | ||
+ | $directory = $cwd; | ||
+ | } | ||
+ | my $dosdrive = "c"; | ||
+ | my $dosdir = "/"; | ||
+ | if ($directory =~ /^([a-zA-Z]):(.*)/) { | ||
+ | $dosdrive = $1; | ||
+ | $dosdir = $2; | ||
+ | } elsif ($directory =~ /^$homedir/) { | ||
+ | if ($directory =~ /^$homedir\/.dosemu\/drive_([a-zA-Z])\/?(.*)/) { | ||
+ | $dosdrive = "$1"; | ||
+ | $dosdir = "/$2"; | ||
+ | } elsif ($directory =~ /^$homedir\/?(.*)/) { | ||
+ | $dosdrive = "d"; | ||
+ | $dosdir = "/$1"; | ||
} | } | ||
− | + | } elsif ($directory !~ /^\s*$/) { | |
+ | $dosdir = "/$directory"; | ||
} | } | ||
+ | $dosdir =~ s/\/+/\\/g; | ||
+ | $dosdir =~ s/\\+/\\\\\\\\/g; | ||
+ | $dosdir =~ s/\\+$//; | ||
+ | |||
+ | return ($dosdrive, $dosdir, $filename); | ||
} | } | ||
</pre> | </pre> | ||
Line 344: | Line 619: | ||
<pre> | <pre> | ||
gs -q -dNOPAUSE -dBATCH -dSAFER -dNOCACHE \ | gs -q -dNOPAUSE -dBATCH -dSAFER -dNOCACHE \ | ||
− | -sDEVICE=epswrite -sOutputFile= | + | -sDEVICE=epswrite -sOutputFile=nofonts.eps input.eps |
</pre> | </pre> | ||
Line 350: | Line 625: | ||
<pre> | <pre> | ||
− | inkscape `pwd`/ | + | inkscape `pwd`/nofonts.eps -T -l output.svg |
</pre> | </pre> | ||
Line 365: | Line 640: | ||
The previous script prints directly in SCOR4 which allows the flexibility of automating any commands. However, pauses in the keystroke typing rate is necessary to accommodate switching between the graphics and text screens. The following script uses the SCORLAS4 program. This special-purpose program only prints binary SCORE data files (which end with .mus). | The previous script prints directly in SCOR4 which allows the flexibility of automating any commands. However, pauses in the keystroke typing rate is necessary to accommodate switching between the graphics and text screens. The following script uses the SCORLAS4 program. This special-purpose program only prints binary SCORE data files (which end with .mus). | ||
− | An advantage of printing by this method is that it can be done faster, since the keystrokes do not need to be buffered | + | An advantage of printing by this method is that it can be done faster, since the keystrokes do not need to be buffered as much because no graphics need to be displayed, and the video mode remains text. A disadvantage is that it only prints binary SCORE data files. So ASCII numeric data with possible macro instructions cannot be printed with this method. |
<pre> | <pre> | ||
#!/usr/bin/perl | #!/usr/bin/perl | ||
+ | # Program name: mus2eps | ||
+ | # Usage: mus2eps [.mus file(s)] | ||
+ | # This will create .eps with same base filename as input files. | ||
+ | |||
use strict; | use strict; | ||
− | my $debug = | + | use Getopt::Mixed; # command-line options parsing |
+ | use vars qw/ $opt_d /; # run in debug mode if -d is given on command line | ||
+ | use vars qw/ $opt_w /; # set the default directory if not current one | ||
+ | my $options = 'd debug>d'; | ||
+ | $options .= ' w=s dir>w'; | ||
+ | Getopt::Mixed::getOptions($options); | ||
+ | my $debug = int($opt_d); | ||
+ | my $directory = $opt_w; | ||
− | my $file; | + | |
− | foreach $ | + | my ($file, $filename, $drive, $dir, $basename, $extension); |
− | + | foreach $filename (@ARGV) { | |
− | $basename =~ s/\.[^.]*//; | + | ($drive, $dir, $file) = getDosDriveDirAndFilename($directory, $filename); |
− | + | $basename = $file; | |
+ | $basename =~ s/\.[^.]*//; | ||
+ | $extension = $file; | ||
$extension =~ s/^$basename\.//; | $extension =~ s/^$basename\.//; | ||
− | if (( | + | if (($extension =~ /mus/i) or ($extension =~ /pag/i)) { |
− | print "Processing file $file\n"; | + | my $tdir = $dir; |
− | createEPS($basename, $extension); | + | $tdir =~ s/\\\\/\\/g; |
+ | print "Processing file $file in $drive:$tdir\n"; | ||
+ | createEPS($basename, $extension, $drive, $dir); | ||
} | } | ||
} | } | ||
+ | |||
sub createEPS { | sub createEPS { | ||
my ($base, $ext) = @_; | my ($base, $ext) = @_; | ||
my $keystrokes = "\\P1;"; # set keypress speed | my $keystrokes = "\\P1;"; # set keypress speed | ||
+ | if ($debug) { | ||
+ | $keystrokes = "\\P50;"; # set keypress speed for debugging | ||
+ | } | ||
+ | $keystrokes .= "$drive:\\r" if $drive !~ /^\s*$/; | ||
+ | $keystrokes .= "cd $dir\\r" if $dir !~ /^\s*$/; | ||
# run the SCORLAS4 program: | # run the SCORLAS4 program: | ||
$keystrokes .= "c:\\\\scor4\\\\scorlas4.exe\\r"; | $keystrokes .= "c:\\\\scor4\\\\scorlas4.exe\\r"; | ||
Line 397: | Line 693: | ||
$keystrokes .= "y\\r"; # answer yes to possible overwrite question | $keystrokes .= "y\\r"; # answer yes to possible overwrite question | ||
$keystrokes .= "\\F6;"; # print the file | $keystrokes .= "\\F6;"; # print the file | ||
− | if ($debug = | + | if ($debug) { |
+ | $keystrokes .= "\\p200;"; # pause a little for printing to finish | ||
+ | } else { | ||
$keystrokes .= "\\p50;"; # pause a little for printing to finish | $keystrokes .= "\\p50;"; # pause a little for printing to finish | ||
− | |||
− | |||
} | } | ||
$keystrokes .= "n\\r"; # don't print another page | $keystrokes .= "n\\r"; # don't print another page | ||
Line 406: | Line 702: | ||
if (-r "$base.$ext") { | if (-r "$base.$ext") { | ||
my $command = "LANG=none dosemu"; | my $command = "LANG=none dosemu"; | ||
− | if ($debug | + | if (!$debug) { |
$command .= " -t"; | $command .= " -t"; | ||
} | } | ||
$command .= " -quiet -input '$keystrokes'"; | $command .= " -quiet -input '$keystrokes'"; | ||
− | if ($debug | + | if (!$debug) { |
− | $command .= " > | + | $command .= " &> /dev/null"; |
} | } | ||
`$command`; | `$command`; | ||
} | } | ||
+ | } | ||
+ | |||
+ | |||
+ | sub getDosDriveDirAndFilename { | ||
+ | my ($directory, $filename) = @_; | ||
+ | |||
+ | $filename =~ s/\/+/\\/g; | ||
+ | $filename =~ s/\\+/\\\\/g; | ||
+ | if ($filename =~ /\\/) { | ||
+ | if ($filename =~ /^(.*\\)([^\\]*)/) { | ||
+ | $directory = $1; | ||
+ | $filename = $2; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | my $cwd = ""; | ||
+ | my $homedir = $ENV{'HOME'}; | ||
+ | if ($directory =~ /^\s*$/) { | ||
+ | $cwd = $ENV{'PWD'}; | ||
+ | $directory = $cwd; | ||
+ | } | ||
+ | my $dosdrive = "c"; | ||
+ | my $dosdir = "/"; | ||
+ | if ($directory =~ /^([a-zA-Z]):(.*)/) { | ||
+ | $dosdrive = $1; | ||
+ | $dosdir = $2; | ||
+ | } elsif ($directory =~ /^$homedir/) { | ||
+ | if ($directory =~ /^$homedir\/.dosemu\/drive_([a-zA-Z])\/?(.*)/) { | ||
+ | $dosdrive = "$1"; | ||
+ | $dosdir = "/$2"; | ||
+ | } elsif ($directory =~ /^$homedir\/?(.*)/) { | ||
+ | $dosdrive = "d"; | ||
+ | $dosdir = "/$1"; | ||
+ | } | ||
+ | } elsif ($directory !~ /^\s*$/) { | ||
+ | $dosdir = "/$directory"; | ||
+ | } | ||
+ | $dosdir =~ s/\/+/\\/g; | ||
+ | $dosdir =~ s/\\+/\\\\/g; | ||
+ | $dosdir =~ s/\\+$//; | ||
+ | |||
+ | return ($dosdrive, $dosdir, $filename); | ||
} | } | ||
</pre> | </pre> | ||
+ | |||
+ | |||
=== <tt>pmx2mus</tt>: Converting PMX into MUS files === | === <tt>pmx2mus</tt>: Converting PMX into MUS files === | ||
− | The following script will convert ASCII notation data into binary data. Binary data can be printed with SCORLAS4.exe. ASCII data can contain plain numeric data, or macro commands. | + | The following script will convert ASCII notation data into binary data. Binary data can be printed with SCORLAS4.exe. ASCII data can contain plain numeric data, or macro commands. Options understood by the program: |
+ | |||
+ | * <tt>-d</tt> → run in debug mode (display the program in X-windows with the keypress rate slowed down) | ||
+ | * <tt>-w directory</tt> → run in the given DOS or linux directory. If a linux directory, then must be mappable to a DOS directory (i.e., it has to be somewhere in your home directory tree). | ||
+ | * <tt>-o filename</tt> → set the output filename. By default output filenames are generated automatically by removing any extension from the input filename, and appending ".mus". When the <tt>-o</tt> option is not used, multiple input files can be processed at the same time. When the <tt>-o</tt> option is used, only the first file will be processed and all subsequent filenames will be ignored. | ||
<pre> | <pre> | ||
Line 427: | Line 771: | ||
# Usage: pmx2mus [.pmx file(s)] | # Usage: pmx2mus [.pmx file(s)] | ||
# This will create .mus with same base filename as input files. | # This will create .mus with same base filename as input files. | ||
+ | use strict; | ||
+ | |||
+ | use Getopt::Mixed; # command-line options parsing | ||
+ | use vars qw/ $opt_d /; # run in debug mode if -d is given on command line | ||
+ | use vars qw/ $opt_w /; # set the default directory if not current one | ||
+ | use vars qw/ $opt_o /; # set the output file name | ||
+ | my $options = 'd debug>d'; | ||
+ | $options .= ' w=s dir>w'; | ||
+ | $options .= ' o=s output>o output-file>o'; | ||
+ | Getopt::Mixed::getOptions($options); | ||
+ | |||
+ | my $debug = int($opt_d); | ||
+ | my $directory = $opt_w; | ||
+ | my $outputfile = $opt_o; | ||
+ | $outputfile =~ s/.*[\\\/]+//; # no directories allowed with -o option | ||
+ | |||
+ | my ($file, $filename, $drive, $dir, $basename, $extension); | ||
+ | foreach $filename (@ARGV) { | ||
+ | ($drive, $dir, $file) = getDosDriveDirAndFilename($directory, $filename); | ||
+ | $basename = $file; | ||
+ | $basename =~ s/\.[^.]*//; | ||
+ | $extension = $file; | ||
+ | $extension =~ s/^$basename\.//; | ||
+ | if (($extension !~ /mus/i) and ($extension !~ /pag/i)) { | ||
+ | my $tdir = $dir; | ||
+ | $tdir =~ s/\\\\\\\\/\\/g; | ||
+ | print "Processing file $file in $drive:$tdir\n"; | ||
+ | createMUS($basename, $extension, $drive, $dir); | ||
+ | } | ||
+ | last if $opt_o !~ /^\s*$/; | ||
+ | } | ||
+ | |||
+ | |||
+ | sub createMUS { | ||
+ | my ($base, $ext) = @_; | ||
+ | my $keystrokes = "\\P3;"; # set keypress speed | ||
+ | if ($debug) { | ||
+ | $keystrokes = "\\P20;"; # slow down keystrokes for debugging | ||
+ | } else { | ||
+ | $keystrokes .= "\\r"; # detect keyboard type in -t mode | ||
+ | } | ||
+ | |||
+ | $keystrokes .= "$drive:\\r" if $drive !~ /^\s*$/; | ||
+ | $keystrokes .= "cd $dir\\r" if $dir !~ /^\s*$/; | ||
+ | # Run the SCORE program: | ||
+ | $keystrokes .= "c:\\\\\\\\scor4\\\\\\\\scor4.exe\\r"; | ||
+ | # Add extra \r to skip the splash screen: | ||
+ | $keystrokes .= "\\r"; | ||
+ | if ($ext =~ /mus/i) { | ||
+ | $keystrokes .= "g"; # Get binary data (.mus files) | ||
+ | } else { | ||
+ | $keystrokes .= "res"; # REad ASCII data (.pmx files) | ||
+ | } | ||
+ | $keystrokes .= " $base.$ext\\r"; # the file to read | ||
+ | |||
+ | # longer pauses needed for larger input files... | ||
+ | if ($debug == 0) { | ||
+ | $keystrokes .= "\\p20;"; # pause 0.2 seconds | ||
+ | } else { | ||
+ | $keystrokes .= "\\p200;"; # pause 2 seconds | ||
+ | } | ||
+ | |||
+ | my $savefile = $outputfile; | ||
+ | $savefile = "$base.mus" if $savefile =~ /^\s*$/; | ||
+ | |||
+ | $keystrokes .= "sa $savefile\\r"; | ||
+ | if (-r "$savefile") { | ||
+ | # overwite .mus file if it already exists | ||
+ | $keystrokes .= "y\\r"; | ||
+ | } | ||
+ | $keystrokes .= "exit\\r"; # exit from SCORE | ||
+ | $keystrokes .= "del #musdir#.tmp\\r"; # clean up the poo | ||
+ | $keystrokes .= "exitemu\\r"; # exit from dosemu | ||
+ | |||
+ | if (-r "$base.$ext") { | ||
+ | my $command = "LANG=none dosemu -quiet"; | ||
+ | if (!$debug) { | ||
+ | $command .= " -t"; | ||
+ | } | ||
+ | $command .= " -input \"$keystrokes\""; | ||
+ | if (!$debug) { | ||
+ | $command .= " &> /dev/null"; | ||
+ | } | ||
+ | `$command`; # run the command | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | sub getDosDriveDirAndFilename { | ||
+ | my ($directory, $filename) = @_; | ||
+ | |||
+ | $filename =~ s/\/+/\\/g; | ||
+ | $filename =~ s/\\+/\\\\/g; | ||
+ | if ($filename =~ /\\/) { | ||
+ | if ($filename =~ /^(.*\\)([^\\]*)/) { | ||
+ | $directory = $1; | ||
+ | $filename = $2; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | my $cwd = ""; | ||
+ | my $homedir = $ENV{'HOME'}; | ||
+ | if ($directory =~ /^\s*$/) { | ||
+ | $cwd = $ENV{'PWD'}; | ||
+ | $directory = $cwd; | ||
+ | } | ||
+ | my $dosdrive = "c"; | ||
+ | my $dosdir = "/"; | ||
+ | if ($directory =~ /^([a-zA-Z]):(.*)/) { | ||
+ | $dosdrive = $1; | ||
+ | $dosdir = $2; | ||
+ | } elsif ($directory =~ /^$homedir/) { | ||
+ | if ($directory =~ /^$homedir\/.dosemu\/drive_([a-zA-Z])\/?(.*)/) { | ||
+ | $dosdrive = "$1"; | ||
+ | $dosdir = "/$2"; | ||
+ | } elsif ($directory =~ /^$homedir\/?(.*)/) { | ||
+ | $dosdrive = "d"; | ||
+ | $dosdir = "/$1"; | ||
+ | } | ||
+ | } elsif ($directory !~ /^\s*$/) { | ||
+ | $dosdir = "/$directory"; | ||
+ | } | ||
+ | $dosdir =~ s/\/+/\\/g; | ||
+ | $dosdir =~ s/\\+/\\\\\\\\/g; | ||
+ | $dosdir =~ s/\\+$//; | ||
+ | |||
+ | return ($dosdrive, $dosdir, $filename); | ||
+ | } | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | === <tt>mus2pmx</tt>: Converting from MUS into PMX files === | ||
+ | |||
+ | MUS files (or sometimes PAG files which implies binary data for a full page) can be converted to ASCII numeric data by running the PMX command within SCORE. The following script converts binary data files into their ASCII equivalent. Options understood by the program: | ||
+ | |||
+ | * <tt>-d</tt> → run in debug mode (display the program in X-windows with the keypress rate slowed down) | ||
+ | * <tt>-w directory</tt> → run in the given DOS or linux directory. If a linux directory, then must be mappable to a DOS directory (i.e., it has to be somewhere in your home directory tree). | ||
+ | * <tt>-o filename</tt> → set the output filename. By default output filenames are generated automatically by removing any extension from the input filename, and appending ".pmx". When the <tt>-o</tt> option is not used, multiple input files can be processed at the same time. When the <tt>-o</tt> option is used, only the first file will be processed and all subsequent filenames will be ignored. | ||
+ | |||
+ | <pre> | ||
+ | #!/usr/bin/perl | ||
+ | # Program name: mus2pmx | ||
+ | # Usage: mus2pmx [.mus file(s)] | ||
+ | # This will create .pmx with same base filename as input files. | ||
+ | use strict; | ||
+ | |||
+ | use Getopt::Mixed; # command-line options parsing | ||
+ | use vars qw/ $opt_d /; # run in debug mode if -d is given on command line | ||
+ | use vars qw/ $opt_w /; # set the default directory if not current one | ||
+ | use vars qw/ $opt_o /; # set the output file name | ||
+ | my $options = 'd debug>d'; | ||
+ | $options .= ' w=s dir>w'; | ||
+ | $options .= ' o=s output>o output-file>o'; | ||
+ | Getopt::Mixed::getOptions($options); | ||
+ | |||
+ | my $debug = int($opt_d); | ||
+ | my $directory = $opt_w; | ||
+ | my $outputfile = $opt_o; | ||
+ | $outputfile =~ s/.*[\\\/]+//; # no directories allowed with -o option | ||
+ | |||
+ | my ($file, $filename, $drive, $dir, $basename, $extension); | ||
+ | foreach $filename (@ARGV) { | ||
+ | ($drive, $dir, $file) = getDosDriveDirAndFilename($directory, $filename); | ||
+ | $basename = $file; | ||
+ | $basename =~ s/\.[^.]*//; | ||
+ | $extension = $file; | ||
+ | $extension =~ s/^$basename\.//; | ||
+ | if (($extension =~ /mus/i) or ($extension =~ /pag/i)) { | ||
+ | my $tdir = $dir; | ||
+ | $tdir =~ s/\\\\\\\\/\\/g; | ||
+ | print "Processing file $file in $drive:$tdir\n"; | ||
+ | createPMX($basename, $extension, $drive, $dir); | ||
+ | } | ||
+ | last if $opt_o !~ /^\s*$/; | ||
+ | } | ||
+ | |||
+ | |||
+ | sub createPMX { | ||
+ | my ($base, $ext) = @_; | ||
+ | my $keystrokes = "\\P3;"; # set keypress speed | ||
+ | if ($debug) { | ||
+ | $keystrokes = "\\P20;"; # slow down keystrokes for debugging | ||
+ | } else { | ||
+ | $keystrokes .= "\\r"; # detect keyboard type in -t mode | ||
+ | } | ||
+ | |||
+ | $keystrokes .= "$drive:\\r" if $drive !~ /^\s*$/; | ||
+ | $keystrokes .= "cd $dir\\r" if $dir !~ /^\s*$/; | ||
+ | # Run the SCORE program: | ||
+ | $keystrokes .= "c:\\\\\\\\scor4\\\\\\\\scor4.exe\\r"; | ||
+ | # Add extra \r to skip the splash screen: | ||
+ | $keystrokes .= "\\r"; | ||
+ | if ($ext =~ /mus/i) { | ||
+ | $keystrokes .= "g"; # Get binary data (.mus files) | ||
+ | } else { | ||
+ | $keystrokes .= "res"; # REad ASCII data (.pmx files) | ||
+ | } | ||
+ | $keystrokes .= " $base.$ext\\r"; # the file to read | ||
+ | |||
+ | # longer pauses needed for larger input files... | ||
+ | if ($debug == 0) { | ||
+ | $keystrokes .= "\\p20;"; # pause 0.2 seconds | ||
+ | } else { | ||
+ | $keystrokes .= "\\p200;"; # pause 2 seconds | ||
+ | } | ||
+ | |||
+ | my $savefile = $outputfile; | ||
+ | $savefile = "$base.pmx" if $savefile =~ /^\s*$/; | ||
+ | $keystrokes .= "pmx\\r"; | ||
+ | $keystrokes.= "$savefile\\r"; | ||
+ | if (-r "$savefile") { | ||
+ | # overwite .mus file if it already exists | ||
+ | $keystrokes .= "y\\r"; | ||
+ | } | ||
+ | $keystrokes .= "exit\\r"; # exit from SCORE | ||
+ | $keystrokes .= "exitemu\\r"; # exit from dosemu | ||
+ | |||
+ | if (-r "$base.$ext") { | ||
+ | my $command = "LANG=none dosemu -quiet"; | ||
+ | if ($debug == 0) { | ||
+ | $command .= " -t"; | ||
+ | } | ||
+ | $command .= " -input \"$keystrokes\""; | ||
+ | if ($debug == 0) { | ||
+ | $command .= " &> /dev/null"; | ||
+ | } | ||
+ | `$command`; # run the command | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | sub getDosDriveDirAndFilename { | ||
+ | my ($directory, $filename) = @_; | ||
+ | |||
+ | $filename =~ s/\/+/\\/g; | ||
+ | $filename =~ s/\\+/\\\\/g; | ||
+ | if ($filename =~ /\\/) { | ||
+ | if ($filename =~ /^(.*\\)([^\\]*)/) { | ||
+ | $directory = $1; | ||
+ | $filename = $2; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | my $cwd = ""; | ||
+ | my $homedir = $ENV{'HOME'}; | ||
+ | if ($directory =~ /^\s*$/) { | ||
+ | $cwd = $ENV{'PWD'}; | ||
+ | $directory = $cwd; | ||
+ | } | ||
+ | my $dosdrive = "c"; | ||
+ | my $dosdir = "/"; | ||
+ | if ($directory =~ /^([a-zA-Z]):(.*)/) { | ||
+ | $dosdrive = $1; | ||
+ | $dosdir = $2; | ||
+ | } elsif ($directory =~ /^$homedir/) { | ||
+ | if ($directory =~ /^$homedir\/.dosemu\/drive_([a-zA-Z])\/?(.*)/) { | ||
+ | $dosdrive = "$1"; | ||
+ | $dosdir = "/$2"; | ||
+ | } elsif ($directory =~ /^$homedir\/?(.*)/) { | ||
+ | $dosdrive = "d"; | ||
+ | $dosdir = "/$1"; | ||
+ | } | ||
+ | } elsif ($directory !~ /^\s*$/) { | ||
+ | $dosdir = "/$directory"; | ||
+ | } | ||
+ | $dosdir =~ s/\/+/\\/g; | ||
+ | $dosdir =~ s/\\+/\\\\\\\\/g; | ||
+ | $dosdir =~ s/\\+$//; | ||
+ | |||
+ | return ($dosdrive, $dosdir, $filename); | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | === <tt>mac2pmx</tt>: Converting macro text into PMX files === | ||
+ | |||
+ | ASCII SCORE data read into the program with RE or RES may contain macros as well as numeric data. Numeric data describing the score is equivalent to the binary data stored in .mus (or .pag) files. Converting macro data into numeric data is non-trivial and essentially can only be done within SCORE itself. The following script will convert any ASCII SCORE file into purely numeric data. The file-naming convention for this program is to store macro data in a file ending in .txt. Any filename ending except .pmx, .mus or .pag will also work. | ||
+ | |||
+ | For example, the following data from user input mode can be loaded into SCORE via the RES command exactly like purely numeric text can. RES is better for loading such macro text non-interactively since this version of RE will not prompt the user to see if they want to edit the input. | ||
+ | |||
+ | <pre> | ||
+ | IN1 0 0 1.0000 100 | ||
+ | 0 100 | ||
+ | TR/K4F/E4/G/F/A/B/M/EU/D/C/PB/A/B/MH; | ||
+ | EX4/Q/SX4/Q/Q; | ||
+ | S 6:9/FE 11/C+ 1 5/C- 6 10; | ||
+ | 2B; | ||
+ | 1 2/3 4; | ||
+ | |||
+ | lj | ||
+ | 1 1 | ||
+ | </pre> | ||
+ | |||
+ | Using the mac2pmx will generate a fully numeric description of the notation: | ||
+ | |||
+ | <pre> | ||
+ | 8. 1.0 .000 .00 1.00 100.00 | ||
+ | 3. 1.0 1.500 | ||
+ | 17. 1.0 9.315 .00 -4.00 | ||
+ | 1. 1.0 23.215 3.00 10.00 .00 .5000 .50 .00 | ||
+ | 4. 1.0 23.215 -3.50 999.00 49.29 | ||
+ | 6. 1.0 23.215 3.50 5.00 29.59 11.0000 | ||
+ | 5. 1.0 23.215 1.00 2.00 29.59 -1.3117 -1.00 | ||
+ | 1. 1.0 29.595 5.00 10.00 .00 .5000 .00 .00 | ||
+ | 1. 1.0 35.974 4.00 10.00 .00 .5000 .50 .00 | ||
+ | 6. 1.0 35.974 4.50 6.00 42.35 11.0000 | ||
+ | 5. 1.0 35.974 2.00 4.00 42.35 -1.4117 -1.00 | ||
+ | 1. 1.0 42.354 6.00 10.00 .00 .5000 .00 .00 | ||
+ | 1. 1.0 49.287 7.00 20.00 .00 1.0000 | ||
+ | 14. 1.0 58.395 1.00 | ||
+ | 1. 1.0 61.526 10.00 20.00 .00 .2500 2.00 .00 .00 7.00 | ||
+ | 4. 1.0 61.526 -3.50 999.00 80.75 -1.0000 | ||
+ | 6. 1.0 61.526 8.00 7.00 75.94 22.0000 | ||
+ | 1. 1.0 66.332 9.00 20.00 .00 .2500 1.33 .00 .00 7.00 | ||
+ | 1. 1.0 71.138 8.00 20.00 .00 .2500 .67 .00 .00 7.00 | ||
+ | 1. 1.0 75.945 7.00 20.00 .00 .2500 .00 .00 .00 7.00 | ||
+ | 1. 1.0 80.751 6.00 10.00 .00 1.0000 | ||
+ | 1. 1.0 90.043 7.00 20.00 .00 1.0000 .00 .00 .00 14.00 | ||
+ | 14. 1.0 100.000 1.00 2.00 | ||
+ | </pre> | ||
+ | |||
+ | Either of the above SCORE data files can be converted into an EPS graphical score using score2eps: | ||
+ | |||
+ | <center>[[Image:dosemu-txt2pmx.svg]]</center> | ||
+ | |||
+ | Here is the PERL script which can convert macro text into PMX data (ASCII numeric SCORE data). | ||
+ | |||
+ | <pre> | ||
+ | #!/usr/bin/perl | ||
+ | # Program name: mac2pmx | ||
+ | # Usage: mac2pmx [.txt file(s)] | ||
+ | # This will create .pmx with same base filename as input files. | ||
use strict; | use strict; | ||
Line 437: | Line 1,112: | ||
my $extension = $file; | my $extension = $file; | ||
$extension =~ s/^$basename\.//; | $extension =~ s/^$basename\.//; | ||
− | if ((-r $file) && ($extension !~ / | + | if ((-r $file) && ($extension !~ /pmx/i)) { |
print "Processing file $file\n"; | print "Processing file $file\n"; | ||
− | + | createPMX($basename, $extension); | |
} | } | ||
} | } | ||
− | sub | + | sub createPMX { |
my ($base, $ext) = @_; | my ($base, $ext) = @_; | ||
my $keystrokes = "\\P3;"; # set keypress speed | my $keystrokes = "\\P3;"; # set keypress speed | ||
Line 459: | Line 1,134: | ||
$keystrokes .= "g"; # Get binary data (.mus files) | $keystrokes .= "g"; # Get binary data (.mus files) | ||
} else { | } else { | ||
− | $keystrokes .= " | + | $keystrokes .= "res"; # REad ASCII data (.pmx files) |
} | } | ||
$keystrokes .= " $base.$ext\\r"; # the file to read | $keystrokes .= " $base.$ext\\r"; # the file to read | ||
Line 470: | Line 1,145: | ||
} | } | ||
− | $keystrokes .= " | + | $keystrokes .= "pmx\\r"; |
+ | $keystrokes.= "$base.pmx\\r"; | ||
if (-r "$base.mus") { | if (-r "$base.mus") { | ||
# overwite .mus file if it already exists | # overwite .mus file if it already exists | ||
Line 476: | Line 1,152: | ||
} | } | ||
$keystrokes .= "exit\\r"; # exit from SCORE | $keystrokes .= "exit\\r"; # exit from SCORE | ||
+ | $keystrokes .= "y\\r"; # don't save editor data | ||
$keystrokes .= "exitemu\\r"; # exit from dosemu | $keystrokes .= "exitemu\\r"; # exit from dosemu | ||
+ | |||
+ | if (-r "$base.$ext") { | ||
+ | my $command = "LANG=none dosemu -quiet"; | ||
+ | if ($debug == 0) { | ||
+ | $command .= " -t"; | ||
+ | } | ||
+ | $command .= " -input \"$keystrokes\""; | ||
+ | if ($debug == 0) { | ||
+ | $command .= " &> /dev/null"; | ||
+ | } | ||
+ | `$command`; # run the command | ||
+ | } | ||
+ | } | ||
</pre> | </pre> | ||
− | |||
− | == | + | An example usage of the mac2pmx program is to apply SCORE commands to numeric data. Below is an example which adjusts note stems to display the music with French stemming (where the stem only extends up to the first beam): |
+ | |||
+ | <center> | ||
+ | <table> | ||
+ | <tr valign=center><td>[[Image:dosemu-nofrench.svg]]</td><td width=20><center>→</center></td> | ||
+ | <td>[[Image:dosemu-french.svg]]</td></tr> | ||
+ | </table> | ||
+ | </center> | ||
+ | |||
+ | Here is input data for <tt>mac2pmx</tt>: | ||
+ | |||
+ | <pre> | ||
+ | 8. 1.0 .000 .00 .00 100.00 | ||
+ | 3. 1.0 1.500 .00 1.00 | ||
+ | 17. 1.0 9.478 .00 1.00 1.00 | ||
+ | 1. 1.0 14.978 6.00 20.00 .00 .1250 1.00 | ||
+ | 6. 1.0 14.978 5.00 11.00 73.17 23.0000 | ||
+ | 1. 1.0 23.291 7.00 20.00 .00 .1250 1.14 | ||
+ | 1. 1.0 31.605 8.00 20.00 .00 .1250 1.29 | ||
+ | 1. 1.0 39.918 9.00 20.00 .00 .1250 1.43 | ||
+ | 1. 1.0 48.231 10.00 20.00 .00 .1250 1.57 | ||
+ | 1. 1.0 56.544 11.00 20.00 .00 .1250 1.71 | ||
+ | 1. 1.0 64.858 12.00 20.00 .00 .1250 1.86 | ||
+ | 1. 1.0 73.171 13.00 20.00 .00 .1250 2.00 | ||
+ | 1. 1.0 81.541 14.00 20.00 .00 .5000 .00 1.00 | ||
+ | 14. 1.0 100.000 -1.00 | ||
+ | |||
+ | adf 99 | ||
+ | </pre> | ||
+ | |||
+ | Note the line "<tt>adf 99</tt>" at the bottom of the file. This is the SCORE command to generate French stemming (ADF = "ADjust French"). The integer 99 after the command means to process all staves in the editor (otherwise, you can apply the adjustment to a particular staff). | ||
+ | |||
+ | After running mac2pmx on the above data, the ADF command is gone, and the stem lengths (column 8 of note data) have been changed in the numeric data: | ||
+ | |||
+ | <pre> | ||
+ | 8. 1.0 .000 .00 .00 100.00 | ||
+ | 3. 1.0 1.500 .00 1.00 | ||
+ | 17. 1.0 9.478 .00 1.00 1.00 | ||
+ | 1. 1.0 14.978 6.00 20.00 .00 .1250 1.00 | ||
+ | 6. 1.0 14.978 5.00 11.00 73.17 23.0000 | ||
+ | 1. 1.0 23.291 7.00 20.00 .00 .1250 -1.86 | ||
+ | 1. 1.0 31.605 8.00 20.00 .00 .1250 -1.71 | ||
+ | 1. 1.0 39.918 9.00 20.00 .00 .1250 -1.57 | ||
+ | 1. 1.0 48.231 10.00 20.00 .00 .1250 -1.43 | ||
+ | 1. 1.0 56.544 11.00 20.00 .00 .1250 -1.29 | ||
+ | 1. 1.0 64.858 12.00 20.00 .00 .1250 -1.14 | ||
+ | 1. 1.0 73.171 13.00 20.00 .00 .1250 2.00 | ||
+ | 1. 1.0 81.541 14.00 20.00 .00 .5000 .00 1.00 | ||
+ | 14. 1.0 100.000 -1.00 | ||
+ | </pre> |
Latest revision as of 01:28, 6 February 2020
Contents
Versions of SCORE compiled for MS-DOS can be run in X-windows (typically on unix or linux computers, but possibly OS X as well) with DOS emulators. This page describes how to run SCORE 4 with dosemu using freedos.
Getting started
Installing and setting up dosemu
Dosemu is one of the DOS/Windows emulators in which SCORE can run. First you will have to install dosemu for your particular operating system and configuration. In Gentoo this is easy to do (as root or with sudo):
emerge dosemu
On other linux systems, you can try "yum install dosemu", "rpm -Uvh dosemu*.rpm" or "apt-get install dosemu" (Ubuntu), or download and compile the source code manually from the dosemu website. Freedos was installed at the same time as dosemu when "emerge dosemu" was run, but you may also need to install that before running dosemu, particularly if you are installing manually.
Once dosemu is installed, type:
dosemu
This will intialize various files in ~/.dosemu which are needed to run dosemu. Dosemu can be run from a non-X terminal or from X-windows in this setup process. To run SCORE for DOS interactively, you will need to run in X-windows for viewing graphical screens, but for the setup process, X-windows is not necessary. Hopefully you will not get any errors... Here is a screenshot of the dosemu terminal which should appear with a C:\> prompt:
To exit from dosemu, type:
exitemu
You should now have a directory called .dosemu in your home directory. Within this directory is a subdirectory called "drive_c". This directory contains files which dosemu calls the C drive when you are running dosemu. Install the SCORE program in this subdirectory. If you have SCORE installed on the C: drive in DOS/Windows, then you should not need to change the SCORE preference file (SCOR4\LIB\PREF-4.SCR).
Disk drives
- The C: drive maps to this subdirectory within your homedirectory: ~/.dosemu/drive_c.
- The D: drive maps to your unix home directory. This allows unix/dos file interactions within DOSemu but outside of the ~/.dosemu directory. For example, you can process your SCORE files on the D: drive in dosemu which allows you to store them in your unix home directory (or a subdirectory within your home).
Running SCORE in dosemu
To run SCORE in dosemu with linux, you must use X-windows. Most linux systems are running X-windows by default, so this should not be a problem; otherwise, you would type "startx" at the text-only console. In an X-window terminal, you should now type:
dosemu
Alternatively, if you have an X-server running, but are using a non-X terminal, you may need to type:
dosemu -X
Then you can run SCORE as usual in DOS:
cd scor4 scor4.exe
or if you are located in the C:\ root directory:
scor4\scor4.exe
or from any DOS drive:
c:\scor4\scor4.exe
After the SCORE splash-screen you should see something like this:
Now SCORE can be used as usual. Sometimes the mouse cursor does not appear when starting dosemu. Restarting it solves the problem. Here is some example music (PMX 1, PMX2) being edited in SCORE within dosemu:
SCORE startup script
The PERL program at the bottom of this section can be used to automate the processes of starting SCORE from the linux command-line. Place the script in a file called "scor4" within your search path (such as /usr/local/bin) and then set the executable permission for the script:
chmod 0755 scor4
Then you can use the linux "scor4" command to start the actual DOS SCOR4.EXE program in one step.
The "scor4" script found below will automatically determine which DOS directory maps to your current working directory. If you are somewhere in your home directory, the script will move to that equivalent location on the D: drive in DOS before starting SCOR4.EXE. If you are located in ~/.dosemu/drive_c when you run the "scor4" script, the DOS directory will be set to the C: drive (similar for any ~/.dosemu/drive_? directory). An optional filename to start editing can be given to the "scor4" script as well.
For example, suppose you are in a subdirectory of your home directory called "score". Then if you type:
scor4 test.mus
the scor4 script will open dosemu, change directory to D:\score and then run SCOR4.EXE, loading test.mus into the score editor. All in a single step.
You can specify a different directory other than your current working directory in linux by using the -d option. The given directory can be a linux directory (which should be mappable to a DOS drive location), or can be a dos drive:directory pathname. For example to start editing the file "test.mus" in the D:\score directory from any linux location:
scor4 test.mus -w d:/score
Alternatively the directory name can be given at the same time as the filename:
scor4 d:/score/test.mus
Backslashes can be used for the pathname, but will have to be doubled in order to be first parsed by the linux terminal:
scor4 d:\\score\\test.mus
#!/usr/bin/perl # Program name: scor4 # Usage: scor4 [.pmx or .mus file] use strict; use Getopt::Mixed; # command-line options parsing use vars qw/ $opt_d /; # used to override current working directory my $options = 'd=s w>d dir>d directory>d'; Getopt::Mixed::getOptions($options); my ($dosdrive, $dosdir, $filename)=getDosDriveDirAndFilename($opt_d, $ARGV[0]); my $input = "\\P1;"; $input .= "$dosdrive:\\r"; $input .= "cd $dosdir\\r"; $input .= "c:\\\\scor4\\\\scor4.exe $filename\\r"; $input .= "\\r"; my $command = "dosemu -X -quiet -input '$input'"; print "Type \"exitemu\" to leave DOS\n"; print "DOS_DIRECTORY: $dosdrive:$dosdir\n"; print "COMMAND: $command\n"; system($command); exit(0); sub getDosDriveDirAndFilename { my ($directory, $filename) = @_; $filename =~ s/\/+/\\/g; $filename =~ s/\\+/\\\\/g; if ($filename =~ /\\/) { if ($filename =~ /^(.*\\)([^\\]*)/) { $directory = $1; $filename = $2; } } my $cwd = ""; my $homedir = $ENV{'HOME'}; if ($directory =~ /^\s*$/) { $cwd = $ENV{'PWD'}; $directory = $cwd; } my $dosdrive = "c"; my $dosdir = "/"; if ($directory =~ /^([a-zA-Z]):(.*)/) { $dosdrive = $1; $dosdir = $2; } elsif ($directory =~ /^$homedir/) { if ($directory =~ /^$homedir\/.dosemu\/drive_([a-zA-Z])\/?(.*)/) { $dosdrive = "$1"; $dosdir = "/$2"; } elsif ($directory =~ /^$homedir\/?(.*)/) { $dosdrive = "d"; $dosdir = "/$1"; } } elsif ($directory !~ /^\s*$/) { $dosdir = "/$directory"; } $dosdir =~ s/\/+/\\/g; $dosdir =~ s/\\+/\\\\/g; $dosdir =~ s/\\+$//; return ($dosdrive, $dosdir, $filename); }
To run this program, you may need the PERL module Getopt::Mixed (or delete the options processing code in the above program). To install, type as root:
perl -MCPAN -e shell
If you have not used this command before there will be some setup questions. After initialization, type the command:
install Getopt::Mixed
If you have run the perl -MCPAN command before, then you can also type this from the command-line:
perl -MCPAN -e "install Getopt::Mixed"
Useful dosemu commands
Dosemu stores the default executable programs on the read-only Z: drive. You can see a list of the search path for commands by typing:
echo %PATH%
which should reply:
z:\bin;z:\gnu;z:\dosemu
exitemu
To exit from dosemu, as mentioned above, type:
exitemu
unix
A useful command within dosemu is unix.com which has the the ability to run unix commands within dosemu. Prefix any unix command with the word "unix" to run the arguments on the operating system which is running dosemu as if they were a command:
unix uname -a Linux hostname 2.6.32-gentoo-r7 #1 SMP Mon Jul 12 05:51:36 PDT 2010 i686 Intel(R) Core(TM)2 Duo CPU E6750 @ 2.66GHz GenuineIntel GNU/Linux
long filenames
To view long filenames (rather than 8+3 length names), use the /LFN option for dir:
dir/lfn
Alternatively, you can use the Z:\GNU\LS.EXE program to view a list of files in a unix style:
ls -asCF
Useful dosemu options
For lists of all options, try these two man pages:
man dosemu man dosemu.bin
-input option
The -input option can be used to pre-type characters into DOS when dosemu is first called. For example, the following unix command will start dosemu and then start SCORE 4 in a single step:
dosemu -quiet -input "\\P1;c:\\\\scor4\\\\scor4.exe\\r\\r"
Deconstruction of the input string:
- \\P1; == set the keypress rate to 1/100th of a second. This will type the characters in the input string as fast as possible into dosemu.
- c:\\\\score4\\\\score4.exe == this is full DOS path name of the score4 program. Four backslash characters are needed to generate a single backslash in the path name. The unix terminal first converts "\\" pairs into single backslashes. Then the dosemu will take "\\" pairs and generate a single backslash which is finally sent to DOS as a keypress. So the final command typed into DOS with this string is:
c:\scor4\scor4.exe
- \\r == this is the enter key in DOS. The second "\\r" in the input string is used to skip the SCORE editor without pausing at the splash screen.
This command can be used more conveniently in a shell script, or as an alias (The SCORE startup script section describes a more generalized solution and the alias method of starting SCORE). To use as an alias in the bash shell, you can type or permanently add this line to the ~/.bashrc file:
alias scor4="dosemu -quiet -input '\\P1;c:\\\\scor4\\\\scor4.exe\\r\\r'"
Log out and in again or type this command to activate the alias within the ~/.bashrc file:
. ~/.bashrc
Then you can type:
scor4
in an X-windows terminal which will start dosemu and open the scor4.exe program in a single step.
The -quiet option is used in this case to prevent dosemu from asking for a keypress to continue (which will happen in certain circumstance and option configurations).
-t option
Dosemu will start up in X-windows mode by default if an X-windows server connection can be found. Use the -t option to force it to open in terminal mode. This is useful for batch-processing with SCORE, since the graphics screens can be avoided which will speed up file processing.
-dumb option
To run a single DOS command, the -dumb option will suppress startup text until the provided command has been started, and then exit after the command has finished. For example, to display a list of files in the default startup directory (the C:\ drive), type this command in a unix terminal:
dosemu -dumb dir
The -dumb option only opens a terminal (like the -t option), so this option is not useful for interactive use of SCORE.
The -dumb option allows standard output processing of the output from dosemu, such as this command to scroll through a long list of files:
dosemu -dumb dir | less
or
dosemu -dumb dir > listing.txt
to save a list of the files in a file called listing.txt.
-s option
The -s option is used to access the hardware (video, keyboard, mouse) directly. This might give the most realistic emulation of DOS for SCORE (but untested).
Dosemu configuration
The dosemu configuration file is found in /etc/dosemu/dosemu.conf. Useful settings are given below.
Low-memory access
In some configurations of dosemu (1.4.0.0 and earlier) and versions of linux (about 3.0.0 and later), you will get the following message caused by the operating system preventing access of dosemu to lower addresses in memory (to minimize security risks to the operating system):
EXPERIMENTAL: using non-zero memory base address 0x110000. You can use the better-tested zero based setup using sysctl -w vm.mmap_min_addr=0 as root, or by changing the vm.mmap_min_addr setting in /etc/sysctl.conf or a file in /etc/sysctl.d/ to 0.
Installing dosemu 1.4.0.1 or higher will prevent this warning message from being printed. Or you can allow dosemu to access low-addressed memory. For example, on Ubuntu computers in the file /etc/sysctl.d/10-zeropage.conf, change the line:
vm.mmap_min_addr = 65536
to
vm.mmap_min_addr = 0
Then reboot-the computer to activate the newer setting.
Keyboard layout
By default the keyboard layout variable is set to "auto". This may cause problems if you are running dosemu without X-windows. In this case, dosemu asks you to press ↵ Enter so that it can identify the type of keyboard. This feature is not useful for batch processing in dosemu. This need to press ↵ Enter can be removed by setting the $_layout variable in the configuration file, such as a US keyboard layout:
$_layout = "us";
Process priority
The priority level of the dosemu process. By default the priority is set to be the nicest at 1. Increasing this (probably up to 15) will give a higher priority to the dosemu program. Using a priority of 0 will use all computer resources to run dosemu (probably dangerous to do if you are not careful). To set to a mid-level priority add this line to dosemu.conf:
$_hogthreshold = (7)
CPU speed emulation
By default dosemu sets the emulated cpu speed. You can set manually:
$_cpuspeed = (2000)
This seems to speed up the emulation.
Disable CD-ROM drive
To disable use of the CD-ROM drive (or have dosemu search for it when starting), change this line in ~/.dosemu/drive_c/autoexec.bat:
lredir e: linux\fs/media/cdrom c
to
rem lredir e: linux\fs/media/cdrom c
Other DOS emulators
- On Apple OS X:
- On Windows:
- dosbox — see Tom Broadhead's instructions for running SCORE in dosbox.
- ScummVM
Converting SCORE EPS into PDF, PNG or SVG files
EPS to PDF
The Encapsulated PostScript files generated by SCORE can be converted to a pdf file with the command-line program ps2pdf which is a front-end to GhostScript:
ps2pdf mytest.eps
which will automatically create mytest.pdf. Or used in a pipeline:
cat mytest.eps | ps2pdf - - > mytest.pdf
Using the default settings, ps2pdf will generate a PDF file of the entire page of music: fullpage.pdf. In this case the music was placed in the default position at the bottom of the page when created in SCORE (so you may have to scroll down in the PDF viewer to see it).
You can give the -dEPSCrop option to ps2pdf so that the bounding box region of the EPS is used as the margins in the output PDF file:
cat mytest.eps | ps2pdf -dEPSCrop - - > boundingbox.pdf
To produce a PDF file which does not contain any font information (more portable):
gs -q -dNOPAUSE -dBATCH -dSAFER -dNOCACHE -sDEVICE=epswrite \ -sOutputFile=output.eps input.eps ps2pdf -dEPSCrop output.eps output.pdf
Other important options for ps2pdf/gs:
-sPAPERSIZE=letter
Use this option if the music is printed to U.S. letter size of 8.5" by 11". By default the ps2pdf program is usually set up to generate pages in the A4 size.
-dPDFSETTINGS=/prepress
This is useful to make PDF/X conformant (with embedded fonts).
-dCompatibilityLevel=1.4
The compatibility level of 1.4 makes the PDF compatible with older PDF viewing programs.
EPS to PNG
Here is an example of converting the EPS file into a PNG image using pstopnm and ImageMagick's convert program:
cat mytest.eps | pstopnm -dpi=300 | convert - -trim -resize '40%' mytest.png
which results in this image:
The pstopnm program uses GhostScript to extract a bitmap from the EPS file. You can also directly call the gs command to convert the EPS file into a PNG file. The following example will also anti-alias the image, which is done above using the convert command after pstopnm extracts a higher-resolution 2-color image.
gs -sDEVICE=pnggray -dEPSCrop -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -r91 -o output.png input.eps
which results in this image:
The second method of extracting PNG image from EPS files is faster (80 ms compared to 616 ms for this test image). The -r 91 option samples the EPS image at 91 pixels per inch. The -dEPSCrop option causes the output image region to match the bounding box information within the EPS file, rather than the entire page. The -dGraphicsAlphaBits=4 option controls the anti-aliasing amount. Use 2 for a coarser anti-aliasing amount, or 1 (or omit the Alpha options) for no anti-aliasing. See the GhostScript options for more conversion controls. For colored images, use the device option -sDEVICE=png16m.
EPS to SVG
To generate an SVG graphic from EPS, the EPS file should be processed in two steps. The first step is optional if the EPS file does not contain text:
gs -q -dNOPAUSE -dBATCH -dSAFER -dNOCACHE -sDEVICE=epswrite \ -sOutputFile=nofonts.eps input.eps
The above GhostScript command will convert text from fonts to character outlines in the EPS data which is written to nofonts.eps (primarily caused by adding the -dNOCACHE option). After fonts have been removed from the EPS file (or there were no fonts to begin with), use this command to create the SVG file:
inkscape `pwd`/nofonts.eps -T -l output.svg
which generates this image:
The above image is actually a PNG file, since WikiMedia automatically converts SVG files (vector graphics) into PNG files (bitmap graphics) so that the image can be viewed on any browser. Click on the above image twice to view the raw SVG image in the browser.
The options to inkscape used for this conversion from EPS into SVG:
- `pwd`/file.eps → Inkscape (v0.48) cannot read EPS files unless they are given with absolute path names. Pwd is the unix command which displays the present working directory.
- -l → Set the output type to plain SVG (as opposed to Inkscape SVG).
- -T → convert text characters into outlines. This is needed for portable display of text since necessary fonts may not be available on client browsers. The gs command above must be used first to convert the fonts to outlines in the EPS file for this option to work.
The above image is automatically converted into a PNG file in mediawiki (click twice on the image to see the raw SVG image). Here is a raw display of the same SVG graphic directly on this webpage (which will not display on older Internet Explorer versions and has scaling problems in recent IE versions) with a size carefully chosen to minimize anti-aliasing:
If this page is printed to a 600 dpi printer, then the above raw SVG image will be printed at 600 dpi (even though it is displayed on the screen around 100 dpi).
Here is a PERL script which can be used to automatically convert from EPS to SVG files in one step:
#!/usr/bin/perl # Program name: eps2svg # Usage: eps2svg [eps file(s)] # Converts EPS files into SVG files, converting # text into outlines. my $ext; my $base; my $file; my $command1; my $command2; my $tempfile = "temp"; $tempfile .= int(rand(1000000)); $tempfile .= ".eps"; foreach $file (@ARGV) { $base = $file; $base =~ s/\.[^.]*//; $ext = $file; $ext =~ s/^$base\.//; next if $ext !~ /[e]ps/i; # first embed fonts in file $command1 = "gs -q -dNOPAUSE -dBATCH -dSAFER -dNOCACHE"; $command1 .= " -sDEVICE=epswrite"; $command1 .= " -sOutputFile=$tempfile"; $command1 .= " $file"; # then convert to SVG $command2 = " inkscape `pwd`/$tempfile -T -l $base.svg"; print "Processing $file...\n"; `$command1`; `$command2`; `rm -f $tempfile`; }
Underlying software packages used to generate SVG graphics from PDF files:
- Poppler: a free software library used to render PDF documents.
- Cairo: a software library used to provide a vector graphics-based, device-independent API for software developers.
SCORE in batch mode using dosemu
SCORE can be used in an automatic manner with dosemu. In this case the -I option of dosemu can be used to feed keystrokes to SCORE as if you were typing them.
As an example, suppose that you have a file called mytest.pmx which contains ASCII data for a page of music:
8. 1.0 .000 .00 .00 .00 3. 1.0 1.500 17. 1.0 9.500 .00 1.00 1. 1.0 14.300 1.00 10.00 .00 1.0000 1. 1.0 29.275 2.00 10.00 .00 1.0000 1. 1.0 44.250 3.00 10.00 .00 1.0000 1. 1.0 59.225 4.00 10.00 .00 1.0000 14. 1.0 74.200 1.00 1. 1.0 77.700 5.00 10.00 .00 1.0000 1. 1.0 92.675 6.00 10.00 .00 1.0000 1. 1.0 107.650 7.00 20.00 .00 1.0000 1. 1.0 122.625 8.00 20.00 .00 1.0000 14. 1.0 137.600 1.00 1. 1.0 141.100 9.00 20.00 .00 1.0000 1. 1.0 156.075 10.00 20.00 .00 1.0000 1. 1.0 171.050 11.00 20.00 .00 1.0000 1. 1.0 186.025 12.00 20.00 .00 1.0000 14. 1.0 200.000 1.00 2.00
To create an Encapsulated-PostScript file of this music, you can type this command in the unix terminal (run from the ~/.dosemu/drive_c directory (or any subdirectory within) and assuming mytext.pmx is in the same subdirectory):
LANG=utf-8 dosemu -input "\P1;c:\\scor4\\scor4.exe\r\rre mytest.pmx\rprint\r1 mytest.eps\ry\rg\rexit\ry\rexitemu\r"
The "LANG=utf-8" may not be necessary, but is used in this case to prevent an error/warning about the character encoding being undefined. The -I option is used to configure dosemu. In this case the -I option is used to pass keystrokes to dosemu. The special characters used in the keystroke string:
\r = carriage return \\ = backspace \P1; = feed 100 characters per second to dosemu. \P20; would feed 5 characters per second (useful for debugging)
Other useful control characters:
\F10; = press the F10 key. \p15; = wait 150 milliseconds before typing next key. \^[ = escape character
The above keystroke string contains the text script necessary to print mytest.pmx into the file mytest.eps:
c:\score\scor4.exe # start SCORE <enter> # skip the splash screen re mytest.pmx # read the macro text print # go to the print menu 1 mytest.eps # save output to mytest.eps y # overwrite mytest.eps (if it exists) g # start printing to file exit # exit from SCORE y # exit without saving any changes exitemu # exit dosemu
You can adjust the script as necessary, adding any special characters such as \r for the enter key.
The final result is a file called mytest.eps.
For more information on the non-interactive modes of dosemu see: http://www.dosemu.org/docs/HOWTO/x304.html#AEN309
Conversion scripts
To run any of the following PERL scripts, save the contents of the program to a file. And then on the command-line type the command:
chmod 0755 program
Where program is the name of the file with the PERL script, and 0755 set the permissions so that anyone can run the program. To run the program, you may have to add "./" (without the quotes) before the command name, such as:
./score2eps *.pmx *.mus
To run the following programs, you may need the PERL module Getopt::Mixed (or delete the options processing code in the above program). To install, type as root:
perl -MCPAN -e shell
If you have not used this command before there will be some setup questions. After initialization, type the command:
install Getopt::Mixed
If you have run the perl -MCPAN command before, then you can also type this from the command-line:
perl -MCPAN -e "install Getopt::Mixed"
score2eps: Converting MUS or PMX data into EPS files
Below is a PERL script which converts PMX files or MUS files into EPS files. Multiple PMX/MUS files can be given as arguments. This automatic method of converting SCORE data into EPS images is not so great because time delays proportional to the amount of data on the page are required (or always use a long delay before starting to print so that music can be drawn on the screen). A more generalized version of the program which solves this problem and also converts ScoreXML files to EPS can be found on this page.
The score2eps script has two options. The -d option can be used to debug. If there is a problem converting a file, you can run the debug mode to watch the various automated steps to see where the problem might be occurring in the process. The -w option can be used to process all files in a directory which is not the one which you are running the program from (but the directory must be accessible to dosemu).
A caveat is that you should not type any characters on the computer keyboard while this program (or any other conversion script given further below) is running, since the characters will be sent to dosemu and interleave with the automatic feed of characters which are part of the conversion processing. This problem does not occur if you change window focus from the terminal in which you are running the program.
#!/usr/bin/perl # Program name: score2eps # Usage: score2eps [.pmx and/or .mus file(s)] # This will create .eps with same base filename as input files. use strict; use Getopt::Mixed; # command-line options parsing use vars qw/ $opt_d /; # run in debug mode if -d is given on command line use vars qw/ $opt_w /; # set the default directory if not current one my $options = 'd debug>d'; $options .= ' w=s dir>w'; Getopt::Mixed::getOptions($options); my $debug = int($opt_d); my $directory = $opt_w; my ($file, $filename, $drive, $dir, $basename, $extension); foreach $filename (@ARGV) { ($drive, $dir, $file) = getDosDriveDirAndFilename($directory, $filename); $basename = $file; $basename =~ s/\.[^.]*//; $extension = $file; $extension =~ s/^$basename\.//; print "Processing file $file in $drive:$dir\n"; createEPS($basename, $extension, $drive, $dir); } sub createEPS { my ($base, $ext, $drive, $dir) = @_; my $keystrokes = "\\P3;"; # set keypress speed if ($debug != 0) { $keystrokes = "\\P20;"; # slow down keystrokes for debugging $keystrokes .= "\\r"; # detect keyboard type in -t mode } $keystrokes .= "$drive:\\r" if $drive !~ /^\s*$/; $keystrokes .= "cd $dir\\r" if $dir !~ /^\s*$/; # Run the SCORE program: $keystrokes .= "c:\\\\\\\\scor4\\\\\\\\scor4.exe\\r"; # Add extra \r to skip the splash screen: $keystrokes .= "\\r"; if ($ext =~ /mus/i) { $keystrokes .= "g"; # Get binary data (.mus files) } else { $keystrokes .= "res"; # REad ASCII data (.pmx files) } $keystrokes .= " $base.$ext\\r"; # the file to read # longer pauses needed for larger input files... if ($debug == 0) { $keystrokes .= "\\p20;"; # pause 0.2 seconds } else { $keystrokes .= "\\p200;"; # pause 2 seconds } $keystrokes .= "print\\r"; # go to print menu $keystrokes .= "\\p10;"; $keystrokes .= "1 $base.eps\\r"; # set the print output file $keystrokes .= "y\\r"; # answer yes to possible overwrite question $keystrokes .= "\\F6;"; # print the file data # Longer pauses needed for larger input files... if ($debug == 0) { # About 1 second / 800 objects is needed. $keystrokes .= "\\p100;"; # pause 1 second } else { # About 1 second / 80 objects is needed. $keystrokes .= "\\p1000;"; # pause 10 seconds } $keystrokes .= "exit\\r"; # exit from SCORE if (($ext !~ /mus/i) and ($ext !~ /pag/i)) { $keystrokes .= "y\\r"; # don't save pmx data to binary file } $keystrokes .= "exitemu\\r"; # exit from dosemu my $command = "LANG=none dosemu -quiet"; if ($debug == 0) { $command .= " -t"; } $command .= " -input \"$keystrokes\""; if ($debug == 0) { $command .= " &> /dev/null"; } print "$command\n" if $debug != 0; `$command`; # run the command } sub getDosDriveDirAndFilename { my ($directory, $filename) = @_; $filename =~ s/\/+/\\/g; $filename =~ s/\\+/\\\\/g; if ($filename =~ /\\/) { if ($filename =~ /^(.*\\)([^\\]*)/) { $directory = $1; $filename = $2; } } my $cwd = ""; my $homedir = $ENV{'HOME'}; if ($directory =~ /^\s*$/) { $cwd = $ENV{'PWD'}; $directory = $cwd; } my $dosdrive = "c"; my $dosdir = "/"; if ($directory =~ /^([a-zA-Z]):(.*)/) { $dosdrive = $1; $dosdir = $2; } elsif ($directory =~ /^$homedir/) { if ($directory =~ /^$homedir\/.dosemu\/drive_([a-zA-Z])\/?(.*)/) { $dosdrive = "$1"; $dosdir = "/$2"; } elsif ($directory =~ /^$homedir\/?(.*)/) { $dosdrive = "d"; $dosdir = "/$1"; } } elsif ($directory !~ /^\s*$/) { $dosdir = "/$directory"; } $dosdir =~ s/\/+/\\/g; $dosdir =~ s/\\+/\\\\\\\\/g; $dosdir =~ s/\\+$//; return ($dosdrive, $dosdir, $filename); }
Here is example PMX data which was converted to EPS with the above script, and then converted to SVG using these two steps:
gs -q -dNOPAUSE -dBATCH -dSAFER -dNOCACHE \ -sDEVICE=epswrite -sOutputFile=nofonts.eps input.eps
The above gs (GhostScript) command embeds the fonts used in the input.eps file into the file withfonts.eps. The withfonts.eps file can be converted to the final output.svg image with this command:
inkscape `pwd`/nofonts.eps -T -l output.svg
Here is the final SVG image (rendered automatically by mediawiki into a PNG file, so click twice on the image below to see the raw SVG file displayed in the browser):
Compare the above rendering as a PNG image to a direct display of the SVG image below (not viewable on older versions of Internet Explorer, and does not scale well on recent IE versions). The difference will be more noticeable if this page is printed.
mus2eps: Faster script for converting MUS into EPS files
The previous script prints directly in SCOR4 which allows the flexibility of automating any commands. However, pauses in the keystroke typing rate is necessary to accommodate switching between the graphics and text screens. The following script uses the SCORLAS4 program. This special-purpose program only prints binary SCORE data files (which end with .mus).
An advantage of printing by this method is that it can be done faster, since the keystrokes do not need to be buffered as much because no graphics need to be displayed, and the video mode remains text. A disadvantage is that it only prints binary SCORE data files. So ASCII numeric data with possible macro instructions cannot be printed with this method.
#!/usr/bin/perl # Program name: mus2eps # Usage: mus2eps [.mus file(s)] # This will create .eps with same base filename as input files. use strict; use Getopt::Mixed; # command-line options parsing use vars qw/ $opt_d /; # run in debug mode if -d is given on command line use vars qw/ $opt_w /; # set the default directory if not current one my $options = 'd debug>d'; $options .= ' w=s dir>w'; Getopt::Mixed::getOptions($options); my $debug = int($opt_d); my $directory = $opt_w; my ($file, $filename, $drive, $dir, $basename, $extension); foreach $filename (@ARGV) { ($drive, $dir, $file) = getDosDriveDirAndFilename($directory, $filename); $basename = $file; $basename =~ s/\.[^.]*//; $extension = $file; $extension =~ s/^$basename\.//; if (($extension =~ /mus/i) or ($extension =~ /pag/i)) { my $tdir = $dir; $tdir =~ s/\\\\/\\/g; print "Processing file $file in $drive:$tdir\n"; createEPS($basename, $extension, $drive, $dir); } } sub createEPS { my ($base, $ext) = @_; my $keystrokes = "\\P1;"; # set keypress speed if ($debug) { $keystrokes = "\\P50;"; # set keypress speed for debugging } $keystrokes .= "$drive:\\r" if $drive !~ /^\s*$/; $keystrokes .= "cd $dir\\r" if $dir !~ /^\s*$/; # run the SCORLAS4 program: $keystrokes .= "c:\\\\scor4\\\\scorlas4.exe\\r"; $keystrokes .= "1\\r"; # 1 = print file $keystrokes .= "\\r"; # print single page $keystrokes .= "$base.$ext 1\\r"; # input filename and count $keystrokes .= "\\r"; # continue $keystrokes .= "1 $base.eps\\r"; # set the print output file $keystrokes .= "y\\r"; # answer yes to possible overwrite question $keystrokes .= "\\F6;"; # print the file if ($debug) { $keystrokes .= "\\p200;"; # pause a little for printing to finish } else { $keystrokes .= "\\p50;"; # pause a little for printing to finish } $keystrokes .= "n\\r"; # don't print another page $keystrokes .= "exitemu\\r"; # exit from dosemu if (-r "$base.$ext") { my $command = "LANG=none dosemu"; if (!$debug) { $command .= " -t"; } $command .= " -quiet -input '$keystrokes'"; if (!$debug) { $command .= " &> /dev/null"; } `$command`; } } sub getDosDriveDirAndFilename { my ($directory, $filename) = @_; $filename =~ s/\/+/\\/g; $filename =~ s/\\+/\\\\/g; if ($filename =~ /\\/) { if ($filename =~ /^(.*\\)([^\\]*)/) { $directory = $1; $filename = $2; } } my $cwd = ""; my $homedir = $ENV{'HOME'}; if ($directory =~ /^\s*$/) { $cwd = $ENV{'PWD'}; $directory = $cwd; } my $dosdrive = "c"; my $dosdir = "/"; if ($directory =~ /^([a-zA-Z]):(.*)/) { $dosdrive = $1; $dosdir = $2; } elsif ($directory =~ /^$homedir/) { if ($directory =~ /^$homedir\/.dosemu\/drive_([a-zA-Z])\/?(.*)/) { $dosdrive = "$1"; $dosdir = "/$2"; } elsif ($directory =~ /^$homedir\/?(.*)/) { $dosdrive = "d"; $dosdir = "/$1"; } } elsif ($directory !~ /^\s*$/) { $dosdir = "/$directory"; } $dosdir =~ s/\/+/\\/g; $dosdir =~ s/\\+/\\\\/g; $dosdir =~ s/\\+$//; return ($dosdrive, $dosdir, $filename); }
pmx2mus: Converting PMX into MUS files
The following script will convert ASCII notation data into binary data. Binary data can be printed with SCORLAS4.exe. ASCII data can contain plain numeric data, or macro commands. Options understood by the program:
- -d → run in debug mode (display the program in X-windows with the keypress rate slowed down)
- -w directory → run in the given DOS or linux directory. If a linux directory, then must be mappable to a DOS directory (i.e., it has to be somewhere in your home directory tree).
- -o filename → set the output filename. By default output filenames are generated automatically by removing any extension from the input filename, and appending ".mus". When the -o option is not used, multiple input files can be processed at the same time. When the -o option is used, only the first file will be processed and all subsequent filenames will be ignored.
#!/usr/bin/perl # Program name: pmx2mus # Usage: pmx2mus [.pmx file(s)] # This will create .mus with same base filename as input files. use strict; use Getopt::Mixed; # command-line options parsing use vars qw/ $opt_d /; # run in debug mode if -d is given on command line use vars qw/ $opt_w /; # set the default directory if not current one use vars qw/ $opt_o /; # set the output file name my $options = 'd debug>d'; $options .= ' w=s dir>w'; $options .= ' o=s output>o output-file>o'; Getopt::Mixed::getOptions($options); my $debug = int($opt_d); my $directory = $opt_w; my $outputfile = $opt_o; $outputfile =~ s/.*[\\\/]+//; # no directories allowed with -o option my ($file, $filename, $drive, $dir, $basename, $extension); foreach $filename (@ARGV) { ($drive, $dir, $file) = getDosDriveDirAndFilename($directory, $filename); $basename = $file; $basename =~ s/\.[^.]*//; $extension = $file; $extension =~ s/^$basename\.//; if (($extension !~ /mus/i) and ($extension !~ /pag/i)) { my $tdir = $dir; $tdir =~ s/\\\\\\\\/\\/g; print "Processing file $file in $drive:$tdir\n"; createMUS($basename, $extension, $drive, $dir); } last if $opt_o !~ /^\s*$/; } sub createMUS { my ($base, $ext) = @_; my $keystrokes = "\\P3;"; # set keypress speed if ($debug) { $keystrokes = "\\P20;"; # slow down keystrokes for debugging } else { $keystrokes .= "\\r"; # detect keyboard type in -t mode } $keystrokes .= "$drive:\\r" if $drive !~ /^\s*$/; $keystrokes .= "cd $dir\\r" if $dir !~ /^\s*$/; # Run the SCORE program: $keystrokes .= "c:\\\\\\\\scor4\\\\\\\\scor4.exe\\r"; # Add extra \r to skip the splash screen: $keystrokes .= "\\r"; if ($ext =~ /mus/i) { $keystrokes .= "g"; # Get binary data (.mus files) } else { $keystrokes .= "res"; # REad ASCII data (.pmx files) } $keystrokes .= " $base.$ext\\r"; # the file to read # longer pauses needed for larger input files... if ($debug == 0) { $keystrokes .= "\\p20;"; # pause 0.2 seconds } else { $keystrokes .= "\\p200;"; # pause 2 seconds } my $savefile = $outputfile; $savefile = "$base.mus" if $savefile =~ /^\s*$/; $keystrokes .= "sa $savefile\\r"; if (-r "$savefile") { # overwite .mus file if it already exists $keystrokes .= "y\\r"; } $keystrokes .= "exit\\r"; # exit from SCORE $keystrokes .= "del #musdir#.tmp\\r"; # clean up the poo $keystrokes .= "exitemu\\r"; # exit from dosemu if (-r "$base.$ext") { my $command = "LANG=none dosemu -quiet"; if (!$debug) { $command .= " -t"; } $command .= " -input \"$keystrokes\""; if (!$debug) { $command .= " &> /dev/null"; } `$command`; # run the command } } sub getDosDriveDirAndFilename { my ($directory, $filename) = @_; $filename =~ s/\/+/\\/g; $filename =~ s/\\+/\\\\/g; if ($filename =~ /\\/) { if ($filename =~ /^(.*\\)([^\\]*)/) { $directory = $1; $filename = $2; } } my $cwd = ""; my $homedir = $ENV{'HOME'}; if ($directory =~ /^\s*$/) { $cwd = $ENV{'PWD'}; $directory = $cwd; } my $dosdrive = "c"; my $dosdir = "/"; if ($directory =~ /^([a-zA-Z]):(.*)/) { $dosdrive = $1; $dosdir = $2; } elsif ($directory =~ /^$homedir/) { if ($directory =~ /^$homedir\/.dosemu\/drive_([a-zA-Z])\/?(.*)/) { $dosdrive = "$1"; $dosdir = "/$2"; } elsif ($directory =~ /^$homedir\/?(.*)/) { $dosdrive = "d"; $dosdir = "/$1"; } } elsif ($directory !~ /^\s*$/) { $dosdir = "/$directory"; } $dosdir =~ s/\/+/\\/g; $dosdir =~ s/\\+/\\\\\\\\/g; $dosdir =~ s/\\+$//; return ($dosdrive, $dosdir, $filename); }
mus2pmx: Converting from MUS into PMX files
MUS files (or sometimes PAG files which implies binary data for a full page) can be converted to ASCII numeric data by running the PMX command within SCORE. The following script converts binary data files into their ASCII equivalent. Options understood by the program:
- -d → run in debug mode (display the program in X-windows with the keypress rate slowed down)
- -w directory → run in the given DOS or linux directory. If a linux directory, then must be mappable to a DOS directory (i.e., it has to be somewhere in your home directory tree).
- -o filename → set the output filename. By default output filenames are generated automatically by removing any extension from the input filename, and appending ".pmx". When the -o option is not used, multiple input files can be processed at the same time. When the -o option is used, only the first file will be processed and all subsequent filenames will be ignored.
#!/usr/bin/perl # Program name: mus2pmx # Usage: mus2pmx [.mus file(s)] # This will create .pmx with same base filename as input files. use strict; use Getopt::Mixed; # command-line options parsing use vars qw/ $opt_d /; # run in debug mode if -d is given on command line use vars qw/ $opt_w /; # set the default directory if not current one use vars qw/ $opt_o /; # set the output file name my $options = 'd debug>d'; $options .= ' w=s dir>w'; $options .= ' o=s output>o output-file>o'; Getopt::Mixed::getOptions($options); my $debug = int($opt_d); my $directory = $opt_w; my $outputfile = $opt_o; $outputfile =~ s/.*[\\\/]+//; # no directories allowed with -o option my ($file, $filename, $drive, $dir, $basename, $extension); foreach $filename (@ARGV) { ($drive, $dir, $file) = getDosDriveDirAndFilename($directory, $filename); $basename = $file; $basename =~ s/\.[^.]*//; $extension = $file; $extension =~ s/^$basename\.//; if (($extension =~ /mus/i) or ($extension =~ /pag/i)) { my $tdir = $dir; $tdir =~ s/\\\\\\\\/\\/g; print "Processing file $file in $drive:$tdir\n"; createPMX($basename, $extension, $drive, $dir); } last if $opt_o !~ /^\s*$/; } sub createPMX { my ($base, $ext) = @_; my $keystrokes = "\\P3;"; # set keypress speed if ($debug) { $keystrokes = "\\P20;"; # slow down keystrokes for debugging } else { $keystrokes .= "\\r"; # detect keyboard type in -t mode } $keystrokes .= "$drive:\\r" if $drive !~ /^\s*$/; $keystrokes .= "cd $dir\\r" if $dir !~ /^\s*$/; # Run the SCORE program: $keystrokes .= "c:\\\\\\\\scor4\\\\\\\\scor4.exe\\r"; # Add extra \r to skip the splash screen: $keystrokes .= "\\r"; if ($ext =~ /mus/i) { $keystrokes .= "g"; # Get binary data (.mus files) } else { $keystrokes .= "res"; # REad ASCII data (.pmx files) } $keystrokes .= " $base.$ext\\r"; # the file to read # longer pauses needed for larger input files... if ($debug == 0) { $keystrokes .= "\\p20;"; # pause 0.2 seconds } else { $keystrokes .= "\\p200;"; # pause 2 seconds } my $savefile = $outputfile; $savefile = "$base.pmx" if $savefile =~ /^\s*$/; $keystrokes .= "pmx\\r"; $keystrokes.= "$savefile\\r"; if (-r "$savefile") { # overwite .mus file if it already exists $keystrokes .= "y\\r"; } $keystrokes .= "exit\\r"; # exit from SCORE $keystrokes .= "exitemu\\r"; # exit from dosemu if (-r "$base.$ext") { my $command = "LANG=none dosemu -quiet"; if ($debug == 0) { $command .= " -t"; } $command .= " -input \"$keystrokes\""; if ($debug == 0) { $command .= " &> /dev/null"; } `$command`; # run the command } } sub getDosDriveDirAndFilename { my ($directory, $filename) = @_; $filename =~ s/\/+/\\/g; $filename =~ s/\\+/\\\\/g; if ($filename =~ /\\/) { if ($filename =~ /^(.*\\)([^\\]*)/) { $directory = $1; $filename = $2; } } my $cwd = ""; my $homedir = $ENV{'HOME'}; if ($directory =~ /^\s*$/) { $cwd = $ENV{'PWD'}; $directory = $cwd; } my $dosdrive = "c"; my $dosdir = "/"; if ($directory =~ /^([a-zA-Z]):(.*)/) { $dosdrive = $1; $dosdir = $2; } elsif ($directory =~ /^$homedir/) { if ($directory =~ /^$homedir\/.dosemu\/drive_([a-zA-Z])\/?(.*)/) { $dosdrive = "$1"; $dosdir = "/$2"; } elsif ($directory =~ /^$homedir\/?(.*)/) { $dosdrive = "d"; $dosdir = "/$1"; } } elsif ($directory !~ /^\s*$/) { $dosdir = "/$directory"; } $dosdir =~ s/\/+/\\/g; $dosdir =~ s/\\+/\\\\\\\\/g; $dosdir =~ s/\\+$//; return ($dosdrive, $dosdir, $filename); }
mac2pmx: Converting macro text into PMX files
ASCII SCORE data read into the program with RE or RES may contain macros as well as numeric data. Numeric data describing the score is equivalent to the binary data stored in .mus (or .pag) files. Converting macro data into numeric data is non-trivial and essentially can only be done within SCORE itself. The following script will convert any ASCII SCORE file into purely numeric data. The file-naming convention for this program is to store macro data in a file ending in .txt. Any filename ending except .pmx, .mus or .pag will also work.
For example, the following data from user input mode can be loaded into SCORE via the RES command exactly like purely numeric text can. RES is better for loading such macro text non-interactively since this version of RE will not prompt the user to see if they want to edit the input.
IN1 0 0 1.0000 100 0 100 TR/K4F/E4/G/F/A/B/M/EU/D/C/PB/A/B/MH; EX4/Q/SX4/Q/Q; S 6:9/FE 11/C+ 1 5/C- 6 10; 2B; 1 2/3 4; lj 1 1
Using the mac2pmx will generate a fully numeric description of the notation:
8. 1.0 .000 .00 1.00 100.00 3. 1.0 1.500 17. 1.0 9.315 .00 -4.00 1. 1.0 23.215 3.00 10.00 .00 .5000 .50 .00 4. 1.0 23.215 -3.50 999.00 49.29 6. 1.0 23.215 3.50 5.00 29.59 11.0000 5. 1.0 23.215 1.00 2.00 29.59 -1.3117 -1.00 1. 1.0 29.595 5.00 10.00 .00 .5000 .00 .00 1. 1.0 35.974 4.00 10.00 .00 .5000 .50 .00 6. 1.0 35.974 4.50 6.00 42.35 11.0000 5. 1.0 35.974 2.00 4.00 42.35 -1.4117 -1.00 1. 1.0 42.354 6.00 10.00 .00 .5000 .00 .00 1. 1.0 49.287 7.00 20.00 .00 1.0000 14. 1.0 58.395 1.00 1. 1.0 61.526 10.00 20.00 .00 .2500 2.00 .00 .00 7.00 4. 1.0 61.526 -3.50 999.00 80.75 -1.0000 6. 1.0 61.526 8.00 7.00 75.94 22.0000 1. 1.0 66.332 9.00 20.00 .00 .2500 1.33 .00 .00 7.00 1. 1.0 71.138 8.00 20.00 .00 .2500 .67 .00 .00 7.00 1. 1.0 75.945 7.00 20.00 .00 .2500 .00 .00 .00 7.00 1. 1.0 80.751 6.00 10.00 .00 1.0000 1. 1.0 90.043 7.00 20.00 .00 1.0000 .00 .00 .00 14.00 14. 1.0 100.000 1.00 2.00
Either of the above SCORE data files can be converted into an EPS graphical score using score2eps:
Here is the PERL script which can convert macro text into PMX data (ASCII numeric SCORE data).
#!/usr/bin/perl # Program name: mac2pmx # Usage: mac2pmx [.txt file(s)] # This will create .pmx with same base filename as input files. use strict; my $debug = 0; # run without -t option to see what problem may be my $file; foreach $file (@ARGV) { my $basename = $file; $basename =~ s/\.[^.]*//; my $extension = $file; $extension =~ s/^$basename\.//; if ((-r $file) && ($extension !~ /pmx/i)) { print "Processing file $file\n"; createPMX($basename, $extension); } } sub createPMX { my ($base, $ext) = @_; my $keystrokes = "\\P3;"; # set keypress speed if ($debug != 0) { $keystrokes = "\\P20;"; # slow down keystrokes for debugging $keystrokes .= "\\r"; # detect keyboard type in -t mode } # Run the SCORE program: $keystrokes .= "c:\\\\\\\\scor4\\\\\\\\scor4.exe\\r"; # Add extra \r to skip the splash screen: $keystrokes .= "\\r"; if ($ext =~ /mus/i) { $keystrokes .= "g"; # Get binary data (.mus files) } else { $keystrokes .= "res"; # REad ASCII data (.pmx files) } $keystrokes .= " $base.$ext\\r"; # the file to read # longer pauses needed for larger input files... if ($debug == 0) { $keystrokes .= "\\p20;"; # pause 0.2 seconds } else { $keystrokes .= "\\p200;"; # pause 2 seconds } $keystrokes .= "pmx\\r"; $keystrokes.= "$base.pmx\\r"; if (-r "$base.mus") { # overwite .mus file if it already exists $keystrokes .= "y\\r"; } $keystrokes .= "exit\\r"; # exit from SCORE $keystrokes .= "y\\r"; # don't save editor data $keystrokes .= "exitemu\\r"; # exit from dosemu if (-r "$base.$ext") { my $command = "LANG=none dosemu -quiet"; if ($debug == 0) { $command .= " -t"; } $command .= " -input \"$keystrokes\""; if ($debug == 0) { $command .= " &> /dev/null"; } `$command`; # run the command } }
An example usage of the mac2pmx program is to apply SCORE commands to numeric data. Below is an example which adjusts note stems to display the music with French stemming (where the stem only extends up to the first beam):
Here is input data for mac2pmx:
8. 1.0 .000 .00 .00 100.00 3. 1.0 1.500 .00 1.00 17. 1.0 9.478 .00 1.00 1.00 1. 1.0 14.978 6.00 20.00 .00 .1250 1.00 6. 1.0 14.978 5.00 11.00 73.17 23.0000 1. 1.0 23.291 7.00 20.00 .00 .1250 1.14 1. 1.0 31.605 8.00 20.00 .00 .1250 1.29 1. 1.0 39.918 9.00 20.00 .00 .1250 1.43 1. 1.0 48.231 10.00 20.00 .00 .1250 1.57 1. 1.0 56.544 11.00 20.00 .00 .1250 1.71 1. 1.0 64.858 12.00 20.00 .00 .1250 1.86 1. 1.0 73.171 13.00 20.00 .00 .1250 2.00 1. 1.0 81.541 14.00 20.00 .00 .5000 .00 1.00 14. 1.0 100.000 -1.00 adf 99
Note the line "adf 99" at the bottom of the file. This is the SCORE command to generate French stemming (ADF = "ADjust French"). The integer 99 after the command means to process all staves in the editor (otherwise, you can apply the adjustment to a particular staff).
After running mac2pmx on the above data, the ADF command is gone, and the stem lengths (column 8 of note data) have been changed in the numeric data:
8. 1.0 .000 .00 .00 100.00 3. 1.0 1.500 .00 1.00 17. 1.0 9.478 .00 1.00 1.00 1. 1.0 14.978 6.00 20.00 .00 .1250 1.00 6. 1.0 14.978 5.00 11.00 73.17 23.0000 1. 1.0 23.291 7.00 20.00 .00 .1250 -1.86 1. 1.0 31.605 8.00 20.00 .00 .1250 -1.71 1. 1.0 39.918 9.00 20.00 .00 .1250 -1.57 1. 1.0 48.231 10.00 20.00 .00 .1250 -1.43 1. 1.0 56.544 11.00 20.00 .00 .1250 -1.29 1. 1.0 64.858 12.00 20.00 .00 .1250 -1.14 1. 1.0 73.171 13.00 20.00 .00 .1250 2.00 1. 1.0 81.541 14.00 20.00 .00 .5000 .00 1.00 14. 1.0 100.000 -1.00