Exemplo n.º 1
0
        public IOWriteResult Write(BinaryWriter writer, List <WriteMesh> vMeshes, WriteOptions options)
        {
            string header = "g3sharp_stl ";

            byte[] header_bytes = ASCIIEncoding.ASCII.GetBytes(header);
            byte[] stl_header   = new byte[80];
            Array.Clear(stl_header, 0, stl_header.Length);
            Array.Copy(header_bytes, stl_header, header_bytes.Length);

            writer.Write(stl_header);

            int total_tris = 0;

            foreach (WriteMesh mesh in vMeshes)
            {
                total_tris += mesh.Mesh.TriangleCount;
            }
            writer.Write(total_tris);

            for (int mi = 0; mi < vMeshes.Count; ++mi)
            {
                IMesh mesh = vMeshes[mi].Mesh;

                if (options.ProgressFunc != null)
                {
                    options.ProgressFunc(mi, vMeshes.Count - 1);
                }

                Func <int, stl_triangle> producerF = (ti) => {
                    stl_triangle tri = new stl_triangle();
                    Index3i      t = mesh.GetTriangle(ti);
                    Vector3D     a = mesh.GetVertex(t.a), b = mesh.GetVertex(t.b), c = mesh.GetVertex(t.c);
                    Vector3D     n = math.MathUtil.Normal(a, b, c);

                    tri.nx     = (float)n.x; tri.ny = (float)n.y; tri.nz = (float)n.z;
                    tri.ax     = (float)a.x; tri.ay = (float)a.y; tri.az = (float)a.z;
                    tri.bx     = (float)b.x; tri.by = (float)b.y; tri.bz = (float)b.z;
                    tri.cx     = (float)c.x; tri.cy = (float)c.y; tri.cz = (float)c.z;
                    tri.attrib = 0;
                    return(tri);
                };
                Action <stl_triangle> consumerF = (tri) => {
                    byte[] tri_bytes = Util.StructureToByteArray(tri);
                    writer.Write(tri_bytes);
                };

                ParallelStream <int, stl_triangle> stream = new ParallelStream <int, stl_triangle>();
                stream.ProducerF = producerF;
                stream.ConsumerF = consumerF;

                // parallel version is slower =\
                //stream.Run_Thread(mesh.TriangleIndices());
                stream.Run(mesh.TriangleIndices());
            }

            return(new IOWriteResult(IOCode.Ok, ""));
        }
Exemplo n.º 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();
        }
 public R Visit <T>(ParallelStream <T> stream, T data)
 {
     return(stream.Accept(this, data));
 }
Exemplo n.º 4
0
        static void Main(string[] args)
        {
            if (args.Length < 1 || !File.Exists(args[0]))
            {
                PrintHelp();
            }

            GetArgs(args);

            var filePath = args[0];
            var tempFile = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileName(filePath) + ".mid.tmp");

            File.Delete(tempFile); //Delete old temp file if it exist
            var streams = new ParallelStream(File.Open(tempFile, FileMode.Create));


            Console.WriteLine("flp2midi | Version: 1.3.0");
            Console.WriteLine("Loading FL Studio project file...");

            Project proj = Project.Load(filePath, false);

            string title   = proj.ProjectTitle;
            string version = proj.VersionString;

            Console.WriteLine("Title: " + title + " | Version: " + version);

            object l = new object();

            var patternDict = new Dictionary <int, Dictionary <Channel, Note[]> >();

            Parallel.ForEach(proj.Patterns, pat =>
            {
                int id      = pat.Id;
                string name = pat.Name;

                var notes = pat.Notes.ToDictionary(c => c.Key, c =>
                {
                    byte channel  = 0;
                    var colorchan = false;

                    if (c.Key.Data is GeneratorData data && data.GeneratorName.ToLower() == "midi out")
                    {
                        if (data.PluginSettings[29] == 0x01)
                        {
                            colorchan = true;
                        }
                        channel = data.PluginSettings[4];
                    }

                    var noteList = new List <Note>(c.Value.Count);

                    var lastNoteZeroTick = -1.0;
                    foreach (var n in c.Value.OrderBy(n => n.Position))
                    {
                        var newNote = new Note((colorchan || ForceColor) ? n.Color : channel, Math.Min((byte)127, n.Key), Math.Min((byte)127, n.Velocity), (double)n.Position, (double)n.Position + (double)n.Length);
                        noteList.Add(newNote);

                        if (lastNoteZeroTick != -1.0 && lastNoteZeroTick != newNote.Start)
                        {
                            lastNoteZeroTick  = -1.0;
                            noteList[^ 2].End = newNote.Start;
                        }