private void InitMap(clsOnOff onoff, clsTrks.T intrk, bool exclpb) //virtual channel (= track) { foreach (clsTrks.T trk in P.F.Trks.Ints.Next) //create this[] from modded note (map) { if (intrk != null && intrk != trk) { continue; } for (int note = 0; note < 12; note++) { int cnt = 0; for (int qtime = 0; qtime < onoff.Length; qtime++) { cnt += onoff[qtime, note, trk, true]; //if (cnt > 0) Debugger.Break(); //ON this[qtime, note, trk] = (cnt > 0); } } if (exclpb) { for (int qtime = 0; qtime < onoff.Length; qtime++) { for (int note = 0; note < 12; note++) { if (this[qtime, note, trk] && PB[trk][qtime] != 8192) { this[qtime, note, trk] = false; } } } } } }
internal void InitPWTrk(clsTrks.T trk) { for (int qi = 0; qi < PB[trk].Length; qi++) { PB[trk][qi] = 8192; } }
//internal override bool QI_OOR(int qi) { // return (qi >= P.F.MaxBBT.QI || qi >= NewMap[new clsTrks.T(P.F.Trks, 0)].Length); //} //internal override void Realloc(int qlen) { // int maplen = _Map[new clsTrks.T(P.F.Trks, 0)].Length; // if (qlen == maplen) return; // clsTrks.Array<ushort[]> newmap = new clsTrks.Array<ushort[]>(delegate () { return new ushort[qlen]; }); // clsTrks.Array<BigInteger[]> newfullmap = new clsTrks.Array<BigInteger[]>(delegate () { return new BigInteger[qlen]; }); // bool[,] trk_selected = new bool[qlen, 128]; // clsTrks.Array<short[]> pb = new clsTrks.Array<short[]>(delegate () { // short[] pw = new short[qlen]; // for (int i = 0; i < qlen; i++) pw[i] = -1; // return pw; // }); // byte[,] filter = new byte[qlen, 12]; // for (int q = 0; q < qlen; q++) { // if (q < maplen) { // foreach (clsTrks.T trk in P.F.Trks.Ints.Next) { // newmap[trk][q] = _Map[trk][q]; // newfullmap[trk][q] = _FullMap[trk][q]; // pb[trk][q] = PB[trk][q]; // } // for (int n = 0; n < 128; n++) trk_selected[q, n] = Trk_Selected[q, n]; // for (int n = 0; n < 12; n++) filter[q, n] = Filter[q, n]; // } // } //} private void InitFullMap(clsOnOff onoff, clsTrks.T intrk, bool exclpb) { foreach (clsTrks.T trk in TrkMinPitch.Next) //create this[] from unmodded note (fullmap) { if (intrk != null && intrk != trk) { continue; } for (int note = TrkMinPitch[trk]; note <= TrkMaxPitch[trk]; note++) { int cnt = 0; for (int qtime = 0; qtime < onoff.Length; qtime++) { cnt += onoff[qtime, note, trk, false]; //if (cnt > 0) Debugger.Break(); //ON this[qtime, note, trk, false] = (cnt > 0); } } if (exclpb) { for (int qtime = 0; qtime < onoff.Length; qtime++) { for (int note = TrkMinPitch[trk]; note <= TrkMaxPitch[trk]; note++) { if (this[qtime, note, trk, false] && PB[trk][qtime] != 8192) { this[qtime, note, trk, false] = false; } } } } } }
internal bool this[int qtime, int note, clsTrks.T trk] { //modded note for one trk get { return((_Map[trk][qtime] & NoteMask12[note]) > 0); } set { SetMap12(_Map, qtime, note, trk, value); } }
internal bool this[clsTrks.T trk] { get { return(MutedTracks[trk]); } set { MutedTracks[trk] = value; MutedTrackFromStart[trk] = false; //use StartPlay() to mute from start } }
//internal override int GetLengthQTime() { // return NewMap[new clsTrks.T(P.F.Trks, 0)].Length; //} internal bool TrkEmpty(int qtime, clsTrks.T trk) { for (int n = 0; n < 12; n++) { if (this[qtime, n, trk]) { return(false); } } return(true); }
internal bool IsSolo(clsTrks.T trk) { //* return true if trk is solo'ed (played) if (SoloTracks == 0) { return(false); } long mask = 1L << trk.TrkNum; return((SoloTracks & mask) != 0); }
private void SetMap12(clsTrks.Array <ushort[]> map, int qtime, int note, clsTrks.T trk, bool value) { if (value) { map[trk][qtime] |= NoteMask12[note]; } else { map[trk][qtime] &= (ushort)~NoteMask12[note]; } }
protected clsPicNoteMap(PictureBox pic, clsTrks.T trk, bool firsttrk, Font barfont, bool weighted) { Weighted = weighted; Pic = pic; Trk = trk; //BarFont = null; if (firsttrk) { BarFont = barfont; } //if (firsttrk) BarFont = new Font(new FontFamily("Arial"), 10, FontStyle.Bold); }
internal int NoteCount(int qtime, clsTrks.T trk) { int cnt = 0; for (int note = 0; note < 12; note++) { if (this[qtime, note, trk]) { cnt++; } } return(cnt); }
internal void SetSolo(clsTrks.T trk, bool val) { long mask = 1L << trk.TrkNum; if (val) { SoloTracks |= mask; } else { SoloTracks &= ~mask; } }
//* used by frmMultiMap - one trk only internal clsPicNoteMapMM(Forms.frmTrackMap multimap, PictureBox pic, clsTrks.T trk) : base(pic, trk, false, multimap.BarFont, false) { frmMM = multimap; //FileName = multimap.FileName; //NoteMap = multimap.NoteMap; //MaxQTime = multimap.MaxQTime; //NumTrks = multimap.NumTrks; //QIdd = multimap.QIdd; //TicksPerQI = multimap.TicksPerQI; //FirstTrk = false; SetPicSize(multimap); }
private bool GetindSaveTrack(clsTrks.T trk) { if (FS.OnCount[trk] == 0 && FS.Title[trk].Length == 0) { return(false); } //if (trk == FS.NumTrks - 1 && FS.OnCount[trk] == 0) return false; //last (recording) trk if (!P.frmSaveMidiFileAs.chkSaveMutedTrks.Checked && P.F.Mute[trk]) { return(false); } //if (!P.frmSaveMidiFileAs.chkSaveEmptyTrks.Checked && FS.OnCount[trk] == 0) return false; return(true); }
//internal void SetPB(clsTrks.T trk, int qi, short val) { // PB[trk][qi] = val; //} internal void SyncPCFromPitches(int qtime, int pc, clsTrks.T trk) { //* set Map12 from Map128 pitch values //* use to synchronise Map12 from Map128 for (int n = pc; n < 128; n += 12) { if (this[qtime, n, trk, false]) { this[qtime, pc, trk, true] = true; return; } } this[qtime, pc, trk, true] = false; }
//private int NumTrks; internal int this[int qi, int note, clsTrks.T trk, bool mod] { //return/set count get { int modval = 128; if (mod) { modval = 12; } int evcount = 0; if (Evs[qi] == null) { return(0); } foreach (clsEv ev in Evs[qi]) { if (trk != ev.Trk || note != (ev.Note % modval)) { continue; } evcount += ev.Count; } return(evcount); } set { //if (qi == 84) Debugger.Break(); //tmp if (mod) { LogicError.Throw(eLogicError.X068); } if (Evs[qi] == null) { Evs[qi] = new List <clsEv>(); } List <clsEv> evs = Evs[qi]; for (int i = 0; i < evs.Count; i++) { clsEv ev = evs[i]; if (note != ev.Note || trk != ev.Trk) { continue; } ev.Count = value; return; } evs.Add(new clsEv(note, trk, value)); } }
internal bool MutedEv(clsTrks.T trk, int chan, bool on) { //* check if an (ON) event should play if (ExclCh10 && chan == 9) { return(true); //exclch10 overrides solo and mute } if (IsSolo(trk)) { return(false); //solo always plays } if (SoloTracks != 0 && on) { return(true); //don't play ON if other trk(s) solo'ed } if (on) { return(MutedTracks[trk]); } return(MutedTrackFromStart[trk]); //OFF & others }
internal bool this[int qtime, int note, clsTrks.T trk, bool mod] { //* note for one trk, mod/nomod get { if (mod) { return(this[qtime, note, trk]); } else { return((_FullMap[trk][qtime] & NoteMask128[note]) > 0); } } set { if (mod) { this[qtime, note, trk] = value; } else { SetMap128(_FullMap, qtime, note, trk, value); } } }
internal clsEv(int note, clsTrks.T trk, int count) { Trk = trk; Note = note; Count = count; }
private void DrawChord(clsNoteMap notemap, Graphics xgr, Forms.frmTrackMap frm, int pwval, int qtime, int hdiv, int vfactor) { string name = Pic.Name; //int trk = Trk; int[] chweights = null; int maxchweight = 0; Brush brush; if (pwval != 8192) { brush = BrushPW; } else { brush = BrushNoPW; } int noteborder = (ShowKB) ? vfactor / 3 : 0; //vertical pixels not coloured in (to allow black keyboard notes to be seen) if (Trk == null) //all channels (not multimap) //* get chord colours (int[12] chweights) { bool[] boolmap; if (Weighted) { boolmap = notemap.IsF(qtime); } else { boolmap = notemap[qtime]; } ChordDB.clsDesc desc = ChordDB.GetChord(boolmap); if (desc != null) //matches chord exactly //brush = clsChBrush.GetOldBrush(desc.Rank); { brush = clsChBrush.GetOldBrush(); } else //no match - show note weights { chweights = ChordDB.GetChordWeights(boolmap); maxchweight = chweights.Max(); } } int width = Math.Max(1, HFactor / hdiv); if (!OneOct) //frmMultiMap or notemap.midi //* calc note display limits //int minpitch, maxpitch; //GetMinMaxPitch(out minpitch, out maxpitch); //int y, minc; //GetYMinC(frm, out y, out minc); //* draw note if notemap[..] true { for (int note = MinPitchShow; note <= MaxPitchShow; note++) { if (!GetNoteMap(notemap, qtime, note, false)) { continue; } int notemod = note.Mod12(); if (Pic.Name == "picNoteMapMidi") { //brush = Brushes.Black; if (P.F.CF != null && P.F.CF.NoteMap[qtime, note.Mod12()]) { brush = P.ColorsNoteMap["Note Match"].Br; } else { brush = P.ColorsNoteMap["Note No Match"].Br; } } else if (Pic == P.frmSC.picNoteMap) { for (int i = 0; i < P.frmSC.MapTrks.Count; i++) { clsTrks.T trk = P.frmSC.MapTrks[i]; int trknum = trk.TrkNum; if (trknum > 15) { trknum %= 16; } if (((clsNoteMapMidi)notemap)[qtime, note, trk, false]) { brush = TrkBrushes[i]; xgr.FillRectangle(brush, (qtime * HFactor) / hdiv, GetY(note - MinC, PixPerNoteInt), width, vfactor); } } continue; } else { brush = GetNoteBrush(chweights, maxchweight, brush, notemod, notemap, qtime); } if (frm?.NoteMap?.Delete != null && //trackmap Trk == frm.MouseTrk && frm.NoteMap.Delete[qtime, note]) { brush = Brushes.Red; } xgr.FillRectangle(brush, (qtime * HFactor) / hdiv, GetY(note - MinC, PixPerNoteInt), width, vfactor); } } else //oneoct - called from frm NoteMap (any) or frmMultiMap //* draw note if notemap[..] true { for (int notemod = 0; notemod < 12; notemod++) { if (!GetNoteMap(notemap, qtime, notemod)) { continue; } if (Pic.Name == "picNoteMapMidi") { brush = Brushes.Black; if (P.F.CF != null && P.F.CF.NoteMap[qtime, notemod]) { brush = P.ColorsNoteMap["Note Match"].Br; } else { brush = P.ColorsNoteMap["Note No Match"].Br; } } else { brush = GetNoteBrush(chweights, maxchweight, brush, notemod, notemap, qtime); } xgr.FillRectangle(brush, (qtime * HFactor) / hdiv, GetY(notemod, vfactor) + noteborder, width, vfactor - 2 * noteborder); } if ((Pic.Name == "picNoteMapMidi" || Pic.Name == "picNoteMapQuant") && (P.F.frmChordMapAdv != null && P.F.frmChordMapAdv.optChordMatch.Checked)) { //* check if pitchclass (pc) present in notemapcf, but not in pic for (int pc = 0; pc < 12; pc++) { if (P.F.CF.NoteMap[qtime, pc] && !GetNoteMap(notemap, qtime, pc)) { Brush gbrush = clsChBrush.Green; xgr.FillRectangle(gbrush, (qtime * HFactor) / hdiv, GetY(pc, vfactor) + noteborder, width, vfactor - 2 * noteborder); } } } } }
//internal bool GetMapPB(int qtime, int note, int trk, bool mod) { // //* note for one trk, excl. pitchbent notes // if (PB[qtime, trk] != 8192) return false; //pitchbent // return this[qtime, note, trk, mod]; //} internal ushort[] Map_GetTrk(clsTrks.T trk) //called by frmTrackMap Undo/Redo { return(_Map[trk]); }
internal T this[clsTrks.T trk] { get { return(Arr[trk.TrkNum]); } set { Arr[trk.TrkNum] = value; } }
internal void Map_SetTrk(clsTrks.T trk, ushort[] val) //called by frmTrackMap Undo/Redo { _Map[trk] = val; }
internal BigInteger[] FullMap_GetTrk(clsTrks.T trk) //called by frmTrackMap Undo/Redo { return(_FullMap[trk]); }
internal void FullMap_SetTrk(clsTrks.T trk, BigInteger[] val) //called by frmTrackMap Undo/Redo { _FullMap[trk] = val; }
internal void PropagatePW(clsFileStream filestream, int len, clsTrks.T trk) { //* null trk = all trks //* initialize PB if (trk == null) { PB = new clsTrks.Array <short[]>(delegate() { short[] pw = new short[len]; for (int i = 0; i < len; i++) { pw[i] = -1; } return(pw); }); } else { PB[trk] = new short[len]; for (int i = 0; i < len; i++) { PB[trk][i] = -1; } } //* read stream clsFileStream.clsEvStrm[] strm = filestream.Strm; for (int i = 0; i < strm.Length; i++) { if (strm[i] is clsFileStream.clsEvShort) { clsFileStream.clsEvShort ev = ((clsFileStream.clsEvShort)strm[i]); if (trk != null && trk != ev.Trk) { continue; } if ((ev.Status & 0xe0) != 0xe0) { continue; //not pitchbend } int val = ev.Msg + (ev.Data << 7); PB[ev.Trk][ev.QTime] = (short)val; //channel not used - only track } } //* propagate PB foreach (clsTrks.T t in PB.Next) { if (trk != null && trk != t) { continue; } short pw = 8192; //centre (default) for (int qi = 0; qi < len; qi++) { if (PB[t][qi] >= 0) { pw = PB[t][qi]; //set current value } PB[t][qi] = pw; } } }
private void WriteTrack(clsTrks.T trk) { int prevticks = 0; using (stTrk = new MemoryStream()) { BinaryWriter br = new BinaryWriter(stTrk); MWriterTrk = new clsMWriter(br); string strtitle = (P.F.frmTrackMap == null || P.F.frmTrackMap.txtTitles[trk] == null) ? FS.Title[trk] : P.F.frmTrackMap.txtTitles[trk].Text; byte[] bytestitle = Encoding.ASCII.GetBytes(strtitle); clsFileStream.clsEvTitle evtitle = new clsFileStream.clsEvTitle(0, 0, -1, bytestitle); //trk param not used evtitle.WriteTitle(this, 0); //* write overriding controllers (vol, pan, patch) clsFileStream.clsEvShort evshort; bool indvol = false, indpan = false, indpatch = false; if (P.F.Chan[trk] >= 0) { int chan = P.F.Chan[trk]; byte vol = (byte)P.F.Vol[chan]; if (vol <= 127) { indvol = true; evshort = new clsFileStream.clsEvShort(0, trk.TrkNum, (byte)(0xb0 | chan), 7, vol); WriteStrmMsg(ref prevticks, evshort); } byte pan = (byte)P.F.Pan[chan]; if (pan <= 127) { indpan = true; evshort = new clsFileStream.clsEvShort(0, trk.TrkNum, (byte)(0xb0 | chan), 10, pan); WriteStrmMsg(ref prevticks, evshort); } byte patch = (byte)P.F.Patch[chan]; if (patch <= 127) { indpatch = true; evshort = new clsFileStream.clsEvShort(0, 0, trk.TrkNum, (byte)(0xc0 | chan), patch); WriteStrmMsg(ref prevticks, evshort); } } foreach (clsFileStream.clsEvStrm ev in FS.Strm) { if (ev.Trk != trk) { continue; } if (ev is clsFileStream.clsEvBeat) { continue; } if (ev is clsFileStream.clsEvShort) { clsFileStream.clsEvShort evsh = (clsFileStream.clsEvShort)ev; int status = evsh.Status & 0xf0; if (indvol && status == 0xb0 && evsh.Msg == 7) { continue; //vol overriden } if (indpan && status == 0xb0 && evsh.Msg == 10) { continue; //pan overriden } if (indpatch && status == 0xc0) { continue; //patch overriden } } WriteStrmMsg(ref prevticks, ev); } WriteToFileStream(prevticks); } }
private void SetMap128(clsTrks.Array <BigInteger[]> map, int qtime, int note, clsTrks.T trk, bool value) { if (value) { map[trk][qtime] |= NoteMask128[note]; } else { map[trk][qtime] &= ~NoteMask128[note]; } }
internal short GetPB(clsTrks.T trk, int qi) { return(PB[trk][qi]); }
protected bool ReadTrack(int midifiletrk, bool indtsigs, clsTrks.Array <List <clsFileStream.clsOO> > oo) //trk0 = first non-conductor trk //* return false if midi trk data in trk0 (eg midi ON, OFF, patch, ...) { InitTrack(); //if (trk >= 0) FileStream.OO[trk] = new List<clsFileStream.clsOO>(); clsTrks.T trk = (midifiletrk >= 0) ? new clsTrks.T(P.F.Trks, midifiletrk) : null; FileStream.StrmLL.ResetCurrentLLN(); int delta = MReaderTrk.ReadIntV(); int ticks = 0; byte status = 0; //usually >= 0x80 int chan = -1; int seq = -1; //bool sustainon = false; //set only only if P.frmStart.chkMidiFileSustain.Checked //bool[] sustained = new bool[128]; //set only only if P.frmStart.chkMidiFileSustain.Checked while (delta >= 0) //not EOF { seq++; ticks += delta; if (TPQNConv) { ticks = (ticks * TPQNMult) / TPQNDiv; //should normally not need rounding } byte b = MReaderTrk.ReadByte(); if (b >= 0x80) //new status { status = b; chan = -1; if (status < 0xf0) { chan = status & 0x0f; b = MReaderTrk.ReadByte(); //not sysex or metaev } if (Format == 0) { midifiletrk = chan; if (chan < 0) { trk = new clsTrks.T(P.F.Trks, 0); } else { trk = new clsTrks.T(P.F.Trks, midifiletrk); } } } switch (status & 0xf0) { case 0x90: //ON case 0x80: //OFF //* 2 data bytes if (midifiletrk < 0) { return(false); } //int chan = status & 0x0f; //byte pitch = (byte)(b + FileStream.Transpose); byte pitch = b; byte vel = MReaderTrk.ReadByte(); bool on = (status & 0xf0) == 0x90 && (vel > 0); //* throw new TestException(); if (on) { FileStream.UpdateChanOnTotals(trk, chan, pitch); } FileStream.ChanAllCount[trk][chan]++; FileStream.StrmLL.InsertShortEv(seq, ticks, midifiletrk, status, b, vel); if (!Excl10 || chan != 9) { oo[new clsTrks.T(P.F.Trks, midifiletrk)].Add(new clsFileStream.clsOO( ticks, on, chan, pitch, vel, P.F.TicksPerQI)); } break; case 0xa0: //poly key pressure case 0xb0: //control change case 0xe0: //pitch wheel //* 2 data bytes //if (trk < 0) return true; if (midifiletrk < 0) //ignore { MReaderTrk.ReadByte(); break; } byte c = MReaderTrk.ReadByte(); if (FileStream.Title[trk].StartsWith("Cakewalk TTS-1")) { break; //kludge to get around Sonar bug } if ((status & 0xf0) == 0xe0) //pitchbend { if (b != 0 || c != 64) { FileStream.indPitchBend[trk] = true; //not middle value } } //else if (P.frmStart.chkMidiFileSustain.Checked && (!Excl10 || chan != 9)) { // if ((status & 0xf0) == 0xb0 && b == 64) { //sustain // sustainon = (c > 64); // if (!sustainon) { //sustainon -> sustainoff // for (int i = 0; i < 128; i++) { // if (sustained[i]) { // FileStream.OO[trk].Add(new clsFileStream.clsOO(ticks, false, chan, i, 0, P.F.TicksPerQI)); // sustained[i] = false; // } // } // } // } //} FileStream.StrmLL.InsertShortEv(seq, ticks, midifiletrk, status, b, c); FileStream.ChanAllCount[trk][status & 0x0f]++; break; case 0xc0: //program change (patch) //* 1 data byte //if (trk < 0) return false; if (midifiletrk < 0) { break; //ignore } if (FileStream.Title[trk].StartsWith("Cakewalk TTS-1")) { break; //kludge to get around Sonar bug } //if (!FileStream.Summary) FileStream.InsertShortEv(ticks, trk, status, b); FileStream.StrmLL.InsertShortEv(seq, ticks, midifiletrk, status, b); FileStream.ChanAllCount[trk][status & 0x0f]++; break; case 0xd0: //channel pressure //if (trk < 0) return false; if (midifiletrk < 0) { break; } //* 1 data byte //if (!FileStream.Summary && FileStream.TrkSelect[trk]) { //if (!FileStream.Summary) { FileStream.StrmLL.InsertShortEv(seq, ticks, midifiletrk, status, b); //} FileStream.ChanAllCount[trk][status & 0x0f]++; break; case 0xf0: //system common messages int len; switch (status) { case 0xf0: //sysex start case 0xf7: //sysex end len = MReaderTrk.ReadIntV(); byte[] sysdata = MReaderTrk.ReadBytes(len); FileStream.StrmLL.InsertSystemEv(seq, ticks, midifiletrk, status, sysdata); status = 0; //sysex cancels running status break; case 0xff: //meta event status = 0; //metaev cancels running status byte type = MReaderTrk.ReadByte(); len = MReaderTrk.ReadIntV(); byte[] metadata; switch (type) { case 0x03: //title metadata = MReaderTrk.ReadBytes(len); string title = Encoding.Default.GetString(metadata, 0, metadata.Length); if (midifiletrk == -1) { FileStream.ProjectTitle = title; } else { FileStream.Title[trk] = title; } FileStream.StrmLL.InsertTitleEv(seq, ticks, midifiletrk, metadata); break; //case 0x21: //device (port) number // if (len != 1) throw new MidiFileException(); // int pp = (int)MReaderTrk.ReadUIntF(1); // if (pp != 0) Debug.WriteLine("MidiPortNumber: " + pp + " found - ignored"); // break; //case 0x09: //device (port) name // //MReaderTrk.ReadBytes(len); //ignore metaev // break; case 0x51: //tempo ////if (!IsCondTrk(midifiletrk)) { //// MReaderTrk.ReadBytes(len); //ignore //// Debug.WriteLine("Invalid tempo found on track " + midifiletrk + " - ignored"); //// break; ////} if (len != 3) { throw new MidiFileException(); } int data = (int)MReaderTrk.ReadUIntF(3); FileStream.TempoMap.Add(ticks, data); FileStream.StrmLL.InsertTempoEv(seq, ticks, data); break; case 0x58: //tsig ////if (!IsCondTrk(midifiletrk)) { //// MReaderTrk.ReadBytes(len); //ignore //// Debug.WriteLine("Invalid time signature found on track " + midifiletrk + " - ignored"); //// break; ////} if (len != 4) { throw new MidiFileException(); } int nn = (int)MReaderTrk.ReadUIntF(1); int dd = (int)MReaderTrk.ReadUIntF(1); MReaderTrk.ReadUIntF(1); //bb - not used MReaderTrk.ReadUIntF(1); //cc - not used if (indtsigs) { int tsigdd = (int)Math.Pow(2, dd); clsMTime.clsBBT bbt = new clsMTime.clsBBT(ticks); P.frmStart.TraceLoad("add tsig " + nn + "/" + tsigdd + " ticks " + ticks + " from midifile"); //P.F.MTime.UpdateTSigsTicks(nn, tsigdd, ticks); if (ticks == 0) { P.F.MTime.AddTSigFirst(nn, tsigdd); } else { P.F.MTime.AddTSig(nn, tsigdd, ticks, adj: true); } } else { P.frmStart.TraceLoad("bypass tsig from midifile at ticks " + ticks); } break; case 0x59: //key sig //if (!IsCondTrk(midifiletrk)) { // MReaderTrk.ReadBytes(len); //ignore // MessageBox.Show("Invalid key signature found on track " + midifiletrk + " - ignored"); // break; //} if (len != 2) { throw new MidiFileException(); } int midikey = MReaderTrk.ReadIntSByte(); midikey = Math.Min(Math.Max(midikey, -7), 7); string scale = MajMin(MReaderTrk.ReadUIntF(1)); P.frmStart.TraceLoad("add midifile key to _MidiKeys at ticks " + ticks); P.F._MidiKeys.Add(midikey, scale, ticks); break; case 0x01: //text metadata = MReaderTrk.ReadBytes(len); //other metaev FileStream.StrmLL.InsertMetaEv(seq, ticks, midifiletrk, type, metadata); if (IsCondTrk(midifiletrk)) { string text = Encoding.Default.GetString(metadata, 0, metadata.Length); if (ticks == 0) //general text about the midifile? { FileStream.Text00.Add(text); } } break; case 0x2f: //end of track MaxMidiTicks = Math.Max(MaxMidiTicks, ticks); break; //don't put in stream!!! default: metadata = MReaderTrk.ReadBytes(len); //other metaev FileStream.StrmLL.InsertMetaEv(seq, ticks, midifiletrk, type, metadata); break; } break; default: status = 0; //probably throw new MidiFileException(); //not sysex or metaev } break; default: break; } delta = MReaderTrk.ReadIntV(); if (delta < 0) { break; } } MReaderTrk.Close(); //if (P.F.MTime.TSigsSrc == clsMTime.eSource.None) P.F.MTime.TSigsSrc = clsMTime.eSource.Midi; return(true); }
//public override bool[] this[int qtime] { //return array of modded notes // get { // bool[] ret = new bool[12]; // for (int n = 0; n < 12; n++) ret[n] = (Map[qtime, n] != 0); //any trk (trk0) // return ret; // } // set { // throw new LogicException(); // } //} internal bool Filled(clsTrks.T trk, int qtime) { //* return true if at least one pitch is ON return(_Map[trk][qtime] > 0); }