[英]About how to create a music player that could play different file one by one to create a music
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.sound.sampled.*;
public class Main{
static File [] arr= new File[100];
static String[] arrNote = new String[100];
public void play(File filename)throws UnsupportedAudioFileException, IOException,InterruptedException,
LineUnavailableException{
AudioInputStream audioStream = AudioSystem.getAudioInputStream(filename);
Clip clip = AudioSystem.getClip();
clip.open(audioStream);
clip.start();
Thread.sleep(500);
clip.close();
}
public static void main(String[]args) throws UnsupportedAudioFileException, IOException,InterruptedException,
LineUnavailableException{
Scanner scanner = new Scanner(System.in);
String response = "";
Main a = new Main();
int numItems = 0;
System.out.println("Store music notes, type in Alphabate + number for example(E3) for the music note you want to store in the array, type Q when finished");
while(!response.equals("Q")){
response = scanner.next();
response.toUpperCase();
switch(response){
case("B3"):
arr[numItems] = new File("C:\\Users\\westg\\OneDrive\\Desktop\\piano.wav\\B3.wav");
arrNote[numItems] = "B3";
numItems++;
break;
case("C3"):
arr[numItems] = new File("C:\\Users\\westg\\OneDrive\\Desktop\\piano.wav\\C3.wav");
arrNote[numItems] = "C3";
numItems++;
break;
case("D3"):
arr[numItems] = new File("C:\\Users\\westg\\OneDrive\\Desktop\\piano.wav\\D3.wav");
arrNote[numItems] = "D3";
numItems++;
break;
case("E3"):
arr[numItems] = new File("C:\\Users\\westg\\OneDrive\\Desktop\\piano.wav\\E3.wav");
arrNote[numItems] = "E3";
numItems++;
break;
case("F3"):
arr[numItems] = new File("C:\\Users\\westg\\OneDrive\\Desktop\\piano.wav\\F3.wav");
arrNote[numItems] = "F3";
numItems++;
break;
case("Q"):
break;
default: System.out.println("Not a valid response");
}
}
System.out.println("Your music note sequence: ");
for (int x = 0; x < numItems; x ++){
System.out.print(x + 1 + "." + arrNote[x] + " ");
}
System.out.println("If you want to play your music, click any key to continue");
response = scanner.next();
while(!response.equals("Q")){
System.out.println("P = play, S = Stop, R= Reset, Q = Quit");
System.out.print("Enter your choice: ");
response = scanner.next();
response = response.toUpperCase();
switch (response) {
case("P"):
for (int i = 0; i < numItems; i++){
a.play(arr[i]);
}
default: System.out.println("Not a valid response");
}
System.out.println("Bye");
}
}
}
这是我用来逐个播放不同钢琴音符wav文件以创建音乐的代码,但是当我使Thread.sleep小于1000时,音符会卡住,它会跳过或一起播放一些音符,是无论如何,我可以按顺序一个一个地播放这些文件,或者还有其他方法可以用来创建一个音乐编辑器,允许我将不同的音符组合在一起使用 java 播放歌曲?`在此处输入代码。
所以,你的基本问题是,你在它有机会播放或完全播放之前关闭剪辑。
而不是依赖Thread.sleep
,它不会考虑播放的可变性质(即源剪辑的长度不同或音响系统需要更多时间),您应该尝试使用更英制的测量。
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class Test {
public static void main(String[] args) {
new Test();
}
public enum Note {
A3_MINOR(Note.class.getResource("/notes/a-3.wav")),
A4_MINOR(Note.class.getResource("/notes/a-4.wav")),
A5_MINOR(Note.class.getResource("/notes/a-5.wav")),
A3(Note.class.getResource("/notes/a3.wav")),
A4(Note.class.getResource("/notes/a4.wav")),
A5(Note.class.getResource("/notes/a5.wav")),
B3(Note.class.getResource("/notes/b3.wav")),
B4(Note.class.getResource("/notes/b4.wav")),
B5(Note.class.getResource("/notes/b5.wav")),
C3_MINOR(Note.class.getResource("/notes/c-3.wav")),
C4_MINOR(Note.class.getResource("/notes/c-4.wav")),
C5_MINOR(Note.class.getResource("/notes/c-5.wav")),
C3(Note.class.getResource("/notes/c3.wav")),
C4(Note.class.getResource("/notes/c4.wav")),
C5(Note.class.getResource("/notes/c5.wav")),
D3_MINOR(Note.class.getResource("/notes/d-3.wav")),
D4_MINOR(Note.class.getResource("/notes/d-4.wav")),
D5_MINOR(Note.class.getResource("/notes/d-5.wav")),
D3(Note.class.getResource("/notes/d3.wav")),
D4(Note.class.getResource("/notes/d4.wav")),
D5(Note.class.getResource("/notes/d5.wav")),
E3(Note.class.getResource("/notes/e3.wav")),
E4(Note.class.getResource("/notes/e4.wav")),
E5(Note.class.getResource("/notes/e5.wav")),
F3_MINOR(Note.class.getResource("/notes/f-3.wav")),
F4_MINOR(Note.class.getResource("/notes/f-4.wav")),
F5_MINOR(Note.class.getResource("/notes/f-5.wav")),
F3(Note.class.getResource("/notes/f3.wav")),
F4(Note.class.getResource("/notes/f4.wav")),
F5(Note.class.getResource("/notes/f5.wav")),
G3_MINOR(Note.class.getResource("/notes/g-3.wav")),
G4_MINOR(Note.class.getResource("/notes/g-4.wav")),
G5_MINOR(Note.class.getResource("/notes/g-5.wav")),
G3(Note.class.getResource("/notes/g3.wav")),
G4(Note.class.getResource("/notes/g4.wav")),
G5(Note.class.getResource("/notes/g5.wav")),;
private URL source;
private Note(URL source) {
this.source = source;
}
public URL getSource() {
return source;
}
}
public Test() {
List<Note> notes = new ArrayList<>(16);
notes.add(Note.A3_MINOR);
notes.add(Note.A4_MINOR);
notes.add(Note.A5_MINOR);
notes.add(Note.A3);
notes.add(Note.A4);
notes.add(Note.A5);
play(notes);
}
protected void play(List<Note> notes) {
for (Note note : notes) {
System.out.println("Play " + note + "; " + note.getSource());
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(note.getSource());
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
clip.drain();
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
现在,如果你运行它,你会发现一个特殊的问题。 他们“似乎”同时演奏(就像在键盘上砸你的手)......不漂亮。
因此,相反,我们需要了解更多信息,特别是剪辑实际完成的时间。
因此,我向Clip
添加了LineListener
并使用ReentrantLock
来“等待”直到剪辑“停止”,例如......
protected void play(List<Note> notes) {
ReentrantLock waitLock = new ReentrantLock();
Condition waitCondition = waitLock.newCondition();
for (Note note : notes) {
System.out.println("Play " + note + "; " + note.getSource());
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(note.getSource());
Clip clip = AudioSystem.getClip();
clip.addLineListener(new LineListener() {
@Override
public void update(LineEvent event) {
if (event.getType().equals(LineEvent.Type.STOP)) {
waitLock.lock();
try {
waitCondition.signal();
} finally {
waitLock.unlock();
}
}
}
});
clip.open(audioInputStream);
clip.start();
clip.drain();
waitLock.lock();
try {
waitCondition.await();
} catch (InterruptedException ex) {
//Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
} finally {
waitLock.unlock();
}
clip.close();
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
这可确保在最后一个音符完成后立即播放每个音符。
现在,如果您希望音符有一点“重叠”,那么简单地说,不要close
剪辑,让它播放。
protected void play(List<Note> notes) {
ReentrantLock waitLock = new ReentrantLock();
Condition waitCondition = waitLock.newCondition();
for (Note note : notes) {
System.out.println("Play " + note + "; " + note.getSource());
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(note.getSource());
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
clip.drain();
Thread.sleep(125);
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException | InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
如果需要,您可以使用LineListener
来close
剪辑
注意:我的笔记文件来自https://sound.stackexchange.com/questions/22769/are-there-free-records-of-separate-piano-notes-in-wav-files-for-instance ,具体来说, http://www.mediafire.com/download/zp8brp1f6q777b1/Midi_Notes.rar和http://www.mediafire.com/download/zd1mqtazulgv28a/mp3_Notes.r 。 我使用了 MP3 文件并将它们转换为 wav 文件
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.