2017-02-14 1 views
1

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 재생되지 않을 수 있다는 것입니다에게 있습니다. 대신 플레이어는 두 악기 사이를 우연히 변경하므로 한 번에 두 패턴을 연주하는 악기 하나만들을 수 있습니다.

+0

나는 sleep' 동기화 할 수있는 끔찍한 방법입니다'실현. 이것은 JFugue의 기능을 시험해보기위한 것입니다. –

+1

나는 여기에서 어떤 일이 일어나고 있는지 보았습니다 : 목소리와 악기가 왼손 및 오른손 패턴에서 혼합되어 있습니다. JFugue가 필요로하는 것은 음성 + 레이어 + 악기 + 노트 튜플렛을 하나의 원자 음악적 요소로 인식하는 방법입니다. 당신의 예제에 힘 입어 새로운 클래스 "Atom"과 pattern.atomize() 메소드 (AtomSubparser)를 만들고 있습니다. 내 목표는 pattern.atomize() 호출을 추가하여 동일한 코드를 사용할 수 있다는 것입니다. 나는 당신을 계속 게시하고 그것이 작동 할 때이 질문에 답할 것입니다. –

+0

David Koelle, 고맙습니다. –

답변

1

이 문제는 JFugue 5.0.8에서 Atom이 도입되어 해결되었습니다. Atom에는 음성, 악기 및 음 정보가 하나의 원자 단위로 포함되어 있으므로 악기가 연주에 사용 된 음과 분리되지 않습니다.

는 좀 더 완벽하게 여기이 업데이트를 설명 : https://medium.com/@dmkoelle/whats-new-in-jfugue-5-0-8-7479abca3be4

관련 문제