NokiMo
lookmumnocomputer
lookmumnocomputer

patreon


Further explaining the console code issue


Also! Look mum no livestream on here at 19:30 GMT on this Thursday

Video further explaining as I didn't fully do it.

Code as is is over here at the bottom of the page https://www.lookmumnocomputer.com/projects#/joans-church-organ

Further explaining the console code issue

Comments

Filmed it all! Ohhhh I'll try that then film again in a bit okie!

Look Mum No Computer

I saw the test on video and I didn’t expect the code to behave so well with Circus Galop 😆 As I said in Discord, here is a v2 with a slight change that may improve the stalling with the missed notes off et the beginning of the song : https://gist.github.com/LenweSaralonde/ee9586e989c860913c29a8a112d0d914 (I keep the v1 untouched since it « works »)

Great job ! The most important is not which code to use but that you fully understand the logic, how it's implemented and how to adjust it if needed (on my side, I tried to keep the stops code untouched since you're already familiar with it). It was a great experience for me since it's the very first time I write Arduino code and I'm proud to have contributed to this project!

Were you able to test the Swell to Great, Swell to Pedal, and Great to Pedal stops? I wasn't sure if I had that configured right.

2 arduinos side by side, roundrobbin the midi notes between them. That'll work, right? :D

Maybe just randomly copy lines from each and paste them together. That will work, right? Haha

Awesome, I'm glad to hear that they worked out! It doesn't matter to me which one you end up running. It was a fun experiment to put it together and cool to hear that it worked. If it were me I'd flip a coin :)

hello all im not sure wether you all see the reply or not if notified. but hopefully you do! i have just tested both lenwe's and chris's code. and have played a bunch of stuff and i can say safely both work very well. i can not tell a discernable difference between the actual function of both of them, even when playing busy stuff. question is what now/. got two great codes and an awesome attempt by gerwin above! awesome stuff. ill make sure to show it functionning in a vlog asap. and will be sure to mention all of your efforts with github links in the up and coming organ video.

Look Mum No Computer

hello all im not sure wether you all see the reply or not if notified. but hopefully you do! i have just tested both lenwe's and chris's code. and have played a bunch of stuff and i can say safely both work very well. i can not tell a discernable difference between the actual function of both of them, even when playing busy stuff. question is what now/. got two great codes and an awesome attempt by gerwin above! awesome stuff. ill make sure to show it functionning in a vlog asap. and will be sure to mention all of your efforts with github links in the up and coming organ video.

Look Mum No Computer

hello all im not sure wether you all see the reply or not if notified. but hopefully you do! i have just tested both lenwe's and chris's code. and have played a bunch of stuff and i can say safely both work very well. i can not tell a discernable difference between the actual function of both of them, even when playing busy stuff. question is what now/. got two great codes and an awesome attempt by gerwin above! awesome stuff. ill make sure to show it functionning in a vlog asap. and will be sure to mention all of your efforts with github links in the up and coming organ video.

Look Mum No Computer

Yes, there is no need to do extreme optimization if there is no need to. Sam and the museum staff will do some tests and if it works as is, there is no need to fix it if it aint broken in the first place.

Pros and cons to both approaches for sure. I think both will likely work. I'd lean on the side of simplicity and consistency to avoid possible edge cases etc., but it's not excessively complicated to do it "smarter" either. Both good solutions!

Yep, exactly my thinking. The execution cost between each loop iteration should be fairly fixed (outside of the midi library reading and writing messages in its buffer). As new notes are pressed, the cost of handling is minimal (direct writes to the correct array, no looping). So it shouldn't matter how many notes are being pressed, the performance of each loop should be about the same. If it needs to be faster, unroll loops, go back to bitmaps and bitwise operations to remove looping, etc. By processing the output changes with each incoming midi message, performance is changing based on external factors. They both have similar worst case performance, but I don't think that will matter here, which is why I went with an approach that was easier for me to debug and have confidence in the state stability. I just hope one of them works well enough to see the organ in action :D

Flattening won't change anything, processing 4 arrays of 128 elements is the same as 1 array of 512. There is more processing when more keys and stops are on. In my code, the processing is done only when a change of a key or sa top is registered so unless you keep spamming the whole keyboard or send black MIDI over the MIDI in, it - should - work fine.

That's what I mean - there are a couple of nested loops (that could be flattened if performance did become an issue), but they are basically just scanning a few small arrays. I don't think it will take long enough to be the bottleneck and will likely run many times before each midi message comes through. Obviously I could be wrong though, but I think the trade-off for simplicity and stability is worth trying it at least.

MIDI data bandwidth is not an issue. The problem is more the code with nested loops that runs every time a MIDI event is received that could potentially cause problems on a machine powered by a 8-bit CPU @16 MHz with 2K of RAM. But again, this is intended to be used in the organ console which is controlled by an human so the MIDI 32 Kbits/s bandwidth should be rarely pushed beyond limits. It could be interesting however to test the brains part by playing some intensive MIDI files to the keyboard input such as Circus Galop and check how the organ handles it. https://github.com/LenweSaralonde/MusicianTools/blob/master/test/circusgalop.mid

Looking at Chris Riggs' code I think that's the same approach that I would take too. It is also easy to expand if you ever got more pipe banks or what have you. Looping through every note/switch on every loop iteration *sounds* wasteful, but MIDI operates at under 32kbps, and there is not much heavy lifting going on here. I'd imagine the internal midi library stuff would probably take up a lot more "processor time" than this loop, though that's only a guess. Being more "clever" with efficiency increases the chances of rogue stuck notes if there is some weird edge case hit. Edit: I re-read the code and you can ignore the following text. I misinterpreted the function name. Just quickly though, are the setNoteOn() and setNoteOff() functions looking at the currentState correctly or reversed? I'm only skimming but it looks like it will send note-on events when the current state is already on and vice-versa rather than when the state is changed. End Edit

yes. it wouldnt be an issue. this machine can be under refined and still do a more than adequate job :D. ill be loading the stuff from the past 12 hours lenwe latest and such withhin the hour. back from other jobs. :D

Look Mum No Computer

yes it's more of an if an stop bounce and it calculates the note on/off accordingly we might have some stutter in the pipe :) however, to be fair, that would have happened in the analogue version as well. And true, multiple ways to the same outcome.

I'm not too concerned with performance issues of checking the state of the buffers on each loop iteration. It will be executing more average operations each loop, but the total execution time on a change will be essentially the same. The tradeoff is that an external state change won't be seen until a single loop iteration is complete (there should be 100s per second), but we should always end in a consistent state. This avoids some of the potential issues you're seeing with ending in the wrong state due to denouncing triggering unwanted events. There still might be a need to denounce in both cases. I appreciate the performance considerations and I think it's cool to see how we both approached the problem in different ways :D

These old switches will definitely bounce. So there might be some need to de bounce if doing the stops readout and actually setting notes to the pipes on and off in the loop.

In my solution, I check the stops status at each loop iteration and run the update routine only if a change was detected : https://gist.github.com/LenweSaralonde/06c4ab19d9945275914858d00dc1cc2c#file-organ-stops-ino-L274 This way, the code behaves like a received MIDI CC event and the processing is done only when necessary to avoid potential performance issues. The problem I encountered with the simulator was the bouncing causing the routine to be triggered several times and randomly ending on the wrong state. This also caused some unexpected note on / note off events being sent in a very short amount of time (not sure the solenoids like that). After I added the 10K resistors, it worked fine. But again, it's a simulator, I can't guarantee it would work flawlesly on the real thing, even with 10K resistors.

I mean it's function is not of a function that really be effected by bouncing. Not really an issue for stops

Look Mum No Computer

Yes that might happen, although the ADC is probably too slow to register those events.

Do you get 'bouncing" issues with analog pins too ? On the other hand, it would be great that wokwi adds real MIDI connectivity to the emulator so we could connect atual keyboards and synths to check how it behaves and detect performance / latency issues that can't be done using debug traces https://wokwi.com/projects/363743573533928449

Yep but the last 2 analog pins on an arduino don't function as digital pins. Hence last one just coded as analog read as digital read won't work.

Look Mum No Computer

One thing I wasn't sure about is why one of the pins is an analogRead and everything else is a digitalRead. My understanding is that didgitalRead is just analogRead > x, but I could be completely wrong.

I haven't done much Arduino programming, I would love to have a good way to unit test and mock the IO pins and midi library. It would be much faster to develop.... It is just C, so maybe move all of the logic into another file that's Arduino agnostic and test that, and add a shim implementation for the midi library. Programming without tests: https://youtu.be/TYM4QKMg12o

Regarding your comment about erratic results with the stop pins, it could be caused by "bouncing" which is a phenomenon caused when the switch closes that can spam on/off several times in a short amount of time. To resolve this, you may add a 10K resistor between the GND and the pin in your simulator diagram. I've been researching ways to run unit tests on Arduino code to test the logic without messing with the MIDI API and hardware constraints. AUnit seems to be a good framework but it needs to run on the actual hardware or an emulator, while common test framework may run on any computer. https://github.com/bxparks/AUnit

I also threw another revision together, incorporating some of the logic in Lenwë's latest revision and ditching ulong[4] for boolean[128] arrays to keep state. I added a debug flag that will simulate some note events, and print out all of the input and output state. I think all of the Swell to Great, Swell to Pedal, and Great to Pedal switches should be working as well, assuming the pins are configured correctly. Hopefully there's enough variations between our implementations that one of them will work :D https://gist.github.com/criggs/8d01d96675dab9641c9430a5773b6d87


Related Creators