1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
<!doctype html>
<html>
<head>
<title>Test multichannel support.</title>
<style type="text/css">
body {
margin: 2em;
}
.manual-test-ui {
font-family: Arial;
padding: 1em;
border: 1px solid #999;
}
.manual-test-ui button {
padding: 1em;
font-size: 1em;
}
</style>
</head>
<body>
<h1>Test Multichannel Audio Output</h1>
<p>Tests that multichannel audio output (> 8 channels) is working correctly.
This test cannot be run with an offline audio context because it requires
an actual audio hardware with the multichannel capability.</p>
<p>Press "Start Test Tone" to run the test. You should hear an one-second
sine tone from all the available audio output channels from the channel 1
to the last channel.</p>
<p>Note that this test only works on OSX because CoreAudio driver supports
the multichannel streams (more than 2) on a single audio device whereas
other platforms do not.</p>
<p>CRBUG issue: <a href="https://code.google.com/p/chromium/issues/detail?id=424795" target="_blank">
424795</a></p>
<div class="manual-test-ui">
<p>Max Channel Count: <span id="eMaxChannelCount">2</span></p>
<p>Currently playing: <span id="eChannelIndex">NONE</span></p>
<button id="eButton" onclick="startTestTones()">Start Test Tone</button>
</div>
<script type="text/javascript">
// Silent interval between the test tones.
var testToneInterval = 0.1;
// The safe range for the equal loudness of sinusoid is roughly between
// 200 ~ 1000Hz, which is A3(57) ~ C6(84). In this test, the starting
// pitch is 220Hz and the interval is the whole tone. (2 MIDI pitch)
// With 16 speakers, the last test tone will play the MIDI pitch of
// F6(89), which is 1396Hz.
var startMIDIPitch = 57;
var eMaxChannelCount = document.querySelector('#eMaxChannelCount');
var eButton = document.querySelector('#eButton');
var eChannelIndex = document.querySelector('#eChannelIndex');
var context = new AudioContext();
var maxChannelCount = context.destination.maxChannelCount;
// Sets the destination properties for multichannel access.
context.destination.channelCount = maxChannelCount;
context.destination.channelCountMode = 'explicit';
context.destination.channelInterpretation = 'discrete';
// The ChannelMerger for the individual channel access.
var merger = context.createChannelMerger(maxChannelCount);
merger.channelCountMode = 'explicit';
merger.channelInterpretation = 'discrete';
merger.connect(context.destination);
eMaxChannelCount.textContent = maxChannelCount;
// Convert the MIDI pitch to frequency.
function midi2freq(midiPitch) {
return 440 * Math.pow(2, (midiPitch - 69) / 12);
}
// Play a test tone for the specified amount of duration at the channel.
function playTestToneAtChannel(channelIndex, gain, duration) {
var osc = context.createOscillator();
var amp = context.createGain();
osc.connect(amp);
amp.connect(merger, 0, channelIndex);
osc.onended = function () {
var nextChannelIndex = channelIndex + 1;
if (nextChannelIndex < maxChannelCount)
playTestToneAtChannel(nextChannelIndex, gain, duration);
else
endTestTone();
};
// The pitch for each speaker goes up as the channel index increases.
// Note that the interval is 2, whole tone.
osc.frequency.value = midi2freq(startMIDIPitch + channelIndex * 2);
// The channel index starts from 1.
eChannelIndex.textContent = 'Channel #' + (channelIndex + 1);
var now = context.currentTime;
var toneDuration = duration - testToneInterval;
// Add fade in and out to avoid the click noise.
amp.gain.setValueAtTime(0.0, now);
amp.gain.linearRampToValueAtTime(gain, now + toneDuration * 0.1);
amp.gain.setValueAtTime(gain, now + toneDuration * 0.9);
amp.gain.linearRampToValueAtTime(0.0, now + toneDuration);
osc.start(now);
osc.stop(now + duration);
}
// When the button is clicked the button to produce the test sound,
// the button is grayed out so one cannot press again until the tone is
// over. (producing sounds multiple times in a short period time will
// hurt the speaker).
function startTestTones() {
eButton.disabled = true;
// Math.SQRT1_2(=0.707..) is -3dB. This is necessary because 1.0
// amplitude can cause overload/distortion on some speakers.
playTestToneAtChannel(0, Math.SQRT1_2, 1.0);
}
// The button needs to be active back again when the test tone is over.
// The index number in DIV should also be reset.
function endTestTone() {
eButton.disabled = false;
eChannelIndex.textContent = 'NONE';
}
</script>
</body>
</html>
|