├── .github ├── ISSUE_TEMPLATE │ ├── bug.md │ ├── feature-request.md │ └── general-issues.md ├── PULL_REQUEST_TEMPLATE └── release-drafter.yml ├── .gitignore ├── .travis.yml ├── Gemfile ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── neurolab │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── ic_launcher_round-web.png │ ├── java │ │ └── io │ │ │ └── neurolab │ │ │ ├── activities │ │ │ ├── AboutUsActivity.java │ │ │ ├── DataLoggerActivity.java │ │ │ ├── DeviceInstructionsActivity.java │ │ │ ├── FocusParentActivity.java │ │ │ ├── MeditationActivity.java │ │ │ ├── MeditationHome.java │ │ │ ├── MeditationListActivity.java │ │ │ ├── MemoryGraphParent.java │ │ │ ├── OnBoardingActivity.java │ │ │ ├── PinLayoutActivity.java │ │ │ ├── ProgramModeActivity.java │ │ │ ├── RelaxParentActivity.java │ │ │ ├── SettingsActivity.java │ │ │ ├── ShareDataActivity.java │ │ │ └── TestModeActivity.java │ │ │ ├── adapters │ │ │ ├── DataLoggerListAdapter.java │ │ │ └── MeditationListAdapter.java │ │ │ ├── communication │ │ │ ├── DataReceiver.java │ │ │ ├── USBCommunicationHandler.java │ │ │ └── bluetooth │ │ │ │ ├── BluetoothConnectionManager.java │ │ │ │ └── BluetoothTestActivity.java │ │ │ ├── fragments │ │ │ ├── ConfigFragment.java │ │ │ ├── FocusVisualFragment.java │ │ │ ├── MemoryGraphFragment.java │ │ │ ├── NeuroSettingsFragment.java │ │ │ ├── RelaxVisualFragment.java │ │ │ ├── SpectrumFragment.java │ │ │ └── StatisticsFragment.java │ │ │ ├── gui │ │ │ ├── CustomOutputView.java │ │ │ ├── CustomSpaceView.java │ │ │ ├── GraphicBgRenderer.java │ │ │ ├── LongtermAnalyzer.java │ │ │ ├── NFBSettingsWindow.java │ │ │ ├── SerialForwardMask.java │ │ │ ├── SpectralViewPanel.java │ │ │ ├── ThresholdRenderer.java │ │ │ └── VJ.java │ │ │ ├── interfaces │ │ │ ├── DataReceiver.java │ │ │ ├── FFTData.java │ │ │ ├── InputInterface.java │ │ │ ├── Recorder.java │ │ │ └── Task.java │ │ │ ├── main │ │ │ ├── DeviceConnector.java │ │ │ ├── FakeLock.java │ │ │ ├── LongtermFeedbackGraph.java │ │ │ ├── LongtermGraph.java │ │ │ ├── NFBGraph.java │ │ │ ├── NFBServer.java │ │ │ ├── NeuroLab.java │ │ │ ├── PlaybackStream.java │ │ │ ├── ProgramModeActivity.java │ │ │ ├── SampleSlide.java │ │ │ ├── network │ │ │ │ ├── OSCForwarder.java │ │ │ │ ├── OSCReceiver.java │ │ │ │ ├── OSCReceiverFragment.java │ │ │ │ └── SerialForwarder.java │ │ │ ├── output │ │ │ │ ├── audio │ │ │ │ │ ├── AudioFeedback.java │ │ │ │ │ ├── FocusAudioFeedback.java │ │ │ │ │ ├── JSynThread.java │ │ │ │ │ ├── MediaPlayerHolder.java │ │ │ │ │ ├── PlaybackInfoListener.java │ │ │ │ │ └── PlayerAdapter.java │ │ │ │ ├── feedback │ │ │ │ │ └── Feedback.java │ │ │ │ └── visual │ │ │ │ │ ├── FocusOMeter.java │ │ │ │ │ ├── FocusOMeterGLRenderer.java │ │ │ │ │ ├── LongtermFFTVisualizer.java │ │ │ │ │ ├── NeuroGameRenderer.java │ │ │ │ │ ├── NeuroGameVisuals.java │ │ │ │ │ ├── OSCFeedback.java │ │ │ │ │ ├── SpaceAnimationVisuals.java │ │ │ │ │ ├── ZenSpaceGLRenderer.java │ │ │ │ │ └── ZenSpaceVisuals.java │ │ │ └── task │ │ │ │ ├── BinaryFileOutputTask.java │ │ │ │ ├── LongtermFeedbackTrackerTask.java │ │ │ │ ├── OscForwardTask.java │ │ │ │ └── SerialForwardTask.java │ │ │ ├── model │ │ │ ├── Config.java │ │ │ ├── DataPacket.java │ │ │ ├── DefaultFFTData.java │ │ │ ├── FFTPreprocessor.java │ │ │ ├── FileOutputTask.java │ │ │ ├── GenericFeedbackSettings.java │ │ │ ├── NFBProcessor.java │ │ │ └── OSCForwardMask.java │ │ │ ├── settings │ │ │ ├── ConfigurationSettings.java │ │ │ ├── DefaultAudioFeedbackSettings.java │ │ │ ├── FeedbackSettings.java │ │ │ ├── FocusFeedbackSettings.java │ │ │ ├── NFBRelaxSettings.java │ │ │ ├── NeuroSettings.java │ │ │ ├── OSCSettings.java │ │ │ ├── RelaxFeedbackSettings.java │ │ │ └── ServerSettings.java │ │ │ ├── tools │ │ │ ├── Animations.java │ │ │ ├── BaselineCorrectionFunction.java │ │ │ ├── ColorMap.java │ │ │ ├── ResourceManager.java │ │ │ ├── Utils.java │ │ │ └── WindowFunction.java │ │ │ └── utilities │ │ │ ├── ConfigUtils.java │ │ │ ├── FilePathUtil.java │ │ │ ├── Filter.java │ │ │ ├── FrequencyProcessor.java │ │ │ ├── LocationTracker.java │ │ │ ├── MathBasics.java │ │ │ ├── NeuroUtils.java │ │ │ ├── PermissionUtils.java │ │ │ └── PinDetails.java │ └── res │ │ ├── anim │ │ ├── slide_down.xml │ │ └── slide_up.xml │ │ ├── color │ │ └── bottom_tab_item_foreground.xml │ │ ├── drawable-nodpi-v4 │ │ ├── bg_focus_background.jpg │ │ ├── universe_bg.png │ │ └── yantra.png │ │ ├── drawable-v21 │ │ ├── ic_menu_send.xml │ │ └── ic_menu_share.xml │ │ ├── drawable-xxhdpi │ │ └── meditation_bg.jpg │ │ ├── drawable │ │ ├── app_logo.JPG │ │ ├── back_pin_layout.png │ │ ├── bg_card_focus.xml │ │ ├── bg_card_meditation.xml │ │ ├── bg_card_mem_graph.xml │ │ ├── bg_card_relax.xml │ │ ├── button_bg_rounded.xml │ │ ├── dialog_body_background.xml │ │ ├── dialog_header_background.xml │ │ ├── front_pin_layout.png │ │ ├── game_one_pic.png │ │ ├── gradient_focus.xml │ │ ├── gradient_meditation.xml │ │ ├── gradient_mem_graph.xml │ │ ├── gradient_relax.xml │ │ ├── ic_brain.xml │ │ ├── ic_bug_report_black_24dp.xml │ │ ├── ic_card_focus.xml │ │ ├── ic_card_meditation.xml │ │ ├── ic_card_mem_graph.xml │ │ ├── ic_card_relax.xml │ │ ├── ic_depressed.xml │ │ ├── ic_device_connected.xml │ │ ├── ic_disconnected.xml │ │ ├── ic_edit.xml │ │ ├── ic_file_black.xml │ │ ├── ic_graph.xml │ │ ├── ic_happiness.xml │ │ ├── ic_happy.xml │ │ ├── ic_happy_black.xml │ │ ├── ic_import.xml │ │ ├── ic_indicator.xml │ │ ├── ic_info.xml │ │ ├── ic_insert_drive_file_black_24dp.xml │ │ ├── ic_intro_guide1.xml │ │ ├── ic_intro_guide2.xml │ │ ├── ic_intro_guide3.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_lg_break.xml │ │ ├── ic_offline_dot.xml │ │ ├── ic_pause_meditate.xml │ │ ├── ic_person_black.xml │ │ ├── ic_play.xml │ │ ├── ic_play_meditate.xml │ │ ├── ic_record_stop_white.xml │ │ ├── ic_record_white.xml │ │ ├── ic_refresh_meditate.xml │ │ ├── ic_rocket_focus.xml │ │ ├── ic_rocket_focus_indicator.xml │ │ ├── ic_sad.xml │ │ ├── ic_settings.xml │ │ ├── ic_sh_break.xml │ │ ├── ic_sleep.xml │ │ ├── ic_spectrum.xml │ │ ├── ic_starsone.xml │ │ ├── ic_starsthree.xml │ │ ├── ic_starstwo.xml │ │ ├── ic_startup.xml │ │ ├── ic_stats.xml │ │ ├── ic_stop.xml │ │ ├── ic_travel.xml │ │ ├── ic_update.xml │ │ ├── icons8_usb_connected_100.png │ │ ├── icons_usb_disconnected_100.png │ │ ├── neurolab_back_colormap.png │ │ ├── neurolab_front_colormap.png │ │ ├── side_nav_bar.xml │ │ ├── splash_image.png │ │ └── splash_screen.xml │ │ ├── font │ │ └── montserrat.xml │ │ ├── layout-land │ │ ├── activity_focus_parent.xml │ │ ├── activity_meditation.xml │ │ ├── activity_relax_parent.xml │ │ └── content_main.xml │ │ ├── layout │ │ ├── activity_bluetooth_test.xml │ │ ├── activity_data_logger.xml │ │ ├── activity_focus_parent.xml │ │ ├── activity_main.xml │ │ ├── activity_meditation.xml │ │ ├── activity_meditation_home.xml │ │ ├── activity_meditation_list.xml │ │ ├── activity_memory_graph_parent.xml │ │ ├── activity_pin_layout.xml │ │ ├── activity_program_mode.xml │ │ ├── activity_relax_parent.xml │ │ ├── activity_settings.xml │ │ ├── activity_share_data.xml │ │ ├── activity_test_mode.xml │ │ ├── app_bar_main.xml │ │ ├── card_focus.xml │ │ ├── card_meditation.xml │ │ ├── card_mem_graph.xml │ │ ├── card_relax.xml │ │ ├── content_main.xml │ │ ├── content_test_mode.xml │ │ ├── device_instruction_layout.xml │ │ ├── fragment_focus_visual.xml │ │ ├── fragment_intro1.xml │ │ ├── fragment_intro2.xml │ │ ├── fragment_intro3.xml │ │ ├── fragment_memory_graph.xml │ │ ├── fragment_oscreceiver.xml │ │ ├── fragment_relax_visual.xml │ │ ├── fragment_spectrum.xml │ │ ├── fragment_statistics.xml │ │ ├── item_meditation_layout.xml │ │ ├── logged_data_item.xml │ │ ├── nav_header_main.xml │ │ ├── pin_description_dialog.xml │ │ ├── progress_dialog_layout.xml │ │ ├── spectrum_info_layout.xml │ │ └── stat_items.xml │ │ ├── menu │ │ ├── activity_main_drawer.xml │ │ ├── focus_utility_menu.xml │ │ ├── main.xml │ │ ├── navigation_mem_graph.xml │ │ ├── share_menu.xml │ │ ├── spectrum_menu.xml │ │ └── utility_menu.xml │ │ ├── mipmap-anydpi-v26 │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── raw │ │ ├── breathing_space_practice.mp3 │ │ ├── calm_the_mind.mp3 │ │ ├── easing_stress.mp3 │ │ ├── focus_screen_bg.m4v │ │ ├── sample1.csv │ │ ├── sample2.csv │ │ ├── sample3.csv │ │ ├── sample4.csv │ │ └── soften_and_relax.mp3 │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values │ │ ├── baud_rates_array.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── drawables.xml │ │ ├── font_certs.xml │ │ ├── preloaded_fonts.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── device_filter.xml │ │ ├── filepaths.xml │ │ ├── fragment_config_settings.xml │ │ └── fragment_neuro_settings.xml │ └── test │ └── java │ └── io │ └── neurolab │ └── ExampleUnitTest.java ├── arduino └── sketch_read_transmit_from_sd │ ├── k24bit.csv │ └── sketch_read_transmit_from_sd.ino ├── build.gradle ├── datasets ├── Dataset1 │ ├── About.txt │ ├── Dataset1.csv │ └── Dataset1.png ├── Dataset10 │ ├── About.txt │ ├── Dataset10.csv │ └── Dataset10.png ├── Dataset11 │ ├── About.txt │ ├── Dataset11.csv │ └── Dataset11.png ├── Dataset12 │ ├── About.txt │ ├── Dataset12.csv │ └── Dataset12.png ├── Dataset13 │ ├── About.txt │ ├── Dataset13.csv │ └── Dataset13.png ├── Dataset14 │ ├── About.txt │ ├── Dataset14.csv │ └── Dataset14.png ├── Dataset15 │ ├── About.txt │ ├── Dataset15.csv │ └── Dataset15.png ├── Dataset16 │ ├── About.txt │ ├── Dataset16.csv │ └── Dataset16.png ├── Dataset17 │ ├── About.txt │ ├── Dataset17.csv │ └── Dataset17.png ├── Dataset18 │ ├── About.txt │ ├── Dataset18.csv │ └── Dataset18.png ├── Dataset19 │ ├── About.txt │ ├── Dataset19.csv │ └── Dataset19.png ├── Dataset2 │ ├── About.txt │ ├── Dataset2.csv │ └── Dataset2.png ├── Dataset20 │ ├── About.txt │ ├── Dataset20.csv │ └── Dataset20.png ├── Dataset21 │ ├── About.txt │ ├── Dataset21.csv │ └── Dataset21.png ├── Dataset22 │ ├── About.txt │ ├── Dataset22.csv │ └── Dataset22.png ├── Dataset23 │ ├── About.txt │ ├── Dataset23.csv │ └── Dataset23.png ├── Dataset24 │ ├── About.txt │ ├── Dataset24.csv │ └── Dataset24.png ├── Dataset25 │ ├── About.txt │ ├── Dataset25.csv │ └── Dataset25.png ├── Dataset26 │ ├── About.txt │ ├── Dataset26.csv │ └── Dataset26.png ├── Dataset27 │ ├── About.txt │ ├── Dataset27.csv │ └── Dataset27.png ├── Dataset28 │ ├── About.txt │ ├── Dataset28.csv │ └── Dataset28.png ├── Dataset29 │ ├── About.txt │ ├── Dataset29.csv │ └── Dataset29.png ├── Dataset3 │ ├── About.txt │ ├── Dataset3.csv │ └── Dataset3.png ├── Dataset30 │ ├── About.txt │ ├── Dataset30.csv │ └── Dataset30.png ├── Dataset31 │ ├── About.txt │ ├── Dataset31.csv │ └── Dataset31.png ├── Dataset32 │ ├── About.txt │ ├── Dataset32.csv │ └── Dataset32.png ├── Dataset33 │ ├── About.txt │ ├── Dataset33.csv │ └── Dataset33.png ├── Dataset34 │ ├── About.txt │ ├── Dataset34.csv │ └── Dataset34.png ├── Dataset4 │ ├── About.txt │ ├── Dataset4.csv │ └── Dataset4.png ├── Dataset5 │ ├── About.txt │ ├── Dataset5.csv │ └── Dataset5.png ├── Dataset6 │ ├── About.txt │ ├── Dataset6.csv │ └── Dataset6.png ├── Dataset7 │ ├── About.txt │ ├── Dataset7.csv │ └── Dataset7.png ├── Dataset8 │ ├── About.txt │ ├── Dataset8.csv │ └── Dataset8.png └── Dataset9 │ ├── About.txt │ ├── Dataset9.csv │ └── Dataset9.png ├── docs └── images │ ├── about_screen.jpeg │ ├── card-backgrounds │ ├── bg_card_focus.svg │ ├── bg_card_mem_graph.svg │ └── bg_card_relax.svg │ ├── focus_mode.png │ ├── home_screen.jpeg │ ├── meditate.jpg │ ├── memory_graph_sc.jpeg │ ├── nav_menu.jpeg │ ├── pinlayout.jpeg │ ├── relax.jpg │ ├── settings_screen.jpeg │ ├── spectrum.png │ ├── start_screen_1.jpeg │ └── statistics.jpeg ├── fastlane ├── Appfile ├── Fastfile └── metadata │ └── android │ └── en-US │ ├── changelogs │ └── 1 │ ├── full_description.txt │ ├── images │ ├── icon.png │ └── phoneScreenshots │ │ ├── focus_mode.png │ │ ├── launcher_screen.png │ │ ├── meditate.jpg │ │ ├── memory_graph_sc.jpeg │ │ ├── relax.jpg │ │ └── settings_screen.jpeg │ ├── short_description.txt │ └── title.txt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── scripts ├── prep-key.sh └── upload-apk.sh └── settings.gradle /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Report a bug 3 | about: Report a bug which you have noticed, to help us improve NeuroLab Android app 4 | title: '' 5 | labels: Bug 6 | assignees: 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | 12 | 13 | **Expected Behavior** 14 | 15 | 16 | **Steps to reproduce it** 17 | 18 | 19 | **LogCat for the issue** 20 | 21 | 22 | **Screenshots of the issue** 23 | 24 | 25 | **System Information** 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
Devicee.g. Moto G5 Plus
Android version/OSeg: Oreo 8.1
34 | 35 | **Would you like to work on the issue?** 36 | 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for the project Neurolab 4 | title: '' 5 | labels: Feature 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Actual Behaviour.** 11 | 12 | 13 | **Expected Behaviour** 14 | 15 | 16 | **Steps to reproduce it** 17 | 18 | 19 | **Additional context** 20 | 21 | 22 | **Would you like to work on the issue?** 23 | 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/general-issues.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: General issues 3 | about: Issues related to docs, workflow, dependency and others 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the issue** 11 | 12 | 13 | 14 | **Would you like to work on the issue?** 15 | 16 | 17 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | Fixes #[Add issue number here. Note: This will automatically closes the issue. If you do not solve the issue entirely, please change the message to e.g. "First steps for issues #IssueNumber] 2 | 3 | **Changes**: [Add here what changes were made in this issue and if possible provide links.] 4 | 5 | **Screenshot/s for the changes**: [Add screenshot/s of the layout where you made changes or a `*.gif` containing a demonstration. Use `` to add images] 6 | 7 | **Checklist**: [Please tick following check boxes with `[x]` if the respective task is completed] 8 | - [ ] I have used resources from `strings.xml`, `dimens.xml` and `colors.xml` without hard-coding them 9 | - [ ] No modifications done at the end of resource files `strings.xml`, `dimens.xml` or `colors.xml` 10 | - [ ] I have reformatted code in every file included in this PR [CTRL+ALT+L] 11 | - [ ] My code does not contain any extra lines or extra spaces 12 | - [ ] I have requested reviews from other members 13 | 14 | **APK for testing**: [Compress the `app-debug.apk` file into a `.rar` or `.zip` file and upload it here] 15 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: 'v$NEXT_PATCH_VERSION 🌈' 2 | tag-template: 'v$NEXT_PATCH_VERSION' 3 | categories: 4 | - title: '🚀 Features' 5 | labels: 6 | - 'feature' 7 | - 'enhancement' 8 | - title: '🐛 Bug Fixes' 9 | labels: 10 | - 'fix' 11 | - 'bug' 12 | - title: '🧰 Maintenance' 13 | label: 'chore' 14 | - title: Dependencies and Libraries 15 | label: dependencies 16 | change-template: '- $TITLE @$AUTHOR (#$NUMBER)' 17 | template: | 18 | ## Changes 19 | 20 | $CHANGES 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/*.iml 2 | .gradle 3 | /local.properties 4 | **/.idea/** 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | 3 | sudo: false 4 | 5 | jdk: oraclejdk8 6 | 7 | dist : trusty 8 | 9 | android: 10 | components: 11 | - tools 12 | - platform-tools 13 | - android-29 14 | - build-tools-29.0.2 15 | 16 | before_cache: 17 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 18 | 19 | cache: 20 | directories: 21 | - "${TRAVIS_BUILD_DIR}/gradle/caches/" 22 | - "${TRAVIS_BUILD_DIR}/gradle/wrapper/dists/" 23 | - "$HOME/.gradle/caches/" 24 | - "$HOME/.gradle/wrapper/" 25 | 26 | script: 27 | - ./gradlew build --stacktrace 28 | 29 | after_success: 30 | - bash scripts/prep-key.sh 31 | - bash scripts/upload-apk.sh 32 | 33 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/io/neurolab/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package io.neurolab; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("io.neurolab", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/ic_launcher_round-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/ic_launcher_round-web.png -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/activities/DeviceInstructionsActivity.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.activities; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | 7 | import io.neurolab.R; 8 | 9 | public class DeviceInstructionsActivity extends AppCompatActivity { 10 | 11 | @Override 12 | protected void onCreate(@Nullable Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.device_instruction_layout); 15 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 16 | } 17 | 18 | @Override 19 | public boolean onSupportNavigateUp(){ 20 | finish(); 21 | return true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/activities/FocusParentActivity.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.activities; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.design.widget.FloatingActionButton; 6 | import android.support.v7.app.AppCompatActivity; 7 | 8 | import io.neurolab.R; 9 | import io.neurolab.fragments.FocusVisualFragment; 10 | import io.neurolab.main.NeuroLab; 11 | 12 | public class FocusParentActivity extends AppCompatActivity { 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_focus_parent); 18 | setTitle(R.string.focus); 19 | 20 | FloatingActionButton gameButton = findViewById(R.id.play_focus_game); 21 | 22 | gameButton.setOnClickListener(v -> startProgramModeActivity(FocusVisualFragment.FOCUS_FLAG)); 23 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 24 | } 25 | 26 | private void startProgramModeActivity(String mode) { 27 | Intent intent = new Intent(this, ProgramModeActivity.class); 28 | Bundle bundle = new Bundle(); 29 | bundle.putString(ProgramModeActivity.INTENT_KEY_PROGRAM_MODE, mode); 30 | intent.putExtras(bundle); 31 | startActivity(intent); 32 | finish(); 33 | } 34 | 35 | @Override 36 | public boolean onSupportNavigateUp(){ 37 | onBackPressed(); 38 | return true; 39 | } 40 | 41 | @Override 42 | public void onBackPressed() { 43 | super.onBackPressed(); 44 | startActivity(new Intent(this, NeuroLab.class)); 45 | finish(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/activities/MeditationHome.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.activities; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.CardView; 7 | 8 | import io.neurolab.R; 9 | import io.neurolab.main.NeuroLab; 10 | 11 | public class MeditationHome extends AppCompatActivity { 12 | 13 | public static final String MEDITATION_DIR_KEY = "MEDITATION"; 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_meditation_home); 19 | setTitle(R.string.meditation); 20 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 21 | 22 | CardView happinessView = findViewById(R.id.happy_card); 23 | CardView depressionView = findViewById(R.id.depression_card); 24 | CardView sleepView = findViewById(R.id.sleep_card); 25 | CardView travelView = findViewById(R.id.travel_card); 26 | CardView shBreakView = findViewById(R.id.sh_break_card); 27 | CardView lgBreakView = findViewById(R.id.lg_break_card); 28 | 29 | setMeditationCategoryIntent(happinessView); 30 | setMeditationCategoryIntent(depressionView); 31 | setMeditationCategoryIntent(sleepView); 32 | setMeditationCategoryIntent(travelView); 33 | setMeditationCategoryIntent(shBreakView); 34 | setMeditationCategoryIntent(lgBreakView); 35 | } 36 | 37 | @Override 38 | public boolean onSupportNavigateUp(){ 39 | onBackPressed(); 40 | return true; 41 | } 42 | 43 | @Override 44 | public void onBackPressed() { 45 | super.onBackPressed(); 46 | startActivity(new Intent(this, NeuroLab.class)); 47 | finish(); 48 | } 49 | 50 | private void setMeditationCategoryIntent(CardView view) { 51 | view.setOnClickListener(v -> { 52 | startActivity(new Intent(MeditationHome.this, MeditationListActivity.class)); 53 | finish(); 54 | } 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/activities/OnBoardingActivity.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.activities; 2 | 3 | import android.content.SharedPreferences; 4 | import android.os.Bundle; 5 | import android.preference.PreferenceManager; 6 | import android.support.annotation.Nullable; 7 | import android.support.v4.app.Fragment; 8 | import android.support.v4.content.ContextCompat; 9 | import android.view.Window; 10 | import android.view.WindowManager; 11 | 12 | import com.github.paolorotolo.appintro.AppIntro2; 13 | 14 | import io.neurolab.R; 15 | import io.neurolab.main.SampleSlide; 16 | 17 | public class OnBoardingActivity extends AppIntro2 { 18 | 19 | private static final String COMPLETED_ONBOARDING_PREF_NAME = "on_boarding_pref"; 20 | 21 | @Override 22 | protected void onCreate(@Nullable Bundle savedInstanceState) { 23 | // disabling the status bar 24 | requestWindowFeature(Window.FEATURE_NO_TITLE); 25 | this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); 26 | 27 | super.onCreate(savedInstanceState); 28 | 29 | // add On Boarding Fragments here 30 | addSlide(SampleSlide.newInstance(R.layout.fragment_intro1)); 31 | addSlide(SampleSlide.newInstance(R.layout.fragment_intro2)); 32 | addSlide(SampleSlide.newInstance(R.layout.fragment_intro3)); 33 | 34 | // color of the indicator dots (on/off) 35 | setIndicatorColor(ContextCompat.getColor(this, R.color.on_boarding_activity_indicator_on), ContextCompat.getColor(this, R.color.on_boarding_activity_indicator_off)); 36 | 37 | // setting the transition animation 38 | setFadeAnimation(); 39 | } 40 | 41 | @Override 42 | public void onSkipPressed(Fragment currentFragment) { 43 | super.onSkipPressed(currentFragment); 44 | markVisited(); 45 | finish(); 46 | } 47 | 48 | // this method marks the visited state by populating the shared preferences 49 | private void markVisited(){ 50 | SharedPreferences.Editor sharedPreferencesEditor = 51 | PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit(); 52 | sharedPreferencesEditor.putBoolean( 53 | COMPLETED_ONBOARDING_PREF_NAME, true); 54 | sharedPreferencesEditor.apply(); 55 | } 56 | 57 | public static String getOnBoardingPrefKey(){ 58 | return COMPLETED_ONBOARDING_PREF_NAME; 59 | } 60 | 61 | @Override 62 | public void onDonePressed() { 63 | super.onDonePressed(); 64 | markVisited(); 65 | finish(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/activities/RelaxParentActivity.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.activities; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.design.widget.FloatingActionButton; 6 | import android.support.v7.app.AppCompatActivity; 7 | 8 | import io.neurolab.R; 9 | import io.neurolab.fragments.RelaxVisualFragment; 10 | import io.neurolab.main.NeuroLab; 11 | 12 | public class RelaxParentActivity extends AppCompatActivity { 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_relax_parent); 18 | setTitle(R.string.relax); 19 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 20 | 21 | FloatingActionButton gameButton = findViewById(R.id.play_relax_illusion); 22 | 23 | gameButton.setOnClickListener(v -> startProgramModeActivity(RelaxVisualFragment.RELAX_PROGRAM_FLAG)); 24 | } 25 | 26 | private void startProgramModeActivity(String mode) { 27 | Intent intent = new Intent(this, ProgramModeActivity.class); 28 | Bundle bundle = new Bundle(); 29 | bundle.putString(ProgramModeActivity.INTENT_KEY_PROGRAM_MODE, mode); 30 | intent.putExtras(bundle); 31 | startActivity(intent); 32 | finish(); 33 | } 34 | 35 | @Override 36 | public boolean onSupportNavigateUp(){ 37 | onBackPressed(); 38 | return true; 39 | } 40 | 41 | @Override 42 | public void onBackPressed() { 43 | super.onBackPressed(); 44 | startActivity(new Intent(this, NeuroLab.class)); 45 | finish(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/activities/SettingsActivity.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.activities; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v4.app.FragmentManager; 6 | import android.support.v4.app.FragmentTransaction; 7 | import android.support.v7.app.AppCompatActivity; 8 | 9 | import io.neurolab.R; 10 | import io.neurolab.fragments.ConfigFragment; 11 | import io.neurolab.fragments.NeuroSettingsFragment; 12 | import io.neurolab.main.NeuroLab; 13 | 14 | public class SettingsActivity extends AppCompatActivity { 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_settings); 20 | setTitle(getResources().getString(R.string.action_settings)); 21 | 22 | FragmentManager fragmentManager = getSupportFragmentManager(); 23 | FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 24 | fragmentTransaction.add(R.id.container_edit_text_preferences, new NeuroSettingsFragment()) 25 | .add(R.id.container_config_params, new ConfigFragment()) 26 | .commit(); 27 | } 28 | 29 | @Override 30 | public void onBackPressed() { 31 | super.onBackPressed(); 32 | startActivity(new Intent(this, NeuroLab.class)); 33 | finish(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/fragments/ConfigFragment.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.fragments; 2 | 3 | import android.content.SharedPreferences; 4 | import android.os.Bundle; 5 | import android.support.v14.preference.SwitchPreference; 6 | import android.support.v7.preference.CheckBoxPreference; 7 | import android.support.v7.preference.Preference; 8 | import android.support.v7.preference.PreferenceFragmentCompat; 9 | import android.widget.Toast; 10 | 11 | import io.neurolab.R; 12 | import io.neurolab.main.NeuroLab; 13 | 14 | import static io.neurolab.main.NeuroLab.DEV_MODE_KEY; 15 | 16 | public class ConfigFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener, Preference.OnPreferenceChangeListener { 17 | 18 | private SwitchPreference developerModeCheck; 19 | private SharedPreferences sharedPreferences; 20 | 21 | @Override 22 | public void onCreatePreferences(Bundle bundle, String s) { 23 | setPreferencesFromResource(R.xml.fragment_config_settings, s); 24 | 25 | developerModeCheck = (SwitchPreference) getPreferenceScreen().findPreference(DEV_MODE_KEY); 26 | sharedPreferences = getPreferenceScreen().getSharedPreferences(); 27 | } 28 | 29 | @Override 30 | public void onCreate(Bundle savedInstanceState) { 31 | super.onCreate(savedInstanceState); 32 | developerModeCheck.setOnPreferenceChangeListener(this); 33 | } 34 | 35 | @Override 36 | public void onResume() { 37 | super.onResume(); 38 | sharedPreferences.registerOnSharedPreferenceChangeListener(this); 39 | } 40 | 41 | @Override 42 | public void onPause() { 43 | super.onPause(); 44 | sharedPreferences.unregisterOnSharedPreferenceChangeListener(this); 45 | } 46 | 47 | @Override 48 | public void onDestroyView() { 49 | super.onDestroyView(); 50 | } 51 | 52 | @Override 53 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 54 | switch (key) { 55 | case DEV_MODE_KEY: 56 | if (!developerModeCheck.isChecked()) 57 | NeuroLab.developerMode = true; 58 | else { 59 | NeuroLab.developerMode = false; 60 | Toast.makeText(getActivity(), R.string.dev_mode_msg, Toast.LENGTH_SHORT).show(); 61 | } 62 | break; 63 | default: 64 | break; 65 | } 66 | } 67 | 68 | @Override 69 | public boolean onPreferenceChange(Preference preference, Object o) { 70 | return true; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/fragments/RelaxVisualFragment.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.fragments; 2 | 3 | 4 | import android.os.Bundle; 5 | import android.support.annotation.NonNull; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import io.neurolab.R; 11 | import io.neurolab.tools.Animations; 12 | 13 | public class RelaxVisualFragment extends android.support.v4.app.Fragment { 14 | 15 | public static final String RELAX_PROGRAM_FLAG = "Relax"; 16 | 17 | @Override 18 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, 19 | Bundle savedInstanceState) { 20 | // Inflate the layout for this fragment 21 | View view = inflater.inflate(R.layout.fragment_relax_visual, container, false); 22 | 23 | Animations.rotateView(view.findViewById(R.id.yantraOneImageView), 360f, 0); 24 | Animations.rotateView(view.findViewById(R.id.yantraTwoImageView), 0, 360f); 25 | 26 | return view; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/gui/CustomOutputView.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.gui; 2 | 3 | import android.content.Context; 4 | import android.widget.Scroller; 5 | import android.widget.TextView; 6 | 7 | public class CustomOutputView { 8 | private TextView textArea; 9 | private Context context; 10 | 11 | public CustomOutputView(Context context, TextView textArea) { 12 | this.textArea = textArea; 13 | this.context = context; 14 | } 15 | 16 | public void write(char b) { 17 | // redirects data to the text area 18 | textArea.append(String.valueOf(b)); 19 | // scrolls the text area to the end of data 20 | textArea.setScroller(new Scroller(context)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/gui/GraphicBgRenderer.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.gui; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.VideoView; 6 | 7 | public class GraphicBgRenderer extends VideoView { 8 | 9 | private int mForceHeight = 0; 10 | private int mForceWidth = 0; 11 | 12 | public GraphicBgRenderer(Context context) { 13 | super(context); 14 | } 15 | 16 | public GraphicBgRenderer(Context context, AttributeSet attrs) { 17 | this(context, attrs, 0); 18 | } 19 | 20 | public GraphicBgRenderer(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | } 23 | 24 | public void setDimensions(int w, int h) { 25 | this.mForceHeight = h; 26 | this.mForceWidth = w; 27 | } 28 | 29 | @Override 30 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 31 | setMeasuredDimension(mForceWidth, mForceHeight); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/gui/NFBSettingsWindow.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.gui; 2 | 3 | import java.util.ArrayList; 4 | 5 | import io.neurolab.main.NFBServer; 6 | import io.neurolab.settings.FeedbackSettings; 7 | 8 | public class NFBSettingsWindow { 9 | private NFBServer nfbServer; 10 | private FeedbackSettings feedbackSettings; 11 | 12 | private String feedbackTitle; 13 | private String difficultyFactor; 14 | private String feedbackOutput; 15 | 16 | private ArrayList listModel; 17 | 18 | public NFBSettingsWindow(NFBServer nfbServer) { 19 | 20 | this.nfbServer = nfbServer; 21 | this.feedbackSettings = nfbServer.getCurrentFeedbackSettings(); 22 | 23 | feedbackTitle = " feedback type: " + feedbackSettings.getFeedbackSettingsName() + " "; 24 | listModel = new ArrayList(); 25 | 26 | for (FeedbackSettings feedbackSettings : nfbServer.getAllSettings()) 27 | listModel.add(feedbackSettings.getFeedbackSettingsName()); 28 | } 29 | 30 | public void actionPerformed(int index) { 31 | feedbackSettings = nfbServer.getAllSettings().get(index); 32 | nfbServer.setCurrentFeedbackSettings(feedbackSettings); 33 | } 34 | 35 | public String getFeedbackTitle() { 36 | return feedbackTitle; 37 | } 38 | 39 | public String getDifficultyFactor() { 40 | return difficultyFactor; 41 | } 42 | 43 | public void setDifficultyFactor(String difficultyFactor) { 44 | this.difficultyFactor = difficultyFactor; 45 | } 46 | 47 | public String getFeedbackOutput() { 48 | return feedbackOutput; 49 | } 50 | 51 | public void setFeedbackOutput(String feedbackOutput) { 52 | this.feedbackOutput = feedbackOutput; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/gui/SpectralViewPanel.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.gui; 2 | 3 | public class SpectralViewPanel { 4 | // public setValues in future development if needed. 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/gui/ThresholdRenderer.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.gui; 2 | 3 | import android.gesture.GestureStroke; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.Rect; 7 | import android.media.Image; 8 | import android.os.Build; 9 | import android.widget.FrameLayout; 10 | import android.widget.ImageView; 11 | 12 | public class ThresholdRenderer { 13 | private float min; 14 | private float max; 15 | private float range; 16 | private float cur; 17 | private float thresh; 18 | 19 | private int panelWidth; 20 | private int panelHeight; 21 | private Image renderImage; 22 | private ImageView renderGraphics; 23 | private GestureStroke stroke; 24 | private int pos; 25 | 26 | public synchronized void setRange(float min, float max) { 27 | this.min = min; 28 | this.max = max; 29 | this.range = Math.max(min,max) - Math.min(min,max); 30 | } 31 | 32 | public synchronized void setCur(float cur) { 33 | this.cur = cur; 34 | } 35 | public ThresholdRenderer(FrameLayout windowSize, float min, float max, float cur) { 36 | this.panelWidth = windowSize.getWidth()-16; 37 | this.panelHeight = windowSize.getHeight(); 38 | setRange(min, max); 39 | this.cur = cur; 40 | thresh = 0.5f; 41 | Rect renderRect = new Rect(panelWidth, panelHeight, panelWidth, panelHeight); 42 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 43 | renderImage.setCropRect(renderRect); 44 | } 45 | pos = 0; 46 | } 47 | public void paint(ImageView image){ 48 | image.setBackgroundColor(Color.WHITE); 49 | Rect outrect = new Rect(0, 0, panelWidth, panelHeight); 50 | image.getDrawingRect(outrect); 51 | image.setBackgroundColor(Color.BLACK); 52 | Rect newrect = new Rect(1, 1, panelWidth-1, panelHeight-1); 53 | image.getDrawingRect(newrect); 54 | pos = (int)((float)panelWidth*((cur-min)/range)); 55 | Canvas newCanvas = new Canvas(); // A bitmap (background image) should be provided in future. 56 | image.draw(newCanvas); 57 | } 58 | public synchronized void setMin(float min) { 59 | setRange(min, max); 60 | } 61 | public synchronized void setMax(float max) { 62 | setRange(min, max); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/gui/VJ.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.gui; 2 | 3 | 4 | import android.content.Context; 5 | 6 | import java.util.LinkedList; 7 | 8 | import io.neurolab.main.NFBServer; 9 | import io.neurolab.main.output.audio.AudioFeedback; 10 | import io.neurolab.main.output.visual.LongtermFFTVisualizer; 11 | import io.neurolab.main.task.OscForwardTask; 12 | import io.neurolab.model.Config; 13 | import io.neurolab.model.DefaultFFTData; 14 | import io.neurolab.model.FFTPreprocessor; 15 | import io.neurolab.model.GenericFeedbackSettings; 16 | import io.neurolab.model.NFBProcessor; 17 | import io.neurolab.interfaces.Task; 18 | import io.neurolab.settings.FeedbackSettings; 19 | 20 | public class VJ { 21 | 22 | private Context context; 23 | private NFBServer rn; 24 | private FeedbackSettings currentFeedbackSettings; 25 | 26 | public void run(Context context) { 27 | this.context = context; 28 | Config config = new Config("filename"); 29 | try { 30 | 31 | rn = new NFBServer(config); 32 | 33 | // fft data and preprocessor task 34 | DefaultFFTData fftData = new DefaultFFTData(NFBServer.samplesPerSecond, NFBServer.bins, NFBServer.numChannels); 35 | FFTPreprocessor fftPreprocessor = new FFTPreprocessor(fftData, rn); 36 | 37 | // feedback settings and processor task 38 | FeedbackSettings currentFeedbackSettings = new GenericFeedbackSettings(fftData, NFBServer.getLock(), config); 39 | NFBProcessor nfbProcessor = new NFBProcessor(currentFeedbackSettings); 40 | 41 | OscForwardTask oscForwardTask = new OscForwardTask(rn); 42 | 43 | // longterm fft visualization 44 | LongtermFFTVisualizer longtermFFTVisualizer = new LongtermFFTVisualizer(fftData, rn); 45 | 46 | LinkedList tasks = rn.getTasks(); 47 | tasks.add(fftPreprocessor); 48 | tasks.add(nfbProcessor); 49 | tasks.add(longtermFFTVisualizer); 50 | tasks.add(oscForwardTask); 51 | rn.setTasks(tasks); 52 | 53 | rn.setCurrentFeedbackSettings(currentFeedbackSettings); 54 | 55 | addFeedback(); 56 | 57 | } catch (Exception e) { 58 | e.printStackTrace(); 59 | } 60 | 61 | } 62 | 63 | private void addFeedback() { 64 | AudioFeedback audioFeedback = new AudioFeedback(context, rn.getCurrentFeedbackSettings()); 65 | currentFeedbackSettings.addFeedback(audioFeedback); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/interfaces/DataReceiver.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.interfaces; 2 | 3 | import java.util.List; 4 | 5 | public interface DataReceiver { 6 | 7 | void appendData(List data); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/interfaces/FFTData.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.interfaces; 2 | 3 | public interface FFTData { 4 | void updateFFTData(double[][] fftData); 5 | 6 | void updateFFTData(); 7 | 8 | void setTrainingFactor(double trainingFactor); 9 | 10 | double getTrainingFactor(); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/interfaces/InputInterface.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.interfaces; 2 | 3 | public interface InputInterface extends Runnable { 4 | 5 | int shutDown(); 6 | boolean isConnectionSuccessful(); 7 | boolean sendCommand(String string); 8 | boolean record(String filename); 9 | void stopRecording(); 10 | boolean isRecording(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/interfaces/Recorder.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.interfaces; 2 | 3 | public interface Recorder { 4 | 5 | void write(long timestamp, String data); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/interfaces/Task.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.interfaces; 2 | 3 | public interface Task 4 | { 5 | void init(); 6 | void run(); 7 | void stop(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/DeviceConnector.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main; 2 | 3 | import android.app.PendingIntent; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.hardware.usb.UsbDevice; 7 | import android.hardware.usb.UsbDeviceConnection; 8 | import android.hardware.usb.UsbManager; 9 | 10 | import com.felhr.usbserial.UsbSerialDevice; 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | public class DeviceConnector { 15 | 16 | Context context; 17 | private UsbManager usbManager; 18 | private UsbDevice device; 19 | private UsbSerialDevice serialPort; 20 | private UsbDeviceConnection connection; 21 | private int baudRate = 9600; 22 | private int arduinoVid = 0x2341; 23 | 24 | private final String ACTION_USB_PERMISSION = "io.neurolab.USB_PERMISSION"; 25 | 26 | public DeviceConnector(UsbManager usbManager) { 27 | this.usbManager = usbManager; 28 | } 29 | 30 | public UsbDevice getDevice() { 31 | return device; 32 | } 33 | 34 | public void setDevice(UsbDevice device) { 35 | this.device = device; 36 | } 37 | 38 | public UsbSerialDevice getSerialPort() { 39 | return serialPort; 40 | } 41 | 42 | public void setSerialPort(UsbSerialDevice serialPort) { 43 | this.serialPort = serialPort; 44 | } 45 | 46 | public int getBaudRate() { 47 | return baudRate; 48 | } 49 | 50 | public void setBaudRate(int baudRate) { 51 | this.baudRate = baudRate; 52 | } 53 | 54 | public int getArduinoVid() { 55 | return arduinoVid; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/FakeLock.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main; 2 | 3 | public class FakeLock { 4 | 5 | public FakeLock(){ 6 | 7 | } 8 | 9 | public void lock(){ 10 | 11 | } 12 | 13 | public void unlock(){ 14 | 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/LongtermFeedbackGraph.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main; 2 | 3 | public class LongtermFeedbackGraph { 4 | // TODO: Implementation to be carried out in future. 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/LongtermGraph.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main; 2 | 3 | public class LongtermGraph { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/NFBGraph.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main; 2 | 3 | import android.content.Context; 4 | 5 | import io.neurolab.settings.FeedbackSettings; 6 | import io.neurolab.interfaces.Task; 7 | 8 | public class NFBGraph implements Task { 9 | 10 | private Context context; 11 | private FeedbackSettings feedbackSettings; 12 | private int pointer; 13 | private int bins; 14 | private int channels; 15 | private NFBServer nfbServer; 16 | private int s; 17 | private long ts = -1; 18 | private boolean slowMode = false; 19 | 20 | public NFBGraph(Context context, NFBServer nfbServer, FeedbackSettings feedbackSettings) { 21 | this.context = context; 22 | this.feedbackSettings = feedbackSettings; 23 | this.nfbServer = nfbServer; 24 | this.init(); 25 | } 26 | 27 | @Override 28 | public void init() { 29 | bins = feedbackSettings.getBins(); 30 | channels = feedbackSettings.getNumChannels(); 31 | pointer = 0; 32 | s = 255 / (bins * channels); 33 | } 34 | 35 | @Override 36 | public void run() { 37 | if ((slowMode) && (System.currentTimeMillis() - ts < 75)) 38 | return; 39 | 40 | if (nfbServer.getNumSamples() < 1) 41 | return; 42 | 43 | int numSamples = 1; 44 | ts = System.currentTimeMillis(); 45 | } 46 | 47 | @Override 48 | public void stop() { 49 | // TODO: Needs to be implemented for stopping the task. 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/SampleSlide.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | public class SampleSlide extends Fragment { 11 | 12 | private static final String ARG_LAYOUT_RES_ID = "layoutResId"; 13 | private int layoutResId; 14 | 15 | public static SampleSlide newInstance(int layoutResId) { 16 | SampleSlide sampleSlide = new SampleSlide(); 17 | 18 | Bundle args = new Bundle(); 19 | args.putInt(ARG_LAYOUT_RES_ID, layoutResId); 20 | sampleSlide.setArguments(args); 21 | 22 | return sampleSlide; 23 | } 24 | 25 | @Override 26 | public void onCreate(@Nullable Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | 29 | if (getArguments() != null && getArguments().containsKey(ARG_LAYOUT_RES_ID)) { 30 | layoutResId = getArguments().getInt(ARG_LAYOUT_RES_ID); 31 | } 32 | } 33 | 34 | @Nullable 35 | @Override 36 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 37 | @Nullable Bundle savedInstanceState) { 38 | return inflater.inflate(layoutResId, container, false); 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/network/OSCForwarder.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main.network; 2 | 3 | import java.net.DatagramSocket; 4 | import java.net.InetAddress; 5 | import java.net.SocketException; 6 | import java.net.UnknownHostException; 7 | 8 | import com.illposed.osc.OSCBundle; 9 | import com.illposed.osc.OSCMessage; 10 | import com.illposed.osc.OSCPacket; 11 | import com.illposed.osc.OSCPortOut; 12 | 13 | public class OSCForwarder { 14 | 15 | public static void main(String[] args) throws UnknownHostException, SocketException, InterruptedException { 16 | OSCForwarder of = new OSCForwarder(); 17 | } 18 | 19 | private DatagramSocket socket = null; 20 | private String address; 21 | private String port; 22 | private String oscAddress; 23 | private OSCPortOut oscPortOut; 24 | private boolean connected = false; 25 | 26 | public OSCForwarder() { 27 | 28 | } 29 | 30 | public OSCForwarder(String address, String port) { 31 | this.address = address; 32 | this.port = port; 33 | connect(address, port); 34 | } 35 | 36 | 37 | public boolean connect(String address, String port) { 38 | InetAddress addr; 39 | 40 | try { 41 | addr = InetAddress.getByName(address); 42 | } catch (UnknownHostException e1) { 43 | e1.printStackTrace(); 44 | return false; 45 | } 46 | 47 | try { 48 | oscPortOut = new OSCPortOut(addr, Integer.valueOf(port)); 49 | connected = true; 50 | } catch (NumberFormatException | SocketException e1) { 51 | e1.printStackTrace(); 52 | connected = false; 53 | return false; 54 | } 55 | 56 | int i = 1; 57 | Object[] args = new Object[1]; 58 | return true; 59 | } 60 | 61 | public void forwardBundle(OSCBundle bundle) { 62 | for (OSCPacket packet : bundle.getPackets()) { 63 | System.out.println(packet.toString()); 64 | } 65 | 66 | try { 67 | oscPortOut.send(bundle); 68 | } catch (Exception e) { 69 | e.printStackTrace(); 70 | } 71 | } 72 | 73 | public boolean isConnected() { 74 | return connected; 75 | } 76 | 77 | public void forwardMessage(OSCMessage message) { 78 | try { 79 | oscPortOut.send(message); 80 | } catch (Exception e) { 81 | e.printStackTrace(); 82 | } 83 | } 84 | 85 | public boolean disconnect() { 86 | oscPortOut.close(); 87 | connected = false; 88 | return true; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/network/OSCReceiver.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main.network; 2 | 3 | import android.content.Context; 4 | 5 | import com.illposed.osc.OSCListener; 6 | import com.illposed.osc.OSCPortIn; 7 | 8 | import java.net.SocketException; 9 | import java.util.ArrayList; 10 | 11 | import io.neurolab.model.Config; 12 | 13 | public class OSCReceiver { 14 | protected OSCPortIn receiver; 15 | protected ArrayList senderList; 16 | protected boolean exit = false; 17 | protected boolean listening = false; 18 | protected boolean forwarding = false; 19 | private String address; 20 | private OSCListener oscListener; 21 | private Context context; 22 | 23 | public static void run(String fileName) throws SocketException { 24 | Config config = new Config(fileName); 25 | ArrayList senderList = new ArrayList<>(); 26 | senderList.add("/dev/rfcomm0/"); 27 | senderList.add("/dev/rfcomm1/"); 28 | OSCReceiver or = new OSCReceiver(7009, senderList); 29 | 30 | OSCListener listener = (time, message) -> { 31 | 32 | System.out.println("received " + message.getAddress() + ":"); 33 | for (Object argument : message.getArguments()) 34 | System.out.println(argument.toString()); 35 | 36 | }; 37 | or.addOSCListener("/sayhello1", listener); 38 | or.addOSCListener("/sayhello2", listener); 39 | or.startListening(); 40 | 41 | } 42 | 43 | public void addOSCListener(String address, OSCListener oscListener) { 44 | this.address = address; 45 | this.oscListener = oscListener; 46 | } 47 | 48 | public void startListening() { 49 | receiver.startListening(); 50 | listening = true; 51 | } 52 | 53 | public void stopListening() { 54 | receiver.stopListening(); 55 | listening = false; 56 | } 57 | 58 | public OSCReceiver(int port, ArrayList senderList) throws SocketException { 59 | receiver = new OSCPortIn(port); 60 | 61 | } 62 | 63 | public OSCPortIn getReceiver() { 64 | return receiver; 65 | } 66 | 67 | public void setReceiver(OSCPortIn receiver) { 68 | this.receiver = receiver; 69 | } 70 | 71 | public ArrayList getSenderList() { 72 | return senderList; 73 | } 74 | 75 | public void setSenderList(ArrayList senderList) { 76 | this.senderList = senderList; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/output/audio/JSynThread.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main.output.audio; 2 | 3 | import com.jsyn.JSyn; 4 | import com.jsyn.Synthesizer; 5 | import com.jsyn.devices.AudioDeviceFactory; 6 | 7 | public class JSynThread implements Runnable { 8 | 9 | private Synthesizer synth; 10 | 11 | @Override 12 | public void run() { 13 | synth = JSyn.createSynthesizer( AudioDeviceFactory.createAudioDeviceManager( true )); 14 | } 15 | 16 | public synchronized Synthesizer getSynth() { 17 | return synth; 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/output/audio/PlaybackInfoListener.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main.output.audio; 2 | 3 | import android.support.annotation.IntDef; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | 8 | // An abstract class providing some methods(to be implemented) for updating the user interface when media player evokes the corresponding events. 9 | public abstract class PlaybackInfoListener { 10 | 11 | @IntDef({State.INVALID, State.PLAYING, State.PAUSED, State.RESET, State.COMPLETED}) 12 | @Retention(RetentionPolicy.SOURCE) 13 | @interface State { 14 | 15 | int INVALID = -1; 16 | int PLAYING = 0; 17 | int PAUSED = 1; 18 | int RESET = 2; 19 | int COMPLETED = 3; 20 | } 21 | 22 | public static String convertStateToString(@State int state) { 23 | String stateString; 24 | switch (state) { 25 | case State.COMPLETED: 26 | stateString = "COMPLETED"; 27 | break; 28 | case State.INVALID: 29 | stateString = "INVALID"; 30 | break; 31 | case State.PAUSED: 32 | stateString = "PAUSED"; 33 | break; 34 | case State.PLAYING: 35 | stateString = "PLAYING"; 36 | break; 37 | case State.RESET: 38 | stateString = "RESET"; 39 | break; 40 | default: 41 | stateString = "N/A"; 42 | break; 43 | } 44 | return stateString; 45 | } 46 | 47 | public abstract void onLogUpdated(String formattedMessage); 48 | 49 | public abstract void onDurationChanged(int duration); 50 | 51 | public abstract void onPositionChanged(int position); 52 | 53 | public abstract void onStateChanged(@State int state); 54 | 55 | public abstract void onPlaybackCompleted(); 56 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/output/audio/PlayerAdapter.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main.output.audio; 2 | 3 | // An Interface which allows the client Activity (containing the Media Controller UI) to control playback functions. 4 | public interface PlayerAdapter { 5 | 6 | void loadMedia(int resourceId); 7 | 8 | void release(); 9 | 10 | boolean isPlaying(); 11 | 12 | void play(); 13 | 14 | void reset(); 15 | 16 | void pause(); 17 | 18 | void initializeProgressCallback(); 19 | 20 | void seekTo(int position); 21 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/output/feedback/Feedback.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main.output.feedback; 2 | 3 | import io.neurolab.settings.FeedbackSettings; 4 | 5 | public abstract class Feedback implements Runnable { 6 | protected FeedbackSettings feedbackSettings; 7 | protected double[][][] currentMultivariateFeedback; 8 | protected double currentFeedback; 9 | protected boolean running; 10 | 11 | protected Feedback() { 12 | } 13 | 14 | public void updateCurrentMultivariateFeedback(double[][][] currentMultivariateFeedback) { 15 | this.currentMultivariateFeedback = currentMultivariateFeedback; 16 | } 17 | 18 | public void updateCurrentFeedback(double currentFeedback) { 19 | this.currentFeedback = currentFeedback; 20 | } 21 | 22 | public double getCurrentFeedback() { 23 | return currentFeedback; 24 | } 25 | 26 | public Feedback(FeedbackSettings feedbackSettings) { 27 | this.feedbackSettings = feedbackSettings; 28 | } 29 | 30 | public void init() { 31 | } 32 | 33 | @Override 34 | public void run() { 35 | running = true; 36 | } 37 | 38 | public boolean isRunning() { 39 | return running; 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/output/visual/FocusOMeter.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main.output.visual; 2 | 3 | import android.content.Context; 4 | 5 | import com.illposed.osc.OSCPortIn; 6 | import com.jogamp.opengl.GLAutoDrawable; 7 | import com.jogamp.opengl.GLCapabilities; 8 | import com.jogamp.opengl.GLProfile; 9 | 10 | import java.net.SocketException; 11 | 12 | import io.neurolab.main.output.feedback.Feedback; 13 | import io.neurolab.settings.FeedbackSettings; 14 | 15 | public class FocusOMeter extends Feedback { 16 | 17 | private static OSCPortIn receiver; 18 | private Context context; 19 | 20 | private GLCapabilities glcapabilities; 21 | 22 | public FocusOMeter(Context context) { 23 | this.context = context; 24 | } 25 | 26 | public void setCurrentFeedback(float currentFeedback) { 27 | FocusOMeterGLRenderer.setCurrentFeedback(currentFeedback); 28 | } 29 | 30 | double currentFeedback = 0; 31 | 32 | public void setOSCInput(int port) { 33 | try { 34 | receiver = new OSCPortIn(port); 35 | 36 | } catch (SocketException e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | 41 | public FocusOMeter(FeedbackSettings feedbackSettings) { 42 | super(feedbackSettings); 43 | 44 | GLProfile glprofile = GLProfile.getDefault(); 45 | glcapabilities = new GLCapabilities(glprofile); 46 | } 47 | 48 | public void reshape(GLAutoDrawable glautodrawable, int x, int y, int width, int height) { 49 | FocusOMeterGLRenderer.setup(glautodrawable.getGL().getGL2(), width, height); 50 | } 51 | 52 | public void display(GLAutoDrawable glautodrawable) { 53 | FocusOMeterGLRenderer.render(glautodrawable.getGL().getGL2(), glautodrawable.getSurfaceWidth(), glautodrawable.getSurfaceHeight()); 54 | } 55 | 56 | public GLCapabilities getGlcapabilities() { 57 | return glcapabilities; 58 | } 59 | 60 | @Override 61 | public void updateCurrentFeedback(double currentFeedback) { 62 | super.updateCurrentFeedback(currentFeedback); 63 | setCurrentFeedback((float) currentFeedback); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/output/visual/FocusOMeterGLRenderer.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main.output.visual; 2 | 3 | import com.jogamp.opengl.GL; 4 | import com.jogamp.opengl.GL2; 5 | import com.jogamp.opengl.glu.GLU; 6 | 7 | 8 | public class FocusOMeterGLRenderer { 9 | 10 | private static float currentFeedback = 0; 11 | 12 | public static void setCurrentFeedback(float currentFeedback) { 13 | FocusOMeterGLRenderer.currentFeedback = currentFeedback; 14 | } 15 | 16 | protected static void setup(GL2 gl2, int width, int height) { 17 | gl2.glMatrixMode(GL2.GL_PROJECTION); 18 | gl2.glLoadIdentity(); 19 | 20 | GLU glu = new GLU(); 21 | glu.gluOrtho2D(0.0f, width, 0.0f, height); 22 | 23 | gl2.glMatrixMode(GL2.GL_MODELVIEW); 24 | gl2.glLoadIdentity(); 25 | 26 | gl2.glViewport(0, 0, width, height); 27 | } 28 | 29 | protected static void render(GL2 gl2, int width, int height) { 30 | gl2.glClear(GL.GL_COLOR_BUFFER_BIT); 31 | 32 | gl2.glLoadIdentity(); 33 | gl2.glBegin(GL2.GL_QUADS); 34 | gl2.glColor3f(1, 0, 0); 35 | gl2.glVertex2f(0, 0); 36 | gl2.glColor3f(1, 0, 0); 37 | gl2.glVertex2f(width, 0); 38 | gl2.glColor3f(1, 1, 0); 39 | gl2.glVertex2f(width, height / 2); 40 | gl2.glColor3f(1, 1, 0); 41 | gl2.glVertex2f(0, height / 2); 42 | gl2.glEnd(); 43 | 44 | gl2.glBegin(GL2.GL_QUADS); 45 | gl2.glColor3f(1, 1, 0); 46 | gl2.glVertex2f(0, height / 2); 47 | gl2.glColor3f(1, 1, 0); 48 | gl2.glVertex2f(width, height / 2); 49 | gl2.glColor3f(0, 1, 0); 50 | gl2.glVertex2f(width, height); 51 | gl2.glColor3f(0, 1, 0); 52 | gl2.glVertex2f(0, height); 53 | gl2.glEnd(); 54 | 55 | gl2.glBegin(GL2.GL_QUADS); 56 | gl2.glColor3f(0, 0, 0); 57 | gl2.glVertex2f(0, height); 58 | gl2.glColor3f(0, 0, 0); 59 | gl2.glVertex2f(width, height); 60 | gl2.glColor3f(0, 0, 0); 61 | gl2.glVertex2f(width, currentFeedback * height / 2 + height / 2); 62 | gl2.glColor3f(0, 0, 0); 63 | gl2.glVertex2f(0, currentFeedback * height / 2 + height / 2); 64 | gl2.glEnd(); 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/output/visual/NeuroGameVisuals.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main.output.visual; 2 | 3 | import android.content.Context; 4 | 5 | import io.neurolab.main.output.audio.AudioFeedback; 6 | import io.neurolab.main.output.feedback.Feedback; 7 | import io.neurolab.settings.FeedbackSettings; 8 | 9 | import com.jogamp.opengl.GLCapabilities; 10 | import com.jogamp.opengl.GLProfile; 11 | 12 | public class NeuroGameVisuals extends Feedback { 13 | 14 | private static boolean debug = false; 15 | private static int xStart = 0; 16 | private static int yStart = 0; 17 | private static AudioFeedback audioFeedback; 18 | private Context context; 19 | private double currentFeedback = 0; 20 | private NeuroGameRenderer neurofeedbackRenderer; 21 | 22 | public NeuroGameVisuals(Context context, FeedbackSettings feedbackSettings) { 23 | super(feedbackSettings); 24 | this.context = context; 25 | 26 | if (feedbackSettings == null) 27 | currentFeedback = 0.01f; 28 | 29 | GLProfile glprofile = GLProfile.getDefault(); 30 | 31 | neurofeedbackRenderer = new NeuroGameRenderer(glprofile); 32 | GLCapabilities glcapabilities = new GLCapabilities(glprofile); 33 | } 34 | 35 | public void setCurrentFeedback(float currentFeedback) { 36 | neurofeedbackRenderer.setCurrentFeedback(currentFeedback); 37 | } 38 | 39 | @Override 40 | public void updateCurrentFeedback(double currentFeedback) { 41 | super.updateCurrentFeedback(currentFeedback); 42 | setCurrentFeedback((float) currentFeedback); 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/output/visual/OSCFeedback.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main.output.visual; 2 | 3 | import java.net.SocketException; 4 | 5 | import io.neurolab.main.output.feedback.Feedback; 6 | import io.neurolab.settings.FeedbackSettings; 7 | import com.illposed.osc.OSCPortIn; 8 | 9 | public class OSCFeedback extends Feedback { 10 | 11 | private static OSCPortIn receiver; 12 | double currentFeedback = 0; 13 | 14 | public OSCFeedback(FeedbackSettings feedbackSettings) { 15 | super(feedbackSettings); 16 | } 17 | 18 | public void setCurrentFeedback(float currentFeedback) { 19 | FocusOMeterGLRenderer.setCurrentFeedback(currentFeedback); 20 | } 21 | 22 | public void setOSCInput(int port) { 23 | try { 24 | receiver = new OSCPortIn(port); 25 | } catch (SocketException e) { 26 | e.printStackTrace(); 27 | } 28 | } 29 | 30 | @Override 31 | public void updateCurrentFeedback(double currentFeedback) { 32 | super.updateCurrentFeedback(currentFeedback); 33 | setCurrentFeedback((float) currentFeedback); 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/output/visual/ZenSpaceVisuals.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main.output.visual; 2 | 3 | import android.content.Context; 4 | 5 | import io.neurolab.main.output.feedback.Feedback; 6 | import io.neurolab.settings.FeedbackSettings; 7 | 8 | import com.jogamp.opengl.GLCapabilities; 9 | import com.jogamp.opengl.GLProfile; 10 | 11 | public class ZenSpaceVisuals extends Feedback { 12 | 13 | private Context context; 14 | private double currentFeedback = 0; 15 | private ZenSpaceGLRenderer zenSpaceRenderer; 16 | 17 | public ZenSpaceVisuals(Context context, FeedbackSettings feedbackSettings) { 18 | super(feedbackSettings); 19 | this.context = context; 20 | 21 | GLProfile glprofile = GLProfile.getDefault(); 22 | 23 | zenSpaceRenderer = new ZenSpaceGLRenderer(context, glprofile); 24 | GLCapabilities glcapabilities = new GLCapabilities(glprofile); 25 | } 26 | 27 | public void setCurrentFeedback(float currentFeedback) { 28 | zenSpaceRenderer.setCurrentFeedback(currentFeedback); 29 | } 30 | 31 | @Override 32 | public void updateCurrentFeedback(double currentFeedback) { 33 | super.updateCurrentFeedback(currentFeedback); 34 | setCurrentFeedback((float) currentFeedback); 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/main/task/LongtermFeedbackTrackerTask.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.main.task; 2 | 3 | import io.neurolab.main.LongtermGraph; 4 | import io.neurolab.model.DefaultFFTData; 5 | import io.neurolab.settings.FeedbackSettings; 6 | import io.neurolab.interfaces.Task; 7 | 8 | public class LongtermFeedbackTrackerTask implements Task{ 9 | 10 | private DefaultFFTData defaultFFData; 11 | private FeedbackSettings feedbackSettings; 12 | private LongtermGraph longtermGraph; 13 | 14 | public LongtermFeedbackTrackerTask(DefaultFFTData defaultFFTData, FeedbackSettings feedbackSettings, LongtermGraph longtermGraph) { 15 | this.defaultFFData = defaultFFTData; 16 | this.feedbackSettings = feedbackSettings; 17 | this.longtermGraph = longtermGraph; 18 | } 19 | 20 | @Override 21 | public void init() { 22 | 23 | } 24 | 25 | @Override 26 | public void run() { 27 | 28 | } 29 | 30 | @Override 31 | public void stop() { 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/model/Config.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.model; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.prefs.BackingStoreException; 6 | import java.util.prefs.Preferences; 7 | 8 | import io.neurolab.tools.ResourceManager; 9 | 10 | public class Config { 11 | 12 | public enum audiofeedback_params {sample, volume, x, y} 13 | 14 | public enum server_settings_params {serial_address, pro_mode, pp, load_from_disk, audiofeedback, simulation, bit24, fir, avg, tf} 15 | 16 | public enum osc_settings_params {mode, address, ip, port} 17 | 18 | public enum serial_settings_params {address, baudrate, message, mode} 19 | 20 | public static String serial_settings = "serial_settings"; 21 | public static String osc_settings = "osc_settings"; 22 | public static String audiofeedback = "default_audiofeedback"; 23 | public static String server_settings = "server_settings"; 24 | 25 | private File iniFile; 26 | public Preferences prefs; 27 | 28 | public Config(String filename) { 29 | iniFile = new File(filename); 30 | System.out.println("opening config from " + filename); 31 | try { 32 | loadConfig(iniFile); 33 | } catch (BackingStoreException e) { 34 | e.printStackTrace(); 35 | } catch (IOException e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | 40 | public boolean loadConfig(File iniFile) throws BackingStoreException, IOException { 41 | System.out.println(iniFile); 42 | 43 | System.out.println("loaded config"); 44 | return true; 45 | } 46 | 47 | public boolean setPref(String section, String key, String value) { 48 | try { 49 | prefs.sync(); 50 | return true; 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | } 54 | return false; 55 | } 56 | 57 | public String getPref(String section, String key) { 58 | try { 59 | if (prefs.nodeExists(section)) 60 | return prefs.node(section).get(key, null); 61 | } catch (BackingStoreException e) { 62 | e.printStackTrace(); 63 | } 64 | return null; 65 | } 66 | 67 | public boolean store() { 68 | try { 69 | System.out.println("stored config"); 70 | return true; 71 | } catch (Exception e) { 72 | e.printStackTrace(); 73 | } 74 | return false; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/model/DataPacket.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.model; 2 | 3 | public class DataPacket { 4 | // TODO: Implementation to be carried out in the future. 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/model/FileOutputTask.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.model; 2 | 3 | import java.io.PrintWriter; 4 | import java.nio.ByteBuffer; 5 | 6 | import io.neurolab.interfaces.Task; 7 | import io.neurolab.main.NFBServer; 8 | 9 | public class FileOutputTask implements Task { 10 | 11 | private NFBServer nfbServer; 12 | private PrintWriter out = null; 13 | private byte[] stopBytes; 14 | private String fileName = "defaultFileOutput.bw"; 15 | private boolean write = false; 16 | 17 | public FileOutputTask(NFBServer nfbServer) { 18 | this.nfbServer = nfbServer; 19 | this.stopBytes = doubleToByteArray(Double.MAX_VALUE); 20 | } 21 | 22 | public void setFileName(String fileName) { 23 | this.fileName = fileName; 24 | init(); 25 | } 26 | 27 | public void setWrite(boolean write) { 28 | this.write = write; 29 | } 30 | 31 | @Override 32 | public void run() { 33 | if ((write) && (!nfbServer.getInputData().isEmpty())) { 34 | try { 35 | for (int s = 0; s < nfbServer.getNumSamples(); s++) { 36 | double[] currentPacket = nfbServer.getInputData().get(s); 37 | 38 | out.print(nfbServer.getCurrentTimestamp() + ","); 39 | for (int c = 0; c < currentPacket.length; c++) 40 | out.print(currentPacket[c] + ","); 41 | out.println(""); 42 | } 43 | } catch (Exception e) { 44 | e.printStackTrace(); 45 | } 46 | } 47 | } 48 | 49 | public static byte[] doubleToByteArray(double value) { 50 | byte[] bytes = new byte[8]; 51 | ByteBuffer.wrap(bytes).putDouble(value); 52 | return bytes; 53 | } 54 | 55 | public static byte[] longToByteArray(long value) { 56 | byte[] bytes = new byte[8]; 57 | ByteBuffer.wrap(bytes).putLong(value); 58 | return bytes; 59 | } 60 | 61 | public static double toDouble(byte[] bytes) { 62 | return ByteBuffer.wrap(bytes).getDouble(); 63 | } 64 | 65 | @Override 66 | public void init() { 67 | try { 68 | if (out != null) 69 | out.close(); 70 | out = new PrintWriter(fileName, "UTF-8"); 71 | } catch (Exception e) { 72 | e.printStackTrace(); 73 | } 74 | } 75 | 76 | @Override 77 | public void stop() { 78 | try { 79 | out.close(); 80 | } catch (Exception e) { 81 | e.printStackTrace(); 82 | } 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/model/NFBProcessor.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.model; 2 | 3 | import io.neurolab.interfaces.Task; 4 | import io.neurolab.settings.FeedbackSettings; 5 | 6 | public class NFBProcessor implements Task { 7 | 8 | private FeedbackSettings feedbackSettings = null; 9 | 10 | public NFBProcessor(FeedbackSettings feedbackSettings) { 11 | setFeedbackSettings(feedbackSettings); 12 | } 13 | 14 | public void setFeedbackSettings(FeedbackSettings feedbackSettings) { 15 | this.feedbackSettings = feedbackSettings; 16 | } 17 | 18 | @Override 19 | public void run() { 20 | if (feedbackSettings!=null) 21 | feedbackSettings.updateFeedback(); 22 | } 23 | 24 | @Override 25 | public void init() { 26 | 27 | } 28 | 29 | @Override 30 | public void stop() { 31 | 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/model/OSCForwardMask.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.model; 2 | 3 | import java.math.RoundingMode; 4 | import java.text.DecimalFormat; 5 | 6 | import io.neurolab.main.network.OSCForwarder; 7 | import io.neurolab.main.task.OscForwardTask; 8 | 9 | public class OSCForwardMask { 10 | private OSCForwarder oscForwarder; 11 | private DefaultFFTData fftData; 12 | DecimalFormat df = new DecimalFormat("#.##"); 13 | 14 | private OscForwardTask fwdTask; 15 | private Config config; 16 | 17 | public OSCForwardMask(OscForwardTask fwdTask, DefaultFFTData fftData, Config config) { 18 | this.fwdTask = fwdTask; 19 | this.config = config; 20 | df.setRoundingMode(RoundingMode.CEILING); 21 | 22 | this.fftData = fftData; 23 | oscForwarder = new OSCForwarder(); 24 | 25 | } 26 | 27 | public void init(DefaultFFTData fftData) { 28 | this.fftData = fftData; 29 | } 30 | 31 | public void save(String ipText) { 32 | if (config != null) { 33 | config.setPref(Config.osc_settings, String.valueOf(Config.osc_settings_params.ip), ipText); 34 | config.store(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/settings/ConfigurationSettings.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.settings; 2 | 3 | public class ConfigurationSettings { 4 | 5 | private ServerSettings serverSettings = new ServerSettings(); 6 | private NFBRelaxSettings nfbRelaxSettings = new NFBRelaxSettings(); 7 | 8 | public ServerSettings getServerSettings() { 9 | return serverSettings; 10 | } 11 | 12 | public NFBRelaxSettings getNfbRelaxSettings(){ 13 | return nfbRelaxSettings; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/settings/FocusFeedbackSettings.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.settings; 2 | 3 | import java.util.concurrent.locks.ReentrantLock; 4 | 5 | import io.neurolab.utilities.MathBasics; 6 | import io.neurolab.model.Config; 7 | import io.neurolab.model.DefaultFFTData; 8 | 9 | public class FocusFeedbackSettings extends FeedbackSettings { 10 | protected int[] binRanges = {4, 7, 12, 18, 22, 35}; 11 | protected int[] binRangesAmount = {4, 7, 14}; 12 | 13 | @Override 14 | public String getFeedbackSettingsName() { 15 | return "focus"; 16 | } 17 | 18 | public FocusFeedbackSettings(DefaultFFTData fftData, ReentrantLock lock, Config config) { 19 | super(fftData, lock, config); 20 | this.binLabels = new String[]{"theta", "smr", "high beta"}; 21 | this.fftData.setBinRanges(binRanges); 22 | String[] localBinlabels = this.fftData.getBinLabels(); 23 | localBinlabels = this.binLabels; 24 | this.bins = 3; 25 | } 26 | 27 | @Override 28 | public void updateFeedback() { 29 | for (int c = 0; c < fftData.getNumChannels(); c++) 30 | for (int b = 0; b < fftData.getBins(); b++) 31 | fftData.getRewardFFTBins()[b][c] = MathBasics.getZScore(fftData.getShortMeanFFTBins()[b][c], fftData.getMeanFFTBins()[b][c], Math.sqrt(fftData.getVarFFTBins()[b][c])); 32 | 33 | currentFeedback = 0; 34 | for (int c = 0; c < fftData.getNumChannels(); c++) { 35 | for (int b = 0; b < binRangesAmount.length; b++) { 36 | double rewardBin = fftData.getRewardFFTBins()[b][c] * -1d; 37 | if (b == 1) 38 | rewardBin *= -2d; 39 | currentFeedback += rewardBin; 40 | } 41 | currentFeedback /= (double) binRangesAmount.length; 42 | currentFeedback /= (float) (fftData.getNumChannels()); 43 | lastFeedback = currentFeedback; 44 | } 45 | super.updateFeedback(); 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/settings/NFBRelaxSettings.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.settings; 2 | 3 | public class NFBRelaxSettings { 4 | 5 | private double duration = 25; 6 | private int currentSession = 0; 7 | 8 | public double getDuration() { 9 | return duration; 10 | } 11 | 12 | public void setDuration(double duration) { 13 | this.duration = duration; 14 | } 15 | 16 | public int getCurrentSession() { 17 | return currentSession; 18 | } 19 | 20 | public void setCurrentSession(int currentSession) { 21 | this.currentSession = currentSession; 22 | } 23 | 24 | // Converts to the string representation and can be used for debugging purposes. 25 | @Override 26 | public String toString() { 27 | return "duration = " + duration + " | " + "currentSession = " + currentSession; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/settings/NeuroSettings.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.settings; 2 | 3 | 4 | import android.annotation.TargetApi; 5 | import android.os.Build; 6 | 7 | import java.util.concurrent.ConcurrentLinkedDeque; 8 | 9 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 10 | public class NeuroSettings { 11 | 12 | //Default place holder values 13 | private int samplesPerSecond = 3; 14 | private int bins = 4; 15 | private int numChannels = 2; 16 | 17 | public ConcurrentLinkedDeque getCurrentData() { 18 | return currentData; 19 | } 20 | 21 | public void setCurrentData(ConcurrentLinkedDeque currentData) { 22 | this.currentData = currentData; 23 | } 24 | 25 | protected ConcurrentLinkedDeque currentData = new ConcurrentLinkedDeque(); 26 | 27 | // Constructors 28 | public NeuroSettings() { 29 | } 30 | 31 | public NeuroSettings(int samplesPerSecond, int numChannels, int bins) { 32 | this.samplesPerSecond = samplesPerSecond; 33 | this.numChannels = numChannels; 34 | this.bins = bins; 35 | } 36 | 37 | // Getters 38 | public int getSamplesPerSecond() { 39 | return samplesPerSecond; 40 | } 41 | 42 | public int getBins() { 43 | return bins; 44 | } 45 | 46 | public int getNumChannels() { 47 | return numChannels; 48 | } 49 | 50 | // Setters 51 | public void setSamplesPerSecond(int samplesPerSecond) { 52 | this.samplesPerSecond = samplesPerSecond; 53 | } 54 | 55 | public void setBins(int bins) { 56 | this.bins = bins; 57 | } 58 | 59 | public void setNumChannels(int numChannels) { 60 | this.numChannels = numChannels; 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/tools/Animations.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.tools; 2 | 3 | import android.view.View; 4 | import android.view.animation.Animation; 5 | import android.view.animation.LinearInterpolator; 6 | import android.view.animation.RotateAnimation; 7 | 8 | public final class Animations { 9 | 10 | private Animations() { 11 | 12 | } 13 | 14 | public static void rotateView(View view, float fromDegrees, float toDegrees) { 15 | RotateAnimation rotate = new RotateAnimation(fromDegrees, toDegrees, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 16 | rotate.setInterpolator(new LinearInterpolator()); 17 | rotate.setRepeatCount(Animation.INFINITE); 18 | rotate.setDuration(30000); 19 | rotate.setInterpolator(new LinearInterpolator()); 20 | view.startAnimation(rotate); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/tools/BaselineCorrectionFunction.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.tools; 2 | 3 | import android.annotation.TargetApi; 4 | 5 | import java.util.function.Function; 6 | 7 | import io.neurolab.utilities.MathBasics; 8 | 9 | @TargetApi(24) 10 | public class BaselineCorrectionFunction implements Function { 11 | 12 | private int sampleSize; 13 | private int sampleCount; 14 | private double currentMean; 15 | 16 | public BaselineCorrectionFunction(int sampleSize) { 17 | this.sampleSize = sampleSize; 18 | this.sampleCount = 0; 19 | } 20 | 21 | @Override 22 | public Double apply(Double value) { 23 | incrementSampleCount(); 24 | 25 | currentMean = MathBasics.updateMean(currentMean, sampleCount, value); 26 | return value - currentMean; 27 | } 28 | 29 | private void incrementSampleCount() { 30 | sampleCount = sampleCount < sampleSize ? sampleCount + 1 : sampleCount; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/tools/ResourceManager.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.tools; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import java.io.File; 7 | import java.net.URL; 8 | 9 | public class ResourceManager { 10 | public static ResourceManager resourceManager; 11 | private static ClassLoader classLoader; 12 | public static boolean loadFromPhone = false; 13 | private Context context; 14 | 15 | private static String TAG = ResourceManager.class.getCanonicalName(); 16 | 17 | public static ResourceManager getInstance() { 18 | if (resourceManager == null) { 19 | resourceManager = new ResourceManager(); 20 | classLoader = resourceManager.getClass().getClassLoader(); 21 | } 22 | return resourceManager; 23 | } 24 | 25 | public File getResource(Context context, String resourceName) { 26 | this.context = context; 27 | Log.d(TAG, "loading resource '" + resourceName + "'"); 28 | if (resourceName.startsWith("ABSPATH:")) { 29 | return new File(this.context.getFilesDir(), resourceName.substring(8)); 30 | } 31 | if (loadFromPhone) 32 | return new File(this.context.getFilesDir(), "./resources/" + resourceName); 33 | 34 | URL resource = classLoader.getResource(resourceName); 35 | if (resource == null) 36 | return new File(resourceName); 37 | else 38 | return new File(classLoader.getResource(resourceName).getFile().replaceAll("%20", " ")); 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/tools/Utils.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.tools; 2 | 3 | import java.io.BufferedInputStream; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.InputStream; 7 | 8 | public class Utils { 9 | 10 | public static int countLines(String filename) throws Exception { 11 | return countLines(new File(filename)); 12 | } 13 | 14 | public static int countLines(File file) throws Exception { 15 | 16 | try (InputStream input = new BufferedInputStream(new FileInputStream(file))) { 17 | byte[] c = new byte[1024]; 18 | int count = 0; 19 | int readChars = 0; 20 | boolean empty = true; 21 | while ((readChars = input.read(c)) != -1) { 22 | empty = false; 23 | for (int i = 0; i < readChars; ++i) { 24 | if (c[i] == '\n') { 25 | ++count; 26 | } 27 | } 28 | } 29 | return (count == 0 && !empty) ? 1 : count; 30 | } catch (Exception e) { 31 | throw e; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/utilities/ConfigUtils.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.utilities; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.gson.Gson; 6 | 7 | import java.io.File; 8 | import java.io.FileInputStream; 9 | import java.io.FileOutputStream; 10 | import java.io.IOException; 11 | 12 | import io.neurolab.settings.ConfigurationSettings; 13 | 14 | public class ConfigUtils { 15 | 16 | private static final String CONFIG_FILE_NAME = "config.json"; 17 | 18 | public static ConfigurationSettings loadSettingsConfig(Context context){ 19 | File configFile = new File(context.getFilesDir(), CONFIG_FILE_NAME); 20 | if(!configFile.isFile()){ 21 | return new ConfigurationSettings(); 22 | } 23 | 24 | String json = readConfigFile(configFile); 25 | 26 | Gson gson = new Gson(); 27 | ConfigurationSettings configurationSettings = gson.fromJson(json, ConfigurationSettings.class); 28 | return configurationSettings; 29 | } 30 | 31 | public static void saveSettingsConfig(Context context, ConfigurationSettings configurationSettings){ 32 | File configFile = new File(context.getFilesDir(), CONFIG_FILE_NAME); 33 | 34 | if(!configFile.isFile()){ 35 | createConfigFile(configFile); 36 | } 37 | 38 | Gson gson = new Gson(); 39 | String json = gson.toJson(configurationSettings); 40 | 41 | try(FileOutputStream fos = new FileOutputStream(configFile, false)){ 42 | byte[] b = json.getBytes(); 43 | fos.write(b); 44 | }catch (IOException e){ 45 | e.printStackTrace(); 46 | } 47 | } 48 | 49 | private static void createConfigFile(File configFile){ 50 | try{ 51 | configFile.createNewFile(); 52 | } 53 | catch (IOException e){ 54 | e.printStackTrace(); 55 | } 56 | } 57 | 58 | private static String readConfigFile(File configFile){ 59 | String json = null; 60 | 61 | try(FileInputStream fis = new FileInputStream(configFile)) { 62 | int size = fis.available(); 63 | byte[] buffer = new byte[size]; 64 | fis.read(buffer); 65 | json = new String(buffer, "UTF-8"); 66 | } catch (IOException ex) { 67 | ex.printStackTrace(); 68 | } 69 | 70 | return json; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/utilities/Filter.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.utilities; 2 | 3 | public class Filter { 4 | 5 | private double resonance; 6 | private double frequency; 7 | private int sampleRate; 8 | private boolean lowPass; 9 | private double c, a1, a2, a3, b1, b2; 10 | private double[] inputHistory = new double[2]; 11 | private double[] outputHistory = new double[3]; 12 | 13 | public Filter() { 14 | } 15 | 16 | public Filter(double frequency, int sampleRate, boolean lowPass, double resonance) { 17 | setFilter(frequency, sampleRate, lowPass, resonance); 18 | } 19 | 20 | private void setCoefficients() { 21 | if (lowPass) { 22 | c = 1.0f / (float) Math.tan((Math.PI * frequency) / sampleRate); 23 | a1 = 1.0f / (1.0f + (resonance * c) + (c * c)); 24 | a2 = 2f * a1; 25 | a3 = a1; 26 | b1 = 2.0f * (1.0f - (c * c)) * a1; 27 | b2 = (1.0f - (resonance * c) + (c * c)) * a1; 28 | 29 | } else { // high Pass filter 30 | c = (float) Math.tan((Math.PI * frequency) / sampleRate); 31 | a1 = 1.0f / (1.0f + (resonance * c) + (c * c)); 32 | a2 = -2f * a1; 33 | a3 = a1; 34 | b1 = 2.0f * ((c * c) - 1.0f) * a1; 35 | b2 = (1.0f - (resonance * c) + (c * c)) * a1; 36 | } 37 | } 38 | 39 | public void setFilter(double frequency, int sampleRate, boolean lowPass, double resonance) { 40 | this.resonance = resonance; 41 | this.frequency = frequency; 42 | this.sampleRate = sampleRate; 43 | this.lowPass = lowPass; 44 | setCoefficients(); 45 | } 46 | 47 | public double update(double newInput) { 48 | double newOutput = (a1 * newInput) + (a2 * this.inputHistory[0]) + (a3 * this.inputHistory[1]) 49 | - (b1 * this.outputHistory[0]) - (b2 * this.outputHistory[1]); 50 | 51 | this.inputHistory[1] = this.inputHistory[0]; 52 | this.inputHistory[0] = newInput; 53 | 54 | this.outputHistory[2] = this.outputHistory[1]; 55 | this.outputHistory[1] = this.outputHistory[0]; 56 | this.outputHistory[0] = newOutput; 57 | 58 | return this.outputHistory[0]; 59 | } 60 | 61 | public double getValue() { 62 | return this.outputHistory[0]; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/utilities/NeuroUtils.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.utilities; 2 | 3 | import java.util.HashMap; 4 | 5 | public class NeuroUtils { 6 | 7 | public static HashMap getHexLookUpTable(float startVal, float endVal, int val) { 8 | 9 | HashMap lookUpTable = new HashMap(); 10 | 11 | float range = Math.abs(startVal - endVal); 12 | 13 | float step = range / (float)val; 14 | float curVal = startVal; 15 | 16 | for (int i = 0; i < val+1; i++) { 17 | String hex = Integer.toHexString(i); 18 | while (hex.length()<3) 19 | hex="0"+hex; 20 | lookUpTable.put(hex, curVal); 21 | curVal += step; 22 | } 23 | return lookUpTable; 24 | } 25 | 26 | public static long parseUnsignedHex(String text) { 27 | try { 28 | return Long.parseLong(text, 16); 29 | } 30 | catch (NumberFormatException e) { 31 | System.err.println("tried to interpret a non-valid hexadecimal value! (string: '" + text + "')"); 32 | } 33 | return 0l; 34 | } 35 | 36 | public static HashMap getBrainduinoDefaultLookupTable() { 37 | int val = 1023; 38 | float startVal = -100f; 39 | float endVal = 100f; 40 | HashMap lookUpTable = getHexLookUpTable(startVal, endVal, val); 41 | return lookUpTable; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/io/neurolab/utilities/PinDetails.java: -------------------------------------------------------------------------------- 1 | package io.neurolab.utilities; 2 | 3 | public class PinDetails { 4 | 5 | private String name; 6 | private String description; 7 | private int categoryColor; 8 | private int colorID; 9 | 10 | public PinDetails(String name, String description, int categoryColor, int colorID) { 11 | this.name = name; 12 | this.description = description; 13 | this.categoryColor = categoryColor; 14 | this.colorID = colorID; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public String getDescription() { 22 | return description; 23 | } 24 | 25 | public int getCategoryColor() { 26 | return categoryColor; 27 | } 28 | 29 | public int getColorID() { 30 | return colorID; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_down.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_up.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/color/bottom_tab_item_foreground.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi-v4/bg_focus_background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable-nodpi-v4/bg_focus_background.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi-v4/universe_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable-nodpi-v4/universe_bg.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi-v4/yantra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable-nodpi-v4/yantra.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_send.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_share.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/meditation_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable-xxhdpi/meditation_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/app_logo.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable/app_logo.JPG -------------------------------------------------------------------------------- /app/src/main/res/drawable/back_pin_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable/back_pin_layout.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_bg_rounded.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/dialog_body_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | 10 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/dialog_header_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | 10 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/front_pin_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable/front_pin_layout.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/game_one_pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable/game_one_pic.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/gradient_focus.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/gradient_meditation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/gradient_mem_graph.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/gradient_relax.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_brain.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_bug_report_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_card_focus.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_card_meditation.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_card_mem_graph.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_card_relax.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_device_connected.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_disconnected.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_edit.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_file_black.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_graph.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_happiness.xml: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_happy.xml: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_happy_black.xml: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_import.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_indicator.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_info.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_insert_drive_file_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_intro_guide2.xml: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_lg_break.xml: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_offline_dot.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 16 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pause_meditate.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_person_black.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_play.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_play_meditate.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_refresh_meditate.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_rocket_focus.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_rocket_focus_indicator.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_spectrum.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_starsone.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_starsthree.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_starstwo.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_stats.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_stop.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_travel.xml: -------------------------------------------------------------------------------- 1 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_update.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/icons8_usb_connected_100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable/icons8_usb_connected_100.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/icons_usb_disconnected_100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable/icons_usb_disconnected_100.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/neurolab_back_colormap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable/neurolab_back_colormap.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/neurolab_front_colormap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable/neurolab_front_colormap.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/splash_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/neurolab-android/1c99d825f6bc7980a127646763bb6e9f48007c85/app/src/main/res/drawable/splash_image.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/splash_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/font/montserrat.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | 15 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_data_logger.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 17 | 18 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 16 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_meditation_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 23 | 24 | 30 | 31 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_memory_graph_parent.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 18 | 19 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_pin_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_program_mode.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 15 | 16 | 17 | 18 | 22 | 23 | 27 | 28 | 29 | 30 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_share_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 17 | 18 |