Войти
ПрограммированиеФорумЗвук

Аудио визуализатор (эквалайзер) на Unity3d

#0
15:46, 27 фев. 2013

Привет!

Потребовалось сделать графический эквалайзер для игры на Unity3D. Со звуком работать не доводилось.
Эквалайзер должен представлять собой набор столбиков из кирпичеков, выстраивающихся вверх-вниз в такт музыке.

Я вижу это так. Unity предоставляет ф-ию GetSpectrumData(), которая возвращает массив float, каждый элемент которого равен от 0f до 1f.  http://docs.unity3d.com/Documentation/ScriptReference/AudioSource… trumData.html
По этим данным можно выстраивать высоту столбца. Например, у нас 64 столбика, значит в каждый кадр получаем GetSpectrumData() для 64 семплов, а затем каждый столбец "подпрыгивает" вверх в зависимости от соотвествующего значения массива, который вернёт GetSpectrumData(), где значению 0f соотвествует минимальной высоте стобца, а 1f - максимальной высоте.

Что я упустил или не так понимаю, поправьте, пожалуйста:)


#1
14:36, 28 фев. 2013

Камрады, никто не в курсе?

#2
22:29, 28 фев. 2013

Так в чем вопрос? Все правильно, делай :)

#3
2:45, 1 мар. 2013

Riddik
чтобы столбец эквалайзера плавно затухал, можно еще вот так сделать:

- вводишь переменную, которая отвечает за максимальную высоту столбца (maxRow = 0.0)
label:
- читаешь уровень
- если уровень больше maxRow, то maxRow = новый уровень
- строишь полосу из кирпичиков высотой maxRow
- уменьшаешь maxRow на один кирпич
- goto label

#4
11:02, 1 мар. 2013

имеешь значение спектра частот сигнала для текущего момента времени
и для каждой часотты с каким то шагом дискретной точности рисуешь амплитуду которая там же дожна возвращаться
всё

#5
11:08, 1 мар. 2013

Большое спасибо!!! Этого и ждал)

#6
13:37, 11 мар. 2013

The Andreyp
> и для каждой часотты с каким то шагом дискретной точности рисуешь амплитуду

Этот шаг задать для каждого столбца нужно?

spectrum = new float[64];
в Update():
audio.GetSpectrumData(spectrum, 0, FFTWindow.BlackmanHarris);
for(int i = 0; i < columns.Lenght; ++i) columns[i].Update(spectrum[i]);

GetSpectrumData() минимум возвращает 64 элемента спектра, у меня всего 42 стобика. Столбик на максимальной высоте, если spectrum равен 1f и не рисуется вообще, если spectrum равен нулю.
Беру для 42 столбцов первые 42 элемента spectrum[], получается, что только первый столбик более менее дрыгается вверх-вниз на ударных (бас), остальные бъёт почти одинаковая лихорадка в пределах одной пятой-четвёртой амплитутды.

Нужно ввести коэффициент для каждого столбца, на который будут умножаться spectrum?

Есть ещё вариант воспользоваться ф-ией GetOutputData(), которая Returns a block of the currently playing source's output data. Тогда все столбики прыгают повыше, но почти все одинаково.

Подскажите, пожалуйста, как грамотнее?

#7
20:31, 25 апр. 2013

Надеюсь еще актуально) "лихорадка" скорее всего из-за того, что ты часто обновляешь спектр, обрабатывая малое количество семплов, поэтому неулавливаешь происходящее. Если частота звука 44100 Гц и частота обновления 30 раз, то получаем 44100/30 = 1470. Это примерное количество семплов, которые нужно обработать. Т.е. надо брать не 64 семпла, а например 1024, как в том же примере из Unity. Если тебе ненужно все 1024 значения, то при обработке можно брать, например, каждое 2ое (512 столбиков), либо каждое 16ое (64 столбика).
Также исходя из примера Unity, лучше брать логарифм от значения. Только не натуральный, а по основанию 10. Это переведет линейный уровень громкости в дБ (почти все анализаторы работают по этой шкале). Однако, надо учитывать, что логарифма от 0 несуществует. Должно быть как-то так:

float level;
for(int i = 0; i < columns.Lenght; ++i) {
  if ( spectrum[i] < 0.00001f )
    level = -100.0f
  else
    level = log10f( spectrum[i] ) * 20.0f;
  columns[i].Update(level);
}
В массиве columns будут значения от -100 до 0. При выводе добавляемое некое значение (например 50) и получаем высоту столбика (от 0 до 50). Если столбики почти всегда находятся наверху, то можно уменьшить это значение, и наоборот, если много внизу, то увеличиваем.
Также, как сказал Ruslan, для еще большей плавности можно сделать плавное угасание столбиков. Если при обновлении столбика новое значение больше, то присваиваем его. Если меньше, то текущее значение столбика уменьшаем на некую константу. Значение этой константы регулирует как быстро столбик будет угасать.

#8
20:44, 25 апр. 2013

fullspektr
Большое спасибо за такое подробное разъяснение!

ПрограммированиеФорумЗвук

Тема в архиве.