Magazine Archive

Home -> Magazines -> Issues -> Articles in this issue -> View

Lab Notes: MUS1

With the New Miracle Ingredient - STG

Article from Polyphony, April/May 1978


With the exception of the bare-bones listing of POLY 1.0 that ran in the last issue, we haven't looked at any software — mainly because there was little to examine.

But MUS1 was just recently finalized, so that situation is beginning to change.

MUS1, for the benefit of those of you who haven't been waiting for it for the last six months, is what many would call "system firmware" — and since that has the sort of technical ring to it that tends to make things interesting, we'll call it that, too.

In almost any computer application there are some programs which, for one reason or another, are best handled as firmware — a name that these days means not software (which must be loaded from some storage media external to the computer) and not hardware (a permanently wired collection of gates, etc. which cause a specific, set sequence of actions to take place) but something betwixt and between; most usually, software that is contained in a PROM somewhere.

The most obvious firmware is a monitor program such as PIEBUG. Since this program is the thing that allows for the entry of data and instructions into the memory of the computer in the first place (as well as usually providing whatever de-bugging and editing features the designer thought were important and/or had room for), it is at least inconvenient to have to load it every time it is needed. Much better to have it in a dedicated PROM where it is always available for immediate use.

The firmware of MUS1 is roughly analogous. These are universally useful routines that, with rare exceptions, will be used with everything we do musically. It's a waste of tine and resources to have to load them to RAM from tape (or worse yet, manually) every time they're needed. A PROM is their happiest home. In our 8700 Computer/Controller, MUS1 is a 1702A PROM that occupies the address range $D00-$DFF (IC-17).

Examples? OK, the keyboard reading routine (LOOK). It isn't particularly long or complicated (a little over 30 bytes) but we're going to need it every time we turn on the system — even if it isn't used to read the keyboard, it's the thing that our protocols dictate will be the tempo-determining element in the system (based on the clock rate of the encoder). At some future date the occasion may arise when we can examine this in detail. Today, it's not the point.

The QuAsh drivers (called NOTE) — same thing — we're going to need them for almost everything we do. Why bother to load them?

In addition to these two routines, MUS1 also contains:

INIT: an initialization routine that takes care of setting various variables and buffer areas to a known, acceptable state (as opposed to the random numbers they will contain when power is first applied.)

POLY: essentially the polyphonic (I still prefer polytonic) allocation algorhythm from POLY1.0, except refined somewhat to take less memory space.

TRGN: The new miracle Ingredient — Software Transient Generators (STG). A routine that will serve as a software substitute for ADSRs.

OPTN: A very simple option selecting program that allows the remaining firmware of MUS1 to be tied together into a 16 voice polyphonic synthesizer with or without software transient generators — without having to load any additional software (though several parameters will need to be initialized manually).

All of this is pretty straight-ahead code that should be understandable from the documented listing that appears at the end of this article — you may need to refer back to previous articles in this series for background information; "In Pursuit of the Wild QuAsh" (reference Polyphony, July '77) and "What the Computer Does" (reference Polyphony 4/76) would be particularly useful ones.

Two exceptions, NOTE and TRGN, need some additional explanation — they introduce some new ideas.

In an embryonic form, NOTE was a part of POLY 1.0. It is the responsibility of this routine to take individual entries from the output buffer area (NTBL), add to it the corresponding entry from the Transpose buffer area (TTBL) and output the results to the QuAsh channels. Some aspects of the significance of the addition that takes place will be seen when we look at TRGN — for now, it will suffice to say that this will be an extraordinarily handy convention in a number of cases.

A more important function of NOTE is to make sure that what comes out of the QuAsh channels has no annoying glitches that may be artefacts of the D/A and multiplexing process. In an earlier story, we looked at one of the annoyances — the fact that our 8780 D/A, though quick, takes a finite amount of time to change from one value to the next and if appropriate settling time is not allowed between writes to the QuAsh channels we will be able to hear the changes as a slight "buzz" in each of the channels. The solution here is to output the data first to a "dummy channel" that is occupied solely by the D/A, with no corresponding QuAsh, followed immediately by a write of the identical information to an output which does correspond to a QuAsh channel. The first write allows the D/A to settle while the second strobes the settled output into the appropriate QuAsh channel.

And here we come face to face with the next problem; the QuAsh really need some settling time since they are at their heart nothing more than an RC circuit.

As long as we are thinking in terms of small systems (8 output channels or less) this is not a big problem since it can be dealt with simply by delaying after writing to one QuAsh but before setting up the next. If the delay is not long enough, we will hear changes from one value to the next not as an instantaneous change, but rather as a series of steps from the initial value to the final one:

figure a


In larger systems, this constant delay approach is not a practical solution because there is not enough time during alternate "dummy" scans of the keyboard (the time which our conventions allow for processing, output driving, allocations, etc.) to allow all of the output channels the luxury of a delay. The time comes for the keyboard to be read again (or other things to happen) and the processor is still busy waiting for all of those QuAsh to get to the right value.

The key to the solution of this problem is to notice that there is really only one set of circumstances under which the long QuAsh-settling delay is required, and that's when the output of one of these channels must change from one value to another (which happens only a small percentage of the time) and then, only when the glide of the channel is turned off. (If the glide is on, its integrating action will smooth out the steps; and, in fact, a short write time is preferable here since it will serve to increase the time required for the glide.)

The actual solution is what I feel we should call "DYNAMIC QuAsh DRIVERS" — a small block of programming, more or less in the middle of NOTE.

This part of the program first checks to see if the glide control bit (the most significant bit of the data just written to D/A and S/Hs) was turned on or not. If we are in "glide mode," no delay is required so the program immediately goes to see if there are any channels left to write; if there are, it services them.

If the glide is not on, we have a candidate for dynamic operation so the dynamic mode switch is checked (more later) and if this option is selected the current data is compared to the data that was previously written to this channel (requires a new table that we've generated called "LAST") and if they're different (a change), the program goes into the delay that allows the output of the QuAsh to instantaneously (apparently) step from its previous value to the next one. The new value is saved in LAST (for use next time) and if there are more channels to do — it does them.

SOFTWARE TRANSIENT GENERATORS



Here we begin, for the first time, to replace some of the elements that constitute traditional synthesizer hardware with software that performs the same function (hopefully as well, or better) with less costly hardware. STGs are a good place to start because they're not super difficult to implement.

Just like their hardware equivalents, STGs respond to a note which has just been triggered (pressed on the keyboard) by producing a voltage that rises at a controlled Attack rate. After reaching some peak value, the voltage then drops at a Decay rate until it reaches a pre-set Sustain level where it stays as long as the note remains triggered. When the key is released, the voltage drops to its lowest level at the Release rate.

Computing the number which represents the current value of the transient is only slightly more complicated than adding, subtracting and comparing.

Unlike an ADSR, an STG has no knobs to set, in their place you enter numbers setting Attack rate, etc. into the computer.

Perhaps the biggest problem having to do with STGs is deciding where they should come out. Oh, the QuAsh channels, obviously; but which ones? Of the numerous possibilities, we've selected the convention of having pitch setting voltages (those that correspond to notes) and transient voltages come from alternate QuAsh channels, primarily because this will work nicely with some stuff under development (or consideration, at least), without making obsolete all of the hardware that we've accumulated up to now.

This implies two distinct modes of operation; the first in which the STGs are not asserted and POLY assigns notes to sequential QuAsh channels; and, the second mode (STGs on), in which notes are assigned by POLY* to the odd number QuAsh channels (first, third, etc.) while transients are produced at the even number outputs (second, fourth, etc.).

* Note that POLY checks to see if the STGs are turned on as it assigns notes to outputs.

The note produced at the first QuAsh output has a corresponding transient happening at the second output, and so on. Just as if the trigger from the first channel were patched to the input of an ADSR whose output was somehow tied to the output of the second QuAsh channel.

This would seem a good place to mention (in case it's not already obvious) that in this implementation all of the STGs produce the same kind of transient, and for the kinds of things that we're doing now, this is how it should be. It may also be worth mentioning that while the transients are all the same, they are totally independent where following the triggered and released states of their respective note channels is concerned.

There are also some internal details which muddy the STG waters. For instance, a key that is currently down may require a transient function that is either in the Attack cycle (increasing) or Decay/Sustain cycle (decreasing or holding) depending on its past history (had it already peaked?). Somewhere we need to save information on which cycle the transient is actually in.

Another, somewhat interrelated, problem concerns the smoothing of the transient waveform. Under most conditions, the glide of the QuAsh channels that are being used as transient outputs should be turned on so that a smoothly increasing or decreasing function is produced. But, the glide can't always be on because that would limit the maximum attack rate.

Without having the space to cover it entirely, I can only state that the solution to both of these difficulties lies in the use of the Transpose table and remembering that the data stored in TTBL entries is added to the output parameter in NTBL (where we're storing the actual current value of the transient) before the output operation takes place. Note also that while the data in NTBL is manipulated extensively by POLY and TRGN (as they calculate, allocate, — regurgitate?) TTBL is untouched by computer hands, and this makes it an ideal place to save control type functions. Not only transpositions, but a place that glide and trigger bits and such can be permanently set.

These locations are so handy for this application that in TRGN they have been re-named CWRD (Control-Words... but do not be confused, this is still our old friend TTBL and has no relationship at all to the System Control Word-CTRL) and it is here that we keep track of the A/D/S state of each of the transient channels.

Also, to help me keep things straight in my own mind, the NTBL bytes that are used to store the current value of the transient have been re-named PARM (parameter); but, again, this is the same physical area as NTBL.

NOW, HOW DO WE USE ALL THIS?



Perhaps the best way to begin an essay on how to use MUS1 is to state one of the functions that it was devised to perform. As you are no doubt beginning to realize, we've carefully developed a system that will have applications far beyond what we've discussed to this point. It's complex; and while the complexity implies unmatched versatility, it undeniably has its intimidating aspects.

At one level of use, MUS1 should reduce this intimidation by giving the user an instrument with a specific (though within certain limits alterable) personality the instant that it's turned on, without having to hassle around with loading any additional programs (success) or variables (well...)

Also, these program modules should be written so that they easily interface with future expansions of the system, either hardware or software, so that, when needed, they can be accessed by programs offering distinctly different personalities (success here maybe — only time will really tell).

While we've reduced the intimidation, we've not eliminated it entirely because even when using MUS1 as a stand-alone personality there are some variables which must be initialized before you begin to play — some information that the system must have in order to operate properly. This data could be part of the PROM, but not without significantly compromising versatility.

For instance, we've mentioned in passing a couple of times the System Control Word-CTRL. This is a single word in the computer's RAM memory at location $0E8.

It is most helpful to visualize CTRL as a collection of eight "switches", each bit representing one switch. To MUS1, only two of these switches have any significance — D7, which turns the STGs on and off, and D6, which enables or disables the dynamic mode option. The rest are reserved.

Every time you power up the system, CTRL must be set so that the desired options are selected — there is no default setting that is part of MUS1. If you want dynamic mode (which you should, for now) then bit 7 should be turned on. If you want STGs, bit 8 must be set.

The 4 possible combinations of these 2 bits then have the following significance:

binary hex action
00000000 $00 STGs off; dynamic mode off
01000000 $40 STGs off; dynamic mode on
10000000 $80 STGs on; dynamic mode off
11000000 $00 STGs on; dynamic mode on


CTRL is not the only variable which must be initialized manually. There's also:


Most of these are easily understood or have been examined in the past, so we won't go into any great detail. A few points are worth mentioning, however.

ODLY — this is a number that represents the delay that the QuAsh drivers will use, when required. For normal use, a value in the range of $20-$30 is most appropriate.

OUTS — this variable tells the POLY subroutine how many output channels it has to work with, so that notes don't get lost; we talked about this last time. Now we need to notice that when the STGs are asserted we should think of the QuAsh channel that is producing the transient as simply an extension of the channel producing the note. In other words, the two QuAsh channels constitute a single "hardware supported" channel. A single QuAsh represents two such channels.

ATCK/DCY/SUST/RELS — When the transient generators are turned on, we also need to enter the attack, delay, sustain and release parameters that we want produced. These four entries should need little explanation other than the examples which follow shortly; their range is from $01-$3F, with $01 representing the lowest rate or level and $3F the highest.

PEAK — this fifth transient parameter needs a little extra attention. PEAK has only one use; it determines whether the transient produced is going to be percussive (quickest possible attack and full ADSR segments) or non-percussive. In the non-percussive mode, the glide is on for all segments of the transient and the Decay and Sustain states of the transient are eliminated entirely.

In fact, there is only one bit in the word PEAK that is changed to select one of these two options — the most significant bit. The remaining seven bits should (for now — until you have a real feel for what's happening) be set to $3F (00111111 in binary). If the most significant bit of this word is cleared, you're in percussive mode. If the bit is set (so that PEAK contains $BF — 10111111 in binary) you are in non-percussive mode.

The differences between the two are great. Assume for a moment that we have set the ADSR parameters at $3F/$04/$20/$01 respectively (fastest attack/moderated decay/medium sustain/slowest release) and that we are only going to change the PEAK parameter. If PEAK contains $3F (percussive mode), a 'scope display of the transient will look something like this:

figure b


Setting PEAK to $BF (non-percussive) produces this result:

figure c


Because the glide is now on during the entire attack cycle and the Decay and Sustain portion of the transients are eliminated. Straightforward stuff, really.

We need to cover an example of system set-up before we wind up, but first must notice that the effect of having the PEAK parameter are far more far-reaching than we've been able to cover in detail. A quick example:

ADSR parameters set to $10/$04/$20/$01 and PEAK containing $3F will produce this kind of transient:

figure d


which, when heard, starts out with a non-percussive kind of "swell" with a percussive "pip" added at the last instant before the transition to the Decay and Sustain cycles. This would seem to be a unique and useful transient that isn't produced by traditional ADSRs.

Along the same lines, the TSGs can be considered to be "better" than our hardware ADSRs in that they need not finish the Attack cycle before transitioning to the Release state. If a key is released before its transient has gone all the way to PEAK, the transient immediately switches to the release state. This is frequently called "muting' and it offers the possibility of effective control of expression directly from the AGO keyboard.

A SUMMARY OF SORTS



So, we've gotten our hands on a MUS1 PROM and are ready to start doing things. What has to be done first? Really very little.

First, the System Control Word, Output Delay and number of hardware channels available must be set. For example:

keystrokes explanation
0-E-8-DISP sets monitor pointer to $E8-CTRL
C-0-ENT sets $E8-asserts STGs dynamic mode
3-0-ENT sets ODLY value
0-2-ENT sets output channels at 2


these entries define the personality of the instrument as a 2 voice polyphonic synthesizer (notes from channels A & C) with software transient generators (which appear at QuAsh channels B & D).

Next, we must set the transient parameters to the desired values:

keystrokes explanation
0-B-A-DISP sets monitor pointer to $BA — ATCK
3-F-ENT sets shortest attack
0-4-ENT sets moderate decay
2-0-ENT sets moderate sustain
0-1-ENT sets slowest release
3-F-ENT percussive mode


and you may recognize these parameters as being those that we examined in the illustration earlier.

Finally, we simply begin running the program:

keystrokes explanation
D-0-0-DISP sets monitor pointer to beginning of OPTN
RUN presto — the program runs


A typical patching configuration that would be consistent with these entries would look something like this:

figure e


Oh, yes — I almost forgot. OPTN, like POLY 1.0 , uses the 8700 keyboard to control two important functions. While OPTN is running, touching key 0 of the control keyboard will cause the entire system to be re-initialized. Not the entries that we made manually — those remain unchanged, but all the notes and transients go immediately to zero level.

Similarly, touching key #1 produces a tuning function that makes the synthesizer respond as if all the channels were seeing the second C on a three octave keyboard held down. The transients go, the notes play, etc. After tuning, be sure to re-initialize the system by touching control key #0.

I prefaced one of the earlier paragraphs with "at one level of use." In all of the preceding words, that's all that we've examined — one level of use (the simplest and most obvious level — at that.) . I've also referred in the past to "software modules" which can be strung together in different ways (just as can hardware modules) to produce different effects and personalities. MUS1 is the first set of these modules.

With more regret than you can imagine, I haven't the space here to go into all of the implications of this (even if I knew them all, which I'm sure I don't).

Providing you're more than just casually interested, you should spend some time trying to understand how MUS1 works internally (there are numerous different entry points to the routines that we haven't covered — for instance). I believe that the time investment will be wisely made.

(Click image for higher resolution version)


(Click image for higher resolution version)


More with this topic


Browse by Topic:

Computing


Also featuring gear in this article



Previous Article in this issue

Patches

Next article in this issue

Spotlight


Publisher: Polyphony - Polyphony Publishing Company

The current copyright owner/s of this content may differ from the originally published copyright notice.
More details on copyright ownership...

 

Polyphony - Apr/May 1978

Donated & scanned by: Mike Gorman

Topic:

Computing


Gear in this article:

Sequencer > PAIA > 8700 Computer/Controller


Gear Tags:

CV/Gate Sequencer

Feature by John Simonton

Previous article in this issue:

> Patches

Next article in this issue:

> Spotlight


Help Support The Things You Love

mu:zines is the result of thousands of hours of effort, and will require many thousands more going forward to reach our goals of getting all this content online.

If you value this resource, you can support this project - it really helps!

Donations for January 2025
Issues donated this month: 0

New issues that have been donated or scanned for us this month.

Funds donated this month: £22.00

All donations and support are gratefully appreciated - thank you.


Magazines Needed - Can You Help?

Do you have any of these magazine issues?

> See all issues we need

If so, and you can donate, lend or scan them to help complete our archive, please get in touch via the Contribute page - thanks!

Please Contribute to mu:zines by supplying magazines, scanning or donating funds. Thanks!

Monetary donations go towards site running costs, and the occasional coffee for me if there's anything left over!
muzines_logo_02

Small Print

Terms of usePrivacy