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

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

適当に作ろう

JavaでもやってるけどCreateWindowな環境でもやってたりします

#include "MidiOut.h"
#include <assert.h>

void MidiOut::open(){
	midiOutOpen(&hMidiOut, MIDI_MAPPER, 0, 0, 0);
}

void MidiOut::noteOn(int32_t channel, int32_t note, int32_t velocity) {
	assert(0 <= velocity && velocity <= 127);
	assert(0 <= channel && channel <= 15);
	assert(0 <= note && note <= 127);

	int32_t outData = NOTE_ON | channel;
	outData |= (note << 8);
	outData |= (velocity << 16);

	midiOutShortMsg(hMidiOut, outData);
}

void MidiOut::noteOff(int32_t channel, int32_t note, int32_t velocity) {
	assert(0 <= velocity && velocity <= 127);
	assert(0 <= channel && channel <= 15);
	assert(0 <= note && note <= 127);

	int32_t outData = NOTE_OFF | channel;
	outData |= (note << 8);
	outData |= (velocity << 16);

	midiOutShortMsg(hMidiOut, outData);
}

void MidiOut::reset() {
	midiOutReset(hMidiOut);
}

void MidiOut::close() {
	midiOutClose(hMidiOut);
}

上達が遅いかもしれないが

上達は遅いかもしれないが少しずつエレキギターは上手くなっている。もっと私に目標や熱意があればもっと早く上達したかもしれないが、元々私がエレキギターに興味を持っていなかったため仕方ないところもある。でも2年以上も続けているし頑張ってはいるよ!ただペースが遅いだけです

とりあえずJavaでMIDI編 その1

現在以下のようなXMLを読み込ませるとピアノがドレミファソラシドと8分で鳴らし、ベースはドを8分で鳴らし続け、ドラムは8ビートの基本的なパターンでバスドラムとスネアのみが鳴る。適当にSMF形式のファイル読み込めるようにして鳴らしてみようかな

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MidiMusic>
    <Tracks>
        <Track number="1" program="0">
            <NoteList>
                <Note pitch="60" position="0" type="144" velocity="100"/>
                <Note pitch="60" position="250" type="128" velocity="100"/>
                
                <Note pitch="62" position="250" type="144" velocity="100"/>
                <Note pitch="62" position="500" type="128" velocity="100"/>
                
                <Note pitch="64" position="500" type="144" velocity="100"/>
                <Note pitch="64" position="750" type="128" velocity="100"/>
                
                <Note pitch="65" position="750" type="144" velocity="100"/>
                <Note pitch="65" position="1000" type="128" velocity="100"/>
                
                <Note pitch="67" position="1000" type="144" velocity="100"/>
                <Note pitch="67" position="1250" type="128" velocity="100"/>
                
                <Note pitch="69" position="1250" type="144" velocity="100"/>
                <Note pitch="69" position="1500" type="128" velocity="100"/>
                
                <Note pitch="71" position="1500" type="144" velocity="100"/>
                <Note pitch="71" position="1750" type="128" velocity="100"/>
                
                <Note pitch="72" position="1750" type="144" velocity="100"/>
                <Note pitch="72" position="2000" type="128" velocity="100"/>
            </NoteList>
        </Track>
    
        <Track number="1" program="34">
            <NoteList>
                <Note pitch="36" position="0" type="144" velocity="100"/>
                <Note pitch="36" position="250" type="128" velocity="100"/>
                
                <Note pitch="36" position="250" type="144" velocity="100"/>
                <Note pitch="36" position="500" type="128" velocity="100"/>
                
                <Note pitch="36" position="500" type="144" velocity="100"/>
                <Note pitch="36" position="750" type="128" velocity="100"/>
                
                <Note pitch="36" position="750" type="144" velocity="100"/>
                <Note pitch="36" position="1000" type="128" velocity="100"/>
                
                <Note pitch="36" position="1000" type="144" velocity="100"/>
                <Note pitch="36" position="1250" type="128" velocity="100"/>
                
                <Note pitch="36" position="1250" type="144" velocity="100"/>
                <Note pitch="36" position="1500" type="128" velocity="100"/>
                
                <Note pitch="36" position="1500" type="144" velocity="100"/>
                <Note pitch="36" position="1750" type="128" velocity="100"/>
                
                <Note pitch="36" position="1750" type="144" velocity="100"/>
                <Note pitch="36" position="2000" type="128" velocity="100"/>
            </NoteList>
        </Track>

        <Track number="9" program="0">
            <NoteList>
                <Note pitch="36" position="0" type="144" velocity="100"/>
                <Note pitch="38" position="500" type="144" velocity="100"/>
                <Note pitch="36" position="1000" type="144" velocity="100"/>
                <Note pitch="36" position="1250" type="144" velocity="100"/>
                <Note pitch="38" position="1500" type="144" velocity="100"/>
            </NoteList>
        </Track>
    </Tracks>
</MidiMusic>

プログラミング教室の講師になります

プログラミング要員の派遣社員として働いてきましたが、プログラミングの出来ないプログラマという存在に危機感を覚え、そんな状況を少しでも改善したいと考え講師に名乗りあげました。というかプログラミング入門書を仕事時間中に読み続け、本を読むために残業までしているプログラマがいたのは衝撃的だった。まぁ、私の教えられる範囲で出し惜しみなく教えたいし、できるだけ基礎力を付けられるように持っていきたい。うまくいくかはわからないけど、今のままではいろいろ危ない気がする業界である。ちなみに所属はSeed Music Schoolという音楽系のスクールですがプログラミング教室では音楽は一切関係ありません。なぜ音楽教室でプログラミングのレッスンがあるのかは…通っている人の中に「プログラミングを学びたい」という人がいたから急遽作ったそうな…そのうち料理教室とか盆栽教室とか始まったりするかもね…怖

Seed Coder’s教室 d-kami – Seed Music School

一人暮らし時代について

はてなブログのお題が目についたので書いておく

私自身それほど一人暮らしに縁があるわけでもないが、筑波大学大学院に行っていたときに一人暮らしを体験した。学生宿舎に1年ほどと大学の敷地の近くにあるアパートを借りて暮らしていた。学生宿舎も大学の敷地内なのだが研究室まで徒歩30分ほどかかっていた。

まぁ、最初のころは近くのコンビニでレトルトカレーとか豆腐を買ってきて、ご飯炊いて食べていた…気がする。一人暮らしに慣れるにつれてだんだん外食に傾いてきて、筑波大学の学生ならわかるであろうRanRanとか夢屋とかそこらへんに行くようになっていた。週3でRanRanに通いBIG丼を食べ続けた結果1年で15kgほど太った。明らかに健康に悪い生活を送ってしまった。研究室にも最初の頃は17:00ぐらいで撤退していたものの、あまりにも過ごしやすかったため気づいたら0:00近くまで研究室にいたりもした。特に作業が押していたわけではないのだが、気づいたら遅くまでいたため、近くのスーパー(徒歩30分ほど)に行っていろいろ買って研究室で食べるなどの生活も増えていった。

まぁ、家に帰っても何も無いので家の部屋より広い研究室の方が居心地がよかったのだろう。何よりも[諸事情により言えない行為]があったため、娯楽が家よりも研究室の方が充実していたのは確かだった。研究室には良い意味で頭のおかしい人が集まっていたため、楽しい話題はたくさんあったので某国立と間違われやすいK大学にいたころよりもずっと楽しかった。

そして今気づいたのだが、一人暮らしというより単なる大学院生活の話になっとるがな!何が言いたいのかよくわからないままこのエントリを書き終えるが、BIG丼は週3で食べる物ではないのは確かだと思った。ましてや、私は大盛を食べていたのだからそりゃ太る…というわけでBIG丼が好きだったというエントリでした

エントリ数を稼ぐためにソースコードを貼り付けるd-kami

まぁ、何か作ってますよ程度のもの。Java FXとJava Sound APIを使って遊んでるだけです

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 java.io.File;
import java.util.List;

import javax.xml.bind.JAXB;

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

import net.d_kami.midi.data.MidiNote;
import net.d_kami.midi.data.MidiTrack;
import net.d_kami.midi.data.MidiMusic;

import javax.sound.midi.InvalidMidiDataException;
 
public class MidiTest extends Application {
    private Receiver receiver;
    private Timeline timer;

    private int timerCount = 0;
    
    private int bassIndex = 0;
    private int drumIndex = 0;

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

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

        music = JAXB.unmarshal(new File("midi.xml"), MidiMusic.class);
        
        Button button = createMidiButton("8ビート!");
        BorderPane pane = new BorderPane();
        pane.setCenter(button);
        Scene scene = new Scene(pane, 320, 120);
        stage.setScene(scene);
        stage.show();
    }
    
    private Button createMidiButton(String text){
        loadProgram();
        setTempo(120);

        return createButton(text);
    }
    
    private Button createButton(String text){
        Button button = new Button(text);
        
        button.setOnAction(e -> {
            if(timer.getStatus() == Animation.Status.STOPPED){
                timer.setCycleCount(160);
                timer.play();
            }
        });
        
        return button;
    }
    
    private void setTempo(int bpm){
        int duration = 60000 / bpm * 4 / 128;
        
        setTimer(duration);
    }
    
    private void setTimer(int duration){
        List<MidiTrack> tracks = music.getTracks();
        int[] indices = new int[tracks.size()];
        
        timer = new Timeline(new KeyFrame(Duration.millis(duration), event -> {
            try{
                for(int i = 0; i < tracks.size(); i++){
                    MidiTrack track = tracks.get(i);
                    midiEvent(track, duration, indices, i);
                }
            }catch(InvalidMidiDataException ex){
                ex.printStackTrace();
            }
            
            timerCount++;
        }));
    }
    
    private void loadProgram(){
        music.getTracks().forEach(track -> {
            try{
                programChange(track.getNumber(), track.getProgram());
            }catch(InvalidMidiDataException e){
                e.printStackTrace();
            }
        });
    }
    
    private void programChange(int trackNumber, int program) throws InvalidMidiDataException{
        ShortMessage message = new ShortMessage();
        message.setMessage(ShortMessage.PROGRAM_CHANGE, trackNumber, program, 0);
        receiver.send(message, -1);
    }
    
    private void midiEvent(MidiTrack track, int duration, int[] indices, int i) throws InvalidMidiDataException{
        List<MidiNote> notes = track.getNotes();
        
        if(indices[i] < notes.size()){
            MidiNote note = notes.get(indices[i]);
            
            if(duration * timerCount > note.getPosition()){
                note(track.getNumber(), note.getType(), note.getNote(), note.getVelocity());
                indices[i]++;
            }
        }
    }
    
    private void note(int trackNumber, int type, int note, int velocity) throws InvalidMidiDataException{
        ShortMessage message = new ShortMessage();
        message.setMessage(type, trackNumber, note, velocity);
        receiver.send(message, -1);
    }
}

何となくMIDI

なんかいろいろおかしくなってるので要素名を修正するつもりだがJAXBで出力したXML。これを読み込んでJavaで鳴らしている。現在ベースとドラムが鳴っている模様

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MidiMusic>
    <Tracks>
        <Track number="0" program="34">
            <NoteList>
                <Note Note="34" Position="0" Type="144" Velocity="100"/>
                <Note Note="34" Position="250" Type="128" Velocity="100"/>
                
                <Note Note="34" Position="250" Type="144" Velocity="100"/>
                <Note Note="34" Position="500" Type="128" Velocity="100"/>
                
                <Note Note="34" Position="500" Type="144" Velocity="100"/>
                <Note Note="34" Position="750" Type="128" Velocity="100"/>
                
                <Note Note="34" Position="750" Type="144" Velocity="100"/>
                <Note Note="34" Position="1000" Type="128" Velocity="100"/>
                
                <Note Note="34" Position="1000" Type="144" Velocity="100"/>
                <Note Note="34" Position="1250" Type="128" Velocity="100"/>
                
                <Note Note="34" Position="1250" Type="144" Velocity="100"/>
                <Note Note="34" Position="1500" Type="128" Velocity="100"/>
                
                <Note Note="34" Position="1500" Type="144" Velocity="100"/>
                <Note Note="34" Position="1750" Type="128" Velocity="100"/>
                
                <Note Note="34" Position="1750" Type="144" Velocity="100"/>
                <Note Note="34" Position="2000" Type="128" Velocity="100"/>
            </NoteList>
        </Track>
        <Track number="9" program="0">
            <NoteList>
                <Note Note="36" Position="0" Type="144" Velocity="100"/>
                <Note Note="38" Position="500" Type="144" Velocity="100"/>
                <Note Note="36" Position="1000" Type="144" Velocity="100"/>
                <Note Note="36" Position="1250" Type="144" Velocity="100"/>
                <Note Note="38" Position="1500" Type="144" Velocity="100"/>
            </NoteList>
        </Track>
    </Tracks>
</MidiMusic>