HISE Logo Forum
    • Categories
    • Register
    • Login

    MIDI Processor Inconsistent/Processing Speed Issue?

    Scheduled Pinned Locked Moved Scripting
    51 Posts 5 Posters 7.7k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • d.healeyD
      d.healey @Christoph Hart
      last edited by

      @Christoph-Hart said in MIDI Processor Inconsistent/Processing Speed Issue?:

      array so I would have to make a 2D array which then grows to a non-trivial size.

      Rather than a 2D array could you not add a flag to the data stored in each element of the current array you're using?

      Christoph HartC 1 Reply Last reply Reply Quote 0
      • Christoph HartC
        Christoph Hart @d.healey
        last edited by

        @d-healey Or maybe I'll add a (short) queue of events with the required action attached to it. During the MIDI processing inside the buffering this gets populated and then used later by the voice allocation. At the end of the buffer the queue can be cleared because the problem only arises with multiple messages within a buffer.

        1 Reply Last reply Reply Quote 1
        • A
          aaronventure @Christoph Hart
          last edited by aaronventure

          @Christoph-Hart said in MIDI Processor Inconsistent/Processing Speed Issue?:

          yeah I guess there wasn't a project yet where the error of a RR group mismatch caused a "critical error" like this - usually all that happens is that it uses the same RR group for two different notes if they are played exactly at the same time (and only if you don't use the inbuilt RR counter as this calculated right before the voice start). Within a normal RR sample set this is hardly noticeable, but if you rely on it working with mathematical precision because the note ranges do not overlap, you're in trouble.

          I can see how this could go unnoticed. If you have different articulations in different groups, you trigger the keyswitch which sets the active group and it just works, you're not setting activeGroup on each noteOn. If you're using it for RR, it just skips a group and 3/15 for a group skip is still plenty of variance unless you have like 2 RRs.

          Is it fine if I just call setActiveGroup() at the very end of the noteOn callback?

          I'd like to point out that in my actual project, I'm ignoring the event in the guitar's noteOn, and then have a Synth.playNoteWithOffset because I need it to play up to 5 notes (based on multitracking settings), which are all neighbouring zones. So when I press a C3, it plays B2, A#2, C#3 and D3, and the pitch modulator checks for the IDs and applies correct pitch modulation to make them all sound at the correct pitch.

          Back when I had this in the playLogic script which was above the samplers, these Synth.play method calls produced 5 artificial noteOn events in the sampler.

          I don't know what that looks like when the Synth.play happens in the sampler itself.

          I am storing the IDs of the Synth.play calls, though. Is it a good idea to maybe have another method which sets the active group for a given event ID?

          Christoph HartC 1 Reply Last reply Reply Quote 0
          • Christoph HartC
            Christoph Hart @aaronventure
            last edited by

            hmm, that makes it even more complicated and I would have to change the API for the setActiveGroup() call to take in an event ID.

            On the other hand this would leave the "default" path as it is right now without overhead but the slight inconsistency that the active group will get overriden for each event in the current audio buffer (and chances are great that if you go into this kind of advanced event modification & RR group control you want it to be tied to the event ID properly anyways).

            So in this case I would add a new API method

            Sampler.setActiveGroupForEventId(int eventId, int groupIndex).
            

            which will take the event ID and then check in the note on callback of the sampler which group to use for the current group index.

            A 2 Replies Last reply Reply Quote 1
            • A
              aaronventure @Christoph Hart
              last edited by

              @Christoph-Hart exactly, yeah!

              Great.

              Don't forget warning for any clowning around with usage of both this and the current setActiveGroup method in the same callback (or will one simply override the other?)

              1 Reply Last reply Reply Quote 0
              • A
                aaronventure @Christoph Hart
                last edited by aaronventure

                @Christoph-Hart said in MIDI Processor Inconsistent/Processing Speed Issue?:

                Sampler.setActiveGroupForEventId(int eventId, int groupIndex).

                Also, any chance this bad boy could also be taking an array of indices in its second parameter? That'd be two flies with one strike.

                Christoph HartC 1 Reply Last reply Reply Quote 1
                • Christoph HartC
                  Christoph Hart @aaronventure
                  last edited by

                  @aaronventure I think you can just use a for loop for that, I would avoid branching inside the API call for your special use case :)

                  A 1 Reply Last reply Reply Quote 0
                  • A
                    aaronventure @Christoph Hart
                    last edited by

                    @Christoph-Hart Really? Wouldn't another call override the previous one?

                    I meant what if one wanted two different groups active for a note? I mean, sure, that can be another Synth.playNote and its ID passed into another Sampler.setActiveGroupForEventId(int eventId, int groupIndex) call.

                    Christoph HartC 1 Reply Last reply Reply Quote 0
                    • Christoph HartC
                      Christoph Hart @aaronventure
                      last edited by

                      @aaronventure Ah you mean the second parameter, I thought you were just too lazy to make a for loop for your 5 events that you want to spawn.

                      For this, I would rather add another API call that's similar to setMultiGroupIndex() as this would be the non-event-ID-agnostic counterpart in the Sampler API.

                      d.healeyD A 2 Replies Last reply Reply Quote 1
                      • d.healeyD
                        d.healey @Christoph Hart
                        last edited by d.healey

                        This post is deleted!
                        1 Reply Last reply Reply Quote 0
                        • A
                          aaronventure @Christoph Hart
                          last edited by

                          @Christoph-Hart haha isn't looping the lazy way?

                          Just so we're on the same page, I play a note, I ignore the event, then I execute 5 notes via Synth.playNote in a loop, storing their ID, and right in the next line (still within the loop) I just pass that ID into the Sampler.setActiveGroupForEventId?

                          So it would be possible to have multiple Sampler.setActiveGroupForEventId calls within a single noteOn callback, each directing its own eventId to the appropriate group?

                          Christoph HartC 1 Reply Last reply Reply Quote 1
                          • Christoph HartC
                            Christoph Hart @aaronventure
                            last edited by

                            @aaronventure yes, that should be possible.

                            A 1 Reply Last reply Reply Quote 2
                            • A
                              aaronventure @Christoph Hart
                              last edited by

                              @Christoph-Hart fuckin' A

                              Christoph HartC 1 Reply Last reply Reply Quote 0
                              • Christoph HartC
                                Christoph Hart @aaronventure
                                last edited by

                                @aaronventure Alright, it's pushed to the current working branch new_dispatcher (which should be considered stable unless you're on Linux, then it won't compile :)

                                Link Preview Image
                                - added Sampler.setActiveGroupForEventId() et al · christophhart/HISE@05b9f1f

                                The open source framework for sample based instruments - - added Sampler.setActiveGroupForEventId() et al · christophhart/HISE@05b9f1f

                                favicon

                                GitHub (github.com)

                                and:

                                Link Preview Image
                                HISE | Docs

                                favicon

                                (docs.hise.audio)

                                A 2 Replies Last reply Reply Quote 3
                                • A
                                  aaronventure @Christoph Hart
                                  last edited by

                                  @Christoph-Hart oh shit look at that doc entry!

                                  1 Reply Last reply Reply Quote 0
                                  • A
                                    aaronventure @Christoph Hart
                                    last edited by aaronventure

                                    @Christoph-Hart I'm ready to test this, but the plugin version of HISE fails to build. Standalone builds fine.

                                    Windows 11. All commits since this one. Reverted back to develop just to check, develop builds fine.

                                    1>F:\HISE\HISE Source\tools\SDK\perfetto\perfetto.h(338,1): fatal  error C1189: #error:  Perfetto is exploring a switch to C++17 in v34 (Feb 2023). During this transitionary period, we are throwing an error when compiling Perfetto with a standard less than C++17. Please reach out to perfetto-dev@googlegroups.com if you have objections or thoughts on this move. To continue compiling this release of Perfetto with C++11/14, specify the define PERFETTO_ALLOW_SUB_CPP17. *Note*: this define *will* stop working in v34 (Feb 2023). (compiling source file ..\..\JuceLibraryCode\include_hi_core.cpp)
                                    1>F:\HISE\HISE Source\tools\SDK\perfetto\perfetto.h(338,1): fatal  error C1189: #error:  Perfetto is exploring a switch to C++17 in v34 (Feb 2023). During this transitionary period, we are throwing an error when compiling Perfetto with a standard less than C++17. Please reach out to perfetto-dev@googlegroups.com if you have objections or thoughts on this move. To continue compiling this release of Perfetto with C++11/14, specify the define PERFETTO_ALLOW_SUB_CPP17. *Note*: this define *will* stop working in v34 (Feb 2023). (compiling source file ..\..\Source\PluginProcessor.cpp)
                                    1>F:\HISE\HISE Source\tools\SDK\perfetto\perfetto.h(338,1): fatal  error C1189: #error:  Perfetto is exploring a switch to C++17 in v34 (Feb 2023). During this transitionary period, we are throwing an error when compiling Perfetto with a standard less than C++17. Please reach out to perfetto-dev@googlegroups.com if you have objections or thoughts on this move. To continue compiling this release of Perfetto with C++11/14, specify the define PERFETTO_ALLOW_SUB_CPP17. *Note*: this define *will* stop working in v34 (Feb 2023). (compiling source file ..\..\JuceLibraryCode\include_hi_snex.cpp)
                                    1>F:\HISE\HISE Source\tools\SDK\perfetto\perfetto.h(338,1): fatal  error C1189: #error:  Perfetto is exploring a switch to C++17 in v34 (Feb 2023). During this transitionary period, we are throwing an error when compiling Perfetto with a standard less than C++17. Please reach out to perfetto-dev@googlegroups.com if you have objections or thoughts on this move. To continue compiling this release of Perfetto with C++11/14, specify the define PERFETTO_ALLOW_SUB_CPP17. *Note*: this define *will* stop working in v34 (Feb 2023). (compiling source file ..\..\JuceLibraryCode\include_hi_snex_62.cpp)
                                    1>F:\HISE\HISE Source\tools\SDK\perfetto\perfetto.h(338,1): fatal  error C1189: #error:  Perfetto is exploring a switch to C++17 in v34 (Feb 2023). During this transitionary period, we are throwing an error when compiling Perfetto with a standard less than C++17. Please reach out to perfetto-dev@googlegroups.com if you have objections or thoughts on this move. To continue compiling this release of Perfetto with C++11/14, specify the define PERFETTO_ALLOW_SUB_CPP17. *Note*: this define *will* stop working in v34 (Feb 2023). (compiling source file ..\..\JuceLibraryCode\include_hi_streaming.cpp)
                                    1>F:\HISE\HISE Source\tools\SDK\perfetto\perfetto.h(338,1): fatal  error C1189: #error:  Perfetto is exploring a switch to C++17 in v34 (Feb 2023). During this transitionary period, we are throwing an error when compiling Perfetto with a standard less than C++17. Please reach out to perfetto-dev@googlegroups.com if you have objections or thoughts on this move. To continue compiling this release of Perfetto with C++11/14, specify the define PERFETTO_ALLOW_SUB_CPP17. *Note*: this define *will* stop working in v34 (Feb 2023). (compiling source file ..\..\JuceLibraryCode\include_hi_scripting_01.cpp)
                                    1>F:\HISE\HISE Source\tools\SDK\perfetto\perfetto.h(338,1): fatal  error C1189: #error:  Perfetto is exploring a switch to C++17 in v34 (Feb 2023). During this transitionary period, we are throwing an error when compiling Perfetto with a standard less than C++17. Please reach out to perfetto-dev@googlegroups.com if you have objections or thoughts on this move. To continue compiling this release of Perfetto with C++11/14, specify the define PERFETTO_ALLOW_SUB_CPP17. *Note*: this define *will* stop working in v34 (Feb 2023). (compiling source file ..\..\JuceLibraryCode\include_hi_scripting_03.cpp)
                                    1>F:\HISE\HISE Source\tools\SDK\perfetto\perfetto.h(338,1): fatal  error C1189: #error:  Perfetto is exploring a switch to C++17 in v34 (Feb 2023). During this transitionary period, we are throwing an error when compiling Perfetto with a standard less than C++17. Please reach out to perfetto-dev@googlegroups.com if you have objections or thoughts on this move. To continue compiling this release of Perfetto with C++11/14, specify the define PERFETTO_ALLOW_SUB_CPP17. *Note*: this define *will* stop working in v34 (Feb 2023). (compiling source file ..\..\JuceLibraryCode\include_hi_tools.cpp)
                                    1>Done building project "HISE_SharedCode.vcxproj" -- FAILED.
                                    2>------ Rebuild All started: Project: HISE_VST, Configuration: Release x64 ------
                                    2>include_juce_audio_plugin_client_VST2.cpp
                                    2>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(1096,5): error MSB6006: "link.exe" exited with code 1181.
                                    2>LINK : fatal error LNK1181: cannot open input file 'HISE x64.lib'
                                    2>Done building project "HISE_VST.vcxproj" -- FAILED.
                                    

                                    Testing in the standalone, it seems to work. I can't get it it "drop" a note. Going back and forth between the new and the old method, I get wrong active group 3/20 times with the old one, and so far none with the new one.

                                    Great!

                                    d.healeyD 1 Reply Last reply Reply Quote 0
                                    • d.healeyD
                                      d.healey @aaronventure
                                      last edited by

                                      @aaronventure Did you try cleaning the build folder between building the standalone and the plugin?

                                      A 1 Reply Last reply Reply Quote 0
                                      • A
                                        aaronventure @d.healey
                                        last edited by aaronventure

                                        @d-healey I always do.

                                        Tried it again just in case I was maybe tripping earlier but no, clearing and building fails.

                                        1 Reply Last reply Reply Quote 1
                                        • A
                                          aaronventure
                                          last edited by

                                          Everything working great in the latest commit. 🍻

                                          1 Reply Last reply Reply Quote 1
                                          • A
                                            aaronventure
                                            last edited by

                                            @Christoph-Hart Posting here because I think it's related.

                                            I wanna introduce humanization to my instrument. In theory, this is dead simple: call the delay method for a random number of samples within a limited range.

                                            The issue: storing event IDs and properly noting them off, as well as preventing execution of the play() method in the first place in case the note was shorter than the set humanized delay.

                                            The noteOn callback will always execute in its entirety before the noteOff callback (for the same key). if there's a Message.delay() in there, the noteOn still executes and it seems like it stores any Synth.play() calls into a queue.

                                            So I thought about reverting my dismemberment of the original Play Logic script and stuffing it all back there (since the new setActiveGroupForEventId() solves the issue there), and did a quick test.

                                            I call Console.print() in noteOn and noteOff of the Play Logic, which resides in the master container, and then in the Guitar Event Handler which is a Script Processor for the Sampler. The Guitar Event Handler features a Message.delay() call in the loop that executes its <5 voices (multitracking).

                                            The actual MIDI note is incredibly short. It's released way before the delayed events begin playing. Even so, the noteOns get executed first, and then noteOffs.

                                            68c5ecda-c5d9-4cca-bee7-b96791732307-image.png

                                            This makes any isKeyDown checks (whether using the built in Synth class method or filling my own array in noteOn/noteOff) impossible, because even though the note was released at the time the delayed note is scheduled to launch, the scheduling of it was executed on the physical noteOn.

                                            The noteOff happens before the scheduled play() execution, there's no event ID to noteOff and the scheduled voice will then play forever (or until the sample/envelope runs out, but you get it).

                                            I'm not sure if timers are a solution because this would require a crazy resolution of 1ms or shorter (and I've already been yelled at by HISE for timer timing before).

                                            Christoph HartC 1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            43

                                            Online

                                            1.7k

                                            Users

                                            11.7k

                                            Topics

                                            102.0k

                                            Posts