Skip to content

Repository files navigation

JNI bindings for Roc Toolkit

buildcodecovAndroid releaseAndroid javadocMatrix chat

This library provides JNI bindings for Roc Toolkit, a toolkit for real-time audio streaming over the network.

The bindings can be used in Java, Kotlin, and other JVM-based languages.

Android support included!

About Roc

Key features of Roc Toolkit:

  • real-time streaming with guaranteed latency;
  • robust work on unreliable networks like Wi-Fi, due to use of Forward Erasure Correction codes;
  • CD-quality audio;
  • multiple profiles for different CPU and latency requirements;
  • relying on open, standard protocols, like RTP and FECFRAME;
  • interoperability with both Roc and third-party software.

Compatible Roc Toolkit senders and receivers include:

Documentation

Documentation for the Java API generated from javadoc comments can be found on javadoc.io.

Documentation for the C API can be found here.

Quick start

Sender

importorg.rocstreaming.roctoolkit.*;
try (RocContextcontext = newRocContext()) {
RocSenderConfigconfig = RocSenderConfig.builder()
.frameEncoding(
MediaEncoding.builder()
.rate(44100)
.format(Format.PCM_FLOAT32)
.channels(ChannelLayout.STEREO)
.build()
)
.fecEncoding(FecEncoding.RS8M)
.clockSource(ClockSource.INTERNAL)
.build();
try (RocSendersender = newRocSender(context, config)) {
EndpointsourceEndpoint = newEndpoint("rtp+rs8m://192.168.0.1:10001");
EndpointrepairEndpoint = newEndpoint("rs8m://192.168.0.1:10002");
sender.connect(Slot.DEFAULT, Interface.AUDIO_SOURCE, sourceEndpoint);
sender.connect(Slot.DEFAULT, Interface.AUDIO_REPAIR, repairEndpoint);
while (/* not stopped */) {
float[] samples = /* generate samples */sender.write(samples);
}
}
}

Receiver

importorg.rocstreaming.roctoolkit.*;
try (RocContextcontext = newRocContext()) {
RocReceiverConfigconfig = RocReceiverConfig.builder()
.frameEncoding(
MediaEncoding.builder()
.rate(44100)
.format(Format.PCM_FLOAT32)
.channels(ChannelLayout.STEREO)
.build()
)
.clockSource(ClockSource.INTERNAL)
.build();
try (RocReceiverreceiver = newRocReceiver(context, config)) {
EndpointsourceEndpoint = newEndpoint("rtp+rs8m://0.0.0.0:10001");
EndpointrepairEndpoint = newEndpoint("rs8m://0.0.0.0:10001");
receiver.bind(Slot.DEFAULT, Interface.AUDIO_SOURCE, sourceEndpoint);
receiver.bind(Slot.DEFAULT, Interface.AUDIO_REPAIR, repairEndpoint);
while (/* not stopped */) {
float[] samples = newfloat[320];
receiver.read(samples);
/* process received samples */
}
}
}

Bindings version

Java bindings and the C library both use semantic versioning.

Bindings are compatible with the C library when:

  • major version of bindings is same as major version of C library
  • minor version of bindings is same or higher as minor version of C library

Patch versions of bindings and C library are independent.

For example, version 1.2.3 of the bindings would be compatible with 1.2.x and 1.3.x, but not with 1.1.x (minor version is lower) or 2.x.x (major version is different).

Note that prebuilt AAR package for Android already ships the right version of libroc, so you don't need to bother with compatibility between bindings and libroc if you're using AAR.

Java and Android versions

Minimum Java version:

  • on build machine: JDK 17
  • on target machine: JRE 8 (== Java 1.8)

Minimum Android SDK version:

  • on build machine: API level 31 (Android 12 SDK)
  • on target machine: API level 29 (Android 10 runtime)

Minimum Android NDK version:

  • on build machine: NDK r21e

Use prebuilt AAR for Android

Add mavenCentral repository in build.gradle file:

repositories {
mavenCentral()
}

Add dependency to project (versions):

implementation 'org.roc-streaming.roctoolkit:roc-android:<VERSION>'

Build JAR for desktop

Install JDK 17 or higher.

Follow official instructions to install libroc system-wide. Take care to pick the right version as described above.

Then run:

./gradlew build

If libroc is not in default path you can specify ROC_INCLUDE_PATH (path to roc headers) and ROC_LIBRARY_PATH (path to roc library) variables with:

  • environment variables
  • gradle system variables

Additional compilation and linking flags can be specified respectively with CFLAGS and LDFLAGS gradle system variables.

JAR is located at build/libs. It expected that libroc shared library is present on system.

Build AAR for Android (docker way)

Install Docker.

Optionally, export environment variables:

export ROC_REVISION=master
export SDK_LEVEL=31
export API_LEVEL=29
export NDK_VERSION=26.3.11579264
export BUILD_TOOLS_VERSION=35.0.0
export CMAKE_VERSION=3.18.1

This will pull docker image, install dependencies inside container, and run build:

./scripts/android_docker.sh build

AAR is located at android/roc-android/build/outputs/aar. It contains libroc built for all Android architectures.

Build AAR for Android (manual way)

Install JDK 17 or higher and Android SDK 31 or higher.

Optionally, export environment variables:

export ROC_REVISION=master
export SDK_LEVEL=31
export API_LEVEL=29
export NDK_VERSION=26.3.11579264
export BUILD_TOOLS_VERSION=35.0.0
export CMAKE_VERSION=3.18.1

Install Android components:

sdkmanager "platforms;android-${SDK_LEVEL}"
sdkmanager "build-tools;${BUILD_TOOLS_VERSION}"
sdkmanager "ndk;${NDK_VERSION}"
sdkmanager "cmake;${CMAKE_VERSION}"

Install build-time dependencies of Roc Toolkit, e.g. on macOS run:

brew install scons ragel gengetopt

Download and build Roc Toolkit:

./scripts/android/build_roc.sh

And finally build bindings and package everything into AAR:

cd android
./gradlew build

AAR is located at android/roc-android/build/outputs/aar. It contains libroc built for all Android architectures.

Android build variables

These environment variables are used when building for Android, with or without Docker. Each variable has default value and is optional.

When docker is used, corresponding components (SDK, NDK, etc) will be installed automatically according to the specified variables. When docker is not used, you should install them manually before build.

In both cases, export this variables before invoking android_docker.sh or gradlew.

VariableDescription
JAVA_VERSIONWhich JDK to pull (when using docker)
ROC_REVISIONWhich Roc Toolkit to build (when using docker)
ROC_DIRWhich Roc Toolkit to use (when not using docker)
SDK_LEVELandroid-platform version and compileSdkVersion
API_LEVELminSdkVersion and targetSdkVersion
NDK_VERSIONWhich ndk to install/use
BUILD_TOOLS_VERSIONWhich build-tools to install/use
CMAKE_VERSIONWhich cmake to install/use
AVD_IMAGEWhich image to use for emulator (when using docker)
AVD_ARCHWhich arch to use for emulator (when using docker)

Hacking

Contributions are always welcome! You can find issues needing help using help wanted and good first issue labels.

See HACKING.md for details about the project internals.

Authors

You can find list of authors and contributors here. Feel free to send a pull request if you're missing from the list or want to change your appearance.

For Roc Toolkit authors, see here.

License

Bindings are licensed under MIT.

For details on Roc Toolkit licensing, see here.

Releases

Sponsor this project

Used by

Contributors

Languages