HelpBrowser: path box becomes a more conventional search box
[supercollider.git] / SCClassLibrary / Common / Control / Score.sc
blobbe1009f4689060c2b93df16ab440f28ea96ab894
1 Score {
2         var <>score, routine, isPlaying = false;
3         classvar <>program, <>options;
5         *initClass {
6                 program = Platform.case(\windows, {".\\scsynth.exe"}, {"./scsynth"});
7                 options = ServerOptions.new;
8         }
10         *new { arg list;
11                 ^super.new.init(list);
12         }
14         *newFromFile { arg path;
15                 var list;
16                 list = thisProcess.interpreter.executeFile(path);
17                 ^super.new.init(list);
18         }
20         init { arg list;
21                 score = [[0.0, ["/g_new", 1]]] ++ list;
22                 this.sort;
23         }
25         add { arg bundle;
26                 score = score.add(bundle)
27         }
29         *playFromFile { arg path, server;
30                 var list;
31                 list = thisProcess.interpreter.executeFile(path);
32                 ^this.new(list).play(server);
33         }
35         *play { arg list, server;
36                 ^this.new(list).play(server);
37         }
38         sort {
39                 score = score.sort({ arg a, b; b[0] >= a[0] });
40         }
41         play { arg server, clock, quant=0.0;
42                 var size, osccmd, timekeep, inserver, rout;
43                 isPlaying.not.if({
44                         inserver = server ? Server.default;
45                         size = score.size;
46                         timekeep = 0;
47                         routine = Routine({
48                                 size.do { |i|
49                                         var deltatime, msg;
50                                         osccmd = score[i];
51                                         deltatime = osccmd[0];
52                                         msg = osccmd.copyToEnd(1);
53                                         (deltatime-timekeep).wait;
54                                         inserver.listSendBundle(inserver.latency, msg);
55                                         timekeep = deltatime;
56                                 };
57                                 isPlaying = false;
58                         });
59                         isPlaying = true;
60                         routine.play(clock, quant);
61                 }, {"Score already playing".warn;}
62                 );
63         }
65         endTime { ^score.last[0] }
66         startTime { ^score.first[0] }
68         section { arg start = 0, end, configevents;
69                 var sectionlist;
70                 if(end.isNil) { end =  this.endTime };
71                 sectionlist = Array.new;
72                 score.do { arg item;
73                         if(item[0].inclusivelyBetween(start, end)) {
74                         item = item.copy;
75                         item[0] = item[0] - start;
76                         sectionlist = sectionlist.add(item);
77                         }
78                 };
79                 sectionlist = sectionlist.add([end - start, [0]]); // add dummy command (cmd_none)
80                 if(configevents.notNil,
81                         {if(configevents.isArray,
82                                 {if(configevents[0] == 0.0,
83                                         {sectionlist = sectionlist.addFirst(configevents)},
84                                         {"Configuration events should have a timestamp of 0.0".warn; ^nil})},
85                                 {"Configuration events need to be a bundle array: [time, [events]]".warn;
86                                         ^nil})});
87                 ^this.class.new(sectionlist);
88         }
90         writeOSCFile { arg path, from, to, clock;
91                 if(to.notNil or: {from.notNil}) {
92                         from = from ? 0.0;
93                         to = to ? this.endTime;
94                         this.section(from, to).write(path, clock)
95                 } {
96                         this.write(path, clock)
97                 };
98         }
100         recordNRT { arg oscFilePath, outputFilePath, inputFilePath, sampleRate = 44100, headerFormat =
101                 "AIFF", sampleFormat = "int16", options, completionString="", duration = nil, action = nil;
102                 this.writeOSCFile(oscFilePath, 0, duration);
103                 unixCmd(program + " -N" + oscFilePath.quote
104                         + if(inputFilePath.notNil, { inputFilePath.quote }, { "_" })
105                         + outputFilePath.quote
106                         + sampleRate + headerFormat + sampleFormat +
107                         (options ? Score.options).asOptionsString
108                         + completionString, action);
109         }
111         *recordNRT { arg list, oscFilePath, outputFilePath, inputFilePath, sampleRate = 44100,
112                 headerFormat = "AIFF", sampleFormat = "int16", options, completionString="", duration = nil, action = nil;
113                 this.new(list).recordNRT(oscFilePath, outputFilePath, inputFilePath, sampleRate,
114                 headerFormat, sampleFormat, options, completionString, duration, action);
115         }
118         stop {
119                 isPlaying.if({routine.stop; isPlaying = false; routine = nil;}, {"Score not playing".warn;}
120                 );
121         }
123         *writeFromFile { arg path, oscFilePath, clock;
124                 var list;
125                 list = thisProcess.interpreter.executeFile(path);
126                 this.write(list, oscFilePath, clock);
127         }
129         *write { arg list, oscFilePath, clock;
130                 var osccmd, f, tempoFactor;
131                 f = File(oscFilePath, "w");
132                 tempoFactor = (clock ? TempoClock.default).tempo.reciprocal;
133                 protect {
134                         list.size.do { |i|
135                                 var msg = list[i].copy;
136                                 msg[0] = msg[0]* tempoFactor;
137                                 osccmd = msg.asRawOSC;
138                                 f.write(osccmd.size).write(osccmd);
139                         };
140                 }{
141                         f.close;
142                 };
143                 //"done".postln;
144         }
146         write { arg oscFilePath, clock;
147                 this.class.write(score, oscFilePath, clock);
148         }
150         saveToFile { arg path;
151                 var f;
152                 f = File.new(path, "w");
153                 f.putString("[ // SuperCollider Score output " ++ Date.getDate ++ "\n");
154                 score.do{ arg me;
155                         f.putString((me).asCompileString ++ ",\n");
156                 };
157                 f.putString("]");
158                 f.close;
159         }
161         storeArgs {
162                 ^score
163         }
165         asScore {}