결합 된 주파수로 사인파를 생성하고 싶습니다. 나는 이런 식으로 갈거야 :Android. 생성 된 사인파는 매초마다 노크 노이즈를 발생합니다.
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 정확한 기간이라고 생각하지 않습니까? –
또한 짝수 사이클이있는 길이를 미리 계산하는 것은 좋지 않습니다. 1.0000kHz의 사인파와 결합 된 1kHz의 사인파를 상상해보십시오. – jaket
그래서 솔루션은 "클릭"노이즈를 따로 떼어 놓을 수 있다는 것입니다. 우리는 1 초마다 그것을들을 수는 없지만 1 시간마다 (예를 들어)들을 것이다. 사실입니까? –