A mobile application for nasalance measurement and speech assessment
- Overview
- Features
- Prerequisites
- Database Setup
- Installation
- Configuration
- Running the App
- Key Components
- Project Structure
- Technology Stack
- Team
- Contributing
- License
nasomEATR is a specialized mobile application designed for speech-language pathologists and clinicians to measure and assess nasalance in patients. The app uses dual-microphone input to simultaneously record oral and nasal acoustic data, analyze speech patterns, and provide real-time feedback on nasalance measurements.
- Account Creation & Login: Create and access accounts using email and password
- Secure Authentication: Authentication powered by Supabase
- Patient Creation:
- Create new patient profiles with Medical Record Number (MRN)
- Assign sex (M/F) and date of birth
- Add demographic information (languages, ethnicity, race, country of origin)
- Patient Editing: Edit patient information after creation
- Patient Profiles:
- View comprehensive patient information and demographics
- Track total evaluations and average nasalance scores
- View nasalance trends over time via graphical representation
- Export evaluation results to CSV
- Add clinical notes to patient profiles
- Device Connection: Connect to compatible stereo microphones via USB-C transmitter
- Audio Recording: Record from dual microphone sources simultaneously
- Audio Processing: On-device audio splitting into oral and nasal channels
- Result Analysis: View nasalance scores after recording
- Audio Playback: Play back audio from both oral and nasal channels
Sound pressure level (SPL) or acoustic pressure level (APL) is a logarithmic measure of the effective pressure of a sound relative to a reference value.
Sound pressure level, denoted Lp and measured in dB.
where
- p is the root mean square sound pressure,
- p0 is a reference sound pressure,
- 1 Np is the neper,
- 1 B = (
$\frac{1}{2}\ln 10$ ) Np is the bel, - 1 dB = (
$\frac{1}{20}\ln 10$ ) Np is the decibel.
You can actually test out and grab the SPL from bitstreams through using a python script, something like so will do:
y, sr = librosa.load(audio_path)
rms = librosa.feature.rms(y=y, frame_length=512)[0] # Get RMS energy
rsp = 20e-6 # Reference Sound Pressure
spl_db = 20 * np.log10(rms / rsp)
mean_spl = np.mean(spl_db)
max_spl = np.max(spl_db)
min_spl = np.min(spl_db)Otherwise, you can calculate the sound pressure level through this equation:
over the course of the audio file / recorded period for our pediatric patient that easily with just 2 mics.
- Analysis: Identification of low/high nasalance
- Playback: Review audio recordings from both channels
- Device Info: Display details of connected recording devices
- Microphone Testing: Test microphones without saving to patient profiles
Before installing nasomEATR, ensure you have the following:
- Node.js (v16 or newer)
- npm (v8 or newer) or yarn (v1.22 or newer)
- Git
- Android Studio (for Android development)
- Android SDK Platform 33+
- Android SDK Build-Tools 33.0.0+
- Android Virtual Device (or physical device)
- JDK 11 or newer
- Expo CLI (
npm install -g expo-cli) - eas-cli (
npm install -g eas-cli)
Follow these steps to set up the Supabase database for nasomEATR:
-
Create a Supabase account using your GitHub or email account. If you already have a Supabase account, create a new organization for this project.
-
Using the SQL Editor in Supabase, create the following tables in the exact order provided:
create table public.clinician (
id uuid not null,
email text null,
username text null,
full_name text null,
constraint clinician_pkey primary key (id),
constraint clinician_email_key unique (email),
constraint clinician_id_key unique (id),
constraint clinician_username_key unique (username),
constraint clinician_id_fkey foreign KEY (id) references auth.users (id)
) TABLESPACE pg_default;
create table public.patient (
mrn bigint not null,
full_name text null,
dob date null,
created_at timestamp with time zone not null default now(),
assigned_clinician uuid null,
gender public.gender null,
picture_url text null,
notes text null,
first_language text null,
second_language text null,
ethnicity text null,
race text null,
country text null,
constraint patient_pkey primary key (mrn),
constraint patient_mrn_key unique (mrn),
constraint patient_assigned_clinician_fkey foreign KEY (assigned_clinician) references clinician (id)
) TABLESPACE pg_default;
create table public.patient_data (
id bigint generated by default as identity not null,
avg_nasalance_score double precision null,
created_at timestamp with time zone not null default now(),
nasal_audio text null,
oral_audio text null,
nasalance_data jsonb null,
mrn bigint null,
constraint patient_data_pkey primary key (id),
constraint patient_data_audio_link_key unique (nasal_audio),
constraint patient_data_id_key unique (id),
constraint patient_data_oral_audio_key unique (oral_audio),
constraint patient_data_mrn_fkey foreign KEY (mrn) references patient (mrn)
) TABLESPACE pg_default;-
Clone the repository:
git clone git@github.com:bluetooth-nasometer/nasomEATR.git cd nasomEATR -
Install dependencies:
npm install # or yarn install
-
Supabase Configuration:
- Create a
.envfile in the root directory:
REACT_APP_SB_API_KEY="your_supabase_api_key" - Create a
-
Android Configuration:
-
Enable Developer options and USB Debugging on your Android device:
- Go to Settings > About phone > Tap "Build number" 7 times
- Return to Settings > System > Developer options
- Enable USB debugging
-
For Windows: Ensure
android/local.propertieshas the correct SDK path:sdk.dir=C\:\\Users\\YourUsername\\AppData\\Local\\Android\\Sdk -
For Linux:
sdk.dir=/home/YourUsername/Android/Sdk
-
-
Expo Configuration:
- The app uses Expo Development Client. No additional configuration is needed for basic development.
-
Connect your Android device via USB
-
Enable USB debugging on your device
-
Run the following command:
npm run android # or yarn android -
Alternatively, open the Android project in Android Studio:
cd androidThen open the folder in Android Studio and click "Run"
-
Start the Expo development server:
npm start # or yarn start -
Use the Expo Go app on your device to scan the QR code, or press 'a' in the terminal to open on Android
The app uses the BluetoothRecorder utility to manage audio recording and device connections:
// Key methods in BluetoothRecorder.js
async startRecording(deviceId = null, onAmplitudeUpdate = null) {
// Initialize recording session with Bluetooth device
}
async stopRecording() {
// Stop recording and process audio files
}Authentication and data storage are managed through Supabase:
// supabaseClient.js
export const supabase = createClient(supabaseUrl, supabaseKey, {
auth: {
storage: AsyncStorage,
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: false,
},
});Real-time audio visualization is handled by the AudioVisualizer component:
// AudioVisualizer.js
const AudioVisualizer = ({
splData,
nasalSplData,
nasalanceData,
stats,
timer
}) => {
// Render waveforms and nasalance graphs
};For advanced audio processing, the app includes native Android modules:
// EnhancedAudioModule.java
public class EnhancedAudioModule extends ReactContextBaseJavaModule {
@ReactMethod
public void startRecording(String filePath, Promise promise) {
// Native audio recording implementation
}
}nasomEATR/
βββ android/ # Android native code
βββ assets/ # App assets (images, fonts)
βββ components/ # React components
β βββ common/ # Shared components
β βββ ... # Screen components
βββ constants/ # App constants
βββ modules/ # Native modules
βββ utils/ # Utility functions
β βββ BluetoothRecorder.js # Audio recording utility
β βββ supabaseClient.js # Supabase connection
β βββ ... # Other utilities
βββ App.js # App entry point
βββ app.json # Expo configuration
βββ index.js # JavaScript entry point
βββ package.json # Dependencies
- Frontend: React Native, Expo
- State Management: React Hooks
- Database/Backend: Supabase
- Authentication: Supabase Auth
- Audio Processing: React Native AV, Native Modules
- Data Visualization: React Native Chart Kit
- Navigation: React Navigation
- Storage: Expo FileSystem, AsyncStorage
- Bluetooth Integration: React Native Bluetooth Classic
| Name | Role | |
|---|---|---|
| Jasper Doan | Team Lead | jasperd1@uci.edu / jasperdoan@gmail.com |
| Kaila Long | Team Member | kailal2@uci.edu |
| Baly A. Martinez | Team Member | balym@uci.edu |
| Vaani Mathur | Team Member | vaanim@uci.edu |
| John Norombaba | Team Member | jnoromba@uci.edu |
| Shayla My Tien Ho | Team Member | shaylamh@uci.edu |
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Android: Android 8.0+
- iOS: Not supported in current version (lacks necessary libraries)
- Web: Not supported in current version
- Password Reset: To reset an account's password, use the "Send Password Recovery" link on your Supabase project dashboard under Authentication > Users.
- Deleting Evaluations: Please use Table Editor in Supabase to delete individual evaluations from the public.patient_data table.
- Edit Profile: Please use the Table Editor in Supabase to change individual information like name from the public.clinician table.
For support or inquiries, please contact the team members listed above or open an issue in the GitHub repository.
