Domanda

per un progetto su cui sto lavorando, voglio essere in grado di concatenare più file .wav.

Attraverso la mia ricerca sono stato in grado di elaborare questo codice:

File sample1 = new File("F:\\Programming\\Resources\\Java_Sound\\trumpet1.wav");
File sample2 = new File("F:\\Programming\\Resources\\Java_Sound\\trumpet2.wav");

File fileOut = new File("F:\\Programming\\Resources\\Java_Sound\\Test.wav");

AudioInputStream audio1 = AudioSystem.getAudioInputStream(sample1);
AudioInputStream audio2 = AudioSystem.getAudioInputStream(sample2);

AudioInputStream audioBuild = new AudioInputStream(new SequenceInputStream(audio1, audio2), audio1.getFormat(), audio1.getFrameLength() + audio2.getFrameLength());

//for(int i = 0; i < 5; i++){
//    audioBuild = new AudioInputStream(new SequenceInputStream(audioBuild, audio2), audioBuild.getFormat(), audioBuild.getFrameLength() + audio2.getFrameLength());
//}

AudioSystem.write(audioBuild, AudioFileFormat.Type.WAVE, fileOut);

funziona bene per la combinazione di due file .wav, tuttavia quando rimuovo il commento dal ciclo for, il file .wav prodotto riproduce l'audio solo per la prima concatenazione. La traccia audio sembra terminare in anticipo, poiché la barra della durata di wmp percorre solo 1 \ 5 circa sullo schermo.

Ho assunto che il problema sia con l'intestazione nel file .wav creato. Ho studiato molte pagine web diverse che discutevano su come costruire un'intestazione, ma tutte avevano definizioni leggermente diverse, ma tutte dicevano che l'intestazione dovrebbe essere in esadecimale. Durante la conversione del flusso (non il flusso audio, un FileInputStream standard) le intestazioni che avevo erano in decimale. Inoltre, dopo la parte RIFF e prima della parte WAVE, dovrebbe esserci la dimensione dell'intero file, esclusi i primi 8 byte. Tuttavia alcuni dei miei includevano trattini. Ad essere onesti, non ho idea di cosa significhino. Ignorandoli tuttavia, la dimensione del file di prova dopo aver rimosso il commento dal codice sopra è ancora un numero maggiore.

Quindi, dopo aver studiato sia come concatenare più file audio, sia come creare \ gestire le intestazioni .wav, non ho ancora idea del motivo per cui il resto del mio audio non viene riprodotto, se esiste. Qualsiasi aiuto è molto apprezzato. Grazie in anticipo.

È stato utile?

Soluzione

Potrebbe essere perché i flussi di input non possono essere letti più di una volta.Una volta letto un flusso di input, sarà alla fine e il tentativo di leggere ulteriormente non leggerà più byte da quel flusso.

Questo dovrebbe funzionare con una leggera modifica, continua a creare nuovi flussi di input audio nel tuo loop:

File sample1 = new File("f1.wav");
File sample2 = new File("f2.wav");

File fileOut = new File("combined.wav");

AudioInputStream audio1 = AudioSystem.getAudioInputStream(sample1);
AudioInputStream audio2 = AudioSystem.getAudioInputStream(sample2);

AudioInputStream audioBuild = new AudioInputStream(new SequenceInputStream(audio1, audio2), audio1.getFormat(), audio1.getFrameLength() + audio2.getFrameLength());

for(int i = 0; i < 5; i++)
{
    audioBuild = new AudioInputStream(new SequenceInputStream(audioBuild, /* keep creating new input streams */ AudioSystem.getAudioInputStream(sample2)), audioBuild.getFormat(), audioBuild.getFrameLength() + audio2.getFrameLength());
}

AudioSystem.write(audioBuild, AudioFileFormat.Type.WAVE, fileOut);

Inoltre, assicurati che i formati audio per i file siano esattamente gli stessi.Ovvero, stessa frequenza di campionamento, stesso numero di canali, stessi bit per campione.Altrimenti avrai bisogno di codice aggiuntivo per eseguire una conversione di esempio.

Altri suggerimenti

Questo è ciò che ho usato per unire qualsiasi quantità di file wave.Ho ripetuto un elenco dei valori di stringa per i percorsi dei file wave e ogni volta che mi unisco al precedente AudioInputStream risultante con la clip successiva.

List<String> paths;
AudioInputStream clip1 = null;
for (String path : paths)
{
    if(clip1 == null)
    {
        clip1 = AudioSystem.getAudioInputStream(new File(path));
        continue;
    }
    AudioInputStream clip2 = AudioSystem.getAudioInputStream(new File(path));
    AudioInputStream appendedFiles = new AudioInputStream(
            new SequenceInputStream(clip1, clip2),     
            clip1.getFormat(), 
            clip1.getFrameLength() + clip2.getFrameLength());
    clip1 = appendedFiles;
}
AudioSystem.write(clip1, AudioFileFormat.Type.WAVE, new File("exported.wav"));
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top