~ubuntu-branches/ubuntu/oneiric/muse/oneiric

« back to all changes in this revision

Viewing changes to songfile.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2002-04-23 17:28:23 UTC
  • Revision ID: james.westby@ubuntu.com-20020423172823-w8yplzr81a759xa3
Tags: upstream-0.5.2
ImportĀ upstreamĀ versionĀ 0.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//=========================================================
 
2
//  MusE
 
3
//  Linux Music Editor
 
4
//  $Id: songfile.cpp,v 1.1 2002/01/30 14:10:07 muse Exp $
 
5
//
 
6
//  (C) Copyright 1999/2000 Werner Schweer (ws@seh.de)
 
7
//=========================================================
 
8
 
 
9
#include <assert.h>
 
10
#include <qmessagebox.h>
 
11
 
 
12
#include "app.h"
 
13
#include "song.h"
 
14
#include "seq.h"
 
15
#include "arranger.h"
 
16
#include "transport.h"
 
17
#include "cobject.h"
 
18
#include "drumedit.h"
 
19
#include "pianoroll.h"
 
20
#include "globals.h"
 
21
#include "xml.h"
 
22
#include "drummap.h"
 
23
#include "event.h"
 
24
#include "marker/marker.h"
 
25
#include "midiport.h"
 
26
#include "sf/sndfile.h"
 
27
#include "audiothread.h"
 
28
#include "mitplugin.h"
 
29
 
 
30
// midictrl.h:
 
31
extern void writeMidiController(int, Xml&);
 
32
extern void readMidiController(Xml&);
 
33
 
 
34
//---------------------------------------------------------
 
35
//   NKey::write
 
36
//---------------------------------------------------------
 
37
 
 
38
void NKey::write(int level, Xml& xml) const
 
39
      {
 
40
      xml.intTag(level, "key", val);
 
41
      }
 
42
 
 
43
//---------------------------------------------------------
 
44
//   NKey::read
 
45
//---------------------------------------------------------
 
46
 
 
47
void NKey::read(Xml& xml)
 
48
      {
 
49
      for (;;) {
 
50
            Xml::Token token = xml.parse();
 
51
            switch (token) {
 
52
                  case Xml::Error:
 
53
                  case Xml::End:
 
54
                        return;
 
55
                  case Xml::Text:
 
56
                        val = xml.s1().toInt();
 
57
                        break;
 
58
                  case Xml::TagEnd:
 
59
                        if (xml.s1() == "key")
 
60
                              return;
 
61
                  default:
 
62
                        break;
 
63
                  }
 
64
            }
 
65
      }
 
66
 
 
67
//---------------------------------------------------------
 
68
//   Scale::write
 
69
//---------------------------------------------------------
 
70
 
 
71
void Scale::write(int level, Xml& xml) const
 
72
      {
 
73
      xml.intTag(level, "scale", val);
 
74
      }
 
75
 
 
76
//---------------------------------------------------------
 
77
//   Scale::read
 
78
//---------------------------------------------------------
 
79
 
 
80
void Scale::read(Xml& xml)
 
81
      {
 
82
      for (;;) {
 
83
            Xml::Token token = xml.parse();
 
84
            switch (token) {
 
85
                  case Xml::Error:
 
86
                  case Xml::End:
 
87
                        return;
 
88
                  case Xml::Text:
 
89
                        val = xml.s1().toInt();
 
90
                        break;
 
91
                  case Xml::TagEnd:
 
92
                        if (xml.s1() == "scale")
 
93
                              return;
 
94
                  default:
 
95
                        break;
 
96
                  }
 
97
            }
 
98
      }
 
99
 
 
100
//---------------------------------------------------------
 
101
//   Part::write
 
102
//---------------------------------------------------------
 
103
 
 
104
void Part::write(int level, Xml& xml, int offset=0) const
 
105
      {
 
106
      xml.tag(level++, "part");
 
107
      xml.strTag(level, "name", _name);
 
108
 
 
109
      PosLen poslen(*this);
 
110
      poslen.setPosTick(posTick() + offset);
 
111
      poslen.write(level, xml, "poslen");
 
112
      xml.intTag(level, "selected", _selected);
 
113
      xml.intTag(level, "color", _colorIndex);
 
114
      xml.intTag(level, "mute", _mute);
 
115
      const EventList* el = cevents();
 
116
      for (ciEvent e = el->begin(); e != el->end(); ++e)
 
117
            e->second->write(level, xml, offset);
 
118
      xml.etag(level, "part");
 
119
      }
 
120
 
 
121
//---------------------------------------------------------
 
122
//   Part::read
 
123
//---------------------------------------------------------
 
124
 
 
125
void Part::read(Xml& xml, int offset=0)
 
126
      {
 
127
      for (;;) {
 
128
            Xml::Token token = xml.parse();
 
129
            const QString& tag = xml.s1();
 
130
            switch (token) {
 
131
                  case Xml::Error:
 
132
                  case Xml::End:
 
133
                        return;
 
134
                  case Xml::TagStart:
 
135
                        if (tag == "name")
 
136
                              _name = xml.parse1();
 
137
                        else if (tag == "poslen")
 
138
                              PosLen::read(xml, "poslen");
 
139
                        else if (tag == "pos") {
 
140
                              Pos pos;
 
141
                              pos.read(xml, "pos");  // obsolete
 
142
                              setPosTick(pos.posTick());
 
143
                              }
 
144
                        else if (tag == "len") {
 
145
                              Pos len;
 
146
                              len.read(xml, "len");  // obsolete
 
147
                              setLenTick(len.posTick());
 
148
                              }
 
149
                        else if (tag == "selected")
 
150
                              _selected = xml.parseInt();
 
151
                        else if (tag == "color")
 
152
                              _colorIndex = xml.parseInt();
 
153
                        else if (tag == "mute")
 
154
                              _mute = xml.parseInt();
 
155
                        else if (tag == "event") {
 
156
                              Event* e = newEvent();
 
157
                              e->setPort(track()->outPort());
 
158
                              e->setChannel(track()->outChannel());
 
159
                              e->read(xml);
 
160
                              e->move(offset);
 
161
                              _events->add(e);
 
162
                              }
 
163
                        else
 
164
                              xml.unknown("Part");
 
165
                        break;
 
166
                  case Xml::TagEnd:
 
167
                        if (tag == "part")
 
168
                              return;
 
169
                  default:
 
170
                        break;
 
171
                  }
 
172
            }
 
173
      }
 
174
 
 
175
//---------------------------------------------------------
 
176
//   Track::write
 
177
//---------------------------------------------------------
 
178
 
 
179
void Track::write(int level, Xml& xml) const
 
180
      {
 
181
      xml.tag(level++, "track type=\"%d\"", _type);
 
182
      xml.intTag(level, "channel", outChannel());
 
183
      xml.intTag(level, "device", outPort());
 
184
      xml.intTag(level, "inportMap", inPortMask());
 
185
      xml.intTag(level, "inchannelMap", inChannelMask());
 
186
      xml.strTag(level, "name", _name);
 
187
      if (!_comment.isEmpty())
 
188
            xml.strTag(level, "comment", _comment);
 
189
      xml.intTag(level, "locked", _locked);
 
190
      xml.intTag(level, "selected", _selected);
 
191
      xml.intTag(level, "record", _recordFlag);
 
192
      const PartList* pl = cparts();
 
193
      for (ciPart p = pl->begin(); p != pl->end(); ++p)
 
194
            p->second->write(level, xml);
 
195
      xml.etag(level, "track");
 
196
      }
 
197
 
 
198
//---------------------------------------------------------
 
199
//   Track::read
 
200
//---------------------------------------------------------
 
201
 
 
202
void Track::read(Xml& xml)
 
203
      {
 
204
      for (;;) {
 
205
            Xml::Token token = xml.parse();
 
206
            const QString& tag = xml.s1();
 
207
            switch (token) {
 
208
                  case Xml::Error:
 
209
                  case Xml::End:
 
210
                        return;
 
211
                  case Xml::TagStart:
 
212
                        if (tag == "name")
 
213
                              _name = xml.parse1();
 
214
                        else if (tag == "comment")
 
215
                              _comment = xml.parse1();
 
216
                        else if (tag == "selected")
 
217
                              _selected = xml.parseInt();
 
218
                        else if (tag == "locked")
 
219
                              _locked = xml.parseInt();
 
220
                        else if (tag == "part") {
 
221
                              Part* p = newPart();
 
222
                              p->read(xml);
 
223
//DEBUG
 
224
//PosLen *lp = p;
 
225
//printf("part %p:%p  %d len %d %d\n",
 
226
//     p, lp, p->posTick(), p->lenTick(), p->lenSample());
 
227
                              parts()->add(p);
 
228
                              }
 
229
                        else if (tag == "wavepart") {
 
230
                              WavePart* p = new WavePart((WaveTrack*)this);
 
231
                              p->read(xml);
 
232
                              parts()->add(p);
 
233
                              }
 
234
                        else if (tag == "channel")
 
235
                              setOutChannel(xml.parseInt());
 
236
                        else if (tag == "device")
 
237
                              setOutPort(xml.parseInt());
 
238
                        else if (tag == "inport")   // old
 
239
                              setInPortMask(1 << xml.parseInt());
 
240
                        else if (tag == "inchannel") // old
 
241
                              setInChannelMask(1 << xml.parseInt());
 
242
                        else if (tag == "inportMap")
 
243
                              setInPortMask(xml.parseInt());
 
244
                        else if (tag == "inchannelMap")
 
245
                              setInChannelMask(xml.parseInt());
 
246
                        else if (tag == "record")
 
247
                              setRecordFlag(xml.parseInt());
 
248
                        else
 
249
                              xml.unknown("Track");
 
250
                        break;
 
251
                  case Xml::Attribut:
 
252
                        if (tag == "type")
 
253
                              _type = TrackType(xml.s2().toInt());
 
254
                        break;
 
255
                  case Xml::TagEnd:
 
256
                        if (tag == "track")
 
257
                              return;
 
258
                  default:
 
259
                        break;
 
260
                  }
 
261
            }
 
262
      }
 
263
 
 
264
//---------------------------------------------------------
 
265
//   MidiTrack::write
 
266
//---------------------------------------------------------
 
267
 
 
268
void MidiTrack::write(int level, Xml& xml) const
 
269
      {
 
270
      xml.tag(level++, "miditrack");
 
271
      Track::write(level, xml);
 
272
 
 
273
      xml.tag(level++, "staff sys=0");
 
274
      key.write(level, xml);
 
275
      scale.write(level, xml);
 
276
      xml.tag(level--, "/staff");
 
277
 
 
278
      xml.tag(level++, "staff sys=1");
 
279
      keyL.write(level, xml);
 
280
      scaleL.write(level, xml);
 
281
      xml.tag(level--, "/staff");
 
282
 
 
283
      xml.intTag(level, "noteQuant", noteQuant);
 
284
      xml.intTag(level, "restQuant", restQuant);
 
285
      xml.intTag(level, "staffmode", int(mode));
 
286
      xml.intTag(level, "splitpoint", splitpoint);
 
287
      xml.intTag(level, "transposition", transposition);
 
288
      xml.intTag(level, "velocity", velocity);
 
289
      xml.intTag(level, "delay", delay);
 
290
      xml.intTag(level, "len", len);
 
291
      xml.intTag(level, "compression", compression);
 
292
      xml.intTag(level, "mute", mute());
 
293
      xml.intTag(level, "solomute", soloMute());
 
294
      xml.intTag(level, "midiThru", midiThruFlag());
 
295
 
 
296
      xml.tag(level, "/miditrack");
 
297
      }
 
298
 
 
299
//---------------------------------------------------------
 
300
//   readStaff
 
301
//---------------------------------------------------------
 
302
 
 
303
void MidiTrack::readStaff(Xml& xml)
 
304
      {
 
305
      int staff = 0;
 
306
      for (;;) {
 
307
            Xml::Token token = xml.parse();
 
308
            const QString& tag = xml.s1();
 
309
            switch (token) {
 
310
                  case Xml::Error:
 
311
                  case Xml::End:
 
312
                        return;
 
313
                  case Xml::TagStart:
 
314
                        if (tag == "key") {
 
315
                              if (staff == 0)
 
316
                                    key.read(xml);
 
317
                              else
 
318
                                    keyL.read(xml);
 
319
                              }
 
320
                        else if (tag == "scale") {
 
321
                              if (staff == 0)
 
322
                                    scale.read(xml);
 
323
                              else
 
324
                                    scaleL.read(xml);
 
325
                              }
 
326
                        else
 
327
                              xml.unknown("Staff");
 
328
                        break;
 
329
                  case Xml::Attribut:
 
330
                        if (tag == "sys")
 
331
                              staff = xml.s2().toInt();
 
332
                        break;
 
333
                  case Xml::TagEnd:
 
334
                        if (tag == "staff") {
 
335
                              return;
 
336
                              }
 
337
                  default:
 
338
                        break;
 
339
                  }
 
340
            }
 
341
      }
 
342
 
 
343
//---------------------------------------------------------
 
344
//   MidiTrack::read
 
345
//---------------------------------------------------------
 
346
 
 
347
void MidiTrack::read(Xml& xml)
 
348
      {
 
349
      for (;;) {
 
350
            Xml::Token token = xml.parse();
 
351
            const QString& tag = xml.s1();
 
352
            switch (token) {
 
353
                  case Xml::Error:
 
354
                  case Xml::End:
 
355
                        return;
 
356
                  case Xml::TagStart:
 
357
                        if (tag == "track")
 
358
                              Track::read(xml);
 
359
                        else if (tag == "noteQuant")
 
360
                              noteQuant = xml.parseInt();
 
361
                        else if (tag == "restQuant")
 
362
                              restQuant = xml.parseInt();
 
363
                        else if (tag == "splitpoint")
 
364
                              splitpoint = xml.parseInt();
 
365
                        else if (tag == "staffmode")
 
366
                              mode = StaffMode(xml.parseInt());
 
367
                        else if (tag == "transposition")
 
368
                              transposition = xml.parseInt();
 
369
                        else if (tag == "velocity")
 
370
                              velocity = xml.parseInt();
 
371
                        else if (tag == "delay")
 
372
                              delay = xml.parseInt();
 
373
                        else if (tag == "len")
 
374
                              len = xml.parseInt();
 
375
                        else if (tag == "compression")
 
376
                              compression = xml.parseInt();
 
377
                        else if (tag == "staff")
 
378
                              readStaff(xml);
 
379
                        else if (tag == "mute")
 
380
                              setMute(xml.parseInt());
 
381
                        else if (tag == "solomute")
 
382
                              setSolo(xml.parseInt());
 
383
                        else if (tag == "midiThru")
 
384
                              setMidiThruFlag(xml.parseInt());
 
385
                        else
 
386
                              xml.unknown("MidiTrack");
 
387
                        break;
 
388
                  case Xml::Attribut:
 
389
                        break;
 
390
                  case Xml::TagEnd:
 
391
                        if (tag == "miditrack") {
 
392
                              return;
 
393
                              }
 
394
                  default:
 
395
                        break;
 
396
                  }
 
397
            }
 
398
      }
 
399
 
 
400
void WaveTrack::write(int level, Xml& xml) const
 
401
      {
 
402
      xml.tag(level++, "wavetrack");
 
403
      Track::write(level, xml);
 
404
      AudioNode::writeConfiguration(level, xml);
 
405
      if (_recFile) {
 
406
            xml.tag(level++, "recfile");
 
407
            xml.strTag(level, "path",       _recFile->path());
 
408
            xml.intTag(level, "channels",   _recFile->channels());
 
409
            xml.intTag(level, "format",     _recFile->format());
 
410
            xml.intTag(level, "samplebits", _recFile->sampleBits());
 
411
            xml.etag(level--, "recfile");
 
412
            }
 
413
      xml.etag(level, "wavetrack");
 
414
      }
 
415
 
 
416
//---------------------------------------------------------
 
417
//   readRecfile
 
418
//---------------------------------------------------------
 
419
 
 
420
void WaveTrack::readRecfile(Xml& xml)
 
421
      {
 
422
      QString path;
 
423
      int channels   = 2;
 
424
      int format     = SF_FORMAT_WAV | SF_FORMAT_PCM;
 
425
      int samplebits = 16;
 
426
 
 
427
      for (;;) {
 
428
            Xml::Token token = xml.parse();
 
429
            if (token == Xml::Error || token == Xml::End)
 
430
                  break;
 
431
            const QString& tag = xml.s1();
 
432
            switch (token) {
 
433
                  case Xml::TagStart:
 
434
                        if (tag == "path")
 
435
                              path = xml.parse1();
 
436
                        else if (tag == "channels")
 
437
                              channels = xml.parseInt();
 
438
                        else if (tag == "format")
 
439
                              format = xml.parseInt();
 
440
                        else if (tag == "samplebits")
 
441
                              samplebits = xml.parseInt();
 
442
                        else
 
443
                              xml.unknown("recfile");
 
444
                        break;
 
445
                  case Xml::TagEnd:
 
446
                        if (tag == "recfile") {
 
447
                              SndFile* sf = new SndFile(path);
 
448
                              sf->setFormat(format, channels, sampleRate, samplebits);
 
449
                              if (sf->openWrite()) {
 
450
                                    printf("open wave file failed\n");
 
451
                                    delete sf;
 
452
                                    }
 
453
                              else {
 
454
                                    if (_recFile)
 
455
                                          delete _recFile;
 
456
                                    _recFile = sf;
 
457
                                    }
 
458
                              return;
 
459
                              }
 
460
                  default:
 
461
                        break;
 
462
                  }
 
463
            }
 
464
 
 
465
 
 
466
      }
 
467
 
 
468
//---------------------------------------------------------
 
469
//   read
 
470
//---------------------------------------------------------
 
471
 
 
472
void WaveTrack::read(Xml& xml)
 
473
      {
 
474
      for (;;) {
 
475
            Xml::Token token = xml.parse();
 
476
            const QString& tag = xml.s1();
 
477
            switch (token) {
 
478
                  case Xml::Error:
 
479
                  case Xml::End:
 
480
                        return;
 
481
                  case Xml::TagStart:
 
482
                        if (tag == "track")
 
483
                              Track::read(xml);
 
484
                        else if (tag == "audionode") {
 
485
                              AudioNode::readConfiguration(xml);
 
486
                              }
 
487
                        else if (tag == "recfile")
 
488
                              readRecfile(xml);
 
489
                        else
 
490
                              xml.unknown("WaveTrack");
 
491
                        break;
 
492
                  case Xml::Attribut:
 
493
                        break;
 
494
                  case Xml::TagEnd:
 
495
                        if (tag == "wavetrack") {
 
496
                              return;
 
497
                              }
 
498
                  default:
 
499
                        break;
 
500
                  }
 
501
            }
 
502
      }
 
503
 
 
504
//---------------------------------------------------------
 
505
//   writeFont
 
506
//---------------------------------------------------------
 
507
 
 
508
void Song::writeFont(int level, Xml& xml, const char* name,
 
509
   const Font& font) const
 
510
      {
 
511
      xml.nput(level, "<%s family=\"%s\" size=\"%d\"",
 
512
         name, font.family().latin1(), font.pointSize());
 
513
      if (font.weight() != QFont::Normal)
 
514
            xml.nput(" weight=\"%d\"", font.weight());
 
515
      if (font.italic())
 
516
            xml.nput(" italic=\"1\"");
 
517
      xml.nput(" />\n");
 
518
      }
 
519
 
 
520
//---------------------------------------------------------
 
521
//   write
 
522
//---------------------------------------------------------
 
523
 
 
524
void Song::write(int level, Xml& xml) const
 
525
      {
 
526
      xml.tag(level++, "song");
 
527
      if (!_name.isEmpty())
 
528
            xml.strTag(level, "name", _name);
 
529
      if (!_komponist1.isEmpty())
 
530
            xml.strTag(level, "komponist1", _komponist1);
 
531
      if (!_komponist2.isEmpty())
 
532
            xml.strTag(level, "komponist2", _komponist2);
 
533
 
 
534
      writeFont(level, xml, "name_font", _nameFont);
 
535
      writeFont(level, xml, "author_font", _komponistFont);
 
536
      writeFont(level, xml, "pageno_font", _pageNoFont);
 
537
      writeFont(level, xml, "measureno_font", _measureNoFont);
 
538
      writeFont(level, xml, "trackname_font", _tracknameFont);
 
539
      writeFont(level, xml, "lyrics_font", _lyricsFont);
 
540
 
 
541
      xml.intTag(level, "show_page_no", _showPageNo);
 
542
      xml.intTag(level, "show_measure_no", _showMeasureNo);
 
543
      xml.doubleTag(level, "paper_width", paperWidth);
 
544
      xml.doubleTag(level, "paper_height", paperHeight);
 
545
      xml.doubleTag(level, "top_margin", topMargin);
 
546
      xml.doubleTag(level, "bottom_margin", bottomMargin);
 
547
      xml.doubleTag(level, "left_margin", leftMargin);
 
548
      xml.doubleTag(level, "right_margin", rightMargin);
 
549
      xml.intTag(level, "bars_page", barsPage);
 
550
      xml.doubleTag(level, "print_scale", printScale);
 
551
 
 
552
      xml.intTag(level, "show_track_name", _showTrackname);
 
553
      xml.intTag(level, "master", _masterFlag);
 
554
      xml.intTag(level, "loop", loopFlag);
 
555
      xml.intTag(level, "punchin", punchinFlag);
 
556
      xml.intTag(level, "punchout", punchoutFlag);
 
557
      xml.intTag(level, "record", recordFlag);
 
558
      xml.intTag(level, "solo", soloFlag);
 
559
      xml.intTag(level, "type", _mtype);
 
560
      xml.intTag(level, "recmode", _recMode);
 
561
      xml.intTag(level, "cycle", _cycleMode);
 
562
      xml.intTag(level, "click", _click);
 
563
      xml.intTag(level, "quantize", _quantize);
 
564
      xml.intTag(level, "len", _len);
 
565
      xml.intTag(level, "follow", _follow);
 
566
 
 
567
      if (!_copyright.isEmpty())
 
568
            xml.strTag(level, "copyright", _copyright);
 
569
 
 
570
      for (ciTrack i = _tracks.begin(); i != _tracks.end(); ++i)
 
571
            (*i)->write(level, xml);
 
572
      tempomap.write(level, xml);
 
573
      sigmap.write(level, xml);
 
574
      _markerList->write(level, xml);
 
575
 
 
576
      xml.tag(level, "/song");
 
577
      }
 
578
 
 
579
//---------------------------------------------------------
 
580
//   readFont
 
581
//---------------------------------------------------------
 
582
 
 
583
Font Song::readFont(Xml& xml, const char* name)
 
584
      {
 
585
      Font f;
 
586
      for (;;) {
 
587
            Xml::Token token = xml.parse();
 
588
            switch (token) {
 
589
                  case Xml::Error:
 
590
                  case Xml::End:
 
591
                        return f;
 
592
                  case Xml::TagStart:
 
593
                        xml.unknown("readFont");
 
594
                        break;
 
595
                  case Xml::Attribut:
 
596
                        if (xml.s1() == "family")
 
597
                              f.setFamily(xml.s2());
 
598
                        else if (xml.s1() == "size")
 
599
                              f.setPointSize(xml.s2().toInt());
 
600
                        else if (xml.s1() == "weight")
 
601
                              f.setWeight(xml.s2().toInt());
 
602
                        else if (xml.s1() == "italic")
 
603
                              f.setItalic(xml.s2().toInt());
 
604
                        break;
 
605
                  case Xml::TagEnd:
 
606
                        if (xml.s1() == name)
 
607
                              return f;
 
608
                  default:
 
609
                        break;
 
610
                  }
 
611
            }
 
612
      return f;
 
613
      }
 
614
 
 
615
//---------------------------------------------------------
 
616
//   read
 
617
//---------------------------------------------------------
 
618
 
 
619
void Song::read(Xml& xml)
 
620
      {
 
621
      for (;;) {
 
622
            Xml::Token token;
 
623
            token = xml.parse();
 
624
            const QString& tag = xml.s1();
 
625
// printf("song <%s>\n", tag.latin1());
 
626
            switch (token) {
 
627
                  case Xml::Error:
 
628
                  case Xml::End:
 
629
                        return;
 
630
                  case Xml::TagStart:
 
631
                        if (tag == "name")
 
632
                              _name = xml.parse1();
 
633
                        else if (tag == "name_font")
 
634
                              _nameFont = readFont(xml, "name_font");
 
635
                        else if (tag == "author_font")
 
636
                              _komponistFont = readFont(xml, "author_font");
 
637
                        else if (tag == "pageno_font")
 
638
                              _pageNoFont = readFont(xml, "pageno_font");
 
639
                        else if (tag == "measureno_font")
 
640
                              _measureNoFont = readFont(xml, "measureno_font");
 
641
                        else if (tag == "trackname_font")
 
642
                              _tracknameFont = readFont(xml, "trackname_font");
 
643
                        else if (tag == "lyrics_font")
 
644
                              _lyricsFont = readFont(xml, "lyrics_font");
 
645
                        else if (tag == "komponist1")
 
646
                              _komponist1 = xml.parse1();
 
647
                        else if (tag == "komponist2")
 
648
                              _komponist2 = xml.parse1();
 
649
                        else if (tag == "show_page_no")
 
650
                              _showPageNo = xml.parseInt();
 
651
                        else if (tag == "show_measure_no")
 
652
                              _showMeasureNo  = xml.parseInt();
 
653
                        else if (tag == "show_track_name")
 
654
                              _showTrackname  = xml.parseInt();
 
655
                        else if (tag == "paper_width")
 
656
                              paperWidth  = xml.parseDouble();
 
657
                        else if (tag == "paper_height")
 
658
                              paperHeight  = xml.parseDouble();
 
659
                        else if (tag == "top_margin")
 
660
                              topMargin  = xml.parseDouble();
 
661
                        else if (tag == "bottom_margin")
 
662
                              bottomMargin  = xml.parseDouble();
 
663
                        else if (tag == "left_margin")
 
664
                              leftMargin  = xml.parseDouble();
 
665
                        else if (tag == "right_margin")
 
666
                              rightMargin  = xml.parseDouble();
 
667
                        else if (tag == "bars_page")
 
668
                              barsPage  = xml.parseInt();
 
669
                        else if (tag == "print_scale")
 
670
                              printScale  = xml.parseDouble();
 
671
                        else if (tag == "master")
 
672
                              setMasterFlag(xml.parseInt());
 
673
                        else if (tag == "loop")
 
674
                              setLoop(xml.parseInt());
 
675
                        else if (tag == "punchin")
 
676
                              setPunchin(xml.parseInt());
 
677
                        else if (tag == "punchout")
 
678
                              setPunchout(xml.parseInt());
 
679
                        else if (tag == "record")
 
680
                              setRecord(xml.parseInt());
 
681
                        else if (tag == "solo")
 
682
                              soloFlag = xml.parseInt();
 
683
                        else if (tag == "type")
 
684
                              _mtype  = MType(xml.parseInt());
 
685
                        else if (tag == "recmode")
 
686
                              _recMode  = xml.parseInt();
 
687
                        else if (tag == "cycle")
 
688
                              _cycleMode  = xml.parseInt();
 
689
                        else if (tag == "click")
 
690
                              setClick(xml.parseInt());
 
691
                        else if (tag == "quantize")
 
692
                              _quantize  = xml.parseInt();
 
693
                        else if (tag == "len")
 
694
                              _len  = xml.parseInt();
 
695
                        else if (tag == "follow")
 
696
                              _follow  = FollowMode(xml.parseInt());
 
697
                        else if (tag == "copyright")
 
698
                              _copyright  = xml.parse("copyright");
 
699
                        else if (tag == "tempolist") {
 
700
                              tempomap.read(xml);
 
701
                              }
 
702
                        else if (tag == "siglist")
 
703
                              sigmap.read(xml);
 
704
                        else if (tag == "miditrack") {
 
705
                              MidiTrack* track = new MidiTrack();
 
706
                              track->read(xml);
 
707
                              _tracks.add(track);
 
708
                              }
 
709
                        else if (tag == "wavetrack") {
 
710
                              WaveTrack* track = new WaveTrack();
 
711
                              track->read(xml);
 
712
                              _tracks.add(track);
 
713
 
 
714
                              // track is not yet connected:
 
715
                              AudioNode* route = track->route();
 
716
                              track->setRoute(0); // to avoid disconect errors
 
717
                              audioThread->msgAddRoute(track, route);
 
718
                              }
 
719
                        else if (tag == "marker")
 
720
                              readMarker(xml);
 
721
                        else
 
722
                              xml.unknown("Song");
 
723
                        break;
 
724
                  case Xml::Attribut:
 
725
                        break;
 
726
                  case Xml::TagEnd:
 
727
                        if (tag == "song") {
 
728
                              return;
 
729
                              }
 
730
                  default:
 
731
                        break;
 
732
                  }
 
733
            }
 
734
      dirty = false;
 
735
      }
 
736
 
 
737
//---------------------------------------------------------
 
738
//   readPart
 
739
//---------------------------------------------------------
 
740
 
 
741
Part* MusE::readPart(Xml& xml)
 
742
      {
 
743
      Part* part = 0;
 
744
      for (;;) {
 
745
            Xml::Token token = xml.parse();
 
746
            const QString& tag = xml.s1();
 
747
            switch (token) {
 
748
                  case Xml::Error:
 
749
                  case Xml::End:
 
750
                        return part;
 
751
                  case Xml::Text:
 
752
                        {
 
753
                        int trackIdx, partIdx;
 
754
                        sscanf(tag.latin1(), "%d:%d", &trackIdx, &partIdx);
 
755
                        Track* track = song->tracks()->findIdx(trackIdx);
 
756
                        if (track)
 
757
                              part = track->parts()->find(partIdx);
 
758
                        }
 
759
                        break;
 
760
                  case Xml::TagStart:
 
761
                        xml.unknown("readPart");
 
762
                        break;
 
763
                  case Xml::TagEnd:
 
764
                        if (tag == "part")
 
765
                              return part;
 
766
                  default:
 
767
                        break;
 
768
                  }
 
769
            }
 
770
      }
 
771
 
 
772
//---------------------------------------------------------
 
773
//   readToplevels
 
774
//---------------------------------------------------------
 
775
 
 
776
void MusE::readToplevels(Xml& xml)
 
777
      {
 
778
      PartList* pl = new PartList;
 
779
      for (;;) {
 
780
            Xml::Token token = xml.parse();
 
781
            const QString& tag = xml.s1();
 
782
            switch (token) {
 
783
                  case Xml::Error:
 
784
                  case Xml::End:
 
785
                        return;
 
786
                  case Xml::TagStart:
 
787
                        if (tag == "part") {
 
788
                              Part* part = readPart(xml);
 
789
                              if (part)
 
790
                                    pl->add(part);
 
791
                              }
 
792
                        else if (tag == "pianoroll") {
 
793
                              startPianoroll(pl);
 
794
                              toplevels.back().cobject()->readStatus(xml);
 
795
                              pl = new PartList;
 
796
                              }
 
797
                        else if (tag == "drumedit") {
 
798
                              startDrumEditor(pl);
 
799
                              toplevels.back().cobject()->readStatus(xml);
 
800
                              pl = new PartList;
 
801
                              }
 
802
                        else if (tag == "midimixer") {
 
803
                              startMidiMixer();
 
804
                              toplevels.back().cobject()->readStatus(xml);
 
805
                              }
 
806
                        else if (tag == "listeditor") {
 
807
                              startListEditor(pl);
 
808
                              toplevels.back().cobject()->readStatus(xml);
 
809
                              pl = new PartList;
 
810
                              }
 
811
                        else if (tag == "scoreeditor") {
 
812
                              startScoreEditor(pl);
 
813
                              toplevels.back().cobject()->readStatus(xml);
 
814
                              pl = new PartList;
 
815
                              }
 
816
                        else if (tag == "master") {
 
817
                              startMasterEditor();
 
818
                              toplevels.back().cobject()->readStatus(xml);
 
819
                              }
 
820
                        else if (tag == "lmaster") {
 
821
                              startLMasterEditor();
 
822
                              toplevels.back().cobject()->readStatus(xml);
 
823
                              }
 
824
                        else if (tag == "audiomixer") {
 
825
                              TopWin* tw = startAudioMixer();
 
826
                              tw->readStatus(xml);
 
827
                              }
 
828
                        else if (tag == "marker") {
 
829
                              startMarkerView();
 
830
                              toplevels.back().cobject()->readStatus(xml);
 
831
                              }
 
832
                        else if (tag == "waveedit") {
 
833
                              startWaveEditor(pl);
 
834
                              toplevels.back().cobject()->readStatus(xml);
 
835
                              pl = new PartList;
 
836
                              }
 
837
                        else if (tag == "cliplist") {
 
838
                              startClipList();
 
839
                              toplevels.back().cobject()->readStatus(xml);
 
840
                              }
 
841
                        else
 
842
                              xml.unknown("MusE");
 
843
                        break;
 
844
                  case Xml::Attribut:
 
845
                        break;
 
846
                  case Xml::TagEnd:
 
847
                        if (tag == "toplevels") {
 
848
                              delete pl;
 
849
                              return;
 
850
                              }
 
851
                  default:
 
852
                        break;
 
853
                  }
 
854
            }
 
855
      }
 
856
 
 
857
//---------------------------------------------------------
 
858
//   readCtrl
 
859
//---------------------------------------------------------
 
860
 
 
861
void MusE::readCtrl(Xml& xml, int prt, int channel)
 
862
      {
 
863
      ChannelState* iState = midiPorts[prt].iState(channel);
 
864
 
 
865
      int idx = 0;
 
866
      int val = -1;
 
867
 
 
868
      for (;;) {
 
869
            Xml::Token token = xml.parse();
 
870
            switch (token) {
 
871
                  case Xml::Error:
 
872
                  case Xml::End:
 
873
                        return;
 
874
                  case Xml::TagStart:
 
875
                        xml.unknown("readCtrl");
 
876
                        break;
 
877
                  case Xml::Attribut:
 
878
                        if (xml.s1() == "idx")
 
879
                              idx = xml.s2().toInt();
 
880
                        else if (xml.s1() == "val")
 
881
                              val = xml.s2().toInt();
 
882
                        break;
 
883
                  case Xml::TagEnd:
 
884
                        if (xml.s1() == "ctrl") {
 
885
                              iState->controller[idx] = val;
 
886
// printf("%d %d ctrl %d val %d\n", prt, channel, idx, val);
 
887
                              return;
 
888
                              }
 
889
                  default:
 
890
                        break;
 
891
                  }
 
892
            }
 
893
      }
 
894
 
 
895
//---------------------------------------------------------
 
896
//   readMidichannel
 
897
//---------------------------------------------------------
 
898
 
 
899
void MusE::readMidichannel(Xml& xml, int prt)
 
900
      {
 
901
      int channel = 0;
 
902
      MidiPort* port = &midiPorts[prt];
 
903
      ChannelState* iState = 0;
 
904
 
 
905
      for (;;) {
 
906
            Xml::Token token = xml.parse();
 
907
            const QString& tag = xml.s1();
 
908
            switch (token) {
 
909
                  case Xml::Error:
 
910
                  case Xml::End:
 
911
                        return;
 
912
                  case Xml::TagStart:
 
913
                        if (tag == "pitch")
 
914
                              iState->pitch = xml.parseInt();
 
915
                        else if (tag == "program") {
 
916
                              iState->program = xml.parseInt();
 
917
                              }
 
918
                        else if (tag == "ctrl")
 
919
                              readCtrl(xml, prt, channel);
 
920
                        else {
 
921
                              xml.unknown("readMidichannel");
 
922
                              }
 
923
                        break;
 
924
                  case Xml::Attribut:
 
925
                        if (tag == "ch") {
 
926
                              channel = xml.s2().toInt();
 
927
                              iState = port->iState(channel);
 
928
                              }
 
929
                        break;
 
930
                  case Xml::TagEnd:
 
931
                        if (tag == "midichannel")
 
932
                              return;
 
933
                  default:
 
934
                        break;
 
935
                  }
 
936
            }
 
937
      }
 
938
 
 
939
//---------------------------------------------------------
 
940
//   readMidiport
 
941
//---------------------------------------------------------
 
942
 
 
943
void MusE::readMidiport(Xml& xml)
 
944
      {
 
945
      int port = 0;
 
946
      for (;;) {
 
947
            Xml::Token token = xml.parse();
 
948
            const QString& tag = xml.s1();
 
949
            switch (token) {
 
950
                  case Xml::Error:
 
951
                  case Xml::End:
 
952
                        return;
 
953
                  case Xml::TagStart:
 
954
                        if (tag == "midichannel")
 
955
                              readMidichannel(xml, port);
 
956
                        else {
 
957
                              xml.unknown("readMidiport");
 
958
                              }
 
959
                        break;
 
960
                  case Xml::Attribut:
 
961
                        if (tag == "port") {
 
962
                              port = xml.s2().toInt();
 
963
                              }
 
964
                        break;
 
965
                  case Xml::TagEnd:
 
966
                        if (tag == "midiport") {
 
967
                              return;
 
968
                              }
 
969
                  default:
 
970
                        break;
 
971
                  }
 
972
            }
 
973
      }
 
974
 
 
975
//---------------------------------------------------------
 
976
//   write
 
977
//    write song
 
978
//---------------------------------------------------------
 
979
 
 
980
void MusE::write(Xml& xml) const
 
981
      {
 
982
      xml.header();
 
983
 
 
984
      int level = 0;
 
985
      xml.tag(level++, "muse version=\"1.0\"");
 
986
      writeConfiguration(level, xml);
 
987
 
 
988
      for (int i = 0; i < MIDI_PORTS; ++i) {
 
989
            MidiPort* port = &midiPorts[i];
 
990
            bool active = false;
 
991
            for (int k = 0; k < MIDI_CHANNELS; ++k) {
 
992
                  ChannelState* iState = port->iState(k);
 
993
                  if ((iState->pitch != -1) || (iState->program != -1))
 
994
                        active = true;
 
995
                  for (int l = 0; l < 128; ++l) {
 
996
                        if (iState->controller[l] != -1)
 
997
                              active = true;
 
998
                        }
 
999
                  }
 
1000
            if (!active)
 
1001
                  continue;
 
1002
 
 
1003
            xml.tag(level++, "midiport port=\"%d\"", i);
 
1004
 
 
1005
            for (int k = 0; k < MIDI_CHANNELS; ++k) {
 
1006
                  bool active = false;
 
1007
                  ChannelState* iState = port->iState(k);
 
1008
                  if ((iState->pitch != -1) || (iState->program != -1))
 
1009
                        active = true;
 
1010
                  for (int l = 0; l < 128; ++l) {
 
1011
                        if (iState->controller[l] != -1)
 
1012
                              active = true;
 
1013
                        }
 
1014
                  if (!active)
 
1015
                        continue;
 
1016
 
 
1017
                  xml.tag(level++, "midichannel ch=\"%d\"", k);
 
1018
                  if (iState->pitch != -1)
 
1019
                        xml.intTag(level, "pitch", iState->pitch);
 
1020
                  if (iState->program != -1)
 
1021
                        xml.intTag(level, "program", iState->program);
 
1022
                  for (int l = 0; l < 128; ++l) {
 
1023
                        if (iState->controller[l] != -1)
 
1024
                              xml.tag(level, "ctrl idx=\"%d\" val=\"%d\" /", l,
 
1025
                                 iState->controller[l]);
 
1026
                        }
 
1027
                  xml.etag(level--, "midichannel");
 
1028
                  }
 
1029
            xml.etag(level--, "midiport");
 
1030
            }
 
1031
 
 
1032
      waveClips->write(level, xml);
 
1033
      writeMidiController(level, xml);
 
1034
      writeStatusMidiInputTransformPlugins(level, xml);
 
1035
 
 
1036
      song->write(level, xml);
 
1037
 
 
1038
      xml.intTag(level, "cpos", song->cpos());
 
1039
      xml.intTag(level, "rpos", song->rpos());
 
1040
      xml.intTag(level, "lpos", song->lpos());
 
1041
 
 
1042
      if (!toplevels.empty()) {
 
1043
            xml.tag(level++, "toplevels");
 
1044
            for (ciToplevel i = toplevels.begin(); i != toplevels.end(); ++i) {
 
1045
                  if (i->cobject()->isVisible())
 
1046
                        i->cobject()->writeStatus(level, xml);
 
1047
                  }
 
1048
            xml.tag(level--, "/toplevels");
 
1049
            }
 
1050
      writeDrumMap(level, xml, false);
 
1051
      xml.tag(level, "/muse");
 
1052
      }
 
1053
 
 
1054
//---------------------------------------------------------
 
1055
//   readMarker
 
1056
//---------------------------------------------------------
 
1057
 
 
1058
void Song::readMarker(Xml& xml)
 
1059
      {
 
1060
      Marker m;
 
1061
      m.read(xml);
 
1062
      _markerList->add(m);
 
1063
      }
 
1064
 
 
1065
//---------------------------------------------------------
 
1066
//   read
 
1067
//    read song
 
1068
//---------------------------------------------------------
 
1069
 
 
1070
void MusE::read(Xml& xml)
 
1071
      {
 
1072
      bool skipmode = true;
 
1073
      int pos;
 
1074
 
 
1075
      for (;;) {
 
1076
            Xml::Token token = xml.parse();
 
1077
            const QString& tag = xml.s1();
 
1078
            switch (token) {
 
1079
                  case Xml::Error:
 
1080
                  case Xml::End:
 
1081
                        return;
 
1082
                  case Xml::TagStart:
 
1083
                        if (skipmode && tag == "muse")
 
1084
                              skipmode = false;
 
1085
                        else if (skipmode)
 
1086
                              break;
 
1087
                        else if (tag == "configuration")
 
1088
                              readConfiguration(xml);
 
1089
                        else if (tag == "song")
 
1090
                              song->read(xml);
 
1091
                        else if (tag == "cpos") {
 
1092
                              pos = xml.parseInt();
 
1093
                              song->setPos(Song::CPOS, pos, true, true, true);
 
1094
                              }
 
1095
                        else if (tag == "lpos") {
 
1096
                              pos = xml.parseInt();
 
1097
                              song->setPos(Song::LPOS, pos, true, true, true);
 
1098
                              }
 
1099
                        else if (tag == "rpos") {
 
1100
                              pos = xml.parseInt();
 
1101
                              song->setPos(Song::RPOS, pos, true, true, true);
 
1102
                              }
 
1103
                        else if (tag == "midiport")
 
1104
                              readMidiport(xml);
 
1105
                        else if (tag == "toplevels")
 
1106
                              readToplevels(xml);
 
1107
                        else if (tag == "drummap")
 
1108
                              readDrumMap(xml, false);
 
1109
                        else if (tag == "clip") {
 
1110
                              Clip* clip = new Clip();
 
1111
                              clip->read(xml);
 
1112
                              }
 
1113
                        else if (tag == "mctrl")
 
1114
                              readMidiController(xml);
 
1115
                        else if (tag == "mplugin")
 
1116
                              readStatusMidiInputTransformPlugin(xml);
 
1117
                        else
 
1118
                              xml.unknown("muse");
 
1119
                        break;
 
1120
                  case Xml::Attribut:
 
1121
                        break;
 
1122
                  case Xml::TagEnd:
 
1123
                        if (!skipmode && tag == "muse")
 
1124
                              return;
 
1125
                  default:
 
1126
                        break;
 
1127
                  }
 
1128
            }
 
1129
      initDrumMap();
 
1130
      }