audio-vs1053b
Advanced tools
Comparing version 0.1.2 to 0.1.3
@@ -0,42 +1,41 @@ | ||
// Any copyright is dedicated to the Public Domain. | ||
// http://creativecommons.org/publicdomain/zero/1.0/ | ||
/********************************************* | ||
This Audio Module demo sets volume, then plays | ||
an audio file out over Headphones/Line out | ||
*********************************************/ | ||
var tessel = require('tessel'); | ||
var fs = require('fs'); | ||
var audio = require('../').use(tessel.port('a')); | ||
var audio = require('../').use(tessel.port['A']); // Replace '../' with 'audio-vs1053b' in your own code | ||
console.log('trying to connect...'); | ||
var audioFile = 'sample.mp3'; | ||
// Wait for the module to connect | ||
audio.on('ready', function() { | ||
console.log("Ready to go!"); | ||
audio.setVolume(20, 20, function(err) { | ||
if (err) return console.log('err setting volume', err); | ||
var song = fs.readFileSync('/app/sample.mp3'); | ||
console.log("Audio module connected! Setting volume..."); | ||
// Set the volume in decibels. Around 20 is good; smaller is louder. | ||
audio.setVolume(20, function(err) { | ||
if (err) { | ||
return console.log(err); | ||
} | ||
// Get the song | ||
console.log('Retrieving file...'); | ||
var song = fs.readFileSync(audioFile); | ||
// Play the song | ||
console.log('Playing ' + audioFile + '...'); | ||
audio.play(song, function(err) { | ||
if (err) { | ||
console.log("error playing song: ", err); | ||
console.log(err); | ||
} else { | ||
console.log('Done playing', audioFile); | ||
} | ||
else { | ||
console.log("Done playing the first song"); | ||
} | ||
}); | ||
// setTimeout(function audioPause() { | ||
// console.log('pausing!'); | ||
// audio.pause(function paused() { | ||
// setTimeout(function audioResume() { | ||
// audio.play(); | ||
// console.log('started playing again'); | ||
// setTimeout(function stopping() { | ||
// console.log('stopping'); | ||
// audio.stop(function stopped() { | ||
// console.log('stopped!'); | ||
// }) | ||
// }, 1000); | ||
// }, 1000); | ||
// }); | ||
// }, 1000); | ||
}) | ||
}); | ||
}); | ||
// If there is an error, report it | ||
audio.on('error', function(err) { | ||
console.log("Failed to connect", err); | ||
console.log(err); | ||
}); | ||
setInterval(function(){}, 20000); |
54
index.js
@@ -1,2 +0,9 @@ | ||
// VS1053b module | ||
// Copyright 2014 Technical Machine, Inc. See the COPYRIGHT | ||
// file at the top-level directory of this distribution. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
@@ -6,3 +13,3 @@ var fs = require('fs'); | ||
var util = require('util'); | ||
var hw = process.binding('hw') | ||
var hw = process.binding('hw'); | ||
var Writable = require('stream').Writable; | ||
@@ -67,3 +74,3 @@ var Readable = require('stream').Readable; | ||
// Waits for the audio data event which is recorded data being output from the C shim | ||
process.on('audio_recording_data', this._handleRecordedData.bind(this)); | ||
process.on('audio_recording_data', this._handleRecordedData.bind(this)); | ||
@@ -87,3 +94,3 @@ // Waits for final flushed buffer of a recording | ||
// Make sure we can comm and have the right version | ||
self._checkVersion(function(err) { | ||
self._checkVersion(function(err) { | ||
if (err) { self._failConnect(err, callback); } | ||
@@ -95,3 +102,3 @@ else { | ||
else { | ||
// Enabke headphones and lineIn | ||
// Enabke headphones and lineIn | ||
self.setDefaultIO(function(err) { | ||
@@ -106,3 +113,3 @@ if (err) { self._failConnect(err, callback); } | ||
}); | ||
} | ||
} | ||
}); | ||
@@ -238,3 +245,3 @@ } | ||
Audio.prototype._checkVersion = function(callback) { | ||
this._readSciRegister16(SCI_STATUS, function(err, MP3Status) { | ||
this._readSciRegister16(SCI_STATUS, function(err, MP3Status) { | ||
if (err) { return callback && callback(err); } | ||
@@ -254,3 +261,3 @@ else if ((MP3Status >> 4) & 0x000F != 4){ | ||
// Set multiplier to 3.0x | ||
this._writeSciRegister16(SCI_CLOCKF, 0x6000, function(err) { | ||
this._writeSciRegister16(SCI_CLOCKF, 0x6000, function(err) { | ||
if (err) { return callback && callback(err); } | ||
@@ -261,3 +268,3 @@ else { | ||
} | ||
}.bind(this)); | ||
}.bind(this)); | ||
@@ -391,5 +398,25 @@ } | ||
Audio.prototype.setVolume = function(leftChannelDecibels, rightChannelDecibels, callback) { | ||
if (rightChannelDecibels === undefined) { | ||
// If no volume was provided | ||
if (leftChannelDecibels === undefined) { | ||
// Just callback | ||
if (callback) { | ||
callback(); | ||
} | ||
// and return | ||
return; | ||
} | ||
// If the user passed in one decibel level and a callback | ||
else if (typeof rightChannelDecibels === 'function' && !callback) { | ||
// set the callback | ||
callback = rightChannelDecibels; | ||
// And make both channels the same | ||
rightChannelDecibels = leftChannelDecibels; | ||
} | ||
// If the user only passed in a decibel level | ||
else if (rightChannelDecibels === undefined && callback === undefined) { | ||
// Make both channels the same | ||
rightChannelDecibels = leftChannelDecibels; | ||
} | ||
@@ -399,2 +426,3 @@ // The units are in half decibels | ||
rightChannelDecibels = rightChannelDecibels/0.5 | ||
// Set VS10xx Volume Register | ||
@@ -644,3 +672,3 @@ this._writeSciRegister(SCI_VOL, leftChannelDecibels, rightChannelDecibels, callback); | ||
if (ret < 0) { | ||
var err; | ||
var err; | ||
@@ -668,3 +696,3 @@ if (ret == -1) { | ||
callback(); | ||
} | ||
} | ||
@@ -703,2 +731,2 @@ this.emit('startRecording'); | ||
exports.use = use; | ||
exports.use = use; |
{ | ||
"name": "audio-vs1053b", | ||
"version": "0.1.2", | ||
"version": "0.1.3", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
201
README.md
@@ -1,181 +0,122 @@ | ||
#Audio Module | ||
#Audio | ||
Driver for the audio-vs1053b Tessel audio module ([VS1053B](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=0CC8QFjAB&url=http%3A%2F%2Fwww.vlsi.fi%2Ffileadmin%2Fdatasheets%2Fvlsi%2Fvs1053.pdf&ei=YXiFU4LrE8P3oATVwICADA&usg=AFQjCNF4G61PCB76XncJH2V8x9NE18ycqg&bvm=bv.67720277,d.cGU)) | ||
##Installation | ||
```sh | ||
npm install audio-vs1053b | ||
``` | ||
```npm install audio-vs1053b``` | ||
## Limitations | ||
##Limitations | ||
The current version of the Tessel runtime is too slow to play audio files smoothly. That means we wrote a custom C shim that handles most of the playback and recording of data. There are several consequences of the C shim: | ||
* Any other modules that use SPI for communication will be blocked while the audio module is playing a buffer. | ||
* You can only have one audio module attached to Tessel at a time. | ||
* Any other modules that use SPI for communication will be blocked while the Audio Module is playing a buffer. | ||
* You can only have one Audio Module attached to Tessel at a time. | ||
* Updates to the Audio Module driver must be released in both firmware and this npm repo. | ||
It sucks but we're expecting major runtime speed improvements to render the C shim uncessesary within the next couple months. | ||
It sucks but we're expecting major runtime speed improvements to render the C shim unnecessary within the next couple of months. | ||
##Example | ||
1. Writing mic data to a file (w/out streams) | ||
```.js | ||
// Any copyright is dedicated to the Public Domain. | ||
// http://creativecommons.org/publicdomain/zero/1.0/ | ||
/********************************************* | ||
This Audio Module demo sets volume, then plays | ||
an audio file out over Headphones/Line out | ||
*********************************************/ | ||
var tessel = require('tessel'); | ||
var fs = require('fs'); | ||
var audio = require('audio-vs1053b').use(tessel.port('a'), function(err) { | ||
// Start recording data for a second into a file | ||
audio.setInput('mic', function(err) { | ||
var chunks = []; | ||
var audio = require('../').use(tessel.port('a')); | ||
audio.on('data', function(data) { | ||
chunks.push(data); | ||
console.log('trying to connect...'); | ||
audio.on('ready', function() { | ||
console.log("Ready to go!"); | ||
audio.setVolume(20, 20, function(err) { | ||
if (err) return console.log('err setting volume', err); | ||
var song = fs.readFileSync('/app/sample.mp3'); | ||
audio.play(song, function(err) { | ||
if (err) { | ||
console.log("error playing song: ", err); | ||
} | ||
else { | ||
console.log("Done playing the first song"); | ||
} | ||
}); | ||
// Start the recording | ||
audio.startRecording(function(err) { | ||
// In one second | ||
setTimeout(function() { | ||
// Stop recording | ||
audio.stopRecording(function(err) { | ||
// Write the buffer to a file | ||
fs.writeFile("micdata", Buffer.concat(chunks), function(err) { | ||
console.log("Wrote to a file"); | ||
}); | ||
}) | ||
}, 1000); | ||
}); | ||
}); | ||
}); | ||
``` | ||
2. Writing line-in to a file (w/ streams) | ||
```.js | ||
var tessel = require('tessel'); | ||
var fs = require('fs'); | ||
var audio = require('audio-vs1053b').use(tessel.port('a'), function(err) { | ||
// Start recording data for a second into a file | ||
audio.setInput('line-in', function(err) { | ||
// Open a stream to a file | ||
var file = fs.createWriteStream('lineInData.ogg'); | ||
// Create a readable stream of incoming data | ||
var soundData = audio.createRecordStream(); | ||
// Pipe data to the file | ||
soundData.pipe(file); | ||
}); | ||
audio.on('error', function(err) { | ||
console.log("Failed to connect", err); | ||
}); | ||
``` | ||
3. Output audio on the headphone Jack (w/o streams) | ||
```.js | ||
var tessel = require('tessel'); | ||
var fs = require('fs'); | ||
var audio = require('audio-vs1053b').use(tessel.port('a'), function(err) { | ||
// Start recording data for a second into a file | ||
audio.setOutput('headphone', function(err) { | ||
// Open a file | ||
var audioFile = fs.readFileSync('Oops... I did it again.mp3'); | ||
// Play the file | ||
audio.play(audioFile); | ||
}); | ||
}); | ||
``` | ||
4. Output audio on the headphone Jack (with streams) | ||
```.js | ||
var tessel = require('tessel'); | ||
var fs = require('fs'); | ||
var audio = require('audio-vs1053b').use(tessel.port('a'), function(err) { | ||
// Start recording data for a second into a file | ||
audio.setOutput('headphone', function(err) { | ||
// Open a file | ||
fs.createReadStream('rayman.ogg').pipe(audio.createPlayStream()); | ||
}); | ||
}); | ||
##Methods | ||
``` | ||
##### * `audio.setVolume(leftChannelDb, [rightChannelDb,] callback(err))` Set the output volume. Level is a Number from 0.0 to 1.0 | ||
##API | ||
##### * `audio.setInput(input, callback(err))` Set the input to either 'lineIn' or 'mic'. Defaults to 'lineIn'. | ||
###Commands | ||
##### * `audio.setOutput(output, callback(err))` Set the output to either 'lineOut' or 'headPhones'. Defaults to 'lineOut'. | ||
```.js | ||
// Set the output volume. Level is a Number from 0.0 to 1.0 | ||
audio.setVolume( level, function(err) {...} ); | ||
##### * `audio.startRecording([profile] callback(err))` Start recording sound from the input. (Receive data in the 'data' event) Callback called after recording initialized (not stopped). quality is an optional argument that can be 'voice', 'wideband-voice', 'wideband-stereo', 'hifi-voice', or 'stereo-music'. Default is 'hifi-voice'. | ||
// Set the input to either 'lineIn' or 'mic'. Defaults to 'lineIn'. | ||
audio.setInput( input, function(err) {...} ); | ||
##### * `audio.stopRecording(callback(err))` Stop recording sound (note that may receive one more 'data' event before this completes when the buffer is flushed.) | ||
// Set the output to either 'lineOut' or 'headPhones'. Defaults to 'lineOut'. | ||
audio.setOutput(output, function(err) {...} ); | ||
##### * `audio.play([audioBuff], callback(err))` Play a buffer. If no buffer is passed in, the module will attempt to resume a buffer that was paused. | ||
// Start recording sound from the input. (Receive data in the 'data' event) Callback called after recording initialized (not stopped.) | ||
quality is an optional argument that can be 'voice', 'wideband-voice', 'wideband-stereo', 'hifi-voice', or 'stereo-music'. Default is 'hifi-voice'. | ||
audio.startRecording([profile] function(err) {...} ); | ||
##### * `audio.pause(callback(err))` Pause the buffer | ||
// Stop recording sound (note that may receive one more 'data' event before this completes when the buffer is flushed.) | ||
audio.stopRecording( function(err) {...} ); | ||
##### * `audio.stop(callback(err))` Stop playing and flush the buffer | ||
// Play a buffer. If no buffer is passed in, the module | ||
// will attempt to resume a buffer that was paused. | ||
audio.play( [audioBuff], function(err) {...} ); | ||
##### * `audio.createPlayStream()` Returns a stream that a buffer can be piped into to play audio | ||
// Pause the buffer | ||
audio.pause( function(err) {...} ); | ||
##### * `audio.createRecordStream()` Returns a readable stream of mic data | ||
// Stop playing and flush the buffer | ||
audio.stop( function(err) {...} ); | ||
##### * `audio.availableRecordingProfiles()` Returns an array of available profiles | ||
// Returns a stream that a buffer can be piped into to play audio | ||
audio.createPlayStream(); | ||
// Returns a readable stream of mic data | ||
audio.createRecordStream() | ||
##Events | ||
// Returns an array of available profiles | ||
audio.availableRecordingProfiles(); | ||
##### * `audio.on('ready', callback())` The audio module is ready to use | ||
``` | ||
##### * `audio.on('error', callback(err))` The audio module had an error on connection | ||
###Events | ||
##### * `audio.on('volume', callback(volume))` Volume was set | ||
```.js | ||
##### * `audio.on('input', callback(input))` The input mode was set | ||
// The audio module is ready to use | ||
audio.on( 'ready', function() {...} ); | ||
##### * `audio.on('output', callback(output))` The output mode was set | ||
// The audio module had an error on connection | ||
audio.on( 'error', function(err) {...} ); | ||
##### * `audio.on('startRecording', callback())` Started recording from the input | ||
// Volume was set | ||
audio.on( 'volume', function(volume) {...} ); | ||
##### * `audio.on('data', callback(audioBuff))` Received recorded data | ||
// The input mode was set | ||
audio.on('input', function(input) {...} ); | ||
##### * `audio.on('stopRecording', callback())` Stopped recording on the input | ||
// The output mode was set | ||
audio.on('output', function(output) {...} ); | ||
##### * `audio.on('play', callback())` A buffer is beginning to be played | ||
// Started recording from the input | ||
audio.on('startRecording', function() {...} ); | ||
##### * `audio.on('pause', callback())` Playback was paused | ||
// Received recorded data | ||
audio.on('data', function(audioBuff) {...} ); | ||
##### * `audio.on('stop', callback())` Playback was stopped | ||
// Stopped recording on the input | ||
audio.on('stopRecording', function() {...} ); | ||
##### * `audio.on('end', callback(err)` The buffer finished playing | ||
// A buffer is beginning to be played | ||
audio.on('play', function() {...} ); | ||
// Playback was paused | ||
audio.on('pause', function() {...} ); | ||
##Further Examples | ||
See the examples folder for code. | ||
// Playback was stopped | ||
audio.on('stop', function() {...} ); | ||
* audio-out-no-streams: Listen to audio without using streams. | ||
// The buffer finished playing | ||
audio.on('end', function(err) {...}) | ||
* record-sound: Record sound from the microphone without using streams. | ||
``` | ||
* stream-audio-out: Stream audio from a file to Headphones/Line out | ||
* stream-sound-to-file: Stream audio input from line in to a file. | ||
##License | ||
MIT | ||
APACHE |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
417646
20
882
1
1
123
8