Генерировать один период частоты? - PullRequest
1 голос
/ 02 февраля 2012

Я хотел бы иметь возможность брать частоту (например, 1000 Гц, 250 Гц, 100 Гц) и воспроизводить ее через аппаратное обеспечение телефона.

Я знаю, что AndroidTrack позволит мне воспроизводить 16-бит PCM, если я могу вычислить массив битов или шорт.Я хотел бы рассчитать только один период , чтобы позже я мог зациклить его без каких-либо проблем, и чтобы я мог сократить время расчета.

Как этого достичь?

1 Ответ

2 голосов
/ 02 февраля 2012

Циклирование одного периода не обязательно является хорошей идеей - цикл может не вписываться в точное число выборок, поэтому вы можете получить нежелательную прерывистость в конце каждого цикла или, что еще хуже, слышимая частота может закончиться немного выключен.

Тем не менее, математика не сложно:

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 Гц.

Строго говоря, для этого нужно 100,227 сэмплов, но приведенный выше код выдаст 100. Поэтому, если вы будете повторять ваши 100 сэмплов снова и снова, вы фактически будете воспроизводить сэмпл 441 раз в секунду, так что ваша высота будет на 1 Гц.

Чтобы избежать этой проблемы, вам действительно нужно рассчитать несколько периодов формы волны, хотя я не знаю, сколько нужно, чтобы обмануть слух, чтобы услышать правильную высоту.

В идеале это было бы столько, сколько нужно, чтобы:

i / samples_per_cycle

- это целое число, так что последняя выборка (технически после последней выборки) заканчивается точно на границе цикла. Я думаю , если все ваши входные частоты являются целыми числами, то получение значения одной секунды точно будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...