9
9
import android .graphics .drawable .Drawable ;
10
10
import android .location .Location ;
11
11
import android .location .LocationManager ;
12
+ import android .media .AudioDeviceInfo ;
12
13
import android .media .AudioFormat ;
13
14
import android .media .AudioManager ;
14
15
import android .media .AudioTrack ;
@@ -140,6 +141,8 @@ public class WaveGeneratorActivity extends AppCompatActivity {
140
141
Button btnAnalogMode ;
141
142
@ BindView (R .id .digital_mode_btn )
142
143
Button btnDigitalMode ;
144
+ @ BindView (R .id .use_phone_btn )
145
+ Button btnUsePhone ;
143
146
@ BindView (R .id .pwm_btn_freq )
144
147
Button pwmBtnFreq ;
145
148
@ BindView (R .id .pwm_btn_duty )
@@ -187,7 +190,9 @@ public class WaveGeneratorActivity extends AppCompatActivity {
187
190
private RelativeLayout squareModeControls ;
188
191
private LineChart previewChart ;
189
192
private boolean isPlayingSound = false ;
193
+ private boolean usePhone = false ;
190
194
private ProduceSoundTask produceSoundTask ;
195
+ private GenerateWavesFromPhoneTask generateWavesFromPhoneTask ;
191
196
192
197
@ SuppressLint ("ClickableViewAccessibility" )
193
198
@ Override
@@ -334,6 +339,24 @@ public void onClick(View v) {
334
339
}
335
340
});
336
341
342
+ btnUsePhone .setOnClickListener (new View .OnClickListener () {
343
+ @ Override
344
+ public void onClick (View v ) {
345
+ usePhone = !usePhone ;
346
+ if (usePhone ) {
347
+ if (isPlayingSound ) {
348
+ btnProduceSound .callOnClick ();
349
+ }
350
+ btnUsePhone .setText (R .string .text_use_pslab );
351
+ generateWavesFromPhoneTask = new GenerateWavesFromPhoneTask (WaveGeneratorActivity .this );
352
+ generateWavesFromPhoneTask .execute ();
353
+ } else {
354
+ btnUsePhone .setText (R .string .text_use_phone );
355
+ generateWavesFromPhoneTask .cancel (true );
356
+ }
357
+ }
358
+ });
359
+
337
360
btnPwmSq1 .setOnClickListener (new View .OnClickListener () {
338
361
@ Override
339
362
public void onClick (View view ) {
@@ -1282,6 +1305,42 @@ public void recordSensorData(RealmObject sensorData) {
1282
1305
realm .commitTransaction ();
1283
1306
}
1284
1307
1308
+ /**
1309
+ * Samples a wave into an AudioTrack instance. Useful for either playing sound or pushing the signal
1310
+ * through the headphone jack.
1311
+ *
1312
+ */
1313
+ public void sampleWaveIntoAudioTrack (AudioTrack track , int sampleRateInHz , int bufferLength , AsyncTask asyncTask ) {
1314
+ assert (track != null );
1315
+
1316
+ short [] buffer = new short [bufferLength ];
1317
+ float angle = 0 ;
1318
+ float samples [] = new float [bufferLength ];
1319
+ double frequency ;
1320
+
1321
+ while (!asyncTask .isCancelled ()) {
1322
+ if (WaveGeneratorCommon .mode_selected == WaveConst .SQUARE ) {
1323
+ frequency = WaveGeneratorCommon .wave .get (waveBtnActive ).get (WaveConst .FREQUENCY );
1324
+ } else {
1325
+ frequency = WaveGeneratorCommon .wave .get (WaveConst .SQR1 ).get (WaveConst .FREQUENCY );
1326
+ }
1327
+ float increment = (float ) ((2 * Math .PI ) * frequency / sampleRateInHz );
1328
+ for (int i = 0 ; i < samples .length ; i ++) {
1329
+ samples [i ] = (float ) Math .sin (angle );
1330
+ if (WaveGeneratorCommon .mode_selected == WaveConst .PWM ) {
1331
+ samples [i ] = (samples [i ] >= 0.0 ) ? 1 : -1 ;
1332
+ } else {
1333
+ if (WaveGeneratorCommon .wave .get (waveBtnActive ).get (WaveConst .WAVETYPE ) == 2 ) {
1334
+ samples [i ] = (float ) ((2 / Math .PI ) * Math .asin (samples [i ]));
1335
+ }
1336
+ }
1337
+ buffer [i ] = (short ) (samples [i ] * Short .MAX_VALUE );
1338
+ angle += increment ;
1339
+ }
1340
+ track .write (buffer , 0 , buffer .length );
1341
+ }
1342
+ }
1343
+
1285
1344
public enum WaveConst {WAVETYPE , WAVE1 , WAVE2 , SQR1 , SQR2 , SQR3 , SQR4 , FREQUENCY , PHASE , DUTY , SQUARE , PWM }
1286
1345
1287
1346
public enum WaveData {
@@ -1300,47 +1359,66 @@ public final int getValue() {
1300
1359
1301
1360
private class ProduceSoundTask extends AsyncTask <Void , Void , Void > {
1302
1361
1303
- private AudioTrack track ;
1362
+ final int sampleRateInHz = 44100 ;
1363
+ final int bufferLength = 1024 ;
1364
+ private AudioTrack track = new AudioTrack (AudioManager .STREAM_MUSIC , sampleRateInHz , AudioFormat .CHANNEL_CONFIGURATION_MONO , AudioFormat .ENCODING_PCM_16BIT , bufferLength , AudioTrack .MODE_STREAM );
1304
1365
1305
1366
@ Override
1306
1367
protected Void doInBackground (Void ... voids ) {
1307
- short [] buffer = new short [1024 ];
1308
- track = new AudioTrack (AudioManager .STREAM_MUSIC , 44100 , AudioFormat .CHANNEL_CONFIGURATION_MONO , AudioFormat .ENCODING_PCM_16BIT , buffer .length , AudioTrack .MODE_STREAM );
1309
- float angle = 0 ;
1310
- float samples [] = new float [1024 ];
1311
-
1312
1368
track .play ();
1313
- double frequency ;
1314
- while (isPlayingSound ) {
1315
- if (WaveGeneratorCommon .mode_selected == WaveConst .SQUARE ) {
1316
- frequency = WaveGeneratorCommon .wave .get (waveBtnActive ).get (WaveConst .FREQUENCY );
1317
- } else {
1318
- frequency = WaveGeneratorCommon .wave .get (WaveConst .SQR1 ).get (WaveConst .FREQUENCY );
1319
- }
1320
- float increment = (float ) ((2 * Math .PI ) * frequency / 44100 );
1321
- for (int i = 0 ; i < samples .length ; i ++) {
1322
- samples [i ] = (float ) Math .sin (angle );
1323
- if (WaveGeneratorCommon .mode_selected == WaveConst .PWM ) {
1324
- samples [i ] = (samples [i ] >= 0.0 ) ? 1 : -1 ;
1325
- } else {
1326
- if (WaveGeneratorCommon .wave .get (waveBtnActive ).get (WaveConst .WAVETYPE ) == 2 ) {
1327
- samples [i ] = (float ) ((2 / Math .PI ) * Math .asin (samples [i ]));
1328
- }
1329
- }
1330
- buffer [i ] = (short ) (samples [i ] * Short .MAX_VALUE );
1331
- angle += increment ;
1332
- }
1333
- track .write (buffer , 0 , buffer .length );
1334
- }
1369
+ sampleWaveIntoAudioTrack (track , sampleRateInHz , bufferLength , this );
1370
+ track .flush ();
1371
+ track .stop ();
1372
+ track .release ();
1335
1373
return null ;
1336
1374
}
1375
+ }
1376
+
1377
+ private class GenerateWavesFromPhoneTask extends AsyncTask <Void , Void , Void > {
1378
+
1379
+ WaveGeneratorActivity activity = null ;
1380
+ final int sampleRateInHz = 44100 ;
1381
+ final int bufferLength = 1024 ;
1382
+ private AudioTrack track = new AudioTrack (AudioManager .STREAM_MUSIC , sampleRateInHz , AudioFormat .CHANNEL_CONFIGURATION_MONO , AudioFormat .ENCODING_PCM_16BIT , bufferLength , AudioTrack .MODE_STREAM );
1383
+
1384
+ public GenerateWavesFromPhoneTask (WaveGeneratorActivity activity ) {
1385
+ this .activity = activity ;
1386
+ }
1337
1387
1338
1388
@ Override
1339
- protected void onCancelled () {
1340
- super .onCancelled ();
1389
+ protected Void doInBackground (Void ... voids ) {
1390
+ boolean wired = false ;
1391
+ AudioManager audioManager = (AudioManager )getSystemService (Context .AUDIO_SERVICE );
1392
+ AudioDeviceInfo [] audioDevices = audioManager .getDevices (AudioManager .GET_DEVICES_ALL );
1393
+ for (AudioDeviceInfo deviceInfo : audioDevices ){
1394
+ if (deviceInfo .getType ()==AudioDeviceInfo .TYPE_WIRED_HEADPHONES
1395
+ || deviceInfo .getType ()==AudioDeviceInfo .TYPE_WIRED_HEADSET ){
1396
+ wired = true ;
1397
+ break ;
1398
+ }
1399
+ }
1400
+ if (!wired ) {
1401
+ activity .runOnUiThread (new Runnable () {
1402
+ @ Override
1403
+ public void run () {
1404
+ Toast .makeText (getApplicationContext (), R .string .text_not_wired ,Toast .LENGTH_SHORT ).show ();
1405
+ }
1406
+ });
1407
+ return null ;
1408
+ }
1409
+ track .play ();
1410
+ sampleWaveIntoAudioTrack (track , sampleRateInHz , bufferLength , this );
1341
1411
track .flush ();
1342
1412
track .stop ();
1343
1413
track .release ();
1414
+ return null ;
1415
+ }
1416
+
1417
+ @ Override
1418
+ protected void onPostExecute (Void aVoid ) {
1419
+ super .onPostExecute (aVoid );
1420
+ activity .usePhone = false ;
1421
+ activity .btnUsePhone .setText (R .string .text_use_phone );
1344
1422
}
1345
1423
}
1346
1424
}
0 commit comments