download MKOrchestra.h
Language: ObjectiveC
Copyright: (c) 1999-2004 The MusicKit Project. Copyright 1988-1992, NeXT Inc. All rights reserved. Copyright 1993, CCRMA, Stanford Univ.
LOC: 245
Project Info
The MusicKit(musickit)
Server: SourceForge
Type: cvs
...sicKit\Frameworks\MusicKit\
   _ArielQP.h
   _DSPMK.h
   _error.h
   _midi.h
   _MKAppProxy.h
   _MKAppProxy.m
   _MKNameTable.h
   _MKNameTable.m
   _MKParameter.h
   _MTCHelper.h
   _MTCHelper.m
   _musickit.h
   _noteRecorder.h
   _OrchloopbeginUG.h
   _OrchloopbeginUG.m
   _ParName.h
   _ParName.m
   _scorefile.h
   _ScorefileVar.h
   _ScorefileVar.m
   _SharedSynthInfo.h
   _SharedSynthInfo.m
   _synthElementMethods.m
   _time.h
   ArielQP.h
   ArielQP.m
   classFuncs.h
   ConductorPrivate.h
   dsp_types.h
   DSPSerialPortDevice.h
   dspwrap.h
   EnvelopePrivate.h
   equalTempered.m
   errors.h
   fastFFT.c
   fastFFT.h
   GNUmakefile.postamble
   GNUmakefile.preamble.in
   InstrumentPrivate.h
   keynums.h
   libMusicKit.def
   Localized.strings
   make.sh
   Makefile.postamble
   Makefile.preamble
   midi_spec.h
   midifile.h
   midifile.m
   MidiPrivate.h
   midiTranslation.h
   MKConductor.h
   MKConductor.m
   MKConductorDelegate.h
   MKDeviceStatus.h
   MKEnvelope.h
   MKEnvelope.m
   MKFilePerformer.h
   MKFilePerformer.m
   MKFileWriter.h
   MKFileWriter.m
   MKInstrument.h
   MKInstrument.m
   MKMidi.h
   MKMidi.m
   MKMixerInstrument.h
   MKMixerInstrument.m
   MKMTCPerformer.h
   MKMTCPerformer.m
   MKNote.h
   MKNoteFilter.h
   MKNoteFilter.m
   MKNoteReceiver.h
   MKNoteReceiver.m
   MKNoteSender.h
   MKNoteSender.m
   MKOrchestra.h
   MKPart.m
   MKPartials.h
   MKPartials.m
   ...tialsWaveshapingTable.m
   MKPartPerformer.h
   MKPartPerformer.m
   MKPartRecorder.h
   MKPartRecorder.m
   MKPatch.h
   MKPatch.m
   MKPatchConnection.h
   MKPatchConnection.m
   MKPatchEntry.h
   MKPatchEntry.m
   MKPatchTemplate.h
   MKPatchTemplate.m
   MKPerformer.h
   MKPerformer.m
   MKPerformerDelegate.h
   MKPlugin.h
   MKSamplerInstrument.h
   MKSamplerInstrument.m
   MKSamples.h
   MKScore.h
   MKScore.m
   MKScorefileObject.h
   MKScorefilePerformer.h
   MKScorefilePerformer.m
   MKScorefileWriter.m
   MKScorePerformer.h
   MKScorePerformer.m
   MKScoreRecorder.h
   MKScoreRecorder.m
   MKSynthData.h
   MKSynthData.m
   MKSynthInstrument.h
   MKSynthPatch.h
   MKTimbre.h
   MKTimbre.m
   MKTuningSystem.h
   MKTuningSystem.m
   MKUnitGenerator.h
   MKUnitGenerator.m
   MKWaveTable.h
   MKWaveTable.m
   mtcMidi.m
   mtcMidiPrivate.m
   MusicKit-Info.plist
   MusicKit.h
   MusicKitConfig.h.in
   names.h
   noDVal.h
   noteDispatcherMethods.m
   NotePrivate.h
   noteRecorderCFuncs.m
   noteRecorderMethods.m
   orch.h
   OrchestraPrivate.h
   OrchloopbeginUG.h
   OrchloopbeginUG.m
   orchloopbeginUGInclude.m
   params.h
   parNames.m
   partialsDBInclude.m
   PartialsPrivate.h
   PartPerformerPrivate.h
   PartPrivate.h
   PartRecorderPrivate.h
   PatchTemplatePrivate.h
   PB.project
   PerformerPrivate.h
   pitches.h
   platform.make
   ...efilePerformerPrivate.h
   ScorePerformerPrivate.h
   ScorePrivate.h
   ScoreRecorderPrivate.h
   SynthDataPrivate.h
   synthElementCFuncs.m
   synthElementMethods.m
   SynthInstrumentPrivate.h
   SynthPatchList.h
   SynthPatchList.m
   SynthPatchPrivate.h
   timetagInclude.m
   timeunits.h
   tokenNames.m
   tokens.h
   trigonometry.c
   trigonometry.h
   TuningSystemPrivate.h
   UnitGeneratorPrivate.h
   win32-def.top
   writeBinary.m
   writeMidi.m
   writeScore.m

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
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
/*
  $Id: MKOrchestra.h,v 2.8 2005/05/30 03:28:19 leighsmith Exp $
  Defined In: The MusicKit

  Description:
    See headerdoc description below for details.
 
    The MKOrchestra factory object manages all programs running on all the DSPs.
    Each instance of the MKOrchestra class corresponds to a single DSP. We call
    these instances "orchestra instances" or, simply, "orchestras". We call the
    collection of all orchestras the "MKOrchestra". Each orchestra instance is
    referred to by an integer 'orchIndex'. These indecies start at 0. 
    For the basic configuration, orchIndex is always 0.

    There are two levels of allocation: MKSynthPatch allocation and
    unit generator allocation. MKSynthPatches are higher-level entities,
    collections of MKUnitGenerators. Both levels may be used at the same time.

    CF: MKUnitGenerator.m, MKSynthPatch.m, MKSynthData.m and MKPatchTemplate.m.

  Original Author: David A. Jaffe

  Copyright 1988-1992, NeXT Inc.  All rights reserved.
  DSP Serial Port and subclass support and other 4.0 release extensions,
  Copyright 1993, CCRMA, Stanford Univ.
  Portions Copyright (c) 1999-2004 The MusicKit Project.
*/
/*!
  @class MKOrchestra
  @brief This is the allocator and manager of DSP resources.
  
  The MKOrchestra class manages signal processing resources used in music synthesis.
  Each instance of MKOrchestra represents a single "signal processor resource" that 
  may refer to a DSP hardware processor, or to processing behaviour performed by the
  main processor, a networked processor (i.e Beowulf clustered), or perhaps one of 
  the vector processor resources of a main processor. This is for historical reasons
  collectively termed a "DSP". The signal processing resource is identified by 
  <b>orchIndex</b>, a zero-based integer index.
  
  In the basic NeXT hardware configuration, there's only one MC56001 DSP so there's
  only one MKOrchestra instance (<b>orchIndex</b> 0).  On Intel-based hardware, there may
  be any number of DSPs or none, depending on how many DSP cards the user has installed (See
  "INSTALLING INTEL-BASED DSP DRIVERS" below). On PowerPC class machines the signal
  processing is performed on the main processor, so there's only one MKOrchestra.

  The methods defined by the MKOrchestra class let you manage a DSP by allocating 
  (TODO should this be assign?, i.e. alloc as normal, then assign the initialised instance?)
  portions of its memory for specific synthesis modules and by setting its
  processing characteristics. There are two levels of allocation: MKSynthPatch allocation and
  unit generator allocation. MKSynthPatches are higher-level entities, collections of
  MKUnitGenerators. 
 
  You can allocate entire MKSynthPatches or individual
  MKUnitGenerator and MKSynthData objects through the methods defined here.  Keep in
  mind, however, that similar methods defined in other class - specifically, the
  MKSynthPatch allocation methods defined in MKSynthInstrument, and the MKUnitGenerator
  and MKSynthData allocation methods defined in MKSynthPatch - are built upon and
  designed to usurp those defined by MKOrchestra.  You only to need to allocate
  synthesis objects directly if you want to assemble sound-making modules at a low
  level.

  Before you can do anything with an MKOrchestra - particularly, before you can
  allocate synthesis objects - you must create and open the MKOrchestra.  The
  MKOrchestra is a shared resource (that is, various DSP modules all use the same
  single MKOrchestra instance.)  Therefore, creation is done through the <b>orchestra</b>
  method - sending <b>orchestra</b> twice returns the same object.   (This strange
  convention is for historical reasons and matches the ApplicationKit
  convention.)  To open an MKOrchestra, you send it the <b>open</b> message.  This
  provides a channel of communication with the DSP that the MKOrchestra represents. 
  Once you've allocated the objects that you want, either through the methods
  described here or through those defined by MKSynthInstrument and MKSynthPatch, you
  can start the synthesis by sending the <b>run</b> message to the MKOrchestra.  (If
  your application uses the MusicKit's performance scheduling mechanism, the
  <b>run</b> message should be sent immediately before or immediately after the
  <b>startPerformance</b> message is sent to the MKConductor.) The <b>stop</b>
  method halts synthesis and <b>close</b> breaks communication with the DSP. 
  These methods change the MKOrchestra's status, which is always one of the
  following MKDeviceStatus values:

 <table border=1 cellspacing=2 cellpadding=0 align=center>
 <thead>
 <tr>
 <th align=left>MKDeviceStatus</th>
 <th align=left>Description</th>
 </tr>
 </thead>
 <tbody>
 <tr>
 <td align=left>MK_devOpen</td>
 <td align=left>The MKOrchestra is open but not running.</td>
 </tr>
 <tr>
 <td align=left>MK_devRunning</td>
 <td align=left>The MKOrchestra is open and running.</td>
 </tr>
 <tr>
 <td align=left>MK_devStopped</td>
 <td align=left>The MKOrchestra has been running, but is now stopped.</td>
 </tr>
 <tr>
 <td align=left>MK_devClosed</td>
 <td align=left>The MKOrchestra is closed.</td>
 </tr>
 </thead>
 </table>

  You can query an MKOrchestra's status through the <b>deviceStatus</b>
  method.

  When the MKOrchestra is running, the allocated MKUnitGenerators produce a stream of
  samples that, by default, are sent to the "default sound output".  On most modern
  hardware, that is the stereo digital to analog converter (the
  DAC), which converts the samples into an audio signal.  This type of sound
  output is called "Host sound output" because the samples are sent from the DSP to
  the host computer.  
 
 TODO modify this:
 But there are a number of other alternatives.  You can write the
samples to the DSP serial port, to be played through any of a number of devices
that have their own DACs or do digital transfer to DAT recorders.  To do this,
invoke the method <b>setSerialSoundOut:</b> with a <b>YES</b> argument before
sending <b>open</b> to the MKOrchestra.  This is also called "SSI" sound output.
 See the DSPSerialPortDevice class for more details.  

  Another option is to write the samples to a soundfile. You do this by invoking the
  method <b>setOutputSoundfile:</b> before sending <b>open</b> to the MKOrchestra. 
  If you're writing a soundfile, the computer's DAC is automatically disabled.
  It is also possible to save the DSP commands as a "DSP commands format
  soundfile".   Such files are much smaller than the equivalent soundfile.  Use
  the method <b>setOutputCommandsFile:</b> to create such a file.  However,
  support for playing DSP commands file may not continue in future releases. 
  Therefore, we do not encourage their use.

  The MKOrchestra can also process sound that it receives. 
  To do this, send <b>setSoundIn:</b> with a <b>YES</b> argument. 
 TODO update this:
  &lt;&lt;Note that currently serial input may not be combined with writing a
  soundfile.&gt;&gt;

Every command that's sent to the DSP is given a timestamp indicating when the
command should be executed.  The manner in which the DSP regards these
timestamps depends on whether its MKOrchestra is timed or untimed, as set through
the <b>setTimed:</b> method.  In a timed MKOrchestra, commands are executed at the
time indicated by its timestamp.  If the MKOrchestra is untimed, the DSP ignores
the timestamps, executing commands as soon as it receives them.  By default, an
MKOrchestra is timed.

Since the DSP is a separate processor, it has its own clock and its own notion
of the current time. Since the DSP can be dedicated to a single task - in this
case, generating sound - its clock is generally more reliable than the main
processor, which may be controlling any number of other tasks.  If your
application is generating MKNotes without user-interaction, for example, if it's
playing a MKScore or scorefile, then you should set the Music Kit performance to
be unclocked, through the MKConductor's <b>setClocked:</b> method, and the
MKOrchestra to be timed.  This allows the Music Kit to process MKNotes and send
timestamped commands to the DSP as quickly as possible, relying on the DSP's
clock to synthesize the MKNotes at the correct time.  However, if your application
must respond to user-initiated actions with as little latency as possible, then
the MKConductor must be clocked.  In this case, you can set the MKOrchestra to be
untimed.  A clocked MKConductor and an untimed MKOrchestra yields the best possible
response time.

If your application responds to user actions, but can sustain some latency
between an action and its effect, then you may want to set the MKConductor to be
clocked and the DSP to be timed, and then use the C function
<b>MKSetDeltaT()</b> to set the <i>delta time</i>.  Delta time is an imposed
latency that allows the Music Kit to run slightly ahead of the DSP.  Any
rhythmic irregularities created by the Music Kit's dependence on the CPU's clock
are evened out by the utter dependability of the DSP's clock (assuming that the
such an irregularity isn't greater than the delta time).

Since parameter updates can occur asynchronously, the MKOrchestra doesn't know, at
the beginning of a MKNote, if the DSP can execute a given set of MKUnitGenerators
quickly enough to produce a steady supply of output samples for the entire
duration of the MKNote.  However, it makes an educated estimate and will deny
allocation requests that it thinks will overload the DSP and cause it to fall
out of real time.  Such a denial may result in a smaller number of
simultaneously synthesized voices.  You can adjust the MKOrchestra's DSP
processing estimate, or headroom, by invoking the <b>setHeadroom:</b> method. 
This takes an argument between -1.0 and 1.0; a negative headroom allows a more
liberal estimate of the DSP resources - resulting in more simultaneous voices -
but it runs the risk of causing the DSP to fall out of real time.  Conversely, a
positive headroom is more conservative: You have a greater assurance that the
DSP won't fall out of real time but the number of simultaneous voices is
decreased.  The default is a somewhat conservative 0.1.  If you're writing
samples to a soundfile with the DAC disabled, headroom is ignored.  On
Intel-based hardware, the differences between the clock and memory speed of
various DSP cards requires some hand-tuning of the headroom variable.  Slower
DSP cards should use a higher headroom and faster cards should use a negative
headroom.

When sending sound to the DSP serial port, there is very little latency - for
example, sound can be taken in the serial port, processed, and sent out again
with less than 10 milliseconds of delay.  However, in the case of sound output
via the NeXT monitor, there's a sound output time delay that's equal to the size
of the buffer that's used to collect computed samples before they're shovelled
to the NeXT DAC.  To accommodate applications that require the best possible
response time (the time between the iniitation of a sound and its actual
broadcast from the DAC), a smaller sample output buffer can be requested by
sending the <b>setFastResponse:YES</b> message to an MKOrchestra.  However, the
more frequent attention demanded by the smaller buffer will detract from
synthesis computation and, again, fewer simultaneous voices may result.  You can
also improve response time by using the high sampling rate (44100) although
this, too, attenuates the synthesis power of the DSP.  By default, the
MKOrchestra's sampling rate is 22050 samples per second.  <b>setFastResponse:</b>
has no effect when sending samples to the DSP serial port.

To avoid creating duplicate synthesis modules on the DSP, each instance of
MKOrchestra maintains a shared object table.  Objects on the table are
MKSynthPatches, SynthDatas, and MKUnitGenerators and are indexed by some other
object that represents the shared object.  For example, the OscgafUG
MKUnitGenerator (a family of oscillators) lets you specify its waveform-generating
wave table as a MKPartials object (you can also set it as a MKSamples object; for
the purposes of this example we only consider the MKPartials case).  When its wave
table is set, through the <b>setTable:length:</b> method, the oscillator
allocates a MKSynthData object from the MKOrchestra to represent the DSP memory that
will hold the waveform data that's computed from the MKPartials.  It also places
the MKSynthData on the shared object table using the MKPartials as an index by
sending the message

<tt>[MKOrchestra installSharedSynthData:theSynthData for:thePartials];</tt>

If another oscillator's wave table is set as the same MKPartials object, the
already-allocated MKSynthData can be returned by sending the message

<tt>id aSynthData = [MKOrchestra sharedObjectFor:thePartials];</tt>

The method <b>installSharedObject:for:</b> is provided for installing
MKSynthPatches and MKUnitGenerators.

If appropriate hardware is available, multiple DSPs may be used in concert.  The
MKOrchestra automatically performs allocation on the pool of DSPs.  On Intel-based
hardware, multiple DSP support is achieved by adding multiple DSP cards.  On
NeXT hardware, multiple DSP support is available via the Ariel QuintProcessor, a
5-DSP card.  

The MKOrchestra class may be subclassed to support other 56001-based cards.  See
the ArielQP and ArielQPSat objects for an example.

The default sound output configuration may be customized by using the defaults
data base.  On NeXT hardware, you can specify the destination of the sound
output, and on both NeXT hardware and Intel-based DSP cards with NeXT-compatible
DSP serial ports, you can specify the type of the serial port device.  The
default sound out type is derived from the MusicKit "OrchestraSoundOut" variable
in the defaults data base, which may currently have the value "SSI" or "Host".  
More values may be added in the future.  Note that an "SSI" value for
"OrchestraSoundOut" refers to the DSP's use of the SSI port and that usage does
not imply NeXT-compatiblility.  For example, for the Turtle Beach cards, the
default is "serialSoundOut" via the on-card CODEC.  (On Intel-based hardware,
the determination as to whether the DSP serial port is NeXT-compatible is based
on the driver's "SerialPortDevice" parameter - if its value is "NeXT", the
serial port is NeXT-compatible. )  You can always return to the default sample
output configuration by sending the message <b>setDefaultSoundOut</b>.

New MKOrchestras are auto-configured with their default configuration, with a
DSPSerialPortDevice object automatically created.  For devices with
NeXT-compatible DSP serial ports, you may change the configuration using the
MKOrchestra methods such as <b>-setSerialPortDevice:</b>.  

INSTALLING INTEL-BASED DSP DRIVERS

To install an Intel-based DSP driver, follow these steps:

1. Double click on the driver you want to install.  The drivers can be found on
<b>/LocalLibrary/Devices/.</b>  For example, to install the ArielPC56D driver,
double click on <b>/LocalLibrary/Devices/ArielPC56D.config</b>.  Type the root
pass word. It will tell you driver was successfully installed. Click
OK.
You've now "installed" the driver.

2. In<b> Configure.app</b>, Click Other. Click Add... Click Add.  Select the
driver (from the "other" category) and make sure that the I/O port corresponds
to your hardware configuration.  From Menu/Configuration, select Save.   You've
now "added the driver".	

3. Repeat the process for any other drivers, such as the TurtleBeach Multisound
driver, <b>/LocalLibrary/Devices/TurtleBeachMS.config.</b>	

4. If you have multiple cards of a certain type, repeat step 2, making sure to
assign a different I/O address to each instance of the driver.  The first will
be given the name &lt;driverName&gt;0, where &lt;driverName&gt; is the name of
the driver (e.g. "ArielPC56D")  The second will be given the name
&lt;driverName&gt;1, etc. The trailing number is called the "unit."  For
example,  if you add 2 Ariel cards to your system, they will be assigned the
names "ArielPC56D0" and "ArielPC56D1".  If you have one Multisound card, it will
be assigned the name "TurtleBeachMS0".  This assignment is done by the
<b>Configure.app</b> application.

5. Reboot.  Drivers are now installed and usable.

All DSP drivers are in the same "family", called "DSP."  All DSP units are
numbered with a set of "DSP indecies", beginning with 0.  (Note that this is
distinct from the "unit" numbers.) If there is only one DSP card, there is no
ambiguity.  However, if there is more than one card, the user's defaults data
base determines which DSP or DSPs should be used.  For example, in the example
given above, a user's defaults data base may have:
 	
MusicKit DSP0 ArielPC56D1	
MusicKit DSP2 ArielPC56D0	
MusicKit DSP4 TurtleBeachMS0

This means that the default DSP is the one on the 2nd Ariel card that you
installed.  Also, notice that there may be "holes" - in this example, there is
no DSP1 or DSP3.  DSP identifiers up to 15 may be used.  The DSP indecies refer
to the MKOrchestra index passed to methods like<b> +newOnDSP:</b>.  If there is no
driver for that DSP, <b>+newOnDSP:</b> returns nil.  

Some DSP cards support multiple DSPs on a single card.  For such cards, we have
the notion of a "sub-unit", which follows the unit in the assigned name with the
following format:  &lt;driver&gt;&lt;unit&gt;-&lt;subunit&gt;.   For example if
a card named "Frankenstein" supports 4 DSPs, and there are two Frankenstein
units installed in the system, the user's defaults data base might look like
this:
	
MusicKit DSP0 Frankenstein0-0	
MusicKit DSP1 Frankenstein0-1	
MusicKit DSP2 Frankenstein0-2	
MusicKit DSP3 Frankenstein0-3	
MusicKit DSP4 Frankenstein1-0	
MusicKit DSP5 Frankenstein1-1	
MusicKit DSP6 Frankenstein1-2	
MusicKit DSP7 Frankenstein1-3

Currently, the Music Kit provides drivers for the following cards: <b>Ariel
PC56D,  Turtle Beach Multisound</b>, <b>I*Link i56, Frankenstein</b>.  See the
release notes for the latest information on supported drivers.
*/
#ifndef __MK_Orchestra_H___
#define __MK_Orchestra_H___

#import <Foundation/Foundation.h>
#import "orch.h"
#import "MKDeviceStatus.h"
#import "MKSynthData.h"

/*!
  @file MKOrchestra.h
 */

/*!
  @brief This enumeration defines the types of shared objects that can be
  registered with the MKOrchestra's shared object mechanism.
 
  The shared object mechanism manages reference counts, automatic lazy garbage
  collection, etc. Note that the same data object may be registered as the key for
  several different types of shared data.  For example, a MKPartials
  object may have associated with it two MKSynthData objects, one
  representing its oscTable representation and one representing its
  waveshapingTable representation.
 */
typedef enum _MKOrchSharedType {
    /*! Wildcard. */
    MK_noOrchSharedType = 0, 
    /*! Data used as a wave table for an oscillator.  This shared
	type must be a power of 2 in length and if a request for
        a shorter length is made, it is	downsampled. */
    MK_oscTable = 1, 
    /*! Data used as a waveshaping table. This table performs a non-linear mapping.
        When looked-up with a sine wave, it provides a specified spectrum.  */
    MK_waveshapingTable = 2,
    /*! Data used as an excitation table for waveguide-based synthesis. 
        This type is similar to oscTable but it need not be a power of 2 and
        it is shortened by truncation (from the end.) */
    MK_excitationTable = 3
} MKOrchSharedType;

typedef enum _MKEMemType {
    MK_orchEmemNonOverlaid = 0, 
    MK_orchEmemOverlaidXYP = 1, 
    MK_orchEmemOverlaidPX = 2
} MKEMemType;

/*!
  @brief MK_UNTIMED and MK_TIMED are arguments for the MKConductor <b>setTimed:</b> method.     
 
  @see <b>MKConductor</b> and the Performance Concepts documentation for details.
 */
typedef enum {
    /*! DSP commands are executed as soon as they are sent. */
    MK_UNTIMED = 0,
    /*! DSP commands are executed at the time of their time-stamp. */
    MK_TIMED = 1,
    /*! Obsolete. */
    MK_SOFTTIMED = 2
} MKOrchestraTiming;

/*!
  @brief Get the MKSynthPatch preemption time

  During a performance, DSP resources can become scarce; it's sometimes
  necessary to preempt active MKSynthPatches in order to synthesize new
  MKNotes.  This preemption is handled by MKSynthInstrument objects. But
  rather than simply yank the rug from under an active MKSynthPatch, a
  certain amount of time is given to allow the patch to &ldquo;wind
  down&rdquo; before it's killed in order to prevent clicks.  By default,
  this grace period, or &ldquo;preempt duration&rdquo;, is 0.006 seconds -
  not a lot of time but enough to avoid snapping the MKSynthPatch's
  envelopes.  You can set the preempt duration yourself through
  <b>MKSetPreemptDuration()</b>.  Preempt duration is global to an
  application; it's current value is retrieved through
  <b>MKGetPreemptDuration()</b>. 
  @return Returns the preempt duration.
*/
extern double MKGetPreemptDuration(void);

/*!
  @brief Set the MKSynthPatch preemption time.

  During a performance, DSP resources can become scarce; it's sometimes
  necessary to preempt active MKSynthPatches in order to synthesize new
  MKNotes.  This preemption is handled by MKSynthInstrument objects. But
  rather than simply yank the rug from under an active MKSynthPatch, a
  certain amount of time is given to allow the patch to &ldquo;wind
  down&rdquo; before it's killed in order to prevent clicks.  By default,
  this grace period, or &ldquo;preempt duration&rdquo;, is 0.006 seconds -
  not a lot of time but enough to avoid snapping the MKSynthPatch's
  envelopes.  You can set the preempt duration yourself through
  <b>MKSetPreemptDuration()</b>.  Preempt duration is global to an
  application; it's current value is retrieved through
  <b>MKGetPreemptDuration()</b>. 
  @param  seconds is a double.
*/
extern void MKSetPreemptDuration(double seconds);
 
@interface MKOrchestra : SndStreamClient
{
    double computeTime;      /* Runtime of orchestra loop in seconds. */
    double samplingRate;     /* Sampling rate. */
    /* Stack of MKUnitGenerator instances in the order they appear in DSP memory. 
    MKSynthData instances are not on this unitGeneratorStack. */
    NSMutableArray *unitGeneratorStack;      
    NSString *outputSoundfile; /* For output sound samples. */
    id outputSoundDelegate;
    NSString *inputSoundfile; /* For output sound samples. */ /* READ DATA */
    NSString *outputCommandsFile; /* For output DSP commands. */
    id xZero;         /* Special pre-allocated x patch-point that always holds
                         0 and to which nobody ever writes, by convention.  */
    id yZero;         /* Special pre-allocated y patch-point that always holds
                         0 and to which nobody ever writes, by convention.  */
    id xSink;      /* Special pre-allocated x patch-point that nobody ever
                      reads, by convention. */
    id ySink;      /* Special pre-allocated y patch-point that nobody ever
                      reads, by convention. */
    id xModulusSink;/* Special pre-allocated x patch-point that nobody ever
                      reads, by convention. */
    id yModulusSink;/* Special pre-allocated y patch-point that nobody ever
                      reads, by convention. */
    id sineROM;    /* Special read-only MKSynthData object used to represent
                      the SineROM. */
    id muLawROM;   /* Special read-only MKSynthData object used to represent
                      the Mu-law ROM. */
    /*! @var deviceStatus Status of MKOrchestra. */
    MKDeviceStatus deviceStatus;
    /*! @var orchIndex Index of the DSP resource managed by this instance. */
    unsigned short orchIndex;
    char isTimed;    /* Determines whether DSP commands go out timed or not. */
    BOOL useDSP;     /* YES if running on an actual DSP (Default is YES) */
    BOOL hostSoundOut;   /* YES if sound is going to the DACs. */
    /*! @var soundIn Indicates if this orchestra will process incoming sound. */
    BOOL soundIn;
    BOOL isLoopOffChip; /* YES if loop has overflowed off chip. */
    BOOL fastResponse;  /* YES if response latency should be minimized */
    double localDeltaT; /* positive offset in seconds added to out-going
                           time-stamps */
    short onChipPatchPoints;
    int release;
    char version;
    NSString *monitorFileName;   /* NULL uses default monitor */
    DSPLoadSpec *mkSys;
    NSString *lastAllocFailStr;
    id _sysUG;
    int _looper;
    void *_availDataMem[3];
    void  *_eMemList[3];
    NSMutableDictionary *_sharedSet;
    DSPAddress _piLoop;
    DSPAddress _xArg;
    DSPAddress _yArg;
    DSPAddress _lArg;
    DSPAddress _maxXArg;
    DSPAddress _maxYArg;
    DSPAddress *_xPatch;
    DSPAddress *_yPatch;
    unsigned long _xPatchAllocBits;
    unsigned long _yPatchAllocBits;
    double _headroom;
    double _effectiveSamplePeriod;
    id _orchloopClass;
    id _previousLosingTemplate;
    DSPFix48 _previousTimeStamp;
    int _parenCount;
    int _bottomOfMemory;
    unsigned int _bottomOfExternalMemory[3];
    int _topOfExternalMemory[3];
    int _onChipPPPartitionSize;
    int _numXArgs;
    int _numYArgs;
    float _xArgPercentage;
    float _yArgPercentage;
    void *_simFP;
    MKEMemType _overlaidEMem;
    BOOL _nextCompatibleSerialPort;
    NSString *_driverParMonitorFileName;
    // added in by LMS, thawing the ancient ivar freeze
    double previousTime;
    NSHashTable *sharedGarbage;
    char *simulatorFile;
    id readDataUG;
    id xReadData;
    id yReadData;
    double timeOffset;
    double synchTimeRatio;
    NSTimer *timedEntry;
    BOOL synchToConductor;
}

/*!
  @return Returns a MKDeviceStatus.
  @brief Returns the MKDeviceStatus of the receiver, one of
  
	  <UL>
  <LI>	MK_devClosed 
  <LI>	MK_devOpen 
  <LI>	MK_devRunning 
  <LI>	MK_devStopped
  </UL>
  
  The MKOrchestra states are explained in the class description, above.

  
*/
- (MKDeviceStatus) deviceStatus;

/*!
  @param  headroom is a double.
  @return Returns an id.
  @brief Sets the receiver's computation headroom, adjusting the tradeoff
  between processing power and reliability.

  The argument should be in
  the range -1.0 to 1.0.  As you increase an MKOrchestra's headroom, the
  risk of falling out of real time decreases, but synthesis power is
  also weakened.  The default, 0.1, is a conservative estimate and can
  be decreased in many cases without heightening the risk of falling
  out of real time.
  
  The effective sampling period - the amount of time the MKOrchestra 
  thinks the DSP has to produce a sample - is based on the formula
  
  (1.0/<b>samplingRate</b>) * (1.0 - <b>headroom</b>).
  
  Returns the receiver.
*/
- (void) setHeadroom: (double) headroom;

/*!
  @brief Sets the headroom of all MKOrchestras instances that have been created.
  @param  headroom is a double.
  @return Returns the receiver.
  @see  -<b>setHeadroom:</b>
*/
+ (void) setHeadroom: (double) headroom;

/*!
  @brief Returns the receiver's headroom, as set through the <b>setHeadroom:</b> method.

  Headroom should be a value between -.0  and 1.0.  The default is 0.1.
  @return Returns a double.
*/
- (double) headroom;

// TODO investigate if needed.
// TODO candidate to return void
/*!
  @return Returns an id.
  @brief Marks the beginning of a section of DSP commands that are sent as a
  unit.

  Returns the receiver.
*/
- beginAtomicSection;

// TODO investigate if needed.
// TODO candidate to return void
/*!
  @return Returns an id.
  @brief Marks the end of a section of DSP commands that are sent as a unit.

  Returns the receiver.
*/
- endAtomicSection;

/*!
  @brief Returns and initializes a new MKOrchestra for the default DSP, if one
  doesn't already exist, otherwise returns the existing one.
 
  The DSP isn't actually claimed until the MKOrchestra instance is sent the
  <b>open</b>message.
  @return Returns an autoreleased MKOrchestra instance.
*/
+ orchestra; 

/*!
  @brief Creates and returns an MKOrchestra instance for the <i>index</i>'th DSP.

  If an MKOrchestra object already exists for the specified DSP,
  the existing object is returned.  Returns <b>nil</b> if <i>index</i>
  is out of bounds or if the <i>index</i>'th DSP isn't available.  For
  example, on Intel hardware, if there is no driver for the
  <i>index</i>'th DSP, this method returns nil.  Note that for some
  types of DSP devices, the object returned will be a <i>subclass</i>
  of MKOrchestra, rather than an instance of MKOrchestra.  
  @param  index is an unsigned short indicating which DSP resource to initialise on.
  @return Returns an id.
  @see registerOrchestraSubclass:forOrchIndex:.
*/
+ orchestraOnDSP: (unsigned short) index; 

/*!
  @brief Creates an MKOrchestra instance for every available DSP, if it has not
  already been created.

  This is accomplished by consulting the user's defaults data base (setable with the
  Preferences application).  Returns all the MKOrchestra's created.
  @return Returns an NSArray of MKOrchestra instances.
*/
+ (NSArray *) orchestrasOnAllDSPs;

/*!
  @brief Flushes all currently buffered DSP commands by invoking the
  <b>flushTimedMessages</b> instance method for each MKOrchestra.

  The usual way to invoke this method is via the MKConductor
  +<b>unlockPerformance</b> method  (which must be preceeded by
  +<b>lockPerformance</b>.)    
  @return Returns an id.
*/
+ flushTimedMessages; 

/*!
  @brief Returns the maximum possible number of DSPs.

  This may be more than the number of DSPs you actually have.   
  @return Returns an unsigned short.
*/
+ (unsigned short) DSPCount;

/*!
  @brief Returns the MKOrchestra of the <i>index</i>'th DSP.

  If <i>index</i> is out of bounds, or if an MKOrchestra hasn't been created for the
  specified DSP, <b>nil</b> is returned.
  @param  index is an unsigned short.
  @return Returns an id.
*/
+ (MKOrchestra *) nthOrchestra: (unsigned short) index; 

/*!
  @brief Initialises the MKOrchestra instance on the first (default) DSP resource.
 */
- init;

/*!
  @brief Initialises an MKOrchestra instance on the given DSP processing resource.
  
  A DSP processing resource is nowdays an abstract concept of processing resource which
  may refer to a hardware DSP processor, vector unit or networked processor.
  @param dspIndex The index of the DSP processing resource as returned by +driverNames.
 */
- initOnDSP: (unsigned short) dspIndex;

/*!
  @brief Sends <b>open</b> to each of the MKOrchestra instances and sets each
  to MK_devOpen.

  If any of the MKOrchestras responds to the <b>open</b>
  message by returning <b>nil</b>, so too does this method return
  <b>nil</b>.  Otherwise returns the receiver.  Note that if you first
  send <b>open</b> and then create a new MKOrchestra, the new MKOrchestra
  will not automatically be opened.  
  @return Returns an id.
*/
+ open; 

/*!
  @brief Sends <b>run</b> to each of the MKOrchestra instances and sets each to MK_devRunning.

  If any of the MKOrchestras responds to the <b>run</b>
  message by returning <b>nil</b>, so too does this method return
  <b>nil</b>.  Otherwise returns the receiver.
  @return Returns an id.
*/
+ run; 

/*!
  @brief Sends <b>stop</b> to each of the MKOrchestra instances and sets each
  to MK_devStopped.

  If any of the MKOrchestras responds to the
  <b>run</b> message by returning <b>nil</b>, so too does this method
  return <b>nil</b>.  Otherwise returns the receiver.
  @return Returns an id.
*/
+ stop; 

/*!
  @brief Sends <b>close</b> to each of the MKOrchestra instances and sets each
  to MK_devClosed.

  If any of the MKOrchestras responds to the <b>close</b> message by returning <b>nil</b>,
  so too does this method return <b>nil</b>.  Otherwise returns the receiver.
  @return Returns an id.
*/
+ close; 

/*!
  @brief Sends <b>abort</b> to each of the MKOrchestra instances and sets each to MK_devClosed.

  If any of the MKOrchestras responds to the <b>abort</b> message by returning <b>nil</b>,
  so too does this method return <b>nil</b>.  Otherwise returns the receiver.
  @return Returns an id.  
*/
+ abort;

// TODO document
// TODO investigate if needed.
- (void) synchTime: (NSTimer *) timer;

/*!
  @brief Returns the tick size used by synthesis unit-generators.

  Each unit generator runs for this many frames, and patchpoints are this
  length. Since 1989, the tick-size used on the DSP has been 16. 
  @return Returns an int.
*/
- (int) tickSize; 

/*!
  @brief Returns the receiver's sampling rate.

  The default is determined by the method <b>defaultSamplingRate</b>.
  @return Returns a double.
*/
- (double) samplingRate; 

// TODO candidate to return void
/*!
  @param  newSRate is a double.
  @return Returns an id.
  @brief Sets the sampling rate of all the MKOrchestra instances by sending
  <b>setSamplingRate:</b><i>newSRate</i> to all closed MKOrchestras.

  
  This method also changes the default sampling rate; when a new
  MKOrchestra is subsequently created, it also gets set to
  <i>newSRate</i>.  Returns the receiver.
*/
+ (void) setSamplingRate: (double) newSRate; 

// TODO candidate to return BOOL
/*!
  @param  newSRate is a double.
  @return Returns an id.
  @brief Sets the receiver's sampling rate to <i>newSRate</i>, taken as
  samples per second.

  The receiver must be closed - <b>nil</b> is
  returned if the receiver's status isn't MK_devClosed.  Returns the
  receiver.
*/
- setSamplingRate: (double) newSRate; 

// TODO candidate to return void
/*!
  @param  areOrchsTimed is a MKOrchestraTiming.
  @return Returns an id.
  @brief Sends <b>setTimed:</b><i>areOrchsTimed</i> to each MKOrchestra
  instance.

  If <i>areOrchsTimed</i> is YES, the DSP processes the
  commands that it receives at the times specified by the commands'
  timestamps.  If it's <b>NO</b>, DSP commands are processed as
  quickly as possible.  By default, an MKOrchestra is timed.  Note,
  however, that this method changes the default to
  <i>areOrchsTimed</i>.
*/
+ setTimed: (MKOrchestraTiming) areOrchsTimed; 

// TODO candidate to return void
/*!
  @param  isOrchTimed is a MKOrchestraTiming.
  @return Returns an id.
  @brief If <i>isOrchTimed</i> is YES, the receiver's DSP executes the
  commands it receives according to their timestamps.

  If it's NO, it
  ignores the timestamps processes the commands immediately.  By
  default, an MKOrchestra is timed.   * Note that untimed mode was
  originally intended primarily as a means of inserting "out of band"
  messages into a timed stream and is not as efficient for
  high-bandwidth transfers normally associated with a Music Kit
  performance.  Note also that untimed mode is not deterministic with
  respect to precise timing. However, it has the advantage of
  providing the minimum possible latency.  It is permissable to change
  time timing mode during a Music Kit performance.
*/
- setTimed: (MKOrchestraTiming) isOrchTimed; 

/*!
  @brief Returns <b>YES</b> if the receiver is timed <b>NO</b> if it's untimed.
  @return Returns a MKOrchestraTiming.
*/
- (MKOrchestraTiming) isTimed; 

// TODO candidate to return void
/*!
  @brief Specify that the MKOrchestra is to synchronize the DSP's notion of
  time to that of the MKConductor's time.
 
   The DSP sample counter and the System clock (i.e. the MKConductor
  clock) are intended to keep the same time (except for fluctuations
  due to the internal buffering of the DSP and sound drivers).  Over a
  long-term  performance, however, the two clocks may begin to drift
  apart slightly, on the order of a few milliseconds per minutes.  If
  you are running with an extremely small "delta time" (cf.
  <b>MKSetDeltaT()</b>), you may want to synchronize the two clocks
  periodically.  By sending <b>setSynchToConductor:YES</b>, you
  specify that the MKOrchestra is to synchronizes the DSP's notion of
  time to that of the MKConductor's time every 10 seconds to account for
  slight differences between the rate of the two clocks.   This method
  assumes an Application object exists and is running and that the
  MKConductor is in clocked mode.
  
  Note:  This method may cause time to go backwards in the DSP temporarily,
  and thus may cause distortion of envelopes, lost notes, etc.
  Therefore, its use is recommended only when absolutely necessary.
  An alternative method of synchronization (though no safer) can be found
  in the Ensemble programming example.
  @param  yesOrNo is a BOOL.
  @return Returns an id.
*/
- setSynchToConductor: (BOOL) yesOrNo;

/*!
  @brief &lt;&lt;NeXT hardware only.&gt;&gt; Sets the size of the sound
  output buffer; two sizes are possible.

  If <i>yesOrNo</i> is YES,
  the smaller size is used, thereby improving response time but
  somewhat decreasing the DSP's synthesis power.  If it's NO, the
  larger buffer is used.  By default, an MKOrchestra uses the larger
  buffer.  Returns the receiver.  This method has no effect if sound
  output is done via the DSP serial port.
  @param  yesOrNo is a BOOL.
  @return Returns an id.
*/
- setFastResponse: (char) yesOrNo;

/*!
  @param  yesOrNo is a BOOL.
  @return Returns an id.
  @brief Sends <b>setFastResponse:</b><i>yesOrNo</i> to all existing
  MKOrchestras objects and returns the receiver.

  This also sets the
  default used by subsequently created MKOrchestras.
*/
+setFastResponse:(char)yesOrNo;

/*!
  @brief Returns YES if the receiver is using small sound-out buffers to
  minimize response latency.

  Otherwise returns NO.
  @return Returns a BOOL.
*/
- (char) fastResponse;

+ setAbortNotification:aDelegate;

/*!
  @brief Sets the offset, in seconds, that's added to the timestamps of
  commands sent to the receiver's DSP.

  The offset is added to the delta time that's set with <b>MKSetDeltaT()</b>.
  This has no effect if the receiver isn't timed.  
  @param  val is a double.
  @return Returns the receiver.
*/
- setLocalDeltaT: (double) val;

/*!
  @brief Returns the value set through <b>setLocalDeltaT:</b>.
  @return Returns a double.
*/
- (double) localDeltaT;

/*!
  @brief Sets the local delta time for all MKOrchestras and changes the
  default, which is otherwise 0.0.
  @param  val is a double.
  @return Returns an id.
*/
+ setLocalDeltaT: (double) val;

/*!
  @param  yesOrNo is a BOOL.
  @return Returns an id.
  @brief Sets whether the receiver, which must be
  closed, sends its sound signal to the host DAC, as <i>yesOrNo</i> is
  YES or NO.

  Returns the receiver, or <b>nil</b> if it isn't closed. 
  On NeXT hardware, the default is to send sound to the host
  DAC.
  
  Sending <b>setHostSoundOut:YES</b> also sends <b>setOutputSoundfile: nil</b>;
  you can't write samples to a soundfile and to the DAC at the same time.
  Sending <b>setHostSoundOut:YES</b> also sends s<b>etSerialSoundOut: NO</b>;
  you can't write samples to the DSP serial port and to the DAC at the same time.
*/
- setHostSoundOut: (BOOL) yesOrNo;

- (BOOL) hostSoundOut;

- setSoundOut: (BOOL) yesOrNo;

/*!
  @brief Sets whether the receiver, which must be closed, receives sound, as <i>yesOrNo</i> is YES or NO.
  @param  yesOrNo is a BOOL.
  @return Returns the receiver, or <b>nil</b> if it isn't closed.
 */
- setSoundIn: (BOOL) yesOrNo;

/*!
  @brief Sets whether soundIn is enabled.
  @return Returns a BOOL.
 */
- (BOOL) soundIn;

/*!
  @brief Sets extra debugging information during orchestra synthesis to printed.
  
  Used to be setOnChipMemoryDebug:patchPoints:.
 */
- (void) setDebug: (BOOL) yesOrNo;

/*!
  @brief Sets the soundfile to which sound samples are written.

  The receiver must be closed; <b>nil</b> is returned if it's open, otherwise
  returns the receiver.  A copy of <i>fileName</i> is stored in the
  instance variable <i>outputSoundfile</i>.    If you re-run the
  MKOrchestra, the file is rewritten. To specify that you no longer want
  to write a file when the MKOrchestra is re-run, close the MKOrchestra,
  then send <b>setOutputSoundfile:NULL</b>.  When switching from
  soundfile writing to other forms of sound output,  note that you
  must explicitly send <b>setHostSoundOut:YES</b>or <b>
  setSerialSoundOut:YES </b>after setting the output soundfile to
  NULL. 
  
  It is not permissable to have an output soundfile open and do host
  or serial port sound output at the same time.  
  @param  fileName is an NSString instance.
  @return Returns an id.
*/
- setOutputSoundfile: (NSString *) fileName;

/*!
  @brief Returns a pointer to the name of the receiver's output soundfile, or nil if none.
  @return Returns an NSString instance.
*/
- (NSString *) outputSoundfile;

-setOutputSoundDelegate:aDelegate;
-outputSoundDelegate;

/*!
  @param  fileName is an NSString instance.
  @return Returns an id.
  @brief Sets a file name to which DSP commands are to be written as a DSP
  Commands format soundfile.

  A copy of the fileName is stored in the
  instance variable <i>outputCommandsFile</i>.   This message is
  ignored if the receiver is not closed.  Playing of DSP Commands
  format soundfiles is currently (1995) implemented only for NeXT
  hardware.
*/
- setOutputCommandsFile: (NSString *) fileName;

/*!
  @return Returns a NSString.
  @brief Returns the output soundfile or <b>nil</b> if none.
*/
- (NSString *) outputCommandsFile;

/*!
  @param  classObj is an id.
  @return Returns an id.
  @brief Allocates a MKUnitGenerator of class <i>classObj</i>.

  The object is allocated on the first MKOrchestra that can accomodate it.  Returns
  the MKUnitGenerator, or <b>nil</b> if the object couldn't be
  allocated.
*/
+ allocUnitGenerator: (id) classObj; // (Class) classObj 

/*!
  @param  segment is a MKOrchMemSegment.
  @param  size is an unsigned.
  @return Returns an id.
  @brief Allocates a MKSynthData object.

  The allocation is on the first
  MKOrchestra that will accommodate <i>size</i> words in segment
  <i>segment</i>.  Returns the MKSynthData, or <b>nil</b> if the object
  couldn't be allocated.
*/
+ allocSynthData: (MKOrchMemSegment) segment length: (unsigned) size; 

/*!
  @brief Allocates a patchpoint in segment <i>segment</i> Returns the
  patchpoint (a MKSynthData object), or <b>nil</b> if the object
  couldn't be allocated.
  @param  segment is a MKOrchMemSegment.
  @return Returns an id.
*/
+ allocPatchpoint: (MKOrchMemSegment) segment; 

/*!
  @brief This is the same as <b>allocSynthPatch:patchTemplate:</b> but uses
  the default template obtained by sending the message
  <b>defaultPatchTemplate</b> to <i>aSynthPatchClass.</i>
  @param  aSynthPatchClass is an id.
  @return Returns an id.
*/
+ allocSynthPatch: (id) aSynthPatchClass;  // (Class) aSynthPatchClass 

/*!
  @brief Allocates a MKSynthPatch with a MKPatchTemplate of <i>p</i> on the first
  DSP with sufficient resources.

  Returns the MKSynthPatch or <b>nil</b> if it couldn't be allocated.
  @param  aSynthPatchClass is an id.
  @param  p is an id.
  @return Returns an id.
*/
+ allocSynthPatch: (id) aSynthPatchClass patchTemplate: (id) p;

/*!
  @brief Deallocates the argument, which must be a previously allocated
  MKSynthPatch, MKUnitGenerator or MKSynthData, by sending it the
  <b>dealloc</b> message.

  This method is provided for symmetry with
  the <b>alloc</b>family of methods.
  @param  aSynthResource is an id.
  @return Returns an id.
*/
+ dealloc: (id) aSynthResource;

/*!
  @brief Sends buffered DSP commands to the DSP.

  This is done for you by the MKConductor.  However, if your application sends messages directly to
  a MKSynthPatch or MKUnitGenerator without the assistance of a MKConductor,
  you must invoke this method yourself (after sending the synthesis
  messages). The usual way to invoke this method is via the
  MKConductor <b>+unlockPerformance</b> method (which must be preceeded
  by <b>+lockPerformance</b>). Note that you must send flushTimedMessages even if the MKOrchestra is set to
  MK_UNTIMED mode ("flushTimedMessages" is somewhat of a misnomer; a
  better name would have been "sendBufferedDSPCommands").
  @return Returns the receiver.
*/
- flushTimedMessages;

+ (int) sharedTypeForName: (char *) str;
+ (char *) nameForSharedType: (int) typeInt;

/*!
  @brief Places <i>aSynthObj</i> on the shared object table and sets its reference count to 1.

  <i>aKeyObj</i> is  any object associated with
  the abstract notion of the data and is used to index the shared
  object.  Does nothing and returns <b>nil</b> if the <i>aSynthObj</i>
  is already present in the table.  Also returns <b>nil</b> if the
  orchestra isn't open.  Otherwise, returns the receiver.
  
  This method differs from <b>installSharedObjectWithSegmentAndLength:for:</b> 
  in that the length and segment are wild cards.
  @param  aSynthObj is an id.
  @param  aKeyObj is an id.
  @return Returns an id.
*/
- installSharedObject: (id) aSynthObj for: (id) aKeyObj;

/*!
  @brief Places <i>aSynthObj</i> on the shared object table and sets its
  reference count to 1.

  <i>aKeyObj</i> is used to index the shared
  object.  <i>type</i> is used to specify additional details about the
  data that is being installed.  For example, oscillator tables are
  intsalled as type <b>MK_oscTable</b>, while waveshaping tables are
  installed as <b>MK_waveshapingTable</b>. Waveguide physical model
  excitation tables are installed as <b>MK_excitationTable.</b> <i>type</i>
  makes it possible to use <i>aKeyObj</i> to lookup various
  different types of Synth objects.  Does nothing and returns
  <b>nil</b> if the <i>aSynthObj</i> is already present in the table. 
  Also returns <b>nil</b> if the orchestra isn't open.  Otherwise,
  returns the receiver.
  
  This method differs from <b>installSharedObjectWithSegmentAndLength:for:</b>
  in that the length and segment are wild cards.
  @param  aSynthObj is an id.
  @param  aKeyObj is an id.
  @param  aType is a MKOrchSharedType.
  @return Returns an id.
 */
- installSharedObject: (id) aSynthObj for: (id) aKeyObj type: (MKOrchSharedType) aType;

/*!
  segment specified by <i>aSynthDataObj</i> and sets its reference
  count to 1.

  Does nothing and returns <b>nil</b> if the
  <i>aSynthObj</i> is already present in the table.  Also returns
  <b>nil</b> if the orchestra is not open.  Otherwise, returns the
  receiver.
  
  This method differs from <b>installSharedObjectWithSegmentAndLength:for:</b> in that the length is a wild card.
  @param  aSynthDataObj is an id.
  @param  aKeyObj is an id.
  @return Returns an id.
  @brief Places <i>aSynthDataObj</i> on the shared object table in the
 */
- installSharedSynthDataWithSegment: (id) aSynthDataObj for: (id) aKeyObj;

/*!
  @brief Places <i>aSynthDataObj</i> on the shared object table in the
  segment specified by <i>aSynthDataObj</i> and sets its reference
  count to 1.

  Does nothing and returns <b>nil</b> if the
  <i>aSynthObj</i> is already present in the table.  Also returns
  <b>nil</b> if the orchestra is not open.  Otherwise, returns the
  receiver.
  
  This method differs from <b>installSharedObjectWithSegmentAndLength:for:</b> in that the length
  is a wild card.
  @param  aSynthDataObj is an id.
  @param  aKeyObj is an id.
  @param  aType is an MKOrchSharedType.
  @return Returns an id.
 */
- installSharedSynthDataWithSegment: (id) aSynthDataObj 
				for: (id) aKeyObj 
			       type: (MKOrchSharedType) aType;

- installSharedSynthDataWithSegmentAndLength: (MKSynthData *) aSynthDataObj
					 for: (id) aKeyObj;

/*!
  @brief Places <i>aSynthDataObj</i> on the shared object table in the
  segment of aSynthDataObj with the specified length and sets its
  reference count to 1.

  <i>aKeyObj</i> is used to index the shared
  object.  Does nothing and returns <b>nil</b> if the
  <i>aSynthDataObj</i> is already present in the table.  Also returns
  <b>nil</b> if the orchestra is not open.  Otherwise, returns the
  receiver.
 @param  aSynthDataObj is an id.
 @param  aKeyObj is an id.
 @param  aType is an MKOrchSharedType.
 @return Returns an id. 
*/
- installSharedSynthDataWithSegmentAndLength: (MKSynthData *) aSynthDataObj
					 for: (id) aKeyObj
					type: (MKOrchSharedType) aType;

/*!
  @brief Returns, from the receiver's shared object table, the MKSynthData,
  MKUnitGenerator, or MKSynthPatch object that's indexed by <i>aKeyObj</i>
  If the object is found,  <i>aKeyObj</i>'s reference count is
  incremented.

  If it isn't found, or if the receiver isn't open,
  returns <b>nil</b>.
  @param  aKeyObj is an id.
  @return Returns an id.
*/
- sharedObjectFor: (id) aKeyObj;

/*!
  @brief Returns, from the receiver's shared object table, the MKSynthData,
  MKUnitGenerator, or MKSynthPatch object that's indexed by
  <i>aKeyObj.</i> <i> </i> The object must be allocated with the
  specified type.

  If the object is found,  <i>aKeyObj</i>'s reference
  count is incremented. If it isn't found, or if the receiver isn't
  open, returns <b>nil</b>.
 @param  aKeyObj is an id.
 @param  aType is a MKOrchSharedType.
 @return Returns an id.
 */
- sharedObjectFor: (id) aKeyObj type: (MKOrchSharedType) aType;

/*!
  @brief Returns, from the receiver's shared data table, the MKSynthData,
  MKUnitGenerator, or MKSynthPatch object that's indexed by
  <i>aKeyObj</i>.

  The object must be allocated in the specifed
  segment.  <i>aKeyObj</i> on the receiver in the specified segment. 
  If the object is found, <i>aKeyObj</i>'s reference count is
  incremented.  If it isn't found, or if the receiver isn't open,
  returns <b>nil</b>.
  @param  aKeyObj is an id.
  @param  whichSegment is a MKOrchMemSegment.
  @return Returns an id.
*/
- sharedSynthDataFor: (id) aKeyObj segment: (MKOrchMemSegment) whichSegment;

/*!
  @brief Returns, from the receiver's shared data table, the MKSynthData,
  MKUnitGenerator, or MKSynthPatch object that's indexed by
  <i>aKeyObj</i>.

  The object must be allocated in the specifed
  segment.  <i>aKeyObj</i> on the receiver in the specified segment. 
  If the object is found, <i>aKeyObj</i>'s reference count is
  incremented.  If it isn't found, or if the receiver isn't open,
  returns <b>nil</b>.
  @param  aKeyObj is an id.
  @param  whichSegment is a MKOrchMemSegment.
  @param  aType is a MKOrchSharedType.
  @return Returns an id.
*/
- sharedSynthDataFor: (id) aKeyObj 
	     segment: (MKOrchMemSegment) whichSegment
		type: (MKOrchSharedType) aType; 

/*!
  @brief Returns, from the receiver's shared data table, the MKSynthData,
  MKUnitGenerator, or MKSynthPatch object that's indexed by
  <i>aKeyObj</i>.

  The object must be allocated in the specifed
  segment.  <i>aKeyObj</i> on the receiver in the specified segment. 
  If the object is found, <i>aKeyObj</i>'s reference count is
  incremented.  If it isn't found, or if the receiver isn't open,
  returns <b>nil</b>.
  @param  aKeyObj is an id.
  @param  whichSegment is a MKOrchMemSegment.
  @param  length is an integer.
  @return Returns an id.
*/
- sharedSynthDataFor: (id) aKeyObj
	     segment: (MKOrchMemSegment) whichSegment 
	      length: (int) length;

/*!
  @brief Returns, from the receiver's shared data table, the MKSynthData,
  MKUnitGenerator, or MKSynthPatch object that's indexed by
  <i>aKeyObj</i>.

  The object must be allocated in the specifed
  segment, have a length of <i>length</i>and have a type <i>type</i> .
  <i>aKeyObj</i> on the receiver in the specified segment.  If the
  object is found, <i>aKeyObj</i>'s reference count is incremented. 
  If it isn't found, or if the receiver isn't open, returns
  <b>nil</b>.
  @param  aKeyObj is an id.
  @param  whichSegment is a MKOrchMemSegment.
  @param  length is an int.
  @param  aType is a MKOrchSharedType.
  @return Returns an id.
 */
- sharedSynthDataFor: (id) aKeyObj
	     segment: (MKOrchMemSegment) whichSegment
	      length: (int) length
		type: (MKOrchSharedType) aType; 

/*!
  @return Returns an id.
  @brief Returns a MKSynthData object representing the SineROM.

  You should
  never deallocate this object.
*/
- sineROM; 

/*!
  @return Returns an id.
  @brief Returns a MKSynthData object representing the MuLawROM.

  You should
  never deallocate this object.
*/
- muLawROM; 

/*!
  @param  segment is a MKOrchMemSegment.
  @return Returns an id.
  @brief Returns a special pre-allocated patchpoint (a MKSynthData) in the
  specified segment that always holds 0 and to which, by convention,
  nothing is ever written.

  The patchpoint shouldn't be deallocated. 
  <i>segment</i> can be MK_xPatch or MK_yPatch.
*/
- segmentZero: (MKOrchMemSegment) segment; 

/*!
  @param  segment is a MKOrchMemSegment.
  @return Returns an id.
  @brief Returns a special pre-allocated patchpoint (a MKSynthData) in the
  specified segment which may be used to write garbage.

  It's commonly
  used as a place to send the output of idle MKUnitGenerators.  The
  patchpoint shouldn't be deallocated.  <i>segment</i> can be
  MK_xPatch or MK_yPatch.
*/
- segmentSink: (MKOrchMemSegment) segment; 

/*!
  @param  segment is a MKOrchMemSegment.
  @return Returns an id.
  @brief Returns a special pre-allocated patchpoint (a MKSynthData) in the
  specified segment, aligned for modulus addressing, which may be used
  to write garbage.

  It's commonly used as a place to send the output
  of idle MKUnitGenerators.  The patchpoint shouldn't be deallocated. 
  <i>segment</i> can be MK_xPatch or MK_yPatch.
*/
- segmentSinkModulus: (MKOrchMemSegment) segment; 

/*!
  @return Returns an id.
  @brief Opens the receiver's DSP and sets the receiver's status to
  MK_devOpen.

  Resets orchestra loop (if not already reset), freeing
  all Unit Generators and MKSynthPatches.  Returns <b>nil</b> if the DSP
  can't be opened for some reason,  otherwise returns the receiver.  
  To find out why the DSP can't be opened, enable Music Kit or DSP
  error tracing.  Possible problems opening the DSP include another
  application using the DSP, a missing DSP monitor file, a version
  mismatch and missing or broken hardware. 
*/
- open; 

/*!
  @return Returns an id.
  @brief Starts the clock on the receiver's DSP, thus allowing the processor
  to begin executing commands, and sets the receiver's status to
  MK_devRunning.

  This opens the DSP if it isn't already open. 
  Returns <b>nil</b> if the DSP couldn't be opened or run, otherwise
  returns the receiver.
*/
- run; 

/*!
  @return Returns an id.
  @brief Stops the clock on the receiver's DSP, thus halting execution of
  commands, and sets the receiver's status to MK_devStopped.

  This
  opens the DSP if it isn't already open.  Returns <b>nil</b> if an
  error occurs, otherwise returns the receiver.
*/
- stop; 

/*!
  @return Returns an id.
  @brief Waits for all enqueued DSP commands to be executed.

  Then severs
  communication with the DSP, allowing other processes to claim it. 
  The MKSynthPatch-allocated MKUnitGenerators and MKSynthInstrument-allocated MKSynthPatches are freed.  All MKSynthPatches must be idle and non-MKSynthPatch-allocated MKUnitGenerators must be deallocated before sending this message.  Returns <b>nil</b> if an error occurs, otherwise returns the receiver.
*/
- close; 

/*!
  @return Returns an id.
  @brief This is the same as <b>close</b>, except that it doesn't wait for
  enqueued DSP commands to be executed.

  Returns <b>nil</b> if an
  error occurs, otherwise returns the receiver.
*/
- abort;

- useDSP: (BOOL) useIt; 
- (BOOL) isDSPUsed; 

/*!
  @param  typeOfInfo is an int.
  @param  fmt,... is a char *.
  @return Returns an id.
  @brief Used to print debugging information.

  The arguments to the <b>msg:</b> keyword are like those to <b>printf()</b>.  If the
  <i>typeOfInfo</i> trace is set, prints to stderr.  
*/
- trace: (int) typeOfInfo msg: (NSString *) fmt,...; 

/*!
  @brief Returns a pointer to the name of the specified MKOrchMemSegment.
  
  The name is not copied and should not be freed.
  @param  whichSegment is an int.
  @return Returns an NSString instance.
*/
- (NSString *) segmentName: (int) whichSegment; 

/*!
  @return Returns an unsigned short.
  @brief Returns the index of the DSP associated with the receiver.
  
  Used to be named index.
*/
- (unsigned short) orchestraIndex; 

/*!
  @brief Returns the compute time estimate currently used by the receiver in
  seconds per sample.
  @return Returns a double.
*/
- (double) computeTime; 

/*!
  @brief Same as <b>allocSynthPatch:patchTemplate:</b> but uses the default
  template, obtained by sending the message <b>defaultPatchTemplate</b> to <i>aSynthPatchClass</i>.
  @param  aSynthPatchClass is an id.
  @return Returns an id.
*/
- allocSynthPatch: (id) aSynthPatchClass; 

/*!
  @brief Allocates and returns a MKSynthPatch for MKPatchTemplate <i>p</i>.

  The receiver first tries to find an idle MKSynthPatch; failing that, it
  creates and returns a new one.  The MKUnitGenerators are added to the
  SynthPatch's unitGenerators list in the same order they are
  specified in the MKPatchTemplate.  If a new MKSynthPatch can't be built,
  this method returns <b>nil</b>.
  @param  aSynthPatchClass is an id.
  @param  p is an id.
  @return Returns an id.
 */
- allocSynthPatch: (id) aSynthPatchClass patchTemplate: (id) p; 

/*!
  @brief Allocates and returns a MKUnitGenerator of the specified class,
  creating a new one, if necessary.
  @param  aClass is an id.
  @return Returns an id.
*/
- allocUnitGenerator: (id) aClass; 

/*!
  @brief Allocates and returns a MKUnitGenerator of the specified class.

  The newly allocated object will execute before <i>aUnitGeneratorInstance</i>.
  @param  aClass is an id.
  @param  aUnitGeneratorInstance is an id.
  @return Returns an id.
*/
- allocUnitGenerator: (id) aClass before: (id) aUnitGeneratorInstance; 

/*!
  @brief Allocates and returns a MKUnitGenerator of the specified class.

  The newly allocated object will execute after <i>aUnitGeneratorInstance</i>.
  @param  aClass is an id.
  @param  aUnitGeneratorInstance is an id.
  @return Returns an id. 
 */
- allocUnitGenerator: (id) aClass after: (id) aUnitGeneratorInstance; 

/*!
  @brief Allocates and returns an MKUnitGenerator of the specified class.

  The newly allocated object will execute immediately after
  <i>aUnitGeneratorInstance</i> and before <i>anotherUnitGenerator</i>.
  @param  aClass is an id.
  @param  aUnitGeneratorInstance is an id.
  @param  anotherUnitGeneratorInstance is an id.
  @return Returns an id.
 */
- allocUnitGenerator: (id) aClass between: (id) aUnitGeneratorInstance : (id) anotherUnitGeneratorInstance;

- (NSString *) lastAllocationFailureString;

/*!
  @brief Allocates and returns a new MKSynthData object with the specified
  length, or <b>nil</b> if the receiver doesn't have sufficient
  resources, if <i>size</i> is 0, or if an illegal segment is
  requested.

  <i>segment</i> should be MK_xData or MK_yData.
  @param  segment is a MKOrchMemSegment.
  @param  size is an unsigned.
  @return Returns an id.
 */
- allocSynthData: (MKOrchMemSegment) segment length: (unsigned) size; 

/*!
  @brief Allocates and returns a MKSynthData to be used as a patchpoint in the
  specified segment (MK_xPatch or MK_yPatch).

  Returns <b>nil</b> if an illegal segment is requested.
  @param  segment is a MKOrchMemSegment.
  @return Returns an id.
*/
- allocPatchpoint: (MKOrchMemSegment) segment; 

/*!
  @brief Deallocates <i>aSynthResource</i> by sending it the <b>dealloc</b>
  message.

  <i>aSynthResource</i> may be a MKUnitGenerator, a MKSynthData
  or a MKSynthPatch.  This method is provided for symmetry with the
  <b>alloc</b> family of methods.
  @param  aSynthResource is an id.
  @return Returns an id.
*/
- dealloc: (id) aSynthResource;

/*!
  @brief Returns <b>YES</b> if the receiver runs in real time.

  This will be <b>YES</b> if any of soundOut, serialSoundOut or soundIn is
  <b>YES</b>.  Subclasses may want to override this method.
  @return Returns a BOOL.
*/
- (BOOL) isRealTime;


/*!
  @brief Returns YES if the DSP or driver supports the specified sampling
  rate (or half that rate).

  The implementation forwards the message
  <b>supportsSamplingRate:</b> to the serial port device, if
  serialSoundOut or soundIn is enabled.  Otherwise, for NeXT
  hardware, it returns YES if aRate is 22050 or 44100.  A subclass may
  override this method.
  @param  rate is a double.
  @return Returns a BOOL.
*/
- (BOOL) supportsSamplingRate: (double) rate;

- (int) hardwareSupportedSamplingRates: (double **) arr;

/*!
  @return Returns a double.
  @brief Returns the default sampling rate for the driver or hardware
  corresponding to this MKOrchestra instance's DSP.

  If serialSoundOut
  or soundIn is enabled, this method simply forwards the
  <b>defaultSamplingRate</b> message to the DSPSerialPortDevice
  object.  Otherwise, returns 22050.0.  Note that you may change the
  sampling rate using <b>setSamplingRate:</b>, but the default will
  still remain the same.  A subclass may override this method to
  provide a different default.
*/
- (double) defaultSamplingRate;

/*!
  @return Returns a BOOL.
  @brief Returns YES if the MKOrchestra will do better with a lower sampling
  rate than is ordinarily needed.

  The default implementation returns
  YES if the driver parameter "WaitStates" is "3".  This is to
  accomodate the Multisound card.
*/
- (BOOL) prefersAlternativeSamplingRate;

+ setAbortNotification: aDelegate;

/*!
  @brief Resets serialSoundOut, hostSoundOut, serialPortDevice, etc. to
  produce the "default sound output" for the given hardware.
 
  On NeXT hardware, the default sound output is the NeXT monitor's DAC. On
  Intel-based hardware, this method sets up the card with the default
  serial port device, if any.
  @return Returns an id.
*/
- setDefaultSoundOut;

#define MK_nextCompatibleDSPPort 1
#define MK_hostSoundOut (1<<1)
#define MK_serialSoundOut (1<<2)
#define MK_soundIn (1<<3)
#define MK_soundfileOut (1<<4)

/*!
  @return Returns an unsigned.
  @brief returns an unsigned int, the bits of which report what capabilities
  are provided by the DSP device corresponding to the MKOrchestra.

  Possible values (defined in MKOrchestra.h) are as follows:
<tt>
#define MK_nextCompatibleDSPPort 1
#define MK_hostSoundOut (1<<1)
#define MK_serialSoundOut (1<<2)
#define MK_soundIn (1<<3)
#define MK_soundfileOut (1<<4)
</tt> 
*/
- (unsigned) capabilities;

/*!
  @brief Returns the number of output channels.

  This information is normally derived from the serial port device,
  if any, or it defaults to 2. 
  However, subclasses may override this method.  For example, the
  ArielQPSat class, when sending its sound to the hub DSP, forwards
  this message to the ArielQP obect that represents the hub DSP.
  @return Returns an int.
*/
- (int) outputChannelCount;

/*!
  @brief When sending sound to the DSP serial port, the sound
  may need to be up-sampled if the current sampling rate is supported
  by the serial port device only as a "half sampling rate" @see
  DSPSerialPortDevice for more info).
 
  Subclasses may override this method. For example, the ArielQPSat
  class, when sending its sound to the hub DSP, forwards this message
  to the ArielQP obect that represents the hub DSP.
  @return Returns YES if we are upsampling the sound before sending it to its output location.
*/
- (BOOL) upSamplingOutput;

/*!
  @brief A subclass may implement this message.

  It is sent after boot and before sound out is started.
  The default implementation does nothing.
  @return Returns an id.
*/
- setUpDSP;

/*!
  @brief Returns YES.

  Subclass can override, if desired.  For example, the
  ArielQP class overrides this method to return NO.
  @return Returns a BOOL.
*/
- (BOOL) startSoundWhenOpening;

/*!
  @brief Used by subclasses to register themselves as the default class for
  the specified DSP index.

  This allows the user to say <b>[MKOrchestra orchestraOnDSP:3]</b> and get an
  instance of <b>ArielQPSat</b>, for example.
  @param  classObject is an id.
  @param  index is an int.
  @return Returns an id.
 */
+ registerOrchestraSubclass: (id) classObject forOrchIndex: (int) index;

- segmentInputSoundfile: (MKOrchMemSegment) segment;
- setInputSoundfile: (NSString *) file;
- (NSString *) inputSoundfile;
- pauseInputSoundfile;
- resumeInputSoundfile;

/*!
  @brief Drivers now refer to independently addressable sound ports which consist of 1 or more channels
  of sound.

  Returns those drivers returned by the SndKit.
  @return Returns an NSArray of driver names.
 */
+ (NSArray *) getDriverNames;

/*!
  @brief Returns the name of the sound driver associated with this instance of MKOrchestra.

  The string is copied.   
  @return Returns a NSString instance.
*/
- (NSString *) driverName;

/*!
  @brief &lt;&lt;Intel-based hardware only&gt;&gt; Returns the unit of the
  DSP driver associated with this instance of MKOrchestra.
  @return Returns an int.
*/
- (int) driverUnit;

- (int) driverSubUnit;

/*!
  @brief &lt;&lt;Intel-based hardware only&gt;&gt; Returns the parameter
  value of the specified driver parameter for the driver associated
  with the given index of MKOrchestra.

  The string is not copied and should not be freed.   
 @param  parameterName is a NSString.
 @param  index is an unsigned short.
 @return Returns an NSString.
 */
+ (NSString *) driverParameter: (NSString *) parameterName forOrchIndex: (unsigned short) index;

/*!
  @brief &lt;&lt;Intel-based hardware only&gt;&gt; Returns the parameter
  value of the specified driver parameter for the driver associated
  with this instance of MKOrchestra.

  The string is not copied and should not be freed.   
  @param  parameterName is an NSString.
  @return Returns an NSString.
*/
- (NSString *) driverParameter: (NSString *) parameterName;

- awaitEndOfTime: (double) endOfTime timeStamp: (DSPTimeStamp *) aTimeStampP;

- setSimulatorFile: (char *) filename;
- (char *) simulatorFile;

- sharedObjectFor: aKeyObj segment: (MKOrchMemSegment) whichSegment length: (int) length;
- sharedObjectFor: aKeyObj segment: (MKOrchMemSegment) whichSegment;

@end

@interface OrchestraDelegate : NSObject

-orchestra: (id) sender didRecordData: (short *) data size: (unsigned int) dataCount;

@end

#endif

About Koders | Resources | Downloads | Support | Black Duck | Submit Project | Terms of Service | DMCA | Privacy Policy | Site Map| Contact Us