Print This Post Print This Post

DB50XG Voice Selection Table and Routines in ‘C’

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.

Copy the code below to your web site.
x 
  • Share/Bookmark
PDF Printer    Send article as PDF   

You must be logged in to post a comment.