JFugue 5.0.7에서 문제가 발생했습니다. 음악을 무기한 재생하는 실시간 응용 프로그램을 코딩하고 있지만 jfugue 라이브러리가 제공하는 RealtimePlayer는 악기를 서로 믹스합니다.JFugue RealtimePlayer가 동시에 여러 악기를 재생할 수 없습니다.
는 다음 코드
public class HelloJFugue {
public static int BPM = 150;
public static int SIGNATURE = 3;
public static boolean RANDOM = false;
public static void main(String[] args) throws MidiUnavailableException {
RealtimePlayer player = new RealtimePlayer();
BlockingQueue<Pattern> queue = new SynchronousQueue<>();
List<PatternProducer> pProducers = createPatternProducers();
Thread pConsumer = new Thread(new PatternConsumer(player, queue));
Thread pProducer = new Thread(new PatternMediator(queue, pProducers));
pConsumer.start();
pProducer.start();
}
private static List<PatternProducer> createPatternProducers() {
Random rand = new Random();
PatternProducer rightHand = new PatternProducer() {
int counter = 0;
String[] patterns = {
"Rq Rq E6i D#6i",
"E6i D#6i E6i B5i D6i C6i",
"A5q Ri C5i E5i A5i",
"B5q Ri E5i G#5i B5i",
"C6q Ri E5i E6i D#6i",
"E6i D#6i E6i B5i D6i C6i",
"A5q Ri C5i E5i A5i",
"B5q Ri E5i C6i B5i",
"A5q Ri E5i E6i D#6i"
};
@Override
public Pattern getPattern() {
Pattern p = new Pattern(patterns[RANDOM ? rand.nextInt(patterns.length - 1) + 1 : counter])
.setVoice(0)
.setInstrument("Piano");
counter++;
if (counter >= patterns.length) {
counter = 1;
}
return p;
}
};
PatternProducer leftHand = new PatternProducer() {
int counter = 0;
String[] patterns = {
"Rq Rq Rq",
"Rq Rq Rq",
"A3i E4i A4i Ri Rq",
"E3i E4i G#4i Ri Rq",
"A3i E4i A4i Ri Rq",
"Rq Rq Rq",
"A3i E4i A4i Ri Rq",
"E3i E4i G#4i Ri Rq",
"A3i E4i A4i Ri Rq"
};
@Override
public Pattern getPattern() {
Pattern p = new Pattern(patterns[RANDOM ? rand.nextInt(patterns.length - 1) + 1 : counter])
.setVoice(1)
.setInstrument("Guitar");
counter++;
if (counter >= patterns.length) {
counter = 1;
}
return p;
}
};
return new ArrayList<PatternProducer>() {
{
add(rightHand);
add(leftHand);
}
};
}
}
public class PatternMediator implements Runnable {
private BlockingQueue<Pattern> queue;
private List<PatternProducer> producers;
public PatternMediator(BlockingQueue<Pattern> queue, List<PatternProducer> producers) {
this.queue = queue;
this.producers = producers;
}
private void fillQueue() throws InterruptedException {
Pattern p = new Pattern();
for (PatternProducer producer : producers) {
p.add(producer.getPattern().setTempo(HelloJFugue.BPM));
}
this.queue.put(p);
}
@Override
public void run() {
while (true) {
try {
fillQueue();
} catch (InterruptedException ex) {
Logger.getLogger(PatternMediator.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public class PatternConsumer implements Runnable {
private RealtimePlayer player;
private BlockingQueue<Pattern> queue;
public PatternConsumer(RealtimePlayer player, BlockingQueue<Pattern> queue) {
this.player = player;
this.queue = queue;
}
private void playFromQueue() throws InterruptedException {
player.play(queue.take());
}
@Override
public void run() {
while (true) {
try {
playFromQueue();
Thread.sleep(HelloJFugue.SIGNATURE * 60000/HelloJFugue.BPM);
} catch (InterruptedException ex) {
Logger.getLogger(PatternConsumer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
문제는 두 악기 (기타, 피아노)를 연주 할 때하는 것은 혼동하고, 두 simultanously 재생되지 않을 수 있다는 것입니다에게 있습니다. 대신 플레이어는 두 악기 사이를 우연히 변경하므로 한 번에 두 패턴을 연주하는 악기 하나만들을 수 있습니다.
나는 sleep' 동기화 할 수있는 끔찍한 방법입니다'실현. 이것은 JFugue의 기능을 시험해보기위한 것입니다. –
나는 여기에서 어떤 일이 일어나고 있는지 보았습니다 : 목소리와 악기가 왼손 및 오른손 패턴에서 혼합되어 있습니다. JFugue가 필요로하는 것은 음성 + 레이어 + 악기 + 노트 튜플렛을 하나의 원자 음악적 요소로 인식하는 방법입니다. 당신의 예제에 힘 입어 새로운 클래스 "Atom"과 pattern.atomize() 메소드 (AtomSubparser)를 만들고 있습니다. 내 목표는 pattern.atomize() 호출을 추가하여 동일한 코드를 사용할 수 있다는 것입니다. 나는 당신을 계속 게시하고 그것이 작동 할 때이 질문에 답할 것입니다. –
David Koelle, 고맙습니다. –