MIDI(ボタン操作!Pygame)program_change | ..あちゃ! no mic's

..あちゃ! no mic's

クラウドファンディング予定~2026年度
何度でもチャレンジ!
ただいまソーラーピックアップのテスト中

SANTA no Mix

Gertduinoシリアル通信でMIDI。
Python(PyserialとPygame)使用。
Tkinterでボタンを表示。
操作が出来るようにした。

Arduino側テストプログラム
/*
  This file is public domain. Use it as you like.
*/

#include <ardumidi.h>

int ledPin = 13;
int note_on = 0;

void setup()
{
  Serial.begin(38400);
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  
  if (!note_on)
  {
	// play a Cminor chord on channel 0, at maximum volume (127)
    midi_note_on(0, MIDI_C, 127);
    midi_note_on(0, MIDI_E + MIDI_FLAT + MIDI_OCTAVE, 127);
    midi_note_on(0, MIDI_G + MIDI_OCTAVE, 127);
    delay(1000);
    midi_note_on(0,44,127);
    delay(1000);
    midi_note_on(0,46,127);
    delay(1000);
	// The MIDI_* macros were created to make your life easier, but you
	// don't have to use them. You may enter numbers instead if you know
	// what you're doing.

    note_on = 1;
    digitalWrite(ledPin, HIGH);
  }

  else
  {
	// stop the Cminor chord
    midi_note_off(0, MIDI_C, 127);
    midi_note_off(0, MIDI_E + MIDI_FLAT + MIDI_OCTAVE, 127);
    midi_note_off(0, MIDI_G + MIDI_OCTAVE, 127);
    delay(1000);
    midi_note_off(0,44,127);
    delay(1000);
    midi_note_off(0,46,127);
    delay(1000);


    note_on = 0;
    digitalWrite(ledPin, LOW);
  }
  
  delay(500);
}

// Available commands:
//
// Start/stop playing a certain note:
//   midi_note_on(byte channel, byte key, byte velocity);
//   midi_note_off(byte channel, byte key, byte velocity);
//
// Change pressure of specific keys:
//   midi_key_pressure(byte channel, byte key, byte value);
//
// Change controller value (used for knobs, etc):
//   midi_controller_change(byte channel, byte controller, byte value);
//
// Change "program" (change the instrument):
//   midi_program_change(byte channel, byte program);
//
// Change key pressure of entire channels:
//   midi_channel_pressure(byte channel, byte value);
//
// Change pitch-bend wheel:
//   midi_pitch_bend(byte channel, int value);
//
// Send a comment:
//   midi_comment(char* str);
//
// Send a series of bytes (to be interpreted by another program):
//   midi_printbytes(char* bytes, int len);
//
// Parameters:
//   channel             an integer from 0 to 15
//   pitch-bend value    an integer from 0 to 16383
//   all other values    an integer from 0 to 127
//





RaspberryPi側プログラム
#!/usr/bin/env python
#coding: utf8
from Tkinter import *
import pygame
import pygame.midi
from time import sleep
import serial

def change():
	global out
	out = out + 1

inst = 0
note = 0
out = 71
velocity = 0

def midi_load():
	pygame.init()
	pygame.midi.init()
	port = 2
	ser = serial.Serial('/dev/ttyAMA0', baudrate=38400)
	global midiOutput
	global out
	midiOutput = pygame.midi.Output(port, 0)
	midiOutput.set_instrument(inst)

	TIME = 0
	while TIME in range(25):
	  TIME = TIME + 1
	  message = [0, 0, 0]
	  i = 0
	  while i < 3:
	    data = ord(ser.read(1))
	    if data >> 7 != 0:  
	      i = 0      
	    message[i] = data
	    i += 1
	    if i == 2 and message[0] >> 4 == 12:
	      message[2] = 0
	      i = 3

	  messagetype = message[0] >> 4
	  messagechannel = (message[0] & 15) + 1
	  note = message[1] if len(message) > 1 else None
	  velocity = message[2] if len(message) > 2 else None

	  midiOutput.write_short(0xc0,out)
	  if messagetype == 9:    # Note on
	#		 pygame.midi.Output(port,0).note_on(note, velocity)
			 midiOutput.note_on(note, velocity)
	#		 sleep(.25)
	  elif messagetype == 8:  # Note off
	#		 pygame.midi.Output(port,0).note_off(note, velocity)
			midiOutput.note_off(note, velocity)         
	  elif messagetype == 12: # Program change
	 	 out = out + 1
	 	 gert = C1(0xc0,out)
	 	 gert.Program_change()
  
	del midiOutput
	pygame.midi.quit()

root = Tk()

button1=Button(root,text='START',bd='4',bg='dimgray',fg='white',command=midi_load)
button1.grid(column=1,row=0)

button2=Button(root,text='CHANGE',bd='4',bg='dimgray',fg='white',command=change)
button2.grid(column=2,row=0)
root.mainloop()