• Witamy w największym polskim serwisie internetowym poświęconym w całości zagadnieniom samodzielnej budowy nagłośnienia.
    Dzięki DIYaudio.pl poznasz zagadnienia samodzielnej budowy nagłośnienia od podszewki oraz będziesz mógł dyskutować o DIY audio do woli.

    Artykuły z dawnego portalu zostały przeniesione do sekcji forum na samym dole.

Mój własny streamer/preamp: Reaktywacja (Alpha 0.10). Walka z materią i kodem

Rejestracja
Paź 3, 2022
Postów
23
Reakcji
3
Lokalizacja
Green Mountain City
Cześć wszystkim!

Od dobrych nastu lat zabieram się za produkcję własnego zestawu stereo. Kolumny, po ciężkich bojach, są już na ukończeniu – zostały detale i mam nadzieję, że w tym roku w końcu zamknę ten temat. Jednak wciąż z tyłu głowy siedzi mi autorski wzmacniacz/streamer.

Moja droga była kręta:

  1. Lampa: Najpierw marzył mi się prosty wzmacniacz lampowy (nawet 1W), ale o lampach wiem niewiele, a im więcej czytałem o transformatorach głośnikowych, tym szybciej przybywało mi siwych włosów.
  2. Gainclone: Później padło na projekt Gainclone z Arduino, ale czułem, że to zbyt ograniczone rozwiązanie.
  3. Volumio: Przez kilka lat używałem Volumio. Malinka leżała "nago" na komodzie i... tak leży do dziś. Nic się nie zmieniło.
Dziś mam już pełną świadomość ograniczeń sprzętowych i programowych. Właśnie uśmierciłem swoją 9. wersję projektu (Alpha 0.9). Dlaczego? Bo szukam czegoś więcej niż "gotowca".

O co walczę?​

Nie interesuje mnie radio internetowe z pogodą, polityką i durnymi komentarzami dziennikarzy. Odpaliłem RMF – działa, ale to potrafi nawet kalkulator. Znalazłem stację Trance Pulse, która nadaje w wysokiej jakości i tu mój projekt poległ – po każdym utworze przepełniał się bufor i system stawał "jak widły w gnoju".

Volumio i podobne softy są super, jak chcesz tylko streamingu (Spotify, YT i koniec). Mój projekt idzie o krok dalej:

  • Serce: Początkowo miał być STM32, ale uznałem, że to walka z wiatrakami. Wybrałem Raspberry Pi 3B (wersja bez Wi-Fi, co mi nie przeszkadza).
  • DAC: Aktualnie PCM5102. Docelowo planuję PCM5122 lub jakieś dedykowane DSP, jak budżet pozwoli.
  • Analog Input (To mnie odróżnia!): Realizowane na PCM1808. Nie znalazłem niczego lepszego/tańszego, co trzymałoby przyzwoitą jakość przy wprowadzaniu analogu do cyfry.
  • Selektor wejść: Szalony pomysł na przełącznik analogowy 4:1 sterowany po szynie I2C. Pierwsze wejście będzie dedykowane pod gramofon.
  • Digital In: Planuję wejście SPDIF jako czwarte źródło (prawdopodobnie przez prosty przetwornik D/A, żeby sprowadzić to do wspólnego mianownika). Później może cos lepszego
  • Bluetooth: jako ostanie wejście.
Dodatki typu dotykowy ekran czy enkodery to dla mnie oczywistość – to ma być solidny, stacjonarny streamer.

Główny wróg: Oprogramowanie​

O ile Linux sam w sobie jest przewidywalny, to soft audio ma własne życie. Albo gra muzyka, ale nie działa korektor, albo podpięcie enkodera pod GPIO gryzie się z przerwaniami audio i wszystko trzeszczy.

W poniedziałek startuję z wersją Alpha 0.10. Mam nadzieję, że to ostatnia prosta. Plan na start jest minimalistyczny:

  1. Stabilne radio internetowe.
  2. Interfejs webowy do podstawowego sterowania (wgrywanie/usuwanie stacji).
Większość gratów już mam na stole. Jeśli ktoś z Was budował coś podobnego, walczył z implementacją wejść analogowych w malinie albo ma sprawdzone sposoby na stabilne bufory przy streamingu Hi-Res – będę wdzięczny za każdą wskazówkę, przemyślenia, a nawet konstruktywny hejt.

Wrzucam link do repozytorium (wszystko Open Source). Polecam gałąź new_project, bo tam dzieje się najwięcej:🔗 https://github.com/xtreamx2/streamer

Fotki z postępów wrzucę niebawem. Co o tym sądzicie?

PS. Ekran będzie obsługiwany przez RP2040 - bo musi działać nawet jak Raspberry będzie wstawać. To interakcja już będzie od strzała.

ps2 - Repo jeszcze nie dostepne na gicie - EDIT, Już jest.

v0.10.1 :
- widok jak na dole - interfejs WWW.
- działa Radio
- uruchomiona obsługa bluetooth
- stabilne 60st na procesorze (optymalna praca)

bug:
- problemy z interface
- czasami apka zailcza crush
- znikające podstrony

Zrzut ekranu 2026-03-11 114619.png

Zrzut ekranu 2026-03-11 114629.png

Zrzut ekranu 2026-03-11 114648.png

2026-03-09 13:22:30,182 INFO [__main__] Inicjalizacja managerów...
2026-03-09 13:22:30,184 INFO [core.uart_manager] UART start: /dev/ttyAMA0 @ 115200
2026-03-09 13:22:30,185 INFO [core.uart_manager] UART connected: /dev/ttyAMA0
2026-03-09 13:22:30,190 INFO [__main__] Przywracanie ostatniego źródła...
2026-03-09 13:22:30,191 INFO [core.source_manager] Switch: None → radio
2026-03-09 13:22:30,194 INFO [core.source_manager] Active: radio
2026-03-09 13:22:30,266 INFO [__main__] Streamer v3.0 — http://0.0.0.0:8000
2026-03-09 13:22:30,267 INFO [__main__] ALSA: hw:sndrpihifiberry,0
2026-03-09 13:22:30,267 INFO [__main__] UART: /dev/ttyAMA0 @ 115200
* Serving Flask app 'app'
* Debug mode: off
2026-03-09 13:22:30,279 INFO [werkzeug] WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:8000
* Running on http://192.168.1.71:8000
2026-03-09 13:22:30,279 INFO [werkzeug] Press CTRL+C to quit
2026-03-09 13:22:30,536 INFO [sources.radio] Radio play: http://stream.trance.ie:8000/tpmixes
2026-03-09 13:22:30,613 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:30] "GET /api/status HTTP/1.1" 200 -
2026-03-09 13:22:30,635 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:30] "POST /api/radio/play HTTP/1.1" 200 -
2026-03-09 13:22:30,959 INFO [sources.radio] Decoder: audio/x-raw
2026-03-09 13:22:30,977 INFO [sources.radio] Title: Ana Criado — Still There's You (A.R.D.I. Remix)
2026-03-09 13:22:33,579 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:33] "GET /api/status HTTP/1.1" 200 -
2026-03-09 13:22:37,104 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:37] "POST /api/volume HTTP/1.1" 200 -
2026-03-09 13:22:37,812 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:37] "POST /api/volume HTTP/1.1" 200 -
2026-03-09 13:22:38,558 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:38] "GET /api/status HTTP/1.1" 200 -
2026-03-09 13:22:41,149 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:41] "POST /api/volume HTTP/1.1" 200 -
2026-03-09 13:22:41,770 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:41] "POST /api/volume HTTP/1.1" 200 -
2026-03-09 13:22:42,042 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:42] "POST /api/volume HTTP/1.1" 200 -
2026-03-09 13:22:42,297 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:42] "POST /api/volume HTTP/1.1" 200 -
2026-03-09 13:22:43,582 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:43] "GET /api/status HTTP/1.1" 200 -
2026-03-09 13:22:48,562 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:48] "GET /api/status HTTP/1.1" 200 -
2026-03-09 13:22:53,550 INFO [werkzeug] 192.168.1.84 - - [09/Mar/2026 13:22:53] "GET /api/status HTTP/1.1" 200 -
 
Ostatnia edycja:
Changelog:

v0.10.3.35:
EQ save
Spectrum/VU
- naprawiony regex w initMeterMode, timeout skrócony do 500ms
SD card - _save_config(debounce=True) dla EQ/gain/last_source — max 1 zapis co 5s; volume zapisuje natychmiast
Bitrate FLAC - teraz próbuje bitrate, nominal-bitrate, maximum-bitrate po kolei
Mono - usunięty z UI całkowicie

v0.10.3.34:
EQ save 500
- active_id() nie istniało, zastąpione active_source().SOURCE_ID
werkzeug logi - wyciszone (tylko WARNING+), błędy będą widoczne w journalctl
loadUserPresetNames - usunięty duplikat
Gain per wejście - suwaki -10..+6 dB w Settings → "Gain wejść"
Auto Gain - przywrócony z nową logiką CLIP

v0.10.3.33:
500 na /api/status
- _last_rx był niezdefiniowany w __init__, stąd AttributeError
_meterBusy guard - przeniesiony do scope globalnego, teraz naprawdę blokuje kolejne requesty
Auto Gain - przywrócony z etykietą i opisem; logika: przy CLIP (peak ≥ -0.1 dBFS) obniża gain o 1dB i zapisuje
Gain per wejście - suwaki -10..+6 dB w sekcji "Gain wejść" w Settings; stosowany jako pre-gain przy każdym przełączeniu źródła
Naprawione etykiety Mono w ustawieniach

v0.10.3.32 - bug APP (część modułów zaliczyło crash):
VU
- RMS bar bezpośrednio (bez smoothing) = dynamiczne
User1/User2 preset - PRESETS w JS ma user1/user2, loadUserPresetNames() wczytuje gains z serwera, saveUserPreset aktualizuje lokalnie po zapisie
Auto Gain - usunięty z UI (nie był zaimplementowany)
UART status - active zamiast connected — OK tylko gdy RP2040 przysłał dane w ostatnich 30s
WiFi toggle - przyciski w Network page

v0.10.3.31:
Edit → Direct
- przycisk naprawiony (był zduplikowany w pliku)
VU peak - teraz śledzi max RMS (nie surowy peak z GStreamer który zawsze jest blisko 0dB), płynne RMS bar, 2s hold
IP - eth0 ma priorytet nad wlan0
WiFi - przyciski "WiFi OFF/ON" i "Rozłącz" w Network page
streamer.service - wersja aktualizowana automatycznie

v0.10.3.30:
ERR_CONNECTION_RESET
- initMeterMode z 2s opóźnieniem, serwer ma czas się uruchomić
Peak hold - timestamp-based (1.5s hold, potem płynne opadanie), nie zależy od szybkości animacji
Spectrum - warunek hasFft sprawdza czy jakiekolwiek pasmo > -58 (nie tylko pierwsze)
streamer.service - wersja zsynchronizowana z app.py, usunięty zduplikowany After=

v0.10.3.29 - bug APP (nie włącza się):
Direct
- przycisk zastępuje Edit w sekcji EQ; aktywny = bypass EQ (wszystkie pasma 0) + ignoruje loudness
User 1 / User 2 - presety EQ w ustawieniach; "Save →" zapisuje bieżące nastawy, "Rename" zmienia nazwę
initMeterMode - spectrum/VU włącza się automatycznie przy ładowaniu strony

'''
loudness w tym projekcie jest tylko jako preset EQ (zestaw gainów) - nie jest jeszcze stosowany jako dodatkowa korekta na bieżący preset.
'''

v0.10.3.25-28:
- ciągła poprawa spectrum analizator
- spectrum 16 pasm zamiast 32 (string ~590 znaków, mieści się w to_string()), czysty regex parse.
- spectrum fix: zamiast get_value('magnitude') (które crashuje na GstValueList), parsujemy structure.to_string() przez regex.

v0.10.3.24:
VU zawieszanie
- _meterBusy guard - pomija request jeśli poprzedni nie wrócił, eliminuje kolejkowanie
Peak hold - JS-owy hold 1.5s + płynne opadanie 0.8dB/frame, niezależny od serwera
Pipeline - level+spectrum przed EQ/vol (surowy sygnał)

v0.10.3.23:
Pipeline
- level i spectrum przeniesione przed EQ/vol — mierzą surowy sygnał, nie zależą od głośności
Peak-ttl - skrócony do 100ms (szybsze opadanie)
Spectrum - element teraz w prawidłowym miejscu pipeline, powinien wysyłać dane
IP - zawsze pobiera z eth0 pierwszego
Zakładka - Streamer · TrancePulse
Stream info - kHz i Stereo już w poprzedniej wersji

v0.10.3.22:
Zakładka
-Streamer · TrancePulse dla radia (nazwa stacji), Streamer · Bluetooth dla BT itd.
Stream info -kHz i Stereo/ch z GStreamer - BUG

v0.10.3.21:
Meters
- jeden endpoint /api/meters zamiast dwóch, polling co 100ms — koniec z ERR_CONNECTION_RESET
BT/Radio konflikt ALSA - bluealsa-aplay automatycznie zatrzymywany gdy radio aktywne, wznawiany gdy BT aktywne
Spectrum - te same dane, ale teraz serwer nie pada pod obciążeniem

v0.10.3.20:
IP
- fallback na eth0/wlan0/end0, zwraca IP niezależnie od interfejsu
Spectrum - prawdziwy FFT z GStreamer spectrum element (32 pasma), endpoint /api/spectrum, canvas rysuje realne dane - BUG
VU polling - 80ms zamiast 60ms

v0.10.3.19 changelog:
Bugfix:

-usunięty subprocess bluealsa-aplay z kodu, audio BT obsługuje teraz systemowy serwis.
Podsumowanie stanu BT:
bluealsa.service -daemon BlueZ A2DP
bluealsa-aplay.service -przekazuje audio na hw:sndrpihifiberry,0 (skonfigurowany przez override)
Streamer -obsługuje tylko parowanie/connect przez D-Bus, audio zostawia systemowi

v0.10.3.18 changelog:
Stacja
- przywracana przy starcie zawsze, oraz automatycznie gdy przełączasz z BT/innego źródła na radio
Głośność - przywracana do wszystkich sources przy starcie
Śmieciowy katalog - usunięty z paczki katalog z dziwną nazwą który wygenerował się przy okazji jakiegoś programu

v0.10.3.17 changelog:
Stacja
- przywracana zawsze przy starcie, niezależnie od last_source -BUG
BT audio - bluealsa-aplay w pętli wątkowej, automatycznie restartuje gdy telefon zaczyna/kończy grać - BUG
Spectrum - usunięty roundRect (niekompatybilny ze starszym Chromium), naprawiony rozmiar canvas - BUG

v0.10.3.16 changelog:
Spectrum/VU
- chip VU domyślnie on, container widoczny od startu - BUG
IP - usunięte błędne pole IP4 z nmcli - BUG
BT audio - bluealsa-aplay uruchamiany jako subprocess przy activate, zatrzymywany przy deactivate

v0.10.3.15 changelog:
Peak hold
- marker przeniesiony poza maskę CSS, biały z glow, widoczny
Spectrum - 32 pasma animowane przez requestAnimationFrame, kształt EQ-like (basy/górne wzmocnione), peak ticki białe, ten sam gradient co VU, płynne opadanie - BUG

v0.10.3.14 changelog:
- Gradient zawsze rozłożony na całej szerokości tracku (niebieski → żółty → czerwony)
- Ciemna maska CSS ::after odkrywa gradient proporcjonalnie do poziomu
- Peak marker biały z delikatnym glow - BUG
- Brak JS manipulacji kolorem — wszystko w CSS

v0.10.3.10 changelog:
- Sieć - naprawiony parser nmcli (obsługuje connected (externally)) - BUG
- Loudness - endpoint /api/setting + zapis w config + przywracanie przy starcie - BUG
- Ostatnia stacja radiowa - przywracana automatycznie po restarcie - BUG
- BT - auto-trust przy connect

v0.10.3 changelog:
New:
- parowanie BT
- W-Fi conect

Bugfix:
- Sieć - usunięte hardkodowane dane, dynamiczne ID, filtr BT z listy urządzeń
- Głośność - była zapisywana ale teraz też last_station_id jest zapisywane przy każdym play
- Ostatnia stacja - przywracana automatycznie przy starcie - BUG
- Loudness - prawdziwy endpoint /api/setting, zapisywany w config, przywracany przy starcie
- BT connect - auto-trust przed połączeniem - BUG

v0.10.2 changelog:
Bugfix:
- problemy z interface
- czasami apka zailcza crush
- znikające podstrony

v0.10.1 changelog:
- interfejs WWW.
- działa Radio
- uruchomiona obsługa bluetooth - BUG
- stabilne 60° na procesorze (optymalna praca)

bug:
- problemy z interface
- czasami apka zailcza crush
- znikające podstrony
 
Ostatnia edycja:
Zapowiada się pięknie.
Ja od kilku już lat przymierzam się do procesorowego sterowania magnetofonem szpulowym. HMMM- nadal się przymierzam. :)
 
Wczoraj przy kawie zacząłem się zastanawiać ile lat minęło od pierwszego pomysłu. Sam nie wierzę, ale to juz 14 lat...
Teraz nie wszystko działa idealnie, ale na tym etapie jestem mega zadowolony.
Liczylem na pomoc, a tu okazuje się ze wystarczyło MPD zamienić na GStreaming i jakoś działa.
Największą bolączką to wizualizacja. Na tym etapie wkuża, ale nie jest krytyczna.
Czekam na RP2040 - w końcu by zobaczyć czy główne założenie (dotykowy ekran) będzie działać z projektem.

Czas pokaże...
 
Powrót
Góra