chakokuのブログ(rev4)

日々のごった煮ブログです

LPC810でMIDI音源を操作してみる

自宅にはYAHAMAのエレクトーン(EL-100)がありまして、このエレクトーンにはMIDI入出力があります。LPC810にはSerialがあるので、MIDI-IFの回路をくっつけてMIDI音源の制御をやってみました。やっつけ仕事ですが、昔PSoC用に試作したソースをLPC810に書き換えてパーカッションが鳴るのを確認しました(ご参考にソースを添付します。デバッグとか検証はまだ。引用元のソースは数年前に作ったソースですが、なぜCH:9を指定しているのか失念。。)。EL-100は初期状態ではエレクトーン用のチャンネル設定らしいのですが、MIDI経由でコマンドを送ることによりXGモードに切り替わり、XGモードのMIDI音源として動作します。ソース中、 関数:switch_to_XG()がモード切替え、関数:midi_sound_out()がMIDIデータ出力です。ついでにLEDをチカチカさせています。
まとめますと、、単に音を出すだけならこれぐらいのコードでMIDI音源の制御が可能なのでございます(シリアル入出力の制御はNXPが提供するライブラリを使用)。音楽を再生するにはタイマーで正確に演奏時間を管理しながらMIDI信号を出力するように実装する必要があるとは思いますが。。



#include "LPC8xx.h"
#include "lpc8xx_clkconfig.h"
#include "lpc8xx_uart.h"
#include "lpc8xx_gpio.h"
#include "lpc8xx_mrt.h"

extern uint32_t mrt_counter;
volatile uint32_t UARTLoopbackCount = 0;

extern volatile uint32_t UARTRxCount;
extern volatile uint32_t RxErrorCount;
extern volatile uint8_t UARTRxBuffer[BUFSIZE];

#define MIDI_BAUD 31250
#define PORT0_0 0
#define PORT_DIR_OUT 1
#define PORT_H 1
#define PORT_L 0

#define XG_MODE_SIZE 9
static uint8_t xg_mode[XG_MODE_SIZE] = {0xF0,0x43,0x10,0x4C,0x00,0x00,0x7E,0x00,0xF7};

#define MIDI_TAM_SIZE 3
static uint8_t midi_tam[MIDI_TAM_SIZE] = {0x99,47,60}; // why ch9??

void midi_sound_out(void);
void switch_to_XG(void);

/*****************************************************************************
** Function name: Main
**
** Descriptions: Main entry
** parameters: None
** Returned value: int
**
*****************************************************************************/
int main (void)
{ /* Main Program */

extern uint32_t mrt_counter;
uint32_t regVal;


SystemCoreClockUpdate();

/* Set port p0.0 to output */
GPIOSetDir( 0, PORT0_0, PORT_DIR_OUT );
init_mrt(0x8000);

/*
* Initialize UARTx pin connect
*/
/* connect the UART0 TXD sigals to port pins(P0.4)*/
regVal = LPC_SWM->PINASSIGN0 & ~( 0xFF << 0 );
LPC_SWM->PINASSIGN0 = regVal | ( 4 << 0 ); /* P0.4 is UART0 TXD, ASSIGN0(7:0) */
UARTInit(LPC_USART0, MIDI_BAUD); /*set BaudRate*/

/* Initialize Sound Generator (switch to XG Mode)*/
switch_to_XG();

while ( 1 ){

/* I/O configuration and LED setting pending. */
if (mrt_counter == 0){

GPIOSetBitValue( 0, PORT0_0, PORT_H ); // LED on
midi_sound_out();

}else if(mrt_counter == 20){

GPIOSetBitValue( 0, PORT0_0, PORT_L ); // LED off

}else if(mrt_counter == 160){

mrt_counter = 0;

}
}
}
void midi_sound_out(void)
{
extern uint8_t midi_tam[];
UARTSend(LPC_USART0, midi_tam , MIDI_TAM_SIZE);
}

void switch_to_XG(void)
{
extern uint8_t xg_mode[];
UARTSend(LPC_USART0, xg_mode , XG_MODE_SIZE);
}