XVA1 User Interface build progress

here’s my completed and expanded build, controlled by a Teensy 3.6

14 Likes

This… I really was looking on the table, in between the tools, where the synth was. That’s impressive. Do the controls of the CME ( pitch bend, mod wheel…) also send data to the XVA? I repeat. I’m impressed!

Hi, yes the CME has an internal MIDI and power cable as well as the external MIDI, so I fed these into my controller along with a MIDI in to allow the XVA1 to be accessed as a module, so all information of the CME is passed onto the XVA1, so the 8 sliders can be used a the MIDI parameter controllers 1-8, volume slider works, pitch, mod wheel etc. The rotary controls also work for panning etc. the patch changer tells the XVA1 editor to load the next patch. Also I’ve set the shortcut buttons to be program up and progam down by interpreting two unused controller values to be up and down prgram changes. It does mean that tha XVA1 patch number can become out of sync with the CME program change but thats the only downside. Keyboard, velocity and aftertouch are also passed through to the XVA1.

1 Like

You have my respect. Do you happen to have a product design background?

Here is our setup.
The MPC Live is used by me almost exclusively. I have a couple of weeks to explore XFM2/XVA for sound design. You’ve given me the idea to look for the Midi page within the MPC.
As I read the XVA manual, it seems possible to map all the CCs to the corresponding ones on the MPC. Is it then possible to work with it without using the spreadsheet?

Here’s the MIDI-Program page. 8 Tabs, 16 Parameters on each.
As of right now, I’m still waiting for my XFM2/XVA1 parts to arrive. I hope you are enjoying it. Can you tell how Bugfree/Stable it is? I decided against a Digitone and a Mother32.
I hope I won’t be the next “cheap gear joke”…

3 Likes

Not at all, in fact design is probably one of my weak points, I tend to wing it and hope for the best.

2 Likes

You can only map 8 CC’s to the XVA1 and some of the more comon ones are accepted, to eit the XVA1 you must use the serial interface or SYSEX commans over MID. It would be impossible to map all 512 paramters of the XVA1 to a controller over CC because of the 127 limit of CC numbers and the 127 limit of values, if NRPN was implemented then you could get past this limit as have full editing of the XVA1 over NRPN, but the designer chose to use SYSEX commands, which are simple enough buyt the sending device needs to be able to send sysex from sliders and switches etc,

1 Like

This is my eitor for the XFM2 synthesizer, the FM older brother of the XVA1, again built into a CME UF-70.

9 Likes

i’m still drooling over this synth and the possibilities, but the current form is a showstopper unfortunately. really hope someone with some fab/product dev abilities finds this thing and does a kickstarter for a dedicated interface. wrong site to express my developmental ineptitude i know, but sadly free time is not on my side in the next few years.

1 Like

That style of illuminated button never goes out of style.

1 Like

I had never programmed anything two years ago when I started working with Teensy SOCs. I had an idea of what I wanted to achieve and then went from there. So much internet help etc around to build great projects.

wow… This looks very good.

1 Like

Hi I recently found this thread as I am building the xva1 myself. I mainly build hte midibox controllers from ucapps.de I have several on the go at the moment. My son saw this synth online so we are building it together and will also be making a controlelr enclosure using the MB_NG system.

I would also like to add the Seeeduino xiao board to the xv1a however this will be my first steps into anything arduino based or programming in any revision of “C”.

I would love to get some insight on adding the single display to the xiao and linking it to the xv1a if possible, i can then start my own build thread and share how i progress on this.

I am 51 and used to program assembly, now i am into the midibox ng code and learning the scripting for that to use with my vst synths.

It would be good to be able to get into this as well, I have bought a couple of books to start with to learn c++ and programming an arduino, small steps and all that!!

Thanks
ssp

1 Like

This evening i managed to find a small Leonardo micro board and linked it to an ssd1306 128x64 oled. I found a tutorial on linking it to the micro and loading some code, glad to say it worked first time for me. i am now playing around with displaying some text and a few other things. As soon as i can get some help with the linking the seeed to the xva1 i will start the new thread and see how things go and try to understand and break down the code for me to get a better understanding.

I’ve got some code, but it"s still a work in progress, and it’s targetted at an STM32.

The plan is to have 8 oleds and 8 encoders with a few buttons. Mostly works on a breadboard, and it looks like it talks to the XVA1 fpga okay, although I haven’t had it hooked up while making sounds, so don’t know yet whether or not the parameters are being received properly.

The trickiest bit for me so far has been the UI - how to deal with encoder clicks and parameter pages and the like, but I think I’ve got a skeleton that should work.

Let me know if you’re interested, I can probably share what I have.
Eventually it’ll go up on github, but I’m not there yet…

2 Likes

I have written the code for the MB_NG and tested that and its working fine, that uses the stm32f4 discovery board with the rest of the MB boards ( Ainser64 + Dout + Dinr5) i have them set up in banks so i can assign most of the control change or sysex to the code for assignment/learn functions or pre mapped functions.

The base Os is Mios then the .ngc code is used over that.

This is a section of my code for the MB_NG control interface that also used banking to allow for multiple functions per encoder, fader, pot etc. This will give me enough to control what i want to on the synth.

The Ainser64 gives me 64 analog in’s I can have 2 linked to the board

RESET_HW

LCD "%C@(1:1:1)Bank Test"

# Controlled from buttons

# select Bank1 directly
EVENT_BUTTON id=1 type= Meta meta= SetBank meta= RunSection:1 button_mode=OnOnly range=1:1

# For testing purposes: decrement bank
EVENT_BUTTON id=2 type= Meta meta= DecBank meta= RunSection:1 button_mode= OnOnly   #Bank decrease 

# For testing purposes: increment bank
EVENT_BUTTON id=3 type= Meta meta= IncBank meta= RunSection:1 button_mode= OnOnly   #Bank increase 


# Bank 1
EVENT_AINSER id=1 hw_id =1 bank=1 fwd_to_lcd=1  type=CC chn=1 cc=16 range=0:127 offset=0 lcd_pos=2:1:1 label="ENC1 #%3i %3d@(2:1:2)%B" 



#Bank 2
EVENT_AINSER id=2 hw_id =1 bank=2 fwd_to_lcd=1  type=CC chn=2 cc=17 range=0:127 offset=0 lcd_pos=3:1:1 label="ENC2 #%3i %3d@(3:1:2)%B" 


EVENT_LED id= 1 range= 1:1 radio_group= 1 #bank1

EVENT_LED id= 2 range= 2:2 radio_group= 1 #bank2

EVENT_LED id= 3 range= 3:3 radio_group= 1 #bank3

EVENT_LED id= 4 range= 4:4 radio_group= 4 #bank4


# AIN hardware
AIN enable_mask=00000000


# AINSER hardware
AINSER n=1   enabled=1  muxed=1  cs=0  num_pins=1  resolution=7bit
AINSER n=2   enabled=0  muxed=1  cs=1  num_pins=0  resolution=7bit
2 Likes

Yeah, I took a good look at the midibox stuff when I was considering how to go about this.
I decided to roll my own and write it on bare metal - mostly as a learning exercise. I did make the observation that it was almost starting to look a little like an OS when I had to rewrite it a second time and add a proper event queue for handling all the knobs and buttons and menu pages and so forth.
Might take another look at midibox one of these days.

I would be very interested in some basic overview on how to tackle something like this, if you don’t mind explaining! I am still slowly working on my repeat step sequencer (similar to metropolis) and I have close to no experience in ux programming. I imagined I would just have a read_buttons function which collects all the states of buttons and pots, saves them and then another function makes everything happen :wink: but this does only work for 1-button 1-function, no way to use any shift button or having a little sub menu for certain stuff. Ofc I want to minimize menu diving but I think for some stuff it will be necessary. Combine this with debouncing and interrupts for advancing the sequencer and I am completely lost! :wink:
So, for starters: what is an event queue and how would I use it exactly?

1 Like

So, it really depends on your hardware - the microcontroller and the surrounding glue logic.

In my case I’m using these MCP23017 IO port expanders to connect all the knobs and buttons and leds. They can generate an interrupt when an input changes. On the MCU side, I create a representation of all the encoders and buttons etc in memory. When there’s an interrupt from the MCP23017 it is scanned to see which thing has changed state (and the internal representation is updated too). Once the thing that has changed has been identified an event is created and shoved into the event queue. That’s all that happens in the interrupt service routine (ISR).

For the event queue I made something like what is described on this page:

The ISR looks something like this:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
  process_io_board(&io_board);
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}

process_io_board does the scanning to see what has changed. An example here is if it’s figured out that it’s a button that has been pressed, it will generate an event like this, where i is the number of the button that was either pressed or let go:

      push_event((next_state == 0x00) ? EV_BTN_DOWN : EV_BTN_UP, i);

Then in the main routine I have this:

  while (1)
  { 

    while (queue_has_event()) {
      handle_ui_event(&screens);
    }

    if (led_tick++ > TICK_COUNT) {
      push_event(EV_TIME, event_time);
      event_time++;
      led_tick = 0;
    }
    HAL_Delay(1);
  }

Then, the handle_ui_event() pulls an event out of the queue - looks at what it was, checks which page or parameter or action is being used and updates the rest of the system - it can send parameter changes to the synth, it can update the display, whatever.

The point here is, as events come in, the are shoved into the queue as they happen by the interrupt. Then, when there is some idle cycles, the code deals with the events. That way, we should catch all the button presses or encoder turns.

Cheers

3 Likes