You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MicrofonSensor.java 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. package com.example.greenwatch.sensors;
  2. import android.media.AudioFormat;
  3. import android.media.AudioRecord;
  4. import android.media.MediaRecorder;
  5. import android.os.AsyncTask;
  6. import androidx.lifecycle.MutableLiveData;
  7. import com.example.greenwatch.sensors.MicrofonHelperClasses.GleitenderMittelwert;
  8. import com.example.greenwatch.sensors.MicrofonHelperClasses.RingPuffer;
  9. import com.example.greenwatch.sensors.MicrofonHelperClasses.Verarbeitungsergebnis;
  10. public class MicrofonSensor {
  11. private MutableLiveData<Boolean> mMicrofonAlarmDetected = new MutableLiveData<>();
  12. private AufnahmeTask aufnahmeTask;
  13. private static MicrofonSensor microfonSensorInstance;
  14. private boolean microfonAlarmDetected = false;
  15. private boolean kalibrierung_do = true;
  16. private float threshold = 40;
  17. private float sensitivity = 10;
  18. private float amplitudeInDB = 0;
  19. private RingPuffer ringPuffer = new RingPuffer(10);
  20. private MicrofonSensor() {
  21. }
  22. public static synchronized MicrofonSensor getInstance() {
  23. if (microfonSensorInstance == null){
  24. microfonSensorInstance = new MicrofonSensor();
  25. }
  26. return microfonSensorInstance;
  27. }
  28. public void start() {
  29. aufnahmeTask = new AufnahmeTask();
  30. aufnahmeTask.execute();
  31. }
  32. public void stop() {
  33. if(aufnahmeTask !=null) {
  34. aufnahmeTask.cancel(true);
  35. aufnahmeTask = null;
  36. }
  37. }
  38. public void doRecalibration() {
  39. stop();
  40. microfonAlarmDetected = false;
  41. kalibrierung_do = true;
  42. threshold = 40;
  43. sensitivity = 10;
  44. amplitudeInDB = 0;
  45. }
  46. public float getAmplitudeInDB() {
  47. return amplitudeInDB;
  48. }
  49. private void setAmplitudeInDB(float amplitudeInDB) {
  50. this.amplitudeInDB = amplitudeInDB;
  51. }
  52. public MutableLiveData<Boolean> getAccelerometerAlarmDetected() {
  53. setMutableLiveDataMicrofonAlarmDetected();
  54. return mMicrofonAlarmDetected;
  55. }
  56. private void setMutableLiveDataMicrofonAlarmDetected() {
  57. mMicrofonAlarmDetected.setValue(microfonAlarmDetected);
  58. }
  59. class AufnahmeTask extends AsyncTask<Long, Verarbeitungsergebnis, Void> {
  60. private AudioRecord recorder;
  61. private final int sampleRateInHz = 44100;
  62. private final int channelConfig = AudioFormat.CHANNEL_IN_MONO;
  63. private final int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
  64. private int minPufferGroesseInBytes;
  65. private int pufferGroesseInBytes;
  66. public AufnahmeTask() {
  67. minPufferGroesseInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
  68. pufferGroesseInBytes = minPufferGroesseInBytes * 2;
  69. recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig, audioFormat, pufferGroesseInBytes);
  70. }
  71. public float kalibrieren(short[] puffer){
  72. try {
  73. Thread.sleep(3000);
  74. } catch (InterruptedException e) {
  75. e.printStackTrace();
  76. }
  77. int anzahlIterationen = 100;
  78. float sum = 0.0f;
  79. for(int i = 0; i < anzahlIterationen; i++){
  80. int z = recorder.read(puffer, 0, puffer.length);
  81. Verarbeitungsergebnis kalibrierung = verarbeiten(puffer, z);
  82. sum += kalibrierung.getDB();
  83. }
  84. return sum/anzahlIterationen;
  85. }
  86. public void Detektion(Verarbeitungsergebnis ergebnis){
  87. if(ergebnis.getDB() >= (threshold+sensitivity)){
  88. microfonAlarmDetected = true;
  89. }
  90. else if (ergebnis.getDB() <= (threshold)) {
  91. microfonAlarmDetected = false;
  92. }
  93. }
  94. @Override
  95. protected Void doInBackground(Long... params) {
  96. recorder.startRecording();
  97. short[] puffer = new short[pufferGroesseInBytes / 2];
  98. GleitenderMittelwert gleitenderMittelwertdB = new GleitenderMittelwert(0.2f);
  99. float db = 0.0f;
  100. //kalibrierung
  101. if(kalibrierung_do){
  102. threshold = kalibrieren(puffer);
  103. kalibrierung_do = false;
  104. }
  105. for (; ; ) {
  106. if (isCancelled()) {
  107. break;
  108. }
  109. else {
  110. //ergebnis ermitteln
  111. int n = recorder.read(puffer, 0, puffer.length);
  112. Verarbeitungsergebnis ergebnis = verarbeiten(puffer, n);
  113. //Mittelwertberechnnung
  114. db = ergebnis.getDB();
  115. db = gleitenderMittelwertdB.mittel(db);
  116. ergebnis.setDB(db);
  117. //Db Wert mit Schwellwert vergleichen und Warnung setzen
  118. Detektion(ergebnis);
  119. publishProgress(ergebnis);
  120. try {
  121. Thread.sleep(10);
  122. } catch (InterruptedException e) {
  123. e.printStackTrace();
  124. }
  125. }
  126. }
  127. recorder.release();
  128. return null;
  129. }
  130. private Verarbeitungsergebnis verarbeiten(short[] daten, int n) {
  131. String status;
  132. short maxAmp = -1;
  133. int db = 0, db_wert = 0;
  134. if (n == AudioRecord.ERROR_INVALID_OPERATION) {
  135. status = "ERROR_INVALID_OPERATION";
  136. } else if (n == AudioRecord.ERROR_BAD_VALUE) {
  137. status = "ERROR_BAD_VALUE";
  138. } else {
  139. status = "OK";
  140. short max = 0;
  141. for (int i = 0; i < n; i++) {
  142. if (daten[i] > max) {
  143. max = daten[i];
  144. }
  145. }
  146. ringPuffer.hinzufuegen(max);
  147. maxAmp = ringPuffer.maximum();
  148. }
  149. //Umwandlung Amplitudenwert in dB
  150. db_wert = (int) (20*Math.log10(maxAmp));
  151. if (db_wert > 0){
  152. db = db_wert;
  153. }
  154. return new Verarbeitungsergebnis(status, maxAmp, db);
  155. }
  156. @Override
  157. protected void onProgressUpdate(Verarbeitungsergebnis... progress) {
  158. super.onProgressUpdate(progress);
  159. setAmplitudeInDB(progress[0].getDB());
  160. if (microfonAlarmDetected != mMicrofonAlarmDetected.getValue()){
  161. setMutableLiveDataMicrofonAlarmDetected();
  162. }
  163. //textViewMaxAmpdb.setText("" + progress[0].db);
  164. }
  165. }
  166. }