Soundable allows you to play sounds, single and in sequence, in a very easy way

Overview

Overview

Pod Version Pod Platform Carthage compatible Pod License

Soundable is a tiny library that uses AVFoundation to manage the playing of sounds in iOS applications in a simple and easy way. You can play single audios, in sequence and in parallel, all is handled by the Soundable library and all they have completion closures when playing finishes.

Requirements

  • iOS 9.0+
  • Xcode 10.0+
  • Swift 4.2+

Install

Cocoapods

Add this line to your Podfile:

pod 'Soundable', '~> 1.0'

Carthage

Add this line to your cartfile:

github "ThXou/Soundable" ~> 1.0

And then follow the official documentation about Adding frameworks to an application.

Setup

Import Soundable in your source file:

import Soundable

Playing Sounds

Single Sounds

Soundable provides multiple ways to play a sound. The first one is by creating a Sound object:

let sound = Sound(fileName: "guitar-chord.wav")
sound.play()

This will play the guitar-chord.wav track located in the main bundle of the application. If you have multiple bundles in your application, use the fileName:bundle: function to create the sound. If you have an URL object instead, you can use:

let sound = Sound(url: url)
sound.play()

The second one is using the Soundable class functions:

Soundable.play(fileName: "guitar-chord.wav")

And the third is for the laziest people. Put the file name in a String object and just tryToPlay:

"guitar-chord.wav".tryToPlay()

This is possible due to a simple String category packed with the library that will try to play an audio file located in the application's main bundle with the specified name.

If you have an URL object and are lazzy too, you can use it like this also:

url.tryToPlay()

All these functions have their respective completion closures that passes an Error object if something wrong have happened in the process:

sound.play { error in
    if let error = error {
        print("error: \(error.localizedDescription)")
    }
}

Multiple Sounds

Playing In Parallel

To play audios in parallel your only have to worry on call the play function in all the audios you want to play in parallel, all the completion closures will be called when the audio finished playing.

Playing In Sequence

Soundable supports the playing of audios in sequence, and as for a single sound, you have multitple ways to play audios in sequence. The first one is the best (IMO):

let sound1 = Sound(fileName: "guitar-chord.wav")
let sound2 = Sound(fileName: "rain.mp3")
let sound3 = Sound(fileName: "water-stream.wav")

let sounds = [sound1, sound2, sound3]
sounds.play()

Or:

[sound1, sound2, sound3].play()

Can you play and array of Sound objects?. Yes. This is thanks to a simple Sequence extension packed with the library that only accepts Sound objects to play.

The second one is using the Soundable class functions, again:

Soundable.play(sounds: [sound1, sound2, sound3])

And the third is using the SoundsQueue object to create a queue of sounds:

let soundsQueue = SoundsQueue(sounds: [sound1, sound2, sound3])
soundsQueue.play()

As for single sounds, you also have the completion closure after all the sound sequence have been played.

Stop Sounds

To stop sounds and queues is as simple as play them. If you created the sound using the Sound object do it like this:

let sound = Sound(fileName: "guitar-chord.wav")
sound.play()
...
sound.stop()

You can stop a specific sound using the Soundable class functions:

Soundable.stop(sound)

You can stop all the sounds currently playing with Soundable, including sound queues:

Soundable.stopAll()

Or you can stop all the sounds in a specific group. I explain to you what is that thing of "Groups" in the next section.

Stop the sounds or sound queues does not trigger the completion closure.

Sound Groups

Sound groups is a feature that allows you to group sounds under the same string key, then you can stop all the sounds in that group and keep playing the rest.

By default all the sounds and sound queues are created under the SoundableKey.DefaultGroupKey key. In this way, you can group for example, game sounds under the "game_sounds" key and then stop only those sounds:

Soundable.stopAll(for: "game_sounds")

All the rest of the sounds keep playing until they reach the end of the track or queue.

You can set the group where a sound will belong to in the groupKey parameter of every play function. For example, when creating a Sound object:

let sound = Sound(fileName: "sprite-walk.wav")
sound.play(groupKey: "game_sounds") { error in
   // Handle error if any
}

Mute sounds

If you don't want to completelly stop the sound but only mute all sounds that are playing (Aka put the volume to 0.0), then use the Soundable mute functions:

// To mute
Soundable.muteAll()
Soundable.muteAll(for: "game_sounds")

// To unmute
Soundable.unmuteAll()
Soundable.unmuteAll(for: "game_sounds")

Alternativelly you can mute/unmute single sounds and queues:

sound.mute()
sound.unmute()

soundsQueue.mute()
soundsQueue.unmute()

Even check for the muting state with the sound and queue's isMuted property.

If the sound or queue finished while muted, the completion closure is called anyway and the mute state of the sound and queue is restored (Aka volume turns to be zero again).

Looped Sounds

Play sounds and sound queues in loop by setting the loopsCount parameter in every play call, as with the groupKey:

let sound = Sound(fileName: "sprite-walk.wav")
sound.play(groupKey: "game_sounds", loopsCount: 2) { error in
   // Handle error if any
}

The sound or sound queue will play a total of loopsCount + 1 times before it triggers the completion closure.

Disabling Sounds

You can enable/disable all the currently playing sounds and sound queues by setting the soundEnabled property of the Soundable class:

Soundable.soundEnabled = false

If disabled, it will stop all the playing sounds and sound queues and will return an error for subsequent attempts of playing sounds with the library. Disabling the sound system will not fire the completion closures.

Setup Audio Session Category

You can setup and activate the shared AVAudioSession category with a single call (no error handler). For example to continue playing the sounds when in the app is in background or the device is locked (background modes required):

import AVFoundation

// Setup the category
Soundable.activateSession(category: .playback)

Or also deactivate the current active session category:

Soundable.deactivateSession()

Handling Audio Interruptions

A playing sound or sound queue can be interrupted due to many reasons. For example when you are playing your sounds and then the user receives a phone call, the operating system stops all the sounds playing arround in order to listen the incoming audio from the call. In this case, Soundable allows you to catch this kind of events and let you react to an audio interruption:

Soundable.observeInterruptions { (type, userInfo) in
    if type == .began {
        print("interruption began")
    } else if type == .ended {
        print("interruption ended")
    }
}

In the closure you will receive the type of interruption, whether if it has .began or .ended, and the userInfo object containing the details about the interruption in order to make a more finest handling.

Credits

The sounds in the code example has been downloaded from the FreeSound database (https://freesound.org).

You might also like...
MusicalInstrument - Play musical instrument in just few lines of swift code

MusicalInstrument Play musical instrument in just few lines of swift code. Requi

KeyAudioManager - A swift package to make it a lot easier to play audio in your app

KeyAudioManager A swift package to make it a lot easier to play audio in your ap

A very simple soundboard that plays the first 5 seconds of the CSI Miami theme (YEAAAAAAAAAA)

MiamiSunglasses This app is a single-sound soundboard that plays the first few seconds of the CSI Miami theme song when you press the sunglasses. Disc

FDWaveformView is an easy way to display an audio waveform in your app
FDWaveformView is an easy way to display an audio waveform in your app

FDWaveformView is an easy way to display an audio waveform in your app. It is a nice visualization to show a playing audio file or to select a position in a file.

🗣Voice overlay helps you turn your user's voice into text, providing a polished UX while handling for you the necessary permissions
🗣Voice overlay helps you turn your user's voice into text, providing a polished UX while handling for you the necessary permissions

Voice overlay helps you turn your user's voice into text, providing a polished UX while handling for you the necessary permissions. It uses i

macOS app that allows the control of Spotify and AppleMusic/iTunes music playback from the menu bar.
macOS app that allows the control of Spotify and AppleMusic/iTunes music playback from the menu bar.

PlayStatus is a simple macOS app that allows the control of Spotify, Apple Music(macOS 10.15+) and iTunes including iTunes Radio/Beats1 playback from

A drop-in universal library allows to record audio within the app with a nice User Interface.
A drop-in universal library allows to record audio within the app with a nice User Interface.

IQAudioRecorderController IQAudioRecorderController is a drop-in universal library allows to record and crop audio within the app with a nice User Int

 A simple way to get a music pitch from a frequency.
A simple way to get a music pitch from a frequency.

Pitchy provides a simple way to get a music pitch from a frequency. Other than that it has a bunch of useful data structures, calculators and helper functions to work with notes, octaves and acoustic waves.

Extensions and classes in Swift that make it easy to get an iOS device reading and processing MIDI data

MorkAndMIDI A really thin Swift layer on top of CoreMIDI that opens a virtual MIDI destination and port and connects to any MIDI endpoints that appear

Comments
  • Need to call closure after every song finished in sequence play

    Need to call closure after every song finished in sequence play

    Hi, I need to call the finished playing queue after completing all the songs. but I need to call it after each song gets finished playing and get called when the new song started.

    is it possible?

    opened by ralspatel 0
  • does not loop

    does not loop

    Hello, i tested with my sound and found it does not loop, can u help?

    let sound = Sound(fileName: "Ringtone.caf")
                sound.play(groupKey: "outgoing", loopsCount: 10) { (error) in
                    print("play error: \(error)")
                }
    
    opened by fukemy 0
  • Play sequence of sounds without delay?

    Play sequence of sounds without delay?

    Hello, I'm wondering if it's possible to play a sequence of sounds without any delay. I'm using: let sound1 = Sound(fileName: "guitar-chord.wav") let sound2 = Sound(fileName: "rain.mp3") let sound3 = Sound(fileName: "water-stream.wav")

    let sounds = [sound1, sound2, sound3] sounds.play()

    and there is a slight delay before each new sound starts.

    Thanks!

    opened by gwenfriedman 0
  • play from folder

    play from folder

    If files are located in subfolder thant it will not play even if to indicate file with path Sound.swfit should be changed to this function

    public init(fileName: String, bundle: Bundle = Bundle.main) {
        super.init()
        
        let urlName = URL(fileURLWithPath: fileName)
        let file = urlName.deletingPathExtension().path
        let fileExtension = urlName.pathExtension
        
        name = fileName
        if let path =  bundle.path(forResource: file, ofType: fileExtension) {
            url = URL(fileURLWithPath: path)
            identifier = url?.absoluteString ?? ""
        }
        
        preparePlayer()
    }
    
    question 
    opened by duca14036 1
Owner
Luis Cárdenas
Code writer
Luis Cárdenas
The easiest way to prepare, play, and remove sounds in your Swift app!

Chirp The easiest way to prepare, play, and remove sounds in your Swift app! ##Installation ###CocoaPods Installation Chirp is available on CocoaPods.

null 309 Dec 17, 2022
SoundManager - A simple framework to load and play sounds in your app.

SoundManager - A simple framework to load and play sounds in your app.

Jonathan Chacón 3 Jan 5, 2022
SwiftySound is a simple library that lets you deal with Swift sounds easily

SwiftySound Overview SwiftySound is a simple library that lets you deal with Swift sounds easily. Static methods Sound.play(file: "dog.wav") Sound.pla

Adam Cichy 1.1k Dec 17, 2022
iOS application for finding formants in spoken sounds

FORMANT PLOTTER Buy on the App Store: https://itunes.apple.com/us/app/formant-analyzer/id799183655?mt=8&uo=4&at=11l6hc&ct=fnd This is an iOS project t

William Entriken 51 Dec 25, 2022
Analyser BPM in Swift for your music/sounds/records, whatever..

BPM-Analyser Analyser BPM in Swift for your music/sounds/records, whatever.. Powered with Superpowered Preview: How To: Copy theese files to your proj

Gleb Karpushkin 71 Dec 24, 2022
Background sounds feature from iOS 15 on iOS 11+

Tranquil Background sounds feature from iOS 15 on iOS 11+ Only physically tested on iOS 14.3 and iOS 12.1.2, but it should support iOS 11 - iOS 15.x (

Dana Buehre 4 Dec 15, 2022
An iOS app that visually clones Spotify's app and consumes the official Spotify's Web API to show(and play) songs, podcasts, artists and more.

SpotifyClone An iOS app that visually clones Spotify's app and consumes the official Spotify's Web API to show(and play) songs, podcasts, artists and

null 104 Jan 7, 2023
Play and share sound inserts from Medo e Delírio em Brasília, a Brazilian podcast.

Play and share sound inserts from Medo e Delírio em Brasília, a Brazilian podcast.

Rafael Schmitt 18 Dec 26, 2022
Subsonic is a small library that makes it easier to play audio with SwiftUI

Subsonic is a small library that makes it easier to play audio with SwiftUI

Paul Hudson 218 Dec 16, 2022
SPlayer - play mp3/pm4

SPlayer - play mp3/pm4

null 1 Nov 18, 2021