我不应该在for循环中使用该循环的样本长度吗?我不明白为什么它会播放正弦波公式而不是锯齿波...这是从一个非常相似的结构的哔哔声类中修改的,也许它是中间的for循环产生太多的mamy rounds来得到锯齿形状。你怎么看?这是我的代码:
class MakeSaw
{
static void makeSaw(double f, int t) throws Exception
{
int nChannel = 1; // number of channel : 1 or 2
// samples per second
float sampleRate = 16000; // valid:8000,11025,16000,22050,44100
int nBit = 16; // 8 bit or 16 bit sample
int bytesPerSample = nChannel*nBit/8;
int bufferSize = (int) (nChannel*sampleRate*t*bytesPerSample);
byte[] audioData = new byte[bufferSize];
// "type cast" to ShortBuffer
java.nio.ByteBuffer byteBuffer = java.nio.ByteBuffer.wrap(audioData);
java.nio.ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
int sampleLength = audioData.length/bytesPerSample;
// generate the wave
double volume = 8192; // 0-32767
double PI = Math.PI;
double sawWave=0;
//make saw wave
for(int i = 0; i < sampleLength; i++)
{
double time = i/sampleRate;
sawWave = sawWave + Math.sin(2*PI*f*(i*t)/i); //passing amplitude frequency and time
short amplitude = (short) (volume*sawWave);
for (int c=0;c<1;c++) //repeat once because audio playing on one channel
{
shortBuffer.put(amplitude);
}
}
//end wave making//end generating sound wave sample
boolean isSigned=true;
boolean isBigEndian=true;
// Define audio format
javax.sound.sampled.AudioFormat audioFormat =
new javax.sound.sampled.AudioFormat(sampleRate, nBit, nChannel, isSigned,isBigEndian);
javax.sound.sampled.DataLine.Info dataLineInfo =
new javax.sound.sampled.DataLine.Info(
javax.sound.sampled.SourceDataLine.class, audioFormat);
// get the SourceDataLine object
javax.sound.sampled.SourceDataLine sourceDataLine =
(javax.sound.sampled.SourceDataLine)
javax.sound.sampled.AudioSystem.getLine(dataLineInfo);
sourceDataLine.open(audioFormat);
sourceDataLine.start();
// actually play the sound
sourceDataLine.write(audioData,0,audioData.length);
// "flush", wait until the sound is completed
sourceDataLine.drain();
}
public static void main(String[] args) throws Exception
{
makeSaw(400,2);
}
}
答案 0 :(得分:2)
您对sawWave
的计算错误。所有振幅都为零。
我没有尝试为你调试这个,但有三件事情在
中脱颖而出 double time = i/sampleRate;
sawWave = sawWave + Math.sin(2*PI*f*(i*t)/i); //passing amplitude frequency and time
time
计算中使用sawWave
。i
之间的划分看起来很可疑。sin()
?