- Timestamp:
- 12/09/12 06:35:28 (8 years ago)
- Branches:
- master, RawEEG, Raw_EEG_Plot, Servo, Tab_Interface, pyramid
- Children:
- 403fb9a
- Parents:
- a32b629
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
android/src/info/puzzlebox/orbit/MainActivity.java
ra32b629 rcd5d285 1 1 package info.puzzlebox.orbit; 2 2 3 //import java.io.IOException; 4 //import java.util.concurrent.ExecutorService; 5 //import java.util.concurrent.Executors; 6 7 //import com.hoho.android.usbserial.driver.UsbSerialDriver; 8 //import com.hoho.android.usbserial.driver.UsbSerialProber; 9 //import com.hoho.android.usbserial.util.SerialInputOutputManager; 10 import com.neurosky.thinkgear.TGDevice; 3 /** 4 * Puzzlebox Orbit 5 * 6 * Copyright Puzzlebox Productions, LLC (2012) 7 * 8 * This code is released under the GNU Public License (GPL) version 2 9 * For more information please refer to http://www.gnu.org/copyleft/gpl.html 10 * 11 * NOTE: USB Serial support is necessary for communicating with 12 * an Arduino UNO, however requires Android 3.2 or later. 13 * For compatibility with earlier handsets we have left USB Serial 14 * support commented out by default throughout this source file. 15 */ 11 16 12 17 import android.media.AudioFormat; … … 29 34 import android.util.Log; 30 35 import android.view.Gravity; 31 //import android.view.Menu;32 //import android.view.MenuItem;33 36 import android.view.View; 34 37 import android.widget.Button; 35 38 import android.widget.ProgressBar; 36 //import android.widget.RemoteViews;37 39 import android.widget.SeekBar; 38 40 import android.widget.TextView; 39 41 import android.widget.Toast; 40 //import android.support.v4.app.NavUtils;41 42 import android.text.Layout; 42 43 import android.text.method.ScrollingMovementMethod; 43 44 45 //import java.io.IOException; 46 //import java.util.concurrent.ExecutorService; 47 //import java.util.concurrent.Executors; 48 49 import com.neurosky.thinkgear.TGDevice; 50 51 //import com.hoho.android.usbserial.driver.UsbSerialDriver; 52 //import com.hoho.android.usbserial.driver.UsbSerialProber; 53 //import com.hoho.android.usbserial.util.SerialInputOutputManager; 54 55 44 56 public class MainActivity extends Activity implements SeekBar.OnSeekBarChangeListener { 45 46 // @Override47 // public void onCreate(Bundle savedInstanceState) {48 // super.onCreate(savedInstanceState);49 // setContentView(R.layout.activity_main);50 // getActionBar().setDisplayHomeAsUpEnabled(true);51 // }52 //53 // @Override54 // public boolean onCreateOptionsMenu(Menu menu) {55 // getMenuInflater().inflate(R.menu.activity_main, menu);56 // return true;57 // }58 //59 //60 // @Override61 // public boolean onOptionsItemSelected(MenuItem item) {62 // switch (item.getItemId()) {63 // case android.R.id.home:64 // NavUtils.navigateUpFromSameTask(this);65 // return true;66 // }67 // return super.onOptionsItemSelected(item);68 // }69 57 70 58 BluetoothAdapter bluetoothAdapter; … … 81 69 String TAG = "MainActivity"; 82 70 83 int tgSignal = 0; 84 int[] thresholdValuesAttention = new int[101]; 85 int[] thresholdValuesMeditation = new int[101]; 86 // int minimumPower = 60; // minimum power to which the flame effect can be set 87 int minimumPower = 0; // minimum power to which the flame effect can be set 88 int maximumPower = 100; 89 90 // SerialDevice serial; 91 // int serialBaudRate = 9600; 92 // int serialBaudRate = 133333; 93 94 95 TGDevice tgDevice; 96 final boolean rawEnabled = false; 97 71 /** 72 * The Bluetooth MAC address is temporarily hard-coded into the source code 73 */ 98 74 private static final String MAC_ADDRESS = "D0:DF:9A:69:5D:42"; // MindWave Mobile Dev (p1-dev-60-01) 99 75 // private static final String MAC_ADDRESS = "9C:B7:0D:5E:E5:6A"; // UK So Television … … 101 77 // private static final String MAC_ADDRESS = "9C:B7:0D:90:EB:92"; // Steve Harvey Show 102 78 103 // int audioFile = R.raw.throttle_max_android_common; 104 // int audioFile = R.raw.throttle_min_android_common; 79 /** 80 * Currently the flight control command is hard-coded into WAV files 81 * In a future release the tones used to communicate with the infrared dongle 82 * will be generated on-the-fly. This conversion process is already underway 83 */ 105 84 int audioFile = R.raw.throttle_hover_android_common; 106 85 // int audioFile = R.raw.throttle_hover_android_htc_one_x; 107 86 87 88 TGDevice tgDevice; 89 int tgSignal = 0; 90 int[] thresholdValuesAttention = new int[101]; 91 int[] thresholdValuesMeditation = new int[101]; 92 int minimumPower = 0; // minimum power for the helicopter throttle 93 int maximumPower = 100; // maximum power for the helicopter throttle 108 94 String currentCommand = "neutral"; 95 final boolean rawEnabled = false; 96 97 // SerialDevice serial; 98 // int serialBaudRate = 9600; 109 99 110 100 private SoundPool soundPool; … … 113 103 114 104 115 // Tone Generator 116 // http://stackoverflow.com/questions/2413426/playing-an-arbitrary-tone-with-android 105 /** 106 * Tone Generator 107 * This is used to generate a carrier signal, to be played out the right 108 * audio channel when the IR dongle is attached 109 * Reference link - http://stackoverflow.com/questions/2413426/playing-an-arbitrary-tone-with-android 110 */ 117 111 private final int duration = 10; // seconds 118 112 private final int sampleRate = 8000; 119 113 private final int numSamples = duration * sampleRate; 120 114 private final double sample[] = new double[numSamples]; 121 private final double freqOfTone = 440; // hz115 private final double freqOfTone = 440; // Hz 122 116 123 117 private final byte generatedSnd[] = new byte[2 * numSamples]; … … 161 155 /** Called when the activity is first created. */ 162 156 super.onCreate(savedInstanceState); 163 // setContentView(R.layout.main);164 157 setContentView(R.layout.activity_main); 165 166 // mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);167 158 168 159 progressBarAttention = (ProgressBar)findViewById(R.id.progressBarAttention); … … 174 165 progressBarAttention.setProgressDrawable(progressAttention); 175 166 progressBarAttention.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal)); 176 // progressBarAttention.setProgress(80);177 167 178 168 progressBarMeditation = (ProgressBar)findViewById(R.id.progressBarMeditation); … … 183 173 progressBarMeditation.setProgressDrawable(progressMeditation); 184 174 progressBarMeditation.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal)); 185 // progressBarMeditation.setProgress(60);186 175 187 176 progressBarSignal = (ProgressBar)findViewById(R.id.progressBarSignal); … … 192 181 progressBarSignal.setProgressDrawable(progressSignal); 193 182 progressBarSignal.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal)); 194 // progressBarSignal.setProgress(40);195 183 progressBarSignal.setProgress(tgSignal); 196 184 … … 202 190 progressBarPower.setProgressDrawable(progressPower); 203 191 progressBarPower.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal)); 204 //progressBarPower.setProgress(20);205 206 //tv = (TextView)findViewById(R.id.textViewDebugConsole);207 //tv.setText("");208 //tv.append("Android version: " + Integer.valueOf(android.os.Build.VERSION.SDK) + "\n" );209 192 210 193 seekBarAttention = (SeekBar)findViewById(R.id.seekBarAttention); … … 212 195 seekBarMeditation = (SeekBar)findViewById(R.id.seekBarMeditation); 213 196 seekBarMeditation.setOnSeekBarChangeListener(this); 214 215 197 216 198 tv = (TextView)findViewById(R.id.textViewDebugConsole); … … 230 212 finish(); 231 213 return; 232 } else {233 /* create the TGDevice */214 } else { 215 /** create the TGDevice */ 234 216 tgDevice = new TGDevice(bluetoothAdapter, handler); 235 217 } 236 218 237 219 220 // mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE); 238 221 // serial = new SerialDevice(); 239 222 // serial.setSerialDevice(mSerialDevice); 240 223 241 224 242 genTone(); 243 //playTone(); 244 245 246 // Set the hardware buttons to control the music 225 // genTone(); 226 227 228 /** Set the hardware buttons to control the audio output */ 247 229 this.setVolumeControlStream(AudioManager.STREAM_MUSIC); 248 // Load the sound 230 231 /** Preload the flight control WAV file into memory */ 249 232 soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0); 250 233 soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() { 251 // @Override252 234 public void onLoadComplete(SoundPool soundPool, int sampleId, 253 235 int status) { … … 255 237 } 256 238 }); 257 258 239 soundID = soundPool.load(this, audioFile, 1); 259 240 … … 265 246 protected void onResume() { 266 247 super.onResume(); 248 /** This section handles the USB Serial device when the program is resumed */ 267 249 // mSerialDevice = UsbSerialProber.acquire(mUsbManager); 268 250 // // Log.d(TAG, "Resumed, mSerialDevice=" + mSerialDevice); … … 297 279 @Override 298 280 public void onDestroy() { 281 299 282 tgDevice.close(); 283 300 284 // if (mSerialDevice != null) { 301 285 // try { … … 306 290 // } 307 291 // } 292 308 293 super.onDestroy(); 309 294 } 295 296 297 private void appendTextAndScroll(String text) { 298 if (tv != null) { 299 // tv.append(text + "\n"); 300 tv.append(text); 301 final Layout layout = tv.getLayout(); 302 if (layout != null) { 303 int scrollDelta = layout.getLineBottom(tv.getLineCount() - 1) 304 - tv.getScrollY() - tv.getHeight(); 305 if (scrollDelta > 0) 306 tv.scrollBy(0, scrollDelta); 307 } 308 } 309 } // appendTextAndScroll 310 311 312 public void setButtonText(int buttonId, String text) { 313 314 Button button = (Button) findViewById(buttonId); 315 button.setText(text); 316 317 } // setButtonText 318 319 320 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { 321 //appendTextAndScroll(progress + " " + 322 //getString(R.string.seekbar_from_touch) + "=" + fromTouch); 323 324 updatePowerThresholds(); 325 updatePower(); 326 327 } // onProgressChanged 328 329 330 public void onStartTrackingTouch(SeekBar seekBar) { 331 //appendTextAndScroll(getString(R.string.seekbar_tracking_on)); 332 } // onStartTrackingTouch 333 334 335 public void onStopTrackingTouch(SeekBar seekBar) { 336 //appendTextAndScroll(getString(R.string.seekbar_tracking_off)); 337 } // onStopTrackingTouch 338 339 340 private void stopIoManager() { 341 // if (mSerialIoManager != null) { 342 // // Log.i(TAG, "Stopping io manager .."); 343 // mSerialIoManager.stop(); 344 // mSerialIoManager = null; 345 // } 346 } // stopIoManager 347 348 349 private void startIoManager() { 350 // if (mSerialDevice != null) { 351 // // Log.i(TAG, "Starting io manager .."); 352 // mSerialIoManager = new SerialInputOutputManager(mSerialDevice, mListener); 353 // mExecutor.submit(mSerialIoManager); 354 // } 355 } // startIoManager 356 357 358 private void onDeviceStateChange() { 359 stopIoManager(); 360 startIoManager(); 361 } // onDeviceStateChange 310 362 311 363 … … 345 397 case TGDevice.STATE_DISCONNECTED: 346 398 Log.d(TAG, "EEG Disconnected"); 347 //appendTextAndScroll("EEG Disconnected\n");399 appendTextAndScroll("EEG Disconnected\n"); 348 400 break; 349 401 } … … 353 405 case TGDevice.MSG_POOR_SIGNAL: 354 406 tgSignal = calculateSignal(msg.arg1); 355 //signal = msg.arg1;356 // tv.append("PoorSignal: " + msg.arg1 + "\n");357 407 Log.v(TAG, "PoorSignal: " + msg.arg1); 358 408 // appendTextAndScroll("\nPoorSignal: " + msg.arg1 + "\n"); … … 360 410 361 411 updatePower(); 362 363 412 364 413 break; … … 429 478 430 479 431 public void setButtonText(int buttonId, String text) {432 433 // RemoteViews remoteViews = new RemoteViews(getApplicationContext().getPackageName(), R.layout.activity_main);434 // remoteViews.setTextViewText(buttonId, text);435 436 Button button = (Button) findViewById(buttonId);437 button.setText(text);438 439 }440 441 442 480 public int calculateSignal(int signal) { 481 482 /** 483 * The ThinkGear protocol states that a signal level of 200 will be 484 * returned when a clean ground/reference is not detected at the ear clip, 485 * and a value of 0 when the signal is perfectly clear. We need to 486 * convert this information into usable settings for the Signal 487 * progress bar 488 */ 489 443 490 int value; 444 491 … … 455 502 456 503 457 private void appendTextAndScroll(String text) {458 if (tv != null) {459 // tv.append(text + "\n");460 tv.append(text);461 final Layout layout = tv.getLayout();462 if (layout != null) {463 int scrollDelta = layout.getLineBottom(tv.getLineCount() - 1)464 - tv.getScrollY() - tv.getHeight();465 if (scrollDelta > 0)466 tv.scrollBy(0, scrollDelta);467 }468 }469 } // appendTextAndScroll470 471 472 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {473 //appendTextAndScroll(progress + " " +474 //getString(R.string.seekbar_from_touch) + "=" + fromTouch);475 476 updatePowerThresholds();477 updatePower();478 479 } // onProgressChanged480 481 482 public void onStartTrackingTouch(SeekBar seekBar) {483 //appendTextAndScroll(getString(R.string.seekbar_tracking_on));484 } // onStartTrackingTouch485 486 487 public void onStopTrackingTouch(SeekBar seekBar) {488 //appendTextAndScroll(getString(R.string.seekbar_tracking_off));489 } // onStopTrackingTouch490 491 492 504 public void updatePowerThresholds() { 493 505 … … 507 519 for (int i = attentionSeekValue; i < thresholdValuesAttention.length; i++) { 508 520 509 // Slider @ 70 510 // Attention @ 70 511 // Percentage = 0% ((100-70) - (100-70)) / (100-70) 512 // Power = 60 (minimumPower) 513 514 // Slider @ 70 515 // Attention @ 80 516 // Percentage = 33% ((100-70) - (100-80)) / (100-70) 517 // Power = 73 518 519 // Slider @ 70 520 // Attention @ 90 521 // Percentage = 66% ((100-70) - (100-90)) / (100-70) 522 // Power = 86 523 524 // Slider @ 70 525 // Attention @ 100 526 // Percentage = 100% ((100-70) - (100-100)) / (100-70) 527 // Power = 100 521 /** 522 * Slider @ 70 523 * 524 * Attention @ 70 525 * Percentage = 0% ((100-70) - (100-70)) / (100-70) 526 * Power = 60 (minimumPower) 527 * 528 * Slider @ 70 529 * Attention @ 80 530 * Percentage = 33% ((100-70) - (100-80)) / (100-70) 531 * Power = 73 532 * 533 * Slider @ 70 534 * Attention @ 90 535 * Percentage = 66% ((100-70) - (100-90)) / (100-70) 536 * Power = 86 537 * 538 * Slider @ 70 539 * Attention @ 100 540 * Percentage = 100% ((100-70) - (100-100)) / (100-70) 541 * Power = 100 542 */ 528 543 529 544 percentOfMaxPower = (float)( ((100 - attentionSeekValue) - (100 - i)) / (float)(100 - attentionSeekValue) ); … … 544 559 545 560 } // updatePowerThresholds 561 562 563 public int calculateSpeed() { 564 565 int attention = progressBarAttention.getProgress(); 566 int meditation = progressBarMeditation.getProgress(); 567 int attentionSeekValue = seekBarAttention.getProgress(); 568 int meditationSeekValue = seekBarMeditation.getProgress(); 569 570 int speed = 0; 571 572 if (attention > attentionSeekValue) 573 speed = thresholdValuesAttention[attention]; 574 if (meditation > meditationSeekValue) 575 speed = speed + thresholdValuesMeditation[meditation]; 576 577 if (speed > maximumPower) 578 speed = maximumPower; 579 if (speed < minimumPower) 580 speed = 0; 581 582 return(speed); 583 584 } // calculateSpeed 546 585 547 586 … … 609 648 610 649 public void playControl() { 611 612 // Getting the user sound settings 650 651 /** 652 * Play audio control file 653 */ 654 655 /** Getting the user sound settings */ 613 656 AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE); 614 float actualVolume = (float) audioManager 615 .getStreamVolume(AudioManager.STREAM_MUSIC); 616 float maxVolume = (float) audioManager 617 .getStreamMaxVolume(AudioManager.STREAM_MUSIC); 657 float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 658 float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 618 659 float volume = actualVolume / maxVolume; 619 / / Is the sound loaded already?660 /** Is the sound loaded already? */ 620 661 if (loaded) { 621 662 soundPool.play(soundID, volume, volume, 1, 0, 1f); … … 627 668 628 669 public void stopControl() { 670 671 /** 672 * Stop playing audio file 673 */ 629 674 630 675 try { … … 635 680 } 636 681 637 } 682 } // stopControl 683 684 685 void genTone(){ 686 /** fill out the array */ 687 for (int i = 0; i < numSamples; ++i) { 688 sample[i] = Math.sin(2 * Math.PI * i / (sampleRate/freqOfTone)); 689 } 690 691 /** 692 * convert to 16 bit pcm sound array 693 * assumes the sample buffer is normalized. 694 */ 695 int idx = 0; 696 for (final double dVal : sample) { 697 /** scale to maximum amplitude */ 698 final short val = (short) ((dVal * 32767)); 699 /** in 16 bit wav PCM, first byte is the low order byte */ 700 generatedSnd[idx++] = (byte) (val & 0x00ff); 701 generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8); 702 703 } 704 } // genTone 705 706 707 void playTone(){ 708 final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 709 // sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, 710 sampleRate, AudioFormat.CHANNEL_OUT_MONO, 711 // sampleRate, AudioFormat.CHANNEL_OUT_STEREO, 712 // sampleRate, AudioFormat.CHANNEL_OUT_FRONT_RIGHT, 713 // sampleRate, AudioFormat.CHANNEL_CONFIGURATION_STEREO, 714 AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, 715 AudioTrack.MODE_STATIC); 716 audioTrack.write(generatedSnd, 0, generatedSnd.length); 717 audioTrack.play(); 718 } // playTone 638 719 639 720 … … 644 725 playControl(); 645 726 727 /** The following demo mode, when used with an Arduino-controlled infrared circuit, 728 * should cause the helicopter to briefly hover, then return to the ground 729 */ 730 // 646 731 // String command = "neutral"; 647 732 // … … 656 741 // } 657 742 // 658 //// command = "hover"; 659 // command = "idle"; 743 // command = "hover"; 660 744 // appendTextAndScroll("Command for serial device: " + command + "\n"); 661 745 // serial.setCommand(command); … … 677 761 678 762 679 public int calculateSpeed() { 680 681 int attention = progressBarAttention.getProgress(); 682 int meditation = progressBarMeditation.getProgress(); 683 int attentionSeekValue = seekBarAttention.getProgress(); 684 int meditationSeekValue = seekBarMeditation.getProgress(); 685 686 int speed = 0; 687 688 if (attention > attentionSeekValue) 689 speed = thresholdValuesAttention[attention]; 690 if (meditation > meditationSeekValue) 691 speed = speed + thresholdValuesMeditation[meditation]; 692 693 if (speed > maximumPower) 694 speed = maximumPower; 695 if (speed < minimumPower) 696 speed = 0; 697 698 return(speed); 699 700 } // calculateSpeed 701 702 703 private void stopIoManager() { 704 // if (mSerialIoManager != null) { 705 // // Log.i(TAG, "Stopping io manager .."); 706 // mSerialIoManager.stop(); 707 // mSerialIoManager = null; 708 // } 709 } // stopIoManager 710 711 712 private void startIoManager() { 713 // if (mSerialDevice != null) { 714 // // Log.i(TAG, "Starting io manager .."); 715 // mSerialIoManager = new SerialInputOutputManager(mSerialDevice, mListener); 716 // mExecutor.submit(mSerialIoManager); 717 // } 718 } // startIoManager 719 720 721 private void onDeviceStateChange() { 722 stopIoManager(); 723 startIoManager(); 724 } // onDeviceStateChange 725 726 727 void genTone(){ 728 // fill out the array 729 for (int i = 0; i < numSamples; ++i) { 730 sample[i] = Math.sin(2 * Math.PI * i / (sampleRate/freqOfTone)); 731 } 732 733 // convert to 16 bit pcm sound array 734 // assumes the sample buffer is normalized. 735 int idx = 0; 736 for (final double dVal : sample) { 737 // scale to maximum amplitude 738 final short val = (short) ((dVal * 32767)); 739 // in 16 bit wav PCM, first byte is the low order byte 740 generatedSnd[idx++] = (byte) (val & 0x00ff); 741 generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8); 742 743 } 744 } // genTone 745 746 747 void playTone(){ 748 final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 749 // sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, 750 sampleRate, AudioFormat.CHANNEL_OUT_MONO, 751 // sampleRate, AudioFormat.CHANNEL_OUT_STEREO, 752 // sampleRate, AudioFormat.CHANNEL_OUT_FRONT_RIGHT, 753 // sampleRate, AudioFormat.CHANNEL_CONFIGURATION_STEREO, 754 AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, 755 AudioTrack.MODE_STATIC); 756 audioTrack.write(generatedSnd, 0, generatedSnd.length); 757 audioTrack.play(); 758 } // playTone 759 760 761 } 763 } // MainActivity
Note: See TracChangeset
for help on using the changeset viewer.