java钢琴_Java swing实现支持录音等功能的钢琴程序
时间: 2024-02-09 08:09:25 浏览: 179
Java Swing是一种基于Java语言的图形用户界面(GUI)工具包。使用Java Swing,可以轻松地创建各种GUI应用程序,包括钢琴程序。以下是一个简单的Java Swing钢琴程序示例,支持录音等功能。
```java
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.sound.midi.*;
import javax.swing.*;
public class Piano extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private JButton[] whiteKeys = new JButton[7];
private JButton[] blackKeys = new JButton[5];
private JButton recordButton;
private JButton playButton;
private JButton stopButton;
private boolean isRecording = false;
private boolean isPlaying = false;
private Sequence sequence;
private Sequencer sequencer;
private Track track;
private int currentTick;
private ByteArrayOutputStream byteArrayOutputStream;
private AudioFormat audioFormat;
private TargetDataLine targetDataLine;
private AudioInputStream audioInputStream;
private byte[] audioData;
public Piano() {
setTitle("Java Piano");
setSize(800, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JPanel keyboardPanel = new JPanel();
keyboardPanel.setLayout(new GridLayout(1, 0));
// Add white keys
String[] whiteNotes = {"C", "D", "E", "F", "G", "A", "B"};
for (int i = 0; i < 7; i++) {
whiteKeys[i] = new JButton(whiteNotes[i]);
whiteKeys[i].setPreferredSize(new Dimension(80, 200));
whiteKeys[i].addActionListener(this);
keyboardPanel.add(whiteKeys[i]);
}
// Add black keys
String[] blackNotes = {"C#", "D#", "", "F#", "G#", "A#"};
for (int i = 0; i < 6; i++) {
if (i != 2) {
blackKeys[i] = new JButton(blackNotes[i]);
blackKeys[i].setPreferredSize(new Dimension(50, 120));
blackKeys[i].setBackground(Color.BLACK);
blackKeys[i].setOpaque(true);
blackKeys[i].addActionListener(this);
keyboardPanel.add(blackKeys[i]);
}
}
// Add record, play, and stop buttons
JPanel controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
recordButton = new JButton("Record");
recordButton.addActionListener(this);
controlPanel.add(recordButton);
playButton = new JButton("Play");
playButton.addActionListener(this);
controlPanel.add(playButton);
stopButton = new JButton("Stop");
stopButton.addActionListener(this);
controlPanel.add(stopButton);
add(keyboardPanel, BorderLayout.CENTER);
add(controlPanel, BorderLayout.SOUTH);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == recordButton) {
if (!isRecording) {
isRecording = true;
recordButton.setText("Stop Recording");
startRecording();
} else {
isRecording = false;
recordButton.setText("Record");
stopRecording();
}
} else if (e.getSource() == playButton) {
if (!isPlaying) {
isPlaying = true;
playButton.setText("Stop Playing");
startPlaying();
} else {
isPlaying = false;
playButton.setText("Play");
stopPlaying();
}
} else {
JButton button = (JButton) e.getSource();
String note = button.getText();
playSound(note);
if (isRecording) {
addNoteToSequence(note);
}
}
}
private void startRecording() {
try {
audioFormat = getAudioFormat();
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
targetDataLine.open(audioFormat);
targetDataLine.start();
byteArrayOutputStream = new ByteArrayOutputStream();
audioData = new byte[1024];
new Thread(new Runnable() {
public void run() {
while (isRecording) {
int numBytesRead = targetDataLine.read(audioData, 0, audioData.length);
byteArrayOutputStream.write(audioData, 0, numBytesRead);
}
}
}).start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void stopRecording() {
try {
targetDataLine.stop();
targetDataLine.close();
byteArrayOutputStream.close();
byte[] byteArray = byteArrayOutputStream.toByteArray();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray);
audioInputStream = new AudioInputStream(byteArrayInputStream, audioFormat, byteArray.length / audioFormat.getFrameSize());
// Convert audio data to MIDI sequence
AudioToMidiConverter converter = new AudioToMidiConverter();
sequence = converter.convert(audioInputStream);
// Create new track to add notes to
sequencer = MidiSystem.getSequencer();
sequencer.open();
sequence.deleteTrack(sequence.getTracks()[0]);
track = sequence.createTrack();
currentTick = 0;
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void startPlaying() {
try {
sequencer.setSequence(sequence);
sequencer.start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void stopPlaying() {
sequencer.stop();
sequencer.close();
}
private void addNoteToSequence(String note) {
try {
int velocity = 127;
int duration = 100;
int pitch = getMidiPitch(note);
ShortMessage messageOn = new ShortMessage(ShortMessage.NOTE_ON, 0, pitch, velocity);
track.add(new MidiEvent(messageOn, currentTick));
currentTick += duration;
ShortMessage messageOff = new ShortMessage(ShortMessage.NOTE_OFF, 0, pitch, velocity);
track.add(new MidiEvent(messageOff, currentTick));
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void playSound(String note) {
try {
Synthesizer synthesizer = MidiSystem.getSynthesizer();
synthesizer.open();
MidiChannel[] channels = synthesizer.getChannels();
int velocity = 127;
int pitch = getMidiPitch(note);
channels[0].noteOn(pitch, velocity);
Thread.sleep(100);
channels[0].noteOff(pitch, velocity);
synthesizer.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private int getMidiPitch(String note) {
String[] notes = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
int[] pitches = {60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71};
for (int i = 0; i < notes.length; i++) {
if (note.equals(notes[i])) {
return pitches[i];
}
}
return 0;
}
private AudioFormat getAudioFormat() {
float sampleRate = 44100.0F;
int sampleSizeInBits = 16;
int channels = 1;
boolean signed = true;
boolean bigEndian = false;
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
}
public static void main(String[] args) {
new Piano();
}
}
```
这个程序使用Java Swing创建了一个钢琴界面,包括白键和黑键。它还包括三个按钮:录音,播放和停止。当用户按下一个键时,程序将播放相应的音符,并且如果正在录音,则将该音符添加到MIDI序列中。当用户按下录音按钮时,程序开始录制音频,并将其转换为MIDI序列。当用户按下播放按钮时,程序将播放MIDI序列中的音符。
阅读全文