roc-streaming / roc-java

JNI bindings for Roc Toolkit.
https://roc-streaming.org
MIT License
21 stars 14 forks source link
audio dsp fec hacktoberfest networking real-time streaming

JNI bindings for Roc Toolkit

build codecov Android release Android javadoc Matrix 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:

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

import org.rocstreaming.roctoolkit;

try (RocContext context = new RocContext()) {
    RocSenderConfig config = RocSenderConfig.builder()
        .frameSampleRate(44100)
        .frameChannels(ChannelSet.STEREO)
        .frameEncoding(FrameEncoding.PCM_FLOAT)
        .fecEncoding(FecEncoding.RS8M)
        .clockSource(ClockSource.INTERNAL)
        .build();

    try (RocSender sender = new RocSender(context, config)) {
        Endpoint sourceEndpoint = new Endpoint("rtp+rs8m://192.168.0.1:10001");
        Endpoint repairEndpoint = new Endpoint("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

import org.rocstreaming.roctoolkit;

try (RocContext context = new RocContext()) {
    RocReceiverConfig config = RocReceiverConfig.builder()
        .frameSampleRate(44100)
        .frameChannels(ChannelSet.STEREO)
        .frameEncoding(FrameEncoding.PCM_FLOAT)
        .clockSource(ClockSource.INTERNAL)
        .build();

    try (RocReceiver receiver = new RocReceiver(context, config)) {
        Endpoint sourceEndpoint = new Endpoint("rtp+rs8m://0.0.0.0:10001");
        Endpoint repairEndpoint = new Endpoint("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 = new float[320];
            receiver.read(samples);

            /* process received samples */
        }
    }
}

Versioning

Java bindings and the C library both use semantic versioning.

Bindings are compatible with the C library when:

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.

Using 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>'

Building JAR from sources

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

Then run:

./gradlew build

Building AAR from sources (docker way)

This will install dependencies inside docker and run build:

./scripts/android_docker.sh build

This will start emulator inside docker and run tests on it:

./scripts/android_docker.sh test

Building AAR from sources (manual way)

First, export required environment variables:

export API=26
export NDK_VERSION=21.1.6352462
export BUILD_TOOLS_VERSION=28.0.3
export CMAKE_VERSION=3.10.2.4988404

Then install Android components:

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

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

brew install scons ragel gengetopt

Now we can download and build Roc Toolkit:

./scripts/android/build_roc.sh

And finally build bindings and package everything into AAR:

cd android
./gradlew build

Optionally, run tests on device or emulator (you'll have to create one):

cd android
./gradlew cAT --info --stacktrace

Developer instructions

Local build

Build (native code and Java code):

./gradlew build

Build only native code:

./gradlew roc_jni:build

Run tests:

./gradlew test

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:

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

Android build via docker

This command will pull docker image, install Android SDK and NDK inside it, download and build Roc Toolkit, build JNI bindings, and package everything into AAR:

./scripts/android_docker.sh build

To run instrumented tests in Android emulator inside docker image, use this:

./scripts/android_docker.sh test

To remove build results, run:

./scripts/android_docker.sh clean

To remove build results and docker container, run:

./scripts/android_docker.sh purge

If desired, you can export some variables for Android environment configuration; each variable has default value and is optional:

export JAVA_VERSION=8
export API=26
export NDK_VERSION=21.1.6352462
export BUILD_TOOLS_VERSION=28.0.3
export CMAKE_VERSION=3.10.2.4988404
export AVD_IMAGE=default
export AVD_ARCH=x86_64

./scripts/android_docker.sh [build|test]

Additional information on the env-android docker image, which is used by this script, is available here.

Documentation build

Generate docs:

./gradlew javadoc

Publishing Android release

Release workflow:

Followed env variables should be set in GitHub Actions:

Authors

See here.

License

Bindings are licensed under MIT.

For details on Roc Toolkit licensing, see here.