TooTallNate / node-speaker

Output PCM audio data to the speakers
648 stars 145 forks source link

Support for Audio.js? #80

Closed jamen closed 8 years ago

jamen commented 8 years ago

I have started a new project called "audio" (I got lucky and freed it on npm) where you have a central Audio object that holds PCM data along with some audio format options for interacting with the data. Our APIs are actually almost compatible, which I think is pretty cool.

I think it would be nice if you could plop an Audio object right into the Speaker object, and have it play:

var Speaker = require('speaker');
var Audio = require('audio');
var random = require('crypto').randomBytes;

// Create 5s random audio.
var foo = new Audio(random(800 * 5), {
  sampleRate: 800, 
  bitDepth: 8, 
  signed: false
});

new Speaker(foo);

The APIs are pretty much compatible with how I designed Audio, except that Speaker doesn't accept my object, and also that it doesn't accept PCM data in the initialization so you have to write it after you initialize.

I made a small wrapper over your library for mine called "audio-out" but I think it would be cool if it could just work with node-speaker out of the box (considering they almost work and how small audio-out is).

I was thinking, node-speaker could take the Audio object (where the existing API is compatible), but add one feature for the audio.sample, where if it exists it automatically writes that data to the speaker.

Another cool thought I had is where you could do things like this to play WAV files (and for other formats when I made the decoders for them):

var read = require('fs').readFileSync;
var decodeWav = require('audio-decode-wav');
var Speaker = require('speaker');

var foo = read('./example.wav'); // Get raw WAV data.
var wav = decodeWav(foo); // Decode WAV data to an Audio object.
new Speaker(wav); // Play Audio with Speaker.

This is almost possible (and is possible with audio-out)!

Currently, there is little documentation for my object, but I have it unit tested and it does work. I also need to update my modules and make more encoders and decoders for different formats.

Do you think this is a good idea?

jamen commented 8 years ago

I've made some new plans to how audio.js's plugin basing will primarily work. Somewhat like this with streams:

fs.createReadStream('./foo.wav')
.pipe(decodeWav())
// ... use `Audio` in stream.

I think it is in everyone's interests to keep both these efficient, and I no longer think my idea is valid, since writing the sample in itself is easy:

speaker.write(audio.sample);

Or even a very simple plugin for getting the .sample so you can pipe right to speaker.

.pipe(encodeRaw) // simple turns audio.sample into readable
.pipe(speaker)