views:

180

answers:

3

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, &currentAudioBuffer[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?

A: 

Why don't you just keep this code in C++ and invoke it in your Java through JNI ?

Amir Afghani
Sorry, should have put in an Android tag, I'm actually porting to Android, which (according to my research) makes JNI stuff extra horrible. And also it's part of my final year project, it's one of the things I've said I'd do in my project, and work on future projects may incorporate the results of this, so the less layers of complexity the better.
fredley
Fair nuff. I have to keep typing or SO won't let me commit...
Amir Afghani
+2  A: 

libsndfile can be compiled for Android using the Native Development Kit. Once you have the library compiled for Android, you should be able to use JNI to access it from Java.

Erik de Castro Lopo
Any tips? I've never used the NDK before...
fredley
Try on the libsndfile-devel mailing list. There is at least one person there who has done this.
Erik de Castro Lopo