package at.tugraz.ist.musicdroid;
import java.io.File;
import java.io.IOException;
import java.lang.Object;
import java.util.*;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import at.tugraz.ist.musicdroid.common.Constants;
public class PianoActivity extends Activity implements OnTouchListener {
private HorizontalScrollView scroll;
private ImageView piano;
private DrawTonesView toneView;
private Button playMidi;
private Button stopMidi;
private MidiPlayer midiplayer;
private NoteMapper mapper;
private SoundPlayer soundplayer;
static final int SEMIQUAVER = 4;
static final int QUAVER = 8;
static final int CROTCHET = 16;
static final int MINIM = 32;
static final int SEMIBREVE = 64;
private String ActivityName = "PianoActivity";
private Context context;
private boolean[] buttonStates = null;
private ArrayList<Integer> midi_values;
private int sizeofMidiValues = 0;
private boolean[] newButtonStates = new boolean[Constants.NUMBER_PIANO_BUTTONS];
ProgressDialog progress;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.piano);
context = this.getApplicationContext();
soundplayer = new SoundPlayer(context);
progress = ProgressDialog.show(this, ActivityName,
getString(R.string.piano_loading_sounds), true);
new Thread(new Runnable() {
public void run() {
soundplayer.initSoundpool();
createMidiSounds();
runOnUiThread(new Runnable() {
public void run() {
progress.dismiss();
}
});
}
}).start();
init();
piano.setOnTouchListener(this);
buttonStates = new boolean[Constants.NUMBER_PIANO_BUTTONS];
midi_values = new ArrayList<Integer>(12);
}
// @Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
boolean isDownAction = (action & 0x5) == 0x5
|| action == MotionEvent.ACTION_DOWN
|| action == MotionEvent.ACTION_MOVE;
int mapped_key = 0;
int y = piano.getHeight();
for (int touchIndex = 0; touchIndex < event.getPointerCount(); touchIndex++) {
if (event.getY(touchIndex) > 2 * y / 3) {
int index = 0;
mapped_key = mapper.getWhiteKeyFromPosition(round(event
.getX(touchIndex)));
index = mapped_key - 35;
newButtonStates[index] = isDownAction;
} else {
mapped_key = mapper.getBlackKeyFromPosition(round(event
.getX(touchIndex)));
if (mapped_key >= 0) {
int index = 0;
index = mapped_key - 35;
newButtonStates[index] = isDownAction;
} else {
Log.e("nokey", String.valueOf(mapped_key));
}
}
if (touchIndex == (event.getPointerCount() - 1)) {
if ((isDownAction == true) & event.getPointerCount() > 1) {
int toneSize = toneView.getTonesSize();
toneView.deleteElement(toneSize - 1);
}
organizeAction();
}
}
return true;
}
private void organizeAction() {
midi_values.clear();
for (int index = 0; index < newButtonStates.length; index++) {
if (newButtonStates[index] == true) {
midi_values.add(index + 35);
}
}
sizeofMidiValues = midi_values.size();
Log.e("organizeAction", "" + midi_values.size());
for (int i = 0; i < sizeofMidiValues; i++) {
Log.d("Value " + i, " " + midi_values.get(i));
}
for (int index = 0; index < newButtonStates.length; index++) {
if (buttonStates[index] != newButtonStates[index]) {
int midivalue = 0;
buttonStates[index] = newButtonStates[index];
midivalue = index + 35;
toggleSound(midivalue, newButtonStates[index]);
}
}
newButtonStates = new boolean[Constants.NUMBER_PIANO_BUTTONS];
}
@SuppressWarnings("unchecked")
private void toggleSound(int midivalue, boolean down) {
if (down) {
if (!soundplayer.isNotePlaying(midivalue)) {
soundplayer.playNote(midivalue);
Object test = new ArrayList<Integer>(12);
test = midi_values.clone();
toneView.addElement((ArrayList<Integer>) test);
}
} else {
soundplayer.stopNote(midivalue);
}
}
@SuppressWarnings("deprecation")
private void init() {
scroll = (HorizontalScrollView) findViewById(R.id.scrollView);
piano = (ImageView) findViewById(R.id.piano);
stopMidi = (Button) findViewById(R.id.StopMidiButton);
stopMidi.setEnabled(false);
playMidi = (Button) findViewById(R.id.PlayMidiButton);
scroll.setId(2);
LinearLayout layout = (LinearLayout) findViewById(R.id.parentLayout);
Display display = getWindowManager().getDefaultDisplay();
int height = display.getHeight();
int width = display.getWidth();
layout.setLayoutParams(new RelativeLayout.LayoutParams(width,
height / 2));
int radius = getResources().getInteger(R.integer.radius);
int topline = getResources().getInteger(R.integer.topmarginlines);
toneView = new DrawTonesView(this, R.drawable.violine, radius, topline,
true);
toneView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, 280));
layout.addView(toneView, 0);
midiplayer = new MidiPlayer(toneView, context);
mapper = new NoteMapper();
scroll.postDelayed(new Runnable() {
public void run() {
int x = piano.getWidth();
float white_key_width = (x / (float) 35);
float position = white_key_width * 10;
float black_key_width = (x / (float) 60.0);
String pos = "" + x;
Log.e("position", pos);
scroll.scrollTo(round(position), 0);
mapper.initializeWhiteKeyMap(white_key_width);
mapper.initializeBlackKeyMap(black_key_width);
}
}, 100L);
playMidi.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
midiplayer.writeToMidiFile();
midiplayer.playMidiFile();
stopMidi.setEnabled(true);
}
});
stopMidi.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
midiplayer.stopMidiPlayer();
}
});
}
private int round(float val) {
val += 0.5;
return (int) val;
}
private String getMidiNote(int value) {
switch (value) {
case 0:
return "C";
case 1:
return "Cis";
case 2:
return "D";
case 3:
return "Dis";
case 4:
return "E";
case 5:
return "F";
case 6:
return "Fis";
case 7:
return "G";
case 8:
return "Gis";
case 9:
return "A";
case 10:
return "Ais";
case 11:
return "H";
}
return "W";
}
private boolean createMidiSounds() {
boolean success = false;
File directory;
String midi_note;
String file_name;
String path;
int midi_value = 0;
int counter = 0;
directory = new File(Environment.getExternalStorageDirectory()
+ File.separator + "records" + File.separator
+ "piano_midi_sounds");
if (!directory.exists()) {
directory.mkdirs();
}
counter = 0;
for (midi_value = 36; midi_value < 96; midi_value++) {
midi_note = getMidiNote(counter);
file_name = midi_note + "_" + midi_value + ".mid";
path = directory.getAbsolutePath() + File.separator + file_name;
File file = new File(path);
if (!file.exists()) {
MidiFile midiFile = new MidiFile();
midiFile.noteOn(0, midi_value, 127);
midiFile.noteOff(SEMIBREVE, midi_value);
try {
midiFile.writeToFile(path);
} catch (IOException e) {
finish();
}
} else {
// at the moment, do nothing
}
counter++;
if (counter == 12)
counter = 0;
soundplayer.setSoundpool(path);
}
return success;
}
}