#116351 sfront: strange envelope behaviour

Package:
sfront
Source:
sfront
Description:
MPEG 4 Structured Audio decoder
Submitter:
Santiago Vila
Date:
2005-07-18 03:38:11 UTC
Severity:
normal
#116351#5
Date:
2001-10-20 10:14:48 UTC
From:
To:
Hello Enrique!

I have two different .sasl files and a .saol file.

sample1.sasl is like this:

0 i1 1
2 i1 1
4 i1 1
0 tempo 60

sample2.sasl is like this:

0 i1 1
2 i1 1
4 i1 1
0 tempo 100

sample.saol is like this:

global {
  table cyc1(harm, 4096, 1);
  srate 44100;
  krate 44100;
}

instr i1 () {
  imports exports table cyc1;
  asig a1;
  ivar atime;
  ivar rtime;
  ivar attack;
  ivar release;
  ivar sustain;
  ksig env;
  atime = 0.1;
  rtime = 0.1;
  if (dur > atime + rtime) {
      attack = atime;
      release = rtime;
      sustain = dur - atime - rtime;
  }
  else {
    attack = dur/2;
    release = dur/2;
    sustain = 0;
  }
  env = kline(0, attack, 1, sustain, 1, release, 0);
  a1 = env*oscil(cyc1, 440);
  output(a1);
}

The following script may be used to generate .wav files from them:

#!/bin/sh
sfront -orc sample.saol -sco sample1.sasl -o sample1.c -aout sample1.wav
sfront -orc sample.saol -sco sample2.sasl -o sample2.c -aout sample2.wav
gcc -o sample1 sample1.c
gcc -o sample2 sample2.c
./sample1
./sample2

If you take a look at the .wav files using for example `mxv'
(from the mixviews package) you'll see that the first note in
sample2.wav has not the same envelope as the others, as it happens in
sample1.wav, where the three notes have the same envelope.

I think this is a bug (but of course it is possible that I'm missing
something important, if so please let me know).

Thanks.

#116351#10
Date:
2001-10-20 12:45:19 UTC
From:
To:
Hi!

I have also been able to reproduce it after simplifying a little your
example, changing i1 like this:

instr i1 () {
  imports exports table cyc1;
  asig a1;
  ivar attack;
  ivar release;
  ivar sustain;
  ksig env;
  attack = dur/2;
  release = dur/2;
  sustain = 0;
  env = kline(0, attack, 1, sustain, 1, release, 0);
  a1 = env*oscil(cyc1, 440);
  output(a1);
}

Initially I also thought it was a bug, but after looking more
carefully, I think that this behaviour is the right one. Consider
these:

  - The first instrument instantiation takes place BEFORE the first
    tempo line is executed. This is consistent with the SAOL
    specification.

  - attack, release and sustain are initialized during this
    instantiation. They are ivar signals, so they wont change their
    value. Your initial tempo line has not yet been executed, so dur
    will be set acording to the default tempo (60 beats/second)

  - After your tempo change takes place, i1 dur variable gets updated
    (or should be, acording to the standard), but your asignments to
    attack, release, and sustain are not being executed any more.

So it seems you have hit a limitation in kline (and other signal
generators) rather than a bug: kline arguments are ivars, so you can
not change your envelope configuration during instrument execution.

In this particular example, you can do an easy workaround by
instantiatin your first instrument a bit latter than 0.0 segs, so that
the tempo line is executed first:

0.1 i1 1
2.1 i1 1
4.1 i1 1
0 tempo 100

This works, but it would stop working if you send tempo changes in the
middle of an instrument execution:

0.1 i1 1
2.1 i1 1
4.1 i1 1
0 tempo 100
0.5 tempo 200

A better approach would be to implement your own k-rate envelope
generator, so you can do tempo changes during instrument executions,
and get the proper envelope applied.

Please let me know if you think that this explanation is
wrong. I may also be missing something.

Thanks,

  Enrique.