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

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

新曲は2番までできています

今回は私の曲では初となるマイナーキーの曲です。部分的にマイナーなのはありますが、全体を通してマイナーというのは多分今まで一度も作ったことが無いはずです。今まで35(+α)曲作っていたが、ずっとメジャーキーでした。なので明るい曲が多かったです。個人的には去年の曲の印象が強く、特に元気のでるような雰囲気が多かったかなぁと。ただ、今回はマイナーキーで暗い感じです。同じコードがひたすら続いたり中二感の強いバッキングが特徴となっているかと。曲が暗めの雰囲気でボカロはどうしようか悩んでいましたが、これらの発言によりIAに決定しました

新曲『黄色いハンカチ』

第3回Ranaコンピ Ranairo Raibow Octet 収録曲(トラック03)
はい、ボーマスやコミケでもしかしたら頒布されるかもしれない
アルバムRanairo Raibow Octetの中の1曲を担当させていただきました。
アルバム全体のテーマが虹色で、それぞれの曲が7色のどれかの色をテーマとしています。最後に全体をテーマとした1曲もあり、全8曲という構成です。

とりあえず黄色をテーマとした自分の曲を貼っておきます

 

www.nicovideo.jp

なんとなくkotlinで書き直してみる

まだよくわかってないけどkotlinしてみる

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

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

import javafx.event.ActionEvent
import javafx.event.EventHandler

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

fun main(args: Array<String>){
    Application.launch(DrumTest::class.java, *args)
}

class DrumTest() : Application(){
    private val receiver: Receiver
    
    private val pattern = "B-S-BBS-"
    private var patternIndex = 0
    
    init{
        receiver = MidiSystem.getReceiver()
    }
    
    override fun start(stage: Stage){
        val button = createDrumButton("8ビート!")
        val pane = BorderPane()
        
        pane.setCenter(button)
        
        val scene = Scene(pane, 320.0, 120.0)
        
        stage.setScene(scene)
        stage.show()
    }
    
    private fun createDrumButton(text: String): Button{
        val button = Button(text)
        
        val timer = Timeline(KeyFrame(Duration.millis(250.0), object : EventHandler<ActionEvent>{
            override fun handle(event: ActionEvent?){
                try{
                    if(pattern[patternIndex] == 'B'){
                        noteBassDrum();
                    }else if(pattern[patternIndex] == 'S'){
                        noteSnareDrum();
                    }
                }catch(ex: InvalidMidiDataException){
                    ex.printStackTrace();
                }

                patternIndex = (patternIndex + 1) % 8;
            }
        }))
        
        button.setOnAction({ _ ->
            if(timer.getStatus() == Animation.Status.STOPPED){
                timer.setCycleCount(16);
                timer.play();
            }
        })
        
        return button
    }
    
    private fun noteBassDrum(){
        val message = ShortMessage()
        message.setMessage(ShortMessage.NOTE_ON, 9, 36, 100)
        receiver.send(message, -1)
    }
    
    private fun noteSnareDrum(){
        val message = ShortMessage()
        message.setMessage(ShortMessage.NOTE_ON, 9, 38, 100)
        receiver.send(message, -1)
    }
}

参考
qiita.com

なんとなくバスドラムとスネアドラムで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);
    }
}

なんとなく定期的にバスドラムを鳴らしてみる

JavaFXのタイマ使って8回バスドラムを鳴らしてみます。
参考↓
JavaFX 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.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;

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

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

        Button button = createDrumButton("ドラム!");
        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);
        
        button.setOnAction( e -> {
            Timeline timer = new Timeline(new KeyFrame(Duration.millis(250), event -> {
                try{
                    ShortMessage message = new ShortMessage();
                    message.setMessage(ShortMessage.NOTE_ON, 9, 36, 100);
                    receiver.send(message, -1);
                }catch(InvalidMidiDataException ex){
                    ex.printStackTrace();
                }
            }));

            timer.setCycleCount(8);
            timer.play();
        });

        return button;
    }
}