mirror of
https://github.com/shadowfacts/lwjgl2-arm64.git
synced 2026-04-06 15:04:41 +00:00
FMusic done, including callbacks!
Added synctest to fmod, showing how to use FMusic
This commit is contained in:
parent
9c8ac5d794
commit
5803d98ddc
9 changed files with 633 additions and 167 deletions
|
|
@ -33,9 +33,12 @@ package org.lwjgl.fmod;
|
|||
|
||||
import java.io.File;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.lwjgl.Sys;
|
||||
|
||||
/**
|
||||
* $Id$
|
||||
* <br>
|
||||
|
|
@ -45,7 +48,7 @@ import java.util.StringTokenizer;
|
|||
public class FMOD {
|
||||
|
||||
/** Array of hashmaps for callbacks */
|
||||
private static HashMap[] callbacks = new HashMap[14];
|
||||
private static HashMap[] callbacks = new HashMap[17];
|
||||
|
||||
/** FMOD System level clear dsp unit */
|
||||
static FSoundDSPUnit fmodClearUnit;
|
||||
|
|
@ -66,46 +69,56 @@ public class FMOD {
|
|||
static FloatBuffer fmodFFTBuffer;
|
||||
|
||||
/** Type defining the music callback entries in callback hashmap array */
|
||||
public static final int FMUSIC_CALLBACK = 0;
|
||||
public static final int FMUSIC_INSTCALLBACK = 0;
|
||||
|
||||
/** Type defining the music callback entries in callback hashmap array */
|
||||
public static final int FMUSIC_ORDERCALLBACK = 1;
|
||||
|
||||
/** Type defining the music callback entries in callback hashmap array */
|
||||
public static final int FMUSIC_ROWCALLBACK = 2;
|
||||
|
||||
/** Type defining the music callback entries in callback hashmap array */
|
||||
public static final int FMUSIC_ZXXCALLBACK = 3;
|
||||
|
||||
|
||||
/** Type defining the dsp callback entries in callback hashmap array */
|
||||
public static final int FSOUND_DSPCALLBACK = 1;
|
||||
public static final int FSOUND_DSPCALLBACK = 4;
|
||||
|
||||
/** Type defining the stream callback entries in callback hashmap array */
|
||||
public static final int FSOUND_STREAMCALLBACK = 2;
|
||||
public static final int FSOUND_STREAMCALLBACK = 5;
|
||||
|
||||
/** Type defining the alloc callback entries in callback hashmap array */
|
||||
public static final int FSOUND_ALLOCCALLBACK = 3;
|
||||
public static final int FSOUND_ALLOCCALLBACK = 6;
|
||||
|
||||
/** Type defining the realloc callback entries in callback hashmap array */
|
||||
public static final int FSOUND_REALLOCCALLBACK = 4;
|
||||
public static final int FSOUND_REALLOCCALLBACK = 7;
|
||||
|
||||
/** Type defining the free callback entries in callback hashmap array */
|
||||
public static final int FSOUND_FREECALLBACK = 5;
|
||||
public static final int FSOUND_FREECALLBACK = 8;
|
||||
|
||||
/** Type defining the open callback entries in callback hashmap array */
|
||||
public static final int FSOUND_OPENCALLBACK = 6;
|
||||
public static final int FSOUND_OPENCALLBACK = 9;
|
||||
|
||||
/** Type defining the close callback entries in callback hashmap array */
|
||||
public static final int FSOUND_CLOSECALLBACK = 7;
|
||||
public static final int FSOUND_CLOSECALLBACK = 10;
|
||||
|
||||
/** Type defining the metadata callback entries in callback hashmap array */
|
||||
public static final int FSOUND_METADATACALLBACK = 8;
|
||||
public static final int FSOUND_METADATACALLBACK = 11;
|
||||
|
||||
/** Type defining the read callback entries in callback hashmap array */
|
||||
public static final int FSOUND_READCALLBACK = 9;
|
||||
public static final int FSOUND_READCALLBACK = 12;
|
||||
|
||||
/** Type defining the seek callback entries in callback hashmap array */
|
||||
public static final int FSOUND_SEEKCALLBACK = 10;
|
||||
public static final int FSOUND_SEEKCALLBACK = 13;
|
||||
|
||||
/** Type defining the tell callback entries in callback hashmap array */
|
||||
public static final int FSOUND_TELLCALLBACK = 11;
|
||||
public static final int FSOUND_TELLCALLBACK = 14;
|
||||
|
||||
/** Type defining the "end" callback entries in callback hashmap array */
|
||||
public static final int FSOUND_ENDCALLBACK = 12;
|
||||
public static final int FSOUND_ENDCALLBACK = 15;
|
||||
|
||||
/** Type defining the "sync" callback entries in callback hashmap array */
|
||||
public static final int FSOUND_SYNCCALLBACK = 13;
|
||||
public static final int FSOUND_SYNCCALLBACK = 16;
|
||||
|
||||
/** Have we been created? */
|
||||
protected static boolean created;
|
||||
|
|
@ -304,10 +317,23 @@ public class FMOD {
|
|||
* @param callbackHandler Object to register as the call back handler
|
||||
*/
|
||||
static void registerCallback(int type, long handle, Object handled, Object callbackHandler) {
|
||||
Long callbackID = new Long(handle);
|
||||
ArrayList callbackList = (ArrayList) callbacks[type].get(callbackID);
|
||||
|
||||
if (callbackList == null ) {
|
||||
if (callbackHandler == null) {
|
||||
Sys.log("No callbackhandlers registered for handle: " + handle);
|
||||
} else {
|
||||
callbackList = new ArrayList();
|
||||
callbacks[type].put(callbackID, callbackList);
|
||||
}
|
||||
}
|
||||
|
||||
// are we going to add or remove from the list?
|
||||
if(callbackHandler == null) {
|
||||
callbacks[type].remove(new Long(handle));
|
||||
callbacks[type].remove(callbackID);
|
||||
} else {
|
||||
callbacks[type].put(new Long(handle), new FMOD.WrappedCallback(handled, callbackHandler));
|
||||
callbackList.add(new FMOD.WrappedCallback(handled, callbackHandler));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -316,8 +342,8 @@ public class FMOD {
|
|||
* @param handle Handle to native object being monitored
|
||||
* @return Call back handler, or null if no such handler
|
||||
*/
|
||||
static WrappedCallback getCallback(int type, long handle) {
|
||||
return (WrappedCallback) callbacks[type].get(new Long(handle));
|
||||
static ArrayList getCallbacks(int type, long handle) {
|
||||
return (ArrayList) callbacks[type].get(new Long(handle));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@
|
|||
package org.lwjgl.fmod;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.lwjgl.fmod.callbacks.FMusicCallback;
|
||||
|
||||
|
|
@ -107,27 +109,38 @@ public class FMusic {
|
|||
* </i>
|
||||
* </p>
|
||||
*
|
||||
* @param name_or_data Name of song or data containing song to load (if loading from memory and not file). On PlayStation 2 data must be 16 byte aligned if loading from memory
|
||||
* @param data containing song to load. On PlayStation 2 data must be 16 byte aligned if loading from memory
|
||||
* @param offset Optional. 0 by default. If > 0, this value is used to specify an offset in a file, so fmod will seek before opening
|
||||
* @param length Optional. 0 by default. If > 0, this value is used to specify the length of a memory block when using FSOUND_LOADMEMORY, or it is the length of a file or file segment if the offset parameter is used. On PlayStation 2 this must be 16 byte aligned for memory loading
|
||||
* @param mode Mode for opening song. With module files, only FSOUND_LOADMEMORY, FSOUND_NONBLOCKING, FSOUND_LOOP_NORMAL, or FSOUND_LOOP_OFF are supported. For FSB files, FSOUND_2D, FSOUND_HW3D, FSOUND_FORCEMONO also work
|
||||
* @param sampleList Optional. Buffer of sample indicies to load. Leave as Null if you want all samples to be loaded (default behaviour). See Remarks for more on this
|
||||
* @return On success, a FMusicModule instance is returned. On failure, Null is returned
|
||||
*/
|
||||
public static FMusicModule FMUSIC_LoadSongEx(ByteBuffer name_or_data, int offset, int length, int mode, IntBuffer sampleList) {
|
||||
long result = 0;
|
||||
|
||||
if((mode & FSound.FSOUND_LOADMEMORY) == FSound.FSOUND_LOADMEMORY) {
|
||||
result = nFMUSIC_LoadSongEx(name_or_data, name_or_data.position(), offset, length, mode, (sampleList != null) ? sampleList : null, (sampleList != null) ? sampleList.position() : 0, (sampleList != null) ? sampleList.remaining() : 0);
|
||||
} else {
|
||||
byte[] data = new byte[name_or_data.remaining()];
|
||||
result = nFMUSIC_LoadSongEx(new String(data), offset, length, mode, (sampleList != null) ? sampleList : null, (sampleList != null) ? sampleList.position() : 0, (sampleList != null) ? sampleList.remaining() : 0);
|
||||
}
|
||||
public static FMusicModule FMUSIC_LoadSongEx(ByteBuffer data, int offset, int length, int mode, IntBuffer sampleList) {
|
||||
long result = nFMUSIC_LoadSongEx(data, data.position(), offset, length, mode, (sampleList != null) ? sampleList : null, (sampleList != null) ? sampleList.position() : 0, (sampleList != null) ? sampleList.remaining() : 0);
|
||||
if(result != FMUSIC_TYPE_NONE) {
|
||||
return new FMusicModule(result);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #FMUSIC_LoadSongEx(ByteBuffer, int, int, int, IntBuffer)
|
||||
* @param name of song
|
||||
* @param offset Optional. 0 by default. If > 0, this value is used to specify an offset in a file, so fmod will seek before opening
|
||||
* @param length Optional. 0 by default. If > 0, this value is used to specify the length of a memory block when using FSOUND_LOADMEMORY, or it is the length of a file or file segment if the offset parameter is used. On PlayStation 2 this must be 16 byte aligned for memory loading
|
||||
* @param mode Mode for opening song. With module files, only FSOUND_LOADMEMORY, FSOUND_NONBLOCKING, FSOUND_LOOP_NORMAL, or FSOUND_LOOP_OFF are supported. For FSB files, FSOUND_2D, FSOUND_HW3D, FSOUND_FORCEMONO also work
|
||||
* @param sampleList Optional. Buffer of sample indicies to load. Leave as Null if you want all samples to be loaded (default behaviour). See Remarks for more on this
|
||||
* @return On success, a FMusicModule instance is returned. On failure, Null is returned
|
||||
*/
|
||||
public static FMusicModule FMUSIC_LoadSongEx(String name, int offset, int length, int mode, IntBuffer sampleList) {
|
||||
long result = nFMUSIC_LoadSongEx(name, offset, length, mode, (sampleList != null) ? sampleList : null, (sampleList != null) ? sampleList.position() : 0, (sampleList != null) ? sampleList.remaining() : 0);
|
||||
|
||||
if(result != FMUSIC_TYPE_NONE) {
|
||||
return new FMusicModule(result);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static native long nFMUSIC_LoadSongEx(ByteBuffer data, int dataOffset, int offset, int length, int mode, IntBuffer sampleList, int bufferOffset, int remaining);
|
||||
private static native long nFMUSIC_LoadSongEx(String name, int offset, int length, int mode, IntBuffer sampleList, int bufferOffset, int remaining);
|
||||
|
||||
|
|
@ -148,8 +161,10 @@ public class FMusic {
|
|||
*/
|
||||
public static boolean FMUSIC_FreeSong(FMusicModule module) {
|
||||
// when freeing a song, we automatically deregister any callbacks
|
||||
FMOD.registerCallback(FMOD.FMUSIC_CALLBACK, module.moduleHandle, null, null);
|
||||
|
||||
FMOD.registerCallback(FMOD.FMUSIC_INSTCALLBACK, module.moduleHandle, null, null);
|
||||
FMOD.registerCallback(FMOD.FMUSIC_ORDERCALLBACK, module.moduleHandle, null, null);
|
||||
FMOD.registerCallback(FMOD.FMUSIC_ROWCALLBACK, module.moduleHandle, null, null);
|
||||
FMOD.registerCallback(FMOD.FMUSIC_ZXXCALLBACK, module.moduleHandle, null, null);
|
||||
return nFMUSIC_FreeSong(module.moduleHandle);
|
||||
}
|
||||
private static native boolean nFMUSIC_FreeSong(long module);
|
||||
|
|
@ -204,10 +219,10 @@ public class FMusic {
|
|||
* @return On success, true is returned. On failure, false is returned
|
||||
*/
|
||||
public static boolean FMUSIC_SetZxxCallback(FMusicModule module, FMusicCallback callback) {
|
||||
FMOD.registerCallback(FMOD.FMUSIC_CALLBACK, module.moduleHandle, module, callback);
|
||||
return nFMUSIC_SetZxxCallback(module.moduleHandle, callback);
|
||||
FMOD.registerCallback(FMOD.FMUSIC_ZXXCALLBACK, module.moduleHandle, module, callback);
|
||||
return nFMUSIC_SetZxxCallback(module.moduleHandle);
|
||||
}
|
||||
private static native boolean nFMUSIC_SetZxxCallback(long module, FMusicCallback callback);
|
||||
private static native boolean nFMUSIC_SetZxxCallback(long module);
|
||||
|
||||
/**
|
||||
* Sets a user callback to occur on every row divisible by the rowstep parameter, played from a MOD, S3M, XM or IT file.
|
||||
|
|
@ -231,10 +246,10 @@ public class FMusic {
|
|||
* @return On success, true is returned. On failure, false is returned
|
||||
*/
|
||||
public static boolean FMUSIC_SetRowCallback(FMusicModule module, FMusicCallback callback, int rowstep) {
|
||||
FMOD.registerCallback(FMOD.FMUSIC_CALLBACK, module.moduleHandle, module, callback);
|
||||
return nFMUSIC_SetRowCallback(module.moduleHandle, callback, rowstep);
|
||||
FMOD.registerCallback(FMOD.FMUSIC_ROWCALLBACK, module.moduleHandle, module, callback);
|
||||
return nFMUSIC_SetRowCallback(module.moduleHandle, rowstep);
|
||||
}
|
||||
private static native boolean nFMUSIC_SetRowCallback(long module, FMusicCallback callback, int rowstep);
|
||||
private static native boolean nFMUSIC_SetRowCallback(long module, int rowstep);
|
||||
|
||||
/**
|
||||
* Sets a user callback to occur on every order divisible by the orderstep parameter, played from a MOD, S3M, XM or IT file
|
||||
|
|
@ -258,10 +273,10 @@ public class FMusic {
|
|||
* @return On success, true is returned. On failure, false is returned
|
||||
*/
|
||||
public static boolean FMUSIC_SetOrderCallback(FMusicModule module, FMusicCallback callback, int orderstep) {
|
||||
FMOD.registerCallback(FMOD.FMUSIC_CALLBACK, module.moduleHandle, module, callback);
|
||||
return nFMUSIC_SetOrderCallback(module.moduleHandle, callback, orderstep);
|
||||
FMOD.registerCallback(FMOD.FMUSIC_ORDERCALLBACK, module.moduleHandle, module, callback);
|
||||
return nFMUSIC_SetOrderCallback(module.moduleHandle, orderstep);
|
||||
}
|
||||
private static native boolean nFMUSIC_SetOrderCallback(long module, FMusicCallback callback, int orderstep);
|
||||
private static native boolean nFMUSIC_SetOrderCallback(long module, int orderstep);
|
||||
|
||||
/**
|
||||
* Sets a user callback to occur every time a instrument is played, triggered from a MOD, S3M, XM or IT file.
|
||||
|
|
@ -285,10 +300,10 @@ public class FMusic {
|
|||
* @return On success, true is returned. On failure, false is returned
|
||||
*/
|
||||
public static boolean FMUSIC_SetInstCallback(FMusicModule module, FMusicCallback callback, int instrument) {
|
||||
FMOD.registerCallback(FMOD.FMUSIC_CALLBACK, module.moduleHandle, module, callback);
|
||||
return nFMUSIC_SetInstCallback(module.moduleHandle, callback, instrument);
|
||||
FMOD.registerCallback(FMOD.FMUSIC_INSTCALLBACK, module.moduleHandle, module, callback);
|
||||
return nFMUSIC_SetInstCallback(module.moduleHandle, instrument);
|
||||
}
|
||||
private static native boolean nFMUSIC_SetInstCallback(long module, FMusicCallback callback, int instrument);
|
||||
private static native boolean nFMUSIC_SetInstCallback(long module, int instrument);
|
||||
|
||||
/**
|
||||
* Replaces a mod's sample with a sample definition specified.
|
||||
|
|
@ -712,10 +727,12 @@ public class FMusic {
|
|||
* @param module Module to get the open state from
|
||||
* @return On success, userdata set by FMUSIC_SetUserData is returned. On failure, Null is returned.
|
||||
*/
|
||||
public static ByteBuffer FMUSIC_GetUserData(FMusicModule module) {
|
||||
return nFMUSIC_GetUserData(module.moduleHandle);
|
||||
public static ByteBuffer FMUSIC_GetUserData(FMusicModule module, int capacity) {
|
||||
ByteBuffer buffer = nFMUSIC_GetUserData(module.moduleHandle, capacity);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
return buffer;
|
||||
}
|
||||
private static native ByteBuffer nFMUSIC_GetUserData(long module);
|
||||
private static native ByteBuffer nFMUSIC_GetUserData(long module, int capacity);
|
||||
|
||||
/**
|
||||
* This is the callback rutine called by the native implementation whenever a
|
||||
|
|
@ -724,10 +741,64 @@ public class FMusic {
|
|||
* @param handle Handle to native object being monitored
|
||||
* @param param parameter passed to callback
|
||||
*/
|
||||
private static void music_callback(long modulehandle, int param) {
|
||||
// locate out callback and call it back
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) FMOD.getCallback(FMOD.FSOUND_DSPCALLBACK, modulehandle);
|
||||
FMusicCallback callback = (FMusicCallback) wCallback.callback;
|
||||
callback.FMUSIC_CALLBACK((FMusicModule) wCallback.handled, param);
|
||||
public static void music_instcallback(long modulehandle, int param) {
|
||||
// we got a callback - notify everybody
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FMUSIC_INSTCALLBACK, modulehandle);
|
||||
for(int i=0; i<handlers.size(); i++) {
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(i);
|
||||
FMusicCallback callback = (FMusicCallback) wCallback.callback;
|
||||
callback.FMUSIC_CALLBACK((FMusicModule) wCallback.handled, param);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the callback rutine called by the native implementation whenever a
|
||||
* register callback is notified.
|
||||
*
|
||||
* @param handle Handle to native object being monitored
|
||||
* @param param parameter passed to callback
|
||||
*/
|
||||
public static void music_ordercallback(long modulehandle, int param) {
|
||||
// we got a callback - notify everybody
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FMUSIC_ORDERCALLBACK, modulehandle);
|
||||
for(int i=0; i<handlers.size(); i++) {
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(i);
|
||||
FMusicCallback callback = (FMusicCallback) wCallback.callback;
|
||||
callback.FMUSIC_CALLBACK((FMusicModule) wCallback.handled, param);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the callback rutine called by the native implementation whenever a
|
||||
* register callback is notified.
|
||||
*
|
||||
* @param handle Handle to native object being monitored
|
||||
* @param param parameter passed to callback
|
||||
*/
|
||||
public static void music_rowcallback(long modulehandle, int param) {
|
||||
// we got a callback - notify everybody
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FMUSIC_ROWCALLBACK, modulehandle);
|
||||
for(int i=0; i<handlers.size(); i++) {
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(i);
|
||||
FMusicCallback callback = (FMusicCallback) wCallback.callback;
|
||||
callback.FMUSIC_CALLBACK((FMusicModule) wCallback.handled, param);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the callback rutine called by the native implementation whenever a
|
||||
* register callback is notified.
|
||||
*
|
||||
* @param handle Handle to native object being monitored
|
||||
* @param param parameter passed to callback
|
||||
*/
|
||||
public static void music_zxxcallback(long modulehandle, int param) {
|
||||
// we got a callback - notify everybody
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FMUSIC_ZXXCALLBACK, modulehandle);
|
||||
for(int i=0; i<handlers.size(); i++) {
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(i);
|
||||
FMusicCallback callback = (FMusicCallback) wCallback.callback;
|
||||
callback.FMUSIC_CALLBACK((FMusicModule) wCallback.handled, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ package org.lwjgl.fmod;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.lwjgl.fmod.callbacks.FSoundCloseCallback;
|
||||
import org.lwjgl.fmod.callbacks.FSoundDSPCallback;
|
||||
|
|
@ -354,13 +355,18 @@ public class FSound {
|
|||
public static void FSOUND_File_SetCallbacks(
|
||||
FSoundOpenCallback open, FSoundCloseCallback close, FSoundReadCallback read,
|
||||
FSoundSeekCallback seek, FSoundTellCallback tell) {
|
||||
FMOD.registerCallback(FMOD.FSOUND_OPENCALLBACK, -1, null, open);
|
||||
FMOD.registerCallback(FMOD.FSOUND_CLOSECALLBACK, -1, null, open);
|
||||
FMOD.registerCallback(FMOD.FSOUND_READCALLBACK, -1, null, open);
|
||||
FMOD.registerCallback(FMOD.FSOUND_SEEKCALLBACK, -1, null, open);
|
||||
FMOD.registerCallback(FMOD.FSOUND_TELLCALLBACK, -1, null, open);
|
||||
|
||||
nFSOUND_File_SetCallbacks();
|
||||
if(open != null && close != null && read != null && seek != null && tell != null) {
|
||||
FMOD.registerCallback(FMOD.FSOUND_OPENCALLBACK, -1, null, open);
|
||||
FMOD.registerCallback(FMOD.FSOUND_CLOSECALLBACK, -1, null, open);
|
||||
FMOD.registerCallback(FMOD.FSOUND_READCALLBACK, -1, null, open);
|
||||
FMOD.registerCallback(FMOD.FSOUND_SEEKCALLBACK, -1, null, open);
|
||||
FMOD.registerCallback(FMOD.FSOUND_TELLCALLBACK, -1, null, open);
|
||||
|
||||
nFSOUND_File_SetCallbacks();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot supply null callback");
|
||||
}
|
||||
}
|
||||
private static native void nFSOUND_File_SetCallbacks();
|
||||
|
||||
|
|
@ -922,26 +928,39 @@ public class FSound {
|
|||
* 0 or above - The absolute index into the sample pool. The pool will grow as the index gets larger. If a slot is already used it will be replaced.
|
||||
* FSOUND_FREE - Let FSOUND select an arbitrary sample slot.
|
||||
* FSOUND_UNMANAGED - Dont have this sample managed within fsounds sample management system
|
||||
* @param name_or_data Name of sound file or pointer to memory image to load.
|
||||
* @param data ByteBuffer of memory image to load.
|
||||
* @param inputmode Description of the data format, OR in the bits defined in FSOUND_MODES to describe the data being loaded.
|
||||
* @param offset Optional. 0 by default. If > 0, this value is used to specify an offset in a file, so fmod will seek before opening. length must also be specified if this value is used.
|
||||
* @param length Optional. 0 by default. If > 0, this value is used to specify the length of a memory block when using FSOUND_LOADMEMORY, or it is the length of a file or file segment if the offset parameter is used. On PlayStation 2 this must be 16 byte aligned for memory loading.
|
||||
* @return On success, a sample is returned. On failure, NULL is returned.
|
||||
*/
|
||||
public static FSoundSample FSOUND_Sample_Load(int index, ByteBuffer name_or_data, int inputmode, int offset, int length) {
|
||||
long result = 0;
|
||||
|
||||
if((inputmode & FSound.FSOUND_LOADMEMORY) == FSound.FSOUND_LOADMEMORY) {
|
||||
result = nFSOUND_Sample_Load(index, name_or_data, name_or_data.position(), inputmode, offset, length);
|
||||
} else {
|
||||
byte[] data = new byte[name_or_data.remaining()];
|
||||
result = nFSOUND_Sample_Load(index, new String(data), inputmode, offset, length);
|
||||
}
|
||||
public static FSoundSample FSOUND_Sample_Load(int index, ByteBuffer data, int inputmode, int offset, int length) {
|
||||
long result = nFSOUND_Sample_Load(index, data, data.position(), inputmode, offset, length);
|
||||
if(result != 0) {
|
||||
return new FSoundSample(result);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #FSOUND_Sample_Load(int, ByteBuffer, int, int, int)
|
||||
* @param index Sample pool index. See remarks for more on the sample pool.
|
||||
* 0 or above - The absolute index into the sample pool. The pool will grow as the index gets larger. If a slot is already used it will be replaced.
|
||||
* FSOUND_FREE - Let FSOUND select an arbitrary sample slot.
|
||||
* FSOUND_UNMANAGED - Dont have this sample managed within fsounds sample management system
|
||||
* @param name Name of sound file.
|
||||
* @param inputmode Description of the data format, OR in the bits defined in FSOUND_MODES to describe the data being loaded.
|
||||
* @param offset Optional. 0 by default. If > 0, this value is used to specify an offset in a file, so fmod will seek before opening. length must also be specified if this value is used.
|
||||
* @param length Optional. 0 by default. If > 0, this value is used to specify the length of a memory block when using FSOUND_LOADMEMORY, or it is the length of a file or file segment if the offset parameter is used. On PlayStation 2 this must be 16 byte aligned for memory loading.
|
||||
* @return On success, a sample is returned. On failure, NULL is returned.
|
||||
*/
|
||||
public static FSoundSample FSOUND_Sample_Load(int index, String name, int inputmode, int offset, int length) {
|
||||
long result = nFSOUND_Sample_Load(index, name, inputmode, offset, length);
|
||||
if(result != 0) {
|
||||
return new FSoundSample(result);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static native long nFSOUND_Sample_Load(int index, ByteBuffer data, int dataOffset, int inputmode, int offset, int length);
|
||||
private static native long nFSOUND_Sample_Load(int index, String name, int inputmode, int offset, int length);
|
||||
|
||||
|
|
@ -3508,9 +3527,13 @@ public class FSound {
|
|||
* @param param parameter passed to callback
|
||||
*/
|
||||
private static void dsp_callback(long dspHandle, ByteBuffer originalbuffer, ByteBuffer newbuffer, int length) {
|
||||
// locate out callback and call it back
|
||||
FSoundDSPCallback callback = (FSoundDSPCallback) ((FMOD.WrappedCallback) FMOD.getCallback(FMOD.FSOUND_DSPCALLBACK, dspHandle)).callback;
|
||||
callback.FSOUND_DSPCALLBACK(originalbuffer, newbuffer, length);
|
||||
// we got a callback - notify everybody
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FSOUND_DSPCALLBACK, dspHandle);
|
||||
for(int i=0; i<handlers.size(); i++) {
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(i);
|
||||
FSoundDSPCallback callback = (FSoundDSPCallback) wCallback.callback;
|
||||
callback.FSOUND_DSPCALLBACK(originalbuffer, newbuffer, length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3521,10 +3544,13 @@ public class FSound {
|
|||
* @param param parameter passed to callback
|
||||
*/
|
||||
private static void stream_callback(long streamHandle, ByteBuffer buff, int length) {
|
||||
// locate out callback and call it back
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) FMOD.getCallback(FMOD.FSOUND_STREAMCALLBACK, streamHandle);
|
||||
FSoundStreamCallback callback = (FSoundStreamCallback) wCallback.callback;
|
||||
callback.FSOUND_STREAMCALLBACK((FSoundStream) wCallback.handled, buff, length);
|
||||
// we got a callback - notify everybody
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FSOUND_STREAMCALLBACK, streamHandle);
|
||||
for(int i=0; i<handlers.size(); i++) {
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(i);
|
||||
FSoundStreamCallback callback = (FSoundStreamCallback) wCallback.callback;
|
||||
callback.FSOUND_STREAMCALLBACK((FSoundStream) wCallback.handled, buff, length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3535,10 +3561,13 @@ public class FSound {
|
|||
* @param param parameter passed to callback
|
||||
*/
|
||||
private static void end_callback(long streamHandle) {
|
||||
// locate out callback and call it back
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) FMOD.getCallback(FMOD.FSOUND_ENDCALLBACK, streamHandle);
|
||||
FSoundStreamCallback callback = (FSoundStreamCallback) wCallback.callback;
|
||||
callback.FSOUND_STREAMCALLBACK((FSoundStream) wCallback.handled, null, 0);
|
||||
// we got a callback - notify everybody
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FSOUND_ENDCALLBACK, streamHandle);
|
||||
for(int i=0; i<handlers.size(); i++) {
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(i);
|
||||
FSoundStreamCallback callback = (FSoundStreamCallback) wCallback.callback;
|
||||
callback.FSOUND_STREAMCALLBACK((FSoundStream) wCallback.handled, null, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3549,10 +3578,13 @@ public class FSound {
|
|||
* @param param parameter passed to callback
|
||||
*/
|
||||
private static void sync_callback(long streamHandle, ByteBuffer buff, int lenght) {
|
||||
// locate out callback and call it back
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) FMOD.getCallback(FMOD.FSOUND_SYNCCALLBACK, streamHandle);
|
||||
FSoundStreamCallback callback = (FSoundStreamCallback) wCallback.callback;
|
||||
callback.FSOUND_STREAMCALLBACK((FSoundStream) wCallback.handled, buff, lenght);
|
||||
// we got a callback - notify everybody
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FSOUND_SYNCCALLBACK, streamHandle);
|
||||
for(int i=0; i<handlers.size(); i++) {
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(i);
|
||||
FSoundStreamCallback callback = (FSoundStreamCallback) wCallback.callback;
|
||||
callback.FSOUND_STREAMCALLBACK((FSoundStream) wCallback.handled, buff, lenght);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3563,9 +3595,10 @@ public class FSound {
|
|||
* @param param parameter passed to callback
|
||||
*/
|
||||
private static int open_callback(String name) {
|
||||
// locate out callback and call it back
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) FMOD.getCallback(FMOD.FSOUND_OPENCALLBACK, -1);
|
||||
FSoundOpenCallback callback = (FSoundOpenCallback) wCallback.callback;
|
||||
// we got a callback - notify THE handler
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FSOUND_OPENCALLBACK, -1);
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(0);
|
||||
FSoundOpenCallback callback = (FSoundOpenCallback) wCallback.callback;
|
||||
return callback.FSOUND_OPENCALLBACK(name);
|
||||
}
|
||||
|
||||
|
|
@ -3577,9 +3610,10 @@ public class FSound {
|
|||
* @param param parameter passed to callback
|
||||
*/
|
||||
private static void close_callback(int handle) {
|
||||
// locate out callback and call it back
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) FMOD.getCallback(FMOD.FSOUND_CLOSECALLBACK, -1);
|
||||
FSoundCloseCallback callback = (FSoundCloseCallback) wCallback.callback;
|
||||
// we got a callback - notify THE handler
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FSOUND_CLOSECALLBACK, -1);
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(0);
|
||||
FSoundCloseCallback callback = (FSoundCloseCallback) wCallback.callback;
|
||||
callback.FSOUND_CLOSECALLBACK(handle);
|
||||
}
|
||||
|
||||
|
|
@ -3591,9 +3625,10 @@ public class FSound {
|
|||
* @param param parameter passed to callback
|
||||
*/
|
||||
private static int read_callback(ByteBuffer buffer, int size, int handle) {
|
||||
// locate out callback and call it back
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) FMOD.getCallback(FMOD.FSOUND_CLOSECALLBACK, -1);
|
||||
FSoundReadCallback callback = (FSoundReadCallback) wCallback.callback;
|
||||
// we got a callback - notify THE handler
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FSOUND_READCALLBACK, -1);
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(0);
|
||||
FSoundReadCallback callback = (FSoundReadCallback) wCallback.callback;
|
||||
return callback.FSOUND_READCALLBACK(buffer, size, handle);
|
||||
}
|
||||
|
||||
|
|
@ -3605,9 +3640,10 @@ public class FSound {
|
|||
* @param param parameter passed to callback
|
||||
*/
|
||||
private static int seek_callback(int handle, int pos, int mode) {
|
||||
// locate out callback and call it back
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) FMOD.getCallback(FMOD.FSOUND_CLOSECALLBACK, -1);
|
||||
FSoundSeekCallback callback = (FSoundSeekCallback) wCallback.callback;
|
||||
// we got a callback - notify THE handler
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FSOUND_SEEKCALLBACK, -1);
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(0);
|
||||
FSoundSeekCallback callback = (FSoundSeekCallback) wCallback.callback;
|
||||
return callback.FSOUND_SEEKCALLBACK(handle, pos, mode);
|
||||
}
|
||||
|
||||
|
|
@ -3619,9 +3655,10 @@ public class FSound {
|
|||
* @param param parameter passed to callback
|
||||
*/
|
||||
private static int tell_callback(int handle) {
|
||||
// locate out callback and call it back
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) FMOD.getCallback(FMOD.FSOUND_CLOSECALLBACK, -1);
|
||||
FSoundTellCallback callback = (FSoundTellCallback) wCallback.callback;
|
||||
// we got a callback - notify THE handler
|
||||
ArrayList handlers = FMOD.getCallbacks(FMOD.FSOUND_TELLCALLBACK, -1);
|
||||
FMOD.WrappedCallback wCallback = (FMOD.WrappedCallback) handlers.get(0);
|
||||
FSoundTellCallback callback = (FSoundTellCallback) wCallback.callback;
|
||||
return callback.FSOUND_TELLCALLBACK(handle);
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -38,7 +38,11 @@ import java.io.IOException;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import org.lwjgl.fmod.*;
|
||||
import org.lwjgl.fmod.FMOD;
|
||||
import org.lwjgl.fmod.FMODException;
|
||||
import org.lwjgl.fmod.FMusic;
|
||||
import org.lwjgl.fmod.FMusicModule;
|
||||
import org.lwjgl.fmod.FSound;
|
||||
|
||||
/**
|
||||
* $Id$
|
||||
|
|
@ -74,12 +78,18 @@ public class MusicPlayer {
|
|||
}
|
||||
|
||||
System.out.println("Loading " + args[0]);
|
||||
|
||||
// choose either way of loading...
|
||||
|
||||
// using name (path)
|
||||
FMusicModule module = FMusic.FMUSIC_LoadSong(args[0]);
|
||||
//ByteBuffer buffer = ByteBuffer.allocateDirect(11).order(ByteOrder.nativeOrder());
|
||||
//buffer.put("razorbck.it".getBytes());
|
||||
//buffer.flip();
|
||||
//FMusicModule module = FMusic.FMUSIC_LoadSongEx(getData(args[0]), 0, 0, 0, null);
|
||||
//FMusicModule module = FMusic.FMUSIC_LoadSongEx(buffer, 0, 0, 0, null);
|
||||
|
||||
// using name (path), extended mode
|
||||
//FMusicModule module = FMusic.FMUSIC_LoadSongEx(args[0], 0, 0, 0, null);
|
||||
|
||||
// using memory buffers
|
||||
//ByteBuffer data = getData(args[0]);
|
||||
//FMusicModule module = FMusic.FMUSIC_LoadSongEx(data, 0, data.remaining(), FSound.FSOUND_LOADMEMORY, null);
|
||||
|
||||
if(module != null) {
|
||||
System.out.println("Loaded. Playing module of type: " + FMusic.FMUSIC_GetType(module));
|
||||
|
|
@ -96,6 +106,7 @@ public class MusicPlayer {
|
|||
FMusic.FMUSIC_FreeSong(module);
|
||||
} else {
|
||||
System.out.println("Unable to play: " + args[0]);
|
||||
System.out.println("Error: " + FMOD.FMOD_ErrorString(FSound.FSOUND_GetError()));
|
||||
}
|
||||
|
||||
FSound.FSOUND_Close();
|
||||
|
|
@ -104,39 +115,40 @@ public class MusicPlayer {
|
|||
|
||||
/**
|
||||
* Reads the file into a ByteBuffer
|
||||
*
|
||||
* @param filename Name of file to load
|
||||
*
|
||||
* @param filename
|
||||
* Name of file to load
|
||||
* @return ByteBuffer containing file data
|
||||
*/
|
||||
static protected ByteBuffer getData(String filename) {
|
||||
ByteBuffer buffer = null;
|
||||
ByteBuffer buffer = null;
|
||||
|
||||
System.out.println("Attempting to load: " + filename);
|
||||
|
||||
try {
|
||||
BufferedInputStream bis = new BufferedInputStream(MusicPlayer.class.getClassLoader().getResourceAsStream(filename));
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
int bufferLength = 4096;
|
||||
byte[] readBuffer = new byte[bufferLength];
|
||||
int read = -1;
|
||||
|
||||
while((read = bis.read(readBuffer, 0, bufferLength)) != -1) {
|
||||
baos.write(readBuffer, 0, read);
|
||||
}
|
||||
|
||||
//done reading, close
|
||||
bis.close();
|
||||
|
||||
// if ogg vorbis data, we need to pass it unmodified to alBufferData
|
||||
buffer = ByteBuffer.allocateDirect(baos.size());
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer.put(baos.toByteArray());
|
||||
buffer.flip();
|
||||
System.out.println("loaded " + buffer.remaining() + " bytes");
|
||||
} catch (Exception ioe) {
|
||||
ioe.printStackTrace();
|
||||
System.out.println("Attempting to load: " + filename);
|
||||
|
||||
try {
|
||||
BufferedInputStream bis = new BufferedInputStream(StreamPlayer.class.getClassLoader().getResourceAsStream(filename));
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
int bufferLength = 4096;
|
||||
byte[] readBuffer = new byte[bufferLength];
|
||||
int read = -1;
|
||||
|
||||
while ((read = bis.read(readBuffer, 0, bufferLength)) != -1) {
|
||||
baos.write(readBuffer, 0, read);
|
||||
}
|
||||
return buffer;
|
||||
|
||||
//done reading, close
|
||||
bis.close();
|
||||
|
||||
// if ogg vorbis data, we need to pass it unmodified to alBufferData
|
||||
buffer = ByteBuffer.allocateDirect(baos.size());
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer.put(baos.toByteArray());
|
||||
buffer.flip();
|
||||
System.out.println("loaded " + buffer.remaining() + " bytes");
|
||||
} catch (Exception ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
242
src/java/org/lwjgl/test/fmod/SyncTest.java
Normal file
242
src/java/org/lwjgl/test/fmod/SyncTest.java
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* Copyright (c) 2004 LWJGL Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of 'LWJGL' nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.lwjgl.test.fmod;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.Sys;
|
||||
import org.lwjgl.fmod.FMOD;
|
||||
import org.lwjgl.fmod.FMODException;
|
||||
import org.lwjgl.fmod.FMusic;
|
||||
import org.lwjgl.fmod.FMusicModule;
|
||||
import org.lwjgl.fmod.FSound;
|
||||
import org.lwjgl.fmod.callbacks.FMusicCallback;
|
||||
|
||||
/**
|
||||
* $Id$ <br>
|
||||
*
|
||||
* @author Brian Matzon <brian@matzon.dk>
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class SyncTest {
|
||||
|
||||
/** Path to file to play */
|
||||
private String filePath;
|
||||
|
||||
/** Module instance loaded */
|
||||
private FMusicModule module;
|
||||
|
||||
/** Whether test is running */
|
||||
private boolean running = true;
|
||||
|
||||
/** Current row */
|
||||
private int row;
|
||||
|
||||
/** Current order */
|
||||
private int order;
|
||||
|
||||
/** Number of orders in the song */
|
||||
private int numOrders;
|
||||
|
||||
/**
|
||||
* Creates a new SyncTest
|
||||
* @param string
|
||||
*/
|
||||
public SyncTest(String filePath) {
|
||||
this.filePath = filePath;
|
||||
|
||||
// create thread to exit when a key has been pressed
|
||||
Thread t = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
System.in.read();
|
||||
} catch (IOException ioe) {
|
||||
}
|
||||
running = false;
|
||||
}
|
||||
};
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
// check for file existance
|
||||
File file = new File(args[0]);
|
||||
if (!file.exists()) {
|
||||
System.out.println("No such file: " + args[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize FMOD
|
||||
try {
|
||||
System.out.println("Initializing FMOD");
|
||||
FMOD.create();
|
||||
} catch (FMODException fmode) {
|
||||
fmode.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
// start actual test
|
||||
SyncTest sync = new SyncTest(args[0]);
|
||||
sync.executeTest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the test
|
||||
*/
|
||||
public void executeTest() {
|
||||
// do setup
|
||||
setup();
|
||||
|
||||
// if we have a module - get going
|
||||
if (module != null) {
|
||||
// high priority... - might otherwise skip
|
||||
Sys.setProcessPriority(Sys.HIGH_PRIORITY);
|
||||
|
||||
// go go go!
|
||||
run();
|
||||
}
|
||||
|
||||
// we're done - clean up
|
||||
destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup FMOD
|
||||
*/
|
||||
private void setup() {
|
||||
if (!FSound.FSOUND_Init(44100, 32, 0)) {
|
||||
System.out.println("Failed to initialize FMOD");
|
||||
System.out.println("Error: " + FMOD.FMOD_ErrorString(FSound.FSOUND_GetError()));
|
||||
return;
|
||||
}
|
||||
|
||||
// load module
|
||||
System.out.println("Loading " + filePath);
|
||||
module = FMusic.FMUSIC_LoadSong(filePath);
|
||||
|
||||
if (module == null) {
|
||||
System.out.println("Unable to load " + filePath + ": " + FMOD.FMOD_ErrorString(FSound.FSOUND_GetError()));
|
||||
return;
|
||||
}
|
||||
|
||||
// get number of orders
|
||||
numOrders = FMusic.FMUSIC_GetNumOrders(module);
|
||||
|
||||
// install order callback
|
||||
FMusic.FMUSIC_SetOrderCallback(module, new FMusicCallback() {
|
||||
public void FMUSIC_CALLBACK(FMusicModule module, int param) {
|
||||
order = param;
|
||||
}
|
||||
}, 1);
|
||||
|
||||
// install row callback
|
||||
// will be called once PER CHANNEL! - but since we only set the row
|
||||
// no harm is done :)
|
||||
FMusic.FMUSIC_SetRowCallback(module, new FMusicCallback() {
|
||||
public void FMUSIC_CALLBACK(FMusicModule module, int param) {
|
||||
row = param;
|
||||
}
|
||||
}, 1);
|
||||
|
||||
// try to add some userdata
|
||||
ByteBuffer buffer = BufferUtils.createByteBuffer(24);
|
||||
buffer.putInt(1).putInt(2).putInt(3).putInt(4).putInt(5).putInt(6).rewind();
|
||||
FMusic.FMUSIC_SetUserData(module, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update status of module - spew it out in console
|
||||
*/
|
||||
private void update() {
|
||||
// mark as not running when finished
|
||||
if(FMusic.FMUSIC_IsFinished(module)) {
|
||||
running = false;
|
||||
}
|
||||
|
||||
int patternLength = FMusic.FMUSIC_GetPatternLength(module, order);
|
||||
int time = FMusic.FMUSIC_GetTime(module) / 1000;
|
||||
int time2 = FMusic.FMUSIC_GetTime(module) % 1000 / 10;
|
||||
double cpu = Math.round(FSound.FSOUND_GetCPUUsage() * 100.0) / 100.0;
|
||||
|
||||
System.out.println("O: " +
|
||||
((order < 10) ? "0" : "") + order + "/" + numOrders + " | R: "
|
||||
+ ((row < 10) ? "0" : "") + row + "/" + patternLength + " | T: "
|
||||
+ time + "."
|
||||
+ ((time2 < 10) ? "0" : "") + time2 + " | BPM: " + FMusic.FMUSIC_GetBPM(module) + " | Play: " + FMusic.FMUSIC_IsFinished(module)
|
||||
+ " | C: " + FSound.FSOUND_GetChannelsPlaying() + " | CPU: " + cpu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the actual test - that is, play | update ad nausea
|
||||
*/
|
||||
private void run() {
|
||||
// play
|
||||
FMusic.FMUSIC_PlaySong(module);
|
||||
|
||||
// loop, printing update, if we actually changed row
|
||||
int lastRow = row;
|
||||
while(running) {
|
||||
if(lastRow != row) {
|
||||
lastRow = row;
|
||||
update();
|
||||
} else {
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clean up our own mess
|
||||
private void destroy() {
|
||||
if(module != null) {
|
||||
// retrieve userdata
|
||||
ByteBuffer buffer = FMusic.FMUSIC_GetUserData(module, 24);
|
||||
|
||||
// should contain 1,2,3,4,5,6
|
||||
for(int i=0; i<6; i++) {
|
||||
System.out.println(buffer.getInt());
|
||||
}
|
||||
|
||||
FMusic.FMUSIC_FreeSong(module);
|
||||
}
|
||||
FSound.FSOUND_Close();
|
||||
FMOD.destroy();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue