Skip to content
Igor Zinken edited this page Apr 15, 2018 · 12 revisions

If you wish to use MWEngine from Java, you can benefit from the static JavaUtilities class that is provided inside the /jni-folder.

The methods exposed in this class act as convenient wrappers for several native functions provided by MWEngine, but provide an API that is more in line with those of the Android SDK.

Using JavaUtilities inside your project

Ensure that inside the makefile Android.mk you include:

jni/javautilities.cpp \

to ensure it is part of the compiled library.

Inside the SWIG interface file mwengine.i be sure to add:

#include "jni/javautilities.h"
%include "jni/javautilities.h"

to ensure that the static JavaUtilities-class is exposed to the Java-layer.

The AudioBuffer-class is not exposed to Java as it is a core actor of the engine and is indirectly created/referenced by AudioEvents instead...

...which is kinda annoying if you want to use samples loaded directly from your Java application. To overcome this, you can use the following wrapper function to directly load .WAV files :

1. Creating AudioBuffers directly from packaged .WAV assets...

...meaning .WAV files that are packaged with your application and reside in the /assets folder of your project. The benefit here is that these files are compressed and do not require any swapping to the Android file system.

boolean JavaUtilities.createSampleFromAsset( String aKey, AssetManager assetManager, String cacheDir, String assetName );

where String aKey is the unique identifier under which the sample will be stored inside the SampleManager. AssetManager assetManager is a reference to the Android AssetManager (can be retrieved from the ApplicationContext via getAssets()) and String assetName is the filename of the asset. This method requires a writable folder (cacheDir, which can be retrieved from (applicationContext.getCacheDir().getAbsolutePath())) to create a temporary file during parsing of the WAV data. The method returns a boolean indicating whether the file has been loaded and stored successfully.

2. Creating AudioBuffers directly from .WAV files and storing them inside the SampleManager...

...meaning .WAV files that are stored on the device's filesystem.

boolean JavaUtilities.createSampleFromFile( String aKey, String aWAVFilePath );

where String aKey is the unique identifier under which the sample will be stored inside the SampleManager and String aWAVFilePath is an (absolute path) to a .WAV file on the Android filesystem. The method returns a boolean indicating whether the file has been loaded and stored successfully.

Using a sample from the SampleManager

To now use this AudioBuffer/sample inside your application you can follow the example on working with sample based content.

but basically, to create a new SampleEvent to play back the sample "foo" from the SampleManager :

if ( JavaUtilities.createSampleFromFile( "foo", "path/to/file.wav" )) {
    SampleEvent fooEvent = new SampleEvent( sampledInstrumentReference );
    fooEvent.setSample( SampleManager.getSample( "foo" ));
}

Creating AudioBuffers from audio samples and storing them inside the SampleManager

If you want to load audio content from non .WAV-files (e.g. AIFF, .MP3, .OGG, etc.) you will need a third party library to read the uncompressed audio samples from these files (the samples should be of double floating point precision in the range of -1.0 to +1.0). Once you have access to the raw samples you can convert them to AudioBuffers and store them inside the SampleManager using these wrapper functions:

JavaUtilities.createSampleFromBuffer( String sampleId, int bufferSize, int amountOfChannels,
                                      double[] leftBuffer, double[] optRightBuffer );

which will create an AudioBuffer holding amountOfChannels amount of channels each at bufferSize in length and register it inside the SampleManager under the given key sampleId. The leftBuffer and optRightBuffer values are arrays holding the aforementioned uncompressed sample data.

If we assume the sample data is stored inside this variable:

double[][] sampleBuffers;

...where the first dimension holds the channels (two for a stereo buffer) and the second dimension contains all the samples for a channel (note the amount of samples should be equal for all channels), we can then register a stereo sample under the name "foo" like this :

JavaUtilities.createSampleFromBuffer( "foo", sampleBuffers[0].length, sampleBuffers.length,
                                      sampleBuffers[0], sampleBuffers[1] );

or register a mono sample under the name "bar" like this:

JavaUtilities.createSampleFromBuffer( "bar", sampleBuffers[0].length, sampleBuffers.length,
                                      sampleBuffers[0], null );

More channels are currently unsupported for the "createSampleFromBuffer"-methods.

NOTE : once a sample has been registered inside the engines SampleManager, you can clear all references to the sampleBuffers in Java, so they can be garbage collected (a copy of the data has been made to store them inside the SampleManager in the native layer).

Clone this wiki locally