A => Android.mk +48 -0
@@ 0,0 1,48 @@
+
+LOCAL_MODULE := minibpm
+LOCAL_MODULE_FILENAME := libminibpm-jni
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/minibpm/src
+
+MINIBPM_PATH := minibpm
+MINIBPM_SRC_PATH := $(MINIBPM_PATH)/src
+
+MINIBPM_JNI_FILES := \
+ $(MINIBPM_SRC_PATH)/jni/MiniBpmJNI.cpp
+
+MINIBPM_SRC_FILES := \
+ $(MINIBPM_SRC_PATH)/MiniBpm.cpp
+
+LOCAL_SRC_FILES += \
+ $(MINIBPM_JNI_FILES) \
+ $(MINIBPM_SRC_FILES)
+
+LOCAL_CFLAGS_DEBUG := \
+ -g \
+ -mfloat-abi=softfp
+
+LOCAL_CFLAGS_RELEASE := \
+ -O3 \
+ -mfpu=neon \
+ -mfloat-abi=softfp \
+ -ffast-math \
+ -ftree-vectorize \
+ -ftree-vect-loop-version \
+ -freciprocal-math \
+ -fsingle-precision-constant \
+ -D__ARM_ARCH_7__
+
+LOCAL_CFLAGS := \
+ -Wall \
+ -I$(MINIBPM_SRC_PATH) \
+ -DNO_EXCEPTIONS \
+ $(LOCAL_CFLAGS_RELEASE)
+
+LOCAL_LDLIBS += -llog
+
+TARGET_ARCH_ABI := armeabi-v7a
+LOCAL_ARM_MODE := arm
+LOCAL_ARM_NEON := true
+
+include $(BUILD_SHARED_LIBRARY)
+
A => Makefile +14 -0
@@ 0,0 1,14 @@
+
+CXXFLAGS := -O3 -Wall
+
+default: libminibpm.a test
+
+libminibpm.a: src/MiniBpm.o
+ ar cr $@ $^
+ ranlib $@
+
+test:
+ $(MAKE) -C tests
+
+clean:
+ rm -f libminibpm.a src/MiniBpm.o
M README.txt +1 -1
@@ 6,7 6,7 @@ A simple beats-per-minute estimator for
implemented in C++ with few external dependencies.
Written by Chris Cannam, chris.cannam@breakfastquay.com.
-Copyright 2012 Particular Programs Ltd.
+Copyright 2012-2014 Particular Programs Ltd.
See http://breakfastquay.com/minibpm/ for more information.
A => com/breakfastquay/minibpm/MiniBpm.java +118 -0
@@ 0,0 1,118 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ MiniBPM
+ A fixed-tempo BPM estimator for music audio
+ Copyright 2012-2014 Particular Programs Ltd.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. See the file
+ COPYING included with this distribution for more information.
+
+ Alternatively, if you have a valid commercial licence for MiniBPM
+ obtained by agreement with the copyright holders, you may
+ redistribute and/or modify it under the terms described in that
+ licence.
+
+ If you wish to distribute code using MiniBPM under terms other
+ than those of the GNU General Public License, you must obtain a
+ valid commercial licence before doing so.
+*/
+
+package com.breakfastquay.minibpm;
+
+/**
+ * A fixed-tempo BPM estimator. This Java wrapper currently provides
+ * only the single-shot API from the C++ library.
+ *
+ * A single channel of audio only may be supplied (multi-channel is
+ * not supported). To process multi-channel audio, average the
+ * channels first.
+ */
+public class MiniBpm
+{
+ public MiniBpm(int sampleRate) {
+ handle = 0;
+ initialise(sampleRate);
+ }
+
+ /**
+ * Call this to dispose of the tempo estimator after use. You must
+ * do so after you have finished using this estimator object, as
+ * the Java garbage collector cannot collect the native object.
+ */
+ public native void dispose();
+
+ /**
+ * Set the range of valid tempi. The default is 55-190bpm.
+ */
+ public native void setBPMRange(double min, double max);
+
+ /**
+ * Get the current minimum supported tempo.
+ */
+ public native double getBPMMin();
+
+ /**
+ * Get the current maximum supported tempo.
+ */
+ public native double getBPMMax();
+
+ /**
+ * Set the number of beats per bar, if known. If unknown, leave at
+ * the default (which is 4).
+ */
+ public native void setBeatsPerBar(int bpb);
+
+ /**
+ * Get the current number of beats per bar. (This simply returns
+ * the value set by setBeatsPerBar, which is a hint to the tempo
+ * estimator: the estimator does not estimate meter.)
+ */
+ public native int getBeatsPerBar();
+
+ /**
+ * Return the estimated tempo in bpm of the music audio in the
+ * given sequence of samples. nsamples contains the number of
+ * samples, starting at the given offset in the given input
+ * array. If the tempo cannot be estimated because the clip is too
+ * short, return 0.
+ *
+ * The input samples are expected to be in the range [-1,1].
+ *
+ * If you wish to subsequently obtain a tempo estimate of a
+ * different clip, you must call reset() before calling this
+ * function again. (This is so that the data that is available to
+ * be returned from getTempoCandidates can be cleared.)
+ */
+ public native double estimateTempoOfSamples(float[] input,
+ int offset, int nsamples);
+
+ /**
+ * Return all candidate tempi for the last tempo estimation that
+ * was carried out, in order of likelihood (best first). The value
+ * returned from estimateTempoOfSamples will therefore be the
+ * first in the returned sequence. Calling reset() will clear this
+ * information.
+ */
+ public native double[] getTempoCandidates();
+
+ /**
+ * Prepare the object to carry out another tempo estimation on a
+ * new audio clip. You can either call this between uses, or
+ * simply destroy this object and construct a new one.
+ */
+ public native void reset();
+
+ private native void initialise(int sampleRate);
+ private long handle;
+
+ static {
+ System.loadLibrary("minibpm-jni");
+ }
+};
+
+
+
M src/MiniBpm.cpp +5 -4
@@ 3,7 3,7 @@
/*
MiniBPM
A fixed-tempo BPM estimator for music audio
- Copyright 2012 Particular Programs Ltd.
+ Copyright 2012-2014 Particular Programs Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ 461,6 461,7 @@ public:
m_lfdf.clear();
m_hfdf.clear();
m_rms.clear();
+ m_candidates.clear();
m_partialFill = 0;
}
@@ 506,13 507,13 @@ public:
zero(acf, acfLength);
- acfcalc.acfUnityNormalised(m_lfdf.data(), temp);
+ acfcalc.acfUnityNormalised(&m_lfdf[0], temp);
for (int i = 0; i < acfLength; ++i) acf[i] += temp[i];
- acfcalc.acfUnityNormalised(m_hfdf.data(), temp);
+ acfcalc.acfUnityNormalised(&m_hfdf[0], temp);
for (int i = 0; i < acfLength; ++i) acf[i] += temp[i] * 0.5;
- acfcalc.acfUnityNormalised(m_rms.data(), temp);
+ acfcalc.acfUnityNormalised(&m_rms[0], temp);
for (int i = 0; i < acfLength; ++i) acf[i] += temp[i] * 0.1;
int minlag = Autocorrelation::bpmToLag(m_maxbpm, hopsPerSec);
M src/MiniBpm.h +11 -3
@@ 3,7 3,7 @@
/*
MiniBPM
A fixed-tempo BPM estimator for music audio
- Copyright 2012 Particular Programs Ltd.
+ Copyright 2012-2014 Particular Programs Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ 70,7 70,9 @@ public:
void setBeatsPerBar(int bpb);
/**
- * Get the current number of beats per bar.
+ * Get the current number of beats per bar. (This simply returns
+ * the value set by setBeatsPerBar, which is a hint to the tempo
+ * estimator: the estimator does not estimate meter.)
*/
int getBeatsPerBar() const;
@@ 84,6 86,11 @@ public:
* calls followed by an estimateTempo() call. Do not call both
* process() and estimateTempoOfSamples() on the same estimator
* object.
+ *
+ * If you wish to subsequently obtain a tempo estimate of a
+ * different clip, you must call reset() before calling this
+ * function again. (This is so that the data that is available to
+ * be returned from getTempoCandidates can be cleared.)
*/
double estimateTempoOfSamples(const float *samples, int nsamples);
@@ 106,7 113,8 @@ public:
* Return all candidate tempi for the last tempo estimation that
* was carried out, in order of likelihood (best first). The value
* returned from estimateTempo or estimateTempoOfSamples will
- * therefore be the first in the returned sequence.
+ * therefore be the first in the returned sequence. Calling
+ * reset() will clear this information.
*/
std::vector<double> getTempoCandidates() const;
A => src/jni/MiniBpmJNI.cpp +205 -0
@@ 0,0 1,205 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ MiniBPM
+ A fixed-tempo BPM estimator for music audio
+ Copyright 2012-2014 Particular Programs Ltd.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. See the file
+ COPYING included with this distribution for more information.
+
+ Alternatively, if you have a valid commercial licence for MiniBPM
+ obtained by agreement with the copyright holders, you may
+ redistribute and/or modify it under the terms described in that
+ licence.
+
+ If you wish to distribute code using MiniBPM under terms other
+ than those of the GNU General Public License, you must obtain a
+ valid commercial licence before doing so.
+*/
+
+#include "MiniBpm.h"
+
+#include <jni.h>
+
+using namespace breakfastquay;
+
+extern "C" {
+/*
+ * Class: com_breakfastquay_minibpm_MiniBpm
+ * Method: dispose
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_breakfastquay_minibpm_MiniBpm_dispose
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_breakfastquay_minibpm_MiniBpm
+ * Method: setBPMRange
+ * Signature: (DD)V
+ */
+JNIEXPORT void JNICALL Java_com_breakfastquay_minibpm_MiniBpm_setBPMRange
+ (JNIEnv *, jobject, jdouble, jdouble);
+
+/*
+ * Class: com_breakfastquay_minibpm_MiniBpm
+ * Method: getBPMMin
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL Java_com_breakfastquay_minibpm_MiniBpm_getBPMMin
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_breakfastquay_minibpm_MiniBpm
+ * Method: getBPMMax
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL Java_com_breakfastquay_minibpm_MiniBpm_getBPMMax
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_breakfastquay_minibpm_MiniBpm
+ * Method: setBeatsPerBar
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_breakfastquay_minibpm_MiniBpm_setBeatsPerBar
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_breakfastquay_minibpm_MiniBpm
+ * Method: getBeatsPerBar
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_breakfastquay_minibpm_MiniBpm_getBeatsPerBar
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_breakfastquay_minibpm_MiniBpm
+ * Method: estimateTempoOfSamples
+ * Signature: ([FII)D
+ */
+JNIEXPORT jdouble JNICALL Java_com_breakfastquay_minibpm_MiniBpm_estimateTempoOfSamples
+ (JNIEnv *, jobject, jfloatArray, jint, jint);
+
+/*
+ * Class: com_breakfastquay_minibpm_MiniBpm
+ * Method: getTempoCandidates
+ * Signature: ()[D
+ */
+JNIEXPORT jdoubleArray JNICALL Java_com_breakfastquay_minibpm_MiniBpm_getTempoCandidates
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_breakfastquay_minibpm_MiniBpm
+ * Method: reset
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_breakfastquay_minibpm_MiniBpm_reset
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_breakfastquay_minibpm_MiniBpm
+ * Method: initialise
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_breakfastquay_minibpm_MiniBpm_initialise
+ (JNIEnv *, jobject, jint);
+
+
+}
+
+MiniBPM *
+getMiniBPM(JNIEnv *env, jobject obj)
+{
+ jclass c = env->GetObjectClass(obj);
+ jfieldID fid = env->GetFieldID(c, "handle", "J");
+ jlong handle = env->GetLongField(obj, fid);
+ return (MiniBPM *)handle;
+}
+
+void
+setMiniBPM(JNIEnv *env, jobject obj, MiniBPM *minibpm)
+{
+ jclass c = env->GetObjectClass(obj);
+ jfieldID fid = env->GetFieldID(c, "handle", "J");
+ jlong handle = (jlong)minibpm;
+ env->SetLongField(obj, fid, handle);
+}
+
+JNIEXPORT void JNICALL
+Java_com_breakfastquay_minibpm_MiniBpm_initialise(JNIEnv *env, jobject obj, jint sampleRate)
+{
+ setMiniBPM(env, obj, new MiniBPM(sampleRate));
+}
+
+JNIEXPORT void JNICALL
+Java_com_breakfastquay_minibpm_MiniBpm_dispose(JNIEnv *env, jobject obj)
+{
+ delete getMiniBPM(env, obj);
+ setMiniBPM(env, obj, 0);
+}
+
+JNIEXPORT void JNICALL
+Java_com_breakfastquay_minibpm_MiniBpm_setBPMRange(JNIEnv *env, jobject obj, jdouble min, jdouble max)
+{
+ getMiniBPM(env, obj)->setBPMRange(min, max);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_com_breakfastquay_minibpm_MiniBpm_getBPMMin(JNIEnv *env, jobject obj)
+{
+ double min, max;
+ getMiniBPM(env, obj)->getBPMRange(min, max);
+ return min;
+}
+
+JNIEXPORT jdouble JNICALL
+Java_com_breakfastquay_minibpm_MiniBpm_getBPMMax(JNIEnv *env, jobject obj)
+{
+ double min, max;
+ getMiniBPM(env, obj)->getBPMRange(min, max);
+ return max;
+}
+
+JNIEXPORT void JNICALL
+Java_com_breakfastquay_minibpm_MiniBpm_setBeatsPerBar(JNIEnv *env, jobject obj, jint bpb)
+{
+ getMiniBPM(env, obj)->setBeatsPerBar(bpb);
+}
+
+JNIEXPORT jint JNICALL
+Java_com_breakfastquay_minibpm_MiniBpm_getBeatsPerBar(JNIEnv *env, jobject obj)
+{
+ return getMiniBPM(env, obj)->getBeatsPerBar();
+}
+
+JNIEXPORT jdouble JNICALL
+Java_com_breakfastquay_minibpm_MiniBpm_estimateTempoOfSamples(JNIEnv *env, jobject obj, jfloatArray data, jint offset, jint n)
+{
+ float *arr = env->GetFloatArrayElements(data, 0);
+
+ double estimate =
+ getMiniBPM(env, obj)->estimateTempoOfSamples(arr + offset, n);
+
+ env->ReleaseFloatArrayElements(data, arr, 0);
+
+ return estimate;
+}
+
+JNIEXPORT jdoubleArray JNICALL
+Java_com_breakfastquay_minibpm_MiniBpm_getTempoCandidates(JNIEnv *env, jobject obj)
+{
+ std::vector<double> candidates = getMiniBPM(env, obj)->getTempoCandidates();
+ jdoubleArray out = env->NewDoubleArray(candidates.size());
+ env->SetDoubleArrayRegion(out, 0, candidates.size(), &candidates[0]);
+ return out;
+}
+
+JNIEXPORT void JNICALL
+Java_com_breakfastquay_minibpm_MiniBpm_reset(JNIEnv *env, jobject obj)
+{
+ getMiniBPM(env, obj)->reset();
+}
M tests/TestMiniBpm.cpp +1 -1
@@ 3,7 3,7 @@
/*
MiniBPM
A fixed-tempo BPM estimator for music audio
- Copyright 2012 Particular Programs Ltd.
+ Copyright 2012-2014 Particular Programs Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
M vamp/MiniBpmVamp.cpp +1 -1
@@ 3,7 3,7 @@
/*
MiniBPM
A fixed-tempo BPM estimator for music audio
- Copyright 2012 Particular Programs Ltd.
+ Copyright 2012-2014 Particular Programs Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
M vamp/MiniBpmVamp.h +1 -1
@@ 3,7 3,7 @@
/*
MiniBPM
A fixed-tempo BPM estimator for music audio
- Copyright 2012 Particular Programs Ltd.
+ Copyright 2012-2014 Particular Programs Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
M vamp/libmain.cpp +1 -1
@@ 3,7 3,7 @@
/*
MiniBPM
A fixed-tempo BPM estimator for music audio
- Copyright 2012 Particular Programs Ltd.
+ Copyright 2012-2014 Particular Programs Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as