2012-02-20 1 views
1

매개 변수에 따라 1 분 동안 지정된 소리가 나는 소리를 생성하는 프로그램을 만들려고합니다. 아래 코드를 포함 시켰습니다. setUpSound() 함수에는 volumne를 제어하는 ​​줄 "control.setValue(integer)"이 있습니다. 예를 들어 값이 -30이면 1 초 동안 실제로 부드럽게 울립니다. 값이 20이면 1 초 동안 실제로 큰 소리가납니다.자바 사운드 - 부드러운 노이즈 이전의 초기 시끄러운 소리

잡음이 약한 경우 (매개 변수가 -30 ~ -10 범위에있는 경우) 약 100 밀리 초 정도 지속되는 초기 시끄러운 소음이 있고 부드러운 표준 소리가 들립니다. 그것은 정상적인 사운드를 재생하기 전에 제 컴퓨터의 사운드 카드가 몇 초 동안 놀란 것처럼 들립니다. 말이 돼? 당신도 당신의 컴퓨터에서 그것을 시도 할 수 있습니다. Lion을 실행하는 MacBook Pro를 사용하고 있습니다.

자바가 왜 이것을하는지, 어떻게 해결할 수 있는지 알아 내려고합니다.

import java.io.ByteArrayInputStream; 

import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.Clip; 
import javax.sound.sampled.FloatControl; 
import javax.sound.sampled.LineUnavailableException; 
import javax.swing.JSlider; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

public class Test { 

    FloatControl control; 

    public static void main(String[] args) { 
     Test test = new Test(); 
     test.setUpSound(); 
     test.loopSound(true); 

     try { 
      Thread.sleep(1000); 
     } catch(Exception e) { 

     } 
     test.loopSound(false); 
    } 
    Clip clip; 

    public void setUpSound() { 

     /** Volume */ 

      try { 

       generateTone(); 

       control = (FloatControl) 
         clip.getControl(FloatControl.Type.MASTER_GAIN); 

      System.out.println("min volume: " + control.getMinimum()); 
      System.out.println("max volume " + control.getMaximum()); 
      System.out.println("end of sounds"); 

      control.setValue(-40); 



      } catch(Exception e) { 
       e.printStackTrace(); 
      } 
     } 

    public void loopSound(boolean commence) { 
     if (commence) { 
      clip.setFramePosition(0); 
      clip.loop(Clip.LOOP_CONTINUOUSLY); 
     } else { 
      clip.stop(); 
     } 
    } 

    /** Generates a tone, and assigns it to the Clip. */ 
    public void generateTone() 
     throws LineUnavailableException { 
     if (clip!=null) { 
      clip.stop(); 
      clip.close(); 
     } else { 
      clip = AudioSystem.getClip(); 
     } 
     boolean addHarmonic = true; 

     int intSR = 10025; 
     int intFPW = 20; 
     System.out.println("sampleRate = " + intSR); 
     System.out.println("framesPerWavelength = " + intFPW); 

     float sampleRate = (float)intSR; 

     // oddly, the sound does not loop well for less than 
     // around 5 or so, wavelengths 
     int wavelengths = 5; 
     byte[] buf = new byte[2*intFPW*wavelengths]; 
     AudioFormat af = new AudioFormat(
      sampleRate, 
      8, // sample size in bits 
      2, // channels 
      true, // signed 
      false // bigendian 
      ); 

     for(int i=0; i<intFPW*wavelengths; i++){ 
      double angle = ((float)(i*2)/((float)intFPW))*(Math.PI); 
      buf[i*2]=getByteValue(angle); 
      if(addHarmonic) { 
       buf[(i*2)+1]=getByteValue(2*angle); 
      } else { 
       buf[(i*2)+1] = buf[i*2]; 
      } 
     } 

     try { 
      byte[] b = buf; 
      AudioInputStream ais = new AudioInputStream(
       new ByteArrayInputStream(b), 
       af, 
       buf.length/2); 

      clip.open(ais); 
     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    /** Provides the byte value for this point in the sinusoidal wave. */ 
    private static byte getByteValue(double angle) { 
     int maxVol = 127; 
     return (new Integer(
      (int)Math.round(
      Math.sin(angle)*maxVol))). 
      byteValue(); 
    } 
} 

답변

1

..how를 해결하기 위해?

단독 마스터 볼륨을두고 getByteValue() 방법에 다른 파라미터를 이용하여 볼륨을 조절 (소프트 사운드의 작은 바이트 반환 값). 다른 파라미터 ..use

..


- 변경 getByteValue()에서 getByteValue(float scale)으로 변경하십시오.
-throwIllegalArgumentException 범위가 0.0f-1.0f 외부 인 경우. - 그 순간의 신호 값에 scale 값을 곱하십시오.

scale에 0.5f의 값을 지정하면 소리가 1.0f보다 작아집니다.

+0

죄송합니다. 완전히 이해하지 못했습니다. 조금 더 설명 할 수 있습니까? 다른 매개 변수를 사용하라고하셨습니까? 이걸 확장 할 수 있습니까? 감사! – CodeGuy

+0

답변을 수정하십시오. –

+0

getByteValue (double angle) 함수를 변경하려고합니까? 나는 아직도 약간 혼란 스럽다. 미안하다. 새로운 기능은 무엇입니까? – CodeGuy