|
|
|
|
|
|
|
|
import android.media.AudioRecord; |
|
|
import android.media.AudioRecord; |
|
|
import android.media.MediaRecorder; |
|
|
import android.media.MediaRecorder; |
|
|
import android.os.AsyncTask; |
|
|
import android.os.AsyncTask; |
|
|
|
|
|
import android.util.Log; |
|
|
|
|
|
|
|
|
import androidx.core.app.ActivityCompat; |
|
|
import androidx.core.app.ActivityCompat; |
|
|
import androidx.core.content.ContextCompat; |
|
|
import androidx.core.content.ContextCompat; |
|
|
|
|
|
|
|
|
private AufnahmeTask aufnahmeTask; |
|
|
private AufnahmeTask aufnahmeTask; |
|
|
public boolean armed = false; |
|
|
public boolean armed = false; |
|
|
public int Schwellwert_Alarm = 100; |
|
|
public int Schwellwert_Alarm = 100; |
|
|
GraphView graph; |
|
|
|
|
|
|
|
|
|
|
|
Logger logger; |
|
|
|
|
|
private Activity MainActivityForClass; |
|
|
private Activity MainActivityForClass; |
|
|
|
|
|
|
|
|
public MicrophoneDetector(Context context, Logger MainLogger, GraphView MainGraph) { |
|
|
|
|
|
|
|
|
public MicrophoneDetector(Context context) { |
|
|
super(context); |
|
|
super(context); |
|
|
MainActivityForClass = (Activity) context; |
|
|
MainActivityForClass = (Activity) context; |
|
|
logger = MainLogger; //Class uses the same logger as the MainActivity |
|
|
|
|
|
logger.log(this.getClass().getSimpleName() + ".onCreate"); |
|
|
|
|
|
graph = MainGraph; |
|
|
|
|
|
|
|
|
|
|
|
if (!istZugriffAufMikrofonErlaubt()) { |
|
|
if (!istZugriffAufMikrofonErlaubt()) { |
|
|
zugriffAufMikrofonAnfordern(); |
|
|
zugriffAufMikrofonAnfordern(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
@Override |
|
|
public void startDetection() { |
|
|
public void startDetection() { |
|
|
logger.log(this.getClass().getSimpleName() + ".startDetection"); |
|
|
|
|
|
|
|
|
|
|
|
if (!istZugriffAufMikrofonErlaubt()) { |
|
|
if (!istZugriffAufMikrofonErlaubt()) { |
|
|
zugriffAufMikrofonAnfordern(); |
|
|
zugriffAufMikrofonAnfordern(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
@Override |
|
|
public void stopDetection() { |
|
|
public void stopDetection() { |
|
|
logger.log(this.getClass().getSimpleName() + ".stopDetection"); |
|
|
|
|
|
if (aufnahmeTask != null) { |
|
|
if (aufnahmeTask != null) { |
|
|
aufnahmeTask.cancel(true); |
|
|
aufnahmeTask.cancel(true); |
|
|
// aufnahmeTask = null; // if aufnahmeTask = null, break in for loop would not work (Nullpointer Exception) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private boolean istZugriffAufMikrofonErlaubt() { |
|
|
private boolean istZugriffAufMikrofonErlaubt() { |
|
|
if (ContextCompat.checkSelfPermission(MainActivityForClass, android.Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { |
|
|
if (ContextCompat.checkSelfPermission(MainActivityForClass, android.Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { |
|
|
logger.log("Zugriff auf Mikrofon ist verboten."); |
|
|
|
|
|
|
|
|
Log.d("0","Zugriff auf Mikrofon ist verboten."); |
|
|
return false; |
|
|
return false; |
|
|
} else { |
|
|
} else { |
|
|
logger.log("Zugriff auf Mikrofon ist erlaubt."); |
|
|
|
|
|
|
|
|
Log.d("0","Zugriff auf Mikrofon ist erlaubt."); |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig, audioFormat, pufferGroesseInBytes); |
|
|
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig, audioFormat, pufferGroesseInBytes); |
|
|
|
|
|
|
|
|
// textViewMinPufferGroesseInBytes.setText("" + minPufferGroesseInBytes); |
|
|
|
|
|
// textViewPufferGroesseInBytes.setText("" + pufferGroesseInBytes); |
|
|
|
|
|
// textViewAbtastrate.setText("" + recorder.getSampleRate()); |
|
|
|
|
|
// textViewAnzahlKanaele.setText("" + recorder.getChannelCount()); |
|
|
|
|
|
|
|
|
|
|
|
logger.log("Puffergroeße: "+ minPufferGroesseInBytes + " " + pufferGroesseInBytes); |
|
|
|
|
|
logger.log("Recorder (SR, CH): "+ recorder.getSampleRate() + " " + recorder.getChannelCount()); |
|
|
|
|
|
|
|
|
Log.d("0","Puffergroeße: "+ minPufferGroesseInBytes + " " + pufferGroesseInBytes); |
|
|
|
|
|
Log.d("0","Recorder (SR, CH): "+ recorder.getSampleRate() + " " + recorder.getChannelCount()); |
|
|
|
|
|
|
|
|
int anzahlBytesProAbtastwert; |
|
|
int anzahlBytesProAbtastwert; |
|
|
String s; |
|
|
String s; |
|
|
|
|
|
|
|
|
default: |
|
|
default: |
|
|
throw new IllegalArgumentException(); |
|
|
throw new IllegalArgumentException(); |
|
|
} |
|
|
} |
|
|
// textViewAudioFormat.setText(s); |
|
|
|
|
|
|
|
|
|
|
|
switch (recorder.getChannelConfiguration()) { |
|
|
switch (recorder.getChannelConfiguration()) { |
|
|
case AudioFormat.CHANNEL_IN_MONO: |
|
|
case AudioFormat.CHANNEL_IN_MONO: |
|
|
|
|
|
|
|
|
default: |
|
|
default: |
|
|
throw new IllegalArgumentException(); |
|
|
throw new IllegalArgumentException(); |
|
|
} |
|
|
} |
|
|
// textViewKanalKonfiguration.setText(s); |
|
|
|
|
|
logger.log("Konfiguration: "+ s); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Log.d("0","Konfiguration: "+ s); |
|
|
|
|
|
|
|
|
int pufferGroesseInAnzahlAbtastwerten = pufferGroesseInBytes / anzahlBytesProAbtastwert; |
|
|
int pufferGroesseInAnzahlAbtastwerten = pufferGroesseInBytes / anzahlBytesProAbtastwert; |
|
|
int pufferGroesseInMillisekunden = 1000 * pufferGroesseInAnzahlAbtastwerten / recorder.getSampleRate(); |
|
|
int pufferGroesseInMillisekunden = 1000 * pufferGroesseInAnzahlAbtastwerten / recorder.getSampleRate(); |
|
|
|
|
|
|
|
|
// textViewPufferGroesseInAnzahlAbtastwerte.setText("" + pufferGroesseInAnzahlAbtastwerten); |
|
|
|
|
|
// textViewPufferGroesseInMillisekunden.setText("" + pufferGroesseInMillisekunden); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@Override |
|
|
@Override |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Kalibrierung |
|
|
//Kalibrierung |
|
|
try { |
|
|
try { |
|
|
Thread.sleep(3000); |
|
|
|
|
|
|
|
|
Thread.sleep(3000); // Time to lay down the phone |
|
|
} catch (InterruptedException e) { |
|
|
} catch (InterruptedException e) { |
|
|
e.printStackTrace(); |
|
|
e.printStackTrace(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
kalibierWert = kalibierWert/i; |
|
|
kalibierWert = kalibierWert/i; |
|
|
|
|
|
|
|
|
|
|
|
// __Part of FFT__ |
|
|
// Complex[] zeitSignal = new Complex[puffer.length]; |
|
|
// Complex[] zeitSignal = new Complex[puffer.length]; |
|
|
// for (int j = 0; j < puffer.length; j++) { |
|
|
// for (int j = 0; j < puffer.length; j++) { |
|
|
// zeitSignal[j] = new Complex(puffer[j], 0); |
|
|
// zeitSignal[j] = new Complex(puffer[j], 0); |
|
|
// } |
|
|
// } |
|
|
// Complex[] spektrum = FFT.fft(zeitSignal); |
|
|
// Complex[] spektrum = FFT.fft(zeitSignal); |
|
|
double[] spektrum = calculateFFT(puffer); |
|
|
|
|
|
DataPoint AddPoint; |
|
|
|
|
|
|
|
|
// double[] spektrum = calculateFFT(puffer); |
|
|
|
|
|
// DataPoint AddPoint; |
|
|
// LineGraphSeries<DataPoint> series = new LineGraphSeries<DataPoint>(new DataPoint[]{}); |
|
|
// LineGraphSeries<DataPoint> series = new LineGraphSeries<DataPoint>(new DataPoint[]{}); |
|
|
// for (i = 0; i < spektrum.length; i++) { |
|
|
// for (i = 0; i < spektrum.length; i++) { |
|
|
// AddPoint = new DataPoint(i, spektrum[i]); |
|
|
// AddPoint = new DataPoint(i, spektrum[i]); |
|
|
// series.appendData(AddPoint, true, spektrum.length); |
|
|
// series.appendData(AddPoint, true, spektrum.length); |
|
|
// } |
|
|
// } |
|
|
// graph.addSeries(series); |
|
|
// graph.addSeries(series); |
|
|
// logger.log(spektrum.toString()); |
|
|
|
|
|
|
|
|
|
|
|
for (; ; ) { |
|
|
for (; ; ) { |
|
|
if (aufnahmeTask.isCancelled()) { |
|
|
if (aufnahmeTask.isCancelled()) { |
|
|
|
|
|
|
|
|
int n = recorder.read(puffer, 0, puffer.length); |
|
|
int n = recorder.read(puffer, 0, puffer.length); |
|
|
Verarbeitungsergebnis ergebnis = verarbeiten(puffer, n); |
|
|
Verarbeitungsergebnis ergebnis = verarbeiten(puffer, n); |
|
|
anzahlVerarbeitet += n; |
|
|
anzahlVerarbeitet += n; |
|
|
|
|
|
// __Part of FFT__ |
|
|
|
|
|
// spektrum = calculateFFT(puffer); |
|
|
|
|
|
// LineGraphSeries<DataPoint> newseries = new LineGraphSeries<DataPoint>(new DataPoint[]{}); |
|
|
|
|
|
// for (i = 0; i < spektrum.length; i++) { |
|
|
|
|
|
// AddPoint = new DataPoint(i, spektrum[i]); |
|
|
|
|
|
// newseries.appendData(AddPoint, true, spektrum.length); |
|
|
|
|
|
// } |
|
|
|
|
|
|
|
|
spektrum = calculateFFT(puffer); |
|
|
|
|
|
LineGraphSeries<DataPoint> newseries = new LineGraphSeries<DataPoint>(new DataPoint[]{}); |
|
|
|
|
|
for (i = 0; i < spektrum.length; i++) { |
|
|
|
|
|
AddPoint = new DataPoint(i, spektrum[i]); |
|
|
|
|
|
newseries.appendData(AddPoint, true, spektrum.length); |
|
|
|
|
|
} |
|
|
|
|
|
graph.removeAllSeries(); |
|
|
|
|
|
graph.addSeries(newseries); |
|
|
|
|
|
zaehlerZeitMessung++; |
|
|
zaehlerZeitMessung++; |
|
|
if (zaehlerZeitMessung == maxZaehlerZeitMessung) { |
|
|
if (zaehlerZeitMessung == maxZaehlerZeitMessung) { |
|
|
long time = System.currentTimeMillis(); |
|
|
long time = System.currentTimeMillis(); |
|
|
|
|
|
|
|
|
publishProgress(ergebnis); |
|
|
publishProgress(ergebnis); |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
Thread.sleep(100); |
|
|
|
|
|
|
|
|
Thread.sleep(10); |
|
|
} catch (InterruptedException e) { |
|
|
} catch (InterruptedException e) { |
|
|
e.printStackTrace(); |
|
|
e.printStackTrace(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
for (int i = 0; i < n; i++) { |
|
|
for (int i = 0; i < n; i++) { |
|
|
if (daten[i] > max) { |
|
|
if (daten[i] > max) { |
|
|
max = daten[i]; |
|
|
max = daten[i]; |
|
|
//max = 20 * log10(abs(daten[i]) / 32768); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
@Override |
|
|
protected void onProgressUpdate(Verarbeitungsergebnis... progress) { |
|
|
protected void onProgressUpdate(Verarbeitungsergebnis... progress) { |
|
|
super.onProgressUpdate(progress); |
|
|
super.onProgressUpdate(progress); |
|
|
// textViewMaxAmp.setText("" + progress[0].maxAmp); |
|
|
|
|
|
// textViewVerarbeitungsrate.setText("" + progress[0].verarbeitungsrate); |
|
|
|
|
|
float maxAmpPrint = round(20*log10(abs(progress[0].maxAmp/1.0))); |
|
|
float maxAmpPrint = round(20*log10(abs(progress[0].maxAmp/1.0))); |
|
|
float kalibierWertPrint = round(20*log10(abs(kalibierWert))); |
|
|
float kalibierWertPrint = round(20*log10(abs(kalibierWert))); |
|
|
logger.overwriteLastlog("VR, Max, Kal:" + progress[0].verarbeitungsrate + ", " + maxAmpPrint |
|
|
|
|
|
|
|
|
Log.d("0","VR, Max, Kal:" + progress[0].verarbeitungsrate + ", " + maxAmpPrint |
|
|
+ " dB, " + kalibierWertPrint + " dB"); |
|
|
+ " dB, " + kalibierWertPrint + " dB"); |
|
|
|
|
|
|
|
|
if (progress[0].maxAmp >= Schwellwert_Alarm+kalibierWert && armed == true) { |
|
|
if (progress[0].maxAmp >= Schwellwert_Alarm+kalibierWert && armed == true) { |
|
|
armed = false; |
|
|
armed = false; |
|
|
detectionReport = new DetectionReport("Mic1", "Audio", maxAmpPrint); |
|
|
detectionReport = new DetectionReport("Mic1", "Audio", maxAmpPrint); |
|
|
//reportViolation("Mic1", "Audio", maxAmpPrint); |
|
|
|
|
|
logger.log(""); |
|
|
|
|
|
logger.log("Alarm!"); |
|
|
|
|
|
logger.log(detectionReport.toString()); |
|
|
|
|
|
logger.log(""); |
|
|
|
|
|
|
|
|
reportViolation("Mic1", "Audio", maxAmpPrint); |
|
|
|
|
|
Log.d("1",detectionReport.toString()); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
y = FFT.fft(complexSignal); |
|
|
y = FFT.fft(complexSignal); |
|
|
|
|
|
|
|
|
mMaxFFTSample = 0.0; |
|
|
mMaxFFTSample = 0.0; |
|
|
// mPeakPos = 0; |
|
|
|
|
|
for(int i = 0; i < (mNumberOfFFTPoints/2); i++) |
|
|
for(int i = 0; i < (mNumberOfFFTPoints/2); i++) |
|
|
{ |
|
|
{ |
|
|
absSignal[i] = y[i].abs(); |
|
|
absSignal[i] = y[i].abs(); |
|
|
|
|
|
|
|
|
// if(absSignal[i] > mMaxFFTSample) |
|
|
// if(absSignal[i] > mMaxFFTSample) |
|
|
// { |
|
|
// { |
|
|
// mMaxFFTSample = absSignal[i]; |
|
|
// mMaxFFTSample = absSignal[i]; |
|
|
// // mPeakPos = i; |
|
|
|
|
|
// } |
|
|
// } |
|
|
} |
|
|
} |
|
|
|
|
|
|