Skip to content

Commit

Permalink
implement usage of meta model
Browse files Browse the repository at this point in the history
implement GPS usage
icon modified
layout improvements
  • Loading branch information
woheller69 committed Jan 30, 2024
1 parent e5c8256 commit 393bef7
Show file tree
Hide file tree
Showing 13 changed files with 392 additions and 221 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This work is licensed under a
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/"><img src="https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey.svg">

- This app is built on the [BirdNET framework](https://github.com/kahst/BirdNET-Lite) by [**@kahst**](https://github.com/kahst), published under CC BY NC SA 4.0 license
- It uses the TFLite library from [BirdNET-Analyzer](https://github.com/kahst/BirdNET-Analyzer/tree/main/checkpoints), published under CC BY NC SA 4.0 license
- At first start it downloads the BirdNet TFLite library, which is published under CC BY NC SA 4.0 license, from a different location
- Label files from BirdNET are used under GPL 3.0 with permission from the author
- It uses code from [Tensorflow](https://www.tensorflow.org/lite/examples) examples, published under [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0.html)

1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.tensorflow.lite.examples.soundclassifier">

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<application
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.tensorflow.lite.examples.soundclassifier;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.Toast;

import androidx.core.app.ActivityCompat;

public class Location {

private static LocationListener locationListenerGPS;

static void stopLocation(Context context){
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (locationListenerGPS!=null) locationManager.removeUpdates(locationListenerGPS);
locationListenerGPS=null;
}

static void requestLocation(Context context, SoundClassifier soundClassifier) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED && checkLocationProvider(context)) {
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (locationListenerGPS==null) locationListenerGPS = new LocationListener() {
@Override
public void onLocationChanged(android.location.Location location) {
soundClassifier.runMetaInterpreter(location);
}

@Deprecated
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}

@Override
public void onProviderEnabled(String provider) {
}

@Override
public void onProviderDisabled(String provider) {
}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000, 0, locationListenerGPS);
}
}

public static boolean checkLocationProvider(Context context) {
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Toast.makeText(context, "Error no GPS", Toast.LENGTH_SHORT).show();
return false;
} else {
return true;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ package org.tensorflow.lite.examples.soundclassifier
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import android.view.WindowManager
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
Expand All @@ -38,74 +37,56 @@ class MainActivity : AppCompatActivity() {
soundClassifier = SoundClassifier(this, binding, SoundClassifier.Options()).also {
it.lifecycleOwner = this
}
binding.gps.setText(getString(R.string.latitude)+": --.-- / " + getString(R.string.longitude) + ": --.--" )

with(binding) {
gainSlider.value = soundClassifier.audioGain
gainSlider.addOnChangeListener { _, value, _ ->
soundClassifier.audioGain = value
}
}

requestMicrophonePermission()
requestPermissions()
}

override fun onResume() {
super.onResume()
Location.requestLocation(this, soundClassifier)
if (checkMicrophonePermission()){
soundClassifier.start()
} else {
Toast.makeText(this, "Audio permission not granted :(", Toast.LENGTH_LONG).show()
}
if (!checkLocationPermission()){
Toast.makeText(this, "Location permission not granted :(", Toast.LENGTH_LONG).show()
}
keepScreenOn(true)
}

override fun onTopResumedActivityChanged(isTopResumedActivity: Boolean) {
// Handles "top" resumed event on multi-window environment
if (checkMicrophonePermission()) {
if (isTopResumedActivity) {
soundClassifier.start()
} else {
soundClassifier.stop()
}
}
override fun onPause() {
super.onPause()
Location.stopLocation(this)
if (soundClassifier.isRecording) soundClassifier.stop()
}

override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQUEST_RECORD_AUDIO) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Audio permission granted :)")
soundClassifier.start()
} else {
Log.e(TAG, "Audio permission not granted :(")
}
private fun checkMicrophonePermission(): Boolean {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO ) == PackageManager.PERMISSION_GRANTED) {
return true
} else {
return false
}
}

private fun checkMicrophonePermission(): Boolean {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.RECORD_AUDIO
) == PackageManager.PERMISSION_GRANTED
) {
private fun checkLocationPermission(): Boolean {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
return true
} else {
return false
}
}

private fun requestMicrophonePermission() {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.RECORD_AUDIO
) != PackageManager.PERMISSION_GRANTED
) {
requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), REQUEST_RECORD_AUDIO)
private fun requestPermissions() {
val perms = mutableListOf<String>()
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
perms.add(Manifest.permission.RECORD_AUDIO)
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
perms.add(Manifest.permission.ACCESS_COARSE_LOCATION)
}
if (!perms.isEmpty()) requestPermissions(perms.toTypedArray(), REQUEST_PERMISSIONS)
}

private fun keepScreenOn(enable: Boolean) =
Expand All @@ -116,7 +97,6 @@ class MainActivity : AppCompatActivity() {
}

companion object {
const val REQUEST_RECORD_AUDIO = 1337
private const val TAG = "BirdNET-lite"
const val REQUEST_PERMISSIONS = 1337
}
}
Loading

0 comments on commit 393bef7

Please sign in to comment.