From 8d64d2bcc8735c8741fb4434881cf1f61700b673 Mon Sep 17 00:00:00 2001 From: logicseeker Date: Fri, 22 Oct 2021 12:59:03 +0900 Subject: Translate the below document. Background audio processing using AudioWorklet --- .../web_audio_api/using_audioworklet/index.html | 174 ++++++++++----------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/files/ko/web/api/web_audio_api/using_audioworklet/index.html b/files/ko/web/api/web_audio_api/using_audioworklet/index.html index b103225f09..9d82fbef88 100644 --- a/files/ko/web/api/web_audio_api/using_audioworklet/index.html +++ b/files/ko/web/api/web_audio_api/using_audioworklet/index.html @@ -1,5 +1,5 @@ --- -title: Background audio processing using AudioWorklet +title: AudioWorklet을 사용하는 백그라운드 오디오 프로세싱 slug: Web/API/Web_Audio_API/Using_AudioWorklet tags: - API @@ -16,53 +16,53 @@ tags: ---

{{APIRef("Web Audio API")}}

-

When the Web Audio API was first introduced to browsers, it included the ability to use JavaScript code to create custom audio processors that would be invoked to perform real-time audio manipulations. The drawback to ScriptProcessorNode was simple: it ran on the main thread, thus blocking everything else going on until it completed execution. This was far less than ideal, especially for something that can be as computationally expensive as audio processing.

+

Web Audio API가 처음 브라우저에 소개되었을 때, 이것은 실시간 오디오 조작을 수행하기 위해 호출될 사용자 정의 오디오 프로세서를 생성하기 위해 JavaScript 코드를 사용하는 능력을 포함했습니다. ScriptProcessorNode의 문제점은 간단했습니다: 이것은 메인 스레드 위에서 실행되었으므로, 이것이 실행을 마치기 전까지 모든 것을 막았습니다. 이것은 이상보다 훨씬 못 미쳤습니다. 특히 오디오 프로세싱같이 계산적으로 비용이 많이 들 수 있는 무언가에 대해서 말입니다.

-

Enter {{domxref("AudioWorklet")}}. An audio context's audio worklet is a {{domxref("Worklet")}} which runs off the main thread, executing audio processing code added to it by calling the context's {{domxref("Worklet.addModule", "audioWorklet.addModule()")}} method. Calling addModule() loads the specified JavaScript file, which should contain the implementation of the audio processor. With the processor registered, you can create a new {{domxref("AudioWorkletNode")}} which passes the audio through the processor's code when the node is linked into the chain of audio nodes along with any other audio nodes.

+

{{domxref("AudioWorklet")}}이 도입되었습니다. 오디오 컨텍스트의 오디오 worklet은 메인 스레드에서 떨어져 실행되는 {{domxref("Worklet")}}인데, 이는 컨텍스트의 {{domxref("Worklet.addModule", "audioWorklet.addModule()")}} 메서드를 호출함으로써 이것에 추가된 오디오 프로세싱 코드를 실행합니다. addModule()을 호출하는 것은 명시된 JavaScript 파일을 로드하는데, 이는 오디오 프로세서의 구현을 포함하고 있어야 합니다. 프로세서가 등록된 채로, 여러분은 노드가 다른 오디오 노드들에 덧붙여 오디오 노드의 체인에 연결되었을 때 프로세서의 코드를 통해 오디오를 전달하는 새로운 {{domxref("AudioWorkletNode")}}을 생성할 수 있습니다.

-

The process of creating an audio processor using JavaScript, establishing it as an audio worklet processor, and then using that processor within a Web Audio application is the topic of this article.

+

JavaScript를 사용해 오디오 프로세서를 생성하고, 오디오 worklet 프로세서로서 그것을 임명하고, 그리고 나서 Web Audio 애플리케이션 내에서 그 프로세서를 사용하는 과정이 이 글의 주제입니다.

-

It's worth noting that because audio processing can often involve substantial computation, your processor may benefit greatly from being built using WebAssembly, which brings near-native or fully native performance to web apps. Implementing your audio processing algorithm using WebAssembly can make it perform markedly better.

+

오디오 프로세싱이 종종 상당한 계산을 수반하기 때문에, 여러분의 프로세서는 WebAssembly를 사용하여 개발되는 것으로부터 대단히 이득을 볼 지도 모르는데, 이는 웹 앱에 네이티브에 가깝거나 완전히 네이티브인 성능을 가져다준다는 것에 주목할 가치가 있습니다. WebAssembly를 사용하여 오디오 프로세싱 알고리즘을 구현하는 것은 이것이 현저히 낫게 수행되도록 만들 수 있습니다.

-

High level overview

+

고수준 개요

-

Before we start looking at the use of AudioWorklet on a step-by-step basis, let's start with a brief high-level overview of what's involved.

+

단계적인 기초 위에서 AudioWorklet의 사용을 살펴보기 전에, 무엇이 관련되어 있는지에 대한 간략한 고수준의 개요로 시작합시다.

    -
  1. Create module that defines a audio worklet processor class, based on {{domxref("AudioWorkletProcessor")}} which takes audio from one or more incoming sources, performs its operation on the data, and outputs the resulting audio data.
  2. -
  3. Access the audio context's {{domxref("AudioWorklet")}} through its {{domxref("BaseAudioContext.audioWorklet", "audioWorklet")}} property, and call the audio worklet's {{domxref("Worklet.addModule", "addModule()")}} method to install the audio worklet processor module.
  4. -
  5. As needed, create audio processing nodes by passing the processor's name (which is defined by the module) to the {{domxref("AudioWorkletNode.AudioWorkletNode", "AudioWorkletNode()")}} constructor.
  6. -
  7. Set up any audio parameters the {{domxref("AudioWorkletNode")}} needs, or that you wish to configure. These are defined in the audio worklet processor module.
  8. -
  9. Connect the created AudioWorkletNodes into your audio processing pipeline as you would any other node, then use your audio pipeline as usual.
  10. +
  11. 하나 또는 그 이상의 들어오는 소스로부터 오디오를 취하고, 데이터에서 작업을 수행하고, 결과 오디오 데이터를 출력하는 {{domxref("AudioWorkletProcessor")}}에 기반한 오디오 worklet 프로세서 클래스를 정의하는 모듈을 만듭니다.
  12. +
  13. 오디오 컨텍스트의 {{domxref("BaseAudioContext.audioWorklet", "audioWorklet")}} 속성을 통해 이것의 {{domxref("AudioWorklet")}}에 접근하고, 오디오 worklet 프로세서 모듈을 설치하기 위해서 오디오 worklet의 {{domxref("Worklet.addModule", "addModule()")}} 메서드를 호출합니다.
  14. +
  15. 필요한 대로, (모듈에 의해 정의된) 프로세서의 이름을 {{domxref("AudioWorkletNode.AudioWorkletNode", "AudioWorkletNode()")}} 생성자에 전달함으로써 오디오 프로세싱 노드를 생성합니다.
  16. +
  17. {{domxref("AudioWorkletNode")}}가 필요로 하는, 또는 여러분이 설정하기를 원하는 오디오 매개변수들을 설정합니다. 이것들은 오디오 worklet 프로세서 모듈에 정의되어 있습니다.
  18. +
  19. 생성된 AudioWorkletNode를 다른 노드처럼 오디오 프로세싱 파이프라인에 연결하고, 오디오 파이프라인을 평상시처럼 사용합니다.
-

Throughout the remainder of this article, we'll look at these steps in more detail, with examples (including working examples you can try out on your own).

+

이 글의 나머지 부분까지, 우리는 이 과정들을 (직접 시도해볼 수 있는 작동하는 예제를 포함하는) 예제와 함께 더욱 자세하게 살펴볼 것입니다.

-

The example code found on this page is derived from this working example which is part of MDN's GitHub repository of Web Audio examples. The example creates an oscillator node and adds white noise to it using an {{domxref("AudioWorkletNode")}} before playing the resulting sound out. Slider controls are available to allow controlling the gain of both the oscillator and the audio worklet's output.

+

이 페이지에서 찾을 수 있는 예제 코드는 MDN의 Web Audio 예제의 GitHub 레포지토리의 부분인 이 작동하는 예제에서 왔습니다. 이 예제는 오실레이터 노드를 생성하고 결과 사운드를 발생시키기 전에 {{domxref("AudioWorkletNode")}}를 사용하여 이것에 백색소음을 추가합니다. 슬라이더 조종 장치는 오실레이터와 오디오 worklet의 출력 둘 다의 gain을 제어하기 위해 이용 가능합니다.

-

See the code

+

코드 보기

-

Try it live

+

직접 시도해보기

-

Creating an audio worklet processor

+

오디오 worklet 프로세서 생성하기

-

Fundamentally, an audio worklet processor (which we'll refer to usually as either an "audio processor" or as a "processor" because otherwise this article will be about twice as long) is implemented using a JavaScript module that defines and installs the custom audio processor class.

+

기본적으로, (우리가 보통 "오디오 프로세서" 또는 "프로세서"로 나타낼, 왜냐하면 그렇지 않으면 이 글은 두 배 가량 길어질 것이기 때문에) 오디오 worklet 프로세서는 사용자 정의 오디오 프로세서 클래스를 정의하고 설치하는 JavaScript 모듈을 사용하여 구현됩니다.

-

Structure of an audio worklet processor

+

오디오 worklet 프로세서의 구조

-

An audio worklet processor is a JavaScript module which consists of the following:

+

오디오 worklet 프로세서는 다음을 포함하는 JavaScript 모듈입니다:

-

A single audio worklet processor module may define multiple processor classes, registering each of them with individual calls to registerProcessor(). As long as each has its own unique name, this will work just fine. It's also more efficient than loading multiple modules from over the network or even the user's local disk.

+

하나의 오디오 worklet 프로세서 모듈은 registerProcessor()의 개개의 호출과 함께 다수의 프로세서 클래스를 등록하며 그것들을 정의할 지도 모릅니다. 각각이 고유한 이름을 가지고 있는 한, 이것은 단지 잘 작동할 것입니다. 이것은 또한 다수의 모듈을 네트워크로부터 또는 심지어 사용자의 로컬 디스크로부터 로딩하는 것보다 더욱 효율적입니다.

-

Basic code framework

+

기본 코드 프레임워크

-

The barest framework of an audio processor class looks like this:

+

오디오 프로세서 클래스의 가장 기본적인 프레임워크는 다음과 같습니다:

class MyAudioProcessor extends AudioWorkletProcessor {
   constructor() {
@@ -70,8 +70,8 @@ tags:
   }
 
   process(inputList, outputList, parameters) {
-    /* using the inputs (or not, as needed), write the output
-       into each of the outputs */
+    /* 입력들을 사용하여 (또는 안 사용하여, 필요한 대로),
+       각 출력들에 출력을 작성합니다 */
 
     return true;
   }
@@ -80,41 +80,41 @@ tags:
 registerProcessor("my-audio-processor", MyAudioProcessor);
 
-

After the implementation of the processor comes a call to the global function {{domxref("AudioWorkletGlobalScope.registerProcessor", "registerProcessor()")}}, which is only available within the scope of the audio context's {{domxref("AudioWorklet")}}, which is the invoker of the processor script as a result of your call to {{domxref("Worklet.addModule", "audioWorklet.addModule()")}}. This call to registerProcessor() registers your class as the basis for any {{domxref("AudioWorkletProcessor")}}s created when {{domxref("AudioWorkletNode")}}s are set up.

+

프로세서의 구현 이후에 전역 함수 {{domxref("AudioWorkletGlobalScope.registerProcessor", "registerProcessor()")}}에 대한 호출이 오는데, 이는 오직 오디오 컨텍스트의 {{domxref("AudioWorklet")}}의 스코프 내에서만 이용 가능한데, 이는 {{domxref("Worklet.addModule", "audioWorklet.addModule()")}}에 대한 호출의 결과로써 프로세서 스크립트의 호출자입니다. registerProcessor()에 대한 이 호출은 {{domxref("AudioWorkletNode")}}들이 설정되었을 때, 생성된 모든 {{domxref("AudioWorkletProcessor")}}에 대한 기초로써 여러분의 클래스를 등록합니다.

-

This is the barest framework and actually has no effect until code is added into process() to do something with those inputs and outputs. Which brings us to talking about those inputs and outputs.

+

이것이 가장 기본적인 프레임워크이고 실제로는 코드가 이 입력과 출력을 가지고 무언가를 하기 위해 process()에 추가되기 전까지는 어떠한 영향도 가지지 않습니다. 이는 우리를 이 입력과 출력에 대해 이야기하는 것으로 이끕니다.

-

The input and output lists

+

입력과 출력 리스트

-

The lists of inputs and outputs can be a little confusing at first, even though they're actually very simple once you realize what's going on.

+

비록 입력과 출력 리스트가 여러분이 한 번 무엇이 진행되는지를 깨달으면 실제로는 매우 단순할지라도, 이것들은 처음에는 조금 혼란스러울 수 있습니다.

-

Let's start at the inside and work our way out. Fundamentally, the audio for a single audio channel (such as the left speaker or the subwoofer, for example) is represented as a Float32Array whose values are the individual audio samples. By specification, each block of audio your process() function receives contains 128 frames (that is, 128 samples for each channel), but it is planned that this value will change in the future, and may in fact vary depending on circumstances, so you should always check the array's length rather than assuming a particular size. It is, however, guaranteed that the inputs and outputs will have the same block length.

+

내부에서 시작해 바깥으로 나가 봅시다. 기본적으로, 하나의 오디오 채널에 대한 오디오 (예를 들자면 좌측 스피커나 서브우퍼같은) 는 하나의 Float32Array로써 표현되는데 이것의 값은 개개의 오디오 샘플들입니다. 명세에 의하면, process() 함수가 받는 오디오의 각 블럭은 128 프레임을 포함하고 있지만 (즉, 각 채널에 대해 128 샘플), 이 값이 미래에 바뀔 것이라는 건 예정되어 있고, 사실은 상황에 따라 다양할 지도 모르므로, 여러분은 특정한 크기를 추정하기보다는 항상 배열의 length를 확인해야 합니다. 그러나, 입력과 출력이 같은 블럭 길이를 가질 것이라는 것은 보장됩니다.

-

Each input can have a number of channels. A mono input has a single channel; stereo input has two channels. Surround sound might have six or more channels. So each input is, in turn, an array of channels. That is, an array of Float32Array objects.

+

각각의 입력은 얼마간의 채널을 가지고 있습니다. 모노 입력은 하나의 채널을 가지고 있습니다; 스테레오 입력은 두 개의 채널을 가지고 있습니다. 서라운드 사운드는 여섯 개 혹은 그 이상의 채널을 가지고 있을 지도 모릅니다. 그래서 각각의 입력은, 차례로, 채널의 배열입니다. 즉, Float32Array 객체의 배열입니다.

-

Then, there can be multiple inputs, so the inputList is an array of arrays of Float32Array objects. Each input may have a different number of channels, and each channel has its own array of samples.

+

그렇다면, 다수의 입력이 있을 수 있으므로, inputListFloat32Array 객체들의 배열들의 배열입니다. 각각의 입력은 각각 다른 수의 채널을 가지고 있을 지도 모르고, 각 채널은 채널마다의 샘플의 배열을 가지고 있습니다.

-

Thus, given the input list inputList:

+

따라서, 입력 리스트 inputList가 주어지면:

const numberOfInputs = inputList.length;
 const firstInput = inputList[0];
 
 const firstInputChannelCount = firstInput.length;
-const firstInputFirstChannel = firstInput[0]; // (or inputList[0][0])
+const firstInputFirstChannel = firstInput[0]; // (또는 inputList[0][0])
 
 const firstChannelByteCount = firstInputFirstChannel.length;
-const firstByteOfFirstChannel = firstInputFirstChannel[0]; // (or inputList[0][0][0])
+const firstByteOfFirstChannel = firstInputFirstChannel[0]; // (또는 inputList[0][0][0])
 
-

The output list is structured in exactly the same way; it's an array of outputs, each of which is an array of channels, each of which is an array of Float32Array objects, which contain the samples for that channel.

+

출력 리스트는 정확히 같은 방식으로 구성됩니다; 이것은 출력들의 배열인데, 이것의 각각은 채널들의 배열이고, 이것의 각각은 Float32Array 객체의 배열인데, 이는 그 채널에 대한 샘플을 포함합니다.

-

How you use the inputs and how you generate the outputs depends very much on your processor. If your processor is just a generator, it can ignore the inputs and just replace the contents of the outputs with the generated data. Or you can process each input independently, applying an algorithm to the incoming data on each channel of each input and writing the results into the corresponding outputs' channels (keeping in mind that the number of inputs and outputs may differ, and the channel counts on those inputs and outputs may also differ). Or you can take all the inputs and perform mixing or other computations that result in a single output being filled with data (or all the outputs being filled with the same data).

+

여러분이 어떻게 입력을 사용하고 어떻게 출력을 생성할 것인가는 여러분의 프로세서에 아주 달려 있습니다. 만약 여러분의 프로세서가 단지 생성기라면, 이것은 입력을 무시하고 단지 생성된 데이터로 출력의 내용을 대체할 수 있습니다. 또는 여러분은 각 입력의 각 채널의 들어오는 데이터에 알고리즘을 적용하고 결과를 해당하는 출력의 채널에 작성하며 (입력과 출력의 수는 다를지도 모르고, 채널은 또한 다를지도 모르는 이 입력과 출력에 기대고 있다는 것을 명심하십시오), 각각의 입력을 독립적으로 처리할 수 있습니다. 또는 여러분은 모든 입력을 취해서 믹싱이나 데이터로 채워진 하나의 출력 (또는 같은 데이터로 채워진 모든 출력) 을 낳는 다른 계산을 수행할 수 있습니다.

-

It's entirely up to you. This is a very powerful tool in your audio programming toolkit.

+

이것은 전적으로 여러분에게 달려 있습니다. 이것은 오디오 프로그래밍 툴킷에서 매우 강력한 도구입니다.

-

Processing multiple inputs

+

다수의 입력 처리하기

-

Let's take a look at an implementation of process() that can process multiple inputs, with each input being used to generate the corresponding output. Any excess inputs are ignored.

+

해당하는 출력을 생성하기 위해 사용되는 각 입력과 함께, 다수의 입력을 처리할 수 있는 process()의 구현을 살펴봅시다. 초과되는 입력은 무시됩니다.

process(inputList, outputList, parameters) {
   const sourceLimit = Math.min(inputList.length, outputList.length);
@@ -130,7 +130,7 @@ const firstByteOfFirstChannel = firstInputFirstChannel[0]; // (or inputList[0][0
       for (let i = 0; i < sampleCount; i++) {
         let sample = input[channelNum][i];
 
-        /* Manipulate the sample */
+        /* 샘플 조작하기 */
 
         output[channelNum][i] = sample;
       }
@@ -141,11 +141,11 @@ const firstByteOfFirstChannel = firstInputFirstChannel[0]; // (or inputList[0][0
 }
 
-

Note that when determining the number of sources to process and send through to the corresponding outputs, we use Math.min() to ensure that we only process as many channels as we have room for in the output list. The same check is performed when determining how many channels to process in the current input; we only process as many as there are room for in the destination output. This avoids errors due to overrunning these arrays.

+

해당하는 출력에 보내고 처리하기 위한 소스의 수를 결정할 때, 우리는 우리가 오직 출력 리스트에 있는 방 만큼만 처리한다는 것을 확실히 하기 위해 Math.min()을 사용한다는 것에 주목하십시오. 이것과 같은 확인은 현재 입력에서 얼마나 많은 채널을 처리할 지 결정할 때 수행됩니다; 우리는 오직 목적지 출력에 있는 방 만큼만 처리합니다. 이것은 이 배열들을 초과함에 따른 오류를 방지합니다.

-

Mixing inputs

+

입력 믹싱하기

-

Many nodes perform mixing operations, where the inputs are combined in some way into a single output. This is demonstrated in the following example.

+

많은 노드들은 입력들이 어떤 방법으로 하나의 출력으로 결합되는 믹싱 작업을 수행합니다. 이것은 아래의 예제에서 시연됩니다.

process(inputList, outputList, parameters) {
   const sourceLimit = Math.min(inputList.length, outputList.length);
@@ -175,33 +175,33 @@ const firstByteOfFirstChannel = firstInputFirstChannel[0]; // (or inputList[0][0
 }
 
-

This is similar code to the previous sample in many ways, but only the first output—outputList[0]—is altered. Each sample is added to the corresponding sample in the output buffer, with a simple code fragment in place to prevent the samples from exceeding the legal range of -1.0 to 1.0 by capping the values; there are other ways to avoid clipping that are perhaps less prone to distortion, but this is a simple example that's better than nothing.

+

이것은 많은 방식에서 이전 예제와 비슷한 코드이지만, 오직 첫번째 출력—outputList[0]—이 변경되었습니다. 각각의 샘플은, 값을 덮어씌움으로써 올바른 범위인 -1.0에서 1.0을 초과하는 샘플들을 방지하기 위해 작동하는 간단한 코드 조각과 함께, 출력 버퍼에서 해당하는 샘플에 추가되었습니다; 깎아내기를 방지할 아마도 덜 왜곡될 경향이 있는 다른 방법들이 있지만, 이것은 아무것도 아닌 것 보다는 나은 간단한 예제입니다.

-

Lifetime of an audio worklet processor

+

오디오 worklet 프로세서의 생애

-

The only means by which you can influence the lifespan of your audio worklet processor is through the value returned by process(), which should be a Boolean value indicating whether or not to override the {{Glossary("user agent")}}'s decision-making as to whether or not your node is still in use.

+

여러분이 오디오 worklet 프로세서의 생명에 영향을 줄 유일한 수단은 process()에 의해 반환된 값을 통해서인데, 이는 노드가 여전히 사용되고 있는지 아닌지에 대한 {{Glossary("user agent")}}의 의사 결정을 무시하는지 아닌지를 나타내는 Boolean 값이어야만 합니다.

-

In general, the lifetime policy of any audio node is simple: if the node is still considered to be actively processing audio, it will continue to be used. In the case of an {{domxref("AudioWorkletNode")}}, the node is considered to be active if its process() function returns true and the node is either generating content as a source for audio data, or is receiving data from one or more inputs.

+

일반적으로, 오디오 노드의 생애 정책은 단순합니다: 만약 노드가 여전히 활발히 오디오를 프로세싱하고 있는 것으로 여겨진다면, 이것은 계속 사용될 것입니다. {{domxref("AudioWorkletNode")}}의 경우, 노드는 만약 이것의 process() 함수가 true를 반환하고 그리고 노드가 오디오 데이터에 대한 소스로서 내용을 생성하거나 하나 혹은 그 이상의 입력으로부터 데이터를 받고 있다면 작동 중인 것으로 여겨집니다.

-

Specifying a value of true as the result from your process() function in essence tells the Web Audio API that your processor needs to keep being called even if the API doesn't think there's anything left for you to do. In other words, true overrides the API's logic and gives you control over your processor's lifetime policy, keeping the processor's owning {{domxref("AudioWorkletNode")}} running even when it would otherwise decide to shut down the node.

+

본질적으로 process() 함수로부터의 결과로써 true의 값을 명시한다는 것은 Web Audio API에게 심지어 API가 여러분을 위해 할 것 무언가가 있지 않다고 생각한다 할 지라도 여러분의 프로세서가 계속 호출될 필요가 있다고 말해주는 것입니다. 다른 말로 하자면, true는 API의 논리를 무시하고 여러분의 프로세서의 생애 정책에 대한 제어를 제공하는데, 심지어 이것이 그렇지 않다면 노드를 끄기로 결정할 때 프로세서의 소유 중인 {{domxref("AudioWorkletNode")}} 실행을 유지합니다.

-

Returning false from the process() method tells the API that it should follow its normal logic and shut down your processor node if it deems it appropriate to do so. If the API determines that your node is no longer needed, process() will not be called again.

+

process() 메서드로부터 false를 반환하는 것은 API에게 만약 이것이 그렇게 하는 것이 적절하다고 여겨진다면 이것은 이것의 보통의 논리를 따르고 프로세서 노드를 꺼야 한다고 말해주는 것입니다. 만약 API가 여러분의 노드가 더 이상 필요가 없다고 결정한다면, process()는 다시 호출되지 않을 것입니다.

-

Note: At this time, unfortunately, Chrome does not implement this algorithm in a manner that matches the current standard. Instead, it keeps the node alive if you return true and shuts it down if you return false. Thus for compatibility reasons you must always return true from process(), at least on Chrome. However, once this Chrome issue is fixed, you will want to change this behavior if possible as it may have a slight negative impact on performance.

+

참고: 이 시점에서, 불행하게도, Chrome은 어떤 의미로는 현재 표준에 일치하는 이 알고리즘을 구현하지 않았습니다. 대신, 이것은 만약 여러분이 true를 반환하면 노드를 살려두고 만약 여러분이 false를 반환하면 끕니다. 따라서 호환성의 이유로 적어도 Chrome에서는 여러분은 항상 반드시 process()에서 true를 반환해야 합니다. 그러나, 이 Chrome 이슈가 수정되고 나면, 이것은 성능에 약간 부정적인 영향을 가질지도 모르므로 여러분은 만약 가능하다면 이 동작을 변경하기를 원할 것입니다.

-

Creating an audio processor worklet node

+

오디오 프로세서 worklet 노드 생성하기

-

To create an audio node that pumps blocks of audio data through an {{domxref("AudioWorkletProcessor")}}, you need to follow these simple steps:

+

{{domxref("AudioWorkletProcessor")}}를 통해 오디오 데이터의 블럭을 퍼내는 오디오 노드를 생성하기 위해서는, 여러분은 다음의 간단한 단계를 따를 필요가 있습니다:

    -
  1. Load and install the audio processor module
  2. -
  3. Create an {{domxref("AudioWorkletNode")}}, specifying the audio processor module to use by its name
  4. -
  5. Connect inputs to the AudioWorkletNode and its outputs to appropriate destinations (either other nodes or to the {{domxref("AudioContext")}} object's {{domxref("AudioContext.destination", "destination")}} property.
  6. +
  7. 오디오 프로세서 모듈을 로드하고 설치하기
  8. +
  9. 이름으로 사용하기 위해서 오디오 프로세서 모듈을 명시하며, {{domxref("AudioWorkletNode")}} 생성하기
  10. +
  11. AudioWorkletNode에 입력을 연결하고 이것의 출력을 적절한 목적지 (다른 노드거나 {{domxref("AudioContext")}} 객체의 {{domxref("AudioContext.destination", "destination")}} 속성에 연결합니다.
-

To use an audio worklet processor, you can use code similar to the following:

+

오디오 worklet 프로세서를 사용하기 위해서, 여러분은 다음과 유사한 코드를 사용할 수 있습니다:

let audioContext = null;
 
@@ -220,25 +220,25 @@ async function createMyAudioProcessor() {
 }
 
-

This createMyAudioProcessor() function creates and returns a new instance of {{domxref("AudioWorkletNode")}} configured to use your audio processor. It also handles creating the audio context if it hasn't already been done.

+

createMyAudioProcessor() 함수는 오디오 프로세서를 사용하기 위해 설정된 {{domxref("AudioWorkletNode")}}의 새로운 인스턴스를 생성하고 반환합니다. 이것은 또한 만약 오디오 컨텍스트 생성이 이미 완료되지 않았다면 오디오 컨텍스트 생성을 다룹니다.

-

In order to ensure the context is usable, this starts by creating the context if it's not already available, then adds the module containing the processor to the worklet. Once that's done, it instantiates and returns a new AudioWorkletNode. Once you have that in hand, you connect it to other nodes and otherwise use it just like any other node.

+

컨텍스트가 사용 가능함을 확실히 하기 위해서, 이것은 컨텍스트가 이미 사용 가능하지 않다면 컨텍스트를 생성함으로써 시작하고, 그리고 나서 프로세서를 포함하는 모듈을 worklet에 추가합니다. 이것이 완료되고 나면, 이것은 새로운 AudioWorkletNode를 인스턴스화하고 반환합니다. 완료되고 나면, 여러분은 이것을 다른 노드에 연결하고 그렇지 않다면 이것을 여타 다른 노드들처럼 사용합니다.

-

You can then create a new audio processor node by doing this:

+

여러분은 새로운 오디오 프로세서 노드를 다음을 함으로써 생성할 수 있습니다:

let newProcessorNode = createMyAudioProcessor();
-

If the returned value, newProcessorNode, is non-null, we have a valid audio context with its hiss processor node in place and ready to use.

+

만약 반환된 값 newProcessorNodenull이 아니라면, 우리는 유효한 오디오 컨텍스트를 가지고 있고 사용할 준비가 된 것입니다.

-

Supporting audio parameters

+

오디오 매개변수 지원하기

-

Just like any other Web Audio node, {{domxref("AudioWorkletNode")}} supports parameters, which are shared with the {{domxref("AudioWorkletProcessor")}} that does the actual work.

+

다른 Web Audio 노드들처럼, {{domxref("AudioWorkletNode")}}은 매개변수를 지원하는데, 이는 실제 작업을 하는 {{domxref("AudioWorkletProcessor")}}와 공유됩니다.

-

Adding parameter support to the processor

+

프로세서에 매개변수 지원 추가하기

-

To add parameters to an {{domxref("AudioWorkletNode")}}, you need to define them within your {{domxref("AudioWorkletProcessor")}}-based processor class in your module. This is done by adding the static getter {{domxref("AudioWorkletProcessor.parameterDescriptors", "parameterDescriptors")}} to your class. This function should return an array of {{domxref("AudioParam")}} objects, one for each parameter supported by the processor.

+

{{domxref("AudioWorkletNode")}}에 매개변수를 추가하기 위해서, 여러분은 모듈 내에서 {{domxref("AudioWorkletProcessor")}} 기반의 프로세서 클래스 내에서 그것들을 정의할 필요가 있습니다. 이것은 정적 getter {{domxref("AudioWorkletProcessor.parameterDescriptors", "parameterDescriptors")}}를 클래스에 추가함으로써 완료됩니다. 이 함수는 프로세서에 의해 지원되는 각 파라미터에 대해 {{domxref("AudioParam")}} 객체의 배열을 하나 반환해야 합니다.

-

In the following implementation of parameterDescriptors(), the returned array has two AudioParam objects. The first defines gain as a value between 0 and 1, with a default value of 0.5. The second parameter is named frequency and defaults to 440.0, with a range from 27.5 to 4186.009, inclusively.

+

parameterDescriptors()의 다음의 구현에서, 반환된 배열은 두 개의 AudioParam 객체를 가지고 있습니다. 첫번째는 gain을 기본값은 0.5인 0과 1사이의 값으로 정의했습니다. 두번째 매개변수는 frequency라는 이름이 부여되었고 기본값은 440.0인데, 범위는 전부 통틀어 27.5에서 4186.009까지입니다.

static get parameterDescriptors() {
   return [
@@ -257,16 +257,16 @@ async function createMyAudioProcessor() {
   ];
 }
-

Accessing your processor node's parameters is as simple as looking them up in the parameters object passed into your implementation of {{domxref("AudioWorkletProcessor.process", "process()")}}. Within the parameters object are arrays, one for each of your parameters, and sharing the same names as your parameters.

+

프로세서 노드의 매개변수에 접근하는 것은 {{domxref("AudioWorkletProcessor.process", "process()")}}의 구현에 전달된 parameters 객체에서 그것들을 찾는 것만큼 간단합니다. parameters 객체 내부에 있는 것은 배열인데, 각 매개변수 당 하나이고, 매개변수로서 같은 이름을 공유합니다.

-
A-rate parameters
-
For a-rate parameters—parameters whose values automatically change over time—the parameter's entry in the parameters object is an array of {{domxref("AudioParam")}} objects, one for each frame in the block being processed. These values are to be applied to the corresponding frames.
-
K-rate parameters
-
K-rate parameters, on the other hand, can only change once per block, so the parameter's array has only a single entry. Use that value for every frame in the block.
+
A-rate 매개변수
+
a-rate 매개변수에 대해서—시간에 따라 값이 자동적으로 변하는 매개변수—parameters 객체에서 매개변수의 엔트리는 {{domxref("AudioParam")}} 객체의 배열인데, 이는 처리된 블록에서 각 프레임 당 하나입니다. 이 값들은 해당하는 프레임들에 적용될 것입니다.
+
K-rate 매개변수
+
K-rate 매개변수는, 반면에, 블럭당 한 번만 변할 수 있어서, 매개변수의 배열은 오직 하나의 엔트리를 가집니다. 블럭의 모든 프레임에 대해 이 값을 사용하십시오.
-

In the code below, we see a process() function that handles a gain parameter which can be used as either an a-rate or k-rate parameter. Our node only supports one input, so it just takes the first input in the list, applies the gain to it, and writes the resulting data to the first output's buffer.

+

아래의 코드에서, 우리는 a-rate 또는 k-rate 매개변수로 쓰일 수 있는 gain 매개변수를 다루는 process() 함수를 볼 수 있습니다. 우리의 노드는 오직 하나의 입력만을 지원하므로, 이것은 단지 리스트의 첫번째 입력만을 취하고, gain을 이것에 적용하고, 결과 데이터를 첫번째 출력의 버퍼에 작성합니다.

process(inputList, outputList, parameters) {
   const input = inputList[0];
@@ -277,9 +277,9 @@ async function createMyAudioProcessor() {
     const inputChannel = input[channel];
     const outputChannel = output[channel];
 
-    // If gain.length is 1, it's a k-rate parameter, so apply
-    // the first entry to every frame. Otherwise, apply each
-    // entry to the corresponding frame.
+    // 만약 gain.length가 1이면, 이것은 k-rate 매개변수이므로,
+    // 첫번째 엔트리를 모든 프레임에 적용합니다.
+    // 그렇지 않으면, 각 엔트리를 해당하는 프레임에 적용합니다.
 
     if (gain.length === 1) {
       for (let i = 0; i < inputChannel.length; i++) {
@@ -296,30 +296,30 @@ async function createMyAudioProcessor() {
 }
 
-

Here, if gain.length indicates that there's only a single value in the gain parameter's array of values, the first entry in the array is applied to every frame in the block. Otherwise, for each frame in the block, the corresponding entry in gain[] is applied.

+

여기서, 만약 gain.lengthgain 매개변수의 값들의 배열에 오직 하나의 값만이 있다는 것을 나타내면, 배열의 첫번째 엔트리는 블럭의 모든 프레임에 적용됩니다. 그렇지 않으면, 블럭의 각 프레임에 대해, gain[]의 해당하는 엔트리가 적용됩니다.

-

Accessing parameters from the main thread script

+

메인 스레드 스크립트에서 매개변수 접근하기

-

Your main thread script can access the parameters just like it can any other node. To do so, first you need to get a reference to the parameter by calling the {{domxref("AudioWorkletNode")}}'s {{domxref("AudioWorkletNode.parameters", "parameters")}} property's {{domxref("AudioParamMap.get", "get()")}} method:

+

여러분의 메인 스레드 스크립트는 다른 노드들이 할 수 있는 것과 마찬가지로 매개변수에 접근할 수 있습니다. 이렇게 하기 위해서는, 첫째로 여러분은 {{domxref("AudioWorkletNode")}}의 {{domxref("AudioWorkletNode.parameters", "parameters")}} 속성의 {{domxref("AudioParamMap.get", "get()")}} 메서드를 호출함으로써 매개변수에 대한 참조를 얻을 필요가 있습니다.

let gainParam = myAudioWorkletNode.parameters.get("gain");
 
-

The value returned and stored in gainParam is the {{domxref("AudioParam")}} used to store the gain parameter. You can then change its value effective at a given time using the {{domxref("AudioParam")}} method {{domxref("AudioParam.setValueAtTime", "setValueAtTime()")}}.

+

gainParam에 반환되고 저장된 값은 gain 매개변수를 저장하기 위해 사용된 {{domxref("AudioParam")}}입니다. 여러분은 그리고 나서 {{domxref("AudioParam")}} 메서드 {{domxref("AudioParam.setValueAtTime", "setValueAtTime()")}}을 사용하여 주어진 시간의 값을 효과적으로 바꿀 수 있습니다.

-

Here, for example, we set the value to newValue, effective immediately.

+

예를 들어, 여기서, 우리는 값을 newValue로, 효과적으로 즉시 설정했습니다.

gainParam.setValueAtTime(newValue, audioContext.currentTime);
-

You can similarly use any of the other methods in the {{domxref("AudioParam")}} interface to apply changes over time, to cancel scheduled changes, and so forth.

+

여러분은 유사하게 {{domxref("AudioParam")}} 인터페이스에 있는 다른 메서드를 시간에 따른 변화를 적용하기 위해, 예정된 변화를 취소하기 위해, 그리고 등등을 위해 사용할 수 있습니다.

-

Reading the value of a parameter is as simple as looking at its {{domxref("AudioParam.value", "value")}} property:

+

매개변수의 값을 읽는 것은 {{domxref("AudioParam.value", "value")}} 속성을 보는 것 만큼이나 간단합니다:

let currentGain = gainParam.value;
-

See also

+

같이 보기

-- cgit v1.2.3-54-g00ecf