LINUX.ORG.RU

Визуализация музыки через FFT, визуально работает хуже чем на слух.

 , ,


1

1

Делаю подсветку для стола на адресной rgb ленте, пытаюсь визуализировать музыку, для этого использую FFT (разложение на спектр), а дальше на каждый светодиод вывожу цвет в зависимости от интенсивности звука в определенном спектре.

Это работает, но как-то коряво/слабо. Например https://www.youtube.com/watch?v=__TvPr_Wtvc с 14 секунды начинается «ритм» который я явно слышу на слух, но в спектре визуально я не замечаю ничего отчетливого (обновляю спектр 60 раз в секунду).

Попытки гуглить на английском приводят к готовым программам, либо плагинам для редакторов видео, меня же интересует теория и алгоритмы как это вообще сделать

★★★

Волноформу и спектрограмму в студию(можете сделать в audacity), да и чего вы конкретно ожидали ? если высокую динамику то это лучше волноформу визуализировать, ежели спектр, то там у вас тупо низкие частоты чаще фигурировать начинают, а всё остальное тупо может не быть заметным - плюс учтите поправку на физические возможности светодиодов и полагаю, что при нкоторой частоте вы по сути сделаете ШИМ и получите очень плавное поведение загорания-затухания

AKonia ★★
()
Последнее исправление: AKonia (всего исправлений: 1)
Ответ на: комментарий от izzholtik

хмм, большой спасибо, действительно что-то не так. синусоида одной частоты попадает сразу в несколько (~6) зон.

abs ★★★
() автор топика
Ответ на: комментарий от abs

что-то не так

А ты не спектр визуализуй, а разность от предыдущего такта.

anonymous
()
Ответ на: комментарий от AKonia

то там у вас тупо низкие частоты чаще фигурировать начинают

У меня нет музыкального образования, но вроде как в песне с 14 секунды ритм каким-то низкочастотным звуком и создается

плюс учтите поправку на физические возможности светодиодов и полагаю

Я предварительно вывожу информацию на компьютер, на нем и проверяю

что при нкоторой частоте вы по сути сделаете ШИМ и получите очень плавное поведение загорания-затухания

На данный момент я вывожу спектр на светодиоды, но я могу и поменять это, например написать алгоритм который пытается найти «такт» или «ритм» - а уже на основе этой информации как-то визуализировать

abs ★★★
() автор топика
Ответ на: комментарий от abs

на слух совпадает

А ежели всё-таки разницу от предыдущего такта по спектру применить?

anonymous
()
Ответ на: комментарий от abs

Я предварительно вывожу информацию на компьютер

Постройте график, сравните, может режете или не понимаете что-то, например преобразование как выполнете, готовой библиоткой или самописной ? Какой размер окна используете ? Хорошо было бы если вы построили спектрограмму того, что сами получаете или как минимум преобразование нескольких окон(во время интересующих скачков и после), в идеале бы просто код выложили - уверен так проще увидеть изъяны

AKonia ★★
()
Ответ на: комментарий от AKonia

Я использую https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getFloatFrequencyData

В документации написано что этот метод отдает последние обработанные 128 sample при запросе, я запрашиваю 60 раз в секунду.

https://ibb.co/Trr4GX7

(графики не идеально синхронизированны по оси Х)

в идеале бы просто код выложили - уверен так проще увидеть изъяны

Та у меня не прям чтоб много кода,

  const normalized = soundFrequenceArray.map(item => (item + 100) * 5); 

// Нормализирую значение с децибел в что-то близкое к 0-255



  return _.times(ledCount, (i) => {
    return rangeToColor(normalized[i] / 255) 
// 0-255 преобразовываю в 0-1, а 0-1 в цветовую карту. 
  });
abs ★★★
() автор топика
Ответ на: комментарий от AKonia

В документации написано что этот метод отдает последние обработанные 128 sample при запросе, я запрашиваю 60 раз в секунду.

Я ошибся или что-то не так понял. Я сам выбираю с помощью вот этого параметра https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize

щас пробую разные значения

abs ★★★
() автор топика
Ответ на: комментарий от abs

в целом похоже на правду, а касательно «узких» полос попробуйте увеличить размер окна, в аудасити оно у вас значительно больше, по умолчанию вроде 1024, да и знайте, что при частоте_выборки = 48 кГц для дорожки, частота смены значений (48000 / размер_окна) из-за чего в динамике при малом размере окна, например 200, вы получите частоту мерцания 240 Гц, поэтому узких полос ваш глаз не увидит(особенно при контрастном мерцании от очень тусклого до яркого), поэтому рекомендую взять размер окна 1024-2048, ну или

размер_окна = частота_дискретизации / желаемая_частота_обновления`, 
например 48000 / (60 Гц) = 800

Это пропадание вполне естественная вещь для кусочного ПФ, т.к. высокочатотная выборка окон гасит высокие частоты(т.к. в приближении получаются весьма гладкие низкочатотные сигналы) или другими словами уменьшает разрешение по частоте, в целом уменьшая размер окна вы повышаете разрешение по времени, но снижаете по частоте и наоборот.

AKonia ★★
()
Последнее исправление: AKonia (всего исправлений: 8)
Ответ на: комментарий от abs

вроде как в песне с 14 секунды ритм каким-то низкочастотным звуком и создается

Там бочка ~50 Гц, но параллельно ей ещё бас, так что у нужного тебе сигнала ДД всего около 10-15 дБ. То есть надо постараться, чтобы не промазать с порогом. И в каждой песне надо будет свой ставить, или что-то адаптирующееся выдумывать (тут будет полезно знать, что бочка обычно самая сильная по амплитуде). Про размер окна правильно советуют. Либо частоту дискретизации уменьшай, чтобы меньше считать, если тебе только низкие частоты нужны. Ещё и лаг меньше будет.

anonymous
()

интересует теория и алгоритмы как это вообще сделать

The Canonical Csound Reference Manual ©.

quickquest ★★★★★
()
Ответ на: комментарий от abs

А сколько светодидов всего?

синусоида одной частоты попадает сразу в несколько (~6) зон.

Это называется растекание спектра. Чтобы такого не было, нужно входные данные умножать на оконную функцию.

А чтобы не было хаотичного мерцания, нужно сделать накопление с усреднением, можно скользящее.

Puzan ★★★★★
()
Ответ на: комментарий от Puzan

А сколько светодидов всего?

2 метра, 60 светодиодов

Чтобы такого не было, нужно входные данные умножать на оконную функцию.

У меня почти нет параметров у функции которая возвращает результат FFT, я могу воспользоваться функцией которая возвращает RAW звук и сам написать FFT, но не уверен насколько это будет медленнее

abs ★★★
() автор топика

Добавь усреднение по последним ~20 окнам fft и бери окна из сигнала с перекрытием (overlap) в 3/4 окна. При обработке каждого следующего окна нужно заново пересчитывать усредненные бины спектра по последним 20 fft из истории (т.е. не на каждые 20 окон визуализировать, а на каждое 1 окно)

anonymous
()
Ответ на: комментарий от abs

На 60 отсчетов можно и вручную посчитать, медленно не будет.

Совет анонимуса про перекрытие не слушай, не нужно оно тебе. Тем более на 3/4 (откуда эта цифра?).

Puzan ★★★★★
()
Ответ на: комментарий от Puzan

А чтобы не было хаотичного мерцания, нужно сделать накопление с усреднением, можно скользящее.

Совет анонимуса про перекрытие не слушай, не нужно оно тебе

Это тоже самое.

anonymous
()
Ответ на: комментарий от Puzan

Посмотрел у себя в коде, там такое перекрытие. Подобранно на глаз чтобы был красивый спектр.

    FftDataProcessingSettings fftSet;
    fftSet.mode = FftDataProcessingMode::i;
    fftSet.fftSize = 4096;
    fftSet.skipSize = 0;
    fftSet.overlap = 3072;
    fftSet.average = 20;
    fftSet.sampleRate = 48000;
    fftSet.sampleSize = FftDataProcessingSampleSize::qint16x2;
    fftSet.windowMode = FftDataProcessingWindow::BlackmanWindow;
    fftSet.reverseIQ = false;
    fftSet.freqOffset = 0;

Вроде вполне адекватно спектр движется если настроить приемник на АМ станцию с музыкой.

anonymous
()
Ответ на: комментарий от anonymous

Наверное потому, что у тебя длина блока 1/10 секунды, без перекрытия нет плавности картинки. Зачем тебе, кстати, такой большой размер?

Puzan ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.