private void LoadScore() { var strictMode = false; mf = new MidiFile(MidiScoreFile, strictMode); ppq = mf.DeltaTicksPerQuarterNote; ScoreLoaded = true; tempo = PlayerCtrl.Control.tempo; //Find first note var track = mf.Events[0]; // MIDI Files for VRMIN should only have one track int eventIdx = 0; NoteOnEvent firstNoteEvent = null; foreach (var midiEvent in track) { if (MidiEvent.IsNoteOn(midiEvent)) { firstNoteEvent = (NoteOnEvent)midiEvent; break; } } if (firstNoteEvent != null) { CurrentNote = new NoteMessage(-1, firstNoteEvent.NoteNumber, PlayerCtrl.Control.startDelay); } else { throw new System.ArgumentException("No Data in loaded Score"); } }
public void HandleMidiEvent(MidiEvent me) { if (MidiEvent.IsNoteOn(me)) { HandleNoteOn(((NoteOnEvent)me).NoteNumber); } else if (MidiEvent.IsNoteOff(me)) { HandleNoteOff(((NoteEvent)me).NoteNumber); } else if (me.CommandCode == MidiCommandCode.PitchWheelChange) { HandlePitchWheelChange(((PitchWheelChangeEvent)me).Pitch); } else if (me.CommandCode == MidiCommandCode.ControlChange) { HandleControlChange(((ControlChangeEvent)me).Controller, ((ControlChangeEvent)me).ControllerValue); } else if (me.CommandCode == MidiCommandCode.MetaEvent) { Debug.Assert(me is MetaEvent); if (me is TempoEvent) { HandleTempoChange(((TempoEvent)me).MicrosecondsPerQuarterNote); } } }
/// <summary> /// MIDI in event handler. /// </summary> /// <param name="sender">Calling object.</param> /// <param name="e">Arguments passed.</param> private void MidiInDevice_messageHandler(object sender, MidiInMessageEventArgs e) { // Do nothing if we don't have any tones to play if (tonesAvailable == null || tonesAvailable.Length == 0) { return; } // Call ToggleTone on the UI thread using Invoke ToggleToneDelegate ttd = new ToggleToneDelegate(ToggleTone); Object[] args = new Object[2]; if (MidiEvent.IsNoteOn(e.MidiEvent)) { args[0] = ((NoteOnEvent)e.MidiEvent).NoteNumber; args[1] = Toggle.Play; Invoke(ttd, args); } else if (MidiEvent.IsNoteOff(e.MidiEvent)) { args[0] = ((NoteEvent)e.MidiEvent).NoteNumber; args[1] = Toggle.Stop; Invoke(ttd, args); } }
private void midiInReceived(object sender, MidiInMessageEventArgs e) { if (e.MidiEvent == null) { return; } NoteEvent noteEvent; try { noteEvent = (NoteEvent)e.MidiEvent; } catch (Exception) { Console.WriteLine("midicontroller exc"); return; } if (MidiEvent.IsNoteOn(e.MidiEvent)) { int calculatedNote = offsetNote(noteEvent.NoteNumber, KeyboardController.KeyOffset); MidiOutput.play(calculatedNote); if (currentlyPressedKeys.ContainsKey(calculatedNote)) { return; } if (Guide == null) { return; } currentlyPressedKeys.Add(calculatedNote, GuidesController.StopWatch.ElapsedMilliseconds); Guide.ActiveKeys = currentlyPressedKeys; Guide.UpdatePianoKeys(); //Thread.Sleep inside GUI is just for example } else { int calculatedNote = offsetNote(noteEvent.NoteNumber, KeyboardController.KeyOffset); MidiOutput.stop(calculatedNote); if (Guide == null) { return; } currentlyPressedKeys.Remove(calculatedNote); Guide.ActiveKeys = currentlyPressedKeys; Guide.UpdatePianoKeys(); } }
public void MidiEvent(MidiEvent midiEvent) { if (!NoteInputMode.IsMidi()) { return; } if (midiEvent.IsNoteOn()) { var pitch = MidiPitchMapping.Map(midiEvent.Cast <NoteEvent>()); NoteSink.NoteOn(pitch); } else if (midiEvent.IsNoteOff()) { var pitch = MidiPitchMapping.Map(midiEvent.Cast <NoteEvent>()); NoteSink.NoteOff(pitch); } }
void Init() { _piece = new MidiFile(FilePath, false); distanceToTheNextBonus = (int)UnityEngine.Random.Range(5.0f, 8.0f); _platforms = new List <GameObject>(); if (_piece != null) { for (int n = 0; n < 1; ++n) { foreach (var midiEvent in _piece.Events[n]) { if (MidiEvent.IsNoteOn(midiEvent)) { var note = (NoteOnEvent)midiEvent; _platforms.Add( UpdateNewPlatformPositionAndScale( Instantiate(PlatformPrefab, DeterminePlatformPosition(note), Quaternion.identity), note) ); // Check if platform is accessible if (_platforms.Count > 1 && !CheckIfPossibleToGoForward()) { var tempPlat = _platforms[_platforms.Count - 1]; tempPlat.transform.position = new Vector3( tempPlat.transform.position.x + _platforms[_platforms.Count - 2].transform.localScale.x / 2.0f, tempPlat.transform.position.y); } lastPosition = _platforms[_platforms.Count - 1].transform.position; lastPosition.x += _platforms[_platforms.Count - 1].transform.localScale.x / 2.0f; } } } Player = Instantiate(PlayerPrefab, _platforms[0].transform.position + new Vector3(0, 10), Quaternion.identity); } }
public Midi2NBS(string path) { mf = new MidiFile(path, false); for (int i = 0; i < mf.Tracks; i++) { var @event = mf.Events[i]; for (int j = 0; j < @event.Count; j++) { var midiEvent = @event[j]; if (MidiEvent.IsNoteOn(midiEvent)) { string name = ((NoteOnEvent)midiEvent).NoteName; int note = NoteToInt(name); if (note < MinimumNote || note > MaximumNote) { Console.WriteLine($"The key {name} is out of range!"); continue; } var info = IntToInfo(note); int order = (int)(1 + midiEvent.AbsoluteTime * 4 / mf.DeltaTicksPerQuarterNote); if (order > MaxNotePosition) { MaxNotePosition = order; } if (NoteData.ContainsKey(order)) { NoteData[order].Add(info); } else { NoteData.Add(order, new List <NoteInfo> { info }); } if (NoteData[order].Count > Layers) { Layers = (short)NoteData[order].Count; } } } } }
void Start() { music = GetComponent <AudioSource>(); mf = new MidiFile(string.Format("Assets/Music/{0}.mid", filename)); for (int t = 0; t < mf.Tracks; t++) { foreach (MidiEvent ev in mf.Events[t]) { if (ev.CommandCode == MidiCommandCode.MetaEvent && ((MetaEvent)ev).MetaEventType == MetaEventType.TimeSignature) { beatsInBar = ((TimeSignatureEvent)ev).Numerator; ticksInBar = beatsInBar * mf.DeltaTicksPerQuarterNote; } else if (MidiEvent.IsNoteOn(ev)) { events.Add((NoteOnEvent)ev); } } } }
private IEnumerator PlayMidiTrack() { UnityEngine.Debug.Log("Starting MIDI File"); var track = mf.Events[0]; // MIDI Files for VRMIN should only have one track int eventIdx = 0; foreach (var midiEvent in track) { if (MidiEvent.IsNoteOn(midiEvent)) { NoteOnEvent noteOn = (NoteOnEvent)midiEvent; //find next note on int nextIdx = eventIdx + 1; while (nextIdx < track.Count && !MidiEvent.IsNoteOn(track[nextIdx])) { nextIdx++; } // found a note on event or end of track //build Note Message int nextNote = nextIdx != track.Count ? ((NoteOnEvent)track[nextIdx]).NoteNumber : -1; // if we reached the end without a Note on then send -1 float length = (noteOn.NoteLength / ppq) * 60 / tempo; // Note length in seconds CurrentNote = new NoteMessage(noteOn.NoteNumber, nextNote, length); Debug.Log("Note Length: " + length); yield return(new WaitForSecondsRealtime(length)); } eventIdx++; } CurrentNote = new NoteMessage(-1); // Done so let's send a final Message with note = -1 Running = false; playMidi = PlayMidiTrack(); // And reset the IEnumerator to we can play another track }
// CLASS FUNCTIONS public void readMidiFile(string fileName) { if (GetComponent <MidiLoad>().Load(fileName)) { int index = 0; for (int n = 0; n < GetComponent <MidiLoad>().midifile.Tracks; ++n) { foreach (MidiEvent midiEvent in GetComponent <MidiLoad>().midifile.Events[n]) { if (MidiEvent.IsNoteOn(midiEvent)) { NoteEvent ne = (NoteEvent)midiEvent; MusicSheet.instance.addNote(ne.NoteNumber, ne.NoteName, index++, (float)midiEvent.AbsoluteTime / GetComponent <MidiLoad>().midifile.DeltaTicksPerQuarterNote); } } } MusicSheet.instance.initialize(); } else { Debug.Log("error loading midi file"); } }
public Midi(string path) { var mf = new MidiFile(path, false); // Get the minimum startation tick. int TickTime = mf.DeltaTicksPerQuarterNote; MidiMBT mbt = new MidiMBT(mf); for (int i = 0; i < mf.Tracks; i++) { var @event = mf.Events[i]; for (int j = 0; j < @event.Count; j++) { var midiEvent = @event[j]; if (!MidiEvent.IsNoteOn(midiEvent)) { continue; } var tick = mbt.GetTick(midiEvent.AbsoluteTime); if (tick < TickTime && tick > 0) { TickTime = (int)tick; } } } for (int i = 0; i < mf.Tracks; i++) { var @event = mf.Events[i]; for (int j = 0; j < @event.Count; j++) { var midiEvent = @event[j]; if (MidiEvent.IsNoteOn(midiEvent)) { string name = ((NoteOnEvent)midiEvent).NoteName; int note = NoteToInt(name); if (note < MinimumNote || note > MaximumNote) { LogBuilder.AppendLine($"The key {name} is out of range!"); continue; } var info = IntToInfo(note); int order = 1 + (int)midiEvent.AbsoluteTime / TickTime; if (order > MaxNotePosition) { MaxNotePosition = order; } if (NoteData.ContainsKey(order)) { NoteData[order].Add(info); } else { NoteData.Add(order, new List <NoteInfo> { info }); } if (NoteData[order].Count > Layers) { Layers = (short)NoteData[order].Count; } } } } }
public static List <HitsoundLayer> ImportMidi(string path, double offset = 0, bool instruments = true, bool keysounds = true, bool lengths = true, double lengthRoughness = 1, bool velocities = true, double velocityRoughness = 1) { List <HitsoundLayer> hitsoundLayers = new List <HitsoundLayer>(); var strictMode = false; var mf = new MidiFile(path, strictMode); Console.WriteLine( $@"Format {mf.FileFormat}, " + $@"Tracks {mf.Tracks}, " + $@"Delta Ticks Per Quarter Note {mf.DeltaTicksPerQuarterNote}"); List <TempoEvent> tempos = new List <TempoEvent>(); foreach (var track in mf.Events) { tempos.AddRange(track.OfType <TempoEvent>()); } tempos = tempos.OrderBy(o => o.AbsoluteTime).ToList(); List <double> cumulativeTime = CalculateCumulativeTime(tempos, mf.DeltaTicksPerQuarterNote); Dictionary <int, int> channelBanks = new Dictionary <int, int>(); Dictionary <int, int> channelPatches = new Dictionary <int, int>(); // Loop through every event of every track for (int track = 0; track < mf.Tracks; track++) { foreach (var midiEvent in mf.Events[track]) { if (midiEvent is PatchChangeEvent pc) { channelPatches[pc.Channel] = pc.Patch; } else if (midiEvent is ControlChangeEvent co) { if (co.Controller == MidiController.BankSelect) { channelBanks[co.Channel] = (co.ControllerValue * 128) + (channelBanks.ContainsKey(co.Channel) ? (byte)channelBanks[co.Channel] : 0); } else if (co.Controller == MidiController.BankSelectLsb) { channelBanks[co.Channel] = co.ControllerValue + (channelBanks.ContainsKey(co.Channel) ? channelBanks[co.Channel] >> 8 * 128 : 0); } } else if (MidiEvent.IsNoteOn(midiEvent)) { var on = midiEvent as NoteOnEvent; double time = CalculateTime(on.AbsoluteTime, tempos, cumulativeTime, mf.DeltaTicksPerQuarterNote); double length = on.OffEvent != null ? CalculateTime(on.OffEvent.AbsoluteTime, tempos, cumulativeTime, mf.DeltaTicksPerQuarterNote) - time : -1; length = RoundLength(length, lengthRoughness); bool keys = keysounds || on.Channel == 10; int bank = instruments ? on.Channel == 10 ? 128 : channelBanks.ContainsKey(on.Channel) ? channelBanks[on.Channel] : 0 : -1; int patch = instruments && channelPatches.ContainsKey(on.Channel) ? channelPatches[on.Channel] : -1; int instrument = -1; int key = keys ? on.NoteNumber : -1; length = lengths ? length : -1; int velocity = velocities ? on.Velocity : -1; velocity = (int)RoundVelocity(velocity, velocityRoughness); string lengthString = Math.Round(length).ToString(CultureInfo.InvariantCulture); string filename = $"{bank}\\{patch}\\{instrument}\\{key}\\{lengthString}\\{velocity}.wav"; string instrumentName = on.Channel == 10 ? "Percussion" : patch >= 0 && patch <= 127 ? PatchChangeEvent.GetPatchName(patch) : "Undefined"; string keyName = on.NoteName; string name = instrumentName; if (keysounds) { name += "," + keyName; } if (lengths) { name += "," + lengthString; } if (velocities) { name += "," + velocity; } var sampleArgs = new SampleGeneratingArgs(filename, bank, patch, instrument, key, length, velocity); var importArgs = new LayerImportArgs(ImportType.MIDI) { Path = path, Bank = bank, Patch = patch, Key = key, Length = length, LengthRoughness = lengthRoughness, Velocity = velocity, VelocityRoughness = velocityRoughness }; // Find the hitsoundlayer with this path HitsoundLayer layer = hitsoundLayers.Find(o => o.ImportArgs == importArgs); if (layer != null) { // Find hitsound layer with this path and add this time layer.Times.Add(time + offset); } else { // Add new hitsound layer with this path HitsoundLayer newLayer = new HitsoundLayer(name, SampleSet.Normal, Hitsound.Normal, sampleArgs, importArgs); newLayer.Times.Add(time + offset); hitsoundLayers.Add(newLayer); } } } } // Stretch the velocities to reach 127 int maxVelocity = hitsoundLayers.Max(o => o.SampleArgs.Velocity); foreach (var hsl in hitsoundLayers) { hsl.SampleArgs.Velocity = (int)Math.Round(hsl.SampleArgs.Velocity / (float)maxVelocity * 127); } // Sort the times hitsoundLayers.ForEach(o => o.Times = o.Times.OrderBy(t => t).ToList()); // Sort layers by name hitsoundLayers = hitsoundLayers.OrderBy(o => o.Name).ToList(); return(hitsoundLayers); }
public MidiNote[] GetNotes() { BuildTempoList(); List <MidiNote> notes = new List <MidiNote>(); double defaultTempo = 120; for (int n = 0; n < MidiFile.Tracks; n++) { foreach (MidiEvent midiEvent in MidiFile.Events[n]) { try { var tempoEvent = (NAudio.Midi.TempoEvent)midiEvent; defaultTempo = tempoEvent.Tempo; } catch { } } } for (int n = 0; n < MidiFile.Tracks; n++) { foreach (MidiEvent midiEvent in MidiFile.Events[n]) { if (MidiEvent.IsNoteOn(midiEvent)) { try { var t_note = (NoteOnEvent)midiEvent; MidiNote noteOn = new MidiNote(); noteOn.Note = t_note.NoteName; //noteOn.Channel = t_note.Channel; noteOn.Channel = n; noteOn.Velocity = t_note.Velocity; noteOn.StartTime = t_note.AbsoluteTime; if (_tempoEvents.Count > 0) { try { noteOn.Tempo = MidiFile.DeltaTicksPerQuarterNote * _tempoEvents.Last(a => a.AbsoluteTime <= t_note.AbsoluteTime).BPM / 60; } catch (Exception e) { noteOn.Tempo = MidiFile.DeltaTicksPerQuarterNote * defaultTempo / 60; } } else { noteOn.Tempo = MidiFile.DeltaTicksPerQuarterNote * defaultTempo / 60; } noteOn.Length = t_note.NoteLength / (float)noteOn.Tempo; notes.Add(noteOn); } catch (Exception formatEx) { throw formatEx; } } } } return(SortNotes(notes).ToArray()); }
public static bool IsNoteOn(this MidiEvent midiEvent) => MidiEvent.IsNoteOn(midiEvent);