Modified:
/trunk/src/android/AndroidManifest.xml
/trunk/src/android/src/org/musikcube/core/PaceDetector.java
/trunk/src/android/src/org/musikcube/core/Workout.java
=======================================
--- /trunk/src/android/AndroidManifest.xml Mon Aug 31 03:00:07 2009
+++ /trunk/src/android/AndroidManifest.xml Mon Aug 31 07:01:12 2009
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.musikcube"
- android:versionName="1.0.2" android:versionCode="2">
+ android:versionName="1.0.3" android:versionCode="3">
<application android:icon="@drawable/icon"
android:label="@string/app_name" android:name="App"
android:debuggable="false">
<activity android:name=".main"
android:label="@string/app_name"
android:launchMode="singleTask" android:screenOrientation="portrait">
=======================================
--- /trunk/src/android/src/org/musikcube/core/PaceDetector.java Mon Aug 31
03:00:07 2009
+++ /trunk/src/android/src/org/musikcube/core/PaceDetector.java Mon Aug 31
07:01:12 2009
@@ -11,21 +11,25 @@
public class PaceDetector implements Runnable, SensorEventListener{
- static final public float MAX_BPM = 100;
- static final public float MIN_BPM = 40;
+ static final public float MAX_BPM = 170;
+ static final public float MIN_BPM = 45;
+ static final public float MAX_TIME_DIFF = 60000/MIN_BPM;
+ static final public float MIN_TIME_DIFF = 60000/MAX_BPM;
static final public int WAVE_MEMORY = 20;
static final public int WAVE_MIN_CALC = 10;
static final public float WAVE_MIN_BPM_DIFF = 100; // This is in
miliseconds
static final public int WAVE_COMPARE = 4;
static final public int MIN_PLAYTIME = 20000; // Play at leased 20
seconds of a track
+ static final public int BPM_ACCEPTANCE = 5;
//static final public float BPM_THRESHOLD = 10; // if BPM is off by more
than 10 bpm, switch track
private float currentBPM = 0;
- private float currentAccuracy = 0;
- private long currentBPMstart = 0;
+ //private float currentAccuracy = 0;
+ //private long currentBPMstart = 0;
private Object lock = new Object();
-
- private Context context;
+ public java.util.ArrayList<Float> lastBPMs = new
java.util.ArrayList<Float>();
+
+ //private Context context;
private class PaceDimension{
public java.util.ArrayList<Long> beatTimes = new
java.util.ArrayList<Long>();
@@ -70,33 +74,39 @@
}
// Lets calculate BPM
- long bpmSum = 0;
+ long timediffSum = 0;
//java.util.TreeSet<Long> bpms = new java.util.TreeSet<Long>();
- java.util.ArrayList<Long> bpms = new java.util.ArrayList<Long>();
- for(int i=0;i<this.beatTimes.size()-WAVE_COMPARE;i++){
+ java.util.ArrayList<Long> timediffs = new java.util.ArrayList<Long>();
+ final int beatTimesSize = this.beatTimes.size();
+ for(int i=0;i<beatTimesSize;i++){
long orgSample = this.beatTimes.get(i);
- for(int j=i+1;j<i+WAVE_COMPARE;j++){
+ boolean valid = true;
+ for(int j=i+1;j<beatTimesSize && valid;j++){
//float bpmSample = 60000/(this.beatTimes.get(j)-orgSample);
- long bpmSample = this.beatTimes.get(j)-orgSample;
+ long timeSample = this.beatTimes.get(j)-orgSample;
//Log.v("MC2::C","s "+bpmSample);
- if(bpmSample>(60000/MAX_BPM) && bpmSample<(60000/MIN_BPM)){
- bpms.add(bpmSample);
- bpmSum += bpmSample;
+ if(timeSample<MAX_TIME_DIFF){
+ if(timeSample>MIN_TIME_DIFF){
+ timediffs.add(timeSample);
+ timediffSum += timeSample;
+ }
+ }else{
+ valid = false;
}
}
}
- Collections.sort(bpms);
+ Collections.sort(timediffs);
//Log.v("MC2::BEAT","B "+(bpms.size()));
// Lets remove the most "off" samples and correct the AVG until we
are down to the desired "diff"
boolean qualified = false;
long bpmDiff = 0;
- while(!qualified && bpms.size()>=WAVE_MIN_CALC){
- Long first = bpms.get(0);
- Long last = bpms.get(bpms.size()-1);
+ while(!qualified && timediffs.size()>=WAVE_MIN_CALC){
+ Long first = timediffs.get(0);
+ Long last = timediffs.get(timediffs.size()-1);
bpmDiff = last-first;
- int bpmSize = bpms.size();
+ int timediffSize = timediffs.size();
// Log.v("MC2::DIFF","diff "+bpmSize+" "+first+"-"+last+" diff="+bpmDiff);
@@ -104,15 +114,15 @@
qualified = true;
}else{
// Remove the element that is most far away from the average
- long avg = bpmSum/bpmSize;
+ long avg = timediffSum/timediffSize;
if(avg-first>last-avg){
// Remove first
- bpmSum -= first;
- bpms.remove(0);
+ timediffSum -= first;
+ timediffs.remove(0);
}else{
// Remove last
- bpmSum -= last;
- bpms.remove(bpms.size()-1);
+ timediffSum -= last;
+ timediffs.remove(timediffs.size()-1);
}
}
}
@@ -126,8 +136,8 @@
amplitude /= this.amplitude.size();
- this.currentBPM = ((float)60000*bpms.size())/((float)bpmSum);
- this.currentAccuracy = (100-bpmDiff)+bpms.size()*13+amplitude*5;
+ this.currentBPM =
((float)60000*timediffs.size())/((float)timediffSum);
+ this.currentAccuracy = (100-bpmDiff)+timediffs.size()*13+amplitude*5;
PaceDetector.this.ChangeBPM(this.currentBPM,this.currentAccuracy);
}
}
@@ -169,32 +179,57 @@
}
public void ChangeBPM(float bpm,float accuracy){
+ bpm *= 2;
+
while(bpm<85){
bpm *= 2;
}
- while(bpm>200){
+ while(bpm>195){
bpm *= 0.5;
}
- if(accuracy>=this.xAxis.currentAccuracy &&
accuracy>=this.yAxis.currentAccuracy &&
accuracy>=this.zAxis.currentAccuracy && accuracy>150){
+ if(accuracy>=this.xAxis.currentAccuracy &&
accuracy>=this.yAxis.currentAccuracy &&
accuracy>=this.zAxis.currentAccuracy && accuracy>170){
// The BPM has changed
- long currentTime = android.os.SystemClock.elapsedRealtime();
+ //long currentTime = android.os.SystemClock.elapsedRealtime();
// if(currentTime>this.currentBPMstart+MIN_PLAYTIME){
//Log.v("BPM","3 "+bpm);
// We have played more than minimum time
// if(bpm>this.currentBPM+BPM_THRESHOLD ||
bpm<this.currentBPM-BPM_THRESHOLD){
// BPM has changed enough to switch track
- this.currentBPMstart = currentTime;
-
+ //this.currentBPMstart = currentTime;
+
synchronized(lock){
- this.currentBPM = bpm;
- if(this.listener!=null){
- this.listener.OnBPMUpdate();
+
+ // Lets add them to the last bpms
+ this.lastBPMs.add(bpm);
+ // Remove old bpms, only keep the last 3
+ while(this.lastBPMs.size()>4){
+ this.lastBPMs.remove(0);
+ }
+ // check if the lastBPMs are within BPM_ACCEPTANCE
+ float minBPM = this.lastBPMs.get(0);
+ float maxBPM = minBPM;
+ for(int i=1;i<this.lastBPMs.size();i++){
+ final float currentBPM = this.lastBPMs.get(i);
+ if(currentBPM>maxBPM){
+ maxBPM = currentBPM;
+ }
+ if(currentBPM<minBPM){
+ minBPM = currentBPM;
+ }
+ }
+
+ // Is this within acceptance?
+ if(maxBPM-minBPM<BPM_ACCEPTANCE){
+ this.currentBPM = bpm;
+ if(this.listener!=null){
+ this.listener.OnBPMUpdate();
+ }
}
}
- this.currentAccuracy = accuracy;
+ //this.currentAccuracy = accuracy;
// }
// }
@@ -202,7 +237,7 @@
}
public void StartSensor(Context context){
- this.context = context;
+ //this.context = context;
SensorManager sensorMgr =
(SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
Sensor accelerometer =
sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorMgr.registerListener(this,accelerometer,SensorManager.SENSOR_DELAY_GAME);
=======================================
--- /trunk/src/android/src/org/musikcube/core/Workout.java Mon Aug 31
03:00:07 2009
+++ /trunk/src/android/src/org/musikcube/core/Workout.java Mon Aug 31
07:01:12 2009
@@ -7,6 +7,7 @@
import android.content.Context;
import android.content.Intent;
+import android.util.Log;
public class Workout implements OnBPMListener, Runnable,
OnQueryResultListener {
@@ -21,7 +22,9 @@
private boolean useAccelerometer = false;
private long lastQueryTime = -30000;
private int minimumPlaytime = 30000;
- static final public float BPM_THRESHOLD = 10; // if BPM is off by more
than 10 bpm, switch track
+ static final public float BPM_THRESHOLD = 8; // if BPM is off by more
than 10 bpm, switch track
+
+ private float reportBPM = 100;
private ArrayList<Integer> selectedCategories = new ArrayList<Integer>();
private String category = "";
@@ -118,7 +121,7 @@
public float GetBPM(){
synchronized(lock){
- return this.bpm;
+ return this.reportBPM;
}
}
@@ -126,13 +129,17 @@
synchronized(lock){
final float bpm = this.paceDetector.GetBPM();
if(bpm>0.0){
+ this.reportBPM = bpm;
+// Log.v("BPM","bpm="+bpm);
if(bpm>this.bpm+BPM_THRESHOLD || bpm<this.bpm-BPM_THRESHOLD){
this.bpm = bpm;
- if(this.listener!=null){
- this.listener.OnBPMUpdate();
- }
+ this.reportBPM = bpm;
this.QueryTracks(false);
}
+
+ if(this.listener!=null){
+ this.listener.OnBPMUpdate();
+ }
}
}
}