Shihong Ren
email: renshihong@hotmail.com

Stéphane Letz

Yann Orlarey
email: orlarey@grame.fr

Romain Michon
email: michon@grame.fr

Dominique Fober
email: fober@grame.fr

Michel Buffa

Jerome Lebrun
email: lebrun@i3s.unice.fr

Using Faust DSL to Develop Custom, Sample Accurate DSP Code and Audio Plugins for the Web Browser 1

The development and porting of virtual instruments or audio effects on the Web is a hot topic. Several initiatives are emerging, from industry-driven ones (e.g., Propellerhead Rack Extension running on the Web 2 ), to more community based open-source projects [1]. Most of them aim at adapting existing code bases (usually developed in native languages like C/C++) as well as facilitating the use of existing audio Digital Signal Processing (DSP) languages and platforms. Our two teams previously presented an open format for WebAudio Plugins coined WAP [2]. It aims at: (i) improving the interoperability of audio/MIDI plugins developed using pure Web APIs, (ii) porting existing native code bases, or (iii) using Domain Specific Languages (DSL). In this paper, we present a solution based around FAUST DSL, its Web-based editor, and the integration of a plugin GUI editor allowing to directly test, generate and deploy WAP plugins. We also evoke our collaborative work: one team hatching and improving FAUST, the other working on the recreation of tube guitar amplifiers and pedalboards within Web browsers. So as to fully illustrate the FAUST online framework, a case study is detailed with complete workflow, from the FAUST DSP source code written and tested in a fully functional online editor, to a self-contained plugin running in a separate host application.

Figure 1: the FAUST IDE provides many embedded tools: oscilloscopes, spectroscope and spectrogram analyzer, functional default GUI, schema preview, etc.

1.

INTRODUCTION

There are many ways to develop software with the WebAudio API today. In pure JavaScript, the genish.js environment for instance [3] allows for the development of sample-level audio processing algorithms. [START_REF] Roberts | Strategies for Per-Sample Processing of Audio Graphs in the Browser[END_REF] C/C++ written code can be transpiled to WebAssembly using Emscripten [4] and wrapped by additional JavaScript code to become ready-to-use audio nodes. Domain Specific Languages (DSL) for programming DSP algorithms that also compile to WebAssembly, like the mature Csound [5] with its set of WebAudio examples, [START_REF] Zakai | Emscripten: an LLVM to JavaScript Compiler[END_REF] or the recently announced SOUL DSP language with its playground5 can be used. They all provide a dedicated and usually self-contained working environment.

When audio effects or audio/MIDI instruments have to be shared between several DAWs or audio environments, a plugin model is usually preferred. Several native audio plugin standards are currently available, including Steinberg's VST (Virtual Studio Technology, created in 1997 by Cubase creators), Apple's Audio Units (Logic Audio, GarageBand), Avid's AAX (ProTools creators), and LV2 from the Linux audio community. Although the APIs offered by these formats are different, they share a common goal: to implement instruments or audio effects, and to allow a host application to load them.

In the first years after the birth of WebAudio (2011), there was no standard format for high-level audio plugins. With the emergence of Web-based audio software such as digital audio workstations (DAWs) developed by companies like SoundTrap, BandLab, or AmpedStudio, it became desirable to have a standard to make WebAudio instruments and effects interoperable as plugins compatible with these DAWs, and more generally with any compatible host software.

Such a plugin standard needs to be flexible enough to support these different approaches, including the use of a variety of programming languages. New features made possible by the very nature of the Web platform (e.g., plugins can be remote or local and identified by URIs) should also be available for plugins written in different ways. To this end, some initiatives have been proposed [6,7] and with other groups of researchers and developers we made in 2018 a proposal for a WebAudio plugin standard called WAP (WebAudio Plugins), which includes an API specification, an SDK, online plugin validation tools, and a series of plugin examples written in JavaScript but also with other languages [START_REF] Jillings | Intelligent Audio Plug-in Framework for the Web Audio API[END_REF] .

These examples serve as proof of concept for developers and also illustrate the power of the Web platform: plugins can be discovered from remote repositories, dynamically uploaded to a host WebApp and instantiated, connected together, etc. The project includes examples of very simple plugins and host software, but also more ambitious tools to validate the WAP standard: a virtual guitar "pedalboard" that discovers plugins from several remote repositories, and allows musicians to chain for examplevirtual audio effects pedal plugins, synthesizers, guitar amplifier simulators, drum machines, etc., and to control them via MIDI in real-time (see Fig. 1). [START_REF] Kleimola | Web Audio Modules[END_REF] As of last year, WAP now includes support for pure MIDI plugins (a GM midi synthesizer, virtual midi keyboards, a MIDI event monitoring plugin, etc [START_REF] Choi | WAAX: Web Audio API eXtension[END_REF] ). For more details about the WAP proposal, and how it is related to other approaches like Web Audio Modules (WAMs), WebAudio API eXtension (WAAX) [8], or JavaScript Audio Plugin (JSAP), see [2].

Figure 2: The virtual pedalboard host application scans multiple remote WAP plugin servers. WAP plugins can then be dragged and dropped and assembled in a graph.

This paper is a further extended, fully revamped version of an awarded presentation that was given during the WebAudio Conference 2019 [9]. Our goal is here to highlight and detail some of the results presented, to introduce new perspectives and to flesh out newer developments. For example, the compilation chain of the Faust code on remote servers will be fully characterized and the GUI Builder will have a full section detailing a "practical case" of design with the full recreation of a novel tube guitar amplifiers PowerAmp stage simulation using a Faust approach. Also a complete user evaluation has been conducted and will be detailed with the obtained results analyzed.

In the next sections, we will focus on the new online IDE we developed, that is well suited for coding, testing, and publishing WAP plugins written in FAUST, directly in a Web browser. The IDE includes a graphical interface editor allowing developers to fine-tune the look and feel of the plugins. This editor offers a rich set of widgets that can be controlled by midi-learn. Once complete (DSP + GUI), the plugins are packaged in the form of standard W3C WebComponents and published on remote WAP plugin servers. The plugins will then be directly usable by any compatible host software, using their URLs. You can picture the WAP plugins as images in an HTML document, their URL is sufficient, and can be dynamically retrieved using APIs from a remote Web Service.

BACKGROUND CONTEXT AND TERMS

FAUST [10] is a functional, synchronous, domain specific programming language working at the sample level, designed for real time audio signal processing and synthesis.

FAUST programs can be efficiently compiled to a variety of target programming languages, from C++ to WebAssembly. The FAUST compiler is organized in successive stages, from the DSP block diagram to signals, and finally to the FIR (FAUST Imperative Representation) which is then translated into several target languages. The FIR language describes the computation performed on the audio samples in a generic manner. It contains primitives to read and write variables and arrays, do arithmetic operations, and defines the necessary control structures (e.g., for and while loops, if statements, etc.).

As a specification language, the FAUST code only describes the DSP part, and an abstract version of the control interface. It says nothing about the audio drivers or the GUI toolkit to be used. Architecture files are written (typically in C++ or JavaScript) to describe how to connect the DSP code to the external world.

Additional generic code is added to connect the DSP computation itself with audio inputs/outputs, and with parameter controllers, which could be buttons, sliders, numerical entries, etc. Architectures files can also possibly implement polyphonic support for MIDI-controllable instruments, by automatically dealing with dynamic voice allocation, and decoding and mapping of incoming MIDI events [11].

Several prior developments have been done to use the language on the Web platform. By adding an asm.js9 backend in the compiler, and compiling the compiler itself in asm.js/JavaScript using the Emscripten transpiler, the dynamic generation of WebAudio nodes from FAUST code has been demonstrated [12,13].

With the rise of the more stable and better designed WebAssembly10 format in 2017 (a portable binary-code format for executable programs, firstly to be used on the Web, but also on native environments) as a replacement of asm.js, the previous work done with asm.js was adapted. For the Web platform, two backends have been developed to generate WebAssembly text (so-called "wast" or "wat") and binary formats (so-called "wasm") [14]. When embedded in the FAUST compiler running on the Web, they allow us to dynamically compile FAUST DSP programs as pure Web applications. Additional JavaScript glue code is added to transform DSP modules in fully functional WebAudio nodes.

The node generated by the FAUST compiler can be an AudioWorklet or a ScriptProcessor. These nodes are connectable with other WebAudio nodes to create an audio processing graph, and are designed to allow the development of custom low-level DSP algorithms. The AudioWorklet currently becomes a standard in the WebAudio API as it allows the computation of audio buffers in a dedicated audio thread (different from the "main thread" where the GUI is being executed). An AudioWorklet is composed of a JavaScript wrapper called the AudioWorkletProcessor that communicates with the AudioWorkletNode [15].

FAUST also allows us to circumvent many important limitations of the WebAudio standard, like the buffer size issues, as loops appearing in the graph of connected WebAudio nodes always introduce a delay of at least one buffer (128 samples), and thus one sample delay recursive algorithms cannot be expressed. This limitation was encountered in our previous works on the implementation of feedback loops in the signal chain using pure JavaScript high-level WebAudio nodes. To illustrate how FAUSTbased solutions fulfil this important need for temporally accurate solutions, this practical case study will be detailed in Section 4.

3.

CURRENT STATE

The New FAUST Online Web IDE

The compiler module generated by Emscripten was previously implemented in the FAUST IDE [START_REF] Letz | Polyphony, Sample-accurate Control and MIDI Support for FAUST DSP using Combinable Architecture Files[END_REF] using a JavaScript wrapper which allowed the application to compile and transform FAUST source code into a WebAudio node. We recently restructured this wrapper in order to take advantage of modern JavaScript development environments. An updated toolchain is now used to ensure the efficiency and the compatibility of the wrapper to transform it into another JavaScript UMD [START_REF] Denoux | Composing a Web of Audio Applications[END_REF] module which can be imported and used in either a Webpage's runtime or a JavaScript compiling environment.

The past versions of this wrapper already provided the following features:

• Load WebAssembly version of the FAUST compiler and import its C functions into JavaScript • Compile the code: the input is the FAUST source code, the output is the compiled WebAssembly binary version with some related data • Load and wrap the module as a DSP processing function inside an AudioWorkletProcessor or a ScriptProcessor AudioNode

We added some new features to the module:

• A virtual file system (VFS): Emscripten supports a virtual file system (in memory) compatible with the C++ I/O standard library, but also usable from the JavaScript wrapper. This file system became important as the FAUST compiler searches for libraries and imported source code locally, or generates DSP code for other targets/architectures. For instance, FAUST block diagrams in SVG [START_REF] Letz | Faust Audio DSP Language on the Web[END_REF] format generated as additional files in the compilation process, are simply written on the fly in the VFS, then loaded, decoded, and displayed. • Data output: a callback has been added into the AudioWorklet node to support additional processing or analysis after the buffer has been fully calculated. This callback returns the current output buffer, the current buffer index, and parameters change events.

In addition, to be able to calculate audio separately with a FAUST DSP independent from the browser audio context, we created an "offline processor" which will be used exclusively for getting the very first samples calculated by a DSP. This allows us to debug the DSP code running with a different sample rate. While a DSP developer needs to hear the sound produced by the algorithm, he should also be able to test it with other audio inputs, precisely display its time and frequency domain representation, etc. So, we emerged visualization, testing, and debugging tools such as MIDI/audio input simulation and output recording around the FAUST code editor to provide an integrated environment for DSP designing. This is the reason why we built a new online IDE (see Fig. 1) that provides more information and details on the generated DSP through graphical representation in a Web page (e.g. real-time FAUST block diagram, signal visualizations). [START_REF] Letz | Faust Audio DSP Language on the Web[END_REF] https://www.w3.org/Graphics/SVG/ 14 https://github.com/j-funk/kissfft-js/

The layout is responsive and configurable following the browser viewport dimensions:

• All options related to FAUST code compilation are located using controllers from the left sidebar; • All options and displays related to DSP runtime, such as MIDI, audio inputs, and quick signal probing are placed in the right sidebar; • The remaining central zone of the page is divided into two parts with configurable heights: a source code editor on the top and a multi-tab display panel which can display the logs from the compiler, a FAUST block diagram corresponding to the DSP code, a larger signal scope, a running GUI of the plugin being developed, and finally, a GUI builder/exporter for designing the user interface of the WAP plugin version of the code, usable in external host applications.

Besides UI improvements facilitating code editing and compilation, audio probes are an important addition to the new editor. We designed four modes of signal visualizations to help FAUST users to debug their DSPs: data table, oscilloscope (stacked and interleaved by channels), spectroscope, and spectrogram analyzer (see Fig. 3). To implement all four probe modes, precise sample values are needed. In the browser environment, we have two ways to get audio output samples.

The first approach consists of using WebAudio AnalyserNode with its integrated functions to get the realtime audio data in frequency and time domain: This approach provides both sample values and the spectrum given by the FFT of the current audio buffer. However, it has several drawbacks. First, the AnalyserNode has only one input, which means that it needs an additional ChannelSplitterNode to retrieve the correct channel from the FAUST DSP node. Secondly, as we cannot tell when the AnalyserNode does the analysis, the audio data is provided only on demand. Thus it is impossible to get precise data in a specific buffer calculated by the FAUST DSP.

The second approach consists of getting the sample values directly with a callback in a FAUST DSP node. These values are associated with its buffer index and an event list containing all parameter changes occurring in this buffer. To get the corresponding frequency domain data, an additional FFT is required. We chose the JavaScript version of KissFFT 14 for its high performance when compiled to WebAssembly. [START_REF] Choi | AudioWorklet: The Future of Web Audio[END_REF] Thus, we perform the FFT computation in the FAUST online editor with two overlaps using a Blackman window function.

The first approach is used in the implementation of the two scopes in the right sidebar as it can also probe the audio input. The second approach is used for the larger scope at the bottom. It is more flexible and it can adapt itself to continuous or on-demand signal display. Developers may need to have options to select which part of the signals they want to display: we provide four modes to trigger differently the drawing function of the scopes: Offline, Continuous, On Event, and Manual:

• Offline: FAUST WebAudio wrapper offers an "offline processor" which is useful to allow a DSP to calculate the first samples at any sample rate independently of the actual audio context one. • Continuous: similar to normal audio scopes, this mode draws in real time the most recent samples processed by the FAUST DSP. Parameter change events will be shown in the scope. On a standard personal computer, the editor is able to draw up to 1 million samples continuously without significant rendering lag. • On Event: as the FAUST DSP usually comes with a GUI to control its parameters, it is important to visualize the part of signals while parameters change.

In this mode, the scope draws only when it captures parameter change events, which is useful for debugging. • Manual: in Manual mode, the scope displays the latest samples when a user clicks on a button. After a FAUST DSP is tested in the editor, users can export the DSP to different architectures including WebAudio Plugins (WAPs) which is compiled by an online compiling service (see Fig. 4). A dedicated GUI builder is integrated in the IDE that receives FAUST DSP's GUI definitions while it is compiled. Then, a default GUI is proposed and users can start customizing the GUI, testing the plugin functionalities, and finally publishing the plugin to a remote server. These points are detailed in the next two sections. [START_REF] Buffa | Guitar Pedal Board using WebAudio[END_REF] https://www.gnu.org/software/libmicrohttpd/

3.2

The Remote Compilation Service

In order to export and run FAUST programs outside the Web browser, a Compiler as a Service (CaaS) located at https://faustservicecloud.grame.fr/ has been designed, which can cross-compile executables binaries for most of the platforms supported by FAUST.

The service is accessible via the export button of the editor (see Fig. 4).

The Service API

The dialog between the editor and the remote compilation service is based on a very simple API (Application Programming Interface) of REST (Representational State Transfer) type which is detailed in the Appendix located at the end of this paper.

The first thing the editor does is to ask the server for a list of supported platforms (Windows, macOS, Web, ...) and architectures (VST, Max, ...). This information is needed in order to present possible choices to the user. When the user requests an export for the first time, the FAUST code is sent to the compilation service which will check it, and if it is correct returns an SHA key which will represent the source code for all the following operations.

To trigger the compilation itself, and retrieve the binary code, a URL is dynamically forged by the editor from this SHA key, the platform, and the architecture. If the compilation goes well, a zip folder containing the binary code is downloaded from the server. The server maintains a cache, with a limited lifetime, to avoid unnecessary recompilations of the same code.

Implementation and Deployment

The server is written in C++ and based on libmicrohttpd, [START_REF] Buffa | Guitar Pedal Board using WebAudio[END_REF] a C library from the GNU Foundation allowing us to easily write a simple HTTP server.

It runs in a docker container built on top of Ubuntu 16.04 to which are added all the packages needed to compile and use FAUST, the FAUST distribution itself, all the needed SDKs, and several cross-compilers.

The server is almost exclusively limited to implementing the API we have just described. As for the FAUST compilation itself, it relies on a series of Makefiles, with precise naming conventions to perform all compilation tasks. This makes the service easily extensible just by adding Makefiles (i.e., without the need to modify it).

These Makefiles are organized in a two-level hierarchy, one folder per platform containing all the Makefiles related to that platform. By analyzing this folder hierarchy, the server can respond to the targets request seen above. The makefiles are pretty simple. They rely directly on the compilation tools of the FAUST distribution.

When the POST of a file foo.dsp is processed, the SHA-1 key of the file is first calculated. This key is used as the name of a folder containing all the compilations related to this file. When afterwards a /<sha>/<platform>/<arch>/binary.zip request is processed, it is first converted into a filename: sessions/<sha>/<platform>/<arch>/binary.zip to check if it has not already been generated. If it is not the case, the software will:

• Check that makefiles/<platform>/Makefile.<arch> exists The session folder thus serves as a cache and makes it easy to retrieve the compilation results. It is periodically emptied when the number of sessions becomes too large.

Figure 5: a default GUI is proposed from a FAUST code in the editor.

3.3

The GUI Editor

FAUST code can include abstract definitions of GUI controllers, such as in this source code extract: Here, the code describes the definition of two parameters named "Fuzz" and "Level" along with some data defining the default value, min, max, step, unit type, etc. These parameters can be programmatically set/computed such as "default_level*2" in the second example, instead of using literal values.

As previously explained, the FAUST DSP code is compiled to a JavaScript wrapper and a WebAssembly module. This is all done on the client-side. The GUI builder shares a JavaScript parameter descriptor variable that has been generated after the compilation step and that can be statically interpreted. From this parameter descriptor, a "GUI pivot descriptor" is created and a "default GUI" displayed in the GUI builder (see Fig. 5). It can be filled during the GUI edition process and used to generate the final GUI code (see Fig. 6). So far, we implemented only a generator for WebAudio plugins, using HTML/CSS/JavaScript code that complies with the W3C WebComponents specifications.17 At any time, the plugin (DSP + GUI) can be tested from within the IDE, without having to download it on a local disk. It is then possible to refine the GUI, adjust the layout, appearance of the controllers among a rich set of knobs, sliders, switches (Figs 6, 7 and 9 show different looks and feels that can be created from the same DSP code).

The editor is not yet 100% bijective with the FAUST definition of GUI controllers (that serve as a "hint" to bootstrap the GUI design process). For example, if you change the type of controller (i.e., slider to knob), it does not change the FAUST code back. However, having a way to build and customize a GUI this way is a great time encapsulated HTML/CSS/JS/WASM code without namespace conflicts. See https://www.webcomponents.org. saver, full sync between the FAUST code and GUI is planned as future enhancements.

The plugin can also be published on a remote plugin server, using standard Web services; this is shown in the life cycle workflow from Fig. 8. This allows us to preview it in its "running state" directly in the IDE (see Fig. 9). From this dialog, a WAP plugin generated by the FAUST IDE can also be downloaded as a zipped archive file that contains the DSP WebAssembly module, the standard JSON [START_REF] Buffa | Web Audio Guitar Tube Amplifier vs Native Simulations[END_REF] WAP descriptor and the GUI code (HTML/CSS/JavaScript) wrapped as a WebComponent. It also includes a host HTML page for trying and testing the plugin, making the plugin usable by humans as well as by client applications. In fact, once published on a server, this file is unzipped in a remote directory. The plugin is associated with a "remote URI" and can be dynamically loaded and "unit tested" by different validation tools that come with the WAP SDK [START_REF] Buffa | Real-Time Emulation of a Marshall JCM 800 Guitar Tube Amplifier, Audio FX Pedals, in a Virtual Pedal Board[END_REF] (i.e., checked for compliance of their API to the specification, that the plugin is able to [START_REF] Buffa | Web Audio Guitar Tube Amplifier vs Native Simulations[END_REF] https://www.json.org/json-en.html [START_REF] Buffa | Real-Time Emulation of a Marshall JCM 800 Guitar Tube Amplifier, Audio FX Pedals, in a Virtual Pedal Board[END_REF] Examples/demos of online validators can be tested online, see for example https://jsbin.com/jeretab/edit?js,output.

save/restore its state, etc.), or discovered by host web applications (e.g., DAWs, etc.) One of these hosts is our "virtual pedalboard" Web application [16], a host for WAP plugins we developed to showcase the WAP standard (see Fig. 10), that targets guitar and keyboard players. This application scans remote WAP servers for available plugins and makes them accessible to final users that can drag and drop and assemble them in the main part of the screen. In this example, all virtual pedal effects at the bottom of the screen have been coded and compiled with their GUI designed and tested in the FAUST IDE. [START_REF] Buffa | Emerging W3C APIs opened up Commercial Opportunities for Computer Music Applications[END_REF]

A PRACTICAL USE CASE: MODELING THE POWER AMP STAGE OF A TUBE GUITAR AMP

Since 2015, we have been involved in the design, development and constant improvement of perceptually faithful simulations of existing tube guitar amplifiers like the Marshall JCM 800, used by many famous artists (e.g., AC/DC, Guns and Roses, Deep Purple, etc.), with a major constraint that everything should run within just a webbrowser [17]. Our first versions were developed in pure JavaScript using the W3C WebAudio API and are available to play with. [START_REF] Meseguer-Brocal | WASABI: a Two Million Song Database Project with Audio and Cultural Metadata plus WebAudio enhanced Client Applications[END_REF]

Limitations of the WebAudio API and high-level WebAudio nodes when processing feedback loops

Most tube guitar amplifiers have similar topology: a preamplifier stage, a so-called "tonestack" stage including bass, midrange, and treble controls, followed by a power stage (the Power Amp). The preamplifier beefs up the high-impedance low-level signal coming from the guitar pickup microphones to a lower impedance mid-voltage signal that can drive the power stage. The preamplifier also shapes the tone of the signal; higher gain in the preamplifier leads to "overload", creating desirable crunch/distorted sounds. The power amplifier, with the help of the output transformer outputs a very low impedance, high current signal adequate to efficiently drive a loudspeaker and to produce loud amplified sounds. Another obvious and intended purpose of guitar amps is to produce interesting distorted sounds. For more details about all these stages, one can browse the AikenAmps website. 22 In our previous implementations in JavaScript with the WebAudio API, the first stages were quite faithfully recreated (incl. harmonics and temporal dynamics) with very low latency [17,18,19]. However, the poweramp stage proved to be trickier to implement as it includes a Negative Feedback (NFB) loop. With pure JavaScript WebAudio API, major issues arise when dealing with loops, firstly due to the limitations imposed by its blockprocessing paradigm and also because of some divergences/bugs in how different browsers parse WebAudio graphs with loops. In the WebAudio API specs, the loops in a graph are required to include at least one delay node. Without this delay node, Firefox browser stops rendering the graph, while Chrome browser does not complain but adds, behind the scenes, a 3ms delay (the minimum size of an audio buffer being 128 frames, hence the minimal delay of 128/sampling rate: roughly 3ms at 44.1kHz). Now, to get a timewise precise implementation of loops, as the NFB with its simple RC networks induces delays usually much shorter than 3ms, a finer time precision at the level of some samples would be required to match this delay. With the current limitations, and quite un-consistently, this 3ms delay in the loopso as to conform to the specsbrings also slightly different coloring of the amps between Firefox and Chrome.

Rewriting the Power Amp stage in FAUST, in order to bypass the above mentioned limitations

Our initial WebAudio implementations were based on high level nodes provided by the API: a bank of biquad filters in series (for the Presence in the NFB loop), a waveshaper node (for simulating tubes), gain nodes (master volume, negative gain in the NFB loop and for fine tuning), and a delay node (in the NFB loop). Consequently, the first step was recreating with FAUST our signal chain as faithfully as possible -i.e. using the same filters with the same parameters, the same transfer function, the same gain values, etc. Adapting FAUST filters to behave like WebAudio ones was not straightforward but after some interactions with the FAUST and WebAudio implementers, it proved to be easier to restart from the original C++ implementation of the WebAudio filter API (Chromium browser's source code). This porting done with the FAUST team ended up in a so-called webaudio.lib (available now in the FAUST distribution). To properly simulate the tube stages, we looked for any prior art available in FAUST (e.g., in guitarix.lib from the Guitarix project23 ), or waveshapers (as done by Oleg Kapitonov24 in his plugins Pack or by Nick Thompson of Creative Intent for his Temper Distortion plugin25 ). Most tube simulations, like the Guitarix tube simulations, relied heavily on C/C++ code, making it quite difficult to run them in Web browsers as the FAUST toolchain does not support yet hybrid FAUST/C source code with compilation target set to WebAudio/WebAssembly.

Luckily, the "Temper Distortion" simulation included a 100% FAUST-based implementation of a simple but efficient waveshaper that produced a warm, adjustable, controllable distortion that would easily fit our needs. We used it as a starting point for further developments. The code included the implementation of a simple transfer function whose curve could be adjusted (i.e., leading to more subtle/less aggressive curves). The transfer function from the Temper Distortion waveshaper code26 is based on a parameterized tanh function : This is very close to the one we used in our JavaScript implementation (see Fig. 11 for comparison) with parameter k driving the S-shape of the curve.

In this way, our current JavaScript poweramp implementation (made of a dozen of high level WebAudio nodes) was replaced by a simple FAUST generated AudioWorklet node. 28 Major differences are the introduction of the Presence control (made of two peaking filters, at 2kHz and 4kHz) in the feedback loop, the introduction of an adjustable NFB gain and the removal of some unnecessary elements (like the now pointless resonant lowpass filter at the input). Finally, we added some GUI elements (knobs) in order to allow for the fine-tuning in real-time of the different parameters (see Fig. 14), in particular the ones that control the waveshaper (i.e., drive, curve, and distortion), the NFB gain, and the Presence filters.

Generating the graphical interface, publishing and integrating the plugin in a host software, testing the plugin in the amplifier simulation chain

The current "Temper-inspired" implementation of the waveshaper does not rely on pre-calculated point tables, but on a transfer function applied to each sound sample. Obviously, this leaves some room for further optimization. The dynamic time response of the tubes is obtained using a simple amplitude-follower before the waveshaper to drive an allpass filter, altering the DC offset, and thus the slope of the curve. This simple approach would benefit from being fully confronted with our previous JavaScript implementation where both the slope and the S-shape were dynamically changed.29 This FAUST poweramp proved to be fully functional and adjustable, so we could proceed to the evaluation part. The first step of the evaluation were careful measurements and critical listening to assess the dynamical and harmonic possible shortcomings of this FAUST implementation in standalone mode, tweaking the different parameters (i.e., master volume, presence, NFB gain, presence, transfer function parameters), and also comparing its behavior with our WebAudio/JavaScript implementation. Either with dry guitar sound samples or real guitars as inputs, the Master volume and Presence controls reacted quite similarly in both implementations. Again, the typical oscillatory effects (Larsen) we got when going towards positive feedback within our JavaScript implementation were similar, slightly more controlled, in the FAUST version when pushing some parameters (Presence and NFB gain) close to their limit values.

Evaluation, latency measures

The FAUST IDE allowed also for the creation of a bona-fide WebAudio plugin from the FAUST implementation of the PowerAmp (see Fig. 15). Inside our virtual pedalboard, we chained a special version of our JavaScript tube guitar amplifier simulation with bypassed power amp and cabinet simulation stages, and replaced the last stage with our novel FAUST-based poweramp stage (see Fig. 16), and finally we compared it with the full featured, JavaScript based simulations. These results can be seen/heard in a video we published online,30 using the online pedalboard WebAudio application. 31 Figure 16: The PowerAmp plugin in our pedalboard application, with a version of our AmpSim in which we bypassed the JS PowerAmp and cabinet simulator stages.

The differences in terms of sound/timbre and playing dynamics proved to be very small and subtle. However, we noticed that the FAUST implementation was much more stable and versatile when pushing the internal parameters of the feedback loop. When pushed towards positive feedback loops, the FAUST poweramp produced cleaner oscillations with less intermodulation distortion suggesting a smaller latency from the NFB loop.

The last step was to get a closer look at the behavior of the NFB loop whose delay ought to be lower than the undesired 3ms lower limit in our previous JavaScript implementation (due to block-based processing imposing delays of 128 samples in the back-fed signal). In the FAUST implementation, the measurement tools (Fig. 17) proved the sample-wise nature of the processing with a delay of just one-sample for the NFB/Presence loop. 32 This also explains the increased stability of this loop. Now, in terms of aggregated latency for the Power Amp, we did measurements of the "end-to-end" latency, from guitar to cabinet and obtained consistently better values for latency with the new FAUST implementation: around 20-21 ms compared to the 23-24 ms latency of our previous finelytuned JavaScript implementation (both using a Firefox Nightly 75.0a1 browser with an external Focusrite Scarlett and a Macbook Pro 16 under 10.14). This confirms a saving of 3ms in accordance with the difference of processing of loops between FAUST (sample-wise) and WebAudio API/JavaScript (block based).

To conclude, we have been able, using only the online FAUST IDE, to completely redesign our Power Amp stage, to fine tune it using the embedded measurement tools, to build its GUI and to thoroughly test the final version before publishing it as a plugin for Web-based host applications.

Figure 17: The PowerAmp plugin latency can be measured achieving sample-wise accuracy using the tools embedded in the IDE. Yellow: a gate signal, Pink: the output from the PowerAmp. X-axis is in samples.

DISCUSSION

Now, the short term goals of the authors are to complete and stabilize the presented workflow, to add support for polyphonic MIDI controllable instrument plugins, and to develop more features within the WAP GUI Builder that currently provides basic editing tools. The FAUST IDE itself needs to be extended to include sound file management, so that plugins using audio samples/wavetables, for instance could be implemented. To do that, thanks to Emscripten, we plan to expose more of the already written C++ architecture files used to access sound resources on the JavaScript side. 33 This will also require to extend the FAUST remote compilation service. Deploying the resulting plugins in other host applications (like more traditional DAW running on the Web) should be straightforward if they comply with the WAP specification. For example, some concluding tests have already been conducted with the AmpedStudio DAW. 34 In addition, we asked a group of six audio plugin developers, with different level of expertise with the FAUST language, to follow a tutorial 35 that guided them through the creation and publication of a phaser effect only using the IDE. They did this exercise remotely and after the completion of the proposed tasks they answered an online form 36 where we asked them to evaluate their experience. These questions started by "did you manage to create, publish and test the created plugin in an online host?", and included ratings and comments of different aspects.

The results are summarized below:

• 100% of the developers managed to create a plugin (including its GUI), to publish and to test it, • Average time to complete the tasks: 37 minutes, • 83.3% of them used the visualization tools and considered them an important addition to help understanding the DSP code behavior, • 100% appreciated the fact that a default GUI is generated automatically. They found it useful both for testing the plugin during development and for prototyping its ergonomics. • 100% managed to customize the GUI as suggested in the tutorial (change size, position, colors, textures, shape of elements in the GUI) • 100% tried to do things that are not yet supported in the GUI builder (change a knob into a slider or into a push button, change default value for knobs and sliders, change the behavior of the bypass switch). All these things are possible but they require changing the source code. • 100% found the tool very useful for rapid audio plugin development/prototyping.

The questionnaire also asked to suggest improvements.

Here many proposed to improve the overall ergonomics of the GUI builder ("the most important features should be presented in a more compact way", "where is the undo button?", "the dimensions in pixels should be always visible") and complained about the lack of a magnetic grid or alignment tools. Actions like changing a slider into a knob or changing the default parameter values from the GUI builder are also missing and have been asked by all users (while this can be done by changing the source code of the plugin parameter declarations). The GUI builder is still at an early stage and a more comprehensive user needs analysis will be conducted, focusing mainly on the ergonomics of the GUI builder. This first version however, has been considered as "very useful" for prototyping rapidly an audio plugin, prior to polishing its GUI by hand, editing the HTML/CSS code.

CONCLUSION

In this paper, we presented the combined work of two teams deeply involved in the development of an audio DSP programming language and its complete ecosystem on the one hand, and the definition of a WebAudio plugin standard (WAP) and its complete surrounding environment on the other. We made extensive use of 37 https://guitarix.org/ 38 https://www.rebeltech.org/product/owl-pedal/ recent technologies like Emscripten as well as recognized Web standards (like WebComponents) to achieve the porting of native source components to higher performance versions using WebAudio and WebAssembly API. Combining client side and shared remote services is also part of the presented solution.

The complete workflow from the initial DSP source code, testing and running it in an integrated editor, polishing its user interface in another specialized GUI editor, to the finalized plugin running in an external host has been presented. Many examples of audio effects have been ported to WAPs directly by copying and pasting existing code from the Guitarix 37 and the OWL pedal project, 38 or from various open-source projects, into the new FAUST online IDE. Once compiled, the GUI has been customized within the GUI builder part of the IDE and published to remote WAP servers. They can now be tested online in host web applications such as our Virtual Pedalboard host presented in Figs 2,10 and 17. 39 Having the authoring tools as well as the deployment platform as pure Web applications facilitates the workflow and interoperability of these components [20]. We also think that the presented toolchain could be easily adapted to other plugin formats or audio DSP production tools. Source code for the FAUST and IDE projects is located at:

• https://github.com/grame-cncm/faust • https://github.com/grame-cncm/faustide 7.

APPENDIX: Remote Compilation Service API

The dialog between the editor and the remote compilation service (workflow in Fig. below) is based on a very simple API (Application Programming Interface) of REST (Representational State Transfer) type that we will detail here:

GET /targets

The GET https://faustservicecloud.grame.fr/targets allows for the querying of the service on supported platforms and architectures. The response is in json format, organized in platforms, with a list of supported architectures for each platform. Here is a simplified example of a response: { "ios": ["ios","ios-osc"], "web": ["wap","wap-poly",...], "android": ["android","smartkeyb",...], ... } Three platforms are indicated here: ios, web and android with a list of available architectures for each of them. This information is then used to forge compilation requests by indicating the desired platform and architecture, for example web/wap.

POST /

The POST request https://faustservicecloud.grame.fr accompanied by a file foo.dsp allows to transfer this file to the compilation service. In response, it receives a 160-bit SHA-1 key, for example cf55531c580cc7d3485a5161259f0571d3e6bdef, which uniquely identifies the contents of the file and will be used to represent this file in some requests.

GET /<sha>/<platform>/<arch>/binary.zip

The GET request /<sha>/<platform>/<arch>/binary.zip launches the compilation of a source file (previously posted and represented by its SHA-1 key) for the specified platform and architecture. The result is rendered as a compressed folder that always has the same name: binary.zip.

GET /<sha>/<platform>/<arch>/binary.apk

The GET request /<sha>/<platform>/<arch>/binary.apk is identical to the previous one but retrieves an .apk (Android Package) folder that can be directly installed on Android phones.

GET /<sha>/<platform>/<arch>/precompile

The GET request /<sha>/<platform>/<arch>/precompile launches the compilation of a source file (previously posted and represented by its SHA-1 key) for the specified platform and architecture, but without downloading the result. It allows to know the readiness of the compilation result (depending on the architecture, it can take several minutes) and only then will it trigger a download request.

POST /compile/<platform>/<arch>/binary.zip

The POST /compile/<platform>/<arch>/binary.zip combines in a single query the transfer of the file to be compiled and the retrieval of the compilation result. This request is useful when the compilation service runs on a server in stateless mode, as with the new "cloud run" service from Google.

Figure 3 :

 3 Figure 3: Signal visualizations: oscilloscopes, spectroscope and spectrogram analyzer provided by the FAUST IDE.

Figure 4 :

 4 Figure 4: The export panel.

Figure 6 :

 6 Figure 6: The default GUI can be customized: textures, knobs, sliders, switches positions size, appearance and labels, etc.

Figure 7 :

 7 Figure 7: Other designs for the same DSP code.

Figure 8 :

 8 Figure 8: Workflow of the end-to-end design and implementation of a WebAudio plugin.

Figure 9 :

 9 Figure 9: Other designs for the same DSP code

Figure 10 :

 10 Figure 10: Host application example. The plugins set is discovered by requesting a remote WAP plugin server. Plugins are loaded dynamically when dragged and dropped in the main area.

Figure 11 :

 11 Figure 11: Left, the transfer function for our JS implementation, Right, the one from the FAUST implementation 27 with k=1.

  Figs 12 and 13 show the final diagram of the FAUST implementation of this poweramp based on the Temper Distortion source code.

Figure 12 :

 12 Figure 12: Diagrams of the final implementation.

Figure 13 :

 13 Figure 13: The feedback circuit. The presence filter is a set of peaking filters ported in FAUST from the WebAudio API implementation.

Figure 14 :

 14 Figure 14: GUI generated by the FAUST IDE, some extra parameters (negative feedback gain, waveshaper; drive, curve, saturation) are tweakable, enabling fine tuning of the NFB loop.

Figure 15 :

 15 Figure 15: For testing purposes, we created a WebAudio plugin from the FAUST code, using the WAP GUI Builder we developed, integrated in the FAUST IDE.

Figure :

 : Figure: Communication protocol between the editor and the remote compilation service.

  • Create the path sessions/<sha>/<platform>/<arch>/ • Copy makefiles/<platform>/Makefile.<arch> into sessions/<sha>/<platform>/<arch>/Makefile • Cun the make command • And return session/<sha>/<platform>/<arch>/binary.zip

http://www.charlie-roberts.com/genish/

https://waaw.csound.com

https://soul.dev

https://github.com/micbuffa/WebAudioPlugins

Videos presenting the results of this work can be found online: https://www.youtube.com/watch?v=pe8zg8O-BFs.

See the midi folder in the github repository of the WAP SDK, video https://www.youtube.com/watch?v=jHftK3YxcjQ

http://asmjs.org/

https://webassembly.org

https://faustide.grame.fr

https://github.com/umdjs/umd

https://github.com/j-funk/js-dsp-test/

The WebComponents W3C standard (now in the HTML 5.2 specification) defines a way to easily distribute components with

An online tutorial explains how to create step by step a complete plugin, including its GUI and try it in the pedalboard host : https://tinyurl.com/wnw2yl7

Demos on: https://mainline.i3s.unice.fr/AmpSim5/

More details on: http://www.aikenamps.com/index.php

http://guitarix.org/

https://github.com/olegkapitonov/Kapitonov-Plugins-Pack

https://github.com/creativeintent/temper

See http://www.musicdsp.org/showone.php?id=238

Check our online comparison tool: https://jsbin.com/qifexor/edit?js,console,output,

We did that in the past by replacing the tonestack stage by some FAUST implementations[START_REF] Buffa | Real Time Tube Guitar Amplifier Simulation using WebAudio[END_REF].

Simulation of tube amp Sag/Squish: https://youtu.be/zBhn7odezUQ

https://youtu.be/uNp-0hzveeo

https://mainline.i3s.unice.fr/Wasabi-Pedalboard/#, check the PowerAmp tab at bottom, drag'n'drop in the main area.

As measured in the FAUST IDE, using process = button("gate") <: ((poweramp), _); style code and the embedded visualisation tools.

C++ code using the libsndfile library can be directly compiled to WebAssembly and ported to JavaScript.

https://ampedstudio.com/

Tutorial "Create your own WebAudio Plugins": https://tinyurl.com/wnw2yl7

Evaluation form (french): https://tinyurl.com/y9vny8qu

ACKNOWLEDGMENTS

This work was partially supported by the French Research National Agency (ANR) and the WASABI [21] team (contract ANR-16-CE23-0017-01). The authors would particularly like to thank Jordan Sintes, Guillaume Etevenard and Elmahdi Korfed for their contributions to the WAP standard.

THE AUTHORS

• Stéphane Letz is a researcher in Computer Music at GRAME-CNCM (Lyon, France), a member of the Audio Working Group of the W3C, and a specialist in real-time audio architectures and music protocols. He is the designer of Jack2, the popular low latency audio server. He is also one of the main developer and maintainer of the FAUST compiler.

• Yann Orlarey is the scientific director of GRAME-CNCM (Lyon, France). His research work focuses on the design and implementation of programming languages for musical and sound creation, with a particular interest in lambdacalculus, functional programming, and real-time and compilation techniques. Yann Orlarey and his colleagues at Grame are the designers of FAUST, a functional programming language for sound synthesis and audio processing with a strong focus on the design of synthesizers, musical instruments, audio effects, etc.

• Dominique Fober is a researcher in Computer Music at GRAME-CNCM (Lyon, France). His research is concerned mainly with software architecture for real-time music systems, languages for musical composition, and music notation and representation systems.


Michel Buffa
email: michel.buffa@univ-cotedazur.fr

Jerome Lebrun
email: lebrun@i3s.unice.fr

A FAUST-BASED RE -CREATION OF THE POWER AMP STAGE FOR W EB A UDIO -BASED SIMULATIONS OF GUITAR TUBE AMPLIFIERS

BSTRACT

In this paper, we detail our on-going browser-based re-creations of famous tube guitar amplifiers and describe the JavaScript implementations we have been developing using the WebAudio API. The tricky part of such amplifiers is the power stage (Power Amp) which contains a parametric negative feedback loop. We show the limits of the high-level WebAudio API layer, and how FAUST allows us to re-implement the Power Amp part more faithfully. Finally we also compare FAUST vs JavaScript development, and mention future optimizations.

I NTRODUCTION

Since 2015, we have been designing and developing faithful simulations of iconic tube guitar amplifiers like the Marshall JCM 800 or the Mesa-Boogie 2:90, used by many famous artists (AC/DC, Guns and Roses, Deep Purple, Metallica, etc.), that can run in a web browser [START_REF] Buffa | Real Time Tube Guitar Amplifier Simulation using WebAudio[END_REF]. This work consisted in emulating the different parts of the electronic circuit of this amplifier using WebAudio, implementing the necessary signal processing algorithms using the available API, and finding adequate solutions to circumvent some limitations specific to the web browser environment (thread priority, latency, JavaScript API limitations).

Finally, we extensively compared (quantitatively and qualitatively) our realization with the state of the art, i.e. native simulations, mostly commercial, written in C++, and not having the constraints of webapps. The results exceeded our expectations. Since then, we have continued this work by refining the models used in the simulation, and we designed a framework to reproduce different electronic architectures present in various other tube amplifiers found in many musicians' equipment [START_REF] Buffa | WebAudio Virtual Tube Guitar Amps and Pedal Board Design[END_REF]. We can now simulate for example a Fender, a Vox or a Mesa Boogie amplifier, etc. or even create new original designs. These customizable simulations have been tested by professional guitarists, are being used by music schools on an experimental basis and are the subject of a marketing contract by the CNRS in order to be included as plugins [START_REF] Buffa | Towards an Open Web Audio Plug-in Standard[END_REF][START_REF] Buffa | WAP: Ideas for a Web Audio Plug-in Standard[END_REF] in an online commercial digital audio workstation. So far, our simulations were fully developed in JavaScript and based on the WebAudio API.

W EB A UDIO

WebAudio is a W3C-standard JavaScript API that relies on 1 building an "audio graph" by connecting processing nodes one to another. The signal is sequentially processed through the block diagram where each node crossed can modify the signal (e.g. a filter node may be used to remove high-pitched sounds, etc ...). Some particular nodes can also be used as a sound source (audio file, wave generator, link to an HTML5 element <audio> or <video>). Fig. 1. High level simulation. The lamps and filters are identified and simulated part by part using the WebAudio API.

To our knowledge, there is no previous research work that has tried to simulate a complete guitar amplifier using WebAudio. When we started, we made the choice of relying on higher level psycho-acoustic emulations, in which the "logical" parts are well identified (filters, lamps, etc.) and perceptually emulated using separate templates for each part (Fig. 1). This work has been presented in [START_REF] Buffa | Real Time Tube Guitar Amplifier Simulation using WebAudio[END_REF] and validated by professional guitar players during different campaigns of user tests. This may be in theory less accurate than a 'global' physical simulation because some effects and interactions such as feedback loops from overloaded tubes or the damping factor of the loudspeaker impedance on the power amplifier may not be precisely taken into account. However, this approach is much simpler and more tunable.

It can be implemented real-time within a browser and is surely more adapted to WebAudio, its ecosystem and its limitations.

In our approach, we precisely analyzed the electronic schematics of amplifiers: lamps, filters structures, power supply, output transformers were identified and simulated part by part by JavaScript code relying on the WebAudio API. WebAudio provides a set of "high-level" nodes (such as the WaveShaper node and the BiquadFilter node) that can be used to model the lamps and filters, and it has been shown that when properly used, waveshaping techniques , 2 combined with proper oversampling and filtering, can give quite good results [START_REF] Pakarinen | A Review of Digital Techniques for Modeling Vacuum-Tube Guitar Amplifiers[END_REF].

One big advantage of JavaScript/WebAudio API is the really flexible and dynamic way you can manipulate the audiograph (by changing its topology in real-time, even while playing guitar) or the parameters of the different nodes, in particular, you can reshape in real-time the transfer functions used by the waveshaper nodes. Another advantage of using WebAudio high level nodes, is that most of the audio processing is done in their C++ implementation that lies in the web browser internals, so performance is generally not an issue. Our simulation has a very low CPU impact and runs audio processing threads with the highest priority. On a MacBook Pro from 2016, we could run up to 15 amp simulations in parallel (all stages: preamp, tonestack, power amp, speaker simulation), in a DAW, without noticing any glitche and with a CPU stress level of less than 50%.

However, until recently, one main limitation of the WebAudio API design was that default signal processing is constrained to block-processing of chunks of 128 samples at a time, and until very recently it was not possible to do stream processing at the sample-wise level without introducing glitches and latency. Not being able to perform processing with time-granularity below this 3ms limit caused a lot of issues in the implementation of the PowerAmp part of the amplifier schematic. Indeed, in its classic Push/Pull configuration, the power stage includes a crucial negative feedback loop that could not be faithfully simulated without introducing customized solutions to mitigate this major limitation. This issue has been recently partially solved with the arrival of the AudioWorklet node and a new WebAssembly standard in 2018 . Writing custom DSP code in JavaScript, 3 or coding in WebAssembly by hand, is nevertheless quite tedious.

Fortunately, FAUST quickly proposed WebAudio/WebAssembly as a compilation target and proved to be an ideal framework for developing powerful custom code (we even did some personal contributions to FAUST's WebAudio support) [START_REF] Ren | FAUST online IDE: dynamically compile and publish FAUST code as WebAudio Plugins[END_REF].

In this paper, we will detail how a PowerAmp works (Section 3), introduce our initial solution to mitigate the block-processing limitations of WebAudio (Section 4), and devote the rest of the article to detail our FAUST and WebAssembly-based approaches to achieve more faithful low-latency simulations (Section 5). We will conclude by comparing the advantages and disadvantages of the two approaches (JavaScript + WebAudio high level nodes vs. FAUST/WebAssembly) with special care on the performance measurements (latency, cpu usage, etc.) (Section 6).

T UBE GUITAR AMPLIFIER DESIGN

Overview

A guitar amplifier is composed of different parts: usually, a preamplifier stage, a so-called "tonestack" stage that includes bass, midrange and treble controls, and a power stage (the Power Amp). See Figure 2 The preamplifier beefs up the high-impedance low-level signal coming from the guitar pickup microphones to a lower impedance mid voltage signal that can drive the power stage. The preamplifier also shapes the tone of the signal; high settings of the preamplifier lead to 'overload' that creates crunch/distorted sounds. The power amplifier with the help of the output transformer outputs a very low impedance, high current signal adequate to efficiently drive a loudspeaker and to produce loud amplified sounds. Another clear aim of guitar amps is of course to create desirable distortions too.

Fig. 3. The back of a Marshall JCM800 power head. We can see the two amplification stages.

To get a finer understanding of this critical stage, we will further detail how a PowerAmp works, its role in the signal chain and why the power amplifier is so tricky to emulate due to the presence of some feedback loop in the circuitry.

The PowerAmp stage

Usually solely controlled by the Master Volume and Presence knobs (Fig 4 .), the Power Amp stage has a profound impact on the sound and overall dynamics. Indeed, the type of sound you can get from the preamp stage alone remains on the lean side in terms of distortions. Referring to Kuehnel [START_REF] Kuehnel | Circuit Analysis of a Legendary Tube Amplifier: The Fender Bassman 5F6-A[END_REF] and Denton [START_REF] Denton | Electronics for Guitarists[END_REF], when you turn up the volume of a tube amp using the Master Volume knob, the power tubes get more and more distorted and the sound gets thicker and thicker, and also less controlled. And as you get closer to power saturation (i.e. clipping the power tubes and/or saturating the output transformer core causing the famous grinding effect, a mixture of saturation/oscillations, but also possibly starving the power supply -more about this later in this section), the output dynamics get tighter, resulting in muddy distortions with a heavier sound. The English slang to characterize these sounds is difficult to translate: in French, one would speak of "thick", "heavy", "metallic", "abrasive" (translation of gritty), "rich" sounds. In Power Amps, the Negative Feedback Loop (NFB)/Presence control (see Figs. 5 and6) are typically introduced to extend the usable frequency bandwidth by limiting/reshaping the unwanted distortions originating from the non-linearities of the output transformer at the price of a slightly lower total gain. The negative feedback loop (NFB) takes a portion of the signal from the output transformer secondary winding, dephasing it with a 180 degree phase shift and re-injects it back into the splitter stage (see the highlighted plot in Fig. 5 and the "Feedback" loop in Fig. 6). Amplifiers without NFBs are usually more powerful (higher gain) with more distortion, but their coloration also tends to become rougher and unpredictable when pushed into saturation. The NFB loop smoothes out the sound by reducing the level of distortion in the parts of the spectrum where it is most disturbing (typ. mid-range ) [START_REF] Kuehnel | Circuit Analysis of a Legendary Tube Amplifier: The Fender Bassman 5F6-A[END_REF].

Unknown to concert stage or HiFi power amps, a 'Presence' control is added to the NFB loop of guitar amps to allow control on the coloration of the NFB and thus to provide a simple but efficient way of adjusting the brightness and sharpness of the sound at the Power Amp stage. The Presence may be looked at as a global time/frequency control on the brightness of timbre by 4 altering the signal fed back from the negative feedback loop. The effects of negative feedback can be reduced for certain frequencies as the Presence knob controls the resistor part of a RC network, hence a tunable filter made of Resistors and Capacitors (RC) in the loop. With less negative feedback in the high frequencies, the sound becomes brighter, louder, more vivid and dynamic. The behavior of this control is very different from those of the tonestack (bass, midrange, treble), which merely equalizes the output of the preamp. Namely, unlike conventional treble control which is mainly subtractive, Presence control is pseudo-additive in that it limits the fundamental subtractive aspect of the NFB loop. It should be noticed also that the NFB/Presence has a major influence at the temporal level [START_REF] Letz | Compiling Faust Audio DSP Code to WebAssembly[END_REF] as the RC networks controlled by the Presence knob induce some frequency-dependent group-delay in the NFB loop. This may explain the blurring/sharpening effect that Presence has on the attack slopes of the notes played, acting as a "softening/anti-softening" pedal. This clearly motivates our introduction of a curve-based parametric Presence control to choose in which frequency band one wants its brightness.

To design properly a NFB/Presence circuit, lots of parameters are involved and a lot of care must be taken when adjusting them. With real amplifiers' power amps, manufacturers are very conservative: the allowed range of Presence control is restricted so as to avoid unwanted oscillations that may be destructive to the speaker/cabinet. As a consequence, only subtle alterations (mostly upper-mids/lower-high range brightness) are possible, the sound signature being mainly carved through the preamp settings. In our simulations, the curve-based parametric Presence control allows us to fully carve the time/frequency coloration at the Power Amp level to add punch or special effects to the output from the Preamp and Tonestack. Some other important controls on the Power Amp are the Master volume to adapt gain with the Preamp output level, and the Bias setting of the tubes may be changed to introduce some light non-linearities/asymmetries in the tube response curves. In real-world tube Power Amps, Bias allows us to change the class of operation of the tubes (typ. class AB for push-pull) from almost class A to almost class B. And of course the Presence setting for adjusting the overall tone/brightness is quite important and can lead to destructive positive feedback if not designed correctly (freq ranges, etc.). Historically, some amps have a Power Amp section which is more important in their sound signature, in general they are the most "vintage" ones, think of the Fenders, the first Marshalls, the Vox AC30 … Improving the real-time dynamics in simulations is crucial to get them more realistic . Namely, when pushed to their 5 limits by large transients, classic guitar tube amplifiers (esp. with tube rectifiers based power supply) have a tendency towards harmonic saturation with typical dynamic range compression/expansion effects (known as 'sag' and 'bloom'), temporal lag (known as 'squish') or spatialisation artifacts (known as 'swirl') . Sag is consecutive to some 6 drooping of the supply voltage in the Preamp stage in response to large transients. The recovery from Sag as voltage supply returns to normal is coined as 'Bloom' and is again a well appreciated effect. Now, Squish is linked to some temporal hysteresis induced by some increased time lag in the feedback loop -also in response to large transients. Finally, Swirl is linked to saturation of the core in the output transformer from overload, leading to phase inconsistencies and spatial blurring of the chord played (ala Univox Uni-Vibe pedal effect). All those effects proved to be quite tricky to emulate in real-time . [START_REF] Kuehnel | Circuit Analysis of a Legendary Tube Amplifier: The Fender Bassman 5F6-A[END_REF] We introduced a dedicated method to approximate these advanced temporal, nonlinear behaviours of tubes (typ. 'sag'/'bloom', 'squish'/'swirl' effects). Namely, in the WebAudio API, the slope of the tube transfer function curves can be driven real-time by the power of input signal enveloppe emulating hysteresis phenomena. Consequently, to mimic this hysteresis and the sag in the response of a tube Preamp stage, we implemented it with simple dynamical real-time changes in the slopes of the transfer functions in our preamp simulation . By properly adjusting the threshold at which we get the squish, only the higher power transients from the envelope amplitude will trigger controlled change of slope. This is still an experimental feature that needs to be properly adjusted and evaluated. Figure 7 shows a curve animated in real time with hysteresis behaviour in the transfer function triggered by the input signal envelope. 5 Video: https://www.youtube.com/watch?v=zBhn7odezUQ 6 More details on: http://www.aikenamps.com/index.php/what-is-sag 7 Some examples at: http://www.diale.org/tube_emulation.html The Bias control corresponds to the idle voltage around which the tubes are amplifying signals and thus controls their linearity/asymmetry characteristics . With Bias, one 10 can change the amount of (negative) voltage offset applied to the signal at the grid of the tubes. Colder settings will make the pentodes/tetrodes draw less current, decreasing the overall output volume and potentially introducing cross-over distortion due to the class AB getting closer to class B (which may be what a guitarist looks after to achieve a more dirty/loose tone). Hotter settings will make the pentodes/tetrodes draw more current moving closer to class A, with a thicker, louder perceived output level and eventually up to power supply "sagging" (depending on the Sagging control setting), adding compression or, in extreme cases, saturation and cleaning up the tone from potential cross-over distortion.

-I MPLEMENTING THE P OWER A MP STAGE WITH W EB A UDIO HIGH LEVEL NODES , DEALING WITH LIMITATIONS

In the current implementation, the presence filter is fully customizable and can be controlled in real time using a graphic equalizer (Fig. 8) to select the frequency range of the filter. The min and max values of the negative gain in the NFB can also be adjusted using a slider. These tools (NFB and Presence) are quite sensitive (at the edge of creating positive feedback with oscillations and Larsen effects so we provide controls in the GUI to adjust/restrict the admissible range) but this novel presence control provides an utterly powerful and spectacular tool to shape the final sound.

Being able to adjust all the parameters (gains, filter parameters, transfer function of the waveshaper, etc.) is crucial to fine tune this stage using WebAudio nodes. We strongly advise the player to watch this YouTube video 11 which shows the differences in sound and dynamics with and without this loop (Power Amp on / off) in our simulation. It sounds and plays very well (we made several user evaluations [START_REF] Buffa | Real Time Tube Guitar Amplifier Simulation using WebAudio[END_REF][START_REF] Buffa | WebAudio Virtual Tube Guitar Amps and Pedal Board Design[END_REF] that showed that guitarists, even professional ones, liked the way the dynamics of a real amp was simulated). As said in previous sections, we simulate tubes using filters and waveshaper nodes with properly adjusted transfer functions. As shown in Fig 8 . The green transfer function curve on the left of the graphic EQ (presence bank of filters) is rather linear, meaning that only little distortion is added to the signal, and only at high amplitudes. Being able to adjust this function is also crucial to avoid oscillations. On top of that, the Bias control has to be properly adapted to the selected tube transfer functions to guarantee coherent coloration/output volume (making it easier to compare different tubes and choose the right one).

Nevertheless, we encountered many issues in the implementation of our signal loops in WebAudio. Proper simulations of NFB and Presence have been quite difficult to achieve due to some limitations of the WebAudio API and divergences/bugs in how browsers generally parse the WebAudio graphs with loops. In the WebAudio API specs, loops in the graph are required to include at least one delay node. Without this delay node, Firefox stops rendering the graph, while Chrome does not complain but adds, behind the scenes, a 3 ms delay (the minimal delay from a frame audio buffer of 128 sample-frames as within WebAudio API, the signal is always processed in packets of 128 samples, which means that the minimum value for a delay is 128 / sample rate, i.e. about 128/44100 = 3ms). With the current limitations in WebAudio, and quite strangely, this 3ms delay in the loop to conform to the specs, brings slightly different coloring of the amps between FF and Chrome. We have reported these errors and discussed them with the implementers (Raymond Toy from Google and Paul Adenot from Firefox) but so far, nothing has been fixed (September 2020). For a good implementation of NFB, a stable delay of fewer samples would have been preferable (higher delays increase latency and the softening of attacks). Now, to faithfully implement loops like the NFB with its RC networks inducing shorter delays, finer precision at the level of some sample-frames is required. To circumvent these limitations and allow a proper sample-wise accuracy in the processing of loops, we decided to re-implement the NFB loop (and other critical parts in general) in FAUST as AudioWorklets, ending up re-implementing all the processing nodes present in the circuit: filters, gain and wave shaper, in this language.

FAUST IMPLEMENTATION OF THE P OWER A MP STAGE

A guitar amplifier is composed of different parts: usually, a Preamplifier stage, a so-called "Tonestack" stage that includes bass, midrange and treble controls, and a Power stage (the Power Amp). Our general approach consisted in looking at the different parts we needed to re-create. However, as mentioned in the previous section, the poweramp stage is quite tricky to implement as it includes a negative feedback loop. In our initial purely WebAudio implementation [1, 2], we were using a bank of biquad filters in series (for the presence implementation), a waveshaper node with appropriate biquad filters (for simulating tubes), some gain nodes (master volume at the input of the stage, negative gain in the NFB loop and a few others for fine tuning the signal level at different locations in the audio graph), and a delay node (in the NFB loop). Aware of the great difficulties encountered in simulating the power amp in JavaScript/WebAudio, we first tried to re-create as faithfully as possible the signal chain that gave good results. For example, using the same types of filters with the same parameters, the same transfer function with the core issue of simulating properly a waveshaper in FAUST, the same gain values, etc. And of course, we looked closely at the behavior of the NFB loop whose delay hopefully should be lower than the 3ms barrier imposed by the previous implementation. This way, we can replace the current power amp implementation (made of a dozen of high level WebAudio nodes) with a single FAUST generated AudioWorklet node .

12 WebAudio comes with a set of classic biquad filters types: lowpass, highpass, bandpass, lowshelf, highshelf, peaking, notch and allpass. All these filters have a fixed set of parameters: frequency, gain, Q and detune, whereas some of these parameters are not relevant to some type of filters (as Q for lowshelf/highshelf). FAUST does not come with similar filters out of the box. After trying to adapt existing FAUST filters to behave like WebAudio filter ones, and after talking with FAUST and WebAudio implementers the conclusion was that for a really faithfull behavior, it would be better to start from the original C++ implementation of the WebAudio filter API, taken from the Chromium browser source code. The FAUST team did the port and provided us with the so-called webaudio.lib that is now available in the FAUST distribution.

For the power amp tubes, we looked at the way FAUST developers simulated tubes (e.g. in the Guitarix project 13source repository, in particular in the guitarix.lib file), or waveshapers (as in several distortion plugins such as the ones by Oleg Kapitonov or by Nick Thompson's Creative 14 Intent Temper Distortion plugin ). We found out that most 15 tube simulations relied on C/C++ code and could not be used out of the box (typ. guitarix tube simulations), as we must be able to run these in a Web browser, and the FAUST toolchain still does not support hybrid FAUST/C source code when the compilation target is set to WebAudio/WebAssembly. The Temper distortion simulation, however, used a 100% FAUST based implementation of a simple waveshaper that produced a warm, adjustable, distortion sound that could easily fit our needs. We used it as a starting point. Furthermore, the code contained the definition of a transfer function curve that could be adjusted (i.e using a more subtle/less aggressive curve). Fig. 9 shows the transfer function from the Temper Distortion waveshaper code, that is very close to the one we used in our JavaScript implementation (see Fig. 10. for comparisons), the parameter k driving the S shape of the curve. Finally we added GUI elements (knobs) in order to fine tune in real time different parameters (Fig. 13), in particular the ones that control the waveshaper (drive, curve, distorsion), the NFB gain and the Presence filters.

The current implementation (mainly based on the code from the Temper Distortion) of the waveshaper does not rely on pre-calculated point tables, but on a transfer function applied to each sound sample, which leaves room for optimization. The dynamic time response of the tubes is approximated using an amplitude follower placed in the signal chain just before the waveshaper that drives an allpass filter (and which aims at modifying the DC offset, and thus the slope of the curve). We still have to evaluate whether this approach is as efficient or flexible as the method we used previously in the JavaScript implementation, which changes the slope but also the S-shape of the curve (see section 3, Fig. 7).

Once our FAUST-based Power Amp re-creation was functional and adjustable, we could proceed to the evaluation phase.

E VALUATION

The first step of the evaluation was to listen to the global overall sound when we used the Power Amp in standalone mode, tweaking the different parameters (Master volume, Presence, negative gain, transfer function parameters), and to check its behavior compared to our previous WebAudio/JavaScript implementation. We did some trials using dry guitar sound samples, but also with a real guitar as inputs. The general feeling is that the two main settings, Master volume and Presence, reacted very closely with both implementations. In addition, the classic effects of oscillation and positive feedback could be obtained again when pushing some parameters close to the limit values (Presence, NFB gain).

In a second step we used the FAUST IDE to create a WebAudio plugin from the FAUST implementation of the Power Amp (Fig. 14) and we chained a special version of our tube guitar amplifier simulations in which we bypassed the embedded power amp and cabinet simulation stages (Fig. 15), and compared with the full featured, JavaScript based simulations. Results can be seen/heard in a video we published online , or in the online pedalboard WebAudio 18 application .

19

The differences in terms of sound/timbre and playing dynamics are small and subtle. However, we noticed that the FAUST implementation was much more stable and versatile when adjusting the internal parameters of the feedback loop. The processing in our JavaScript implementation was based on blocks of 128 samples, inducing an undesirable delay of 3ms in the back-fed signal as opposed to only two samples with the FAUST loop . In the FAUST implementation, the measurement 20 tools (Fig. 16) proved the sample-wise nature of the processing with a delay of just one-sample for the NFB/Presence loop. This also explains the increased 21 stability of this loop. Now, in terms of aggregated latency 18 https://youtu.be/uNp-0hzveeo 19 https://mainline.i3s.unice.fr/Wasabi-Pedalboard/# , check the PowerAmp tab at bottom, drag'n'drop in the main area. 20 As measured in the FAUST IDE, using process = button("gate") <: ((poweramp), _); style code and the embedded visualization tools. 21 As measured in the FAUST IDE, using process = button("gate") <: ((poweramp), _); style code and the embedded visualisation tools.

for the Power Amp, we did measurements of the "end-to-end" latency, from guitar to cabinet and obtained consistently better values for latency with the new FAUST implementation: around 20-21 ms compared to the 23-24 ms latency of our previous finely-tuned JavaScript implementation (both using a Firefox Nightly 75.0a1 browser with an external Focusrite Scarlett and a Macbook Pro 16 under 10.14). This confirms a saving of 3ms in accordance with the difference of processing of loops between FAUST (sample-wise) and WebAudio API/JavaScript (block based). Fig. 16: The latency can be measured achieving sample-wise accuracy using the tools embedded in the IDE. Yellow: a gate signal, Pink: the output from the PowerAmp. X-axis is in samples.

In addition, the use of the FAUST IDE for coding, debugging and profiling this Power Amp plugin has been evaluated by six audio plugin developers with different levels of expertise with the FAUST language. They had to follow a tutorial that guided them and after that, they had to answer a detailed survey. The IDE has been considered as "very useful" for prototyping rapidly an audio plugin, prior to polishing its GUI by hand, editing the HTML/CSS code. Details of this evaluation are available in [START_REF] Ren | Using Faust DSL to Develop Custom, Sample Accurate DSP Code and Audio Plugins for the Web Browser[END_REF].

P ERSPECTIVES AND CONCLUSIONS

FAUST has proven to be particularly suitable for porting the JavaScript code of an existing Power Amp in a very similar way, freeing it from the limitations, inconsistencies and constraints of the WebAudio API. We performed preliminary qualitative measurements and measured the latency of the processing, which proved to be almost identical. We did not investigate some aspects that can still be improved/optimized, such as the implementation of a full-featured waveshaper in FAUST (based on pre-calculated tables and interpolation to describe the transfer function, for example), or on more complex tube models. At the evaluation level, additional systematic measurements have to be made and the power amp behavior should also be compared with native implementations, for example, those of the TPA-1 by Ignit Amps plugins, or the TSE X50 by TSE audio (in which the poweramp stage can be isolated).

  and 3 below..

Fig. 2 .

 2 Fig. 2. The typical stages of guitar amplifiers and their associated signal paths. Some brands (as Fender) may switch the PreAmp and the Tonestack stages.

Fig 4 .

 4 Fig 4. The Power Amp stage is controlled by the Master Volume and Presence knobs.

Fig 5 .

 5 Fig 5. For illustration, the Power Amp stage of a Mesa/Boogie 2:90. The Negative Feedback Loop (NFB)/Presence with its RC network is highlighted. The JCM 800 has similar topology.

Fig 6 .

 6 Fig 6. An abstraction of a classic Push/Pull Power Amp.

Fig 7 .

 7 Fig 7. A tool we developed in order to adjust the real-time dynamics of the tube simulation based on waveshapers .

9

 9

Fig 8 .

 8 Fig 8. The settings of the NFB power amplifier can be changed/adjusted dynamically on the fly, even while playing, without generating any audio glitches/dropouts.

Fig. 9 :Fig. 10 :

 910 Fig. 9: FAUST transfer function, uses an approximation of tanh for computational improvements .16

Figs. 11

 11 Figs. 11 and 12 show the final diagram of the FAUST implementation of the PowerAmp based on the Temper Distortion source code. Differences from the Temper Distortion source code are mainly the introduction of the Presence (made of two peaking filters, at 2kHz and 4kHz) in the feedback loop, the introduction of an adjustable negative feedback gain, the removing of some unnecessary elements (i.e. a resonant lowpass filter at the beginning of our signal chain).

Fig. 11 :Fig. 12 :

 1112 Fig. 11: Diagrams of the final implementation.

Fig. 13 :

 13 Fig. 13: GUI generated by the FAUST IDE, some extra parameters (negative feedback gain, waveshaper; drive, curve, saturation) are tweakable, enabling fine tuning of the NFB loop.

Fig. 14 :

 14 Fig. 14: For testing purposes, we created a WebAudio plugin from the FAUST code: using the WAP GUI Builder we developed, integrated in the FAUST IDE.

Fig. 15 :

 15 Fig. 15: The PowerAmp plugin in our pedalboard application, with a version of our AmpSim in which we bypassed our Power Amp pure-JavaScript version and the cabinet simulator stages.

https://www.w3.org/TR/webaudio/

The most straightforward method for obtaining signal distortion with digital devices is to apply an instantaneous nonlinear transformation, using a so-called "transfer function" from the input signal to the output variable. This type of timbre alteration is coined waveshaping[START_REF] Arfib | Digital Synthesis of Complex Spectra by Means of Multiplication of Nonlinear Distorted Sine Waves[END_REF][START_REF] Lebrun | Digital Waveshaping Synthesis[END_REF].

WebAssembly is a W3C standard: a portable binary-code format for executable programs, firstly to be used on the Web, but also on native environments. WebAssembly aims to execute at native speed by taking advantage of common hardware capabilities available on a wide range of platforms. See https://webassembly.org .

Proceedings of the 2 nd International Faust Conference (IFC-20), Maison des Sciences de l'Homme Paris Nord, Saint-Denis, France, December[START_REF] Buffa | Real Time Tube Guitar Amplifier Simulation using WebAudio[END_REF][START_REF] Buffa | WebAudio Virtual Tube Guitar Amps and Pedal Board Design[END_REF] 2020

Fender: Be in the Moment: The Presence Control Explained: What is it and how can it help energize your live sound? ( https://www.fender.com/articles/tech-talk/be-in-the-moment-the-presence-c ontrol-explained )

See this in our amp simulation in this video: https://www.youtube.com/watch?v=zBhn7odezUQ

https://jsbin.com/zotaver/edit

Aiken -The last word on Biasing: https://www.aikenamps.com/the-last-word-on-biasing

WebAudio implementation demo of the PowerAmp stage: https://www.youtube.com/watch?v=-NdMdJQx2Bw

We already did that in the past by replacing the tonestack stage by some FAUST implementations[START_REF] Buffa | WebAudio Virtual Tube Guitar Amps and Pedal Board Design[END_REF].

http://guitarix.org/

https://github.com/olegkapitonov/Kapitonov-Plugins-Pack

https://github.com/creativeintent/temper

http://www.igniteamps.com/#tpa-1

https://www.tseaudio.com/software/x50v2

ACKNOWLEDGMENTS

This work was partially supported by the French Research National Agency (ANR) and the WASABI [21] team (contract ANR-16-CE23-0017-01).