【发布时间】:2016-04-26 11:22:14
【问题描述】:
我已经编写了这个小信号生成方法。我的目标是在两个通道(左右)之间产生轻微的时间延迟或通道之间的增益略有不同的哔哔声。 目前,我通过为一个通道填充一个零并为第二个通道填充一个值并进一步向下交换通道之间的行为来创建延迟(如果您有任何提示或想法如何更好地做到这一点,我们将不胜感激。) 下一阶段是对增益做类似的事情。我已经看到 Java 通过 FloatControl 提供了内置的增益控制:
FloatControl gainControl =
(FloatControl) sdl.getControl(FloatControl.Type.MASTER_GAIN);
但我不确定如何分别控制每个通道的增益。有没有内置的方法来做到这一点? 我需要两个单独的流,每个通道一个吗?如果是这样,我如何同时播放它们? 我对声音编程相当陌生,如果有更好的方法可以做到这一点,请告诉我。很感谢任何形式的帮助。
这是我目前的代码:
public static void generateTone(int delayR, int delayL, double gainRightDB, double gainLeftDB)
throws LineUnavailableException, IOException {
// in hz, number of samples in one second
int sampleRate = 100000; // let sample rate and frequency be the same
// how much to add to each side:
double gainLeft = 100;//Math.pow(10.0, gainLeftDB / 20.0);
double gainRight = 100;// Math.pow(10.0, gainRightDB / 20.0);;
// click duration = 40 us
double duration = 0.08;
double durationInSamples = Math.ceil(duration * sampleRate);
// single delay window duration = 225 us
double baseDelay = 0.000225;
double samplesPerDelay = Math.ceil(baseDelay * sampleRate);
AudioFormat af;
byte buf[] = new byte[sampleRate * 4]; // one second of audio in total
af = new AudioFormat(sampleRate, 16, 2, true, true); // 44100 Hz, 16 bit, 2 channels
SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
sdl.open(af);
sdl.start();
// only one should be delayed at a time
int delayRight = delayR;
int delayLeft = delayL;
int freq = 1000;
/*
* NOTE:
* The buffer holds data in groups of 4. Every 4 bytes represent a single sample. The first 2 bytes
* are for the left side, the other two are for the right. We take 2 each time because of a 16 bit rate.
*
*
*/
for(int i = 0; i < sampleRate * 4; i++){
double time = ((double)i/((double)sampleRate));
// Left side:
if (i >= delayLeft * samplesPerDelay * 4 // when the left side plays
&& i % 4 < 2 // access first two bytes in sample
&& i <= (delayLeft * 4 * samplesPerDelay)
+ (4 * durationInSamples)) // make sure to stop after your delay window
buf[i] = (byte) ((1+gainLeft) * Math.sin(2*Math.PI*(freq)*time)); // sound in left ear
//Right side:
else if (i >= delayRight * samplesPerDelay * 4 // time for right side
&& i % 4 >= 2 // use second 2 bytes
&& i <= (delayRight * 4 * samplesPerDelay)
+ (4 * durationInSamples)) // stop after your delay window
buf[i] = (byte) ((1+gainRight) * Math.sin(2*Math.PI*(freq)*time)); // sound in right ear
}
for (byte b : buf)
System.out.print(b + " ");
System.out.println();
sdl.write(buf,0,buf.length);
sdl.drain();
sdl.stop();
sdl.close();
}
【问题讨论】:
-
"..不确定如何分别控制每个通道的增益。"
FloatControl.Type.BALANCE.. -
如需尽快获得更好的帮助,请发帖minimal reproducible example 或Short, Self Contained, Correct Example。
标签: java audio javasound sampling