public void WriteMusic(SmfMusic music) { WriteHeader(music.Format, (short)music.Tracks.Count, music.DeltaTimeSpec); foreach (var track in music.Tracks) { WriteTrack(track); } }
public void Read(Stream stream) { this.stream = stream; data = new SmfMusic(); try { DoParse(); } finally { this.stream = null; } }
public MidiSyncPlayer(SmfMusic music, IMidiTimeManager timeManager) { if (music == null) { throw new ArgumentNullException("music"); } time_manager = timeManager; this.music = music; messages = SmfTrackMerger.Merge(music).Tracks [0].Messages; state = PlayerState.Stopped; }
public MidiPlayer(SmfMusic music, IMidiOutput output, IMidiTimeManager timeManager) { if (music == null) { throw new ArgumentNullException("music"); } if (output == null) { throw new ArgumentNullException("output"); } if (timeManager == null) { throw new ArgumentNullException("timeManager"); } this.output = output; player = new MidiSyncPlayer(music, timeManager); EventReceived += (m) => { switch (m.EventType) { case SmfEvent.SysEx1: case SmfEvent.SysEx2: if (buffer.Length <= m.Data.Length) { buffer = new byte [buffer.Length * 2]; } buffer [0] = m.StatusByte; Array.Copy(m.Data, 0, buffer, 1, m.Data.Length); output.SendAsync(buffer, 0, m.Data.Length + 1, 0); break; case SmfEvent.Meta: // do nothing. break; default: var size = SmfEvent.FixedDataSize(m.StatusByte); buffer [0] = m.StatusByte; buffer [1] = m.Msb; buffer [2] = m.Lsb; output.SendAsync(buffer, 0, size + 1, 0); break; } }; }
public SmfMusic Split() { int totalDeltaTime = 0; foreach (var e in source) { totalDeltaTime += e.DeltaTime; int id = GetTrackID(e); GetTrack(id).AddMessage(totalDeltaTime, e); } var m = new SmfMusic(); m.DeltaTimeSpec = delta_time_spec; foreach (var t in tracks.Values) { m.Tracks.Add(t.Track); } return(m); }
public MidiSyncPlayer(SmfMusic music, IMidiTimeManager timeManager) { if (music == null) throw new ArgumentNullException ("music"); time_manager = timeManager; this.music = music; messages = SmfTrackMerger.Merge (music).Tracks [0].Messages; state = PlayerState.Stopped; }
public MidiPlayer(SmfMusic music, IMidiTimeManager timeManager) : this(music, MidiAccessManager.Empty, timeManager) { }
public static void Main(string [] args) { int inId = -1, outId = -1, bufsize = -1; string filename = null; TimeSpan interval = TimeSpan.Zero; byte [] ex = null; foreach (var arg in args) { if (arg.StartsWith ("--in:")) { if (!int.TryParse (arg.Substring (5), out inId)) inId = -1; } if (arg.StartsWith ("--out:")) { if (!int.TryParse (arg.Substring (6), out outId)) outId = -1; } if (arg.StartsWith ("--buffer:")) { if (!int.TryParse (arg.Substring (9), out bufsize)) bufsize = -1; } if (arg.StartsWith ("--file:")) filename = arg.Substring (7); if (arg.StartsWith ("--interval:")) { int intervalint; if (int.TryParse (arg.Substring (11), out intervalint)) interval = TimeSpan.FromMilliseconds (intervalint); } if (arg.StartsWith ("--sysex:")) { string [] l = arg.Substring (8).Split (','); ex = new byte [l.Length]; byte v; for (int i = 0; i < ex.Length; i++) { if (byte.TryParse (l [i], NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out v)) ex [i] = v; else { ex = null; break; } } if (ex == null) { Console.WriteLine ("invalid sysex: " + arg); return; } } } var a = new List<MidiDeviceInfo> (MidiDeviceManager.AllDevices); if (inId < 0) { foreach (var dev in a) if (dev.IsInput) Console.WriteLine ("ID {0}: {1}", dev.ID, dev.Name); Console.WriteLine ("Type number to select MIDI In Device to use (type anything else to quit)"); if (!int.TryParse (Console.ReadLine (), out inId)) return; } if (outId < 0) { foreach (var dev in a) if (dev.IsOutput) Console.WriteLine ("ID {0}: {1}", dev.ID, dev.Name); Console.WriteLine ("Type number to select MIDI Out Device to use (type anything else to quit)"); if (!int.TryParse (Console.ReadLine (), out outId)) return; } var dump = new BulkDump (); if (interval != TimeSpan.Zero) dump.Interval = interval; if (bufsize > 0) dump.BufferSize = bufsize; if (ex != null) dump.SetSysEx (ex); dump.Start (inId, outId); Console.WriteLine ("Type [CR] to stop receiving"); Console.ReadLine (); dump.Stop (); if (String.IsNullOrEmpty (filename)) { Console.Write ("Type filename to save if you want: "); filename = Console.ReadLine (); } if (filename.Length > 0) { var music = new SmfMusic (); var track = new SmfTrack (); foreach (var e in dump.Results) { if (e.SysEx != null) track.Messages.Add (new SmfMessage (e.Timestamp, new SmfEvent (0xF0, 0, 0, e.SysEx))); else track.Messages.Add (new SmfMessage (e.Timestamp, new SmfEvent (e.Message.Value))); } music.Tracks.Add (track); using (var f = File.Create (filename)) new SmfWriter (f).WriteMusic (music); } }
public static void Main(string [] args) { int inId = -1, outId = -1, bufsize = -1; string filename = null; TimeSpan interval = TimeSpan.Zero; byte [] ex = null; foreach (var arg in args) { if (arg.StartsWith("--in:")) { if (!int.TryParse(arg.Substring(5), out inId)) { inId = -1; } } if (arg.StartsWith("--out:")) { if (!int.TryParse(arg.Substring(6), out outId)) { outId = -1; } } if (arg.StartsWith("--buffer:")) { if (!int.TryParse(arg.Substring(9), out bufsize)) { bufsize = -1; } } if (arg.StartsWith("--file:")) { filename = arg.Substring(7); } if (arg.StartsWith("--interval:")) { int intervalint; if (int.TryParse(arg.Substring(11), out intervalint)) { interval = TimeSpan.FromMilliseconds(intervalint); } } if (arg.StartsWith("--sysex:")) { string [] l = arg.Substring(8).Split(','); ex = new byte [l.Length]; byte v; for (int i = 0; i < ex.Length; i++) { if (byte.TryParse(l [i], NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out v)) { ex [i] = v; } else { ex = null; break; } } if (ex == null) { Console.WriteLine("invalid sysex: " + arg); return; } } } var a = new List <MidiDeviceInfo> (MidiDeviceManager.AllDevices); if (inId < 0) { foreach (var dev in a) { if (dev.IsInput) { Console.WriteLine("ID {0}: {1}", dev.ID, dev.Name); } } Console.WriteLine("Type number to select MIDI In Device to use (type anything else to quit)"); if (!int.TryParse(Console.ReadLine(), out inId)) { return; } } if (outId < 0) { foreach (var dev in a) { if (dev.IsOutput) { Console.WriteLine("ID {0}: {1}", dev.ID, dev.Name); } } Console.WriteLine("Type number to select MIDI Out Device to use (type anything else to quit)"); if (!int.TryParse(Console.ReadLine(), out outId)) { return; } } var dump = new BulkDump(); if (interval != TimeSpan.Zero) { dump.Interval = interval; } if (bufsize > 0) { dump.BufferSize = bufsize; } if (ex != null) { dump.SetSysEx(ex); } dump.Start(inId, outId); Console.WriteLine("Type [CR] to stop receiving"); Console.ReadLine(); dump.Stop(); if (String.IsNullOrEmpty(filename)) { Console.Write("Type filename to save if you want: "); filename = Console.ReadLine(); } if (filename.Length > 0) { var music = new SmfMusic(); var track = new SmfTrack(); foreach (var e in dump.Results) { if (e.SysEx != null) { track.Messages.Add(new SmfMessage(e.Timestamp, new SmfEvent(0xF0, 0, 0, e.SysEx))); } else { track.Messages.Add(new SmfMessage(e.Timestamp, new SmfEvent(e.Message.Value))); } } music.Tracks.Add(track); using (var f = File.Create(filename)) new SmfWriter(f).WriteMusic(music); } }
public MidiSyncPlayer(SmfMusic music) { if (music == null) throw new ArgumentNullException ("music"); this.music = music; events = SmfTrackMerger.Merge (music).Tracks [0].Events; state = PlayerState.Stopped; }
SmfTrackMerger(SmfMusic source) { this.source = source; }
public MidiPlayer(SmfMusic music) : this(music, MidiAccessManager.Empty) { }
public MidiPlayer(SmfMusic music, IMidiAccess access) : this(music, access, new SimpleMidiTimeManager()) { }
MmlSmfGenerator(MmlResolvedMusic source) { this.source = source; result = new SmfMusic () { DeltaTimeSpec = (short) (source.BaseCount / 4) }; }
public PortMidiPlayer(MidiOutput output, SmfMusic music) : base(music) { this.output = output; MessageReceived += delegate (SmfMessage m) { SendMidiMessage (m); }; }
public MidiPlayer(SmfMusic music, IMidiOutput output, IMidiTimeManager timeManager) { if (music == null) throw new ArgumentNullException ("music"); if (output == null) throw new ArgumentNullException ("output"); if (timeManager == null) throw new ArgumentNullException ("timeManager"); this.output = output; player = new MidiSyncPlayer (music, timeManager); EventReceived += (m) => { switch (m.EventType) { case SmfEvent.SysEx1: case SmfEvent.SysEx2: if (buffer.Length <= m.Data.Length) buffer = new byte [buffer.Length * 2]; buffer [0] = m.StatusByte; Array.Copy (m.Data, 0, buffer, 1, m.Data.Length); output.SendAsync (buffer, 0, m.Data.Length + 1, 0); break; case SmfEvent.Meta: // do nothing. break; default: var size = SmfEvent.FixedDataSize (m.StatusByte); buffer [0] = m.StatusByte; buffer [1] = m.Msb; buffer [2] = m.Lsb; output.SendAsync (buffer, 0, size + 1, 0); break; } }; }
public MidiPlayer(SmfMusic music, IMidiAccess access, IMidiTimeManager timeManager) : this(music, access.OpenOutputAsync (access.Outputs.First ().Id).Result, timeManager) { should_dispose_output = true; }
public MidiPlayer(SmfMusic music, IMidiOutput output) : this(music, output, new SimpleMidiTimeManager()) { }
public MidiPlayer(SmfMusic music, IMidiAccess access) : this(music, access, new SimpleMidiTimeManager ()) { }
public static SmfMusic Merge(SmfMusic source) { return(new SmfTrackMerger(source).GetMergedMessages()); }
public MidiPlayer(SmfMusic music, IMidiAccess access, IMidiTimeManager timeManager) : this(music, access.OpenOutputAsync(access.Outputs.First()).Result, timeManager) { should_dispose_output = true; }
// FIXME: it should rather be implemented to iterate all // tracks with index to messages, pick the track which contains // the nearest event and push the events into the merged queue. // It's simpler, and costs less by removing sort operation // over thousands of events. SmfMusic GetMergedMessages() { IList <SmfMessage> l = new List <SmfMessage> (); foreach (var track in source.Tracks) { int delta = 0; foreach (var mev in track.Messages) { delta += mev.DeltaTime; l.Add(new SmfMessage(delta, mev.Event)); } } if (l.Count == 0) { return new SmfMusic() { DeltaTimeSpec = source.DeltaTimeSpec } } ; // empty (why did you need to sort your song file?) // Sort() does not always work as expected. // For example, it does not always preserve event // orders on the same channels when the delta time // of event B after event A is 0. It could be sorted // either as A->B or B->A. // // To resolve this ieeue, we have to sort "chunk" // of events, not all single events themselves, so // that order of events in the same chunk is preserved // i.e. [AB] at 48 and [CDE] at 0 should be sorted as // [CDE] [AB]. var idxl = new List <int> (l.Count); idxl.Add(0); int prev = 0; for (int i = 0; i < l.Count; i++) { if (l [i].DeltaTime != prev) { idxl.Add(i); prev = l [i].DeltaTime; } } idxl.Sort(delegate(int i1, int i2) { return(l [i1].DeltaTime - l [i2].DeltaTime); }); // now build a new event list based on the sorted blocks. var l2 = new List <SmfMessage> (l.Count); int idx; for (int i = 0; i < idxl.Count; i++) { for (idx = idxl [i], prev = l [idx].DeltaTime; idx < l.Count && l [idx].DeltaTime == prev; idx++) { l2.Add(l [idx]); } } //if (l.Count != l2.Count) throw new Exception (String.Format ("Internal eror: count mismatch: l1 {0} l2 {1}", l.Count, l2.Count)); l = l2; // now messages should be sorted correctly. var waitToNext = l [0].DeltaTime; for (int i = 0; i < l.Count - 1; i++) { if (l [i].Event.Value != 0) // if non-dummy { var tmp = l [i + 1].DeltaTime - l [i].DeltaTime; l [i] = new SmfMessage(waitToNext, l [i].Event); waitToNext = tmp; } } l [l.Count - 1] = new SmfMessage(waitToNext, l [l.Count - 1].Event); var m = new SmfMusic(); m.DeltaTimeSpec = source.DeltaTimeSpec; m.Format = 0; m.Tracks.Add(new SmfTrack(l)); return(m); } }
public MidiPlayer(SmfMusic music) { player = new MidiSyncPlayer (music); }
// FIXME: it should rather be implemented to iterate all // tracks with index to messages, pick the track which contains // the nearest event and push the events into the merged queue. // It's simpler, and costs less by removing sort operation // over thousands of events. SmfMusic GetMergedMessages() { IList<SmfMessage> l = new List<SmfMessage> (); foreach (var track in source.Tracks) { int delta = 0; foreach (var mev in track.Messages) { delta += mev.DeltaTime; l.Add (new SmfMessage (delta, mev.Event)); } } if (l.Count == 0) return new SmfMusic () { DeltaTimeSpec = source.DeltaTimeSpec }; // empty (why did you need to sort your song file?) // Sort() does not always work as expected. // For example, it does not always preserve event // orders on the same channels when the delta time // of event B after event A is 0. It could be sorted // either as A->B or B->A. // // To resolve this ieeue, we have to sort "chunk" // of events, not all single events themselves, so // that order of events in the same chunk is preserved // i.e. [AB] at 48 and [CDE] at 0 should be sorted as // [CDE] [AB]. var idxl = new List<int> (l.Count); idxl.Add (0); int prev = 0; for (int i = 0; i < l.Count; i++) { if (l [i].DeltaTime != prev) { idxl.Add (i); prev = l [i].DeltaTime; } } idxl.Sort (delegate (int i1, int i2) { return l [i1].DeltaTime - l [i2].DeltaTime; }); // now build a new event list based on the sorted blocks. var l2 = new List<SmfMessage> (l.Count); int idx; for (int i = 0; i < idxl.Count; i++) for (idx = idxl [i], prev = l [idx].DeltaTime; idx < l.Count && l [idx].DeltaTime == prev; idx++) l2.Add (l [idx]); //if (l.Count != l2.Count) throw new Exception (String.Format ("Internal eror: count mismatch: l1 {0} l2 {1}", l.Count, l2.Count)); l = l2; // now messages should be sorted correctly. var waitToNext = l [0].DeltaTime; for (int i = 0; i < l.Count - 1; i++) { if (l [i].Event.Value != 0) { // if non-dummy var tmp = l [i + 1].DeltaTime - l [i].DeltaTime; l [i] = new SmfMessage (waitToNext, l [i].Event); waitToNext = tmp; } } l [l.Count - 1] = new SmfMessage (waitToNext, l [l.Count - 1].Event); var m = new SmfMusic (); m.DeltaTimeSpec = source.DeltaTimeSpec; m.Format = 0; m.Tracks.Add (new SmfTrack (l)); return m; }
internal void LoadFileAsync(FileInfo file) { FileInfo prevfile = midifile; if (file == prevfile || file == null) return; midifile = file; new Thread ((ThreadStart) delegate { try { DrawCommon ("Loading " + midifile.Name); UpdateView(); jetfile = midifile; using (var fs = File.OpenRead(midifile.FullName)) { SmfReader r = new SmfReader(fs); r.Parse(); smf_music = r.Music; smf_music = SmfTrackMerger.Merge(smf_music); DrawCommon("Loaded"); } } catch (SmfParserException ex) { DrawCommon ("Parse error " + ex); } catch (IOException ex) { DrawCommon ("I/O error " + ex); } }).Start(); }
public void WriteMusic(SmfMusic music) { WriteHeader (music.Format, (short) music.Tracks.Count, music.DeltaTimeSpec); foreach (var track in music.Tracks) WriteTrack (track); }
public void Read(Stream stream) { this.stream = stream; data = new SmfMusic (); try { DoParse (); } finally { this.stream = null; } }
public MidiPlayer(SmfMusic music, IMidiOutput output) : this(music, output, new SimpleMidiTimeManager ()) { }
public static SmfMusic Merge(SmfMusic source) { return new SmfTrackMerger (source).GetMergedMessages (); }
public MidiSyncPlayer(SmfMusic music) : this(music, new SimpleMidiTimeManager()) { }
public SmfMusic Split() { int totalDeltaTime = 0; foreach (var e in source) { totalDeltaTime += e.DeltaTime; int id = GetTrackID (e); GetTrack (id).AddMessage (totalDeltaTime, e); } var m = new SmfMusic (); m.DeltaTimeSpec = delta_time_spec; foreach (var t in tracks.Values) m.Tracks.Add (t.Track); return m; }
public int GetTotalPlayTimeMilliseconds() { return(SmfMusic.GetTotalPlayTimeMilliseconds(messages, music.DeltaTimeSpec)); }
void StartNewSong(SmfMusic music) { if (player != null) player.Dispose (); player = new MidiPlayer (music, MidiState.Instance.GetMidiOutput (this)); player.PlayAsync (); }
public MidiSyncPlayer(SmfMusic music) : this(music, new SimpleMidiTimeManager ()) { }