Skip to content

Commit 04ddfa7

Browse files
committed
WIP
Signed-off-by: Daniel W. S. Almeida <[email protected]>
1 parent 1308834 commit 04ddfa7

File tree

3 files changed

+128
-31
lines changed

3 files changed

+128
-31
lines changed

app/src/main/java/io/pslab/activity/WaveGeneratorActivity.java

+108-30
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import android.graphics.drawable.Drawable;
1010
import android.location.Location;
1111
import android.location.LocationManager;
12+
import android.media.AudioDeviceInfo;
1213
import android.media.AudioFormat;
1314
import android.media.AudioManager;
1415
import android.media.AudioTrack;
@@ -140,6 +141,8 @@ public class WaveGeneratorActivity extends AppCompatActivity {
140141
Button btnAnalogMode;
141142
@BindView(R.id.digital_mode_btn)
142143
Button btnDigitalMode;
144+
@BindView(R.id.use_phone_btn)
145+
Button btnUsePhone;
143146
@BindView(R.id.pwm_btn_freq)
144147
Button pwmBtnFreq;
145148
@BindView(R.id.pwm_btn_duty)
@@ -187,7 +190,9 @@ public class WaveGeneratorActivity extends AppCompatActivity {
187190
private RelativeLayout squareModeControls;
188191
private LineChart previewChart;
189192
private boolean isPlayingSound = false;
193+
private boolean usePhone = false;
190194
private ProduceSoundTask produceSoundTask;
195+
private GenerateWavesFromPhoneTask generateWavesFromPhoneTask;
191196

192197
@SuppressLint("ClickableViewAccessibility")
193198
@Override
@@ -334,6 +339,24 @@ public void onClick(View v) {
334339
}
335340
});
336341

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+
337360
btnPwmSq1.setOnClickListener(new View.OnClickListener() {
338361
@Override
339362
public void onClick(View view) {
@@ -1282,6 +1305,42 @@ public void recordSensorData(RealmObject sensorData) {
12821305
realm.commitTransaction();
12831306
}
12841307

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+
12851344
public enum WaveConst {WAVETYPE, WAVE1, WAVE2, SQR1, SQR2, SQR3, SQR4, FREQUENCY, PHASE, DUTY, SQUARE, PWM}
12861345

12871346
public enum WaveData {
@@ -1300,47 +1359,66 @@ public final int getValue() {
13001359

13011360
private class ProduceSoundTask extends AsyncTask<Void, Void, Void> {
13021361

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);
13041365

13051366
@Override
13061367
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-
13121368
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();
13351373
return null;
13361374
}
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+
}
13371387

13381388
@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);
13411411
track.flush();
13421412
track.stop();
13431413
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);
13441422
}
13451423
}
13461424
}

app/src/main/res/layout/wave_generator_main_controls.xml

+17
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,21 @@
5151
android:textAllCaps="false"
5252
android:textColor="@color/white"
5353
android:textSize="@dimen/wave_gen_control_text_size" />
54+
55+
<Button
56+
android:id="@+id/use_phone_btn"
57+
android:layout_width="match_parent"
58+
android:layout_height="match_parent"
59+
android:layout_marginStart="@dimen/margin_btn"
60+
android:layout_marginTop="@dimen/margin_btn"
61+
android:layout_marginEnd="@dimen/margin_btn"
62+
android:layout_marginBottom="@dimen/margin_btn"
63+
android:layout_weight="1"
64+
android:background="@drawable/btn_back_rounded"
65+
android:minWidth="@dimen/btn_min_width"
66+
android:stateListAnimator="@animator/selector_animator"
67+
android:text="@string/text_use_phone"
68+
android:textAllCaps="false"
69+
android:textColor="@color/white"
70+
android:textSize="@dimen/wave_gen_control_text_size" />
5471
</LinearLayout>

app/src/main/res/values/strings.xml

+3-1
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,9 @@
695695
<string name="duty_cycle">Duty Cycle:</string>
696696
<string name="mode">Mode</string>
697697
<string name="text_digital">Digital</string>
698-
698+
<string name="text_use_phone">Use Phone</string>
699+
<string name="text_use_pslab">Use PSLab</string>
700+
<string name="text_not_wired">Nothing plugged in the headphone jack</string>
699701
<string name="text_connected">Connected</string>
700702
<string name="text_disconnected">Disconnected</string>
701703

0 commit comments

Comments
 (0)