void AttackFM(NoteEvent non) { Task.Factory.StartNew(() => { if (non.Velocity == 0) { ReleaseFM(non); return; } var reln = non.NoteNumber - 69; var fmul = Math.Pow(freqmul, reln); var s = 0; for (int i = 0; i < chs; i++) { if (atk[i] == null) { s = i; break; } } atk[s] = non; synth[s].Attack(440.0 * fmul); vel[s] = (double)non.Velocity / 128; time[s] = 0; }); }
void midiIn_MessageReceived(object sender, MidiInMessageEventArgs e) { progressLog1.LogMessage(Color.Blue, String.Format("Time {0} Message 0x{1:X8} Event {2}", e.Timestamp, e.RawMessage, e.MidiEvent)); //SendMidiOutMessage(e.MidiEvent); if (VSTForm.vst != null) { MidiEvent midiEvent = e.MidiEvent; byte[] midiData = { 0, 0, 0 }; if (midiEvent is NAudio.Midi.NoteEvent) { NAudio.Midi.NoteEvent me = (NAudio.Midi.NoteEvent)midiEvent; midiData = new byte[] { 0x90, // Cmd (byte)me.NoteNumber, // Val 1 (byte)me.Velocity, // Val 2 }; } else if (midiEvent is NAudio.Midi.ControlChangeEvent) { NAudio.Midi.ControlChangeEvent cce = (NAudio.Midi.ControlChangeEvent)midiEvent; midiData = new byte[] { 0xB0, // Cmd (byte)cce.Controller, // Val 1 (byte)cce.ControllerValue, // Val 2 }; } else if (midiEvent is NAudio.Midi.PitchWheelChangeEvent) { // Pitch Wheel Value 0 is minimum, 0x2000 (8192) is default, 0x4000 (16384) is maximum NAudio.Midi.PitchWheelChangeEvent pe = (PitchWheelChangeEvent)midiEvent; midiData = new byte[] { 0xE0, // Cmd (byte)(pe.Pitch & 0x7f), // Val 1 (byte)((pe.Pitch >> 7) & 0x7f), // Val 2 }; } progressLog1.LogMessage(Color.Chocolate, String.Format("Sending mididata 0x00{0:X2}{1:X2}{2:X2}", midiData[2], midiData[1], midiData[0])); VstMidiEvent vse = new VstMidiEvent(/*DeltaFrames*/ 0, /*NoteLength*/ 0, /*NoteOffset*/ 0, midiData, /*Detune*/ 0, /*NoteOffVelocity*/ 0); VstEvent[] ve = new VstEvent[1]; ve[0] = vse; VSTForm.vst.pluginContext.PluginCommandStub.ProcessEvents(ve); } }
/// <summary> /// Whether this is a note off event /// </summary> public static bool IsNoteOff(MidiEvent midiEvent) { if (midiEvent != null) { if (midiEvent.CommandCode == MidiCommandCode.NoteOn) { NoteEvent ne = (NoteEvent)midiEvent; return(ne.Velocity == 0); } return(midiEvent.CommandCode == MidiCommandCode.NoteOff); } return(false); }
// Token: 0x0600050F RID: 1295 RVA: 0x00011064 File Offset: 0x0000F264 private void FindNoteOn(NoteEvent offEvent, List <NoteOnEvent> outstandingNoteOns) { bool flag = false; foreach (NoteOnEvent noteOnEvent in outstandingNoteOns) { if (noteOnEvent.Channel == offEvent.Channel && noteOnEvent.NoteNumber == offEvent.NoteNumber) { noteOnEvent.OffEvent = offEvent; outstandingNoteOns.Remove(noteOnEvent); flag = true; break; } } if (!flag && this.strictChecking) { throw new FormatException(string.Format("Got an off without an on {0}", offEvent)); } }
private void FindNoteOn(NoteEvent offEvent, List<NoteOnEvent> outstandingNoteOns) { bool found = false; foreach(NoteOnEvent noteOnEvent in outstandingNoteOns) { if ((noteOnEvent.Channel == offEvent.Channel) && (noteOnEvent.NoteNumber == offEvent.NoteNumber)) { noteOnEvent.OffEvent = offEvent; outstandingNoteOns.Remove(noteOnEvent); found = true; break; } } if(!found) { if (strictChecking) { //throw new FormatException(String.Format("Got an off without an on {0}", offEvent)); } } }
/// <summary> /// Constructs a MidiEvent from a BinaryStream /// </summary> /// <param name="br">The binary stream of MIDI data</param> /// <param name="previous">The previous MIDI event (pass null for first event)</param> /// <returns>A new MidiEvent</returns> public static MidiEvent ReadNextEvent(BinaryReader br, MidiEvent previous) { int deltaTime = MidiEvent.ReadVarInt(br); MidiCommandCode commandCode; int channel = 1; byte b = br.ReadByte(); if((b & 0x80) == 0) { // a running command - command & channel are same as previous commandCode = previous.CommandCode; channel = previous.Channel; br.BaseStream.Position--; // need to push this back } else { if((b & 0xF0) == 0xF0) { // both bytes are used for command code in this case commandCode = (MidiCommandCode) b; } else { commandCode = (MidiCommandCode) (b & 0xF0); channel = (b & 0x0F) + 1; } } MidiEvent me; switch(commandCode) { case MidiCommandCode.NoteOn: me = new NoteOnEvent(br); break; case MidiCommandCode.NoteOff: case MidiCommandCode.KeyAfterTouch: me = new NoteEvent(br); break; //case MidiCommandCode.ControlChange: // me = new ControlChangeEvent(br); // break; case MidiCommandCode.PatchChange: me = new PatchChangeEvent(br); break; case MidiCommandCode.ChannelAfterTouch: me = new ChannelAfterTouchEvent(br); break; case MidiCommandCode.PitchWheelChange: me = new PitchWheelChangeEvent(br); break; case MidiCommandCode.TimingClock: case MidiCommandCode.StartSequence: case MidiCommandCode.ContinueSequence: case MidiCommandCode.StopSequence: me = new MidiEvent(); break; case MidiCommandCode.Sysex: me = SysexEvent.ReadSysexEvent(br); break; case MidiCommandCode.MetaEvent: try { me = MetaEvent.ReadMetaEvent(br); } catch(FormatException) { me = new MidiEvent(); } break; default: me = new MidiEvent(); break; //throw new FormatException(String.Format("Unsupported MIDI Command Code {0:X2}",(byte) commandCode)); } me.channel = channel; me.deltaTime = deltaTime; me.commandCode = commandCode; return me; }
/// <summary> /// Creates a MidiEvent from a raw message received using /// the MME MIDI In APIs /// </summary> /// <param name="rawMessage">The short MIDI message</param> /// <returns>A new MIDI Event</returns> public static MidiEvent FromRawMessage(int rawMessage) { long absoluteTime = 0; int b = rawMessage & 0xFF; int data1 = (rawMessage >> 8) & 0xFF; int data2 = (rawMessage >> 16) & 0xFF; MidiCommandCode commandCode; int channel = 1; if ((b & 0xF0) == 0xF0) { // both bytes are used for command code in this case commandCode = (MidiCommandCode)b; } else { commandCode = (MidiCommandCode)(b & 0xF0); channel = (b & 0x0F) + 1; } MidiEvent me; switch (commandCode) { case MidiCommandCode.NoteOn: case MidiCommandCode.NoteOff: case MidiCommandCode.KeyAfterTouch: if (data2 > 0 && commandCode == MidiCommandCode.NoteOn) { me = new NoteOnEvent(absoluteTime, channel, data1, data2, 0); } else { me = new NoteEvent(absoluteTime, channel, commandCode, data1, data2); } break; //case MidiCommandCode.ControlChange: // me = new ControlChangeEvent(absoluteTime,channel,(MidiController)data1,data2); // break; case MidiCommandCode.PatchChange: me = new PatchChangeEvent(absoluteTime,channel,data1); break; case MidiCommandCode.ChannelAfterTouch: me = new ChannelAfterTouchEvent(absoluteTime,channel,data1); break; case MidiCommandCode.PitchWheelChange: me = new PitchWheelChangeEvent(absoluteTime, channel, data1 + (data2 << 7)); break; case MidiCommandCode.TimingClock: case MidiCommandCode.StartSequence: case MidiCommandCode.ContinueSequence: case MidiCommandCode.StopSequence: case MidiCommandCode.AutoSensing: me = new MidiEvent(absoluteTime,channel,commandCode); break; case MidiCommandCode.MetaEvent: case MidiCommandCode.Sysex: default: throw new FormatException(String.Format("Unsupported MIDI Command Code for Raw Message {0}", commandCode)); } return me; }
private void FindNoteOn(NoteEvent offEvent, List<NoteOnEvent> outstandingNoteOns) { bool found = false; foreach(NoteOnEvent noteOnEvent in outstandingNoteOns) { if ((noteOnEvent.Channel == offEvent.Channel) && (noteOnEvent.NoteNumber == offEvent.NoteNumber)) { noteOnEvent.OffEvent = offEvent; outstandingNoteOns.Remove(noteOnEvent); found = true; break; } } if(!found) { if (strictChecking) { throw new FormatException(String.Format("Got an off without an on {0}", offEvent)); } } }
/// <summary> /// Opens a MIDI file for reading /// </summary> /// <param name="filename">Name of MIDI file</param> /// <param name="strictChecking">If true will error on non-paired note events</param> public MidiFile(string filename, bool strictChecking) { this.strictChecking = strictChecking; BinaryReader br = new BinaryReader(File.OpenRead(filename)); using (br) { string chunkHeader = Encoding.ASCII.GetString(br.ReadBytes(4)); if (chunkHeader != "MThd") { throw new FormatException("Not a MIDI file - header chunk missing"); } uint chunkSize = SwapUInt32(br.ReadUInt32()); if (chunkSize != 6) { throw new FormatException("Unexpected header chunk length"); } // 0 = single track, 1 = multi-track synchronous, 2 = multi-track asynchronous fileFormat = SwapUInt16(br.ReadUInt16()); int tracks = SwapUInt16(br.ReadUInt16()); deltaTicksPerQuarterNote = SwapUInt16(br.ReadUInt16()); events = new MidiEventCollection((fileFormat == 0) ? 0 : 1, deltaTicksPerQuarterNote); for (int n = 0; n < tracks; n++) { events.AddTrack(); } long absoluteTime = 0; for (int track = 0; track < tracks; track++) { if (fileFormat == 1) { absoluteTime = 0; } chunkHeader = Encoding.ASCII.GetString(br.ReadBytes(4)); if (chunkHeader != "MTrk") { throw new FormatException("Invalid chunk header"); } chunkSize = SwapUInt32(br.ReadUInt32()); long startPos = br.BaseStream.Position; MidiEvent me = null; List <NoteOnEvent> outstandingNoteOns = new List <NoteOnEvent>(); while (br.BaseStream.Position < startPos + chunkSize) { me = MidiEvent.ReadNextEvent(br, me); absoluteTime += me.DeltaTime; me.AbsoluteTime = absoluteTime; events[track].Add(me); if (me.CommandCode == MidiCommandCode.NoteOn) { NoteEvent ne = (NoteEvent)me; if (ne.Velocity > 0) { outstandingNoteOns.Add((NoteOnEvent)ne); } else { // don't remove the note offs, even though // they are annoying // events[track].Remove(me); FindNoteOn(ne, outstandingNoteOns); } } else if (me.CommandCode == MidiCommandCode.NoteOff) { FindNoteOn((NoteEvent)me, outstandingNoteOns); } else if (me.CommandCode == MidiCommandCode.MetaEvent) { MetaEvent metaEvent = (MetaEvent)me; if (metaEvent.MetaEventType == MetaEventType.EndTrack) { //break; // some dodgy MIDI files have an event after end track if (strictChecking) { if (br.BaseStream.Position < startPos + chunkSize) { throw new FormatException(String.Format("End Track event was not the last MIDI event on track {0}", track)); } } } } } if (outstandingNoteOns.Count > 0) { if (strictChecking) { throw new FormatException(String.Format("Note ons without note offs {0} (file format {1})", outstandingNoteOns.Count, fileFormat)); } } if (br.BaseStream.Position != startPos + chunkSize) { throw new FormatException(String.Format("Read too far {0}+{1}!={2}", chunkSize, startPos, br.BaseStream.Position)); } } } }
/// <summary> /// Constructs a MidiEvent from a BinaryStream /// </summary> /// <param name="br">The binary stream of MIDI data</param> /// <param name="previous">The previous MIDI event (pass null for first event)</param> /// <returns>A new MidiEvent</returns> public static MidiEvent ReadNextEvent(BinaryReader br, MidiEvent previous) { int deltaTime = MidiEvent.ReadVarInt(br); MidiCommandCode commandCode; int channel = 1; byte b = br.ReadByte(); if ((b & 0x80) == 0) { // a running command - command & channel are same as previous commandCode = previous.CommandCode; channel = previous.Channel; br.BaseStream.Position--; // need to push this back } else { if ((b & 0xF0) == 0xF0) { // both bytes are used for command code in this case commandCode = (MidiCommandCode)b; } else { commandCode = (MidiCommandCode)(b & 0xF0); channel = (b & 0x0F) + 1; } } MidiEvent me; switch (commandCode) { case MidiCommandCode.NoteOn: me = new NoteOnEvent(br); break; case MidiCommandCode.NoteOff: case MidiCommandCode.KeyAfterTouch: me = new NoteEvent(br); break; case MidiCommandCode.ControlChange: me = new ControlChangeEvent(br); break; case MidiCommandCode.PatchChange: me = new PatchChangeEvent(br); break; case MidiCommandCode.ChannelAfterTouch: me = new ChannelAfterTouchEvent(br); break; case MidiCommandCode.PitchWheelChange: me = new PitchWheelChangeEvent(br); break; case MidiCommandCode.TimingClock: case MidiCommandCode.StartSequence: case MidiCommandCode.ContinueSequence: case MidiCommandCode.StopSequence: me = new MidiEvent(); break; case MidiCommandCode.Sysex: me = SysexEvent.ReadSysexEvent(br); break; case MidiCommandCode.MetaEvent: me = MetaEvent.ReadMetaEvent(br); break; default: throw new FormatException(String.Format("Unsupported MIDI Command Code {0:X2}", (byte)commandCode)); } me.channel = channel; me.deltaTime = deltaTime; me.commandCode = commandCode; return(me); }
/// <summary> /// Creates a MidiEvent from a raw message received using /// the MME MIDI In APIs /// </summary> /// <param name="rawMessage">The short MIDI message</param> /// <returns>A new MIDI Event</returns> public static MidiEvent FromRawMessage(int rawMessage) { long absoluteTime = 0; int b = rawMessage & 0xFF; int data1 = (rawMessage >> 8) & 0xFF; int data2 = (rawMessage >> 16) & 0xFF; MidiCommandCode commandCode; int channel = 1; if ((b & 0xF0) == 0xF0) { // both bytes are used for command code in this case commandCode = (MidiCommandCode)b; } else { commandCode = (MidiCommandCode)(b & 0xF0); channel = (b & 0x0F) + 1; } MidiEvent me; switch (commandCode) { case MidiCommandCode.NoteOn: case MidiCommandCode.NoteOff: case MidiCommandCode.KeyAfterTouch: if (data2 > 0 && commandCode == MidiCommandCode.NoteOn) { me = new NoteOnEvent(absoluteTime, channel, data1, data2, 0); } else { me = new NoteEvent(absoluteTime, channel, commandCode, data1, data2); } break; case MidiCommandCode.ControlChange: me = new ControlChangeEvent(absoluteTime, channel, (MidiController)data1, data2); break; case MidiCommandCode.PatchChange: me = new PatchChangeEvent(absoluteTime, channel, data1); break; case MidiCommandCode.ChannelAfterTouch: me = new ChannelAfterTouchEvent(absoluteTime, channel, data1); break; case MidiCommandCode.PitchWheelChange: me = new PitchWheelChangeEvent(absoluteTime, channel, data1 + (data2 << 7)); break; case MidiCommandCode.TimingClock: case MidiCommandCode.StartSequence: case MidiCommandCode.ContinueSequence: case MidiCommandCode.StopSequence: case MidiCommandCode.AutoSensing: me = new MidiEvent(absoluteTime, channel, commandCode); break; case MidiCommandCode.MetaEvent: case MidiCommandCode.Sysex: default: throw new FormatException(String.Format("Unsupported MIDI Command Code for Raw Message {0}", commandCode)); } return(me); }
/// <summary> /// Constructs a MidiEvent from a BinaryStream /// </summary> /// <param name="br">The binary stream of MIDI data</param> /// <param name="previous">The previous MIDI event (pass null for first event)</param> /// <returns>A new MidiEvent</returns> // Token: 0x060004C8 RID: 1224 RVA: 0x0000FF78 File Offset: 0x0000E178 public static MidiEvent ReadNextEvent(BinaryReader br, MidiEvent previous) { int num = MidiEvent.ReadVarInt(br); int num2 = 1; byte b = br.ReadByte(); MidiCommandCode midiCommandCode; if ((b & 128) == 0) { midiCommandCode = previous.CommandCode; num2 = previous.Channel; br.BaseStream.Position -= 1L; } else if ((b & 240) == 240) { midiCommandCode = (MidiCommandCode)b; } else { midiCommandCode = (MidiCommandCode)(b & 240); num2 = (int)((b & 15) + 1); } MidiCommandCode midiCommandCode2 = midiCommandCode; MidiEvent midiEvent; if (midiCommandCode2 <= MidiCommandCode.ControlChange) { if (midiCommandCode2 <= MidiCommandCode.NoteOn) { if (midiCommandCode2 != MidiCommandCode.NoteOff) { if (midiCommandCode2 != MidiCommandCode.NoteOn) { goto IL_15F; } midiEvent = new NoteOnEvent(br); goto IL_175; } } else if (midiCommandCode2 != MidiCommandCode.KeyAfterTouch) { if (midiCommandCode2 != MidiCommandCode.ControlChange) { goto IL_15F; } midiEvent = new ControlChangeEvent(br); goto IL_175; } midiEvent = new NoteEvent(br); goto IL_175; } if (midiCommandCode2 <= MidiCommandCode.ChannelAfterTouch) { if (midiCommandCode2 == MidiCommandCode.PatchChange) { midiEvent = new PatchChangeEvent(br); goto IL_175; } if (midiCommandCode2 == MidiCommandCode.ChannelAfterTouch) { midiEvent = new ChannelAfterTouchEvent(br); goto IL_175; } } else { if (midiCommandCode2 == MidiCommandCode.PitchWheelChange) { midiEvent = new PitchWheelChangeEvent(br); goto IL_175; } if (midiCommandCode2 == MidiCommandCode.Sysex) { midiEvent = SysexEvent.ReadSysexEvent(br); goto IL_175; } switch (midiCommandCode2) { case MidiCommandCode.TimingClock: case MidiCommandCode.StartSequence: case MidiCommandCode.ContinueSequence: case MidiCommandCode.StopSequence: midiEvent = new MidiEvent(); goto IL_175; case MidiCommandCode.MetaEvent: midiEvent = MetaEvent.ReadMetaEvent(br); goto IL_175; } } IL_15F: throw new FormatException(string.Format("Unsupported MIDI Command Code {0:X2}", (byte)midiCommandCode)); IL_175: midiEvent.channel = num2; midiEvent.deltaTime = num; midiEvent.commandCode = midiCommandCode; return(midiEvent); }
private void sr_OnTrackEvent(object sender, TrackEventArgs e) { long counter = 0; long notesBefore = TotalNotes; foreach (var ev in e.Events.Where(x => x is MidiUtils.IO.MidiEvent)) { counter++; // Convert the event to NAudio's system so we can get a shortMessage var em = (MidiUtils.IO.MidiEvent)ev; if (ev.Type == EventType.NoteOn) TotalNotes++; MidiEvent me; try { switch (ev.Type) { case EventType.NoteOn: case EventType.NoteOff: case EventType.PolyphonicKeyPressure: if (em.Data2 > 0 && ev.Type == EventType.NoteOn) { me = new NoteOnEvent(ev.Tick, em.Channel + 1, em.Data1, em.Data2, 0); } else { me = new NoteEvent(ev.Tick, em.Channel + 1, (MidiCommandCode)(int)ev.Type, em.Data1, em.Data2); } break; case EventType.ControlChange: me = new ControlChangeEvent(ev.Tick, em.Channel + 1, (MidiController)em.Data1, em.Data2); break; case EventType.ProgramChange: me = new PatchChangeEvent(ev.Tick, em.Channel + 1, em.Data1); break; case EventType.ChannelPressure: me = new ChannelAfterTouchEvent(ev.Tick, em.Channel + 1, em.Data1); break; case EventType.Pitchbend: me = new PitchWheelChangeEvent(ev.Tick, em.Channel + 1, em.Data1 + (em.Data2 << 7)); break; default: throw new InvalidOperationException("Unsupported MIDI event type: " + ev.Type); } } catch (Exception ex) { Exceptions++; continue; } // Send the message try { _midi.Send(me.GetAsShortMessage()); } catch (MmException ex) { if ((int)ex.Result == 67) Overloads++; else Exceptions++; continue; } if (ev.Type == EventType.NoteOn) SuccessNotes++; } PeakNotesPerInterval = Math.Max(PeakNotesPerInterval, TotalNotes - notesBefore); PeakEventsPerInterval = Math.Max(PeakEventsPerInterval, counter); TotalEvents += counter; }
private void ShortcutPopup_Load(object sender, EventArgs e) { if (MIDIController.GetInstance().DevicesCount == 1) { this._MIDIHandler = new EventHandler<MidiInMessageEventArgs>(this.MIDIMessageReceived); MIDIController.GetInstance().AddMessageReceivedHandler(0, this._MIDIHandler); } this.KeyBox.Text = this.Key.ToString(); if (this.Note != null && this.Note.ID > 0 && this.Note.ID <= 128) { NoteEvent n = new NoteEvent(0, 1, MidiCommandCode.NoteOn, this.Note.ID-1, 127); this.PitchBox.Text = n.NoteName; } else { this.PitchBox.Text = "None"; } }
/// <summary> /// Opens a MIDI file for reading /// </summary> /// <param name="filename">Name of MIDI file</param> /// <param name="strictChecking">If true will error on non-paired note events</param> // Token: 0x0600050B RID: 1291 RVA: 0x00010D64 File Offset: 0x0000EF64 public MidiFile(string filename, bool strictChecking) { this.strictChecking = strictChecking; BinaryReader binaryReader = new BinaryReader(File.OpenRead(filename)); using (binaryReader) { string @string = Encoding.UTF8.GetString(binaryReader.ReadBytes(4)); if (@string != "MThd") { throw new FormatException("Not a MIDI file - header chunk missing"); } uint num = MidiFile.SwapUInt32(binaryReader.ReadUInt32()); if (num != 6u) { throw new FormatException("Unexpected header chunk length"); } this.fileFormat = MidiFile.SwapUInt16(binaryReader.ReadUInt16()); int num2 = (int)MidiFile.SwapUInt16(binaryReader.ReadUInt16()); this.deltaTicksPerQuarterNote = MidiFile.SwapUInt16(binaryReader.ReadUInt16()); this.events = new MidiEventCollection((this.fileFormat == 0) ? 0 : 1, (int)this.deltaTicksPerQuarterNote); for (int i = 0; i < num2; i++) { this.events.AddTrack(); } long num3 = 0L; for (int j = 0; j < num2; j++) { if (this.fileFormat == 1) { num3 = 0L; } @string = Encoding.UTF8.GetString(binaryReader.ReadBytes(4)); if (@string != "MTrk") { throw new FormatException("Invalid chunk header"); } num = MidiFile.SwapUInt32(binaryReader.ReadUInt32()); long position = binaryReader.BaseStream.Position; MidiEvent midiEvent = null; List <NoteOnEvent> list = new List <NoteOnEvent>(); while (binaryReader.BaseStream.Position < position + (long)((ulong)num)) { midiEvent = MidiEvent.ReadNextEvent(binaryReader, midiEvent); num3 += (long)midiEvent.DeltaTime; midiEvent.AbsoluteTime = num3; this.events[j].Add(midiEvent); if (midiEvent.CommandCode == MidiCommandCode.NoteOn) { NoteEvent noteEvent = (NoteEvent)midiEvent; if (noteEvent.Velocity > 0) { list.Add((NoteOnEvent)noteEvent); } else { this.FindNoteOn(noteEvent, list); } } else if (midiEvent.CommandCode == MidiCommandCode.NoteOff) { this.FindNoteOn((NoteEvent)midiEvent, list); } else if (midiEvent.CommandCode == MidiCommandCode.MetaEvent) { MetaEvent metaEvent = (MetaEvent)midiEvent; if (metaEvent.MetaEventType == MetaEventType.EndTrack && strictChecking && binaryReader.BaseStream.Position < position + (long)((ulong)num)) { throw new FormatException(string.Format("End Track event was not the last MIDI event on track {0}", j)); } } } if (list.Count > 0 && strictChecking) { throw new FormatException(string.Format("Note ons without note offs {0} (file format {1})", list.Count, this.fileFormat)); } if (binaryReader.BaseStream.Position != position + (long)((ulong)num)) { throw new FormatException(string.Format("Read too far {0}+{1}!={2}", num, position, binaryReader.BaseStream.Position)); } } } }
void ReleaseFM(NoteEvent non) { Parallel.For(0, chs, (i) => { if (atk[i] == null) return; if (non.Channel == atk[i].Channel && non.NoteNumber == atk[i].NoteNumber) { atk[i] = null; time[i] = 0; vel[i] = 0; synth[i].Release(); return; } }); }