I'm porting a small (<10 classes) C++ project to Java. The project manipulates sound files, and in C++ does this using libsndfile. The code includes stuff like:
const int channels = audioFileInfo.channels;
...
sf_readf_double( audioFile, inputBuffer, MAX_ECHO );
...
sf_writef_double( outputAudioFile, ¤tAudioBuffer[WINDOW_SIZE * channels], SEGMENTATION_LENGTH );
In Java, what's the best way to manipulate sound files on a low level? I'm talking about stuff like normalizing, adding echoes etc.
Progress Report
After a bit of digging I've found javax.sound.sampled, which looks like it might do the job.
Edit 2 On closer inspection, it won't work (or at least not in any usable way), since it relies on the com.sun.sound
package.
Edit 3 On even more inspection, and experimentation, the com.sun.sound
and sun.misc
packages are released under the GNU GPLv2, and I've downloaded them into my project. Having renamed javax.sound.sampled
to imp.javax.sound.sampled
, the project compiles, and I can create AudioFileFormat
objects without any exceptions being thrown, yet. I haven't had a chance to play around much yet but I'll keep you updated.
Edit 4 Ok, Some things appear to work with javax.sound.sampled, others do not. For example, calls such as:
AudioInputStream stream = AudioSystem.getAudioInputStream(waveFile));
do not work, however I can get around this by doing:
WaveFileReader wfr = new WaveFileReader();
AudioInputStream stream = wfr.getAudioInputStream(waveFile);
In general, calls to things like AudioSystem.getAudioFileTypes()
return empty lists. I can delve into the packages and see it's something to do with providers, but I'm at a loss how to remedy this. Having got my stream
object it does report its encoding etc. correctly, which is encouraging.
My big problem at the moment is creating a Clip object. This needs to be created with a Line object, which would normally come from AudioSystem. Can anyone think of a way around this?