source: gs3-extensions/web-audio/trunk/js-mad/sink.js-master/README.md@ 28388

Last change on this file since 28388 was 28388, checked in by davidb, 11 years ago

Set of JS, CSS, PNG etc web resources to support a mixture of audio player/document display capabilities

File size: 5.2 KB
Line 
1sink.js
2=======
3
4sink.js is a javascript library dedicated for audio output. Features include buffer fill callbacks, synchronous write, asynchronous write, ring buffers and recording. Currently supported platforms are Firefox 4+ and Chrome with Web Audio API enabled in ``` about:flags ```. Additional platforms, such as a flash fallback can be added as plugins, but are currently not featured, nor will ever be enabled by default. For a platform to be added as enabled by default, it needs to be reliable in terms of latency and stability. Flash fallbacks – for example – cannot offer this kind of reliability and the sound will always be flaky at best.
5
6Basic usage
7-------------
8
9To create a sink, the following function is available:
10
11```
12
13var sink = Sink([callback=null], [channelCount=2], [preBufferSize=4096], [sampleRate=44100])
14
15```
16
17Currently, it is recommended to check that you are actually running at the sample rate that you specified, so when you create a sink, get the samplerate reference always from its ``` .sampleRate ``` property.
18
19The callback is fed with two arguments, the buffer to fill and the channel count of the buffer. For example, to play back stereo noise, you can do the following:
20
21```javascript
22
23var sink = Sink(function(buffer, channelCount){
24 var i;
25 for (i=0; i<buffer.length; i++){
26 buffer[i] = Math.random() - 0.5;
27 }
28});
29
30```
31
32Note that `buffer` is interleaved and therefore the samples should be written as :
33
34```javascript
35[
36 channel1, channel2, ... channelN, // frame 1
37 channel1, channel2, ... channelN, // frame 2
38 ... // ...
39]
40```
41
42For example, to play back a 440Hz sine wave in stereo, you can do :
43
44```javascript
45var k, v, n = 0;
46var sink = Sink(function(buffer, channelCount){
47 for (var j=0; j<buffer.length; j+=2, n++) {
48 v = Math.sin(k*n);
49 buffer[j] = v;
50 buffer[j+1] = v;
51 }
52}, 2); // 2 channels ... which is already the default
53
54k = 2*Math.PI*440/sink.sampleRate;
55```
56
57Note also that the length of the `buffer` can vary, it will however always be less than `preBufferSize`. If you need control over `buffer`'s length, check-out [proxies][proxy].
58
59To bring the sink to a force stop, you can use the ``` .kill() ``` method. But so far, this doesn't work in Chrome, and the Chrome's AudioContext can't be taken down. This will be fixed as soon as possible. Also, beware of creating multiple sinks to avoid unexpected results.
60
61Buffer writing API
62-------------------
63
64As an alternative to the callback API, you can directly write sound to the buffers with ``` .write(buffer, [delay=undefined]) ``` method. The default writing mode is "async" where the specified buffer will be mixed with existing data. If a delay is not specified, the system will automatically create a delay to try to compensate the latency. The delay is specified as number of samples.
65
66Another mode of writing is "sync". You can set this by changing your sink's ``` .writeMode ``` property to "sync". In the "sync" write mode, the delay is disregarded and instead all written buffers will be appended right after the previous one has been exhausted. To get the current sample offset in the "sync" write mode, you can use the ``` .getSyncWriteOffset() ``` method.
67
68Beware of writing zero-length buffers, as they will induce NaNs to your buffers. This can be a bad thing especially if written in the "sync" mode and combined with some effects processing in a callback.
69
70Proxy
71------
72
73[proxy]:
74
75`Proxy` is a thin-wrapper around the basic sink, allowing you to control the size of the buffer received by the callback.
76
77To create a proxy, use the following function:
78
79```
80
81var proxy = Sink.createProxy([bufferSize=4096])
82
83```
84
85For example, to play back a 440Hz sine wave in stereo, you can do :
86
87```javascript
88var bufferSize = 4096, sink = Sink();
89var proxy = sink.createProxy(bufferSize);
90proxy.on('audioprocess', function(buffer, channelCount){
91 for (var j=0; j<bufferSize; j+=2, n++) {
92 v = Math.sin(k*n);
93 buffer[j] = v;
94 buffer[j+1] = v;
95 }
96});
97```
98
99Recording
100-----------
101
102Recording can be done by creating an instance of the recording, like this:
103
104```javascript
105
106var recording = sink.record();
107
108// And when you want to stop recording:
109
110recording.stop();
111
112// To join the recording into a single buffer:
113
114var buffer = recording.join();
115
116```
117
118Ring buffer
119-------------
120
121Here's an example how to use the ring buffer:
122
123```javascript
124
125// Enable & create the ring buffer
126
127sink.ringBuffer = new Float32Array(sink.sampleRate * sink.channelCount);
128
129// Get or modify the current offset of the ring buffer.
130
131console.log(sink.ringOffset);
132
133```
134
135That would create a ring buffer of the length of a single second, and you can manipulate that anyway you want, and use it together with callbacks and / or writing.
136
137Projects using sink.js
138----------------------
139
140* [aurora.js](https://github.com/jensnockert/aurora.js) A JS-powered video and audio playback framework.
141* [Audiolet](https://github.com/oampo/Audiolet) A comphrehensive, graph based audio synthesis / composition library for JS.
142* [audiolib.js](https://github.com/jussi-kalliokoski/audiolib.js) A full-fletched audio synthesis / processing framework.
143
144License
145-------
146
147sink.js is released under MIT license.
Note: See TracBrowser for help on using the repository browser.