-1
0
1
1024
0
Amplitude
Samples
-1
0
1
1024
0
Amplitude
Samples
-1
0
1
1024
0
Amplitude
Samples
2 sine waves
4 sine waves
8 sine waves
16 sine waves
Figure 7.16
Impulse as a sum of all frequencies.
heard as sounds themselves and are referred to as
envelope
or
line
signals in
many situations. The pseudo code listing shows a very simple attack and decay
line that rises to 1
.
0 and then falls to 0
.
0 over a certain number of samples.
f l o a t
b l o c k [ 6 4 ] ;
f l o a t
env = 0 ;
i n t
t i m e = 0 ;
f l o a t
a t t a c k t i m e = 2 5 6 ;
f l o a t
d e c a y t i m e = 7 6 8 ;
f l o a t
a t t a c k s l o p e = 1 . 0 / a t t a c k t i m e ;
f l o a t
d e c a y s l o p e = 1 . 0 / d e c a y t i m e ;
i n t
sample ;
while
( 1 )
f i l l b l o c k ( ) ;
void
f i l l b l o c k ( )
{
sa mple = 6 3 ;
while
( sample
−−
)
{
b l o c k [ sa mple ] = env ;
i f
( t i m e
<
a t t a c k t i m e )
{
env = env + a t t a c k s l o p e ;
}
e l s e i f
( t i m e
<
a t t a c k t i m e + d e c a y t i m e )
{
env = env
−
d e c a y s l o p e ;
}
}
}
7.3 Generating Digital Waveforms
141
We can use a signal as an envelope to modify the volume of another sound.
To do this we multiply the line output by the signal we want to modify. We
say that one signal
modulates
the other. The line signal is modulating a 100Hz
sine wave in the waveform plot of figure 7.17. It produces a symmetrical signal
because the sine signal contains positive and negative values but the enve-
lope is only positive. A positive number times a negative one gives a nega-
tive one, so an envelope signal in the range 0
.
0 to 1
.
0 works fine as a volume
control.
-1
0
1
0
1024
Amplit
u
de
Time
-1
0
1
0
1024
Amplit
u
de
Time
Figure 7.17
Envelope control signals.
Signal Programming Abstraction
So, how do we multiply a line generator by a wave generator in code? Suppose
we had already defined a sine wave generator as a function taking a frequency
argument, and a line generator taking attack and decay times. How would each
function know the global time? It would be tedious to pass it to every function.
while
( sample
−−
)
{
b l o c k [ sa mple ] = l i n e ( 1 0 , 1 0 0 , t i m e )
∗
s i n e w a v e ( 4 4 0 , t i m e ) ;
}
What we really want is a much better language than C for sound design. Low-
level languages are great for efficiently designing basic functions, or objects,
sometimes called
unit generators
. By doing so we obtain a layer of abstraction,
hiding away the messy details like sample rates, time, buffers, and memory allo-
cation. Since the 1960s many computer languages have been developed specifi-
cally for sound (Geiger 2005; Roads 1996). Most have been designed for musical
applications, giving them features which are superfluous but not necessarily in
conflict with our needs as sound designers. Two contrasting, historically impor-
tant classes are the imperative MUSIC-N type languages originating with Max
Mathews, from which Csound (Vercoe) descends, and the functional Lisp based
family like Common Lisp Music (Schottstaedt) and Nyquist (Dannenberg). The
two code snippets below (from Geiger 2005) illustrate these.
Do'stlaringiz bilan baham: |