```  1  #!/usr/bin/env python
2
3  """
4  Here are some examples to wet your appetite.
5  To run them, use the number as arg, eg.
6  \$ ./tutorial.py 5
7  Make sure the volume is turned down first!
8  """
9
10  from Sonic import *
11
12  def test00():
13    # play a sin wave
14    sin = Sin() # make a task
15    sin | Dsp() # connect it to a soundcard task
16    while 1:
17      sin.push() # push signal upstream
18
19  def test01():
20    f = 440.0
21    sin = Sin(f)
22    sin | Dsp()
23    while 1:
24      sin.push()
25      f *= 0.99
26      sin.set_f(f) # change the frequency
27
28  def test02():
29    # mixing sources
30    sins = [ Sin(110 + i*110, 0.2) for i in range(5) ]
31    dsp = Dsp()
33    for sin in sins:
36    while 1:
37      # a single push won't work here, so we
38      # pull from downstream
39      dsp.pull()
40
41  # Task objects process signals
42  # obtained from Buffer objects (memory)
43  # via Pipe objects (smart pointers).
44
45  def test03():
46    sin = Sin() # a Task
47    dsp = Dsp() # a Task
48
49    # sin | dsp
50    buf = Buffer() # a Buffer
51    p1 = Pipe( sin, buf )  # open a Pipe
52    p2 = Pipe( buf, dsp ) # another Pipe
53
54    while 1:
55      sin.push()
56
57
58  # pipes can be told to limit how much they read or write.
59  def test04():
60    sin1 = Sin(110)
61    sin2 = Sin(220)
62    dsp = Dsp()
63    buf = Buffer()
64
65    # a utility function (!alias pipe)
66    # that makes pipes between tasks and buffers:
67    p1, p2 = connect( sin1, buf, dsp )
68
69    p1.rlimit( 4096 )
70    # ! this uses a bytecount:
71    # ! each (mono) sample is 2 bytes (a short)
72    # ! so we will get 2048 samples, at 44100 samples/second
73    # ! this is about 1/20th second
74
75    null_log() # turn off logging
76    while 1:
77      while not p1.done():
78        dsp.pull()
79      p1.close()
80      p1 = Pipe( sin2, buf ) # new Pipe
81      p1.rlimit( 4096 )
82      while not p1.done():
83        dsp.pull()
84      p1.close()
85      p1 = Pipe( sin1, buf )
86      p1.rlimit( 4096 )
87    # blech, sounds terrible ..
88
89  # Most of the tasks deal with short int (2 byte) sample data (no floats!).
90
91  def test05():
92    sources = [ Sin(110), Sin(220) ]
93    # You could add more oscillators, eg. Tri() or Squ().
94
95    # Use a linear envelope to smooth the changes between sources
96    w = 128  # smoothing width
97    W = 4096 # total width
98    env = Linear(
99      # these are linear control points: (width, level) pairs
100      ((w, 1<<14), (W-2*w, 1<<14), (w, 0)) )
101    # ! Because Linear objects are arithmetic they
102    # ! deal with sample size, which equals bytecount/2
103
104    ebuf = Buffer() # envelope buffer
105    rmod = RMod() # this will multiply it's inputs
106    dsp = Dsp()
107    connect( env, ebuf, rmod )
108    rmod | dsp
109    sbuf = Buffer() # signal buffer
110    p = Pipe( sources[0], sbuf )
111    Pipe( sbuf, rmod )
112    # draw a picture :)
113
114    p.rlimit(W*2) # ! bytecount
115
116    null_log() # turn off logging
117    i = 0
118    while 1:
119      while not p.done():
120        dsp.pull()
121
122      # check all buffers are empty
123      while dsp.pull():
124        pass
125
126      p.close()
127      i += 1
128      p = Pipe( sources[i%len(sources)], sbuf )
129      p.rlimit(W*2) # ! bytecount
130    # sounds better, huh?
131
132  # Connected objects (pipes, bufs, tasks) all
133  # reference each other, so we only need to hold
134  # a reference to one of them to keep them from being
135  # garbage collected.
136
137  def test06():
138    # FIXME: files need to be in raw (cdr) format.
139    # use eg. sox to convert from/to wav,aif etc:
140    # \$ sox mysound.wav mysound.raw
141    # \$ sox -r 44100 -w -s -c 1 mysound.raw mysound.wav
142    print " *** WARNING: On OSX and PPC platforms you may need to use ./swab.py to swap the byte order of sample.raw. *** "
143    null_log()
145    dsp = Dsp()
146    ifile | dsp
147    while not ifile.done():
148      ifile.push()
149
150  def test07():
151    sources = [ Sin( 60+80*i, 0.3**i ) for i in range(4) ] +\
152      [ Tri( 60+81*i, 0.3**i ) for i in range(4) ]
153    mix = Mix(0.7)
154    dsp = Dsp()
155    dsp( mix( *sources )) # connect using the call notation
156    while 1:
157      dsp.pull()
158
159  # a stereo test
160  def test08():
161    left = Mix()(*[ Sin( 60+80*i, 0.3**i ) for i in range(4) ])
162    right = Mix()(*[ Sin( 40+81*i, 0.3**i ) for i in range(4) ])
163    dsp = Dsp(stereo=1)
164    dsp( Interleave()(left, right) )
165    while 1:
166      dsp.pull()
167
168  # SDL test
169  def test09():
170    dsp = Dsp( mode="r" ) # read from the soundcard
171    dsp | Trace() # make an oscilloscope window
172    while 1:
173      dsp.push()
174
175  if __name__ == "__main__":
176    try:
177      i = int(sys.argv[1])
178      exec "test%.2d()"%i
179    except IndexError:
180      i = 0
181      print __doc__
182
183
184
185
```