package com.PP.LunarTabsAndroid.Activities; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.herac.tuxguitar.song.models.TGBeat; import org.herac.tuxguitar.song.models.TGSong; import org.herac.tuxguitar.song.models.TGTrack; import android.app.Dialog; import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.Spinner; import android.widget.Toast; import com.PP.AudioIcon.AudioIconAPI; import com.PP.IntelliSeg.Abstract.Segment; import com.PP.IntelliSeg.MeasureIncrementSegmenter.MeasureIncrementSegmenter; import com.PP.LunarTabsAndroid.APIs.FileOpAPI; import com.PP.LunarTabsAndroid.APIs.MediaPlayerAPI; import com.PP.LunarTabsAndroid.APIs.TextToSpeechAPI; import com.PP.LunarTabsAndroid.APIs.TuxGuitarUtil; import com.PP.LunarTabsAndroid.APIs.VolumeAPI; import com.PP.LunarTabsAndroid.APIs.WordActivatorAPI; import com.PP.LunarTabsAndroid.Dialogs.GuitarFileLoaderDialog; import com.PP.LunarTabsAndroid.Dialogs.MeasureIncrementDialog; import com.PP.LunarTabsAndroid.Dialogs.MidiFollowingEnableDialog; import com.PP.LunarTabsAndroid.Dialogs.PlaybackSpeedDialog; import com.PP.LunarTabsAndroid.Dialogs.SelectSectionDialog; import com.PP.LunarTabsAndroid.Dialogs.SetHomeDirectoryDialog; import com.PP.LunarTabsAndroid.Dialogs.StomperEnableDialog; import com.PP.LunarTabsAndroid.Dialogs.VoiceActionsDialog; import com.PP.LunarTabsAndroid.InstrumentModels.ChordDB; import com.PP.LunarTabsAndroid.InstrumentModels.ChordRecognizer; import com.PP.LunarTabsAndroid.UI.AccListView; import com.PP.LunarTabsAndroid.UI.DataModel; import com.PP.LunarTabsAndroid.UI.InstructionContentDescription; import com.PP.LunarTabsAndroid.UI.ResourceModel; import com.PP.LunarTabsAndroid.UI.SerializedParams; import com.PP.MidiServer.AbstractMidiServerActivity; import com.PP.MidiServer.ChordRecognitionListener; import com.PP.MidiServer.MidiServer; import com.PP.StompDetector.InstructionStomp; import com.PP.StompDetector.StompDetector; import com.example.lunartabsandroid.R; import com.root.gast.speech.activation.SpeechActivationListener; public class MainActivity extends AbstractMidiServerActivity implements OnClickListener, SpeechActivationListener, ChordRecognitionListener { //debug fags protected static final boolean MIDI_FOLLOWER_DEBUG = false; protected static final String FRAGMENT_MANAGER_TAG = "LunarTabs"; //components protected Button loadTabFileButton; protected Button toggleModesButton; protected Button playSampleButton; protected Button prevMeasButton; protected Button nextMeasButton; protected Button upButton; protected Button downButton; protected Spinner trackChooser; protected AccListView instructionsList; //stomp detector protected static StompDetector stomper = null; @Override protected void onCreate(Bundle savedInstanceState) { //init stuff super.onCreate(savedInstanceState); // this.requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); ResourceModel.getInstance().loadResources(this); //load components loadTabFileButton = (Button) findViewById(R.id.loadTabFileButton); toggleModesButton = (Button) findViewById(R.id.toggleModesButton); playSampleButton = (Button) findViewById(R.id.playSampleButton); prevMeasButton = (Button) findViewById(R.id.prevMeasButton); nextMeasButton = (Button) findViewById(R.id.nextMeasButton); upButton = (Button) findViewById(R.id.upButton); downButton = (Button) findViewById(R.id.downButton); trackChooser = (Spinner) findViewById(R.id.trackChooser); instructionsList = (AccListView) findViewById(R.id.instructionsList); //register listeners if(!loadTabFileButton.hasOnClickListeners()) { loadTabFileButton.setOnClickListener(this); } if(!toggleModesButton.hasOnClickListeners()) { toggleModesButton.setOnClickListener(this); } if(!playSampleButton.hasOnClickListeners()) { playSampleButton.setOnClickListener(this); } if(!prevMeasButton.hasOnClickListeners()) { prevMeasButton.setOnClickListener(this); } if(!nextMeasButton.hasOnClickListeners()) { nextMeasButton.setOnClickListener(this); } if(!upButton.hasOnClickListeners()) { upButton.setOnClickListener(this); } if(!downButton.hasOnClickListeners()) { downButton.setOnClickListener(this); } //colors loadTabFileButton.setBackgroundColor(Color.WHITE); loadTabFileButton.setTextColor(Color.BLACK); toggleModesButton.setBackgroundColor(Color.WHITE); toggleModesButton.setTextColor(Color.BLACK); playSampleButton.setBackgroundColor(Color.WHITE); playSampleButton.setTextColor(Color.BLACK); prevMeasButton.setBackgroundColor(Color.WHITE); prevMeasButton.setTextColor(Color.BLACK); nextMeasButton.setBackgroundColor(Color.WHITE); nextMeasButton.setTextColor(Color.BLACK); upButton.setBackgroundColor(Color.WHITE); upButton.setTextColor(Color.BLACK); downButton.setBackgroundColor(Color.WHITE); downButton.setTextColor(Color.BLACK); //init components int hilightColor = getResources().getColor(R.color.background_holo_light); instructionsList.init(hilightColor,Color.WHITE); //set up segmenter if(DataModel.getInstance().getSegmenter()==null) { DataModel.getInstance().setSegmenter(new MeasureIncrementSegmenter()); } //enable APIs TextToSpeechAPI.init(this); //init data directory FileOpAPI.init(); TuxGuitarUtil.cleanUp(FileOpAPI.SAVE_PATH); //Chord DB initialize ChordDB.getInstance(); //init voice commands and restart if bundle requires String[] voiceCommands = ResourceModel.getInstance().voiceCommands; WordActivatorAPI.getInstance().init(voiceCommands, this); if(savedInstanceState!=null && savedInstanceState.containsKey(WordActivatorAPI.getInstance().toString())) { boolean turnOn = savedInstanceState.getBoolean(WordActivatorAPI.getInstance().toString()); if(turnOn) { DataModel.getInstance().setVoiceActionsEnabled(true); WordActivatorAPI.getInstance().start(); } } //reinit stomper and restart if was on if(stomper==null) { stomper = new StompDetector(this); stomper.addStompListener(new InstructionStomp(this)); } stomper.setMainActivity(this); if(savedInstanceState!=null && savedInstanceState.containsKey(stomper.toString())) { boolean turnOn = savedInstanceState.getBoolean(stomper.toString()); if(turnOn) { stomper.start(); } } //init Midi Server and restart if bundle requires MidiServer.getInstance().clearChordRecognitionListeners(); MidiServer.getInstance().addChordRecognitionListener(this); if(savedInstanceState!=null && savedInstanceState.containsKey(MidiServer.getInstance().toString())) { boolean turnOn = savedInstanceState.getBoolean(MidiServer.getInstance().toString()); if(turnOn) { MidiServer.getInstance().start(); } } //init Audio Icon AudioIconAPI.getInstance().init(this); //set application volume // VolumeAPI.getInstance().init(this); // VolumeAPI.getInstance().setVolume(VolumeAPI.DEFAULT_VOLUME_FACTOR); } @Override public void onStop() { //call on stop functions super.onStop(); WordActivatorAPI.getInstance().onStop(); stomper.onStop(); MidiServer.getInstance().onStop(); //clean up and save TuxGuitarUtil.cleanUp(FileOpAPI.SAVE_PATH); DataModel.getInstance().saveInstance(); SerializedParams.getInstance().saveInstance(); } @Override public void onResume() { //call on resume functions (if not already running) super.onResume(); if(!DataModel.getInstance().isVoiceActionsEnabled()) { WordActivatorAPI.getInstance().onResume(); } if(!stomper.isEnabled()) { stomper.onResume(); } if(!MidiServer.getInstance().isRunning()) { MidiServer.getInstance().onResume(); } //reinit GUI from file (if exists) refreshGUI(); //garbage collect System.gc(); } /** * Refresh GUI based on current data model (either from file or in memory). */ public void refreshGUI() { DataModel dataModel = DataModel.getInstance(); int prevInstSel = dataModel.getSelectedInstructionIndex(); if(dataModel.getFileName()!=null && !dataModel.getFileName().trim().equals("")) { this.setTitle(dataModel.getFileName().trim()); } if(dataModel.getSong()!=null && dataModel.getTracksList()!=null) { populateTrackOptions(dataModel.getTracksList(),dataModel.getTrackNum()); } if(dataModel.getCurrentSegment()!=-1 && dataModel.getInstSegments()!=null) { //populate instructions Segment c_seg = dataModel.getInstSegments().get(dataModel.getCurrentSegment()); if(dataModel.isVerbose()) { populateInstructionPane(c_seg.getSfInst()); } else { populateInstructionPane(c_seg.getChordInst()); } //re-enable highlighting and instruction selected instructionsList.setHilightEnabled(true); if(prevInstSel!=-1) { dataModel.setSelectedInstructionIndex(prevInstSel); } //set title this.setTitle(dataModel.getFileName().trim() + " " + c_seg.getTitlePresentation()); } //refresh instructions list instructionsList.refreshGUI(); } @Override public void onClick(View v) { //stop media player MediaPlayerAPI.getInstance().stop(); //handle button press if(v.getId()==loadTabFileButton.getId()) { showLoadFileDialog(); } else if(v.getId()==toggleModesButton.getId()) { toggleModes(); } else if(v.getId()==playSampleButton.getId()) { playSample(); } else if(v.getId()==prevMeasButton.getId()) { prevMeasure(); } else if(v.getId()==nextMeasButton.getId()) { nextMeasure(); } else if(v.getId()==upButton.getId()) { prevInstruction(); } else if(v.getId()==downButton.getId()) { nextInstruction(); } } public void prevInstruction() { DataModel dataModel = DataModel.getInstance(); if(dataModel.getFilePath()!=null && dataModel.getSong()!=null && dataModel.getCurrentSegment()>=0 && dataModel.getTrackNum()>=0 && dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()>0 && dataModel.getCurrentSegment()>=0 && dataModel.getInstSegments().get(dataModel.getCurrentSegment()).getChordInst().size()>0) { //update index and perform click int selectedInstructionIndex = DataModel.getInstance().getSelectedInstructionIndex(); if(selectedInstructionIndex >= 0) { //decrement instruction index selectedInstructionIndex--; //perform click on GUI instructionsList.programmaticSelect(selectedInstructionIndex); //find and read instruction if(selectedInstructionIndex >= 0) { String c_inst = null; Segment cSeg = dataModel.getInstSegments().get(dataModel.getCurrentSegment()); if(dataModel.isVerbose()) { c_inst = cSeg.getSfInst().get(selectedInstructionIndex); } else { c_inst = cSeg.getChordInst().get(selectedInstructionIndex); } if(c_inst!=null) { TextToSpeechAPI.speak( InstructionContentDescription.makeAccessibleInstruction(c_inst)); } } } else { //no previous instruction TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_PREV_INST); } } else if(dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()==0) { //no data in section TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_DATA); } else { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_FILE_LOADED); } } public void nextInstruction() { DataModel dataModel = DataModel.getInstance(); if(dataModel.getFilePath()!=null && dataModel.getSong()!=null && dataModel.getCurrentSegment()>=0 && dataModel.getTrackNum()>=0 && dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()>0 && dataModel.getCurrentSegment()>=0) { //update index and perform click Segment cSeg = dataModel.getInstSegments().get(dataModel.getCurrentSegment()); int numInst = cSeg.getChordInst().size(); int selectedInstructionIndex = DataModel.getInstance().getSelectedInstructionIndex(); if(selectedInstructionIndex < (numInst-1)) { //increment instruction selectedInstructionIndex++; //perform click on GUI instructionsList.programmaticSelect(selectedInstructionIndex); //find and read instruction String c_inst = null; if(dataModel.isVerbose()) { c_inst = cSeg.getSfInst().get(selectedInstructionIndex); } else { c_inst = cSeg.getChordInst().get(selectedInstructionIndex); } if(c_inst!=null) { TextToSpeechAPI.speak( InstructionContentDescription.makeAccessibleInstruction(c_inst)); } } else { //no next instruction TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_NEXT_INST); } } else if(dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()==0) { //no data in section TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_DATA); } else { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_FILE_LOADED); } } public void playSample() { DataModel dataModel = DataModel.getInstance(); if(dataModel.getFilePath()!=null && dataModel.getSong()!=null && dataModel.getCurrentSegment()>=0 && dataModel.getTrackNum()>=0 && dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()>0) { Segment cSeg = dataModel.getInstSegments().get(dataModel.getCurrentSegment()); cSeg.play(); } else if(dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()==0) { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_DATA); } else { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_FILE_LOADED); } } public void toggleModes() { DataModel dataModel= DataModel.getInstance(); if(dataModel.getFilePath()!=null && dataModel.getSong()!=null && dataModel.getCurrentSegment()>=0 && dataModel.getTrackNum()>=0) { if(!dataModel.isOnPercussionTrack()) { if(dataModel.isVerbose()) { //populate instructions populateInstructionPane(dataModel.getInstSegments().get(dataModel.getCurrentSegment()).getChordInst()); //flip stored flag dataModel.setVerbose(false); //read currently selected instruction if(dataModel.getSelectedInstructionIndex() >= 0) { instructionsList.programmaticSelect(dataModel.getSelectedInstructionIndex()); List<String> inst = dataModel.getInstSegments().get(dataModel.getCurrentSegment()).getChordInst(); String instr = inst.get(dataModel.getSelectedInstructionIndex()); TextToSpeechAPI.speak( InstructionContentDescription.makeAccessibleInstruction(instr)); } } else { //populate instructions populateInstructionPane(dataModel.getInstSegments().get(dataModel.getCurrentSegment()).getSfInst()); //flip stored flag dataModel.setVerbose(true); //read currently selected instruction if(dataModel.getSelectedInstructionIndex() >= 0) { instructionsList.programmaticSelect(dataModel.getSelectedInstructionIndex()); List<String> inst = dataModel.getInstSegments().get(dataModel.getCurrentSegment()).getSfInst(); String instr = inst.get(dataModel.getSelectedInstructionIndex()); TextToSpeechAPI.speak( InstructionContentDescription.makeAccessibleInstruction(instr)); } } } } else if(dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()==0) { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_DATA); } else { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_FILE_LOADED); } } public void nextMeasure() { DataModel dataModel = DataModel.getInstance(); if(dataModel.getSong()!=null && dataModel.getInstSegments()!=null && dataModel.getCurrentSegment() < (dataModel.getInstSegments().size()-1)) { dataModel.setCurrentSegment(dataModel.getCurrentSegment()+1); if(dataModel.isVerbose()) { populateInstructionPane(dataModel.getInstSegments().get(dataModel.getCurrentSegment()).getSfInst()); } else { populateInstructionPane(dataModel.getInstSegments().get(dataModel.getCurrentSegment()).getChordInst()); } DataModel.getInstance().clearSelectedInstructionIndex(); instructionsList.refreshGUI(); Segment c_seg = dataModel.getInstSegments().get(dataModel.getCurrentSegment()); this.setTitle(dataModel.getFileName().trim() + " " + c_seg.getTitlePresentation()); } else if(dataModel.getSong()!=null && dataModel.getInstSegments()!=null && dataModel.getCurrentSegment() == (dataModel.getInstSegments().size()-1)) { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_LAST_SECTION); } else if(dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()==0) { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_DATA); } else { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_FILE_LOADED); } } public void prevMeasure() { DataModel dataModel = DataModel.getInstance(); if(dataModel.getSong()!=null && dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()>0 && dataModel.getCurrentSegment() > 0) { dataModel.setCurrentSegment(dataModel.getCurrentSegment()-1); if(dataModel.isVerbose()) { populateInstructionPane(dataModel.getInstSegments().get(dataModel.getCurrentSegment()).getSfInst()); } else { populateInstructionPane(dataModel.getInstSegments().get(dataModel.getCurrentSegment()).getChordInst()); } DataModel.getInstance().clearSelectedInstructionIndex(); instructionsList.refreshGUI(); Segment c_seg = dataModel.getInstSegments().get(dataModel.getCurrentSegment()); this.setTitle(dataModel.getFileName().trim() + " " + c_seg.getTitlePresentation()); } else if(dataModel.getSong()!=null && dataModel.getInstSegments()!=null && dataModel.getCurrentSegment() == 0) { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_FIRST_SECTION); } else if(dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()==0) { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_DATA); } else { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_FILE_LOADED); } } public void loadInstructions() { //get model DataModel dataModel = DataModel.getInstance(); //generate instructions dataModel.genInstructions(); //populate instructions pane with current measure if(dataModel.getCurrentSegment() < dataModel.getInstSegments().size()) { if(dataModel.isVerbose()) { populateInstructionPane(dataModel.getInstSegments().get(dataModel.getCurrentSegment()).getSfInst()); } else { populateInstructionPane(dataModel.getInstSegments().get(dataModel.getCurrentSegment()).getChordInst()); } } //bug fix -- if out of bounds, reset back to start if(dataModel.getCurrentSegment() >= dataModel.getInstSegments().size()) { dataModel.setCurrentSegment(0); } //display Segment c_seg = dataModel.getInstSegments().get(dataModel.getCurrentSegment()); this.setTitle(dataModel.getFileName().trim() + " " + c_seg.getTitlePresentation()); } public void populateInstructionPane(List<String> instructions) { ArrayAdapter<String> a_opts = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,instructions); instructionsList.setAdapter(a_opts); } public void showLoadFileDialog() { GuitarFileLoaderDialog dialog = new GuitarFileLoaderDialog(this,this); dialog.show(); } public void showHomeDirectoryDialog() { SetHomeDirectoryDialog dialog = new SetHomeDirectoryDialog(this,this); dialog.show(); } public void populateTrackOptions(List<String> tracksList, int start_sel_position) { ArrayAdapter<String> a_opts = new ArrayAdapter<String>(this, R.layout.my_spinner,tracksList); trackChooser.setAdapter(a_opts); trackChooser.setSelection(start_sel_position); trackChooser.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { DataModel.getInstance().setTrackNum(arg2); loadInstructions(); } @Override public void onNothingSelected(AdapterView<?> arg0) {} }); } public void createTrackOptions() { //load data model DataModel dataModel = DataModel.getInstance(); //populate options in list. Avoid duplicates. ArrayList<String> tracksList = new ArrayList<String>(); Map<String,Integer> tracksDD = new HashMap<String,Integer>(); Set<String> multipleEntries = new HashSet<String>(); TGSong songLoaded = dataModel.getSong(); if(songLoaded!=null && songLoaded.countTracks() > 0) { for(int x=0; x < songLoaded.countTracks(); x++) { TGTrack track = songLoaded.getTrack(x); int offset = track.getOffset(); String capoStr = ""; if(offset!=0) { String CAPO = ResourceModel.getInstance().CAPO; capoStr = " ["+CAPO+" "+offset+"]"; } String trackHash = track.getName().trim().toLowerCase() + capoStr; if(tracksDD.containsKey(trackHash)) { int newCnt = tracksDD.get(trackHash) + 1; tracksDD.put(trackHash, newCnt); multipleEntries.add(trackHash); } else { tracksDD.put(trackHash, 1); } } for(int x=(songLoaded.countTracks()-1); x>=0; x--) { TGTrack track = songLoaded.getTrack(x); int offset = track.getOffset(); String capoStr = ""; if(offset!=0) { String CAPO = ResourceModel.getInstance().CAPO; capoStr = " ["+CAPO+" "+offset+"]"; } String trackHash = track.getName().trim().toLowerCase() + capoStr; String trackName = track.getName().trim() + capoStr; if(multipleEntries.contains(trackHash)) { tracksList.add(0,trackName + " (" + tracksDD.get(trackHash) + ")"); tracksDD.put(trackHash, tracksDD.get(trackHash)-1); } else { tracksList.add(0,trackName); } } } //populate in GUI populateTrackOptions(tracksList,0); //store DataModel.getInstance().setTracksList(tracksList); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); return true; } @Override public boolean onPrepareOptionsMenu (Menu menu) { //set title of menu buttons if(stomper.isEnabled()) { MenuItem stompModeMenuItem = menu.findItem(R.id.StompModeMenuItem); if(stompModeMenuItem!=null) { stompModeMenuItem.setTitle(ResourceModel.getInstance().DISABLE_STOMP_MODE); } } else { MenuItem stompModeMenuItem = menu.findItem(R.id.StompModeMenuItem); if(stompModeMenuItem!=null) { stompModeMenuItem.setTitle(ResourceModel.getInstance().ENABLE_STOMP_MODE); } } if(DataModel.getInstance().isVoiceActionsEnabled()) { MenuItem voiceActionsMenuItem = menu.findItem(R.id.VoiceActionsMenuItem); if(voiceActionsMenuItem!=null) { voiceActionsMenuItem.setTitle(ResourceModel.getInstance().DISABLE_VOICE_ACTIONS); } } else { MenuItem voiceActionsMenuItem = menu.findItem(R.id.VoiceActionsMenuItem); if(voiceActionsMenuItem!=null) { voiceActionsMenuItem.setTitle(ResourceModel.getInstance().ENABLE_VOICE_ACTIONS); } } if(MidiServer.getInstance().isRunning()) { MenuItem voiceActionsMenuItem = menu.findItem(R.id.MidiFollowingMenuItem); if(voiceActionsMenuItem!=null) { voiceActionsMenuItem.setTitle(ResourceModel.getInstance().DISABLE_MIDI_FOLLOWING); } } else { MenuItem voiceActionsMenuItem = menu.findItem(R.id.MidiFollowingMenuItem); if(voiceActionsMenuItem!=null) { voiceActionsMenuItem.setTitle(ResourceModel.getInstance().ENABLE_MIDI_FOLLOWING); } } return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { //stop media player MediaPlayerAPI.getInstance().stop(); // Handle item selection switch (item.getItemId()) { case R.id.SetHomeDirMenuItem: showHomeDirectoryDialog(); return true; case R.id.SecIncMenuItem: showSelectIncDialog(); return true; case R.id.GoToMenuItem: showSelectSectionDialog(); return true; case R.id.PlaybackSpeedMenuItem: showSetPlaybackSpeedDialog(); return true; case R.id.StompModeMenuItem: stompModeDialog(item); return true; case R.id.VoiceActionsMenuItem: voiceActionsDialog(item); return true; case R.id.CalibStompModeMenuItem: calibrateStompMode(); return true; case R.id.MidiFollowingMenuItem: midiFollowingDialog(item); return true; default: return super.onOptionsItemSelected(item); } } public void midiFollowingDialog(MenuItem item) { //tab file must be loaded for stomper DataModel dataModel = DataModel.getInstance(); if(dataModel.getSong()!=null && dataModel.getTrackNum() >=0) { //enable midi follower if not active if(!MidiServer.getInstance().isRunning()) { //ask if enable midi follower final Dialog dialog = new MidiFollowingEnableDialog(this,this,item); dialog.show(); } else if(MidiServer.getInstance().isRunning()) { //stop midi follower MidiServer.getInstance().stop(); //change text on menu item item.setTitle(ResourceModel.getInstance().ENABLE_MIDI_FOLLOWING); } } else { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_FILE_LOADED); } } public void calibrateStompMode() { //stop stomper and voice actions stomper.onStop(); WordActivatorAPI.getInstance().onStop(); //start new activity Intent i = new Intent(this, StomperCalibActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivity(i); } public void voiceActionsDialog(MenuItem menuItem) { if(!DataModel.getInstance().isVoiceActionsEnabled()) { //show dialog for voice actions VoiceActionsDialog m = new VoiceActionsDialog(menuItem); m.show(getFragmentManager(), FRAGMENT_MANAGER_TAG); } else { //stop voice actions DataModel.getInstance().setVoiceActionsEnabled(false); WordActivatorAPI.getInstance().stopListening(); //relabel menu item menuItem.setTitle(ResourceModel.getInstance().ENABLE_VOICE_ACTIONS); } } public void stompModeDialog(MenuItem item) { //tab file must be loaded for stomper DataModel dataModel = DataModel.getInstance(); if(dataModel.getSong()!=null && dataModel.getTrackNum() >=0) { //enable stomper if not active if(!stomper.isEnabled()) { //show stomper enabled dialog final Dialog dialog = new StomperEnableDialog(this,stomper,this,item); dialog.show(); } else if(stomper.isEnabled()) { //stop stomper stomper.stop(); //change text on menu item item.setTitle(ResourceModel.getInstance().ENABLE_STOMP_MODE); } } else { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_FILE_LOADED); } } public void showSelectIncDialog() { DataModel dataModel = DataModel.getInstance(); if(dataModel.getSong()!=null && dataModel.getInstSegments()!=null && dataModel.getTrackNum()!=-1 && dataModel.getCurrentSegment()!=-1 && dataModel.getInstSegments()!=null) { MeasureIncrementDialog m = new MeasureIncrementDialog(this); m.show(getFragmentManager(), FRAGMENT_MANAGER_TAG); } else if(dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()==0) { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_DATA); } else { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_FILE_LOADED); } } public void showSetPlaybackSpeedDialog() { PlaybackSpeedDialog m = new PlaybackSpeedDialog(this); m.show(getFragmentManager(), FRAGMENT_MANAGER_TAG); } public void showSelectSectionDialog() { DataModel dataModel = DataModel.getInstance(); if(dataModel.getSong()!=null && dataModel.getInstSegments()!=null && dataModel.getTrackNum()!=-1 && dataModel.getCurrentSegment()!=-1 && dataModel.getInstSegments()!=null) { SelectSectionDialog m = new SelectSectionDialog(this); m.show(getFragmentManager(), FRAGMENT_MANAGER_TAG); } else if(dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()==0) { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_DATA); } else { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_FILE_LOADED); } } public void playAudioIcon() { DataModel dataModel = DataModel.getInstance(); if(dataModel.getSong()!=null && dataModel.getInstSegments()!=null && dataModel.getTrackNum()!=-1 && dataModel.getCurrentSegment()!=-1 && dataModel.getInstSegments()!=null && dataModel.getSelectedInstructionIndex()!=-1) { //get beat and play (if not on percussion track) if(!dataModel.isOnPercussionTrack()) { Segment c_seg = dataModel.getInstSegments().get(dataModel.getCurrentSegment()); List<TGBeat> beats = c_seg.getBeats(); TGBeat beat = beats.get(dataModel.getSelectedInstructionIndex()); if(beat!=null) { AudioIconAPI.getInstance().playBeatAudioIcon(beat); } } } else if(dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()==0) { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_DATA); } else if(dataModel.getInstSegments()!=null && dataModel.getInstSegments().size()!=0 && dataModel.getCurrentSegment()>=0 && dataModel.getTrackNum()>=0 && dataModel.getSelectedInstructionIndex()==-1) { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_INST_SELECTED); } else { TextToSpeechAPI.speak(ResourceModel.getInstance().ERROR_NO_FILE_LOADED); } } /** * Voice Activator callback */ @Override public void activated(boolean success, String wordHeard) { //stop media player MediaPlayerAPI.getInstance().stop(); //handle activation Log.d("ACTIVATED", wordHeard); String[] VOICE_COMMANDS = ResourceModel.getInstance().voiceCommands; if(wordHeard.equalsIgnoreCase(VOICE_COMMANDS[0])) { this.toggleModesButton.performClick(); } else if(wordHeard.equalsIgnoreCase(VOICE_COMMANDS[1])) { this.playSampleButton.performClick(); } else if(wordHeard.equalsIgnoreCase(VOICE_COMMANDS[2])) { this.nextMeasButton.performClick(); } else if(wordHeard.equalsIgnoreCase(VOICE_COMMANDS[3])) { this.prevMeasButton.performClick(); } else if(wordHeard.equalsIgnoreCase(VOICE_COMMANDS[4])) { this.upButton.performClick(); } else if(wordHeard.equalsIgnoreCase(VOICE_COMMANDS[5])) { this.downButton.performClick(); } else if(wordHeard.equalsIgnoreCase(VOICE_COMMANDS[6])) { playAudioIcon(); } } /** * @return the instructionsList */ public AccListView getInstructionsList() { return instructionsList; } @Override public void chordRecognized(final String chord) { //get chord hash final String chordHash = ChordRecognizer.getChordHash(chord); //match final DataModel dataModel = DataModel.getInstance(); if(dataModel.getSong()!=null && dataModel.getInstSegments()!=null && dataModel.getTrackNum()!=-1 && dataModel.getCurrentSegment()!=-1 && dataModel.getInstSegments()!=null && dataModel.getSelectedInstructionIndex()!=-1) { //see if chord hash matches target final Segment seg = dataModel.getInstSegments().get(dataModel.getCurrentSegment()); final String target = seg.getMatchTargets().get(dataModel.getSelectedInstructionIndex()); if(target.equals(chordHash) || ChordRecognizer.robustMidiMatch(chordHash, target)) { //play success track if(MIDI_FOLLOWER_DEBUG) { this.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "Success: " + target, Toast.LENGTH_SHORT).show(); } }); } //update gui for next available index this.updateGUIForNextAvailableIndex(); } else { //play buzzer if(MIDI_FOLLOWER_DEBUG) { this.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "Failure: " + chordHash + " ::: " + target, Toast.LENGTH_SHORT).show(); } }); } } } } public boolean updateToNextAvailableIndex() { //get data model DataModel dataModel = DataModel.getInstance(); //increment to next available one or say end of track if not anymore. int initSeg = dataModel.getCurrentSegment(); int segCtr = dataModel.getCurrentSegment(); int instCtr = dataModel.getSelectedInstructionIndex()+1; outer:while(segCtr < dataModel.getInstSegments().size()) { if(segCtr >= 0) { Segment seg = dataModel.getInstSegments().get(segCtr); while(instCtr < seg.getMatchTargets().size()) { if(instCtr >= 0) { String newTarget = seg.getMatchTargets().get(instCtr); if(!newTarget.equals("")) { dataModel.setCurrentSegment(segCtr); dataModel.setSelectedInstructionIndex(instCtr); break outer; } } instCtr++; } } segCtr++; instCtr=0; } //if chose end of track, just set to last instruction. if(segCtr==dataModel.getInstSegments().size()) { dataModel.setCurrentSegment(segCtr-1); dataModel.setSelectedInstructionIndex(dataModel.getInstSegments().get(dataModel.getCurrentSegment()).getSfInst().size()-1); } return (initSeg!=segCtr); } public void updateGUIForNextAvailableIndex() { //update to next index final boolean segChanged = updateToNextAvailableIndex(); //refresh gui this.runOnUiThread(new Runnable() { @Override public void run() { //update gui and perform programmatic selection int temp = DataModel.getInstance().getSelectedInstructionIndex(); if(segChanged) { DataModel.getInstance().clearSelectedInstructionIndex(); MainActivity.this.refreshGUI(); } MainActivity.this.instructionsList.programmaticSelect(temp); //find and read instruction using tts String c_inst = null; final DataModel dataModel = DataModel.getInstance(); final Segment seg = dataModel.getInstSegments().get(dataModel.getCurrentSegment()); if(dataModel.isVerbose()) { c_inst = seg.getSfInst().get(DataModel.getInstance().getSelectedInstructionIndex()); } else { c_inst = seg.getChordInst().get(DataModel.getInstance().getSelectedInstructionIndex()); } if(c_inst!=null) { TextToSpeechAPI.speak( InstructionContentDescription.makeAccessibleInstruction(c_inst)); } } }); } @Override public void onSaveInstanceState(Bundle bundle) { bundle.putBoolean(stomper.toString(), stomper.isEnabled()); bundle.putBoolean(WordActivatorAPI.getInstance().toString(), DataModel.getInstance().isVoiceActionsEnabled()); bundle.putBoolean(MidiServer.getInstance().toString(), MidiServer.getInstance().isRunning()); } /** * @return the downButton */ public Button getDownButton() { return downButton; } }