lame.wasm: the MP3 encoder of ToolHero (toolhero.dev) ===================================================== lame.wasm is LAME 3.100's encoder, with a small C interface of ours, compiled to WebAssembly. No browser can encode MP3, so ToolHero loads this module when it writes an MP3, on your device: your audio never leaves it. LAME is free software under the GNU Library General Public License (LGPL), version 2 or any later version. This module is LAME, and it is offered to you under that licence: ToolHero takes the later version, the GNU Lesser General Public License version 2.1 (LGPL-2.1.txt), and COPYING.txt is the version 2 text that comes with LAME. No code of ToolHero's website or apps is part of it, and it takes nothing from the page that loads it. The only code of ours inside is the two small C files that give it its interface (src/), which are part of the module and offered under the same licence. The module is a separate file, loaded on its own (see "Replace it"), and you can swap it for your own build. LAME: https://lame.sourceforge.io/ (the LAME Project; Copyright (c) 1999-2017 and earlier by Mike Cheng, Mark Taylor, Takehiro Tominaga, Robert Hegemann, Gabriel Bouvigne, Alexander Leidinger, Albert L. Faber, Jonathan Dee, Don Melton, Ron Mayer (the FFT), David Robinson and Glen Sawyer (ReplayGain), and others; see the headers of the files in the tarball). What is in this folder ---------------------- lame.wasm the module, as ToolHero serves it vendor/lame-3.100.tar.gz LAME 3.100 exactly as released, unmodified src/toolhero_lame.c our C interface (the th_* functions) over LAME's API src/libc_stubs.c stubs for the C library's file output, so the module needs no imports from its host config.h LAME's config.h, written by hand for wasm32 build.sh the build: LAME + our two files, compiled and linked toolchain.json the compiler it is built with, and the checksum of each download LGPL-2.1.txt the licence we take: GNU Lesser General Public License, version 2.1, as gnu.org publishes it COPYING.txt the licence that comes with LAME (GNU Library General Public License, version 2; COPYING in the repository) README.txt this file (README.md in the repository) Everything needed to build lame.wasm again, byte for byte, is here. ToolHero patches none of LAME's source: build.sh unpacks the tarball and compiles it as it is (a `patches/` folder with `*.patch` files would be applied first, and published here; there are none). The upstream source ------------------- LAME 3.100 https://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz SHA-256 ddfe36cab873794038ae2c1210557ad34857a4b6bdc515785d1da9e175b1da1e (the same file, with the same checksum, is vendor/lame-3.100.tar.gz here) What is compiled in, and what is not ------------------------------------ Compiled: the 19 encoder files of libmp3lame (VbrTag, bitstream, encoder, fft, gain_analysis, id3tag, lame, newmdct, presets, psymodel, quantize, quantize_pvt, reservoir, set_get, tables, takehiro, util, vbrquantize, version). Not compiled: LAME's decoder (mpglib), the command-line program, the x86 assembly and SSE routines, the analyser hooks. The module encodes and does nothing else. Build it yourself ----------------- You need the WASI SDK 34.0 (clang 23.1.0 with wasm-ld and wasi-libc), a POSIX shell, tar and sha256sum (or shasum). toolchain.json lists the download for each platform and its SHA-256: https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-34 tar -xzf wasi-sdk-34.0-.tar.gz WASI_SDK_PATH=$PWD/wasi-sdk-34.0- sh build.sh lame.wasm sha256sum lame.wasm The result is identical on every machine: ToolHero's own copy was built on macOS (arm64) and rebuilt, byte for byte, on Linux (arm64) in a container, from a different folder. The module ToolHero serves has SHA-256: c9b8a436d342f3f53c420fece6296200172ad1e1e3b67a84ac4c6864adf3561d (219,025 bytes) Replace it ---------- LGPL asks that you can run the program with a changed LAME. ToolHero loads the module from its own file, `/lame/lame.wasm` on the website and `lame/lame.wasm` among the desktop app's resource files (beside the executable, not inside it), only when an MP3 is written. It is not part of any script and is not inlined in one. To use your own build of LAME, build a module that exports the interface below and put it where this one is: on a copy of the site you host, or with a browser's local-override feature; in the desktop app, at `lame/lame.wasm` in the app's data folder (on macOS, ~/Library/Application Support/dev.toolhero.desktop/lame/lame.wasm), which the app reads before its own copy (the copy among its resource files is sealed by the app's signature). ToolHero will encode with it. The interface (version 1; src/toolhero_lame.c is the reference, and every function is exported by that name): memory the module's linear memory _initialize() the C runtime's start-up, called once after instantiating th_api_version() -> i32 1 th_malloc(len) -> ptr th_free(ptr) th_open(sample_rate, channels, mode, value, quality) -> handle mode 0 = constant bitrate (value: kbit/s), 1 = average bitrate (value: kbit/s), 2 = variable bitrate (value: 0 best to 9 smallest); quality: LAME's -q (0 to 9) th_last_status() -> i32 why th_open returned 0 th_encode_f32(handle, left, right, n, out, cap) -> bytes, or a negative error th_encode_f32_interleaved(handle, pcm, n, out, cap) th_encode_i16(handle, left, right, n, out, cap) th_encode_i16_interleaved(handle, pcm, n, out, cap) th_flush(handle, out, cap) th_close(handle) th_out_capacity(n) -> bytes a safe `cap` for n samples per channel th_sample_rate, th_channels, th_bitrate, th_samples_per_frame, th_encoder_delay, th_encoder_padding (handle) -> i32 The module takes no imports; the app instantiates it with an empty import object. Patents ------- The patents on MP3 encoding and decoding have expired (the licensing programme ended in 2017). LAME's README still suggests that, where software patents are recognised, you take your own advice. Warranty -------- This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License (LGPL-2.1.txt) for more details. Written offer ------------- If you received a copy of ToolHero's desktop app, the files above are in its resources, and they are also at https://toolhero.dev/lame/README.txt (this file, with the rest beside it). ToolHero (Semantic Bridge LLC) will give anyone the complete corresponding source of the module, on request to legal@semanticbridge.org, for at least three years after the version that contains it was last offered, at no more than the cost of physically performing the distribution.