Receiving sysex

Discuss problems and solutions.
Post Reply
strophlex
Newbie
Posts: 6
Joined: 01 Feb 2015 20:49

Receiving sysex

Post by strophlex »

Hello

I am making a template for controlling the Ex-800 with HAWK800 mod. I can now control all parameters, but I'd like to be able to read and dump complete patches too. When reading a patch a specific syx message is sent to the synth and the patch dump is sent back. I all works, but trouble arrises when reading the received dump. It worked as expected as long as I had implemented just the first parameters, but then lemur crashed and I think it was because of the limit of script length. I then researched if there is a way to call a script with parameters (the received syx dump) but it doesn't seem like that. Instead I made a second script that also receives syx (On MIDI, F0 - system exclusive, none, 0 to 127, 1 to 1). The second script starts reading where the first script left off. But now when I receive the sysex dump, Lemur crashes. Is it possible to do like I do? Is there some way around this? The array of sysex is 256 I think, but I read about 240.

Script 1
(On MIDI, F0 - system exclusive, none, 0 to 127, 1 to 1)

Code: Select all

decl i = 4;
DCO1_oct.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
DCO1_wave.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
DCO1_harmonics.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
DCO1_harm_modulation_waveform.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
DCO1_harm_modulation_source.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
DCO1_harm_modulation_depth.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
DCO1_volume.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
DCO1_mode.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];

DCO2_oct.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
DCO2_wave.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
DCO2_harmonics.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
DCO2_harm_modulation_waveform.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
DCO2_harm_modulation_source.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
DCO2_harm_modulation_depth.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
DCO2_volume.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
i += 2;
DCO2_interval.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/12;
DCO2_detune.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/3;
Noise_level.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
i += 10;
Frequency.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/99;
Freq_keyboard_track.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
Freq_EG_Invert.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
Freq_EG_depth.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
EG3_retrigger.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
i += 4;
Chorus.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
DCO1_attack.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
DCO1_decay.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
DCO1_breakpoint.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
DCO1_slope.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
DCO1_sustain.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
DCO1_release.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
i += 4;
DCO2_attack.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
DCO2_decay.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
DCO2_breakpoint.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
DCO2_slope.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
DCO2_sustain.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
DCO2_release.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
i += 4;
EG3_attack.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
EG3_decay.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
EG3_breakpoint.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
EG3_slope.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
EG3_sustain.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
EG3_release.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/31;
i += 4;
Velocity_OP1_intensity.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/4;
Velocity_OP1_invert.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
Velocity_OP1_target.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
Velocity_OP2_intensity.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/4;
Velocity_OP2_invert.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
Velocity_OP2_target.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
Freq_velocity.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/6;
Freq_vel_resp_shape.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
Script 2
(On MIDI, F0 - system exclusive, none, 0 to 127, 1 to 1)

Code: Select all

decl i = 65*2+4;
LFO1_frequency.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
LFO1_delay_timer.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
LFO1_free_runing.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
LFO1_delay_invert.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
LFO1_PWM_phase.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/62;
LFO1_LFO3_modulation_waveform.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
LFO1_LFO3_modulation_depth.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
i += 2;
LFO2_frequency.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
LFO2_delay_timer.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
LFO2_free_runing.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
LFO2_delay_invert.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
LFO2_PWM_phase.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/62;
LFO2_LFO4_modulation_waveform.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
LFO2_LFO4_modulation_depth.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
i += 2;
DCO_pitch_modulation_waveform.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
DCO_pitch_modulation_source.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
DCO_pitch_modulation_depth.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
i += 2;
DCO_pitch_modulation_eg_invert.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
DCO_pitch_modulation_depth_eg.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
i += 2;
DCO_pitch_modulation_mode.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
VCF_freq_LFO_waveform1.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
VCF_freq_LFO_source1.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
VCF_freq_LFO_depth1.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
VCF_freq_LFO_waveform2.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
VCF_freq_LFO_source2.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
VCF_freq_LFO_depth2.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
i += 2;
Filter_mode.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
Resonance.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/99;
VCF_res_LFO_waveform.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
VCF_res_LFO_source.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
VCF_res_LFO_depth.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
i += 2;
Res_EG_depth.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
Res_EG_Invert.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
Aggressive_resonance.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
FM800_depth.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/99;
FM800_LFO_waveform.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
FM800_LFO_source.selection = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
FM800_LFO_depth.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
i += 2;
FM800_EG_depth.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
FM800_EG_Invert.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
i += 2;
SLFO3_frequency.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
SLFO3_phase.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/62;
SLFO3_free_runing.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
SH_rate.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/99;
SLFO4_frequency.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/15;
SLFO4_phase.x = (MIDI_ARGS[i++]*16 + MIDI_ARGS[i++])/62;
SLFO4_free_runing.x = MIDI_ARGS[i++]*16 + MIDI_ARGS[i++];
oldgearguy
Regular
Posts: 315
Joined: 02 Nov 2013 11:19

Re: Receiving sysex

Post by oldgearguy »

A couple quick suggestions.
First - set Lemur aside.
Second - use MIDI-Ox/Sysex Librarian/other tool to manually send the dump request to the EX-800 and save off the returned sysex stream.
Third - manually count the bytes received, F0->F7 inclusive. If the number is 256 or less, continue working on your template. If it is more, stop and do something else, currently it *will not* work with the lemur no matter how many receive scripts you write.

If you are continuing,
MIDI_ARGS is the complete sysex buffer received. You can use a modification of the program attached to display each byte of MIDI data in the buffer (change midiArgs to MIDI_ARGS and add your sysex receive routine) to verify you are getting everything. Then you can figure out how to break it all apart.
Attachments
showIt.jzml
basic script to show data in a sysex buffer
(4.03 KiB) Downloaded 116 times
strophlex
Newbie
Posts: 6
Joined: 01 Feb 2015 20:49

Re: Receiving sysex

Post by strophlex »

I checked the reference documents and according to that the sysex is 256 bytes of patch data plus six bytes of head/tail which means it is 262 bytes in total. Does that mean this project is doomed or is it possible to read the first 256 bytes? It is a bit strange that all worked well when receiving the first about 160 bytes or something (the first script only)...
oldgearguy
Regular
Posts: 315
Joined: 02 Nov 2013 11:19

Re: Receiving sysex

Post by oldgearguy »

strophlex wrote:I checked the reference documents and according to that the sysex is 256 bytes of patch data plus six bytes of head/tail which means it is 262 bytes in total. Does that mean this project is doomed or is it possible to read the first 256 bytes? It is a bit strange that all worked well when receiving the first about 160 bytes or something (the first script only)...

256 total for Lemur. Any data received beyond that causes weirdness/corruption/crashing. So even though it is 256 of actual data, Lemur doesn't distinguish data from wrapper. This hard limit has doomed more than one patch editor/librarian project.

Given how embedded the number 8 is in all the Lemur stuff (referencing 0-255 only requires 8 bits/1 byte of data), my guess is that it would be a significant rewrite to expand that buffer size.

Unless you can get the EX-800 to send the data in smaller blocks with a significant time gap between the blocks (so that Lemur clocks over to the next frame and does a fresh read) you'll just be chasing your tail trying to get it to work reliably.
strophlex
Newbie
Posts: 6
Joined: 01 Feb 2015 20:49

Re: Receiving sysex

Post by strophlex »

Thanks for the insight. I will just ditch this template and do it from scratch in MAX / MIRA then.
Post Reply