Code Monkey home page Code Monkey logo

nowsound's Introduction

NowSound

Low latency audio library for Windows 10, targeted at Unity UWP and desktop apps.

NowSound is a wrapper library around the JUCE audio library. It exposes a P/Invoke C-style API, such that it can be invoked by Unity apps (on either the .NET or Mono runtimes).

Status as of August 2019: the library works and has VST2 plugin support, and the demo .NET looper app supports multiple tracks, input sound effects, track muting, and track deleting.

APIs

The P/Invokable C API is defined in NowSoundLib.h. The C# wrapper around that API is in NowSoundLib.cs.

Project structure

NowSound consists of the following subprojects:

  • NowSoundLibShared: the core C++ classes for streaming and buffering
    • Had I started this project with JUCE I might have used JUCE's classes for these functions; as it is, I'm sticking with mine
  • NowSoundLib: a UWP C++ library sharing NowSoundLibShared and invoking AudioGraph, exposing a P/Invoke interface
  • NowSoundPInvokeLib: a .NET C# library that wraps the P/Invoke NowSoundLib interface
  • NowSoundWinFormsApp: a C# WinForms app (old school!) that uses the NowSoundPInvokeLib to demonstrate multitrack looping
  • UnitTestsDesktop: a C++ TAEF testing library for the NowSoundLibShared code

Note that any pull requests must ensure that all tests are passing.

Dependencies and Building

The JUCE library is required for compiling this project; the existing build expects it to be next to this repository in a directory named "JUCE".

VST2 dependencies are a bit tricky to come by as Steinberg (the company which owns the standard) no longer wants new VST2 development to occur. Unfortunately for them, very many plugins in the wild still use VST2, including the one I most wanted. Fortunately for us, Steinberg still makes old versions of the VST2/3 SDK available. This one contains the VST2 folders needed by this project:

https://www.steinberg.net/sdk_downloads/vstsdk366_27_06_2016_build_61.zip

I will soon write up exactly what to do with this zip file. If you want to try building this before then, create an issue to encourage me to do so :-)

Rationale

I implemented NowSound because I needed lower-latency audio than is available in Unity's audio subsystems, and because I needed to ensure all audio processing was happening natively. On tight low-latency audio deadlines, driving audio from C# (or any garbage-collected language) is sure to cause audible trouble at some point.

JUCE is just a great audio system. In particular the JUCE AudioProcessorGraph abstraction is critical to how NowSoundLib handles effects processing; each track has its own internal pipeline of AudioProcessor nodes, which it can manage purely internally without the rest of the system needing to be involved.

If you are interested in NowSound, check out the project which motivated me to write it: my gestural Kinect-and-mixed-reality live looper, Holofunk. You might also enjoy my blog.

Code Patterns

It's worth mentioning some aspects of the code that are pretty important to developing and maintaining it:

Modern C++ Ownership

There is not a single explicit C++ delete statement in this repository. Using std::unique_ptr, std::move, and rvalue && references means that the code is able to handle all buffer management efficiently and correctly, without reference counting or GC overhead and without explicit deletion.

Generic Types for Units

In my early audio programming experience with C, I learned a deep fear of the "int" data type. Integers (either short, normal, or long) were used for sample counts, byte counts, numbers of ticks, timestamps, milliseconds, and every other quantity. Getting confused was easy to do and hard to debug.

This code uses a common pattern, defining generic types Time<T> and Duration<T>. The "T" generic parameter serves as a placeholder for the type of time/duration involved. For instance, Time<Sample> defines a timestamp in terms of a count of audio samples since the start of the program. Duration<Sample> defines a time interval in terms of a number of audio samples. Arithmetic operators exist to add Time + Duration, subtract Duration from Time, subtract Time from Time giving a Duration, etc., provided that the T parameters match; you can't subtract a Time<Sample> from a Time<Seconds> as the compiler won't let you.

This may look verbose, but it precludes so many kinds of bugs that it has been well worth doing.

nowsound's People

Contributors

robjellinghaus avatar

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.