File: part15.html

package info (click to toggle)
nyquist 3.24%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 58,156 kB
  • sloc: ansic: 74,757; lisp: 18,169; java: 10,942; cpp: 6,688; sh: 175; xml: 58; makefile: 40; python: 15
file content (1698 lines) | stat: -rw-r--r-- 95,458 bytes parent folder | download
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
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
<!DOCTYPE html>
<html><head><title>Xmusic and Algorithmic Composition</title>
<link rel="stylesheet" type="text/css" href="nyquiststyle.css">
<link rel="icon" href="nyquist-icon.png" />
<link rel="shortcut icon" href="nyquist-icon.png" />
</head>
<body bgcolor="ffffff">
<a href = "part14.html">Previous Section</a> | <a href = "part16.html">Next Section</a> | <a href = "title.html#toc">Table of Contents</a> | <a href = "indx.html">Index</a> | <a href = "title.html">Title Page</a>
<hr>
<a name = "157"><h2>Xmusic and Algorithmic Composition</h2></a><a name="index1163"></a><a name="index1164"></a>
<p>Several Nyquist libraries offer support for algorithmic composition. Xmusic 
is a library for generating sequences and patterns of data. Included in Xmusic 
are:
<ul>
<li>
pattern objects, used to generate interesting sequences of parameter values,</li>
<li>random number generators, used to create random sequences from
different distributions (contained in the <code>distributions.lsp</code>
library) </li>
<li>a standard representation for "note lists" called <i>scores</i> and
functions to render them as sounds, </li>
<li>the <code>score-gen</code> macro which helps to generate scores from patterns, </li>
<li>score manipulation functions to select, transform, shift, and perform
other operations on scores. 
</li></ul></p>
<a name = "158"><h3>Xmusic Basics</h3></a>
<p>Xmusic is inspired by and based on Common Music by Rick Taube. 
Common Music supports MIDI and
various other synthesis languages and includes a graphical interface, some
visualization tools, and many other features. Common Music runs in Common
Lisp and Scheme, but not XLISP (the base language for Nyquist). </p>

<p>The Xmusic libraries in Nyquist offer an interesting subset of the
tools in Common Music. One important feature of Xmusic is that it is
integrated with all of the Nyquist synthesis functions, so you can use
Xmusic patterns and scores to control fine details of sound
synthesis. </p>
<a name = "159"><h3>Xmusic Patterns</h3></a><a name="index1165"></a>
<p>Xmusic patterns are objects that generate data streams. For example, 
the <code>cycle-class</code> of objects generate cyclical patterns such as 
"1 2 3 1 2 3 1 2 3 ...", or "1 2 3 4 3 2 1 2 3 4 ...". Patterns can
be used to  specify pitch sequences, rhythm, loudness, and other parameters.</p>

<p>Xmusic functions are automatically loaded when you start Nyquist.
To use a pattern object, you first create the pattern, e.g.
</p>
<pre>
set pitch-source = make-cycle(list(c4, d4, e4, f4))
</pre>

<p>
<a name="index1166"></a><a name="index1167"></a>
In this example, <code>pitch-source</code> is an object of class
<code>cycle-class</code> which inherits from <code>pattern-class</code>. </p>
<small>
Because SAL is not an object-oriented language, these classes and
their methods are not directly accessible from SAL.
Instead, Xmusic defines a functional interface, e.g. <code>make-cycle</code>
creates an instance of <code>cycle-class</code>, and the <code>next</code>
function, introduced below, retrieves the next value from any instance
of <code>pattern-class</code>. Using LISP syntax, you can have full access
to the methods of all objects (see the source code in <code>xm.lsp</code>,
but the functional interface described here should be sufficient and
it is recommended that you limit your access to this interface.
</small>

<p>After creating the pattern, you can access it repeatedly 
with <code>next</code><a name="index1168"></a> to generate data, e.g.
</p>
<pre>
play seqrep(i, 13, pluck(next(pitch-source), 0.2))
</pre>

<p>
This will create a sequence of notes with the following pitches: c, d, 
e, f, c, d, e, f, c, d, e, f, c. If you evaluate this again, the 
pitch sequence will continue, starting on "d".</p>

<p>It is very important not to confuse the creation of a sequence with 
its access. Consider this example:
</p>
<pre>
play seqrep(i, 13,
         pluck(next(make-cycle(list(c4, d4, e4, f4))), 0.2))
</pre>

<p>
This looks very much like the previous example, but it only repeats notes
on middle-C. The reason is that every time <code>pluck</code> is evaluated, 
<code>make-cycle</code> is called and creates a new pattern object. After the 
first item of the pattern is extracted with <code>next</code>, the cycle is not
used again, and no other items are generated.</p>

<p>To summarize this important point, there are two steps to using a pattern.
First, the pattern is created and stored in a
variable. Second, the pattern is accessed (multiple
times) using <code>next</code>.</p>
<dl>
<dt>
<code>next(<a name="index1169"></a><i>pattern-object</i> [, #t])</code> [SAL]<br>

<code>(next <i>pattern-object</i> [t])</code> [LISP]</dt>
<dd>Returns the next element from a pattern generator object. If the optional second argument is true (default value is false), then an entire period is returned as a list.
</dd></dl> <a name = "160"><h4>Nested Patterns</h4></a>
<p>Patterns can be nested, that is, you can write patterns of patterns. 
In general, the <code>next</code> function does not return patterns. Instead,
if the next item in a pattern is a (nested) pattern, <code>next</code> recursively
gets the next item of the nested pattern.</p>

<p>While you might expect that each call to <code>next</code> would advance the
top-level pattern to the next item, and descend recursively if necessary
to the inner-most nesting level, this is not how <code>next</code> works. Instead,
<code>next</code> remembers the last top-level item, and if it was a pattern, 
<code>next</code> continues to generate items from that same inner pattern
until the end of the inner pattern's <i>period</i> is reached. The next 
paragraph explains the concept of the <i>period</i>.</p>
<a name = "161"><h4>Periods</h4></a>
<p>The data returned by a pattern object is structured into logical groups
called <i>periods</i>. You can get an entire period (as a list) by calling
<code>next(<i>pattern</i>, t)</code><a name="index1170"></a>. For example:
</p>
<pre>
set pitch-source = make-cycle(list(c4, d4, e4, f4))
print next(pitch-source, t)
</pre>

<p>
This prints the list <code>(60 62 64 65)</code>, which is one period 
of the cycle.</p>

<p>You can also get explicit markers that 
delineate periods by calling <code>send(<i>pattern</i>, :next)</code>. In this 
case, the value returned is either the next item of the pattern, or the
symbol <code>+eop+</code> if the end of a period has been reached. What 
determines a period? This is up to the specific pattern class, so see the
documentation for specifics. You can override the &ldquo;natural&rdquo; period
using the keyword <code>for:</code>, e.g.
</p>
<pre>
set pitch-source = make-cycle(list(c4, d4, e4, f4), for: 3)
print next(pitch-source, t)
print next(pitch-source, t)
</pre>

<p>
This prints the lists <code>(60 62 64) (60 62 64)</code>. Notice that
the cycle starts from the beginning after only 3 items and the 
fourth is never reached in this case. The <code>for:</code> parameter
<i>could itself be a pattern</i>, in which case the a new cycle length would
be computed at the beginning of every cycle.</p>

<p>A variation on this restructures the stream of items 
into groups of 3:
</p>
<pre>
set pitch-source = make-length(make-cycle(list(c4, d4, e4 f4)), 3)
print next(pitch-source, t)
print next(pitch-source, t)
</pre>

<p>
This prints the lists <code>(60 62 64) (65 60 62)</code>. Note that in
this case the cycle pattern is producing default cycles of length 4
because there is no <code>for:</code> specification, and these are regrouped
by the length pattern.</p>

<p>Nested patterns are probably easier to understand by example than by
specification. Here is a simple nested pattern of cycles:
</p>
<pre>
set cycle-1 = make-cycle({a b c})
set cycle-2 = make-cycle({x y z})
set cycle-3 = make-cycle(list(cycle-1, cycle-2))
loop repeat 9 exec format(t, "~A ", next(cycle-3)) end
</pre>

<p>
This will print "A B C X Y Z A B C". Notice that the inner-most
cycles <code>cycle-1</code> and <code>cycle-2</code> generate a period of items
before the top-level <code>cycle-3</code> advances to the next pattern.</p>
<a name = "162"><h4>General Parameters for Creating Pattern objects</h4></a>
<p>Before describing specific pattern classes, there are several optional
parameters that apply in the creating of any pattern object. These are:
<dl>
<dt>
<code>for:</code></dt>
<dd>The length of a period. This overrides the default 
by providing a numerical length. The value of this optional 
parameter may be a pattern that generates a sequence of integers
that determine the length of each successive period. A period 
length may not be negative, but it may be zero.</p>
<dt><code>name:</code></dt>
<dd>A pattern object may be given a name. This is useful 
if the <code>trace:</code> option is used.<br><br>
<dt><code>trace:</code></dt>
<dd>If non-null, this optional parameter causes information
about the pattern to be printed each time an item is generated 
from the pattern.
</dd></dl>
The built-in pattern classes are described in the following section.<a name = "163"><h4>cycle</h4></a>
<p>The <code>cycle-class</code> iterates repeatedly through a list of items. 
For example, two periods of <code>make-cycle({a b c})</code> would be
<code>(A B C) (A B C)</code>. </p>
<dl>
<dt>
<code>make-cycle(<a name="index1171"></a><a name="index1172"></a><a name="index1173"></a><i>items</i>, for: <i>for</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-cycle <i>items</i> :for <i>for</i> :name <i>name</i>
 :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Make a cycle 
pattern that iterates over <i>items</i>. The default period length is the
length of <i>items</i>. (See above for a description of the 
optional parameters.)  The
list is replaced and restarted every period of the cycle, which 
defaults to the whole list, but may be specified by the <code>for:</code> keyword.
If <i>items</i> is a pattern, a new period of <i>items</i>
becomes the list from which items are generated for each cycle pattern. 
Note that the <i>items</i> list may be truncated by the use of <code>for:</code>.
Different groupings and repetitions can be obtained by nesting <code>make-cycle</code> 
within <code>make-length</code> and/or <code>make-copier</code> patterns. 
</dd></dl><a name = "164"><h4>line</h4></a>
<p>The <code>line-class</code> is similar to the cycle class, but when it reaches the 
end of the list of items, it simply repeats the last item in the list. 
For example, two periods of <code>make-line({a b c})</code> would be
<code>(A B C) (C C C)</code>. </p>
<dl>
<dt>
<code>make-line(<a name="index1174"></a><a name="index1175"></a><a name="index1176"></a><i>items</i>, for: <i>for</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-line <i>items</i> :for <i>for</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Make a line 
pattern that iterates over <i>items</i>. The default period length is the
length of <i>items</i>. As with <code>make-cycle</code>, <i>items</i> may be a 
pattern. (See above for a description of the optional parameters.)
</dd></dl><a name = "165"><h4>random</h4></a>
<p>The <code>random-class</code> generates items at random from a list. The default
selection is uniform random with replacement, but items may be further 
specified with a weight, a minimum repetition count, and a maximum 
repetition count. Weights give the relative probability of the selection
of the item (with a default weight of one). The minimum count specifies how
many times an item, once selected at random, will be repeated. The maximum
count specifies the maximum number of times an item can be selected in a row.
If an item has been generated <i>n</i> times in succession, and the maximum
is equal to <i>n</i>, then the item is disqualified in the next random selection.
Weights (but not currently minima and maxima) can be patterns. The patterns 
(thus the weights) are recomputed every period.  </p>
<dl>
<dt>
<code>make-random(<a name="index1177"></a><a name="index1178"></a><a name="index1179"></a><i>items</i>, for: <i>for</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-random <i>items</i> :for <i>for</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Make a random 
pattern that selects from <i>items</i>. Any (or all) element(s) of <i>items</i>
may be lists of the following form: <code>(<i>value</i> :weight <i>weight</i>
:min <i>mincount</i> :max <i>maxcount</i>)</code>, where <i>value</i> is the item 
(or pattern) to be generated, <i>weight</i> is the (optional) 
relative probability of 
selecting this item, <i>mincount</i> is the (optional) minimum number of repetitions
when this item is selected, and <i>maxcount</i> is the (optional) maximum number of 
repetitions allowed before selecting some other item. The default period
length is the length of <i>items</i>. If <i>items</i> is a pattern, a period
from that pattern becomes the list from which random selections are
made, and a new list is generated every period.
</dd></dl><a name = "166"><h4>palindrome</h4></a>
<p>The <code>palindrome-class</code> repeatedly traverses a list forwards and then 
backwards. For example, two periods of <code>make-palindrome({a b c})</code> 
would be <code>(A B C C B A) (A B C C B A)</code>. The <code>elide:</code>
keyword parameter controls whether the first and/or last elements are
repeated:
</p>
<pre>
make-palindrome({a b c}, elide: nil)
     ;; generates A B C C B A A B C C B A ...

make-palindrome({a b c}, elide: t)
     ;; generates A B C B A B C B ...

make-palindrome({a b c}, elide: :first)
     ;; generates A B C C B A B C C B ...

make-palindrome({a b c}, elide: :last)
     ;; generates A B C B A A B C B A ...
</pre>

<p></p>
<dl>
<dt>
<code>make-palindrome(<a name="index1180"></a><a name="index1181"></a><a name="index1182"></a><i>items</i>, elide: <i>elide</i>, for: <i>for</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-palindrome <i>items</i> :elide <i>elide</i> :for <i>for</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Generate items
from list alternating in-order and reverse-order sequencing. The keyword 
parameter <i>elide</i> can have the values <code>:first</code>, <code>:last</code>, 
<code>t</code>, or <code>nil</code> to control repetition of the first and last elements.
The <i>elide</i> parameter can also be a pattern, in which case it is evaluated
every period. One period is one complete forward and backward traversal
of the list. If <i>items</i> is a pattern, a period
from that pattern becomes the list from which random selections are
made, and a new list is generated every period.
</dd></dl><a name = "167"><h4>heap</h4></a>
<p>The <code>heap-class</code> selects items in random order from a list
 without replacement, which means that all items are generated once before
any item is repeated. For example, two periods of <code>make-heap({a b c})</code>
 might be <code>(C A B) (B A C)</code>. Normally, repetitions can occur 
even if all list elements are distinct. This happens when the last element
of a period is chosen first in the next period. To avoid repetitions, the
<code>max:</code> keyword argument can be set to 1. The <code>max:</code> keyword only
controls repetitions from the end of one period to the beginning of the next.
If the list contains more than one copy of the same value, it may be repeated
within a period regardless of the value of <code>max:</code>.</p>
<dl>
<dt>
<code>make-heap(<a name="index1183"></a><a name="index1184"></a><a name="index1185"></a><i>items</i>, for: <i>for</i>, max: <i>max</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-heap <i>items</i> :for <i>for</i> :max <i>max</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Generate items
randomly from list without replacement. If <i>max</i> is 1, the first element of 
a new period will not be the same as the last element of the previous period,
avoiding repetition. The default value of <i>max</i> is 2, meaning repetition is
allowed. The period length is the length
of <i>items</i>. If <i>items</i> is a pattern, a period
from that pattern becomes the list from which random selections are
made, and a new list is generated every period.
</dd></dl><a name = "168"><h4>accumulation</h4></a>
<p>The <code>accumulation-class</code> takes a list of values and returns
the first, followed by the first two, followed by the first three, 
etc. In other words, for each list item, return all items from the
first through the item. For example, if the list is (A B C), each
generated period is (A A B A B C).</p>
<dl>
<dt>
<code>make-accumulation(<a name="index1186"></a><a name="index1187"></a><a name="index1188"></a><i>items</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-accumulation <i>items</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Return 
the prefixes of items, e.g. the first element followed by the
first and second elements, then the first three, until the 
entire list is returned. The period length is (<i>n</i><sup T>2</sup> + <i>n</i>) / 2
where <i>n</i> is the length of <i>items</i>.  If <i>items</i> is a pattern, a period
from that pattern becomes the list from which items are generated,
and a new list is generated every period. Note that this is similar in 
name but different from <code>make-accumulate</code>.
</dd></dl><a name = "169"><h4>copier</h4></a>
<p>The <code>copier-class</code> makes copies of periods from a sub-pattern.
For example, three periods 
of <code>make-copier(make-length(make-cycle({a b c}), 1), repeat: 2, merge: t)</code>
would be <code>(A A) (B B) (C C)</code>. Note that entire periods (not
individual items) are repeated, so in this example, <code>make-length</code> 
is used to re-group the cycle into periods of length one so that 
each item is repeated by the <code>repeat:</code> count.</p>
<dl>
<dt>
<code>make-copier(<a name="index1189"></a><a name="index1190"></a><a name="index1191"></a><i>sub-pattern</i>, repeat: <i>repeat</i>, merge: <i>merge</i>, for: <i>for</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-copier <i>sub-pattern</i> :repeat <i>repeat</i> :merge <i>merge</i> :for <i>for</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Generate a period
from <i>sub-pattern</i> and repeat it <i>repeat</i> times. If <i>merge</i> is false
(the default), each repetition of a period from <i>sub-pattern</i> results
in a period by default. If <i>merge</i> is true (non-null), then all
<i>repeat</i> repetitions of the period are merged into one result
period by default. If the <code>for:</code> keyword is used, the same items
are generated, but the items are grouped into periods determined by
the <code>for:</code> parameter. If the <code>for:</code> parameter is a pattern,
it is evaluated every result period. The <i>repeat</i> and <i>merge</i> values 
may be patterns that return a repeat count and a boolean value, respectively. 
If so, these patterns are evaluated initially and after each <i>repeat</i>
 copies are made (independent of the <code>for:</code> keyword parameter, if any).
The <i>repeat</i> value returned by a pattern can also be negative. A negative
number indicates how many periods of <i>sub-pattern</i> to skip. After skipping
these patterns, new <i>repeat</i> and <i>merge</i> values are generated.
</dd></dl><a name = "170"><h4>accumulate</h4></a>
<p>The <code>accumulate-class</code> forms the sum of numbers returned by another
pattern.  For example, each period
of <code>make-accumulate(make-cycle({1 2 -3}))</code> is <code>(1 3 0)</code>.
The default output period length is the length of the input period.</p>
<dl>
<dt>
<code>make-accumulate(<a name="index1192"></a><a name="index1193"></a><a name="index1194"></a><i>sub-pattern</i>, for: <i>for</i>, max: <i>maximum</i>, min: <i>minimum</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-accumulate <i>sub-pattern</i> :for <i>for</i> :max <i>maximum</i> :min <i>minimum</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Keep
a running sum of numbers generated by <i>sub-pattern</i>. The default
period lengths match the period lengths from <i>sub-pattern</i>. 
If <i>maximum</i> (a pattern or a number) is specified, and the 
running sum exceeds <i>maximum</i>, the running sum is reset 
to <i>maximum</i>. If <i>minimum</i> (a pattern or a number) is 
specified, and the running sum falls below <i>minimum</i>, the 
running sum is reset to <i>minimum</i>. If <i>minimum</i> is greater 
than <i>maximum</i>, the running sum will be set to one of the two 
values. Minimum and maximum patterns are reevaluated every cycle. 
Note that this is similar in name but not in function to <code>make-accumulation</code>.
</dd></dl><a name = "171"><h4>sum</h4></a>
<p>The <code>sum-class</code> forms the sum of numbers, one from each of two other
patterns.  For example, each period
of <code>make-sum(make-cycle({1 2 3}), make-cycle({4 5 6}))</code> 
is <code>(5 7 9)</code>.
The default output period length is the length of the input period of the 
first argument. Therefore, the first argument must be a pattern, but the
second argument can be a pattern or a number.</p>
<dl>
<dt>
<code>make-sum(<a name="index1195"></a><a name="index1196"></a><a name="index1197"></a><i>x</i>, <i>y</i>, for: <i>for</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-sum <i>x</i> <i>y</i> :for <i>for</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Form
sums of items (which must be numbers) from pattern
<i>x</i> and pattern or number <i>y</i>.  The default
period lengths match the period lengths from <i>x</i>.
</dd></dl><a name = "172"><h4>product</h4></a>
<p>The <code>product-class</code> forms the product of numbers, one
from each of two other
patterns.  For example, each period
of <code>make-product(make-cycle({1 2 3}), make-cycle({4 5 6}))</code> 
is <code>(4 10 18)</code>.
The default output period length is the length of the input period of the 
first argument. Therefore, the first argument must be a pattern, but the
second argument can be a pattern or a number.</p>
<dl>
<dt>
<code>make-product(<a name="index1198"></a><a name="index1199"></a><a name="index1200"></a><i>x</i>, <i>y</i>, for: <i>for</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-product <i>x</i> <i>y</i> :for <i>for</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Form
products of items (which must be numbers) from pattern
<i>x</i> and pattern or number <i>y</i>.  The default
period lengths match the period lengths from <i>x</i>.
</dd></dl><a name = "173"><h4>eval</h4></a>
<p>The <code>eval-class</code> evaluates an expression to produce each output item.
The default output period length is 1 if the expression is an expression;
otherwise, the expression must be a pattern that returns expressions to
be evaluated, and the output periods match the periods of the expression pattern.</p>
<dl>
<dt>
<code>make-eval(<a name="index1201"></a><a name="index1202"></a><a name="index1203"></a><a name="index1204"></a><a name="index1205"></a><i>expr</i>, for: <i>for</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-eval <i>expr</i> :for <i>for</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Evaluate
 <i>expr</i> to generate each item. If <i>expr</i> is a pattern, each item is generated 
by getting the next item from <i>expr</i> and evaluating it. Note that <i>expr</i> is 
evaluated as a Lisp expression, which is a list consisting of the function name followed
by parameter expressions (which may also be lists). In the simplest case (recommended),
create a SAL function with no parameters that performs the computation. For example, to
create a pattern in SAL that calls the parameterless function <code>rrandom</code>, write
 <code>make-eval({rrandom})</code>. In SAL, <code>{rrandom}</code> creates a list with the 
(unevaluated) symbol <code>rrandom</code>, equivalent to <code>list(quote(rrandom))</code>.
</dd></dl><a name = "174"><h4>length</h4></a>
<p>The <code>length-class</code> generates periods of a specified length from 
another pattern. This is similar to using the <code>for:</code> keyword, but
for many patterns, the <code>for:</code> parameter alters the points at which
other patterns are generated. For example, if the palindrome pattern
has an <code>elide:</code> pattern parameter, the value will be computed every
period. If there is also a <code>for:</code> parameter with a value of 2, then
<code>elide:</code> will be recomputed every 2 items. In contrast, if the 
palindrome (without a <code>for:</code> parameter) is embedded in a <i>length</i>
pattern with a lenght of 2, then the periods will all be of length 2, but
the items will come from default periods of the palindrome, and therefore
the <code>elide:</code> values will be recomputed at the beginnings of 
default palindrome periods.</p>
<dl>
<dt>
<code>make-length(<a name="index1206"></a><a name="index1207"></a><a name="index1208"></a><i>pattern</i>, <i>length-pattern</i>, 
name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-length <i>pattern</i> <i>length-pattern</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Make a pattern of class
<code>length-class</code> that regroups items generated by a
<i>pattern</i> according to pattern lengths given by <i>length-pattern</i>.
Note that <i>length-pattern</i> is not optional: There is no default
pattern length and no <code>for:</code> keyword.
</dd></dl><a name = "175"><h4>window</h4></a>
<p>The <code>window-class</code> groups items from another pattern by using a sliding
window. If the <i>skip</i> value is 1, each output period is formed
by dropping the first item of the previous perioda and appending the next item
from the pattern. The <i>skip</i> value and the output period length can change
every period. For a simple example, if the period length is 3 and the 
skip value is 1, and the input pattern generates the sequence A, B, C, ...,
then the output periods will be (A B C), (B C D), (C D E), (D E F), ....</p>
<dl>
<dt>
<code>make-window(<a name="index1209"></a><a name="index1210"></a><a name="index1211"></a><i>pattern</i>, <i>length-pattern</i>, 
<i>skip-pattern</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-window <i>pattern</i> <i>length-pattern</i> <i>skip-pattern</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Make
 a pattern of class
<code>window-class</code> that regroups items generated by a
<i>pattern</i> according to pattern lengths given by <i>length-pattern</i> 
and where the period advances by the number of items given by
<i>skip-pattern</i>.
Note that <i>length-pattern</i> is not optional: There is no default
pattern length and no <code>for:</code> keyword.
</dd></dl><a name = "176"><h4>markov</h4></a>
<p>The <code>markov-class</code> generates items from a Markov model. A Markov model
generates a sequence of <i>states</i> according to rules which specify possible
future states
given the most recent states in the past. For example, states might be 
pitches, and each pitch might lead to a choice of pitches for the next state.
In the <code>markov-class</code>, states can be either symbols or numbers, but
not arbitrary values or patterns. This makes it easier to specify rules.
However, symbols can be mapped to arbitrary values including pattern 
objects, and these become the actual generated items.
By default, all future states are weighted equally, but weights
may be associated with future states. A Markov model must be
initialized with
a sequence of past states using the <code>past:</code> keyword. 
The most common form of Markov model is a "first
order Markov model" in which the future item depends only upon one
past item. However, higher order models where the future items depend on
two or more past items are possible. A "zero-order" Markov model, which
depends on no past states, is essentially equivalent to the random pattern.
As an example of a first-order Markov pattern,
two periods of <code>make-markov({{a -&gt; b c} {b -&gt; c} {c -&gt; a}}, past: {a})</code>
might be <code>(C A C) (A B C)</code>.</p>
<dl>
<dt>
<code>make-markov(<a name="index1212"></a><a name="index1213"></a><a name="index1214"></a><i>rules</i>, past: <i>past</i>, produces: <i>produces</i>, for: <i>for</i>, name: <i>name</i>, trace: <i>trace</i>)</code> [SAL]<br>

<code>(make-markov <i>rules</i> <i>past</i> :produces <i>produces</i> :for <i>for</i> :name <i>name</i> :trace <i>trace</i>)</code> [LISP]</dt>
<dd>Generate a sequence
of items from a Markov process. The <i>rules</i> parameter is a list of rules where each rule has the form: 
<code>(<i>prev1</i> <i>prev2</i> ... <i>prevn</i> -&gt; <i>next1</i> <i>next2</i> ... <i>nextn</i>)</code>
where <i>prev1</i> through <i>prevn</i> represent a sequence of most recent
(past) states. The symbol <code>*</code> is treated specially: it matches any
previous state. If <i>prev1</i> through <i>prevn</i> (which may be just one state
as in the example above) match the previously generated states, this
rule applies. Note that every rule must specify the same number of previous
states; this number is known as the order of the Markov model.
The first rule in <i>rules</i> that applies is used to select the
next state. If no rule applies, the next state is <code>NIL</code> (which is 
a valid state that can be used in rules).
Assuming a rule applies, the list of possible next
states is specified by <i>next1</i> 
through <i>nextn</i>. Notice that these are alternative choices for the
next state, not a sequence of future states, and each rule can have
any number of choices. Each choice may be the state
itself (a symbol or a number), or the choice may be a list consisting of
the state and a weight. The weight may be given by a pattern, in which
case the next item of the pattern is obtained every time the rule is 
applied. For example, this rules says that if the previous states were
A and B, the next state can be A with a weight of 0.5 or C with an 
implied weight of 1: <code>(A B -&gt; (A 0.5) C)</code>. The
default length of the period is the length of <i>rules</i>. The 
<i>past</i> parameter must be provided. It is a list of states whose length
matches the order of the Markov model. The keyword parameter <i>produces</i>
may be used to map from state symbols or numbers to other values or 
patterns. The parameter is a list of alternating symbols and values. For
example, to map A to 69 and B to 71, use <code>list(quote(a), 69, quote(b), 71)</code>.
  You can
also map symbols to patterns, for example
<code>list(quote(a), make-cycle({57 69}), quote(b), make-random({59 71}))</code>. The
next item of the pattern is is generated each time the Markov model generates
the corresponding state.  Finally, the <i>produces</i> keyword can be 
<code>:eval</code>, which means to evaluate the Markov model state. This could 
be useful if states are Nyquist global variables such as 
<code>C4, CS4, D4, ]..., which evaluate to numerical 
values (60, 61, 62, ...</code>.<br><br>
<dt><code>markov-create-rules(<a name="index1215"></a><a name="index1216"></a><i>sequence</i>, <i>order</i> [, <i>generalize</i>])</code> [SAL]<br>

<code>(markov-create-rules <i>sequence</i> <i>order</i> [<i>generalize</i>])</code> [LISP]</dt>
<dd>Generate a set of rules suitable for the 
<code>make-markov</code> function. The <i>sequence</i> is a &ldquo;typical&rdquo; sequence
of states, and <i>order</i> is the order of the Markov model. It is often the
case that a sample sequence will not have a transition from the last state 
to any other state, so the generated Markov model can reach a &ldquo;dead end&rdquo; 
where no rule applies. This might lead to an infinite stream of NIL's. To
avoid this, the optional parameter <i>generalize</i> can be set to <code>t</code> 
(true), indicating that there should be a fallback rule that matches any
previous states and whose future states are weighted according to their
frequency in <i>sequence</i>. For example, if sequence contains 5 A's, 5 B's and
10 G's, the default rule will be <code>(* -&gt; (A 5) (B 5) (G 10))</code>. This
rule will be appended to the end so it will only apply if no other rule does.
</dd></dl><a name = "177"><h3>Random Number Generators</h3></a><a name="index1217"></a><a name="index1218"></a><a name="index1219"></a><a name="index1220"></a>
<p>The <code>distributions.lsp</code> library implements random number generators that return random values with various probability distributions. Without this library, you can generate random numbers with <i>uniform</i> distributions. In a uniform distribution, all values are equally likely. To generate a random integer in some range, use <code>random</code>. To generate a real number (FLONUM) in some range, use <code>real-random</code> (or <code>rrandom</code> if the range is 0-1). But there are other interesting distributions. For example, the Gaussian distribution is often used to model 
real-world errors and fluctuations where values are clustered around some central value and large deviations are more unlikely than small ones. See Dennis Lorrain, "A Panoply of Stochastic 'Canons'," <i>Computer Music Journal</i> vol. 4, no. 1, 1980, pp. 53-81.
Further discussion and examples can be found in 
<code>nyquist/demos/probability_distributions.htm</code><a name="index1221"></a>. </p>

<p>In most of the random number generators described below, there are optional parameters to indicate a maximum and/or minimum value. These can be used to truncate the distribution. For example, if you basically want a Gaussian distribution, but you never want a value greater than 5, you can specify 5 as the maximum value. 
The upper and lower bounds are implemented simply by drawing a random number from the full distribution repeatedly until a number falling into the desired range is obtained. Therefore, if you select an acceptable range that is unlikely, it may take Nyquist a long time to find each acceptable random number. The intended use of the upper and lower bounds is to weed out values that are already fairly unlikely.</p>
<dl>
<dt>
<code>linear-dist(<a name="index1222"></a><a name="index1223"></a><i>g</i>)</code> [SAL]<br>

<code>(linear-dist <i>g</i>)</code> [LISP]</dt>
<dd>Return a <code>FLONUM</code> value from a linear distribution, where the probability of a value decreases linearly from zero to <i>g</i> which must be greater than zero. (See Figure <a href = "#177">7</a>.) The linear distribution is useful for generating for generating time and pitch intervals.
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="linear-fig.gif"><br><br>

<p><b>Figure 7: </b>The Linear Distribution, <i>g</i> = 1.

</p>
<hr><dl>
<dt>
<code>exponential-dist(<a name="index1224"></a><a name="index1225"></a><i>delta</i> [, <i>high</i>])</code> [SAL]<br>

<code>(exponential-dist <i>delta</i> [<i>high</i>])</code> [LISP]</dt>
<dd>Return a <code>FLONUM</code> value from an exponential distribution. The initial downward slope is steeper with larger values of <i>delta</i>, which must be greater than zero. (See Figure <a href = "#177">8</a>. The optional <i>high</i> parameter puts an artificial upper bound on the return value.
The exponential distribution generates values greater
than 0, and can be used to generate time intervals. Natural random intervals such as the time intervals between the release of atomic particles or the passing of yellow volkswagons in traffic have exponential distributions. The
exponential distribution is memory-less: knowing that a random number from this distribution is greater than some value (e.g. a note duration is at least 1 second) tells you nothing new about how soon the note will end. This
is a continuous distribution, but <code>geometric-dist</code> (described below) implements the discrete form.
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="exponential-fig.gif"><br><br>

<p><b>Figure 8: </b>The Exponential Distribution, <i>delta</i> = 1.

</p>
<hr><dl>
<dt>
<code>gamma-dist(<a name="index1226"></a><i>nu</i> [, <i>high</i>])</code> [SAL]<br>

<code>(gamma-dist <i>nu</i> [<i>high</i>])</code> [LISP]</dt>
<dd>Return a <code>FLONUM</code> value from a Gamma distribution. The value is greater than zero, has a mean of <i>nu</i> (a <code>FIXNUM</code> greater than zero), and a mode (peak) of around <i>nu</i> - 1. 
 The optional <i>high</i> parameter puts an artificial upper bound on the return value.
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="gamma-fig.gif"><br><br>

<p><b>Figure 9: </b>The Gamma Distribution, <i>nu</i> = 4.

</p>
<hr><dl>
<dt>
<code>bilateral-exponential-dist(<a name="index1227"></a><a name="index1228"></a><i>xmu</i>,
<i>tau</i> [, <i>low</i>, <i>high</i>])</code> [SAL]<br>

<code>(bilateral-exponential-dist <i>xmu</i> <i>tau</i> [<i>low</i> <i>high</i>])</code> [LISP]</dt>
<dd>Returns a <code>FLONUM</code> value from a bilateral exponential distribution, where <i>xmu</i> is the center of the double exponential and <i>tau</i> controls the spread of the distribution. A larger <i>tau</i> gives a wider distribution (greater variance), and <i>tau</i> must be greater than zero. The <i>low</i> and <i>high</i> parameters give optional artificial bounds on the minimum and maximum output values, respectively.
This distribution is similar to the exponential, except
it is centered at 0 and can output negative values as well. Like
the exponential, it can be used to generate time intervals; however, it might be necessary to add a lower bound so as not to compute a negative time interval.
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="bilateral-fig.gif"><br><br>

<p><b>Figure 10: </b>The Bilateral Exponential Distribution.

</p>
<hr><dl>
<dt>
<code>cauchy-dist(<a name="index1229"></a><a name="index1230"></a><i>tau</i> [, <i>low</i>, <i>high</i>])</code> [SAL]<br>

<code>(cauchy-dist <i>tau</i> [<i>low</i> <i>high</i>])</code> [LISP]</dt>
<dd>Returns a <code>FLONUM</code> from the Cauchy distribution, a symmetric distribution with a high peak at zero and a width (variance) that increases with parameter <i>tau</i>, which must be greater than zero. The <i>low</i> and <i>high</i> parameters give optional artificial bounds on the minimum and maximum output values, respectively.
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="cauchy-fig.gif"><br><br>

<p><b>Figure 11: </b>The Cauchy Distribution, <i>tau</i> = 1.

</p>
<hr><dl>
<dt>
<code>hyperbolic-cosine-dist(<a name="index1231"></a>[<i>low</i>, <i>high</i>])</code> [SAL]<br>

<code>(hyperbolic-cosine-dist [<i>low</i> <i>high</i>])</code> [LISP]</dt>
<dd>Returns a <code>FLONUM</code> value from the hyperbolic cosine distribution, a symmetric distribution with its peak at zero. The <i>low</i> and <i>high</i> parameters give optional artificial bounds on the minimum and maximum output values, respectively.
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="hyperbolic-fig.gif"><br><br>

<p><b>Figure 12: </b>The Hyperbolic Cosine Distribution.

</p>
<hr><dl>
<dt>
<code>logistic-dist(<a name="index1232"></a><a name="index1233"></a><i>alpha</i>, <i>beta</i> [, <i>low</i>, <i>high</i>])</code> [SAL]<br>

<code>(logistic-dist <i>alpha</i> <i>beta</i> [<i>low</i> <i>high</i>])</code> [LISP]</dt>
<dd>Returns a <code>FLONUM</code> value from the logistic distribution, which is symmetric about the mean. The <i>alpha</i> parameter primarily affects dispersion (variance), with larger values resulting in values closer to the mean (less variance), and the <i>beta</i> parameter primarily influences the mean. The <i>low</i> and <i>high</i> parameters give optional artificial bounds on the minimum and maximum output values, respectively.
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="logistic-fig.gif"><br><br>

<p><b>Figure 13: </b>The Logistic Distribution, alpha = 1, beta = 2.

</p>
<hr><dl>
<dt>
<code>arc-sine-dist(<a name="index1234"></a><a name="index1235"></a>)</code> [SAL]<br>

<code>(arc-sine-dist)</code> [LISP]</dt>
<dd>Returns a <code>FLONUM</code> value from the arc sine distribution, which outputs values between 0 and 1. It is symmetric about the mean of 1/2, but is more likely to generate values closer to 0 and 1. 
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="arcsine-fig.gif"><br><br>

<p><b>Figure 14: </b>The Arc Sine Distribution.

</p>
<hr><dl>
<dt>
<code>gaussian-dist(<a name="index1236"></a><a name="index1237"></a><i>xmu</i>, <i>sigma</i> [, <i>low</i>, <i>high</i>])</code> [SAL]<br>

<code>(gaussian-dist <i>xmu</i> <i>sigma</i> [<i>low</i> <i>high</i>])</code> [LISP]</dt>
<dd>Returns a <code>FLONUM</code> value from the Gaussian or Gauss-Laplace distribution, a linear function of the normal distribution. It is symmetric about the mean of <i>xmu</i>, with a standard deviation of <i>sigma</i>, which must be greater than zero. The <i>low</i> and <i>high</i> parameters give optional artificial bounds on the minimum and maximum output values, respectively.
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="gaussian-fig.gif"><br><br>

<p><b>Figure 15: </b>The Gauss-Laplace (Gaussian) Distribution, <i>xmu</i> = 0, <i>sigma</i> = 1.

</p>
<hr><dl>
<dt>
<code>beta-dist(<a name="index1238"></a><a name="index1239"></a><i>a</i>, <i>b</i>)</code> [SAL]<br>

<code>(beta-dist <i>a</i> <i>b</i>)</code> [LISP]</dt>
<dd>Returns a <code>FLONUM</code> value from the Beta distribution. This distribution outputs values between 0 and 1, with outputs more likely to be close to 0 or 1. The parameter <i>a</i> controls the height (probability) of the right side of the distribution (at 1) and <i>b</i> controls the height of the left side (at 0). The distribution is symmetric about 1/2 when <i>a</i> = <i>b</i>.
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="beta-fig.gif"><br><br>

<p><b>Figure 16: </b>The Beta Distribution, <i>alpha</i> = .5, <i>beta</i> = .25.

</p>
<hr><dl>
<dt>
<code>bernoulli-dist(<a name="index1240"></a><a name="index1241"></a><i>px1</i> [, <i>x1</i>, <i>x2</i>])</code> [SAL]<br>

<code>(bernoulli-dist <i>px1</i> [<i>x1</i> <i>x2</i>])</code> [LISP]</dt>
<dd>Returns either <i>x1</i> (default value is 1) with probability <i>px1</i> or <i>x2</i> (default value is 0) with probability 1 - <i>px1</i>. The value of <i>px1</i> should be between 0 and 1. By
convention, a result of <i>x1</i> is viewed as a success while <i>x2</i> is viewed as
a failure.
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="bernoulli-fig.gif"><br><br>

<p><b>Figure 17: </b>The Bernoulli Distribution, <i>px1</i> = .75.

</p>
<hr><dl>
<dt>
<code>binomial-dist(<a name="index1242"></a><a name="index1243"></a><i>n</i>, <i>p</i>)</code> [SAL]<br>

<code>(binomial-dist <i>n</i> <i>p</i>)</code> [LISP]</dt>
<dd>Returns a <code>FIXNUM</code> value from the binomial distribution, where <i>n</i> is the number of Bernoulli trials run (a <code>FIXNUM</code>) and <i>p</i> is the probability of success in the Bernoulli trial (a <code>FLONUM</code> from 0 to 1). The mean is the product of <i>n</i> and <i>p</i>.
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="binomial-fig.gif"><br><br>

<p><b>Figure 18: </b>The Binomial Distribution, <i>n</i> = 5, <i>p</i> = .5.

</p>
<hr><dl>
<dt>
<code>geometric-dist(<a name="index1244"></a><a name="index1245"></a><i>p</i>)</code> [SAL]<br>

<code>(geometric-dist <i>p</i>)</code> [LISP]</dt>
<dd>Returns a <code>FIXNUM</code> value from the geometric distribution, which is defined as the number of failures before a success is achieved in a Bernoulli trial with probability of success <i>p</i> (a <code>FLONUM</code> from 0 to 1).
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="geometric-fig.gif"><br><br>

<p><b>Figure 19: </b>The Geometric Distribution, <i>p</i> = .4.

</p>
<hr><dl>
<dt>
<code>poisson-dist(<a name="index1246"></a><a name="index1247"></a><i>delta</i>)</code> [SAL]<br>

<code>(poisson-dist <i>delta</i>)</code> [LISP]</dt>
<dd>Returns a <code>FIXNUM</code> value from the Poisson distribution with a mean of <i>delta</i> (a <code>FIXNUM</code>). The Poisson distribution is often used to generate a sequence of time intervals, resulting in random but often pleasing rhythms.
</dd></dl><hr>
<blockquote>
</blockquote>
<img src="poisson-fig.gif"><br><br>

<p><b>Figure 20: </b>The Poisson Distribution, <i>delta</i> = 3.

</p>
<hr><a name = "178"><h3>Score Generation and Manipulation</h3></a>
<p>A common application of pattern generators is to specify parameters 
for notes. (It should be understood that &ldquo;notes&rdquo; in this context
means any Nyquist behavior, whether it represents a conventional note,
an abstract sound object, or even some micro-sound event that is just
a low-level component of a hierarchical sound organization. Similarly,
&ldquo;score&rdquo; should be taken to mean a specification for a 
sequence of these &ldquo;notes.&rdquo;) 
The <code>score-gen</code> macro (defined by 
loading <code>xm.lsp</code>) establishes a convention for representing 
scores and for generating them using patterns.</p>

<p>The <code>timed-seq</code> macro, described in Section <a href = "part8.html#99">Combination and Time Structure</a>, 
already provides a way to represent a &ldquo;score&rdquo; as a list of expressions.
The Xmusic representation goes a bit further by specifying that
<i>all notes are specified by an alternation of keywords and values, where
some keywords have specific meanings and interpretations.</i></p>

<p>The basic idea of <code>score-gen</code><a name="index1248"></a> is you provide a template for notes in 
a score as a set of keywords and values. For example,
</p>
<pre>
set pitch-pattern = make-cycle(list(c4, d4, e4, f4))
score-gen(dur: 0.4, name: quote(my-sound),
          pitch: next(pitch-pattern), score-len: 9)
</pre>

<p>
generates a score of 9 notes as follows:
</p>
<pre>
((0 0 (SCORE-BEGIN-END 0 3.6))
 (0 0.4 (MY-SOUND :PITCH 60))
 (0.4 0.4 (MY-SOUND :PITCH 62))
 (0.8 0.4 (MY-SOUND :PITCH 64))
 (1.2 0.4 (MY-SOUND :PITCH 65))
 (1.6 0.4 (MY-SOUND :PITCH 60))
 (2 0.4 (MY-SOUND :PITCH 62))
 (2.4 0.4 (MY-SOUND :PITCH 64))
 (2.8 0.4 (MY-SOUND :PITCH 65))
 (3.2 0.4 (MY-SOUND :PITCH 60)))
</pre>

<p>
The use of keywords like <code>:PITCH</code> helps to make scores
readable and easy to process without specific knowledge of 
about the functions called in the score. For example, one 
could write a transpose operation to transform all the 
<code>:pitch</code> parameters in a score without having to know 
that pitch is the first parameter of <code>pluck</code> and the
second parameter of <code>piano-note</code>. Keyword parameters are
also used to give flexibility to note specification with
<code>score-gen</code>. Since this approach requires the use of
keywords, the next section 
is a brief explanation of how to define functions that use
keyword parameters.</p>
<a name = "179"><h4>Keyword Parameters</h4></a><a name="index1249"></a><a name="index1250"></a>
<p>Keyword parameters are parameters whose presence is
indicated by a special symbol, called a keyword, followed
by the actual parameter. Keyword parameters in SAL have
default values that are used if no actual parameter is
provided by the caller of the function. (See Appendix
<a href = "part19.html#224">Appendix 3: XLISP: An Object-oriented Lisp</a> to learn about keywords in XLISP.)</p>

<p>To specify that a parameter is a keyword parameter, 
use a keyword symbol (one that ends in a colon) followed
by a default value.
  For example, here is a function that
accepts keyword parameters and invokes the <code>pluck</code> 
function:
</p>
<pre>
define function k-pluck(pitch: 60, dur: 1)
  return pluck(pitch, dur)
</pre>

<p>
Now, we can call k-pluck with keyword parameters. The 
keywords are simply the formal parameter names with
a prepended colon character (<code>:pitch</code> and <code>:dur</code>
in this example), so a function call would look like:
</p>
<pre>
k-pluck(pitch: c3, dur: 3)
</pre>

<p>
Usually, it is best to give keyword parameters useful
default values. That way, if a parameter such as <code>dur:</code>
is missing, a reasonable default value (1) can be used
automatically. 
It is never an error to omit a keyword parameter, but the
called function can check to see if a keyword parameter 
was supplied or not.
Because of default values, we can call 
<code>k-pluck(pitch: c3)</code> with no duration, 
<code>k-pluck(dur: 3)</code> with only a duration, 
or even <code>k-pluck()</code> with no parameters.</p>

<p>In XLISP, there is additional syntax to specify an alternate symbol
to be used as the keyword and to allow the called function
to determine whether or not a keyword parameter was 
supplied, but these features are little-used. See the XLISP
manual for details.</p>
<a name = "180"><h4>Using score-gen</h4></a><a name="index1251"></a>
<p>The <code>score-gen</code> macro computes a score based on keyword parameters.
Some keywords have a special meaning, while others are not interpreted
but merely placed in the score. The resulting score can be synthesized
using <code>timed-seq</code> (see Section <a href = "part8.html#99">Combination and Time Structure</a>).</p>

<p>The form of a call to <code>score-gen</code> is simply:
<dl>
<dt>
<code>score-gen(<a name="index1252"></a><i>k1:</i> <i>e1</i>, <i>k2:</i> <i>e2</i>, <span style="font-style:normal">...</span>)</code> [SAL]<br>

<code>(score-gen <i>:k1</i> <i>e1</i> <i>:k2</i> <i>e2</i> <span style="font-style:normal">...</span>)</code> [LISP]</dt>
<dd>where the <i>k</i>'s 
are keywords and the <i>e</i>'s are 
expressions. A score is generated by evaluating the expressions once for 
each note and constructing a list of keyword-value pairs. A number
of keywords have special interpretations. The rules for interpreting
these parameters will be explained through a set of
questions and answers below.
</dd></dl></p>

<p> <i>How many notes will be generated?</i> The keyword 
parameter <code>score-len:</code> specifies an upper bound on the number
of notes. (Note: in LISP syntax, keywords
are always <i>preceded</i> by colons, so you would write
<code>:score-len</code> instead.) The keyword <code>score-dur:</code> specifies an upper bound
on the starting time of the last note in the score. (To be more
precise, the <code>score-dur:</code> bound is reached when the 
default starting time of the next note is greater than or equal
to the <code>score-dur:</code> value. This definition is necessary because
note times are not strictly increasing.) When either bound
is reached, score generation ends. At least one of these two
parameters must be specified or an error is raised. These keyword
parameters are evaluated just once and are not copied into the
parameter lists of generated notes.</p>

<p> <i>What is the duration of generated notes?</i> The 
keyword <code>dur:</code> defaults to 1 and specifies the nominal duration
in seconds. Since the generated note list is compatible with 
<code>timed-seq</code>, the starting time and duration (to be precise, the
<i>stretch factor</i>) are not passed as parameters to the notes. Instead,
they control the Nyquist environment in which the note will be evaluated.</p>

<p> <i>What is the start time of a note?</i> The default start time of the
first note is zero. Given a note, the default start time of the next note is 
the start time plus the inter-onset time, which is given by the <code>ioi:</code>
parameter. If no <code>ioi:</code> parameter is specified, the inter-onset time
defaults to the duration, given by <code>dur:</code>. In all cases, the default
start time of a note can be overridden by the keyword parameter <code>time:</code>.</p>

<p> <i>When does the score begin and end?</i> The behavior <code>SCORE-BEGIN-END</code> 
contains the beginning and ending of the
score (these are used for score manipulations, e.g. when scores are merged,
their begin times can be aligned.) When <code>timed-seq</code> is used to 
synthesize a score, the <code>SCORE-BEGIN-END</code> marker is
not evaluated. The <code>score-gen</code> macro inserts a &ldquo;note&rdquo; of the form
<code>(0 0 (SCORE-BEGIN-END <i>begin-time</i> <i>end-time</i>))</code> 
at the time given by the <code>begin:</code> keyword, with <i>begin-time</i> and 
<i>end-time</i> determined by the <code>begin:</code> and <code>end:</code> 
keyword parameters, respectively. If the <i>begin:</i> keyword is not 
provided, the score begins at zero. If the <code>end:</code> keyword
is not provided, the score ends at the default start time
of what would be the next note after the last note in the score 
(as described in the previous paragraph). Note: if <code>time:</code> is used to 
compute note starting times, and these times are not increasing, it is
strongly advised to use <code>end:</code> to specify an end time for the score,
because the default end time may be anywhere in the middle of the 
generated sequence.</p>

<p> <i>What function is called to synthesize the note?</i> The <code>name:</code> 
parameter names the function. Like other parameters, the value can be any
expression, including something like <code>next(fn-name-pattern)</code>,
allowing function names to be recomputed for each note. The default value 
is <code>note</code>.</p>

<p> <i>Can I make parameters depend upon the starting time or the duration
of the note?</i> Parameter expressions can use the variable <code>sg:start</code> 
to access the start time of the note, <code>sg:ioi</code> to access the 
inter-onset time, and <code>sg:dur</code> to access the 
duration (stretch factor) of the note. Also, <code>sg:count</code> counts how 
many notes have been computed so far, starting at 0. The order of 
computation is: <code>sg:start</code> first, then <code>sg:ioi</code> and <code>sg:dur</code>,
so for example, an expression to compute <code>sg:dur</code> can 
depend on <code>sg:ioi</code>.</p>

<p> <i>Can parameters depend on each other?</i> The keyword <code>pre:</code> 
introduces an expression that is evaluated before each note, and 
<code>post:</code> provides an expression to be evaluated after each note. 
The <code>pre:</code> expression can assign one or more global variables 
which are then used in one or more expressions for parameters.</p>

<p> <i>How do I debug <code>score-gen</code> expressions?</i> You can set the 
<code>trace:</code> parameter to true (<code>t</code>) to enable a print statement
for each generated note.</p>

<p> <i>How can I save scores generated by <code>score-gen</code> that I like?</i> If the
keyword parameter <code>save:</code> is set to a symbol, the global variable
named by the symbol is set to the value of the generated sequence. Of 
course, the value returned by <code>score-gen</code> is just an ordinary list that
can be saved like any other value.</p>

<p>In summary, the following keywords have special interpretations 
in <code>score-gen</code>: 
<code>begin:</code>, <code>end:</code>, <code>time:</code>, <code>dur:</code>, <code>name:</code>, 
<code>ioi:</code>, <code>trace:</code>,
<code>save:</code>, <code>score-len:</code>, <code>score-dur:</code>, <code>pre:</code>, <code>post:</code>.
 All other keyword
parameters are expressions that are evaluated once for each note
and become the parameters of the notes.</p>
<a name = "181"><h4>Score Manipulation</h4></a><a name="index1253"></a><a name="index1254"></a>
<p>Nyquist encourages the representation of music as 
executable programs, or <i>behaviors</i>, and there are various
ways to modify behaviors, including time stretching, 
transposition, etc. An alternative to composing executable
programs is to manipulate scores as editable data. Each 
approach has its strengths and weaknesses. This section 
describes functions intended to manipulate Xmusic scores
as generated by, or at least in the form generated by, 
<code>score-gen</code>. Recall that this means scores are lists
of events (e.g. notes), where events are three-element lists of the form
(<i>time</i> <i>duration</i> <i>expression</i>, and where <i>expression</i>
is a standard lisp function call where all parameters are
keyword parameters. In addition, the first &ldquo;note&rdquo; may be
the special <code>SCORE-BEGIN-END</code> expression. If this is 
missing, the score begins at zero and ends at the end of the
last note.</p>

<p>For convenience, a set of functions is offered to access properties
of events (or notes) in scores. Although lisp functions such as 
<code>car</code>, <code>cadr</code>, and <code>caddr</code> can be used, code is more
readable when more mnemonic functions are used to access events.</p>
<dl>
<dt>
<code>event-time(<a name="index1255"></a><i>event</i>)</code> [SAL]<br>

<code>(event-time <i>event</i>)</code> [LISP]</dt>
<dd>Retrieve the time field from 
an event.<br><br>
<dt><code>event-set-time(<a name="index1256"></a><i>event</i>, <i>time</i>)</code> [SAL]<br>

<code>(event-set-time <i>event</i> <i>time</i>)</code> [LISP]</dt>
<dd>Construct
a new event where the time of <i>event</i> is replaced by <i>time</i>.<br><br>
<dt><code>event-dur(<a name="index1257"></a><i>event</i>)</code> [SAL]<br>

<code>(event-dur <i>event</i>)</code> [LISP]</dt>
<dd>Retrieve the duration 
(i.e. the stretch factor) field from an event.<br><br>
<dt><code>event-set-dur(<a name="index1258"></a><i>event</i>, <i>dur</i>)</code> [SAL]<br>

<code>(event-set-dur <i>event</i> <i>dur</i>)</code> [LISP]</dt>
<dd>Construct
a new event where the duration (or stretch factor) of <i>event</i> is
replaced by <i>dur</i>.<br><br>
<dt><code>event-expression(<a name="index1259"></a><i>event</i>)</code> [SAL]<br>

<code>(event-expression <i>event</i>)</code> [LISP]</dt>
<dd>Retrieve the expression 
field from an event.<br><br>
<dt><code>event-set-expression(<a name="index1260"></a><i>event</i>, 
<i>dur</i>)</code> [SAL]<br>

<code>(event-set-expression <i>event</i> <i>dur</i>)</code> [LISP]</dt>
<dd>Construct
a new event where the expression of <i>event</i> is replaced by <i>expression</i>.<br><br>
<dt><code>event-end(<a name="index1261"></a><i>event</i>)</code> [SAL]<br>

<code>(event-end <i>event</i>)</code> [LISP]</dt>
<dd>Retrieve the end time 
of <i>event</i>, its time plus its duration.<br><br>
<dt><code>expr-has-attr(<a name="index1262"></a><i>expression</i>, <i>attribute</i>)</code> [SAL]<br>

<code>(expr-has-attr <i>expression</i> <i>attribute</i>)</code> [LISP]</dt>
<dd>Test 
whether a score event <i>expression</i> has the given <i>attribute</i>.<br><br>
<dt><code>expr-get-attr(<a name="index1263"></a><i>expression</i>, <i>attribute</i> [, <i>default</i>])</code> [SAL]<br>

<code>(expr-get-attr <i>expression</i> <i>attribute</i> [<i>default</i>])</code> [LISP]</dt>
<dd>Get the value of the given <i>attribute</i> from a score event
<i>expression</i>. If <i>attribute</i> is not present, return <i>default</i> if
specified, and otherwise <code>nil</code>. (See the example 
after <code>score-apply</code> below for an example using <code>expr-get-attr</code>.)<br><br>
<dt><code>expr-set-attr(<a name="index1264"></a><i>expr</i>, <i>attribute</i>, <i>value</i>)</code> [SAL]<br>

<code>(expr-set-attr <i>expr</i> <i>attribute</i> <i>value</i>)</code> [LISP]</dt>
<dd>Construct a new expression identical to <i>expr</i> except that the <i>attribute</i> has <i>value</i>.  (See the example after <code>score-apply</code> below for an example
using <code>expr-set-attr</code>.)<br><br>
<dt><code>event-has-attr(<a name="index1265"></a><i>event</i>, <i>attribute</i>)</code> [SAL]<br>

<code>(event-has-attr <i>event</i> <i>attribute</i>)</code> [LISP]</dt>
<dd>Test 
whether a given score <i>event</i>'s expression has the given <i>attribute</i>.<br><br>
<dt><code>event-get-attr(<a name="index1266"></a><i>event</i>, <i>attribute</i>, 
[<i>default</i>])</code> [SAL]<br>

<code>(event-get-attr <i>event</i> <i>attribute</i> [<i>default</i>])</code> [LISP]</dt>
<dd>Get the value of the given <i>attribute</i> from a score 
<i>event</i>'s expression. If <i>attribute</i> is not present, return <i>default</i> if
specified, and otherwise <code>nil</code>.<br><br>
<dt><code>event-set-attr(<a name="index1267"></a><i>event</i>, <i>attribute</i>, <i>value</i>)</code> [SAL]<br>

<code>(event-set-attr <i>event</i> <i>attribute</i> <i>value</i>)</code> [LISP]</dt>
<dd>Construct a new event identical to <i>event</i> except that the <i>attribute</i> has <i>value</i>.
</dd></dl>
<p>Functions are provided to shift the starting times of notes,
stretch times and durations, stretch only durations,
add an offset to a keyword parameter, scale a keyword parameter, and
other manipulations. Functions are also provided to extract 
ranges of notes, notes that match criteria, and to combine scores.
Most of these functions (listed below in detail)
share a set of keyword parameters that optionally limit the range over which 
the transformation operates. The <code>from-index:</code> and <code>to-index:</code> 
parameters specify the index of the first note and the index of the
last note to be changed, where 1 (not zero) denotes the first note.
If indices are in range, the number of note selected is 
<code>to-index</code> <code>-</code> <code>from-index</code> <code>+</code> <code>1</code>). Out-of-range
indices are ignored. 
If these numbers are negative, they are offsets 
from the end of the score, e.g. -1 denotes the last note of the score. The
<code>from-time:</code> and <code>to-time:</code> indicate a range of starting times
of notes that will be affected by the manipulation. Only notes whose time
is greater than or equal to the <i>from-time</i> and <i>strictly less than</i>
 the <i>to-time</i> are modified. If both index and time ranges are specified,
only notes that satisfy <i>both</i> constraints are selected. (Note: in
LISP syntax, colons <i>precede</i> the keyword, so use
<code>:from-index</code>, <code>:to-index</code>, 
<code>:from-time</code>, and <code>:to-time</code>.)</p>
<dl>
<dt>
<code>score-sorted(<a name="index1268"></a><i>score</i>)</code> [SAL]<br>

<code>(score-sorted <i>score</i>)</code> [LISP]</dt>
<dd>Test if <i>score</i> is sorted.<br><br>
<dt><code>score-sort(<a name="index1269"></a><i>score</i> [, <i>copy-flag</i>])</code> [SAL]<br>

<code>(score-sort <i>score</i> [<i>copy-flag</i>])</code> [LISP]</dt>
<dd>Sort
 the notes in a 
score into start-time order. If copy-flag is nil, this is a destructive
operation which should only be performed if the top-level score list
is a fresh copy that is not shared by any other variables. (The 
<i>copy-flag</i> is intended for internal system use only.)
 For the following operations, it is assumed
that scores are sorted, and all operations return a sorted score.<br><br>
<dt><code>score-shift(<a name="index1270"></a><i>score</i>, <i>offset</i>, from-index: <i>i</i>, to-index: <i>j</i>, from-time: <i>x</i>,
 to-time: <i>y</i>)</code> [SAL]<br>

<code>(score-shift <i>score</i> <i>offset</i>
 :from-index <i>i</i> :to-index <i>j</i> :from-time <i>x</i>
 :to-time <i>y</i>)</code> [LISP]</dt>
<dd>Add a constant 
<i>offset</i> to the starting time of a set of notes in <i>score</i>. By default,
all notes are modified, but the range of notes can be limited with the
keyword parameters. The begin time of the score is decreased if necessary to 
the minimum time of any event that is moved to an earlier time (by a negative
<i>offset</i>), and the end time of the score is increased if necessary 
to the maximum end time of any event that is moved to a later time. If
 all shifted events remain within the score's begin-to-end range, the begin
and end times are not changed.
The original score is not modified, and a new score is returned.<br><br>
<dt><code>score-stretch(<a name="index1271"></a><i>score</i>, <i>factor</i>, dur: <i>dur-flag</i>, time: <i>time-flag</i>, from-index: <i>i</i>,
 to-index: <i>j</i>, from-time: <i>x</i>, to-time: <i>y</i>)</code> [SAL]<br>

<code>(score-stretch <i>score</i> <i>factor</i>
 :dur <i>dur-flag</i> :time <i>time-flag</i> :from-index <i>i</i>
 :to-index <i>j</i> :from-time <i>x</i> :to-time <i>y</i>)</code> [LISP]</dt>
<dd>Stretch  
note times and durations by <i>factor</i>. The default <i>dur-flag</i> is 
non-null, but if <i>dur-flag</i> is null, the original durations are retained
and only times are stretched. Similarly, the default <i>time-flag</i> is 
non-null, but if <i>time-flag</i> is null, the original times are retained
and only durations are stretched. If both <i>dur-flag</i> and <i>time-flag</i>
are null, the score is not changed. If a range
of notes is specified, times are scaled within that range, and 
notes after the range are shifted so that the stretched region does not
create a "hole" or overlap with notes that follow. If the range begins
or ends with a time (via <code>from-time:</code> and <code>to-time:</code>), time
stretching
takes place over the indicated time interval independent of whether 
any notes are present or where they start. In other words, the 
&ldquo;rests&rdquo; are stretched along with the notes.
The original score is not modified, and a new score is returned.<br><br>
<dt><code>score-transpose(<a name="index1272"></a><i>score</i>,
<i>keyword</i>,  <i>amount</i>, from-index: <i>i</i>, to-index: <i>j</i>, from-time: <i>x</i>, to-time: <i>y</i>)</code> [SAL]<br>

<code>(score-transpose <i>score</i>
<i>keyword</i> <i>amount</i> :from-index <i>i</i> :to-index <i>j</i> :from-time <i>x</i> :to-time <i>y</i>)</code> [LISP]</dt>
<dd>For 
 each note in the score and in any indicated range, if there is a keyword
 parameter matching <i>keyword</i> and the
parameter value is a number, increment
the parameter value by <i>amount</i>. For example, to tranpose up by a whole
step, write <code>(score-transpose 2 :pitch <i>score</i>)</code>. The 
original score is not modified, and a new score 
is returned. If <i>keyword</i> is <code>:pitch</code> and a corresponding parameter value
is a list, each element of the list is incremented by <i>amount</i>. This special
case is in keeping with the convention of <code>timed-seq</code> in which score
events with lists for the <code>:pitch</code> attribute are expanded into "chords"
by instantiating an event for each element (pitch) in the list (chord).<br><br>
<dt><code>score-scale(<a name="index1273"></a><i>score</i>, <i>keyword</i>, <i>amount</i>, from-index: <i>i</i>, to-index: <i>j</i>, from-time: <i>x</i>,
 to-time: <i>y</i>)</code> [SAL]<br>

<code>(score-scale <i>score</i> <i>keyword</i> <i>amount</i>
 :from-index <i>i</i> :to-index <i>j</i> :from-time <i>x</i> :to-time <i>y</i>)</code> [LISP]</dt>
<dd>For each note
in the score and in any indicated range, if there is a keyword 
parameter matching <i>keyword</i> and the
parameter value is a number, multiply
the parameter value by <i>amount</i>. The original score is not modified, 
and a new score is returned.<br><br>
<dt><code>score-sustain(<a name="index1274"></a><i>score</i>, <i>factor</i>, from-index: <i>i</i>, to-index: <i>j</i>, from-time: <i>x</i>,
 to-time: <i>y</i>)</code> [SAL]<br>

<code>(score-sustain <i>score</i> <i>factor</i>
 :from-index <i>i</i> :to-index <i>j</i> :from-time <i>x</i>
 :to-time <i>y</i>)</code> [LISP]</dt>
<dd>For each note
in the score and in any indicated range, multiply
the duration (stretch factor) by <i>amount</i>. This can be used to
make notes sound more legato or staccato, and does not change their 
starting times. The original score is not modified, and 
a new score is returned.<br><br>
<dt><code>score-voice(<a name="index1275"></a><i>score</i>,
<i>replacement-list</i>, from-index: <i>i</i>, to-index: <i>j</i>, from-time: <i>x</i>, to-time: <i>y</i>)</code> [SAL]<br>

<code>(score-voice <i>score</i>
<i>replacement-list</i> :from-index <i>i</i> :to-index <i>j</i> :from-time <i>x</i> :to-time <i>y</i>)</code> [LISP]</dt>
<dd>For each note
in the score and in any indicated range, replace the behavior (function)
name using <i>replacement-list</i>, which has the format: 
<code>((<i>old1 new1</i>) (<i>old2 new2</i>) <span style="font-style:normal">...</span>)</code>, where <i>oldi</i> indicates
a current behavior name and <i>newi</i> is the replacement. If <i>oldi</i> 
is <code>*</code>, it matches anything.  For example, to 
replace <code>my-note-1</code> by <code>trombone</code> and <code>my-note-2</code> by
<code>horn</code>, use <code>score-voice(<i>score</i>, {{my-note-1 trombone}
{my-note-2 horn}})</code>. To replace all instruments with 
<code>piano</code>, use <code>score-voice(<i>score</i>, {{* piano}})</code>. 
The original score is not modified, and a
 new score is returned.<br><br>
<dt><code>score-merge(<a name="index1276"></a><i>score1</i>, <i>score2</i>, <span style="font-style:normal">...</span>)</code> [SAL]<br>

<code>(score-merge <i>score1</i> <i>score2</i> <span style="font-style:normal">...</span>)</code> [LISP]</dt>
<dd>Create
a new score containing all the notes of the parameters, which are all
scores. The resulting notes retain their original times and durations. The
merged score begin time is the minimum of the begin times of the parameters
and the merged score end time is the maximum of the end times of 
the parameters. The original scores are not modified, and a new 
score is returned.<br><br>
<dt><code>score-append(<a name="index1277"></a><i>score1</i>, <i>score2</i>, <span style="font-style:normal">...</span>)</code> [SAL]<br>

<code>(score-append <i>score1</i> <i>score2</i> <span style="font-style:normal">...</span>)</code> [LISP]</dt>
<dd>Create
a new score containing all the notes of the parameters, which are all
scores. The begin time of the first score is unaltered. The begin time of
 each other score is aligned to the end time of the
previous score; thus, scores are &ldquo;spliced&rdquo; in sequence. The original 
scores are not modified, and a new score is returned.<br><br>
<dt><code>score-select(<a name="index1278"></a><a name="index1279"></a><i>score</i>,
<i>predicate</i>, from-index: <i>i</i>, to-index: <i>j</i>, from-time: <i>x</i>,
 to-time: <i>y</i>, reject: <i>flag</i>, extract: <i>ex</i></code> [SAL]<br>

<code>(score-select <i>score</i>
<i>predicate</i> :from-index <i>i</i> :to-index <i>j</i> :from-time <i>x</i>
 :to-time <i>y</i> :reject <i>flag</i> :extract <i>ex</i>)</code> [LISP]</dt>
<dd>Select
(or reject) notes to form a new score. Notes are selected if they fall
into the given ranges of index and time <i>and</i> they satisfy
<i>predicate</i>, a function of three parameters that is applied to the
start time, duration, and the expression of the note. Alternatively,
<i>predicate</i> may be <code>t</code>, indicating that all notes in range are
to be selected.  Note that <code>from-index:</code> <i>i</i> and <code>to-index:</code>
<i>j</i> are 1-based: A value of 1 refers to the first note, etc., because
the zeroth element of the score is a <code>SCORE-BEGIN-END</code> event.
For consistency, if a <code>SCORE-BEGIN-END</code> event is missing 
from <i>score</i>, one is inserted before any further processing.
The selected notes are combined to form a new
score. By default, <i>ex</i>, the value of the <code>extract:</code> keyword,
is false, and the begin and end markers are retained from
<i>score</i>. Conceptually, the score and its timing are retained as an
object, but only some of its constituent sound events are retained.
Otherwise, if <i>ex</i> is
true (non-nil), the begin and end times are computed based on the
selected (extracted) events: The begin time is <code>from-time</code> <i>x</i>,
if present, and otherwise the time of the first event (if any), and
otherwise the begin time of <i>score</i>. Similarly, the end time is the
<code>to-time</code> <i>y</i>, if present, and otherwise the end time of the
last event (if any), and otherwise the new start time.  Alternatively,
if the <code>reject:</code> parameter is non-null, the notes <i>not</i>
selected form the new score. In other words the selected notes are
rejected or removed to form the new score. The begin and end times of
<i>score</i> are
retained and the <code>extract</code> parameter (<i>ex</i>) is ignored.  In all
cases, the original score is not modified, and a new score is
returned.<br><br>
<dt><code>score-set-begin(<a name="index1280"></a><i>score</i>, <i>time</i>)</code> [SAL]<br>

<code>(score-set-begin <i>score</i> <i>time</i>)</code> [LISP]</dt>
<dd>The begin 
time
 from the <i>score</i>'s <code>SCORE-BEGIN-END</code> marker is set to <i>time</i>. The 
original score is not modified, and a new score is returned.<br><br>
<dt><code>score-get-begin(<a name="index1281"></a><i>score</i>)</code> [SAL]<br>

<code>(score-get-begin <i>score</i>)</code> [LISP]</dt>
<dd>Return the begin
time of the <i>score</i>.<br><br>
<dt><code>score-set-end(<a name="index1282"></a><i>score</i>, <i>time</i>)</code> [SAL]<br>

<code>(score-set-end <i>score</i> <i>time</i>)</code> [LISP]</dt>
<dd>The end time
 from the <i>score</i>'s <code>SCORE-BEGIN-END</code> marker is set to <i>time</i>. The 
original score is not modified, and a new score is returned.<br><br>
<dt><code>score-get-end(<a name="index1283"></a><i>score</i>)</code> [SAL]<br>

<code>(score-get-end <i>score</i>)</code> [LISP]</dt>
<dd>Return the end
time of the <i>score</i>.<br><br>
<dt><code>score-must-have-begin-end(<a name="index1284"></a><i>score</i>)</code> [SAL]<br>

<code>(score-must-have-begin-end <i>score</i>)</code> [LISP]</dt>
<dd>If 
<i>score</i> does not have a begin and end time, construct a score with a
<code>SCORE-BEGIN-END</code> expression and return it. If score already has a begin
and end time, just return the score. The orignal score is not modified.<br><br>
<dt><code>score-filter-length(<a name="index1285"></a><i>score</i>, 
<i>cutoff</i>)</code> [SAL]<br>

<code>(score-filter-length <i>score</i> <i>cutoff</i>)</code> [LISP]</dt>
<dd>Remove
notes that extend beyond the <i>cutoff</i> time. This
is similar to <code>score-select</code>, but the here, events are removed when
their nominal ending time (start time plus duration) exceeds the <i>cutoff</i>,
whereas the <code>to-time:</code> parameter is compared to the note's start time.
The original score is not modified, and a new score is returned.<br><br>
<dt><code>score-repeat(<a name="index1286"></a><i>score</i>, <i>n</i>)</code> [SAL]<br>

<code>(score-repeat <i>score</i> <i>n</i>)</code> [LISP]</dt>
<dd>Make a sequence
of <i>n</i> copies of <i>score</i>. Each copy is shifted to that it's begin
time aligns with the end time of the previous copy, as in <code>score-append</code>.
The original score is not modified, and a new score is returned.<br><br>
<dt><code>score-stretch-to-length(<a name="index1287"></a><i>score</i>,
 <i>length</i>)</code> [SAL]<br>

<code>(score-stretch-to-length <i>score</i> <i>length</i>)</code> [LISP]</dt>
<dd>Stretch the score so that the end time of the score is
the score's begin time plus <i>length</i>. 
The original score is not modified, and a new score is returned.<br><br>
<dt><code>score-filter-overlap(<a name="index1288"></a><i>score</i>)</code> [SAL]<br>

<code>(score-filter-overlap <i>score</i>)</code> [LISP]</dt>
<dd>Remove
overlapping notes (based on the note start time and duration), giving
priority to the
positional order within the note list (which is also time order). 
The original score is not modified, 
and a new score is returned.<br><br>
<dt><code>score-print(<a name="index1289"></a><i>score</i>, [<i>lines</i>])</code> [SAL]<br>

<code>(score-print <i>score</i> [<i>lines</i>])</code> [LISP]</dt>
<dd>Print a score with
one note per line. Returns <code>nil</code>. If <i>lines</i> (optional FIXNUM) is given, print a maximum of that many lines (but the minimum is at least 3). The format is first <i>lines</i>-2 score events, the line "<code>...</code>", and the last score event.<br><br>
<dt><code>score-play(<a name="index1290"></a><i>score</i>)</code> [SAL]<br>

<code>(score-play <i>score</i>)</code> [LISP]</dt>
<dd>Play <i>score</i>
using <code>timed-seq</code> to convert the score to a sound, and 
<code>play</code> to play the sound.<br><br>
<dt><code>score-adjacent-events(<a name="index1291"></a><i>score</i>,
<i>function</i>,
 from-index: <i>i</i>, to-index: <i>j</i>, from-time: <i>x</i>, to-time: <i>y</i>)</code> [SAL]<br>

<code>(score-adjacent-events <i>score</i> <i>function</i> :from-index <i>i</i> :to-index <i>j</i> :from-time <i>x</i> :to-time <i>y</i>)</code> [LISP]</dt>
<dd>Call
<code>(<i>function</i> <i>A</i> <i>B</i> <i>C</i>)</code>, where
<i>A</i>, <i>B</i>, and <i>C</i> are consecutive notes in the score. The result
replaces <i>B</i>. If the result is <code>nil</code>, <i>B</i> is deleted, and the
next call will be <code>(<i>function A C D</i>)</code>, etc. The first call is
to <code>(<i>function</i> nil <i>A B</i>)</code> and the last is to 
<code>(<i>function</i> <i>Y Z</i> nil)</code>. If there is just one note in the
score, <code>(<i>function</i> nil <i>A</i> nil)</code> is called. Function calls 
are not made if the note is outside of the indicated range.
This function 
allows notes and their parameters to be adjusted according to their 
immediate context. The original score is not modified, 
and a new score is returned.<br><br>
<dt><code>score-apply(<a name="index1292"></a><i>score</i>, <i>function</i>,
 from-index: <i>i</i>, to-index: <i>j</i>, from-time: <i>x</i>, to-time: <i>y</i>)</code> 
[SAL]<br>

<code>(score-apply <i>score</i> <i>function</i> :from-index <i>i</i> :to-index <i>j</i> :from-time <i>x</i> :to-time <i>y</i>)</code> [LISP]</dt>
<dd>Replace
each note in the score with the result of
<code>(<i>function time dur expression</i>)</code> (in Lisp) or
<code><i>function</i>(<i>time</i>, <i>dur</i>, <i>expression</i>)</code> (in SAL), 
where <i>time</i>, <i>dur</i>, 
and <i>expression</i> are the time, duration, and expression of the note.
If a range is indicated, only notes in the range are replaced.
The original score is not modified, and a new score is returned.
</dd></dl>
For example, the following uses <code>score-apply</code> to insert an
<code>accent:</code> attribute with value 100 on every sound event 
(note) where <code>pitch:</code> is greater than 70. Notice that
<code>add-accents</code> must be quoted to pass the <i>name</i> of the function
to <code>score-apply</code> (without the <code>quote</code>, 
<code>add-accents</code> denotes the value of a variable, but as a variable,
<code>add-accents</code> is undefined). Also, note that <code>add-accents</code> 
must construct and return a valid score event, hence the expression
<code>list(time, dur, sound))</code>.

<p></p>
<pre>
set my-score = {{0 1 {note pitch: 60}}
                {1 1 {note pitch: 72}}}

function add-accents(time, dur, sound)
  begin
    if expr-get-attr(sound, :pitch, 70) &gt; 70 then
      set sound = expr-set-attr(sound, :accent, 100)
    return list(time, dur, sound)
  end

exec score-print(score-apply(my-score, quote(add-accents)))
</pre>

<p>
The output will be:
</p>
<pre>
((0 0 (SCORE-BEGIN-END 0 2))
(0 1 (NOTE :PITCH 60))
(1 1 (NOTE :PITCH 72 :ACCENT 100))
)
</pre>

<p></p>
<dl>
<dt>
<code>score-indexof(<a name="index1293"></a><i>score</i>, <i>function</i>,
 from-index: <i>i</i>, to-index: <i>j</i>, from-time: <i>x</i>, to-time: <i>y</i>)</code> [SAL]<br>

<code>(score-indexof <i>score</i> <i>function</i> :from-index <i>i</i> :to-index <i>j</i> :from-time <i>x</i> :to-time <i>y</i>)</code> [LISP]</dt>
<dd>Return the index (position)
of the first score event (in range) for which applying <i>function</i> 
using <code>(<i>function time dur expression</i>)</code> returns true.<br><br>
<dt><code>score-last-indexof(<a name="index1294"></a><i>score</i>,
<i>function</i>, from-index: <i>i</i>, to-index: <i>j</i>, from-time: <i>x</i>, 
to-time: <i>y</i>)</code> [SAL]<br>

<code>(score-last-indexof <i>score</i> <i>function</i>
 :from-index <i>i</i> :to-index <i>j</i> :from-time <i>x</i> :to-time <i>y</i>)</code> [LISP]</dt>
<dd>Return 
the index (position)
of the last score event (in range) for which applying <i>function</i> 
using <code>(<i>function time dur expression</i>)</code> returns true.<br><br>
<dt><code>score-randomize-start(<a name="index1295"></a><a name="index1296"></a><a name="index1297"></a><a name="index1298"></a><i>score</i>, <i>amt</i>, from-index: <i>i</i>, to-index: <i>j</i>, from-time: <i>x</i>, to-time: <i>y</i>)</code> [SAL]<br>

<code>(score-randomize-start <i>score</i> <i>amt</i>
 :from-index <i>i</i> :to-index <i>j</i> :from-time <i>x</i> :to-time <i>y</i>)</code> [LISP]</dt>
<dd>Alter the 
start times of notes by a 
random amount up to plus or minus <i>amt</i>.
The original score is not modified, and a new score is returned.
</dd></dl><a name = "182"><h4>Xmusic and Standard MIDI Files</h4></a><a name="index1299"></a><a name="index1300"></a>
<p>Nyquist has a general facility to read and write MIDI files. 
You can even translate to and from a text representation, as described
in Chapter <a href = "part12.html#123">MIDI, Adagio, and Sequences</a>. It is also useful sometimes to read notes
from Standard MIDI Files into Xmusic scores and vice versa. </p>

<p>Using <code>score-read-smf</code> and <code>score-read</code>, MIDI notes are 
translated to Xmusic score events as follows: 
<blockquote>
<code>(<i>time</i> <i>dur</i> (NOTE :chan <i>channel</i> :pitch <i>keynum</i> :vel <i>velocity</i>))</code>,<br>

</blockquote> where <i>channel</i>, <i>keynum</i>, and <i>velocity</i> come directly 
from the MIDI message (channels are numbered starting from zero).
Note also that note-off messages are implied by the stretch factor 
<i>dur</i> which is duration in seconds.</p>

<p>The <code>score-from-seq</code> function allows you to obtain control changes 
and other MIDI messages.</p>
<dl>
<dt>
<code>score-read-smf(<a name="index1301"></a><a name="index1302"></a><i>filename</i>)</code> [SAL]<br>

<code>(score-read-smf <i>filename</i>)</code> [LISP]</dt>
<dd>Read a 
standard MIDI file from <i>filename</i>. Return an Xmusic score, or <code>nil</code>
if the file could not be opened. The
start time is zero, and the end time is the maximum end time of all
notes. A very limited interface is offered to extract MIDI program numbers
from the file: The global variable <code>*rslt*</code> is set to a list of MIDI
program numbers for each channel. E.g. if <code>*rslt*</code> is <code>(0 20 77)</code>, 
then program for channel 0 is 0, for channel 1 is 20, and for channel 2 is 77. 
Program changes were not found on other channels. The default program number is
0, so in this example, it is not known whether the program 0 on channel 0 
is the result of a real MIDI program change command or just a default value. 
If more than one program change exists on a channel, the <i>last</i> program 
number is recorded and returned, so this information will only be completely
correct when the MIDI file sends single program change per channel before
any notes are played. This, however, is a fairly common practice. Note that 
the list returned as <code>*rslt*</code> can be passed 
to <code>score-write-smf</code>, described below.<br><br>
<dt><code>score-read(<a name="index1303"></a><a name="index1304"></a><i>filename</i>)</code> [SAL]<br>

<code>(score-read <i>filename</i>)</code> [LISP]</dt>
<dd>Read an Adagio 
file from <i>filename</i>. Return an Xmusic score, or <code>nil</code>
if the file could not be opened.  See Chapter <a href = "part12.html#123">MIDI, Adagio, and Sequences</a> for details on 
Adagio, a text-based score language.  See <code>score-read-smf</code> for 
details on handling program changes.<br><br>
<dt><code>score-from-seq(<a name="index1305"></a><a name="index1306"></a><i>seq</i>, prog: <i>pflag</i>, synths: <i>synths</i>, bend: <i>bend</i>, cpress: <i>cpress</i>, ctrl: <i>ctrls</i>)</code> [SAL]<br>

<code>(score-from-seq <i>seq</i> :prog <i>pflag</i> :synths <i>synths</i> :bend <i>bend</i> :cpress <i>cpress</i> :ctrl <i>ctrls</i>)</code> [LISP]</dt>
<dd>Produce
a score from a sequence (see Section <a href = "part12.html#124">The SEQ Type</a>) type
 <i>seq</i>. The optional <i>pflag</i>, if non-null, will insert program
 changes as event <code>:prog</code> attributes in score events. The
 <i>bend</i> and <i>cpress</i> (channel pressure) values may be
 <code>:onset</code> to introduce <code>:bend</code> or <code>:cpress</code> attributes
 into score events, or <code>:contin</code> to encode these MIDI messages as
 SOUNDs available through event <code>:contin</code> attributes. The
 <i>ctrl</i> parameter is a list where the first element is either
 <code>:onset</code> or <code>:contin</code> and the remaining elements are
 controller numbers to be encoded. In all cases <code>:contin</code> values
 appear in score events as an object. You can access the SOUNDs that
 encode control changes using the functions
 <code>ctrlfn-bend(<i>contin</i>)</code><a name="index1307"></a>,
 <code>ctrlfn-cpress(<i>contin</i>)</code><a name="index1308"></a> or
 <code>ctrlfn-ctrl(<i>contin</i>, <i>number</i>)</code><a name="index1309"></a>, which
 will return <code>const(0)</code> if no corresponding MIDI messages were 
found. (As a special case the default for controller 7 (volume pedal)
 is <code>const(1)</code>).
 See <code>lib/midi/midi_tutorial.htm</code> for more details and code 
examples. To test for the presence of MIDI messages and avoid the
 construction of <code>const(0)</code>, use 
 <code>ctrlfn-bend?(<i>contin</i>)</code><a name="index1310"></a>,
 <code>ctrlfn-cpress?(<i>contin</i>)</code><a name="index1311"></a> or
 <code>ctrlfn-ctrl?(<i>contin</i>, <i>number</i>)</code><a name="index1312"></a>.<br><br>
<dt><code>score-write-smf(<a name="index1313"></a><a name="index1314"></a><i>score</i>, <i>filename</i>,
[<i>programs</i> <i>as-adagio</i>])</code> [SAL]<br>

<code>(score-write-smf <i>score</i> <i>filename</i> [<i>programs</i> <i>as-adagio</i>])</code> [LISP]</dt>
<dd>Write a standard MIDI file to <i>filename</i> 
with notes in <i>score</i>. In this function,
<i>every</i> event in the score with a <code>pitch:</code> attribute, regardless of the
&ldquo;instrument&rdquo; (or function name), generates a
MIDI note, using the <code>chan:</code> attribute for the channel (default 0) and
the <code>vel:</code> attribute for velocity (default 100). There is no facility
(in the current implementation) to issue control changes, but to allow
different instruments, MIDI programs may be set in two ways. The simplest is
to associate programs with channels using
the optional <i>programs</i> parameter, which is simply a list of up to 16 MIDI
program numbers. Corresponding program change commands are added to the 
beginning of the MIDI file. If <i>programs</i> has less than 16 elements, program
change commands are only sent on the first <i>n</i> channels. The second way to 
issue MIDI program changes is to add a <code>program:</code> keyword parameter to 
a note in the score. Typically, the note will have a <code>pitch:</code> of 
<code>nil</code> so that no actual MIDI note-on message is generated. If program 
changes and notes have the same starting times, their relative playback
order is undefined, and the note may be cut off by an immediately 
following program change. Therefore, program changes should occur slightly,
e.g. 1 ms, before any notes. <i>Program numbers and channels are numbered
starting at zero, matching the internal MIDI representation. This may be
one less than displayed on MIDI hardware, sequencers, etc.</i> The 
<i>as-adagio</i> optional parameter should normally be omitted. 
If non-nil, the file is written in Adagio format, but if you 
want to do that, call <code>score-write</code> instead. Xmusic scores do not specify
tempo, so the MIDI file is written with a fixed tempo of 100bpm. If you create
scores or stretch scores so that each beat is exactly 0.6s (100bpm), sequencers
and score editors will quantize your scores correctly. Otherwise, the <i>timing</i>
will be correct, but for example a score with one note every second will be 
notated as 1 note every 1 2/3 beats.<br><br>
<dt><code>score-write(<a name="index1315"></a><a name="index1316"></a><i>score</i>, <i>filename</i>,
[<i>programs</i>, <i>absolute</i>])</code> [SAL]<br>

<code>(score-write <i>score</i> <i>filename</i> [<i>programs</i> <i>absolute</i>)]</code> [LISP]</dt>
<dd>Write an Adagio format file to <i>filename</i> with notes in <i>score</i>, using absolute times if <i>absolute</i> is true, otherwise write relative times (the default). See Chapter <a href = "part12.html#123">MIDI, Adagio, and Sequences</a> for details on Adagio, a text-based score language. See <code>score-write-smf</code> for details on MIDI program changes.
</dd></dl><a name = "183"><h4>Workspaces</h4></a><a name="index1317"></a>
<p>When working with scores, you may find it necessary to save 
them in files between work sessions. This is not an issue
with functions because they are 
normally edited in files and loaded from them. In contrast,
scores are created as Lisp data, and unless you take care to
save them, they will be destroyed when you exit the Nyquist 
program.</p>

<p>A simple mechanism called a workspace has been created
to manage scores (and any other Lisp data, for that matter).
A workspace is just a set of lisp global variables. These
variables are stored in the file <code>workspace.lsp</code>. 
For simplicity, there is only one workspace, and no backups
or versions are maintained, but the user is free to make
backups and copies of <code>workspace.lsp</code>.
To help remember what each variable is for, you can also
associate and retrieve a text string with each variable.
The following functions manage workspaces.</p>

<p>In addition, when a workspace is loaded, you can request that
functions be called. For example, the workspace might store
descriptions of a graphical interface. When the workspace is
loaded, a function might run to convert saved data into a 
graphical interface. (This is how sliders are saved by the IDE.)</p>
<dl>
<dt>
<code>add-to-workspace(<a name="index1318"></a><i>symbol</i>)</code> [SAL]<br>

<code>(add-to-workspace <i>symbol</i>)</code> [LISP]</dt>
<dd>Adds 
a global variable to the workspace. The <i>symbol</i> should be a (quoted)
symbol.<br><br>
<dt><code>save-workspace(<a name="index1319"></a>)</code> [SAL]<br>

<code>(save-workspace)</code> [LISP]</dt>
<dd>All global variables
in the workspace are saved to <code>workspace.lsp</code> (in the current
directory), overwriting the previous file.<br><br>
<dt><code>describe(<a name="index1320"></a><i>symbol</i> [, <i>description</i>])</code>
[SAL]<br>

<code>(describe <i>symbol</i> [<i>description</i>])</code> [LISP]</dt>
<dd>If <i>description</i>, a text string, is present, 
associate <i>description</i> with the variable named by the
<i>symbol</i>. If <i>symbol</i> is not already in the workspace, 
it is added. If <i>description</i> is omitted, the function returns
the current description (from a previous call) for <i>symbol</i>.<br><br>
<dt><code>add-action-to-workspace(<a name="index1321"></a><i>symbol</i>)</code> [SAL]<br>

<code>(add-action-to-workspace <i>symbol</i>)</code> [LISP]</dt>
<dd>Requests that the function named by <i>symbol</i> be
called when the workspace is loaded (if the function is defined).
</dd></dl>
<p>To restore a workspace, use the command <code>load "workspace"</code>. This restores
the values of the workspace variables to the values they had when
<code>save-workspace</code> was last called. It also restores the documentation
strings, if set, by <code>describe</code>. If you load two or more
<code>workspace.lsp</code> files, the variables will be merged into a
single workspace. The current set of workspace variables are saved in
the list <code>*workspace*</code>. To clear the workspace, set <code>*workspace*</code> 
to <code>nil</code>. This does not delete any variables, but means that
no variables will be saved by <code>save-workspace</code> until variables are
added again.</p>

<p>Functions to be called are saved in the list <code>*workspace-actions*</code>.
to clear the functions, set <code>*workspace-actions*</code> to <code>nil</code>.
Restore functions to the list with <code>add-action-to-workspace</code>.</p>
<a name = "184"><h4>Utility Functions</h4></a>
<p>This chapter concludes with details of various utility functions for score 
manipulation.</p>
<dl>
<dt>
<code>patternp(<a name="index1322"></a><i>expression</i>)</code> [SAL]<br>

<code>(patternp <i>expression</i>)</code> [LISP]</dt>
<dd>Test if <i>expression</i> is 
an Xmusic pattern.<br><br>
<dt><code>params-transpose(<a name="index1323"></a><i>params</i>, <i>keyword</i>, 
<i>amount</i>)</code> [SAL]<br>

<code>(params-transpose <i>params</i> <i>keyword</i> <i>amount</i>)</code> [LISP]</dt>
<dd>Add a transposition amount to a score event parameter. The 
<i>params</i>
parameter is a list of keyword/value pairs (not preceded by a function name). 
The <i>keyword</i> is the keyword of the value to be altered, and <i>amount</i>
is a number to be added to the value. If no matching keyword is present 
in <i>params</i>, then <i>params</i> is returned. Otherwise, a new parameter 
list is constructed and returned. The original <i>params</i> is not changed.<br><br>
<dt><code>params-scale(<a name="index1324"></a><i>params</i>, <i>keyword</i>,
<i>amount</i>)</code> [SAL]<br>

<code>(params-scale <i>params</i> <i>keyword</i> <i>amount</i>)</code> [LISP]</dt>
<dd>Scale a score event parameter by some factor. This is like 
<code>params-transpose</code>, only using multiplication. The <i>params</i> 
list is a list of 
keyword/value pairs, <i>keyword</i> is the parameter keyword, 
and <i>amount</i> is the scale factor. <br><br>
<dt><code>interpolate(<a name="index1325"></a><a name="index1326"></a><i>x</i>, <i>x1</i>, <i>y1</i>, <i>x2</i>, <i>y2</i>)</code> [SAL]<br>

<code>(interpolate <i>x</i> <i>x1</i> <i>y1</i> <i>x2</i> <i>y2</i>)</code> [LISP]</dt>
<dd>Linearly interpolate (or extrapolate)
 between points
(<i>x1</i>, <i>y1</i>) and (<i>x2</i>, <i>y2</i>) to compute the y value
 corresponding to <i>x</i>.<br><br>
<dt><code>intersection(<a name="index1327"></a><a name="index1328"></a><i>a</i>,
<i>b</i>)</code> [SAL]<br>

<code>(intersection <i>a</i> <i>b</i>)</code> [LISP]</dt>
<dd>Compute the set intersection of lists <i>a</i> and <i>b</i>.<br><br>
<dt><code>union(<a name="index1329"></a><a name="index1330"></a><i>a</i>, <i>b</i>)</code> [SAL]<br>

<code>(union <i>a</i> <i>b</i>)</code> [LISP]</dt>
<dd>Compute 
the set union of lists <i>a</i> and <i>b</i>.<br><br>
<dt><code>set-difference(<a name="index1331"></a><a name="index1332"></a><i>a</i>,
<i>b</i>)</code> [SAL]<br>

<code>(set-difference <i>a</i> <i>b</i>)</code> [LISP]</dt>
<dd>Compute the set of all elements that are in <i>a</i> but not in <i>b</i>.<br><br>
<dt><code>subsetp(<a name="index1333"></a><a name="index1334"></a><i>a</i>, <i>b</i>)</code> [SAL]<br>

<code>(subsetp <i>a</i> <i>b</i>)</code> [LISP]</dt>
<dd>Returns true iff
<i>a</i> is a subset of <i>b</i>, that is, each element of <i>a</i> is a member 
of <i>b</i>.
</dd></dl><hr>
<a href = "part14.html">Previous Section</a> | <a href = "part16.html">Next Section</a> | <a href = "title.html#toc">Table of Contents</a> | <a href = "indx.html">Index</a> | <a href = "title.html">Title Page</a>
</body></html>