aboutsummaryrefslogtreecommitdiff
path: root/files
diff options
context:
space:
mode:
Diffstat (limited to 'files')
-rw-r--r--files/ko/web/api/web_audio_api/advanced_techniques/index.html272
1 files changed, 136 insertions, 136 deletions
diff --git a/files/ko/web/api/web_audio_api/advanced_techniques/index.html b/files/ko/web/api/web_audio_api/advanced_techniques/index.html
index d3ce7cd56d..215536d836 100644
--- a/files/ko/web/api/web_audio_api/advanced_techniques/index.html
+++ b/files/ko/web/api/web_audio_api/advanced_techniques/index.html
@@ -1,5 +1,5 @@
---
-title: 'Advanced techniques: Creating and sequencing audio'
+title: '고급 기법: 오디오 생성 및 시퀸싱'
slug: Web/API/Web_Audio_API/Advanced_techniques
tags:
- API
@@ -12,91 +12,91 @@ tags:
---
<div>{{DefaultAPISidebar("Web Audio API")}}</div>
-<p class="summary">In this tutorial, we're going to cover sound creation and modification, as well as timing and scheduling. We're going to introduce sample loading, envelopes, filters, wavetables, and frequency modulation. If you're familiar with these terms and you're looking for an introduction to their application within with the Web Audio API, you've come to the right place.</p>
+<p class="summary">이 자습서에서, 우리는 사운드 생성과 수정 뿐만 아니라, 타이밍과 스케쥴링도 다룰 것입니다. 우리는 샘플 로딩, 엔벨로프, 필터, 웨이브 테이블, 주파수 조정을 소개할 것입니다. 만약 여러분이 이 용어들에 익숙하고 Web Audio API 내에서의 이것들의 응용에 대한 입문을 찾고 있다면, 맞는 장소에 오셨습니다.</p>
-<h2 id="Demo">Demo</h2>
+<h2 id="Demo">데모</h2>
-<p>We're going to be looking at a very simple step sequencer:</p>
+<p>우리는 아주 간단한 스텝 시퀸서를 살펴볼 것입니다:</p>
-<p><img alt="A sound sequencer application featuring play and BPM master controls, and 4 different voices with controls for each." src="sequencer.png"><br>
+<p><img alt="재생과 BPM 주 제어, 각각을 제어할 수 있는 4가지의 다른 소리를 기능으로 가지는 사운드 시퀸서 애플리케이션." src="sequencer.png"><br>
 </p>
-<p>In practice this is easier to do with a library — the Web Audio API was built to be built upon. If you are about to embark on building something more complex, <a href="https://tonejs.github.io/">tone.js</a> would be a good place to start. However, we want to demonstrate how to build such a demo from first principles, as a learning exercise.</p>
+<p>실제로는 이것은 라이브러리로 하는 것이 더 쉽습니다 — Web Audio API는 기반이 되도록 개발되었습니다. 만약 여러분이 무언가 더욱 복잡한 것의 개발에 착수하려고 한다면, <a href="https://tonejs.github.io/">tone.js</a>가 시작하기 좋은 지점일 것입니다. 그러나, 학습 예제로서, 우리는 이런 데모를 기본 원칙들으로부터 어떻게 개발하는지를 보이고 싶습니다.</p>
<div class="note">
-<p><strong>Note</strong>: You can find the source code on GitHub as <a href="https://github.com/mdn/webaudio-examples/tree/master/step-sequencer">step-sequencer</a>; see the <a href="https://mdn.github.io/webaudio-examples/step-sequencer/">step-sequencer running live</a> also.</p>
+<p><strong>참고</strong>: 여러분은 <a href="https://github.com/mdn/webaudio-examples/tree/master/step-sequencer">step-sequencer</a> 소스 코드를 GitHub에서 찾을 수 있습니다; <a href="https://mdn.github.io/webaudio-examples/step-sequencer/">step-sequencer 작동 예제</a>도 확인해 보세요.</p>
</div>
-<p>The interface consists of master controls, which allow us to play/stop the sequencer, and adjust the BPM (beats per minute) to speed up or slow down the "music".</p>
+<p>인터페이스는 시퀸서를 재생/정지할 수 있게 하는 주 제어 버튼, 그리고 "음악"의 속도를 올리거나 내릴 수 있게 하는 BPM (beats per minute) 조절 슬라이더로 이루어져 있습니다.</p>
-<p>There are four different sounds, or voices, which can be played. Each voice has four buttons, which represent four beats in one bar of music. When they are enabled the note will sound. When the instrument plays, it will move across this set of beats and loop the bar.</p>
+<p>재생될 수 있는 네 가지의 다른 음, 또는 소리가 있습니다. 각 소리는 네 개의 버튼을 가지고 있는데, 이는 음악의 한 마디에 있는 네 개의 비트를 나타냅니다. 이것들이 활성화되었을 때 노트는 소리를 낼 것입니다. 악기가 재생될 때, 이것은 이 비트들의 세트를 가로질러 이동하고 마디를 반복할 것입니다.</p>
-<p>Each voice also has local controls, which allow you to manipulate the effects or parameters particular to each technique we are using to create those voices. The techniques we are using are:</p>
+<p>각 소리들은 또한 해당 소리를 수정할 수 있는 슬라이더를 가지고 있는데, 이는 이펙트나 우리가 이 소리들을 만들기 위해 사용한 각 기법의 특정한 매개변수를 조작할 수 있게 해 줍니다. 우리가 사용하는 이 기법들은:</p>
<table class="standard-table">
<thead>
<tr>
- <th scope="col">Name of voice</th>
- <th scope="col">Technique</th>
- <th scope="col">Associated Web Audio API feature</th>
+ <th scope="col">소리의 이름</th>
+ <th scope="col">기법</th>
+ <th scope="col">연관된 Web Audio API 기능</th>
</tr>
</thead>
<tbody>
<tr>
- <td>"Sweep"</td>
- <td>Oscillator, periodic wave</td>
+ <td>"스윕"</td>
+ <td>오실레이터, 주기파</td>
<td>{{domxref("OscillatorNode")}}, {{domxref("PeriodicWave")}}</td>
</tr>
<tr>
- <td>"Pulse"</td>
- <td>Multiple oscillators</td>
+ <td>"펄스"</td>
+ <td>다수의 오실레이터</td>
<td>{{domxref("OscillatorNode")}}</td>
</tr>
<tr>
- <td>"Noise"</td>
- <td>Random noise buffer, Biquad filter</td>
+ <td>"노이즈"</td>
+ <td>무작위 노이즈 버퍼, 바이쿼드 필터</td>
<td>{{domxref("AudioBuffer")}}, {{domxref("AudioBufferSourceNode")}}, {{domxref("BiquadFilterNode")}}</td>
</tr>
<tr>
- <td>"Dial up"</td>
- <td>Loading a sound sample to play</td>
+ <td>"다이얼 음"</td>
+ <td>재생할 사운드 샘플 로딩하기</td>
<td>{{domxref("BaseAudioContext/decodeAudioData")}}, {{domxref("AudioBufferSourceNode")}}</td>
</tr>
</tbody>
</table>
<div class="note">
-<p><strong>Note</strong>: This instrument was not created to sound good, it was created to provide demonstration code and represents a <em>very</em> simplified version of such an instrument. The sounds are based on a dial-up modem. If you are unaware of how one sounds you can <a href="https://soundcloud.com/john-pemberton/modem-dialup">listen to one here</a>.</p>
+<p><strong>참고</strong>: 이 악기는 좋은 소리를 내기 위해 만들어지지 않았습니다. 이것은 데모 코드를 제공하기 위해 만들어졌고 이런 악기의 <strong>아주</strong> 단순화된 버전을 나타냅니다. 이 소리들은 다이얼 접속 모뎀에 기반합니다. 만약 여러분이 이것이 어떤 소리인지 모른다면 <a href="https://soundcloud.com/john-pemberton/modem-dialup">여기서 들어볼 수 있습니다.</a></p>
</div>
-<h2 id="Creating_an_audio_context">Creating an audio context</h2>
+<h2 id="Creating_an_audio_context">오디오 컨텍스트 생성하기</h2>
-<p>As you should be used to by now, each Web Audio API app starts with an audio context:</p>
+<p>지금쯤은 이미 익숙할지도 모르지만, 각 Web Audio API 앱은 오디오 컨텍스트로 시작합니다:</p>
-<pre class="brush: js">// for cross browser compatibility
+<pre class="brush: js">// 크로스 브라우저 호환성을 위해
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioCtx = new AudioContext();</pre>
-<h2 id="The_sweep_—_oscillators_periodic_waves_and_envelopes">The "sweep" — oscillators, periodic waves, and envelopes</h2>
+<h2 id="The_sweep_—_oscillators_periodic_waves_and_envelopes">"스윕" — 오실레이터, 주기파, 엔벨로프</h2>
-<p>For what we will call the "sweep" sound, that first noise you hear when you dial up, we're going to create an oscillator to generate the sound.</p>
+<p>여러분이 접속할 때 처음 듣는 노이즈인 우리가 "스윕" 소리라고 부를 것에 대해서, 우리는 소리를 생성하기 위해 오실레이터를 생성할 것입니다.</p>
-<p>The {{domxref("OscillatorNode")}} comes with basic waveforms out of the box — sine, square, triangle or sawtooth. However, instead of using the standard waves that come by default, we're going to create our own using the {{domxref("PeriodicWave")}} interface and values set in a wavetable. We can use the {{domxref("BaseAudioContext.createPeriodicWave")}} method to use this custom wave with an oscillator.</p>
+<p>{{domxref("OscillatorNode")}}에는 바로 사용할 수 있는 기본 파형 — 사인파, 사각파, 삼각파, 톱니파 — 이 딸려 있습니다. 그러나, 기본으로 딸린 표준 파동을 사용하는 대신, 우리는 {{domxref("PeriodicWave")}} 인터페이스와 웨이브 테이블에 설정된 값들을 이용해 우리만의 소리를 만들 것입니다. 우리는 오실레이터로 이 사용자 정의 파동을 만들기 위해 {{domxref("BaseAudioContext.createPeriodicWave")}} 메서드를 사용할 수 있습니다.</p>
-<h3 id="The_periodic_wave">The periodic wave</h3>
+<h3 id="The_periodic_wave">주기파</h3>
-<p>First of all, we'll create our periodic wave. To do so, We need to pass real and imaginary values into the {{domxref("BaseAudioContext.createPeriodicWave()")}} method.:</p>
+<p>우선, 우리는 주기파를 생성합니다. 이렇게 하기 위해서는, 우리는 {{domxref("BaseAudioContext.createPeriodicWave()")}} 메서드에 real과 imaginary 값을 전달할 필요가 있습니다:</p>
<pre class="brush: js">const wave = audioCtx.createPeriodicWave(wavetable.real, wavetable.imag);
</pre>
<div class="note">
-<p><strong>Note</strong>: In our example the wavetable is held in a separate JavaScript file (<code>wavetable.js</code>), because there are <em>so</em> many values. It is taken from a <a href="https://github.com/GoogleChromeLabs/web-audio-samples/tree/main/archive/demos/wave-tables">repository of wavetables</a>, which can be found in the <a href="https://github.com/GoogleChromeLabs/web-audio-samples/">Web Audio API examples from Google Chrome Labs</a>.</p>
+<p><strong>참고</strong>: 우리의 예제에서 웨이브 테이블은 별도의 JavaScript 파일 (<code>wavetable.js</code>) 에 저장되어 있는데, 왜냐하면 <strong>아주</strong> 많은 값들이 있기 때문입니다. 이것은 <a href="https://github.com/GoogleChromeLabs/web-audio-samples/">Google Chrome Labs으로부터의 Web Audio API 예제들</a>에서 찾을 수 있는 <a href="https://github.com/GoogleChromeLabs/web-audio-samples/tree/main/archive/demos/wave-tables">웨이브 테이블 레포지토리</a>에서 가져온 것입니다.</p>
</div>
-<h3 id="The_Oscillator">The Oscillator</h3>
+<h3 id="The_Oscillator">오실레이터</h3>
-<p>Now we can create an {{domxref("OscillatorNode")}} and set its wave to the one we've created:</p>
+<p>이제 우리는 {{domxref("OscillatorNode")}}를 생성하고 우리가 생성한 것에 이것의 파동을 설정합니다.</p>
<pre class="brush: js">function playSweep(time) {
const osc = audioCtx.createOscillator();
@@ -107,13 +107,13 @@ const audioCtx = new AudioContext();</pre>
osc.stop(time + 1);
}</pre>
-<p>We pass in a time parameter to the function here, which we'll use later to schedule the sweep.</p>
+<p>여기서 우리는 시간 매개변수를 함수에 전달하는데, 이는 우리가 나중에 스윕을 스케쥴하기 위해서 사용할 것입니다.</p>
-<h3 id="Controlling_amplitude">Controlling amplitude</h3>
+<h3 id="Controlling_amplitude">진폭 제어하기</h3>
-<p>This is great, but wouldn't it be nice if we had an amplitude envelope to go with it? Let's create a simple one so we get used to the methods we need to create an envelope with the Web Audio API.</p>
+<p>이것은 훌륭하지만, 만약 우리가 이것에 적용되는 진폭 엔벨로프를 가지고 있다면 멋지지 않을까요? Web Audio API로 엔벨로프를 생성하기 위해 필요한 메서드들에 익숙해지도록 간단한 것을 생성해 봅시다.</p>
-<p>Let's say our envelope has attack and release. We can allow the user to control these using <a href="/en-US/docs/Web/HTML/Element/input/range">range inputs</a> on the interface:</p>
+<p>우리의 엔벨로프가 attack과 release를 가지고 있다고 해 봅시다. 우리는 사용자가 이것들을 인터페이스의 <a href="/ko/docs/Web/HTML/Element/input/range">range 입력</a>를 사용하여 제어할 수 있도록 할 수 있습니다.</p>
<pre class="brush: html">&lt;label for="attack"&gt;Attack&lt;/label&gt;
&lt;input name="attack" id="attack" type="range" min="0" max="1" value="0.2" step="0.1" /&gt;
@@ -121,7 +121,7 @@ const audioCtx = new AudioContext();</pre>
&lt;label for="release"&gt;Release&lt;/label&gt;
&lt;input name="release" id="release" type="range" min="0" max="1" value="0.5" step="0.1" /&gt;</pre>
-<p>Now we can create some variables over in JavaScript and have them change when the input values are updated:</p>
+<p>이제 우리는 JavaScript에서 몇 가지 변수들을 생성하고 입력 값들이 업데이트되었을 때 바뀌도록 할 수 있습니다:</p>
<pre class="brush: js">let attackTime = 0.2;
const attackControl = document.querySelector('#attack');
@@ -135,13 +135,13 @@ releaseControl.addEventListener('input', function() {
releaseTime = Number(this.value);
}, false);</pre>
-<h3 id="The_final_playSweep_function">The final playSweep() function</h3>
+<h3 id="The_final_playSweep_function">최종 playSweep() 함수</h3>
-<p>Now we can expand our <code>playSweep()</code> function. We need to add a {{domxref("GainNode")}} and connect that through our audio graph to actually apply amplitude variations to our sound. The gain node has one property: <code>gain</code>, which is of type {{domxref("AudioParam")}}.</p>
+<p>이제 우리는 우리의 <code>playSweep()</code> 함수를 확장할 수 있습니다. 우리는 {{domxref("GainNode")}}를 추가하고 실제로 진폭 변화를 소리에 적용하기 위하여 우리의 오디오 그래프를 통해 이 노드를 연결할 필요가 있습니다. gain 노드는 하나의 속성 <code>gain</code> 을 가지고 있는데, 이는 {{domxref("AudioParam")}} 유형입니다.</p>
-<p>This is really useful — now we can start to harness the power of the audio param methods on the gain value. We can set a value at a certain time, or we can change it <em>over</em> time with methods such as {{domxref("AudioParam.linearRampToValueAtTime")}}.</p>
+<p>이것은 정말로 유용합니다 — 이제 우리는 gain 값에 audio param 메서드의 힘을 사용할 수 있습니다. 우리는 특정한 시간에 값을 설정할 수 있거나, {{domxref("AudioParam.linearRampToValueAtTime")}}과 같은 메서드로 시간에 <strong>따라</strong> 이것을 변화시킬 수 있습니다.</p>
-<p>For our attack and release, we'll use the <code>linearRampToValueAtTime</code> method as mentioned above. It takes two parameters — the value you want to set the parameter you are changing to (in this case the gain) and when you want to do this. In our case <em>when</em> is controlled by our inputs. So in the example below the gain is being increased to 1, at a linear rate, over the time the attack range input has been set to. Similarly, for our release, the gain is being set to 0, at a linear rate, over the time the release input has been set to.</p>
+<p>우리의 attack과 release에 대해, 우리는 위에서 언급된 <code>linearRampToValueAtTime</code> 메서드를 사용할 것입니다. 이것은 두 개의 매개변수를 취합니다 — 변화시키고 있는 매개변수에 설정하기 원하는 값 (이 경우 gain) 그리고 언제 이것을 하고 싶은지. 우리의 경우 <strong>언제</strong>는 우리의 입력에 의해 제어됩니다. 그래서 아래의 예제에서 gain은 attack 범위 입력이 설정된 시간에 따라 선형 비율로 1까지 증가됩니다. 비슷하게 release의 경우, release 입력이 설정된 시간에 걸쳐 선형 비율로 gain은 0으로 설정됩니다.</p>
<pre class="brush: js">let sweepLength = 2;
function playSweep(time) {
@@ -152,9 +152,9 @@ function playSweep(time) {
let sweepEnv = audioCtx.createGain();
sweepEnv.gain.cancelScheduledValues(time);
sweepEnv.gain.setValueAtTime(0, time);
- // set our attack
+ // attack을 설정합니다
sweepEnv.gain.linearRampToValueAtTime(1, time + attackTime);
-  // set our release
+  // release를 설정합니다
sweepEnv.gain.linearRampToValueAtTime(0, time + sweepLength - releaseTime);
osc.connect(sweepEnv).connect(audioCtx.destination);
@@ -162,34 +162,34 @@ function playSweep(time) {
osc.stop(time + sweepLength);
}</pre>
-<h2 id="The_pulse_—_low_frequency_oscillator_modulation">The "pulse" — low frequency oscillator modulation</h2>
+<h2 id="The_pulse_—_low_frequency_oscillator_modulation">"펄스" — 낮은 주파수 오실레이터 조정</h2>
-<p>Great, now we've got our sweep! Let's move on and take a look at that nice pulse sound. We can achieve this with a basic oscillator, modulated with a second oscillator.</p>
+<p>훌륭합니다, 이제 우리는 스윕을 가지고 있습니다! 계속해서 이 멋진 펄스 사운드에도 관심을 기울여 봅시다. 우리는 이것을 두 번째 오실레이터에 의해 조정되는 기본적인 오실레이터로 달성할 수 있습니다.</p>
-<h3 id="Initial_oscillator">Initial oscillator</h3>
+<h3 id="Initial_oscillator">첫 오실레이터</h3>
-<p>We'll set up our first {{domxref("OscillatorNode")}} the same way as our sweep sound, except we won't use a wavetable to set a bespoke wave — we'll just use the default <code>sine</code> wave:</p>
+<p>우리가 맞춤형 파동을 설정하기 위해 웨이브 테이블을 사용하지 않을 것이라는 점을 제외하고, 우리는 스윕 사운드에 한 것과 같은 방식으로 첫번째 {{domxref("OscillatorNode")}}를 설정합니다 — 우리는 단지 기본 <code>sine</code>파를 사용할 것입니다:</p>
<pre class="brush: js">const osc = audioCtx.createOscillator();
osc.type = 'sine';
osc.frequency.value = 880;</pre>
-<p>Now we're going to create a {{domxref("GainNode")}}, as it's the <code>gain</code> value that we will oscillate with our second, low frequency oscillator:</p>
+<p>우리가 두 번째 저주파 오실레이터로 진동시킬 것은 gain 값이므로, 이제 우리는 {{domxref("GainNode")}}를 만들 것입니다.</p>
<pre class="brush: js">const amp = audioCtx.createGain();
amp.gain.setValueAtTime(1, audioCtx.currentTime);</pre>
-<h3 id="Creating_the_second_low_frequency_oscillator">Creating the second, low frequency, oscillator</h3>
+<h3 id="Creating_the_second_low_frequency_oscillator">두 번째 저주파 오실레이터 생성하기</h3>
-<p>We'll now create a second — <code>square</code> — wave (or pulse) oscillator, to alter the amplification of our first sine wave:</p>
+<p>첫 번째 사인파의 진폭을 변경하기 위해 우리는 이제 두 번째 — <code>square</code> — 파 (또는 펄스) 오실레이터를 생성할 것입니다:</p>
<pre class="brush: js">const lfo = audioCtx.createOscillator();
lfo.type = 'square';
lfo.frequency.value = 30;</pre>
-<h3 id="Connecting_the_graph">Connecting the graph</h3>
+<h3 id="Connecting_the_graph">그래프 연결하기</h3>
-<p>The key here is connecting the graph correctly, and also starting both oscillators:</p>
+<p>여기서 중요한 점은 그래프를 옳게 연결하는 것이고, 더불어 두 개의 오실레이터를 모두 시작시키는 것입니다:</p>
<pre class="brush: js">lfo.connect(amp.gain);
osc.connect(amp).connect(audioCtx.destination);
@@ -198,19 +198,19 @@ osc.start(time);
osc.stop(time + pulseTime);</pre>
<div class="note">
-<p><strong>Note</strong>: We also don't have to use the default wave types for either of these oscillators we're creating — we could use a wavetable and the periodic wave method as we did before. There is a multitude of possibilities with just a minimum of nodes.</p>
+<p><strong>참고</strong>: 우리는 또한 우리가 생성하는 이 오실레이터 중 어느 것에 대해서도 기본 파동 유형을 사용할 필요가 없습니다 — 우리는 웨이브 테이블과 우리가 전에 한 것처럼 주기파를 사용할 수 있습니다. 최소한의 노드들로도 다수의 가능성이 있습니다.</p>
</div>
-<h3 id="Pulse_user_controls">Pulse user controls</h3>
+<h3 id="Pulse_user_controls">펄스 슬라이더</h3>
-<p>For the UI controls, let's expose both frequencies of our oscillators, allowing them to be controlled via range inputs. One will change the tone and the other will change how the pulse modulates the first wave:</p>
+<p>UI 제어에 대해, 오실레이터의 두 주파수들이 range 입력을 통해 제어될 수 있도록 모두 노출합시다. 하나는 음색을 변경할 것이고 나머지 하나는 어떻게 펄스가 첫번째 파동을 조정하는지를 변경할 것입니다.</p>
<pre class="brush: html">&lt;label for="hz"&gt;Hz&lt;/label&gt;
&lt;input name="hz" id="hz" type="range" min="660" max="1320" value="880" step="1" /&gt;
&lt;label for="lfo"&gt;LFO&lt;/label&gt;
&lt;input name="lfo" id="lfo" type="range" min="20" max="40" value="30" step="1" /&gt;</pre>
-<p>As before, we'll vary the parameters when the range input values are changed by the user.</p>
+<p>이전처럼, 우리는 range 입력 값이 사용자에 의해 변화되었을 때 매개변수에 변화를 줄 것입니다.</p>
<pre class="brush: js">let pulseHz = 880;
const hzControl = document.querySelector('#hz');
@@ -224,9 +224,9 @@ lfoControl.addEventListener('input', function() {
lfoHz = Number(this.value);
}, false);</pre>
-<h3 id="The_final_playPulse_function">The final playPulse() function</h3>
+<h3 id="The_final_playPulse_function">최종 playPulse() 함수</h3>
-<p>Here's the entire <code>playPulse()</code> function:</p>
+<p>여기 전체 <code>playPulse()</code> 함수가 있습니다:</p>
<pre class="brush: js">let pulseTime = 1;
function playPulse(time) {
@@ -248,66 +248,66 @@ function playPulse(time) {
osc.stop(time + pulseTime);
}</pre>
-<h2 id="The_noise_—_random_noise_buffer_with_biquad_filter">The "noise" — random noise buffer with biquad filter</h2>
+<h2 id="The_noise_—_random_noise_buffer_with_biquad_filter">"노이즈" — 바이쿼드 필터와 함께하는 무작위 노이즈 버퍼</h2>
-<p>Now we need to make some noise! All modems have noise. Noise is just random numbers when it comes to audio data, so is, therefore, a relatively straightforward thing to create with code.</p>
+<p>이제 우리는 노이즈를 만들 필요가 있습니다! 모든 모뎀은 노이즈를 가지고 있습니다. 노이즈는 오디오 데이터에 관한 한 단지 무작위 숫자들이므로, 코드로 생성하기 비교적 간단한 것입니다.</p>
-<h3 id="Creating_an_audio_buffer">Creating an audio buffer</h3>
+<h3 id="Creating_an_audio_buffer">오디오 버퍼 생성하기</h3>
-<p>We need to create an empty container to put these numbers into, however, one that the Web Audio API understands. This is where {{domxref("AudioBuffer")}} objects come in. You can fetch a file and decode it into a buffer (we'll get to that later on in the tutorial), or you can create an empty buffer and fill it with your own data.</p>
+<p>우리는 이 값들을 넣을 빈 컨테이너를 만들 필요가 있지만, 이것은 Web Audio API가 이해하는 것이어야 합니다. 여기서 {{domxref("AudioBuffer")}} 객체가 등장합니다. 여러분은 파일을 가지고 와서 버퍼 안에 디코드하거나 (자습서에서 나중에 시작할 것입니다), 또는 여러분은 빈 버퍼를 만들고 여러분만의 데이터로 채울 수 있습니다.</p>
-<p>For noise, let's do the latter. We first need to calculate the size of our buffer, to create it. We can use the {{domxref("BaseAudioContext.sampleRate")}} property for this:</p>
+<p>노이즈에 대해, 후자를 선택합시다. 우리는 버퍼를 만들기 위해 버퍼의 크기를 계산할 필요가 있습니다. 우리는 이것을 위해 {{domxref("BaseAudioContext.sampleRate")}} 속성을 사용할 수 있습니다:</p>
<pre class="brush: js">const bufferSize = audioCtx.sampleRate * noiseLength;
const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);</pre>
-<p>Now we can fill it with random numbers between -1 and 1:</p>
+<p>이제 우리는 이것을 -1과 1 사이의 랜덤 값으로 채울 수 있습니다.</p>
-<pre class="brush: js">let data = buffer.getChannelData(0); // get data
+<pre class="brush: js">let data = buffer.getChannelData(0); // 데이터 얻기
-// fill the buffer with noise
+// 버퍼를 노이즈로 채우기
for (let i = 0; i &lt; bufferSize; i++) {
data[i] = Math.random() * 2 - 1;
}</pre>
<div class="note">
-<p><strong>Note</strong>: Why -1 to 1? When outputting sound to a file or speakers we need to have a number to represent 0db full scale — the numerical limit of the fixed point media or DAC. In floating point audio, 1 is a convenient number to map to "full scale" for mathematical operations on signals, so oscillators, noise generators and other sound sources typically output bipolar signals in the range -1 to 1. A browser will clamp values outside this range.</p>
+<p><strong>참고</strong>: 왜 -1에서 1인가요? 파일이나 스피커에 사운드를 출력할 때 우리는 0db 풀 스케일을 표현하기 위해 하나의 숫자를 가질 필요가 있습니다 — 고정점 미디어나 DAC의 숫자로 나타낸 한도입니다. 부동점 오디오에서, 1은 신호에 대한 수학적 연산을 위한 "풀 스케일"을 매핑하는 편리한 숫자입니다. 그래서 오실레이터, 노이즈 생성기, 그리고 다른 음원은 보통 -1에서 1 범위에서 쌍극(bipolar) 신호를 출력합니다. 브라우저는 이 범위 바깥의 값들을 고정시킬 것입니다.</p>
</div>
-<h3 id="Creating_a_buffer_source">Creating a buffer source</h3>
+<h3 id="Creating_a_buffer_source">버퍼 소스 생성하기</h3>
-<p>Now we have the audio buffer and have filled it with data, we need a node to add to our graph that can use the buffer as a source. We'll create a {{domxref("AudioBufferSourceNode")}} for this, and pass in the data we've created:</p>
+<p>이제 우리는 오디오 버퍼를 가지고 있고 이것을 데이터로 채웠으니, 우리는 소스로서 버퍼를 사용할 수 있는 그래프에 추가할 노드가 필요합니다. 우리는 이것을 위해 {{domxref("AudioBufferSourceNode")}}를 생성하고, 우리가 생성한 데이터를 전달할 것입니다:</p>
<pre class="brush: js">let noise = audioCtx.createBufferSource();
noise.buffer = buffer;</pre>
-<p>If we connect this through our audio graph and play it —</p>
+<p>만약 우리가 이것을 오디오 그래프를 통해 연결시키고 재생한다면 —</p>
<pre class="brush: js">noise.connect(audioCtx.destination);
noise.start();</pre>
-<p>you'll notice that it's pretty hissy or tinny. We've created white noise, that's how it should be. Our values are running from -1 to 1, which means we have peaks of all frequencies, which in turn is actually quite dramatic and piercing. We <em>could</em> modify the function to run values from 0.5 to -0.5 or similar to take the peaks off and reduce the discomfort, however, where's the fun in that? Let's route the noise we've created through a filter.</p>
+<p>여러분은 이것이 꽤 쉭쉭하는 소리가 나거나 금속성의 소리가 나는 것을 인지하였을 것입니다. 우리는 백색소음을 만들었고, 백색소음이라면 그래야만 합니다. 값은 -1과 1 사이에서 실행되는데, 이는 우리가 모든 주파수의 피크를 가지고 있고, 결국 실제로 꽤 찢어지는 듯한 소리가 난다는 것을 의미합니다. 우리는 이 함수가 0.5에서 -0.5에서 실행되거나 피크를 내려 불편함을 줄이는 유사한 작업을 하도록 수정<strong>할 수 있는데</strong>, 그렇게 하면 재미가 없죠? 우리가 생성한 노이즈가 필터를 통과하도록 전송합시다.</p>
-<h3 id="Adding_a_biquad_filter_to_the_mix">Adding a biquad filter to the mix</h3>
+<h3 id="Adding_a_biquad_filter_to_the_mix">믹스에 바이쿼드 필터 추가하기</h3>
-<p>We want something in the range of pink or brown noise. We want to cut off those high frequencies and possibly some of the lower ones. Let's pick a bandpass biquad filter for the job.</p>
+<p>우리는 분홍색 또는 갈색 소음의 범위에 있는 무언가를 원합니다. 우리는 저 높은 주파수들과 아마 몇몇 낮은 것들을 잘라내기를 원합니다. 이 일을 위해 밴드패스 바이쿼드 필터를 도입합시다.</p>
<div class="note">
-<p><strong>Note</strong>: The Web Audio API comes with two types of filter nodes: {{domxref("BiquadFilterNode")}} and {{domxref("IIRFilterNode")}}. For the most part a biquad filter will be good enough — it comes with different types such as lowpass, highpass, and bandpass. If you're looking to do something more bespoke, however, the IIR filter might be a good option — see <a href="/en-US/docs/Web/API/Web_Audio_API/Using_IIR_filters">Using IIR filters</a> for more information.</p>
+<p><strong>참고</strong>: Web Audio API는 두 종류의 필터 노드를 가지고 있습니다: {{domxref("BiquadFilterNode")}}와 {{domxref("IIRFilterNode")}}입니다. 대부분의 경우 바이쿼드 필터는 충분히 좋습니다 — 이것은 로우패스, 하이패스, 밴드패스와 같은 다른 종류의 필터들을 가지고 있습니다. 그러나 만약 여러분이 좀 더 맞춤형의 무언가를 찾고 있다면, IIR 필터가 좋은 옵션일 수 있습니다 — 더 많은 정보가 필요하시다면 <a href="/ko/docs/Web/API/Web_Audio_API/Using_IIR_filters">IIR 필터 사용하기</a>를 참고해 보세요.</p>
</div>
-<p>Wiring this up is the same as we've seen before. We create the {{domxref("BiquadFilterNode")}}, configure the properties we want for it and connect it through our graph. Different types of biquad filters have different properties — for instance setting the frequency on a bandpass type adjusts the middle frequency, however on a lowpass it would set the top frequency.</p>
+<p>이것을 연결하는 것은 우리가 전에 본 것과 같습니다. 우리는 {{domxref("BiquadFilterNode")}}를 생성하고, 원하는 속성들을 설정하고 그래프를 통해 연결시킵니다. 바이쿼드 필터의 다른 유형들은 다른 속성들을 가지고 있습니다 — 예를 들자면 밴드패스 유형에 주파수를 설정하는 것은 중앙 주파수를 조정하는데, 로우패스에서 이것은 위쪽 주파수를 설정할 것입니다.</p>
<pre class="brush: js">let bandpass = audioCtx.createBiquadFilter();
bandpass.type = 'bandpass';
bandpass.frequency.value = 1000;
-// connect our graph
+// 그래프 연결하기
noise.connect(bandpass).connect(audioCtx.destination);</pre>
-<h3 id="Noise_user_controls">Noise user controls</h3>
+<h3 id="Noise_user_controls">노이즈 슬라이더</h3>
-<p>On the UI we'll expose the noise duration and the frequency we want to band, allowing the user to adjust them via range inputs and event handlers just like in previous sections:</p>
+<p>UI에서 우리는 사용자가 range 입력과 지난 섹션에서처럼의 이벤트 처리기를 통해 노이즈 지속과 우리가 밴드하기를 원하는 주파수를 조정할 수 있도록 이것들을 노출시킬 것입니다.</p>
<pre class="brush: html">&lt;label for="duration"&gt;Duration&lt;/label&gt;
&lt;input name="duration" id="duration" type="range" min="0" max="2" value="1" step="0.1" /&gt;
@@ -328,21 +328,21 @@ bandControl.addEventListener('input', function() {
bandHz = Number(this.value);
}, false);</pre>
-<h3 id="The_final_playNoise_function">The final playNoise() function</h3>
+<h3 id="The_final_playNoise_function">최종 playNoise() 함수</h3>
-<p>Here's the entire <code>playNoise()</code> function:</p>
+<p>여기 전체 <code>playNoise()</code> 함수가 있습니다:</p>
<pre class="brush: js">function playNoise(time) {
- const bufferSize = audioCtx.sampleRate * noiseDuration; // set the time of the note
- const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate); // create an empty buffer
+ const bufferSize = audioCtx.sampleRate * noiseDuration; // 노트의 시간을 설정합니다
+ const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate); // 빈 버퍼를 생성합니다
let data = buffer.getChannelData(0); // get data
- // fill the buffer with noise
+ // 버퍼를 노이즈로 채웁니다
for (let i = 0; i &lt; bufferSize; i++) {
data[i] = Math.random() * 2 - 1;
}
- // create a buffer source for our created data
+ // 생성된 데이터에 대해 버퍼 소스 생성하기
let noise = audioCtx.createBufferSource();
noise.buffer = buffer;
@@ -350,18 +350,18 @@ bandControl.addEventListener('input', function() {
bandpass.type = 'bandpass';
bandpass.frequency.value = bandHz;
- // connect our graph
+ // 그래프 연결하기
noise.connect(bandpass).connect(audioCtx.destination);
noise.start(time);
}</pre>
-<h2 id="Dial_up_—_loading_a_sound_sample">"Dial up" — loading a sound sample</h2>
+<h2 id="Dial_up_—_loading_a_sound_sample">"다이얼 음" — 사운드 샘플 로딩하기</h2>
-<p>It's straightforward enough to emulate phone dial (DTMF) sounds, by playing a couple of oscillators together using the methods we've already looked at, however, in this section, we'll load in a sample file instead so we can take a look at what's involved.</p>
+<p>이미 살펴본 메서드들을 사용해 두 개의 오실레이터를 함께 재생함으로써 휴대폰 다이얼 (DTMF) 소리를 모방하는 것은 충분히 간단하지만, 이 섹션에서, 우리는 무엇이 관여되어 있는지를 살펴볼 수 있도록 대신 샘플 파일을 로드할 것입니다.</p>
-<h3 id="Loading_the_sample">Loading the sample</h3>
+<h3 id="Loading_the_sample">샘플 로딩하기</h3>
-<p>We want to make sure our file has loaded and been decoded into a buffer before we use it, so let's create an <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/async_function">async</a></code> function to allow us to do this:</p>
+<p>우리가 파일을 사용하기 전에 파일이 로드되었고 버퍼 안으로 디코드되었음을 확실히 하기를 원하므로, 이를 하기 위해서 <code><a href="/ko/docs/Web/JavaScript/Reference/Statements/async_function">async</a></code> 함수를 생성합시다.</p>
<pre class="brush: js">async function getFile(audioContext, filepath) {
const response = await fetch(filepath);
@@ -370,9 +370,9 @@ bandControl.addEventListener('input', function() {
return audioBuffer;
}</pre>
-<p>We can then use the <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/await">await</a></code> operator when calling this function, which ensures that we can only run subsequent code when it has finished executing.</p>
+<p>그리고 나서 이 함수를 호출할 때 우리는 <code><a href="/ko/docs/Web/JavaScript/Reference/Operators/await">await</a></code> 연산자를 사용할 수 있는데, 이는 이것이 실행을 마쳤을 때 오직 우리가 차후의 코드를 실행할 수 있다는 것을 보장합니다.</p>
-<p>Let's create another <code>async</code> function to set up the sample — we can combine the two async functions in a nice promise pattern to perform further actions when this file is loaded and buffered:</p>
+<p>샘플을 설정하기 위해 또 다른 <code>async</code> 함수를 생성합시다 — 이 파일이 로드되고 버퍼된 후의 동작을 수행하기 위해 우리는 두 개의 async 함수를 멋진 프로미스 패턴으로 결합할 수 있습니다:</p>
<pre class="brush: js">async function setupSample() {
const filePath = 'dtmf.mp3';
@@ -381,22 +381,22 @@ bandControl.addEventListener('input', function() {
}</pre>
<div class="note">
-<p><strong>Note</strong>: You can easily modify the above function to take an array of files and loop over them to load more than one sample. This would be very handy for more complex instruments, or gaming.</p>
+<p><strong>참고</strong>: 파일의 배열을 취해서 하나 이상의 샘플의 로드를 반복하기 위해 여러분은 쉽게 위의 함수를 수정할 수 있습니다. 이것은 더욱 복잡한 악기나, 게이밍에 대해 매우 유용할 것입니다.</p>
</div>
-<p>We can now use <code>setupSample()</code> like so:</p>
+<p>이제 우리는 <code>setupSample()</code>을 다음과 같이 사용할 수 있습니다:</p>
<pre class="brush: js">setupSample()
.then((sample) =&gt; {
- // sample is our buffered file
+ // 샘플은 우리의 버퍼된 파일입니다
// ...
});</pre>
-<p>When the sample is ready to play, the program sets up the UI so it is ready to go.</p>
+<p>샘플이 재생할 준비가 되었을 때, 프로그램을 UI를 설정하므로 이것은 실행될 준비가 됩니다.</p>
-<h3 id="Playing_the_sample">Playing the sample</h3>
+<h3 id="Playing_the_sample">샘플 재생하기</h3>
-<p>Let's create a <code>playSample()</code> function in a similar manner to how we did with the other sounds. This time it will create an {{domxref("AudioBufferSourceNode")}}, and put the buffer data we've fetched and decoded into it, and play it:</p>
+<p>우리가 다른 소리들에 대해 한 것과 비슷한 방법으로 <code>playSample()</code> 함수를 생성해 봅시다. 이번엔 이것은 {{domxref("AudioBufferSourceNode")}}를 생성하고, 우리가 가져온 버퍼 데이터를 넣고 내부에서 디코드하고, 재생할 것입니다:</p>
<pre class="brush: js">function playSample(audioContext, audioBuffer, time) {
const sampleSource = audioContext.createBufferSource();
@@ -407,12 +407,12 @@ bandControl.addEventListener('input', function() {
}</pre>
<div class="note">
-<p><strong>Note</strong>: We can call <code>stop()</code> on an {{domxref("AudioBufferSourceNode")}}, however, this will happen automatically when the sample has finished playing.</p>
+<p><strong>참고</strong>: 우리는 {{domxref("AudioBufferSourceNode")}}의 <code>stop()</code>을 호출할 수 있지만, 이것은 샘플이 재생을 마쳤을 때 자동적으로 발생할 것입니다.</p>
</div>
-<h3 id="Dial-up_user_controls">Dial-up user controls</h3>
+<h3 id="Dial-up_user_controls">다이얼 음 슬라이더</h3>
-<p>The {{domxref("AudioBufferSourceNode")}} comes with a <code><a href="/en-US/docs/Web/API/AudioBufferSourceNode/playbackRate">playbackRate</a></code> property. Let's expose that to our UI, so we can speed up and slow down our sample. We'll do that in the same sort of way as before:</p>
+<p>{{domxref("AudioBufferSourceNode")}}는 <code><a href="/ko/docs/Web/API/AudioBufferSourceNode/playbackRate">playbackRate</a></code> 속성을 가지고 있습니다. 우리가 샘플의 속도를 올리고 내릴 수 있도록, 이것을 UI에 드러내 봅시다. 우리는 이전에 한 것과 같은 종류의 방법으로 이것을 할 것입니다:</p>
<pre class="brush: html">&lt;label for="rate"&gt;Rate&lt;/label&gt;
&lt;input name="rate" id="rate" type="range" min="0.1" max="2" value="1" step="0.1" /&gt;</pre>
@@ -423,9 +423,9 @@ rateControl.addEventListener('input', function() {
playbackRate = Number(this.value);
}, false);</pre>
-<h3 id="The_final_playSample_function">The final playSample() function</h3>
+<h3 id="The_final_playSample_function">최종 playSample() 함수</h3>
-<p>We'll then add a line to update the <code>playbackRate</code> property to our <code>playSample()</code> function. The final version looks like this:</p>
+<p>그리고 나서 우리는 <code>playbackRate</code> 속성을 <code>playSample()</code> 함수에 업데이트하기 위한 라인을 추가할 것입니다. 최종 버전은 다음과 같습니다:</p>
<pre class="brush: js">function playSample(audioContext, audioBuffer, time) {
const sampleSource = audioContext.createBufferSource();
@@ -437,20 +437,20 @@ rateControl.addEventListener('input', function() {
}</pre>
<div class="note">
-<p><strong>Note</strong>: The sound file was <a href="http://soundbible.com/1573-DTMF-Tones.html">sourced from soundbible.com</a>.</p>
+<p><strong>참고</strong>: 이 사운드 파일의 출처는 <a href="https://soundbible.com/1573-DTMF-Tones.html">soundbible.com</a>입니다.</p>
</div>
-<h2 id="Playing_the_audio_in_time">Playing the audio in time</h2>
+<h2 id="Playing_the_audio_in_time">시간에 맞춰 오디오 재생하기</h2>
-<p>A common problem with digital audio applications is getting the sounds to play in time so that the beat remains consistent, and things do not slip out of time.</p>
+<p>디지털 오디오 애플리케이션의 일반적인 문제는 사운드를 비트가 일정하게 유지되고, 시간에서 벗어나지 않도록, 제 시간에 재생하는 것입니다.</p>
-<p>We could schedule our voices to play within a <code>for</code> loop, however the biggest problem with this is updating whilst it is playing, and we've already implemented UI controls to do so. Also, it would be really nice to consider an instrument-wide BPM control. The best way to get our voices to play on the beat is to create a scheduling system, whereby we look ahead at when the notes are going to play and push them into a queue. We can start them at a precise time with the currentTime property and also take into account any changes.</p>
+<p>우리는 <code>for</code> 반복문 내에서 소리가 재생되도록 스케쥴할 수 있지만, 이것의 가장 큰 문제는 이것이 재생되는 도중에 업데이트되고, 우리는 이미 이것을 하기 위한 UI를 구현했다는 것입니다. 또한, 악기 전체의 BPM 슬라이더를 고려하는 것은 정말 좋을 것입니다. 비트에 맞춰 소리를 재생시키는 가장 좋은 방법은 우리가 노드가 언제 재생될지 내다보고 그것들을 큐에 넣는 스케쥴링 시스템을 만드는 것입니다. 우리는 currentTime 속성으로 정밀한 시간에서 이것들을 시작시킬 수 있고 또한 어떠한 변화도 고려할 수 있습니다.</p>
<div class="note">
-<p><strong>Note</strong>: This is a much stripped down version of <a href="https://www.html5rocks.com/en/tutorials/audio/scheduling/">Chris Wilson's A Tale Of Two Clocks</a> article, which goes into this method in much more detail. There's no point repeating it all here, but it's highly recommended to read this article and use this method. Much of the code here is taken from his <a href="https://github.com/cwilso/metronome/blob/master/js/metronome.js">metronome example</a>, which he references in the article.</p>
+<p><strong>참고</strong>: 이것은 <a href="https://www.html5rocks.com/en/tutorials/audio/scheduling/">Chris Wilson의 A Tale Of Two Clocks</a> 글의 가장 기본적인 것만 남긴 버전인데, 저 글은 이 방법을 더욱 자세하게 다룹니다. 이것을 모두 여기서 반복할 필요는 없지만, 저 글을 읽고 이 방법을 사용하는 것을 대단히 추천합니다. 여기서의 대부분의 코드는 그의 <a href="https://github.com/cwilso/metronome/blob/master/js/metronome.js">메트로놈 예제</a>에서 가져온 것인데, 이 예제는 그가 저 글에서 언급했습니다.</p>
</div>
-<p>Let's start by setting up our default BPM (beats per minute), which will also be user-controllable via — you guessed it — another range input.</p>
+<p>또한 — 추측하셨다시피 — 유저가 또 다른 range 입력을 통해 제어할 수 있는 기본 BPM (beats per minute)을 설정하면서 시작해 봅시다.</p>
<pre class="brush: js">let tempo = 60.0;
const bpmControl = document.querySelector('#bpm');
@@ -458,35 +458,35 @@ bpmControl.addEventListener('input', function() {
tempo = Number(this.value);
}, false);</pre>
-<p>Then we'll create variables to define how far ahead we want to look, and how far ahead we want to schedule:</p>
+<p>그리고 나서 우리는 얼마나 미리 우리가 내다보기를 원하는지, 그리고 얼마나 미리 우리가 스케쥴하기를 원하는지를 정의하는 변수를 생성할 것입니다:</p>
-<pre class="brush: js">const lookahead = 25.0; // How frequently to call scheduling function (in milliseconds)
-const scheduleAheadTime = 0.1; // How far ahead to schedule audio (sec)</pre>
+<pre class="brush: js">const lookahead = 25.0; // 얼마나 자주 스케쥴링 함수를 호출할 것인지 (밀리세컨드로)
+const scheduleAheadTime = 0.1; // 얼마나 미리 오디오를 스케쥴할지 (초)</pre>
-<p>Let's create a function that moves the note forwards by one beat, and loops back to the first when it reaches the 4th (last) one:</p>
+<p>한 박마다 노트를 앞으로 이동시키고, 박자가 4번째 (마지막)에 도달했을 때 첫번째로 반복해 돌아오는 함수를 생성해 봅시다:</p>
<pre class="brush: js">let currentNote = 0;
-let nextNoteTime = 0.0; // when the next note is due.
+let nextNoteTime = 0.0; // 다음 노트가 예정되어 있을 때
function nextNote() {
const secondsPerBeat = 60.0 / tempo;
- nextNoteTime += secondsPerBeat; // Add beat length to last beat time
+ nextNoteTime += secondsPerBeat; // 박자 시간을 유지하기 위해 비트 길이를 추가
- // Advance the beat number, wrap to zero
+ // 박자 숫자를 진행시키고, 0으로 만듭니다
currentNote++;
if (currentNote === 4) {
currentNote = 0;
}
}</pre>
-<p>We want to create a reference queue for the notes that are to be played, and the functionality to play them using the functions we've previously created:</p>
+<p>우리는 재생될 노트에 대한 참조 큐와, 이전에 우리가 만든 함수들을 사용해 그것들을 재생할 기능을 만들기를 원합니다:</p>
<pre class="brush: js">const notesInQueue = [];
function scheduleNote(beatNumber, time) {
- // push the note on the queue, even if we're not playing.
+ // 우리가 재생 중이 아닐지라도, 노트를 큐에 푸시합니다.
notesInQueue.push({ note: beatNumber, time: time });
if (pads[0].querySelectorAll('button')[beatNumber].getAttribute('aria-checked') === 'true') {
@@ -503,12 +503,12 @@ function scheduleNote(beatNumber, time) {
}
}</pre>
-<p>Here we look at the current time and compare it to the time for the next note; when the two match it will call the previous two functions.</p>
+<p>여기서 우리는 현재 시간을 보고 다음 노트에 대한 시간과 비교합니다; 두 개가 일치할 때 이것은 이전의 두 함수를 호출할 것입니다.</p>
-<p>{{domxref("AudioContext")}} object instances have a <code><a href="/en-US/docs/Web/API/BaseAudioContext/currentTime">currentTime</a></code> property, which allows us to retrieve the number of seconds after we first created the context. This is what we shall use for timing within our step sequencer — It's extremely accurate, returning a float value accurate to about 15 decimal places.</p>
+<p>{{domxref("AudioContext")}} 객체 인스턴스는 <code><a href="/en-US/docs/Web/API/BaseAudioContext/currentTime">currentTime</a></code> 속성을 가지고 있는데, 이는 우리가 처음 컨텍스트를 생성한 이후의 초를 얻을 수 있게 합니다. 이것은 우리가 우리의 스텝 시퀸서 내에서 타이밍을 위해 사용해야만 하는 것입니다 — 약 소수 15자리까지의 정확한 float 값을 반환하는 이것은 극도로 정확합니다.</p>
<pre class="brush: js">function scheduler() {
- // while there are notes that will need to play before the next interval, schedule them and advance the pointer.
+ // 다음 구간 전에 재생할 필요가 있을 노트가 있는 동안, 그것들을 스케쥴하고 포인터를 진행시킵니다.
while (nextNoteTime &lt; audioCtx.currentTime + scheduleAheadTime ) {
scheduleNote(currentNote, nextNoteTime);
nextNote();
@@ -516,7 +516,7 @@ function scheduleNote(beatNumber, time) {
timerID = window.setTimeout(scheduler, lookahead);
}</pre>
-<p>We also need a draw function to update the UI, so we can see when the beat progresses.</p>
+<p>언제 비트가 진행하는지를 볼 수 있도록 우리는 또한 UI를 업데이트할 그리기 함수가 필요합니다.</p>
<pre class="brush: js">let lastNoteDrawn = 3;
@@ -526,10 +526,10 @@ function draw() {
while (notesInQueue.length &amp;&amp; notesInQueue[0].time &lt; currentTime) {
drawNote = notesInQueue[0].note;
- notesInQueue.splice(0,1); // remove note from queue
+ notesInQueue.splice(0,1); // 노트를 큐에서 제거합니다
}
- // We only need to draw if the note has moved.
+ // 우리는 오직 노트가 이동되었을 경우 그릴 필요가 있습니다.
if (lastNoteDrawn != drawNote) {
pads.forEach(function(el, i) {
el.children[lastNoteDrawn].style.borderColor = 'hsla(0, 0%, 10%, 1)';
@@ -538,38 +538,38 @@ function draw() {
lastNoteDrawn = drawNote;
}
- // set up to draw again
+ // 다시 그리기 위해 설정됨
requestAnimationFrame(draw);
}</pre>
-<h2 id="Putting_it_all_together">Putting it all together</h2>
+<h2 id="Putting_it_all_together">종합하기</h2>
-<p>Now all that's left to do is make sure we've loaded the sample before we are able to <em>play</em> the instrument. We'll add a loading screen that disappears when the file has been fetched and decoded, then we can allow the scheduler to start using the play button click event.</p>
+<p>이제 남은 것은 우리가 악기를 <strong>재생</strong>할 수 있기 전에 샘플이 로드된 것을 확실히 하는 것입니다. 우리는 파일이 가져와지고 디코드되었을 때 사라지는 로딩 스크린을 추가할 것이고, 그리고 나서 우리는 재생 버튼 클릭 이벤트를 사용해 스케쥴러가 시작되도록 할 수 있습니다.</p>
-<pre class="brush: js">// when the sample has loaded allow play
+<pre class="brush: js">// 로드된 샘플이 재생을 허용했을 때
let loadingEl = document.querySelector('.loading');
const playButton = document.querySelector('[data-playing]');
let isPlaying = false;
setupSample()
.then((sample) =&gt; {
- loadingEl.style.display = 'none'; // remove loading screen
+ loadingEl.style.display = 'none'; // 로딩 스크린 제거
- dtmf = sample; // to be used in our playSample function
+ dtmf = sample; // 우리의 playSample 함수에서 사용될 것임
playButton.addEventListener('click', function() {
isPlaying = !isPlaying;
- if (isPlaying) { // start playing
+ if (isPlaying) { // 재생 시작
- // check if context is in suspended state (autoplay policy)
+ // 컨텍스트가 연기(suspended) 상태인지 확인 (자동 재생 정책)
if (audioCtx.state === 'suspended') {
audioCtx.resume();
}
currentNote = 0;
nextNoteTime = audioCtx.currentTime;
- scheduler(); // kick off scheduling
- requestAnimationFrame(draw); // start the drawing loop.
+ scheduler(); // 스케쥴링 시작
+ requestAnimationFrame(draw); // 드로잉 루프 시작.
this.dataset.playing = 'true';
} else {
@@ -581,6 +581,6 @@ setupSample()
})
});</pre>
-<h2 id="Summary">Summary</h2>
+<h2 id="Summary">요약</h2>
-<p>We've now got an instrument inside our browser! Keep playing and experimenting — you can expand on any of these techniques to create something much more elaborate.</p>
+<p>우리는 이제 브라우저 안에 악기를 가지고 있습니다! 계속 재생하고 실험해 보세요 — 여러분은 무언가 더욱 복잡한 것을 만들기 위해 이 모든 기법을 확장할 수 있습니다.</p>