123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- package com.example.greenwatch.sensors;
-
- import android.media.AudioFormat;
- import android.media.AudioRecord;
- import android.media.MediaRecorder;
- import android.os.AsyncTask;
-
- import androidx.lifecycle.MutableLiveData;
-
- import com.example.greenwatch.sensors.MicrofonHelperClasses.GleitenderMittelwert;
- import com.example.greenwatch.sensors.MicrofonHelperClasses.RingPuffer;
- import com.example.greenwatch.sensors.MicrofonHelperClasses.Verarbeitungsergebnis;
-
- public class MicrofonSensor {
-
- private MutableLiveData<Boolean> mMicrofonAlarmDetected = new MutableLiveData<>();
- private AufnahmeTask aufnahmeTask;
- private static MicrofonSensor microfonSensorInstance;
- private boolean microfonAlarmDetected = false;
- private boolean kalibrierung_do = true;
- private float threshold = 40;
- private float sensitivity = 10;
-
- private float amplitudeInDB = 0;
-
- private RingPuffer ringPuffer = new RingPuffer(10);
-
- private MicrofonSensor() {
- }
-
- public static synchronized MicrofonSensor getInstance() {
- if (microfonSensorInstance == null){
- microfonSensorInstance = new MicrofonSensor();
- }
- return microfonSensorInstance;
- }
-
- public void start() {
- aufnahmeTask = new AufnahmeTask();
- aufnahmeTask.execute();
- }
-
- public void stop() {
- if(aufnahmeTask !=null) {
- aufnahmeTask.cancel(true);
- aufnahmeTask = null;
- }
- }
-
- public void doRecalibration() {
- stop();
- microfonAlarmDetected = false;
- kalibrierung_do = true;
- threshold = 40;
- sensitivity = 10;
- amplitudeInDB = 0;
- }
-
- public float getAmplitudeInDB() {
- return amplitudeInDB;
- }
-
- private void setAmplitudeInDB(float amplitudeInDB) {
- this.amplitudeInDB = amplitudeInDB;
- }
-
- public MutableLiveData<Boolean> getAccelerometerAlarmDetected() {
- setMutableLiveDataMicrofonAlarmDetected();
- return mMicrofonAlarmDetected;
- }
-
- private void setMutableLiveDataMicrofonAlarmDetected() {
- mMicrofonAlarmDetected.setValue(microfonAlarmDetected);
- }
-
- class AufnahmeTask extends AsyncTask<Long, Verarbeitungsergebnis, Void> {
- private AudioRecord recorder;
- private final int sampleRateInHz = 44100;
- private final int channelConfig = AudioFormat.CHANNEL_IN_MONO;
- private final int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
- private int minPufferGroesseInBytes;
- private int pufferGroesseInBytes;
- public AufnahmeTask() {
- minPufferGroesseInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
- pufferGroesseInBytes = minPufferGroesseInBytes * 2;
- recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig, audioFormat, pufferGroesseInBytes);
- }
- public float kalibrieren(short[] puffer){
- try {
- Thread.sleep(3000);
-
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- int anzahlIterationen = 100;
- float sum = 0.0f;
- for(int i = 0; i < anzahlIterationen; i++){
- int z = recorder.read(puffer, 0, puffer.length);
- Verarbeitungsergebnis kalibrierung = verarbeiten(puffer, z);
- sum += kalibrierung.getDB();
- }
- return sum/anzahlIterationen;
- }
-
- public void Detektion(Verarbeitungsergebnis ergebnis){
- if(ergebnis.getDB() >= (threshold+sensitivity)){
- microfonAlarmDetected = true;
- }
- else if (ergebnis.getDB() <= (threshold)) {
- microfonAlarmDetected = false;
- }
- }
-
- @Override
- protected Void doInBackground(Long... params) {
-
- recorder.startRecording();
- short[] puffer = new short[pufferGroesseInBytes / 2];
- GleitenderMittelwert gleitenderMittelwertdB = new GleitenderMittelwert(0.2f);
- float db = 0.0f;
-
- //kalibrierung
- if(kalibrierung_do){
- threshold = kalibrieren(puffer);
- kalibrierung_do = false;
- }
-
-
- for (; ; ) {
- if (isCancelled()) {
- break;
- }
- else {
- //ergebnis ermitteln
- int n = recorder.read(puffer, 0, puffer.length);
- Verarbeitungsergebnis ergebnis = verarbeiten(puffer, n);
-
- //Mittelwertberechnnung
- db = ergebnis.getDB();
- db = gleitenderMittelwertdB.mittel(db);
- ergebnis.setDB(db);
-
- //Db Wert mit Schwellwert vergleichen und Warnung setzen
- Detektion(ergebnis);
- publishProgress(ergebnis);
-
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- recorder.release();
- return null;
- }
-
- private Verarbeitungsergebnis verarbeiten(short[] daten, int n) {
- String status;
- short maxAmp = -1;
- int db = 0, db_wert = 0;
-
- if (n == AudioRecord.ERROR_INVALID_OPERATION) {
- status = "ERROR_INVALID_OPERATION";
- } else if (n == AudioRecord.ERROR_BAD_VALUE) {
- status = "ERROR_BAD_VALUE";
- } else {
- status = "OK";
- short max = 0;
- for (int i = 0; i < n; i++) {
- if (daten[i] > max) {
- max = daten[i];
- }
- }
- ringPuffer.hinzufuegen(max);
- maxAmp = ringPuffer.maximum();
- }
- //Umwandlung Amplitudenwert in dB
- db_wert = (int) (20*Math.log10(maxAmp));
- if (db_wert > 0){
- db = db_wert;
- }
-
-
- return new Verarbeitungsergebnis(status, maxAmp, db);
- }
- @Override
- protected void onProgressUpdate(Verarbeitungsergebnis... progress) {
- super.onProgressUpdate(progress);
-
- setAmplitudeInDB(progress[0].getDB());
-
- if (microfonAlarmDetected != mMicrofonAlarmDetected.getValue()){
- setMutableLiveDataMicrofonAlarmDetected();
- }
- //textViewMaxAmpdb.setText("" + progress[0].db);
- }
-
- }
- }
|