/// <summary> /// Initializes a new instance of the Track class. /// </summary> public Track() { MetaMessage msg = new MetaMessage(MetaType.EndOfTrack, 0); MidiEvent e = new MidiEvent(msg, 0); midiEvents.Add(e); }
/// <summary> /// Visits meta messages. /// </summary> /// <param name="message"> /// The meta message to visit. /// </param> /// <remarks> /// This method should not be called by an outside source. /// </remarks> public override void Visit(MetaMessage message) { if (message.Type == MetaType.Tempo) { tempoChangeMessage = message; } }
/// <summary> /// Initializes a new instance of the TimeSignature class with the /// specified meta message. /// </summary> /// <param name="message"> /// The meta message to use for initialization. /// </param> /// <exception cref="ArgumentException"> /// If the specified meta message is not a time signature type. /// </exception> public TimeSignature(MetaMessage message) { // Enforce preconditions. if(message.Type != MetaType.TimeSignature) throw new ArgumentException("Wrong meta message type.", "message"); this.message = (MetaMessage)message.Clone(); }
/// <summary> /// Initializes a new instance of the TimeSignature class. /// </summary> public TimeSignature() { message = new MetaMessage(MetaType.TimeSignature, MetaMessage.TimeSigLength); Numerator = DefaultNumerator; Denominator = DefaultDenominator; ClocksPerMetronomeClick = DefaultClocksPerMetronomeClick; ThirtySecondNotesPerQuarterNote = DefaultThirtySecondNotesPerQuarterNote; }
/// <summary> /// Initializes a new instance of the TimeSignature class with the /// specified meta message. /// </summary> /// <param name="message"> /// The meta message to use for initialization. /// </param> /// <exception cref="ArgumentException"> /// If the specified meta message is not a time signature type. /// </exception> public TimeSignature(MetaMessage message) { // Enforce preconditions. if (message.Type != MetaType.TimeSignature) { throw new ArgumentException("Wrong meta message type.", "message"); } this.message = (MetaMessage)message.Clone(); }
/// <summary> /// Visits meta messages. /// </summary> /// <param name="message"> /// The meta message to visit. /// </param> public override void Visit(MetaMessage message) { midiStream.WriteByte((byte)message.Status); midiStream.WriteByte((byte)message.Type); WriteVariableLengthQuantity(message.Length); for (int i = 0; i < message.Length; i++) { midiStream.WriteByte(message[i]); } }
/// <summary> /// Visit meta messages. /// </summary> /// <param name="message"> /// The message to visit. /// </param> public override void Visit(MetaMessage message) { // If this is a tempo change message, change the tempo of the tick // generator. if (message.Type == MetaType.Tempo) { TempoChange change = new TempoChange(message); //tickGen.Tempo = change.Tempo; tickGen.Tempo = 60000000f / change.Tempo; } }
/// <summary> /// Initializes a new instance of the MetaMessageText class with the /// specified meta message. /// </summary> /// <param name="message"> /// The meta message to use for initialization. /// </param> /// <exception cref="ArgumentException"> /// If the meta message is not a text based type. /// </exception> /// <remarks> /// The meta message must be one of the following text based types: /// <list> /// <item> /// Copyright /// </item> /// <item> /// Cuepoint /// </item> /// <item> /// DeviceName /// </item> /// <item> /// InstrumentName /// </item> /// <item> /// Lyric /// </item> /// <item> /// Marker /// </item> /// <item> /// ProgramName /// </item> /// <item> /// Text /// </item> /// <item> /// TrackName /// </item> /// </list> /// If the meta message is not a text based type, an exception will be /// thrown. /// </remarks> public MetaMessageText(MetaMessage message) { // Enforce preconditions. if (!IsTextType(message.Type)) { throw new ArgumentException("Not text based meta message.", "message"); } this.message = (MetaMessage)message.Clone(); this.type = message.Type; }
/// <summary> /// Initializes the MIDI chaser. /// </summary> private void Initialize() { channelPressureMessage = null; polyPressureMessage = null; programChangeMessage = null; pitchBendMessage = null; for (int i = 0; i < controllers.Length; i++) { controllers[i] = null; } tempoChangeMessage = null; }
/// <summary> /// Removes all but the last MIDI event from the track. /// </summary> /// <remarks> /// The very last message in a track is an end of track meta message /// This message must be present at the end of all tracks. When a track /// is cleared, all but the last message are removed; The end of track /// message is left so that the track remains valid after it has been /// cleared. /// </remarks> public void Clear() { // Enforce preconditions. if (IsLocked()) { throw new InvalidOperationException( "Cannot modify track. It is currently locked"); } midiEvents.Clear(); MetaMessage msg = new MetaMessage(MetaType.EndOfTrack, 0); midiEvents.Add(new MidiEvent(msg, 0)); version++; }
private bool IsTrackNameMetaMessage(IMidiMessage message) { // Guard. if (!(message is MetaMessage)) { return(false); } MetaMessage msg = (MetaMessage)message; if (msg.Type == MetaType.TrackName) { return(true); } else { return(false); } }
/// <summary> /// /// </summary> /// <param name="message"></param> public virtual void Visit(MetaMessage message) { }
/// <summary> /// Initializes a new instance of the MetaMessage class with /// another instance of the MetaMessage class. /// </summary> /// <param name="message"> /// The MetaMessage instance to use for initialization. /// </param> public MetaMessage(MetaMessage message) { type = message.type; data = new byte[message.data.Length]; message.data.CopyTo(data, 0); }
/// <summary> /// Reads the data for the next track from the Midi file. /// </summary> /// <param name="trackNum"> /// The track number. /// </param> private void ReadNextTrack(int trackNum) { int status = 0; int runningStatus = 0; // Read length of track. binReader.ReadBytes(LengthByteCount); // Continue reading Midi events until the end of the track. while (true) { // Next Midi message in track. IMidiMessage msg = null; // Ticks for next Midi event. int ticks = ReadVariableLengthQuantity(); // Read status byte for the next Midi message. status = binReader.ReadByte(); // If this is a status byte. if ((status & StatusFlag) == StatusFlag) { // If the next Midi message is a channel message. if (ChannelMessage.IsChannelMessage(status)) { // Read channel message from the Midi file. msg = ReadChannelMessage(status); // Update running status. runningStatus = status; } // Else if the next Midi message is a meta message. else if (MetaMessage.IsMetaMessage(status)) { // Read the type of meta message. MetaType mType = (MetaType)binReader.ReadByte(); // If this is the end of the track. if (mType == MetaType.EndOfTrack) { // Make sure end of track message has the same // ticks value as the end of track message in the // file. tracks[trackNum].Slide(tracks[trackNum].Count - 1, ticks); // Break out of loop - finished with this track. break; } // Read the length of the meta message data. int length = ReadVariableLengthQuantity(); // Read the meta message data. byte[] data = binReader.ReadBytes(length); // Create meta message. msg = new MetaMessage(mType, data); } // Else if the next Midi message is a system exclusive // message. else if (SysExMessage.IsSysExMessage(status)) { // The type of system exclusive message. SysExType type = (SysExType)status; // Read the length of the system exclusive data. int length = ReadVariableLengthQuantity(); // Read the system exclusive data. byte[] data = binReader.ReadBytes(length); // Create system exclusive message. msg = new SysExMessage(type, data); } } // Assumes running status. else { // Create channel message. msg = ReadChannelMessage(runningStatus, status); } // Create the next Midi event and store it in the specified // track. MidiEvent e = new MidiEvent(msg, ticks); tracks[trackNum].Add(e); } }
/// <summary> /// Initializes a new instance of the TempoChange class. /// </summary> public TempoChange() { message = new MetaMessage(MetaType.Tempo, MetaMessage.TempoLength); Tempo = DefaultTempo; }
/// <summary> /// Visit meta messages. /// </summary> /// <param name="message"> /// The message to visit. /// </param> public override void Visit(MetaMessage message) { // If this is a tempo change message, change the tempo of the tick // generator. if(message.Type == MetaType.Tempo) { TempoChange change = new TempoChange(message); //tickGen.Tempo = change.Tempo; tickGen.Tempo = 60000000f/change.Tempo; } }
/// <summary> /// Reads the data for the next track from the Midi file. /// </summary> /// <param name="trackNum"> /// The track number. /// </param> private void ReadNextTrack(int trackNum) { int status = 0; int runningStatus = 0; // Read length of track. binReader.ReadBytes(LengthByteCount); // Continue reading Midi events until the end of the track. while(true) { // Next Midi message in track. IMidiMessage msg = null; // Ticks for next Midi event. int ticks = ReadVariableLengthQuantity(); // Read status byte for the next Midi message. status = binReader.ReadByte(); // If this is a status byte. if((status & StatusFlag) == StatusFlag) { // If the next Midi message is a channel message. if(ChannelMessage.IsChannelMessage(status)) { // Read channel message from the Midi file. msg = ReadChannelMessage(status); // Update running status. runningStatus = status; } // Else if the next Midi message is a meta message. else if(MetaMessage.IsMetaMessage(status)) { // Read the type of meta message. MetaType mType = (MetaType)binReader.ReadByte(); // If this is the end of the track. if(mType == MetaType.EndOfTrack) { // Make sure end of track message has the same // ticks value as the end of track message in the // file. tracks[trackNum].Slide(tracks[trackNum].Count - 1, ticks); // Break out of loop - finished with this track. break; } // Read the length of the meta message data. int length = ReadVariableLengthQuantity(); // Read the meta message data. byte[] data = binReader.ReadBytes(length); // Create meta message. msg = new MetaMessage(mType, data); } // Else if the next Midi message is a system exclusive // message. else if(SysExMessage.IsSysExMessage(status)) { // The type of system exclusive message. SysExType type = (SysExType)status; // Read the length of the system exclusive data. int length = ReadVariableLengthQuantity(); // Read the system exclusive data. byte[] data = binReader.ReadBytes(length); // Create system exclusive message. msg = new SysExMessage(type, data); } } // Assumes running status. else { // Create channel message. msg = ReadChannelMessage(runningStatus, status); } // Create the next Midi event and store it in the specified // track. MidiEvent e = new MidiEvent(msg, ticks); tracks[trackNum].Add(e); } }
/// <summary> /// Initializes the MIDI chaser. /// </summary> private void Initialize() { channelPressureMessage = null; polyPressureMessage = null; programChangeMessage = null; pitchBendMessage = null; for(int i = 0; i < controllers.Length; i++) { controllers[i] = null; } tempoChangeMessage = null; }
/// <summary> /// Visits meta messages. /// </summary> /// <param name="message"> /// The meta message to visit. /// </param> /// <remarks> /// This method should not be called by an outside source. /// </remarks> public override void Visit(MetaMessage message) { if(message.Type == MetaType.Tempo) { tempoChangeMessage = message; } }
/// <summary> /// Removes all but the last MIDI event from the track. /// </summary> /// <remarks> /// The very last message in a track is an end of track meta message /// This message must be present at the end of all tracks. When a track /// is cleared, all but the last message are removed; The end of track /// message is left so that the track remains valid after it has been /// cleared. /// </remarks> public void Clear() { // Enforce preconditions. if(IsLocked()) throw new InvalidOperationException( "Cannot modify track. It is currently locked"); midiEvents.Clear(); MetaMessage msg = new MetaMessage(MetaType.EndOfTrack, 0); midiEvents.Add(new MidiEvent(msg, 0)); version++; }
/// <summary> /// Initializes a new instance of the MetaMessageText class with the /// specified meta message. /// </summary> /// <param name="message"> /// The meta message to use for initialization. /// </param> /// <exception cref="ArgumentException"> /// If the meta message is not a text based type. /// </exception> /// <remarks> /// The meta message must be one of the following text based types: /// <list> /// <item> /// Copyright /// </item> /// <item> /// Cuepoint /// </item> /// <item> /// DeviceName /// </item> /// <item> /// InstrumentName /// </item> /// <item> /// Lyric /// </item> /// <item> /// Marker /// </item> /// <item> /// ProgramName /// </item> /// <item> /// Text /// </item> /// <item> /// TrackName /// </item> /// </list> /// If the meta message is not a text based type, an exception will be /// thrown. /// </remarks> public MetaMessageText(MetaMessage message) { // Enforce preconditions. if(!IsTextType(message.Type)) throw new ArgumentException("Not text based meta message.", "message"); this.message = (MetaMessage)message.Clone(); this.type = message.Type; }
/// <summary> /// Visits meta messages. /// </summary> /// <param name="message"> /// The meta message to visit. /// </param> public override void Visit(MetaMessage message) { midiStream.WriteByte((byte)message.Status); midiStream.WriteByte((byte)message.Type); WriteVariableLengthQuantity(message.Length); for(int i = 0; i < message.Length; i++) { midiStream.WriteByte(message[i]); } }