2013-11-28 3 views
0

그래서 기타 시뮬레이터를 만들려고합니다. 내가 메서드를 호출하면 해당 노트가 재생됩니다. 그러나 다시 호출하면 이전 사운드가 재생되지 않습니다.Java의 메서드에서 오디오 파일을 재생하는 방법은 무엇입니까? 그러나 해당 메서드를 다시 호출하면 이전 오디오 파일의 재생이 중단됩니까?

public class ytst { 
     public static void main(String[] args)throws Exception { 
      Estring.play(1); 
      TimeUnit.SECONDS.sleep(3); 
    Estring.play(2); 
    } 
    ---------- 
    class Estring{ 
     public static play(int fret){ 
      String filename="E" + fret + ".wav" 
      File soundFile = new File(filename); 
      AudioInputStream audioIn = AudioSystem.getAudioInputStream(soundFile); 
      Clip clip = AudioSystem.getClip(); 
      clip.open(audioIn); 
      clip.start(); 
     } 
    } 

이렇게하면 두 번째 오디오 파일이 첫 번째 오디오 파일과 겹칩니다. 이 메드를 다시 호출하면 이전 사운드 파일의 재생이 중지되므로 어떻게 할 수 있습니까?

답변

1

클립은 재사용되는 사운드를 보유하도록 설계되었습니다. 재생하기 전에 전체 .wav 파일을 메모리에로드해야합니다. 이로 인해 지연 문제가 발생할 수 있습니다. SourceDataLines는 재생을 시작하기 전에 버퍼의 데이터 만로드하기 때문에 재생 속도가 훨씬 빨라집니다.

후에 클립이 빛나고 있습니다. 메모리에로드 된 클립입니다. 파일이 메모리에서 실행되기 때문에 SourceDataLines와 함께 비용이 많이 드는 파일로드가 발생하지 않습니다. 따라서 클립을 사용하려면 먼저 모든 클립을 초기화하는 것이 좋습니다. 이 작업이 너무 많은 메모리를 소비하는 경우 최적화를 위해 멋진 작업을 시도하기 전에 적어도 앱에서 첫 번째 단계에서 SourceDataLines를 사용합니다.

클립을 중지하려면 clip.stop()을 호출하면됩니다. currentClip이라는 변수를 만들고이 메서드로 중지 한 다음 재생하려는 새 메모의 값으로 다시 할당하는 것과 같은 작업을 고려해 볼 수 있습니다. currentClip이 휘발성 일 경우 다양한 노트가 다른 스레드에서 재생되는 경우에도 신속하게 응답해야합니다.

SourceDataLine을 사용하면 SourceDataLine을 종료해도 조금 더 복잡해 지지만 동일한 일을 할 수 있습니다. 일반적인 전략은 가장 안쪽 while 루프에서 조건으로 휘발성 "재생 중"부울을 사용하는 것입니다. "playing"변수를 false로 설정하면 sourceDataLine 스레드가 제대로 작성되었다고 가정 할 때 종료됩니다. Java 자습서, 사운드 섹션에이 예제가 있습니다.