← strona główna

Przyspieszenie godziny nagrania do jednej sekundy przez resampling i przez wycinanie fragmentów ze źródłowego pliku.

Rekonstrukcja metody generowania dźwięków w utworze Johannesa Kreidlera pt. „Compression music”.

Podejście 1. Przyspieszanie odtwarzania (resampling sygnału cyfrowego)

Przykład z nagraniem muzyki (Fryderyk Chopin, Koncert fortepianowy f-moll, cz. 3, Marta Argerich – fortepian).

Fragment oryginalnego nagrania:

Ściśnięcie (kompresja) w proporcji 1:3600 (godzina oryginalnego nagrania to sekunda skompresowanego dźwięku):

W istocie w tej częstotliwość próbkowania została przemnożona przez współczynnik 3600. Przykładowy kod w języku matlab:

fn = "chopin-fmoll-cz3-agerich.wav";
fs = audioinfo(fn).SampleRate;
ratio = 3600;
x = audioread (fn); % odczyt sygnału
x = mean (x, 2); % monofonizacja
y = resample (x, 1, ratio); % przeskalowanie sygnału
y = y / max(abs(y)); % normalizacja amplitudy
dst = strcat (fn, '-resample.wav');
audiowrite (dst, y, fs); % zapis do pliku

Jak widać (słychać) ta metoda nie prowadzi do rezultatów przedstawionych przez Kreidlera.

Podejście 2. Zestawianie krótkich fragmentów nagrania

W tym wypadku z nagrania źródłowego pobierane są co pewien odstęp czasu krótkie fragmenty, długości ułamka sekundy, które następnie sklejone są ze sobą w wyjściowy sygnał cyfrowy.

Fragmenty długości 10 ms:

Fragmenty długości 15 ms:

Fragmenty długości 50 ms:

W tym wypadku w tak „skompresowanej” muzyce można wysłyszeć brzmienie klasycznej orkiestry.

Kod w języku matlab:

fn = "chopin-fmoll-cz3-agerich.mp3";
x = audioread (fn); % czytanue pliku
fs = audioinfo(fn).SampleRate; % częstotliwość próbkowania
len = .050; % długość fragmentu w sekundach
lenSmpl = round(len * fs); % długość fragmentu w samplach
fadeLen = 50; % sciszenie na krańcach fragmentów w samplach
fadein = linspace (0, 1, fadeLen)'; % linie fade in
fadeout = flipud (fadein); % linie fade out
sek = 1; % długość wynikowego dźwięku w sekundach
num = round (sek / len); % liczba fragmentów do złączenia
distances = round (length(x) / (num + 1)); % odstępy pomiędzy fragmentami
X = []; % pojemnik na docelowy dźwięk
for k = 1 : num
    frgmStart = round ((k - 1) * distances + 1); % indeks początku fragmentu
    frgmStop = frgmStart + lenSmpl - 1; % indeks końca fragmentu
    frgm = x (frgmStart:frgmStop, :); % pobranie fragmentu
    for ch = 1 : size (x, 2) % sciszenie na krańcach
        frgm(1:fadeLen, ch) = frgm(1:fadeLen, ch) .* fadein;
        frgm(end-fadeLen+1:end, ch) = frgm(end-fadeLen+1:end, ch) .* fadeout;
    end
    X = [X; frgm]; % dodanie fragmentu
end
X = X ./ max(abs(X(:))); % normalizacja
dst = strcat (fn, '-fragmenty-', num2str(len), '.wav'); % plik docelowy
audiowrite (dst, X, fs); % zapis do pliku

Nagranie głosu ludzkiego

Podobna procedura ale z nagraniem lektora (takich nagrań również użył Kreidler):

Fragment sygnału źródłowego (Stephen King, Ciężarówka wuja Ottona, ze zbioru Szkieletowa załoga, nagrane przez Leszka Teleszczyńskiego i wydane w 2011 roku przez Fundację Klucz):

Resampling (przyspieszenie 3600 razy):

Jako test, obniżenie tak przyspieszonego sygnału o 6 oktaw:

Również bez sukcesu.

Pobieranie fragmentów nagrania w odstępach czasu:

Fragmenty długości 5 ms:

Fragmenty długości 10 ms:

Fragmenty długości 15 ms:

Fragmenty długości 25 ms:

Fragmenty długości 35 ms:

Fragmenty długości 50 ms:


Autorstwo kodu: Marcin Strzelecki