4 Tests that AudioBufferSourceNode can playback at different rates properly.
5 Render 60 notes over a 5 octave range.
10 <script type=
"text/javascript" src=
"resources/audio-testing.js"></script>
11 <script type=
"text/javascript" src=
"resources/buffer-loader.js"></script>
20 var sampleRate
= 44100.0;
21 var numberOfNotes
= 60; // play over a 5 octave range
22 var noteDuration
= 0.025;
23 var noteSpacing
= noteDuration
+ 0.005; // leave 5ms of silence between each "note"
24 var lengthInSeconds
= numberOfNotes
* noteSpacing
;
27 var sinWaveBuffer
= 0;
29 function createOneCycleSinWaveBuffer(frequency
, sampleRate
) {
30 var duration
= 1 / frequency
;
31 var sampleFrameLength
= duration
* sampleRate
;
33 var audioBuffer
= context
.createBuffer(2, sampleFrameLength
, sampleRate
);
35 var n
= audioBuffer
.length
;
36 var channelL
= audioBuffer
.getChannelData(0);
37 var channelR
= audioBuffer
.getChannelData(1);
39 for (var i
= 0; i
< n
; ++i
) {
40 channelL
[i
] = Math
.sin(frequency
* 2.0*Math
.PI
* i
/ sampleRate
);
41 channelR
[i
] = channelL
[i
];
47 function playNote(time
, duration
, playbackRate
) {
48 var source
= context
.createBufferSource();
49 source
.buffer
= sinWaveBuffer
;
50 source
.playbackRate
.value
= playbackRate
;
52 var gainNode
= context
.createGain();
53 source
.connect(gainNode
);
54 gainNode
.connect(context
.destination
);
56 // Loop and play for the given duration.
59 source
.stop(time
+ duration
);
61 // Apply quick fade-in and fade-out to avoid clicks.
62 gainNode
.gain
.value
= 0;
63 gainNode
.gain
.setValueAtTime(0, time
);
64 gainNode
.gain
.linearRampToValueAtTime(1, time
+ 0.005);
65 gainNode
.gain
.setValueAtTime(1, time
+ duration
- 0.005);
66 gainNode
.gain
.linearRampToValueAtTime(0, time
+ duration
);
70 if (!window
.testRunner
)
73 // Create offline audio context.
74 context
= new OfflineAudioContext(2, sampleRate
* lengthInSeconds
, sampleRate
);
76 // Create a single cycle of a sine wave.
77 // We'll loop this to play notes of a given duration, at a given playback rate.
78 sinWaveBuffer
= createOneCycleSinWaveBuffer(440.0, sampleRate
);
80 // Play 60 notes over a 5 octave range.
81 for (var i
= 0; i
< numberOfNotes
; ++i
) {
82 var time
= i
* noteSpacing
;
84 var semitone
= i
- numberOfNotes
/2; // start three octaves down
86 // Convert from semitone to rate.
87 var playbackRate
= Math
.pow(2, semitone
/ 12);
89 playNote(time
, noteDuration
, playbackRate
);
92 context
.oncomplete
= finishAudioTest
;
93 context
.startRendering();
95 testRunner
.waitUntilDone();