public void Write_Compression_DeleteDefaultKeySignature_Obsolete() { var nonDefaultKeySignatureEvent = new KeySignatureEvent(-5, 1); var midiFile = new MidiFile( new TrackChunk( new NoteOnEvent((SevenBitNumber)100, (SevenBitNumber)50), new NoteOffEvent((SevenBitNumber)100, (SevenBitNumber)50), new UnknownMetaEvent(254), new KeySignatureEvent(), nonDefaultKeySignatureEvent)); Write_Compression_Obsolete( midiFile, CompressionPolicy.DeleteDefaultKeySignature, (fileInfo1, fileInfo2) => { var originalMidiFile = MidiFile.Read(fileInfo1.FullName); Assert.AreEqual( 2, originalMidiFile.GetTrackChunks().SelectMany(c => c.Events).OfType <KeySignatureEvent>().Count(), "Invalid count of Key Signature events in original file."); var newMidiFile = MidiFile.Read(fileInfo2.FullName); var keySignatureEvents = newMidiFile.GetTrackChunks().SelectMany(c => c.Events).OfType <KeySignatureEvent>().ToArray(); Assert.AreEqual( 1, keySignatureEvents.Length, "Invalid count of Key Signature events in new file."); MidiAsserts.AreEventsEqual(keySignatureEvents[0], nonDefaultKeySignatureEvent, false, "Invalid Key Signature event."); }); }
public void Write_DeleteDefaultKeySignature_DeleteDefaultSetTempo() { var nonDefaultKeySignatureEvent = new KeySignatureEvent(-5, 1); var nonDefaultSetTempoEvent = new SetTempoEvent(100000); var midiFile = new MidiFile( new TrackChunk( new NoteOnEvent((SevenBitNumber)100, (SevenBitNumber)50), new NoteOffEvent((SevenBitNumber)100, (SevenBitNumber)50), new UnknownMetaEvent(254), new KeySignatureEvent(), nonDefaultKeySignatureEvent, new SetTempoEvent(), nonDefaultSetTempoEvent)); Write( midiFile, settings => { settings.DeleteDefaultKeySignature = true; settings.DeleteDefaultSetTempo = true; }, (fileInfo1, fileInfo2) => { var originalMidiFile = MidiFile.Read(fileInfo1.FullName); var newMidiFile = MidiFile.Read(fileInfo2.FullName); // Assert.AreEqual( 2, originalMidiFile.GetTrackChunks().SelectMany(c => c.Events).OfType <KeySignatureEvent>().Count(), "Invalid count of Key Signature events in original file."); var keySignatureEvents = newMidiFile.GetTrackChunks().SelectMany(c => c.Events).OfType <KeySignatureEvent>().ToArray(); Assert.AreEqual( 1, keySignatureEvents.Length, "Invalid count of Key Signature events in new file."); MidiAsserts.AreEventsEqual(keySignatureEvents[0], nonDefaultKeySignatureEvent, false, "Invalid Key Signature event."); // Assert.AreEqual( 2, originalMidiFile.GetTrackChunks().SelectMany(c => c.Events).OfType <SetTempoEvent>().Count(), "Invalid count of Set Tempo events in original file."); var setTempoEvents = newMidiFile.GetTrackChunks().SelectMany(c => c.Events).OfType <SetTempoEvent>().ToArray(); Assert.AreEqual( 1, setTempoEvents.Length, "Invalid count of Set Tempo events in new file."); MidiAsserts.AreEventsEqual(setTempoEvents[0], nonDefaultSetTempoEvent, false, "Invalid Set Tempo event."); }); }
private bool HasKeySignature(string midiFileName) { MidiFile midiFile = new MidiFile(midiFileName); bool foundKeySignature = false; for (int track = 0; track < midiFile.Tracks; track++) { foreach (MidiEvent midiEvent in midiFile.Events[track]) { KeySignatureEvent kse = midiEvent as KeySignatureEvent; if (kse != null) { foundKeySignature = true; } } } return(foundKeySignature); }
public int getKey() { // Assume C int key = 0; // For each track in the file for (int track = 0; track < m_data.Tracks; track++) { // For each MidiEvent in the track foreach (MidiEvent e in m_data[track]) { // If this is a MetaEvent if (e.CommandCode == MidiCommandCode.MetaEvent) { // Check if the type of event is KeySignatureEvent if (e is KeySignatureEvent) { // Good. We have a key! Cast it. KeySignatureEvent n = (KeySignatureEvent)e; // Representation is: // -: # of flats (to -7) // 0: C // +: # of sharps (to +7) // Directly read in the value key = n.SharpsFlats; // HACKHACK: The documentation for NAUDIO // is incorrect. Flat keys are stored as 255 // minus a key adjustment amount. This corrects // it down to the -7 to 0 range expected. if (key > 7) { key = -1 * (255 - key + 1); } } } } } // Return it return(key); }
public IMessage getMessage(MetaEvent metaEvent) { switch (metaEvent.MetaEventType) { case SetTempo: TempoEvent tempoEvent = (TempoEvent)metaEvent; TempoMetaMessage message = TempoMetaMessage(tempoEvent.Tempo, tempoEvent.AbsoluteTime); return(message); case TimeSignature: TimeSignatureEvent timeSignatureEvent = (TimeSignatureEvent)metaEvent; TimeSignatureMetaMessage message = TimeSignatureMetaMessage(timeSignatureEvent.Numerator, timeSignatureEvent.Numerator, timeSignatureEvent.AbsoluteTime); return(message); case KeySignature: KeySignatureEvent keySignatureEvent = (KeySignatureEvent)metaEvent; TimeSignatureMetaMessage message = TimeSignatureMetaMessage((sbyte)keySignatureEvent.SharpsFlats, (byte)keySignatureEvent.MajorMinor, timeSignatureEvent.AbsoluteTime); return(message); default: return(null); // TODO remaining MetaMessage types } }
private static Tuple <Option <MidiEvent>, int, byte> NextEvent(List <byte> trackData, int startIndex, byte lastMidiChannel) { var i = startIndex - 1; MidiEvent midiEvent = null; { int deltaTime; { var lengthTemp = new List <byte>(); do { i += 1; lengthTemp.Add(trackData.ElementAt(i)); } while (trackData.ElementAt(i) > 0x7F); deltaTime = VariableLengthUtil.decode_to_int(lengthTemp); } i += 1; var eventTypeValue = trackData.ElementAt(i); // MIDI Channel Events if ((eventTypeValue & 0xF0) < 0xF0) { var midiChannelEventType = (byte)(eventTypeValue & 0xF0); var midiChannel = (byte)(eventTypeValue & 0x0F); i += 1; var parameter1 = trackData.ElementAt(i); byte parameter2; // One or two parameter type switch (midiChannelEventType) { // One parameter types case 0xC0: midiEvent = new ProgramChangeEvent(deltaTime, midiChannel, parameter1); lastMidiChannel = midiChannel; break; case 0xD0: midiEvent = new ChannelAftertouchEvent(deltaTime, midiChannel, parameter1); lastMidiChannel = midiChannel; break; // Two parameter types case 0x80: i += 1; parameter2 = trackData.ElementAt(i); midiEvent = new NoteOffEvent(deltaTime, midiChannel, parameter1, parameter2); lastMidiChannel = midiChannel; break; case 0x90: i += 1; parameter2 = trackData.ElementAt(i); midiEvent = new NoteOnEvent(deltaTime, midiChannel, parameter1, parameter2); lastMidiChannel = midiChannel; break; case 0xA0: i += 1; parameter2 = trackData.ElementAt(i); midiEvent = new NoteAftertouchEvent(deltaTime, midiChannel, parameter1, parameter2); lastMidiChannel = midiChannel; break; case 0xB0: i += 1; parameter2 = trackData.ElementAt(i); midiEvent = new ControllerEvent(deltaTime, midiChannel, parameter1, parameter2); lastMidiChannel = midiChannel; break; case 0xE0: i += 1; parameter2 = trackData.ElementAt(i); midiEvent = new PitchBendEvent(deltaTime, midiChannel, parameter1, parameter2); lastMidiChannel = midiChannel; break; // Might be a Control Change Messages LSB default: midiEvent = new ControllerEvent(deltaTime, lastMidiChannel, eventTypeValue, parameter1); break; } i += 1; } // Meta Events else if (eventTypeValue == 0xFF) { i += 1; var metaEventType = trackData.ElementAt(i); i += 1; var metaEventLength = trackData.ElementAt(i); i += 1; var metaEventData = Enumerable.Range(i, metaEventLength).Select(trackData.ElementAt).ToArray(); switch (metaEventType) { case 0x00: midiEvent = new SequenceNumberEvent(BitConverter.ToUInt16(metaEventData.Reverse().ToArray(), 0)); break; case 0x01: midiEvent = new TextEvent(deltaTime, StringEncoder.GetString(metaEventData)); break; case 0x02: midiEvent = new CopyrightNoticeEvent(StringEncoder.GetString(metaEventData)); break; case 0x03: midiEvent = new SequenceOrTrackNameEvent(StringEncoder.GetString(metaEventData)); break; case 0x04: midiEvent = new InstrumentNameEvent(deltaTime, StringEncoder.GetString(metaEventData)); break; case 0x05: midiEvent = new LyricsEvent(deltaTime, StringEncoder.GetString(metaEventData)); break; case 0x06: midiEvent = new MarkerEvent(deltaTime, StringEncoder.GetString(metaEventData)); break; case 0x07: midiEvent = new CuePointEvent(deltaTime, StringEncoder.GetString(metaEventData)); break; case 0x20: midiEvent = new MIDIChannelPrefixEvent(deltaTime, metaEventData[0]); break; case 0x2F: midiEvent = new EndOfTrackEvent(deltaTime); break; case 0x51: var tempo = (metaEventData[2] & 0x0F) + ((metaEventData[2] & 0xF0) * 16) + ((metaEventData[1] & 0x0F) * 256) + ((metaEventData[1] & 0xF0) * 4096) + ((metaEventData[0] & 0x0F) * 65536) + ((metaEventData[0] & 0xF0) * 1048576); midiEvent = new SetTempoEvent(deltaTime, tempo); break; case 0x54: midiEvent = new SMPTEOffsetEvent(deltaTime, metaEventData[0], metaEventData[1], metaEventData[2], metaEventData[3], metaEventData[4]); break; case 0x58: midiEvent = new TimeSignatureEvent(deltaTime, metaEventData[0], metaEventData[1], metaEventData[2], metaEventData[3]); break; case 0x59: midiEvent = new KeySignatureEvent(deltaTime, metaEventData[0], metaEventData[1]); break; case 0x7F: midiEvent = new SequencerSpecificEvent(deltaTime, metaEventData); break; } i += metaEventLength; } // System Exclusive Events else if (eventTypeValue == 0xF0 || eventTypeValue == 0xF7) { var lengthTemp = new List <byte>(); do { i += 1; lengthTemp.Add(trackData.ElementAt(i)); } while (trackData.ElementAt(i) > 0x7F); var eventLength = VariableLengthUtil.decode_to_int(lengthTemp); i += 1; var eventData = Enumerable.Range(i, eventLength).Select(trackData.ElementAt); midiEvent = new SysexEvent(deltaTime, eventTypeValue, eventData); i += eventLength; } } return(midiEvent != null ? new Tuple <Option <MidiEvent>, int, byte>(new Some <MidiEvent>(midiEvent), i - startIndex, lastMidiChannel) : new Tuple <Option <MidiEvent>, int, byte>(new None <MidiEvent>(), i - startIndex, lastMidiChannel)); }
private void CreateTrackZeroEvents(List<MidiEvent> trackZeroEvents, MidiFile midiFile, long startAbsoluteTime, long endAbsoluteTime, bool includeAllTrackEvents) { MetaEvent tempoEvent = null; MetaEvent keySignatureEvent = null; MetaEvent timeSignatureEvent = null; bool gotAStartTempo = false; bool gotAStartKeySig = false; bool gotAStartTimeSig = false; for (int track = 0; track < ((includeAllTrackEvents) ? midiFile.Tracks : 1); track++) { foreach (MidiEvent midiEvent in midiFile.Events[track]) { if ((midiEvent.AbsoluteTime >= startAbsoluteTime) && (midiEvent.AbsoluteTime < endAbsoluteTime)) { bool exclude = false; MetaEvent metaEvent = midiEvent as MetaEvent; if (metaEvent != null) { if (metaEvent.MetaEventType == MetaEventType.EndTrack) { // we'll add our own exclude = true; } if (metaEvent.AbsoluteTime == startAbsoluteTime) { switch (metaEvent.MetaEventType) { case MetaEventType.SetTempo: gotAStartTempo = true; break; case MetaEventType.KeySignature: gotAStartKeySig = true; break; case MetaEventType.TimeSignature: gotAStartTimeSig = true; break; case MetaEventType.Marker: // already done this elsewhere exclude = true; break; case MetaEventType.TextEvent: // exclude if text events as markers is on exclude = settings.TextEventMarkers; break; } } } else { exclude = !includeAllTrackEvents; } if (!exclude) { AddMidiEvent(midiEvent, trackZeroEvents, endAbsoluteTime); } } else if (midiEvent.AbsoluteTime < startAbsoluteTime) { // TODO: perhaps look out for a patch change too MetaEvent metaEvent = midiEvent as MetaEvent; if (metaEvent != null) { switch (metaEvent.MetaEventType) { case MetaEventType.TextEvent: case MetaEventType.Copyright: case MetaEventType.SequenceTrackName: //TextEvent te = (TextEvent)metaEvent; //trackZeroEvents.Add(new TextEvent(te.Text, metaEvent.MetaEventType, startAbsoluteTime)); break; case MetaEventType.KeySignature: KeySignatureEvent kse = (KeySignatureEvent)metaEvent; keySignatureEvent = new KeySignatureEvent(kse.SharpsFlats, kse.MajorMinor, startAbsoluteTime); break; case MetaEventType.SetTempo: tempoEvent = new TempoEvent(((TempoEvent)metaEvent).MicrosecondsPerQuarterNote, startAbsoluteTime); ; break; case MetaEventType.TimeSignature: TimeSignatureEvent tse = (TimeSignatureEvent)metaEvent; timeSignatureEvent = new TimeSignatureEvent(tse.Numerator, tse.Denominator, tse.TicksInMetronomeClick, tse.No32ndNotesInQuarterNote, startAbsoluteTime); break; case MetaEventType.TrackSequenceNumber: // TODO: needed? break; case MetaEventType.TrackInstrumentName: case MetaEventType.Lyric: case MetaEventType.CuePoint: case MetaEventType.Marker: case MetaEventType.SequencerSpecific: case MetaEventType.DeviceName: case MetaEventType.ProgramName: case MetaEventType.SmpteOffset: case MetaEventType.EndTrack: // ignore these break; default: //System.Diagnostics.Debug.Assert(false, String.Format("Unexpected meta event type {0}", metaEvent)); break; } } } } } if ((tempoEvent != null) && (!gotAStartTempo)) trackZeroEvents.Add(tempoEvent); if ((keySignatureEvent != null) && (!gotAStartKeySig)) trackZeroEvents.Add(keySignatureEvent); if ((timeSignatureEvent != null) && (!gotAStartTimeSig)) trackZeroEvents.Add(timeSignatureEvent); // add an end track marker trackZeroEvents.Sort(new MidiEventComparer()); trackZeroEvents.Add(new MetaEvent(MetaEventType.EndTrack,0,trackZeroEvents[trackZeroEvents.Count-1].AbsoluteTime)); }
public static Key GetKeyFromKeySignature(KeySignatureEvent keySignature) { // major = 0 ~ 11 / minor = 21 ~ 23, 12 ~ 20 int k = 0; switch (keySignature.SharpsFlats) { case 0: // C break; case -5: // Db = C# case 7: k += 1; break; case 2: // D k += 2; break; case -3: // Eb k += 3; break; case 4: // E k += 4; break; case -1: // F k += 5; break; case -6: // Gb = F# case 6: k += 6; break; case 1: // G k += 7; break; case -4: // Ab k += 8; break; case 3: // A k += 9; break; case -2: // Bb k += 10; break; case 5: // B = Cb case -7: k += 11; break; } if (keySignature.MajorMinor == 0) { // major return((Key)k); } else { // minor return((Key)(((k + 9) % 12) + 12)); } }