From 41aa0ef3f1b22cc0622cdf0b0096d833fbdf98c7 Mon Sep 17 00:00:00 2001 From: Ricardo Matias Date: Thu, 7 Nov 2019 10:00:19 +0100 Subject: [PATCH 1/4] Add orx-osc extension --- orx-osc/build.gradle | 5 +++ orx-osc/src/main/kotlin/OSC.kt | 69 ++++++++++++++++++++++++++++++++++ settings.gradle | 1 + 3 files changed, 75 insertions(+) create mode 100644 orx-osc/build.gradle create mode 100644 orx-osc/src/main/kotlin/OSC.kt diff --git a/orx-osc/build.gradle b/orx-osc/build.gradle new file mode 100644 index 00000000..9f2daaa2 --- /dev/null +++ b/orx-osc/build.gradle @@ -0,0 +1,5 @@ +dependencies { + def withoutSlf4j = { exclude group: 'org.slf4j' } + + compile "com.illposed.osc:javaosc-core:0.6", withoutSlf4j +} \ No newline at end of file diff --git a/orx-osc/src/main/kotlin/OSC.kt b/orx-osc/src/main/kotlin/OSC.kt new file mode 100644 index 00000000..9efd0548 --- /dev/null +++ b/orx-osc/src/main/kotlin/OSC.kt @@ -0,0 +1,69 @@ +package org.openrndr.extra.osc + +import com.illposed.osc.OSCMessage +import com.illposed.osc.OSCMessageListener +import com.illposed.osc.messageselector.OSCPatternAddressMessageSelector +import com.illposed.osc.transport.udp.OSCPort +import com.illposed.osc.transport.udp.OSCPortIn +import com.illposed.osc.transport.udp.OSCPortOut +import java.net.InetAddress +import java.net.PortUnreachableException + +private typealias OSCListener = Pair + +class OSC ( + address: InetAddress = InetAddress.getLocalHost(), + portIn: Int = OSCPort.DEFAULT_SC_OSC_PORT, + portOut: Int = portIn +) { + private val receiver: OSCPortIn = OSCPortIn(portIn) + private val sender: OSCPortOut = OSCPortOut(address, portOut) + private val listeners: MutableMap = mutableMapOf() + + fun send(channel: String, vararg message: T) { + if (!sender.isConnected) sender.connect() + + val msg = OSCMessage(channel, message.toList()) + + try { + sender.send(msg) + } catch (ex: Exception) { + when(ex) { + is PortUnreachableException -> System.err.println("Error: Could not connect to OUT port") + is IllegalStateException -> System.err.println("Error: Couldn't send message to channel: $channel") + } + // ex.printStackTrace() - Would rather keep this behind a debug flag + } + } + + fun listen(channel: String, callback: (List) -> Unit) { + val selector = OSCPatternAddressMessageSelector(channel); + + val cb = OSCMessageListener { + callback(it.message.arguments) + } + + receiver.dispatcher.addListener(selector, cb) + + listeners[channel] = Pair(selector, cb) + + if (!receiver.isListening) this.startListening() + } + + // Cannot be called inside a listener's callback + fun removeListener(channel: String?) { + val listener = listeners[channel] + + if (listener != null) { + receiver.dispatcher.removeListener(listener.first, listener.second) + } + } + + private fun startListening() { + receiver.dispatcher.isAlwaysDispatchingImmediately = true; + + receiver.startListening() + + if (receiver.isListening) println("OSC is listening..") + } +} diff --git a/settings.gradle b/settings.gradle index bf88a7f5..96fe2a44 100644 --- a/settings.gradle +++ b/settings.gradle @@ -16,6 +16,7 @@ include 'orx-camera', 'orx-noise', 'orx-obj-loader', 'orx-olive', + 'orx-osc', 'orx-poisson-fill', 'orx-shader-phrases', 'orx-kinect-common', From ac86de9ba6198c0094db0ced6d1f1d675d577f8a Mon Sep 17 00:00:00 2001 From: Ricardo Matias Date: Thu, 7 Nov 2019 10:22:14 +0100 Subject: [PATCH 2/4] Add readme to orx-osc --- README.md | 3 ++- orx-osc/README.md | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 orx-osc/README.md diff --git a/README.md b/README.md index 164cce9a..0b2d8a04 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,8 @@ A growing library of assorted data structures, algorithms and utilities. - [`orx-noise`](orx-noise/README.md), library for random number generation and noise - [`orx-no-clear`](orx-no-clear/README.md), a simple extension that provides drawing without clearing the background - [`orx-obj-loader`](orx-obj-loader/README.md), simple Wavefront .obj mesh loader -- [`orx-olive`](orx-olive/README.md), extensions that turns OPENRNDR in to a live coding environment +- [`orx-olive`](orx-olive/README.md), extensions that turns OPENRNDR in to a live coding environment +- [`orx-osc`](orx-osc/README.md), open sound control interface # Developer notes diff --git a/orx-osc/README.md b/orx-osc/README.md new file mode 100644 index 00000000..1d0d6feb --- /dev/null +++ b/orx-osc/README.md @@ -0,0 +1,16 @@ +# orx-osc + +Orx-osc is a wrapper around javaOSC + +## Usage + +```kotlin +// PORT IN and OUT: 57110 +val osc = OSC() + +osc.listen("/live/track2") { + // do something +} + +osc.send("/maxmsp/filter", 500, "hz") +``` From eb7c1d5f4936165c70a400ab0ac96794b90ed2be Mon Sep 17 00:00:00 2001 From: Ricardo Matias Date: Thu, 7 Nov 2019 11:03:30 +0100 Subject: [PATCH 3/4] Use Kotlin-Logging instead of system calls --- orx-osc/src/main/kotlin/OSC.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/orx-osc/src/main/kotlin/OSC.kt b/orx-osc/src/main/kotlin/OSC.kt index 9efd0548..7beeaa7b 100644 --- a/orx-osc/src/main/kotlin/OSC.kt +++ b/orx-osc/src/main/kotlin/OSC.kt @@ -6,15 +6,18 @@ import com.illposed.osc.messageselector.OSCPatternAddressMessageSelector import com.illposed.osc.transport.udp.OSCPort import com.illposed.osc.transport.udp.OSCPortIn import com.illposed.osc.transport.udp.OSCPortOut +import mu.KotlinLogging import java.net.InetAddress import java.net.PortUnreachableException private typealias OSCListener = Pair +private val logger = KotlinLogging.logger {} + class OSC ( - address: InetAddress = InetAddress.getLocalHost(), - portIn: Int = OSCPort.DEFAULT_SC_OSC_PORT, - portOut: Int = portIn + val address: InetAddress = InetAddress.getLocalHost(), + val portIn: Int = OSCPort.DEFAULT_SC_OSC_PORT, + val portOut: Int = portIn ) { private val receiver: OSCPortIn = OSCPortIn(portIn) private val sender: OSCPortOut = OSCPortOut(address, portOut) @@ -29,10 +32,9 @@ class OSC ( sender.send(msg) } catch (ex: Exception) { when(ex) { - is PortUnreachableException -> System.err.println("Error: Could not connect to OUT port") - is IllegalStateException -> System.err.println("Error: Couldn't send message to channel: $channel") + is PortUnreachableException -> logger.error(ex) { "Error: Could not connect to OUT port" } + is IllegalStateException -> logger.error(ex) { "Error: Couldn't send message to channel: $channel" } } - // ex.printStackTrace() - Would rather keep this behind a debug flag } } @@ -64,6 +66,6 @@ class OSC ( receiver.startListening() - if (receiver.isListening) println("OSC is listening..") + if (receiver.isListening) logger.info("OSC is listening on port: $portIn") } } From 4aecc3139a0081987adaceb6587984ae5eb93196 Mon Sep 17 00:00:00 2001 From: Ricardo Matias Date: Fri, 8 Nov 2019 13:52:16 +0100 Subject: [PATCH 4/4] Only catch handled exceptions in orx-osc --- orx-osc/src/main/kotlin/OSC.kt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/orx-osc/src/main/kotlin/OSC.kt b/orx-osc/src/main/kotlin/OSC.kt index 7beeaa7b..6dd393de 100644 --- a/orx-osc/src/main/kotlin/OSC.kt +++ b/orx-osc/src/main/kotlin/OSC.kt @@ -30,11 +30,10 @@ class OSC ( try { sender.send(msg) - } catch (ex: Exception) { - when(ex) { - is PortUnreachableException -> logger.error(ex) { "Error: Could not connect to OUT port" } - is IllegalStateException -> logger.error(ex) { "Error: Couldn't send message to channel: $channel" } - } + } catch (ex: PortUnreachableException) { + logger.error(ex) { "Error: Could not connect to OUT port" } + } catch (ex: IllegalStateException) { + logger.error(ex) { "Error: Couldn't send message to channel: $channel" } } }