Dobry algorytm do rysowania prostej wersji fali ścieżki dźwiękowej

0

Mam 10MB-plik dźwiękowy .wav, i zebrałem jej sample, leci 16000/s. Chcę ją wyświetlić jako fala dźwiękowa, na razie napisałem program w rubym, gtk żeby pokazać takie coś:

screenshot-20220720202255.png

I to co robię, to po prostu iteruję po każdym bajcie z tego 10MB wave'a, kroję go na kawałki, w tym wypadku jak obrazek ma np 200 pikseli, to 10Mb/200=50Kb, i potem wyciągam średnią geometryczną z tych bloczków, i to jest wysokość mojego jednego słupka.

Niestety ten algorytm nie jest wydajny, bo wygenerowanie takiej fali dla Mb pliku zajmuje na moim kompie około 400-700ms.

Jest jakiś lepszy, szybszy sposób? Wiadomo, że im większy plik tym to będzie dłużej trwało, typu np. 1GB wave by się generował pewnie dłużej. Ale chciałbym po prostu ogarnąć coś, co pewnie jest prostsze, a będzie wydajne.

1

Problem już jest w popularnym, aczkolwiek mało profesjonalnym słowie "fala". Więcej wropowadza nieporozumień, niż rozjaśnia.

a) jeśli "fala" jako odwzorowanie dzwięku (jednostajny gwizd z gwizdka - sinusoida), to pewnie by jakiś filtr dolnoprzepustowy na ok połowie/poniżej częstotliwości próbkowania (patzr cz. Nyquista)
Ale praktyce sygnałów z jedną stałą częstotliwością (długo utrzymaną) prawie nie ma, są złożenia wielkiej (bardzo wielkiej) ilości częstotliwości, zmiennych co do siły w czasie (a modulacja zwiększa pasmo). W pewnym momencie stajemy przed bezsensem pełnego bezrefleksyjnego odwzorowania. Pamiętam, na ćwiczeniach z fizyki mieliśmy nadzieję zobaczyć na oscyloskopie fajny "riff" gitary elektrycznej.
Bezsens, ale to była zabawa.
Moze próbkę jednej sekundy, czy podobną, ale nie cały czas i w czasie rzeczywistym, to nie jest do niczego (znanego mi) użyteczne.

Gdyby jednak to robić, to teoretycy sygnału mają olbrzymi dorobek matematyczny, co i jak liczyć, aby się nie zaliczyć na śmierć.

b) jeśli obwiednia, to inna rozmowa, mówimy o wartości bezwzględnej ... ba, tylko z czego? Średnia ważona z X sekund? Średnia z ułamka sekundy?
Hold-peak, czyli wyższe wartości sa ważniejsze, są na dłużej utrwalane, niż mniejsze?
Każdy z tych modeli ma swoje zasłużone miejsce w elektroakustyce, jest wiele zasad wykonywania pomiarów.

0

Ludzie generują spectogramy czyli co jedną sekundę generują wykres wszystkich częstotliwości od zera do 10 tyś i im większa częstwotliwość danej częstotliwości tym bardziej czerwony kolor.

1

Nie robiłem nigdy czegoś takiego, ale tak sobie googluję:

https://supermegaultragroovy.com/2009/10/06/drawing-waveforms/
tutaj gościu pisze o redukcji sampli. Czyli on wtedy nie przechodzi przez każdą próbkę, tylko wyrzuca większość próbek.
Chociaż dalej też pisze, że bierze średnią albo maksimum (poczytaj).

0
LukeJL napisał(a):

Nie robiłem nigdy czegoś takiego, ale tak sobie googluję:

https://supermegaultragroovy.com/2009/10/06/drawing-waveforms/
tutaj gościu pisze o redukcji sampli. Czyli on wtedy nie przechodzi przez każdą próbkę, tylko wyrzuca większość próbek.
Chociaż dalej też pisze, że bierze średnią albo maksimum (poczytaj).

No ja też właśnie biorę średnią i wolno to działa.

Ten artykuł to jest dokładnie to czego szukałem. Dzięki

0

Ściągnąłem sobie przykładowy dźwięk, z freesound.org, i tam był już narysowany waveform. Chciałem taki sam narysować u siebie w programie, i wyszło mi coś innego.

screenshot-20220722014508.png

Z tego pierwszego wave forma, widać gdzie jest dźwięk i głos, z tego mojego nie widać. :/

Dźwięk trwa około 1:20 min, z czego jest 7mln. ramek, wychodzi około 8000 ramek na jeden piksel (słupek). średnia geometryczna/arytmetyczna z tego słupka, to nie jest dobry algorym, bo efekt jaki jest kazdy widzi.

0

tu masz projekt co prawda bardzo stary i w c# ale algorytm sobie może z tego wyciągniesz https://www.codeproject.com/Articles/4838/WaveControl
nie testowałem na ile jest szybki, widzę że wspiera tylko 16b i mono więc trochę pracy trzeba jeszcze włożyć

0
import scipy.io.wavfile as wav
import matplotlib.pyplot as plt
import numpy as np


file = 'sound.wav'
samplerate, data = wav.read(file)


time = np.linspace(0, data.shape[0]/samplerate, data.shape[0])
plt.plot(time, data)
plt.show()

Sprawdziłem sobie jakiś plik wav u siebie, rysowane zwykłymi funkcjami liniowymi od punktu do punktu i wychodzi wszystko ładnie, może masz jakieś skalowanie, normalizację co zaburza wygląd, albo jakiś filtr stosujesz bo widać, że baseline jest jakby przesunięty od zera.

1 użytkowników online, w tym zalogowanych: 0, gości: 1