生成频率的单期?频率

2023-09-06 17:33:25 作者:他的城

我想能够采取的频率(例如1000赫兹,250Hz的,100Hz的),并发挥它通过手机的硬件。

I would like to be able to take a frequency (eg. 1000hz, 250hz, 100hz) and play it out through the phone hardware.

我知道,Android的AudioTrack可以让我发挥16位PCM如果我能计算出位或短裤的数组。我想只计算一个单期这样,以后我可以循环它没有任何问题,所以我可以保持计算时间了。

I know that Android's AudioTrack will allow me to play a 16-bit PCM if I can calculate an array of bits or shorts. I would like to calculate only a single period so that later I can loop it without any issues, and so I can keep the calculation time down.

这怎么可能实现?

推荐答案

循环一个周期不一定是一个好主意 -​​ 周期可能无法很好地适应到采样的准确数量,所以你可能在得到一个不受欢迎的不连续性每个周期,或者更糟的结束时,可听频率可能会略有结束了。

Looping a single period isn't necessarily a good idea - the cycle may not fit nicely into an exact number of samples so you might get an undesirable discontinuity at the end of each cycle, or worse, the audible frequency may end up slightly off.

这就是说,数学并不难:

That said, the math isn't hard:

float sample_rate = 44100;
float samples_per_cycle = sample_rate / frequency;
int samples_to_produce = ....

for (int i = 0; i < samples_to_produce; ++i) {
   sample[i] = Math.floor(32767.0 * Math.sin(2 * Math.PI * i / samples_per_cycle));
}

要明白我的意思以上有关的频率,以440赫兹的标准调整音高。

To see what I meant above about the frequency, take the standard tuning pitch of 440 Hz.

严格,这需要100.227样品,但高于code会产生100所以,如果你重复你的100个样本一遍又一遍,你会真正发挥样品的 441 的每秒次,所以你的音调会被1赫兹被关闭。

Strictly this needs 100.227 samples, but the code above would produce 100. So if you repeat your 100 samples over and over you'll actually play the sample 441 times per second, so your pitch will be off by 1 Hz.

要避免你真的需要计算波形的几个时期,虽然我不知道很多是需要耳朵欺骗听证的权利间距做的问题。

To avoid the problem you'd really need to calculate several periods of the waveform, although I don't know many is needed to fool the ear into hearing the right pitch.

理想情况下是多达需要这样:

Ideally it would be as many as are needed such that:

i / samples_per_cycle

是一个整数,所以最后一个样本(技术上之一的之后的最后一个样本)结束完全是一个周期边界上。我的认为的,如果你的输入频率都是整数,然后生产一秒数价值究竟是可行的。

is a whole number, so that the last sample (technically the one after the last sample) ends exactly on a cycle boundary. I think if your input frequencies are all whole numbers then producing one second's worth exactly would work.