매개 변수에 따라 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();
}
}
죄송합니다. 완전히 이해하지 못했습니다. 조금 더 설명 할 수 있습니까? 다른 매개 변수를 사용하라고하셨습니까? 이걸 확장 할 수 있습니까? 감사! – CodeGuy
답변을 수정하십시오. –
getByteValue (double angle) 함수를 변경하려고합니까? 나는 아직도 약간 혼란 스럽다. 미안하다. 새로운 기능은 무엇입니까? – CodeGuy