Частота и высота звука для AudioClip - Unity3D
Я пытаюсь воссоздать весь спектр гитар только с помощью 6 аудиоклипов.
Я думал, что будет способ установить частоту аудиоклипа, но audio.frequency возвращает только частоту звука на основе формата сжатия, а не фактического тона.
Я знаю, что могу читать GetSpectrumData, но это решение довольно сложное и потребует некоторого анализа с преобразованием Фурье или чего-то в этом роде.
Влияя на высоту, легко изменить тон, чтобы я мог подниматься и опускаться, но есть ли способ выяснить, какие шаги использовать.
void Update ()
{
CheckAudio(KeyCode.Q, 1.0f);
CheckAudio(KeyCode.W, 1.1f);
CheckAudio(KeyCode.E, 1.2f);
CheckAudio(KeyCode.R, 1.3f);
CheckAudio(KeyCode.T, 1.4f);
}
void CheckAudio(KeyCode key, float pitch)
{
if (Input.GetKeyDown (key))
{
audio.pitch = pitch;
audio.Play ();
}
}
Я слышу, это не звучит правильно.
Зная начальный тон E4 329,63 Гц с высотой тона 1, есть ли какое-либо уравнение, влияющее на высоту тона, я бы получил следующий ключ F4 349,23 Гц (или достаточно близко)?
Также следует учитывать, что Unity AudioSource ограничивает высоту звука в диапазоне -3/3 (что, я думаю, более чем необходимо).
РЕДАКТИРОВАТЬ: Добавление личного исследования. Кажется, высота тона 1 является исходной нотой, а установка на 2 дает тот же ключ на октаву выше.
Поскольку хроматическая шкала (все черно-белые ноты на пианино) состоит из 12 клавиш, я предполагаю, что использование 1/12 для каждого шага должно сделать это.
Звучит близко, но я упал не совсем правильно. Вот новый код:
[SerializeField] private AudioSource audio;
float step = 1f/12f;
KeyCode[]keys = new KeyCode[]{
KeyCode.Q, KeyCode.W,KeyCode.E,KeyCode.R,KeyCode.T,
KeyCode.Y, KeyCode.U, KeyCode.I, KeyCode.O, KeyCode.P,
KeyCode.A, KeyCode.S, KeyCode.D
};
void Update ()
{
float f = 0.0f;
foreach (KeyCode key in keys)
{
CheckAudio(key, f);
f += 1f;
}
}
void CheckAudio(KeyCode key, float pitch)
{
if (Input.GetKeyDown (key))
{
audio.pitch = 1f + pitch * step;
audio.Play ();
}
}
1 ответ
То, что вы пытаетесь сделать, не сработает, просто изменив высоту звука. Изменяя высоту звука, вы столкнетесь с другими проблемами, такими как слишком быстрое завершение звука или более длительное время, и звук также не будет хорошим.
Первое решение - создать плагин (Synthesizer) на C++, который читает аудиофайл из Unity и меняет частоту. Также следует выполнить другие действия, чтобы исправить проблемы со скоростью. Это очень сложно, если вы не звукоинженер с отличными математическими навыками. И попробовать это на мобильном устройстве - это совсем другая история. OnAudioFilterRead - это функция, которую вы должны использовать, если решите использовать этот метод.
Второе и рекомендуемое решение - создать аудиофайл для каждой клавиши гитары, а затем поместить их в массив audioClip
, Это решает все остальные проблемы. Недостатком является то, что у вас будет больше файлов.
РЕДАКТИРОВАТЬ:
Если вас не волнует, что он идеален, вы можете использовать что-то ниже от этого хорошего парня в Интернете.
void playSound(){
float transpose = -4;
float note = -1;
if (Input.GetKeyDown("a")) note = 0; // C
if (Input.GetKeyDown("s")) note = 2; // D
if (Input.GetKeyDown("d")) note = 4; // E
if (Input.GetKeyDown("f")) note = 5; // F
if (Input.GetKeyDown("g")) note = 7; // G
if (Input.GetKeyDown("h")) note = 9; // A
if (Input.GetKeyDown("j")) note = 11; // B
if (Input.GetKeyDown("k")) note = 12; // C
if (Input.GetKeyDown("l")) note = 14; // D
if (note>=0){ // if some key pressed...
audio.pitch = Mathf.Pow(2, (note+transpose)/12.0);
audio.Play();
}
РЕДАКТИРОВАТЬ: Для тех из вас, кто интересуется, почему уравнение Mathf.Pow используется и работает, прочитайте следующее: https://en.wikipedia.org/wiki/Twelfth_root_of_two