Changeset a546cc3 in orbit


Ignore:
Timestamp:
03/04/13 18:12:28 (7 years ago)
Author:
Steve Castellotti <sc@…>
Branches:
master, RawEEG, Raw_EEG_Plot, Servo, Tab_Interface, pyramid
Children:
47806a1
Parents:
a86d057
Message:
  • dynamic UI control for hiding and repositioning elements
Location:
android
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • android/res/layout/activity_main.xml

    ra86d057 ra546cc3  
    11<?xml version="1.0" encoding="utf-8"?> 
    22<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    3     android:layout_width="fill_parent" 
    4     android:layout_height="fill_parent" 
     3    android:layout_width="match_parent" 
     4    android:layout_height="match_parent" 
    55    android:orientation="vertical" > 
    66 
     
    1515        android:id="@+id/progressBarAttention" 
    1616        style="?android:attr/progressBarStyleHorizontal" 
    17         android:layout_width="fill_parent" 
     17        android:layout_width="match_parent" 
    1818        android:layout_height="wrap_content" /> 
    1919 
    2020    <SeekBar 
    2121        android:id="@+id/seekBarAttention" 
    22         android:layout_width="fill_parent" 
     22        android:layout_width="match_parent" 
    2323        android:layout_height="wrap_content" 
    2424        android:max="100" 
     
    3737        android:id="@+id/progressBarMeditation" 
    3838        style="?android:attr/progressBarStyleHorizontal" 
    39         android:layout_width="fill_parent" 
     39        android:layout_width="match_parent" 
    4040        android:layout_height="wrap_content" /> 
    4141 
    4242    <SeekBar 
    4343        android:id="@+id/seekBarMeditation" 
    44         android:layout_width="fill_parent" 
     44        android:layout_width="match_parent" 
    4545        android:layout_height="wrap_content" 
    4646        android:max="100" 
     
    5959        android:id="@+id/progressBarSignal" 
    6060        style="?android:attr/progressBarStyleHorizontal" 
    61         android:layout_width="fill_parent" 
     61        android:layout_width="match_parent" 
    6262        android:layout_height="wrap_content" /> 
    6363 
     
    8282    <LinearLayout 
    8383        android:id="@+id/layoutControl" 
    84         android:layout_width="fill_parent" 
     84        android:layout_width="match_parent" 
    8585        android:layout_height="wrap_content" 
    8686        android:orientation="horizontal" > 
     
    127127    <LinearLayout 
    128128        android:id="@+id/layoutAudioService" 
    129         android:layout_width="fill_parent" 
     129        android:layout_width="match_parent" 
    130130        android:layout_height="wrap_content" 
    131131        android:orientation="vertical" > 
     
    139139        <SeekBar 
    140140            android:id="@+id/seekBarThrottle" 
    141             android:layout_width="fill_parent" 
     141            android:layout_width="match_parent" 
    142142            android:layout_height="wrap_content" 
    143143            android:max="127" 
     
    152152        <SeekBar 
    153153            android:id="@+id/seekBarYaw" 
    154             android:layout_width="fill_parent" 
     154            android:layout_width="match_parent" 
    155155            android:layout_height="wrap_content" 
    156156            android:max="127" 
     
    165165        <SeekBar 
    166166            android:id="@+id/seekBarPitch" 
    167             android:layout_width="fill_parent" 
     167            android:layout_width="match_parent" 
    168168            android:layout_height="wrap_content" 
    169169            android:max="63" 
     
    173173    <LinearLayout 
    174174        android:id="@+id/layoutAdvancedOptions" 
    175         android:layout_width="fill_parent" 
     175        android:layout_width="match_parent" 
    176176        android:layout_height="wrap_content" 
    177177        android:orientation="horizontal" > 
    178178 
    179179        <View 
     180            android:layout_width="10dp" 
     181            android:layout_height="0dp" > 
     182        </View> 
     183 
     184        <RadioGroup 
     185            android:id="@+id/radioGroupChannel" 
     186            android:layout_width="wrap_content" 
     187            android:layout_height="wrap_content" 
     188            android:orientation="horizontal" > 
     189 
     190            <TextView 
     191                android:id="@+id/textViewChannel" 
     192                android:layout_width="wrap_content" 
     193                android:layout_height="wrap_content" 
     194                android:text="@string/text_view_channel" /> 
     195 
     196            <RadioButton 
     197                android:id="@+id/radioA" 
     198                android:layout_width="wrap_content" 
     199                android:layout_height="wrap_content" 
     200                android:text="@string/radio_a" /> 
     201 
     202            <RadioButton 
     203                android:id="@+id/radioB" 
     204                android:layout_width="wrap_content" 
     205                android:layout_height="wrap_content" 
     206                android:text="@string/radio_b" /> 
     207 
     208            <RadioButton 
     209                android:id="@+id/radioC" 
     210                android:layout_width="wrap_content" 
     211                android:layout_height="wrap_content" 
     212                android:text="@string/radio_c" /> 
     213        </RadioGroup> 
     214 
     215        <View 
     216            android:id="@+id/viewSpaceGenerateAudio" 
    180217            android:layout_width="10dp" 
    181218            android:layout_height="0dp" > 
     
    186223            android:layout_width="wrap_content" 
    187224            android:layout_height="wrap_content" 
     225            android:checked="true" 
    188226            android:onClick="onCheckBoxGenerateAudioClicked" 
    189             android:text="@string/checkbox_generate_audio" 
    190             android:checked="true" /> 
    191  
    192         <View 
    193             android:layout_width="10dp" 
    194             android:layout_height="0dp" > 
    195         </View> 
    196  
    197         <CheckBox 
    198             android:id="@+id/checkBoxInvertControlSignal" 
    199             android:layout_width="wrap_content" 
    200             android:layout_height="wrap_content" 
    201             android:onClick="onCheckBoxInvertControlSignalClicked" 
    202             android:text="@string/checkbox_invert_control_signal" /> 
    203  
    204         <View 
    205             android:layout_width="10dp" 
    206             android:layout_height="0dp" > 
    207         </View> 
    208  
    209         <RadioGroup 
    210             android:id="@+id/radioGroupChannel" 
    211             android:layout_width="fill_parent" 
     227            android:text="@string/checkbox_generate_audio" /> 
     228 
     229        <LinearLayout 
     230            android:id="@+id/layoutInvertControlSignal" 
     231            android:layout_width="wrap_content" 
    212232            android:layout_height="wrap_content" 
    213233            android:orientation="horizontal" > 
    214234 
    215             <TextView 
    216                 android:id="@+id/textViewChannel" 
    217                 android:layout_width="wrap_content" 
    218                 android:layout_height="wrap_content" 
    219                 android:text="@string/text_view_channel" /> 
    220  
    221             <RadioButton 
    222                 android:id="@+id/radioA" 
    223                 android:layout_width="wrap_content" 
    224                 android:layout_height="wrap_content" 
    225                 android:text="@string/radio_a" /> 
    226  
    227             <RadioButton 
    228                 android:id="@+id/radioB" 
    229                 android:layout_width="wrap_content" 
    230                 android:layout_height="wrap_content" 
    231                 android:text="@string/radio_b" /> 
    232  
    233             <RadioButton 
    234                 android:id="@+id/radioC" 
    235                 android:layout_width="wrap_content" 
    236                 android:layout_height="wrap_content" 
    237                 android:text="@string/radio_c" /> 
    238         </RadioGroup> 
     235            <View 
     236                android:layout_width="10dp" 
     237                android:layout_height="0dp" > 
     238            </View> 
     239 
     240            <CheckBox 
     241                android:id="@+id/checkBoxInvertControlSignal" 
     242                android:layout_width="wrap_content" 
     243                android:layout_height="wrap_content" 
     244                android:onClick="onCheckBoxInvertControlSignalClicked" 
     245                android:text="@string/checkbox_invert_control_signal" /> 
     246        </LinearLayout> 
    239247 
    240248        <View 
     
    253261    <ScrollView 
    254262        android:id="@+id/scrollViewDebugConsole" 
    255         android:layout_width="fill_parent" 
     263        android:layout_width="match_parent" 
    256264        android:layout_height="0.0dip" 
    257265        android:layout_weight="1.0" 
     
    261269        <TextView 
    262270            android:id="@+id/textViewDebugConsole" 
    263             android:layout_width="fill_parent" 
     271            android:layout_width="match_parent" 
    264272            android:layout_height="wrap_content" 
    265273            android:layout_gravity="top" 
  • android/src/info/puzzlebox/orbit/AudioService.java

    ra86d057 ra546cc3  
    1212 
    1313public class AudioService extends Service{ 
    14          
     14 
    1515        /** 
    1616         * default field values. 
     
    1818        AudioTrack track; 
    1919        public int sampleRate = 44100; 
    20          
     20 
    2121        short[] audioData = new short[6144]; 
    2222        public boolean ifFlip = false; 
     
    2727        Integer[] command={throttle,yaw,pitch,channel}; 
    2828        int loopNumberWhileMindControl=20; 
    29                  
     29         
     30         
     31        /**  
     32         * Tone Generator 
     33         * This is used to generate a carrier signal, to be played out the right 
     34         * audio channel when the IR dongle is attached 
     35         * Reference link - http://stackoverflow.com/questions/2413426/playing-an-arbitrary-tone-with-android 
     36         */ 
     37        private final int duration = 10; // seconds 
     38        private final int sampleRateTone = 8000; 
     39        private final int numSamples = duration * sampleRateTone; 
     40        private final double sample[] = new double[numSamples]; 
     41        private final double freqOfTone = 440; // Hz 
     42 
     43        final byte generatedSnd[] = new byte[2 * numSamples]; 
     44         
     45 
    3046        /** 
    3147         * Object constructor. 
     
    3349         * @param ifFlip  
    3450         */ 
    35          
     51 
    3652        public AudioService() 
    3753        { 
     
    3955                track = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRate,AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT,minSize, AudioTrack.MODE_STREAM); 
    4056 
    41         } 
    42          
     57        } // AudioService 
     58 
     59 
     60        // ################################################################ 
     61 
    4362        public AudioService(int sps, boolean flip) 
    4463        { 
    45 //              AudioTrack track; 
     64                //              AudioTrack track; 
    4665                ifFlip = flip; 
    4766                sampleRate = sps; 
     
    4968                track = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRate,AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT,minSize, AudioTrack.MODE_STREAM); 
    5069 
    51                  
    52         } 
    53          
    54  
    55         public class OrbitBinder extends Binder { 
    56                 AudioService getService() { 
    57                         return AudioService.this; 
    58                 } 
    59         } 
     70        } // AudioService 
     71 
     72 
     73        // ################################################################ 
    6074 
    6175        private final IBinder binder = new OrbitBinder(); 
    62          
     76 
    6377        @Override 
    6478        public IBinder onBind(Intent arg0) { 
    6579                //return null; 
    6680                return binder; 
    67         } 
    68          
     81        } // onBind 
     82 
     83 
     84        // ################################################################ 
     85 
    6986        @Override  
    7087        public int onStartCommand(Intent intent, int flags, int startId) { 
    7188                //Toast.makeText(this, "Start sending fly commands through audio jack", Toast.LENGTH_SHORT).show(); 
    7289                try{ 
    73                 new DoBackgroundTask().execute(command); 
     90                        new DoBackgroundTask().execute(command); 
    7491                } catch (Exception e) { 
    7592                        e.printStackTrace(); 
    7693                } 
    7794                return START_STICKY; 
    78         } 
    79          
     95        } // onStartCommand 
     96 
     97 
     98        // ################################################################ 
     99 
    80100        @Override 
    81101        public void onDestroy() { 
     
    83103                super.onDestroy(); 
    84104                //Toast.makeText(this, "Stop sending fly commands in audio jack", Toast.LENGTH_SHORT).show(); 
    85         } 
    86          
    87          
    88         private class DoBackgroundTask extends AsyncTask < Integer , Void , Integer > { 
    89                 protected Integer doInBackground(Integer... command) { 
    90  
    91                         int throttle=command[0].intValue(); 
    92                         int yaw=command[1].intValue(); 
    93                         int pitch=command[2].intValue(); 
    94                         int channel=command[3].intValue(); 
    95                          
    96                         int code=command2code(throttle,yaw,pitch,channel); 
    97                         float[] wave=code2wave(code);    
    98                          
    99                         track.play(); 
    100                          
    101                         for (int j = 0; j<4; j++) 
    102                                 send(wave);              
    103                          
    104                         send(initialWave()); 
    105                          
    106                         for (int j = 0; j<loopNumberWhileMindControl; j++) 
    107                                 send(wave);      
    108                          
    109                         track.stop(); 
    110                         return 0; 
    111                 } 
    112                  
    113 //              protected void onPostexecute(Integer result) { 
    114 //                      stopSelf(); 
    115 //              } 
    116         } 
    117          
    118          
     105        } // onDestroy 
     106 
     107 
     108        // ################################################################ 
     109 
    119110        private final double sampleTime = 1/(double)sampleRate; 
    120          
     111 
    121112        /** 
    122113         * Half periods in the audio code, in seconds. 
     
    126117        private final double shortHIGH = 0.000412649; 
    127118        private final double shortLOW = 0.000378351; 
    128          
     119 
    129120        /** 
    130121         * Pre-calculated and stored half sine waves. 
     
    134125        private final float[] waveShortHIGH=halfSineGen('u',shortHIGH); 
    135126        private final float[] waveShortLOW=halfSineGen('d',shortLOW); 
    136          
     127 
    137128        /** 
    138129         * Pre-assembled audio code bit array in wave form.  
     
    140131        private final float[] waveBit[]= {concatFloat(waveShortHIGH,waveShortLOW),concatFloat(waveLongHIGH,waveLongLOW)}; 
    141132 
    142          
     133 
    143134        public void send(float[] samples) 
    144135        { 
    145136                assembleRightChannel(samples); 
    146137                track.write(audioData,0,2*samples.length); 
    147         } 
    148          
     138        } // send 
     139 
     140 
     141        // ################################################################ 
     142 
    149143        private void assembleRightChannel(float[] samples) 
    150144        { 
    151145                if(audioData.length < 2*samples.length) 
    152146                        audioData=new short[2*samples.length]; 
    153                  
     147 
    154148                float increment = (float)((2*Math.PI)*500/sampleRate); 
    155149                float angle = 0; 
    156                  
     150 
    157151                for (int i=0; i< samples.length; i++){ 
    158152                        audioData[2*i+1]=(short)(Math.sin(angle)*Short.MAX_VALUE); 
     
    160154                        angle += increment; 
    161155                } 
    162         } 
    163          
     156        } // assembleRightChannel 
     157 
     158 
     159        // ################################################################ 
     160 
    164161        /** 
    165162         * release low level resources when not use them anymore. 
     
    167164        public void releasetrack(){ 
    168165                track.release(); 
    169         } 
    170          
    171          
     166        } // releasetrack 
     167 
     168 
     169        // ################################################################ 
     170 
    172171        /** 
    173172         * Turn throttle, pitch, yaw and channel into IR code (in wave form). 
     
    178177         * @return 
    179178         */ 
    180          
     179 
    181180        public int command2code(int throttle, int yaw, int pitch, int channel){ 
    182181                int code = throttle << 21; 
     
    184183                code += yaw << 12; 
    185184                code += pitch << 4 ; 
    186         //  weird, if use int code= throttle << 21 + 1<<20 + yaw <<12 +pitch<<4; it won't work. 
     185                //  weird, if use int code= throttle << 21 + 1<<20 + yaw <<12 +pitch<<4; it won't work. 
    187186                code += ((channel >>> 1) & 1) << 19; 
    188187                code += (channel & 1) << 11; 
    189                  
     188 
    190189                int checkSum=0; 
    191                         for (int i=0; i<7; i++) 
    192                                 checkSum += (code >> 4*i) & 15; //15=0x0F=0b00001111 
     190                for (int i=0; i<7; i++) 
     191                        checkSum += (code >> 4*i) & 15; //15=0x0F=0b00001111 
    193192                checkSum = 16-(checkSum & 15); 
    194193                return code + checkSum; 
    195         } 
    196          
     194        } // command2code 
     195 
     196 
     197        // ################################################################ 
     198 
    197199        /**  
    198200         * Generate one complete fly command in wave form on the fly. 
     
    202204         * @return fully assembled fly command in a float array, to be written in buffer and sent out. 
    203205         */ 
    204          
     206 
    205207        public float[] code2wave(int code){ 
    206208 
     
    209211                wave = concatFloat(wave,tempWave); 
    210212                wave = concatFloat(wave,tempWave); 
    211                  
    212                  
     213 
     214 
    213215                for (int i=27; i>=0; i--)  
    214216                        wave=concatFloat(wave,waveBit[((code >>> i) & 1)]); 
    215                                  
     217 
    216218                wave=concatFloat(wave,waveLongHIGH); 
    217                  
     219 
    218220                if (ifFlip) 
    219221                        for (int i=0; i<wave.length; i++) 
    220222                                wave[i]=-wave[i]; 
    221                  
     223 
    222224                wave=concatFloat(wave,new float[4096]); 
    223                  
    224                         return wave; 
    225         } 
    226                  
     225 
     226                return wave; 
     227        } // code2wave 
     228 
     229 
     230        // ################################################################ 
     231 
    227232        /** 
    228233         * Generate the initial wave required by IR dongle. 
     
    230235         * @return 
    231236         */ 
     237 
    232238        public float[] initialWave(){ 
    233239                final double initLongHIGH=0.001-sampleTime*1; //seconds 
     
    237243                final double initShortLOW=0.00018; 
    238244                final double initPause=0.010; 
    239                  
     245 
    240246                final float[] waveInitLongHIGH=halfSineGen('u',initLongHIGH); 
    241247                final int waveInitLongZEROLength= (int)Math.floor(initLongZERO*sampleRate); 
     
    243249                final float[] waveInitShortHIGH=halfSineGen('u',initShortHIGH); 
    244250                final float[] waveInitShortLOW=halfSineGen('d',initShortLOW); 
    245                                  
     251 
    246252                final float[] waveLongHLongZERO= concatFloat(waveInitLongHIGH,new float[waveInitLongZEROLength]); 
    247253                final float[] waveMediumLShortH = concatFloat(waveInitMediumLOW,waveInitShortHIGH); 
    248254                final float[] waveShortHShortL = concatFloat(waveInitShortHIGH, waveInitShortLOW); 
    249                  
     255 
    250256                float[] initWaveOriginal = concatFloat(waveLongHLongZERO,waveLongHLongZERO); 
    251257                initWaveOriginal = concatFloat(initWaveOriginal,waveInitLongHIGH); 
    252258                initWaveOriginal = concatFloat(initWaveOriginal, waveMediumLShortH); 
    253                  
     259 
    254260                float[] initWave123 = concatFloat(initWaveOriginal,waveInitMediumLOW); 
    255261                float[] initWave456 = concatFloat(initWaveOriginal,waveInitShortLOW); 
    256                  
     262 
    257263                for (int i=0; i<4; i++){ 
    258264                        initWave123 = concatFloat(initWave123,waveShortHShortL); 
    259265                        initWave456 = concatFloat(initWave456,waveShortHShortL); 
    260266                } 
    261                  
     267 
    262268                initWave123 = concatFloat(initWave123,waveInitShortHIGH); 
    263269                initWave123 = concatFloat(initWave123,waveMediumLShortH); 
    264                  
     270 
    265271                initWave456 = concatFloat(initWave456,waveInitShortHIGH); 
    266272                initWave456 = concatFloat(initWave456,waveMediumLShortH); 
    267                  
     273 
    268274                if (ifFlip){ 
    269275                        for (int i=0; i<initWave123.length; i++) 
    270276                                initWave123[i]=-initWave123[i]; 
    271                          
     277 
    272278                        for (int i=0; i<initWave456.length; i++) 
    273279                                initWave456[i]=-initWave456[i]; 
    274280                } 
    275                  
    276                  
     281 
     282 
    277283                int initPauseInSamples=(int)Math.floor(initPause*sampleRate); 
    278284                initWave123 = concatFloat(initWave123,new float[initPauseInSamples]); 
    279285                initWave456 = concatFloat(initWave456,new float[initPauseInSamples]); 
    280                  
     286 
    281287                float[] initWave123Pattern=initWave123; 
    282288                float[] initWave456Pattern=initWave456; 
    283                  
    284                  
     289 
     290 
    285291                for (int i=0; i<2; i++){ 
    286292                        initWave123 = concatFloat(initWave123, initWave123Pattern); 
    287293                        initWave456 = concatFloat(initWave456, initWave456Pattern); 
    288294                } 
    289                  
     295 
    290296                return concatFloat(initWave123,initWave456); 
    291                  
    292         } 
    293          
     297 
     298        } // initialWave 
     299 
     300 
     301        // ################################################################ 
     302 
    294303        /**  
    295304         * Connect arbitrary number of arrays together. 
     
    299308         * @return one array that contains all the parameters in a single array. 
    300309         */ 
    301                 /* 
    302         public float[] concatFloatAll(float[] first, float[]... rest) { 
    303                 int totalLength = first.length; 
    304                 for (float[] array : rest) { 
    305                         totalLength += array.length; 
    306                 } 
    307                 float[] result= Arrays.copyOf(first, totalLength); 
    308                 int offset = first.length; 
    309                 for (float[] array : rest){ 
    310                         System.arraycopy(array, 0, result, offset, array.length); 
    311                         offset += array.length; 
    312                 } 
    313                 return result; 
    314         } 
    315         */ 
    316          
     310 
     311        //      public float[] concatFloatAll(float[] first, float[]... rest) { 
     312        //              int totalLength = first.length; 
     313        //              for (float[] array : rest) { 
     314        //                      totalLength += array.length; 
     315        //              } 
     316        //              float[] result= Arrays.copyOf(first, totalLength); 
     317        //              int offset = first.length; 
     318        //              for (float[] array : rest){ 
     319        //                      System.arraycopy(array, 0, result, offset, array.length); 
     320        //                      offset += array.length; 
     321        //              } 
     322        //              return result; 
     323        //      } // concatFloatAll 
     324 
     325 
     326        // ################################################################ 
     327 
    317328        /** 
    318329         * Connect two array together, use native system operation for max efficiency. 
     
    326337                System.arraycopy(B, 0, C, A.length, B.length); 
    327338                return C; 
    328         } 
    329          
     339        } // concatFloat 
     340 
     341 
     342        // ################################################################ 
     343 
    330344        /** 
    331345         * Generate half sine signal. 
     
    339353                double increment = Math.PI/(halfPeriod*sampleRate); 
    340354                double angle = 0; 
    341                  
     355 
    342356                if (dir == 'u') 
    343357                        for (int i =0; i<halfPeriodInSamples;i++) 
    344358                        { 
    345                         halfSine[i]=(float)Math.sin(angle); 
    346                         angle += increment; 
     359                                halfSine[i]=(float)Math.sin(angle); 
     360                                angle += increment; 
    347361                        } 
    348362                else if (dir == 'd'){ 
     
    350364                        for (int i =0; i<halfPeriodInSamples;i++) 
    351365                        { 
    352                         halfSine[i]=(float)Math.sin(angle); 
    353                         angle += increment; 
     366                                halfSine[i]=(float)Math.sin(angle); 
     367                                angle += increment; 
    354368                        } 
    355369                } 
     370 
     371                return halfSine; 
     372        } // halfSineGen 
     373         
     374         
     375        // ################################################################ 
     376 
     377        void genTone(){ 
     378 
     379                /** 
     380                 * Generate a carrier signal for communication 
     381                 * with the IR Dongle 
     382                 */ 
    356383                 
    357                 return halfSine; 
    358         } 
     384 
     385                /** Fill out the array */ 
     386                for (int i = 0; i < numSamples; ++i) { 
     387                        sample[i] = Math.sin(2 * Math.PI * i / (sampleRateTone/freqOfTone)); 
     388                } 
     389 
     390                /** 
     391                 *  Convert to 16 bit pcm sound array. 
     392                 *  The sample buffer is assumed to be normalized. 
     393                 */ 
     394                int idx = 0; 
     395                for (final double dVal : sample) { 
     396                        /** Scale to maximum amplitude */ 
     397                        final short val = (short) ((dVal * 32767)); 
     398                        /** In 16 bit wav PCM, first byte is the low order byte */ 
     399                        generatedSnd[idx++] = (byte) (val & 0x00ff); 
     400                        generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8); 
     401 
     402                } 
     403        } // genTone 
     404         
     405         
     406        // ################################################################ 
     407 
     408        void playTone(){ 
     409 
     410                /** 
     411                 * Play the generated carrier signal 
     412                 */ 
     413 
     414                final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
     415                                //                sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
     416                                sampleRateTone, AudioFormat.CHANNEL_OUT_MONO, 
     417                                //              sampleRate, AudioFormat.CHANNEL_OUT_STEREO, 
     418                                //                sampleRate, AudioFormat.CHANNEL_OUT_FRONT_RIGHT, 
     419                                //                sampleRate, AudioFormat.CHANNEL_CONFIGURATION_STEREO, 
     420                                AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, 
     421                                AudioTrack.MODE_STATIC); 
     422                audioTrack.write(generatedSnd, 0, generatedSnd.length); 
     423                audioTrack.play(); 
     424        } // playTone 
     425 
     426 
     427        // ################################################################ 
     428        // ################################################################ 
     429 
     430        private class DoBackgroundTask extends AsyncTask < Integer , Void , Integer > { 
     431                protected Integer doInBackground(Integer... command) { 
     432 
     433                        int throttle=command[0].intValue(); 
     434                        int yaw=command[1].intValue(); 
     435                        int pitch=command[2].intValue(); 
     436                        int channel=command[3].intValue(); 
     437 
     438                        int code=command2code(throttle,yaw,pitch,channel); 
     439                        float[] wave=code2wave(code);    
     440 
     441                        track.play(); 
     442 
     443                        for (int j = 0; j<4; j++) 
     444                                send(wave);              
     445 
     446                        send(initialWave()); 
     447 
     448                        for (int j = 0; j<loopNumberWhileMindControl; j++) 
     449                                send(wave);      
     450 
     451                        track.stop(); 
     452                        return 0; 
     453                } // doInBackground 
     454 
     455                //              protected void onPostexecute(Integer result) { 
     456                //                      stopSelf(); 
     457                //              } 
     458        } // DoBackgroundTask 
     459 
     460 
     461        // ################################################################ 
     462        // ################################################################ 
     463 
     464        public class OrbitBinder extends Binder { 
     465                AudioService getService() { 
     466                        return AudioService.this; 
     467                } 
     468        } // OrbitBinder 
     469 
     470 
     471        // ################################################################ 
     472        // ################################################################ 
    359473 
    360474} 
  • android/src/info/puzzlebox/orbit/OrbitActivity.java

    ra86d057 ra546cc3  
    4141import android.view.Gravity; 
    4242import android.view.View; 
     43import android.view.ViewGroup.LayoutParams; 
    4344import android.view.Window; 
    4445import android.widget.Button; 
     
    6263 
    6364public class OrbitActivity extends Activity implements SeekBar.OnSeekBarChangeListener { 
     65 
     66 
     67        /** 
     68         * Configuration 
     69         */ 
     70        boolean demoFlightMode = false; 
    6471 
    6572        /** 
     
    8996        LinearLayout layoutAudioService; 
    9097        LinearLayout layoutAdvancedOptions; 
     98        LinearLayout layoutInvertControlSignal; 
     99        View viewSpaceGenerateAudio; 
    91100 
    92101 
     
    122131        private AudioService serviceBinder; 
    123132        Intent orbitIntent; 
    124  
    125  
    126         /**  
    127          * Tone Generator 
    128          * This is used to generate a carrier signal, to be played out the right 
    129          * audio channel when the IR dongle is attached 
    130          * Reference link - http://stackoverflow.com/questions/2413426/playing-an-arbitrary-tone-with-android 
    131          */ 
    132         private final int duration = 10; // seconds 
    133         private final int sampleRate = 8000; 
    134         private final int numSamples = duration * sampleRate; 
    135         private final double sample[] = new double[numSamples]; 
    136         private final double freqOfTone = 440; // Hz 
    137  
    138         private final byte generatedSnd[] = new byte[2 * numSamples]; 
    139133 
    140134 
     
    266260                checkBoxAdvancedOptions = (CheckBox)findViewById(R.id.checkBoxAdvancedOptions); 
    267261 
    268                 checkBoxGenerateAudio = (CheckBox)findViewById(R.id.checkBoxGenerateAudio); 
    269  
    270                 checkBoxInvertControlSignal = (CheckBox)findViewById(R.id.checkBoxInvertControlSignal); 
    271  
    272262                radioGroupChannel = (RadioGroup)findViewById(R.id.radioGroupChannel); 
    273263                radioButtonChannelA = (RadioButton)findViewById(R.id.radioA); 
    274264                radioButtonChannelB = (RadioButton)findViewById(R.id.radioB); 
    275265                radioButtonChannelC = (RadioButton)findViewById(R.id.radioC);            
    276                 radioButtonChannelA.setId(1); 
    277                 radioButtonChannelB.setId(0); 
     266                radioButtonChannelA.setId(0); 
     267                radioButtonChannelB.setId(1); 
    278268                radioButtonChannelC.setId(2); 
    279                 radioGroupChannel.check(1); 
     269                radioGroupChannel.check(0); 
     270 
     271                viewSpaceGenerateAudio = (View)findViewById(R.id.viewSpaceGenerateAudio); 
     272 
     273                checkBoxGenerateAudio = (CheckBox)findViewById(R.id.checkBoxGenerateAudio); 
     274 
     275                checkBoxInvertControlSignal = (CheckBox)findViewById(R.id.checkBoxInvertControlSignal); 
     276 
    280277 
    281278                imageViewStatus = (ImageView)findViewById(R.id.imageViewStatus); 
     
    290287                layoutAudioService = (LinearLayout)findViewById(R.id.layoutAudioService); 
    291288                layoutAdvancedOptions = (LinearLayout)findViewById(R.id.layoutAdvancedOptions); 
    292  
     289                layoutInvertControlSignal = (LinearLayout)findViewById(R.id.layoutInvertControlSignal); 
    293290 
    294291 
     
    331328                 * Prepare Bluetooth and NeuroSky ThinkGear EEG interface 
    332329                 */ 
    333                  
     330 
    334331                bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
    335332 
     
    501498        public void onCheckBoxGenerateAudioClicked(View view) { 
    502499 
     500                updateAdvancedOptions(); 
     501 
    503502        } // onCheckBoxGenerateAudioClicked 
    504503 
     
    515514        public void updateAdvancedOptions() { 
    516515 
     516                LayoutParams layoutParams; 
     517 
    517518                if (checkBoxAdvancedOptions.isChecked()) { 
    518519 
    519                         layoutAudioService.setVisibility(View.VISIBLE); 
     520                        if (checkBoxGenerateAudio.isChecked()) { 
     521                                layoutAudioService.setVisibility(View.VISIBLE); 
     522                                layoutInvertControlSignal.setVisibility(View.VISIBLE); 
     523 
     524                                layoutParams = viewSpaceGenerateAudio.getLayoutParams(); 
     525                                layoutParams.width = 10; 
     526                                viewSpaceGenerateAudio.setLayoutParams(layoutParams); 
     527 
     528 
     529                        } else { 
     530                                layoutAudioService.setVisibility(View.GONE); 
     531                                layoutInvertControlSignal.setVisibility(View.GONE); 
     532 
     533                                layoutParams = viewSpaceGenerateAudio.getLayoutParams(); 
     534                                //                              layoutParams.width = LayoutParams.MATCH_PARENT; 
     535                                layoutParams.width = 120; 
     536                                viewSpaceGenerateAudio.setLayoutParams(layoutParams); 
     537 
     538                        } 
     539 
    520540                        layoutAdvancedOptions.setVisibility(View.VISIBLE); 
    521541                        tv.setVisibility(View.VISIBLE); 
     
    904924                        speed = 0; 
    905925 
     926                // If control signal is being generated, set the 
     927                // power level equal to the current throttle slider 
     928                if ((checkBoxGenerateAudio.isChecked()) && (speed > 0)){ 
     929 
     930                        speed = seekBarThrottle.getProgress(); 
     931 
     932                } 
     933 
    906934                return(speed); 
    907935 
     
    9901018        public void playControl() { 
    9911019 
    992                 /**  
    993                  * Play audio control file 
    994                  */ 
    995  
    996                 /** Getting the user sound settings */ 
    997                 //              AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE); 
    998                 //              float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 
    999                 //              float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 
    1000                 //              float volume = actualVolume / maxVolume; 
    1001                 //              /** Is the sound loaded already? */ 
    1002                 //              if (loaded) { 
    1003                 //                      soundPool.play(soundID, volume, volume, 1, 0, 1f); 
    1004                 //                      if (DEBUG) 
    1005                 //                              Log.v(TAG, "Played sound"); 
    1006                 //              } 
    1007  
    1008  
    1009                 /** 
    1010                  * Generate signal on the fly 
    1011                  */ 
    1012  
    1013                 if (serviceBinder != null) { 
    1014                         serviceBinder.ifFlip = checkBoxInvertControlSignal.isChecked(); //if checked then flip 
    1015                         int channel = radioGroupChannel.getCheckedRadioButtonId(); 
    1016                         serviceBinder.loopNumberWhileMindControl = 4615; // about 10 minutes     
    1017                         serviceBinder.channel = channel; 
    1018                         startService(new Intent (OrbitActivity.this, AudioService.class)); 
     1020                if (checkBoxGenerateAudio.isChecked()) {                 
     1021 
     1022                        /** 
     1023                         * Generate signal on the fly 
     1024                         */ 
     1025 
     1026                        if (serviceBinder != null) { 
     1027                                serviceBinder.ifFlip = checkBoxInvertControlSignal.isChecked(); // if checked then flip 
     1028                                int channel = radioGroupChannel.getCheckedRadioButtonId(); 
     1029                                if (demoFlightMode) 
     1030                                        serviceBinder.loopNumberWhileMindControl = 4500; // about 10 minutes 
     1031                                else 
     1032                                        serviceBinder.loopNumberWhileMindControl = 20;  
     1033                                serviceBinder.channel = channel; 
     1034                                startService(new Intent (OrbitActivity.this, AudioService.class)); 
     1035                        } 
     1036 
     1037 
     1038                } else { 
     1039 
     1040                        /**  
     1041                         * Play audio control file 
     1042                         */ 
     1043 
     1044                        /** Getting the user sound settings */ 
     1045                        AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE); 
     1046                        float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 
     1047                        float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 
     1048                        float volume = actualVolume / maxVolume; 
     1049                        /** Is the sound loaded already? */ 
     1050                        if (loaded) { 
     1051                                soundPool.play(soundID, volume, volume, 1, 0, 1f); 
     1052                                if (DEBUG) 
     1053                                        Log.v(TAG, "Played sound"); 
     1054                        } 
     1055 
    10191056                } 
    10201057 
     
    10251062 
    10261063        public void stopControl() { 
    1027  
    1028                 /** 
    1029                  * Stop playing audio control file 
    1030                  */ 
    1031  
    1032                 //              if (soundPool != null) { 
    1033                 //                      try { 
    1034                 //                              soundPool.stop(soundID); 
    1035                 //                      } catch (Exception e) { 
    1036                 //                              // TODO Auto-generated catch block 
    1037                 //                              e.printStackTrace(); 
    1038                 //                      } 
    1039                 //              } 
    10401064 
    10411065 
     
    10491073 
    10501074 
     1075                /** 
     1076                 * Stop playing audio control file 
     1077                 */ 
     1078 
     1079                if (soundPool != null) { 
     1080                        try { 
     1081                                soundPool.stop(soundID); 
     1082                        } catch (Exception e) { 
     1083                                // TODO Auto-generated catch block 
     1084                                e.printStackTrace(); 
     1085                        } 
     1086                } 
     1087 
     1088 
    10511089        } // stopControl 
    1052  
    1053  
    1054         // ################################################################ 
    1055  
    1056         void genTone(){ 
    1057  
    1058                 /** 
    1059                  * Generate a carrier signal for communication 
    1060                  * with the IR Dongle 
    1061                  */ 
    1062  
    1063                 /** Fill out the array */ 
    1064                 for (int i = 0; i < numSamples; ++i) { 
    1065                         sample[i] = Math.sin(2 * Math.PI * i / (sampleRate/freqOfTone)); 
    1066                 } 
    1067  
    1068                 /** 
    1069                  *  Convert to 16 bit pcm sound array. 
    1070                  *  The sample buffer is assumed to be normalized. 
    1071                  */ 
    1072                 int idx = 0; 
    1073                 for (final double dVal : sample) { 
    1074                         /** Scale to maximum amplitude */ 
    1075                         final short val = (short) ((dVal * 32767)); 
    1076                         /** In 16 bit wav PCM, first byte is the low order byte */ 
    1077                         generatedSnd[idx++] = (byte) (val & 0x00ff); 
    1078                         generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8); 
    1079  
    1080                 } 
    1081         } // genTone 
    1082  
    1083  
    1084         // ################################################################ 
    1085  
    1086         void playTone(){ 
    1087  
    1088                 /** 
    1089                  * Play the generated carrier signal 
    1090                  */ 
    1091  
    1092                 final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
    1093                                 //                sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
    1094                                 sampleRate, AudioFormat.CHANNEL_OUT_MONO, 
    1095                                 //              sampleRate, AudioFormat.CHANNEL_OUT_STEREO, 
    1096                                 //                sampleRate, AudioFormat.CHANNEL_OUT_FRONT_RIGHT, 
    1097                                 //                sampleRate, AudioFormat.CHANNEL_CONFIGURATION_STEREO, 
    1098                                 AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, 
    1099                                 AudioTrack.MODE_STATIC); 
    1100                 audioTrack.write(generatedSnd, 0, generatedSnd.length); 
    1101                 audioTrack.play(); 
    1102         } // playTone 
    11031090 
    11041091 
     
    11161103                appendTextAndScroll("Sending Test Signal to Helicopter\n"); 
    11171104 
     1105                demoFlightMode = true; 
    11181106                playControl(); 
     1107                demoFlightMode = false; 
    11191108 
    11201109                //              playTone(); 
     
    11601149 
    11611150        public void demoStop(View view) { 
    1162                 stopTest(view); 
     1151                //                      stopTest(view); 
     1152                stopControl(); 
    11631153        } // demoStop 
    11641154 
     
    11661156        // ################################################################ 
    11671157 
    1168         public void testFly(View view) { 
    1169                 if (serviceBinder != null) { 
    1170                         serviceBinder.ifFlip = checkBoxInvertControlSignal.isChecked(); // if checked then flip 
    1171                         int channel = radioGroupChannel.getCheckedRadioButtonId(); 
    1172                         serviceBinder.channel = channel; 
    1173                         serviceBinder.loopNumberWhileMindControl = 20; 
    1174                         startService(new Intent (OrbitActivity.this, AudioService.class)); 
    1175                 } 
    1176         } // testFly 
    1177  
    1178  
    1179         // ################################################################ 
    1180  
    1181         public void stopTest(View view) { 
    1182                 if (serviceBinder != null) { 
    1183                         serviceBinder.track.stop(); 
    1184                         stopService(new Intent(getBaseContext(),AudioService.class)); 
    1185                 } 
    1186         } //stopTest 
     1158        //      public void testFly(View view) { 
     1159        ////            if (serviceBinder != null) { 
     1160        ////                    serviceBinder.ifFlip = checkBoxInvertControlSignal.isChecked(); // if checked then flip 
     1161        ////                    int channel = radioGroupChannel.getCheckedRadioButtonId(); 
     1162        ////                    serviceBinder.channel = channel; 
     1163        ////                    serviceBinder.loopNumberWhileMindControl = 20; 
     1164        ////                    startService(new Intent (OrbitActivity.this, AudioService.class)); 
     1165        ////            } 
     1166        //               
     1167        //              demoMode(view); 
     1168        //               
     1169        //      } // testFly 
     1170 
     1171 
     1172        // ################################################################ 
     1173 
     1174        //      public void stopTest(View view) { 
     1175        // 
     1176        //              stopControl(); 
     1177        // 
     1178        //      } //stopTest 
    11871179 
    11881180 
Note: See TracChangeset for help on using the changeset viewer.