Jump to content

program a pot (or sensor) to play notes


joenteman
 Share

Recommended Posts

Hi Joente,

the application has to send a note-off event for the previous note, before the new note is sent. So long the last pot value is stored (this is the case for MB64 for example), the realization of such a feature isn't a big problem. Which application are you using (selfwritten or official MBxx release?)

Best Regards, Thorsten.

Link to comment
Share on other sites

Ok, I will give you a short hint which should help for the first experiments, but to make it clear: I won't implement the complete solution. This is on your side (I made the experience, that than more complete solutions I publish here, than more people are asking for even more  - this just consumes too much time at my side and prevents the people from learning about how to do this by themself)

So - just open mb64_meta.inc and program a Meta Event which sends Note Off/Note Ons, where the note number if controlled from the pot value:


MB64_META_Handler
;; Meta Event Fx 00: send Note Off for last value, Note On for new value
movlw 0x00
IFNEQ MIDI_EVNT1, ACCESS, rgoto MB64_META_Handler_NotFx00
MB64_META_Handler_Fx00
;; send Note Off, channel number defined in Fx (right digit)
movf MIDI_EVNT0, W
andlw 0x0f
iorlw 0x90
movwf MIDI_EVNT0
movff MB64_POT_LAST_VALUE, MIDI_EVNT1
clrf MIDI_EVNT_VALUE ; (velocity == 0 -> note off)
call MIDI_EVNT_Send

;; send Note On with new value
movff MB64_POT_NEW_VALUE, MIDI_EVNT1
movlw 0x7f
movwf MIDI_EVNT_VALUE ; (velocity == 0x7f: max)
goto MIDI_EVNT_Send

MB64_META_Handler_NotFx00
;; here you could define 126 additional meta events
return
[/code]

(I haven't tried the code - if it doesn't work, it must be a syntax or even more stupid error, but in principle it will work)

I guess that you want to gate the Note events with a pedal. This requires a second Meta event which has to be assigned to a button input.

This meta event has to switch a flag which identifies the current button status. You have to define a new variable in app_defines.inc, and you have to store this flag there.

In addition, this meta event has to send a Note Off if the pedal is released. Problem here: MB64_POT_LAST_VALUE contains the last value of the pot which has been moved the last time. If this wasn't your theremin, then it will contain an invalid information.

Therefore the Meta handler F000 should store the new value which has been used to send a note on in an additional variable (-> also has to be defined in app_defines.h), and this can be used in meta handler F001 (assigned to the pedal) to send a note off

Hope this helps. If you find assembly programming too difficult, then just try the MIOS C Wrapper first. Once the algorithm is working, you can port it to assembler.

Best Regards, Thorsten.

Link to comment
Share on other sites

Hi Joente,

nice to hear that it works! :)

No, there isn't a tutorial available yet. Currently I'm trying to focus on C based examples, since they are easier to handle for people who are not so much into assembly programming and the MB64 application. I think, that the benefit is higher.

E.g., there is a ain64_din128_dout128_v2_0 template available, which is preconfigured for up to 64 pots, 128 buttons, 128 LEDs. MIDI events have to be customized in the program itself, and such special behaviours like for your theremin can be realized with much less lines of code.

So, here the same in C (the AIN_NotifyChange function can be found in main.c)


// global variable which is declared at the top of main.c:
unsigned char thermin_value;

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a pot has been moved
/////////////////////////////////////////////////////////////////////////////
void AIN_NotifyChange(unsigned char pin, unsigned int pin_value) __wparam
{
  // thermin is connected to pin #0
  if( pin == 0 ) {

    // send Note Off at channel 1 for last value
    MIOS_MIDI_TxBufferPut(0x90);
    MIOS_MIDI_TxBufferPut(thermin_value);
    MIOS_MIDI_TxBufferPut(0x00);

    // send Note On at channel 1 for new value
    thermin_value = MIOS_AIN_Pin7bitGet(pin); // don't use 10bit pin_value, but 7bit value
    MIOS_MIDI_TxBufferPut(0x90);
    MIOS_MIDI_TxBufferPut(thermin_value);
    MIOS_MIDI_TxBufferPut(0x7f);

  } else {

    // do anything else with the other AIN pins

  }

  // notify display handler in DISPLAY_Tick() that AIN value has changed
  last_ain_pin = pin;
  app_flags.DISPLAY_UPDATE_REQ = 1;
}
[/code] With this code, modifications should be much easier. E.g., with following extension:
[code]
  // thermin is connected to pin #0
  if( pin == 0 ) {

    // send Note Off if Thermin value is valid
    if( thermin_value != 0xff ) {
      MIOS_MIDI_TxBufferPut(0x90);
      MIOS_MIDI_TxBufferPut(thermin_value);
      MIOS_MIDI_TxBufferPut(0x00);
    }

    // only send Note On when Button DIN#0 is pressed
    if( MIOS_DIN_PinGet(0) == 0 ) { // button value is 0 when pressed
      // send Note On at channel 1 for new value
      thermin_value = MIOS_AIN_Pin7bitGet(pin); // don't use 10bit pin_value, but 7bit value
      MIOS_MIDI_TxBufferPut(0x90);
      MIOS_MIDI_TxBufferPut(thermin_value);
      MIOS_MIDI_TxBufferPut(0x7f);
    } else {
      // invalidate thermin value, so that no additional note off's will be sent
      thermin_value = 0xff;
    }

  } else {

    // do anything else with the other AIN pins

  }

Note On's will only be sent when the pedal is pressed, and Note Off's will only be when really required

Best Regards, Thorsten.

Link to comment
Share on other sites

hai thorsten

thanx for the reply, i,ve tried to program in c, but i can't compile the file. the make.bat doesn't do what it supose to do. I followed the steps as described on the site.

I couldn't figure out how to handle the sdcc stuff in the right way.

thanks for the effort, theremin works very nice already.

greetings Joente

Link to comment
Share on other sites

hi thorsten

Since this is a new direction for me, I would like to help you with your improvement, maybe it is useful to have some feedback from a "first-timer".

i've tried alot of things to get it work. if i start the make.bat, it runs a dos window and returns to windows. In the explorer i see that the files makefile.bat and makefile are updated (if you look at the date). But it doesn't do what it must do. there comes no hex file.

in the makefile.bat i see that there are some commands used as "sdcc, gpasm".

i think it has something to do with the "sdcc", i don't realy understand what i must do with that downloaded files. I've surfed the forum for answers but couldn't find the right one. There is a lot of information in the readme files, but there are a lot of them, but not useful enough for me.

Maybe is it useful for your documentation, to make a "stepperplan" for the compilation-part, especially how to use the different tools, such as perl, sdcc and gputils. For me (and i supose not only for me)  this is a little vague  ???. 

greetings  Joente

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...