Я хочу генерировать синусоиду с комбинированными частотами. Я иду таким образом:
public static byte[] combineSineWave(Collection<Double> frequencies) {
double[] sample = new double[SAMPLE_RATE];
byte[] result = new byte[2 * SAMPLE_RATE];
double coefficient = 2 * Math.PI;
for (int i = 0; i < SAMPLE_RATE; i++) {
double sum = 0;
for (double frequency : frequencies) {
sum += Math.sin(coefficient * i * frequency / SAMPLE_RATE);
}
sample[i] = sum / frequencies.size();
}
convertToPCM16Bit(sample, result);
return result;
}
private static void convertToPCM16Bit(double[] sample, byte[] result) {
int idx = 0;
for (final double dVal : sample) {
// scale to maximum amplitude
final short val = (short) ((dVal * 32767));
// in 16 bit wav PCM, first byte is the low order byte
result[idx++] = (byte) (val & 0x00ff);
result[idx++] = (byte) ((val & 0xff00) >>> 8);
}
}
И воспроизведение сгенерированных байтов по этому коду:
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SoundWaveGenerator.SAMPLE_RATE,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, 2 * SoundWaveGenerator.SAMPLE_RATE,
AudioTrack.MODE_STREAM);
audioTrack.play();
while (true) {
byte[] bytes = SoundWaveGenerator.combineSineWave(frequencies);
audioTrack.write(bytes, 0, bytes.length);
}
Но проблема в том, что я слышу щелчок примерно каждую секунду. Что случилось?
i
. Также я вижу, что в вашем кодеsaple[0] == sample[SAMPLE_RATE + 1]
проблема все еще существует, верно? Можно ли рассчитать правильную длину звука, где у меня будет четное количество циклов? Я думал, что 2 * Math.PI правильный период синусоиды, не так ли? 29.10.2014