|
9 | 9 | import android.graphics.drawable.Drawable;
|
10 | 10 | import android.location.Location;
|
11 | 11 | import android.location.LocationManager;
|
| 12 | +import android.media.AudioFormat; |
| 13 | +import android.media.AudioManager; |
| 14 | +import android.media.AudioTrack; |
| 15 | +import android.os.AsyncTask; |
12 | 16 | import android.os.Bundle;
|
13 | 17 | import android.os.Handler;
|
14 | 18 | import android.support.annotation.NonNull;
|
@@ -182,6 +186,8 @@ public class WaveGeneratorActivity extends AppCompatActivity {
|
182 | 186 | private RelativeLayout pwmModeControls;
|
183 | 187 | private RelativeLayout squareModeControls;
|
184 | 188 | private LineChart previewChart;
|
| 189 | + private boolean isPlayingSound = false; |
| 190 | + private ProduceSoundTask produceSoundTask; |
185 | 191 |
|
186 | 192 | @SuppressLint("ClickableViewAccessibility")
|
187 | 193 | @Override
|
@@ -459,6 +465,23 @@ public void onStopTrackingTouch(IndicatorSeekBar seekBar) {
|
459 | 465 | setReceivedData();
|
460 | 466 | }
|
461 | 467 | chartInit();
|
| 468 | + |
| 469 | + btnProduceSound.setOnClickListener(new View.OnClickListener() { |
| 470 | + @Override |
| 471 | + public void onClick(View v) { |
| 472 | + if (isPlayingSound) { |
| 473 | + btnProduceSound.setText(getResources().getString(R.string.produce_sound_text)); |
| 474 | + produceSoundTask.cancel(true); |
| 475 | + produceSoundTask = null; |
| 476 | + isPlayingSound = false; |
| 477 | + } else { |
| 478 | + btnProduceSound.setText(getResources().getString(R.string.stop_sound_text)); |
| 479 | + produceSoundTask = new ProduceSoundTask(); |
| 480 | + produceSoundTask.execute(); |
| 481 | + isPlayingSound = true; |
| 482 | + } |
| 483 | + } |
| 484 | + }); |
462 | 485 | }
|
463 | 486 |
|
464 | 487 | public void saveWaveConfig() {
|
@@ -1274,4 +1297,50 @@ public final int getValue() {
|
1274 | 1297 | return value;
|
1275 | 1298 | }
|
1276 | 1299 | }
|
| 1300 | + |
| 1301 | + private class ProduceSoundTask extends AsyncTask<Void, Void, Void> { |
| 1302 | + |
| 1303 | + private AudioTrack track; |
| 1304 | + |
| 1305 | + @Override |
| 1306 | + 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 | + 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 | + } |
| 1335 | + return null; |
| 1336 | + } |
| 1337 | + |
| 1338 | + @Override |
| 1339 | + protected void onCancelled() { |
| 1340 | + super.onCancelled(); |
| 1341 | + track.flush(); |
| 1342 | + track.stop(); |
| 1343 | + track.release(); |
| 1344 | + } |
| 1345 | + } |
1277 | 1346 | }
|
0 commit comments