package at.tugraz.ist.musicdroid;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import org.puredata.android.service.PdService;
import org.puredata.android.utils.PdUiDispatcher;
import org.puredata.core.PdBase;
import org.puredata.core.PdListener;
import org.puredata.core.utils.IoUtils;
import org.puredata.core.utils.PdDispatcher;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.Resources;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import at.tugraz.ist.musicdroid.common.Constants;
import at.tugraz.ist.musicdroid.common.DataManagement;
import at.tugraz.ist.musicdroid.common.Projekt;
public class RecToFrequencyActivity extends Activity implements OnClickListener {
private static final int PRERECORD = 0;
private static final int RECORD = 1;
private static final int POSTRECORD = 2;
private int state = 0;
private PdService pdService = null;
private final static String Appname = "rec_to_frequency";
private String path;
private File dir;
private Button StopRecordButton;
private Button StartRecordButton;
private Button SaveFileButton;
private Button NextNoteButton;
private Integer pitch;
private AlertDialog alert;
private AlertDialog.Builder builder;
private DrawTonesView toneView;
ArrayList<Integer> pitches;
private MidiFile mf = new MidiFile();
private final ServiceConnection pdConnection = new ServiceConnection() {
//@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("onServiceConnected", "ServiceConnection");
pdService = ((PdService.PdBinder)service).getService();
try {
initPd();
loadPatch();
} catch (IOException e) {
Log.e(Appname, e.toString());
finish();
}
}
//@Override
public void onServiceDisconnected(ComponentName name) {
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Resources r = getResources();
int radius = 20;// r.getInteger(R.integer.radius);
int topline = r.getInteger(R.integer.topmarginlines);
setContentView(R.layout.record_to_frequency);
toneView = new DrawTonesView(this, R.drawable.violine, radius , topline,false);
toneView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.FILL_PARENT));
//setContentView(toneView);
LinearLayout layout = (LinearLayout)findViewById(R.id.baseLayout);
toneView.setVisibility(View.INVISIBLE);
layout.addView(toneView);
Log.i("test", "test");
pitches = new ArrayList<Integer>();
StopRecordButton = (Button)findViewById(R.id.stopRecordButton);
StopRecordButton.setOnClickListener(this);
StartRecordButton = (Button)findViewById(R.id.startRecordButton);
StartRecordButton.setOnClickListener(this);
SaveFileButton = (Button)findViewById(R.id.saveFileButton);
SaveFileButton.setOnClickListener(this);
NextNoteButton = (Button)findViewById(R.id.nextNoteButton);
NextNoteButton.setOnClickListener(this);
StartRecordButton.setVisibility(View.VISIBLE);
StopRecordButton.setVisibility(View.GONE);
NextNoteButton.setVisibility(View.GONE);
SaveFileButton.setVisibility(View.GONE);
bindService(new Intent(this, PdService.class),pdConnection,BIND_AUTO_CREATE);
Log.i("bindService", "bindService");
builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.save_dialog)
.setCancelable(false)
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
writeMidiFile(pitches);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
alert = builder.create();
}
/* We'll use this to catch print statements from Pd
when the user has a [print] object */
private final PdDispatcher myDispatcher = new PdUiDispatcher() {
@Override
public void print(String s) {
Log.i("Pd print", s);
}
};
/* We'll use this to listen out for messages from Pd.
Later we'll hook this up to a named receiver. */
private final PdListener myListener = new PdListener() {
public void receiveMessage(String source, String symbol, Object... args) {
Log.i("receiveMessage symbol:", symbol);
for (Object arg: args) {
Log.i("receiveMessage atom:", arg.toString());
}
}
/* What to do when we receive a list from Pd. In this example
we're collecting the list from Pd and outputting each atom */
public void receiveList(String source, Object... args) {
for (Object arg: args) {
Log.i("receiveList atom:", arg.toString());
}
}
/* When we receive a symbol from Pd */
public void receiveSymbol(String source, String symbol) {
Log.i("receiveSymbol", symbol);
}
/* When we receive a float from Pd */
public void receiveFloat(String source, float x) {
if(state == RECORD)
{
Log.i("receiveFloat", ((Float)x).toString());
pitch = Math.round(x);
Log.i("Pitch", ((Integer)pitch).toString());
//toneView.deleteElement(0);
toneView.clearList();
toneView.addElement(pitch);
//toneView.refreshDrawableState();
//toneView.invalidate();
//values.add( ((Float)x).toString());
}
}
/* When we receive a bang from Pd */
public void receiveBang(String source) {
Log.i("receiveBang", "bang!");
}
};
private void loadPatch() throws IOException {
Log.e("loadPatch", "loadPatch");
dir = getFilesDir();
IoUtils.extractZipResource(getResources().openRawResource(R.raw.fiddle),
dir, true);
File patchFile = new File(dir, "fiddle.pd");
path = patchFile.getAbsolutePath();
PdBase.openPatch(patchFile.getAbsolutePath());
}
private void initPd() throws IOException {
String name = getResources().getString(R.string.app_name);
Log.i("initPd", "initPd");
pdService.initAudio(-1, 1, -1, -1);
Log.i("initAudio", "initAudio");
pdService.startAudio(new Intent(this, RecToFrequencyActivity.class),
R.drawable.musicdroid_launcher, name, "Return to "
+ name + ".");
Log.i("startAudio", "startAudio");
/* here is where we bind the print statement catcher defined below */
PdBase.setReceiver(myDispatcher);
/* here we are adding the listener for various messages
from Pd sent to "GUI", i.e., anything that goes into the object
[s GUI] will send to the listener defined below */
myDispatcher.addListener("micro", myListener);
}
@Override
public void onDestroy() {
super.onDestroy();
unbindService(pdConnection);
}
public void writeMidiFile(ArrayList<Integer> values) {
if(values.size() <= 0) return;
mf.progChange(76); //select instrument
for(int i=0;i< values.size();i++)
{
mf.noteOnOffNow(MidiFile.QUAVER, values.get(i), 127);
}
AlertDialog.Builder alert2 = new AlertDialog.Builder(this);
alert2.setTitle("Please enter a filename.");
final EditText input = new EditText(this);
alert2.setView(input);
alert2.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
String value = "";
public void onClick(DialogInterface dialog, int which) {
DataManagement management = new DataManagement();
value = input.getText().toString();
if (value != "") {
try
{
File directory = new File(Constants.MAIN_DIRECTORY+Constants.RECORDS_SUB_DIRECTORY);
management.checkDirectory(directory.getAbsolutePath());
//File outputFile = new File(directory, "/miditest.mid");
mf.writeToFile(directory + value);
File f2 = new File(directory + value);
Projekt.getInstance().addRecord(
f2.getAbsolutePath());
if(f2.exists())
Log.i("file exists", "file exists");
}
catch (Exception e) {
Log.e("Midi", e.getMessage());
}
}}
});
alert2.show();
}
public void playfile() {
File f = new File(Environment.getExternalStorageDirectory()+"/records/miditest.mid" );
if(!f.exists()) return;
Uri myUri = Uri.fromFile(f);
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(getApplicationContext(), myUri);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mediaPlayer.start();
}
//@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (arg0 == StartRecordButton)
{
if(state == PRERECORD)
{
// start record
state = RECORD;
StartRecordButton.setVisibility(View.GONE);
StopRecordButton.setVisibility(View.VISIBLE);
NextNoteButton.setVisibility(View.VISIBLE);
SaveFileButton.setVisibility(View.GONE);
toneView.setVisibility(View.VISIBLE);
}
else if(state == POSTRECORD)
{
alert.show();
state = RECORD;
StartRecordButton.setVisibility(View.GONE);
StopRecordButton.setVisibility(View.VISIBLE);
NextNoteButton.setVisibility(View.VISIBLE);
SaveFileButton.setVisibility(View.GONE);
toneView.setVisibility(View.VISIBLE);
toneView.clearList();
}
else
{
Log.e("StartRecord-Error", "StartRecordButton clicked in wrong state");
}
}
if (arg0 == StopRecordButton)
{
if(state == RECORD)
{
// Stop record
toneView.clearList();
state = POSTRECORD;
StartRecordButton.setVisibility(View.VISIBLE);
StopRecordButton.setVisibility(View.GONE);
NextNoteButton.setVisibility(View.GONE);
SaveFileButton.setVisibility(View.VISIBLE);
toneView.setVisibility(View.INVISIBLE);
}
else
{
Log.e("StopRecord-Error", "StopRecordButton clicked in wrong state");
}
}
if (arg0 == SaveFileButton)
{
if(state == POSTRECORD)
{
// save file
writeMidiFile(pitches);
Log.i("writeMidiFile", "writeMidiFile");
state = PRERECORD;
StartRecordButton.setVisibility(View.VISIBLE);
StopRecordButton.setVisibility(View.GONE);
NextNoteButton.setVisibility(View.GONE);
SaveFileButton.setVisibility(View.GONE);
}
else
{
Log.e("SaveFileButton-Error", "SaveFileButton clicked in wrong state");
}
}
if (arg0 == NextNoteButton)
{
if(state == RECORD)
{
pitches.add(pitch);
Log.i("pitch added", "pitch added");
}
else
{
Log.e("NextNoteButton-Error", "NextNoteButton clicked in wrong state");
}
}
}
@Override
public void onBackPressed() {
if (state == POSTRECORD)
{
alert.show();
state = PRERECORD;
}
else
super.onBackPressed();
}
}