/// <summary> /// Show tracks info /// </summary> public static void ShowTracksInfoHtml(string fname, ref string strHtml, int iTrack = -1) { // MIDI ファイルを読み込む var midiData = MidiReader.ReadFrom(fname, Encoding.GetEncoding("shift-jis")); // MIDI イベント数、ノート数、プログラムチェンジの数、コントロールチェンジの数、メタイベント数、エクスクルーシブイベント数 strHtml = "<!DOCTYPE html PUBLIC \" -//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\"><html><head><style type=\"text/css\">" + "body{font-size: 9pt;text-align: center; padding: 0; margin: 0;}" + "table{width:100%;border-collapse: collapse;border: solid 1px;}" + "th{text-align: center;color: #444;background-color: #ccc;border-right: 1px solid #ccc;border-bottom: 1px solid #ccc;}" + "td{background-color: #fafafa;border-right: 1px solid #ccc;border-bottom: 1px solid #ccc;}" + "td.sel{background-color: #faaa8a;border-right: 1px solid #ccc;border-bottom: 1px solid #ccc;}" + "</style></head><body>"; strHtml += "<table><tr><th>Track</th><th>Event</th><th>Note</th><th>Prog</th><th>Control</th><th>Meta</th><th>Exclusive</th><th>Title</th></tr>"; for (int i = 0; i < midiData.Tracks.Count; i++) { string strTd = "<td>"; if (i == iTrack) { strTd = "<td class=\"sel\">"; } var track = midiData.Tracks[i]; strHtml += "<tr>" + strTd + i.ToString() + "</td>" + strTd + track.GetData <MidiEvent>().Count.ToString() + "</td>" + strTd + track.GetData <NoteEvent>().Count.ToString() + "</td>" + strTd + track.GetData <ProgramEvent>().Count.ToString() + "</td>" + strTd + track.GetData <ControlEvent>().Count.ToString() + "</td>" + strTd + track.GetData <MetaEvent>().Count.ToString() + "</td>" + strTd + track.GetData <ExclusiveEvent>().Count.ToString() + "</td>" + strTd + track.GetTitle(i == 0) + "</td></tr>"; } strHtml += "</table></body></html>"; }
private static void InitDomain(string filename) { // MIDI ファイルを読み込み //string fname = "../../../Resources/wood.mid";// 0 | 480 1440 | 2400 2880 3360 | 4320 4800 5280 5760 | 6240 … string fname = filename; if (!File.Exists(fname)) { Console.WriteLine("File does not exist"); return; } var midiData = MidiReader.ReadFrom(fname, Encoding.GetEncoding("shift-jis")); // テンポマップを作成 domain = new MidiFileDomain(midiData); }
public tempoHolder(string fname) { // MIDI ファイルを読み込む var midiData = MidiReader.ReadFrom(fname, Encoding.GetEncoding("shift-jis")); iBaseResolution = midiData.Resolution.Resolution; int nTrack = 0; if (nTrack >= midiData.Tracks.Count) { Console.WriteLine("File does not exist"); return; } #if DEBUG //Debug.Print("Track Evnt Note Prog Cont Meta Excl Title"); //Debug.Print("----- ---- ---- ---- ---- ---- ---- ----------------"); //for (int i = 0; i < midiData.Tracks.Count; i++) //{ // var track = midiData.Tracks[i]; // Debug.Print("{0} {1} {2} {3} {4} {5} {6} {7}", // i.ToString().PadLeft(5), // track.GetData<MidiEvent>().Count.ToString().PadLeft(4), // track.GetData<NoteEvent>().Count.ToString().PadLeft(4), // track.GetData<ProgramEvent>().Count.ToString().PadLeft(4), // track.GetData<ControlEvent>().Count.ToString().PadLeft(4), // track.GetData<MetaEvent>().Count.ToString().PadLeft(4), // track.GetData<ExclusiveEvent>().Count.ToString().PadLeft(4), // track.GetTitle(i == 0)); //} Debug.Print("----- -------- ---- ---- ---- ----------------"); Debug.Print(" 分母 分子"); Debug.Print("Track Tick Num Note Rhyt RequireToSend"); Debug.Print("----- -------- ---- ---- ---- ----------------"); for (int i = 0; i < midiData.Tracks.Count; i++) { var track = midiData.Tracks[i]; var metaEvs = track.GetData <NextMidi.DataElement.MetaData.RhythmEvent>(); if (metaEvs.Count > 0) { foreach (var evs in metaEvs) { Debug.Print("{0} {1} {2} {3} {4} {5}", i.ToString().PadLeft(5), evs.Tick.ToString().PadLeft(8), evs.EventNumber.ToString().PadLeft(4), evs.Note.ToString().PadLeft(4), evs.Rhythm.ToString().PadLeft(4), evs.RequireToSend.ToString()); } } } #endif // all tracks tempo search for (int i = 0; i < midiData.Tracks.Count; i++) { var track = midiData.Tracks[i]; var tempoEvs = track.GetData <TempoEvent>(); if (tempoEvs.Count > 0) { #if DEBUG Debug.Print("------ ----- -------- -------------------------"); Debug.Print("Tick Tempo MicroSec speed / Oh, tempo.Tempo is integer..."); Debug.Print("------ ----- -------- -------------------------"); #endif long nPassedTime = 0; double dPreTickSec = 0.0; long nPreMicroSecond = 0; long nPreTick = 0; long nPreTempo = 0; long nPrePassedTime = 0; foreach (var tempo in tempoEvs) { long nContinueTick = tempo.Tick - nPreTick; nPassedTime += (long)(nContinueTick * dPreTickSec); dPreTickSec = tempo.MicroSecond / 1.0 / midiData.Resolution.Resolution; #if DEBUG Debug.WriteLine("{0} {1} {2} {3}", tempo.Tick.ToString().PadLeft(6), tempo.Tempo.ToString().PadLeft(5), tempo.MicroSecond.ToString().PadLeft(8), 60.0 / (tempo.MicroSecond / 1000000.0)); #endif tempoEventBase _tmp = new tempoEventBase(nPreMicroSecond, nPreTick, tempo.Tick, nPrePassedTime, nPreTempo); if (nPreTick != tempo.Tick) { tempoList.Add(_tmp); } nPreMicroSecond = tempo.MicroSecond; nPreTick = tempo.Tick; nPreTempo = tempo.Tempo; nPrePassedTime = nPassedTime; } tempoEventBase tmp = new tempoEventBase(nPreMicroSecond, nPreTick, Int32.MaxValue - 1, nPrePassedTime, nPreTempo); tempoList.Add(tmp); } } #if DEBUG //Debug.WriteLine("------------------------------------------------------------"); //Debug.WriteLine("us/q-note tick tick tmp passed time from top[ms]"); //Debug.WriteLine("---------- ---------- ---------- --- -----------------------"); //foreach (tempoEventBase _tmp in tempoList) //{ // Debug.WriteLine("{0} {1} {2} {3} {4}", // _tmp.nQuoteNoteMicroSec.ToString().PadLeft(10), // _tmp.nStartTick.ToString().PadLeft(10), // _tmp.nNextTick.ToString().PadLeft(10), // _tmp.nTempo.ToString().PadLeft(3), // _tmp.nPassedTimeMicroSec / 1000); //} //Debug.WriteLine("------------------------------------------------------------"); #endif }
public static int GetMidiDataInfo(string strMidiFile, int iTrack, float keyFramePerSec, long nMMDPasteStartPos, long nPreAction, ref List <List <long> > listMidiFingering, int iReadType = 0) { if (!File.Exists(strMidiFile)) { return(3); } // get tempo information tempoHolder myTempo = new tempoHolder(strMidiFile); if (myTempo == null) { return(2); } // - Reed MIDI file var midiData = MidiReader.ReadFrom(strMidiFile, Encoding.GetEncoding("shift-jis")); if (iReadType == 0) { if (iTrack >= 0) { if (iTrack >= midiData.Tracks.Count) { return(1); } //double dMillisecToFrame = Scene.KeyFramePerSec / 1000.0; double dMillisecToFrame = keyFramePerSec / 1000.0; var track = midiData.Tracks[iTrack]; int iMidiFingeringCnt = 0; // long nPreviousNoteTickCheck = 99999; foreach (var note in track.GetData <NoteEvent>()) { // - 0:frame-paste-to1, 1:frame-paste-to2, 2:note, 3:vel, 4:finger, 5:wrist center pos, 6:self array ID, 7: Polyphonic_ID long nMillisec = myTempo.GetGateOnStartTimeMilliSec(note.Tick); long nFramePaste = (long)(nMillisec * dMillisecToFrame) + nMMDPasteStartPos - nPreAction; long nMillsecHold = myTempo.GetGateOnStartTimeMilliSec(note.Tick + note.Gate); long nFramePasteHold = (long)(nMillsecHold * dMillisecToFrame) + nMMDPasteStartPos + nPreAction; // To correct fog sound (keyframe of on and offs). nFramePasteHold -= 1; listMidiFingering.Add(new List <long>() { nFramePaste, nFramePasteHold, note.Note, note.Velocity, 0, 0, iMidiFingeringCnt, 0, 0 }); iMidiFingeringCnt++; } } } else { byte midiControlNumber = 0x00; if (iReadType == CONTROL_EVENT_HOLD) { midiControlNumber = 0x40; } if (iReadType == CONTROL_EVENT_SUSTAIN) { midiControlNumber = 0x42; } if (iReadType == CONTROL_EVENT_SOFT) { midiControlNumber = 0x43; } // if iTrack is less than 0, get all tracks. for (int i = 0; i < midiData.Tracks.Count; i++) { if ((iTrack >= 0) && (iTrack != i)) { continue; } double dMillisecToFrame = keyFramePerSec / 1000.0; var track = midiData.Tracks[i]; int iMidiFingeringCnt = 0; foreach (var note in track.GetData <ControlEvent>()) { if (note.Number == midiControlNumber) { long nMillisec = myTempo.GetGateOnStartTimeMilliSec(note.Tick); long nFramePaste = (long)(nMillisec * dMillisecToFrame) + nMMDPasteStartPos - nPreAction; if (listMidiFingering.Count > 0 && listMidiFingering.Last()[CommonConstants.CSV_COL_ON_FRAME] == nFramePaste) { nFramePaste++; } long nFramePasteHold = nFramePaste + 1; //listMidiFingering.Add(new List<long>() { 0, nFramePaste, nFramePasteHold, note.Value }); listMidiFingering.Add(new List <long>() { nFramePaste, nFramePasteHold, 0, note.Value, 0, 0, iMidiFingeringCnt, 0, 0 }); iMidiFingeringCnt++; } } } } // hold frame modification // the same key off and on, change off key one step before for (int iMidiCnt = 0; iMidiCnt < listMidiFingering.Count - 1; iMidiCnt++) { long note = listMidiFingering[iMidiCnt][CommonConstants.CSV_COL_NOTE]; long onframe = listMidiFingering[iMidiCnt][CommonConstants.CSV_COL_ON_FRAME]; long offframe = listMidiFingering[iMidiCnt][CommonConstants.CSV_COL_OFF_FRAME]; for (int iNext = iMidiCnt + 1; iNext < Math.Min(iMidiCnt + 10, listMidiFingering.Count); iNext++) { if (listMidiFingering[iNext][CommonConstants.CSV_COL_ON_FRAME] > offframe + 1) { continue; } if (listMidiFingering[iNext][CommonConstants.CSV_COL_NOTE] == note) { if ((offframe + 2) >= listMidiFingering[iNext][CommonConstants.CSV_COL_ON_FRAME]) { if (onframe + 2 < offframe) { listMidiFingering[iMidiCnt][CommonConstants.CSV_COL_OFF_FRAME] = offframe - 2; } else { listMidiFingering[iNext][CommonConstants.CSV_COL_ON_FRAME] = onframe; listMidiFingering[iMidiCnt][CommonConstants.CSV_COL_OFF_FRAME] = listMidiFingering[iNext][CommonConstants.CSV_COL_OFF_FRAME]; } } } } } return(0); }