/**
Copyright 2010 Henrik Andersson
This file is part of Loopist.
Loopist 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 3 of the License, or
(at your option) any later version.
Loopist is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Loopist. If not, see <http://www.gnu.org/licenses/>.
*/
package se.dinamic.loopist;
import java.io.InputStream;
import java.nio.ByteBuffer;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import android.content.Context;
import android.media.SoundPool;
import android.media.AudioManager;
import android.widget.Spinner;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.CheckBox;
import android.widget.Toast;
public class LoopistActivity extends Activity
{
private LoopistEngine _loopistEngine;
private LoopistView _loopistView;
private static Context _context;
private static Spinner _barsSpinner;
private static Spinner _beatsPerBarSpinner;
private static EditText _bpmValue;
private static ImageView _bpmTapButton;
private static CheckBox _generateMetronomeTrack;
private static final SoundPool _soundPool=new SoundPool(1,AudioManager.STREAM_MUSIC,0);
private static int _spClickID=0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN );
_context=this;
_spClickID = _soundPool.load(this,R.raw.click,1);
setContentView(R.layout.new_project);
// Metronome track checkbox
_generateMetronomeTrack = (CheckBox) findViewById(R.id.generate_metronome_track_cb);
// Bars spinner
_barsSpinner = (Spinner) findViewById(R.id.bars_spinner);
ArrayAdapter adapter = ArrayAdapter.createFromResource( this, R.array.bars, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
_barsSpinner.setAdapter(adapter);
_barsSpinner.setSelection(3);
// Beats per bar spinner
_beatsPerBarSpinner = (Spinner) findViewById(R.id.beats_per_bar_spinner);
adapter = ArrayAdapter.createFromResource( this, R.array.bpb, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
_beatsPerBarSpinner.setAdapter(adapter);
_beatsPerBarSpinner.setSelection(2);
// BPM tap button handler
_bpmValue=(EditText)findViewById(R.id.bpm_value);
_bpmTapButton = (ImageView) findViewById(R.id.bpm_tap_button);
_bpmTapButton.setOnTouchListener(
new View.OnTouchListener()
{
private int _nextTapImage=R.drawable.tap2;
private long _lastMillis=0;
private float _averageDelay = 0;
private int _tapCount=0;
private long [] _delays={0,0};
public boolean onTouch(View v, MotionEvent event)
{
if( event.getAction() == MotionEvent.ACTION_DOWN ) {
long current = System.currentTimeMillis();
_bpmTapButton.setImageResource( _nextTapImage );
_soundPool.play(_spClickID,0.6f,0.6f,1,0,1.0f);
if( _nextTapImage == R.drawable.tap1 ) _nextTapImage=R.drawable.tap2;
else _nextTapImage = R.drawable.tap1;
_delays[_tapCount]=(current - _lastMillis);
if( _delays[_tapCount] != current && _delays[_tapCount] < 2000 ) {
// Lets scale down precision of delay to 10th ms..
_delays[_tapCount] = ((long)(_delays[_tapCount] /10))*10;
Log.v("Loopist",_delays[_tapCount] +"ms since last tap...");
_tapCount++;
if( _tapCount == 2 ) {
int avgd = (int) ((_delays[0]+_delays[1] ) / 2.0f);
// Let's also smooth the delay with average value...
if( _averageDelay > 0)
_averageDelay = (_averageDelay + ((_averageDelay + avgd )/2.0f)) / 2.0f;
else
_averageDelay = avgd;
_tapCount=0;
}
// So lets update textview to show BPM
if( _averageDelay > 0 ) {
float bpm = (60000.0f/_averageDelay);
_bpmValue.setText( Integer.toString( (int)bpm) );
}
} else { // Reset bpm
_bpmValue.setText( "---" );
_averageDelay=0;
}
_lastMillis = current;
}
return true;
}
}
);
// Begin loopist button handler
Button button = (Button) findViewById(R.id.begin_button);
if( button != null ) {
button.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View v)
{
ProgressDialog pd = ProgressDialog.show(_context, "Starting...", "Initializing loopist engine and view.",true);
if( _loopistEngine!=null && _loopistView!=null ) {
_loopistView=null;
_loopistEngine=null;
}
// Get the values for bpm,bars and bpb to initialize loopist engine with...
int bpm=0;
try {
bpm = Integer.valueOf(_bpmValue.getText().toString());
} catch ( java.lang.NumberFormatException e) {
Toast.makeText(_context, "The BPM values is invalid, please tap BPM button at least 4 times...",Toast.LENGTH_SHORT).show();
pd.dismiss();
return;
}
int bars=Integer.valueOf((String)_barsSpinner.getSelectedItem());
int bpb=Integer.valueOf((String)_beatsPerBarSpinner.getSelectedItem());
ByteBuffer pcm=null;
if( _generateMetronomeTrack.isChecked() ) {
pcm=ByteBuffer.allocate(40960);
InputStream is = _context.getResources().openRawResource(R.raw.click_raw);
pcm.mark();
try {
int res=0;
do {
res=is.read(pcm.array(),res,4096);
Log.v("Loopist","Read "+res+" bytes from input raw click resource.");
} while(res>0);
} catch ( java.io.IOException e) {
}
pcm.reset();
}
_loopistEngine=new LoopistEngine( bpm, bars, bpb, pcm );
_loopistView=new LoopistView(_loopistEngine,_context);
_loopistEngine.setListener(_loopistView);
pd.dismiss();
setContentView(_loopistView);
}
}
);
} else {
Toast.makeText(this, "Problems with resources...", Toast.LENGTH_SHORT).show();
Log.v("Loopist","LoopistActivity.onCreate() Resource problem... ");
finish();
}
}
@Override
public void onStart()
{
super.onStart();
}
@Override
public void onResume()
{
super.onResume();
if( _loopistEngine != null ) _loopistEngine.resume();
}
@Override
public void onPause()
{
super.onPause();
if( _loopistEngine != null ) _loopistEngine.pause();
}
}
|