Giter Club home page Giter Club logo

recorda's Introduction

Android Build

RECORDA

Overview

RECORDA is an Android application to record LabStreamingLayer (LSL) streams directly on a smartphone. Much like the LabRecorder, RECORDA detects LSL streams on the network and records them in the standard file format for LSL streams (XDF, "Extensible Data Format").

In our lab, RECORDA is mainly used in combination with SENDA, an Android app which streams data from all sensors that it finds on the phone. Typically, the built-in sensors include:

  • Accelerometer
  • Light
  • Proximity
  • Gravity
  • Linear Acceleration
  • Rotation Vector
  • Step Count

For a complete list and full specifications on the sensor data, please check out the official Android Sensor Documentary.

However, since RECORDA is using the LSL framework, it can record any kind of LSL stream, they can stem from seperate devices on the same network.

Getting Started With the App

Getting the APK file

Download the latest release and install the apk on your smartphone or tablet running Android 8.0 or higher.

Recording Data:

  • Start the app
  • You can choose a name for your recording in the settings. If you do not specify a name, a unique name for every new file is used
  • Click the refresh button to see available streams on the network
  • Select all streams you want to record
  • Start the recording by clicking on the start button
  • Once finished with your experiment, click on the Stop button and wait for the file to be written. Recorda will show a notification once the file is ready. This notification also shows the file location.

Quality Monitoring

During a recording, RECORDA monitors the quality of the selected streams. The quality can have three different states: good, laggy, or bad. Good streams are not highlighted in the UI with a specific color, whereas laggy streams will have a yellow background and bad streams will have a red background. If a good stream changes to laggy or bad, a heads-up notification is shown to the user, even if RECORDA runs in the background.

There are several checks that can lead to a change in quality:

  • If the LSL method pull_samples returns an error, the quality of the respective stream is set to bad. RECORDA will continue to call pull_samples, and if new samples are successfully received, the quality will switch back to good. This behaviour is implemented for regular, as well as irregular streams.

Additionally, for streams with a nominal regular sampling rate, two checks are being performed:

  • The duration in which we did not receive any samples (timeout value for laggy: 1.5 seconds, timeout value for bad: 7 seconds)
  • A comparison of the nominal sampling rate with the actual detected sampling rate in a recent time window (of 10s by default). If a lower sampling rate is being detected, the stream is considered laggy (threshold default value 90%). This metric never causes the bad state.

The worse result of these two metrics will be displayed in the UI.

Importantly, streams being declared as having an irregular nominal sampling rate by the sending side, are not checked with the timeout or deviating sampling rate checks.

XDF File Handling

Once data has been recorded, transfer the file to your computer and then open the file with a program of your choice. For Matlab, there are multiple XDF readers available, for example this one.

Build RECORDA

We suggest to download and install the latest release of the app as described above. However, if you want to build the app yourself, you can also clone this repository and then open the project with Android Studio.

Involved Tools

  • Developed with Android Studio Giraffe (2022.3.1)
  • Gradle >= 7.5
  • JNA >= 5.12
  • cmake >= 3.24.1 (install as SDK Tool in Android Studio)
  • Android NDK >= 25 (install in Android Studio)

Contributing

Please feel free to contribute to this project by creating an issue first and then sending a pull request against the issue.

Authors

The app is actively developed by the neuropsychology group of Stefan Debener in Oldenburg, Germany.

Active Developers

Initial Implementation

Ali Ayub Khan - AliAyub007

Adoption

  • Blum S, Hölle D, Bleichner MG, Debener S. Pocketable Labs for Everyone: Synchronized Multi-Sensor Data Streaming and Recording on Smartphones with the Lab Streaming Layer. Sensors. 2021; 21(23):8135. https://doi.org/10.3390/s21238135

recorda's People

Contributors

aliayub007 avatar pmaanen avatar s4rify avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

recorda's Issues

Display sampling rate in GUI

DIsplay the announced and the actual sampling rate if it deviates from the information transmitted in the stream header.
This information can be added to the stream name.

This issue will be assigned to Sören once he has a Github account.

xdf file structure

The xdf file seems to be not constructed correctly.
The lab recorders writes the xml header for all streams at the beginning of the xdf file.
Receiver interleaves xml headers and data.

CI is broken

#21 forced us to revert back to liblsl 1.15.0. This breaks CI builds. Either find a way to use a more current liblsl version or fix CI (1.16.2 build in CI but exposes #21...)

lsl configuration

Hi,

Can you tell me if there is an equivalent for the lsl_api.cfg file?
Is there a way to configure the devices that can broadcast to the recorder?

Thanks in advance

App cannot be installed on some phones

Error message: 'App not installed'.

  • This was only observed, when dragging the apk to the phone, not using the ADB interface
  • Idea: set ADB to verbose when installing
  • find out which phones
  • What is different in the apks?

NullPointerException when not all stream names are visible at once

ListView.getChildAt returns Null when the child is not currently visible.

2023-12-07 15:11:54.287 4139-4139 AndroidRuntime com.uol.neuropsy.LSLReceiver E FATAL EXCEPTION: main Process: com.uol.neuropsy.LSLReceiver, PID: 4139 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setBackgroundColor(int)' on a null object reference at de.uol.neuropsy.recorda.MainActivity.setColorBasedOnQuality(MainActivity.java:307) at de.uol.neuropsy.recorda.MainActivity.updateStreamQualityIndicators(MainActivity.java:296) at de.uol.neuropsy.recorda.MainActivity.access$400(MainActivity.java:48) at de.uol.neuropsy.recorda.MainActivity$7$1.run(MainActivity.java:272) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:313) at android.app.ActivityThread.main(ActivityThread.java:8762) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)

Selection of the file name

The user can select a file name in the settings. This name is not used in the code, though. Previously the file was always "default.xdf", currently the file name is determined automatically and adds time and date to "recording".

Developer documentation

Documentation on

  • how to set up the project in order to contribute features or bug fixes
  • how to navigate the code

I will investigate whether we can use a doc generation tool like Doxygen and whether we can integrate that into our CI/CD pipeline.

LSL Inlets Only Pull One Sample Each Time

In the LSLService class, each call of pull_chunk() is performed with an array size of one (1), effectively limiting the pulled chunk to a sample. This can possibly lead to a buffer overflow after some time.

File is written at the end of recording, not continuously

Functional: Save only after finishing the acquisition.

  • All stream contents are held in memory until the user stops the recording.
    Data is not written to the file during recording, but only at the end.

  • Disadvantage 1: Costs more memory, increases the
    probability of running out of memory out with long recordings. In this case the
    app suddenly crashes during a long recording session and the recording would
    lost without warning. Just as the app is implemented, there are
    no automatic safe shutdown before the memory runs out.

Disadvantage 2: If an error causes the app to crash during recording
or does not work as intended, the recording may be lost.
If the app were to write continuously to a file, the recordings made up to
failure written data can be recovered. "LabRecorder" makes this the
Example better.

Author: Sören Jeserich

Code quality: Duplication

Essential parts of the implementation are six times duplicated with only small differences between the copies. This has been fixed largely in in the (native) C code, but not in the Java code.

Rename apk file to 'Recorda'

The current name is 'app-debug'. We could also think about adding the version number for easier bug tracking.

Use consistent names

This app is sometimes called LSL_RECORDER, sometimes RECORDA, sometimes record-a.

Set up CI/CD pipeline

..and build the recorder on a Github build agent.
Add a deploy stage containing a recent build from the main branch and documentation. Set up build in regular intervals (we don't need nightly builds).

Data quality check and visual feedback

Implement a status indicator for incoming streams which shows the data quality, i.e.: - do the sampling rates announced in the stream and the actual samping rates match

  • do we receive any data at all
  • does the sampling rate vary greatly in short amounts of time
  • did we loose any data recently/during recording

This feature is similar to the status indicator in the desktop LSL Recorder.
This issue will be assigned to Sören once he has a Github account.

Add user documentation

Add screenshots to the readme file and a description on how to transfer files from phone to PC.

All streams are recorded to memory, independently of the user's choice

Functional: recording of all streams.
The app first makes a recording of all detected streams to memory, also those, which were explicitly deselected before.
Only when saving, only those choices are taken into account, and data from the irrelevant streams are discarded.

Disadvantage: Costs more memory, makes a failure more likely.

Author: Sören Jeserich

Only one stream is found when not connected to a WiFi

On some devices only one stream can be resolved if the phone is not connected to a WiFi. The Pocketable Labs release did not exhibit this behaviour. I made a test app https://github.com/pmaanen/HelloResolver. As the bug occurs also in this test app I do not think the bug is on our side. I am currently bisecting and found that this behaviour starts somewhere between liblsl 1.15.2 and 1.16.0. As liblsl 1.15.0 is the last version where this bug does not occur and which works w/ debug builds, we would have to revert to liblsl 1.15.0 if we can not make liblsl's authors fix it on their end soon.

Code quality: Non meaningful identifiers

Many names of variables and functions are chosen in a way, that it takes longer to recognize which tasks and contents they represent.
Example: A file name is stored in variables "temp" and "convertedValue". Other identifiers were "arr" and "arr2" and "i" and "i2".

Disadvantage 1: Understanding and changing the code causes more effort, because one has to go on "treasure hunt" again and again to trace back what is actually written into a variable.

Disadvantage 2: Risk of errors: Two not meaningful variables from the same type can be confused. Who knows what is in "i" and what is in "i2" if the variables were described at a remote code location?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.