Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: third_party/WebKit/ManualTests/webaudio/multichannel-mediastreamdestination.html

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

Powered by Google App Engine
This is Rietveld 408576698