Skip to content

Commit

Permalink
update document
Browse files Browse the repository at this point in the history
  • Loading branch information
trquoccuong committed Jan 24, 2017
1 parent 21dbddf commit ec3bf06
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 49 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
out
gen
node_modules/
npm-debug.log
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Node wave
Render audio waveform like SoundCloud on backend

## Requirement
This module base on `web-audio-api` and `canvas` modules.
## Attribute

| Option | Desciption | Default |
| ------------- | ------------- | ------------- |
| width | Image width | 600px |
| height | Image height | 80px |
| barWidth | bar height | 3px |
| barGrap | space between 2 bar | 0.2 |
| waveColor | bar color | gray |
| waveAlpha | bar opacity | 1 |
| backgroundColor | Image background color | #fff |
| backgroundImage | setup image background | |
| baseline | center of waveform | 40 |
| padding | Top and bottom padding | 10 |
| baselineWidth | baseline width | 1 |
| baselineColor | baseline color | white |
102 changes: 57 additions & 45 deletions lib/render.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,46 @@
var AudioContext = require('web-audio-api').AudioContext;
var fs = require('fs');
var AudioContext = require('web-audio-api').AudioContext
var fs = require('fs')
var Canvas = require('canvas')

Array.prototype.max = function () {
return Math.max.apply(null, this);
};

var defaultSetting = {
width: 600,
height: 80,
barWidth: 3,
barGap: 0.2,
waveColor: "blue",
waveColor: 'gray',
waveAlpha: 1,
backgroundColor: '#fff',
baseline: 60,
}

function bufferMeasure(position, length, data) {
var sum = 0.0
for (var i = position; i <= (position + length) - 1; i++) {
sum += Math.pow(data[i], 2)
}
return Math.sqrt(sum / data.length)
backgroundImage: '',
baseline: 40,
padding: 10,
baselineWidth: 0,
baselineColor: 'white'
}

module.exports = function render(url, options, cb) {
var audioContext = new AudioContext
if (typeof options === "function") {
module.exports = function render (url, options, cb) {
var audioContext = new AudioContext()
if (typeof options === 'function') {
cb = options
options = {}
}

options = Object.assign({}, defaultSetting, options)
if (options.baseline < 0 && options.height < 0 && options.width < 0) {
return cb( new Error('Size must be greater than 0'))
return cb(new Error('Size must be greater than 0'))
}

if (options.baseline > options.height) {
return cb( new Error('Baseline must be smaller than waveform height'))
return cb(new Error('Baseline must be smaller than waveform height'))
}

var canvas = new Canvas(options.width, options.height)
var canvasContext = canvas.getContext('2d')

fs.readFile("Canon.mp3", function (err, buffer) {

if (err) {
return cb(err)
}
fs.readFile(url, function (err, buffer) {
if (err) return cb(err)

audioContext.decodeAudioData(buffer, function (result) {
var data = result.getChannelData(0)
var step = Math.floor(result.length / options.width)
var step = Math.floor(data.length / options.width)
var ratio = options.baseline / options.height
var vals = []

Expand All @@ -62,31 +50,55 @@ module.exports = function render(url, options, cb) {
canvasContext.fillStyle = options.waveColor

for (var i = 0; i < options.width; i += options.barWidth) {
vals.push(bufferMeasure(i * step, step, data) * 10000);
var position = i * step
var sum = 0.0
for (var j = position; j <= (position + step) - 1; j++) {
sum += Math.pow(data[j], 2)
}
vals.push(Math.sqrt(sum / data.length) * 10000)
}

for (var j = 0; j < options.width; j += options.barWidth) {
var scale = options.height / vals.max();
var val = bufferMeasure(j * step, step, data) * 10000;
val *= scale;
val += 1;
var w = options.barWidth;
var maxValue = Math.max.apply(null, vals)

vals.forEach(function (val, index) {
var scale = options.height / maxValue
val *= scale
var w = options.barWidth
if (options.barGap !== 0) {
w *= Math.abs(1 - options.barGap);
w *= Math.abs(1 - options.barGap)
}
var x = index * options.barWidth + (w / 2)

var lowerHeight = val * ratio

if (lowerHeight < options.padding) {
lowerHeight = 1
} else {
lowerHeight -= options.padding
}
var x = j + (w / 2);

var lowerHeight = val * ratio;
var upperHeight = val * (1 - ratio);
var upperHeight = val * (1 - ratio)

if(options.waveAlpha < 1) {
canvasContext.clearRect(x, options.baseline, w, upperHeight);
canvasContext.clearRect(x, options.baseline, w, -lowerHeight);
if (upperHeight < options.padding) {
upperHeight = 1
} else {
upperHeight -= options.padding
}
canvasContext.fillRect(x, options.baseline, w, upperHeight);
canvasContext.fillRect(x, options.baseline, w, -lowerHeight);

if (options.waveAlpha < 1) {
canvasContext.clearRect(x, options.baseline, w, upperHeight)
canvasContext.clearRect(x, options.baseline, w, -lowerHeight)
canvasContext.globalAlpha = options.waveAlpha
}
canvasContext.fillRect(x, options.baseline, w, upperHeight)
canvasContext.fillRect(x, options.baseline, w, -lowerHeight)
})

if (options.baselineWidth >= 1) {
canvasContext.fillStyle = options.baselineColor
canvasContext.fillRect(0, options.baseline - (options.baselineWidth / 2), options.width, options.baselineWidth)
}
cb(null, canvas.toBuffer())
})
});
})
}
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "node-wave",
"version": "0.0.1",
"description": "",
"version": "0.0.2",
"description": "Render waveform image like SoundCloud",
"main": "index.js",
"scripts": {
"test": "standard && node index.js"
"lint": "standard"
},
"author": "Tran Quoc Cuong <[email protected]>",
"license": "MIT",
Expand All @@ -13,6 +13,7 @@
"web-audio-api": "^0.2.2"
},
"devDependencies": {
"mocha": "^3.2.0",
"standard": "^8.6.0"
}
}
Binary file modified test/out.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion test/test.js → test/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ var render = require('../lib/render')
var fs = require('fs')

render('Canon.mp3', function (err, buffer) {
fs.writeFileSync('out.png', buffer);
if (err) return err
fs.writeFileSync('out.png', buffer)
})

0 comments on commit ec3bf06

Please sign in to comment.