1
//=========================================================
4
// $Id: seq.cpp,v 1.4 2002/02/27 15:53:45 muse Exp $
6
// (C) Copyright 1999/2000 Werner Schweer (ws@seh.de)
7
//=========================================================
13
#include <sys/ioctl.h>
14
#include <sys/types.h>
29
#include "plugins/plugin.h"
32
#include "audioport.h"
33
#include "driver/mididev.h"
34
#include "driver/audiodev.h"
36
#include "minstrument.h"
38
#include "sf/sndfile.h"
39
#include "driver/alsamidi.h"
41
#include "audiothread.h"
42
#include "audioprefetch.h"
43
#include "midithread.h"
45
//---------------------------------------------------------
47
//---------------------------------------------------------
49
Sequencer::Sequencer()
51
if (realTimePriority < sched_get_priority_min(SCHED_RR))
52
realTimePriority = sched_get_priority_min(SCHED_RR);
53
else if (realTimePriority > sched_get_priority_max(SCHED_RR))
54
realTimePriority = sched_get_priority_max(SCHED_RR);
56
midiThread = new MidiThread(realTimeScheduling,
57
realTimePriority, lockMemory);
58
audioThread = new AudioThread(realTimeScheduling,
59
realTimePriority/3, lockMemory);
60
audioPrefetch = new AudioPrefetch(realTimeScheduling,
61
realTimePriority/4, lockMemory);
64
//---------------------------------------------------------
66
//---------------------------------------------------------
68
void Sequencer::startThread()
72
audioPrefetch->start();
77
//---------------------------------------------------------
79
//---------------------------------------------------------
81
void Sequencer::stopThread()
85
audioPrefetch->stop();
90
//---------------------------------------------------------
92
//---------------------------------------------------------
94
Sequencer::~Sequencer()
101
//---------------------------------------------------------
102
// writeConfiguration
103
//---------------------------------------------------------
105
void Sequencer::writeConfiguration(int level, Xml& xml)
107
xml.tag(level++, "sequencer");
109
xml.tag(level++, "metronom");
110
xml.intTag(level, "premeasures", preMeasures);
111
xml.intTag(level, "measurepitch", measureClickNote);
112
xml.intTag(level, "measurevelo", measureClickVelo);
113
xml.intTag(level, "beatpitch", beatClickNote);
114
xml.intTag(level, "beatvelo", beatClickVelo);
115
xml.intTag(level, "channel", clickChan);
116
xml.intTag(level, "port", clickPort);
118
xml.intTag(level, "precountEnable", precountEnableFlag);
119
xml.intTag(level, "fromMastertrack", precountFromMastertrackFlag);
120
xml.intTag(level, "signatureZ", precountSigZ);
121
xml.intTag(level, "signatureN", precountSigN);
122
xml.intTag(level, "prerecord", precountPrerecord);
123
xml.intTag(level, "preroll", precountPreroll);
124
xml.intTag(level, "midiClickEnable", midiClickFlag);
125
xml.intTag(level, "audioClickEnable", audioClickFlag);
126
xml.tag(level--, "/metronom");
128
xml.intTag(level, "rcEnable", rcEnable);
129
xml.intTag(level, "rcStop", rcStopNote);
130
xml.intTag(level, "rcRecord", rcRecordNote);
131
xml.intTag(level, "rcGotoLeft", rcGotoLeftMarkNote);
132
xml.intTag(level, "rcPlay", rcPlayNote);
134
SndFile* master = audioThread->masterMix();
136
SndFile* master = audioThread->masterMix();
137
xml.tag(level++, "mixdown");
138
xml.intTag(level, "record", audioThread->mixdownRecord());
139
xml.strTag(level, "path", master->path().latin1());
140
xml.intTag(level, "channels", master->channels());
141
xml.intTag(level, "format", master->format());
142
xml.intTag(level, "samplebits", master->sampleBits());
143
xml.etag(level--, "mixdown");
146
for (int i = 0; i < MIDI_PORTS; ++i) {
147
MidiPort* mport = &midiPorts[i];
148
MidiDevice* dev = mport->device();
150
xml.tag(level++, "midiport idx=\"%d\"", i);
151
xml.strTag(level, "instrument", mport->instrument()->iname());
152
xml.strTag(level, "name", dev->name());
153
xml.intTag(level, "record", dev->rwFlags() & 0x2 ? 1 : 0);
154
xml.etag(level--, "midiport");
157
AudioPort* port = &audioPort;
158
AudioDevice* dev = port->device();
160
xml.tag(level++, "audioport idx=\"%d\"", 0);
161
xml.strTag(level, "name", dev->name().latin1());
162
xml.intTag(level, "record", port->rwFlags() & 0x2 ? 1 : 0);
163
xml.intTag(level, "play", port->rwFlags() & 0x1);
165
port->writeConfiguration(level, xml);
166
xml.tag(level--, "/audioport");
169
for (int i = 0; i < AUDIO_GROUPS; ++i) {
170
xml.tag(level++, "audiogroup idx=\"%d\"", i);
171
song->group(i)->writeConfiguration(level, xml);
172
xml.tag(level--, "/audiogroup");
175
xml.tag(level++, "audiomaster");
176
song->master()->writeConfiguration(level, xml);
177
xml.tag(level--, "/audiomaster");
179
xml.tag(level, "/sequencer");
182
//---------------------------------------------------------
183
// loadConfigMetronom
184
//---------------------------------------------------------
186
void Sequencer::loadConfigMetronom(Xml& xml)
189
Xml::Token token = xml.parse();
190
if (token == Xml::Error || token == Xml::End)
192
QString tag = xml.s1();
195
if (tag == "premeasures")
196
preMeasures = xml.parseInt();
197
else if (tag == "measurepitch")
198
measureClickNote = xml.parseInt();
199
else if (tag == "measurevelo")
200
measureClickVelo = xml.parseInt();
201
else if (tag == "beatpitch")
202
beatClickNote = xml.parseInt();
203
else if (tag == "beatvelo")
204
beatClickVelo = xml.parseInt();
205
else if (tag == "channel")
206
clickChan = xml.parseInt();
207
else if (tag == "port")
208
clickPort = xml.parseInt();
209
else if (tag == "precountEnable")
210
precountEnableFlag = xml.parseInt();
211
else if (tag == "fromMastertrack")
212
precountFromMastertrackFlag = xml.parseInt();
213
else if (tag == "signatureZ")
214
precountSigZ = xml.parseInt();
215
else if (tag == "signatureN")
216
precountSigN = xml.parseInt();
217
else if (tag == "prerecord")
218
precountPrerecord = xml.parseInt();
219
else if (tag == "preroll")
220
precountPreroll = xml.parseInt();
221
else if (tag == "midiClickEnable")
222
midiClickFlag = xml.parseInt();
223
else if (tag == "audioClickEnable")
224
audioClickFlag = xml.parseInt();
226
xml.unknown("Metronome");
229
if (tag == "metronom")
237
//---------------------------------------------------------
239
//---------------------------------------------------------
241
void Sequencer::readConfiguration(Xml& xml)
244
Xml::Token token = xml.parse();
245
if (token == Xml::Error || token == Xml::End)
247
const QString& tag = xml.s1();
250
if (tag == "metronom")
251
loadConfigMetronom(xml);
252
else if (tag == "midiport")
253
readConfigMidiPort(xml);
254
else if (tag == "audioport")
255
readConfigAudioPort(xml);
256
else if (tag == "audiogroup")
257
readConfigAudioGroup(xml);
258
else if (tag == "audiomaster")
259
readConfigAudioMaster(xml);
260
else if (tag == "rcStop")
261
rcStopNote = xml.parseInt();
262
else if (tag == "rcEnable")
263
rcEnable = xml.parseInt();
264
else if (tag == "rcRecord")
265
rcRecordNote = xml.parseInt();
266
else if (tag == "rcGotoLeft")
267
rcGotoLeftMarkNote = xml.parseInt();
268
else if (tag == "rcPlay")
269
rcPlayNote = xml.parseInt();
270
else if (tag == "mixdown")
276
if (tag == "sequencer") {
285
//---------------------------------------------------------
287
//---------------------------------------------------------
289
void Sequencer::readMixdown(Xml& xml)
293
int format = SF_FORMAT_WAV | SF_FORMAT_PCM;
297
Xml::Token token = xml.parse();
298
if (token == Xml::Error || token == Xml::End)
300
const QString& tag = xml.s1();
305
else if (tag == "channels")
306
channels = xml.parseInt();
307
else if (tag == "format")
308
format = xml.parseInt();
309
else if (tag == "samplebits")
310
samplebits = xml.parseInt();
311
else if (tag == "record") {
312
bool record = xml.parseInt();
314
audioThread->msgOpenMixdownRecord();
317
xml.unknown("mixdown");
320
if (tag == "mixdown") {
321
SndFile* sf = new SndFile(path);
322
sf->setFormat(format, channels, sampleRate, samplebits);
323
audioThread->msgSetMixdownFile(sf);
332
//---------------------------------------------------------
333
// readConfigMidiPort
334
//---------------------------------------------------------
336
void Sequencer::readConfigMidiPort(Xml& xml)
341
bool recFlag = false;
342
bool thruFlag = false;
345
Xml::Token token = xml.parse();
346
if (token == Xml::Error || token == Xml::End)
348
QString tag = xml.s1();
352
device = xml.parse1();
353
else if (tag == "record")
354
recFlag = xml.parseInt();
355
else if (tag == "instrument")
356
instrument = xml.parse1();
357
else if (tag == "midithru")
358
thruFlag = xml.parseInt(); // obsolete
360
xml.unknown("MidiDevice");
364
idx = xml.s2().toInt();
368
if (tag == "midiport") {
369
if (idx > MIDI_PORTS) {
370
fprintf(stderr, "bad midi port %d (>%d)\n",
374
MidiDevice* dev = midiDevices.find(device);
375
MidiPort* mp = &midiPorts[idx];
377
mp->setrwFlags(recFlag ? 3 : 1);
378
midiThread->setMidiDevice(mp, dev);
380
midiPorts[idx].setInstrument(
381
registerMidiInstrument(instrument)
391
//---------------------------------------------------------
392
// readConfigAudioPort
393
//---------------------------------------------------------
395
void Sequencer::readConfigAudioPort(Xml& xml)
404
Xml::Token token = xml.parse();
405
if (token == Xml::Error || token == Xml::End)
407
QString tag = xml.s1();
411
device = xml.parse1();
412
else if (tag == "record")
413
rwFlags |= xml.parseInt() ? 2 : 0;
414
else if (tag == "play")
415
rwFlags |= xml.parseInt() ? 1 : 0;
416
else if (tag == "audionode")
417
port->readConfiguration(xml);
419
xml.unknown("AudioDevice");
423
idx = xml.s2().toInt();
429
if (tag == "audioport") {
430
if (!device.isEmpty()) {
431
dev = audioDevices.find(device);
433
port->setrwFlags(rwFlags);
434
audioThread->msgSetAudioDevice(port, dev);
436
audioThread->msgAddRoute(port, port->route());
446
//---------------------------------------------------------
447
// readConfigAudioGroup
448
//---------------------------------------------------------
450
void Sequencer::readConfigAudioGroup(Xml& xml)
452
AudioMixer* mixer = 0;
454
Xml::Token token = xml.parse();
455
if (token == Xml::Error || token == Xml::End)
457
QString tag = xml.s1();
460
if (tag == "audionode")
461
mixer->readConfiguration(xml);
463
xml.unknown("AudioGroup");
467
int idx = xml.s2().toInt();
468
if (idx > AUDIO_GROUPS) {
469
fprintf(stderr, "bad audio group %d (>%d)\n",
473
mixer = song->group(idx);
477
if (tag == "audiogroup") {
478
audioThread->msgAddRoute(mixer, mixer->route());
487
//---------------------------------------------------------
488
// readConfigAudioMaster
489
//---------------------------------------------------------
491
void Sequencer::readConfigAudioMaster(Xml& xml)
493
AudioMixer* mixer = song->master();
495
Xml::Token token = xml.parse();
496
if (token == Xml::Error || token == Xml::End)
498
QString tag = xml.s1();
501
if (tag == "audionode")
502
mixer->readConfiguration(xml);
504
xml.unknown("AudioMaster");
507
if (tag == "audiomaster") {
508
// song->msgAddRoute(*mixer, mixer->route());
509
// mixer.setRoute(audioPort); // override settings