I've been learning Java to build what equates to an audio file merger/mixer.
The idea is to insert voice files into a 4 minute music bed.
I am able to create individual streams and output to different files, but I need to insert the data using an offset.
This is what I have so far. It throws an OutOfBounds Exception.
/**
* @param files list of voice files and music file (at end of array)
* @param outputName output file name
* @throws IOException in case file IO messes up
* @throws UnsupportedAudioFileException audio file errors
*/
public void mix(ArrayList<String> files, String outputName) throws IOException, UnsupportedAudioFileException, LineUnavailableException {
int offset = 2;
int gap = 0;
File outFile = new File(outputName);
File music = new File(files.get(files.size()-1));
AudioInputStream as = AudioSystem.getAudioInputStream(music);
ByteArrayOutputStream b = new ByteArrayOutputStream(2 * (int) as.getFrameLength()+100);
AudioSystem.write(as, AudioFileFormat.Type.WAVE ,b);
for(String file : files) {
if(!file.equals(files.get(files.size()-1))) {
File f = new File(file);
byte[] data = b.toByteArray();
int out = AudioSystem.write(
AudioSystem.getAudioInputStream(f),
AudioFileFormat.Type.WAVE, b
);
b.write(data, 2, data.length);
offset += getFile(file) + gap;
AudioInputStream ais = AudioSystem.getAudioInputStream(new ByteArrayInputStream(data));
AudioSystem.write(ais, AudioFileFormat.Type.WAVE, outFile);
MixerLogging.writeToLogFile(String.format("Offset: %s %s\r\n", file, offset));
}
}
MixerLogging.writeToLogFile(outFile.getName()+"\n");
}
The getFile(file) method simply returns the file length in seconds.
Here is the error message:
Exception in thread "Timer-0" java.lang.IndexOutOfBoundsException: Range [2, 2 + 20512556) out of bounds for length 20512556
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckFromIndexSize(Preconditions.java:82)
at java.base/jdk.internal.util.Preconditions.checkFromIndexSize(Preconditions.java:361)
at java.base/java.util.Objects.checkFromIndexSize(Objects.java:411)
at java.base/java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:129)
at main.java.JMixer.mix(JMixer.java:68)
at main.java.Database.getProds(Database.java:36)
at main.java.Main$1.run(Main.java:17)
at java.base/java.util.TimerThread.mainLoop(Timer.java:566)
at java.base/java.util.TimerThread.run(Timer.java:516)
This is the line referred to in the error:
b.write(data, 2, data.length);
The end goal for this application is to mix the audio and output to a single file with a music bed and short voice tracks overlaid at a specific interval (say 10 seconds between voice files).
Any guidance would be greatly appreciated.