Newsgroup: it.comp.lang.c++
Titolo: xNeil: campionare e ascoltare in real-time

Innanzitutto un grande grazie! Perchč queste info le cercavo tempo fa e pur
avendo risolto, non mi era chiaro il tutto che tu hai spulciato nei minimi
particolari.
Ora io originariamente volevo fare un real-time dsp per la mia chitarra
elettrica (anche se ho gia un multieffetto), ma poi ho un po' lasciato
perdere, perchč in tutti i programmi che mi sono capitati sottomano c'era un
delay di un secondo e se provavo a diminuirlo, avevo l'audio tagliato.
Poi qualcuno mi ha detto che era un limite, proprio di sistema e che
probabilmente non si puň fare di piů.
Ora, fermo restando che se fosse possibile fare il tutto in meno di 50ms,
sarebbe molto bello e che il massimo accettabile č 100ms, volevo chiedere a
te, che ho visto sei molto esperto in materia se sapevi dirmi quali limiti
ci sono, se ci sono furbate varie, se sto chiedendo la luna ad un sistema
che viste le caratteristiche hardware, in teoria dovrebbe avere pure il
tempo di grattarsi la pancia.:)
Scusa se mi ci metto anche io a rompere le scatole! :)
Colgo anche l'occasione per ringraziare tutti coloro che scrivono su questo
NG, che permettono a molti di imparare molto, fino ad adesso, io ho imparato
molto da questo NG...spero di essere in grado al piů presto, anch'io di
"dare".
Ciao e grazie,
Massimiliano


Ciao Massimiliano, innanzi tutto mi associo ai tuoi ringraziamenti per tutti
coloro che si danno da fare su questo e altri NG, condividendo le proprie
conoscenze dal quale ho tratto spunto in molte occasioni, scoprendo
alternative interessanti a varie problematiche.
Tornando ora al tuo piccolo dilemma, vorrei cominciare dapprima con alcuni
presupposti:
Da quanto ho capito, hai seguito i miei precedenti messaggi riguardanti
l'argomento audio, puoi in ogni caso consultare l'ormai iper-citato site
"
http://www.dejanews.com
" inserendo come Forum questo NG (it.comp.lang.c++)
e come Author 
ne...@bluewin.ch
 per ripescare eventuali puntate perse della
tele-novela Audio.
Credo sia superfluo ribadire che, in ogni modo, la velocità del sistema resta
comunque  un punto critico, se si comincia a parlare di DSP (Digital Signal
Processing).
E' vero che, riprendendo la tua battuta, i processori odierni dovrebbero avere
il tempo di grattarsi la pancia durante l'esecuzione dei tasks, ma comunque,
anche se il flusso audio si svolge ad una velocità relativamente bassa, questo
non può permettersi alcuna discontinuità, pena "gaps" nel flusso.
Dovrebbe esserti noto che ogni task é continuamente sottoposto a continue
interruzioni da eventi esterni ("Interrupt", "Time-Slice" e "DMA", per esempio
dovute proprio alla gestione del flusso audio), inoltre molte di queste
interruzioni sono del tutto asincrone (o meglio random) e possono a volte
intervenire nel momento meno opportuno.
Posso già sin d'ora metterti un limite invalicabile che é ovviamente costituito
dal possesso di una scheda audio full-duplex (non dovrebbe essere un problema,
ormai lo sono quasi tutte) e cioè che gestisce contemporaneamente
l'acquisizione dati (Input) con il playback (Output).
Non saprei cosa consigliarti per migliorare le prestazione dei programmi
in tuo possesso e che non svolgono adeguatamente il loro compito.
Se invece l'applicazione DSP la devi scrivere tu, allora posso provare a darti
alcune nozioni base del tutto teoriche (non prenderle come oro colato!!).
In primo luogo, la trattazione di un segnale digitale audio, implica già di per
se un ritardo dipendente dall'algoritmo applicato.
Ad esempio, in un Pitch-Shifter bisogna dapprima stabilire appunto il Pitch
prima di cominciare ad emettere qualcosa in output e questo non può ovviamente
essere stabilito dal primo sample in entrata.
Di conseguenza, solo dopo un certo ritardo e avendo a disposizione un
determinato pacchetto di sample, si può cominciare ad emettere un output.
La programmazione di algoritmi per DSP non é certamente una cosa semplice,
a meno che ti accontenti di qualche primitivo effetto "low-fi".
Se questo argomento ti intriga (io lo trovo molto stimolante), puoi provare
a farti una cultura su qualche libro.
L'unico che ho sottomano in questo momento (gli altri li ho prestati e spero
tanto di rivederli) é "Elaborazione Digitale dei Segnali, Teoria e Pratica" di
"Mario Malcangi" pubblicato dal gruppo Editoriale Jackson (1986, un po'
vecchiotto).
Una volta a conoscenza della teoria degli algoritmi DSP, resta però il non
semplice compito di metterle in pratica.
Se vuoi lavorare in real-time, penso proprio che puoi scartare in partenza
le API MM (Multi-Media) e usare invece DirectSound (credo) destreggiandoti
tra delay e lunghezze di samples-blocchi opportunamente dimensionati.
Non ho nessuna eserienza su questo pacchetto di funzioni (sorry).
Ci sono comunque in giro molti software (plug-ins) di qualità che girano
associati ad applicazioni quali Cubase, Wave-Lab, Sound-Forge etc.
Una delle marche migliori in fatto di Plug-Ins, per quanto mi riguarda, é
"Waves" che per altro é anche molto cara (si sa che la qualità ......).
Sono spiacente di poterti fornire solo informazioni un po' vaghe e niente
di veramente concreto, ma .....
Se comunque qualche altro NG-Navigator avesse delle chicche da scodellare,
che sia il benvenuto.
Saluti, Neil


grazie, delle info che saranno pure "vaghe", ma sono prorpio quelle che mi
sevono per intraprendere la strada più performante...io infatti pensavo che
con le API si potessero raggiungere risulatati migliori che con le
DirectSound!!!
...ma se facessi tutto sotto DOS, programmando la scheda sonora in LowLevel
(ho già del materiale, che mi sembra abbastanza chiaro)? O se invece
cercassi di percorrere la strada di impossessarmi il più possibile del
sistema, come fanno i videogame?
Tu che ne pensi?
A parte il delay dovuto agli alg DSP utilizzati, qual'è la direzione che mi
permette di ridurre al minimo il delay fra campionamento e ascolto del
segnale inalterato? Questo è il dilemma! Fare un prog con glistessi limiti
degli altri in circolazione, mi pare una perdita di tempo!
Ti rigrazio comunque, perchè l'opnione di chi ha già molta esperienza in
materia, è molto preziosa!
Un salutone,
Massimiliano


Ciao Massimiliano, proverò a descrivere una procedura base che potrebbe
adattarsi in vari casi semplicemente variando alcuni parametri.
Non avendo esperienza su DirectSound o altro, mi baserò sugli eventi
notificati dalle normali API waveIn.... e waveOut.... di "Windows 95
multimedia", in particolar modo WIM_DATA che viene inviato alla
Callback specificata in waveInOpen (CALLBACK_FUNCTION).
Assumiamo un delay arbitrario di 10ms (per esempio stabilito in base
all'algoritmo applicato), di conseguenza dimensiona i buffer della coda di
entrata in modo che risultino di 10ms appunto:
    BufLenght = SampleRate * BytePerSample * NumChannels / 100
Assumiamo che 2, o più buffer di input sono nella coda d'entrata.
Una volta avviato l'input con waveInStart:
    1. Dopo 10ms, il primo buffer viene notificato, a questo punto puoi o meno
       applicare un algoritmo sul primo blocco di dati in input.
       Rimetti il buffer nella coda di input.
    2. Questo blocco non lo rimetti in output subito, ma dopo un delay di
        2ms (arbitrario).
    3. Dopo 20ms, giunge la notifica del prossimo blocco di input, che dopo
        essere stato o meno "algoritmizzato", viene messo in output
        immediatamente.
        Mettendo in output immediatamente questo blocco, fa si che sia posto
        nella coda di uscita, perché il precedente blocco non é ancora
        terminato, in questo modo non avrai "gap" nel flusso di output anche
        se le notifiche dei buffer in input hanno una certa latenza (ritardo).
        Rimetti il buffer nella coda di input.
    4. D'ora in avanti, rimetti immediatamente il buffer di input in output così
        da ottenere un flusso continuo.
Guardando tutto questo dal punto di vista temporale:
      0ms  Start primo blocco di input.
    10ms  Notifica primo blocco di input (eventualmente applica un algoritmo).
    12ms  Output del primo blocco.
    20ms  Notifica secondo blocco, output secondo blocco (e algoritmo).
    22ms  Fine primo blocco in output, inizio secondo blocco in output (già in
              coda, nessuna azione da parte tua, se ne occupa il sistema).
    30ms  Notifica terzo blocco, output terzo blocco.
    22ms  Fine secondo blocco in output, inzio terzo blocco in output (già in
              coda, nessuna azione da parte tua, se ne occupa il sistema).
    etc. etc. etc.
Più corto é il delay applicato, più sollecitato risulterà il sistema.
Se usi funzioni diverse da waveIn.... waveOut...., dovrai stabilire quali
siano i meccanismi di notifica relativi.
Inoltre, ho dato per acquisiti i concetti per eseguire l'input e l'output con
questo gruppo di funzioni (vedi precedenti puntate ....).
Saluti, Neil

Sconvolgente! Deduco (correggimi se ho interpretato male) che la notifica e
la disponibilità del buffer viene effettuata "subito", cioè in un tempo di
ordine di grandezza inferiore al ms e che tutto dipende dal tempo di calcolo
dell'alg da applicare.
Se è così, è sconvolgente perchè l'algoritmo pipeline che tu hai descritto è
quello più naturale...e pare che nessuno usi strutture pipeline. Cioè mi
sembra naturale acquisire dati mentre si elaborano quelli precedenti!!!
Se ho interpretato bene quello che mi hai detto allora è tutto OK, mi
ripasso bene le puntate precedenti e mi metto al lavoro con le API.
Ti ringrazio infinitamente per le informazioni, perchè l'approfondimento che
hai fatto, mi ha permesso di capire bene il funzionamento delle API wave,
mentre prima andavo ad intuito.
Grazie veramente,
Un salutone. Ciao! :)
Massimiliano