audiojs/audio

View on GitHub
index.js

Summary

Maintainability
B
4 hrs
Test Coverage
/**
 * @module  audio
 *
 * High-level audio container
 */

'use strict'

const isPlainObj = require('is-plain-obj')
const AudioBufferList = require('audio-buffer-list')
const createBuffer = require('audio-buffer-from')
const isAudioBuffer = require('is-audio-buffer')
const db = require('decibels')

let {isMultisource} = require('./src/util')


module.exports = Audio


// conversions
Audio.gain = db.toGain
Audio.db = db.fromGain

Audio.prototype.time = function offsetToTime (offset) {
    return offset / this.sampleRate
}

Audio.prototype.offset = function timeToOffset (time) {
    return Math.ceil(time * this.sampleRate)
}


// @constructor
function Audio(source, options) {
    if (!(this instanceof Audio)) return new Audio(source, options)

    // handle channels-only options
    if (typeof options === 'number') options = {channels: options}

    if (isPlainObj(source)) {
        options = source
        source = null
    }

    if (!options) options = {}

    // enable metrics
    if (options.stats) this.stats = true

    if (options.data) source = options.data

    let context = options.context

    // empty case
    if (source === undefined || typeof source === 'number') {
        options.duration = source || 0

        if (options.duration < 0) throw Error('Duration should not be negative')

        source = null

        this.buffer = new AudioBufferList(createBuffer(options))
    }

    // audiobufferlist case
     if (source instanceof AudioBufferList) {
        this.buffer = source
    }

    // other Audio instance
    else if (source instanceof Audio) {
        this.buffer = source.buffer.clone()
    }

    // audiobuffer case
    else if (isAudioBuffer(source)) {
        this.buffer = new AudioBufferList(source)
    }

    // array with malformed data
    else if (isMultisource(source)) {
        throw Error('Bad argument. Use `Audio.from` to create joined audio.')
    }

    // fall back to buffer
    else {
        try {
            let buf = createBuffer(source, options)
            this.buffer = new AudioBufferList(buf)
        }
        catch (e) {
            throw e
        }
    }

    // slice by length
    if (options.length != null) {
        if (this.buffer.length > options.length) {
            this.buffer = this.buffer.slice(0, options.length)
        }
        else if (this.buffer.length < options.length) {
            this.buffer.append(options.length - this.buffer.length)
        }
    }

    // TODO: remix channels if provided in options
}


require('./src/core')
require('./src/playback')
require('./src/metrics')
require('./src/manipulations')
require('./src/alias')