Domanda

Sto usando l'API Javax Sound per implementare un semplice programma di riproduzione di console basato su http://www.jsresources.org/examples/audioplayer.html.

Dopo averlo testato usando un file di rampa a 24 bit (ogni campione è l'ultimo campione più 1 nell'intervallo intero di 24 bit) è evidente che sta accadendo qualcosa di strano durante la riproduzione. L'output registrato non è il contenuto del file (ho un loopback digitale per verificarlo).

Sembra che stia interpretando male i campioni in qualche modo che fa sembrare che il canale sinistro abbia un certo guadagno applicato ad esso e il canale destro sembra essere attenuato.

Ho esaminato se i controlli di Pan e Balance necessitano di impostazione, ma questi non sono disponibili e ho controllato le impostazioni del sistema audio di Windows XP. Qualsiasi altra forma di riproduzione di questo file di rampa va bene.

Se faccio lo stesso test con un file a 16 bit, esegue correttamente senza corruzione del flusso.

Quindi qualcuno ha idea del perché l'API Sound Java stia modificando il mio flusso audio?

È stato utile?

Soluzione

Il problema con la riproduzione Java di Audio a 24 bit è in realtà con Microsoft DirectSound e/o la sua implementazione di Windows Java Sound. Usando Linux con il suono Java e ALSA, l'audio a 24 bit si riproduce perfettamente (la registrazione dell'output mostra una corrispondenza bit-perfect con il file di input).

Per capire perché non funziona in Windows, puoi interrogare i formati audio supportati della linea di output su cui si desidera riprodurre in Java utilizzando (dove lineInfo è il Line.Info della linea di output):

DataLine.Info dataLineInfo = (DataLine.Info) lineInfo;

e poi loop attraverso i formati supportati:

for (AudioFormat lineFormat : dataLineInfo.getFormats())

Per Windows ottengo qualcosa di simile:

Format #1: PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
Format #2: PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
Format #3: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
Format #4: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
Format #5: PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
Format #6: PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
Format #7: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
Format #8: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian

Che non ha 24 bit come formato supportato. Ma in Windows XP mi ha ancora permesso di riprodurre audio a 24 bit, ma presumibilmente elaborato fino a 16 bit da Java / DirectSound e poi di nuovo fino a 24 bit dalla Soundcard. Ecco perché l'output dei dati non è corretto. In Windows 7 ho scoperto che mi ha appena rifiutato di riprodurre l'audio a 24 bit (probabilmente più sensato se tutto ciò che farà è comunque cadere a 16 bit).

Per Linux (Fedora 17) ottengo qualcosa di simile (con la stessa idonea Soundcard, un ESI JULI@, sullo stesso PC):

Format #1: PCM_SIGNED unknown sample rate, 32 bit, mono, 4 bytes/frame, little-endian
Format #2: PCM_SIGNED unknown sample rate, 32 bit, mono, 4 bytes/frame, big-endian
Format #3: PCM_SIGNED unknown sample rate, 32 bit, stereo, 8 bytes/frame, little-endian
Format #4: PCM_SIGNED unknown sample rate, 32 bit, stereo, 8 bytes/frame, big-endian
Format #5: PCM_SIGNED unknown sample rate, 24 bit, mono, 4 bytes/frame, little-endian
Format #6: PCM_SIGNED unknown sample rate, 24 bit, mono, 4 bytes/frame, big-endian
Format #7: PCM_SIGNED unknown sample rate, 24 bit, stereo, 8 bytes/frame, little-endian
Format #8: PCM_SIGNED unknown sample rate, 24 bit, stereo, 8 bytes/frame, big-endian
Format #9: PCM_SIGNED unknown sample rate, 24 bit, mono, 3 bytes/frame, little-endian
Format #10: PCM_SIGNED unknown sample rate, 24 bit, mono, 3 bytes/frame, big-endian
Format #11: PCM_SIGNED unknown sample rate, 24 bit, stereo, 6 bytes/frame, little-endian
Format #12: PCM_SIGNED unknown sample rate, 24 bit, stereo, 6 bytes/frame, big-endian
Format #13: PCM_SIGNED unknown sample rate, 20 bit, mono, 3 bytes/frame, little-endian
Format #14: PCM_SIGNED unknown sample rate, 20 bit, mono, 3 bytes/frame, big-endian
Format #15: PCM_SIGNED unknown sample rate, 20 bit, stereo, 6 bytes/frame, little-endian
Format #16: PCM_SIGNED unknown sample rate, 20 bit, stereo, 6 bytes/frame, big-endian
Format #17: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
Format #18: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
Format #19: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
Format #20: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
Format #21: PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
Format #22: PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
Format #23: PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
Format #24: PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame, 

Che ha 24 bit come formato supportato. E come tale funziona come previsto e senza l'elaborazione extra indesiderata.

Quindi sembra che la riproduzione a 24 bit funzioni con Java Sound, a condizione che il sistema operativo (e forse specifico per il dispositivo, ma non ho trovato alcuna variazione tra i dispositivi che ho provato finora) lo elenca come lo elenca come un formato audio supportato. I miei test suggeriscono che Linux (ALSA) lo supporta, mentre Windows (DirectSound) no.

Spero che questo sia utile per qualcuno; Non sono riuscito a trovare nient'altro online, motivo per cui ho pubblicato su una domanda così vecchia.

Quella che segue è stata la mia domanda iniziale, a cui ho appena risposto (l'ho lasciato per riferimento):


Non sono sicuro se questa sia la procedura giusta per porre vecchie domande, ma dalla lettura delle FAQ sembra che questo sia preferito per pubblicarne una nuova. Ho già pubblicato questo problema in un paio di altri posti (incluso il forum di Oracle Java Sound) ma finora senza risposte e questa domanda suona esattamente come il problema che sto avendo:

Sto usando Java Sound per riprodurre file audio (in formato PCM standard) ma ho notato che non riproduce correttamente i dati a 24 bit, in quanto l'output dei dati dalla SoundCard non corrisponde all'ingresso dal file. Funziona bene per dati audio a 16 bit (e persino a 8 bit), ma non per file a 24 bit (e presumibilmente a 32 bit, ma non ho file audio reali da 32 bit da testare). Dall'output sembra che Java Sound stia facendo qualche elaborazione extra (e indesiderata) ai dati audio prima di passarli alla soundcard. Posso dire con certezza che è Java Sound che lo fa perché se eseguo lo stesso test usando ASIO per riprodurre il file, non ci sono problemi e i dati corrispondono come previsto.

Un po 'più di informazioni sull'impostazione: - Java Jre Ultime versione (7u7 credo), in esecuzione su Windows XP SP3. - Suono suonato usando l'esempio di Audioplayer (come menzionato nella domanda principale) su jsresources.org (ho provato in primo luogo a usare il mio codice, ma sono passato a questo nel caso in cui avessi commesso un errore, i risultati sono gli stessi su entrambi). - L'audio viene riprodotto è su un soundcard M-Audio tramite il digitale (S/PDIF), che è direttamente collegato (tramite un cavo esterno) a un digitale su una Lynx Soundcard (nello stesso PC), dove si trova Registrato (usando Sony Sound Forge). - Il file registrato viene quindi confrontato con il file d'onda di input.

Per il test, vengono utilizzati quattro diversi file d'onda di input (generati dallo stesso file di origine): - 16 bit, 44,1 kHz; - 16 bit, 48 kHz; - 24 bit, 44,1 kHz; - 24 bit, 48 kHz.

Utilizzando ASIO per riprodurre i file di test, tutti e quattro i file hanno prodotto l'output corretto (i dati registrati corrispondono al byte dei dati dei file d'onda di input per il byte, dopo aver allineato le posizioni iniziali per il tempo tra la pressione del record e la pressione della riproduzione).

Usando Java per riprodurre i file di test, quelli a 16 bit (entrambi i 44,1 kHz e 48 kHz) producono l'output corretto, mentre quelli a 24 bit (entrambi i 44,1 kHz e 48 kHz) non lo fanno. Non solo, ma il modo in cui l'output non è corretto è incoerente (se eseguo il test due volte, produce un output diverso ogni volta, nessuno dei quali si avvicina alla corrispondenza del file di input). Quindi non solo Java Sound suona i file a 24 bit in modo errato, ma ogni volta lo sta facendo in modo errato in modo diverso. Se mi aiuterà, posso fare screenshot dell'output del suono Java rispetto al file di input (output previsto).

Il modo più semplice per riprodurre questo sarebbe quello di utilizzare l'esempio di Audioplayer sopra menzionato, riprodurre un file a 24 bit e registrare l'output (se si dispone solo di una soundcard potrebbe essere possibile utilizzare il suo mixer per instradare i dati in modo appropriato per consentire che sia catturato). Anche se non è abbastanza sbagliato da poter sentire qualsiasi differenza, sconfigge lo scopo dell'audio ad alta risoluzione se i dati vengono modificati in qualche modo inaspettato (rischi di perdere qualsiasi guadagno dall'uso di 24 bit su 16 bit, anche se io Non voglio davvero entrare in questo argomento qui).

Quindi, per esprimere questo come una domanda: come posso far suonare correttamente il suono Java a 24 bit?

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