1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
|
<HTML>
<TITLE>MAIN</TITLE>
<CENTER><A NAME="main"></A>
<HR><B><A HREF="../REFER.html">QUICK-REF</A></B> - <B><A HREF="../TITLE.html"><FONT SIZE=+1>C</FONT>soundManual</A></B>
- <A HREF="CSCORE.html">Top of this section</A> - <A HREF="./events.html">Previous</A>
- <A HREF="../CONTENTS.html">Contents</A> - <A HREF="../INDEX.html">Index</A>
- <A HREF="./advanced.html">Next</A>
<HR></CENTER>
<H2>
<U>Writing a Main program.</U></H2>
<P>The general format for a control program is:
<P> <TT>#include
"cscore.h"</TT>
<BR><TT> cscore()</TT>
<BR><TT> {</TT>
<BR><TT> /* VARIABLE DECLARATIONS
*/</TT><TT></TT>
<P><TT> /* PROGRAM BODY */</TT>
<BR><TT> }</TT>
<P>The include statement will define the event and list structures for
the program. The following <B>C</B> program will read from a<I> standard
numeric score,</I> up to (but not including) the first <B>s</B> or <B>e</B>
statement, then write that data (unaltered) as output.
<P> <TT>#include
"cscore.h"</TT>
<BR><TT> cscore()</TT>
<BR><TT> {</TT>
<BR><TT> EVLIST *a;
/* a is allowed to point to an event list */</TT>
<BR><TT> a = lget();
/* read events in, return the list pointer */</TT>
<BR><TT> lput(a);
/* write these events out (unchanged) */</TT>
<BR><TT> putstr("e");
/* write the string e to output */</TT>
<BR><TT> }</TT>
<PRE></PRE>
After execution of <B>lget()</B>, the variable a points to a list of event
addresses, each of which points to a stored event. We have used that
same pointer to enable another list function (<B>lput</B>) to access and
write out all of the events that were read. If we now define another
symbol <I>e</I> to be an event pointer, then the statement
<BR>
<PRE> e = a->e[4];</PRE>
<P>will set it to the contents of the 4th slot in the <B>evlist</B> structure.
The contents is a pointer to an event, which is itself comprised of an
<I>array </I>of parameter field values. Thus the term <I>e->p[5]</I>
will mean the value of parameter field 5 of the 4th event in the<B> evlist</B>
denoted by <I>a</I>. The program below will multiply the value of
that <I>pfield </I>by 2 before writing it out.
<P> <TT>#include
"cscore.h"</TT>
<BR><TT> cscore()</TT>
<BR><TT> {</TT>
<BR><TT> EVENT
*e; /* a pointer to an event
*/</TT>
<BR><TT> EVLIST *a;</TT><TT></TT>
<P><TT> a = lget();
/* read a score as a list of events */</TT>
<BR><TT> e = a->e[4];
/* point to event 4 in event list a */</TT>
<BR><TT> e->p[5]
*= 2; /* find pfield 5, multiply its value by 2 */</TT>
<BR><TT> lput(a);
/* write out the list of events */</TT>
<BR><TT> putstr("e");
/* add a "score end" statement */</TT>
<BR><TT> }</TT>
<P>Now consider the following score, in which <I>p[5]</I> contains frequency
in cps.
<BR>
<UL> <TT>f 1 0 257 10 1</TT>
<BR><TT> f 2 0 257 7 0 300 1 212 .8</TT>
<BR><TT> i 1 1 3 0 440 10000</TT>
<BR><TT> i 1 4 3 0 256 10000</TT>
<BR><TT> i 1 7 3 0 880 10000</TT>
<BR><TT> e</TT></UL>
<P>If this score were given to the preceding main program, the resulting
output would look like this:
<BR>
<UL><TT> f 1 0 257 10 1</TT>
<BR><TT> f 2 0 257 7 0 300 1 212 .8</TT>
<BR><TT> i 1 1 3 0 440 10000</TT>
<BR><TT> i 1 4 3 0 512 10000
; p[5] has become 512 instead of 256.</TT>
<BR><TT> i 1 7 3 0 880 10000</TT>
<BR><TT> e</TT></UL>
<P>Note that the 4th event is in fact the second note of the score.
So far we have not distinguished between notes and function table setup
in a numeric score. Both can be classed as events. Also note
that our 4th event has been stored in <I>e[4]</I> of the structure.
For compatibility with <B>Csound</B> <I>pfield</I> notation, we will ignore
<I>p[0]</I> and <I>e[0]</I> of the event and list structures, storing <I>p1</I>
in <I>p[1]</I>, event 1 in <I>e[1]</I>, etc. The<B> Cscore </B>functions
all adopt this convention.
<P>As an extension to the above, we could decide to use <I>a</I> and <I>e</I>
to examine each of the events in the list. Note that e has not preserved
the numeral 4, but the contents of that slot. To inspect <I>p5</I>
of the previous listed event we need only redefine e with the assignment
<BR>
<PRE> e = a->e[3];</PRE>
<P>More generally, if we declare a new variable <I>f </I>to be a pointer
to a pointer to an event, the statement
<BR>
<PRE> f = &a->e[4];</PRE>
<P>will set f to the address of the fourth event in the event list <I>a,</I>
and <I>*f</I> will signify the contents of the slot, namely the event pointer
itself. The expression
<BR>
<PRE> (*f)->p[5],</PRE>
<P>like <I>e->p[5]</I>, signifies the fifth pfield of the selected event.
However, we can advance to the next slot in the <B>evlist</B> by advancing
the pointer <I>f</I>. In <B>C</B> this is denoted by <I>f++</I>.
<P>In the following program we will use the same input score. This
time we will separate the <I>ftable</I> statements from the <I>note </I>statements.
We will next write the three note-events stored in the list<I> a,</I> then
create a second score section consisting of the original pitch set and
a transposed version of itself. This will bring about an octave doubling.
<P>By pointing the variable<I> f</I> to the first note-event and incrementing
f inside a while block which iterates<I> n </I>times (the number of events
in the list), one statement can be made to act upon the same <I>pfield</I>
of each successive event.
<BR>
<UL> <TT>#include "cscore.h"<BR>
cscore()<BR>
{</TT></UL>
<UL><TT> EVENT *e,**f;
/* declarations. see pp.8-9 in the */</TT>
<BR><TT> EVLIST *a,*b;
/* C language programming manual */</TT>
<BR><TT> int n;</TT><TT></TT>
<P><TT> a = lget();
/* read score into event list "a" */</TT>
<BR><TT> b = lsepf(a);
/* separate f statements */</TT>
<BR><TT> lput(b);
/* write f statements out to score */</TT>
<BR><TT> lrelev(b);
/* and release the spaces used */</TT>
<BR><TT> e = defev("t 0 120");
/* define event for tempo statement */</TT>
<BR><TT> putev(e);
/* write tempo statement to score */</TT>
<BR><TT> lput(a);
/* write the notes */</TT>
<BR><TT> putstr("s");
/* section end */</TT>
<BR><TT> putev(e);
/* write tempo statement again */</TT>
<BR><TT> b = lcopyev(a);
/* make a copy of the notes in "a" */</TT>
<BR><TT> n = b->nevents;
/* and get the number present */</TT>
<BR><TT> f = &a->e[1];</TT>
<BR><TT> while (n--)
/* iterate the following line n times: */</TT>
<BR><TT> (*f++)->p[5]
*= .5; /* transpose pitch down one octave */</TT>
<BR><TT> a = lcat(b,a);
/* now add these notes to original pitches */</TT>
<BR><TT> lput(a);</TT>
<BR><TT> putstr("e");</TT></UL>
<TT> }</TT>
<P>The output of this program is:
<BR>
<UL> <TT>f 1 0 257 10 1</TT>
<BR><TT> f 2 0 257 7 0 300 1 212 .8</TT>
<BR><TT> t 0 120</TT>
<BR><TT> i 1 1 3 0 440 10000</TT>
<BR><TT> i 1 4 3 0 256 10000</TT>
<BR><TT> i 1 7 3 0 880 10000</TT>
<BR><TT> s</TT>
<BR><TT> t 0 120</TT>
<BR><TT> i 1 1 3 0 440 10000</TT>
<BR><TT> i 1 4 3 0 256 10000</TT>
<BR><TT> i 1 7 3 0 880 10000</TT>
<BR><TT> i 1 1 3 0 220 10000</TT>
<BR><TT> i 1 4 3 0 128 10000</TT>
<BR><TT> i 1 7 3 0 440 10000</TT>
<BR><TT> e</TT></UL>
<P>Next we extend the above program by using the while statement to look
at <I>p[5]</I> and <I>p[6]</I>. In the original score <I>p[6]</I>
denotes amplitude. To create a diminuendo in the added lower octave,
which is independent from the original set of notes, a variable called
<I>dim</I> will be used.
<P> <TT>#include
"cscore.h"</TT>
<BR><TT> cscore()</TT>
<BR><TT> {</TT>
<UL><TT> EVENT *e,**f;</TT>
<BR><TT> EVLIST *a,*b;</TT>
<BR><TT> int n, dim;
/* declare two integer variables */</TT><TT></TT>
<P><TT> a = lget();</TT>
<BR><TT> b = lsepf(a);</TT>
<BR><TT> lput(b);</TT>
<BR><TT> lrelev(b);</TT>
<BR><TT> e = defev("t 0 120");</TT>
<BR><TT> putev(e);</TT>
<BR><TT> lput(a);</TT>
<BR><TT> putstr("s");</TT>
<BR><TT> putev(e);
/* write out another tempo statement */</TT>
<BR><TT> b = lcopyev(a);</TT>
<BR><TT> n = b->nevents;</TT>
<BR><TT> dim = 0;
/* initialize dim to 0 */</TT>
<BR><TT> f = &a->e[1];</TT>
<BR><TT> while (n--){</TT>
<BR><TT> (*f)->p[6]
-= dim; /* subtract current value of dim */</TT>
<BR><TT> (*f++)->p[5]
*= .5; /* transpose, move f to next event */</TT>
<BR><TT> dim
+= 2000; /* increase
dim for each note */</TT>
<BR><TT> }</TT>
<BR><TT> a = lcat(b,a);</TT>
<BR><TT> lput(a);</TT>
<BR><TT> putstr("e");</TT></UL>
<TT> }</TT>
<P>The increment of <I>f </I>in the above programs has depended on certain
precedence rules of <I>C</I>. Although this keeps the code tight,
the practice can be dangerous for beginners. Incrementing may alternately
be written as a separate statement to make it more clear.
<BR>
<UL> <TT>while (n--){</TT>
<BR><TT> (*f)->p[6] -= dim;</TT>
<BR><TT> (*f)->p[5] *= .5;</TT>
<BR><TT> dim += 2000;</TT>
<BR><TT> f++;</TT>
<BR><TT> }</TT></UL>
<P>Using the same input score again, the output from this program is:
<BR>
<UL> <TT>f 1 0 257 10 1</TT>
<BR><TT> f 2 0 257 7 0 300 1 212 .8</TT>
<BR><TT> t 0 120</TT>
<BR><TT> i 1 1 3 0 440 10000</TT>
<BR><TT> i 1 4 3 0 256 10000</TT>
<BR><TT> i 1 7 3 0 880 10000</TT>
<BR><TT> s</TT>
<BR><TT> t 0 120</TT>
<BR><TT> i 1 1 3 0 440 10000 ; Three original
notes at</TT>
<BR><TT> i 1 4 3 0 256 10000 ; beats 1,4 and
7 with no dim.</TT>
<BR><TT> i 1 7 3 0 880 10000</TT>
<BR><TT> i 1 1 3 0 220 10000 ; three notes
transposed down one octave</TT>
<BR><TT> i 1 4 3 0 128 8000 ; also at
beats 1,4 and 7 with dim.</TT>
<BR><TT> i 1 7 3 0 440 6000</TT>
<BR><TT> e</TT></UL>
<P>In the following program the same three-note sequence will be repeated
at various time intervals. The starting time of each group is determined
by the values of the <I>array</I> cue. This time the <I>dim</I> will
occur for each group of notes rather than each note. Note the position
of the statement which increments the variable <I>dim</I> outside the inner
while block.
<P> <TT>#include
"cscore.h"</TT>
<BR><TT> int cue[3]={0,10,17};
/* declare an array of 3 integers */</TT><TT></TT>
<P><TT> cscore()</TT>
<BR><TT> {<BR>
EVENT *e, **f;<BR>
EVLIST *a, *b;<BR>
int n, dim, cuecount,
holdn; /* declare new variables */</TT>
<UL><TT> a = lget();</TT>
<BR><TT> b = lsepf(a);</TT>
<BR><TT> lput(b);</TT>
<BR><TT> lrelev(b);</TT>
<BR><TT> e = defev("t 0 120");</TT>
<BR><TT> putev(e);</TT>
<BR><TT> n = a->nevents;</TT>
<BR><TT> holdn = n;
/* hold the value of "n" to reset below */</TT>
<BR><TT> cuecount = 0;
/* initilize cuecount to "0" */</TT>
<BR><TT> dim = 0;</TT>
<BR><TT> while (cuecount <= 2) {
/* count 3 iterations of inner "while" */</TT>
<BR><TT> f
= &a->e[1];
/* reset pointer to first event of list "a" */</TT>
<BR><TT> n
= holdn;
/* reset value of "n" to original note count */</TT>
<BR><TT> while
(n--) {</TT>
<BR><TT>
(*f)->p[6] -= dim;</TT>
<BR><TT>
(*f)->p[2] += cue[cuecount]; /* add values of cue */</TT>
<BR><TT>
f++;</TT>
<BR><TT> }</TT>
<BR><TT> printf(";
diagnostic: cue = %d\n", cue[cuecount]);</TT>
<BR><TT> cuecount++;</TT>
<BR><TT> dim
+= 2000;</TT>
<BR><TT> lput(a);</TT>
<BR><TT> }</TT>
<BR><TT> putstr("e");</TT>
<BR><TT> }</TT></UL>
<P>Here the inner while block looks at the events of list a (the notes)
and the outer while block looks at each repetition of the<I> events</I>
of list a (the pitch group repetitions). This program also demonstrates
a useful trouble-shooting device with the <B>printf</B> function. The <I>semi-colon</I>
is first in the character string to produce a comment statement in the
resulting score file. In this case the value of cue is being printed
in the output to insure that the program is taking the proper <I>array</I>
member at the proper time. When output data is wrong or error messages
are encountered, the <B>printf</B> function can help to pinpoint the problem.
<P>Using the identical input file, the <B>C</B> program above will generate:
<BR>
<UL> <TT>f 1 0 257 10 1</TT>
<BR><TT> f 2 0 257 7 0 300 1 212 .8</TT>
<BR><TT> t 0 120</TT><TT></TT>
<P><TT> ; diagnostic: cue = 0</TT>
<BR><TT> i 1 1 3 0 440 10000</TT>
<BR><TT> i 1 4 3 0 256 10000</TT>
<BR><TT> i 1 7 3 0 880 10000</TT><TT></TT>
<P><TT> ; diagnostic: cue = 10</TT>
<BR><TT> i 1 11 3 0 440 8000</TT>
<BR><TT> i 1 14 3 0 256 8000</TT>
<BR><TT> i 1 17 3 0 880 8000</TT><TT></TT>
<P><TT> ; diagnostic: cue = 17</TT>
<BR><TT> i 1 28 3 0 440 4000</TT>
<BR><TT> i 1 31 3 0 256 4000</TT>
<BR><TT> i 1 34 3 0 880 4000</TT>
<BR><TT> e;</TT></UL>
<CENTER><P>
<HR><B><A HREF="../REFER.html">QUICK-REF</A></B> - <B><A HREF="../TITLE.html"><FONT SIZE=+1>C</FONT>soundManual</A></B>
- <A HREF="CSCORE.html">Top of this section</A> - <A HREF="./events.html">Previous</A>
- <A HREF="../CONTENTS.html">Contents</A> - <A HREF="../INDEX.html">Index</A>
- <A HREF="./advanced.html">Next</A>
<HR></CENTER>
<P><CENTER>
<B><I><FONT COLOR="#006600">HTML Csound Manual - <FONT SIZE=-1>©
Jean Piché & Peter J. Nix, 1994-97</FONT></FONT></I></B>
</CENTER>
</HTML>
|