float* target = (float*)env->GetDirectBufferAddress(obj_target);
-//@line:37
+//@line:42
\r
float inv = 1 / 32767.0f;\r
for( int i = 0; i < numSamples; i++, source++, target++ )\r
short* target = (short*)env->GetDirectBufferAddress(obj_target);
-//@line:57
+//@line:62
\r
for( int i = 0; i < numSamples; i++, source++, target++ )\r
*target = (short)(*source * 32767);\r
short* target = (short*)env->GetDirectBufferAddress(obj_target);
-//@line:69
+//@line:74
\r
for( int i = 0; i < numSamples / 2; i++ )\r
{\r
float* target = (float*)env->GetDirectBufferAddress(obj_target);
-//@line:86
+//@line:91
\r
for( int i = 0; i < numSamples / 2; i++ )\r
{\r
static inline jfloat wrapped_Java_com_badlogic_gdx_audio_analysis_AudioTools_spectralFlux
(JNIEnv* env, jclass clazz, jobject obj_spectrumA, jobject obj_spectrumB, jint numSamples, float* spectrumA, float* spectrumB) {
-//@line:103
+//@line:108
\r
float flux = 0;\r
for( int i = 0; i < numSamples; i++ )\r
#include <com.badlogic.gdx.audio.analysis.KissFFT.h>
-//@line:64
+//@line:58
#include <kiss_fftr.h>
#include <stdlib.h>
JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_create(JNIEnv* env, jclass clazz, jint numSamples) {
-//@line:91
+//@line:85
\r
KissFFT* fft = new KissFFT();\r
fft->config = kiss_fftr_alloc(numSamples,0,NULL,NULL);\r
JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_destroy(JNIEnv* env, jclass clazz, jlong handle) {
-//@line:101
+//@line:95
\r
KissFFT* fft = (KissFFT*)handle;\r
free(fft->config);\r
}
-JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_spectrum(JNIEnv* env, jclass clazz, jlong handle, jobject obj_samples, jobject obj_spectrum) {
- short* samples = (short*)env->GetDirectBufferAddress(obj_samples);
- float* spectrum = (float*)env->GetDirectBufferAddress(obj_spectrum);
+JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_spectrum(JNIEnv* env, jclass clazz, jlong handle, jshortArray obj_samples, jfloatArray obj_spectrum) {
+ short* samples = (short*)env->GetPrimitiveArrayCritical(obj_samples, 0);
+ float* spectrum = (float*)env->GetPrimitiveArrayCritical(obj_spectrum, 0);
-//@line:114
+//@line:108
\r
KissFFT* fft = (KissFFT*)handle;\r
kiss_fftr( fft->config, (kiss_fft_scalar*)samples, fft->spectrum );\r
\r
int len = fft->numSamples / 2 + 1;\r
- float* out = (float*)spectrum;\r
- \r
for( int i = 0; i < len; i++ )\r
{\r
float re = scale(fft->spectrum[i].r) * fft->numSamples;\r
float im = scale(fft->spectrum[i].i) * fft->numSamples;\r
\r
if( i > 0 )\r
- out[i] = sqrtf(re*re + im*im) / (fft->numSamples / 2);\r
+ spectrum[i] = sqrtf(re*re + im*im) / (fft->numSamples);\r
else\r
- out[i] = sqrtf(re*re + im*im) / (fft->numSamples);\r
+ spectrum[i] = sqrtf(re*re + im*im) / (fft->numSamples);\r
}\r
+ env->ReleasePrimitiveArrayCritical(obj_samples, samples, 0);
+ env->ReleasePrimitiveArrayCritical(obj_spectrum, spectrum, 0);
}
-JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_getRealPart(JNIEnv* env, jclass clazz, jlong handle, jobject obj_real) {
- short* real = (short*)env->GetDirectBufferAddress(obj_real);
+JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_getRealPart(JNIEnv* env, jclass clazz, jlong handle, jshortArray obj_real) {
+ short* real = (short*)env->GetPrimitiveArrayCritical(obj_real, 0);
-//@line:133
+//@line:125
\r
KissFFT* fft = (KissFFT*)handle;\r
- short* out = (short*)real;\r
for( int i = 0; i < fft->numSamples / 2; i++ )\r
- out[i] = fft->spectrum[i].r;\r
+ real[i] = fft->spectrum[i].r;\r
+ env->ReleasePrimitiveArrayCritical(obj_real, real, 0);
}
-JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_getImagPart(JNIEnv* env, jclass clazz, jlong handle, jobject obj_imag) {
- short* imag = (short*)env->GetDirectBufferAddress(obj_imag);
+JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_getImagPart(JNIEnv* env, jclass clazz, jlong handle, jshortArray obj_imag) {
+ short* imag = (short*)env->GetPrimitiveArrayCritical(obj_imag, 0);
-//@line:140
+//@line:131
\r
KissFFT* fft = (KissFFT*)handle;\r
- short* out = (short*)imag;\r
for( int i = 0; i < fft->numSamples / 2; i++ )\r
- out[i] = fft->spectrum[i].i;\r
+ imag[i] = fft->spectrum[i].i;\r
+ env->ReleasePrimitiveArrayCritical(obj_imag, imag, 0);
}
/*\r
* Class: com_badlogic_gdx_audio_analysis_KissFFT\r
* Method: spectrum\r
- * Signature: (JLjava/nio/ShortBuffer;Ljava/nio/FloatBuffer;)V\r
+ * Signature: (J[S[F)V\r
*/\r
JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_spectrum\r
- (JNIEnv *, jclass, jlong, jobject, jobject);\r
+ (JNIEnv *, jclass, jlong, jshortArray, jfloatArray);\r
\r
/*\r
* Class: com_badlogic_gdx_audio_analysis_KissFFT\r
* Method: getRealPart\r
- * Signature: (JLjava/nio/ShortBuffer;)V\r
+ * Signature: (J[S)V\r
*/\r
JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_getRealPart\r
- (JNIEnv *, jclass, jlong, jobject);\r
+ (JNIEnv *, jclass, jlong, jshortArray);\r
\r
/*\r
* Class: com_badlogic_gdx_audio_analysis_KissFFT\r
* Method: getImagPart\r
- * Signature: (JLjava/nio/ShortBuffer;)V\r
+ * Signature: (J[S)V\r
*/\r
JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_getImagPart\r
- (JNIEnv *, jclass, jlong, jobject);\r
+ (JNIEnv *, jclass, jlong, jshortArray);\r
\r
#ifdef __cplusplus\r
}\r
\r
new AntScriptGenerator().generate(buildConfig, win32home, win32, win64, lin32, lin64, android);\r
\r
- BuildExecutor.executeAnt("jni/build-windows32home.xml", " -v");\r
+ BuildExecutor.executeAnt("jni/build-windows32home.xml", "clean postcompile -v");\r
BuildExecutor.executeAnt("jni/build.xml", "pack-natives -v");\r
}\r
}\r
\r
/**\r
* Generates a mono PCM sample buffer for the given frequency and length in\r
+ * samples for use with {@link AudioMixer}.\r
+ * \r
+ * @param frequency\r
+ * @param numSamples\r
+ * @return PCM data for a sine wave\r
+ */\r
+ public static short[] generate(int samplingRate, int frequency, int numSamples) {\r
+ short[] samples = new short[numSamples];\r
+ float increment = (float) (2 * Math.PI) * frequency / (float)samplingRate;\r
+ float angle = 0;\r
+\r
+ for (int i = 0; i < numSamples; i++) {\r
+ samples[i] = (short)(Math.sin(angle) * Short.MAX_VALUE);\r
+ angle += increment;\r
+ }\r
+ \r
+ return samples;\r
+ }\r
+ \r
+ /**\r
+ * Generates a mono PCM sample buffer for the given frequency and length in\r
* seconds for use with {@link AudioMixer}.\r
* \r
* @param frequency\r
*/\r
public static short[] generate(int samplingRate, int frequency, float length) {\r
int numSamples = (int) (samplingRate * length);\r
- short[] samples = new short[numSamples];\r
+ return generate(samplingRate, frequency, numSamples);\r
+ }\r
+ \r
+ /**\r
+ * Generates a mono PCM sample buffer for the given frequency and length in\r
+ * seconds for use with {@link AudioMixer}.\r
+ * \r
+ * @param frequency\r
+ * @param length\r
+ * @return\r
+ */\r
+ public static float[] generateFloat(int samplingRate, int frequency, int numSamples) {\r
+ float[] samples = new float[numSamples];\r
float increment = (float) (2 * Math.PI) * frequency / (float)samplingRate;\r
float angle = 0;\r
\r
for (int i = 0; i < numSamples; i++) {\r
- samples[i] = (short)(Math.sin(angle) * Short.MAX_VALUE);\r
+ samples[i] = (float)Math.sin(angle);\r
angle += increment;\r
}\r
- \r
return samples;\r
}\r
+ \r
+ /**\r
+ * Generates a mono PCM sample buffer for the given frequency and length in\r
+ * seconds for use with {@link AudioMixer}.\r
+ * \r
+ * @param frequency\r
+ * @param length\r
+ * @return\r
+ */\r
+ public static float[] generateFloat(int samplingRate, int frequency, float length) {\r
+ int numSamples = (int) (samplingRate * length);\r
+ return generateFloat(samplingRate, frequency, numSamples);\r
+ }\r
}\r
coslookup[i] = (float)Math.cos(-(float)Math.PI / i);\r
}\r
}\r
-\r
-// public static void main (String[] argv) {\r
-// FFT fft = new FFT(1024, 44100);\r
-// System.out.println(fft.getRealPart().length);\r
-// System.out.println(fft.getSpectrum().length);\r
-// }\r
}\r
\r
package com.badlogic.gdx.audio.analysis;\r
\r
-import java.nio.FloatBuffer;\r
-import java.nio.ShortBuffer;\r
-\r
import com.badlogic.gdx.utils.Disposable;\r
import com.badlogic.gdx.utils.SharedLibraryLoader;\r
\r
* \r
* @param samples the samples\r
* @param spectrum the spectrum */\r
- public void spectrum (ShortBuffer samples, FloatBuffer spectrum) {\r
+ public void spectrum (short[] samples, float[] spectrum) {\r
spectrum(addr, samples, spectrum);\r
}\r
\r
destroy(addr);\r
}\r
\r
- public void getRealPart (ShortBuffer real) {\r
+ public void getRealPart (short[] real) {\r
getRealPart(addr, real);\r
}\r
\r
- public void getImagPart (ShortBuffer imag) {\r
+ public void getImagPart (short[] imag) {\r
getImagPart(addr, imag);\r
}\r
\r
* @param handle the handle to the kiss fft object\r
* @param samples the samples in 16-bit signed PCM encoding\r
* @param spectrum the spectrum */\r
- private static native void spectrum (long handle, ShortBuffer samples, FloatBuffer spectrum); /*\r
+ private static native void spectrum (long handle, short[] samples, float[] spectrum); /*\r
KissFFT* fft = (KissFFT*)handle;\r
kiss_fftr( fft->config, (kiss_fft_scalar*)samples, fft->spectrum );\r
\r
int len = fft->numSamples / 2 + 1;\r
- float* out = (float*)spectrum;\r
- \r
for( int i = 0; i < len; i++ )\r
{\r
float re = scale(fft->spectrum[i].r) * fft->numSamples;\r
float im = scale(fft->spectrum[i].i) * fft->numSamples;\r
\r
if( i > 0 )\r
- out[i] = sqrtf(re*re + im*im) / (fft->numSamples / 2);\r
+ spectrum[i] = sqrtf(re*re + im*im) / (fft->numSamples);\r
else\r
- out[i] = sqrtf(re*re + im*im) / (fft->numSamples);\r
+ spectrum[i] = sqrtf(re*re + im*im) / (fft->numSamples);\r
}\r
*/\r
\r
- private static native void getRealPart (long handle, ShortBuffer real); /*\r
+ private static native void getRealPart (long handle, short[] real); /*\r
KissFFT* fft = (KissFFT*)handle;\r
- short* out = (short*)real;\r
for( int i = 0; i < fft->numSamples / 2; i++ )\r
- out[i] = fft->spectrum[i].r;\r
+ real[i] = fft->spectrum[i].r;\r
*/\r
\r
- private static native void getImagPart (long handle, ShortBuffer imag); /*\r
+ private static native void getImagPart (long handle, short[] imag); /*\r
KissFFT* fft = (KissFFT*)handle;\r
- short* out = (short*)imag;\r
for( int i = 0; i < fft->numSamples / 2; i++ )\r
- out[i] = fft->spectrum[i].i;\r
+ imag[i] = fft->spectrum[i].i;\r
*/\r
}\r
input.close();\r
output.close();\r
} catch (IOException ex) {\r
- ex.printStackTrace();\r
- throw new RuntimeException(ex);\r
}\r
return nativeFile.exists() ? nativeFile.getAbsolutePath() : null;\r
}\r
// this is only here for me to debug native code faster\r
new SharedLibraryLoader("../../gdx/libs/gdx-natives.jar").load("gdx");\r
\r
- GdxTest test = new com.badlogic.gdx.tests.StbTrueTypeTest();\r
+ GdxTest test = new com.badlogic.gdx.tests.ImmediateModeRendererTest();\r
JoglApplicationConfiguration config = new JoglApplicationConfiguration();\r
config.useGL20 = test.needsGL20();\r
new JoglApplication(test, config);\r
\r
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;\r
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;\r
+import com.badlogic.gdx.tests.ImmediateModeRendererTest;\r
+import com.badlogic.gdx.tests.ShapeRendererTest;\r
import com.badlogic.gdx.tests.SoundTouchTest;\r
import com.badlogic.gdx.tests.VorbisTest;\r
import com.badlogic.gdx.tests.WavTest;\r
new SharedLibraryLoader("../../gdx/libs/gdx-natives.jar").load("gdx");\r
new SharedLibraryLoader("../../extensions/gdx-audio/libs/gdx-audio-natives.jar").load("gdx-audio");\r
\r
- GdxTest test = new WavTest();\r
+ GdxTest test = new ImmediateModeRendererTest();\r
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();\r
config.useGL20 = test.needsGL20();\r
config.vSyncEnabled = true;\r
\r
package com.badlogic.gdx.tests;\r
\r
+import java.nio.FloatBuffer;\r
+import java.nio.ShortBuffer;\r
+import java.util.Arrays;\r
\r
+import com.badlogic.gdx.audio.AudioBuild;\r
+import com.badlogic.gdx.audio.analysis.AudioTools;\r
+import com.badlogic.gdx.audio.analysis.FFT;\r
+import com.badlogic.gdx.audio.analysis.KissFFT;\r
+import com.badlogic.gdx.utils.GdxNativesLoader;\r
+import com.badlogic.gdx.utils.SharedLibraryLoader;\r
+\r
+/**\r
+ * Simples test that makes sure the output of KissFFT and FFT are (mostly)\r
+ * equal.\r
+ * @author mzechner\r
+ *\r
+ */\r
public class FFTTest {\r
-// static int SAMPLES = 256;\r
-//\r
-// public static void main (String[] argv) {\r
-// GdxNativesLoader.load();\r
-// float[] samples = new float[SAMPLES];\r
-// ShortBuffer shortSamples = AudioTools.allocateShortBuffer(SAMPLES, 1);\r
-//\r
-//// createFlat( samples, shortSamples );\r
-// createSine(samples, shortSamples);\r
-// analyse(samples, shortSamples);\r
-// }\r
-//\r
-// private static void analyse (float samples[], ShortBuffer shortSamples) {\r
-// FFT fft = new FFT(SAMPLES, 44100);\r
-// KissFFT kfft = new KissFFT(SAMPLES);\r
-// fft.forward(samples);\r
-// float[] spectrum = fft.getSpectrum();\r
-// FloatBuffer floatSpectrum = AudioTools.allocateFloatBuffer(SAMPLES / 2 + 1, 1);\r
-//\r
-// System.out.println(Arrays.toString(spectrum));\r
-//\r
-// System.out.print("[");\r
-// kfft.spectrum(shortSamples, floatSpectrum);\r
-// for (int i = 0; i < SAMPLES / 2 + 1; i++)\r
-// System.out.print(floatSpectrum.get(i) + ", ");\r
-// System.out.println("]");\r
-//\r
-// System.out.println(sum(samples) / SAMPLES);\r
-//// System.out.println( sum( spectrum ) );\r
-//// System.out.println( sum( floatSpectrum ));\r
-// kfft.dispose();\r
-// }\r
-//\r
-// private static float sum (float samples[]) {\r
-// float sum = 0;\r
-// for (int i = 1; i < samples.length; i++)\r
-// sum += samples[i];\r
-// return sum;\r
-// }\r
-//\r
-// private static float sum (FloatBuffer buffer) {\r
-// float sum = 0;\r
-// for (int i = 1; i < SAMPLES / 2 + 1; i++)\r
-// sum += buffer.get(i) * 2 / SAMPLES;\r
-// return sum;\r
-// }\r
-//\r
-// private static void createFlat (float samples[], ShortBuffer shortSamples) {\r
-// for (int i = 0; i < samples.length; i++) {\r
-// samples[i] = 1;\r
-// shortSamples.put(Short.MAX_VALUE);\r
-// }\r
-// }\r
-//\r
-// private static void createSine (float samples[], ShortBuffer shortSamples) {\r
-// final float frequency = 44100 / (SAMPLES / 2);\r
-// float increment = (float)(2 * Math.PI) * frequency / 44100; // angular increment for each sample\r
-// float angle = 0;\r
-// final float frequency2 = 44100 / (SAMPLES / 2) * 4;\r
-// float increment2 = (float)(2 * Math.PI) * frequency2 / 44100;\r
-// float angle2 = 0;\r
-//\r
-// for (int i = 0; i < samples.length; i++) {\r
-// samples[i] = Math.max(0, Math.min((float)Math.sin(angle) + (float)Math.sin(angle2), 1));\r
-// shortSamples.put((short)(Short.MAX_VALUE * samples[i]));\r
-// angle += increment;\r
-// angle2 += increment2;\r
-// }\r
-// }\r
+ static int SAMPLES = 1024;\r
+\r
+ public static void main (String[] argv) throws Exception {\r
+ new SharedLibraryLoader("../../extensions/gdx-audio/libs/gdx-audio-natives.jar").load("gdx-audio");\r
+ short[] samples = AudioTools.generate(44100, 440, SAMPLES);\r
+ float[] samplesFloat = AudioTools.generateFloat(44100, 440, SAMPLES);\r
+ \r
+ // Damien's FFT\r
+ FFT fft = new FFT(SAMPLES, 44100);\r
+ fft.forward(samplesFloat);\r
+ float[] spectrum = fft.getSpectrum(); \r
+ System.out.println(Arrays.toString(spectrum));\r
+\r
+ // KissFFT\r
+ spectrum = new float[SAMPLES / 2 + 1];\r
+ KissFFT kfft = new KissFFT(SAMPLES);\r
+ kfft.spectrum(samples, spectrum);\r
+ System.out.println(Arrays.toString(spectrum));\r
+ kfft.dispose();\r
+ }\r
}\r
\r
import com.badlogic.gdx.Gdx;\r
import com.badlogic.gdx.graphics.GL10;\r
+import com.badlogic.gdx.graphics.GL20;\r
+import com.badlogic.gdx.graphics.GLCommon;\r
import com.badlogic.gdx.graphics.Texture;\r
+import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer;\r
import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer10;\r
+import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer20;\r
+import com.badlogic.gdx.math.Matrix4;\r
import com.badlogic.gdx.tests.utils.GdxTest;\r
\r
public class ImmediateModeRendererTest extends GdxTest {\r
- ImmediateModeRenderer10 renderer;\r
+ Matrix4 projMatrix = new Matrix4();\r
+ ImmediateModeRenderer renderer;\r
Texture texture;\r
\r
@Override\r
\r
@Override\r
public void render () {\r
- Gdx.graphics.getGL10().glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());\r
- Gdx.graphics.getGL10().glEnable(GL10.GL_TEXTURE_2D);\r
+ Gdx.gl.glEnable(GL10.GL_TEXTURE_2D);\r
texture.bind();\r
- renderer.begin(GL10.GL_TRIANGLES);\r
+ renderer.begin(projMatrix, GL10.GL_TRIANGLES);\r
renderer.texCoord(0, 0);\r
renderer.color(1, 0, 0, 1);\r
renderer.vertex(-0.5f, -0.5f, 0);\r
\r
@Override\r
public void create () {\r
- renderer = new ImmediateModeRenderer10();\r
+ if(Gdx.graphics.isGL20Available()) \r
+ renderer = new ImmediateModeRenderer20(false, true, 1);\r
+ else\r
+ renderer = new ImmediateModeRenderer10();\r
texture = new Texture(Gdx.files.internal("data/badlogic.jpg"));\r
}\r
\r
@Override\r
public boolean needsGL20 () {\r
- return false;\r
+ return true;\r
}\r
\r
}\r
\r
@Override\r
public boolean needsGL20 () {\r
- return false;\r
+ return true;\r
}\r
\r
ShapeRenderer renderer;\r