Domanda

Java è un'alternativa adatta a C / C ++ per l'elaborazione audio in tempo reale?

Sto considerando un'app con ~ 100 (al massimo) tracce audio con linee di ritardo (30s @ 48khz), filtraggio (512 punti FIR?) e altre operazioni di tipo DSP che si verificano contemporaneamente su ciascuna traccia.

Le operazioni verrebbero convertite ed eseguite in virgola mobile.

Probabilmente il sistema sarebbe un quad core 3GHz con 4 GB di RAM, con Ubuntu.

Ho visto articoli su Java essere molto più veloci di un tempo, avvicinandosi a C / C ++ e ora anche con estensioni in tempo reale. Questa è realtà? Richiede la codifica e l'ottimizzazione del core per ottenere le prestazioni del 50% -100% di C che alcuni stanno specificando?

Sto davvero cercando un senso se questo è possibile e un testa a testa per qualsiasi gotchas.

È stato utile?

Soluzione

Per un'applicazione audio spesso hai solo piccole parti di codice in cui viene trascorsa la maggior parte del tempo.

In Java, puoi sempre usare JNI (interfaccia Java Native) e spostare il tuo codice pesante computazionale in un modulo C (o assembly usando SSE se hai davvero bisogno di energia). Quindi direi usare Java e far funzionare il tuo codice. Se si scopre che non si raggiunge il proprio obiettivo prestazionale, utilizzare JNI.

Il 90% del codice molto probabilmente sarà comunque codice colla e roba dell'applicazione. Ma tieni presente che perdi alcune delle funzionalità multipiattaforma in quel modo. Se riesci a convivere con quel JNI ti lascerà sempre la porta aperta per l'esecuzione del codice nativo.

Altri suggerimenti

Java va bene per molte applicazioni audio. Contrariamente ad alcuni degli altri poster, trovo l'audio Java una gioia con cui lavorare. Confronta l'API e le risorse a tua disposizione con l'orrendo, appena documentato mindf * k che è CoreAudio e sarai un credente. L'audio Java soffre di alcuni problemi di latenza, sebbene per molte app ciò sia irrilevante e la mancanza di codec. Ci sono anche molte persone che non si sono mai prese la briga di dedicare del tempo a scrivere buoni motori di riproduzione audio (suggerimento, non chiudere mai un SourceDataLine, invece scrivere zero su di esso) e successivamente incolpare Java per i loro problemi. Dal punto di vista dell'API, l'audio Java è molto semplice, molto facile da usare e ci sono molte e molte linee guida su jsresources .org .

Sicuro, perché no?

Le domande cruciali (indipendentemente dal linguaggio, questo è dalla teoria delle code) sono:

  • qual è il throughput massimo che devi gestire (hai specificato 100 x 48kHz, è mono o stereo, quanti bit equivalgono a quella frequenza?)
  • le tue routine Java possono tenere il passo con questa frequenza in media?
  • qual è la latenza massima consentita?

Se il tuo programma è in grado di tenere il passo con il throughput in media e hai abbastanza spazio per la latenza, allora dovresti essere in grado di usare le code per input e output, e le uniche parti del programma che sono fondamentali per il timing sono i pezzi che inseriscono i dati nella coda di input e li estraggono dalla coda di output e li inviano a un DAC / speaker / qualunque cosa.

Le linee di ritardo hanno un basso carico computazionale, hai solo bisogno di memoria sufficiente (+ larghezza di banda della memoria) ... in effetti probabilmente dovresti semplicemente usare le code di input / output per esso, cioè iniziare a mettere immediatamente i dati nella coda di input e iniziare estrarre i dati dalla coda di emissione 30 secondi dopo. Se non è lì, il tuo programma è troppo lento ...).

I FIR sono più costosi, probabilmente sarà il collo di bottiglia (e quello che vorresti ottimizzare) a meno che tu non abbia in mente qualche altra brutta operazione.

Penso che la latenza sarà il tuo problema principale - è abbastanza difficile mantenere la latenza già in C / C ++ sui sistemi operativi moderni e Java sicuramente aggiunge al problema (garbage collector). Il progetto generale per "in tempo reale" L'elaborazione audio prevede l'esecuzione dei thread di elaborazione in tempo reale (SCHED_FIFO su kernel Linux, equivalenti su altri sistemi operativi) e questi thread non devono mai bloccarsi. Ciò significa che nessuna chiamata di sistema, nessun malloc, naturalmente nessun IO, ecc ... Anche il paging è un problema (il trasferimento di una pagina dal disco alla memoria può richiedere facilmente diversi ms), quindi è necessario bloccare alcune pagine per essere sicuri che non lo siano mai sostituito.

Potresti essere in grado di fare queste cose in Java, ma Java lo rende più complicato, non più facile. Esaminerei un design misto, in cui il core sarebbe in C, e il resto (GUI, ecc ...) sarebbe in java se vuoi.

Una cosa che non ho visto nella tua domanda è se devi riprodurre questi campioni elaborati o se stai facendo qualcos'altro con loro (codificandoli in un file, ad esempio). Sarei più preoccupato per lo stato del motore audio di Java che per quanto velocemente la JVM può eseguire il crunch dei campioni.

Ho spinto piuttosto forte su javax.sound.sampled qualche anno fa e ne sono uscito profondamente non impressionato - non si confronta con framework equivalenti come OpenAL o Core Audio di Mac / iPhone (entrambi usati in un livello di intensità simile). javax.sound.sampled richiede di inserire i campioni in un buffer opaco di durata sconosciuta, il che rende quasi impossibile la sincronizzazione. È anche scarsamente documentato (molto difficile trovare esempi di streaming di lunghezza indeterminata su una linea rispetto agli esempi banali di clip in memoria), ha metodi non implementati (DataLine.getLevel () ... la cui non implementazione non è ' ho persino documentato), e per finire, credo che Sun abbia licenziato l'ultimo ingegnere JavaSound anni fa.

Se dovessi utilizzare un motore Java per il mixaggio e l'output del suono, probabilmente proverei a usare i binding JOAL su OpenAL come prima scelta, dal momento che almeno conoscerei il motore era attualmente supportato e capace di latenza molto bassa. Anche se a lungo termine sospetto che Nils sia corretto e finirai per usare JNI per chiamare l'API del suono nativo.

Sì, Java è ottimo per le applicazioni audio. Puoi usare Java e accedere ai livelli audio tramite Asio e avere una latenza molto bassa (latenza di 64 campioni che è quasi nulla) sulla piattaforma Windows. Significa che avrai la sincronizzazione labiale su video / film. Più latenza su Mac in quanto non esiste Asio per "scorciatoia" la combinazione di OS X e "Java in alto", ma ancora OK. Anche Linux, ma io sono più ignorante. Vedi soundpimp.com per un esempio pratico (e primo al mondo) di Java e Asio che lavorano in perfetta armonia. Vedi anche l'app Android NRK Radio & amp; tv contenente un decodificatore mp3 mp3 (da Java). Puoi fare la maggior parte delle cose audio con Java e quindi utilizzare un livello nativo se il tempo extra è critico.

Scopri una libreria chiamata Jsyn.

http://www.softsynth.com/jsyn/

Perché non trascorrere una giornata e scrivere una semplice applicazione Java che elabora un minimo e convalida se le prestazioni sono adeguate.

Da http://www.jsresources.org/faq_performance.html#java_slow

  

Raccogliamo un po 'di saggezza eterna:

     
      
  • La terra è piatta.

  •   
  • e, per non dimenticare: Java è lento.

  •   
     

Come dimostrano diverse applicazioni (vedere la sezione collegamenti), Java è sufficiente   per costruire editor audio, sistemi di registrazione multitraccia e MIDI   software di elaborazione. Provalo!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top