public MidiTrack(byte[] instPrograms, byte[] drumPrograms, MidiEvent[] midiEvents) { this.instPrograms = instPrograms; this.drumPrograms = drumPrograms; this.midiEvents = midiEvents; this.notesPlayed = 0; this.totalTime = 0; this.activeChannels = 0; }
public void CombineTracks() { //create a new track of the appropriate size MidiTrack finalTrack = MergeTracks(); MidiEvent[][] absevents = new MidiEvent[mTracks.Length][]; //we have to convert delta times to absolute delta times for (int x = 0; x < absevents.Length; x++) { absevents[x] = new MidiEvent[mTracks[x].MidiEvents.Length]; for (int x2 = 0, totalDeltaTime = 0; x2 < absevents[x].Length; x2++) {//create copies absevents[x][x2] = mTracks[x].MidiEvents[x2]; totalDeltaTime += absevents[x][x2].DeltaTime; absevents[x][x2].DeltaTime = totalDeltaTime; } } //sort by absolute delta time also makes sure events occur in order of track and when they are recieved. int eventcount = 0; int delta = 0; int nextdelta = int.MaxValue; int[] counters = new int[absevents.Length]; while (eventcount < finalTrack.MidiEvents.Length) { for (int x = 0; x < absevents.Length; x++) { while (counters[x] < absevents[x].Length && absevents[x][counters[x]].DeltaTime == delta) { finalTrack.MidiEvents[eventcount] = absevents[x][counters[x]]; eventcount++; counters[x]++; } if (counters[x] < absevents[x].Length && absevents[x][counters[x]].DeltaTime < nextdelta) nextdelta = absevents[x][counters[x]].DeltaTime; } delta = nextdelta; nextdelta = int.MaxValue; } //set total time finalTrack.EndTime = finalTrack.MidiEvents[finalTrack.MidiEvents.Length - 1].DeltaTime; //put back into regular delta time for (int x = 0, deltadiff = 0; x < finalTrack.MidiEvents.Length; x++) { int oldtime = finalTrack.MidiEvents[x].DeltaTime; finalTrack.MidiEvents[x].DeltaTime -= deltadiff; deltadiff = oldtime; } this.mTracks = new MidiTrack[] { finalTrack }; this.mTrackFormat = TrackFormat.SingleTrack; }
private static void TrackVoiceStats(MidiEvent midiEvent, List<byte> instList, List<byte> drumList, ref int channelList, ref int noteOnCount) { if (midiEvent.Command == 0x90) //note on { channelList |= 1 << midiEvent.Channel; noteOnCount++; } else if (midiEvent.Command == 0xC0) //prog change { byte prog = (byte)midiEvent.Data1; if (midiEvent.Channel == MidiHelper.DrumChannel && !drumList.Contains(prog)) { drumList.Add(prog); } else if (!instList.Contains(prog)) { instList.Add(prog); } } }
private void LoadStream(BinaryReader reader) { if (!FindHead(reader, 500)) throw new Exception("Invalid midi file : MThd chunk could not be found."); ReadHeader(reader); try { for (int x = 0; x < mTracks.Length; x++) { mTracks[x] = ReadTrack(reader); } } catch(EndOfStreamException ex) { System.Diagnostics.Debug.WriteLine(ex.Message + "\nWarning: the midi file may not have one or more invalid tracks."); byte[] emptyByte = new byte[0]; MidiEvent[] emptyEvents = new MidiEvent[0]; for (int x = 0; x < mTracks.Length; x++) { if (mTracks[x] == null) mTracks[x] = new MidiTrack(emptyByte, emptyByte, emptyEvents); } } }