パラメータに基づいて、指定されたラウドネスで1秒間サウンドを生成するプログラムを作成しようとしています。私は以下のコードを含んでいます。 setUpSound()
機能では、列を制御する行「control.setValue(integer)
」があります。たとえば、値が-30の場合、実際に1秒間ビープ音が鳴ります。値が20の場合、1秒間は本当に大きなノイズが発生します。Javaサウンド - ソフトノイズの前の最初の大きなノイズ
ノイズが柔らかい場合(パラメーターが-30〜-10の範囲にある場合)、約100ミリ秒間続く初期の大きなノイズがあり、その後ソフトな正規の音が鳴ります。通常の通常の音を再生する前に、数秒間コンピュータの存在が驚いたサウンドカードのように聞こえます。それは理にかなっていますか?あなたもあなたのマシンでそれを試すことができます。私はLionを実行しているMacBook Proを使用しています。
私はJavaがこれを行う理由と解決方法を理解しようとしていますか?
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