正弦波交替扭曲在Java
我想生成正弦波并将其添加到字节数组。我搜索并找到了。但是,我总是会像附件一样得到失真的波形。正弦波交替扭曲在Java
请给我你的意见为什么发生。谢谢。
我的代码是在这里
private byte[] getData(int freq) { // taking pitch data
double pha = Math.PI/2; // defining phase
final int LENGTH = 44100 * 10; // defining length of sine wave, byte array
final byte[] arr = new byte[LENGTH];
for(int i = 0; i < arr.length; i++) {
double angle = (2.0 * Math.PI * i*freq+pha)/(44100);
arr[i] = (byte) (Math.cos(angle) *127* 0.3); // 0.3 is amplitude scale
}
return arr;
}
的代码看起来不错。我怀疑它是可视化器将two's complement有符号值解释为无符号(-1
变为255
,-2
变成254
等等)。
写到一个wav文件,并用SonicVisualiser
绘制它根据WAVE PCM soundfile format:
8位采样存储为无符号字节,范围从0到255 16位采样存储为2的补码有符号整数,范围从-32768到32767.
它看起来像你e它需要将正弦波向上移动128(以便它完全适合0-255范围),或者移动到使用16位采样。
您可以使用此代码来说服自己,你产生了什么是Java语义水平适当:
public static void main(String[] args) {
for (byte b : getData(300)) System.out.println(sample(b));
}
static String sample(byte val) {
final int len = (val-Byte.MIN_VALUE)/2;
final StringBuilder b = new StringBuilder();
for (int i = 0; i < len; i++) b.append(i < len-1? ' ' : '#');
return b.toString();
}
它将打印一个很好的垂直正弦波。用这种方法生产的无符号字节修复代码:
static byte[] getData(int freq) {
double pha = Math.PI/2;
final int LENGTH = 44100 * 10;
final byte[] arr = new byte[LENGTH];
for(int i = 0; i < arr.length; i++) {
double angle = (2.0 * Math.PI * i*freq+pha)/(44100);
int unsignedSample = (int) (Math.cos(angle)*Byte.MAX_VALUE*0.3 - Byte.MIN_VALUE);
arr[i] = (byte) (unsignedSample & 0xFF);
}
return arr;
}
如果打印这一点,你会看到你在SonicVisualizer看到了同样的波形,但该工具会显得你意的方式。
它看起来也适用于我,但我无法缩放幅度。我应该在哪里添加* 0.3? – 2014-10-29 14:42:45
它已经在声明unsignedSample的代码中。 – 2014-10-29 15:10:11
是的,我明白了,但它不起作用。 – 2014-10-29 17:46:28
我这么认为,但我无法处理它。 – 2014-10-29 14:15:43
@AkiSuihkonen,这是Java。没有无符号类型。 – 2014-10-29 14:18:27