package com.example.ueberwachungssystem.Detector; | |||||
package com.example.ueberwachungssystem.Detection; | |||||
import static java.lang.Math.*; | import static java.lang.Math.*; | ||||
import androidx.core.app.ActivityCompat; | import androidx.core.app.ActivityCompat; | ||||
import androidx.core.content.ContextCompat; | import androidx.core.content.ContextCompat; | ||||
import com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex; | |||||
import com.example.ueberwachungssystem.Detector.Signalverarbeitung.FFT; | |||||
import com.example.ueberwachungssystem.Detector.logger.Logger; | |||||
import com.jjoe64.graphview.GraphView; | |||||
import com.jjoe64.graphview.series.DataPoint; | |||||
import com.jjoe64.graphview.series.LineGraphSeries; | |||||
import com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex; | |||||
import com.example.ueberwachungssystem.Detection.Signalverarbeitung.FFT; | |||||
import com.example.ueberwachungssystem.Detector.DetectionReport; | |||||
import com.example.ueberwachungssystem.Detector.Detector; | |||||
public class MicrophoneDetector extends Detector { | public class MicrophoneDetector extends Detector { | ||||
/** | /** | ||||
private int pufferGroesseInBytes; | private int pufferGroesseInBytes; | ||||
private RingPuffer ringPuffer = new RingPuffer(10); | private RingPuffer ringPuffer = new RingPuffer(10); | ||||
private float kalibierWert; | private float kalibierWert; | ||||
private DetectionReport detectionReport; | |||||
private com.example.ueberwachungssystem.Detector.DetectionReport detectionReport; | |||||
AufnahmeTask() { | AufnahmeTask() { | ||||
minPufferGroesseInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); | minPufferGroesseInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); |
package com.example.ueberwachungssystem.Detector.Signalverarbeitung; | |||||
package com.example.ueberwachungssystem.Detection.Signalverarbeitung; | |||||
import java.util.Objects; | import java.util.Objects; | ||||
im = imag; | im = imag; | ||||
} | } | ||||
// return a string representation of the invoking com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex object | |||||
// return a string representation of the invoking com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object | |||||
public String toString() { | public String toString() { | ||||
if (im == 0) return re + ""; | if (im == 0) return re + ""; | ||||
if (re == 0) return im + "i"; | if (re == 0) return im + "i"; | ||||
return Math.atan2(im, re); | return Math.atan2(im, re); | ||||
} | } | ||||
// return a new com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex object whose value is (this + b) | |||||
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is (this + b) | |||||
public Complex plus(Complex b) { | public Complex plus(Complex b) { | ||||
Complex a = this; // invoking object | Complex a = this; // invoking object | ||||
double real = a.re + b.re; | double real = a.re + b.re; | ||||
return new Complex(real, imag); | return new Complex(real, imag); | ||||
} | } | ||||
// return a new com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex object whose value is (this - b) | |||||
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is (this - b) | |||||
public Complex minus(Complex b) { | public Complex minus(Complex b) { | ||||
Complex a = this; | Complex a = this; | ||||
double real = a.re - b.re; | double real = a.re - b.re; | ||||
return new Complex(real, imag); | return new Complex(real, imag); | ||||
} | } | ||||
// return a new com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex object whose value is (this * b) | |||||
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is (this * b) | |||||
public Complex times(Complex b) { | public Complex times(Complex b) { | ||||
Complex a = this; | Complex a = this; | ||||
double real = a.re * b.re - a.im * b.im; | double real = a.re * b.re - a.im * b.im; | ||||
return new Complex(alpha * re, alpha * im); | return new Complex(alpha * re, alpha * im); | ||||
} | } | ||||
// return a new com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex object whose value is the conjugate of this | |||||
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is the conjugate of this | |||||
public Complex conjugate() { | public Complex conjugate() { | ||||
return new Complex(re, -im); | return new Complex(re, -im); | ||||
} | } | ||||
// return a new com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex object whose value is the reciprocal of this | |||||
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is the reciprocal of this | |||||
public Complex reciprocal() { | public Complex reciprocal() { | ||||
double scale = re * re + im * im; | double scale = re * re + im * im; | ||||
return new Complex(re / scale, -im / scale); | return new Complex(re / scale, -im / scale); | ||||
return a.times(b.reciprocal()); | return a.times(b.reciprocal()); | ||||
} | } | ||||
// return a new com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex object whose value is the complex exponential of this | |||||
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is the complex exponential of this | |||||
public Complex exp() { | public Complex exp() { | ||||
return new Complex(Math.exp(re) * Math.cos(im), Math.exp(re) * Math.sin(im)); | return new Complex(Math.exp(re) * Math.cos(im), Math.exp(re) * Math.sin(im)); | ||||
} | } | ||||
// return a new com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex object whose value is the complex sine of this | |||||
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is the complex sine of this | |||||
public Complex sin() { | public Complex sin() { | ||||
return new Complex(Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im)); | return new Complex(Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im)); | ||||
} | } | ||||
// return a new com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex object whose value is the complex cosine of this | |||||
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is the complex cosine of this | |||||
public Complex cos() { | public Complex cos() { | ||||
return new Complex(Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im)); | return new Complex(Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im)); | ||||
} | } | ||||
// return a new com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex object whose value is the complex tangent of this | |||||
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is the complex tangent of this | |||||
public Complex tan() { | public Complex tan() { | ||||
return sin().divides(cos()); | return sin().divides(cos()); | ||||
} | } |
package com.example.ueberwachungssystem.Detector.Signalverarbeitung; | |||||
package com.example.ueberwachungssystem.Detection.Signalverarbeitung; | |||||
// Source: https://introcs.cs.princeton.edu/java/97data/FFT.java.html | // Source: https://introcs.cs.princeton.edu/java/97data/FFT.java.html | ||||
/****************************************************************************** | /****************************************************************************** | ||||
* Compilation: javac FFT.java | * Compilation: javac FFT.java | ||||
* Execution: java FFT n | * Execution: java FFT n | ||||
* Dependencies: com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex.java | |||||
* Dependencies: com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex.java | |||||
* | * | ||||
* Compute the FFT and inverse FFT of a length n complex sequence | * Compute the FFT and inverse FFT of a length n complex sequence | ||||
* using the radix 2 Cooley-Tukey algorithm. | * using the radix 2 Cooley-Tukey algorithm. | ||||
return y; | return y; | ||||
} | } | ||||
// display an array of com.example.ueberwachungssystem.Detector.Signalverarbeitung.Complex numbers to standard output | |||||
// display an array of com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex numbers to standard output | |||||
public static void show(Complex[] x, String title) { | public static void show(Complex[] x, String title) { | ||||
System.out.println(title); | System.out.println(title); | ||||
System.out.println("-------------------"); | System.out.println("-------------------"); |
package com.example.ueberwachungssystem.Detector; | |||||
import android.util.Log; | |||||
import java.util.Calendar; | |||||
/** Detection Report Class */ | |||||
public class DetectionReport { | |||||
public String timeStamp; | |||||
public String detectionType; | |||||
public float detectedValue; | |||||
public String detectorID; | |||||
public DetectionReport(String detectorID, String detectionType, float detectedAmplitude) { | |||||
this.timeStamp = String.valueOf(Calendar.getInstance().getTime()); | |||||
this.detectionType = detectionType; | |||||
this.detectedValue = detectedAmplitude; | |||||
this.detectorID = detectorID; | |||||
} | |||||
/** Get Detection Report in String format */ | |||||
public String toString() { | |||||
String time = "Time: " + "[" + this.timeStamp + "]"; | |||||
String type = "Type: " + "[" + this.detectionType + "]"; | |||||
String value = "Value: " + "[" + this.detectedValue + "]"; | |||||
String id = "ID: " + "[" + this.detectorID + "]"; | |||||
return String.join("\t", time, type, value, id); | |||||
} | |||||
/** Debug Report */ | |||||
public void log(String tag) { | |||||
Log.d(tag, this.toString()); | |||||
} | |||||
} |
package com.example.ueberwachungssystem.Detector; | |||||
import android.content.Context; | |||||
import androidx.annotation.NonNull; | |||||
abstract public class Detector { | |||||
private OnDetectionListener listener; | |||||
/** Constructor - takes context of current activity */ | |||||
public Detector(Context context) {}; | |||||
/** On Detection Listener - runs when violation is reported */ | |||||
public interface OnDetectionListener { | |||||
void onDetection(@NonNull DetectionReport detectionReport); | |||||
} | |||||
public void setOnDetectionListener(@NonNull OnDetectionListener listener) { | |||||
this.listener = listener; | |||||
} | |||||
/** Triggers onDetectionListener - call this to trigger violation/alarm */ | |||||
public void reportViolation(String detectorID, String detectionType, float amplitude) { | |||||
if (listener != null) { | |||||
DetectionReport detectionReport = new DetectionReport(detectorID, detectionType, amplitude); | |||||
listener.onDetection(detectionReport); | |||||
} else { | |||||
throw new IllegalStateException("No listener set for violation reporting"); | |||||
} | |||||
} | |||||
/** Starts Detection (abstract method: needs to be overridden in child class) */ | |||||
public abstract void startDetection(); | |||||
/** Stops Detection (abstract method: needs to be overridden in child class) */ | |||||
public abstract void stopDetection(); | |||||
} |