I recently completed and implemented code on a PIC18F4620 to talk to my two DB50XG units. Since the code is in ‘C’, and might prove useful to others implementing such code, I’ve provided a hard-copy (DB50XG.c) snapshot of the relevant sections from my code and give a brief extract of these below.
The XG Voice List Implementation.
Each patch number/program number pair is entered as a two-byte character array, 432 in total, of which I’ve only shown the start and finish in the code example below. The full table is included in the DB50XG.c source-code in the download section.
////////////////////////////////////////////////////
//
// 'C' Routines for selecting DB50 mode, and
// implementing simple selection of a DB50XG patch
// from 'XG Normal Voice List'.
// (From an implementation of mine for PIC18F4620)
//
// (C) 2010 J.W.Brown and joebrown.org.uk
// Use freely as long as credit given.
// JWB 13th December 2010
//
////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
//
// XG synth patch codes voice list
// Derived from 'XG Normal Voice List' starting on Page 32 of DB50XG Manual
//
/////////////////////////////////////////////////////////////////////////
// Each entry comprises (program, bank)
// DO NOT change order of entries.
// DO NOT shorten table
//
// I've annotated the beginning of each section. e.g. 1st is 'Piano'
//
// Piano
rom const char p0[] = {1,0}; // Grand Piano
rom const char p1[] = {1,1};
rom const char p2[] = {1,18}; // Mellow G.Piano
rom const char p3[] = {1,40};
rom const char p4[] = {1,41}; // Dream
rom const char p5[] = {2,0}; // etc.. you get the picture.
rom const char p6[] = {2,1};
rom const char p7[] = {3,0};
rom const char p8[] = {3,1};
rom const char p9[] = {3,32};
rom const char p10[] = {3,40};
rom const char p11[] = {3,41};
rom const char p12[] = {4,0};
rom const char p13[] = {4,1};
rom const char p14[] = {5,0};
rom const char p15[] = {5,1};
rom const char p16[] = {5,18};
rom const char p17[] = {5,32};
rom const char p18[] = {5,40};
// lots more... until:
rom const char p420[] = {119,0};
rom const char p421[] = {119,64};
rom const char p422[] = {119,65};
rom const char p423[] = {120,0};
rom const char p424[] = {121,0};
rom const char p425[] = {122,0};
rom const char p426[] = {123,0};
rom const char p427[] = {124,0};
rom const char p428[] = {125,0};
rom const char p429[] = {126,0};
rom const char p430[] = {127,0};
rom const char p431[] = {128,0};
// end of XG Voice list
// Ensure that this is defined again if you shorten/lengthen the table.
#define VOICE_TABLE_END 432
I‘ve included suggested source-code to access the table and output the contents to the DB50/60XG, plus routines to set the Yamaha unit into ‘XG’ mode, etc.
///////////////////////////////////////////////
//
// Routines and code suggestions.
//
///////////////////////////////////////////////
// I've shown following variables as globals
rom const char *patchvals; // pointer to hold current voice
int patch; // offset into Voice table above
// send voicing to synth, using current channel
void SetPatch(void)
{
// Note: TxMIDI sends a byte to the MIDI OUT port
TxMIDI(0xb0 + midi_channel); // send status byte
TxMIDI(0); // CTRL number = 0
TxMIDI(0); // Bank sel MSB = 0 for 'normal' voices
TxMIDI(0xb0 + midi_channel); // send status byte
TxMIDI(0x20); // CTRL number = 32
TxMIDI(patchvals[1]); // Bank sel from table
// Now need a Program change msg for this to take effect
TxMIDI(0xc0 + midi_channel); // send status byte
TxMIDI(patchvals[0]); // program num from table
}
// put my synth in XG mode
void SetXGModeOn(void)
{
TxMIDI( 0xf0);
TxMIDI( 0x43);
TxMIDI( 0x10);
TxMIDI( 0x4c);
TxMIDI( 0x00);
TxMIDI( 0x00);
TxMIDI( 0x7e);
TxMIDI( 0x00);
TxMIDI( 0xf7);
}
// an example Program Change routine
void ProgramChange(void) // NOTE Also assigns new channel
{
char program;
// get channel from user interface
IndicateDigitRequired();
KeyScan();
InterpretKeyPress();
midi_channel = keyvalue;
if (GetNumber(&program)) // get program number from user interface
{
TxMIDI(0xc0 + midi_channel); // send status byte
TxMIDI(program);
}
}
// selecting a DB50XG patch
// as part of your routine insert similar to below:
if (GetInt(&patch)) // get integer from user interface
{
if (patch < VOICE_TABLE_END) // ensure no jumps into LaLa-Land to get program/bank value!
{
patchvals = p0 + (patch << 1); // add offset to table base p0. (table is 2 bytes wide)
// send bank command
SetPatch();
}
}
// also an example of moving up or down in a selected patch range
// IMPORTANT! ensure patchvals is a valid pointer and also check range for begin and end of table
case 9 : // (my code uses up-arrow and down-arrow on a hexpad)
// increment XG patch
patchvals++;
patchvals++;
SetPatch();
break;
case 6:
// decrement XG patch
patchvals--;
patchvals--;
SetPatch();
break;
// end
Download: DB50XG.c source-code snapshot.



Link to this page