Envelope Engineer #2

By Chris Dewhurst

Originally published in EUG #62

In the last article we introduced the BBC Micro and Electron's ENVELOPE statement, looking at how the pitch of a sound can be changed through time. We noted that effectively an Envelope consists of a pitch and an amplitude (volume) envelope, but because you can't change the loudness of a sound on the Electron, the last six parameters are only of significance on the BBC. We also realised that the duration of the sound as specified in the SOUND statement may not necessarily correspond to the time it takes for the Envelope to evolve, or 'open'.

I left you with an exercise that asked you how you could use only two Envelopes and three SOUND statements to play a scale of C major. Well, even if you aren't a musician you should have cottoned on to the idea that you can use the three sections of the pitch envelope to play three notes per SOUND statement. For example, this program will play one note per second:

      10 ENVELOPE 1,100, 0,8,8,0,1,1, 127,0,0,-127,127,127
      20 ENVELOPE 2,100, 0,4,0,0,1,0, 127,0,0,-127,127,127
      30 SOUND 1,1,52,60
      40 SOUND 1,1,72,60
      50 SOUND 1,2,96,40

In this article we will examine the amplitude envelope. Electron owners are welcome to read the following, but I suggest you jump to the bottom where I present the Envelope editor. With it you can edit parameters by moving a cursor around the screen, choose some random parameters, and you can even get the computer to draw a graph of your Envelope. Electron owners should use the numbers 127,0,0,-127,127,127 as the last six parameters for compatibility with the BBC.

Imagine that you are standing on a station platform. A non-stop train is approaching, and you are listening to what happens to the volume of the sound as the train comes and goes:

  1. Train approaching from the distance. The sound starts quitely and grows steadily louder.
  2. There is a sort of 'thump' as the front of the train passes where you are standing on the platform, and the sound drops very slightly to leave the whooshing sound of the rest of the train going past.
  3. This whooshing sound continues until the train and all of its coaches have passed through the station.
  4. Train disappears into the distance - sound dies away.

We can say that step (1) is the ATTACK, step (2) is the DECAY, step (3) is the SUSTAIN, and step (4) is the RELEASE of the train sound.

This is the basis of the amplitude envelope, the last six parameters of the ENVELOPE statement:

      ENVELOPE n,s, pi1,pi2,pi3,pr1,pr2,pr3, aa,ad,as,ar,ala,ald

The first four of these six parameters - aa,ad,as,ar - describe how quickly each of the four stages (attack, decay, sustain, release) will happen. As you can see, the shorthand helps you to remember what they do. 'a' means that we are talking about the 'a'mplitude envelope, as opposed to 'pi'tch. With the 9th parameter of the ENVELOPE statment, for instance, the second 'a' of 'aa' means 'a'ttack.

The final two parameters, 'ala' and 'ald', specify the target level of attack and the target level of decay respectively. The computer will start the sound at zero volume, and get it to the target attack in stages of the number specified in 'aa'. For example, if aa=2 and ala=127, it will take 127 DIV 2 = 63 steps to get there.

Remember, when we talk about "steps", we mean the number you specified in 's', parameter 2 of the ENVELOPE statement. If s=1 then in the above case it will take about 63 centiseconds (just over half a second) for the volume of the sound to reach its target from zero amplitude. If s=2 then it would take (127 DIV 2)*2=126 centiseconds, and so on.

The values that are allowed for each amplitude parameter are as follows:

    Parameter    Name         Range              Description
    ---------    ----         -----              -----------
          9       aa        -127 to 127          Attack rate 

         10       ad        -127 to 127          Decay rate

         11       as        -127 tp 0            Sustain rate

         12       ar        -127 to 0            Release rate 

         13       ala          0 to 127          Attack target level

         14       ald          0 to 127          Decay target level

Note that it's theoretically possible to have a negative attack rate. This depends on the sound that uses an Envelope with a such negative attack rate interrupting a sound on the same channel which provides the starting amplitude. To be honest I've never been convinced by this so, from now on, I am assuming that 'aa' can be 0 to 127 and 'ad' can be 0 to 127.

If you're on the ball, you will have realised that there are only 16 possible levels of volume on the BBC, i.e. 0 to -15 in a SOUND statement that doesn't use envelopes like SOUND 1,1,-9,20. Yet in the amplitude envelope we can specify an increase of 127 if we want to. Therefore an increase aa=16 corresponds to an actual increase of 1, aa=32 corresponds to an actual increase of 2 and so on, up to aa=127 representing an increase of 16.

The reason for having steps as small as 1 is so that we can just specify the attack target and attack rate and let the computer worry about the interpolation, i.e. exactly how fast it will get there, and when the amplitude will actually change to the next step in the range 0-15.

The same happens for the decay section, or decay PHASE as we call a section in the business, of the sound. We specify the decay rate 'ad' and the decay target 'ald'. The BBC will then work out the amount of time it takes to get from 'ala' to 'ald' going at 'ad'.

For example, if ald=127 (the target at the end of the attack phase is 127), ad=-2, and ald=50, then it will take ABS (127-50) DIV -2 = 38 centiseconds for the decay phase, assuming that the scaling factor is 1. If 's'=2 then this would be 76 centiseconds.

Now we enter the release phase. At a cursory glance, it would seem that there isn't enough information in the ENVELOPE statement for the remaining two phases, the sustain phase and the release phase. Why is there a parameter for the sustain rate, yet no parameter for a target at the end of the sustain rate - an 'als', perhaps?

Important point here. The end of the sustain phase is the end of the SOUND statement itself. And the release phase takes place after the sound has stopped, assuming that it hasn't died away already due to a large 'ar' value. Put another way, the duration of a sound as specified in the SOUND statement equals duration of attack phase plus duration of decay phase plus duration of sustain phase only. This is shown on the diagram below:

            ala                              KEY  
127+        /\                               ~~~
   |       /  \                              aa  = attack rate
   |      /    \ad                           ad  = decay rate
   |     /      \                            as  = sustain rate
   |  aa/        \       as                  ar  = release rate
   |   /          \--------------\  -ald     ala = attack target
   |  /                           \          ald = decay target
   | /                             \ar       ae  = end of attack phase
   |/                               \        de  = end of decay phase
  0+---------+-----+-------------+---+       se  = end of sustain phase
   0         ae    de               se  re       = end of SOUND
            127   165              200 225   re  = end of release phase
                                   Time, cS

As before, we'll assume that aa=1, ad=-2, ala=127 and ald=50, and s=1. It takes (127 DIV 1)*1 = 127 centiseconds to get to 'ae', the end of the attack phase, another ABS ((127-50) DIV -2)*1 = 38 cS to get to the end of the decay phase.

Now let us assume that the duration of the sound in the SOUND statement was specified as 40. That is, se = 40*5 = 200 cS. We can work out the duration of the sustain phase by subtracting the attack and decay portions from this number: 200 - 127 - 38 = 35 cS.

From this we can then work out the level to which the amplitude has dropped at the end of the sustain phase:

ald = ald - ABS(35*ar) or ald = ald + 35*ar

= 50 - ABS(35*-1) = 50 + (35*-1)

= 50 - 15 = 50 + (-35)

= 25 = 25

So the amplitude at the end of the sustain phase is 25. In reality, of course, the BBC does all this for us.

What about the release phase? The amplitude level at the end of the release phase is always zero. Assuming that the ar=-1, it will take ABS (25*-1) = 25 centiseconds for the amplitude to drop from its level at the end of the sustain phase (25) to zero.

The actual duration of the sound, including the release phase, is 200 + 25 = 225 cS. Okay, so what happens if the SOUND ends before the Envelope has entered its sustain phase? Or for that matter, what do we hear if the Envelope hasn't even started its decay phase?

The release phase will always kick in when the sound ends, regardless of whether the sound is in its attack, decay, or sustain phase. Just as in the pitch envelope, the duration of the SOUND isn't related to the evolution of the Envelope, with the one exception that the release phase always starts when the duration as specified in the SOUND statement has elapsed.

Again this is assuming the sound hasn't already died away due to a large 'ar' value, in which case there won't be a release phase. Also if you specify an 'ar' of zero the sound will carry on forever.

So let's put it to the test. Type in this:

      ENVELOPE 1,1, 0,0,0,0,0,0, 1,-1,0,-1,127,50

In order to keep things simple, we are not doing anything to the pitch of the sound, which is why pi1,pi2,pi3,pr1,pr2, and pr3 are zero. Type in each of the following statements, pausing between each to listen to the results:

      SOUND 1,1,52,200

SOUND 1,1,52,150

SOUND 1,1,52,50

In the first case, the Envelope is given the chance to fully evolve, complete with attack, sustain, decay and release phases. In the second case, there is no sustain phase because the end of the sound occurs before the end of the attack phase. See the graph above if you aren't sure why this is so.

In the final case, the Envelope has barely got halfway through its attack before the sound ends and the release phase kicks in. This explains why the sound is a little quiter than the previous two, because the Envelope couldn't reach its attack target before the release phase had to start.

Right, this is where Electron owners can dive back in for discussion of the envelope editor. The program runs in Mode 1, but clarity in the way it's written comes with the expense of memory, so it must be run with PAGE at &1700 or lower. There is a lot of calculation involved, based on the discussion with BBC owners above, in drawing a graph of the amplitude.

The screen is in two sections. At the bottom is a graph of the Envelope in its current state. The upper portion displays 13 editable Envelope parameters. The 14th is the Envelope number which is always 1 - we are editing Envelope 1. A further 3 numbers in the SOUND statement can be adjusted in the same way. You can listen to the effects of the Envelope on a different channel, at a different pitch, or with a longer duration.

Use the left and right cursor (arrow) keys to move the highlight bar to each parameter. The name of the parameter is displayed in inverse video in the middle of the screen. The up and down arrows will increment or decrement the parameter currently being highlighted. Pressing SHIFT in conjunction with the up or down arrows will alter the parameter by 10.

Press S to listen to the sound. G will update the graph. The graph axes are coloured red with gradations of half a second (50 cS) along the horizontal time axis. The pitch wave is drawn in green and the amplitude in yellow. The vertical red bar on the right marks the end of the sound according to the SOUND statement.

Often the best sounds result from choosing random numbers for the parameters. Typing R will fill the pitch envelope with a selection of values in the legal range. I haven't done this for the amplitude numbers as personally I have found this to hamper, rather than help, the design process.

Lastly, we have been saying up till now that you can only have 4 Envelopes in memory. An Envelope takes up 16, or &10 bytes of memory. There is one byte per parameter with two left over. That's because the BBC and Electron finds it easier to work with multiples of &10.

The data for Envelopes 1 to 4 are stored in page 8 at &8C0, &8D0, &8E0 and &8F0 respectively. The extra envelopes, Envelopes 5 to 16, are stored in page 9 at &900, &910..&9B0. Page &9 is sometimes used by the cassette filing system or RS423 interface, but if you're not using either then you can store envelopes there.

If you find an interesting Envelope while using the editor, note down the figures on a piece of paper. Assuming EUG carries on, why not send them in?