2014-10-30 7 views
1

javax.sound.sampled.SourceDataLine을 사용하여 일반 사인파를 생성하고 싶습니다. 하나의 고정 주파수에 대해서는 정상적으로 작동하지만 주파수를 변경할 때 항상 딸깍하는 소리가 들립니다. 무엇이 잘못 되었나요?이를 피하기 위해 무엇을 할 수 있습니까? freq 변경, 전체 정현파가 이동 될 때 때문에java SourceDataLine 사인파 클릭

private double alpha = 0.0; 
private static final double step_alpha = (2.0*Math.PI)/SAMPLE_RATE; 

private void createSineWaveBuffer(final double freq, final byte[] buffer) { 
    for(int i = 0; i < buffer.length; ++i) { 
     buffer[i] = (byte)(Math.sin(freq*alpha)*127.0); 
     alpha += step_alpha; 

     if(alpha >= 2.0*Math.PI) { 
      alpha = 0.0; 
     } 
    } 
} 

답변

1

당신은 클릭을 경험

  line.start(); 
      final byte[] toneBuffer = new byte[SAMPLE_CHUNK]; 

      while(run) { 
       createSineWaveBuffer(frequency, toneBuffer); 
       line.write(toneBuffer, 0, toneBuffer.length); 
      } 

      line.drain(); 
      line.close(); 

. 쉬운 - 투 - 무승부 삼각파와 예를 들어 :

당신이 임의의 시간에 이들 사이를 전환 할 경우
1 Hz 
    /\ /\ /
/\/\/
/ \/ \/ 

.5 Hz_ 
    /\ 
/ \ /
/  \_/ 

:

/\ |\ 
/\ | \ /
/ \| \_/ 

당신은 클릭으로 듣고 불연속이있다.

이것은 sin (freq * alpha)에서 sin (.5 * freq * (alpha + step_alpha))로 갑자기 이동했기 때문에 발생합니다. sin()에 대한 입력의 미분이 불 연속적으로 변경 될뿐만 아니라 (주파수를 변경해야하는 경우) 값이 불 연속적으로 변경됩니다.

이 문제를 해결하려면 입력의 파생어를 sin()으로 변경해야합니다. 당신은 주파수에 따라 따라 점층 적으로 증가되는 계수를 유지하여이 작업을 수행 할 수 있습니다 :

private void createSineWaveBuffer(final double freq, final byte[] buffer) { 

    for(int i = 0; i < buffer.length; ++i) { 
     buffer[i] = (byte)(Math.sin(alpha)*127.0); 
     alpha += freq*step_alpha; 

     if(alpha >= 2.0*Math.PI) { 
      alpha -= 2.0*Math.PI; 
     } 
    } 

    return t; 
} 

는 여기에 현재 freq에 의해 제어되는 속도로 증가하여 alpha을 변경했습니다.

  _ 
    /\ /\ 
/\ / \ 
/ \/   \ 
위로 삼각형 예

,이 모양을