Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using NAudio.Midi;
- using System;
- public class MidiSong : MonoBehaviour {
- AudioSource audioSource;
- MidiFile midiFile; // midi object
- string midiPath = "/Users/queenjazz/Dropbox/projects/Music/2019/Drafts/make.mid"; // path to midi
- public float timeOffset = 0f; // You can use this to start the song mid-way through
- public float bpm = 88f; // bpm of the song
- int ticksPerSecond; // ticks are the midi's internal timer, this is how many ticks per real-world second
- public bool playing = false;
- float startTime;
- public int soloTrack; // use this for "listening" to a track, the number is the index of the track
- List<NoteOnEvent> noteOns; // to store all the events in the track
- // Use this for initialization
- void Start () {
- audioSource=GetComponent<AudioSource>();
- midiFile = new MidiFile(midiPath);
- ticksPerSecond = midiFile.DeltaTicksPerQuarterNote / 4;
- }
- // Update is called once per frame
- void Update () {
- if (Input.GetKeyDown(KeyCode.G)) {
- Play();
- }
- if (Input.GetKeyDown(KeyCode.H)) {
- Stop();
- }
- if (playing) {
- for (int i = noteOns.Count-1; i >= 0; i--) {
- float noteTime = MidiTickToTime(noteOns[i].AbsoluteTime);
- if ((Time.time - startTime) > noteTime) { // we just go through the list every frame and check if out time is past it yet
- // do something with soloNoteOns[i];
- noteOns.RemoveAt(i);
- }
- }
- }
- }
- // midi events use an absoluteTime variable, this function converts it to actual time so you can use it
- public float MidiTickToTime(long absoluteTime) {
- return (60f * absoluteTime) / (bpm * midiFile.DeltaTicksPerQuarterNote);
- }
- // Start playing the song; set the new base time and play the music.
- void Play() {
- audioSource.Play(); // play music
- startTime = Time.time; // set new base time
- startTime -= timeOffset; // if we're starting partway trhough, skip that time
- audioSource.time = timeOffset; // skip the audio too
- playing = true;
- // So we go through the track we're "listening" to, and grab all the events and put em in a list
- noteOns = new List<NoteOnEvent>();
- foreach (MidiEvent me in midiFile.Events[soloTrack]) {
- if (me.CommandCode == MidiCommandCode.NoteOn) { // "NoteOn" is whenever a note starts playing.
- NoteOnEvent noe = (NoteOnEvent) me;
- noteOns.Add(noe); // add it to our list!
- }
- }
- }
- void Stop() {
- GetComponent<AudioSource>().Stop();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement