Changeset d604d68 in orbit


Ignore:
Timestamp:
12/19/12 13:11:34 (7 years ago)
Author:
AzureViolin <zhanghaotz@…>
Branches:
master, RawEEG, Raw_EEG_Plot, Servo, Tab_Interface, pyramid
Children:
948f49a, 66477ef
Parents:
85e0208
Message:

move code which generates audio to OrbitAudioCode?.java, write documents and cleaned up

Location:
android/src/info/puzzlebox/orbit
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • android/src/info/puzzlebox/orbit/MainActivity.java

    r85e0208 rd604d68  
    972972                manualControl(); 
    973973 
    974         } // demoMode 
    975          
    976  
    977         public static final int samplePerSecond = 44100; 
    978         final double sampleTime = 1/(double)samplePerSecond; 
    979          
    980         final double longHIGH = 0.000875-sampleTime*2;//half period HIGH of code '1', in s 
    981         final double longLOW = 0.000729+sampleTime*3; 
    982         final double shortHIGH = 0.000458-sampleTime*2; 
    983         final double shortLOW = 0.000333+sampleTime*2; 
    984          
    985         final float[] waveLongHIGH=halfSineGen('u',longHIGH,samplePerSecond); 
    986         final float[] waveLongLOW=halfSineGen('d',longLOW,samplePerSecond); 
    987         final float[] waveShortHIGH=halfSineGen('u',shortHIGH,samplePerSecond); 
    988         final float[] waveShortLOW=halfSineGen('d',shortLOW,samplePerSecond); 
    989         final float[] waveBit[]= {concatFloat(waveShortHIGH,waveShortLOW),concatFloat(waveLongHIGH,waveLongLOW)}; 
    990  
     974        } // Manual Control Mode 
    991975         
    992976        public void manualControl() { 
     
    1007991                } 
    1008992                */ 
    1009                 AndroidAudioDevice device = new AndroidAudioDevice(); 
     993                OrbitAudioCode orbit = new OrbitAudioCode(44100,false); 
    1010994 
    1011995                for (int j = 0; j<4; j++) 
    1012                         device.writeSamples(code2wave(command2code(80,78,31,'A'),samplePerSecond,false));                
     996                        orbit.send(orbit.code2wave(orbit.command2code(80,78,31,'A')));           
    1013997                 
    1014                 device.writeSamples(initialWave(samplePerSecond,false)); 
     998                orbit.send(orbit.initialWave()); 
    1015999                                 
    10161000                for (int j = 0; j<50; j++){ 
    1017                         device.writeSamples(code2wave(command2code(80,78,31,'A'),samplePerSecond,false));                
    1018                          
    1019                         /*try{ 
    1020                                 Thread.sleep(80); 
    1021                         } catch (InterruptedException e){ 
    1022                                 e.printStackTrace(); 
    1023                         }*/ 
    1024                 } 
     1001                        orbit.send(orbit.code2wave(orbit.command2code(80,78,31,'A')));           
     1002                } 
     1003                orbit.releasetrack(); 
    10251004        } 
    1026          
    1027         /** 
    1028          * command2code, turn throttle, pitch and yaw to IR code (in sound data form). 
    1029          * @param throttle: 0~127, nothing will happen if this value is below 30. 
    1030          * @param yaw: 0~127, normally 78 will keep orbit from rotating. 
    1031          * @param pitch: 0~63, normally 31 will stop the top propeller. 
    1032          * @param channel: 'A' or 'B' or 'C', depend on which channel you want to pair to the orbit. You can fly at most 3 orbit in a same room.  
    1033          * @return 
    1034          */ 
    1035          
    1036         int command2code(int throttle, int yaw, int pitch, char channel){ 
    1037                 int code = throttle << 21; 
    1038                 code += 1 << 20 ; 
    1039                 code += yaw << 12; 
    1040                 code += pitch << 4 ; 
    1041         //  weird, if use int code= throttle << 21 + 1<<20 + yaw <<12 +pitch<<4; it won't work. 
    1042                 switch (channel){ 
    1043                         case 'A':       code += 1 << 11; 
    1044                                                 break; 
    1045                 //      case 'B':       break; 
    1046                         case 'C':       code += 1 << 19; 
    1047                                                 break; 
    1048                         default:        break; 
    1049                 } 
    1050                 int checkSum=0; 
    1051                         for (int i=0; i<7; i++) 
    1052                                 checkSum += (code >> 4*i) & 15; //15=0x0F=0b00001111 
    1053                 checkSum = 16-(checkSum & 15); 
    1054                 return code + checkSum; 
    1055         } 
    1056          
    1057         /** code2wave(,,) 
    1058          * generate 1 full fly command in wave form on the fly. 
    1059          * @param code: the control code array need to be turned into  
    1060          * @param sampleRate: sample rate supported on certain Android device, normally 44100, but on some device it is 48000. 
    1061          * @param flip: on certain Android device, the signal need to be flipped. true means flip, false means not. 
    1062          * @return fully assembled fly command in a float array, to be written in buffer and sent out. 
    1063          */ 
    1064          
    1065         float[] code2wave(int code, int sampleRate, boolean flip){ 
    1066  
    1067                 //float[] wave = concatFloat(concatFloat(waveLongLOW,concatFloat(waveLongHIGH,waveShortLOW)),concatFloat(waveLongHIGH,waveShortLOW)); 
    1068                 /* 
    1069                 final double longHIGH = 0.000875-sampleTime*2;//half period HIGH of code '1', in s 
    1070                 final double longLOW = 0.000729+sampleTime*5; 
    1071                 final double shortHIGH = 0.000458-sampleTime*3; 
    1072                 final double shortLOW = 0.000333+sampleTime*3; 
    1073                 */ 
    1074                 float[] wave = halfSineGen('d',longLOW,sampleRate); 
    1075                 float[] tempWave = concatFloat(halfSineGen('u',longHIGH-sampleTime*2,sampleRate),halfSineGen('d',shortLOW+sampleTime*2,sampleRate)); 
    1076                 wave = concatFloat(wave,tempWave); 
    1077                 wave = concatFloat(wave,tempWave); 
    1078                 /*int waveLength = waveLongLOW.length+(waveLongHIGH.length+waveShortLOW.length)*2; 
    1079                          
    1080                 byte sum=0; 
    1081                 for (int i=0; i<28; i++){ 
    1082                         sum += (code >>> i) & 1) 
    1083                 } 
    1084                 waveLength+=sum*(waveLongHIGH.length+waveLongLOW.length)+(28-sum)*(waveShortHIGH.length+waveShortLOW.length); 
    1085                 waveLength+=waveLongHIGH.length; 
    1086                  
    1087                 float[] wave=new float[waveLength]; 
    1088                 */ 
    1089                  
    1090                 for (int i=27; i>=0; i--)  
    1091                         wave=concatFloat(wave,waveBit[((code >>> i) & 1)]); 
    1092                                  
    1093                 wave=concatFloat(wave,waveLongHIGH); 
    1094                 //float[] zeroArray= new float[1024]; 
    1095                  
    1096                 if (flip) 
    1097                         for (int i=0; i<wave.length; i++) 
    1098                                 wave[i]=-wave[i]; 
    1099                  
    1100                 wave=concatFloat(wave,new float[4096]); 
    1101                  
    1102                         return wave; 
    1103         } 
    1104          
    1105         /* 
    1106         float[] zerosFloat(int num){ 
    1107                 return  new float[num]; 
    1108         } 
    1109         */ 
    1110          
    1111         /* 
    1112         float[] bitGen(short bit, int sampleRate){ 
    1113  
    1114                 if (bit == 0)  
    1115                         return concatFloat(waveShortHIGH,waveShortLOW); 
    1116                 else  
    1117                         return concatFloat(waveLongHIGH,waveLongLOW); 
    1118         } 
    1119 */ 
    1120          
    1121         float[] initialWave(int sampleRate, boolean flip){ 
    1122                 final double initLongHIGH=0.001-sampleTime*1; //seconds 
    1123                 final double initLongZERO=0.002+sampleTime*1; 
    1124                 final double initMediumLOW=0.0005-sampleTime*1; 
    1125                 final double initShortHIGH=0.0001+sampleTime*1; 
    1126                 final double initShortLOW=0.00018; 
    1127                 final double initPause=0.010; 
    1128                 final double initSpace=0.084354; 
    1129                  
    1130                 final float[] waveInitLongHIGH=halfSineGen('u',initLongHIGH,sampleRate); 
    1131                 final int waveInitLongZEROLength= (int)Math.floor(initLongZERO*sampleRate); 
    1132                 final float[] waveInitMediumLOW=halfSineGen('d',initMediumLOW,sampleRate); 
    1133                 final float[] waveInitShortHIGH=halfSineGen('u',initShortHIGH,sampleRate); 
    1134                 final float[] waveInitShortLOW=halfSineGen('d',initShortLOW,sampleRate); 
    1135                                  
    1136                 final float[] waveLongHLongZERO= concatFloat(waveInitLongHIGH,new float[waveInitLongZEROLength]); 
    1137                 final float[] waveMediumLShortH = concatFloat(waveInitMediumLOW,waveInitShortHIGH); 
    1138                 final float[] waveShortHShortL = concatFloat(waveInitShortHIGH, waveInitShortLOW); 
    1139                  
    1140                 float[] initWaveOriginal = concatFloat(waveLongHLongZERO,waveLongHLongZERO); 
    1141                 initWaveOriginal = concatFloat(initWaveOriginal,waveInitLongHIGH); 
    1142                 initWaveOriginal = concatFloat(initWaveOriginal, waveMediumLShortH); 
    1143                  
    1144                 float[] initWave123 = concatFloat(initWaveOriginal,waveInitMediumLOW); 
    1145                 float[] initWave456 = concatFloat(initWaveOriginal,waveInitShortLOW); 
    1146                  
    1147                 for (int i=0; i<4; i++){ 
    1148                         initWave123 = concatFloat(initWave123,waveShortHShortL); 
    1149                         initWave456 = concatFloat(initWave456,waveShortHShortL); 
    1150                 } 
    1151                  
    1152                 initWave123 = concatFloat(initWave123,waveInitShortHIGH); 
    1153                 initWave123 = concatFloat(initWave123,waveMediumLShortH); 
    1154                  
    1155                 initWave456 = concatFloat(initWave456,waveInitShortHIGH); 
    1156                 initWave456 = concatFloat(initWave456,waveMediumLShortH); 
    1157                  
    1158                 if (flip){ 
    1159                         for (int i=0; i<initWave123.length; i++) 
    1160                                 initWave123[i]=-initWave123[i]; 
    1161                          
    1162                         for (int i=0; i<initWave456.length; i++) 
    1163                                 initWave456[i]=-initWave456[i]; 
    1164                 } 
    1165                  
    1166                  
    1167                 int initPauseInSamples=(int)Math.floor(initPause*sampleRate); 
    1168                 initWave123 = concatFloat(initWave123,new float[initPauseInSamples]); 
    1169                 initWave456 = concatFloat(initWave456,new float[initPauseInSamples]); 
    1170                  
    1171                 float[] initWave123Pattern=initWave123; 
    1172                 float[] initWave456Pattern=initWave456; 
    1173                  
    1174                  
    1175                 for (int i=0; i<2; i++){ 
    1176                         initWave123 = concatFloat(initWave123, initWave123Pattern); 
    1177                         initWave456 = concatFloat(initWave456, initWave456Pattern); 
    1178                 } 
    1179                  
    1180                 return concatFloat(initWave123,initWave456); 
    1181                  
    1182         } 
    1183          
    1184         /** concatFloatAll 
    1185          * since Arrays.copyOf is added in API level 9, 
    1186          * so this not compatible with API level < 9, or known as Android 2.3    *  
    1187          * @param arbitrary numbers of arrays that you want to connect together  
    1188          * @return one array that contains all the parameters in a single array. 
    1189          */ 
    1190          
    1191         /* 
    1192         public float[] concatFloatAll(float[] first, float[]... rest) { 
    1193                 int totalLength = first.length; 
    1194                 for (float[] array : rest) { 
    1195                         totalLength += array.length; 
    1196                 } 
    1197                 float[] result= Arrays.copyOf(first, totalLength); 
    1198                 int offset = first.length; 
    1199                 for (float[] array : rest){ 
    1200                         System.arraycopy(array, 0, result, offset, array.length); 
    1201                         offset += array.length; 
    1202                 } 
    1203                 return result; 
    1204         } 
    1205         */ 
    1206          
    1207         public float[] concatFloat(float[] A, float[] B){ 
    1208                 float[] C = new float[A.length+B.length]; 
    1209                 System.arraycopy(A, 0, C, 0, A.length); 
    1210                 System.arraycopy(B, 0, C, A.length, B.length); 
    1211                 return C; 
    1212         } 
    1213          
    1214         float[] halfSineGen(char dir,double halfPeriod, int sampleRate) { 
    1215                 int halfPeriodInSamples = (int)Math.floor(halfPeriod*sampleRate); 
    1216                 float halfSine[] = new float[halfPeriodInSamples]; 
    1217                 double increment = Math.PI/(halfPeriod*sampleRate); 
    1218                 double angle = 0; 
    1219                  
    1220                 if (dir == 'u') 
    1221                         for (int i =0; i<halfPeriodInSamples;i++) 
    1222                         { 
    1223                         halfSine[i]=(float)Math.sin(angle); 
    1224                         angle += increment; 
    1225                         } 
    1226                 else if (dir == 'd'){ 
    1227                         angle = Math.PI; 
    1228                         for (int i =0; i<halfPeriodInSamples;i++) 
    1229                         { 
    1230                         halfSine[i]=(float)Math.sin(angle); 
    1231                         angle += increment; 
    1232                         } 
    1233                 } 
    1234                  
    1235                 return halfSine; 
    1236         } 
     1005 
    12371006 
    12381007} // MainActivity 
    12391008 
    1240  
    1241 class AndroidAudioDevice { 
    1242         AudioTrack track; 
    1243         short[] buffer = new short[6144]; 
    1244          
    1245         public AndroidAudioDevice() 
    1246         { 
    1247                 int minSize = AudioTrack.getMinBufferSize( 44100, AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT); 
    1248                 track = new AudioTrack(AudioManager.STREAM_MUSIC,44100,AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT,minSize, AudioTrack.MODE_STREAM); 
    1249                 track.play(); 
    1250         } 
    1251          
    1252         public void writeSamples(float[] samples) 
    1253         { 
    1254                 fillBuffer(samples); 
    1255                 track.write(buffer,0,2*samples.length); 
    1256         } 
    1257          
    1258         private void fillBuffer(float[] samples) 
    1259         { 
    1260                 if(buffer.length < 2*samples.length) 
    1261                         buffer=new short[2*samples.length]; 
    1262                  
    1263                 float increment = (float)((2*Math.PI)*500/MainActivity.samplePerSecond); 
    1264                 float angle = 0; 
    1265                  
    1266                 for (int i=0; i< samples.length; i++){ 
    1267                         buffer[2*i+1]=(short)(Math.sin(angle)*Short.MAX_VALUE); 
    1268                         buffer[2*i]=(short)(samples[i]*Short.MAX_VALUE); 
    1269                         angle += increment; 
    1270                 } 
    1271         } 
    1272         public void releasetrack(){ 
    1273                 track.release(); 
    1274         } 
    1275 } 
Note: See TracChangeset for help on using the changeset viewer.