1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

USB-MIDIキーボードでpyxelの音を鳴らしてみるテスト その1

Last updated at Posted at 2025-05-19

問題点

☑️同時に鳴らせる音を3つにしたかったけど方法がわからず
☑️鍵盤を離すと音が途切れるようにしてあるので、前の鍵盤を離してから次の鍵盤を押さないと、次の鍵盤の音が途切れてしまう

pyxelをシーケンサーにしたい💫

import pyxel
import mido
import time

# Pyxel の初期化
pyxel.init(256, 64, fps=30)
pyxel.NUM_SOUNDS = 3  # 同時発音数を 3 に制限

# MIDI ノート番号から Pyxel のノート文字列を生成する関数
def midi_to_pyxel_note(midi_note):
    note_names = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
    # MIDI ノート 36 (C2) を Pyxel の C0 に対応させる (調整が必要かもしれません)
    base_midi_note = 36
    if midi_note < base_midi_note:
        return "C0"  # 下限
    octave = (midi_note - base_midi_note) // 12
    note_index = (midi_note - base_midi_note) % 12
    if octave > 7:
        return "B7"  # 上限
    return f"{note_names[note_index]}{octave}"

# Pyxel のサウンドバンクに初期設定 (矩形波、固定スピード)
fixed_speed = 22050 // 10  # 適当な固定値
initial_notes = "A3"
initial_tones = "0"
initial_effects = "n"
initial_volume = "7"
for i in range(pyxel.NUM_SOUNDS):
    pyxel.sounds[i].set(notes=initial_notes, tones=initial_tones, volumes=initial_volume, effects=initial_effects, speed=fixed_speed)

class App:
    def __init__(self):
        self.inport = None
        self.playing_notes = {}  # 再生中の MIDI ノートと Pyxel サウンド ID の対応
        try:
            self.inport = mido.open_input('MPK mini 3')
            pyxel.run(self.update, self.draw)
        except OSError as e:
            print(f"MIDI デバイスが見つかりません: {e}")
        except Exception as e:
            print(f"エラーが発生しました: {e}")
        finally:
            if self.inport:
                self.inport.close()

    def update(self):
        if self.inport:
            received_message = self.inport.poll()
            if received_message:
                print(f"poll() の戻り値の値: {received_message}") # デバッグ用
                if received_message.type == 'note_on':
                    if received_message.velocity > 0:
                        midi_note = received_message.note
                        if midi_note not in self.playing_notes:
                            # 空いているサウンド ID を探す
                            available_sound_id = -1
                            for i in range(pyxel.NUM_SOUNDS):
                                if i not in self.playing_notes.values():
                                    available_sound_id = i
                                    break
                            if available_sound_id != -1:
                                pyxel_note = midi_to_pyxel_note(midi_note)
                                try:
                                    pyxel.sounds[available_sound_id].set(notes=pyxel_note, tones=initial_tones, volumes=initial_volume, effects=initial_effects, speed=fixed_speed)
                                    pyxel.play(0, available_sound_id)
                                    self.playing_notes[midi_note] = available_sound_id
                                except ValueError as e:
                                    print(f"ValueError during sound set: {e}, pyxel_note: {pyxel_note}, midi_note: {midi_note}")
                                except Exception as e:
                                    print(f"Unexpected error during sound set/play: {e}")
                elif received_message.type == 'note_off':
                    midi_note = received_message.note
                    print(f"Note Off received for note: {midi_note}") # デバッグ用
                    if midi_note in self.playing_notes:
                        del self.playing_notes[midi_note]
                        # キーを離したらチャンネル 0 の再生を停止する
                        pyxel.stop(0)

    def draw(self):
        pyxel.cls(0)
        pyxel.text(10, 10, "Playing MIDI Chords (Up to {} notes)".format(pyxel.NUM_SOUNDS), 7)

if __name__ == "__main__":
    App()
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?