OpenOSC - The OpenOSC package contains common infrastructural code for your apps to communicate among computers

Overview

“OpenOSC”/

OpenOSC

Build & Test License: MIT

The OpenOSC package contains common infrastructural code for your apps to communicate among computers, sound synthesizers, and other multimedia devices via OSC.

Architecture

Addresses

An address has a similar syntax to a URL and begins with the character "/", followed by the names of all the containers, in order, along the path from the root of the tree to the method, separated by forward slash characters, followed by the name of the method. All types of addresses found in OpenOSC contain ASCII characters only, as specified in OSC 1.0.

OSC Address Pattern

An address pattern is an address to a potential destination of one ore more methods hosted by an "OSC Server". A number of wildcard characters, such as "*", can be used to allow for a single address pattern to invoke multiple methods.

    let addressPattern = try? OSCAddressPattern("/open/osc/*")

Initialization of an OSCAddressPattern will throw if the format is incorrect or invalid characters are found in the given String.

A String can be evaluated to verify whether it is a valid address pattern by using the following:

    let valid: Bool = OSCAddressPattern.evaluate("/open/osc/*")    

OSC Address

An address is the path to a method hosted by an "OSC Server". No wildcard characters are allowed as this address signifies the endpoint of an OSCMesage and the full path a message traverses to invoke the method associated with it.

    let address = try? OSCAddress("/open/osc/method")

Initialization of an OSCAddress will throw if the format is incorrect or invalid characters are found in the given String.

A String can be evaluated to verify whether it is a valid address by using the following:

    let valid: Bool = OSCAddress.evaluate("/open/osc/method")    

Messages

An OSCMessage is a packet formed of an OSCAddressPattern that directs it towards one or more methods hosted by an "OSC Server" and arguments that can be used when invoking the methods. OpenOSC implements all required argument types as specified in OSC 1.1.

Initialization with an OSCAddressPattern:

    let addressPattern = try! OSCAddressPattern("/open/osc/*")
    let message = OSCMessage(with: addressPattern,
                             arguments: [Int32(1),
                                         Float32(3.142),
                                         "Open OSC",
                                         OSCTimeTag.immediate,
                                         true,
                                         false,
                                         Data([0x01, 0x01]),
                                         OSCArgument.nil,
                                         OSCArgument.impulse])

Initialization with a raw address pattern String:

    let message = try? OSCMessage(with: "/open/osc/*",
                                  arguments: [Int32(1),
                                              Float32(3.142),
                                              "Open OSC",
                                              OSCTimeTag.immediate,
                                              true,
                                              false,
                                              Data([0x01, 0x01]),
                                              OSCArgument.nil,
                                              OSCArgument.impulse])

Initialization of an OSCMessage will throw if the format is incorrect or invalid characters are found in the given String address pattern.


Bundles

An OSCBundle is a container for messages, but also other bundles and allows for the invokation of multiple messages atomically as well scheduling them to be invoked at some point in the future. For further information regarding the temporal semantics of bundles and their associated OSCTimeTags, please see OSC 1.0.

    let message1 = try! OSCMessage(with: "/open/osc/1")
    let message2 = try! OSCMessage(with: "/open/osc/2")
    let message3 = try! OSCMessage(with: "/open/osc/3")
    
    let bundle = OSCBundle([message1, message2, message3], 
                           timetag: .immediate)

Address Spaces

An OSCAddressSpace is a set of methods hosted by an "OSC Server" that can be invoked by one or more OSCMessages. Think of it as a container for blocks of code, that can be dispatched when a message is received, with an address pattern that matches against a methods OSCAddress.

Methods

An OSCMethod is a struct that encapsulates a closure and the OSCAddress needed to invoke it. The idea is that if you wanted to make available control functionality within your application to "OSC Clients" you would begin by creating OSCMethods, adding them to an OSCAddressSpace and when an OSCMessage is received it would be passed to the address space to potentially invoke a method it contains.

For example:

    let method = OSCMethod(with try! OSCAddress("object/coords"), invokedAction { [weak self] message, _ in
        guard message.arguments.count == 2,
              let x = message.argument[0] as? Float32, 
              let y = message.argument[1] as? Float32 else { return }
        print("Received /object/coords, x: \(x), y: \(y)"
        self?.object.x = x
        self?.object.y = y
    })
    
    var addressSpace = OSCAddressSpace(methods: [method])
    
    let message = try! OSCMessage("object/coords", arguments: [Float32(3), Float32(5)])
    addressSpace.invoke(with: message)
                                                     
    print(object.x) // 3
    print(object.y) // 5

Extensions

The following objects are not part of either OSC specification but have been developed after observation of implementations of OSC in the wild and aim to provide help and functionality for you to integrate with them.

Annotations

An OSC annotation is a script for writing an OSCMessage in a human readable format allowing you to enable your users to quickly create OSCMessages by typing them out as well as presenting them in logs. There are two available styles of annotation found in OpenOSC. It is strongly recommended that OSCAnnotationStyle.spaces is used, rather than OSCAnnotationStyle.equalsComma as it will allow you to use the valid "=" character in your OSCAddressPatterns.

A String can be evaluated to verify whether it is a valid annotation by using the following:

    let annotation = "/open/osc 1 3.142 \"A string with spaces\" aString true false nil impulse"
    let valid: Bool = OSCAnnotation.evaluate(annotation, style: .spaces)    

An OSCMessage can be initialized from a valid OSC annotation.

    let annotation = "/open/osc 1 3.142 \"a string with spaces\" aString true"
    
    let message = OSCAnnotation.message(for: annotation, style: .spaces)

    print(message) // OpenOSC.OSCMessage(addressPattern: OpenOSC.OSCAddressPattern(fullPath: "/open/osc", parts: ["open", "osc"], methodName: "osc"), arguments: [1, 3.142, "a string with spaces", "aString", true])

An OSC annotation can be initialized from an OSCMessage.

    let message = try! OSCMessage(with: "/open/osc",
                                  arguments: [Int32(1),
                                              Float32(3.142),
                                              "Open OSC",
                                              true,
                                              false,
                                              OSCArgument.nil,
                                              OSCArgument.impulse])
    // Without argument type tags.
    let annotation1 = OSCAnnotation.annotation(for: message,
                                               style: .spaces,
                                               type: false)
                                               
    print(annotation1) // "/open/osc 1 3.142 "Open OSC" true false nil impulse"
    
    // With argument type tags.
    let annotation2 = OSCAnnotation.annotation(for: message,
                                               style: .spaces,
                                               type: true)
                                               
    print(annotation2) // "/open/osc 1(i) 3.142(f) "Open OSC"(s) true(T) false(F) nil(N) impulse(I)"

Address Filters

An OSCAddressFilter is kind of the reverse of an OSCAddressSpace. Where an address space allows for an address pattern to invoke multiple pre defined methods. An address filter allows for a single method to be invoked by multiple loosly formatted address patterns by using a "#" wildcard character and omitting parts from the pattern matching. Think of an address filter as a container for blocks of code, that can be dispatched when a message is received, with an address pattern that matches against a filter methods OSCFilterAddress.

Filter Methods

An OSCFilterMethod is a struct that encapsulates a closure and the OSCFilterAddress needed to invoke it. The idea is that if you wanted to make available control functionality within your application to "OSC Clients" without the overhead of establishing an address space containing an OSCAddress and method for each control functionality you would begin by creating OSCFilterMethods, adding them to an OSCAddressFilter and when an OSCMessage is received it would be passed to the address filter to potentially invoke a method it contains.

For example:

    let method = OSCFilterMethod(with try! OSCAddress("cue/#/fired"), invokedAction { [weak self] message, _ in
        print("Received: \(message.addressPattern.fullPath)")
        self?.logs.append("Cue \(message.addressPattern.parts[1])")
    })
    
    var addressFilter = OSCAddressFilter(methods: [method])
    
    let message1 = try! OSCMessage(with: "cue/1/fired")
    addressFilter.invoke(with: message1)
    
    let message2 = try! OSCMessage(with: "cue/2/fired")
    addressFilter.invoke(with: message2)
    
    let message3 = try OSCMessage(with: "cue/3/fired")
    addressFilter.invoke(with: message3)
    
    print(logs) // ["Cue 1", "Cue 2", "Cue 3"]

⚠️ - An OSCFilterAddress uses the "#" character, which has been specifically chosen because it is invalid within an OSCAddressPattern. Under no circumstances should you attempt to create an OSCMessage using an OSCFilterAddress as its address pattern.


Refracting

An OSCRefractingAddress can be used to "refract" an OSCAddressPattern to something else. The core idea for this object is to allow an "OSC Server" to act as a router, taking an OSCMessage from one application and routing it to another with modifcations made to the address pattern. Refracting is made possible by using an "#" wildcard character suffixed by a part index number (not 0 indexed). Where a wildcard is used within the refracting address the part will be replaced by the part from the given address pattern. To be succesful at refracting the suffixed index number must be valid with regards to the given address patterns number of parts.

        let refractingAddress = try? OSCRefractingAddress("/open/#2/#4")
        
        let addressPattern = try? OSCAddressPattern("/open/osc/refracting/test")
        
        let refractedAddress: OSCAddressPattern = try? refractingAddress.refract(address: addressPattern)
        
        print(refractedAddress!.fullPath) // "/open/osc/test"

A String can be evaluated to verify whether it is a valid refracting address by using the following:

    let valid: Bool = OSCRefractingAddress.evaluate("/open/#2/#4")    

⚠️ - An OSCRefractingAddress uses the "#" character, which has been specifically chosen because it is invalid within an OSCAddressPattern. Under no circumstances should you attempt to create an OSCMessage using an OSCRefractingAddress as its address pattern.

To Do

  • Enhance the regexes for all address objects: OSCAddressPattern, OSCAddress, OSCRefractingAddress, OSCFilterAddress.
  • Enhance the evaluate(:String) function for all address objects: OSCAddressPattern, OSCAddress, OSCRefractingAddress, OSCFilterAddress.
  • Develop an API for invoking OSCMessages within OSCBundles and respecting the bundles OSCTimeTag.
  • Research and potentially implement OSCQuery.
  • Explore mapping OSCMethods within the OSCAddressSpace to a tree like data structure.

Authors

Sammy Smallman - Initial Work - SammySmallman

Daniel Murfin - Fork - dsmurfin

See also the list of contributors who participated in this project.

You might also like...
Contains common infrastructural code for apps to communicate among computers, sound synthesizers, and other multimedia devices via OSC.

The CoreOSC package contains common infrastructural code for your apps to communicate among computers, sound synthesizers, and other multimedia devices via OSC.

OSCKit - The OSCKit package provides the classes needed for your apps to communicate among computers, sound synthesizers

OSCKit The OSCKit package provides the classes needed for your apps to communica

OpenOSCKit - Communicate among computers, sound synthesizers, and other multimedia devices via OSC over an IP network

OpenOSCKit The OpenOSCKit package provides the classes needed for your apps to c

A Swift Package that allows iOS apps to communicate with AltServer.

AltKit allows apps to communicate with AltServers on the same WiFi network and enable features such as JIT compilation.

Don't start from scratch, start from Here! This is a starter project for iOS projects. It contains all the basic configurations and common libraries for your project.

Starter-iOS Don't start from scratch, start from Here! This is a starter project for iOS projects. It contains all the basic configurations and common

This repository contains code for building Universal Apps with SwiftUI.

MindLikeWater This Repo This repository contains code for building Universal Apps with SwiftUI. The same codebase can be compiled to produce binaries

Pure Declarative Programming in Swift, Among Other Things

Basis The Basis is an exploration of pure declarative programming and reasoning in Swift. It by no means contains idiomatic code, but is instead inten

XLPagerTabStrip is a Container View Controller that allows us to switch easily among a collection of view controllers
XLPagerTabStrip is a Container View Controller that allows us to switch easily among a collection of view controllers

XLPagerTabStrip is a Container View Controller that allows us to switch easily among a collection of view controllers. Pan gesture can be used to move on to next or previous view controller. It shows a interactive indicator of the current, previous, next child view controllers.

AsyncWebSocketClient - A package that contains a client behaving as a wrapper for the URLSessionWebSocketTask

(WORK IN PROGRESS) AsyncWebSocketClient This is a package that contains a client

BluetoothKit Easily communicate between iOS devices using BLE.

BluetoothKit Easily communicate between iOS devices using BLE. Background Apple mostly did a great job with the CoreBluetooth API, but because it enca

Easily communicate between iOS/OSX devices using BLE

BluetoothKit Easily communicate between iOS devices using BLE. Background Apple mostly did a great job with the CoreBluetooth API, but because it enca

Communicate via HTTP easily in Swift.

swift-http-client Communicate via HTTP easily in Swift. Table of Contents Installation How to use Contribution Installation Swift Package Manager (Rec

You can share and communicate with developers around the world through the Fabula app.
You can share and communicate with developers around the world through the Fabula app.

FabulaItemsProvider This is the source package for the Fabula project. You can share and communicate with developers around the world through the Fabu

BubblesChatAppIos - A realtime messenger application Allows the users to communicate through virtual chats
BubblesChatAppIos - A realtime messenger application Allows the users to communicate through virtual chats

Bubbles Chat App a realtime messenger application Allows the users to communicat

Pendo captures product usage data, gathers user feedback, and lets you communicate in-app to onboard, educate, and guide users to value

Pendo SDK for IOS The Pendo Mobile SDK is a code-less, retro-active analytics collector across all of your app's versions. The SDK also allows present

This framework contains SBB (Swiss Federal Railways) UI elements for iOS SwiftUI Apps
This framework contains SBB (Swiss Federal Railways) UI elements for iOS SwiftUI Apps

Framework: Design System Mobile for iOS & SwiftUI This framework contains SBB (Swiss Federal Railways) UI elements for iOS SwiftUI Apps. It allows an

SwiftUI Animation Library. Useful SwiftUI animations including Loading/progress, Looping, On-off, Enter, Exit, Fade, Spin and Background animations that you can directly implement in your next iOS application or project. The library also contains huge examples of spring animations such as Inertial Bounce, Shake, Twirl, Jelly, Jiggle, Rubber Band, Kitchen Sink and Wobble effects. Browse, find and download the animation that fits your needs.
This app presents few examples for common patterns using purer SwiftUI code

VIPERtoSwiftUI GOAL This app presents few examples for common patterns using purer (from authors experience) SwiftUI code. LITERATURE https://www.appy

This repository contains the source code of the EU Digital COVID Certificate Certlogic for iOS.

This repository contains the source code of the EU Digital COVID Certificate Certlogic for iOS.

Releases(1.0.0)
Owner
Dan Murfin
Dan Murfin
Switshot is a game media manager helps you transfer your game media from Nintendo Switch to your phone, and manage your media just few taps.

Switshot is a game media manager helps you transfer your game media from Nintendo Switch to your phone, and manage your media just few taps.

Astrian Zheng 55 Jun 28, 2022
A Swift package for Raylib. Builds Raylib from source so no need to fiddle with libraries.

A Swift package for Raylib. Builds Raylib from source so no need to fiddle with libraries. Just add as a dependency in you game package and go!

Strega's Gate 62 Dec 29, 2022
PlayCover is a project that allows you to sideload iOS apps on macOS( currently arm, Intel support will be tested.

PlayCover Run iOS apps & games on M1 Mac with mouse, keyboard and controller support. Intel macs support will be implemented later. Installation Just

Alexandr 3.9k Jun 30, 2022
SpriteKit 2D Breakout Game on rotating 3D SceneKit cube almost no code

2D Breakout game playable as texture on a rotating cube An Xcode12 project for iOS that implements a simple 2D SpriteKit "Break Out" style game. The S

Erik M. Buck 0 Nov 6, 2021
Open Source release of the code for the iOS retro 80s platform game Loot Raider

Loot Raider iOS v1.7 (c) 2018 Infusions of Grandeur - Written By: Eric Crichlow Background Loot Raider is the "spiritual successor" to a game named "G

Eric Crichlow 9 Feb 9, 2022
🖐 Memory game with hand gesture recognition that will keep your brain in a good shape!

Hands I have always been interested in how I can improve my memory in addition to reading books, and once I came across an interesting technique relat

Tamerlan Satualdypov 35 Dec 19, 2022
Mecha Hamster is a game where you roll through customizable environments that you can share with your friends.

MechaHamster {#mechahamster_readme} MechaHamster is a game about guiding a futuristic hamster ball through dangerous space mazes, create mazes of thei

Google 444 Jan 3, 2023
A Star Wars themed card game designed to see if you know your sith vs jedi

StarWarsCardGame A Star Wars themed card game designed to see if you know your sith vs jedi. Learning Objectives: Alert Controllers, Protocol/Delegate

Jonathan Llewellyn 0 Nov 29, 2021
PowerUp is an educational choose-your-own-adventure game that utilizes a users uploaded curriculum to empower pre-adolescents to take charge of their reproductive health.

PowerUp is an educational choose-your-own-adventure game that utilizes a users uploaded curriculum to empower pre-adolescents to take charge of their reproductive health. This is the iOS version of the game.

AnitaB.org Open Source 39 Sep 26, 2022
ShellSlide - Play 2048 in your shell 🎮

ShellSlide - Play 2048 in your shell ?? Features Keep track of your overall highscore Easily save and resume your games Installation (macOS only) Down

Carl 1 Mar 28, 2022