static private MIDIEvent ReadEvent(int deltaTicks) { MIDIEvent midiEvent = null; if (IsSysExEvent()) { DiscardSysExEvent(); } else if (IsMetaEvent()) { midiEvent = ReadMetaEvent(deltaTicks); } else { // Handle running status // (the status byte is omitted if the current event is supposed to have the same status as the last event) if ((m_status & 0b10000000) == 0) { m_status = m_prevStatus; m_index--; } midiEvent = ReadChannelEvent(deltaTicks); m_prevStatus = m_status; } return(midiEvent); }
private void NotifyEvent(MIDIEvent midiEvent, int trackNumber) { foreach (MIDISongListener m_songListener in m_songListeners) { m_songListener.OnSongEvent(midiEvent, trackNumber); } }
private void NotifyEvent(MIDIEvent midiEvent) { foreach (MIDIDeviceListener deviceListener in m_deviceListeners) { deviceListener.OnDeviceEvent(midiEvent); } }
static private void ReadTrack() { MIDITrack track = new MIDITrack(); track.events = new List <MIDIEvent>(); string trackChunkType = ReadString(4); if (!trackChunkType.Equals("MTrk")) { throw new System.FormatException("No track chunk type has been found."); } int trackChunkLength = ReadInt32(); uint trackChunkEnd = m_index + (uint)trackChunkLength; int accumulatedDeltaTicks = 0; m_prevStatus = 0; while (m_index < trackChunkEnd) { int deltaTicks = ReadVariableLengthInt(); accumulatedDeltaTicks += deltaTicks; m_status = ReadByte(); MIDIEvent midiEvent = ReadEvent(accumulatedDeltaTicks); if (midiEvent != null) { track.events.Add(midiEvent); accumulatedDeltaTicks = 0; } } m_song.tracks.Add(track); }
MIDINote ParseNoteOffEvent(FileStream inFile, MIDIEvent midi_event) { MIDINote note; if (inFile != null) { note = new MIDINote(midi_event); note.note = (UInt32)inFile.ReadByte(); note.velocity = (UInt32)inFile.ReadByte(); } else { note = (MIDINote)midi_event; } if (this.currentNotes.ContainsKey(note.note)) { this.currentNotes[note.note].duration = CurrentTime() - note.absoluteStartTime; this.currentNotes.Remove(note.note); } else { Debug.LogWarning("try to access not existing note: " + note.note); } return(note); }
/// <summary> /// MIDIデータに歌詞を追加します。 /// </summary> private void MakeLyric(MIDITrack midiTrack, List <MeasureAndTextBox> measures) { RemoveLyric(midiTrack); foreach (MeasureAndTextBox measure in measures) { StringBuilder stringBuilder = new StringBuilder(measure.Lyric); for (int i = 0; i < measure.MidiEvent.Length; i++) { if (stringBuilder.Length <= 0) { break; } string lyricChar = stringBuilder[0].ToString(); //先頭の文字を取得 stringBuilder.Remove(0, 1); //先頭の文字を削除 //次の文字が小文字の場合、一緒に歌詞に含める。 if (IsFirstCharacterLowerCase(stringBuilder.ToString())) { lyricChar += stringBuilder[0].ToString(); //先頭の文字を追加 stringBuilder.Remove(0, 1); //先頭の文字を削除 } MIDIEvent targetEvent = measure.MidiEvent[i]; MIDIEvent lyricEvent = MIDIEvent.CreateLyric(targetEvent.Time, lyricChar); midiTrack.InsertEventAfter(lyricEvent, targetEvent); } } }
void ParseSysexEvent(FileStream inFile, MIDIEvent midi_event) { int length = ParseVarLen(inFile); byte[] data = new byte[length]; inFile.Read(data, 0, length); Array.Reverse(data); midi_event.data = data; }
private void noteOn(MIDIEvent evnt) { if (evnt.data[1] != 00) { note[evnt.data[0]].Add(evnt); } else { noteOff(evnt); } }
static private void CorrectDeltaTicksOfNextEvents(MIDIEvent minNextEvent, List <MIDIEvent> nextEventList) { for (int i = 0; i < m_song.tracks.Count; i++) { MIDIEvent nextEvent = nextEventList[i]; if (nextEvent == null || nextEvent == minNextEvent) { continue; } nextEvent.deltaTicks -= minNextEvent.deltaTicks; } }
void MIDIDeviceListener.OnDeviceEvent(MIDIEvent midiEvent) { if (midiEvent.GetType() == typeof(MIDINoteEvent)) { MIDINoteEvent noteEvent = midiEvent as MIDINoteEvent; if (noteEvent.isNoteOn && m_hoveredGameObject != null) { ARButton arButton = m_hoveredGameObject.GetComponent(typeof(ARButton)) as ARButton; if (arButton != null) { arButton.Click(noteEvent.note); } } } }
void FlushEvent(MIDIEvent e) { if (!flushBuffer.TryAdd(e)) { flusherTask.GetAwaiter().GetResult(); RunFlusherTask(); flushBuffer.Add(e); } if (flushBuffer.Count > halfBuffLen) { if (flusherTask == null || flusherTask.IsCompleted) { RunFlusherTask(); } } }
void MIDISongListener.OnSongEvent(MIDIEvent midiEvent, int trackNumber) { if (!m_isEnabled) { return; } if (!m_isRightHandEnabled && trackNumber == 0) { return; } if (!m_isLeftHandEnabled && trackNumber == 1) { return; } if (midiEvent.GetType() == typeof(MIDINoteEvent)) { MIDINoteEvent noteEvent = midiEvent as MIDINoteEvent; if (noteEvent.isNoteOn) { bool pressedEarlyNote = false; foreach (MIDINoteEvent earlyPressedNote in m_earlyPressedNotes) { if (earlyPressedNote.note == noteEvent.note) { m_earlyPressedNotes.Remove(earlyPressedNote); pressedEarlyNote = true; break; } } if (!pressedEarlyNote) { m_pendingNotes.Add(noteEvent, trackNumber); if (m_pendingNotes.Count == 1) { m_songPlayer.Sleep(); } } } } }
void PushNoteEv(MIDIEvent n) { notesTime += n.DeltaTime; parser.ParseUpTo(notesTime); if (n is NoteOnEvent) { notesWritten++; } while (evTime <= notesTime) { if (currentEv == null) { if (otherEvents.TryTake(out currentEv)) { currentEv = currentEv.Clone(); evTime += currentEv.DeltaTime; if (evTime <= notesTime) { currentEv.DeltaTime = (uint)(evTime - time); FlushEvent(currentEv); currentEv = null; time = evTime; } else { break; } } else { break; } } else { currentEv.DeltaTime = (uint)(evTime - time); FlushEvent(currentEv); currentEv = null; time = evTime; } } n.DeltaTime = (uint)(notesTime - time); FlushEvent(n); time = notesTime; }
static private void ForwardMinNextEvent(MIDIEvent minNextEvent, List <MIDIEvent> nextEventList) { for (int i = 0; i < m_song.tracks.Count; i++) { MIDITrack track = m_song.tracks[i]; int nextEventIndex = track.events.IndexOf(minNextEvent); if (nextEventIndex == -1) { continue; } nextEventList[i] = null; nextEventIndex++; if (nextEventIndex < track.events.Count) { nextEventList[i] = track.events[nextEventIndex]; } } }
MIDIEvent ParseChannelEvent(FileStream inFile, MIDIEvent midi_event) { int event_type_mask = (midi_event.event_type & 0xF0); //int event_channel = (midi_event.event_type & 0x0f) + 1; var midi_event_new = midi_event; switch (event_type_mask) { case (int)MIDI_EVENT_TYPES.NOTE_ON: Debug.Log("note on"); midi_event_new = ParseNoteOnEvent(inFile, midi_event); break; case (int)MIDI_EVENT_TYPES.NOTE_OFF: midi_event_new = ParseNoteOffEvent(inFile, midi_event); Debug.Log("note off"); break; case (int)MIDI_EVENT_TYPES.NOTE_AFTERTOUCH: Debug.Log("after touch"); break; case (int)MIDI_EVENT_TYPES.CONTROLLER: Debug.Log("controller"); break; case (int)MIDI_EVENT_TYPES.PROGRAM_CHANGE: Debug.Log("program change"); break; case (int)MIDI_EVENT_TYPES.CHANNEL_AFTERTOUCH: Debug.Log("channel aftertouch"); break; case (int)MIDI_EVENT_TYPES.PITCH_BEND: Debug.Log("pitchbend"); break; } return(midi_event_new); }
static private MIDIEvent FindMinNextEvent(List <MIDIEvent> nextEventList) { int minDeltaTicks = 99999999; MIDIEvent minNextEvent = null; for (int i = 0; i < m_song.tracks.Count; i++) { MIDIEvent nextEvent = nextEventList[i]; if (nextEvent == null) { continue; } if (nextEvent.deltaTicks < minDeltaTicks) { minDeltaTicks = nextEvent.deltaTicks; minNextEvent = nextEvent; } } return(minNextEvent); }
protected void MergeAudioEvents() { int count = LoaderSettings.EventPlayerThreads; MIDINoteEvents = new MIDIEvent[count][]; Parallel.For(0, count, new ParallelOptions() { CancellationToken = cancel }, i => { try { MIDINoteEvents[i] = TimedMerger <MIDIEvent> .MergeMany(parsers.Select(p => new SkipIterator <MIDIEvent>(p.NoteEvents, i, count)).ToArray(), e => { return(e.time); }).ToArray(); } catch (OperationCanceledException) { } }); }
public void Update(float deltaTime) { if (m_isPlaying && !m_isSleeping) { deltaTime = deltaTime * m_speedFactor; NotifyUpdate(deltaTime); m_elapsedTime += deltaTime; CalcCurrentMeasure(); for (int i = 0; i < m_song.tracks.Count; i++) { MIDITrack track = m_song.tracks[i]; bool processedAllEventsWithCurrentTimestamp = false; while (!processedAllEventsWithCurrentTimestamp) { int nextEventIndex = m_nextEventIndexList[i]; if (nextEventIndex >= track.events.Count) { break; } MIDIEvent nextEvent = track.events[nextEventIndex]; if (nextEvent.timestamp <= m_elapsedTime) { NotifyEvent(nextEvent, i); m_nextEventIndexList[i]++; } else { processedAllEventsWithCurrentTimestamp = true; } } } } }
void MIDIDeviceListener.OnDeviceEvent(MIDIEvent midiEvent) { if (!m_isEnabled) { return; } if (midiEvent.GetType() == typeof(MIDINoteEvent)) { MIDINoteEvent noteEvent = midiEvent as MIDINoteEvent; if (noteEvent.isNoteOn) { bool pressedPendingNote = false; foreach (var pendingNote in m_pendingNotes) { if (pendingNote.Key.note == noteEvent.note) { m_pendingNotes.Remove(pendingNote.Key); pressedPendingNote = true; if (m_pendingNotes.Count == 0) { m_songPlayer.WakeUp(); } break; } } if (!pressedPendingNote) { noteEvent.timestamp = 0.0f; m_earlyPressedNotes.Add(noteEvent); } } } }
MIDINote ParseNoteOnEvent(FileStream inFile, MIDIEvent midi_event) { MIDINote note = new MIDINote(midi_event); note.note = (UInt32)inFile.ReadByte(); note.velocity = (UInt32)inFile.ReadByte(); note.absoluteStartTime = CurrentTime(); Debug.Log(midi_event); if (note.velocity == 0) // note off { ParseNoteOffEvent(null, note); } else { if (!currentNotes.ContainsKey(note.note)) { currentNotes.Add(note.note, note); } } return(note); }
MIDITrack ParseTrack(FileStream inFile) { MIDITrack track = new MIDITrack(); // MThd { byte[] _mtrk = new byte[4]; inFile.Read(_mtrk, 0, 4); Array.Reverse(_mtrk); track.MTrk = BitConverter.ToUInt32(_mtrk, 0); if(track.MTrk != (UInt32)MIDI_EVENT_TYPES.TRACK_CHUNK_ID){ throw new Exception("wrong track header"); } } // track length { byte[] _len = new byte[4]; inFile.Read(_len, 0, 4); Array.Reverse(_len); track.track_length = BitConverter.ToUInt32(_len, 0); } // start reading events long pos = inFile.Position; this.timeOffset = 0; while(inFile.Position < pos + track.track_length){ int deltaTime = ParseVarLen(inFile); this.timeOffset += deltaTime; MIDIEvent midi_event = new MIDIEvent(); midi_event.delta_time = deltaTime; midi_event.event_type = inFile.ReadByte(); switch(midi_event.event_type){ case (int)MIDI_EVENT_TYPES.META_EVENT: ParseMetaEvent(inFile, midi_event); // Debug.Log("Meta event"); break; case (int)MIDI_EVENT_TYPES.SYSEX_EVENT: case (int)MIDI_EVENT_TYPES.SYSEX_CHUNK: ParseSysexEvent(inFile, midi_event); // Debug.Log("Sysex event"); break; default: midi_event = ParseChannelEvent(inFile, midi_event); // Debug.Log("channel event"); break; } Debug.Log(midi_event); track.events.Add(midi_event); } return track; }
public MIDINote(MIDIEvent e) { this.delta_time = e.delta_time; this.data = e.data; this.event_type = e.event_type; }
MIDINote ParseNoteOnEvent(FileStream inFile, MIDIEvent midi_event) { MIDINote note = new MIDINote(midi_event); note.note = (UInt32)inFile.ReadByte(); note.velocity = (UInt32)inFile.ReadByte(); note.absoluteStartTime = CurrentTime(); Debug.Log(midi_event); if(note.velocity == 0){ // note off ParseNoteOffEvent(null, note); }else{ if(!currentNotes.ContainsKey(note.note)){ currentNotes.Add(note.note, note); } } return note; }
void ParseMetaEvent(FileStream inFile, MIDIEvent midi_event) { int type = inFile.ReadByte(); midi_event.event_type = type; byte[] data; switch(type){ case (int)MIDI_EVENT_TYPES.SEQ_NUMBER: midi_event.data = ParseMetaValue(inFile); break; case (int)MIDI_EVENT_TYPES.TEXT: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.COPYRIGHT: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.SEQ_NAME: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.INSTRUMENT_NAME: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.LYRICS: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.MARKER: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.CUE_POINT: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.CHANNEL_PREFIX: midi_event.data = ParseMetaValue(inFile); break; case (int)MIDI_EVENT_TYPES.END_OF_TRACK: midi_event.data = ParseMetaData(inFile); break; case (int)MIDI_EVENT_TYPES.TEMPO: int nomenator = (int)MIDI_EVENT_TYPES.MICROSECONDS_PER_MINUTE; int denomenator = (int)ParseMetaValue(inFile); float tempo = (float)nomenator/ (float)denomenator; // bpm midi_event.data = tempo; this.header.tempo = tempo; // set song tempo here!!!! break; case (int)MIDI_EVENT_TYPES.SMPTE_OFFSET: data = ParseMetaData(inFile); // TODO: parse [firstByte, minute, second, frame, subframe] midi_event.data = data; break; case (int)MIDI_EVENT_TYPES.TIME_SIGNATURE: data = ParseMetaData(inFile); Dictionary<String,Int32> signature = new Dictionary<string, int>(); signature.Add("numerator", data[0]); signature.Add("denumerator", (int)Math.Pow((double)data[1], (double)2.0)); midi_event.data = signature; break; case (int)MIDI_EVENT_TYPES.KEY_SIGNATURE: data = ParseMetaData(inFile); int _key = (data[0] ^ 128) - 128; // convert from unsigned byte to signed byte int _scale = data[1]; // if 0 -> major if 1 -> minor Dictionary<string, string> key = new Dictionary<string, string>(); key.Add("key", ((KEY_VALUE_TO_NAME)_key).ToString()); key.Add ("scale", _scale == 0 ? "major" : "minor"); midi_event.data = key; break; case (int)MIDI_EVENT_TYPES.SEQ_SPECIFIC: midi_event.data = ParseMetaData(inFile); break; default: Debug.LogWarning("ignoring unknown meta event on track number"); midi_event.data = ParseMetaData(inFile); break; } }
MIDINote ParseNoteOffEvent(FileStream inFile, MIDIEvent midi_event) { MIDINote note; if(inFile != null){ note = new MIDINote(midi_event); note.note = (UInt32)inFile.ReadByte(); note.velocity = (UInt32)inFile.ReadByte(); }else{ note = (MIDINote)midi_event; } if(this.currentNotes.ContainsKey(note.note) ){ this.currentNotes[note.note].duration = CurrentTime() - note.absoluteStartTime; this.currentNotes.Remove(note.note); }else{ Debug.LogWarning("try to access not existing note: " + note.note); } return note; }
public override string ToString() { return("MIDIEvent: " + MIDIEvent.ToString() + " - TimeBeats: " + TimeBeats + " - DurationBeats: " + DurationBeats); }
/*public MIDIObject(byte[] data, bool strict) : this(data) { this.trulystrict = strict; }*/ private void LoadMIDI(byte[] data) { MemoryStream ms = new MemoryStream(data); BinaryReader br = new BinaryReader(ms); List<Track> tracks = new List<Track>(); //=======Load header====== //Confirm 'MThd' if (data[0] != 0x4D) throw new InvalidMIDIFileException(); if (data[1] != 0x54) throw new InvalidMIDIFileException(); if (data[2] != 0x68) throw new InvalidMIDIFileException(); if (data[3] != 0x64) throw new InvalidMIDIFileException(); br.ReadBytes(4); //Shift position 4 forward for rest of reading //Header length this.header.length = ReadInt(br); //Format int format = ReadShort(br); switch (format) { case 0: this.header.format = Format.SingleTrack; throw new UnsupportedMIDIFileException(); case 1: this.header.format = Format.MultiTrack; break; case 2: this.header.format = Format.MultiSong; throw new UnsupportedMIDIFileException(); default: throw new UnsupportedMIDIFileException(); } //Tracks this.header.tracks = ReadShort(br); //Delta-time this.header.ticksPerQuarterNote = ReadShort(br); //======Load tracks======= for (int tracknumber = 0; tracknumber < this.header.tracks; tracknumber++) { Msg("Track number: " + tracknumber); Track track = new Track(); //=======Load header===== byte[] trackheaderstart = br.ReadBytes(4); if (trackheaderstart[0] != 0x4D) throw new UnreadableTrackException(); if (trackheaderstart[1] != 0x54) throw new UnreadableTrackException(); if (trackheaderstart[2] != 0x72) throw new UnreadableTrackException(); if (trackheaderstart[3] != 0x6B) throw new UnreadableTrackException(); track.datalength = ReadInt(br); track.data = br.ReadBytes(track.datalength); //======Load track events====== BinaryReader tbr = new BinaryReader(new MemoryStream(track.data)); bool readingtrack = true; byte prevcommand = 0x00; List<Event> events = new List<Event>(); while (readingtrack) { Event ev = new Event(); ev.time = ReadVariable(tbr); byte command = tbr.ReadByte(); Msg(ev.time + " Command " + command); if (command >= 0x80) { if (command == 0xFF) { byte metacommand = tbr.ReadByte(); Msg("Meta: " + command); ev.type = EventType.Meta; ev.midiEvent = new MIDIEvent(); ev.midiEvent.midiType = MidiType.none; switch (metacommand) //-------Check for meta-events { case 0x00: //Sequence number { ev.metaType = MetaType.SequenceNumber; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); break; } case 0x01: //Text event { ev.metaType = MetaType.Text; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); break; } case 0x02: //Copyright info { ev.metaType = MetaType.Text; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); break; } case 0x03: //Track name { ev.metaType = MetaType.TrackName; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); track.name = Encoding.ASCII.GetString(ev.data); break; } case 0x04: //Instrument name { ev.metaType = MetaType.InstrumentName; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); break; } case 0x05: //Lyric text { ev.metaType = MetaType.Lyric; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); break; } case 0x06: //Marker { ev.metaType = MetaType.Marker; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); break; } case 0x07: //Cue point { ev.metaType = MetaType.Cue; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); break; } case 0x2F: //End of track { ev.metaType = MetaType.EndOfTrack; readingtrack = false; ev.data = tbr.ReadBytes(1); break; } case 0x51: //Set tempo - I don't get how this shit works { ev.metaType = MetaType.Tempo; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); break; } case 0x58: //Time signature { ev.metaType = MetaType.TimeSignature; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); break; } case 0x59: //Key signature { ev.metaType = MetaType.KeySignature; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); break; } case 0x7F: //Sequencer specific { ev.metaType = MetaType.Specific; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); break; } case 0xF8: //Timing clock { ev.metaType = MetaType.TimingClock; break; } case 0xFA: //Start sequence { ev.metaType = MetaType.StartSequence; break; } case 0xFB: //Continue sequence { ev.metaType = MetaType.ContinueSequence; break; } case 0xFC: //Stop sequence { ev.metaType = MetaType.StopSequence; break; } default: //----------Unrecognized event if (strict && metacommand != 0x21 && metacommand != 0x48) throw new UnrecognizedEventException(); else { int length = ReadByte(tbr); tbr.ReadBytes(length); } break; } } else //MIDI event { ev.type = EventType.Midi; ev.metaType = MetaType.none; MIDIEvent mev = new MIDIEvent(); mev.note = new Note(); string binary = Convert.ToString(command, 2); Msg("Binary: " + binary); while (binary.Length < 8) { binary = "0" + binary; } mev.channel = Convert.ToInt32(Convert.ToUInt32(binary.Substring(4, 4), 2)); mev.controllerNumber = 0; mev.note.number = 0; mev.value = 0; switch (binary.Substring(0, 4)) { case "1000": //Note off mev.midiType = MidiType.NoteOff; mev.note.number = ReadByte(tbr); mev.note.velocity = ReadByte(tbr); break; case "1001": //Note on mev.midiType = MidiType.NoteOn; mev.note.number = ReadByte(tbr); mev.note.velocity = ReadByte(tbr); break; case "1010": //Key after-touch mev.midiType = MidiType.KeyAfterTouch; mev.note.number = ReadByte(tbr); mev.note.velocity = ReadByte(tbr); break; case "1011": //Control change mev.midiType = MidiType.ControlChange; mev.controllerNumber = ReadByte(tbr); mev.value = ReadByte(tbr); break; case "1100": //Patch change mev.midiType = MidiType.PatchChange; mev.value = ReadByte(tbr); break; case "1101": //Channel after-touch mev.midiType = MidiType.ChannelAfterTouch; mev.value = ReadByte(tbr); break; case "1110": //Pitch wheel change mev.midiType = MidiType.PitchWheelChange; mev.value = Convert.ToInt32(tbr.ReadUInt16()); //Yeah, this one is Little Endian. Great consistency. break; case "1111": //Sysex event mev.midiType = MidiType.none; ev.type = EventType.Sysex; int length = ReadByte(tbr); ev.data = tbr.ReadBytes(length); break; default: mev.midiType = MidiType.none; if (strict/* && command != 0x00*/) throw new UnrecognizedEventException(); break; } //Fill in extra note information if (mev.note.number != 0) { mev.note.octave = Convert.ToInt32(Math.Floor((double)mev.note.number / 12)); mev.note.type = (NoteType)(mev.note.number % 12); } else { mev.note.octave = 0; } ev.midiEvent = mev; } prevcommand = command; } //-------------------------------------------------------------------------------- else //Repeat MIDI command { byte firstdata = command; command = prevcommand; //Ugly copypasta from above - should be done better ev.type = EventType.Midi; ev.metaType = MetaType.none; MIDIEvent mev = new MIDIEvent(); mev.note = new Note(); string binary = Convert.ToString(command, 2); Msg("Binary: " + binary); while (binary.Length < 8) { binary = "0" + binary; } mev.channel = Convert.ToInt32(Convert.ToUInt32(binary.Substring(4, 4))); mev.controllerNumber = 0; mev.note.number = 0; mev.value = 0; switch (binary.Substring(0, 4)) { case "1000": //Note off mev.midiType = MidiType.NoteOff; mev.note.number = Convert.ToInt32(Convert.ToUInt32(firstdata)); //mev.note.velocity = ReadByte(tbr); mev.note.velocity = ReadByte(tbr); break; case "1001": //Note on mev.midiType = MidiType.NoteOn; mev.note.number = Convert.ToInt32(Convert.ToUInt32(firstdata)); mev.note.velocity = ReadByte(tbr); break; case "1010": //Key after-touch mev.midiType = MidiType.KeyAfterTouch; mev.note.number = Convert.ToInt32(Convert.ToUInt32(firstdata)); mev.note.velocity = ReadByte(tbr); break; case "1011": //Control change mev.midiType = MidiType.ControlChange; mev.controllerNumber = Convert.ToInt32(Convert.ToUInt32(firstdata)); mev.value = ReadByte(tbr); break; case "1100": //Patch change mev.midiType = MidiType.PatchChange; mev.value = Convert.ToInt32(Convert.ToUInt32(firstdata)); break; case "1101": //Channel after-touch mev.midiType = MidiType.ChannelAfterTouch; mev.value = Convert.ToInt32(Convert.ToUInt32(firstdata)); break; case "1110": //Pitch wheel change mev.midiType = MidiType.PitchWheelChange; //mev.value = Convert.ToInt32(tbr.ReadUInt16()); //Yeah, this one is Little Endian. Great consistency. mev.value = Convert.ToInt32(tbr.ReadByte() * 256 + Convert.ToUInt32(firstdata)); break; case "1111": //Sysex event mev.midiType = MidiType.none; ev.type = EventType.Sysex; int length = Convert.ToInt32(Convert.ToUInt32(firstdata)); ev.data = tbr.ReadBytes(length); break; default: mev.midiType = MidiType.none; if (strict/* && command != 0x00*/) throw new UnrecognizedEventException(); break; } //Fill in extra note information if (mev.note.number != 0) { mev.note.octave = Convert.ToInt32(Math.Floor((double)mev.note.number / 12)); mev.note.type = (NoteType)(mev.note.number % 12); } else { mev.note.octave = 0; } ev.midiEvent = mev; } //Add just specified event to list of events events.Add(ev); } //Add just specified list of events to track track.events = events.ToArray(); //Add just specified track to list of tracks tracks.Add(track); tbr.Close(); //Close the track binary reader } //Store the tracks this.tracks = tracks.ToArray(); AnalyzeMIDI(); loaded = true; br.Close(); //Close binaryreader ms.Close(); //Close memorystream }
private void programChange(MIDIEvent evnt) { line.AppendFormat("@{0}", evnt.data[0]); }
void ParseMetaEvent(FileStream inFile, MIDIEvent midi_event) { int type = inFile.ReadByte(); midi_event.event_type = type; byte[] data; switch (type) { case (int)MIDI_EVENT_TYPES.SEQ_NUMBER: midi_event.data = ParseMetaValue(inFile); break; case (int)MIDI_EVENT_TYPES.TEXT: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.COPYRIGHT: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.SEQ_NAME: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.INSTRUMENT_NAME: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.LYRICS: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.MARKER: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.CUE_POINT: midi_event.data = ParseMetaText(inFile); break; case (int)MIDI_EVENT_TYPES.CHANNEL_PREFIX: midi_event.data = ParseMetaValue(inFile); break; case (int)MIDI_EVENT_TYPES.END_OF_TRACK: midi_event.data = ParseMetaData(inFile); break; case (int)MIDI_EVENT_TYPES.TEMPO: int nomenator = (int)MIDI_EVENT_TYPES.MICROSECONDS_PER_MINUTE; int denomenator = (int)ParseMetaValue(inFile); float tempo = (float)nomenator / (float)denomenator; // bpm midi_event.data = tempo; this.header.tempo = tempo; // set song tempo here!!!! break; case (int)MIDI_EVENT_TYPES.SMPTE_OFFSET: data = ParseMetaData(inFile); // TODO: parse [firstByte, minute, second, frame, subframe] midi_event.data = data; break; case (int)MIDI_EVENT_TYPES.TIME_SIGNATURE: data = ParseMetaData(inFile); Dictionary <String, Int32> signature = new Dictionary <string, int>(); signature.Add("numerator", data[0]); signature.Add("denumerator", (int)Math.Pow((double)data[1], (double)2.0)); midi_event.data = signature; break; case (int)MIDI_EVENT_TYPES.KEY_SIGNATURE: data = ParseMetaData(inFile); int _key = (data[0] ^ 128) - 128; // convert from unsigned byte to signed byte int _scale = data[1]; // if 0 -> major if 1 -> minor Dictionary <string, string> key = new Dictionary <string, string>(); key.Add("key", ((KEY_VALUE_TO_NAME)_key).ToString()); key.Add("scale", _scale == 0 ? "major" : "minor"); midi_event.data = key; break; case (int)MIDI_EVENT_TYPES.SEQ_SPECIFIC: midi_event.data = ParseMetaData(inFile); break; default: Debug.LogWarning("ignoring unknown meta event on track number"); midi_event.data = ParseMetaData(inFile); break; } }
MIDITrack ParseTrack(FileStream inFile) { MIDITrack track = new MIDITrack(); // MThd { byte[] _mtrk = new byte[4]; inFile.Read(_mtrk, 0, 4); Array.Reverse(_mtrk); track.MTrk = BitConverter.ToUInt32(_mtrk, 0); if (track.MTrk != (UInt32)MIDI_EVENT_TYPES.TRACK_CHUNK_ID) { throw new Exception("wrong track header"); } } // track length { byte[] _len = new byte[4]; inFile.Read(_len, 0, 4); Array.Reverse(_len); track.track_length = BitConverter.ToUInt32(_len, 0); } // start reading events long pos = inFile.Position; this.timeOffset = 0; while (inFile.Position < pos + track.track_length) { int deltaTime = ParseVarLen(inFile); this.timeOffset += deltaTime; MIDIEvent midi_event = new MIDIEvent(); midi_event.delta_time = deltaTime; midi_event.event_type = inFile.ReadByte(); switch (midi_event.event_type) { case (int)MIDI_EVENT_TYPES.META_EVENT: ParseMetaEvent(inFile, midi_event); // Debug.Log("Meta event"); break; case (int)MIDI_EVENT_TYPES.SYSEX_EVENT: case (int)MIDI_EVENT_TYPES.SYSEX_CHUNK: ParseSysexEvent(inFile, midi_event); // Debug.Log("Sysex event"); break; default: midi_event = ParseChannelEvent(inFile, midi_event); // Debug.Log("channel event"); break; } Debug.Log(midi_event); track.events.Add(midi_event); } return(track); }
void MIDISongListener.OnSongEvent(MIDIEvent midiEvent, int trackNumber) { }
private void pitchBend(MIDIEvent evnt) { }
MIDIEvent ParseChannelEvent(FileStream inFile, MIDIEvent midi_event) { int event_type_mask = (midi_event.event_type & 0xF0); //int event_channel = (midi_event.event_type & 0x0f) + 1; var midi_event_new = midi_event; switch(event_type_mask){ case (int)MIDI_EVENT_TYPES.NOTE_ON: Debug.Log("note on"); midi_event_new = ParseNoteOnEvent(inFile, midi_event); break; case (int)MIDI_EVENT_TYPES.NOTE_OFF: midi_event_new = ParseNoteOffEvent(inFile, midi_event); Debug.Log("note off"); break; case (int)MIDI_EVENT_TYPES.NOTE_AFTERTOUCH: Debug.Log("after touch"); break; case (int)MIDI_EVENT_TYPES.CONTROLLER: Debug.Log("controller"); break; case (int)MIDI_EVENT_TYPES.PROGRAM_CHANGE: Debug.Log("program change"); break; case (int)MIDI_EVENT_TYPES.CHANNEL_AFTERTOUCH: Debug.Log("channel aftertouch"); break; case (int)MIDI_EVENT_TYPES.PITCH_BEND: Debug.Log("pitchbend"); break; } return midi_event_new; }
private void channelTouch(MIDIEvent evnt) { }
// filepath starts from base application folder public void ParseMIDIFile(string filePath, bool parseNoteOffEvents = false) { fileToParse = File.ReadAllBytes (Application.dataPath + filePath); List<MIDIEvent> eventList = new List<MIDIEvent>(); string s = System.Convert.ToString (fileToParse[12], 2).PadLeft (8, '0') + System.Convert.ToString (fileToParse[13], 2).PadLeft (8, '0'); float ticksPerQuarterNote = (float)System.Convert.ToInt32 (s, 2); float millisecondsPerTick = 60000 / (beatsPerMinute * ticksPerQuarterNote); int i = 18; // position after header block while (i < fileToParse.Length) { s = System.Convert.ToString (fileToParse[i], 2).PadLeft (8, '0'); Debug.Log (i + " " + s); if (s.StartsWith("10010000") && System.Convert.ToString(fileToParse[i+1], 2).PadLeft(8, '0').StartsWith("01000100")) { float deltaTimeInMilliseconds = GetDeltaTimeForEvent(i) * millisecondsPerTick; if (eventList.Count == 0) { MIDIEvent midiEvent = new MIDIEvent(deltaTimeInMilliseconds, deltaTimeInMilliseconds); eventList.Add (midiEvent); Debug.Log (i + " here"); } else { MIDIEvent midiEvent = new MIDIEvent(deltaTimeInMilliseconds, eventList[eventList.Count - 1].TimeFromBeginning () + deltaTimeInMilliseconds); eventList.Add (midiEvent); Debug.Log (i + " here"); } noteOn = true; i += 3; } else if (s.StartsWith ("10000000") && System.Convert.ToString(fileToParse[i+1], 2).PadLeft(8, '0').StartsWith("01000100") && noteOn) { float deltaTimeInMilliseconds = GetDeltaTimeForEvent(i) * millisecondsPerTick; if (eventList.Count == 0) { MIDIEvent midiEvent = new MIDIEvent(deltaTimeInMilliseconds, deltaTimeInMilliseconds, "NoteOff"); eventList.Add (midiEvent); } else { MIDIEvent midiEvent = new MIDIEvent(deltaTimeInMilliseconds, eventList[eventList.Count - 1].TimeFromBeginning () + deltaTimeInMilliseconds, "NoteOff"); eventList.Add (midiEvent); } noteOn = false; i += 3; } i++; } StreamWriter outputStream; filePath = filePath.Remove (filePath.IndexOf (".mid")); filePath = filePath.Trim ().Replace ("/Resources/", ""); outputStream = new StreamWriter (Application.dataPath.Trim().Replace("/MIDIParser/Assets", "") + "/Assets/Resources/BeatConfig/" + filePath + ".txt", false); float timeFromLastEventBuffer = 0; int cumulativeTime = 0; for (i = 0; i < eventList.Count ; i++) { if (eventList [i].EventType () == "NoteOn") { int timeElapsed = (int)System.Math.Round(timeFromLastEventBuffer + eventList [i].TimeFromLastEvent ()); cumulativeTime += timeElapsed; s = eventList [i].EventType () + "," + timeElapsed + "," + cumulativeTime; outputStream.WriteLine (s); outputStream.Flush (); timeFromLastEventBuffer = 0; } else if (eventList[i].EventType() == "NoteOff") { if (parseNoteOffEvents) { int timeElapsed = (int)System.Math.Round(timeFromLastEventBuffer + eventList [i].TimeFromLastEvent ()); cumulativeTime += timeElapsed; s = eventList [i].EventType () + "," + timeElapsed + "," + cumulativeTime; outputStream.WriteLine (s); outputStream.Flush (); timeFromLastEventBuffer = 0; } else { timeFromLastEventBuffer = eventList [i].TimeFromLastEvent (); } } else { outputStream.WriteLine("Unexpected event"); outputStream.Flush(); } } }
void MIDIDeviceListener.OnDeviceEvent(MIDIEvent midiEvent) { if (midiEvent.GetType() == typeof(MIDINoteEvent)) { MIDINoteEvent noteEvent = midiEvent as MIDINoteEvent; if (noteEvent.isNoteOn) { if (m_isEnabled) { m_deviceNoteTimestamps.Add(noteEvent.note, m_elapsedTime); } m_songVisualizer.StartNoteEffect(noteEvent.note); bool isCorrectHit = false; if (m_isRightHandEnabled) { foreach (MIDINoteEvent rightHandSongNote in m_rightHandSongNotes) { if (rightHandSongNote.note == noteEvent.note) { if (m_elapsedTime >= (rightHandSongNote.timestamp - m_noteHitTimingThreshold / 2.0f) && m_elapsedTime <= (rightHandSongNote.timestamp + m_noteHitTimingThreshold / 2.0f)) { isCorrectHit = true; break; } } } } if (m_isLeftHandEnabled) { foreach (MIDINoteEvent leftHandSongNote in m_leftHandSongNotes) { if (leftHandSongNote.note == noteEvent.note) { if (m_elapsedTime >= (leftHandSongNote.timestamp - m_noteHitTimingThreshold / 2.0f) && m_elapsedTime <= (leftHandSongNote.timestamp + m_noteHitTimingThreshold / 2.0f)) { isCorrectHit = true; break; } } } } if (isCorrectHit) { m_songVisualizer.ChangeNoteEffectColor(noteEvent.note, m_wrongHitColor); } else { m_songVisualizer.ChangeNoteEffectColor(noteEvent.note, m_correctHitColor); } } else { m_songVisualizer.StopNoteEffect(noteEvent.note); } } }
private MIDI ConvertToFormat1(MIDI src) { try { Track srcTrack = src.TrackList[0]; var newTracks = new List <Track>(); int cnt = 0; // event counter var eventlist = new LinkedList <Event>(); uint deltaTime = 0; // Create Conductor track foreach (Event ev in srcTrack.EventList) { deltaTime += ev.DeltaTime; if (ev is MetaEvent) { MetaEvent modEv; if (ev is SetTempo) { var st = (SetTempo)ev; modEv = new SetTempo(deltaTime, st.Value); } else if (ev is TimeSignature) { var ts = (TimeSignature)ev; modEv = new TimeSignature(deltaTime, ts.Numerator, ts.DenominatorBitShift, ts.MIDIClockPerMetronomeTick, ts.NumberOfNotesPerClocks); } else if (ev is KeySignature) { var ks = (KeySignature)ev; modEv = new KeySignature(deltaTime, ks.SignatureNumber, ks.MinorFlagNumber); } else if (ev is SequenceTrackName) { var stn = (SequenceTrackName)ev; modEv = new SequenceTrackName(deltaTime, stn.Name); } else if (ev is EndOfTrack) { modEv = new EndOfTrack(deltaTime); } else { modEv = new MetaEvent(deltaTime); } eventlist.AddLast(modEv); deltaTime = 0; if (!(ev is EndOfTrack)) { cnt++; } } } newTracks.Add(new Track(eventlist)); eventlist = new LinkedList <Event>(); deltaTime = 0; // Create System Setup track foreach (Event ev in srcTrack.EventList) { deltaTime += ev.DeltaTime; if (ev is SysExEvent) { eventlist.AddLast(new SysExEvent(deltaTime)); deltaTime = 0; cnt++; } else if (ev is EndOfTrack) { eventlist.AddLast(new EndOfTrack(deltaTime)); } } newTracks.Add(new Track(eventlist)); // Create Notes track for (int ch = 0; cnt + 1 < srcTrack.EventList.Count; ch++) { eventlist = new LinkedList <Event>(); deltaTime = 0; foreach (Event ev in srcTrack.EventList) { deltaTime += ev.DeltaTime; if (ev is MIDIEvent) { var midiEv = (MIDIEvent)ev; if (midiEv.Channel == ch) { MIDIEvent modEv; if (midiEv is NoteOn) { var nton = (NoteOn)midiEv; modEv = new NoteOn(deltaTime, nton.Channel, nton.Number, nton.Velocity); } else if (midiEv is NoteOff) { var ntoff = (NoteOff)midiEv; modEv = new NoteOff(deltaTime, ntoff.Channel, ntoff.Number, ntoff.Velocity); } else if (midiEv is ProgramChange) { var pc = (ProgramChange)midiEv; modEv = new ProgramChange(deltaTime, pc.Channel, pc.Number); } else if (midiEv is Volume) { var vol = (Volume)midiEv; modEv = new Volume(deltaTime, vol.Channel, vol.Value); } else if (midiEv is Pan) { var pan = (Pan)midiEv; modEv = new Pan(deltaTime, pan.Channel, pan.Value); } else if (midiEv is ControlChange) { var cc = (ControlChange)midiEv; modEv = new ControlChange(deltaTime, cc.Channel, cc.Value); } else { modEv = new MIDIEvent(deltaTime, midiEv.Channel); } eventlist.AddLast(modEv); deltaTime = 0; cnt++; } } else if (ev is EndOfTrack) { eventlist.AddLast(new EndOfTrack(deltaTime)); } } newTracks.Add(new Track(eventlist)); } return(new MIDI(newTracks, 1, newTracks.Count, src.TimeDivision)); } catch (Exception ex) { throw new Exception(Resources.ErrorMIDIFormat1, ex); } }