Midi Synth for Pi's
Pages: 1 2
Peter Everett (9846) 59 posts |
There have been a few discussions here about midi over the past few months and a recurring issue has been the lack of a software synth that works on the Pi. About a year ago I ported a midi synthesiser of my own design to RiscOS and Andre Timmermans kindly helped me with testing and sorted out some of my dodgy code. He mentioned it here and some of you may have tried it out. However, it was a stand alone application and not what was really needed. I wondered if I could help by creating a module version of the synth. I have never written a module before but eventually managed to get it to work. It’s a replacement MIDI module and works ok with Rhapsody, Maestro, DigitalCD. I would have liked to create a replacement for the ESP synth but I have no documentation on the interface and it works through ESP MidiSupport, which also doesn’t work on my PI. DigitalCD uses the ESP MPLAY module as the player and it might just be me but MPLAY refuses to play many of the midi files I have. After looking at the MPLAY sources I decided it would be easier to use my own player so I created another module to replace MPLAY. I have tested both modules on a Pi4(RO 5.28) and on an RPCEmu(RO 3.71) but as I’m new to modules, it’s probably best to treat them as test releases. If anyone is interested they are at, http://www.forever.onmypc.netI’d welcome any comments good or bad as I’ve probably not done things correctly and I know many of the synth voices need improvement. However it might fill a gap until something better comes along. |
Paolo Fabio Zaino (28) 1821 posts |
Great job Peter! :) I personally don’t play MIDI files locally, I have a rack of MIDI Synths, so have no need for it. But I am sure people will enjoy it. |
Jeff Doggett (257) 233 posts |
I’m gonna guess that since it says “For Pi’s” in the title, that it’s no surprise that is crashes on an Iyonix. |
Peter Everett (9846) 59 posts |
Ah, I don’t think I can much help with the Iyonix. These days I only have a Pi and an RPCEmu for all the old RiscPC stuff. I’m sure it’s fixable but I don’t have the knowledge or the hardware for testing. Sorry. |
Steve Pampling (1551) 8126 posts |
I thought from your reference to the Iyonix that it might be processor instruction related, but it doesn’t seem to throw a wobbler when run on RPCEmu. Edit: “semi-functional” being the immediately expected not working double-click on a MIDI file producing a complaint the DiskSample is required. So, no great surprise on that. I have to say that it’s the best sound I’ve heard out of the RPCEmu setup1 – despite the install being on a laptop folded shut blocking the speakers as it sits to one side feeding the pair of large screens along with a different (work related) laptop. Is it just me or are the MIDI files rather “thin”? Chumbawumba is definitely lacking in that solid thumping bass line. 1 Standard Windows play of the Midi files is distorted. |
Peter Everett (9846) 59 posts |
I think there’s been a bit of confusion here. I believe Jeff’s problem is with the synth module. I originally ported the application from Windows and all the code for the !MidiPlay application is in application space, no modules except for the audio output. Either DiskSample or SharedSound can be used but yes it will complain if either is missing which is silly it could just use the one that’s present. When I realised that what people really wanted was an ESP synth replacement, I extracted the player code and synth code and created the 2 modules. The bulk of the code is the same. The player module does not require any other resources and uses the system ticker for all it’s timing. The synth module requires SharedSound which it will attempt to load. It would be interesting to know if the !MidiPlay application works or not on the Iyonix, and yes, in general it could do with a bit of bass boost, hence the tone controls on the application. |
Steve Pampling (1551) 8126 posts |
One point of note – the line in the RMEnsure MIDI 0.05 X RMLoad System:Modules.MIDI will always fail as the name of the module file is actually MidiSynth not MIDI but reports itself as module name MIDI With regard to the thin sound – insufficient data for you as I didn’t actually complete the description in the note 1. – The sound from the MIDI file is both distorted and thin when you allow the default player of Windows to have an attempt. |
Peter Everett (9846) 59 posts |
I should have updated !MidiPlay before releasing the modules. !MidiPlay outputs audio via it’s own synth, but also outputs Midi messages to drive an external synth and I should have removed the facility because there are serious timing issues. Thanks for pointing that out, I’ll sort it out. |
Jeff Doggett (257) 233 posts |
Sorry, yes, I wasn’t clear. I do mean the synth module.
Yes, it does. I have patched the init function in the module to always set “type=1” for the call back – this doesn’t crash. I wanted to see if it worked with my Doom game. It doesn’t. I originally stole the midi driving code from DIY doom many years ago. It looks like your swi interface isn’t quite the same as the one that DIY doom was written for. |
Peter Everett (9846) 59 posts |
Thanks Jeff, I need to do some timing tests but at least I know what the problem is with the module now. |
Jean-Michel BRUCK (3009) 334 posts |
Hi Peter I’m doing some tests and even the drum section seems correct, nice to. I’m trying to build one based on Rick’s work, same for the 32b adaptation of MidiSynt (ESP), but it’s not progressing much… |
Jeff Doggett (257) 233 posts |
|
Peter Everett (9846) 59 posts |
Active Sensing (FE) has no effect as it has no real meaning for a synth. Scheduled events are also not implemented, all events are actioned From the log, a string of notes on’s are sent and then a string of note off’s and on’s are scheduled, then “all notes off” are scheduled for all channels. Unfortunately, it will all be actioned immediately and turn off everything that has just been turned on, which might be why you don’t hear much. I modified the audio handler to always use a callback type to fix your crash problem but this does cause occasional breakup on my Pi4. I need a better way of selecting which to use. When I next upload it, TxCommand will always return an “empty buffer” of 512. I don’t think |
Jeff Doggett (257) 233 posts |
It keeps calling TxCommand until the buffer is full. I changed the code here so that the 1st dummy read returns 1, then zero thereafter, hence it was only putting a single command into the buffer each pass.
Since it looks like I’ll have to rework the code anyway to implement the delays, I suspect the the buffer free count will become moot. |
Peter Everett (9846) 59 posts |
I wasn’t planning on adding scheduling, I could but this synth module was really only a quick fix. |
Rick Murray (539) 13751 posts |
The problem is that polling is not reliable, speed wise. It may be that scheduling is necessary to get things to play at the right time…? |
Peter Everett (9846) 59 posts |
Ok, you’re quite right Rick, I’ll see what can be done, I guess something similar to that used in your USB MIDI module. I still have this issue with the shared sound handler type which I don’t have an answer for. I provide a quick buffer fill routine that shared sound regularly calls to read from my buffer. Before returning, the routine requests a call back so the synth can fill my buffer up. Removing the XOS_AddCallback instruction at the end of the handler code stopped the crash but obviosly no audio as my buffer was now not being filled. Using a “callback” handler type works on both machines but is prone to audio breakup on the Pi4. To get the best operation I need a way of selecting the handler type depending on the machine, but it would help if I knew why it was crashing, and select the type using that knowledge. Or maybe rewrite the whole lot correctly if I’m not doing it right, I don’t know. You might think that using a callback handler means I don’t need to setup a further callback but I cannot directly call the synth ‘c’ code from the sharedsound handler as the c environment is not setup. |
Jeff Doggett (257) 233 posts |
For the Iyonix crash, it seemed to be related to the desktop being active. |
Rick Murray (539) 13751 posts |
Strange. Where’s the memory that the callback points to? It’s in the RMA, right? I ask, because that sounds like what could happen if the memory is in application space and the Wimp swaps it out and puts something else there (or maybe nothing, depending upon program size and address). |
Peter Everett (9846) 59 posts |
For the synth module, everything is in the module and so in RMA. The problem seems to be requesting a further callback from within the sharedsound handler doesn’t work in certain situations. This further callback does indeed point to RMA. |
Rick Murray (539) 13751 posts |
Hmm. An alternative could be to set a flag to say “buffer fill needed” and have a separate routine on TickerV (is 100Hz fast enough?) that services this and does the job? Alternatively, what does the buffer fill actually do? If it just shuffles memory around and does some calculations in between (like translating MIDI notes to samples), could it be done on the fly? |
Peter Everett (9846) 59 posts |
The TickerV polling method is effectively how the !MidiPlay application works. 100Hz hertz is ok. The function that is called back actually does all the synthesis and is run for every sample in the buffer. Not something you want to do with interrupts disabled, hence the callback. I had been thinking of using the Ticker since it works ok for the App version. |
Peter Everett (9846) 59 posts |
I’ve updated the synth module with the new timing scheme and it should now be ok on the Iyonix and hopefully machine independent. Adding event scheduling will take a while longer. |
Rick Murray (539) 13751 posts | |
Peter Everett (9846) 59 posts |
Jeff, I have uploaded a test version supporting scheduled events. Included is a couple of test basic files, one sends the commands in the log file you posted which produces sound but is very quiet, the other has maximum volume (note velocity). |
Pages: 1 2