Chaining files - a further discussion

Allan Gardner
In the Questions and Answers sections of AMPLINEX 008 and 010 a few points were raised about the problem of chaining one program from another. I would like to discuss these further in order, I hope, to clear up any misunderstandings that some members may have.
Firstly, may I say that there is no one correct way to accomplish the chaining of one file by another, (or anything else in AMPLE) - the main criterion is 'does it work?', and secondly, 'does it work the way you want it to?'
In chaining from one file to another it might seem there are not too many other factors to worry about, but:
1) Do you want to use an editor whilst the music is running?
2) Do you want to use the keyboard (e.g. to TYPE 'info'), whilst the music is running?
3) Are you not concerned about using the master player (the keyboard) but do want to stop any surplus text printed on the screen at the time of CHAINing?
When I first encountered the problem of chaining files, my main consideration was for a chaining method that did not put anything on the screen. Also I did not want to use the function keys, as they are often re-defined, so that, for instance, you cannot always rely on function key 9 being the 'Jukebox' key (see editor's note in the Hints & Tips section of AMPLINEX 010).
So the result of all this was the method of performing a loop in the master player. This checked for the value of a variable which was set by a music-player at the end of the piece of music.
The example I supplied to DCT, which is available as a downloadable worksheet, is simply this method in a fairly easy-to-understand format.
The subsequent version supplied with the AMPLE Jukebox program in November 1988's edition of A&B Computing is virtually the same, the only difference being that the file to LOAD RUN is always 'Jukebox', as the file sequence can be predetermined from the Jukebox program itself.
It is worth noting that I wrote these versions at the end of 1987, and I still have a lot of learning to do about the intricacies of AMPLE. (The DCT submission went in at the beginning of 1988 and the A&B submission in May 1988 - and you thought 2 months was a long time to wait for the next issue of AMPLINEX!)
Both of these versions suffer from the problem of not having access to the keyboard, because the master player is tied up with checking the 'finished' variable, (not, as suggested in AMPLINEX 010, because of the use of QTIME and IDLE).
This does, however, stop the use of any editors that may be present (there being no keyboard control), but does not prohibit the use of screen output within the program. I have used this chaining method on a piece which prints lyrics on to the screen and then chains back to the Jukebox when it has finished.
If you want to use the Mixing Desk whilst running a program that auto-chains, then use Bernie Dawson's example (Hints and Tips in AMPLINEX 009), which works fine provided that you are actually using the Mixing Desk (or Notepad) whilst the program is running. Should you change your mind and run the program from the MAIN menu, then an error will be generated at the end of the music.
The main difficulty when trying to understand the operation of the various methods is the use of strings. There are two main points to be aware of:
1) A string ("...") used inside a word definition puts it on top of the string stack. A string entered in command mode is put as the second item down, underneath the input line string.
2) System words like LOAD and SAVE take the string from below the input line, leaving the input line undisturbed.
(For a full explanation see the AMPLE Nucleus Programmer Guide page 51, and if you fully understand it then please explain it to me!)
Also on this subject it is worth mentioning that a command can be terminated with a tab character (ASCII 9) instead of the normal carriage return character (ASCII 13). Try MEM<tab> and you will see what I mean.
I think this has something to do with the method that Bernie Dawson uses, as he puts the "filenam"LOADRUN on the string stack and then pushes the tab character into the keyboard buffer to re-enter the Mixing Desk.
To finish off, here is yet another method for auto-chaining. It requires just one word ('chain') to be placed after the last note sounded (in any part or sub-part). You don't need to alter the RUN word; it doesn't alter any function key definitions; it allows full use of the keyboard whilst the music is playing; and you can even use the editors provided you <tab> out to command mode before the end of the music is reached.
The one slight disadvantage with this method is that it will print "filenam"LOADRUN on the screen, before loading in the next program.
There are many ways around that problem but I'll leave that as an 'exercise for the reader'.
Also, it won't work as it stands, if you stay in the Mixing Desk or Notepad, but it will exit the MAIN menu before chaining.
The definition of the word 'chain' is:
"chain" [
REP( QTIME -200 #< )UNTIL(
IDLE )REP 13$CHR "LOADRUN" $+ """" $+
"filenam" % filename to LOAD RUN
$+ """" $+ 0$CHR $+ LEN FOR( 1 $- ASC
#B12 138 &FFF4 CODE #2 #2 )FOR $2
]
All you do is to include the word 'chain' in the part or sub-part that plays the last note, at a point after that last note.
The way it works is this:
The first line is a repeat loop that waits for the sound queue to empty.
The following line starts to build up the string
<NULL>"filenam"LOADRUN<CR>
The NULL character (ASCII 0) is the standard way to exit the MAIN menu.
Because the string add word ($+) adds the second string to the front of the first string (so, "NEX" "AMPLI" $+ produces "AMPLINEX") the string has to be built up in reverse order. Thus we start with the carriage return character (ASCII 13), followed by "LOADRUN", followed by """" which is a string containing a single quote (") character.
The filename is then entered on to the string stack.
Another quote character is then added, and the string is completed by adding the NULL character.
This string is then pushed, 1 character at a time, into the keyboard buffer. This is performed by a FOR(...)FOR loop with the word LEN ensuring that it loops enough times to process every character in the string.
Within the FOR(...)FOR loop the $- word is used to strip 1 character off the string, leaving the rest of the string at the second level down on the string stack (the reverse of the $+ operation, in fact).
This single-character string is then converted into its equivalent ASCII number (via ASC) and this number is switched into the high-byte position by #B12 (so that, for example, &22 becomes &2200). This is necessary because the high-byte contains the Y value for the OSBYTE call 138 which inserts a character into the keyboard buffer. This is then performed via the CODE command.
Finally, the remaining empty string is discarded with $2.
So, to summarize,
<NULL>"filenam"LOADRUN<CR>
is entered into the keyboard buffer character by character, once the music has ended.
If you use a repeating structure, like
"RUN" [ "123-aabbaa"PLAY ]
then define a new part which contains only the 'chain' word and put it at the end of the PLAY list. For example,
"part1z" [ chain ]
"RUN" [ "123-aabbaaz"PLAY ]
If you don't normally alter function key 9 from the default
"Jukebox"LOAD RUN|M
and if you always want the chained program to be "Jukebox" (e.g. if you use the program from A&B) then the above example can be simplified to:
"chain" [
REP( QTIME -200 #< )UNTIL( IDLE )REP
&8900 138 &FFF4 CODE #2 #2
]
as this merely pushes the contents of function key 9 into the keyboard buffer once the sound queue is empty.
I hope this gives some further ideas of what can be done, and possibly clears up any illusions of 'right' and 'wrong' ways to accomplish things in AMPLE.

Published in AMPLINEX 012, July 1989