Hints and tips

Saving space with VOL, VOICE and X

Alan Minns
At one point in reading through AMPLINEX 021, my face assumed a somewhat rosy hue! The error in the use of ';' instead of 'VOICE' in the note on Mixing Desk faders was an unfortunate slip and I am grateful to Hybrid Technology for correcting my mistake.
It so happens that AMPLINEX 020 included both that note and my arrangement of the Widor Toccata in which this same idea was used as part of a memory-saving technique. It is of use with any pattern of repeated chords and, in the case of the Widor, reduced the program length by more than 1000 bytes.
As an example, take the fragment:
B(+fdc) B(+fdc) ^(^^^)
B(+fdc) g(db^) g(db)
We can define the two words:
"q" [ ^(^^^) ]
"x" [ ON; X 1; ]
where 'q' is a chord rest and 'x' re-strikes every note.
Then the example becomes:
B(+fdc) x q
x g(db^) x
But, if this is tried out, there is an obvious discord. It is an unfortunate feature of AMPLE that 'X' re-strikes the last note on that voice, and a rest is not a note! What happens is that on the last chord in the example, the notes which sound are the required 'g', 'd' and 'b' plus the 'c' from the last 4-note chord.
The solution is to define two further words:
"n" [ 4 VOICE 128 VOL ]
"o" [ 4 VOICE 0 VOL ]
where 'n' (on) and 'o' (off) are used to switch the 4th voice so that it makes no audible effect. Thus:
B(+fdc) x q
x g(db^) o x
n % ready for next 4-note chord

Changing volume – correction

Ted Kirk
Many thanks to Neil Walker for 'fade' and 'swell' (AMPLINEX 021 Hints and Tips): I have always wanted these and wondered why they were not system words, but am much too stupid to have written them myself. Unfortunately, there seems to be a mistake in 'fade': it drops the level once and then holds it. I think the #+ must be a misprint for #*, giving:
"fade" [
FOR( #11 COUNT #* 128 #12 #-
v1 / )FOR #2
]
As these words fade and swell the note 'stepwise', to get a smooth fade or swell you have to use a short hold value and small increments. E.g.
0: 48, C E 6, G 2 48 fade
fades from 128 to 32 over 6 crotchets.

MIDI volume

G Adams
On the subject of MIDI volume control, on page 53 of the Music 2000 User Guide the 'levcont' word reads the '=L' dynamic level from parts and converts the values to controller 1 MIDICONTROL (modulation). It can be made to control MIDI volume thus:
"mvol" [
30 ACT( 3 FVAR #? VOICE
4 FVAR #? 2#* 1#-
% gives 127 from 64=L
7 MIDICONTROL % MIDI
volume
ACT )ACT
]
To use, put after SCORE in each part and set '=L' as normal:
"part1a" [ SCORE mvol 30=L music ]
This does not take into account the AMPLE VOL command. Someone more adept may be able to give a more comprehensive solution.

The PAGE, OSHWM distinction

Alan Minns
I was interested to read Allan Gardner's comments (AMPLINEX 021 Hints and Tips) on the background to his work on the C.PREPARE modification and accept his comments on the equivalence of PAGE and OSHWM in that context. He points out that BASIC is in command when */C.PREPARE is invoked although, of course, when PREPARE is running it is the DFS which is in charge! This is ensured by having *BASIC as the first line in the standard Music 5000 !BOOT file.
But that first line is superfluous - it may be removed or it may be replaced by *AMPLE or even *ARIES if the Aries board is present. In such a case the system will start up and run quite happily even if the BASIC ROM is removed from the machine.
However, let me remain pedantic and point out the difference between the two and how that difference can be put to good use in certain cases.
System initialisation on switch-on or following a Break involves a large number of operations amongst which is the setting of OSHWM to &E00 plus the amount of static, and of private, workspace requested by the paged ROMs. In the case of the humble BBC Model B with DFS only, there are 9 pages of static, and a further 2 pages of private, workspace allocated to the filing system! OSHWM is thus raised to &1900.
At the end of the initialisation, the final task is to enter the BASIC ROM, if present, or the highest priority ROM which has a language entry. Note, however, that in the case of a soft Break the language entered is that which was active before the Break.
If the BASIC ROM is entered, it performs its own initialisation and sets PAGE equal to OSHWM.
Thereafter, these values may be altered quite independently and will only be changed by a Break, or a *BASIC command (since this command initialises the BASIC ROM, PAGE is therefore set to the current value of OSHWM).
We are warned in the manuals that operations such as *COPY, *BACKUP or *COMPACT will corrupt the program stored in memory. True - but if we are careful, damage to a program can be avoided.
The DFS is language-independent and, for operations such as *COMPACT, uses the value of OSHWM as the start of its buffer space. A BASIC program resides between the values of PAGE and TOP. So if we set OSHWM to the page boundary above TOP using *FX 180, disc operations may be carried out with impunity (although, for example, a *BACKUP will take a little longer and require more passes due to the reduced size of memory which it is allowed to use).
On the BBC Model B, ?&244=<x> (where <x> is the required page value) is the illegal equivalent of the *FX 180 call. In either case, *FX 20 restores the original value unless the font is exploded (as is the case with the Staff editor characters) in which case *FX20,2 works instead.
Within the Music 5000 environment, in my system at least, the AMPLE command:
&4D7 #? &NOUT
will print the hex value of the module requirement list at the end of a program. Since this is within a few bytes of the true end of the program, setting OSHWM to the next higher page value plus one is safe.

Published in AMPLINEX 022, July 1991