Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-core support #47

Merged
merged 7 commits into from
Mar 14, 2022
Merged

Multi-core support #47

merged 7 commits into from
Mar 14, 2022

Conversation

rsta2
Copy link
Contributor

@rsta2 rsta2 commented Mar 14, 2022

This PR modifies the following:

  • Update submodule circle-stdlib to v15.12
    • System options can be defined cleaner using the "-o" option
    • Include KY-040 driver from Circle (removed from MiniDexed)
  • Render sound on secondary CPU core 1
    • Enable multi-core support on Raspberry Pi 2-4
    • Does still work on the Raspberry Pi 1 with restrictions
    • Use CSoundBaseDevice::Write() instead overriding GetChunk()
    • CMiniDexed is not derived from the sound device classes any more
    • Add option SCREEN_DMA_BURST_LENGTH=1 to relieve bus congestion
  • Add volume control to MIDI CC and UI

There is a new menu item in the UI, which controls the volume level.

The MIDI message dump and profiling should be disabled on the Raspberry Pi 1, otherwise one hears audio drops, when the screen scrolls.

Tested on RPi 1A+ (PWM, HDMI), 2B (PWM, I2S, HDMI) and 4B (PWM, I2S, HDMI). The UI has been tested with a RPi 1A+ only (because my hardware is connected there).

* System options can be defined cleaner using the "-o" option
* Include KY-040 driver from Circle (removed from MiniDexed)
* Enable multi-core support on Raspberry Pi 2-4
* Does still work on the Raspberry Pi 1 with restrictions
* Use CSoundBaseDevice::Write() instead overriding GetChunk()
* CMiniDexed is not derived from the sound device classes any more
* Add option SCREEN_DMA_BURST_LENGTH=1 to relieve bus congestion
@probonopd
Copy link
Owner

probonopd commented Mar 14, 2022

Thanks @rsta2. Here are my test results:

Raspberry Pi Zero with HDMI: Works if MIDI keyboard is directly attached to Pi. Does not work if MIDI keyboard is attached to Official Raspberry Pi Keyboard and Hub which is attached to Pi, getting dwroot: Previous attempt to initialize device failed. When I remove the Official Raspberry Pi Keyboard and Hub at that point and attach the MIDI keyboard directly, then I get 3x dwroot: Previous attempt to initialize device failed. Rebooting at that results in a working MIDI keyboard, I don't get the error message then.
As you write, there is stutter with the debug options enabled. Hence, I would disable the debug output by default.

Raspberry Pi 2 with HDMI: Works if MIDI keyboard is directly attached to Pi. Does not work if MIDI keyboard is attached to Official Raspberry Pi Keyboard and Hub which is attached to Pi, getting usbdev0-1: Cannot get device descriptor (short). When I remove the Official Raspberry Pi Keyboard and Hub at that point and attach the MIDI keyboard directly, then it works (without the need for a reboot). Additionally attaching the Official Raspberry Pi Keyboard and Hub gives usbdev0-1: Cannot get device descriptor (short) and does not result in a working ASCII keyboard, also not after a reboot.

Did not find a way to use the ASCII keyboard anymore.

Did not test Raspberry Pi 3 and 4 yet.

Volume knob on MIDI keyboard works. Volume on LCD GUI works (tested on Raspberry Pi 2 because that is where I have connected the hardware atm). LCD GUI also works correctly when the volume is changed via MIDI. Very nicely implemented!

Pitch Bend and modulation don't seem to do anything that I could hear.

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

@probonopd Thanks for testing. There seems to be a problem with the Official Raspberry Pi Keyboard and Hub with Circle. This is probably independent from this PR. It should have happened with the previous MiniDexed version too? Can you try the option usbpowerdelay=1000 in cmdline.txt with this keyboard?

The debug output is disabled by default, when the respective options are not found in minidexed.ini. But they are present and enabled in the default .ini file. I think, we should remove them there for production.

I tried to implement Pitch Bend and modulation, but because it did not work here, I did not included this in the PR. So it will not work at the moment.

What happened to the lost MIDI events? Does this still happen?

Nice, that you like the LCD volume display. :)

@probonopd
Copy link
Owner

probonopd commented Mar 14, 2022

I still had usbspeed=full in cmdline.txt, could that hurt? With (only) usbpowerdelay=1000, the Official Raspberry Pi Keyboard and Hub

  • Works on Raspberry Pi 2 (both the ASCII keyboard and also as a hub for the MIDI keyboard) but some key events on the MIDI keyboard are missed (To reproduce: Use "ORGAN 1" voice and play rapid glissando; after a while you will hear a "stuck" note)
  • Works on Raspberry Pi Zero (both the ASCII keyboard and also as a hub for the MIDI keyboard) but some key events on the ASCII keyboard and on the MIDI keyboard are missed

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

I think, we had this problem with your USB keyboard and hub before on the RPi 4. It was gone after the boot ROM update. Strange.

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

Yes, please remove the usbspeed=full option.

Maybe the RPi 1 (and Zero) is too slow, to handle USB MIDI without event loss in time. The USB HCI controller emits 8000 interrupts per second. That's huge.

@probonopd
Copy link
Owner

probonopd commented Mar 14, 2022

Note that I can reproduce "stuck notes" on the Raspberry Pi 2 using the MIDI keyboard as well.
Even if the Official Raspberry Pi Keyboard and Hub is not attached at all.

To reproduce: Use "ORGAN 1" voice and play rapid glissando; after a while you will hear a "stuck" note. We could probably code a tester using a Raspberry Pi Pico that would select the "ORGAN 1" voice and would play fast notes in glissando style for testing...

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

Note that I can reproduce "stuck notes" on the Raspberry Pi 2 using the MIDI keyboard as well. (To reproduce: Use "ORGAN 1" voice and play rapid glissando; after a while you will hear a "stuck" note.)

Is this with usbspeed=full or without?

@probonopd
Copy link
Owner

Without.

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

OK. That's bad. You should try this on the RPi 3, when you have some time. mt32-pi did work for you, and it does not run on the RPi 2.

I did not hear stuck notes at all with all MiniDexed versions so far with my AKAIpro LPK25 keyboard. It seems to behave differently then yours. I cannot reproduce this.

@probonopd
Copy link
Owner

mt32-pi did work for you

To be fair, I didn't stress-test it to the same extent ;-)

As the next step, let me see if I can reproduce this using a Raspberry Pi Pico acting as a MIDI keyboard playing notes in really fast succession...

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

Tried "E.ORGAN 1" (voice 17) from the default bank again, sliding for one minute up and down on the keyboard, using a RPi 2B. No stuck note.

Perhaps this is more a test for midi_adapter on the Pico, because it handles the USB in this scenario.

@probonopd
Copy link
Owner

probonopd commented Mar 14, 2022

Strange...
I am not sure whether this is really missed key presses or the synth engine getting stuck somehow.

If I play the same note several times, then the MIDI OFF signal should make that note go silent no matter how often a MIDI ON signal for that note was previously received, correct? So by playing each note slowly I should get all notes back to OFF state. But this is not what happens. Some notes keep playing.

In other words, I keep playing all white keys on the keyboard rapidly and intensively until one note gets stuck, playing forever.
Then I slowly press every white key on the keyboard separately. Each note plays, but the one already playing does not stop.
Until I switch to another voice.

With "E.ORGAN 1" (voice 17) I can get stuck, but I didn't get this with "E.PIANO" yet. (Makes sense: organ-style voices play forever if you keep the key pressed forever while piano-style voices don't.)

So maybe it's not the keyboard that gets stuck after all, but something else?

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

This synth engine behaves differently. This is something, that I noticed too. If you send two "note on" for a specific note, you also have to send two "note off" for that note. Otherwise it will not stop generating sound. I can easily reproduce this here, because I can send single MIDI bytes here via the serial line.

@probonopd
Copy link
Owner

probonopd commented Mar 14, 2022

With MiniDexed_2022-03-14.zip and usbspeed=full I cannot reproduce the issue. I only get the issue with the build from this PR. Same RPi 2 with HDMI. Same MIDI keyboard.

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

Yes, the question remains, why some "note off" events get lost, and if this happens on the RPi 3, and with mt32-pi? I suppose with usbspeed=full, it will also work with the version with PR applied. So it would be no step back, at least. BTW. Your Official RPi keyboard does obviously not work with USB full speed.

@probonopd
Copy link
Owner

So it would be no step back, at least.

That's true.
With usbspeed=full I don't get suck notes but the Official Raspberry Pi Keyboard and Hub doesn't work. Regardless in which version.

the question remains, why some "note off" events get lost, and if this happens on the RPi 3, and with mt32-pi?

I'll try that next.

@probonopd
Copy link
Owner

probonopd commented Mar 14, 2022

Without usbspeed=full I do get stuck notes also on the Rpi 3 using the MiniDexed version from this PR.

Using mt32-pi-0.11.0 on the same hardware and using an Organ-style voice (= a voice that plays forever if you keep the key pressed forever) I cannot reproduce the stuck notes issue.

I notice it has (only) fast=true in cmdline.txt. (Setting the same in the MiniDexed this PR still gets me stuck notes.)

So the question is, why do I get stuck notes in MiniDexed without usbspeed=full but not in mt32-pi-0.11.0 with the exact same hardware combination.

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

Can you try mt32-pi without fast=true? With fast=true and the class CCPUThrottle in the system, the RPi 3B runs twice as fast (1200 MHz). Perhaps this is the right time to add support for enabling the full CPU speed to MiniDexed? It can be switched with this cmdline.txt option. At the moment fast=true has no effect in MiniDexed.

@probonopd
Copy link
Owner

probonopd commented Mar 14, 2022

With quite some forceful effort and persistence I can get stuck notes on mt32-pi without fast=true and using an Organ-style voice. But the difference is that mt32-pi stops playing the stuck note when I hit the same key again (which is possibly not according to the MIDI spec?), which of course makes it more difficult to produce a stuck key situation.

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

I'm quickly preparing a full CPU speed patch for MiniDexed with PR #47.

Yes, this is a difference in the synth engine.

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

Here it is:

full-speed.zip

You still have to add the option fast=true to cmdline.txt. Watch out for the SpeedFactor in one of the first log lines. It should be greater now.

@probonopd
Copy link
Owner

probonopd commented Mar 14, 2022

Does the full-speed patch have any downsides (as long as fast=true is not actively set)? If it doesn't hurt could you apply and push the patch to https://github.com/rsta2/MiniDexed/tree/multi-core-support; once you do a new build will be triggered here automatically which would ease my testing. Thanks!

Normally the CPU runs at a reduced speed in bare metal applications.
With this update and the setting "fast=true" in the file cmdline.txt, it
runs at the full speed.
@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

Done.

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

BTW. With the option socmaxtemp=78 you can set the SoC temperature, at which the CPU speed is throttled again, when it gets too hot. 78°C is the maximum, 60°C the default.

@probonopd
Copy link
Owner

probonopd commented Mar 14, 2022

Can still produce stuck keys with (only) fast=true on Raspberry Pi 2 and 3.

Should we merge this PR anyway?

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

I would merge it, because we need the multi-core support anyway, and it's not a step back. The problem was there before. mt32-pi is very sophisticated after a long development. I think we cannot expect to reach the same after a month. There is room for improvement, that's for sure.

@probonopd probonopd merged commit 6f3f2e1 into probonopd:main Mar 14, 2022
@probonopd
Copy link
Owner

Thanks @rsta2

@rsta2
Copy link
Contributor Author

rsta2 commented Mar 14, 2022

You are welcome.

@rsta2 rsta2 deleted the multi-core-support branch March 14, 2022 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants