Пример #1
0
        public void WriteMidi(string filename, int ticksPerPixel, int ppq, int startOffset, bool useColorEvents)
        {
            int        tracks = (Palette.Colors.Count + 15 - ((Palette.Colors.Count + 15) % 16)) / 16;
            MidiWriter writer = new MidiWriter(new BufferedStream(File.Open(filename, FileMode.Create)));

            writer.Init();
            writer.WriteFormat(1);
            writer.WritePPQ((ushort)ppq);
            writer.WriteNtrks((ushort)tracks);

            //writer.InitTrack();
            //writer.Write(new TimeSignatureEvent(0, 4, 2, 24, 8));
            //writer.Write(new TempoEvent(0, 500000));
            //writer.EndTrack();

            for (int i = 0; i < tracks; i++)
            {
                writer.InitTrack();
                if (useColorEvents)
                {
                    for (byte j = 0; j < 16; j++)
                    {
                        if (i * 16 + j < Palette.Colors.Count)
                        {
                            var c = Palette.Colors[i * 16 + j];
                            writer.Write(new ColorEvent(0, j, c.R, c.G, c.B, c.A));
                        }
                    }
                }

                uint o = (uint)startOffset;
                foreach (MIDIEvent e in EventBuffers[i])
                {
                    var _e = e.Clone();
                    _e.DeltaTime *= (uint)ticksPerPixel;
                    _e.DeltaTime += o;
                    o             = 0;
                    writer.Write(_e);
                }
                writer.EndTrack();
            }
            writer.Close();
        }
Пример #2
0
        static void Main(string[] args)
        {
            string filepath;

            if (args.Length > 0)
            {
                filepath = args[0];
            }
            else
            {
                Console.WriteLine("Select MIDI");
                var open = new OpenFileDialog();
                open.Filter = "Midi files (*.mid)|*.mid";
                if ((bool)open.ShowDialog())
                {
                    filepath = open.FileName;
                }
                else
                {
                    return;
                }
            }

            string output;

            if (args.Length == 1)
            {
                var ext = Path.GetExtension(filepath);
                output = filepath.Substring(filepath.Length - ext.Length, ext.Length) + "_OR.mid";
            }
            else if (args.Length > 2)
            {
                output = args[1];
            }
            else
            {
                Console.WriteLine("Save file...");
                var save = new SaveFileDialog();
                save.Filter = "Midi files (*.mid)|*.mid";
                if ((bool)save.ShowDialog())
                {
                    output = save.FileName;
                }
                else
                {
                    return;
                }
            }

            MidiFile       file;
            ParallelStream tempOutput;
            Stream         trueOutput;

            try
            {
                file = new MidiFile(() => new BufferedStream(File.Open(filepath, FileMode.Open, FileAccess.Read, FileShare.Read), 4096 * 4));
            }
            catch (IOException)
            {
                Console.WriteLine("Could not open input file\nPress any key to exit...");
                Console.ReadKey();
                return;
            }
            try
            {
                var s = File.Open(output + ".tmp", FileMode.Create);
                tempOutput = new ParallelStream(s, 4096 * 16);
            }
            catch (IOException)
            {
                Console.WriteLine("Could not open temporary output file\nPress any key to exit...");
                Console.ReadKey();
                return;
            }
            try
            {
                trueOutput = File.Open(output, FileMode.Create);
            }
            catch (IOException)
            {
                Console.WriteLine("Could not open true output file\nPress any key to exit...");
                Console.ReadKey();
                return;
            }

            Console.WriteLine("Processing the midi...");

            BlockingCollection <MIDIEvent>[] cacheEvents = new BlockingCollection <MIDIEvent> [file.TrackCount];
            AsyncNoteParse[]  inputNotes  = new AsyncNoteParse[file.TrackCount];
            AsyncNoteWriter[] outputNotes = new AsyncNoteWriter[file.TrackCount];
            Note[]            nextNotes   = new Note[file.TrackCount];
            Note[]            topNotes    = new Note[128];
            Queue <Note>[]    fullNotes   = new Queue <Note> [file.TrackCount];

            for (int i = 0; i < file.TrackCount; i++)
            {
                Console.WriteLine("Loading Tracks " + (i + 1) + "/" + file.TrackCount);
                cacheEvents[i] = new BlockingCollection <MIDIEvent>();

                var reader = file.GetAsyncBufferedTrack(i, 10000);
                inputNotes[i] = new AsyncNoteParse(reader, cacheEvents[i], 128);
                inputNotes[i].Init();
                outputNotes[i] = new AsyncNoteWriter(tempOutput.GetStream(i), cacheEvents[i], inputNotes[i], 128);
                fullNotes[i]   = new Queue <Note>();
            }

            for (int i = 0; i < file.TrackCount; i++)
            {
                try
                {
                    nextNotes[i] = inputNotes[i].Take();
                }
                catch { }
            }

            bool      allEnded   = false;
            bool      addedNotes = false;
            long      nc         = 0;
            long      nc2        = 0;
            Stopwatch sw         = new Stopwatch();

            sw.Start();
            Task writeTask = null;

            for (ulong tick = 0; !allEnded;)
            {
                for (int i = 0; i < topNotes.Length; i++)
                {
                    topNotes[i] = null;
                }
                allEnded   = true;
                addedNotes = false;
                ulong nextSmallest = 0;
                bool  first        = true;
                for (int i = 0; i < file.TrackCount; i++)
                {
                    while (nextNotes[i] != null && nextNotes[i].Start == tick)
                    {
                        addedNotes = true;
                        var n = nextNotes[i];

                        if (writeTask != null)
                        {
                            if (!writeTask.IsCompleted)
                            {
                                //Stopwatch d = new Stopwatch();
                                //d.Start();
                                writeTask.GetAwaiter().GetResult();
                                //Console.WriteLine(d.ElapsedTicks);
                            }
                        }

                        if (topNotes[n.Key] == null)
                        {
                            topNotes[n.Key] = n;
                            fullNotes[i].Enqueue(n);
                        }
                        else
                        {
                            if (topNotes[n.Key].End < n.End)
                            {
                                topNotes[n.Key] = n;
                                fullNotes[i].Enqueue(n);
                            }
                            else
                            {
                                if (topNotes[n.Key].Velocity < n.Velocity)
                                {
                                    topNotes[n.Key].Velocity = n.Velocity;
                                }
                            }
                        }

                        try
                        {
                            nextNotes[i] = inputNotes[i].Take();
                            nc++;
                        }
                        catch
                        {
                            nextNotes[i] = null;
                        }
                    }

                    if (nextNotes[i] != null)
                    {
                        allEnded = false;
                        if (first || nextNotes[i].Start < nextSmallest)
                        {
                            first        = false;
                            nextSmallest = nextNotes[i].Start;
                        }
                    }
                }
                if (!allEnded)
                {
                    tick = nextSmallest;
                }
                if (addedNotes)
                {
                    writeTask = Task.Run(() =>
                    {
                        Parallel.For(0, file.TrackCount, i =>
                        {
                            var fn = fullNotes[i];
                            while (fn.Count != 0)
                            {
                                outputNotes[i].Write(fn.Dequeue());
                                //fn.Dequeue();
                                nc2++;
                            }
                            if (nextNotes[i] == null && !outputNotes[i].Finalised)
                            {
                                try
                                {
                                    outputNotes[i].Finalise();
                                }
                                catch { }
                            }
                        });
                    });
                }

                if (sw.ElapsedMilliseconds > 1000)
                {
                    Console.WriteLine("Processed: " + nc.ToString("#,##0") + "\tKept: " + nc2.ToString("#,##0"));
                    sw.Reset();
                    sw.Start();
                }
            }
            Console.WriteLine("Processed: " + nc.ToString("#,##0") + "\tKept: " + nc2.ToString("#,##0"));

            Console.WriteLine("Waiting for all writers to finish...");
            writeTask.GetAwaiter().GetResult();
            for (int i = 0; i < file.TrackCount; i++)
            {
                if (!outputNotes[i].Finalised)
                {
                    try
                    {
                        outputNotes[i].Finalise();
                    }
                    catch { }
                }
            }
            for (int i = 0; i < file.TrackCount; i++)
            {
                outputNotes[i].Join();
            }
            for (int i = 0; i < file.TrackCount; i++)
            {
                outputNotes[i].Close();
            }

            Console.WriteLine("Writing final midi");
            var writer = new MidiWriter(trueOutput);

            writer.Init();
            writer.WriteNtrks((ushort)file.TrackCount);
            writer.WritePPQ(file.PPQ);
            writer.WriteFormat(file.Format);
            for (int i = 0; i < file.TrackCount; i++)
            {
                Console.WriteLine("Copying Track " + i + "/" + file.TrackCount);
                writer.InitTrack();
                var r = tempOutput.GetStream(i, true);
                r.CopyTo(trueOutput);
                r.Close();
                writer.EndTrack();
            }
            writer.Close();
            tempOutput.CloseAllStreams();
            tempOutput.Dispose();
            try
            {
                File.Delete(output + ".tmp");
            }
            catch
            {
                Console.WriteLine("Couldn't delete temporary file");
            }
            Console.WriteLine("Complete!\nPress any key to exit...");
            Console.ReadKey();
        }
Пример #3
0
        static void Main(string[] args)
        {
            //Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new ColourForm());

            var        midiout = new StreamWriter(@"E:\test.mid");
            var        midiin  = new StreamReader(@"E:\Midi\Pi.mid");
            MidiWriter writer  = new MidiWriter(midiout.BaseStream);

            writer.Init();

            var filter = new TrackFilter();


            MidiFileInfo info = MidiFileInfo.Parse(midiin.BaseStream);

            writer.WriteDivision(info.Division);
            writer.WriteNtrks((ushort)Math.Min(info.TrackCount, 65535));
            writer.WriteFormat(info.Format);

            for (int i = 0; i < info.TrackCount; i++)
            {
                Console.WriteLine("Priocessing track: " + i);
                byte[] trackbytes = new byte[info.Tracks[i].Length];
                midiin.BaseStream.Position = info.Tracks[i].Start;
                midiin.BaseStream.Read(trackbytes, 0, (int)info.Tracks[i].Length);
                writer.InitTrack();
                long   prevtime = 0;
                double hue      = i * 60;
                int    d        = 3;
                filter.MidiEventFilter = (byte[] dtimeb, int dtime, byte[] data, long time) =>
                {
                    byte[] e = new byte[] { 0xFF, 0x0A, 0x08, 0x00, 0x0F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFF };
                    //byte[] e = new byte[] { 0xFF, 0x0A, 0x0C, 0x00, 0x0F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF };
                    if (time - prevtime > d)
                    {
                        List <byte> o     = new List <byte>();
                        long        start = time - dtime;
                        while (prevtime + d < time)
                        {
                            prevtime += d;
                            int delta = (int)(prevtime - start);
                            int r, g, b;
                            HsvToRgb(hue, 1, 1, out r, out g, out b);
                            hue += 1;
                            hue  = hue % 360;
                            e[7] = (byte)r;
                            e[8] = (byte)g;
                            e[9] = (byte)b;
                            //HsvToRgb(hue + 60, 1, 1, out r, out g, out b);
                            //hue += 1;
                            //hue = hue % 360;
                            //e[11] = (byte)r;
                            //e[12] = (byte)g;
                            //e[13] = (byte)b;
                            o.AddRange(filter.MakeVariableLen(delta));
                            o.AddRange(e);
                            start += delta;
                        }
                        o.AddRange(filter.MakeVariableLen((int)(time - start)));
                        o.AddRange(data);
                        return(o.ToArray());
                    }
                    return(dtimeb.Concat(data).ToArray());
                };
                var newtrackbytes = filter.FilterTrack(new MemoryByteReader(trackbytes));
                writer.Write(newtrackbytes);
                writer.EndTrack();
            }

            writer.Close();
        }