protected IEnumerator ThreadPlay(byte[] midibytestoplay = null) { midiIsPlaying = true; stopMidiToPlay = false; newMidiToPlay = false; bool first = true; //Debug.Log("Start play"); try { miditoplay = new MidiLoad(); // No midi byte array, try to load from MidiFilesDN from resource if (midibytestoplay == null || midibytestoplay.Length == 0) { TextAsset mididata = Resources.Load <TextAsset>(Path.Combine(MidiPlayerGlobal.MidiFilesDB, MPTK_MidiName)); midibytestoplay = mididata.bytes; } miditoplay.KeepNoteOff = MPTK_KeepNoteOff; miditoplay.Load(midibytestoplay); } catch (System.Exception ex) { MidiPlayerGlobal.ErrorDetail(ex); } if (miditoplay != null) { yield return(StartCoroutine(MPTK_ClearAllSound(true))); try { OnEventStartPlayMidi.Invoke(); } catch (System.Exception ex) { MidiPlayerGlobal.ErrorDetail(ex); } try { miditoplay.ChangeSpeed(MPTK_Speed); miditoplay.ChangeQuantization(MPTK_Quantization); } catch (System.Exception ex) { MidiPlayerGlobal.ErrorDetail(ex); } lastTimePlay = Time.realtimeSinceStartup; timeFromStartPlay = 0d; // Loop on each events midi do { miditoplay.LogEvents = MPTK_LogEvents; miditoplay.EnableChangeTempo = MPTK_EnableChangeTempo; miditoplay.EnablePanChange = MPTK_EnablePanChange; if (MPTK_PauseOnDistance) { distanceEditorModeOnly = MidiPlayerGlobal.MPTK_DistanceToListener(this.transform); if (distanceEditorModeOnly > AudioSourceTemplate.maxDistance) { lastTimePlay = Time.realtimeSinceStartup; yield return(new WaitForSeconds(0.2f)); continue; } } if (playPause) { lastTimePlay = Time.realtimeSinceStartup; yield return(new WaitForSeconds(0.2f)); if (miditoplay.EndMidiEvent || newMidiToPlay || stopMidiToPlay) { break; } if (timeToPauseMilliSeconde > -1f) { timeToPauseMilliSeconde -= 0.2f; if (timeToPauseMilliSeconde <= 0f) { playPause = false; } } continue; } if (!first) { timeFromStartPlay += (Time.realtimeSinceStartup - lastTimePlay) * 1000f; } else { timeFromStartPlay = 0d; first = false; } lastTimePlay = Time.realtimeSinceStartup; //Debug.Log("---------------- " + timeFromStartPlay ); // Read midi events until this time List <MidiNote> notes = miditoplay.ReadMidiEvents(timeFromStartPlay); if (miditoplay.EndMidiEvent || newMidiToPlay || stopMidiToPlay) { break; } // Play notes read if (notes != null && notes.Count > 0) { try { if (OnEventNotesMidi != null) { OnEventNotesMidi.Invoke(notes); } } catch (System.Exception ex) { MidiPlayerGlobal.ErrorDetail(ex); } if (MPTK_DirectSendToPlayer) { MPTK_PlayNotes(notes); } //Debug.Log("---------------- play count:" + notes.Count + " " + timeFromStartMS ); } if (Application.isEditor) { TimeSpan times = TimeSpan.FromMilliseconds(timeFromStartPlay); playTimeEditorModeOnly = string.Format("{0:00}:{1:00}:{2:00}:{3:000}", times.Hours, times.Minutes, times.Seconds, times.Milliseconds); durationEditorModeOnly = string.Format("{0:00}:{1:00}:{2:00}:{3:000}", MPTK_Duration.Hours, MPTK_Duration.Minutes, MPTK_Duration.Seconds, MPTK_Duration.Milliseconds); } yield return(new WaitForSeconds(delayMilliSeconde / 1000f));// 0.01f); }while (true); } midiIsPlaying = false; try { if (OnEventEndPlayMidi != null && !stopMidiToPlay && !newMidiToPlay) { OnEventEndPlayMidi.Invoke(); } if ((MPTK_Loop || newMidiToPlay) && !stopMidiToPlay) { MPTK_Play(); } //stopMidiToPlay = false; } catch (System.Exception ex) { MidiPlayerGlobal.ErrorDetail(ex); } //Debug.Log("Stop play"); }
/// <summary> /// Return information about a midifile : patch change, copyright, ... /// </summary> /// <param name="pathfilename"></param> /// <param name="Info"></param> static public void GeneralInfo(string pathfilename, BuilderInfo Info) { try { int NumberBeatsMeasure; int NumberQuarterBeat; Debug.Log("Open midifile :" + pathfilename); MidiLoad midifile = new MidiLoad(); midifile.Load(pathfilename); if (midifile != null) { Info.Add(string.Format("Format: {0}", midifile.midifile.FileFormat)); Info.Add(string.Format("Tracks: {0}", midifile.midifile.Tracks)); Info.Add(string.Format("Ticks Quarter Note: {0}", midifile.midifile.DeltaTicksPerQuarterNote)); //if (false) { foreach (TrackMidiEvent trackEvent in midifile.MidiSorted) { if (trackEvent.Event.CommandCode == MidiCommandCode.NoteOn) { // Not used //if (((NoteOnEvent)trackEvent.Event).OffEvent != null) //{ // //infoTrackMidi[e.Channel].Events.Add((NoteOnEvent)e); // NoteOnEvent noteon = (NoteOnEvent)trackEvent.Event; //} } else if (trackEvent.Event.CommandCode == MidiCommandCode.NoteOff) { Debug.Log("NoteOff"); } else if (trackEvent.Event.CommandCode == MidiCommandCode.ControlChange) { // Not used //ControlChangeEvent controlchange = (ControlChangeEvent)e; //Debug.Log(string.Format("CtrlChange Track:{0} Channel:{1,2:00} {2}", track, e.Channel, controlchange.ToString())); } else if (trackEvent.Event.CommandCode == MidiCommandCode.PatchChange) { PatchChangeEvent change = (PatchChangeEvent)trackEvent.Event; Info.Add(BuildInfoTrack(trackEvent) + string.Format("PatchChange {0,3:000} {1}", change.Patch, PatchChangeEvent.GetPatchName(change.Patch)), 2); } else if (trackEvent.Event.CommandCode == MidiCommandCode.MetaEvent) { MetaEvent meta = (MetaEvent)trackEvent.Event; switch (meta.MetaEventType) { case MetaEventType.SetTempo: TempoEvent tempo = (TempoEvent)meta; Info.Add(BuildInfoTrack(trackEvent) + string.Format("SetTempo Tempo:{0} MicrosecondsPerQuarterNote:{1}", Math.Round(tempo.Tempo, 0), tempo.MicrosecondsPerQuarterNote), 2); //tempo.Tempo break; case MetaEventType.TimeSignature: TimeSignatureEvent timesig = (TimeSignatureEvent)meta; // Numerator: counts the number of beats in a measure. // For example a numerator of 4 means that each bar contains four beats. // Denominator: number of quarter notes in a beat.0=ronde, 1=blanche, 2=quarter, 3=eighth, etc. // Set default value NumberBeatsMeasure = timesig.Numerator; NumberQuarterBeat = System.Convert.ToInt32(System.Math.Pow(2, timesig.Denominator)); Info.Add(BuildInfoTrack(trackEvent) + string.Format("TimeSignature Beats Measure:{0} Beat Quarter:{1}", NumberBeatsMeasure, NumberQuarterBeat), 2); break; case MetaEventType.SequenceTrackName: // Sequence / Track Name case MetaEventType.ProgramName: case MetaEventType.TrackInstrumentName: // Track instrument name case MetaEventType.TextEvent: // Text event case MetaEventType.Copyright: // Copyright Info.Add(BuildInfoTrack(trackEvent) + ((TextEvent)meta).Text, 1); break; case MetaEventType.Lyric: // lyric case MetaEventType.Marker: // marker case MetaEventType.CuePoint: // cue point case MetaEventType.DeviceName: //Info.Add(BuildInfoTrack(trackEvent) + string.Format("{0} '{1}'", meta.MetaEventType.ToString(), ((TextEvent)meta).Text)); break; } } else { // Other midi event //Debug.Log(string.Format("Track:{0} Channel:{1,2:00} CommandCode:{2,3:000} AbsoluteTime:{3,6:000000}", track, e.Channel, e.CommandCode.ToString(), e.AbsoluteTime)); } } } //else DebugMidiSorted(midifile.MidiSorted); } else { Info.Add("Error reading midi file"); } } catch (System.Exception ex) { MidiPlayerGlobal.ErrorDetail(ex); } }