# **Java `javax.sound.midi` 쉽게 배우기** ## **1. `javax.sound.midi`란?** `javax.sound.midi` 패키지는 **자바에서 MIDI(악기 디지털 인터페이스) 데이터를 다루는 기능**을 제공한다. 이를 이용하면 **MIDI 파일을 재생, 편집, 녹음, 생성**할 수 있다. **주요 기능** ✔ **MIDI 파일 재생** (악기 소리 출력) ✔ **MIDI 이벤트 생성 및 수정** (노트 추가/삭제) ✔ **실시간 MIDI 입력/출력** (MIDI 키보드 연결 가능) --- ## **2. 주요 클래스 및 메서드 정리** ### **(1) `MidiSystem` 클래스 (MIDI 시스템 제어)** | 메서드 | 설명 | |--------|------------------------------| | `getSequencer()` | MIDI 파일을 재생하는 `Sequencer` 객체 반환 | | `getSynthesizer()` | 소프트웨어 신시사이저(`Synthesizer`) 반환 | | `getReceiver()` | MIDI 데이터를 출력할 `Receiver` 반환 | | `getTransmitter()` | MIDI 데이터를 입력받을 `Transmitter` 반환 | --- ### **(2) `Sequencer` 클래스 (MIDI 재생기)** | 메서드 | 설명 | |--------|------------------------------| | `open()` | `Sequencer`를 초기화하고 사용 준비 | | `setSequence(Sequence sequence)` | 재생할 MIDI 시퀀스 설정 | | `start()` | MIDI 재생 시작 | | `stop()` | MIDI 재생 중지 | | `setLoopCount(int count)` | MIDI 반복 재생 설정 | --- ### **(3) `Synthesizer` 클래스 (신시사이저 - 소리 생성)** | 메서드 | 설명 | |--------|------------------------------| | `open()` | 신시사이저를 활성화 | | `getChannels()` | MIDI 채널(`MidiChannel[]`) 가져오기 | | `getReceiver()` | 신시사이저에 MIDI 메시지를 보내는 `Receiver` 반환 | --- ### **(4) `MidiChannel` 클래스 (MIDI 음원 채널)** | 메서드 | 설명 | |--------|------------------------------| | `noteOn(int note, int velocity)` | 특정 음을 연주 (노트 켜기) | | `noteOff(int note)` | 특정 음을 멈춤 (노트 끄기) | | `setInstrument(Instrument instrument)` | 채널의 악기 변경 | --- ### **(5) `Sequence` 클래스 (MIDI 데이터 관리)** | 메서드 | 설명 | |--------|------------------------------| | `createTrack()` | 새로운 `Track`(MIDI 트랙) 생성 | | `getTracks()` | 시퀀스에 포함된 `Track` 목록 가져오기 | --- ### **(6) `Track` 클래스 (MIDI 트랙)** | 메서드 | 설명 | |--------|------------------------------| | `add(MidiEvent event)` | MIDI 이벤트 추가 | | `remove(MidiEvent event)` | MIDI 이벤트 제거 | --- ### **(7) `MidiEvent` 클래스 (MIDI 이벤트)** | 메서드 | 설명 | |--------|------------------------------| | `new MidiEvent(MidiMessage message, long tick)` | 특정 시간(tick)에 MIDI 메시지 추가 | --- ## **3. MIDI 파일 재생 예제** ### **✔ MIDI 파일을 재생하는 코드 (`Sequencer` 사용)** ```java import javax.sound.midi.*; import java.io.File; public class MidiPlayer { public static void main(String[] args) { try { // MIDI 파일 로드 File midiFile = new File("song.mid"); Sequence sequence = MidiSystem.getSequence(midiFile); // Sequencer 생성 및 열기 Sequencer sequencer = MidiSystem.getSequencer(); sequencer.open(); sequencer.setSequence(sequence); // 재생 시작 sequencer.start(); System.out.println("MIDI 재생 시작!"); // 재생이 끝날 때까지 대기 while (sequencer.isRunning()) { Thread.sleep(1000); } // 종료 처리 sequencer.close(); System.out.println("MIDI 재생 완료!"); } catch (Exception e) { e.printStackTrace(); } } } ``` ✅ **MIDI 파일을 불러와 재생하는 코드이다.** ✅ **`Sequencer`를 사용하여 MIDI를 관리하고 재생한다.** --- ## **4. 실시간으로 MIDI 연주하기** ### **✔ 신시사이저를 사용해 실시간으로 MIDI 노트 출력** ```java import javax.sound.midi.*; public class MidiSynthesizer { public static void main(String[] args) { try { // 신시사이저 열기 Synthesizer synthesizer = MidiSystem.getSynthesizer(); synthesizer.open(); // MIDI 채널 가져오기 MidiChannel[] channels = synthesizer.getChannels(); MidiChannel channel = channels[0]; // 첫 번째 채널 사용 // 특정 노트 연주 (도(C4) - MIDI 번호 60) int note = 60; channel.noteOn(note, 80); // 음을 켬 (velocity: 80) System.out.println("도(C4) 연주 중..."); Thread.sleep(1000); // 1초 동안 연주 channel.noteOff(note); // 음을 끔 System.out.println("연주 종료!"); // 신시사이저 닫기 synthesizer.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` ✅ **`Synthesizer`를 사용해 실시간으로 MIDI 소리를 출력한다.** ✅ **`noteOn()`으로 음을 켜고 `noteOff()`로 끈다.** --- ## **5. 새로운 MIDI 파일 생성하기** ### **✔ MIDI 노트를 추가하여 새로운 MIDI 파일 생성** ```java import javax.sound.midi.*; import java.io.File; public class MidiCreator { public static void main(String[] args) { try { // 새로운 시퀀스 생성 Sequence sequence = new Sequence(Sequence.PPQ, 24); Track track = sequence.createTrack(); // 노트 ON (C4 = 60) ShortMessage noteOn = new ShortMessage(); noteOn.setMessage(ShortMessage.NOTE_ON, 0, 60, 80); track.add(new MidiEvent(noteOn, 1)); // 노트 OFF (C4 = 60) ShortMessage noteOff = new ShortMessage(); noteOff.setMessage(ShortMessage.NOTE_OFF, 0, 60, 80); track.add(new MidiEvent(noteOff, 24)); // MIDI 파일로 저장 File midiFile = new File("new_song.mid"); MidiSystem.write(sequence, 1, midiFile); System.out.println("새로운 MIDI 파일이 생성되었습니다: " + midiFile.getAbsolutePath()); } catch (Exception e) { e.printStackTrace(); } } } ``` ✅ **새로운 MIDI 파일을 만들고, C4(도) 음을 추가하여 저장한다.** ✅ **`MidiEvent`를 사용하여 MIDI 데이터를 구성한다.** --- ## **6. 정리** ✔ **`javax.sound.midi`는 자바에서 MIDI 데이터를 다루는 API이다!** ✔ **MIDI 파일을 재생(`Sequencer`), 실시간 연주(`Synthesizer`), 노트 추가(`Track`, `MidiEvent`) 가능** ✔ **기본적으로 자바에서 제공하는 소프트웨어 신시사이저를 이용하여 다양한 MIDI 작업 가능** ✅ **MIDI 파일 플레이어, 가상 피아노, 미디 편집기 등을 만들 수 있다!**