diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 6fade69..063f63c 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -16,10 +16,11 @@ jobs: - name: apt update run: | sudo apt-get update - - name: set up JDK 11 - uses: actions/setup-java@v1 + - name: set up JDK 17 + uses: actions/setup-java@v3 with: - java-version: 11 + java-version: 17 + distribution: temurin - name: apt install run: | echo y | sudo apt-get install doxygen cmake ninja-build libasound2-dev @@ -28,7 +29,9 @@ jobs: - name: copy settings run: mkdir -p ~/.m2 && cp .github/workflows/m2_settings.xml ~/.m2/settings.xml - name: build - run: ./gradlew --warning-mode all build + run: + ./build-native.sh + ./gradlew --warning-mode all build - name: upload artifact if: success() uses: actions/upload-artifact@v2 diff --git a/.gitignore b/.gitignore index 3a556e0..81ac0a1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .idea build alsakt-javacpp/src/main/java/dev/atsushieno/alsakt/javacpp +alsa-dist diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..771dddb --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/alsa-lib"] + path = external/alsa-lib + url = https://github.com/alsa-project/alsa-lib.git diff --git a/README.md b/README.md index 7993184..39318b2 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,21 @@ alsakt is created mostly for use in [ktmidi](https://github.com/atsushieno/ktmid ## Building -It is a Gradle Kotlin/JVM project and `./gradlew build` would work, but -depending on the distribution you may have to edit [build.gradle](alsakt-javacpp/build.gradle#L33) and/or [Alsa.java](alsakt-javacpp/src/main/java/alsakt_presets/Alsa.java) configuration. +Since alsakt 0.3.0, it bundles `libasound.so` on x86_64 Linux (maybe doable for other architectures, but needs native build setup). Before trying to build the Kotlin/JVM library, we have to build `libasound.so` first: + +``` +./build-native.sh +``` + +Then the resulting shared library will be packaged within the .jar by JavaCPP builder. + +It is a Gradle Kotlin/JVM project and `./gradlew build` takes care of the Kotlin/JVM part. ## Licenses alsakt is released under the MIT license. -ALSA headers in `alsakt-javacpp/alsa-headers` are copied from [ALSA](https://github.com/alsa-project/alsa-lib) headers distributed as part of Ubuntu 20.04, which is released under the LGPL v2.1 license. +The ALSA headers and `libasound.so` that are packaged in the resulting jar is built from [alsa-lib](https://github.com/alsa-project/alsa-lib) submodule, which is released under the LGPL v2.1 license. [JavaCPP](https://github.com/bytedeco/javacpp/) is distributed under Apache V2 license. diff --git a/alsakt-javacpp/build.gradle b/alsakt-javacpp/build.gradle index 3e162ed..5287946 100644 --- a/alsakt-javacpp/build.gradle +++ b/alsakt-javacpp/build.gradle @@ -11,7 +11,7 @@ ext { } group 'dev.atsushieno' -version '0.2.1' +version '0.3.0' repositories { mavenCentral() @@ -34,7 +34,10 @@ dependencies { tasks.withType(org.bytedeco.gradle.javacpp.BuildTask).configureEach { // set here default values for all build tasks below, typically just includePath and linkPath, // but also properties to set the path to the NDK and its compiler in the case of Android - includePath = [project.projectDir.toString() + '/alsa-headers', project.projectDir.toString() + '/dummy_headers'] + includePath = [project.projectDir.toString() + '/../alsa-dist/include', project.projectDir.toString() + '/dummy_headers'] + linkPath = [project.projectDir.toString() + '/../alsa-dist/lib-no-symlink'] + copyLibs true + // It is likely dependent of your Linux desktop distro. deleteJniFiles false } diff --git a/alsakt-javacpp/src/main/java/alsakt_presets/Alsa.java b/alsakt-javacpp/src/main/java/alsakt_presets/Alsa.java index 26fbfd0..1531d6e 100644 --- a/alsakt-javacpp/src/main/java/alsakt_presets/Alsa.java +++ b/alsakt-javacpp/src/main/java/alsakt_presets/Alsa.java @@ -14,9 +14,9 @@ value = {"linux-x86", "linux-x86_64"}, // This is so far a limited set of header files which is enough for ktmidi. include = { -// We'd like to remove this line, but adding them results in missing related functions -// which is no-go. It seems the resulting library still builds, so we leave them as is. Also...(contd.) -"dummy_poll.h", + // We'd like to remove this line, but adding them results in missing related functions + // which is no-go. It seems the resulting library still builds, so we leave them as is. Also...(contd.) + "dummy_poll.h", "alsa/asoundef.h", //"alsa/asoundlib.h", @@ -73,9 +73,8 @@ //"alsa/topology.h", //"alsa/ump_msg.h", //"alsa/use-case.h", -}, - link = "asound", - preload = "asound" + }, + link = {"asound"} ) } diff --git a/alsakt/src/main/kotlin/dev/atsushieno/alsakt/AlsaClientInfo.kt b/alsakt/src/main/kotlin/dev/atsushieno/alsakt/AlsaClientInfo.kt index 2ebb10e..6d759a3 100644 --- a/alsakt/src/main/kotlin/dev/atsushieno/alsakt/AlsaClientInfo.kt +++ b/alsakt/src/main/kotlin/dev/atsushieno/alsakt/AlsaClientInfo.kt @@ -73,9 +73,16 @@ class AlsaClientInfo : AutoCloseable { val eventLostCount : Int get() = Alsa.snd_seq_client_info_get_event_lost (handle) + private val midiVersionAvailable = + AlsaVersion.major >=1 && + AlsaVersion.minor >=2 && + AlsaVersion.revision >= 10 var midiVersion : Int - get() = Alsa.snd_seq_client_info_get_midi_version(handle) - set(value) = Alsa.snd_seq_client_info_set_midi_version(handle, value) + get() = if (midiVersionAvailable) Alsa.snd_seq_client_info_get_midi_version(handle) else 0 + set(value) { + if (midiVersionAvailable) + Alsa.snd_seq_client_info_set_midi_version(handle, value) + } val umpConversion : Int get() = Alsa.snd_seq_client_info_get_ump_conversion(handle) diff --git a/alsakt/src/main/kotlin/dev/atsushieno/alsakt/AlsaVersion.kt b/alsakt/src/main/kotlin/dev/atsushieno/alsakt/AlsaVersion.kt new file mode 100644 index 0000000..5a65a56 --- /dev/null +++ b/alsakt/src/main/kotlin/dev/atsushieno/alsakt/AlsaVersion.kt @@ -0,0 +1,11 @@ +package dev.atsushieno.alsakt + +import dev.atsushieno.alsakt.javacpp.global.Alsa + +object AlsaVersion { + val versionString = Alsa.snd_asoundlib_version().string + private val versionTokens = versionString.split('.') + val major = if (versionTokens.size > 0) versionTokens[0].toInt() else 0 + val minor = if (versionTokens.size > 1) versionTokens[1].toInt() else 0 + val revision = if (versionTokens.size > 2) versionTokens[2].toInt() else 0 +} diff --git a/alsakt/src/test/kotlin/dev/atsushieno/alsakt/AlsaSequencerTest.kt b/alsakt/src/test/kotlin/dev/atsushieno/alsakt/AlsaSequencerTest.kt index 87bdf04..7a8c9ef 100644 --- a/alsakt/src/test/kotlin/dev/atsushieno/alsakt/AlsaSequencerTest.kt +++ b/alsakt/src/test/kotlin/dev/atsushieno/alsakt/AlsaSequencerTest.kt @@ -52,6 +52,7 @@ class AlsaSequencerTest { println(cli.client) println(cli.portCount) println(cli.broadcastFilter) + println(cli.midiVersion) } } } diff --git a/alsakt/src/test/kotlin/dev/atsushieno/alsakt/AlsaVersionTest.kt b/alsakt/src/test/kotlin/dev/atsushieno/alsakt/AlsaVersionTest.kt new file mode 100644 index 0000000..42f50a6 --- /dev/null +++ b/alsakt/src/test/kotlin/dev/atsushieno/alsakt/AlsaVersionTest.kt @@ -0,0 +1,14 @@ +package dev.atsushieno.alsakt + +import org.junit.jupiter.api.Test + +class AlsaVersionTest { + @Test + fun getVersion() { + val ver = AlsaVersion.versionString + assert(ver.length > 0) + assert(AlsaVersion.major > 0) // it would not be version 0... + assert(AlsaVersion.minor >= 0) // it would be non-negative + assert(AlsaVersion.revision >= 0) // it would be non-negative + } +} \ No newline at end of file diff --git a/build-native.sh b/build-native.sh new file mode 100755 index 0000000..c19a2ce --- /dev/null +++ b/build-native.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +cd external/alsa-lib +./gitcompile --prefix=`pwd`/../../alsa-dist +make install +cd ../.. +mkdir -p alsa-dist/lib-no-symlink +cp alsa-dist/lib/libasound.so alsa-dist/lib-no-symlink +find alsa-dist/lib-no-symlink + diff --git a/external/alsa-lib b/external/alsa-lib new file mode 160000 index 0000000..ed6b070 --- /dev/null +++ b/external/alsa-lib @@ -0,0 +1 @@ +Subproject commit ed6b07084bfea4155bbc98bcf38508ab81bdd008