Advertisement
Guest User

Untitled

a guest
Mar 26th, 2019
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.53 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using NAudio.Midi;
  5. using System;
  6.  
  7.  
  8. public class MidiSong : MonoBehaviour {
  9.  
  10.     AudioSource audioSource;
  11.  
  12.     MidiFile midiFile; // midi object
  13.     string midiPath = "/Users/queenjazz/Dropbox/projects/Music/2019/Drafts/make.mid"; // path to midi
  14.     public float timeOffset = 0f; // You can use this to start the song mid-way through
  15.     public float bpm = 88f; // bpm of the song
  16.     int ticksPerSecond; // ticks are the midi's internal timer, this is how many ticks per real-world second
  17.     public bool playing = false;
  18.     float startTime;
  19.     public int soloTrack; // use this for "listening" to a track, the number is the index of the track
  20.     List<NoteOnEvent> noteOns; // to store all the events in the track
  21.  
  22.     // Use this for initialization
  23.     void Start () {
  24.  
  25.         audioSource=GetComponent<AudioSource>();
  26.  
  27.         midiFile = new MidiFile(midiPath);
  28.  
  29.         ticksPerSecond = midiFile.DeltaTicksPerQuarterNote / 4;
  30.  
  31.     }
  32.  
  33.     // Update is called once per frame
  34.     void Update () {
  35.         if (Input.GetKeyDown(KeyCode.G)) {
  36.             Play();
  37.         }
  38.  
  39.         if (Input.GetKeyDown(KeyCode.H)) {
  40.             Stop();
  41.         }
  42.  
  43.         if (playing) {
  44.            
  45.             for (int i = noteOns.Count-1; i >= 0; i--) {
  46.                 float noteTime = MidiTickToTime(noteOns[i].AbsoluteTime);
  47.                 if ((Time.time - startTime) > noteTime) { // we just go through the list every frame and check if out time is past it yet
  48.                     // do something with soloNoteOns[i];
  49.                     noteOns.RemoveAt(i);
  50.                 }
  51.             }
  52.         }
  53.     }
  54.  
  55.     // midi events use an absoluteTime variable, this function converts it to actual time so you can use it
  56.     public float MidiTickToTime(long absoluteTime) {
  57.         return (60f * absoluteTime) / (bpm * midiFile.DeltaTicksPerQuarterNote);
  58.     }
  59.  
  60.     // Start playing the song; set the new base time and play the music.
  61.     void Play() {
  62.         audioSource.Play(); // play music
  63.         startTime = Time.time; // set new base time
  64.         startTime -= timeOffset; // if we're starting partway trhough, skip that time
  65.         audioSource.time = timeOffset; // skip the audio too
  66.         playing = true;
  67.  
  68.         // So we go through the track we're "listening" to, and grab all the events and put em in a list
  69.         noteOns = new List<NoteOnEvent>();
  70.         foreach (MidiEvent me in midiFile.Events[soloTrack]) {
  71.             if (me.CommandCode == MidiCommandCode.NoteOn) { // "NoteOn" is whenever a note starts playing.
  72.                 NoteOnEvent noe = (NoteOnEvent) me;
  73.                 noteOns.Add(noe); // add it to our list!
  74.             }
  75.         }
  76.     }
  77.  
  78.     void Stop() {
  79.         GetComponent<AudioSource>().Stop();
  80.     }
  81. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement