New Engine Implementation: Aeolus (Pipe Organ Emulator)

you are absolutely correct !
with a keyword in the controllers definition, one could hope for a change from “Default implementation uses a static controller definition array” to “a little bit of python code to change the midi messages” :slight_smile: (and that’s exactly what the mididings script does)

1 Like

videos here
setup
play

1 Like

Hi @jerash,

Great work!! Could you give some examples of MIDI mapping with mididings and eolus?
I will come back from holidays the Next week and i will give a deeper look …

Thanks!!

Hi,

Midi mapping is « simple »

  1. all midi NOTE messages go thru, nothing to do with those, whatever midi channel.
  2. I have not tried PC and Bankchange messages explained here under.
  3. CC messages used to enable/disable a button in aeolus need to be « filtered » with a special calculation, that’s exactly what the mididings script does (in python with a convenient library), and is self-explanatory :
def aeolus_button(ctrl, group, button):
    return CtrlFilter(ctrl) >> CtrlValueSplit(64,
        [ Ctrl(98, 0x50 | group), Ctrl(98, button) ],
        [ Ctrl(98, 0x60 | group), Ctrl(98, button) ]
    )

run(
    Filter(CTRL) % (
        [ aeolus_button(     n, 0, n) for n in range(12) ] +
        [ aeolus_button(12 + n, 1, n) for n in range(13) ] +
        [ aeolus_button(25 + n, 2, n) for n in range(16) ] +
        [ aeolus_button(41 + n, 3, n) for n in range(16) ]
    )
)

A « Stop » is the pipe organ name for panel buttons enabling a certain pipe sound.
The script is expecting on input :

  • a CC message between 0-56
  • a value < 64 means : deactivate button
  • a value >= 64 means : activate button
    Those CC message are mapped to the 57 buttons of the Aeolus default instrument.

Aeolus is expecting 2 CC98 messages (default defined in global.h at compilation) to move one button, because buttons are organised into « groups » and you first need to explicitly select the group, this is where the calculation occurs when a message is received.
The first CC message to send is the « group » selection
The second midi message to send is the « button » action

Examples (calculation by head, hopefully correct) :
When the script receives a CC 07 with value 32, it means switch off the seventh button, and translates to :

  • CC 98,0x50 (select group 0, and set off)
  • CC 98,0x06 (on seventh button of this group)
    When the script receives a CC 13 with value 90, it means switch on the thirteenth button (first button of group 1), and translates to :
  • CC 98,0x61 (select group 1, and set on)
  • CC 98,0x01 (on first button of this group)

here under is the explanation in details from GitHub - fugalh/aeolus: Aeolus is a high quality pipe organ emulator using additive synthesis. :

The protocol uses one controller number. The default is #98, but you
can change this in global.h. The message is accepted only on channels
enabled for control in the midi matrix.

The value is interpreted as follows:

v = 01mm0ggg

  This type of messages (bit 6 set) selects a group, and either
  resets all stops in that group or sets the mode for the second
  form below.

  mm = mode. This can be:

     00  disabled, also resets all elements in the group.
     01  set off
     10  set on
     11  toggle

  ggg = group, one of the button groups as defined in the instrument
  definition. In the GUI groups start at the top, the first one (for
  division III) being group #0.

  The values of mm and ggg are stored and need not be repeated unless
  they change.

v = 000bbbbb

  According to the current state of mode, this command switches a
  stop on or off, or toggles its state, or does nothing at all.

  bbbbb = button index within the group.

  Buttons are numbered left to right, top to bottom within each
  group. The first one is #0.

Presets can be set and recalled with the MIDI Program Change message. The bank
of presets can be selected with the bank select message.

1100cccc 00sppppp
Program change (on channel c): set or recall program (p). If s is 0,
preset is recalled, if s is 1 preset is stored

1011cccc 00000000 000bbbbb
Bank select on channel c.

As always the message is only accepted on channels enabled for control in the
midi matrix.

hope this helps

Raphaël

this part is not implemented int the mididings script for sake of simplicity, that’s why it always send 2 CC98 message, which doesn’t hurt.

OK! Understand …
I’m thinking the best way of integrating mididings as an advanced option. Why not? :wink:

Regards,

1 Like

Hi @jerash!

I’ve a initial version of the aeolus engine. I’ve implemented the stop mechanism directly in the engine, without using mididings. The code is really simple:

	def send_controller_value(self, zctrl):
		try:
			val=zctrl.get_label2value()
			logging.debug("Sending controller '%s' value => %s" % (zctrl.symbol,val))
			if val=="on":
				mm="10"
			elif val=="off":
				mm="01"
			else:
				mm="11"
			v1="01{0}0{1:03b}".format(mm,zctrl.graph_path[0])
			v2="000{0:05b}".format(zctrl.graph_path[1])
			self.zyngui.zynmidi.set_midi_control(zctrl.midi_chan,self.stop_cc_num,int(v1,2))
			self.zyngui.zynmidi.set_midi_control(zctrl.midi_chan,self.stop_cc_num,int(v2,2))
			logging.debug("Stop Change => mm={}, group={}, button={})".format(mm,zctrl.graph_path[0],zctrl.graph_path[1]))
		except Exception as e:
			logging.debug(e)

I would like to improve it a little bit more before making a release, but i need some help from you:

1.) Does exist some way of generating and saving the Aeolus wave files without using the GUI? The only way i’ve found is clicking “save” from the GUI…

2.) The current engine’s version has the “Default Instrument” structure hardcoded in. It would be possible to parse the “definition file”, but before doing it i would like to know if people like you (a Pipe Organ Expert :wink: ) find this feature interesting and how much interesting is.

3.) Regarding the “presets”: The current engine version can send “Program Change” messages for loading presets, but the zynthian controllers doesn’t show the loaded values. Bad! For reflecting the loaded values, i need to parse the presets file, that is a binary file. It’s not specially complex because the Aeolus code is pretty straighforward and easy to understand:

Anyway, i would like to hear your opinion about it. Are aeolus “presets” really useful? Do you use it frequently? Do you have a better solution?

Kind Regards,

Hi @jofemodo

yes sure, this is really awesome that you had done the logic in the engine definition, really really nice work !

If you want me to test something on my zynthian, please send me some files to try !

From what I know there are 2 options to use :

  • on the first run (with the gui) it checks wheter the files exist, if not then it is creating them (it takes about one minute or two).
  • if the necessary files are copied in the revelant directories BEFORE aeolus is ever started, it will use those files.

I think you want the second option. Meaning that those files generated on another unit must be part of a “static package” for aeolus engine.

Also note that the default directory /usr/share/Aeolus/stops-0.3.0 must be writable but the user running aeolus for the files to be saved for next startup.

Cicking “Save” on the GUI, is only for saving presets and options from what i’ve seen.

I don’t really get what you want to achieve here ?
But I you think about modifying the instrument temperament (all the cursors in the audio option window), which would need a recalculation of the wave files, then I think it is not necessary as most users are ok with the default sound.

Yes they are usefull because when they play a song, or another they will use different stops combination.
And sometimes, with complex or long songs, they will need to change the sound while playing.
Most of these changes involve to switch on and off up to 10 switches, and is not doable while playing.

Organs which often have at minimum 2 hand keyboards + 1 foot pedal keyboard, have 6 presets for each keyboard in standard.
Here Aeolus only has “global” presets that will change the stops on all keyboards.
From what i’ve encountered with people playing in small churches, they use a maximum of 4 presets (and often none).
So this function while not absolutely necessary for beginners and small churches, is anyway necessary for the regular player.

Now if you can SAVE and RECALL presets, I think most users can deal with not having the active stops written on the LCD. In a way, the sound speaks by itself, and it is easy to write down on a paper which preset is used on which song/part.

hope this helps.

I mean that you can use a different “definition” file, with a different instrument configuration. Currently, the default instrument structure (definition) is hardcoded in the zynthian engine and for using a different instrument (definition file), the code must be modified. It could be solved by not hardcoding the instrument structure in the engine and parsing the definition file, but it’s a good amount of work and it seems that everybody is using the default instrument because it’s quite complete …

Regards,

Yes I confirm the default definition is absolutely ok.

Hi @all!

As you can see, the new Aeolus engine is on master now:

FYI, i’ve implemented a read function for the Aeolus presets file and now when you load a preset, the Zynthian UI controllers get updated nicely. Whoaoooo! :sunglasses: :rofl:

@jerash, I included some “random” presets for testing but i would like to include a decent set of presets, could you send a good “presets” file?

Enjoy!

4 Likes

this is insane, i’ll update my zynthian box to test this and report

@jofemodo is faster at work without deadline than other with it :wink:

1 Like

Hi @jofemodo,

I just got my 2nd Zynthian back from Make-Magazin and updated the software last Friday (first update since 4 month) - works!
After seeing the announcement of Aeolus I updated again. Installation procedure seems to work. Starting the engine does work also, but I cannot hear anything when playing. Hmmm… strange.

Does the update work for other users?
Perhaps I should try with a fresh image again?

Regards, Holger

1 Like

You don’t have an Audioinjector in that Zynthian? With mine I had to slide the alsamixer via webconf. …

1 Like

Ok, I think I have to start my notebook and have to look for the problem. Not working “out-of-the-box” :wink:

Regards, Holger

I’ve tried the update with a fresh SD image and it worked. Impossible to test with all infinite SD status.
Of course, the update process is very far from perfect … :disappointed_relieved:

I got it running by installing the latest ZynthianOS image and updating. I had some strange problems with the encoders (MCP23017) after using the image… I have to invest some time to check this again and pick up some debug information.

Aeolus sounds nice! Very cool!!!

Regards, Holger

Hi all,

On my Zynthian v1 worked. A fresh gorgona image and updated …twice did the trick.

Wonderful sounds! Nice work!

Thanks, Jose.

When you did, please tell me how you did that.
I can’t run zynthian.sh or webconf outside systemctl context.

Hi all.
My box wouldnt update due to github certificate problems…
So downloaded the fresh gorgona image yesterday and booted ok.
Will report next week when tested.