[K] Moje narzędzia - epilog?

Dzisiaj naprawdę ostatnia już porcja narzędzi, które powstały na przestrzeni ostatnich miesięcy (albo i tygodni, jeśli chodzi o normalizację). To głównie skrypty w Pythonie, które robią różne męczące i czasochłonne rzeczy - ale może mniej będzie o samych skryptach, co potrzebach za nimi stojących. Chciałbym bowiem podkreślić, że te narzędzia nie powstają tylko po to, by powstać - one faktycznie mi się przydają i rozwiązują realne problemy.

Okładki

Kiedy ktoś tworzy dużo filmów na YouTube, z pewnością zgrzyta zębami na konieczność przygotowania okładek i opisów. Stosuję w tym wypadku dwa osobne podejścia - na kanał GadesMusic tworzę okładki w zasadzie ręcznie, korzystając z Affinity Designera. Znajduję zazwyczaj obraz (albo jakieś swoje zdjęcie), wpisuję tytuły i podtytuły, renderuję i dopiero gotową okładkę łączę z plikiem audio w celu wygenerowania pliku mp4 (kiedyś robiłem to zupełnie ręcznie, o czym można sobie nawet poczytać). Tak można robić, gdy do przygotowania jest jedno nagranie na tydzień, ale nie, jeśli czasem wrzucam kilka nagrań jednego dnia i w dodatku chciałbym samą okładką przekazać maksymalnie dużo informacji.

Już w lutym opisywałem, jak mniej więcej wygląda tworzenie okładek na kanał GadesTester - przygotowałem sobie parę teł, połączyłem nazwy bibliotek z graficznymi "tasiemkami" i dodałem "typy" okładek. Wszystko to jednak było dość brzydko zrealizowane, dużo rzeczy przechowywałem w kodzie i w zasadzie każda zmiana (np. dodanie nowej biblioteki) powodowała, że trzeba było zmieniać kod skryptu.

Poświęciłem zatem dzień lub dwa, by rzecz "wyprostować". Okładki są teraz definiowane przez szablony w plikach json, gdzie mogę swobodnie nakładać na siebie warstwy graficzne (z różną przezroczystością i sposobem krycia) oraz warstwy tekstowe. Wszystkie te elementy są teraz bytem o nazwie "box", który to element można rozmieścić w stosunku do całej okładki albo innych elementów, co pozwoliło mi wreszcie uwolnić się od tego, że dotąd wszystko miałem pozycjonowane bezwzględnie i jeśli tytuł był długi, mógł nachodzić na nazwę biblioteki. Teraz mogę sobie ustawić, że tytuł jest np. 30 pikseli nad nazwą biblioteki, a nad nim 30 pikseli jest wykonawca. Sama nazwa biblioteki jest zaś pozycjonowana na 30 pikseli nad dolną krawędzią, więc jeśli teraz nazwa biblioteki będzie długa, przesunie się w górę, a razem z nią cała reszta.

W dodatku wprowadziłem sobie "dziedziczenie", bo większość okładek jest w zasadzie bardzo podobna, różnią się elementami graficznymi. Absurdem zatem było trzymać w każdej z nich osobno definicje "boksów" tekstowych (wielkość znaków, czcionka, kolory itp. powielone wielokrotnie). Teraz mam to zdefiniowane raz, w okładce "bazowej", gdzie jest uniwersalne tło i napisy, zaś okładki "dziedziczące" definiują własne tło i tyle.

W dodatku wybór konkretnego "boksa" do zastosowania uzależniłem od wartości tagów z pliku audio, więc przy generowaniu okładki wiadomo, że jeśli w określonym tagu jest wartość "keys", to szukamy odpowiedniej okładki powiązanej z taką wartością i już (stąd wystarczy jeszcze w Fender Studio Pro, przed renderowaniem, uzupełnić metadane projektu, a te dane znajdą się w pliku audio i posłużą później do generowania okładki). Profit podwójny, bo wreszcie mam (od miesiąca) porządnie opisane projekty w DAW - kompozytor, tytuł, biblioteka testowa, typ. Dzięki temu też mogłem zintegrować tworzenie okładki z Audio Viewerem - jeden klik i w oparciu o metadane tworzy się automatycznie okładka.

Normalizacja

Przyznam, że to był problem uwierający mnie od dawna. Przyjąłem założenie, że utwory na moich kanałach będą normalizowane do -15LUFS/-1TPdB. Dlaczego nie głośniej? Bo jednak utwory orkiestrowe są dużo bardziej zróżnicowane dynamicznie niż typowy pop/rock/hip-hop. Mamy zwykle cichutkie fragmenty, mamy też często tutti np. na końcu utworu. Specyfika LUFS-I sprawia, że mierzony jest cały utwór i tak dobierana jest jego głośność, by odczuwalnie był on porównywalny z innymi o tej samej głośności LUFS. W praktyce oznacza to, że te najgłośniejsze fragmenty będą naprawdę głośne i trzeba będzie je limitować, a to przy orkiestrach rzadko kończy się dobrze.

Inny problem to właśnie limitowanie - tak czy inaczej jest ono konieczne, choćby dla samego "bezpieczeństwa". Co robi limiter? Ścisza najgłośniejsze fragmenty, które aktywują jego próg. A do czego to prowadzi? Do zmniejszenia LUFS, tym większego, im więcej głośnych fragmentów zawiera utwór.

Dotąd zwykle robiłem rzecz ręcznie - wczytywałem plik do Acon Acoustica, normalizowałem "ciut za głośno", po czym przepuszczałem nagranie przez PSP Flare, który z kolei to "ciut" niwelował. Próbowałem używać ffmpeg, ale ten stosuje dynamiczne dopasowanie przy normalizacji (więc np. ciche fragmenty pogłaśnia mocniej), co prowadzi do "pompowania" (parę takich utworów niestety się przemknęło na GadesTester, zanim to wykryłem).

Ostatecznie napisałem własny skrypt, który działa dokładnie tak, jak tego oczekuję: najpierw mierzy głośność i wyznacza odpowiednią kompensację, żeby uzyskać -15LUFS. Zamiast jednak zapisać wynik, przepuszcza nagranie przez odpowiednio skonfigurowaną wtyczkę PSP Flare, ta robi limitowanie, po czym wracamy do początku - algorytm sprawdza głośność i jeśli nadal jest za mało, koryguje wzmocnienie i znów przepuszcza przez PSP Flare. I tak aż do momentu, kiedy znajdzie takie wzmocnienie, które po limitowaniu da -15LUFS (plus/minus 0.3LUFS, tak sobie przyjąłem, żeby nie wydłużać przesadnie procesowania).

Przeglądarka do plików .song

Czym są pliki song? To projekty Studio One i Fender Studio Pro, czyli odpowiednik np. plików cpr dla Cubase. A po co do nich zaglądać? Ano po to chociażby, żeby zobaczyć, jakich instrumentów się użyło. Albo ile trwa utwór. Albo czy używa wtyczek, których nie mamy zainstalowanych. W ostateczności też po to, by móc w awaryjnych sytuacjach wydobyć dane MIDI, jeśli projektu nie udaje się otworzyć w DAW.

W odróżnieniu od wspomnianego formatu cpr, format song to tak naprawdę spakowane archiwum z plikami xml, z których po śledztwie i znalezieniu powiązań można wydobyć wcale dużo informacji:

Dodałem też, rzecz jasna, wydobycie danych MIDI, które tracą wprawdzie część informacji (np. artykulacje), jednak zawsze to coś, zwłaszcza w przypadku prywatnych kompozycji.

Możliwość odczytania danych o pliku song daje jeszcze więcej możliwości - otóż sporządziłem sobie skrypt, który jest w stanie wyszukać mi utwory korzystające z konkretnej biblioteki, instrumentu czy wręcz wtyczki (np. pogłosu), mam też skrypt do wykrywania projektów korzystających ze starych wtyczek, których już obecnie nie używam.

Strony do wyszukiwania utworów

O tym pisałem dosłownie kilka dni temu. Przygotowałem strony, które służą mi (ale w zasadzie mogą służyć każdemu) do wyszukiwania utworów, np. z GadesTester. Przygotowanie samych stron to jedno, ale trzeba było też napisać skrypt, który specjalnym kluczem API dostanie się do danych z YouTube - niestety, nie da się linków w prosty sposób pobrać wprost z żądania HTTP na przykład (pomijam już tu fakt, że przy żądaniu HTTP warto być zalogowanym, bo inaczej wszystko zakłócą reklamy itp.).

Tak czy owak, musiało powstać narzędzie, które pobierze dane z YouTube, zapisze je w jakiejś zrozumiałej postaci i umieści na serwerze WWW, żeby stronki mogły z tych danych korzystać. Wybrałem ten sposób, bo unikam obciążania YouTube'a żądaniami z mojej domeny, ponoć przy przekroczeniu jakiegoś progu YouTUbe może przestać realizować żądania, bo uzna, że to naruszenie zasad. W każdym razie wolałem nie ryzykować, a wystarczy skrypt odpalić raz dziennie albo po każdym wrzuceniu partii filmów i dane na stronkach są aktualne.

Konwersja MIDI na MP3

Do testów instrumentów klawiszowych, ze względu na niewystarczające umiejętności, muszę używać plików MIDI. Zgromadziłem ich bardzo dużo, owszem, jednak te najbardziej znane już wykorzystałem, więc pozostały mi głównie utwory, których po prostu nie znam. Otwieranie plików MIDI w DAW, żeby tylko ich posłuchać, jest irytujące, więc przez jakiś czas używałem specjalnej wtyczki do foobara2000, czyli foo_midi. Da się ją skonfigurować tak, by korzystała z wtyczek VST (chciałem mieć realny dźwięk fortepianu, a nie "plumkanie" z syntezatora FM). Wypróbowałem Arturia Piano V3 oraz Pianoteq i teoretycznie działały dla pojedynczych utworów, jednak przy próbach odtwarzania całych playlist czy skokach między utworami czasem zanikał dźwięk, a czasem... po prostu foobar się wysypywał...

Przez jakiś czas ratowałem się skojarzeniem plików MIDI z wersją standalone Pianoteq, ale czytając dokumentację odkryłem, że Pianoteq w tej wersji potrafi działać... w trybie wsadowym, gdzie można kazać wczytać mu plik MIDI, a następnie wyrenderować go z wykorzystaniem wskazanego presetu brzmienia do pliku wav lub mp3. Stąd już tylko krok dzielił mnie od napisania w Pythonie skryptu do masowej konwersji WSZYSTKICH posiadanych plików MIDI do postaci audio. Pokusiłem się nawet o wydobycie z nazw plików i katalogów metadanych - nazwisk kompozytorów i tytułów utworów, co z kolei umożliwiło mi także automatyczne generowanie "okładek" i przeprowadzenie normalizacji, by wszystkie te pliki wyglądały i brzmiały spójnie.

Script Commander

Liczba narzędzi rozrosła się do tego stopnia, że zaczęło mi brakować miejsca na belce narzędziowej w Total Commanderze. Postanowiłem zostawić tam tylko te najczęściej używane polecenia, resztę zaś przeniosłem do... nowego narzędzia, które mało odkrywczo nazwałem Script Commanderem:

Jest to "uruchamiacz" skryptów (pythonowych, CLI, PowerShell, w zasadzie bez ograniczeń). Dzięki niemu mogę sobie stworzyć hierarchię skryptów, pogrupowanych według funkcji i wyzwalać je jednym kliknięciem, bez konieczności uruchamiania PyCharma czy skakania do konkretnych katalogów w celu wyszukania odpowiedniego pliczku. Istnieje wprawdzie cała gama gotowych programów tego typu (choćby RoboTask), ale gdzie wtedy radość z programowania?

Sprzątanie

Ostatnie narzędzie, które zamierzam opisać, jest mało efektowne. To skrypt czyszczący - czyści zarówno katalog tymczasowy TEMP, ale także czyści katalog Songs z projektami Studio One i Fender Studio Pro. A po co go czyścić? Bo robi się w nim bałagan po pewnym czasie. Chodzi o to, na co zwykle narzekam przy DAW - tworzą one katalogi czy puste pliki, potrzebne im do zarządzania projektem i jego częściami. W efekcie po pewnym czasie mamy w katalogu roboczym pełno dziwnych pustych projektów, które tylko otworzyliśmy bez zapisu, pełne plików tymczasowych lub plików backupowych, pełne pustych katalogów. A że u mnie cały ten katalog jest na żywo synchronizowany z chmurą Google'a, to nie chcę niepotrzebnie marnować cennego (dosłownie cennego) miejsca.

Stąd właśnie pomysł na skrypt, który jest chyba najstarszym skryptem napisanym przeze mnie w Pythonie. Ma o listę katalogów z różnymi regułami (np. jeden czyści całkowicie, inny tylko z plików większych niż zadana wartość, inny z plików starszych niż jakiś okres) i uruchamia się raz dziennie, robiąc porządki (korzystam w tym celu z systemowego Harmonogramu zadań)

Podsumowanie

Hm, obawiam się, że ciągle nie wyczerpałem całej puli narzędzi, a pewnie w kolejnych tygodniach pojawią się nowe. Najlepszym rozwiązaniem będzie w takim razie zostawienie rzeczy ich biegowi - jeśli coś fajnego będę miał do opisania, to to opiszę, na razie skończę w tym miejscu.

Komentarze