示例#1
0
 public void WriteMusic(SmfMusic music)
 {
     WriteHeader(music.Format, (short)music.Tracks.Count, music.DeltaTimeSpec);
     foreach (var track in music.Tracks)
     {
         WriteTrack(track);
     }
 }
示例#2
0
 public void Read(Stream stream)
 {
     this.stream = stream;
     data        = new SmfMusic();
     try {
         DoParse();
     } finally {
         this.stream = null;
     }
 }
示例#3
0
        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;
        }
示例#4
0
        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;
                }
            };
        }
示例#5
0
        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);
        }
示例#6
0
        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;
        }
示例#7
0
 public MidiPlayer(SmfMusic music, IMidiTimeManager timeManager)
     : this(music, MidiAccessManager.Empty, timeManager)
 {
 }
示例#8
0
        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);
            }
        }
示例#9
0
        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);
            }
        }
示例#10
0
        public MidiSyncPlayer(SmfMusic music)
        {
            if (music == null)
                throw new ArgumentNullException ("music");

            this.music = music;
            events = SmfTrackMerger.Merge (music).Tracks [0].Events;
            state = PlayerState.Stopped;
        }
示例#11
0
 SmfTrackMerger(SmfMusic source)
 {
     this.source = source;
 }
示例#12
0
 public MidiPlayer(SmfMusic music)
     : this(music, MidiAccessManager.Empty)
 {
 }
示例#13
0
 public MidiPlayer(SmfMusic music, IMidiAccess access)
     : this(music, access, new SimpleMidiTimeManager())
 {
 }
示例#14
0
 public MidiPlayer(SmfMusic music)
     : this(music, MidiAccessManager.Empty)
 {
 }
示例#15
0
 MmlSmfGenerator(MmlResolvedMusic source)
 {
     this.source = source;
     result = new SmfMusic () { DeltaTimeSpec = (short) (source.BaseCount / 4) };
 }
示例#16
0
 public PortMidiPlayer(MidiOutput output, SmfMusic music)
     : base(music)
 {
     this.output = output;
     MessageReceived += delegate (SmfMessage m) { SendMidiMessage (m); };
 }
示例#17
0
        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;
                }
            };
        }
示例#18
0
 public MidiPlayer(SmfMusic music, IMidiAccess access, IMidiTimeManager timeManager)
     : this(music, access.OpenOutputAsync (access.Outputs.First ().Id).Result, timeManager)
 {
     should_dispose_output = true;
 }
示例#19
0
 public MidiPlayer(SmfMusic music, IMidiOutput output)
     : this(music, output, new SimpleMidiTimeManager())
 {
 }
示例#20
0
 public MidiPlayer(SmfMusic music, IMidiAccess access)
     : this(music, access, new SimpleMidiTimeManager ())
 {
 }
示例#21
0
 public MidiPlayer(SmfMusic music, IMidiTimeManager timeManager)
     : this(music, MidiAccessManager.Empty, timeManager)
 {
 }
示例#22
0
 public static SmfMusic Merge(SmfMusic source)
 {
     return(new SmfTrackMerger(source).GetMergedMessages());
 }
示例#23
0
 public MidiPlayer(SmfMusic music, IMidiAccess access, IMidiTimeManager timeManager)
     : this(music, access.OpenOutputAsync(access.Outputs.First()).Result, timeManager)
 {
     should_dispose_output = true;
 }
示例#24
0
        // 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);
        }
    }
示例#25
0
文件: SMF.cs 项目: atsushieno/mugene
 SmfTrackMerger(SmfMusic source)
 {
     this.source = source;
 }
示例#26
0
 public MidiPlayer(SmfMusic music)
 {
     player = new MidiSyncPlayer (music);
 }
示例#27
0
文件: SMF.cs 项目: atsushieno/mugene
        // 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;
        }
示例#28
0
 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();
 }
示例#29
0
文件: SMF.cs 项目: atsushieno/mugene
 public void WriteMusic(SmfMusic music)
 {
     WriteHeader (music.Format, (short) music.Tracks.Count, music.DeltaTimeSpec);
     foreach (var track in music.Tracks)
         WriteTrack (track);
 }
示例#30
0
文件: SMF.cs 项目: atsushieno/mugene
 public void Read(Stream stream)
 {
     this.stream = stream;
     data = new SmfMusic ();
     try {
         DoParse ();
     } finally {
         this.stream = null;
     }
 }
示例#31
0
 public MidiPlayer(SmfMusic music, IMidiOutput output)
     : this(music, output, new SimpleMidiTimeManager ())
 {
 }
示例#32
0
文件: SMF.cs 项目: atsushieno/mugene
 public static SmfMusic Merge(SmfMusic source)
 {
     return new SmfTrackMerger (source).GetMergedMessages ();
 }
示例#33
0
 public MidiSyncPlayer(SmfMusic music)
     : this(music, new SimpleMidiTimeManager())
 {
 }
示例#34
0
文件: SMF.cs 项目: atsushieno/mugene
        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;
        }
示例#35
0
 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 ();
 }
示例#37
0
 public MidiSyncPlayer(SmfMusic music)
     : this(music, new SimpleMidiTimeManager ())
 {
 }