Skip to content

matthewreagan/Starling

Repository files navigation

Starling

Starling is a simple audio library for iOS + macOS written in Swift. It provides low-latency sound resource playback for games, real-time media solutions, or other performance-critical applications. It is built around Apple's AVAudioEngine and simplifies the API in an effort to reduce the amount of boilerplate needed for basic audio playback.

Goal

Starling is built for simple & fast audio file playback. It is designed to be as easy to use as possible, and to provide a minimal API which abstracts the under-the-hood interaction with AVFoundation.

Background

Starling was developed while working on Tank Wars, after it became apparent that other common solutions (such as leveraging SKAction or AVAudioPlayer) would be insufficient (even when utilizing somewhat 'hacky' solutions such as pre-playing the sound at 0 volume).

Features

  • Simple & easy-to-use
  • Per-effect control over asynchronous playback / overlapping
  • Nodes are increased dynamically as needed to accommodate any number of concurrent audio effects
  • Thread safe and performant, never blocks the main thread for loading or playback

Basic Playback

  1. Add an audio file to your app (ex: myAlarmSound.wav)

  2. (Optional) Define your sounds by extending SoundIdentifier:

extension SoundIdentifier {
    static let alarm = SoundIdentifier("alarm")
}

Alternatively you can use a string for your sound names, but using static members in this fashion will allow Xcode to provide nice autocompletion within the IDE, and easier refactoring or renaming of sounds in the future.

  1. Create an instance of Starling:

let starling = Starling()

  1. During app launch or game startup, load the sound:

starling.load(resource: "myAlarmSound", type: "wav", for: .alarm)

This only needs to be done once per audio file.

  1. Play the sound!

starling.play(.alarm)

Again, note that we're using the members of the extended SoundIdentifier type. You could also call starling.play("alarm") but avoiding literal strings will make renaming your sounds much easier.

Other Playback Options

In some cases you may wish to prevent a specific sound effect from overlapping itself (playing the same sound asynchronously ontop of itself before the first play() call has finished). This can be avoided by including the allowOverlap argument.

starling.play(.alarm, allowOverlap: false)

Xcode Integration

The demo project includes 3 targets: an iOS framework, a macOS framework, and a simple Mac demo app. You can either include and link against the compiled framework in the usual manner, or you can simply include Starling.swift in your project, which works on both platforms.

More Info

Starling is a very basic API and is still a work-in-progress. Pull requests and feature requests welcome.

Author

Matt Reagan - Website: http://sound-of-silence.com/ - Twitter: @hmblebee

License

Source code and related resources are Copyright (C) Matthew Reagan 2018. The source code is released under the MIT License.