Added:
/trunk/src/android/src/org/musikcube/core/BPMQuery.java
Modified:
/trunk/src/android/res/drawable/album.png
/trunk/src/android/res/layout/category_list.xml
/trunk/src/android/res/layout/main.xml
/trunk/src/android/res/layout/play_control.xml
/trunk/src/android/res/layout/track_list.xml
/trunk/src/android/res/layout-land/play_control.xml
/trunk/src/android/src/org/musikcube/CategoryList.java
/trunk/src/android/src/org/musikcube/PlayerControl.java
/trunk/src/android/src/org/musikcube/Service.java
/trunk/src/android/src/org/musikcube/TrackList.java
/trunk/src/android/src/org/musikcube/core/ListQuery.java
/trunk/src/android/src/org/musikcube/core/PaceDetector.java
/trunk/src/android/src/org/musikcube/core/Player.java
/trunk/src/android/src/org/musikcube/core/TrackPlayer.java
/trunk/src/android/src/org/musikcube/main.java
=======================================
--- /dev/null
+++ /trunk/src/android/src/org/musikcube/core/BPMQuery.java Thu Aug 20
14:19:13 2009
@@ -0,0 +1,47 @@
+package org.musikcube.core;
+
+import doep.xml.WriterNode;
+
+public class BPMQuery extends ListQuery {
+
+ public float queryForBPM = 0;
+
+ public BPMQuery() {
+ super();
+ this.type = "BPMQuery";
+ this.listTracks = true;
+ }
+
+
+ @Override
+ public void SendQuery(WriterNode node)
+ throws Exception
+ {
+ WriterNode queryNode = this.SendQueryNode(node);
+
+ // List selections
+ WriterNode selectionsNode = queryNode.ChildNode("selections");
+ int selectionCount = this.selectionStrings.size();
+ for(int i=0;i<selectionCount;i++){
+ WriterNode selectionNode = selectionsNode.ChildNode("selection");
+ selectionNode.attributes.put("key", this.selectionStrings.get(i));
+ selectionNode.content = this.selectionInts.get(i).toString();
+ }
+
+ // What category to listen for
+ WriterNode listenersNode = queryNode.ChildNode("listeners");
+ listenersNode.content = this.category;
+
+ // List tracks?
+ if(this.listTracks){
+ WriterNode listtracksNode = queryNode.ChildNode("listtracks");
+ listtracksNode.content = "true";
+ }
+
+ WriterNode bpmNode = queryNode.ChildNode("bpm");
+ bpmNode.content = ""+this.queryForBPM;
+
+ queryNode.End();
+ }
+
+}
=======================================
--- /trunk/src/android/res/drawable/album.png Wed Jul 29 17:06:47 2009
+++ /trunk/src/android/res/drawable/album.png Thu Aug 20 14:19:13 2009
Binary file, no diff available.
=======================================
--- /trunk/src/android/res/layout/category_list.xml Sun Aug 9 15:24:12 2009
+++ /trunk/src/android/res/layout/category_list.xml Thu Aug 20 14:19:13 2009
@@ -11,9 +11,13 @@
android:layout_height="fill_parent"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
-
- <TextView android:id="@id/android:empty"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:text=""/>
+
+ <LinearLayout android:id="@id/android:empty"
+ android:orientation="horizontal"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp" android:layout_width="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_height="fill_parent">
+ <ProgressBar android:id="@+id/ProgressBar01" android:keepScreenOn="true"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></ProgressBar>
+ <TextView android:id="@+id/TextView01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:text="Loading..."
android:layout_marginLeft="10sp"></TextView>
+ </LinearLayout>
+
</LinearLayout>
=======================================
--- /trunk/src/android/res/layout/main.xml Sun Aug 16 15:27:03 2009
+++ /trunk/src/android/res/layout/main.xml Thu Aug 20 14:19:13 2009
@@ -13,6 +13,7 @@
<TextView android:id="@+id/TextView01"
android:layout_height="wrap_content" android:text="Browse by:"
android:layout_width="fill_parent"
android:background="@color/headlineColor" android:textSize="16sp"
android:padding="4sp"></TextView>
<Button android:layout_height="wrap_content"
android:layout_width="fill_parent" android:textSize="22sp"
android:text="Genre" android:id="@+id/GenresButton"></Button>
<Button android:layout_height="wrap_content"
android:layout_width="fill_parent" android:textSize="22sp"
android:id="@+id/ArtistsButton" android:text="Artist"></Button>
+ <Button android:layout_height="wrap_content"
android:layout_width="fill_parent" android:textSize="22sp"
android:id="@+id/YearButton" android:text="Year"></Button>
<Button android:layout_height="wrap_content"
android:layout_width="fill_parent" android:textSize="22sp"
android:id="@+id/BPMButton" android:text="Workout mode"></Button>
</LinearLayout>
=======================================
--- /trunk/src/android/res/layout/play_control.xml Tue Aug 11 11:57:11 2009
+++ /trunk/src/android/res/layout/play_control.xml Thu Aug 20 14:19:13 2009
@@ -8,10 +8,10 @@
<ImageView android:src="@drawable/album" android:layout_marginTop="5sp"
android:layout_marginBottom="5sp" android:layout_height="200sp"
android:layout_width="200sp" android:scaleType="fitXY"
android:id="@+id/AlbumCover"></ImageView><LinearLayout
android:id="@+id/LinearLayout01" android:layout_weight="0.5"
android:layout_height="wrap_content" android:orientation="vertical"
android:gravity="left" android:layout_width="200sp">
-<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textSize="24sp"
android:id="@+id/TrackTitle" android:text="Title:"></TextView>
-
-<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Album:"
android:id="@+id/TrackAlbum"></TextView>
-<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Artists:"
android:id="@+id/TrackArtist"></TextView>
+<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textSize="24sp"
android:id="@+id/TrackTitle" android:text="Title:"
android:lines="1"></TextView>
+
+<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Album:"
android:id="@+id/TrackAlbum" android:lines="1"></TextView>
+<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Artists:"
android:id="@+id/TrackArtist" android:lines="1"></TextView>
</LinearLayout>
<LinearLayout android:id="@+id/LinearLayout02"
android:layout_weight="0.5" android:layout_width="wrap_content"
android:layout_height="wrap_content"></LinearLayout><LinearLayout
android:id="@+id/LinearLayout01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:orientation="horizontal">
<ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/MediaPrev"
android:src="@drawable/ic_media_previous" android:adjustViewBounds="true"
android:padding="15sp"></ImageButton>
@@ -27,5 +27,5 @@
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="0:00"
android:id="@+id/TrackDuration" android:typeface="monospace"
android:gravity="right"></TextView>
</LinearLayout>
-<SeekBar android:layout_height="wrap_content"
android:layout_width="fill_parent" android:max="1000"
android:progress="300" android:secondaryProgress="100"
android:id="@+id/TrackProgress"></SeekBar>
+<SeekBar android:layout_height="wrap_content"
android:layout_width="fill_parent" android:max="1000"
android:id="@+id/TrackProgress" android:progress="0"
android:secondaryProgress="0"></SeekBar>
</LinearLayout>
=======================================
--- /trunk/src/android/res/layout/track_list.xml Wed Jul 8 14:54:19 2009
+++ /trunk/src/android/res/layout/track_list.xml Thu Aug 20 14:19:13 2009
@@ -12,8 +12,12 @@
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
- <TextView android:id="@id/android:empty"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:text="Loading...."/>
+ <LinearLayout android:id="@id/android:empty"
+ android:orientation="horizontal"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp" android:layout_width="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_height="fill_parent">
+ <ProgressBar android:id="@+id/ProgressBar01" android:keepScreenOn="true"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></ProgressBar>
+ <TextView android:id="@+id/TextView01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:text="Loading..."
android:layout_marginLeft="10sp"></TextView>
+ </LinearLayout>
+
</LinearLayout>
=======================================
--- /trunk/src/android/res/layout-land/play_control.xml Wed Aug 12 00:00:10
2009
+++ /trunk/src/android/res/layout-land/play_control.xml Thu Aug 20 14:19:13
2009
@@ -9,9 +9,9 @@
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content" android:orientation="horizontal"
android:gravity="center_vertical|center_horizontal">
<ImageView android:src="@drawable/album" android:layout_height="200sp"
android:layout_width="200sp" android:scaleType="fitXY"
android:layout_marginRight="10sp" android:id="@+id/AlbumCover"></ImageView>
<LinearLayout android:id="@+id/LinearLayout01"
android:layout_height="wrap_content" android:orientation="vertical"
android:layout_width="wrap_content">
- <TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textSize="24sp"
android:id="@+id/TrackTitle" android:text="Title:"></TextView>
- <TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Album:"
android:id="@+id/TrackAlbum"></TextView>
- <TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Artists:"
android:id="@+id/TrackArtist"></TextView>
+ <TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textSize="24sp"
android:id="@+id/TrackTitle" android:text="Title:"
android:lines="1"></TextView>
+ <TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Album:"
android:id="@+id/TrackAlbum" android:lines="1"></TextView>
+ <TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Artists:"
android:id="@+id/TrackArtist" android:lines="1"></TextView>
<LinearLayout android:id="@+id/LinearLayout02"
android:layout_weight="0.5" android:layout_width="wrap_content"
android:layout_height="wrap_content"></LinearLayout><LinearLayout
android:id="@+id/LinearLayout01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:orientation="horizontal">
<ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/MediaPrev"
android:clickable="true" android:src="@drawable/ic_media_previous"
android:adjustViewBounds="true" android:padding="15sp"></ImageButton>
<ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:adjustViewBounds="true"
android:id="@+id/MediaPause" android:src="@drawable/ic_media_pause"
android:padding="15sp"></ImageButton>
@@ -28,5 +28,5 @@
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="0:00"
android:id="@+id/TrackDuration" android:typeface="monospace"
android:gravity="right"></TextView>
</LinearLayout>
-<SeekBar android:layout_height="wrap_content"
android:layout_width="fill_parent" android:max="1000"
android:progress="300" android:secondaryProgress="100"
android:id="@+id/TrackProgress"></SeekBar>
+<SeekBar android:layout_height="wrap_content"
android:layout_width="fill_parent" android:max="1000"
android:id="@+id/TrackProgress" android:progress="0"
android:secondaryProgress="0"></SeekBar>
</LinearLayout>
=======================================
--- /trunk/src/android/src/org/musikcube/CategoryList.java Wed Aug 12
00:00:10 2009
+++ /trunk/src/android/src/org/musikcube/CategoryList.java Thu Aug 20
14:19:13 2009
@@ -36,7 +36,7 @@
private ArrayList<String> selectedCategory;
private ArrayList<Integer> selectedCategoryIds;
- private ProgressDialog loadingDialog;
+// private ProgressDialog loadingDialog;
// Need handler for callbacks to the UI thread
final Handler callbackHandler = new Handler();
@@ -60,15 +60,28 @@
}
public int getCount() {
- return this.query.resultsInts.size();
+ int size = this.query.resultsInts.size();
+ if(size==0){
+ return 0;
+ }else{
+ return size+1;
+ }
}
public Object getItem(int position) {
- return this.query.resultsInts.get(position);
+ if(position==0){
+ return 0;
+ }else{
+ return this.query.resultsInts.get(position-1);
+ }
}
public long getItemId(int position) {
- return this.query.resultsInts.get(position);
+ if(position==0){
+ return 0;
+ }else{
+ return this.query.resultsInts.get(position-1);
+ }
}
public View getView(int position, View view, ViewGroup parent) {
@@ -76,32 +89,17 @@
view = inflator.inflate(R.layout.category_list_item, null);
}
- ((TextView)
view.findViewById(R.id.text)).setText(this.query.resultsStrings.get(position));
+ //
+ if(position==0){
+ ((TextView) view.findViewById(R.id.text)).setText("- All -");
+ }else{
+ ((TextView)
view.findViewById(R.id.text)).setText(this.query.resultsStrings.get(position-1));
+ }
return view;
}
}
-/* private class CategoryItemView extends LinearLayout {
- public CategoryItemView(Context context, String title) {
- super(context);
- this.setOrientation(VERTICAL);
-
- mTitle = new TextView(context);
- mTitle.setTextSize(22);
- mTitle.setText(title);
- addView(mTitle, new LinearLayout.LayoutParams(
- LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
-
- }
-
- public void SetTitle(String title) {
- mTitle.setText(title);
- }
-
- private TextView mTitle;
- }
- */
private ResultAdapter listAdapter;
@Override
@@ -151,7 +149,7 @@
org.musikcube.core.Library library =
org.musikcube.core.Library.GetInstance();
- this.loadingDialog =
ProgressDialog.show(this, "", "Loading "+this.category+"...", true);
+ //this.loadingDialog =
ProgressDialog.show(this, "", "Loading "+this.category+"...", true);
library.AddQuery(this.query);
}else{
@@ -165,10 +163,10 @@
public void OnResults(){
//Log.i("CategoryList::OnResults","In right
thread "+this.query.resultsStrings.size());
- if(this.loadingDialog!=null){
+ /*if(this.loadingDialog!=null){
this.loadingDialog.dismiss();
this.loadingDialog = null;
- }
+ }*/
this.listAdapter.notifyDataSetChanged();
}
@@ -192,8 +190,10 @@
ArrayList<String> selectedCategory =
(ArrayList<String>)this.selectedCategory.clone();
ArrayList<Integer> selectedCategoryIds =
(ArrayList<Integer>)this.selectedCategoryIds.clone();
- selectedCategory.add(this.category);
- selectedCategoryIds.add((int)id);
+ if(id!=0){
+ selectedCategory.add(this.category);
+ selectedCategoryIds.add((int)id);
+ }
if(this.nextCategoryList.equals("")){
// List tracks
=======================================
--- /trunk/src/android/src/org/musikcube/PlayerControl.java Wed Aug 12
00:00:10 2009
+++ /trunk/src/android/src/org/musikcube/PlayerControl.java Thu Aug 20
14:19:13 2009
@@ -28,11 +28,13 @@
import android.widget.SeekBar;
import android.widget.TextView;
-public class PlayerControl extends Activity implements
OnTrackUpdateListener, OnQueryResultListener {
+public class PlayerControl extends Activity implements
OnTrackUpdateListener {
private Track track = new Track();
private int duration = 0;
private Object lock = new Object();
+ private boolean enable = false;
+ private int currentAlbumCoverId = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -74,56 +76,24 @@
this.callbackTrackPositionsUpdateHandler.post(this.callbackTrackPositionsUpdateRunnable);
}
public void OnTrackUpdate() {
-/*
- synchronized(lock){
- int newTrackId = Player.GetInstance().GetCurrentTrackId();
- if(newTrackId!=this.trackId){
- this.trackId = newTrackId;
- this.track = new Track();
-
- if(this.trackId!=0){
- MetadataQuery query = new MetadataQuery();
- query.requestedMetakeys.add("title");
- query.requestedMetakeys.add("track");
- query.requestedMetakeys.add("visual_artist");
- query.requestedMetakeys.add("album");
- query.requestedMetakeys.add("year");
- query.requestedMetakeys.add("thumbnail_id");
- query.requestedMetakeys.add("duration");
- query.requestedTracks.add(this.trackId);
- query.SetResultListener(this);
- Library.GetInstance().AddQuery(query);
- }
- }
- }*/
this.callbackTrackUpdateHandler.post(this.callbackTrackUpdateRunnable);
}
-
-
- public void OnQueryResults(IQuery query) {
-/* MetadataQuery mdQuery = (MetadataQuery)query;
- if(!mdQuery.resultTracks.isEmpty()){
- synchronized(lock){
- Track newTrack = mdQuery.resultTracks.get(0);
- if(this.trackId==newTrack.id){
- this.track = newTrack;
-
this.callbackTrackUpdateHandler.post(this.callbackTrackUpdateRunnable);
- }
- }
- }*/
- }
@Override
protected void onPause() {
+ this.enable = false;
Log.v("MC2::PC","OnPause");
Player.GetInstance().SetUpdateListener(null);
super.onPause();
}
@Override
protected void onResume() {
+ this.enable = true;
Log.v("MC2::PC","OnResume");
Player.GetInstance().SetUpdateListener(this);
super.onResume();
+ this.OnUpdateTrackPositionsUI();
+ this.OnUpdateTrackUI();
}
// Need handler for callbacks to the UI thread
@@ -189,13 +159,16 @@
}
// clear image
- ImageView cover = (ImageView)findViewById(R.id.AlbumCover);
- cover.setImageResource(R.drawable.album);
-
- if(thumbnailId!=0){
- // Load image
- Library library = Library.GetInstance();
- new
DownloadAlbumCoverTask().execute("http://"+library.host+":"+library.httpPort+"/cover/?cover_id="+thumbnailId);
+ if(this.currentAlbumCoverId!=thumbnailId){
+ this.currentAlbumCoverId=thumbnailId;
+ ImageView cover = (ImageView)findViewById(R.id.AlbumCover);
+ cover.setImageResource(R.drawable.album);
+
+ if(thumbnailId!=0){
+ // Load image
+ Library library = Library.GetInstance();
+ new
DownloadAlbumCoverTask().execute("http://"+library.host+":"+library.httpPort+"/cover/?cover_id="+thumbnailId);
+ }
}
}
@@ -238,24 +211,26 @@
};
public void OnUpdateTrackPositionsUI() {
- int msPosition = Player.GetInstance().GetTrackPosition();
- int position = msPosition/1000;
- int minutes = (int)Math.floor(position/60);
- int seconds = position-minutes*60;
- String positionText = Integer.toString(minutes)+":";
- if(seconds<10){ positionText += "0"; }
- positionText += Integer.toString(seconds);
- TextView positionView = (TextView)findViewById(R.id.TrackPosition);
- positionView.setText(positionText);
-
- SeekBar seekBar = (SeekBar)findViewById(R.id.TrackProgress);
- synchronized (this.lock) {
- if(this.duration==0){
- seekBar.setProgress(0);
- }else{
- seekBar.setProgress(msPosition/this.duration);
- }
- seekBar.setSecondaryProgress(10*Player.GetInstance().GetTrackBuffer());
+ if(this.enable){
+ int msPosition = Player.GetInstance().GetTrackPosition();
+ int position = msPosition/1000;
+ int minutes = (int)Math.floor(position/60);
+ int seconds = position-minutes*60;
+ String positionText = Integer.toString(minutes)+":";
+ if(seconds<10){ positionText += "0"; }
+ positionText += Integer.toString(seconds);
+ TextView positionView = (TextView)findViewById(R.id.TrackPosition);
+ positionView.setText(positionText);
+
+ SeekBar seekBar = (SeekBar)findViewById(R.id.TrackProgress);
+ synchronized (this.lock) {
+ if(this.duration==0){
+ seekBar.setProgress(0);
+ }else{
+ seekBar.setProgress(msPosition/this.duration);
+ }
+ seekBar.setSecondaryProgress(10*Player.GetInstance().GetTrackBuffer());
+ }
}
// Next callback in 0.5 seconds
=======================================
--- /trunk/src/android/src/org/musikcube/Service.java Sun Aug 16 15:27:03
2009
+++ /trunk/src/android/src/org/musikcube/Service.java Thu Aug 20 14:19:13
2009
@@ -68,6 +68,16 @@
Player player = Player.GetInstance();
player.Play(intent.getIntegerArrayListExtra("org.musikcube.Service.tracklist"),
intent.getIntExtra("org.musikcube.Service.position", 0));
}
+ if(action.equals("appendlist")){
+ Player player = Player.GetInstance();
+
player.Append(intent.getIntegerArrayListExtra("org.musikcube.Service.tracklist"));
+ }
+
+ if(action.equals("playlist_prepare")){
+ Player player = Player.GetInstance();
+
player.PlayWhenPrepared(intent.getIntegerArrayListExtra("org.musikcube.Service.tracklist"),
intent.getIntExtra("org.musikcube.Service.position", 0));
+ }
+
if(action.equals("next")){
Player player = Player.GetInstance();
player.Next();
@@ -90,6 +100,11 @@
this.paceDetector.StartSensor(this);
}
}
+ if(action.equals("bpmstop")){
+ if(this.paceDetector!=null){
+ this.paceDetector.StopSensor(this);
+ }
+ }
if(action.equals("player_start")){
Track track = Player.GetInstance().GetCurrentTrack();
=======================================
--- /trunk/src/android/src/org/musikcube/TrackList.java Wed Aug 12 00:00:10
2009
+++ /trunk/src/android/src/org/musikcube/TrackList.java Thu Aug 20 14:19:13
2009
@@ -16,15 +16,18 @@
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
+import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ContextMenu.ContextMenuInfo;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
/**
* @author doy
@@ -40,6 +43,11 @@
public java.util.TreeSet<Integer> waitingTracks = new
java.util.TreeSet<Integer>();
private java.lang.Object lock = new java.lang.Object();
+
+ final static public int PLAY_THIS_ID = 0;
+ final static public int ADD_THIS_ID = 1;
+ final static public int ADD_ALL_ID = 2;
+
// Need handler for callbacks to the UI thread
final Handler callbackHandler = new Handler();
@@ -164,6 +172,8 @@
this.query.listTracks = true;
library.AddQuery(this.query);
+
+ this.registerForContextMenu(this.getListView());
}
public void OnResults(){
@@ -294,5 +304,46 @@
return super.onContextItemSelected(item);
}
}
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo)
item.getMenuInfo();
+ java.util.ArrayList<Integer> trackList = new
java.util.ArrayList<Integer>();
+ Intent intent = new Intent(this, org.musikcube.Service.class);
+ intent.putExtra("org.musikcube.Service.position", 0);
+ switch (item.getItemId()) {
+ case PLAY_THIS_ID:
+ trackList.add((int)info.id);
+ intent.putExtra("org.musikcube.Service.tracklist", trackList);
+ intent.putExtra("org.musikcube.Service.action", "playlist");
+ startService(intent);
+ Intent intent2 = new Intent(this, PlayerControl.class);
+ startActivity(intent2);
+ return true;
+ case ADD_THIS_ID:
+ trackList.add((int)info.id);
+ intent.putExtra("org.musikcube.Service.tracklist", trackList);
+ intent.putExtra("org.musikcube.Service.action", "appendlist");
+ startService(intent);
+ return true;
+ case ADD_ALL_ID:
+ trackList.add((int)info.id);
+ intent.putExtra("org.musikcube.Service.tracklist", this.trackList);
+ intent.putExtra("org.musikcube.Service.action", "appendlist");
+ startService(intent);
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ menu.add(0, PLAY_THIS_ID, 0, "Play this track");
+ menu.add(0, ADD_THIS_ID, 0, "Add this to current playlist");
+ menu.add(0, ADD_ALL_ID, 0, "Add all to current playlist");
+ }
}
=======================================
--- /trunk/src/android/src/org/musikcube/core/ListQuery.java Wed Aug 5
16:16:30 2009
+++ /trunk/src/android/src/org/musikcube/core/ListQuery.java Thu Aug 20
14:19:13 2009
@@ -6,8 +6,8 @@
public class ListQuery extends IQuery {
public String category = "";
- private java.util.ArrayList<String> selectionStrings = new
java.util.ArrayList<String>();
- private java.util.ArrayList<Integer> selectionInts = new
java.util.ArrayList<Integer>();
+ protected java.util.ArrayList<String> selectionStrings = new
java.util.ArrayList<String>();
+ protected java.util.ArrayList<Integer> selectionInts = new
java.util.ArrayList<Integer>();
public java.util.ArrayList<String> resultsStrings = new
java.util.ArrayList<String>();
public java.util.ArrayList<Integer> resultsInts = new
java.util.ArrayList<Integer>();
public java.util.ArrayList<Integer> trackList = new
java.util.ArrayList<Integer>();
=======================================
--- /trunk/src/android/src/org/musikcube/core/PaceDetector.java Sun Aug 16
15:27:03 2009
+++ /trunk/src/android/src/org/musikcube/core/PaceDetector.java Thu Aug 20
14:19:13 2009
@@ -1,6 +1,11 @@
package org.musikcube.core;
+import java.util.Collections;
+
+import org.musikcube.core.IQuery.OnQueryResultListener;
+
import android.content.Context;
+import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
@@ -8,18 +13,23 @@
import android.util.Log;
-public class PaceDetector implements Runnable, SensorEventListener {
-
- static public float MAX_BPM = 165;
- static public float MIN_BPM = 80;
- static public int WAVE_MEMORY = 12;
- static public int WAVE_MIN_CALC = 6;
- static public float WAVE_MIN_BPM_DIFF = 80; // This is in miliseconds
- static public int WAVE_COMPARE = 3;
+public class PaceDetector implements Runnable, SensorEventListener,
OnQueryResultListener {
+
+ static public float MAX_BPM = 85;
+ static public float MIN_BPM = 40;
+ static public int WAVE_MEMORY = 20;
+ static public int WAVE_MIN_CALC = 8;
+ static public float WAVE_MIN_BPM_DIFF = 120; // This is in miliseconds
+ static public int WAVE_COMPARE = 4;
+ static public int MIN_PLAYTIME = 20000; // Play at leased 20 seconds of a
track
+ static 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 Context context;
+
private class PaceDimension{
public java.util.ArrayList<Long> beatTimes = new
java.util.ArrayList<Long>();
public java.util.ArrayList<Float> amplitude = new
java.util.ArrayList<Float>();
@@ -59,26 +69,30 @@
// Lets calculate BPM
long bpmSum = 0;
- java.util.TreeSet<Long> bpms = new java.util.TreeSet<Long>();
+ //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++){
long orgSample = this.beatTimes.get(i);
for(int j=i+1;j<i+WAVE_COMPARE;j++){
//float bpmSample = 60000/(this.beatTimes.get(j)-orgSample);
long bpmSample = 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;
}
}
}
+ Collections.sort(bpms);
+ //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.first();
- Long last = bpms.last();
+ Long first = bpms.get(0);
+ Long last = bpms.get(bpms.size()-1);
bpmDiff = last-first;
int bpmSize = bpms.size();
@@ -92,11 +106,11 @@
if(avg-first>last-avg){
// Remove first
bpmSum -= first;
- bpms.remove(first);
+ bpms.remove(0);
}else{
// Remove last
bpmSum -= last;
- bpms.remove(last);
+ bpms.remove(bpms.size()-1);
}
}
}
@@ -110,7 +124,7 @@
amplitude /= this.amplitude.size();
- this.currentBPM = (60000*bpms.size())/bpmSum;
+ this.currentBPM = ((float)60000*bpms.size())/((float)bpmSum);
this.currentAccuracy = (100-bpmDiff)+bpms.size()*13+amplitude*5;
PaceDetector.this.ChangeBPM(this.currentBPM,this.currentAccuracy);
}
@@ -134,20 +148,35 @@
this.xAxis.NextValue(values[0]);
this.yAxis.NextValue(values[1]);
this.zAxis.NextValue(values[2]);
-// Log.v("MC2::TJOOOO",""+values[0]);
-
-// Log.v("mC2::ACC","x="+values[0]+" y="+values[1]+" z="+values[2]);
}
public void ChangeBPM(float bpm,float accuracy){
- if(accuracy>=this.xAxis.currentAccuracy ||
accuracy>=this.yAxis.currentAccuracy ||
accuracy>=this.zAxis.currentAccuracy){
- this.currentBPM = bpm;
- this.currentAccuracy = accuracy;
- Log.v("MC2::BPM","bpm="+bpm+" "+accuracy);
+ bpm *= 2; // BPM should be the double
+
+ if(accuracy>=this.xAxis.currentAccuracy &&
accuracy>=this.yAxis.currentAccuracy &&
accuracy>=this.zAxis.currentAccuracy && accuracy>150){
+ // The BPM has changed
+
+ long currentTime = android.os.SystemClock.elapsedRealtime();
+ if(currentTime>this.currentBPMstart+MIN_PLAYTIME){
+ // 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.currentBPM = bpm;
+ this.currentAccuracy = accuracy;
+
+ BPMQuery query = new BPMQuery();
+ query.queryForBPM = this.currentBPM;
+ query.SetResultListener(this);
+ }
+
+ }
}
}
public void StartSensor(Context context){
+ this.context = context;
Log.v("mC2::ACC","Sensor");
SensorManager sensorMgr =
(SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
Sensor accelerometer =
sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
@@ -165,5 +194,16 @@
// TODO Auto-generated method stub
}
+
+ public void OnQueryResults(IQuery query) {
+ BPMQuery bpmQuery = (BPMQuery)query;
+ if(!bpmQuery.trackList.isEmpty()){
+ Intent intent = new Intent(this.context, org.musikcube.Service.class);
+ intent.putExtra("org.musikcube.Service.tracklist", bpmQuery.trackList);
+ intent.putExtra("org.musikcube.Service.position", 0);
+ intent.putExtra("org.musikcube.Service.action", "playlist_prepare");
+ this.context.startService(intent);
+ }
+ }
}
=======================================
--- /trunk/src/android/src/org/musikcube/core/Player.java Tue Aug 11
15:17:53 2009
+++ /trunk/src/android/src/org/musikcube/core/Player.java Thu Aug 20
14:19:13 2009
@@ -19,6 +19,8 @@
private TrackPlayer nextPlayer;
private Track currentTrack = new Track();
+ public boolean playWhenPrepared = false;
+
public android.app.Service service;
public void run() {
@@ -42,6 +44,27 @@
this.Play();
}
+
+ public void Append(java.util.ArrayList<Integer> playlist){
+
+ synchronized(this.lock){
+ this.nowPlaying.addAll(playlist);
+ }
+ }
+
+ public void PlayWhenPrepared(java.util.ArrayList<Integer> playlist,int
position){
+ synchronized(this.lock){
+ this.nowPlaying = playlist;
+ this.position = position;
+ if(this.nextPlayer!=null){
+ this.nextPlayer.SetListener(null);
+ this.nextPlayer.Stop();
+ }
+ this.playWhenPrepared = true;
+ this.nextPlayer = this.PrepareTrack(this.position);
+ this.nextPlayer.SetListener(this);
+ }
+ }
private TrackPlayer PrepareTrack(int position){
synchronized(this.lock){
@@ -70,7 +93,7 @@
this.nextPlayer = null;
}else{
// Something wrong here, not the prepared track
- this.nextPlayer.listener = null;
+ this.nextPlayer.SetListener(null);
this.nextPlayer.Stop();
this.nextPlayer = null;
}
@@ -80,7 +103,7 @@
}
this.playingTracks.add(newPlayer);
this.currentPlayer = newPlayer;
- newPlayer.listener = this;
+ newPlayer.SetListener(this);
newPlayer.Play();
if(this.listener!=null){
@@ -114,7 +137,9 @@
public void OnTrackBufferUpdate(int percent);
public void OnTrackPositionUpdate(int secondsPlayed);
}
+
protected OnTrackUpdateListener listener = null;
+
public void SetUpdateListener(OnTrackUpdateListener listener){
synchronized(this.lock){
this.listener = listener;
@@ -144,7 +169,7 @@
synchronized(this.lock){
this.StopAllTracks();
if(this.nextPlayer!=null){
- this.nextPlayer.listener = null;
+ this.nextPlayer.SetListener(null);
this.nextPlayer.Stop();
this.nextPlayer = null;
}
@@ -157,7 +182,7 @@
this.currentPlayer = null;
int trackCount = this.playingTracks.size();
for(int i=0;i<trackCount;i++){
- this.playingTracks.get(i).listener = null;
+ this.playingTracks.get(i).SetListener(null);
this.playingTracks.get(i).Stop();
}
this.playingTracks.clear();
@@ -263,5 +288,14 @@
return this.currentTrack;
}
}
+
+ public void OnTrackPrepared(TrackPlayer trackPlayer) {
+ synchronized(this.lock){
+ if(this.playWhenPrepared){
+ this.playWhenPrepared = false;
+ this.Play();
+ }
+ }
+ }
}
=======================================
--- /trunk/src/android/src/org/musikcube/core/TrackPlayer.java Sun Aug 9
13:57:19 2009
+++ /trunk/src/android/src/org/musikcube/core/TrackPlayer.java Thu Aug 20
14:19:13 2009
@@ -1,6 +1,7 @@
package org.musikcube.core;
import android.media.MediaPlayer;
+import android.util.Log;
public class TrackPlayer implements Runnable,
MediaPlayer.OnCompletionListener,
MediaPlayer.OnErrorListener,MediaPlayer.OnBufferingUpdateListener {
@@ -20,6 +21,7 @@
public static final int STATUS_EXIT = 10;
public void run() {
+ Log.v("mC2::TrackPlayer", "Thread started "+this.url);
synchronized(this.lock){
this.mediaPlayer = new MediaPlayer();
}
@@ -30,9 +32,15 @@
this.mediaPlayer.setOnBufferingUpdateListener(this);
this.mediaPlayer.setDataSource(this.url);
+ Log.v("mC2::TrackPlayer", "Preparing "+this.url);
this.mediaPlayer.prepare();
+ Log.v("mC2::TrackPlayer", "Prepared "+this.url);
synchronized(this.lock){
+ if(this.listener!=null){
+ this.listener.OnTrackPrepared(this);
+ }
+
while(this.status==STATUS_PREPARED)
this.lock.wait();
}
@@ -42,6 +50,8 @@
currentStatus = this.status;
}
+ Log.v("mC2::TrackPlayer", "Start? "+this.url);
+
if(currentStatus==STATUS_PLAYING)
this.mediaPlayer.start();
@@ -54,6 +64,7 @@
// The track is almost done
this.almostDoneSend = true;
if(this.listener!=null){
+ Log.v("mC2::TrackPlayer", "OnTrackAlmostDone "+this.url);
this.listener.OnTrackAlmostDone(this);
}
}
@@ -62,16 +73,23 @@
}
}
+ Log.v("mC2::TrackPlayer", "Stopping "+this.url);
this.mediaPlayer.stop();
+ this.mediaPlayer.release();
+ synchronized(this.lock){
+ this.mediaPlayer = null;
+ }
} catch (Exception e) {
}
synchronized(this.lock){
this.status = STATUS_EXIT;
}
+ Log.v("mC2::TrackPlayer", "ExitCallbacks "+this.url);
this.CallListener();
+ Log.v("mC2::TrackPlayer", "END "+this.url);
}
@@ -126,8 +144,10 @@
}
private void CallListener(){
- if(this.listener!=null){
- this.listener.OnTrackStatusUpdate(this,this.status);
+ synchronized(this.lock){
+ if(this.listener!=null){
+ this.listener.OnTrackStatusUpdate(this,this.status);
+ }
}
}
@@ -138,11 +158,18 @@
}
public interface OnTrackStatusListener{
+ public void OnTrackPrepared(TrackPlayer trackPlayer);
public void OnTrackStatusUpdate(TrackPlayer trackPlayer,int status);
public void OnTrackAlmostDone(TrackPlayer trackPlayer);
}
- public OnTrackStatusListener listener = null;
+ private OnTrackStatusListener listener = null;
+
+ public void SetListener(OnTrackStatusListener listener){
+ synchronized(this.lock){
+ this.listener = listener;
+ }
+ }
public void onCompletion(MediaPlayer mp) {
synchronized(this.lock){
=======================================
--- /trunk/src/android/src/org/musikcube/main.java Sun Aug 16 15:27:03 2009
+++ /trunk/src/android/src/org/musikcube/main.java Thu Aug 20 14:19:13 2009
@@ -33,6 +33,10 @@
artistsButton.setOnClickListener(this.onArtistsClick);
artistsButton.setEnabled(false);
+ Button yearButton = (Button)findViewById(R.id.YearButton);
+ yearButton.setOnClickListener(this.onYearClick);
+ yearButton.setEnabled(false);
+
Button bpmButton = (Button)findViewById(R.id.BPMButton);
bpmButton.setOnClickListener(this.onBPMClick);
bpmButton.setEnabled(false);
@@ -55,6 +59,14 @@
}
};
+ private OnClickListener onYearClick = new OnClickListener() {
+ public void onClick(View v){
+ Intent intent = new Intent(main.this, CategoryList.class);
+
intent.putExtra("org.musikcube.CategoryList.listCategory", "year,artist,album");
+ startActivity(intent);
+ }
+ };
+
private OnClickListener onBPMClick = new OnClickListener() {
public void onClick(View v){
Intent intent = new Intent(main.this, org.musikcube.Service.class);
@@ -121,15 +133,18 @@
int status = Library.GetInstance().GetStatus();
Button genreButton = (Button)findViewById(R.id.GenresButton);
Button artistsButton = (Button)findViewById(R.id.ArtistsButton);
+ Button yearButton = (Button)findViewById(R.id.YearButton);
Button bpmButton = (Button)findViewById(R.id.BPMButton);
if(status==Library.STATUS_CONNECTED){
genreButton.setEnabled(true);
artistsButton.setEnabled(true);
- bpmButton.setEnabled(true);
+ yearButton.setEnabled(true);
+// bpmButton.setEnabled(true);
}else{
genreButton.setEnabled(false);
artistsButton.setEnabled(false);
+ yearButton.setEnabled(false);
bpmButton.setEnabled(false);
}