Code Monkey home page Code Monkey logo

birdhouse's Introduction

Build

ko-fi

BirdHouse

An OSC to MIDI bridge

Birdhouse in action

With BirdHouse you can receive OSC messages with a DAW or plugin host and have them converted to MIDI.

The Birdhouse OSC to MIDI plugin is a simple plugin that listens for OSC messages, processes their data and sends outputs it as MIDI to allow using it in a DAW or other plugin host environment. Each instance of Birdhouse is able to process a stream of OSC messages to a MIDI event type, with a visualization of the stream and the ability to mute/unmute the output data.

The need for this plugin arose from having to make different projects that rely on OSC communication to generate notes or affect sound parameters. Often this was solved with middlewares written in one of the common computer music languages, with varying levels of success and then passed on to different Digital Audio Workstations with even more varying levels of success. The thing is, different software process OSC messages with different priority levels. This can be annoying in interactive art since we sometimes want to blast software with values from sensors, other software or from wherever, and be able to expect pretty consistent results. Birdhouse attempts to solve this.

Birdhouse in action

Features

  • Convert OSC to MIDI inside any DAW or plugin host
  • Realtime-processing of the incoming OSC messages
  • Audio-rate MIDI
  • Scale from any input value range to MIDI ranges automatically
  • Process 8 streams of OSC messages per instance
  • Output common MIDI message types: Note on/off, MIDI CC, Pitch bend (more coming)

Use cases

  • Controlling your DAW using a phone or tablet
  • Sending OSC from an Arduino, ESP or Raspberry Pi Pico to a DAW to trigger notes or control parameter changes in plugins
  • Using OSC to control a DAW using computer music software like SuperCollider, Max/MSP or PureData

Supported hosts

Tested and working in:

  • ✅ Reaper
  • ✅ BitWig

Untested:

  • ✖️ Ableton Live
  • ✖️ Logic Pro
  • ✖️ Cubase
  • ✖️ Pro Tools
  • ✖️ FL Studio
  • ✖️ Studio One
  • ✖️ Reason

If you test the plugin in one of the untested or unmentioned hosts, please open an issue and let us know how it worked.

Usage

Birdhouse in action

See the manual or check out this tutorial on YouTube.

Development

This project was generated using Cookiejuce.

Supporting the project

If you find this project useful and want to support it, please consider supporting it by buying me a coffee.

Build and install

Prerequisites

Building

Download source code (make sure eto include submodules):

git clone --recurse-submodules  https://github.com/madskjeldgaard/Birdhouse.git
cd Birdhouse

Configure:

cmake -S . -B build

Build.

This will automatically install the plugins on your system.

If you want the standalone, you should copy it manually.

cmake --build build

The plugins are now copied to your system.

Run standalone (on MacOS):

./build/BirdHouse_artefacts/Standalone/BirdHouse.app/Contents/MacOS/BirdHouse

Building the manual

The manual is built using pandoc. Run it from the root of the repo:

pandoc -i manual/birdhouse-manual.md -o manual/birdhouse-manual.pdf

birdhouse's People

Contributors

madskjeldgaard avatar

Stargazers

Mark avatar Pete Webbo avatar Jordan Loehr avatar Matt Nish-Lapidus avatar  avatar  avatar  avatar dom avatar  avatar  avatar MelonJack avatar Fotis and Stuff avatar Ilias Woithe avatar Billy Messenger avatar Morgan Creekmore avatar Christopher Arndt avatar  avatar miranda avatar  avatar Onymous avatar dreamer avatar Reilly Spitzfaden (they/them) avatar

Watchers

 avatar  avatar

birdhouse's Issues

Feature: Add OPS – data processing operations

The point of this plugin is to get rid of middle wares written in SC, Max, Python.

Therefore, to do that, we need to add a way to process data on each OSC Channel.

I call this "OPS".

These may include:

  • Delta triggers: Amount of change in value to trigger a message (very useful for sensors to cause triggers)
  • Smoothing: Smooth out the data to reduce jitter
  • Offset: Add an offset to the data
  • Scale: Scale the data

Auto build with workflows

This repo is set up to use github actions to build binaries.

It is currently disabled, because the macOS build needs an apple developer account which I don't currently have.

Refactor: Rewrite ValueTree to use APVTS and params

  • Rewrite all channels to use parameters
  • Write Attach class for a channel
  • Connect all channels to GUI via Attach
    •  MsgType -> add attachment to channel editor
    • Mute Button -> add attachment to channel editor
    • Attach Port using parameterattach
  • Register non-audio parameter parameters via callbacks/listeners in processor
    • Add callback for Path
    • Add callback for inMin
    • Add callback for inMax
    • Add callback to connect when port is changed
    • Add callback to update "connected" label
  • Re-enable state loading/saving

Some note on/off messages do not pass through

When inputting a periodic signal to a note channel, sometimes it does not pass through the note through the plugin, even though the visualisation indicates the data has been received properly.

TODO:Do not type check with float32

The osc handler currently type checks the input to see if it is a float32 type. This should be changed to allow other number types, then static cast them to float for internal calculations.

Bad access in midi handler

 Normalized value: 0.912 Value accepted: 1 Raw OSC message: /2/value
Process 98709 stopped
* thread #11, name = 'com.apple.audio.IOThread.client', stop reason = EXC_BAD_ACCESS (code=1, address=
0x12f71752d)
    frame #0: 0x00000001006b72e4 BirdHouse`unsigned short juce::readUnaligned<unsigned short>(srcPtr=0
x000000012f71752d) at juce_Memory.h:68:5
   65   inline Type readUnaligned (const void* srcPtr) noexcept
   66   {
   67       Type value;
-> 68       memcpy (&value, srcPtr, sizeof (Type));
   69       return value;
   70   }
   71  
Target 0: (BirdHouse) stopped.
(lldb) bt
* thread #11, name = 'com.apple.audio.IOThread.client', stop reason = EXC_BAD_ACCESS (code=1, address=
0x12f71752d)
  * frame #0: 0x00000001006b72e4 BirdHouse`unsigned short juce::readUnaligned<unsigned short>(srcPtr=0
x000000012f71752d) at juce_Memory.h:68:5
    frame #1: 0x000000010072ee14 BirdHouse`juce::MidiBufferHelpers::getEventDataSize(d=0x000000012f717
529) at juce_MidiBuffer.cpp:35:16
    frame #2: 0x000000010072ee80 BirdHouse`juce::MidiBufferIterator::operator*(this=0x00000001702e64d8
) const at juce_MidiBuffer.cpp:99:14
    frame #3: 0x000000010072f84c BirdHouse`juce::MidiBuffer::addEvents(this=0x00000001702e6588, otherB
uffer=0x00006000000e82e0, startSample=0, numSamples=-1, sampleDeltaToAdd=0) at juce_MidiBuffer.cpp:160
:31
    frame #4: 0x00000001007bdd4c BirdHouse`OSCBridgeChannel::appendMessagesTo(this=0x00006000000e8298,
 processBlockBuffer=0x00000001702e6588) at OSCBridgeChannel.h:121:32
    frame #5: 0x00000001007bdc94 BirdHouse`PluginProcessor::processBlock(this=0x0000000108704080, buff
er=0x00000001702e6688, midiMessages=0x000000012882b8d8) at PluginProcessor.cpp:194:15
    frame #6: 0x00000001007e7ae4 BirdHouse`juce::AudioProcessorPlayer::audioDeviceIOCallbackWithContex
t(this=0x000000012882b5f0, inputChannelData=0x00006000020c0810, numInputChannels=0, outputChannelData=
0x0000600002cfdc60, numOutputChannels=1, numSamples=448, context=0x00000001702e6c18) at juce_AudioProc
essorPlayer.cpp:338:28
    frame #7: 0x0000000100011ab8 BirdHouse`juce::StandalonePluginHolder::audioDeviceIOCallbackWithCont
ext(this=0x000000012882b200, inputChannelData=0x00006000020c0810, numInputChannels=0, outputChannelDat
a=0x0000600002cfdc60, numOutputChannels=1, numSamples=448, context=0x00000001702e6c18) at juce_Standal
oneFilterWindow.h:636:16
    frame #8: 0x0000000100013254 BirdHouse`juce::StandalonePluginHolder::CallbackMaxSizeEnforcer::audi
oDeviceIOCallbackWithContext(this=0x000000012882bb80, inputChannelData=0x0000000000000000, numInputCha
nnels=0, outputChannelData=0x0000600002ec9380, numOutputChannels=1, numSamples=448, context=0x00000001
702e6c18) at juce_StandaloneFilterWindow.h:490:23
    frame #9: 0x00000001008f4d38 BirdHouse`juce::AudioDeviceManager::audioDeviceIOCallbackInt(this=0x0
00000012882b258, inputChannelData=0x0000000000000000, numInputChannels=0, outputChannelData=0x00006000
02ec9380, numOutputChannels=1, numSamples=448, context=0x00000001702e6c18) at juce_AudioDeviceManager.
cpp:1010:37
    frame #10: 0x0000000100900bb0 BirdHouse`juce::AudioDeviceManager::CallbackHandler::audioDeviceIOCa
llbackWithContext(this=0x00006000020f69d0, ins=0x0000000000000000, numIns=0, outs=0x0000600002ec9380, 
numOuts=1, numSamples=448, context=0x00000001702e6c18) at juce_AudioDeviceManager.cpp:79:15
    frame #11: 0x000000010091bbac BirdHouse`juce::CoreAudioClasses::CoreAudioInternal::audioCallback(t
his=0x000000012980d330, inputTimestamp=0x00000001023d00a0, outputTimestamp=0x00000001023d00e0, inInput
Data=0x0000600002cf4470, outOutputData=0x0000600002ef1060) at juce_CoreAudio_mac.cpp:801:23
    frame #12: 0x000000010091b5d8 BirdHouse`juce::CoreAudioClasses::CoreAudioInternal::audioIOProc((nu
ll)=90, inNow=0x00000001023d0060, inInputData=0x0000600002cf4470, inInputTime=0x00000001023d00a0, outO
utputData=0x0000600002ef1060, inOutputTime=0x00000001023d00e0, device=0x000000012980d330) at juce_Core
Audio_mac.cpp:1134:51
    frame #13: 0x000000018c9e973c CoreAudio`HALC_ProxyIOContext::IOWorkLoop() + 9244
    frame #14: 0x000000018c9e6bf0 CoreAudio`invocation function for block in HALC_ProxyIOContext::HALC
_ProxyIOContext(unsigned int, unsigned int) + 108
    frame #15: 0x000000018cb65f2c CoreAudio`HALC_IOThread::Entry(void*) + 88
    frame #16: 0x000000018a1c6034 libsystem_pthread.dylib`_pthread_start + 136

Add to Arch Linux AUR

The project should work on Arch Linux.

It includes a PKGBUILD at the root right now, which is experimental.

We need to:

  • Make the PKGBUILD file work
  • Upload it to the aur repos as birdhouse-git

Add logo to standalone

The standalone version logo is currently Pamplejuce's, this should be changed to something else.

Make the plugin lock-free

This plugin currently isn't entirely lock-free.

This could be an issue for performance.

The plugin should be made lock-free.

The difficult thing is where the realtime processing of incoming OSC messages are done and the resulting data is used to create midi buffers. This is where the lock needs to be right now to avoid data-races, but ideally this shouldn't be the case.

Add lag to output

Some osc updates are too frequent, add lag to allow delayng/smoothing them.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.