~ubuntu-branches/ubuntu/breezy/muse/breezy

« back to all changes in this revision

Viewing changes to midi.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2004-02-07 15:18:22 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040207151822-es27xxkzbcxkebjm
Tags: 0.6.3-1
* New upstream version.
* Added patches:
  + [10_alsa_init_fix] New, from upstream CVS.
    Initialize direction variable when setting Alsa parameters.
  + [10_canvas_translation_fix] New, from upstream CVS.
    Do not translate tooltips twice in canvas popup.
  + [10_checkbox_fix] New, from upstream CVS.
    Use proper set/test methods on metronome checkboxes.
  + [10_html_doc_cleanup] New.
    Fix links and HTML errors in documentation.
  + [20_allow_system_timer] New.
    The new upstream version fails by default if the real-time clock
    could not be accessed (usually the case when not running suid-root).
    This patch reverts the old behaviour of falling back to the more
    inaccurate system timer.
* Updated patches:
  + [11_PIC_fixes_fixup] Rediffed.
* Removed patches:
  + [20_no_atomic_asm] Merged upstream.
* debian/compat: Splice out debhelper compatibility level from rules file.
* debian/control: Build-depend on latest jack release by default.
  Closes: #228788
* debian/control: Bump standards version.
* debian/control: Use auto-generated debconf dependency via misc:Depends.
* debian/control: Minor tweaks to the long description.
* debian/control: Tighten fluidsynth build dependency to sane version.
* debian/muse.doc-base: New. Register HTML documentation with doc-base.
* debian/templates: Tiny rewording, and typo fix.
* debian/templates, debian/po/*: Switch to po-debconf for translations.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
//=========================================================
2
2
//  MusE
3
3
//  Linux Music Editor
4
 
//  $Id: midi.cpp,v 1.2 2002/02/05 14:15:56 muse Exp $
 
4
//  $Id: midi.cpp,v 1.3 2003/11/19 17:59:21 wschweer Exp $
5
5
//
6
6
//  (C) Copyright 1999/2000 Werner Schweer (ws@seh.de)
7
7
//=========================================================
8
8
 
9
9
#include <errno.h>
10
10
#include <values.h>
 
11
#include <assert.h>
11
12
 
12
13
#include "song.h"
13
14
#include "midi.h"
290
291
//   writeEvent
291
292
//---------------------------------------------------------
292
293
 
293
 
void MidiFile::writeEvent(MidiEvent* event)
 
294
void MidiFile::writeEvent(int channel, MidiEvent* event)
294
295
      {
295
 
      int c     = event->channel();
 
296
      int c = channel;
296
297
      int nstat = 0;
297
298
 
298
299
      switch (event->type()) {
448
449
                              // 3 - DRUM 2
449
450
                              // 4 - DRUM 3
450
451
                              // 5 - DRUM 4
451
 
                              printf("xg part mode channel %d to %d\n", buf[4], buf[6]);
 
452
                              printf("xg set part mode channel %d to %d\n", buf[4]+1, buf[6]);
452
453
                              if (buf[6] != 0)
453
454
                                    track->setType(Track::DRUM);
454
455
                              }
527
528
                  return true;
528
529
            if (lastchan == -1) {
529
530
                  el->add(event);         // kann kein channel event sein
530
 
                  event->setPort(track->outPort());
531
 
                  event->setChannel(track->outChannel());
532
531
                  continue;
533
532
                  }
534
533
            if (port == -1) {
560
559
                  if (port != track->outPort())
561
560
                        printf("2 HALOOOO %d %d\n", port, track->outPort());
562
561
                  el->add(event);
563
 
                  event->setPort(track->outPort());
564
 
                  event->setChannel(track->outChannel());
565
562
                  continue;
566
563
                  }
567
564
            if (lastchan != channel) {
579
576
                                    continue;
580
577
                              if (mtrack->outChannel() == lastchan) {
581
578
                                    mtrack->events()->add(event);
582
 
                                    event->setPort(mtrack->outPort());
583
 
                                    event->setChannel(mtrack->outChannel());
584
579
                                    break;
585
580
                                    }
586
581
                              }
614
609
                        el = track->events();
615
610
                        }
616
611
                  }
617
 
            event->setPort(track->outPort());
618
 
            event->setChannel(track->outChannel());
619
612
            el->add(event);
620
613
            }
621
614
      int end = curPos;
717
710
                  if (read(buffer, len)) {
718
711
                        printf("readEvent: error 4\n");
719
712
                        delete event;
720
 
                        delete buffer;
 
713
                        delete[] buffer;
721
714
                        return (MidiEvent*)-2;
722
715
                        }
723
716
                  if (buffer[len-1] != 0xf7) {
728
721
                        --len;      // don't count 0xf7
729
722
                  if (checkSysex(track, len, buffer)) {
730
723
                        event->setType(MidiEvent::Sysex);
731
 
                        event->setDataLen(len);
732
 
                        event->setData(buffer);
 
724
                        EvData* ed = new EvData(buffer, len);
 
725
                        ed->refCount = 1;
 
726
                        event->setEvData(ed);
733
727
                        }
734
728
                  else {
735
 
                        delete buffer;
 
729
                        delete[] buffer;
736
730
                        delete event;
737
731
                        return (MidiEvent*)-1;
738
732
                        }
755
749
                        if (read(buffer, len)) {
756
750
                              printf("readEvent: error 7\n");
757
751
                              delete event;
758
 
                              delete buffer;
 
752
                              delete[] buffer;
759
753
                              return (MidiEvent*)-2;
760
754
                              }
761
755
                        }
762
756
                  buffer[len] = 0;
763
757
                  if (type == 0x2f) {           // End of Track
764
758
                        delete event;
765
 
                        delete buffer;
 
759
                        delete[] buffer;
766
760
                        return 0;
767
761
                        }
768
762
                  switch (type) {
769
763
                        case 0x03:        // Sequence-/TrackName
770
764
                              {
771
765
                              QString s((char*)buffer);
772
 
                              track->setTName(s);
773
 
                              delete buffer;
 
766
                              track->setName(s);
 
767
                              delete[] buffer;
774
768
                              delete event;
775
769
                              }
776
770
                              return (MidiEvent*)-1;  // DEBUG: eigentlich n�chsten Event lesen
778
772
                              {
779
773
                              QString s((char*)buffer);
780
774
                              track->setComment(s);
781
 
                              delete buffer;
 
775
                              delete[] buffer;
782
776
                              delete event;
783
777
                              }
784
778
                              return (MidiEvent*)-1;  // DEBUG: eigentlich n�chsten Event lesen
785
779
                        case 0x22:        // Channel Prefix
786
780
                              if (len == 1) {
787
781
                                    channelprefix = buffer[0];
788
 
                                    delete buffer;
 
782
                                    delete[] buffer;
789
783
                                    delete event;
790
784
                                    return (MidiEvent*)-1;
791
785
                                    }
795
789
                                    lastport = buffer[0];
796
790
                                    if (lastport == 10)
797
791
                                          lastport = 1;
798
 
                                    delete buffer;
 
792
                                    delete[] buffer;
799
793
                                    delete event;
800
794
                                    return (MidiEvent*)-1;
801
795
                                    }
804
798
                              {
805
799
                              int tempo = buffer[2] + (buffer[1] << 8) + (buffer[0] <<16);
806
800
                              tempomap.addTempo(t, tempo);
807
 
                              delete buffer;
 
801
                              delete[] buffer;
808
802
                              delete event;
809
803
                              }
810
804
                              return (MidiEvent*)-1;  // DEBUG: eigentlich n�chsten Event lesen
817
811
                                    timesig_n *= 2;
818
812
                              sigmap.add(t, timesig_z, timesig_n);
819
813
                              delete event;
820
 
                              delete buffer;
 
814
                              delete[] buffer;
821
815
                              }
822
816
                              return (MidiEvent*)-1;  // DEBUG: eigentlich n�chsten Event lesen
823
817
                        case 0x59:  // Key Signature
825
819
                              track->scale.set(buffer[0]);
826
820
                              track->scale.setMajorMinor(buffer[1]);
827
821
                              delete event;
828
 
                              delete buffer;
 
822
                              delete[] buffer;
829
823
                              }
830
824
                              return (MidiEvent*)-1;  // DEBUG: eigentlich n�chsten Event lesen
831
825
                        case 0x6:   // Marker
832
826
                              song->addMarker(QString((const char*)(buffer)), event->posTick(), false);
833
827
                              delete event;
834
 
                              delete buffer;
 
828
                              delete[] buffer;
835
829
                              return (MidiEvent*)-1;  // DEBUG: eigentlich n�chsten Event lesen
836
830
 
837
831
                        case 0:     // Sequence Number
847
841
rest:
848
842
                        default:
849
843
                              event->setType(MidiEvent::Meta);
850
 
                              event->setDataLen(len+1);
851
 
                              event->setData(buffer);
 
844
                              {
 
845
                              EvData* ed = new EvData(buffer, len+1);
 
846
                              ed->refCount = 1;
 
847
                              event->setEvData(ed);
 
848
                              }
852
849
                              event->setA(type);
853
850
                              break;
854
851
                        }
878
875
                        a = me;
879
876
                        }
880
877
                  b = 0;
 
878
                  event->setA(a);
881
879
                  switch (status & 0xf0) {
882
880
                        case 0x80:        // Taste loslassen
883
881
                        case 0x90:        // Taste anschlagen
902
900
                              delete event;
903
901
                              return (MidiEvent*)-2;
904
902
                        }
905
 
                  event->setA(a);
906
903
                  switch (status & 0xf0) {
907
904
                        case 0x80:        // Taste loslassen
908
905
                              event->setType(MidiEvent::NoteOff);
967
964
      //    Setup Measure:
968
965
      //    Trackname, Comment, Instrument, Volume, Pan
969
966
      //
970
 
      if (!track->tname().isEmpty()) {
971
 
            const char* name = track->tname().latin1();
 
967
      if (!track->name().isEmpty()) {
 
968
            const char* name = track->name().latin1();
972
969
            int len = strlen(name);
973
 
            MidiEvent* ev = new MidiEvent(port, channel, 0, MidiEvent::Meta, len, (unsigned char*)name);
 
970
            MidiEvent* ev = new MidiEvent(0, MidiEvent::Meta, len, (unsigned char*)name);
974
971
            ev->setA(0x3);    // Meta Sequence/Track Name
975
972
            events->add(ev);
976
973
            }
977
974
      if (!track->comment().isEmpty()) {
978
975
            const char* comment = track->comment().latin1();
979
976
            int len = strlen(comment);
980
 
            MidiEvent* ev = new MidiEvent(port, channel, 0, MidiEvent::Meta, len, (unsigned char*)comment);
 
977
            MidiEvent* ev = new MidiEvent(0, MidiEvent::Meta, len, (unsigned char*)comment);
981
978
            ev->setA(0x0f);   // Meta Text
982
979
            events->add(ev);
983
980
            }
986
983
 
987
984
      int tick = 300;
988
985
      if (state->controller[CTRL_HBANK] != -1) {
989
 
            events->add(new MidiEvent(port, channel, tick, MidiEvent::Ctrl7, CTRL_HBANK,
 
986
            events->add(new MidiEvent(tick, MidiEvent::Ctrl7, CTRL_HBANK,
990
987
               state->controller[CTRL_HBANK], 0, 0));
991
988
            tick += 10;
992
989
            }
993
990
      if (state->controller[CTRL_LBANK] != -1) {
994
 
            events->add(new MidiEvent(port, channel, tick, MidiEvent::Ctrl7, CTRL_LBANK,
 
991
            events->add(new MidiEvent(tick, MidiEvent::Ctrl7, CTRL_LBANK,
995
992
               state->controller[CTRL_LBANK], 0, 0));
996
993
            tick += 10;
997
994
            }
998
995
      if (state->program != -1) {
999
 
            events->add(new MidiEvent(port, channel, tick, MidiEvent::Program, state->program,
 
996
            events->add(new MidiEvent(tick, MidiEvent::Program, state->program,
1000
997
               0, 0, 0));
1001
998
            tick += 10;
1002
999
            }
1003
1000
      if (state->controller[CTRL_VOLUME] != -1) {
1004
 
            events->add(new MidiEvent(port, channel, tick, MidiEvent::Ctrl7, CTRL_VOLUME,
 
1001
            events->add(new MidiEvent(tick, MidiEvent::Ctrl7, CTRL_VOLUME,
1005
1002
               state->controller[CTRL_VOLUME], 0, 0));
1006
1003
            tick += 10;
1007
1004
            }
1008
1005
      if (state->controller[CTRL_PANPOT] != -1) {
1009
 
            events->add(new MidiEvent(port, channel, tick, MidiEvent::Ctrl7, CTRL_PANPOT,
 
1006
            events->add(new MidiEvent(tick, MidiEvent::Ctrl7, CTRL_PANPOT,
1010
1007
               state->controller[CTRL_PANPOT], 0, 0));
1011
1008
            tick += 10;
1012
1009
            }
1020
1017
            MidiPart* part    = (MidiPart*) (p->second);
1021
1018
            EventList* evlist = part->events();
1022
1019
            for (iEvent i = evlist->begin(); i != evlist->end(); ++i) {
1023
 
                  MidiEvent* ev = (MidiEvent*)i->second;
1024
 
                  if (ev->isNote()) {
1025
 
                        if (ev->velo() == 0) {
 
1020
                  MidiEvent* ev    = (MidiEvent*)i->second;
 
1021
                  int tick         = ev->posTick() + part->posTick();
 
1022
                  MidiEvent* event = new MidiEvent(*ev);
 
1023
                  event->setPosTick(tick);
 
1024
 
 
1025
                  if (event->isNote()) {
 
1026
                        if (event->velo() == 0) {
1026
1027
                              printf("Warning: midi note has velocity 0, (ignored)\n");
1027
1028
                              continue;
1028
1029
                              }
1029
 
                        MidiEvent* event = new MidiEvent(*ev);
1030
 
                        int len   = ev->lenTick();
 
1030
                        int len = event->lenTick();
1031
1031
 
1032
1032
                        //---------------------------------------
1033
1033
                        //   apply trackinfo values
1037
1037
                           || track->velocity
1038
1038
                           || track->compression != 100
1039
1039
                           || track->len != 100) {
1040
 
                              int pitch = ev->pitch();
1041
 
                              int velo  = ev->velo();
 
1040
                              int pitch = event->pitch();
 
1041
                              int velo  = event->velo();
1042
1042
                              pitch += track->transposition;
1043
1043
                              if (pitch > 127)
1044
1044
                                    pitch = 127;
1058
1058
                              }
1059
1059
                        events->add(event);
1060
1060
                        MidiEvent* off = new MidiEvent(*event);
1061
 
                        int tick = off->posTick();
1062
1061
                        if (len <= 0)
1063
1062
                              len = 1;
1064
1063
                        off->setPosTick(tick + len);
1071
1070
                        events->add(off);
1072
1071
                        }
1073
1072
                  else
1074
 
                        events->add(ev);
 
1073
                        events->add(event);
1075
1074
                  }
1076
1075
            }
1077
1076
 
1097
1096
            for (ciMarker m = ml->begin(); m != ml->end(); ++m) {
1098
1097
                  const char* name = m->second.name().latin1();
1099
1098
                  int len = strlen(name);
1100
 
                  MidiEvent* ev = new MidiEvent(port, channel,
 
1099
                  MidiEvent* ev = new MidiEvent(
1101
1100
                     m->first, MidiEvent::Meta,
1102
1101
                     len, (unsigned char*)name);
1103
1102
                  ev->setA(0x6);
1110
1109
            const char* copyright = song->copyright().latin1();
1111
1110
            if (copyright && *copyright) {
1112
1111
                  int len = strlen(copyright);
1113
 
                  MidiEvent* ev = new MidiEvent(port, channel, 0, MidiEvent::Meta,
 
1112
                  MidiEvent* ev = new MidiEvent(0, MidiEvent::Meta,
1114
1113
                     len, (unsigned char*)copyright);
1115
1114
                  ev->setA(0x2);
1116
1115
                  events->add(ev);
1120
1119
            //
1121
1120
            switch(song->mtype()) {
1122
1121
                  case MT_GM:
1123
 
                        events->add(new MidiEvent(port, channel, 0, MidiEvent::Sysex, gmOnMsgLen, gmOnMsg));
 
1122
                        events->add(new MidiEvent(0, MidiEvent::Sysex, gmOnMsgLen, gmOnMsg));
1124
1123
                        break;
1125
1124
                  case MT_GS:
1126
 
                        events->add(new MidiEvent(port, channel, 0, MidiEvent::Sysex, gmOnMsgLen, gmOnMsg));
1127
 
                        events->add(new MidiEvent(port, channel, 250, MidiEvent::Sysex, gsOnMsgLen, gsOnMsg));
 
1125
                        events->add(new MidiEvent(0, MidiEvent::Sysex, gmOnMsgLen, gmOnMsg));
 
1126
                        events->add(new MidiEvent(250, MidiEvent::Sysex, gsOnMsgLen, gsOnMsg));
1128
1127
                        break;
1129
1128
                  case MT_XG:
1130
 
                        events->add(new MidiEvent(port, channel, 0, MidiEvent::Sysex, gmOnMsgLen, gmOnMsg));
1131
 
                        events->add(new MidiEvent(port, channel, 250, MidiEvent::Sysex, xgOnMsgLen, xgOnMsg));
 
1129
                        events->add(new MidiEvent(0, MidiEvent::Sysex, gmOnMsgLen, gmOnMsg));
 
1130
                        events->add(new MidiEvent(250, MidiEvent::Sysex, xgOnMsgLen, xgOnMsg));
1132
1131
                        break;
1133
1132
                  case MT_UNKNOWN:
1134
1133
                        break;
1145
1144
                  data[1] = (tempo >> 8) & 0xff;
1146
1145
                  data[0] = (tempo >> 16) & 0xff;
1147
1146
                  MidiEvent* ev = new MidiEvent(
1148
 
                     port, channel,
1149
1147
                     event->tick, MidiEvent::Meta, 3, data);
1150
1148
                  ev->setA(0x51);
1151
1149
                  events->add(ev);
1171
1169
                              break;
1172
1170
                        }
1173
1171
                  MidiEvent* ev = new MidiEvent(
1174
 
                     port, channel,
1175
1172
                     event->tick, MidiEvent::Meta, 2, data);
1176
1173
                  ev->setA(0x58);
1177
1174
                  events->add(ev);
1188
1185
      for (iEvent i = events->begin(); i != events->end(); ++i) {
1189
1186
            putvl(((i->first-tick) * midiDivision + ::division/2)/::division);
1190
1187
            tick = i->first;
1191
 
            writeEvent((MidiEvent*)i->second);
 
1188
            writeEvent(channel, (MidiEvent*)i->second);
1192
1189
            }
1193
1190
      delete events;
1194
1191
 
1241
1238
            track->setType(Track::DRUM);
1242
1239
 
1243
1240
      MidiPort* port = &midiPorts[track->outPort()];
1244
 
      int channel = track->outChannel();
1245
 
      port->resetIstate(channel, false);
1246
 
 
1247
 
      int trackno  = song->tracks()->index(track);
1248
 
      bool karaoke = song->karaokeFlag();
 
1241
      int channel    = track->outChannel();
 
1242
      int trackno    = song->tracks()->index(track);
 
1243
      bool karaoke   = song->karaokeFlag();
1249
1244
 
1250
1245
      //---------------------------------------------------
1251
1246
      //    get initial controller state
1292
1287
                                    if (trackno == 1 && memcmp(ev->data(), "@KMID", 5) == 0) {
1293
1288
                                          karaoke = true;
1294
1289
                                          song->setKaraokeFlag(true);
1295
 
                                          song->setKaraokeChannel(ev->channel());
 
1290
                                          song->setKaraokeChannel(channel);
1296
1291
                                          tevents->erase(i);
1297
1292
                                          }
1298
1293
                                    if ((trackno == 2) && karaoke) {
1305
1300
                                                            break;
1306
1301
                                                      case 1:     // expect titel
1307
1302
                                                            ++karaokeState;  // language
1308
 
                                                            song->setName(p+2);
 
1303
                                                            song->setName(QString(p+2));
1309
1304
                                                            break;
1310
1305
                                                      case 2:     // expect interpret
1311
1306
                                                            ++karaokeState;
1312
 
                                                            song->setKomponist1(p+2);
 
1307
                                                            song->setKomponist1(QString(p+2));
1313
1308
                                                            break;
1314
1309
                                                      default:
1315
1310
                                                            printf("unexpected @ in karaoke\n");
1339
1334
            }
1340
1335
 
1341
1336
      //---------------------------------------------------
1342
 
      //    NoteOff Events aufl�sen
 
1337
      //    resolve NoteOff events
1343
1338
      //---------------------------------------------------
1344
1339
 
1345
1340
      for (iEvent i = tevents->begin(); i != tevents->end(); ++i) {
1374
1369
                              }
1375
1370
                        }
1376
1371
                  if (k == tevents->end()) {
1377
 
                        printf("-kein note-off! %d channel %d pitch %d velo %d\n",
1378
 
                           i->first, ev->channel(), ev->pitch(), ev->velo());
 
1372
                        printf("-kein note-off! %d pitch %d velo %d\n",
 
1373
                           i->first, ev->pitch(), ev->velo());
1379
1374
                        //
1380
1375
                        // ton am Taktende abschalten
1381
1376
                        //
1388
1383
                  }
1389
1384
            }
1390
1385
 
 
1386
      //
 
1387
      // remap drum pitch with drumInmap
 
1388
      //
 
1389
      if (track->type() == Track::DRUM) {
 
1390
            for (iEvent i = tevents->begin(); i != tevents->end(); ++i) {
 
1391
                  MidiEvent* ev  = (MidiEvent*)i->second;
 
1392
                  if (ev->isNote()) {
 
1393
                        int pitch = drumInmap[ev->pitch()];
 
1394
                        ev->setPitch(pitch);
 
1395
                        }
 
1396
                  }
 
1397
            }
 
1398
 
1391
1399
// DEBUG: any note offs left?
1392
1400
 
1393
1401
      for (iEvent i = tevents->begin(); i != tevents->end(); ++i) {
1394
1402
            MidiEvent* ev  = (MidiEvent*)i->second;
1395
1403
            if (ev->isNoteOff()) {
1396
 
                  printf("+extra note-off! %d channel %d pitch %d velo %d\n",
1397
 
                           i->first, ev->channel(), ev->pitch(), ev->velo());
 
1404
                  printf("+extra note-off! %d pitch %d velo %d\n",
 
1405
                           i->first, ev->pitch(), ev->velo());
1398
1406
//                  ev->dump();
1399
1407
                  }
1400
1408
            }
1492
1500
            int etick = part->posTick() + part->lenTick();
1493
1501
            iEvent r1 = tevents->lower_bound(stick);
1494
1502
            iEvent r2 = tevents->lower_bound(etick);
1495
 
            part->events()->insert(r1, r2);
 
1503
            int startTick = part->posTick();
 
1504
 
 
1505
            EventList* el = part->events();
 
1506
            for (iEvent i = r1; i != r2; ++i) {
 
1507
                  MidiEvent* ev = (MidiEvent*)(i->second);
 
1508
                  int ntick = ev->posTick() - startTick;
 
1509
                  ev->setPosTick(ntick);
 
1510
                  el->add(ev, ntick);
 
1511
                  }
1496
1512
            tevents->erase(r1, r2);
1497
1513
            }
1498
1514
 
1559
1575
                  return true;
1560
1576
            }
1561
1577
 
 
1578
      for (int i = 0; i < 16; ++i)
 
1579
            midiPorts[0].resetIstate(i, false);
 
1580
 
1562
1581
      TrackList* tl = song->tracks();
1563
1582
      for (iTrack t = tl->begin(); t != tl->end(); ++t) {
1564
1583
            MidiTrack* track = dynamic_cast<MidiTrack*>(*t);
1602
1621
                        }
1603
1622
                  }
1604
1623
            }
1605
 
 
1606
1624
      return false;
1607
1625
      }
1608
1626