自作楽器用音源モジュール作成(7)

f:id:tohkaf:20151215004649j:plain

www.youtube.com


今回はUARTを受信してスルーする部分と、内容を読み取ってLCDに表示する(今回はNoteOn,NoteOffのみ)を実装した。

LCDのカスタムフォントでバーグラフが表示できるのでNoteの3Byte目を読み取って表示するようにしてみた。

#include <project.h>

#define MIDI_DATA_SIZE  8

int main()
{
    uint8_t i,data;
    uint8_t midiDataPtrOld = 0x0;
    uint8_t midiDataPtr = 0x0;
    uint8_t midiDataFrom = 0x0;
    uint8_t midiData[MIDI_DATA_SIZE];

    
    CyDelay(1000);
    
    UART_VS1053b_Start();
    UART_1_Start();
    UART_2_Start();

    LCD_Char_1_Start();

    CyGlobalIntEnable; 
    
    while(1)
    {
        data = (uint8_t)UART_1_UartGetChar();
        if(data != 0){
            if(data & 0x80){
                midiDataPtr = 0x0;
                midiDataFrom = 0x1;
            }
            if(midiDataPtr < MIDI_DATA_SIZE) midiData[midiDataPtr++] = data;   
        } 
        data = (uint8_t)UART_2_UartGetChar();
        if(data != 0){
            if(data & 0x80){
                midiDataPtr = 0x0;
                midiDataFrom = 0x2;
            }
            if(midiDataPtr < MIDI_DATA_SIZE) midiData[midiDataPtr++] = data;
        }
        
        if(midiDataPtrOld != midiDataPtr){
            midiDataPtrOld = midiDataPtr;
            if(midiDataPtr == 3 && (midiData[0] & 0x90 || midiData[0] & 0x80)) {
                UART_VS1053b_PutArray(midiData,3);
                midiDataPtr = 0;
                
                LCD_Char_1_WriteControl(LCD_Char_1_CLEAR_DISPLAY);
                LCD_Char_1_Position(0,0);
                LCD_Char_1_PrintString("Note:");
                LCD_Char_1_PrintNumber(midiData[1]);
                LCD_Char_1_PrintString(" ");
                LCD_Char_1_PrintNumber(midiData[2]);
                LCD_Char_1_DrawHorizontalBG(1,0,16,midiData[2]);
            }
        }
    }
}


動作確認のUARTは、PCからC#プログラムでMIDIメッセージを投げつけてFTD2232で送出した。*1

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var uart = new SerialPort("com13", 31250, Parity.None, 8, StopBits.One);
            uart.Open();

            var midiData = new byte[3];
            while (true)
            {
                for (int j = 0; j < 0x7f; ++j)
                {
                    /* Cn:Program Change */
                    midiData[0] = 0xc0;
                    midiData[1] = (byte)j;
                    uart.Write(midiData, 0, 3);

                    for (int i = 0x40; i < 0x50; ++i)
                    {
                        for (int k = 0; k < 0x7f; k += 0x10)
                        {
                            /* 9n:Note On */
                            midiData[0] = 0x90;
                            midiData[1] = (byte)i;
                            midiData[2] = (byte)k;
                            uart.Write(midiData, 0, 3);
                            Console.WriteLine(i);
                            Thread.Sleep(100);
                            /* 8n:Note Off*/
                            midiData[0] = 0x80;
                            midiData[2] = 0x0;
                            uart.Write(midiData, 0, 3);
                        }
                    }
                }
            }
        }
    }
}


残りはメッセージを真面目に読み取ったり、音色変更等を本体から行う機能をつければよし。

*1:もとテスト用のUARTを投げつけるために別のPSoCに書き込みをしようとしたが、逆接してKitProgを破壊してしまったりしていろいろ大変だった。