Coder Social home page Coder Social logo

zenith-midi's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

zenith-midi's Issues

Zenith has crashed!

Every time i open Zenith it shows an error message that goes like this:

invalid parameter

System.Collections.ListDictionaryInternal
at System.IO.__Error.WinIOError(int32 errorCode, String maybeFullPath)
at Systm.Console.set_Title(String value)
at Zenith_MIDI.Program.Main(String[] args)

What is Color Events and how to use it

I find some code of it in a file: MidiTrack.cs
I think color event is a meta event, and like FF 0A 00 0F 00 00 FF FF FF FF
FF 0A 00 0F is prefix,
00 is channel 1,
next byte is useless,
FF FF FF FF is rgba(255,255,255,255)

And I add the same event in a test MIDI, but does not work.
This is the event:
image

This is my test MIDI:
1387298_1.zip

How to use it correctly?

Support Sustain Pedal Event

Hello,
Mystic Piano Here from discord,
I know that i already told you about this, but I am just documenting it so that you don't forget
Also, I can help you translate

THIS ISSUE IS ONLY MEANT FOR DOCUMENTATION. PLEASE DO NOT FEEL THAT THIS ISSUE IS SPAM.

Regards,

Mystic

Render progress window

Make a window that consist of the render progress, along with other information regarding the current render.

Not to be confused with #17 and #29.

Add more options/variables on the Note Counter

Some suggestions from the community:

  • Add thousands seperator options (comma, dot, etc.)
  • Add decimal point options (comma, dot, etc.)
  • Make additional zeros (Mr Blackmidi#5405)

(also suggested by jimo#5727 on the BMC server)

Renders with lags

I decided to render a midi file with a lot of notes. After rendering, the video started to lag from the beginning of the video, but then it started playing normally from 14 seconds. I have a video for which I have lags in the video itself

no sound

I'm sorry, but I can't figure how to sound midi ..

midi sound offset

when i try to render midi with sound the outcome always has a sound offset, like this rendering i made

bsm.mp4

Bring back the original Piano Roll Rain 2D

The mode implemented on Zenith is a variation where the notes and the keyboard are parallel. Why don't we add the original mode where the notes and the keyboard are perpendicular?

(suggested by Mr Blackmidi#5405 on Zenith server)

No notes?

I tried to render nut2.mid but it just showed nothing, only the counter (i had base settings)

Frame Rerender Loop

image
It seems like Zenith keeps rendering the same frame over and over again. This occurs in the latest version of Zenith.

The speed seems to be slowing down and it seems like it's at the end of the midi

Audio

Creating this issue for audio. So why need to import audio instead of save and export. And why not to add synth and soundfont

Crash report/logging system

The program should output the crash report (if the program crashes) or all normal logs on the command prompt in a file (.txt), similar to Minecraft.

Dropping old suggestions for the future.

No audio while playing MIDI files

Pretty self explanatory. While attempting to play ONESTOP.MID there is no response in my headset and the Windows Sound Mixer shows that there isn't any instance of "zenith" open at all.

Video outputs only to the red channel, FFmpeg reports bad packet

While the preview of the render displays with correct colors, the final rendered video appears very red, with no other colors present.
image
This is present on a fresh install, and occurs in every module, so I turned to FFmpeg to find this in the output.
image
This appears to happen no matter what my input. (settings, letting the render complete)

Is there maybe a version of FFmpeg that plays nice with Zenith here? The link in the README is dead too, so I cannot check it out.

Zenith version is 2.1.5
FFmpeg version is 5.0-full_build-www.gyan.dev

Improvements on README.md

Fix minor bugs on the badge, update screenshots, remove some text, all the stuff.

Remind me later

cant run exe

i put the ffmepg.exe next to the exe and it did not fix it
image

Crashes on preview or render

I tried to use zenith instead of ump but whener i try to preview or render it just crashes.
This is what shows up in the command prompt:

image

These are my laptop specs:
CPU: AMD Ryzen 3 7320U with radeon graphics
GPU: None
Graphics: directx 12, opengl doesnt seem to be supported
RAM: 8gb

Implement settings.json for minor global settings

I was thinking of adding a settings.json next to zenith for very minor global settings
I want more meta settings rather than last state of the program
options that should be there but are too minor to add to zenith's settings window
(like for example permanently ignoring kdmapi)

Settings Idea

  • Ignore KDMAPI
  • Default settings window size
  • Default plugin
  • Default background

Command-line interface

Add a command-line interface which let people render Zenith videos using command prompt.

Not to be confused with #17.


random user#8419:

we should add command line args to where we can just

@echo off
zenith.exe -render.xml whateverthefuckthisis.mid Videos\a.mp4
zenith.exe -transparency.xml whateverthefuckthisis.mid Videos\b.mp4
shutdown.exe

(seting xml's being pre saved settings ofc)

Show centiseconds as "Seconds: #.## elapsed / total #.## / remaining #.##"

I guess i add centiseconds counter onto Render.cs
Expected to be:
`using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using ZenithEngine;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using System.Windows.Controls;

namespace NoteCountRender
{
public class Render : IPluginRender
{
#region PreviewConvert
BitmapImage BitmapToImageSource(Bitmap bitmap)
{
using (MemoryStream memory = new MemoryStream())
{
bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Bmp);
memory.Position = 0;
BitmapImage bitmapimage = new BitmapImage();
bitmapimage.BeginInit();
bitmapimage.StreamSource = memory;
bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
bitmapimage.EndInit();

            return bitmapimage;
        }
    }
    #endregion

    public string Name => "Note Counter";

    public string Description => "Generate note counts and other midi statistics";

    public string LanguageDictName { get; } = "notecounter";

    public bool Initialized { get; set; } = false;

    public System.Windows.Media.ImageSource PreviewImage { get; set; }

    public bool ManualNoteDelete => true;

    public double NoteCollectorOffset => 0;

    public double Tempo { get; set; }

    public NoteColor[][] NoteColors { get; set; }

    public MidiInfo CurrentMidi { get; set; }

    public double NoteScreenTime => 0;

    public long LastNoteCount { get; set; } = 0;

    public System.Windows.Controls.Control SettingsControl { get; set; }

    RenderSettings renderSettings;
    Settings settings;

    GLTextEngine textEngine;
    public void Dispose()
    {
        textEngine.Dispose();
        Initialized = false;
        if (outputCsv != null) outputCsv.Close();
        Console.WriteLine("Disposed of NoteCountRender");
    }

    int fontSize = 40;
    string font = "Arial";
    public System.Drawing.FontStyle fontStyle = System.Drawing.FontStyle.Regular;

    StreamWriter outputCsv = null;

    public void Init()
    {
        textEngine = new GLTextEngine();
        if (settings.fontName != font || settings.fontSize != fontSize || settings.fontStyle != fontStyle)
        {
            font = settings.fontName;
            fontSize = settings.fontSize;
            fontStyle = settings.fontStyle;
        }
        textEngine.SetFont(font, fontStyle, fontSize);
        noteCount = 0;
        nps = 0;
        Mnps = 0;
        frames = 0;
        Mplph = 0;
        notesHit = new LinkedList<long>();
        Initialized = true;

        if (settings.saveCsv && settings.csvOutput != "")
        {
            outputCsv = new StreamWriter(settings.csvOutput);
        }

        Console.WriteLine("Initialised NoteCountRender");
    }

    public Render(RenderSettings settings)
    {
        this.renderSettings = settings;
        this.settings = new Settings();
        SettingsControl = new SettingsCtrl(this.settings);
        PreviewImage = BitmapToImageSource(Properties.Resources.preview);
    }

    long noteCount = 0;
    long nps = 0;
    long Mnps = 0;
    int frames = 0;
    long currentNotes = 0;
    long polyphony = 0;
    long Mplph = 0;
    
    LinkedList<long> notesHit = new LinkedList<long>();

    public void RenderFrame(FastList<Note> notes, double midiTime, int finalCompositeBuff)
    {
        GL.BindFramebuffer(FramebufferTarget.Framebuffer, finalCompositeBuff);

        GL.Viewport(0, 0, renderSettings.width, renderSettings.height);
        GL.Clear(ClearBufferMask.ColorBufferBit);
        GL.Clear(ClearBufferMask.DepthBufferBit);

        GL.Enable(EnableCap.Blend);
        GL.EnableClientState(ArrayCap.VertexArray);
        GL.EnableClientState(ArrayCap.ColorArray);
        GL.EnableClientState(ArrayCap.TextureCoordArray);
        GL.Enable(EnableCap.Texture2D);

        GL.EnableVertexAttribArray(0);
        GL.EnableVertexAttribArray(1);

        GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

        if (settings.fontName != font || settings.fontSize != fontSize || settings.fontStyle != fontStyle)
        {
            font = settings.fontName;
            fontSize = settings.fontSize;
            fontStyle = settings.fontStyle;
            textEngine.SetFont(font, fontStyle, fontSize);
        }
        if (!renderSettings.Paused)
        {
            polyphony = 0;
            currentNotes = 0;
            long nc = 0;
            lock (notes)
                foreach (Note n in notes)
                {
                    nc++;
                    if (n.start < midiTime)
                    {
                        if (n.end > midiTime || !n.hasEnded)
                        {
                            polyphony++;
                        }
                        else if (n.meta != null)
                        {
                            n.delete = true;
                        }
                        if (n.meta == null)
                        {
                            currentNotes++;
                            noteCount++;
                            n.meta = true;
                        }
                    }
                    if (n.start > midiTime) break;
                }
            LastNoteCount = nc;
            notesHit.AddLast(currentNotes);
            while (notesHit.Count > renderSettings.fps) notesHit.RemoveFirst();
            nps = notesHit.Sum();
            if (Mnps < nps) Mnps = nps;
            if (Mplph < polyphony) Mplph = polyphony;
            frames++;
        }

        double tempo = Tempo;
        
        int seconds = (int)Math.Floor((double)frames * 1000 / renderSettings.fps);
        int totalsec = (int)Math.Floor(CurrentMidi.secondsLength * 1000);
        int totalframes = (int)Math.Ceiling(CurrentMidi.secondsLength * renderSettings.fps);
        if (seconds > totalsec) seconds = totalsec;
        TimeSpan time = new TimeSpan(0, 0, 0, 0, seconds);
        TimeSpan totaltime = new TimeSpan(0, 0, 0, 0, totalsec);
        if (frames > totalframes) frames = totalframes;

        double barDivide = (double)CurrentMidi.division * CurrentMidi.timeSig.numerator / CurrentMidi.timeSig.denominator * 4;

        long limMidiTime = (long)midiTime;
        if (limMidiTime > CurrentMidi.tickLength) limMidiTime = CurrentMidi.tickLength;

        long bar = (long)Math.Floor(limMidiTime / barDivide) + 1;
        long maxbar = (long)Math.Floor(CurrentMidi.tickLength / barDivide);
        if (bar > maxbar) bar = maxbar;
        string fzp = new string('0', renderSettings.fps.ToString().Length);
        
        Func<string, Commas, string> replace = (text, separator) =>
        {
            Zeroes zeroes = new Zeroes();
            string sep = "";
            if (separator == Commas.Comma) sep = "#,";
            if (settings.PaddingZeroes)
            {
                zeroes.bpm = new string('0', settings.BPMintPad) +"." + new string('0', settings.BPMDecPtPad);
                zeroes.nc = new string('0', settings.NoteCountPad);
                zeroes.plph = new string('0', settings.PolyphonyPad);
                zeroes.nps = new string('0', settings.NPSPad);
                zeroes.tick = new string('0', settings.TicksPad);
                zeroes.bars = new string('0', settings.BarCountPad);
                zeroes.frms = new string('0', settings.FrCountPad);
            }

            text = text.Replace("{bpm}", tempo.ToString(zeroes.bpm));

            text = text.Replace("{nc}", noteCount.ToString(sep + zeroes.nc));
            text = text.Replace("{nr}", (CurrentMidi.noteCount - noteCount).ToString(sep + zeroes.nc));
            text = text.Replace("{tn}", CurrentMidi.noteCount.ToString(sep + zeroes.nc));

            text = text.Replace("{nps}", nps.ToString(sep + zeroes.nps));
            text = text.Replace("{mnps}", Mnps.ToString(sep + zeroes.nps));
            text = text.Replace("{plph}", polyphony.ToString(sep + zeroes.plph));
            text = text.Replace("{mplph}", Mplph.ToString(sep + zeroes.plph));

            text = text.Replace("{currsec}", ((double)(seconds / 10) / 100).ToString(sep + "0.00"));
            text = text.Replace("{currtime}", time.ToString("mm\\:ss"));
            text = text.Replace("{cmiltime}", time.ToString("mm\\:ss\\.fff"));
            text = text.Replace("{cfrtime}", time.ToString("mm\\:ss") + ";" + (frames % renderSettings.fps).ToString(fzp));

            text = text.Replace("{totalsec}", ((double)(totalsec / 10) / 100).ToString(sep + "0.00"));
            text = text.Replace("{totaltime}", totaltime.ToString("mm\\:ss"));
            text = text.Replace("{tmiltime}", totaltime.ToString("mm\\:ss\\.fff"));
            text = text.Replace("{tfrtime}", totaltime.ToString("mm\\:ss") + ";" + (totalframes % renderSettings.fps).ToString(fzp));

            text = text.Replace("{remsec}", ((double)((totalsec - seconds) / 10) / 100).ToString(sep + "0.00"));
            text = text.Replace("{remtime}", (totaltime - time).ToString("mm\\:ss"));
            text = text.Replace("{rmiltime}", (totaltime - time).ToString("mm\\:ss\\.fff"));
            text = text.Replace("{rfrtime}", (totaltime - time).ToString("mm\\:ss") + ";" + ((totalframes - frames + renderSettings.fps) % renderSettings.fps).ToString(fzp));

            text = text.Replace("{currticks}", (limMidiTime).ToString(sep + zeroes.tick));
            text = text.Replace("{totalticks}", (CurrentMidi.tickLength).ToString(sep + zeroes.tick));
            text = text.Replace("{remticks}", (CurrentMidi.tickLength - limMidiTime).ToString(sep + zeroes.tick));

            text = text.Replace("{currbars}", bar.ToString(sep + zeroes.bars));
            text = text.Replace("{totalbars}", maxbar.ToString(sep + zeroes.bars));
            text = text.Replace("{rembars}", (maxbar - bar).ToString(sep + zeroes.bars));

            text = text.Replace("{ppq}", CurrentMidi.division.ToString());
            text = text.Replace("{tsn}", CurrentMidi.timeSig.numerator.ToString());
            text = text.Replace("{tsd}", CurrentMidi.timeSig.denominator.ToString());
            text = text.Replace("{avgnps}", ((double)CurrentMidi.noteCount / (double)CurrentMidi.secondsLength).ToString(sep + "0.00"));

            text = text.Replace("{currframes}", frames.ToString(sep + zeroes.frms));
            text = text.Replace("{totalframes}", totalframes.ToString(sep + zeroes.frms));
            text = text.Replace("{remframes}", (totalframes - frames).ToString(sep + zeroes.frms));

            text = text.Replace("{notep}", (((decimal)noteCount * 1000000 / (decimal)CurrentMidi.noteCount) / 10000).ToString("00.0000"));
            text = text.Replace("{tickp}", (((decimal)limMidiTime * 1000000 / (decimal)CurrentMidi.tickLength) / 10000).ToString("00.0000"));
            text = text.Replace("{timep}", (((decimal)seconds * 1000000 / (decimal)totalsec) / 10000).ToString("00.0000"));
            return text;
        };


        string renderText = settings.text;
        renderText = replace(renderText, settings.thousandSeparator);

        if (settings.textAlignment == Alignments.TopLeft)
        {
            var size = textEngine.GetBoundBox(renderText);
            Matrix4 transform = Matrix4.Identity;
            transform = Matrix4.Mult(transform, Matrix4.CreateScale(1.0f / renderSettings.width, -1.0f / renderSettings.height, 1.0f));
            transform = Matrix4.Mult(transform, Matrix4.CreateTranslation(-1, 1, 0));
            transform = Matrix4.Mult(transform, Matrix4.CreateRotationZ(0));

            textEngine.Render(renderText, transform, Color4.White);
        }
        else if (settings.textAlignment == Alignments.TopRight)
        {
            float offset = 0;
            string[] lines = renderText.Split('\n');
            foreach (var line in lines)
            {
                var size = textEngine.GetBoundBox(line);
                Matrix4 transform = Matrix4.Identity;
                transform = Matrix4.Mult(transform, Matrix4.CreateTranslation(-size.Width, offset, 0));
                transform = Matrix4.Mult(transform, Matrix4.CreateScale(1.0f / renderSettings.width, -1.0f / renderSettings.height, 1.0f));
                transform = Matrix4.Mult(transform, Matrix4.CreateTranslation(1, 1, 0));
                transform = Matrix4.Mult(transform, Matrix4.CreateRotationZ(0));
                offset += size.Height;
                textEngine.Render(line, transform, Color4.White);
            }
        }
        else if (settings.textAlignment == Alignments.BottomLeft)
        {
            float offset = 0;
            string[] lines = renderText.Split('\n');
            foreach (var line in lines.Reverse())
            {
                var size = textEngine.GetBoundBox(line);
                Matrix4 transform = Matrix4.Identity;
                transform = Matrix4.Mult(transform, Matrix4.CreateTranslation(0, offset - size.Height, 0));
                transform = Matrix4.Mult(transform, Matrix4.CreateScale(1.0f / renderSettings.width, -1.0f / renderSettings.height, 1.0f));
                transform = Matrix4.Mult(transform, Matrix4.CreateTranslation(-1, -1, 0));
                transform = Matrix4.Mult(transform, Matrix4.CreateRotationZ(0));
                offset -= size.Height;
                textEngine.Render(line, transform, Color4.White);
            }
        }
        else if (settings.textAlignment == Alignments.BottomRight)
        {
            float offset = 0;
            string[] lines = renderText.Split('\n');
            foreach (var line in lines.Reverse())
            {
                var size = textEngine.GetBoundBox(line);
                Matrix4 transform = Matrix4.Identity;
                transform = Matrix4.Mult(transform, Matrix4.CreateTranslation(-size.Width, offset - size.Height, 0));
                transform = Matrix4.Mult(transform, Matrix4.CreateScale(1.0f / renderSettings.width, -1.0f / renderSettings.height, 1.0f));
                transform = Matrix4.Mult(transform, Matrix4.CreateTranslation(1, -1, 0));
                transform = Matrix4.Mult(transform, Matrix4.CreateRotationZ(0));
                offset -= size.Height;
                textEngine.Render(line, transform, Color4.White);
            }
        }
        else if (settings.textAlignment == Alignments.TopSpread)
        {
            float offset = 0;
            string[] lines = renderText.Split('\n');
            float dist = 1.0f / (lines.Length + 1);
            int p = 1;
            foreach (var line in lines.Reverse())
            {
                var size = textEngine.GetBoundBox(line);
                Matrix4 transform = Matrix4.Identity;
                transform = Matrix4.Mult(transform, Matrix4.CreateTranslation(-size.Width / 2, 0, 0));
                transform = Matrix4.Mult(transform, Matrix4.CreateScale(1.0f / renderSettings.width, -1.0f / renderSettings.height, 1.0f));
                transform = Matrix4.Mult(transform, Matrix4.CreateTranslation((dist * p++) * 2 - 1, 1, 0));
                transform = Matrix4.Mult(transform, Matrix4.CreateRotationZ(0));
                offset -= size.Height;
                textEngine.Render(line, transform, Color4.White);
            }
        }
        else if (settings.textAlignment == Alignments.BottomSpread)
        {
            float offset = 0;
            string[] lines = renderText.Split('\n');
            float dist = 1.0f / (lines.Length + 1);
            int p = 1;
            foreach (var line in lines.Reverse())
            {
                var size = textEngine.GetBoundBox(line);
                Matrix4 transform = Matrix4.Identity;
                transform = Matrix4.Mult(transform, Matrix4.CreateTranslation(-size.Width / 2, -size.Height, 0));
                transform = Matrix4.Mult(transform, Matrix4.CreateScale(1.0f / renderSettings.width, -1.0f / renderSettings.height, 1.0f));
                transform = Matrix4.Mult(transform, Matrix4.CreateTranslation((dist * p++) * 2 - 1, -1, 0));
                transform = Matrix4.Mult(transform, Matrix4.CreateRotationZ(0));
                offset -= size.Height;
                textEngine.Render(line, transform, Color4.White);
            }
        }

        if(outputCsv != null)
        {
            outputCsv.WriteLine(replace(settings.csvFormat, Commas.Nothing));
        }

        GL.Disable(EnableCap.Blend);
        GL.Disable(EnableCap.Texture2D);
        GL.DisableClientState(ArrayCap.VertexArray);
        GL.DisableClientState(ArrayCap.ColorArray);
        GL.DisableClientState(ArrayCap.TextureCoordArray);

        GL.DisableVertexAttribArray(0);
        GL.DisableVertexAttribArray(1);
    }

    public void ReloadTrackColors()
    {

    }
}

}`
plz help.

Problem in Scripted module

I had to set Note screen time to a high value to render horizontal piano.
But if I set Note screen time to a high value(eg 4096) and start preview or render, then it's finishes too early.
This problem is only in Scripted module.

Program crashes on preview or render

Title is pretty self-explanatory.

This is what the console output gave, hopefully I was able to type it down properly.

Unhanded Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    at OpenTK.Graphics.OpenGL.GL.GenFramebuffer()
    at Black_Midi_Render.GLUtils.GenFrameBufferTexture(Int32 width, Int32 height, Int32& fbuffer, Int32& rtexture)
    at Black_Midi_Render.RenderWindows..ctor(CurrentRendererPointer renderer, MidiFile midi, RenderSettings settings)
    at Black_Midi_Render.MainWindows.()c__DisplayClass13_0.(RunRenderWindow)b__0()

    at System.Threading.Tasks.Task.InnerInvoke()
    at System.Threading.Tasks.Task.Execute()
    at System.Threading.Tasks.Task.ExecutionContextCallback(Object obj)
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
    at System.Threading.Tasks.Task.ExecuteEntry(Boolean bPreventDoubleExecution)
    at System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
    at System.Threading.ThreadPoolWorkQueue.Dispatch()
    at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

I'm assuming that this program need a higher version of OpenGL, considering my version is 2.0. (integrated graphics are a pain, lol)

Question

Is there a way to do so this .exe file runs on mac?

Cound not load image

I am trying to load image jpg about 4000x2500
It give me an error
"Cound not load image"

Linux support?

I'm pretty sure there isn't a Linux port for Zenith, but Is there a way to run it in Linux with a compatibility layer (e.g Wine)?

Arrgh, audio aliginment

I use KMC(Keppy's Midi Converter) to renderer audio. It usually removes any beginning empty notes. The problem I get with rendering with audio is that the audio starts before the first note hits the piano roll.
Is it possible to configure Zenith to start adding the audio in when the first note is rendered on the piano roll

This is more of an idea and I want feedback

So I had an idea for a new rendering method where instead of drawing the notes to the screen you bake all the notes into an image and draw that to the screen and move it

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.