Jump to content

49 keys SM MIDI Driver


 Share

Recommended Posts

still beta, not yet stested for real, but no compiling error !

you change the midi channel with the 16 first white keys,

E3 and F3 allows you to increase or decrease Octave (+12 semi tons)

it has a sustain pedal, and a pitch bend

To use with mini yamaha keyboard.

Link to comment
Share on other sites

Ok, i tested for real, and there were bugs !!!

so, i corrected, and it works well now :)

You need one DOUT, one DIN, one CORE, make the scan matrix (i reused a mini yamaha keyboard, which has 8 rows and 6 column, +1 free column so 49 keys)

Add a display (2x16 LCD) to see messages, channel and notes number played.

The only problem is with "Octave", i don't know how to code a ranged value.

Link to comment
Share on other sites

1st thing : thanks Stryd for help

octave &= 0x7F;

??? i tried but doesn't change anything ..

what i would like to do is having :

unsigned char octave into the range 0-127, 0 included and 127 included.

/////////////////////////////////////////////////////////////////////////////
// Fonction de gestion de l'octave
/////////////////////////////////////////////////////////////////////////////
void OCTAVE(void){
// octave doit Ãtre compris entre 0 et 127 inclus
  //octave &= 0x7F;
  if (octave<=-1)
  octave &=0x00;
  if (octave>=0x7f)
  octave &=0x7F;
  

}

when I press several time the "octave up" key (which correpond to a combbinaison between C5 and F3), octave is going up until it reaches Midi Note 127, but then after, it returns to Midi note 1 (meaning the PIC has lost the value of "octave" ...). WTF ??????

Link to comment
Share on other sites

foo &= bar;

is like saying

foo = foo & bar;

so

octave &= 0x7f

is like

octave = octave & b01111111;    // pseudocode- you can't use binary representation in sdcc

which means that the top bit will be masked out, limiting the variable to 127, so

void OCTAVE(void){

// octave doit Ãtre compris entre 0 et 127 inclus

  octave &= 0x7F;

}

That's all you need - although, I don't know if I would put it in a separate function like that, it'll take more time to jump to the code, than to just do this one instruction whenever it's needed.

Link to comment
Share on other sites

the &= 0x7F thing is good to prevent accidentally sending invalid midi, but not necessarily the best thing for setting ranges.

this code will prevent octave shift from exeeding 0x7F and wrapping around 0 for octave up:

unsigned char tmp;
...
tmp = octave + 0x0C;
if !(tmp & 0x80)
  octave = tmp;
i supect, though, that what you really need is to keep octave + your highest note value under 0x7f. so, for octave up:
#define OCTAVE_MAX 64   ;//set this to 0x7F - 0x0C - your highest note number
...
if (octave <= OCTAVE_MAX)
  octave += 0x0C;

same goes for octave down but with 0

hope this helps...

Link to comment
Share on other sites

thanks for their help to Bugfight and Stryd.

The code i did is enough for the moment. I did it for reboot of the forum,  I won't do more in the next days.

Do you know if we can add this keyboard to the MB6582 (without a second Core), and mix the code with the already made code for MB6582 ? That means that we ask to the PIC  to drive 2 scan matrix at the same time.

Link to comment
Share on other sites

  • 1 month later...

WORKING Application ! Connect :

a Yamaha mini Keyboard to J8/J9,

a pot to J5 pinA0 (Pitch wheel)

and GO !

/*
 * Mini driver MIDI de clavier 49 touches
 * ==========================================================================
 *
 *  Copyright 2008 Julien Voirin (julien.voirin@free.fr)
 *  Licensed for personal non-commercial use only.
 *  All other rights reserved.
 *
 * ==========================================================================
 */

#include "cmios.h"
#include "pic18f452.h"

#include "main.h"
#include "sm_simple.h"

/////////////////////////////////////////////////////////////////////////////
// Global variables
/////////////////////////////////////////////////////////////////////////////
unsigned char midich;
unsigned char function_button;

unsigned char octave;

// pour l'affichage
unsigned char Note;
unsigned char Canal;

// status of application (see bitfield declaration in main.h)
app_flags_t app_flags;

/////////////////////////////////////////////////////////////////////////////
// Local variables
/////////////////////////////////////////////////////////////////////////////




/////////////////////////////////////////////////////////////////////////////
// Fonction for highlighting the green light
/////////////////////////////////////////////////////////////////////////////
void GreenLIGHT_On(void){
  PORTDbits.RD4 = 1;
}
void GreenLIGHT_Off(void){
  PORTDbits.RD4 = 0;
}

/////////////////////////////////////////////////////////////////////////////
// Fonction de gestion de l'octave
/////////////////////////////////////////////////////////////////////////////
void OCTAVE(void){
// octave doit être compris entre 0 et 127 inclus
  //octave &= 0x7F;
  if (octave<=-1)
  octave &=0x00;
  if (octave>=0x7f)
  octave &=0x7F;
  

}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS after startup to initialize the 
// application
/////////////////////////////////////////////////////////////////////////////
void Init(void) __wparam
{
  // initialize the scan matrix driver
  SM_Init();

  // initialize the shift registers
  MIOS_SRIO_NumberSet(1);           // use up to 16 shift registers if value = 16
  MIOS_SRIO_DebounceSet(20);         // debouncing value for DINs
  MIOS_SRIO_UpdateFrqSet(2);         // set update frequency
  MIOS_SRIO_TS_SensitivitySet(0);    // disable touch sensors
  // configure MIDI-Merger (enable)
	MIOS_MIDI_MergerSet(MIDI_MERGER_MODE);

	 // initialize the AIN driver
  MIOS_AIN_NumberSet(AIN_NUMBER_INPUTS);
  MIOS_AIN_UnMuxed();
  MIOS_AIN_DeadbandSet(AIN_DEADBAND);

  midich=0x00; // canal midi au démarrage = channel one
  function_button = 0x00 ; // i.e bouton FCT pas appuyé

  octave=0x24; // 3octaves * 12 semitons = 36 = 0x24
  
  // All Notes off
  MIOS_MIDI_TxBufferPut( 0xB0 );
  MIOS_MIDI_TxBufferPut( 0x7B );
  MIOS_MIDI_TxBufferPut( 0x00 );
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS in the mainloop when nothing else is to do
/////////////////////////////////////////////////////////////////////////////
void Tick(void) __wparam
{
  // call the scan matrix button handler
  SM_ButtonHandler();
  
  // management of the octave rules
  OCTAVE();
  
  Canal = midich;

    
}

/////////////////////////////////////////////////////////////////////////////
// This function is periodically called by MIOS. The frequency has to be
// initialized with MIOS_Timer_Set
/////////////////////////////////////////////////////////////////////////////
void Timer(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when the display content should be 
// initialized. Thats the case during startup and after a temporary message
// has been printed on the screen
/////////////////////////////////////////////////////////////////////////////
void DISPLAY_Init(void) __wparam
{
  // clear LCD
  MIOS_LCD_Clear();

  // request display update
  app_flags.DISPLAY_UPDATE_REQ = 1;
}

/////////////////////////////////////////////////////////////////////////////
//  This function is called in the mainloop when no temporary message is shown
//  on screen. Print the realtime messages here
/////////////////////////////////////////////////////////////////////////////
void DISPLAY_Tick(void) __wparam
{  

  
  // update display only when requested to minimize the CPU load
  if( !app_flags.DISPLAY_UPDATE_REQ )
    return;
  app_flags.DISPLAY_UPDATE_REQ = 0;

  
  // print note number
  MIOS_LCD_CursorSet(0x00 + 0);
  MIOS_LCD_PrintCString("Note:");
  
  if (sm_button_value == 0){
  MIOS_LCD_PrintBCD3(Note);
  MIOS_LCD_PrintCString(" ");  
  }else{
  MIOS_LCD_PrintCString(" __ ");
  }
  
  //print midi channel
  MIOS_LCD_CursorSet(0x00 + 0x09);
  MIOS_LCD_PrintCString("CH.");
  MIOS_LCD_PrintBCD2(Canal+0x01);  


  // control visuel du canal midi (pour ajouter une LED par exemple)
  if (midich==0)
  GreenLIGHT_On();// allumage de J14 à +5V quand le canal midi est CH.1 (0x90)
  else
  GreenLIGHT_Off();   
  
/*  
// print message on screen depending on button status (debug, need a 4*20LCD)

  MIOS_LCD_CursorSet(0x80 + 0);
  if( sm_button_value )
    MIOS_LCD_PrintCString("Button Depressed");
  else
    MIOS_LCD_PrintCString("Button Pressed  ");

  // print Column and Row
  MIOS_LCD_CursorSet(0xC0 + 0);
  MIOS_LCD_PrintCString("Col:");
  MIOS_LCD_PrintBCD3(sm_button_column);
  MIOS_LCD_PrintCString("  Row:");
  MIOS_LCD_PrintBCD3(sm_button_row);
*/

}
// 64 characters (0x40) are reserved for each line, up to 4 lines are (natively) spported:
// 1st line begins at 0x00
// 2nd line begins at 0x40
// 3rd line begins at 0x80
//4th line begins at 0xc0)

/////////////////////////////////////////////////////////////////////////////
//  This function is called by MIOS when a complete MIDI event has been received
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI event has been received
// which has been specified in the MIOS_MPROC_EVENT_TABLE
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyFoundEvent(unsigned entry, unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI event has not been completly
// received within 2 seconds
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyTimeout(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI byte has been received
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyReceivedByte(unsigned char byte) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS before the shift register are loaded
/////////////////////////////////////////////////////////////////////////////
void SR_Service_Prepare(void) __wparam
{
  // call the Scan Matrix Driver
  SM_PrepareCol();
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS after the shift register have been loaded
/////////////////////////////////////////////////////////////////////////////
void SR_Service_Finish(void) __wparam
{
  // call the Scan Matrix Driver
  SM_GetRow();
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when an button has been toggled
// pin_value is 1 when button released, and 0 when button pressed
/////////////////////////////////////////////////////////////////////////////
void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when an encoder has been moved
// incrementer is positive when encoder has been turned clockwise, else
// it is negative
/////////////////////////////////////////////////////////////////////////////
void ENC_NotifyChange(unsigned char encoder, char incrementer) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a pot has been moved
/////////////////////////////////////////////////////////////////////////////
void AIN_NotifyChange(unsigned char pin, unsigned int pin_value) __wparam
{
/*  
// a pot has been moved, send CC# at channel 1
  MIOS_MIDI_TxBufferPut(0xb0); // CC at channel 1
  MIOS_MIDI_TxBufferPut(pin);  // pin number corresponds to CC number
  MIOS_MIDI_TxBufferPut(MIOS_AIN_Pin7bitGet(pin));   // don't send 10bit pin_value, but 7bit value
*/  
    unsigned long pin_value1 ;
    
switch ( pin )
    {
    case 0 : // first J5 Header pin

pin_value1 = ((pin_value << 4)) ; // expanding 10bits to 14 bits !! BITSHIFTING
    
    MIOS_MIDI_TxBufferPut(0xE0 + midich);  // Pitch bend
    MIOS_MIDI_TxBufferPut((unsigned int)((pin_value1) >> 0 )& 0x7f);      // pitch Data LSB
    MIOS_MIDI_TxBufferPut((unsigned int)(((pin_value1)>> 7 )& 0x7f)); // pitch Data MSB

    break;
    }

}

/////////////////////////////////////////////////////////////////////////////
// This function is NOT called by MIOS, but by the scan matrix handler
// in sm_simple.asm, when a pin of the scan matrix has been toggled
// Note: in addition to "pin" and "value", the "sm_button_column" and
// "sm_button_row" are available as global variables (defined in sm_simple.h)
/////////////////////////////////////////////////////////////////////////////
void SM_NotifyToggle(unsigned char pin, unsigned char value) __wparam
{
  // send pin number and value as Note On Event

switch( pin ) 
  {
    case 6: // 1ere touche C0
    if (function_button == 1 && value == 0){
    midich = 0x00;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x00 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x00 + octave; 
    }
      break;
            
    case 0: // 2eme touche C#0
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x01 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x01 + octave; 
      break;
      
    case 1: // 3me touche D0
    if (function_button == 1 && value == 0){
    midich = 0x01;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x02 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x02 + octave; 
     }  break;

    case 2: // 4eeme touche D#0
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x03 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x03 + octave; 
      break;
      
    case 3: // 5eme touche E0
    if (function_button == 1 && value == 0){
    midich = 0x02;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x04 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x04 + octave; 
     }  break;
      
    case 4: // 6eme touche F0
    if (function_button == 1 && value == 0){
    midich = 0x03;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x05 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x05 + octave; 
     }  break;
      
    case 5: // 7eme touche F#0
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x06 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x06 + octave; 
      break;
      
    case 8: // 8eme touche G0
    if (function_button == 1 && value == 0){
    midich = 0x04;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x07 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x07 + octave; 
     }  break;
      
    case 9: // 9eme touche G#0
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x08 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x08 + octave; 
      break;
      
    case 10: // 10eme touche A0
    if (function_button == 1 && value == 0){
    midich = 0x05;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x09 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x09 + octave; 
     }  break;
      
    case 11: // 11eme touche A#0
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x0A + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x0A + octave; 
      break;

    case 12: // 12eme touche B0
    if (function_button == 1 && value == 0){
    midich = 0x06;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x0B + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x0B + octave; 
     }  break;
    
    ///////////////////////////////////////////
    
    
    case 13: // 1ere touche C1
    if (function_button == 1 && value == 0){
    midich = 0x07;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x0C + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x0C + octave; 
     }  break;
            
    case 16: // 2eme touche C#1
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x0D + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x0D + octave; 
      break;
      
    case 17: // 3me touche D1
    if (function_button == 1 && value == 0){
    midich = 0x08;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x0E+ octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x0E + octave; 
     }  break;

    case 18: // 4eeme touche D#1
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x0F + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x0F + octave; 
      break;
      
    case 19: // 5eme touche E1
    if (function_button == 1 && value == 0){
    midich = 0x09;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x10+ octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x10 + octave; 
     }  break;
      
    case 20: // 6eme touche F1
    if (function_button == 1 && value == 0){
    midich = 0x0A;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x11+ octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x11 + octave; 
     }  break;
      
    case 21: // 7eme touche F#1
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x12+ octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x12 + octave; 
      break;
      
    case 24: // 8eme touche G1
    if (function_button == 1 && value == 0){
    midich = 0x0B;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x13 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x13 + octave; 
     }  break;
      
    case 25: // 9eme touche G#1
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x14 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x14 + octave; 
      break;
      
    case 26: // 10eme touche A1
    if (function_button == 1 && value == 0){
    midich = 0x0C;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x15 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x15 + octave; 
     }  break;
      
    case 27: // 11eme touche A#1
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x16 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x16 + octave; 
      break;

    case 28: // 12eme touche B1
    if (function_button == 1 && value == 0){
    midich = 0x0D;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x17 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x17 + octave; 
     }  break;
  
    ////////////////////////////////////////////
  
  
    case 29: // 1ere touche C2 etc...
    if (function_button == 1 && value == 0){
    midich = 0x0E;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x18 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x18 + octave; 
      } break;
            
    case 32: // 2eme touche C#2
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x19 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x19 + octave; 
      break;
      
    case 33: // 3me touche D2
    if (function_button == 1 && value == 0){
    midich = 0x0F;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x1A + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x1A + octave; 
     }  break;

    case 34: // 4eeme touche D#2
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x1B + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x1B + octave; 
      break;
      
    case 35: // 5eme touche E2
    if (function_button == 1 && value == 0){
    octave = octave - 0x0C ;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x1C + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x1C + octave; 
     }  break;
      
    case 36: // 6eme touche F2
    if (function_button == 1 && value == 0){
    octave = octave + 0x0c;
    }else{
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x1D + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x1D + octave; 
     }  break;
      
    case 37: // 7eme touche F#2
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x1E + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x1E + octave; 
      break;
      
    case 40: // 8eme touche G2
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x1F + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x1F + octave; 
      break;
      
    case 41: // 9eme touche G#2
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x20 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x20 + octave; 
      break;
      
    case 42: // 10eme touche A2
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x21 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x21 + octave; 
      break;
      
    case 43: // 11eme touche A#2
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x22 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x22 + octave; 
      break;

    case 44: // 12eme touche B2
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x23 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x23 + octave; 
      break;
      
      ///////////////////////////////////////////
      
      
    case 45: // 1ere touche C3 etc...
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x24 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x24 + octave; 
      break;
            
    case 48: // 2eme touche C#3
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x25 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x25 + octave; 
      break;
      
    case 49: // 3me touche D3
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x26 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x26 + octave; 
      break;

    case 50: // 4eeme touche D#3
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x27 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x27 + octave; 
      break;
      
    case 51: // 5eme touche E3
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x28 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x28 + octave; 
      break;
      
    case 52: // 6eme touche F3
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x29 + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x29 + octave; 
      break;
      
    case 53: // 7eme touche F#3
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x2A + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x2A + octave; 
      break;
      
    case 56: // 8eme touche G3
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x2B + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x2B + octave; 
      break;
      
    case 57: // 9eme touche G#3
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x2C + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x2C + octave; 
      break;
      
    case 58: // 10eme touche A3
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x2D + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x2D + octave; 
      break;
      
    case 59: // 11eme touche A#3
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x2E + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x2E + octave; 
      break;

    case 60: // 12eme touche B#3
      MIOS_MIDI_TxBufferPut(0x90 + midich);
      MIOS_MIDI_TxBufferPut(0x2F + octave);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      Note = 0x2F + octave; 
      break;
      
    ///////////////////////////////////////////////
    
    
    case 61: // touche FUNCTION
      if (value == 0){
      function_button = 0x01;
      MIOS_LCD_CursorSet(0x40);
      MIOS_LCD_PrintCString("Choose CH or Oct+/-");
      }else{
      function_button = 0x00;
      MIOS_LCD_CursorSet(0x40);
      MIOS_LCD_PrintCString("                   ");
      }
      break;

    case 07 : //sustain
      MIOS_MIDI_TxBufferPut(0xB0 + midich);
      MIOS_MIDI_TxBufferPut(0x40);
      MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
      
      break;    
    
}
  // request display update
  app_flags.DISPLAY_UPDATE_REQ = 1;
}

Link to comment
Share on other sites

WORKING Application ! Connect :

a Yamaha mini Keyboard to J8/J9,

a pot to J5 pinA0 (Pitch wheel)

and GO !

Hi julienvoirin, do you think this code, maybe tweaked here and there could work with a doepfer(Fatar) 2 octaves keyboard?

1 core, one DOUT and one DIN sounds cheaper than the doepfer MKE module

the  matrix schematic for that kb:25 keys schem

I'm planning to build a standalone Fatman w/keyboard included, your work could be really useful ;)

Thanks,

Freddy.

Link to comment
Share on other sites

The fatar keyboard would make way smaller code, it'd probably be better to take a different approach.

julien has had to include that big switch statement because his keyboard skips a bunch of keys here and there (why? it's really weird!). The fatar keys are all in order, so it'll just need one function for sending all the note values, and an if statement to react to the function key for setting the octave.

Link to comment
Share on other sites

Dear Freddy, don't hesitate to use this code (maybe delete statement for unused keys).

Dear Stryd, ok switch is the HEAVY way, but the PIC manages it very well and it has the benefit to allow you sub functions (SHIFT+a key). Code isn't linear but i am not the designer at Yamaha  ; why making a 8*6 matrix ??

Link to comment
Share on other sites

You can do subfunctions in other ways too, but I don't blame you for your software being heavy: like you said, it's the yamaha designers I couldn't figure out... I was going to suggest some optimisations but once i read the code I could see that you had little other choice (not knowing what the physical layout was)

That said, if you made your matrix 8x6 to match the board, that would be a lot cleaner, and allow for smaller code that could be more easily included in other projects. All you have to do, is wire it the other way, and you could use the row/column variables to quickly calculate the note number, and leave two columns (now rows) of switches unused (perhaps they could be used for other functions later)

But if it works for your purpose and the idea is not portability - why bother :)

Link to comment
Share on other sites

The fatar keyboard would make way smaller code.. so it'll just need one function for sending all the note values, and an if statement to react to the function key for setting the octave.

sounds good

...don't hesitate to use this code...

I have to start somewhere so I'll try it ;)

btw. this code will run on 18f452 only? I have a spare 18f4620 and 18f4685

Link to comment
Share on other sites

4620 and 452 are fully compatible so no worries there. As for the 4685, it kinda depends. You may have to work a little bit with the makefile and more specifically the udata pragma marker. I've done some preparations that might help a little...but, I'd just use the 4620.

Link to comment
Share on other sites

if you made your matrix 8x6 to match the board, that would be a lot cleaner,
diodes were inverted !!

and i like this  "switch/case" design : no matter what is the button pressed, it can send whatever you want for message (CC, program, sysex ....) it seems easier to me for beginner and enhancement ;)

TK uses the same method for every app : you configure the name of the button, not its function, the function is defined later.

Link to comment
Share on other sites

diodes were inverted !!

That's not quite what I meant :)

TK uses the same method for every app : you configure the name of the button, not its function, the function is defined later.

For a normal interface like that, with buttons with very different functions and physical layout, I agree that makes sense, and I do the same thing....but in a keyboard situation the functions are linear (key 0 is note 0...key 64 is note 64), so it makes sense to me to reflect that in code. Having the switch statement is one way of making an exclusion to the linearity, but I prefer to make such exclusions with an if statement.

I guess it also should be considered what the purpose of the thing is... because if it doesn't increase speed, or the speed increase is not noticable, or you don't plan on having any other code on the chip (like putting a synth in the keyboard) ... there's no point optimising at all!

And the switch statement certainly makes it a lot easier for people to modify if they're new to C

But that's the beauty of it... coding is like music, It's an artform :) Each to their own :)

Link to comment
Share on other sites

code handles key velocity?
no, unfortunatly, you have to use the cimo sm1024 code for that. Ask him via the forum.

Another solution is to use and encoder to define the velocity value (fixed or modulating while you are playing), i did it for my previous user project (la boite à boutons)

Cheers

Link to comment
Share on other sites

no, unfortunatly, you have to use the cimo sm1024 code for that. Ask him via the forum.

Another solution is to use and encoder to define the velocity value (fixed or modulating while you are playing), i did it for my previous user project (la boite à boutons)

Cheers

alas! it was not me

Simone

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...