How to play MIDI files using the Java Sound API (specify the MIDI device to use)

Introduction

This is a continuation of the previous article (https://qiita.com/absol_abcX/items/e9c230b808e522154ae5).

Overview

Implement the MIDI synthesizer selection function to be used in the previous MIDI file playback sample. Below is the actual execution screen.

[0] Gervill
[1] LoopBe Internal MIDI
[2] Microsoft MIDI Mapper
[3] CoolSoft MIDIMapper
[4] Microsoft GS Wavetable Synth
[5] VirtualMIDISynth #1
[6] LoopBe Internal MIDI
[7] Real Time Sequencer

Enter the number of the MIDI device to use>> 4
[Microsoft GS Wavetable Synth]Is open...

MIDI file path>> sample.mid
Playing...
Enter an appropriate character string to finish.
>>a
Stop

By the way, The 0th device called "Gervill" is a MIDI synthesizer provided by the Java library. By default, this device is specified.

The "Microsoft GS Wavetable Synth" used this time is a synthesizer that comes standard with Windows.

Sample code

SamplePlayer.java


import java.io.File;
import java.io.IOException;
import java.util.Scanner;

import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;

public class SamplePlayer {

    public static void main(String[] args) {
        //Hardware to play MIDI data/An instance of a software device.
        Sequencer sequencer = null;

        Scanner scanner = new Scanner(System.in);

        try {
            //Get a Sequencer instance.
            sequencer = MidiSystem.getSequencer(false);

            //Open the device and acquire resources.
            sequencer.open();

            //Get a list of available MIDI devices.
    		MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
    		for (int i=0; i<infos.length; i++) {
    			String line = String.format("[%s] %s", i, infos[i].getName());
    			System.out.println(line);
    		}
    		System.out.println();

    		int index = 0;
    		while (true) {
    			//Get the index of the MIDI device to use from the console input.
	    		System.out.print("Enter the number of the MIDI device to use>> ");
	    		String str = scanner.next();

	    		try {
	    			index = Integer.parseInt(str);
	    		}
	    		catch (NumberFormatException nfe) {
	    			continue;
	    		}
	    		break;
	    	}

    		//Request a MIDI device with device information that represents the device of interest to the system.
    		MidiDevice device = MidiSystem.getMidiDevice(infos[index]);

    		System.out.println("[" + device.getDeviceInfo().getName() + "]Is open...");

    		//Open a MIDI device.
    		if (device.isOpen() == false) {
    			device.open();
    		}

    		//Connect the MIDI OUT of the sequencer to the MIDI IN of the MIDI device.
			Receiver receiver = device.getReceiver();
			sequencer.getTransmitter().setReceiver(receiver);
        }
        catch (MidiUnavailableException e) {
            e.printStackTrace();
        }
        System.out.println();

        //Get the MIDI file path from the console input.
        System.out.print("MIDI file path>> ");
        String path = scanner.next();

        try {
            //MIDI data from MIDI files(Sequence object)Get.
            File file = new File(path);
            Sequence sequence = MidiSystem.getSequence(file);

            //Set the acquired MIDI data in the sequencer.
            sequencer.setSequence(sequence);
        }
        catch (InvalidMidiDataException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        //Sequencer playback
        sequencer.start();
        System.out.println("Playing...");

        //Waiting for key input
        System.out.println("Enter an appropriate character string to finish.");
        System.out.print(">>");
        scanner.next();
        scanner.close();

        //Sequencer stop
        sequencer.stop();
        System.out.println("Stop");

        //Close the sequencer and release the resources you were using.
        sequencer.close();
    }
}

Commentary

Get a list of available device information

Gets an object array of all available MIDI device information.

//Get a list of available MIDI devices.
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();

Get device object

You can get the corresponding device by calling getMidiDevice using the obtained device information object. You can operate it by calling open on the acquired device.

//Request a MIDI device with device information that represents the device of interest to the system.
MidiDevice device = MidiSystem.getMidiDevice(infos[index]);

//Open a MIDI device.
if (device.isOpen() == false) {
   device.open();
}

Connect the sequencer and device

There are two interfaces provided by the MIDI device class:

Interface name Overview Commonly used
Transmitter Send MIDI data. Sequencer, MIDI input device, etc.
Receiver Receive MIDI data. Synthesizer / MIDI output device

This time, connect the MIDI receiver port (Receiver) of the specified MIDI device to the MIDI transmit port (Transmitter) of the sequencer.

//Connect the MIDI OUT of the sequencer to the MIDI IN of the MIDI device.
Receiver receiver = device.getReceiver();
sequencer.getTransmitter().setReceiver(receiver);

Then, the configuration image will look like this. Device configuration.png

This completes the device connection.

Recommended Posts

How to play MIDI files using the Java Sound API (specify the MIDI device to use)
How to play MIDI files using the Java Sound API
[Java] How to use the hasNext function
[Java] How to use the HashMap class
[Java] How to use the toString () method
Studying how to use the constructor (java)
[Processing × Java] How to use the loop
[Processing × Java] How to use the class
[Processing × Java] How to use the function
[Java] How to use the Calendar class
[Java] How to use Thread.sleep to pause the program
How to use Java API with lambda expression
How to use the replace () method (Java Silver)
[Java] How to operate List using Stream API
Summary of Java communication API (1) How to use Socket
Summary of Java communication API (3) How to use SocketChannel
How to use Play Framework without using typesafe activator
Summary of Java communication API (2) How to use HttpUrlConnection
[Java] How to use Map
How to use Chain API
[Java] How to use Map
How to use java Optional
How to use java class
[Java] How to use Optional ②
[Java] How to use removeAll ()
[Java] How to use string.format
How to use Java Map
How to use Java variables
[Java] How to use Optional ①
How to use Maven to place resource files outside the JAR
[Must-see for apprentice java engineer] How to use Stream API
I want to use the Java 8 DateTime API slowly (now)
How to call and use API in Java (Spring Boot)
How to use Java HttpClient (Get)
How to use the form_with method
[java8] To understand the Stream API
How to disassemble Java class files
How to use Java HttpClient (Post)
[Java] How to use join method
How to use the wrapper class
[Processing × Java] How to use variables
How to decompile java class files
[Java] How to use LinkedHashMap class
[JavaFX] [Java8] How to use GridPane
How to use class methods [Java]
[Java] How to use List [ArrayList]
How to use classes in Java?
[Processing × Java] How to use arrays
How to use Java lambda expressions
[Java] How to use Math class
How to use Java enum type
Use Docker and Keycloak to specify the access token and execute the API
To use the "java" command line tool ... How to avoid popping up
How to solve the unknown error when using slf4j in Java
The operator that was born to be born, instanceof (Java) ~ How to use the instanceof operator ~
Multilingual Locale in Java How to use Locale
How to use binding.pry for view files
How to use BootStrap with Play Framework
Try using the Stream API in Java
How to use submit method (Java Silver)
[Java] How to calculate age using LocalDate