This repository has been archived by the owner on May 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
212 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
[0.6.0] | ||
- Split functionallity in files | ||
|
||
[0.5.0] | ||
- Duration no longer required (thanks @benwiley4000). | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
var ctx = new window.AudioContext() | ||
var soundfont = require('..')(ctx) | ||
|
||
var osc = soundfont.instrument() | ||
osc.onready(function () { | ||
var time = ctx.currentTime | ||
'G3 B3 D4'.split(' ').forEach(function (note, index) { | ||
osc.play(note, time + index) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
'use strict' | ||
|
||
var midi = require('note.midi') | ||
|
||
module.exports = function (ctx, buffers, options) { | ||
return function (note, time, duration) { | ||
var buffer = buffers[midi(note)] | ||
if (!buffer) return | ||
var source = ctx.createBufferSource() | ||
source.buffer = buffer | ||
source.connect(ctx.destination) | ||
source.start(time) | ||
if (duration > 0) source.stop(time + duration) | ||
return source | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
'use strict' | ||
|
||
var loadBank = require('./load-bank') | ||
var oscillatorPlayer = require('./oscillator-player') | ||
var buffersPlayer = require('./buffers-player') | ||
|
||
module.exports = Soundfont | ||
|
||
/** | ||
* Create a Soundfont object | ||
* | ||
* @param {AudioContext} context - the [audio context](https://developer.mozilla.org/en/docs/Web/API/AudioContext) | ||
* @return {Soundfont} a soundfont object | ||
*/ | ||
function Soundfont (ctx, nameToUrl) { | ||
if (!(this instanceof Soundfont)) return new Soundfont(ctx) | ||
|
||
this.nameToUrl = nameToUrl || Soundfont.nameToUrl || gleitzUrl | ||
this.ctx = ctx | ||
this.instruments = {} | ||
this.promises = [] | ||
} | ||
|
||
Soundfont.prototype.instrument = function (name, options) { | ||
var ctx = this.ctx | ||
name = name || 'default' | ||
if (name in this.instruments) return this.instruments[name] | ||
var inst = { name: name, play: oscillatorPlayer(ctx, options) } | ||
this.instruments[name] = inst | ||
var promise = loadBank(ctx, this.nameToUrl(name)) | ||
this.promises.push(promise) | ||
promise.then(function (buffers) { | ||
inst.play = buffersPlayer(ctx, buffers, options) | ||
}) | ||
inst.onready = function (cb) { promise.then(cb) } | ||
return inst | ||
} | ||
|
||
Soundfont.loadBuffers = function (ctx, name) { | ||
var nameToUrl = Soundfont.nameToUrl || gleitzUrl | ||
return loadBank(ctx, nameToUrl(name)) | ||
} | ||
|
||
/* | ||
* Given an instrument name returns a URL to to the Benjamin Gleitzman's | ||
* package of [pre-rendered sound fonts](https://github.com/gleitz/midi-js-soundfonts) | ||
* | ||
* @param {String} name - instrument name | ||
* @returns {String} the Soundfont file url | ||
*/ | ||
function gleitzUrl (name) { | ||
return 'https://cdn.rawgit.com/gleitz/midi-js-Soundfonts/master/FluidR3_GM/' + name + '-ogg.js' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
'use strict' | ||
|
||
var midi = require('note.midi') | ||
var decodeBuffer = require('./decode-buffer') | ||
|
||
/** | ||
* Load a soundfont bank | ||
* | ||
* @param {AudioContext} ctx - the audio context object | ||
* @param {String} url - the url of the js file | ||
* @param {Function} get - (Optional) given a url return a promise with the contents | ||
* @param {Function} parse - (Optinal) given a js file return JSON object | ||
*/ | ||
module.exports = function (ctx, url, get, parse) { | ||
get = get || getContent | ||
parse = parse || parseJavascript | ||
return Promise.resolve(url).then(get).then(parse) | ||
.then(function (data) { | ||
return { ctx: ctx, data: data, buffers: {} } | ||
}) | ||
.then(decodeBank) | ||
.then(function (bank) { return bank.buffers }) | ||
} | ||
|
||
function getContent (url) { | ||
return new Promise(function (done, reject) { | ||
var req = new window.XMLHttpRequest() | ||
req.open('GET', url) | ||
|
||
req.onload = function () { | ||
if (req.status === 200) { | ||
done(req.response) | ||
} else { | ||
reject(Error(req.statusText)) | ||
} | ||
} | ||
req.onerror = function () { | ||
reject(Error('Network Error')) | ||
} | ||
req.send() | ||
}) | ||
} | ||
|
||
/** | ||
* Parse the SoundFont data and return a JSON object | ||
* (SoundFont data are .js files wrapping json data) | ||
* | ||
* @param {String} data - the SoundFont js file content | ||
* @return {JSON} the parsed data as JSON object | ||
* @api private | ||
*/ | ||
function parseJavascript (data) { | ||
var begin = data.indexOf('MIDI.Soundfont.') | ||
begin = data.indexOf('=', begin) + 2 | ||
var end = data.lastIndexOf(',') | ||
return JSON.parse(data.slice(begin, end) + '}') | ||
} | ||
|
||
/* | ||
* Decode a bank | ||
* @param {Object} bank - the bank object | ||
* @return {Promise} a promise that resolves to the bank with the buffers decoded | ||
* @api private | ||
*/ | ||
function decodeBank (bank) { | ||
var promises = Object.keys(bank.data).map(function (note) { | ||
return decodeBuffer(bank.ctx, bank.data[note]) | ||
.then(function (buffer) { | ||
bank.buffers[midi(note)] = buffer | ||
}) | ||
}) | ||
|
||
return Promise.all(promises).then(function () { | ||
return bank | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
'use strict' | ||
|
||
var freq = require('midi.freq')(440) | ||
var midi = require('note.midi') | ||
|
||
/** | ||
* Returns a function that plays an oscillator | ||
* | ||
*/ | ||
module.exports = function (context, options) { | ||
return function (note, time, duration) { | ||
var f = freq(midi(note)) | ||
if (!f) return | ||
|
||
options = options || {} | ||
duration = duration || 0.2 | ||
|
||
var vcoType = options.vcoType || 'sine' | ||
|
||
var vco = context.createOscillator() | ||
vco.type = vcoType | ||
vco.frequency.value = f | ||
|
||
/* VCA */ | ||
var vca = context.createGain() | ||
vca.gain.value = options.gain || 0.5 | ||
|
||
/* Connections */ | ||
vco.connect(vca) | ||
vca.connect(context.destination) | ||
|
||
vco.start(time) | ||
if (duration > 0) vco.stop(time + duration) | ||
return vco | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters