/// <summary> /// Initializes a new instance of the Track class with another instance /// of the Track class. /// </summary> /// <param name="trk"> /// The Track instance to use for initialization. /// </param> public Track(Track trk) { // Copy events from the existing track into this one. foreach(MidiEvent e in trk.MidiEvents) { this.MidiEvents.Add(e.Clone()); } }
/// <summary> /// Reads the number of tracks in the Midi file. /// </summary> /// <returns> /// <b>MidiFileResult.Succes</b> if the track count and format type /// are valid; otherwise, <b>MidiFileResult.InvalidFormat</b>. /// </returns> private MidiFileResult ReadTrackCount() { MidiFileResult result = MidiFileResult.Success; byte[] trackCount = binReader.ReadBytes(TrackCountByteCount); // Convert array to the same byte order as this platform. ConvertByteArray(trackCount); // Convert array to number. tracks = new Track[BitConverter.ToInt16(trackCount, 0)]; // If there are more than one track and the Midi file is type 0. if(tracks.Length > 1 && Format == 0) { // Indicate that the format is invalid. A type 0 Midi file can // only have one track. result = MidiFileResult.InvalidFormat; } // If the format is valid. if(result == MidiFileResult.Success) { // Allocate tracks. for(int i = 0; i < tracks.Length; i++) { tracks[i] = new Track(); } } return result; }
/// <summary> /// Adds a track to the Sequence. /// </summary> /// <param name="trk"> /// The track to add to the Sequence. /// </param> public void Add(Track trk) { tracks.Add(new TrackInfo(trk)); // Indicate that the sequence has changed. dirty = true; }
/// <summary> /// Initializes a new instance of the TrackInfo class with the /// specified track. /// </summary> /// <param name="trk"> /// The Track. /// </param> public TrackInfo(Track trk) { this.trk = trk; version = trk.Version; }
/// <summary> /// Merge only Tracks that are soloed. /// </summary> private void MergeSoloTracks() { // For each track in the Sequence. foreach(TrackInfo info in tracks) { // If the track is soloed and not muted. if(info.trk.Solo && !info.trk.Mute) { // Merge track. mergedTrack = Track.Merge(mergedTrack, info.trk); } } }
/// <summary> /// Gets all of the Tracks in the Sequence merged into one Track. /// </summary> /// <returns> /// The Tracks in the Sequence merged into one Track. /// </returns> /// <remarks> /// Only Tracks that are not muted are merged into one Track. Also, if /// any of the Tracks have been soloed, only those Tracks are merged. /// </remarks> public Track GetMergedTrack() { // If the Sequence has been changed. if(IsDirty()) { mergedTrack = new Track(); // If any of the tracks have been soloed. if(IsSolo()) { // Merge only the solo tracks. MergeSoloTracks(); } // Else none of the tracks have been soloed. else { // For each track in the sequence. foreach(TrackInfo info in tracks) { // If the track is not muted. if(!info.trk.Mute) { // Merge track. mergedTrack = Track.Merge(mergedTrack, info.trk); } } } // Update versioning information. foreach(TrackInfo info in tracks) { info.version = info.trk.Version; } // Indicate that the merged track has been updated. dirty = false; } return mergedTrack; }
/// <summary> /// Merges two tracks together. /// </summary> /// <param name="trackA"> /// The first of two tracks to merge. /// </param> /// <param name="trackB"> /// The second of two tracks to merge. /// </param> /// <returns> /// The merged track. /// </returns> public static Track Merge(Track trackA, Track trackB) { Track trkA = new Track(trackA); Track trkB = new Track(trackB); Track mergedTrack = new Track(); int a = 0, b = 0; // // The following algorithm merges two Midi tracks together. It // assumes that both tracks are valid in that both end with a // end of track meta message. // // While neither the end of track A or track B has been reached. while(a < trkA.Count - 1 && b < trkB.Count - 1) { // While the end of track A has not been reached and the // current Midi event in track A comes before the current Midi // event in track B. while(a < trkA.Count - 1 && trkA[a].Ticks <= trkB[b].Ticks) { // Slide the events in track B backwards by the amount of // ticks in the current event in track A. This keeps both // tracks in sync. trkB.Slide(b, -trkA[a].Ticks); // Add the current event in track A to the merged track. mergedTrack.Add(trkA[a]); // Move to the next Midi event in track A. a++; } // If the end of track A has not yet been reached. if(a < trkA.Count - 1) { // While the end of track B has not been reached and the // current Midi event in track B comes before the current Midi // event in track A. while(b < trkB.Count - 1 && trkB[b].Ticks < trkA[a].Ticks) { // Slide the events in track A backwards by the amount of // ticks in the current event in track B. This keeps both // tracks in sync. trkA.Slide(a, -trkB[b].Ticks); // Add the current event in track B to the merged track. mergedTrack.Add(trkB[b]); // Move forward to the next Midi event in track B. b++; } } } // If the end of track A has not yet been reached. if(a < trkA.Count - 1) { // Add the rest of the events in track A to the merged track. while(a < trkA.Count) { mergedTrack.Add(trkA[a]); a++; } } // Else if the end of track B has not yet been reached. else if(b < trkB.Count - 1) { // Add the rest of the events in track B to the merged track. while(b < trkB.Count) { mergedTrack.Add(trkB[b]); b++; } } return mergedTrack; }
public void beginRecording(int instrument) { stopallnotes(); //add new track! Track newtrack = new Track(); int nchannel = getCurChannelRecording() + 1; //Set instrument builder.Command = ChannelCommand.ProgramChange; builder.MidiChannel = nchannel; builder.Data1 = instrument; builder.Build(); newtrack.Insert(0, builder.Result); this.midiFilePlayer1.sequence.Add(newtrack); //Also important: send event to the output device. outDevice.Send(builder.Result); recordTicks = new ArrayList(); recordNotes = new ArrayList(); midiFilePlayer1.Start(); isRecording = true; }