マイペースなプログラミング日記

x86エミュレータやFPGA、WebGLにお熱なd-kamiがマイペースに書くブログ

なんとなくバスドラムとスネアドラムで8ビート

ボタンを押すたびによくあるドラムの8ビートパターンを鳴らすようにしてみました。今回はボタンを押すたびにタイマを毎回生成しない仕様。しかもちゃんとタイマの状態をチェックしているので途中でパターンがおかしくなることもないと思われる

import javafx.stage.Stage;
import javafx.application.Application;

import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.animation.Animation;

import javafx.util.Duration;

import javax.sound.midi.Receiver;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.ShortMessage;

import javax.sound.midi.InvalidMidiDataException;
 
public class DrumTest extends Application {
    private Receiver receiver;
    private Timeline timer;
    
    private String pattern = "B-S-BBS-";
    private int patternIndex = 0;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        receiver = MidiSystem.getReceiver();

        Button button = createDrumButton("8ビート!");
        BorderPane pane = new BorderPane();
        pane.setCenter(button);
        Scene scene = new Scene(pane, 320, 120);
        stage.setScene(scene);
        stage.show();
    }
    
    private Button createDrumButton(String text){
        Button button = new Button(text);
        
        timer = new Timeline(new KeyFrame(Duration.millis(250), event -> {
            try{
                if(pattern.charAt(patternIndex) == 'B'){
                    noteBassDrum();
                }else if(pattern.charAt(patternIndex) == 'S'){
                    noteSnareDrum();
                }
            }catch(InvalidMidiDataException ex){
                ex.printStackTrace();
            }
            
            patternIndex = (patternIndex + 1) % 8;
        }));
        
        button.setOnAction( e -> {
            if(timer.getStatus() == Animation.Status.STOPPED){
                timer.setCycleCount(16);
                timer.play();
            }
        });

        return button;
    }
    
    private void noteBassDrum() throws InvalidMidiDataException{
        ShortMessage message = new ShortMessage();
        message.setMessage(ShortMessage.NOTE_ON, 9, 36, 100);
        receiver.send(message, -1);
    }
    
    private void noteSnareDrum() throws InvalidMidiDataException{
        ShortMessage message = new ShortMessage();
        message.setMessage(ShortMessage.NOTE_ON, 9, 38, 100);
        receiver.send(message, -1);
    }
}