From 144b8eb6767e867bab2cdd8773ed79dbb608d80c Mon Sep 17 00:00:00 2001 From: fraba Date: Tue, 20 Jun 2023 16:23:42 +0200 Subject: [PATCH] Kapselung in Funktionen; --- .../greenwatch/GleitenderMittelwert.java | 23 ++ .../java/com/example/greenwatch/Mikrofon.java | 261 ++++-------------- .../com/example/greenwatch/RingPuffer.java | 63 +++++ .../greenwatch/Verarbeitungsergebnis.java | 13 + gradlew | 0 5 files changed, 150 insertions(+), 210 deletions(-) create mode 100644 app/src/main/java/com/example/greenwatch/GleitenderMittelwert.java create mode 100644 app/src/main/java/com/example/greenwatch/RingPuffer.java create mode 100644 app/src/main/java/com/example/greenwatch/Verarbeitungsergebnis.java mode change 100755 => 100644 gradlew diff --git a/app/src/main/java/com/example/greenwatch/GleitenderMittelwert.java b/app/src/main/java/com/example/greenwatch/GleitenderMittelwert.java new file mode 100644 index 0000000..47ebc5c --- /dev/null +++ b/app/src/main/java/com/example/greenwatch/GleitenderMittelwert.java @@ -0,0 +1,23 @@ +package com.example.greenwatch; + +public class GleitenderMittelwert { + private final float wichtungNeuerWert; + private final float wichtungAlterWert; + private float mittelwert = 0; + + private boolean istMittelwertGesetzt = false; + + GleitenderMittelwert(float wichtungNeuerWert) { + this.wichtungNeuerWert = wichtungNeuerWert; + this.wichtungAlterWert = 1 - this.wichtungNeuerWert; + } + + float mittel(float wert) { + if (istMittelwertGesetzt) { + mittelwert = wert * wichtungNeuerWert + mittelwert * wichtungAlterWert; + } else { + mittelwert = wert; + istMittelwertGesetzt = true; + } + return mittelwert; +}} diff --git a/app/src/main/java/com/example/greenwatch/Mikrofon.java b/app/src/main/java/com/example/greenwatch/Mikrofon.java index e09d051..933eb4f 100644 --- a/app/src/main/java/com/example/greenwatch/Mikrofon.java +++ b/app/src/main/java/com/example/greenwatch/Mikrofon.java @@ -34,16 +34,6 @@ public class Mikrofon extends AppCompatActivity { private final static String KEY_WERT = "KEY_WERT_" + Mikrofon.class.getSimpleName(); private final static String KEY_KALIBRIERUNG = "KEY_KALIBRIERUNG_" + Mikrofon.class.getSimpleName(); - //zu speichernde Daten: detection_mic, zeit, - // kalibrierung_do (Unterscheidung, ob Activity aus Benutzersicht (back-Taste --> erneuter Start führt zu erneutem Kalbireren) oder durch Kippen beendet (isFinishing()==false und nicht ernuet kalbrieren), - //threshold + sensitivity speichern, damit beim Kippen das nicht verloren geht, - //Verarbeitungsergebnis ergebnis in der doInBackground Funktion muss auch gespeichert werden, da dort der aktuelle db-Wert enthalten ist --> sonst machen Werte kurz nach dem Kippen keinen Sinn mehr - //aktuell noch SharedPref bei kalibrierung_do und threshold implementiert --> kann nach erfolgreichem Einbinden in Model entfernt werden - //Infos zu Variablen: - //detection_mic: solange true, solange ergebnis.db > threshold+sensitivity -> wird false, sobald ergebnis.db < threshold - //zeit: wird sowohl bei Beginn der Detektion als auch beim Ende der Detektion aktualisiert - //Funktion der App: nach Start 3s Thread.sleep, damit man das Handy positionieren kann -> Kalibrierung folgt, dauert mehrere Sekunden, erst nach Kalbrierung werden Werte angezeigt - //offenes Problem: beim allerersten Start nach der Installation wird der alte Kalbrierwert verwendet und nicht erneut kalibriert --> nach Einbinden Verhalten erneut prüfen @@ -54,9 +44,12 @@ public class Mikrofon extends AppCompatActivity { textViewMaxAmp = (TextView) findViewById(R.id.textViewMaxAmp); textViewMaxAmpdb = (TextView) findViewById(R.id.textViewMaxAmpdb); textViewZeitstempel = (TextView) findViewById(R.id.textViewZeitstempel); + //kalibrierung_do = true; + } + @Override protected void onResume() { super.onResume(); @@ -121,89 +114,64 @@ public class Mikrofon extends AppCompatActivity { private int minPufferGroesseInBytes; private int pufferGroesseInBytes; private RingPuffer ringPuffer = new RingPuffer(10); + private boolean erlaubt_rise = true; + private boolean erlaubt_fall = true; AufnahmeTask() { minPufferGroesseInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); pufferGroesseInBytes = minPufferGroesseInBytes * 2; recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig, audioFormat, pufferGroesseInBytes); + } + //hi + public float kalibrieren(short[] puffer){ + try { + Thread.sleep(3000); - int anzahlBytesProAbtastwert; - String s; - switch (recorder.getAudioFormat()) { - case AudioFormat.ENCODING_PCM_8BIT: - s = "8 Bit PCM "; - anzahlBytesProAbtastwert = 1; - break; - case AudioFormat.ENCODING_PCM_16BIT: - s = "16 Bit PCM"; - anzahlBytesProAbtastwert = 2; - break; - case AudioFormat.ENCODING_PCM_FLOAT: - s = "Float PCM"; - anzahlBytesProAbtastwert = 4; - break; - default: - throw new IllegalArgumentException(); + } catch (InterruptedException e) { + e.printStackTrace(); } - - switch (recorder.getChannelConfiguration()) { - case AudioFormat.CHANNEL_IN_MONO: - s = "Mono"; - break; - case AudioFormat.CHANNEL_IN_STEREO: - s = "Stereo"; - anzahlBytesProAbtastwert *= 2; - break; - case AudioFormat.CHANNEL_INVALID: - s = "ungültig"; - break; - default: - throw new IllegalArgumentException(); + int anzahlIterationen = 100; + float sum = 0; + for(int i = 0; i < anzahlIterationen; i++){ + int z = recorder.read(puffer, 0, puffer.length); + Verarbeitungsergebnis kalibrierung = verarbeiten(puffer, z); + sum += (float) kalibrierung.db; + System.out.println("Aktueller_Wert Kalibrierung" +kalibrierung.db); } - + System.out.println("Summe:"+sum); + return sum/anzahlIterationen; } - + public void Detektion(Verarbeitungsergebnis ergebnis){ + if(ergebnis.db >= (threshold+sensitivity)){ + detection_mic = true; + erlaubt_fall = true; + while(erlaubt_rise){ + erlaubt_rise = false; + zeit = Zeitpunkt() + " - " + ergebnis.db + " - " + (threshold+sensitivity); //Überschreiben des Zeitpunkts beim Erkennen der Detektion + //nur zum Testen in zeit noch ergebnis.db und threshold ausgegeben -> muss am Ende nur Zeitpunkt() rein, Rest weg + } + } else if (ergebnis.db <= (threshold)) { + detection_mic = false; + erlaubt_rise = true; + while(erlaubt_fall){ + erlaubt_fall = false; + zeit = Zeitpunkt(); //erneutes Überschreiben des Zeitpunkts beim Verschwinden der Detektion + } + } + } @Override protected Void doInBackground(Long... params) { recorder.startRecording(); short[] puffer = new short[pufferGroesseInBytes / 2]; - long lastTime = System.currentTimeMillis(); - float verarbeitungsrate = 0; - final int maxZaehlerZeitMessung = 10; - int zaehlerZeitMessung = 0; - int anzahlVerarbeitet = 0; - GleitenderMittelwert gleitenderMittelwert = new GleitenderMittelwert(0.3f); GleitenderMittelwert gleitenderMittelwertdB = new GleitenderMittelwert(0.2f); float db = 0; - boolean erlaubt_rise = true; - boolean erlaubt_fall = true; + //kalibrierung if(kalibrierung_do){ - //3s warten auf weitere Ausführung - try { - Thread.sleep(3000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - int anzahlIterationen = 100; - float sum = 0; - //Mittelwertbildung für kalibrierten threshold - for(int i = 0; i < anzahlIterationen; i++){ - if (isCancelled()) { - break; - } else { - int z = recorder.read(puffer, 0, puffer.length); - Verarbeitungsergebnis kalibrierung = verarbeiten(puffer, z); - sum += (float) kalibrierung.db; - System.out.println("Kalibrierungswert zum Testen" + kalibrierung.db); - } - - } - threshold = sum/anzahlIterationen; + threshold = kalibrieren(puffer); kalibrierung_do = false; } @@ -212,49 +180,19 @@ public class Mikrofon extends AppCompatActivity { if (isCancelled()) { break; } else { + //ergebnis ermitteln int n = recorder.read(puffer, 0, puffer.length); Verarbeitungsergebnis ergebnis = verarbeiten(puffer, n); - anzahlVerarbeitet += n; - - zaehlerZeitMessung++; - if (zaehlerZeitMessung == maxZaehlerZeitMessung) { - long time = System.currentTimeMillis(); - long deltaTime = time - lastTime; - verarbeitungsrate = 1000.0f * anzahlVerarbeitet / deltaTime; - verarbeitungsrate = gleitenderMittelwert.mittel(verarbeitungsrate); - zaehlerZeitMessung = 0; - anzahlVerarbeitet = 0; - lastTime = time; - } + //Mittelwertberechnnung db = (float) ergebnis.db; db = gleitenderMittelwertdB.mittel(db); ergebnis.db = (int) db; - ergebnis.verarbeitungsrate = (int) verarbeitungsrate; - - //Hysterese beim Setzen bzw. Rücksetzen ob detektiert - //beim ersten detektieren wird Zeitpunkt gespeichert - if(ergebnis.db >= (threshold+sensitivity)){ - detection_mic = true; //solange true, solange ergebnis.db > threshold+sensitivity - erlaubt_fall = true; - while(erlaubt_rise){ - erlaubt_rise = false; - zeit = Zeitpunkt() + " - " + ergebnis.db + " - " + (threshold+sensitivity); //Überschreiben des Zeitpunkts beim Erkennen der Detektion - //nur zum Testen in zeit noch ergebnis.db und threshold ausgegeben -> muss am Ende nur Zeitpunkt() rein, Rest weg - //Amplitude zum Zeitpunkt der Detektion steht in ergebnis.db, wird zyklisch bei jedem Durchlauf der for-Schleife überschrieben - } - } else if (ergebnis.db <= (threshold)) { - detection_mic = false; - erlaubt_rise = true; - while(erlaubt_fall){ - erlaubt_fall = false; - zeit = Zeitpunkt(); //erneutes Überschreiben des Zeitpunkts beim Verschwinden der Detektion - } - } + //Db Wert mit Schwellwert vergleichen und Warnung setzen + Detektion(ergebnis); publishProgress(ergebnis); - try { Thread.sleep(10); } catch (InterruptedException e) { @@ -269,7 +207,7 @@ public class Mikrofon extends AppCompatActivity { private Verarbeitungsergebnis verarbeiten(short[] daten, int n) { String status; short maxAmp = -1; - int db = 0, wert_db = 0; + int db = 0, db_wert = 0; if (n == AudioRecord.ERROR_INVALID_OPERATION) { status = "ERROR_INVALID_OPERATION"; @@ -287,14 +225,13 @@ public class Mikrofon extends AppCompatActivity { maxAmp = ringPuffer.maximum(); } //Umwandlung Amplitudenwert in dB - wert_db = (int) (20*Math.log10(maxAmp)); - - if(wert_db > 0){ - db = wert_db; + db_wert = (int) (20*Math.log10(maxAmp)); + if (db_wert > 0){ + db = db_wert; } - return new Verarbeitungsergebnis(status, maxAmp,0, db); + return new Verarbeitungsergebnis(status, maxAmp, db); } ///////////////////////////////////////////// @@ -313,101 +250,5 @@ public class Mikrofon extends AppCompatActivity { } } ///////////////////////////////////////////// - class Verarbeitungsergebnis { - String status; - short maxAmp; - int db; - int verarbeitungsrate; - Verarbeitungsergebnis(String status, short maxAmp, int verarbeitungsrate, int db) { - this.status = status; - this.maxAmp = maxAmp; - this.db = db; - this.verarbeitungsrate = verarbeitungsrate; - } - } - - class RingPuffer { - private short[] puffer; - private final int laenge; - private int anzahlEnthaltenerDaten; - private int position; - - public RingPuffer(int n) { - laenge = n; - anzahlEnthaltenerDaten = 0; - position = 0; - puffer = new short[laenge]; - } - - public void hinzufuegen(short wert) { - puffer[position] = wert; - position++; - if (position >= laenge) { - position = 0; - } - if (anzahlEnthaltenerDaten < laenge) { - anzahlEnthaltenerDaten++; - } - } - - public void hinzufuegen(short[] daten) { - for (short d : daten) { - puffer[position] = d; - position++; - if (position >= laenge) { - position = 0; - } - } - if (anzahlEnthaltenerDaten < laenge) { - anzahlEnthaltenerDaten += daten.length; - if (anzahlEnthaltenerDaten >= laenge) { - anzahlEnthaltenerDaten = laenge; - } - } - } - - public short maximum() { - short max = 0; - for (int i = 0; i < anzahlEnthaltenerDaten; i++) { - if (puffer[i] > max) { - max = puffer[i]; - } - } - return max; - } - - public float mittelwert() { - float summe = 0; - for (int i = 0; i < anzahlEnthaltenerDaten; i++) { - summe += puffer[i]; - } - return summe / anzahlEnthaltenerDaten; - } - } - - class GleitenderMittelwert { - private final float wichtungNeuerWert; - private final float wichtungAlterWert; - private float mittelwert = 0; - private boolean istMittelwertGesetzt = false; - - GleitenderMittelwert(float wichtungNeuerWert) { - this.wichtungNeuerWert = wichtungNeuerWert; - this.wichtungAlterWert = 1 - this.wichtungNeuerWert; - } - - float mittel(float wert) { - if (istMittelwertGesetzt) { - mittelwert = wert * wichtungNeuerWert + mittelwert * wichtungAlterWert; - } else { - mittelwert = wert; - istMittelwertGesetzt = true; - } - return mittelwert; - } - - - } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/greenwatch/RingPuffer.java b/app/src/main/java/com/example/greenwatch/RingPuffer.java new file mode 100644 index 0000000..1f3dc95 --- /dev/null +++ b/app/src/main/java/com/example/greenwatch/RingPuffer.java @@ -0,0 +1,63 @@ +package com.example.greenwatch; + +public class RingPuffer { + + private short[] puffer; + private final int laenge; + private int anzahlEnthaltenerDaten; + private int position; + + + public RingPuffer(int n) { + laenge = n; + anzahlEnthaltenerDaten = 0; + position = 0; + puffer = new short[laenge]; + } + + public void hinzufuegen(short wert) { + puffer[position] = wert; + position++; + if (position >= laenge) { + position = 0; + } + if (anzahlEnthaltenerDaten < laenge) { + anzahlEnthaltenerDaten++; + } + } + + /*public void hinzufuegen(short[] daten) { + for (short d : daten) { + puffer[position] = d; + position++; + if (position >= laenge) { + position = 0; + } + } + if (anzahlEnthaltenerDaten < laenge) { + anzahlEnthaltenerDaten += daten.length; + if (anzahlEnthaltenerDaten >= laenge) { + anzahlEnthaltenerDaten = laenge; + } + } + }*/ + + public short maximum() { + short max = 0; + for (int i = 0; i < anzahlEnthaltenerDaten; i++) { + if (puffer[i] > max) { + max = puffer[i]; + } + } + return max; + } + + /* public float mittelwert() { + float summe = 0; + for (int i = 0; i < anzahlEnthaltenerDaten; i++) { + summe += puffer[i]; + } + return summe / anzahlEnthaltenerDaten; + }*/ +} + diff --git a/app/src/main/java/com/example/greenwatch/Verarbeitungsergebnis.java b/app/src/main/java/com/example/greenwatch/Verarbeitungsergebnis.java new file mode 100644 index 0000000..d163ce4 --- /dev/null +++ b/app/src/main/java/com/example/greenwatch/Verarbeitungsergebnis.java @@ -0,0 +1,13 @@ +package com.example.greenwatch; + +public class Verarbeitungsergebnis { + String status; + short maxAmp; + int db; +// + Verarbeitungsergebnis(String status, short maxAmp, int db) { + this.status = status; + this.maxAmp = maxAmp; + this.db = db; + } +} diff --git a/gradlew b/gradlew old mode 100755 new mode 100644