Rename device identity from DigiRadio to igiRadio
SoftAP SSID, Bluetooth name, and mDNS hostname now use the "igiRadio" prefix (igiRadio-<serial>, igiradio-<serial>.local), matching the iOS app's name instead of the firmware project's repo name. Confirmed live: igiradio-CC4DB4.local resolves, the old digiradio-CC4DB4.local no longer does. Also adds the app-side briefs/notes accumulated today (active_source, volume contract, VU-meter polling, RDS availability) as a single up-to-date file to hand to Cursor. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -147,6 +147,35 @@ componente di riga, stesso stile, filtrato per banda.
|
||||
|
||||
---
|
||||
|
||||
## 4bis. RDS (nome stazione FM) — ora funziona davvero, da oggi
|
||||
|
||||
Fino a oggi il firmware non decodificava **mai** l'RDS (bug a tre livelli,
|
||||
risolto). Ora `GET /api/tuner/status` e lo scan FM completo possono
|
||||
restituire:
|
||||
|
||||
```json
|
||||
"fm": {
|
||||
"frequency_khz": 92100,
|
||||
"rssi_dbuv": 57,
|
||||
"snr_db": 40,
|
||||
"station_name": "M DUE O",
|
||||
"radiotext": "...testo libero..."
|
||||
}
|
||||
```
|
||||
|
||||
`station_name` e `radiotext` sono **opzionali** — compaiono solo dopo qualche
|
||||
secondo di ricezione stabile (l'RDS impiega tempo ad accumularsi), quindi
|
||||
possono mancare subito dopo una sintonizzazione. Mostrali quando presenti
|
||||
(es. nella card "Now Playing" e nella riga della lista stazioni FM),
|
||||
altrimenti mostra la sola frequenza come già fai.
|
||||
|
||||
Se durante l'ascolto normale (non solo durante lo scan) il nome stazione o il
|
||||
radiotext cambiano o compaiono per la prima volta, aggiorna la UI di
|
||||
conseguenza — l'utente ha chiesto esplicitamente un piccolo banner/notifica
|
||||
quando arriva un nuovo nome/messaggio RDS durante la riproduzione.
|
||||
|
||||
---
|
||||
|
||||
## 5. Stile UI — Apple, minimalista ma con una sezione grafica curata
|
||||
|
||||
- Componenti nativi SwiftUI: `Picker` segmented per la sorgente, `Slider` con
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
# Nota per Cursor — Volume master e VU-meter
|
||||
|
||||
Due punti precisi da correggere/implementare nell'app. Segui esattamente i
|
||||
contratti sotto, non improvvisare formati diversi.
|
||||
|
||||
Dispositivo di test: `http://192.168.1.62`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Volume master
|
||||
|
||||
**Endpoint**: fa parte del profilo audio completo, non ha una rotta a sé.
|
||||
|
||||
```
|
||||
GET /api/audio/profile -> legge lo stato attuale (incluso "master")
|
||||
PUT /api/audio/profile -> scrive il profilo COMPLETO
|
||||
```
|
||||
|
||||
Campo:
|
||||
|
||||
```json
|
||||
"master": {"left_db": 0, "right_db": 0}
|
||||
```
|
||||
|
||||
Regole obbligatorie:
|
||||
|
||||
1. **Range reale: da -96.0 a +12.0 dB.** Lo slider volume in UI non deve
|
||||
fermarsi a 0 dB — quello è solo "unity gain", non il massimo. Il massimo
|
||||
vero è **+12 dB**. Se oggi lo slider arriva solo a 0, è un limite messo
|
||||
nell'app, va tolto.
|
||||
2. **`PUT /api/audio/profile` sostituisce l'intero oggetto**, non solo il
|
||||
volume. Ogni volta che l'utente muove lo slider del volume, il body della
|
||||
PUT deve contenere ANCHE `active_source`, `eq` (tutte e 6 le bande) ed
|
||||
`enhancements`, con i valori correnti — non solo `{"master": {...}}`.
|
||||
Il modo corretto:
|
||||
- tieni sempre in memoria (o rileggi con GET) lo stato completo del
|
||||
profilo;
|
||||
- quando l'utente cambia il volume, aggiorna SOLO il campo `master` in
|
||||
quello stato locale;
|
||||
- invia l'intero oggetto aggiornato con PUT.
|
||||
3. Normalmente `left_db` e `right_db` vanno impostati **uguali** con un unico
|
||||
slider "Volume" (non serve un secondo controllo per il bilanciamento L/R,
|
||||
a meno che non venga chiesto esplicitamente).
|
||||
4. Valori fuori range (-96/+12) vengono rifiutati dal firmware con errore —
|
||||
clampa lato client prima di inviare.
|
||||
|
||||
Esempio completo di richiesta corretta (cambio solo il volume a -6 dB,
|
||||
tutto il resto invariato):
|
||||
|
||||
```json
|
||||
PUT /api/audio/profile
|
||||
{
|
||||
"active_source": "radio",
|
||||
"master": {"left_db": -6, "right_db": -6},
|
||||
"eq": [
|
||||
{"gain_db": 0, "center_hz": 20, "q": 1.414},
|
||||
{"gain_db": 0, "center_hz": 100, "q": 1},
|
||||
{"gain_db": 0, "center_hz": 400, "q": 1},
|
||||
{"gain_db": 0, "center_hz": 1000, "q": 1},
|
||||
{"gain_db": 0, "center_hz": 3000, "q": 1},
|
||||
{"gain_db": 0, "center_hz": 8000, "q": 1}
|
||||
],
|
||||
"enhancements": {"stereo_level": 0, "bass_level": 0}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. VU-meter
|
||||
|
||||
**Endpoint nuovo, disponibile da oggi**:
|
||||
|
||||
```
|
||||
GET /api/audio/levels
|
||||
```
|
||||
|
||||
Risposta (tutti i valori in dBFS, tipicamente negativi, 0 = fondo scala):
|
||||
|
||||
```json
|
||||
{
|
||||
"radio_in_left_db": -1.5,
|
||||
"radio_in_right_db": -1.5,
|
||||
"bluetooth_in_left_db": -0.9,
|
||||
"bluetooth_in_right_db": -1.0,
|
||||
"output_left_db": -1.9,
|
||||
"output_right_db": -2.0
|
||||
}
|
||||
```
|
||||
|
||||
Regole obbligatorie:
|
||||
|
||||
1. **Il firmware non fa polling né cache** — ogni chiamata GET rilegge live
|
||||
dal DSP in quel preciso istante. Se vuoi un meter che si aggiorna nel
|
||||
tempo, il polling periodico lo devi fare tu lato app.
|
||||
2. **Frequenza consigliata: ogni 200-500 ms**, non più veloce — ogni
|
||||
chiamata impegna il bus I2C del dispositivo per 6 letture sequenziali
|
||||
(una per meter, il chip ha solo 2 registri hardware di cattura).
|
||||
3. **Ferma il polling quando la schermata con i meter non è visibile**
|
||||
(es. `onDisappear` / quando l'utente cambia tab) — non lasciarlo attivo
|
||||
in background, non serve e spreca risorse sul dispositivo.
|
||||
4. `radio_in_*` sono il livello Si4684 (post-compressore), `bluetooth_in_*`
|
||||
il livello ESP32, `output_*` il livello dopo Bass Boost (prima del
|
||||
limiter finale) — utile per capire dove mostrare quale barra.
|
||||
5. Se la risposta HTTP non è 200 (es. 500), mostra i meter come "non
|
||||
disponibili" invece di un valore congelato/stantio.
|
||||
Reference in New Issue
Block a user