Created
September 5, 2022 11:05
-
-
Save berndporr/c394240401cf510d8c307558259e67d9 to your computer and use it in GitHub Desktop.
Constant logging of sound to firebase with a background worker on Android (sort of a hack)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In the main Application schedule the Worker as a one-off task and then re-schedule the task again: | |
final OneTimeWorkRequest recWorkRequest = | |
new OneTimeWorkRequest.Builder(RecWorker.class) | |
.build(); | |
WorkManager | |
.getInstance(getApplicationContext()) | |
.enqueueUniqueWork(RecWorker.TAG, ExistingWorkPolicy.REPLACE,recWorkRequest); | |
Important here is that the Policy is REPLACE so that really just one of these Workers are running. | |
In the workmanager just re-submit the one-off task over and over. Note that there is no guarantee | |
when it's submitted. | |
Use firebase callbacks to get your RMS once it has been measured in realtime or get it offline from firebase. :) | |
---------------------------------------------------------------------------------------------------------- | |
public class RecWorker extends Worker { | |
public final static String TAG = RecWorker.class.getSimpleName(); | |
final int SAMPLE_RATE = 48000; | |
final int chunkLength = 60; // sec | |
final int bufferSize = SAMPLE_RATE * chunkLength; | |
final double[][] AweightingSOS = { | |
{ | |
7.545506848211794848e-01, 0.000000000000000000e+00, 0.000000000000000000e+00, 1.000000000000000000e+00, -4.053225490428303823e-01, 4.107159219064440703e-02 | |
}, | |
{ | |
1.000000000000000000e+00, -2.000000000000000000e+00, 1.000000000000000000e+00, 1.000000000000000000e+00, -1.893938990943602185e+00, 8.952272888746266588e-01 | |
}, | |
{ | |
1.000000000000000000e+00, -2.000000000000000000e+00, 1.000000000000000000e+00, 1.000000000000000000e+00, -1.994614459236600190e+00, 9.946217102489287587e-01 | |
}, | |
}; | |
final String RMS_COLLECTION = "audio"; | |
final OneTimeWorkRequest recWorkRequest = | |
new OneTimeWorkRequest.Builder(RecWorker.class) | |
.build(); | |
public RecWorker( | |
@NonNull Context context, | |
@NonNull WorkerParameters params) { | |
super(context, params); | |
} | |
private void addToFirestore(String collection, Map<String, Object> data) { | |
FirebaseFirestore firestore = FirebaseFirestore.getInstance(); | |
try { | |
firestore.collection(collection).add(data); | |
} catch (Exception e) { | |
Log.e(TAG,"Firebase couldn't save data.",e); | |
return; | |
} | |
Log.d(TAG,"Firebase: data saved: "+collection); | |
} | |
@NonNull | |
@Override | |
public Result doWork() { | |
final SOSCascade cust = new SOSCascade(); | |
cust.setup(AweightingSOS); | |
short[] audioBuffer = new short[bufferSize]; | |
@SuppressLint("MissingPermission") | |
final AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, | |
SAMPLE_RATE, | |
AudioFormat.CHANNEL_IN_MONO, | |
AudioFormat.ENCODING_PCM_16BIT, | |
bufferSize); | |
if (record.getState() != AudioRecord.STATE_INITIALIZED) { | |
Log.e(TAG, "Audio Record can't initialize!"); | |
try { | |
Thread.sleep(1000 * chunkLength); | |
} catch (Exception e) { | |
Log.e(TAG,"Could not sleep",e); | |
} | |
WorkManager | |
.getInstance(getApplicationContext()) | |
.enqueueUniqueWork(RecWorker.TAG, ExistingWorkPolicy.APPEND,recWorkRequest); | |
return Result.success(); | |
} | |
record.startRecording(); | |
Log.d(TAG, "Start recording"); | |
long shortsRead = 0; | |
int numberOfShort = record.read(audioBuffer, 0, audioBuffer.length); | |
record.stop(); | |
record.release(); | |
Log.d(TAG, "Finished recording"); | |
double rms = 0; | |
double max = 0; | |
int n = 0; | |
for (int i = 0; i < numberOfShort; i++) { | |
double a = ((double) (audioBuffer[i])) / 32768.0; | |
a = Math.abs(a); | |
if (a > max) { | |
max = a; | |
} | |
a = cust.filter(a); | |
//Log.v(TAG,"value="+a); | |
if (i > (SAMPLE_RATE / 20)) { | |
rms = rms + a * a; | |
n++; | |
} | |
} | |
if (n > 0) { | |
rms = rms / (float) n; | |
rms = (float) Math.sqrt(rms); | |
Log.v(TAG, "RMS = " + rms); | |
Log.v(TAG, "max = " + max); | |
Map<String, Object> data = new HashMap<>(); | |
data.put("timestamp", System.currentTimeMillis()); | |
data.put("RMS", (float)rms); | |
addToFirestore(RMS_COLLECTION, data); | |
} else { | |
Log.e(TAG,"No samples from the sound card!"); | |
} | |
WorkManager | |
.getInstance(getApplicationContext()) | |
.enqueueUniqueWork(RecWorker.TAG, ExistingWorkPolicy.APPEND,recWorkRequest); | |
return Result.success(); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment