Code Monkey home page Code Monkey logo

web-audio-api's Introduction

web-audio-api test

Node.js implementation of Web audio API

This library implements the Web Audio API specification (also know as WAA) on Node.js.

What's Implemented

  • AudioContext (partially)
  • AudioParam (almost there)
  • AudioBufferSourceNode
  • ScriptProcessorNode
  • GainNode
  • OscillatorNode
  • DelayNode

Installation

npm install --save web-audio-api

Demo

Get ready, this is going to blow up your mind:

npm install
npm run test-speaker

Audio Output

By default, web-audio-api doesn't play back the sound it generates. In fact, an AudioContext has no default output, and you need to give it a writable node stream to which it can write raw PCM audio. After creating an AudioContext, set its output stream like this : audioContext.outStream = writableStream.

Example: Playing back sound with node-speaker

This is probably the simplest way to play back audio. Install node-speaker with npm install speaker, then do something like this :

import { AudioContext } from 'web-audio-api'
import Speaker from 'speaker'

const context = new AudioContext

context.outStream = new Speaker({
  channels: context.format.numberOfChannels,
  bitDepth: context.format.bitDepth,
  sampleRate: context.sampleRate
})

// Create some audio nodes here to make some noise ...

Example : playing back sound with aplay

Linux users can play back sound from web-audio-api by piping its output to aplay. For this, simply send the generated sound straight to stdout like this :

import { AudioContext } from 'web-audio-api'
const context = new AudioContext()

context.outStream = process.stdout

// Create some audio nodes here to make some noise ...

Then start your script, piping it to aplay like so :

node myScript.js | aplay -f cd

Example : creating an audio stream with icecast2

icecast is a open-source streaming server. It works great, and is very easy to setup. icecast accepts connections from different source clients which provide the sound to encode and stream. ices is a client for icecast which accepts raw PCM audio from its standard input, and you can send sound from web-audio-api to ices (which will send it to icecast) by simply doing :

import { spawn } from 'child_process'
import { AudioContext } from 'web-audio-api'
 const context = new AudioContext()

var ices = spawn('ices', ['ices.xml'])
context.outStream = ices.stdin

A live example is available on Sébastien's website

Using Gibber

Gibber is a great audiovisual live coding environment for the browser made by Charlie Roberts. For audio, it uses Web Audio API, so you can run it on web-audio-api. First install gibber with npm :

npm install gibber.audio.lib

Then to you can run the following test to see that everything works:

npm test gibber.audio.lib

Overall view of implementation

Each time you create an AudioNode (like for instance an AudioBufferSourceNode or a GainNode), it inherits from DspObject which is in charge of two things:

  • register schedule events with _schedule
  • compute the appropriate digital signal processing with _tick

Each time you connect an AudioNode using source.connect(destination, output, input) it connects the relevant AudioOutput instances of source node to the relevant AudioInput instance of the destination node.

To instantiate all of these AudioNode, you needed an overall AudioContext instance. This latter has a destination property (where the sound will flow out), instance of AudioDestinationNode, which inherits from AudioNode. The AudioContext instance keeps track of connections to the destination. When that happens, it triggers the audio loop, calling _tick infinitely on the destination, which will itself call _tick on its input ... and so forth go up on the whole audio graph.

Running the debugger

Right now everything runs in one process, so if you set a break point in your code, there's going to be a lot of buffer underflows, and you won't be able to debug anything.

One trick is to kill the AudioContext right before the break point, like this:

context[Symbol.dispose]()
debugger

that way the audio loop is stopped, and you can inspect your objects in peace.

Alternatives

License

MIT

🕉

web-audio-api's People

Contributors

anprogrammer avatar chrisguttandin avatar dy avatar gitter-badger avatar hughrawlinson avatar jamen avatar kirbysayshi avatar korilakkuma avatar ouhouhsami avatar sebpiq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

web-audio-api's Issues

Microphone level

How to get the microphone level (average volume)? Help me, please!

ES6 refactoring

Well, this is not really an issue. I tried to refactor your app using es6 class. https://github.com/ouhouhsami/node-web-audio-api/tree/es6 (last commit 8219f3b)

  • All tests pass even if there is a lot to do to clean some 'not very pretty' things like remove unused underscore lib

  • One thing I changed is that there is now a base class for DspObject (which inherits from events.EventEmitter) instead of having a mixin DspObjectMixin.

  • I also created a ChannelMixing es6 class - very ugly for the moment.

  • I use es6-transpiler with gulp, lib folder is for es6 code and build, for es5 (transpiled) code.

    If you have any remarks / ideas on this refactoring, feel free !

onended event fired to early

Hello,

This nodejs web audio api implementation is a great idea. (I see one use case: testing).
In fact, I was in process of testing basic web audio code with this implementation, and it happens that I think the 'onended' event for AudioBufferSourceNode is fired before it should. In https://github.com/sebpiq/node-web-audio-api/blob/master/lib/AudioBufferSourceNode.js#L69, if the last outBuffer is not empty, the self.onended() is called too early as the audio will have to play this buffer.

Cheers,

speaker dependency install fails

speaker 0.0.x fails to install on my machine, which is running OS X 10.3. The current version of speaker does not fail to install, but tests do fail for the node-web-audio-api.

Test log is here.

I'll do my best to submit a PR for this soon, as I need node-web-audio-api for university work. Just wanted to ask if there's any reason that upgrading to speaker 0.2.5 (i.e. the current version) would cause any other unforseen issues, once I get the tests passing?

1.0 release ideas/discussion

As discussed with @sebpiq, modularity is one of the goals for web-audio-api. So here are ideas for discussion for the first release.

Specifying AudioContext sample rate

It appears that the AudioContext sample rate is currently fixed at 44.1 kHz. Is there a current way to specify the sample rate in a script that uses this library, or is an enhancement needed?

OscillatorNode (coming soon)

Hi guys,

When do we get oscillator nodes?
and delay nodes?
I would love to see them... as well as reverb nodes!

npm package needs updating

I just installed via npm and it tried to install speaker as an optional dependency. In master, speaker is not a dependency anywhere, which suggests that the npm package and master are not currently in sync.

Implement copyFromChannel/copyToChannel

I was able to work around the lack of copyFromChannel/copyToChannel by using getChannelData and Float32Array::slice and AudioBuffer.fromArray when trying to slice an AudioBuffer:

sliceAudioBuffer = (audioBuffer, startOffset, endOffset, audioContext)->
		# {numberOfChannels, duration, sampleRate, frameCount} = audioBuffer
		# 
		# newAudioBuffer = audioContext.createBuffer(numberOfChannels, endOffset - startOffset, sampleRate)
		# tempArray = new Float32Array(frameCount)
		# 
		# for channel in [0..numberOfChannels]
		# 	audioBuffer.copyFromChannel(tempArray, channel, startOffset)
		# 	newAudioBuffer.copyToChannel(tempArray, channel, 0)
		# 
		# newAudioBuffer
		
		{numberOfChannels, sampleRate} = audioBuffer
		
		array =
			for channel in [0...numberOfChannels]
				samples = audioBuffer.getChannelData(channel)
				samples.slice(startOffset * sampleRate, endOffset * sampleRate)
			
		AudioBuffer.fromArray(array, sampleRate)

But it seems like these should be pretty simple to add.

Cannot find sound card when requiring

On node interpreter:

> var waa = require('web-audio-api');
ALSA lib pcm_dmix.c:1029:(snd_pcm_dmix_open) unable to open slave
[../deps/mpg123/src/output/alsa.c:165] error: cannot open device default
Assertion failed: pcm && params (pcm_params.c: snd_pcm_hw_refine: 2290)
Aborted (core dumped)

System information:

$ cat /etc/*-release
3.4.0
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.4.0
PRETTY_NAME="Alpine Linux v3.4"
HOME_URL="http://alpinelinux.org"
BUG_REPORT_URL="http://bugs.alpinelinux.org"

arecord:

$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Error: the 2 AudioBuffers don't have the same sampleRate

@sebpiq this module is freakin' amazing!

I think I may have stumbled onto a bug when looping an audio file. I load an mp3 file, and run it. It plays for a little while. When it's about to loop, I see this error:

/Users/michaelreinstein/wwwroot/whitenoise/node_modules/web-audio-api/build/AudioBuffer.js:46
      throw new Error('the 2 AudioBuffers don\'t have the same sampleRate')
      ^

Error: the 2 AudioBuffers don't have the same sampleRate
    at AudioBuffer.proto$0.set (/Users/michaelreinstein/wwwroot/whitenoise/node_modules/web-audio-api/build/AudioBuffer.js:46:13)
    at AudioBufferSourceNode.this$0._dsp (/Users/michaelreinstein/wwwroot/whitenoise/node_modules/web-audio-api/build/AudioBufferSourceNode.js:54:21)

when I modify line 54 of build/AudioBufferSourceNode.js from:

outBuffer = new AudioBuffer(this.buffer.numberOfChannels, blockSize, sampleRate)

to:

outBuffer = new AudioBuffer(this.buffer.numberOfChannels, blockSize, this.buffer.sampleRate)

The error goes away. I'm not sure why though! Is this a bug, or something specific to my particular use case?

installation problem

hi guys!
I'm facing this installation issue on mac os 10.8.5 and node 4.1.2:
anyone knows what to do here?

sudo npm install web-audio-api

../deps/mpg123/src/output/coreaudio.c:14:39: warning: CoreServices/CoreServices.h: No such file or directory
../deps/mpg123/src/output/coreaudio.c:15:33: warning: AudioUnit/AudioUnit.h: No such file or directory
../deps/mpg123/src/output/coreaudio.c:16:39: warning: AudioToolbox/AudioToolbox.h: No such file or directory
../deps/mpg123/src/output/coreaudio.c:30: error: expected specifier-qualifier-list before ‘AudioConverterRef’
../deps/mpg123/src/output/coreaudio.c:51: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘playProc’
../deps/mpg123/src/output/coreaudio.c:101: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘convertProc’
../deps/mpg123/src/output/coreaudio.c: In function ‘open_coreaudio’:
../deps/mpg123/src/output/coreaudio.c:117: error: ‘UInt32’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:117: error: (Each undeclared identifier is reported only once
../deps/mpg123/src/output/coreaudio.c:117: error: for each function it appears in.)
../deps/mpg123/src/output/coreaudio.c:117: error: expected ‘;’ before ‘size’
../deps/mpg123/src/output/coreaudio.c:118: error: ‘ComponentDescription’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:118: error: expected ‘;’ before ‘desc’
../deps/mpg123/src/output/coreaudio.c:119: error: ‘Component’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:119: error: expected ‘;’ before ‘comp’
../deps/mpg123/src/output/coreaudio.c:120: error: ‘AudioStreamBasicDescription’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:120: error: expected ‘;’ before ‘inFormat’
../deps/mpg123/src/output/coreaudio.c:121: error: expected ‘;’ before ‘outFormat’
../deps/mpg123/src/output/coreaudio.c:122: error: ‘AURenderCallbackStruct’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:122: error: expected ‘;’ before ‘renderCallback’
../deps/mpg123/src/output/coreaudio.c:123: error: ‘Boolean’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:123: error: expected ‘;’ before ‘outWritable’
../deps/mpg123/src/output/coreaudio.c:126: error: ‘mpg123_coreaudio_t’ has no member named ‘play’
../deps/mpg123/src/output/coreaudio.c:127: error: ‘mpg123_coreaudio_t’ has no member named ‘buffer’
../deps/mpg123/src/output/coreaudio.c:128: error: ‘mpg123_coreaudio_t’ has no member named ‘buffer_size’
../deps/mpg123/src/output/coreaudio.c:129: error: ‘mpg123_coreaudio_t’ has no member named ‘last_buffer’
../deps/mpg123/src/output/coreaudio.c:130: error: ‘mpg123_coreaudio_t’ has no member named ‘play_done’
../deps/mpg123/src/output/coreaudio.c:131: error: ‘mpg123_coreaudio_t’ has no member named ‘decode_done’
../deps/mpg123/src/output/coreaudio.c:135: error: ‘desc’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:135: error: ‘kAudioUnitType_Output’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:136: error: ‘kAudioUnitSubType_DefaultOutput’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:137: error: ‘kAudioUnitManufacturer_Apple’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:140: error: ‘comp’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:140: warning: implicit declaration of function ‘FindNextComponent’
../deps/mpg123/src/output/coreaudio.c:146: warning: implicit declaration of function ‘OpenAComponent’
../deps/mpg123/src/output/coreaudio.c:146: error: ‘mpg123_coreaudio_t’ has no member named ‘outputUnit’
../deps/mpg123/src/output/coreaudio.c:151: warning: implicit declaration of function ‘AudioUnitInitialize’
../deps/mpg123/src/output/coreaudio.c:151: error: ‘mpg123_coreaudio_t’ has no member named ‘outputUnit’
../deps/mpg123/src/output/coreaudio.c:157: warning: implicit declaration of function ‘AudioUnitGetPropertyInfo’
../deps/mpg123/src/output/coreaudio.c:157: error: ‘mpg123_coreaudio_t’ has no member named ‘outputUnit’
../deps/mpg123/src/output/coreaudio.c:157: error: ‘kAudioUnitProperty_StreamFormat’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:157: error: ‘kAudioUnitScope_Output’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:157: error: ‘size’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:157: error: ‘outWritable’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:158: warning: implicit declaration of function ‘AudioUnitGetProperty’
../deps/mpg123/src/output/coreaudio.c:158: error: ‘mpg123_coreaudio_t’ has no member named ‘outputUnit’
../deps/mpg123/src/output/coreaudio.c:158: error: ‘outFormat’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:163: warning: implicit declaration of function ‘AudioUnitSetProperty’
../deps/mpg123/src/output/coreaudio.c:163: error: ‘mpg123_coreaudio_t’ has no member named ‘outputUnit’
../deps/mpg123/src/output/coreaudio.c:163: error: ‘kAudioUnitScope_Input’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:169: error: ‘mpg123_coreaudio_t’ has no member named ‘channels’
../deps/mpg123/src/output/coreaudio.c:170: error: ‘inFormat’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:172: error: ‘kAudioFormatLinearPCM’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:176: error: ‘kLinearPCMFormatFlagIsPacked’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:182: error: ‘kLinearPCMFormatFlagIsSignedInteger’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:183: error: ‘mpg123_coreaudio_t’ has no member named ‘bps’
../deps/mpg123/src/output/coreaudio.c:187: error: ‘mpg123_coreaudio_t’ has no member named ‘bps’
../deps/mpg123/src/output/coreaudio.c:190: error: ‘mpg123_coreaudio_t’ has no member named ‘bps’
../deps/mpg123/src/output/coreaudio.c:194: error: ‘mpg123_coreaudio_t’ has no member named ‘bps’
../deps/mpg123/src/output/coreaudio.c:197: error: ‘kLinearPCMFormatFlagIsFloat’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:198: error: ‘mpg123_coreaudio_t’ has no member named ‘bps’
../deps/mpg123/src/output/coreaudio.c:202: error: ‘mpg123_coreaudio_t’ has no member named ‘bps’
../deps/mpg123/src/output/coreaudio.c:203: error: ‘mpg123_coreaudio_t’ has no member named ‘bps’
../deps/mpg123/src/output/coreaudio.c:205: error: ‘mpg123_coreaudio_t’ has no member named ‘bps’
../deps/mpg123/src/output/coreaudio.c:208: error: ‘renderCallback’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:209: error: ‘convertProc’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:211: error: ‘mpg123_coreaudio_t’ has no member named ‘outputUnit’
../deps/mpg123/src/output/coreaudio.c:211: error: ‘kAudioUnitProperty_SetRenderCallback’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:221: warning: implicit declaration of function ‘AudioConverterNew’
../deps/mpg123/src/output/coreaudio.c:221: error: ‘mpg123_coreaudio_t’ has no member named ‘converter’
../deps/mpg123/src/output/coreaudio.c:226: error: ‘SInt32’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:226: error: expected ‘;’ before ‘channelMap’
../deps/mpg123/src/output/coreaudio.c:227: warning: implicit declaration of function ‘AudioConverterSetProperty’
../deps/mpg123/src/output/coreaudio.c:227: error: ‘mpg123_coreaudio_t’ has no member named ‘converter’
../deps/mpg123/src/output/coreaudio.c:227: error: ‘kAudioConverterChannelMap’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:227: error: ‘channelMap’ undeclared (first use in this function)
../deps/mpg123/src/output/coreaudio.c:234: error: ‘mpg123_coreaudio_t’ has no member named ‘bps’
../deps/mpg123/src/output/coreaudio.c:236: error: ‘mpg123_coreaudio_t’ has no member named ‘fifo’
../deps/mpg123/src/output/coreaudio.c: In function ‘write_coreaudio’:
../deps/mpg123/src/output/coreaudio.c:253: error: ‘mpg123_coreaudio_t’ has no member named ‘fifo’
../deps/mpg123/src/output/coreaudio.c:253: error: ‘mpg123_coreaudio_t’ has no member named ‘fifo’
../deps/mpg123/src/output/coreaudio.c:253: error: ‘mpg123_coreaudio_t’ has no member named ‘fifo’
../deps/mpg123/src/output/coreaudio.c:253: error: ‘mpg123_coreaudio_t’ has no member named ‘fifo’
../deps/mpg123/src/output/coreaudio.c:258: error: ‘mpg123_coreaudio_t’ has no member named ‘fifo’
../deps/mpg123/src/output/coreaudio.c:265: error: ‘mpg123_coreaudio_t’ has no member named ‘play’
../deps/mpg123/src/output/coreaudio.c:267: warning: implicit declaration of function ‘AudioOutputUnitStart’
../deps/mpg123/src/output/coreaudio.c:267: error: ‘mpg123_coreaudio_t’ has no member named ‘outputUnit’
../deps/mpg123/src/output/coreaudio.c:271: error: ‘mpg123_coreaudio_t’ has no member named ‘play’
../deps/mpg123/src/output/coreaudio.c: In function ‘close_coreaudio’:
../deps/mpg123/src/output/coreaudio.c:282: error: ‘mpg123_coreaudio_t’ has no member named ‘decode_done’
../deps/mpg123/src/output/coreaudio.c:283: error: ‘mpg123_coreaudio_t’ has no member named ‘play_done’
../deps/mpg123/src/output/coreaudio.c:283: error: ‘mpg123_coreaudio_t’ has no member named ‘play’
../deps/mpg123/src/output/coreaudio.c:286: warning: implicit declaration of function ‘AudioConverterDispose’
../deps/mpg123/src/output/coreaudio.c:286: error: ‘mpg123_coreaudio_t’ has no member named ‘converter’
../deps/mpg123/src/output/coreaudio.c:287: warning: implicit declaration of function ‘AudioOutputUnitStop’
../deps/mpg123/src/output/coreaudio.c:287: error: ‘mpg123_coreaudio_t’ has no member named ‘outputUnit’
../deps/mpg123/src/output/coreaudio.c:288: warning: implicit declaration of function ‘AudioUnitUninitialize’
../deps/mpg123/src/output/coreaudio.c:288: error: ‘mpg123_coreaudio_t’ has no member named ‘outputUnit’
../deps/mpg123/src/output/coreaudio.c:289: warning: implicit declaration of function ‘CloseComponent’
../deps/mpg123/src/output/coreaudio.c:289: error: ‘mpg123_coreaudio_t’ has no member named ‘outputUnit’
../deps/mpg123/src/output/coreaudio.c:292: error: ‘mpg123_coreaudio_t’ has no member named ‘fifo’
../deps/mpg123/src/output/coreaudio.c:295: error: ‘mpg123_coreaudio_t’ has no member named ‘buffer’
../deps/mpg123/src/output/coreaudio.c:296: error: ‘mpg123_coreaudio_t’ has no member named ‘buffer’
../deps/mpg123/src/output/coreaudio.c:297: error: ‘mpg123_coreaudio_t’ has no member named ‘buffer’
../deps/mpg123/src/output/coreaudio.c: In function ‘flush_coreaudio’:
../deps/mpg123/src/output/coreaudio.c:310: error: ‘mpg123_coreaudio_t’ has no member named ‘outputUnit’
../deps/mpg123/src/output/coreaudio.c:313: error: ‘mpg123_coreaudio_t’ has no member named ‘play’
../deps/mpg123/src/output/coreaudio.c:316: error: ‘mpg123_coreaudio_t’ has no member named ‘fifo’
make: *** [Release/obj.target/output/deps/mpg123/src/output/coreaudio.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: make failed with exit code: 2
gyp ERR! stack at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:270:23)
gyp ERR! stack at emitTwo (events.js:87:13)
gyp ERR! stack at ChildProcess.emit (events.js:172:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:200:12)
gyp ERR! System Darwin 12.6.0
gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/michael/node_modules/speaker
gyp ERR! node -v v4.1.2
gyp ERR! node-gyp -v v3.0.3
gyp ERR! not ok
npm WARN install:speaker [email protected] install: node-gyp rebuild
npm WARN install:speaker Exit status 1

React native

Hi,

Great library ! Do youu think it would be possible to use it with react native ? How would you proceed with the "connect" bit in order to connect it to the speaker output of a phone?

Enhance README examples...

Specifically, please substitute "Create some audio nodes here to make some noise ..." comment by some real code. People who don't know/remember how to create audio nodes (or who don't want to spend time on it) won't hear anything if they directly try to execute these examples, and that's a pity for doing a fast glance of the capabilities of this module.
Thanks!

cannot run test/manual-testing/AudioContext-sound-output.js

After following the instructions in the README, I try to run this manual test and I get this:

$ node test/manual-testing/AudioContext-sound-output.js 

module.js:340
    throw err;
    ^
Error: Cannot find module 'speaker'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/Users/walker/Sites/node-web-audio-api/test/manual-testing/AudioContext-sound-output.js:5:17)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)

Same behavior observed on both Raspberry PI 2 running Raspbian as well as Mac OS X 10.10.2

C++ build failures

I've given this a try on nixos and on arch, but I get the same failure on each when I do npm install. It kind of looks like I might have the wrong version of a C library? The results are below.

My procedure:

install npm via git and make install

git clone https://github.com/npm/npm.git
make install (I think)

install web-audio via git, then npm install

git clone https://github.com/sebpiq/node-web-audio-api.git
cd node-web-audio-api
npm install

result: C++ compile errors.

[bananapi@lemaker node-web-audio-api]$ export PYTHON=python2
[bananapi@lemaker node-web-audio-api]$ npm install
|
> [email protected] install /home/bananapi/code/node-web-audio-api/node_modules/speaker
> node-gyp rebuild

make: Entering directory '/home/bananapi/code/node-web-audio-api/node_modules/speaker/build'
  CC(target) Release/obj.target/output/deps/mpg123/src/output/alsa.o
../deps/mpg123/src/output/alsa.c: In function ‘rates_match’:
../deps/mpg123/src/output/alsa.c:53:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  return actual * 100 > desired * (100 - AUDIO_RATE_TOLERANCE) &&
                      ^
../deps/mpg123/src/output/alsa.c:54:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         actual * 100 < desired * (100 + AUDIO_RATE_TOLERANCE);
                      ^
../deps/mpg123/src/output/alsa.c: In function ‘initialize_device’:
../deps/mpg123/src/output/alsa.c:78:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (i = 0; i < NUM_FORMATS; ++i) {
                ^
../deps/mpg123/src/output/alsa.c: In function ‘get_formats_alsa’:
../deps/mpg123/src/output/alsa.c:201:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (i = 0; i < NUM_FORMATS; ++i) {
                ^
  AR(target) Release/obj.target/deps/mpg123/liboutput.a
  COPY Release/liboutput.a
  CXX(target) Release/obj.target/binding/src/binding.o
In file included from ../src/binding.cc:6:0:
../src/node_pointer.h: In function ‘v8::Handle<v8::Value> WrapPointer(void*, size_t)’:
../src/node_pointer.h:23:16: error: expected primary-expression before ‘*’ token
   node::Buffer *buf = node::Buffer::New((char *)ptr, length, wrap_pointer_cb, user_data);
                ^
../src/node_pointer.h:23:17: error: ‘buf’ was not declared in this scope
   node::Buffer *buf = node::Buffer::New((char *)ptr, length, wrap_pointer_cb, user_data);
                 ^
../src/binding.cc: At global scope:
../src/binding.cc:17:3: error: ‘uv_work_t’ does not name a type
   uv_work_t req;
   ^
../src/binding.cc:25:27: error: ‘Arguments’ does not name a type
 Handle<Value> Open (const Arguments& args) {
                           ^
In file included from ../src/binding.cc:4:0:
/home/bananapi/.node-gyp/0.12.0/deps/v8/include/v8.h: In function ‘v8::Handle<v8::Value> {anonymous}::Open(const int&)’:
/home/bananapi/.node-gyp/0.12.0/deps/v8/include/v8.h:816:13: error: ‘v8::HandleScope::HandleScope()’ is protected
   V8_INLINE HandleScope() {}
             ^
../src/binding.cc:26:15: error: within this context
   HandleScope scope;
               ^
../src/binding.cc:28:79: error: invalid types ‘const int[int]’ for array subscript
   audio_output_t *ao = reinterpret_cast<audio_output_t *>(UnwrapPointer(args[0]));
                                                                               ^
../src/binding.cc:31:32: error: invalid types ‘const int[int]’ for array subscript
   Local<Object> format = args[1]->ToObject();
                                ^
../src/binding.cc:33:30: error: ‘NewSymbol’ is not a member of ‘v8::String’
   ao->channels = format->Get(String::NewSymbol("channels"))->Int32Value(); /* channels */
                              ^
../src/binding.cc:34:26: error: ‘NewSymbol’ is not a member of ‘v8::String’
   ao->rate = format->Get(String::NewSymbol("sampleRate"))->Int32Value(); /* sample rate */
                          ^
../src/binding.cc:36:30: error: ‘NewSymbol’ is not a member of ‘v8::String’
   int bitDepth = format->Get(String::NewSymbol("bitDepth"))->Int32Value();
                              ^
../src/binding.cc:37:31: error: ‘NewSymbol’ is not a member of ‘v8::String’
   bool isSigned = format->Get(String::NewSymbol("signed"))->BooleanValue();
                               ^
../src/binding.cc:38:30: error: ‘NewSymbol’ is not a member of ‘v8::String’
   bool isFloat = format->Get(String::NewSymbol("float"))->BooleanValue();
                              ^
../src/binding.cc:72:16: error: ‘class v8::HandleScope’ has no member named ‘Close’
   return scope.Close(Integer::New(r));
                ^
../src/binding.cc:72:36: error: no matching function for call to ‘v8::Integer::New(int&)’
   return scope.Close(Integer::New(r));
                                    ^
../src/binding.cc:72:36: note: candidate is:
In file included from ../src/binding.cc:4:0:
/home/bananapi/.node-gyp/0.12.0/deps/v8/include/v8.h:2012:25: note: static v8::Local<v8::Integer> v8::Integer::New(v8::Isolate*, int32_t)
   static Local<Integer> New(Isolate* isolate, int32_t value);
                         ^
/home/bananapi/.node-gyp/0.12.0/deps/v8/include/v8.h:2012:25: note:   candidate expects 2 arguments, 1 provided
../src/binding.cc: At global scope:
../src/binding.cc:75:19: error: variable or field ‘write_async’ declared void
 void write_async (uv_work_t *);
                   ^
../src/binding.cc:75:19: error: ‘uv_work_t’ was not declared in this scope
../src/binding.cc:75:30: error: expected primary-expression before ‘)’ token
 void write_async (uv_work_t *);
                              ^
../src/binding.cc:76:19: error: variable or field ‘write_after’ declared void
 void write_after (uv_work_t *);
                   ^
../src/binding.cc:76:19: error: ‘uv_work_t’ was not declared in this scope
../src/binding.cc:76:30: error: expected primary-expression before ‘)’ token
 void write_after (uv_work_t *);
                              ^
../src/binding.cc:78:28: error: ‘Arguments’ does not name a type
 Handle<Value> Write (const Arguments& args) {
                            ^
In file included from ../src/binding.cc:4:0:
/home/bananapi/.node-gyp/0.12.0/deps/v8/include/v8.h: In function ‘v8::Handle<v8::Value> {anonymous}::Write(const int&)’:
/home/bananapi/.node-gyp/0.12.0/deps/v8/include/v8.h:816:13: error: ‘v8::HandleScope::HandleScope()’ is protected
   V8_INLINE HandleScope() {}
             ^
../src/binding.cc:79:15: error: within this context
   HandleScope scope;
               ^
../src/binding.cc:80:79: error: invalid types ‘const int[int]’ for array subscript
   audio_output_t *ao = reinterpret_cast<audio_output_t *>(UnwrapPointer(args[0]));
                                                                               ^
../src/binding.cc:81:81: error: invalid types ‘const int[int]’ for array subscript
   unsigned char *buffer = reinterpret_cast<unsigned char *>(UnwrapPointer(args[1]));
                                                                                 ^
../src/binding.cc:82:19: error: invalid types ‘const int[int]’ for array subscript
   int len = args[2]->Int32Value();
                   ^
../src/binding.cc:83:58: error: invalid types ‘const int[int]’ for array subscript
   Local<Function> callback = Local<Function>::Cast(args[3]);
                                                          ^
../src/binding.cc:90:53: error: no matching function for call to ‘v8::Persistent<v8::Function>::New(v8::Local<v8::Function>&)’
   req->callback = Persistent<Function>::New(callback);
                                                     ^
../src/binding.cc:90:53: note: candidate is:
In file included from ../src/binding.cc:4:0:
/home/bananapi/.node-gyp/0.12.0/deps/v8/include/v8.h:5809:4: note: static T* v8::PersistentBase<T>::New(v8::Isolate*, T*) [with T = v8::Function]
 T* PersistentBase<T>::New(Isolate* isolate, T* that) {
    ^
/home/bananapi/.node-gyp/0.12.0/deps/v8/include/v8.h:5809:4: note:   candidate expects 2 arguments, 1 provided
../src/binding.cc:92:8: error: ‘struct {anonymous}::write_req’ has no member named ‘req’
   req->req.data = req;
        ^
../src/binding.cc:94:33: error: ‘uv_default_loop’ was not declared in this scope
   uv_queue_work(uv_default_loop(), &req->req, write_async, (uv_after_work_cb)write_after);
                                 ^
../src/binding.cc:94:42: error: ‘struct {anonymous}::write_req’ has no member named ‘req’
   uv_queue_work(uv_default_loop(), &req->req, write_async, (uv_after_work_cb)write_after);
                                          ^
../src/binding.cc:94:47: error: ‘write_async’ was not declared in this scope
   uv_queue_work(uv_default_loop(), &req->req, write_async, (uv_after_work_cb)write_after);
                                               ^
../src/binding.cc:94:61: error: ‘uv_after_work_cb’ was not declared in this scope
   uv_queue_work(uv_default_loop(), &req->req, write_async, (uv_after_work_cb)write_after);
                                                             ^
../src/binding.cc:94:89: error: ‘uv_queue_work’ was not declared in this scope
   uv_queue_work(uv_default_loop(), &req->req, write_async, (uv_after_work_cb)write_after);
                                                                                         ^
../src/binding.cc:96:20: error: too few arguments to function ‘v8::Handle<v8::Primitive> v8::Undefined(v8::Isolate*)’
   return Undefined();
                    ^
In file included from ../src/binding.cc:4:0:
/home/bananapi/.node-gyp/0.12.0/deps/v8/include/v8.h:305:28: note: declared here
   friend Handle<Primitive> Undefined(Isolate* isolate);
                            ^
../src/binding.cc: At global scope:
../src/binding.cc:99:19: error: variable or field ‘write_async’ declared void
 void write_async (uv_work_t *req) {
                   ^
../src/binding.cc:99:19: error: ‘uv_work_t’ was not declared in this scope
../src/binding.cc:99:30: error: ‘req’ was not declared in this scope
 void write_async (uv_work_t *req) {
                              ^
../src/binding.cc:104:19: error: variable or field ‘write_after’ declared void
 void write_after (uv_work_t *req) {
                   ^
../src/binding.cc:104:19: error: ‘uv_work_t’ was not declared in this scope
../src/binding.cc:104:30: error: ‘req’ was not declared in this scope
 void write_after (uv_work_t *req) {
                              ^
In file included from ../src/binding.cc:5:0:
/home/bananapi/.node-gyp/0.12.0/src/node.h:405:3: error: expected ‘}’ at end of input
   }
   ^
/home/bananapi/.node-gyp/0.12.0/src/node.h:427:3: note: in expansion of macro ‘NODE_MODULE_X’
   NODE_MODULE_X(modname, regfunc, NULL, 0)
   ^
../src/binding.cc:159:1: note: in expansion of macro ‘NODE_MODULE’
 NODE_MODULE(binding, Initialize)
 ^
../src/binding.cc:25:15: warning: ‘v8::Handle<v8::Value> {anonymous}::Open(const int&)’ defined but not used [-Wunused-function]
 Handle<Value> Open (const Arguments& args) {
               ^
../src/binding.cc:78:15: warning: ‘v8::Handle<v8::Value> {anonymous}::Write(const int&)’ defined but not used [-Wunused-function]
 Handle<Value> Write (const Arguments& args) {
               ^
binding.target.mk:92: recipe for target 'Release/obj.target/binding/src/binding.o' failed
make: *** [Release/obj.target/binding/src/binding.o] Error 1
make: Leaving directory '/home/bananapi/code/node-web-audio-api/node_modules/speaker/build'
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:269:23)
gyp ERR! stack     at ChildProcess.emit (events.js:110:17)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:1067:12)
gyp ERR! System Linux 3.4.103
gyp ERR! command "node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /home/bananapi/code/node-web-audio-api/node_modules/speaker
gyp ERR! node -v v0.12.0
gyp ERR! node-gyp -v v1.0.3
gyp ERR! not ok 
npm WARN optional dep failed, continuing [email protected]

> [email protected] prepublish /home/bananapi/code/node-web-audio-api
> gulp

[15:27:03] Using gulpfile ~/code/node-web-audio-api/gulpfile.js
[15:27:03] Starting 'default'...
[15:27:09] Finished 'default' after 6.49 s
[bananapi@lemaker node-web-audio-api]$ 

Use native es6 if available

Right now (dec 2014) it seems that even when using the --harmony flag, many ES6 features are not supported (including class which we need). So there's no point yet in doing this. But in a near future, index.js should look like this :

var importRoot

// Test if ES6 is supported 
if ('function' === typeof Map) importRoot = './lib/'

// If not, use the transpiled version
else importRoot = './build/'

module.exports = {

  AudioContext: require(importRoot + 'AudioContext'),
  AudioParam: require(importRoot + 'AudioParam'),
  AudioNode: require(importRoot + 'AudioNode'),
  AudioDestinationNode: require(importRoot + 'AudioDestinationNode'),
  AudioBuffer: require(importRoot + 'AudioBuffer'),
  AudioBufferSourceNode: require(importRoot + 'AudioBufferSourceNode'),
  GainNode: require(importRoot + 'GainNode'),

  constants: require(importRoot + 'constants')

}

big cleaning ...

I haven't been able to maintain the library properly, since I haven't used it myself for quite a while :(
I think it needs quite a big cleaning :

  • Reorganizing file structure : right now it's all flat, and quite messy
  • Clean code : some basic sweeping, and style uniformization should be done on the whole codebase, as I have accepted pull requests from different people, and have done a very sloppy job at uniformizing and proof-reading the code when merging.
  • Triage tickets : some of the oldest tickets must be checked ... not sure that they are still valid.

Please make a new npm release

I'm using this for testing, and the master branch works significantly better than the last published version in npm. Please consider publishing a new release.

Thank you very much for the library!

Demo from README.md doesn't work as instructed

Cloning the repo then running:
node test/manual-testing/AudioContext-sound-output.js

throws a syntax error:
SyntaxError: Unexpected reserved word

Looks like this is due to ES6 syntax. Need to run gulp default then make sure the manual test is using the 'build' folder and not the 'lib' folder.

Submitting pull request momentarily...

Capturing audio

Do you recommend anything for capturing audio from a microphone with Node?

Or should something like node-microphone work fine?

Thanks.

Error: Cannot find module 'speaker'

node test/manual-testing/AudioContext-sound-output.js
module.js:339
    throw err;
    ^

Error: Cannot find module 'speaker'
    at Function.Module._resolveFilename (module.js:337:15)
    at Function.Module._load (module.js:287:25)
    at Module.require (module.js:366:17)
    at require (module.js:385:17)
    at Object. (/Users/mbp/Downloads/node-web-audio-api-master/test/manual-testing/AudioContext-sound-output.js:5:17)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Function.Module.runMain (module.js:467:10)

Feature request - AudioContext.createAnalyser()

Hi everyone,
I've found this awesome repo and tried the magnificent code in it

I know it's in an early stage of development, but I was trying it out and figured that there isn't any "createAnalyser" function.

My goal was to create an FFT audio visualizer using node.js, in order to activate some LEDs on my Raspberry Pi.

So I digged into the webkit source code and tried to implement the Analyser node, without any success.
I was really wondering, is it planned for something? Unfortunately I can't implement it by myself because I'm not so good at cpp.

The end goal of my project would be creating something like this FFT visualizer but made out of LEDs:
http://ianreah.com/2013/02/28/Real-time-analysis-of-streaming-audio-data-with-Web-Audio-API.html

(Source code: http://ianreah.com/js/Real-time-frequency-analysis-of-streaming-audio-data/main.js)

Is Analyser Node planned in any way?
Keep up the good work and have a wonderful day!

Handle setting .value properly

"If a value is set during a time when there are any automation events scheduled then it will be ignored and no exception will be thrown."

Right now setting .value overrides the current dsp

Implement ctx.createBiquadFilter

Thanks for this lib. Would like to use it to test createBiquadFilter(), if it's possible. Let me know if you have any alternate testing strategies, if you can! 😃

sample-precise scheduling

Right now, scheduled events are only block-precise (k-rate).
This sucks for example for AudioParam, where we can then have a 3ms (128/44100 s) imprecision.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.