New Engine Implementation: Aeolus (Pipe Organ Emulator)

Following ou discussion on another thread, I’ve successfully ran Aeolus on Zynthian.
All the configuration has been done on the command line, so there is no real engine integration for now, but this should now be easy as it is known to work.

Here below is the process i did :slight_smile:


Zynthian RPI install Aeolus HOWTO

  1. connect to your box
    ssh -Y root@zynthianIP

  2. install aeolus
    root@zynthian:~# apt-get install Aeolus

  3. start Aeolus
    root@zynthian:~# aeolus &

  • (X window is opening on local computer, Aeolus is creating stops files automaticly with blinking buttons, wait a moment)
  • shell says : “Can’t open ‘/root/.aeolus-presets’ for reading” as the file does not exist
  1. lsit jack ports to check is it ok
    root@zynthian:~# jack_lsp
    system:playback_1
    system:playback_2
    ttymidi:MIDI_in
    ttymidi:MIDI_out
    Zyncoder:output
    Zyncoder:input
    aeolus:out.L
    aeolus:out.R
    aeolus:Midi/in

  2. connect audio and midi ports
    root@zynthian:~# jack_connect aeolus:out.L system:playback_1
    root@zynthian:~# jack_connect aeolus:out.R system:playback_2
    root@zynthian:~# jack_connect ttymidi:MIDI_in “aeolus:Midi/in”

  3. set Aeolus midi ports
    go to aeolus panel, open MIDI window, select midi channel for the keyboards (P,I,II,III)

(simple and fast screenshots here in french https://doc.ubuntu-fr.org/aeolus#installation )

  1. play
    play on you midi keyboard and Voilà !

aeolus process is using ~15% cpu on RPi2 when idle


PART 2 : mididings filter

  1. install mididings
    root@zynthian:~# apt-get install mididings

  2. start script
    root@zynthian:~# python aeolus.py &

  3. start alsa midi bridge
    root@zynthian:~# a2jmidid &

  4. list jack ports
    root@zynthian:~# jack_lsp
    system:playback_1
    system:playback_2
    ttymidi:MIDI_in
    ttymidi:MIDI_out
    Zyncoder:output
    Zyncoder:input
    aeolus:out.L
    aeolus:out.R
    aeolus:Midi/in
    a2j:Midi Through [14] (capture): Midi Through Port-0
    a2j:Midi Through [14] (playback): Midi Through Port-0
    a2j:aeolus [128] (playback): In
    a2j:mididings [129] (playback): in_1
    a2j:mididings [129] (capture): out_1

  5. disconnect jack midi ports (if connected)
    root@zynthian:~# jack_disconnect ttymidi:MIDI_in aeolus:Midi/in

  6. connect midi ports
    root@zynthian:~# jack_connect ttymidi:MIDI_in “a2j:mididings [129] (playback): in_1”
    root@zynthian:~# jack_connect “a2j:mididings [129] (capture): out_1” aeolus:Midi/in

  7. set Aeolus midi ports
    go to aeolus panel, open MIDI window, select midi channel for CONTROL

  8. play
    play on you midi keyboard and Voilà !
    Notes are still going through, and CC filter is ready

(see video if i can upload somwhere)


I’m really happy with it, great latency, superb sound !

One more hint : after you clicked “Save” on Aeolus interface, files are created
Writing ‘/usr/share/aeolus/stops/Aeolus/definition’
Writing ‘/root/.aeolus-presets’
Writing ‘/usr/share/aeolus/stops/Aeolus/definition’
Writing ‘/root/.aeolus-presets’

Can someone help to create the necessary engine/script files to be able to use Aeolus as an instrument ?

The wiki page http://wiki.zynthian.org/index.php/Zynthian_Devel_Engine doesn’t says much about starting another program like mididings (needed for stops control)

7 Likes

I don’t think, @jofemodo will approve mididings as requirement.
It has to be setup without.

If the CC calculations could be done without mididings (integrated zynhian midi filter ?) Then hopefully we can have it working.
Unless we could display the aeolus Gui, not having acces to the CC control renders the software useless.

You might have a look at -

Which is pretty short and clear.

I think the CC issue will sort itself with the midi changes coming along but all this boring clerical work of making the zynengine file for it needs to be done as well.

2 Likes

@hammerandtongs yes i will do this file so the engine can be started as is for now.

The midi CC input of Aeolus is just non standard, In order to change a button state (called a “stop”), you need to send two CC messages.
So declaring something like [‘reverb’,91,4,127,‘reverbmix’] would not make sense.

May we do the midi tweaks inside this file or is it just declarative ?

1 Like

Well looking here - https://github.com/zynthian/zynthian-ui/blob/a084967b541bbf2ee41233dd52366aa053b90c6c/zyngine/zynthian_engine.py#L386

It looks like a straight mapping. This is part of where whatever new midi remapping logic would have to go in concert with some kind of logical way of describing the behaviour via the zynengine file for the synths.

1 Like

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