61 |
227 | `
228 |
229 | // FaustEditor Web Component
230 | export default class FaustEditor extends HTMLElement {
231 | constructor() {
232 | super();
233 | }
234 |
235 | connectedCallback() {
236 | // Initial setup when the component is attached to the DOM
237 | let code = this.innerHTML.replace("", "").trim();
238 | this.attachShadow({ mode: "open" }).appendChild(template.content.cloneNode(true));
239 |
240 | // Set up links, buttons, and editor
241 | const ideLink = this.shadowRoot!.querySelector("#ide") as HTMLAnchorElement;
242 | const editorEl = this.shadowRoot!.querySelector("#editor") as HTMLDivElement;
243 | const editor = createEditor(editorEl, code);
244 |
245 | ideLink.onfocus = () => {
246 | // Open current contents of editor in IDE
247 | const urlParams = new URLSearchParams();
248 | urlParams.set("inline", btoa(editor.state.doc.toString()).replace("+", "-").replace("/", "_"));
249 | ideLink.href = `https://faustide.grame.fr/?${urlParams.toString()}`;
250 | }
251 |
252 | const runButton = this.shadowRoot!.querySelector("#run") as HTMLButtonElement;
253 | const stopButton = this.shadowRoot!.querySelector("#stop") as HTMLButtonElement;
254 | const faustUIRoot = this.shadowRoot!.querySelector("#faust-ui") as HTMLDivElement;
255 | const faustDiagram = this.shadowRoot!.querySelector("#faust-diagram") as HTMLDivElement;
256 | const sidebar = this.shadowRoot!.querySelector("#sidebar") as HTMLDivElement;
257 | const sidebarContent = this.shadowRoot!.querySelector("#sidebar-content") as HTMLDivElement;
258 | const tabButtons = [...this.shadowRoot!.querySelectorAll(".tab")] as HTMLButtonElement[];
259 | const tabContents = [...sidebarContent.querySelectorAll("div")] as HTMLDivElement[];
260 |
261 | // Initialize split.js for resizable editor and sidebar
262 | const split = Split([editorEl, sidebar], {
263 | sizes: [100, 0],
264 | minSize: [0, 20],
265 | gutterSize: 7,
266 | snapOffset: 150,
267 | onDragEnd: () => { scope?.onResize(); spectrum?.onResize() },
268 | })
269 |
270 | faustPromise.then(() => runButton.disabled = false);
271 |
272 | // Default sizes for sidebar
273 | const defaultSizes = [70, 30];
274 | let sidebarOpen = false;
275 |
276 | // Function to open the sidebar with predefined sizes
277 | const openSidebar = () => {
278 | if (!sidebarOpen) {
279 | split.setSizes(defaultSizes);
280 | }
281 | sidebarOpen = true;
282 | }
283 |
284 | // Variables for audio and visualization nodes
285 | let node: IFaustMonoWebAudioNode | undefined;
286 | let input: MediaStreamAudioSourceNode | undefined;
287 | let analyser: AnalyserNode | undefined;
288 | let scope: Scope | undefined;
289 | let spectrum: Scope | undefined;
290 | let gmidi = false;
291 | let gnvoices = -1;
292 | let sourceNode: AudioBufferSourceNode | undefined;
293 |
294 | // Counter for compiled DSP
295 | let compiledDSPCounter = 0;
296 | // Counter for compiled SVG
297 | let compiledSVGCounter = 0;
298 |
299 | // Event handler for the run button
300 | runButton.onclick = async () => {
301 | if (audioCtx.state === "suspended") {
302 | await audioCtx.resume();
303 | }
304 | await faustPromise;
305 |
306 | // Compile Faust code
307 | code = editor.state.doc.toString();
308 | let generator = null;
309 | try {
310 | // Compile Faust code to access JSON metadata
311 | await default_generator.compile(compiler, "main", code, "-ftz 2");
312 | const json = default_generator.getMeta();
313 | let { midi, nvoices } = extractMidiAndNvoices(json);
314 | gmidi = midi;
315 | gnvoices = nvoices;
316 |
317 | // Build the generator (possibly reusing default_generator which is a FaustMonoDspGenerator)
318 | generator = nvoices > 0 ? get_poly_generator() : default_generator;
319 | await generator.compile(compiler, "main", code, "-ftz 2");
320 | compiledDSPCounter++;
321 |
322 | } catch (e: any) {
323 | setError(editor, e);
324 | return
325 | }
326 |
327 | // Clear any old errors
328 | clearError(editor);
329 |
330 | // Create an audio node from compiled Faust
331 | if (node !== undefined) node.disconnect();
332 | if (gnvoices > 0) {
333 | node = (await (generator as FaustPolyDspGenerator).createNode(audioCtx, gnvoices))!;
334 | } else {
335 | node = (await (generator as FaustMonoDspGenerator).createNode(audioCtx))!;
336 | }
337 |
338 | // Set up audio input if necessary
339 | if (node.numberOfInputs > 0) {
340 | audioInputSelector.disabled = false;
341 | updateInputDevices(await getInputDevices());
342 | await connectInput();
343 | } else {
344 | audioInputSelector.disabled = true;
345 | audioInputSelector.innerHTML = "";
346 | }
347 | node.connect(audioCtx.destination);
348 | stopButton.disabled = false;
349 | for (const tabButton of tabButtons) {
350 | tabButton.disabled = false;
351 | }
352 |
353 | // Start sensors if available
354 | await node.startSensors();
355 |
356 | // Access MIDI device if available
357 | if (gmidi) {
358 | accessMIDIDevice(midiInputCallback(node))
359 | .then(() => {
360 | console.log('Successfully connected to the MIDI device.');
361 | })
362 | .catch((error) => {
363 | console.error('Error accessing MIDI device:', error.message);
364 | });
365 | }
366 |
367 | openSidebar();
368 |
369 | // Clear old tab contents
370 | for (const tab of tabContents) {
371 | while (tab.lastChild) tab.lastChild.remove();
372 | }
373 | // Create scope & spectrum plots
374 | analyser = new AnalyserNode(audioCtx, {
375 | fftSize: Math.pow(2, 11), minDecibels: -96, maxDecibels: 0, smoothingTimeConstant: 0.85
376 | });
377 | node.connect(analyser);
378 | scope = new Scope(tabContents[2]);
379 | spectrum = new Scope(tabContents[3]);
380 |
381 | // If there are UI elements, open Faust UI (controls tab); otherwise open spectrum analyzer.
382 | const ui = node.getUI();
383 | openTab(ui.length > 1 || ui[0].items.length > 0 ? 0 : 3);
384 |
385 | // Create controls via Faust UI
386 | const faustUI = new FaustUI({ ui, root: faustUIRoot });
387 | faustUI.paramChangeByUI = (path, value) => node?.setParamValue(path, value);
388 | node.setOutputParamHandler((path, value) => faustUI.paramChangeByDSP(path, value));
389 |
390 | // Set editor size to fit UI size
391 | editorEl.style.height = `${Math.max(125, faustUI.minHeight)}px`;
392 | faustUIRoot.style.width = faustUI.minWidth * 1.25 + "px";
393 | faustUIRoot.style.height = faustUI.minHeight * 1.25 + "px";
394 | }
395 |
396 | // Function to set SVG in the block diagram tab
397 | const setSVG = (svgString: string) => {
398 | faustDiagram.innerHTML = svgString;
399 |
400 | for (const a of faustDiagram.querySelectorAll("a")) {
401 | a.onclick = e => {
402 | e.preventDefault();
403 | const filename = (a.href as any as SVGAnimatedString).baseVal;
404 | const svgString = compiler.fs().readFile("main-svg/" + filename, { encoding: "utf8" }) as string;
405 | setSVG(svgString);
406 | }
407 | }
408 | }
409 |
410 | let animPlot: number | undefined;
411 |
412 | // Function to render the scope
413 | const drawScope = () => {
414 | scope!.renderScope([{
415 | analyser: analyser!,
416 | style: "rgb(212, 100, 100)",
417 | edgeThreshold: 0.09,
418 | }])
419 | animPlot = requestAnimationFrame(drawScope);
420 | }
421 |
422 | // Function to render the spectrum
423 | const drawSpectrum = () => {
424 | spectrum!.renderSpectrum(analyser!);
425 | animPlot = requestAnimationFrame(drawSpectrum);
426 | }
427 |
428 | // Function to switch between tabs
429 | const openTab = (i: number) => {
430 | for (const [j, tab] of tabButtons.entries()) {
431 | if (i === j) {
432 | tab.classList.add("active");
433 | tabContents[j].classList.add("active");
434 | } else {
435 | tab.classList.remove("active");
436 | tabContents[j].classList.remove("active");
437 | }
438 | }
439 | // Check if the clicked tab is the "Block Diagram" tab (index 1)
440 | if (i === 1) {
441 | // Check if the SVG has already been compiled for a given DSP
442 | if (compiledSVGCounter !== compiledDSPCounter) {
443 | // Display a "Computing SVG..." message while the SVG is being generated
444 | faustDiagram.innerHTML = "
Computing SVG...
";
445 |
446 | // Use setTimeout to defer the SVG rendering to a separate task
447 | setTimeout(() => {
448 | setSVG(svgDiagrams.from("main", code, "")["process.svg"]);
449 | compiledSVGCounter = compiledDSPCounter;
450 | }, 0);
451 | }
452 | } else if (i === 2) {
453 | scope!.onResize();
454 | if (animPlot !== undefined) cancelAnimationFrame(animPlot);
455 | animPlot = requestAnimationFrame(drawScope);
456 | } else if (i === 3) {
457 | spectrum!.onResize();
458 | if (animPlot !== undefined) cancelAnimationFrame(animPlot);
459 | animPlot = requestAnimationFrame(drawSpectrum);
460 | } else if (animPlot !== undefined) {
461 | cancelAnimationFrame(animPlot);
462 | animPlot = undefined;
463 | }
464 | }
465 |
466 | // Attach event listeners to tab buttons
467 | for (const [i, tabButton] of tabButtons.entries()) {
468 | tabButton.onclick = () => openTab(i);
469 | }
470 |
471 | // Event handler for the stop button
472 | stopButton.onclick = () => {
473 | if (node !== undefined) {
474 | node.disconnect();
475 | node.stopSensors();
476 | node.destroy();
477 | node = undefined;
478 | stopButton.disabled = true;
479 | // TODO: Maybe disable controls in faust-ui tab.
480 | }
481 | }
482 |
483 | // Audio input selector element
484 | const audioInputSelector = this.shadowRoot!.querySelector("#audio-input") as HTMLSelectElement;
485 |
486 | // Update the audio input device list
487 | const updateInputDevices = (devices: MediaDeviceInfo[]) => {
488 | if (audioInputSelector.disabled) return;
489 | while (audioInputSelector.lastChild) audioInputSelector.lastChild.remove();
490 | for (const device of devices) {
491 | if (device.kind === "audioinput") {
492 | audioInputSelector.appendChild(new Option(device.label || device.deviceId, device.deviceId));
493 | }
494 | }
495 | audioInputSelector.appendChild(new Option("Audio File", "Audio File"));
496 | }
497 | deviceUpdateCallbacks.push(updateInputDevices);
498 |
499 | // Connect the selected audio input device
500 | const connectInput = async () => {
501 | const deviceId = audioInputSelector.value;
502 | const stream = await navigator.mediaDevices.getUserMedia({ audio: { deviceId, echoCancellation: false, noiseSuppression: false, autoGainControl: false } });
503 | if (input) {
504 | input.disconnect();
505 | input = undefined;
506 | }
507 | if (node && node.numberOfInputs > 0) {
508 | if (deviceId == "Audio File") {
509 | try {
510 | // Extract the base URL (excluding the script filename)
511 | const scriptTag = document.querySelector('script[src$="faust-web-component.js"]');
512 | const scriptSrc = scriptTag.src;
513 | const baseUrl = scriptSrc.substring(0, scriptSrc.lastIndexOf('/') + 1);
514 | // Load the file
515 | let file = await fetch(baseUrl + '02-XYLO1.mp3');
516 | const arrayBuffer = await file.arrayBuffer();
517 | let audioBuffer = await audioCtx.decodeAudioData(arrayBuffer);
518 | // Create a source node from the buffer
519 | sourceNode = audioCtx.createBufferSource();
520 | sourceNode.buffer = audioBuffer;
521 | sourceNode.connect(node!);
522 | // Start playing the file
523 | sourceNode.start();
524 | } catch (error) {
525 | console.error("Error loading file: ", error);
526 | }
527 | } else {
528 | if (sourceNode !== undefined) {
529 | sourceNode.stop();
530 | sourceNode.disconnect();
531 | sourceNode = undefined;
532 | }
533 | input = audioCtx.createMediaStreamSource(stream);
534 | input.connect(node!);
535 | }
536 | }
537 | }
538 |
539 | audioInputSelector.onchange = connectInput;
540 | }
541 | }
542 |
--------------------------------------------------------------------------------
/COPYING.txt:
--------------------------------------------------------------------------------
1 | faust-web-component
2 | Copyright (C) 2023-2024 GRAME, Centre National de Creation Musicale
3 | ---------------------------------------------------------------------
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU Lesser General Public License as
6 | published by the Free Software Foundation; either version 2.1 of the
7 | License, or (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 |
18 | ----------------------------------------------------------------------------
19 | GNU LESSER GENERAL PUBLIC LICENSE
20 | Version 2.1, February 1999
21 |
22 | Copyright (C) 1991, 1999 Free Software Foundation, Inc.
23 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 | Everyone is permitted to copy and distribute verbatim copies
25 | of this license document, but changing it is not allowed.
26 |
27 | [This is the first released version of the Lesser GPL. It also counts
28 | as the successor of the GNU Library Public License, version 2, hence
29 | the version number 2.1.]
30 |
31 | Preamble
32 |
33 | The licenses for most software are designed to take away your
34 | freedom to share and change it. By contrast, the GNU General Public
35 | Licenses are intended to guarantee your freedom to share and change
36 | free software--to make sure the software is free for all its users.
37 |
38 | This license, the Lesser General Public License, applies to some
39 | specially designated software packages--typically libraries--of the
40 | Free Software Foundation and other authors who decide to use it. You
41 | can use it too, but we suggest you first think carefully about whether
42 | this license or the ordinary General Public License is the better
43 | strategy to use in any particular case, based on the explanations below.
44 |
45 | When we speak of free software, we are referring to freedom of use,
46 | not price. Our General Public Licenses are designed to make sure that
47 | you have the freedom to distribute copies of free software (and charge
48 | for this service if you wish); that you receive source code or can get
49 | it if you want it; that you can change the software and use pieces of
50 | it in new free programs; and that you are informed that you can do
51 | these things.
52 |
53 | To protect your rights, we need to make restrictions that forbid
54 | distributors to deny you these rights or to ask you to surrender these
55 | rights. These restrictions translate to certain responsibilities for
56 | you if you distribute copies of the library or if you modify it.
57 |
58 | For example, if you distribute copies of the library, whether gratis
59 | or for a fee, you must give the recipients all the rights that we gave
60 | you. You must make sure that they, too, receive or can get the source
61 | code. If you link other code with the library, you must provide
62 | complete object files to the recipients, so that they can relink them
63 | with the library after making changes to the library and recompiling
64 | it. And you must show them these terms so they know their rights.
65 |
66 | We protect your rights with a two-step method: (1) we copyright the
67 | library, and (2) we offer you this license, which gives you legal
68 | permission to copy, distribute and/or modify the library.
69 |
70 | To protect each distributor, we want to make it very clear that
71 | there is no warranty for the free library. Also, if the library is
72 | modified by someone else and passed on, the recipients should know
73 | that what they have is not the original version, so that the original
74 | author's reputation will not be affected by problems that might be
75 | introduced by others.
76 |
77 | Finally, software patents pose a constant threat to the existence of
78 | any free program. We wish to make sure that a company cannot
79 | effectively restrict the users of a free program by obtaining a
80 | restrictive license from a patent holder. Therefore, we insist that
81 | any patent license obtained for a version of the library must be
82 | consistent with the full freedom of use specified in this license.
83 |
84 | Most GNU software, including some libraries, is covered by the
85 | ordinary GNU General Public License. This license, the GNU Lesser
86 | General Public License, applies to certain designated libraries, and
87 | is quite different from the ordinary General Public License. We use
88 | this license for certain libraries in order to permit linking those
89 | libraries into non-free programs.
90 |
91 | When a program is linked with a library, whether statically or using
92 | a shared library, the combination of the two is legally speaking a
93 | combined work, a derivative of the original library. The ordinary
94 | General Public License therefore permits such linking only if the
95 | entire combination fits its criteria of freedom. The Lesser General
96 | Public License permits more lax criteria for linking other code with
97 | the library.
98 |
99 | We call this license the "Lesser" General Public License because it
100 | does Less to protect the user's freedom than the ordinary General
101 | Public License. It also provides other free software developers Less
102 | of an advantage over competing non-free programs. These disadvantages
103 | are the reason we use the ordinary General Public License for many
104 | libraries. However, the Lesser license provides advantages in certain
105 | special circumstances.
106 |
107 | For example, on rare occasions, there may be a special need to
108 | encourage the widest possible use of a certain library, so that it becomes
109 | a de-facto standard. To achieve this, non-free programs must be
110 | allowed to use the library. A more frequent case is that a free
111 | library does the same job as widely used non-free libraries. In this
112 | case, there is little to gain by limiting the free library to free
113 | software only, so we use the Lesser General Public License.
114 |
115 | In other cases, permission to use a particular library in non-free
116 | programs enables a greater number of people to use a large body of
117 | free software. For example, permission to use the GNU C Library in
118 | non-free programs enables many more people to use the whole GNU
119 | operating system, as well as its variant, the GNU/Linux operating
120 | system.
121 |
122 | Although the Lesser General Public License is Less protective of the
123 | users' freedom, it does ensure that the user of a program that is
124 | linked with the Library has the freedom and the wherewithal to run
125 | that program using a modified version of the Library.
126 |
127 | The precise terms and conditions for copying, distribution and
128 | modification follow. Pay close attention to the difference between a
129 | "work based on the library" and a "work that uses the library". The
130 | former contains code derived from the library, whereas the latter must
131 | be combined with the library in order to run.
132 |
133 | GNU LESSER GENERAL PUBLIC LICENSE
134 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
135 |
136 | 0. This License Agreement applies to any software library or other
137 | program which contains a notice placed by the copyright holder or
138 | other authorized party saying it may be distributed under the terms of
139 | this Lesser General Public License (also called "this License").
140 | Each licensee is addressed as "you".
141 |
142 | A "library" means a collection of software functions and/or data
143 | prepared so as to be conveniently linked with application programs
144 | (which use some of those functions and data) to form executables.
145 |
146 | The "Library", below, refers to any such software library or work
147 | which has been distributed under these terms. A "work based on the
148 | Library" means either the Library or any derivative work under
149 | copyright law: that is to say, a work containing the Library or a
150 | portion of it, either verbatim or with modifications and/or translated
151 | straightforwardly into another language. (Hereinafter, translation is
152 | included without limitation in the term "modification".)
153 |
154 | "Source code" for a work means the preferred form of the work for
155 | making modifications to it. For a library, complete source code means
156 | all the source code for all modules it contains, plus any associated
157 | interface definition files, plus the scripts used to control compilation
158 | and installation of the library.
159 |
160 | Activities other than copying, distribution and modification are not
161 | covered by this License; they are outside its scope. The act of
162 | running a program using the Library is not restricted, and output from
163 | such a program is covered only if its contents constitute a work based
164 | on the Library (independent of the use of the Library in a tool for
165 | writing it). Whether that is true depends on what the Library does
166 | and what the program that uses the Library does.
167 |
168 | 1. You may copy and distribute verbatim copies of the Library's
169 | complete source code as you receive it, in any medium, provided that
170 | you conspicuously and appropriately publish on each copy an
171 | appropriate copyright notice and disclaimer of warranty; keep intact
172 | all the notices that refer to this License and to the absence of any
173 | warranty; and distribute a copy of this License along with the
174 | Library.
175 |
176 | You may charge a fee for the physical act of transferring a copy,
177 | and you may at your option offer warranty protection in exchange for a
178 | fee.
179 |
180 | 2. You may modify your copy or copies of the Library or any portion
181 | of it, thus forming a work based on the Library, and copy and
182 | distribute such modifications or work under the terms of Section 1
183 | above, provided that you also meet all of these conditions:
184 |
185 | a) The modified work must itself be a software library.
186 |
187 | b) You must cause the files modified to carry prominent notices
188 | stating that you changed the files and the date of any change.
189 |
190 | c) You must cause the whole of the work to be licensed at no
191 | charge to all third parties under the terms of this License.
192 |
193 | d) If a facility in the modified Library refers to a function or a
194 | table of data to be supplied by an application program that uses
195 | the facility, other than as an argument passed when the facility
196 | is invoked, then you must make a good faith effort to ensure that,
197 | in the event an application does not supply such function or
198 | table, the facility still operates, and performs whatever part of
199 | its purpose remains meaningful.
200 |
201 | (For example, a function in a library to compute square roots has
202 | a purpose that is entirely well-defined independent of the
203 | application. Therefore, Subsection 2d requires that any
204 | application-supplied function or table used by this function must
205 | be optional: if the application does not supply it, the square
206 | root function must still compute square roots.)
207 |
208 | These requirements apply to the modified work as a whole. If
209 | identifiable sections of that work are not derived from the Library,
210 | and can be reasonably considered independent and separate works in
211 | themselves, then this License, and its terms, do not apply to those
212 | sections when you distribute them as separate works. But when you
213 | distribute the same sections as part of a whole which is a work based
214 | on the Library, the distribution of the whole must be on the terms of
215 | this License, whose permissions for other licensees extend to the
216 | entire whole, and thus to each and every part regardless of who wrote
217 | it.
218 |
219 | Thus, it is not the intent of this section to claim rights or contest
220 | your rights to work written entirely by you; rather, the intent is to
221 | exercise the right to control the distribution of derivative or
222 | collective works based on the Library.
223 |
224 | In addition, mere aggregation of another work not based on the Library
225 | with the Library (or with a work based on the Library) on a volume of
226 | a storage or distribution medium does not bring the other work under
227 | the scope of this License.
228 |
229 | 3. You may opt to apply the terms of the ordinary GNU General Public
230 | License instead of this License to a given copy of the Library. To do
231 | this, you must alter all the notices that refer to this License, so
232 | that they refer to the ordinary GNU General Public License, version 2,
233 | instead of to this License. (If a newer version than version 2 of the
234 | ordinary GNU General Public License has appeared, then you can specify
235 | that version instead if you wish.) Do not make any other change in
236 | these notices.
237 |
238 | Once this change is made in a given copy, it is irreversible for
239 | that copy, so the ordinary GNU General Public License applies to all
240 | subsequent copies and derivative works made from that copy.
241 |
242 | This option is useful when you wish to copy part of the code of
243 | the Library into a program that is not a library.
244 |
245 | 4. You may copy and distribute the Library (or a portion or
246 | derivative of it, under Section 2) in object code or executable form
247 | under the terms of Sections 1 and 2 above provided that you accompany
248 | it with the complete corresponding machine-readable source code, which
249 | must be distributed under the terms of Sections 1 and 2 above on a
250 | medium customarily used for software interchange.
251 |
252 | If distribution of object code is made by offering access to copy
253 | from a designated place, then offering equivalent access to copy the
254 | source code from the same place satisfies the requirement to
255 | distribute the source code, even though third parties are not
256 | compelled to copy the source along with the object code.
257 |
258 | 5. A program that contains no derivative of any portion of the
259 | Library, but is designed to work with the Library by being compiled or
260 | linked with it, is called a "work that uses the Library". Such a
261 | work, in isolation, is not a derivative work of the Library, and
262 | therefore falls outside the scope of this License.
263 |
264 | However, linking a "work that uses the Library" with the Library
265 | creates an executable that is a derivative of the Library (because it
266 | contains portions of the Library), rather than a "work that uses the
267 | library". The executable is therefore covered by this License.
268 | Section 6 states terms for distribution of such executables.
269 |
270 | When a "work that uses the Library" uses material from a header file
271 | that is part of the Library, the object code for the work may be a
272 | derivative work of the Library even though the source code is not.
273 | Whether this is true is especially significant if the work can be
274 | linked without the Library, or if the work is itself a library. The
275 | threshold for this to be true is not precisely defined by law.
276 |
277 | If such an object file uses only numerical parameters, data
278 | structure layouts and accessors, and small macros and small inline
279 | functions (ten lines or less in length), then the use of the object
280 | file is unrestricted, regardless of whether it is legally a derivative
281 | work. (Executables containing this object code plus portions of the
282 | Library will still fall under Section 6.)
283 |
284 | Otherwise, if the work is a derivative of the Library, you may
285 | distribute the object code for the work under the terms of Section 6.
286 | Any executables containing that work also fall under Section 6,
287 | whether or not they are linked directly with the Library itself.
288 |
289 | 6. As an exception to the Sections above, you may also combine or
290 | link a "work that uses the Library" with the Library to produce a
291 | work containing portions of the Library, and distribute that work
292 | under terms of your choice, provided that the terms permit
293 | modification of the work for the customer's own use and reverse
294 | engineering for debugging such modifications.
295 |
296 | You must give prominent notice with each copy of the work that the
297 | Library is used in it and that the Library and its use are covered by
298 | this License. You must supply a copy of this License. If the work
299 | during execution displays copyright notices, you must include the
300 | copyright notice for the Library among them, as well as a reference
301 | directing the user to the copy of this License. Also, you must do one
302 | of these things:
303 |
304 | a) Accompany the work with the complete corresponding
305 | machine-readable source code for the Library including whatever
306 | changes were used in the work (which must be distributed under
307 | Sections 1 and 2 above); and, if the work is an executable linked
308 | with the Library, with the complete machine-readable "work that
309 | uses the Library", as object code and/or source code, so that the
310 | user can modify the Library and then relink to produce a modified
311 | executable containing the modified Library. (It is understood
312 | that the user who changes the contents of definitions files in the
313 | Library will not necessarily be able to recompile the application
314 | to use the modified definitions.)
315 |
316 | b) Use a suitable shared library mechanism for linking with the
317 | Library. A suitable mechanism is one that (1) uses at run time a
318 | copy of the library already present on the user's computer system,
319 | rather than copying library functions into the executable, and (2)
320 | will operate properly with a modified version of the library, if
321 | the user installs one, as long as the modified version is
322 | interface-compatible with the version that the work was made with.
323 |
324 | c) Accompany the work with a written offer, valid for at
325 | least three years, to give the same user the materials
326 | specified in Subsection 6a, above, for a charge no more
327 | than the cost of performing this distribution.
328 |
329 | d) If distribution of the work is made by offering access to copy
330 | from a designated place, offer equivalent access to copy the above
331 | specified materials from the same place.
332 |
333 | e) Verify that the user has already received a copy of these
334 | materials or that you have already sent this user a copy.
335 |
336 | For an executable, the required form of the "work that uses the
337 | Library" must include any data and utility programs needed for
338 | reproducing the executable from it. However, as a special exception,
339 | the materials to be distributed need not include anything that is
340 | normally distributed (in either source or binary form) with the major
341 | components (compiler, kernel, and so on) of the operating system on
342 | which the executable runs, unless that component itself accompanies
343 | the executable.
344 |
345 | It may happen that this requirement contradicts the license
346 | restrictions of other proprietary libraries that do not normally
347 | accompany the operating system. Such a contradiction means you cannot
348 | use both them and the Library together in an executable that you
349 | distribute.
350 |
351 | 7. You may place library facilities that are a work based on the
352 | Library side-by-side in a single library together with other library
353 | facilities not covered by this License, and distribute such a combined
354 | library, provided that the separate distribution of the work based on
355 | the Library and of the other library facilities is otherwise
356 | permitted, and provided that you do these two things:
357 |
358 | a) Accompany the combined library with a copy of the same work
359 | based on the Library, uncombined with any other library
360 | facilities. This must be distributed under the terms of the
361 | Sections above.
362 |
363 | b) Give prominent notice with the combined library of the fact
364 | that part of it is a work based on the Library, and explaining
365 | where to find the accompanying uncombined form of the same work.
366 |
367 | 8. You may not copy, modify, sublicense, link with, or distribute
368 | the Library except as expressly provided under this License. Any
369 | attempt otherwise to copy, modify, sublicense, link with, or
370 | distribute the Library is void, and will automatically terminate your
371 | rights under this License. However, parties who have received copies,
372 | or rights, from you under this License will not have their licenses
373 | terminated so long as such parties remain in full compliance.
374 |
375 | 9. You are not required to accept this License, since you have not
376 | signed it. However, nothing else grants you permission to modify or
377 | distribute the Library or its derivative works. These actions are
378 | prohibited by law if you do not accept this License. Therefore, by
379 | modifying or distributing the Library (or any work based on the
380 | Library), you indicate your acceptance of this License to do so, and
381 | all its terms and conditions for copying, distributing or modifying
382 | the Library or works based on it.
383 |
384 | 10. Each time you redistribute the Library (or any work based on the
385 | Library), the recipient automatically receives a license from the
386 | original licensor to copy, distribute, link with or modify the Library
387 | subject to these terms and conditions. You may not impose any further
388 | restrictions on the recipients' exercise of the rights granted herein.
389 | You are not responsible for enforcing compliance by third parties with
390 | this License.
391 |
392 | 11. If, as a consequence of a court judgment or allegation of patent
393 | infringement or for any other reason (not limited to patent issues),
394 | conditions are imposed on you (whether by court order, agreement or
395 | otherwise) that contradict the conditions of this License, they do not
396 | excuse you from the conditions of this License. If you cannot
397 | distribute so as to satisfy simultaneously your obligations under this
398 | License and any other pertinent obligations, then as a consequence you
399 | may not distribute the Library at all. For example, if a patent
400 | license would not permit royalty-free redistribution of the Library by
401 | all those who receive copies directly or indirectly through you, then
402 | the only way you could satisfy both it and this License would be to
403 | refrain entirely from distribution of the Library.
404 |
405 | If any portion of this section is held invalid or unenforceable under any
406 | particular circumstance, the balance of the section is intended to apply,
407 | and the section as a whole is intended to apply in other circumstances.
408 |
409 | It is not the purpose of this section to induce you to infringe any
410 | patents or other property right claims or to contest validity of any
411 | such claims; this section has the sole purpose of protecting the
412 | integrity of the free software distribution system which is
413 | implemented by public license practices. Many people have made
414 | generous contributions to the wide range of software distributed
415 | through that system in reliance on consistent application of that
416 | system; it is up to the author/donor to decide if he or she is willing
417 | to distribute software through any other system and a licensee cannot
418 | impose that choice.
419 |
420 | This section is intended to make thoroughly clear what is believed to
421 | be a consequence of the rest of this License.
422 |
423 | 12. If the distribution and/or use of the Library is restricted in
424 | certain countries either by patents or by copyrighted interfaces, the
425 | original copyright holder who places the Library under this License may add
426 | an explicit geographical distribution limitation excluding those countries,
427 | so that distribution is permitted only in or among countries not thus
428 | excluded. In such case, this License incorporates the limitation as if
429 | written in the body of this License.
430 |
431 | 13. The Free Software Foundation may publish revised and/or new
432 | versions of the Lesser General Public License from time to time.
433 | Such new versions will be similar in spirit to the present version,
434 | but may differ in detail to address new problems or concerns.
435 |
436 | Each version is given a distinguishing version number. If the Library
437 | specifies a version number of this License which applies to it and
438 | "any later version", you have the option of following the terms and
439 | conditions either of that version or of any later version published by
440 | the Free Software Foundation. If the Library does not specify a
441 | license version number, you may choose any version ever published by
442 | the Free Software Foundation.
443 |
444 | 14. If you wish to incorporate parts of the Library into other free
445 | programs whose distribution conditions are incompatible with these,
446 | write to the author to ask for permission. For software which is
447 | copyrighted by the Free Software Foundation, write to the Free
448 | Software Foundation; we sometimes make exceptions for this. Our
449 | decision will be guided by the two goals of preserving the free status
450 | of all derivatives of our free software and of promoting the sharing
451 | and reuse of software generally.
452 |
453 | NO WARRANTY
454 |
455 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
456 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
457 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
458 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
459 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
460 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
461 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
462 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
463 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
464 |
465 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
466 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
467 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
468 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
469 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
470 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
471 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
472 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
473 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
474 | DAMAGES.
475 |
476 | END OF TERMS AND CONDITIONS
477 |
478 | How to Apply These Terms to Your New Libraries
479 |
480 | If you develop a new library, and you want it to be of the greatest
481 | possible use to the public, we recommend making it free software that
482 | everyone can redistribute and change. You can do so by permitting
483 | redistribution under these terms (or, alternatively, under the terms of the
484 | ordinary General Public License).
485 |
486 | To apply these terms, attach the following notices to the library. It is
487 | safest to attach them to the start of each source file to most effectively
488 | convey the exclusion of warranty; and each file should have at least the
489 | "copyright" line and a pointer to where the full notice is found.
490 |
491 |
492 | Copyright (C)
493 |
494 | This library is free software; you can redistribute it and/or
495 | modify it under the terms of the GNU Lesser General Public
496 | License as published by the Free Software Foundation; either
497 | version 2.1 of the License, or (at your option) any later version.
498 |
499 | This library is distributed in the hope that it will be useful,
500 | but WITHOUT ANY WARRANTY; without even the implied warranty of
501 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
502 | Lesser General Public License for more details.
503 |
504 | You should have received a copy of the GNU Lesser General Public
505 | License along with this library; if not, write to the Free Software
506 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
507 |
508 | Also add information on how to contact you by electronic and paper mail.
509 |
510 | You should also get your employer (if you work as a programmer) or your
511 | school, if any, to sign a "copyright disclaimer" for the library, if
512 | necessary. Here is a sample; alter the names:
513 |
514 | Yoyodyne, Inc., hereby disclaims all copyright interest in the
515 | library `Frob' (a library for tweaking knobs) written by James Random Hacker.
516 |
517 | , 1 April 1990
518 | Ty Coon, President of Vice
519 |
520 | That's all there is to it!
521 |
--------------------------------------------------------------------------------