File: README.md
Oboe [](https://github.com/google/oboe/actions)
Oboe is a C++ library which makes it easy to build high-performance audio apps on Android. It was created primarily to allow developers to target a simplified API that works across multiple API levels back to API level 16 (Jelly Bean).
Features
- Compatible with API 16 onwards - runs on 99% of Android devices
- Chooses the audio API (OpenSL ES on API 16+ or AAudio on API 27+) which will give the best audio performance on the target Android device
- Automatic latency tuning
- Modern C++ allowing you to write clean, elegant code
- Workarounds for some known issues
- Used by popular apps and frameworks
Documentation
- Getting Started Guide
- Full Guide to Oboe
- API reference
- History of Audio features/bugs by Android version
- Migration guide for apps using OpenSL ES
- Frequently Asked Questions (FAQ)
- Wiki
- Our roadmap - Vote on a feature/issue by adding a thumbs up to the first comment.
Community
- Reddit: r/androidaudiodev
- StackOverflow: #oboe
Testing
Videos
- Getting started with Oboe
- Low Latency Audio - Because Your Ears Are Worth It (Android Dev Summit '18)
- Winning on Android - How to optimize an Android audio app. (ADC '18)
Sample code and apps
- Sample apps can be found in the samples directory.
- A complete "effects processor" app called FXLab can be found in the apps/fxlab folder.
- Also check out the Rhythm Game codelab.
Third party sample code
- Ableton Link integration demo (author: jbloit)
Contributing
We would love to receive your pull requests. Before we can though, please read the contributing guidelines.
Version history
View the releases page.
License
File: apps/OboeTester/docs/AutomatedTesting.md
Automated Testing
OboeTester can be used to measure the round trip latency and glitches.
It can be launched from a shell script by using an Android Intent.
Before running the app from an Intent, it should be launched manually and a Round Trip Latency test run. Then you can give permission for using the microphone to record the looped back sound, and give permission to write to external storage for saving the test result.
Requirements
All tests require:
- host computer
- ADB installed
- ADB USB cable
The latency, glitch and data_paths tests also need:
- loopback adapter
- a 3.5 mm jack on the phone*
* If you don't have a 3.5 mm jack then you can use a USB-C to 3.5mm adapter.
In order to use ADB at the same time you will also need a USB switching device
or use ADB/Wifi.
Start App from Intent
The app can be started by sending a Start comment to the OboeTester class.
The app will run and the results will be written to a file.
adb shell am start -n com.mobileer.oboetester/.MainActivity {parameters}String parameters are sent using:
--es {parameterName} {parameterValue}For example:
--es test latencyInteger parameters are sent using:
--ei {parameterName} {parameterValue}For example:
--ei buffer_bursts 8Boolean parameters are sent using:
--ez {parameterName} {parameterValue}For example:
--ez use_input_presets falseParameters
There are two required parameters for all tests:
--es test {latency, glitch, data_paths, input, output, cpu_load}
The "latency" test will perform a Round Trip Latency test.
It will request EXCLUSIVE mode for minimal latency.
The "glitch" test will perform a single Glitch test.
The "data_paths" test will verify input and output streams in many possible configurations.
The "input" test will open and start an input stream.
The "output" test will open and start an output stream.
The "cpu_load" test will run the CPU LOAD activity.
--es file {name of resulting file}The file will be stored in a directory that can be written by OboeTester without any special permissions.
This is typically "/storage/emulated/0/Android/data/com.mobileer.oboetester/files/".
There are some optional parameter in common for all tests:
--ef volume {volume} // normalized volume in the range of 0.0 to 1.0
--es volume_type {"accessibility", "alarm", "dtmf", "music", "notification", "ring", "system", "voice_call"}
Stream type for the setStreamVolume() call. Default is "music".
--ez background {"true", 1, "false", 0} // if true then Oboetester will continue to run in the background
--ez foreground_service {"true", 1, "false", 0} // if true then Oboetester will ask for record/play permissions via a foreground service
--ez audio_focus {"true", 1, "false", 0} // if true then Oboetester will request for audio focus. Default is true.There are several optional parameters in common for glitch, latency, input, and output tests:
--ei buffer_capacity {capacity} // number of frames in the buffer, default is UNSPECIFIED.
--ei buffer_bursts {bursts} // number of bursts in the buffer, 2 for "double buffered". Do not use together with buffer_frames to avoid conflict. When both set, buffer_bursts will be ignored.
--ei buffer_frames {frames} // number of frames in the buffer, do not use together with buffer_bursts to avoid conflict. When both set, buffer_bursts will be ignored.
--es in_api {"unspecified", "opensles", "aaudio"} // native input API, default is "unspecified"
--es out_api {"unspecified", "opensles", "aaudio"} // native output API, default is "unspecified"
--es in_channel_mask {"mono", "stereo", "2.1", "tri", "triBack", "3.1", "2.0.2", "2.1.2", "3.0.2", "3.1.2", "quad", "quadSide", "surround", "penta", "5.1", "5.1Side", "6.1", "7.1", "5.1.2", "5.1.4", "7.1.2", "7.1.4", "9.1.4", "9.1.6", "frontBack"}
--es out_channel_mask {"mono", "stereo", "2.1", "tri", "triBack", "3.1", "2.0.2", "2.1.2", "3.0.2", "3.1.2", "quad", "quadSide", "surround", "penta", "5.1", "5.1Side", "6.1", "7.1", "5.1.2", "5.1.4", "7.1.2", "7.1.4", "9.1.4", "9.1.6", "frontBack"}
--ei in_channels {samples} // number of input channels, default is 2. This is ignored if in_channel_mask is set.
--ei out_channels {samples} // number of output channels, default is 2. This is ignored if out_channel_mask is set.
--es in_format {"pcm_16_bit", "pcm_float", "pcm_24_bit", "pcm_32_bit", "iec61937", "mp3"}
--es out_format {"pcm_16_bit", "pcm_float", "pcm_24_bit", "pcm_32_bit", "iec61937", "mp3"}
--ei sample_rate {hertz}
--es in_perf {"none", "lowlat", "powersave"} // input performance mode, default is "lowlat"
--es out_perf {"none", "lowlat", "powersave", "powersave_offload"} // output performance mode, default is "lowlat", "powersave_offload" will only be available for output stream
--es out_usage {"media", "voice_communication", "alarm", "notification", "game"} // default is media
--es in_sharing {"shared", "exclusive"} // input sharing mode, default is "exclusive"
--es out_sharing {"shared", "exclusive"} // output sharing mode, default is "exclusive"
--ez in_use_mmap {"true", 1, "false", 0} // if true then MMAP is allowed, if false then MMAP will be disabled
--ez out_use_mmap {"true", 1, "false", 0} // if true then MMAP is allowed, if false then MMAP will be disabledThere are some optional parameters in common for glitch, input, and output tests:
--ei duration {seconds} // glitch test duration, default is 10 seconds
--ez restart_if_closed {"true", 1, "false", 0} // if true, restart stream if its closed or disconnectedThere are several optional parameters for just the "glitch" test:
--ef tolerance {tolerance} // amount of deviation from expected that is considered a glitch
// Range of tolerance is 0.0 to 1.0. Default is 0.1. Note use of "-ef".
// input preset, default is "voicerec"
--es in_preset ("generic", "camcorder", "voicerec", "voicecomm", "unprocessed", "performance"}There are several optional parameters for just the "data_paths" test. Note the Note the use of "-ez" for the boolean parameters.
--ez use_input_presets {"true", 1, "false", 0} // Whether to test various input presets.
--ez use_all_sample_rates {"true", 1, "false", 0} // Whether to test all sample rates. Note use of "-ez". Default is false
--ei single_test_index {testId} // Index for testing one specific testThese parameters are used with the "data_paths" test starting with v2.5.11.
--ez use_input_channel_masks {"true", 1, "false", 0} // Whether to test the reported input channel MASKS. Default is false.
--ez use_all_channel_counts {"true", 1, "false", 0} // Whether to test all the supported channel COUNTS. Default is true.
--ei output_channel_masks_level {0, 1, 2} // Whether to test NONE=0, SOME=1, or ALL=2 channel masks. Default is false.These parameters were used with the "data_paths" test prior to v2.5.11.
--ez use_input_devices {"true", 1, "false", 0} // Whether to test various input devices.
--ez use_output_devices {"true", 1, "false", 0} // Whether to test various output devices.
--ez use_all_output_channel_masks {"true", 1, "false", 0} // Whether to test all output channel masks. Default is false.There are some optional parameters for just the "output" test:
--es signal_type {sine, sawtooth, freq_sweep, pitch_sweep, white_noise} // type of sound to play, default is sineThere are some optional parameters for just the "cpu_load" test:
--ez use_adpf {true, false} // if true, use work boost from performance hints. Default is false.
--ez use_workload {true, false} // if true and using ADPF then report workload changes. Default is false.
--ez scroll_graphics {true, false} // if true then continually update the power scope. Default is false.
--ez use_workload_increase_api {true, false} // if true and using ADPF, notify adpf with workload increase/reset apis. Default is false.For example, a complete command for a "latency" test might be:
adb shell am start -n com.mobileer.oboetester/.MainActivity \
--es test latency \
--ei buffer_bursts 2 \
--ef volume 0.8 \
--es volume_type music \
--ei out_channels 1 \
--es out_usage game \
--es file latency20230608.txtor for a "glitch" test:
adb shell am start -n com.mobileer.oboetester/.MainActivity \
--es test glitch \
--es in_perf lowlat \
--es out_perf lowlat \
--es in_sharing exclusive \
--es out_sharing exclusive \
--ei buffer_bursts 2 \
--ei sample_rate 48000 \
--ef tolerance 0.123 \
--ei in_channels 2 \
--es file glitch20230608.txtor for a "data_paths" test:
adb shell am start -n com.mobileer.oboetester/.MainActivity \
--es test data_paths \
--ez use_input_presets true \
--ez use_input_devices false \
--ez use_output_devices true \
--es file datapaths20230608.txtInterpreting Test Results
Test results are simple files with "name = value" pairs.
After running the test you can determine where the results file was written by entering:
adb logcat | grep EXTFILEThe test results can be obtained using adb pull. For example:
adb pull /storage/emulated/0/Android/data/com.mobileer.oboetester/files/glitch20230608.txt .The beginning of the report is common to latency and glitch tests:
build.fingerprint = google/cheetah/cheetah:14/MASTER/eng.philbu.20230518.172104:userdebug/dev-keys
test.version = 2.5.1
test.version.code = 72
time.millis = 1686156503523
in.channels = 2
in.perf = ll
in.preset = voicerec
in.sharing = ex
in.api = aaudio
in.rate = 48000
in.device = 22
in.mmap = yes
in.rate.conversion.quality = 0
in.hardware.channels = 2
in.hardware.sampleRate = 48000
in.hardware.format = i32
in.burst.frames = 96
in.xruns = 0
out.channels = 1
out.perf = ll
out.usage = game
out.contentType = music
out.sharing = ex
out.api = aaudio
out.rate = 48000
out.device = 3
out.mmap = yes
out.rate.conversion.quality = 0
out.hardware.channels = 2
out.hardware.sampleRate = 48000
out.hardware.format = float
out.burst.frames = 96
out.buffer.size.frames = 192
out.buffer.capacity.frames = 1920
out.xruns = 0Latency Report
Each test also adds specific value. For "latency". If the test fails then some values will be unavailable.
Here is a report from a good test. The '#' comments were added for this document and are not in the report.
confidence = 0.892 # quality of the latency result between 0.0 and 1.0, higher is better
result.text = OK # text equivalent of the result
latency.msec = 23.27 # round trip latency in milliseconds
latency.frames = 1117 # round trip latency in frames
latency.empty.msec = 19.27 # round trip latency if the top output buffer was empty
latency.empty.frames = 925 # same but translated to frames
rms.signal = 0.03142 # Root Mean Square of the signal, if it can be detected
rms.noise = 0.00262 # Root Mean Square of the background noise before the signal is detected
correlation = 0.975 # raw normalized cross-correlation peak
timestamp.latency.msec = 10.35 # latency based on timestamps
timestamp.latency.mad = 0.05 # Mean absolute deviation
timestamp.latency.count = 12 # number of measurements
reset.count = 1 # number of times the full duplex stream input underflowed and had to resynchronize
result = 0 # 0 or a negative errorHere is a report from a test that failed because the output was muted. Note the latency.msec is
missing because it could not be measured.
rms.signal = 0.00000
rms.noise = 0.00048
reset.count = 3
result = -96
result.text = ERROR_CONFIDENCE
confidence = 0.009Glitch Report
Here is a report from a good test. The '#' comments were added for this document and are not in the report.
tolerance = 0.123
state = LOCKED
unlocked.frames = 2528 # frames spent trying to lock onto the signal
locked.frames = 384084 # frames spent locked onto a good signal with no glitches
glitch.frames = 0 # frames spent glitching or recovering from a glitch
reset.count = 208 # number of times the full duplex stream input underflowed and had to resynchronize
peak.amplitude = 0.057714 # peak amplitude of the input signal, between 0.0 and 1.0
signal.noise.ratio.db = 96.3
time.total = 9.96 seconds # close to your specified duration
time.no.glitches = 9.96 # time we have been running with no glitches
max.time.no.glitches = 9.96 # max time with no glitches
glitch.count = 0 # number of glitch events, actual number may be higher if close togetherHere is a report from a test that failed because the output was muted. Note the glitch.count is
missing because it could not be measured.
state = WAITING_FOR_SIGNAL
unlocked.frames = 0
locked.frames = 0
glitch.frames = 0
reset.count = 1
time.total = 9.95 secondsData Paths Report
The report first goes through the info about the specific device before going through input preset tests,
input devices tests, and output tests.
Each will show the specific configuration of a test before showing whether it passed or failed.
At the end of the report, an analysis of the failed tests will be given
followed by the number of passed, failed, and skipped tests.
File: apps/OboeTester/docs/Build.md
How to Build OboeTester
Note that you can now download OboeTester from the Play Store.
But if you want the latest version, or if you want to debug OboeTester, then you can build it using Android Studio.
Download the top level oboe repository from GitHub.
Then use Android Studio (3.3 or above) to build the app in this "apps/OboeTester".
Requirements
- Android Studio
- Android device or emulator
- git installed on your computer (optional)
- USB cable to connect your computer and your phone
Download Oboe
You can either use git to clone Oboe or download a Zip archive.
If you use git then you can quickly update the code or contribute changes.
If you don't use git then just download the Zip archive.
- Visit https://github.com/google/oboe
- Click on the green button that says "Clone or Download" and follow the instructions.
Build and Run OboeTester
- Launch Android Studio
- Click Open from the File menu and browse to the "oboe/apps/OboeTester" folder. Select that folder.
- Wait about a minute for the project to load.
- Connect an Android phone to your computer using a USB cable.
- Look at your phone. You may need to give permission to use ADB on your phone.
- Select "Run App" from the "Run" menu.
- OboeTester should build and then appear on your Android device.
File: apps/OboeTester/docs/PrivacyPolicy.md
OboeTester Privacy Policy
Recorded Audio
OboeTester can record audio.
The data is only used to test the audio recording capability of your device.
These tests include:
- measuring round-trip audio latency
- measuring glitches by listening to an output sine wave
- recording audio for immediate playback and listening
Audio recording is always initiated by a button press.
It is possible for you, the user, to share WAV files that have been recorded.
You can email them to someone, or upload them to Google Drive, or send them to other Sharing destinations.
This is optional. No recorded audio is uploaded or saved by the program unless the user requests it.
Phone State
OboeTester can also check and modify the phone state. This is only used for testing modes like "Speaker Phone" or turning on or off Bluetooth SCO.
Test Results
The user can ask OboeTester to run automated tests that look for audio bugs or measure performance.
These generate reports that contain the results of the test plus information about the phone including:
- manufacturer (eg. Samsung)
- model (eg. S10)
- version and build information (eg. Pie 9.0)
- audio performance metrics (eg. latency, glitch rate)
- audio feature support (eg. AAudio MMAP)
But you, the user, can can email them to someone, or upload them to Google Drive, or send them to other Sharing destinations.
This is optional. No reports are uploaded or saved by the program unless the user requests it.
The source code for Oboetester is available here on GitHub.
File: apps/OboeTester/docs/README.md
OboeTester Documentation
OboeTester is an app that can be used to test many of the features of Oboe, AAudio and OpenSL ES.
It can also be used to test Android devices, measure latency and glitches, etc.
OboeTester can be run as an interactive app.
It can also be run as part of an automated test using Intents
Install OboeTester
You have two options:
- Download OboeTester from the Play Store
- OR build the latest version of OboeTester using Android Studio
[How to Use OboeTester Interactively](Usage.md)
[Automated Testing with OboeTester](AutomatedTesting.md)
-- Privacy Policy --
File: apps/OboeTester/docs/TestOutput.md
Test Output
DRAFT for testing image embedding.
| Notes | Screenshot |
|---|---|
| Tap on the green bar to hide or show the detailed settings dialog. |
The resulting setting will displayed on the far right when the stream is opened.
API: select between OpenSL ES or AAudio (default)
Device: setect output device by type.
Format: note that the 24 and 32-bit formats are only supported in Android 12+. MP3 is only supported on Android 16+. The test uses a 44.1kHz stereo MP3 file for playback. The stream must be configured as 44.1kHz stereo selecting MP3 format.
MMAP: will be disabled if device does not support MMAP
Effect: will enable a simple effect, may prevent LOW_LATENCY
Convert: conversion done in Oboe may allow you to get LOW_LATENCY
SRC: sample rate conversion quality | |File: apps/OboeTester/docs/Usage.md
How to Use OboeTester
Loopback Adapter Needed for Some Tests
Some of these tests require an audio Loopback Adapter that plugs into a 3.5 mm jack.
If the phone does not have a 3.5 mm jack then you can combine that with a USB to 3.5mm adapter.
Loopback adapters can be purchased from PassMark Software.
Test Activities
Launch OboeTester and then select one of the test Activities.
Test Output
Tap the green bar to expand the Settings display.
Test opening, starting, stopping and closing a stream.
Various stream parameters can be selected before opening.
While the stream is playing, the frame counts and stream state are displayed.
The latency is estimated based on the timestamp information.
Experiment with changing the buffer size to see if there are glitches when the size is high or low.
Experiment with changing the "Workload".
Watch the "% CPU" and the #XRuns.
The audio is expected to glitch when the workload is high because there is too much work
and the audio task misses its delivery deadlines.
The extra workload is generated by calculating a number of classic synthesizer voices with two oscillators, two envelopes and a resonant filter.
You can see the affect of the changing workload in the "% cpu" report in the status area.
The extra workload will always cause glitching when you get close to 100% CPU load.
If the workload is causing glitching at a low % CPU load then there may be a problem with the callback timing.
A variety of output signals can be played including frequency sweeps and white noise.
The default output sound is a sine wave on each channel. The base frequency is 330 Hz
and increases by a ratio of 4:3 (a perfect fourth) for each channel.
Instructions for using TEST OUTPUT for 4 or more chanels is in
Wiki/OboeTester_MultiChannelOutput.
Test Input
Test input streams. Displays current volume as VU bars.
Tap to Tone Latency
Measure touch screen latency plus audio output latency.
Press START then tap on the screen with your fingertip.
The app will listen for the sound of your fingernail tapping the screen
and the resulting beep, and then measure the time between them.
If you use headphones then you can eliminate the latency caused by speaker protection.
If you use USB-MIDI input then you can eliminate the latency due to the touch screen, which is around 15-30 msec.
MIDI latency is generally under 1 msec.
This test works well for measuring the output latency of Bluetooth headsets.
More instructions in the Wiki/OboeTester_TapToTone.
Echo Input to Output
This test copies input to output and adds up to 3 seconds of delay.
This can be used to simulate high latency on a phone that supports low latency.
Try putting the phone to your ear with the added delay at 0 and try talking.
Then set it to about 700 msec and try talking on the phone. Notice how the echo can be very confusing.
The test will also display estimated "cold start latency" for full duplex streams.
Round Trip Latency
This test works with either a loopback adapter or through speakers.
Latency through the speakers will probably be higher.
It measures the input and output latency combined.
- Set the Input or Output settings by tapping the green bar to expose the controls.
- Set the volume somewhere above the middle. The test works at almost any volume. But the confidence will be higher at higher volumes.
- Tap "MEASURE" to make a single measurement.
- Or tap "AVERAGE" to run the test several times and report an average and Mean Absolute Deviation.
The test starts by setting up a stable full-duplex stream.
Then it outputs a random series of bits encoded using smoothed Manchester Encoding.
We record the Input and Output stream together for about a second.
Then we correlate the two streams by sliding the portion of the output stream that contains the random bits over the input stream at different time offsets.
The Manchaster Encoded signal provide a very sharp peak when the offset matches the combined input and output latency.
Source code for the analyzer in LatencyAnalyzer.h.
Record and Play
- Tap RECORD to record several seconds of audio. You should see the red VU meters move.
- Tap STOP then PLAY to play it back.
- Tap SHARE button to the recorded WAV file to GDrive, GMail or another app.
You can then examine the WAV file using a program like Audacity.
Glitch Test
This test works best with a loopback adapter. But it can also work in a quiet room.
It plays a sine wave and then tries to record and lock onto that sine wave.
If the actual input does not match the expected sine wave value then it is counted as a glitch.
The test will display the maximum time that it ran without seeing a glitch.
- Plug in loopback adapter. (Optional)
- Press green bars to show input and output settings. Make changes. (optional)
- Press START button.
- Watch for state=LOCKED, which means it has detected and locked onto the sine wave output.
- Note the glitch count, which should be zero.
- Also the "max.time.no.glitches" should be as long as you run the test.
- Press STOP button.
- Press SHARE button to send a WAV file recording of the last glitch by email to yourself.
Look for the #XRuns display.
If #XRuns increments when a glitch occurs then the glitch is probably due to preemption of the audio task.
If #XRuns is not incrementing then the glitches may be due to AAudio MMAP tuning errors in the HAL.
Auto Glitch Test
Measure glitches for various combinations of input and output settings.
Change the test duration to a high value and let it run for a while.
If you get glitches in one configuration then you can investigate using the previous manual Glitch Test.
The Share button will let you email the report to yourself.
Test Disconnect
You can test whether the disconnect logic is working in Android by plugging or unplugging a headset.
Just follow the instructions in red. You will get a report at the end that you can SHARE by GMail or Drive.
Device Report
Provides a device report. This report includes info about the features enabled, the properties set, audio
paths, and microphones.
You can share this report by first pressing the icon with the three vertical dots at the top right of OboeTester.
After that, simply press the share button and you should be able to email this to yourself.
Data Paths
This checks for dead channels, broken Input Presets and other audio data path problems.
- Tap "DATA PATHS" button.
- Connect an analog or USB loopback adapter if desired.
- Set volume to medium high.
- Place the phone on a table and hit START.
- If you are testing the speaker/mic combination then the room must be quiet. You will hear some sine tones.
- Wait a few minutes, quietly, for the test to complete.
- You will get a report at the end that you can SHARE by GMail or Drive.
When a subtest fails it will write a WAV file of the recorded audio to storage. You can pull the file from the Android device and
view it using Audacity of other audio editor. For example, if test #7 failed, enter:
adb pull /storage/emulated/0/Android/data/com.mobileer.oboetester/files/Music/glitch_007.wav ~/.External Tap-to-Tone
This lets you measure the latency between touching a screen to the sound coming out on a second device.
You could use this to measure, for example, the latency on an iPhone.
- Launch OboeTester on Android device (A) in a quiet room.
- Tap "EXTRAS..." button.
- Tap "EXTERNAL TAP" button.
- Launch a program on a second device (B) that will make a sound when you touch the screen. A good example would be an interactive drum pad.
- Tap "START" button to start listening on device (A).
- Tap on the app on the device (B) with your fingertip. You need to make a noise with your fingernail.
- Quickly tap the "ANALYSE" button on device (A).
- OboeTester will now look for two sounds in the recording and measure the time between them.
Plug Latency
Measures the time it takes to close, open, and start streams as audio devices are plugged in and removed.
Error Callback Test
Lets you delete an error callback while it is used by Oboe. Targeted test for issue #1603.
Route Callback Test
Changes the VoiceCommunication route while playing audio. Targeted test for issue #1763.
CPU Load
This test plays a tone and alternates between low and high workloads.
It exercises the kernel's CPU scheduler, which controls CPU frequency and core migration.
More details on the wiki/OboeTester_DynamicCpuLoad.
File: apps/OboeTester/README.md
Oboe Tester
OboeTester is an app that can be used to test many of the features of Oboe, AAudio and OpenSL ES.
It can also be used to measure device latency and glitches.
[OboeTester Documentation](docs)
File: apps/fxlab/docs/Dev-Guide.md
Development
The effects included are designed to be as portable as possible, as well as making it easy to add additional effects.
Building
To build the app, simply open the project in android studio and build. The app integrates Oboe via a git submodule. Make sure
when cloning the repository to clone the submodule as well using git clone --recursive, or git submodule update --init --recursive.
To update the version of Oboe being used, descend into the Oboe repository (oboe location)
and update from its remote. Then, call git submodule update in this repository. Alternatively git submodule update --recursive --remote will pull the latest version of Oboe from remote.
Although the CMake file requires android headers (to use Oboe), the effects themselves can be compiled with any C++17 compliant compiler.
Architecture
The UI code (Kotlin) calls native code through the JNI bridge to query information about the various effects implemented,
and how to render the effect information in the UI. This means that adding an effect only needs to be done on the
native side. The JNI bridge passes information regarding implemented effects descriptions to the UI as well as functions
called when the user modifies effects in the UI.
The DuplexEngine is responsible for managing and syncing the input and output Oboe streams for rendering audio
with as low latency as possible. The FunctionList class contains the a vector of effects that correspond to the list of
effects (and their parameters) that the user wants to use to process their audio. Effects (and the FunctionList) overload
their function operator to take in two numeric iterator types. E.g <template iter_type> void operator() (iter_type begin, iter_type end), where the iter_types correspond to C++ iterators carrying audio data. To erase the type
of different objects, the FunctionList holds objects of types std::function<void(iter_type, iter_type)> i.e. functions
which operate on the range between two numeric iterators in place. The DuplexEnginesimply calls the FunctionList on every
buffer of samples it receives.
The effects folder contains the classes of various implemented effects. It also contains Effects.h where a global tuple of
all the Effect descriptions implemented lives. The description folder contains the description for all of the effects.
Each description takes the form of a class with static methods providing information regarding the effect (including name,
category, parameters, and a factory method).
Adding Effects
To add an effect, simply add a Description class similar to the existing classes, and add the class to the tuple in Effects.h. The description must provide a way to build the effect by either constructing another class corresponding
to an effect, or pointing to a standalone function. Adding new effects is welcome!
Existing Effects
A instructional implemented effect to examine is the TremoloEffect.h (a modulating gain).
Many of the effects in the delay category
inherit from DelayLineEffect which provides a framework to easily implement many delay based effects, as well as
the comb filter effects (FIR, IIR, allpass). The slides have a block diagram displaying the mathematical basis of the effect.
The nonlinear effects (distortion and overdrive) are implemented using a standalone function (from SingleEffectFunctions.h.
The gain effect is implemented by a simple lambda in its description class.