Showing preview only (7,636K chars total). Download the full file or copy to clipboard to get everything.
Repository: tmhglnd/mercury
Branch: master
Commit: b61aabcfba9c
Files: 239
Total size: 7.2 MB
Directory structure:
gitextract_ao7h6v4s/
├── .gitignore
├── .gitmodules
├── LICENSE
├── README.md
├── docs/
│ └── deprecated-docs/
│ ├── 00-general.md
│ ├── 01-global.md
│ ├── 02-instrument.md
│ ├── 03-emitter.md
│ ├── 04-fx.md
│ ├── 05-ring.md
│ ├── 06-shortkeys.md
│ ├── 07-environment.md
│ ├── 08-troubleshooting.md
│ ├── 09-visuals.md
│ ├── 10-includes.md
│ ├── README.md
│ ├── _config.yml
│ ├── collaborate.md
│ ├── linux-guide.md
│ ├── quick-start.md
│ ├── reference.md
│ ├── table-of-content.md
│ └── tutorial.md
├── examples/
│ ├── 00_sample-and-time.txt
│ ├── 01_offset-in-time.txt
│ ├── 02_linear-beat.txt
│ ├── 03_sample-scrubbing.txt
│ ├── 04_possibility-rhythm.txt
│ ├── 05_synth-and-note.txt
│ ├── 06_generative-melody.txt
│ └── 07_granular-playback.txt
├── examples-basic/
│ ├── 01-sample.txt
│ ├── 02-tempo.txt
│ ├── 03-time.txt
│ ├── 04-offset.txt
│ ├── 05-rhythm-ring.txt
│ ├── 06-probability.txt
│ ├── 07-synth.txt
│ ├── 08-two-notes.txt
│ ├── 09-melody-ring.txt
│ ├── 10-scale.txt
│ ├── 11-shape.txt
│ └── 12-fx.txt
├── grammar/
│ ├── .gitignore
│ ├── README.md
│ ├── data/
│ │ ├── bind-functions.json
│ │ ├── bind-instruments.json
│ │ ├── function-parse.js
│ │ ├── instrument-methods.json
│ │ ├── mini-functions.json
│ │ └── objects.js
│ ├── grammar.js
│ ├── mercury.ne
│ ├── mercuryIR.js
│ ├── package.json
│ ├── parser.js
│ ├── src/
│ │ └── dict.js
│ ├── test/
│ │ ├── grammar-example.txt
│ │ ├── mercuryAST.json
│ │ ├── mercuryIR.json
│ │ ├── ring-test.txt
│ │ └── synth-test.txt
│ └── totalSerialismIR.js
└── mercury_ide/
├── .vscode/
│ └── settings.json
├── _deprecated/
│ ├── argBindings.txt
│ ├── arr2dTo1d.maxpat
│ ├── beatSyncSystem.maxpat
│ ├── bind-functions.txt
│ ├── codeParser.js
│ ├── dspLib.genexpr
│ ├── ease.mxe64
│ ├── ease.mxo/
│ │ └── Contents/
│ │ ├── Info.plist
│ │ ├── MacOS/
│ │ │ └── ease
│ │ └── PkgInfo
│ ├── editor.maxpat
│ ├── fb-delay.gendsp
│ ├── ladder~.maxpat
│ ├── listLib.js
│ ├── moogLadderFilter.genexpr
│ ├── noise.genjit
│ ├── phasorRate.gendsp
│ ├── recursiveFolder.js
│ ├── samples.json
│ ├── soundObjectShapeJitter.maxpat
│ ├── textScale.maxpat
│ ├── textToMtx.js
│ └── tokens.txt
├── code/
│ ├── dictionary.js
│ ├── editor.js
│ ├── editorGL.js
│ ├── lexer.js
│ ├── mercury.js
│ ├── package.json
│ ├── parser.js
│ └── preferences.js
├── data/
│ ├── bind-functions.gen.json
│ ├── bind-functions.json
│ ├── binding-instruments.json
│ ├── initials.json
│ ├── mini-functions.json
│ ├── scales.txt
│ └── tonics.txt
├── dev/
│ ├── fx-dev.txt
│ ├── grammar-dev.txt
│ ├── kick-dev.txt
│ ├── midi-dev.txt
│ ├── new-list-functions.txt
│ ├── osc-dev-code.txt
│ ├── osc-digilog.txt
│ ├── osc-receive.maxpat
│ ├── osc-receive.txt
│ ├── osc-receiver.maxpat
│ ├── ring-dev-scale-map.txt
│ ├── ring-dev.txt
│ ├── sample-dev.txt
│ ├── sample-test.txt
│ ├── solo-instruments.maxpat
│ ├── string-dev.txt
│ ├── synth-dev.txt
│ ├── synth-test.txt
│ ├── util-dev.txt
│ └── visual-dev.txt
├── external/
│ ├── aka.speech.mxo/
│ │ └── Contents/
│ │ ├── Info.plist
│ │ ├── MacOS/
│ │ │ └── aka.speech
│ │ ├── PkgInfo
│ │ ├── Resources/
│ │ │ └── maxmspsdk.xcconfig
│ │ └── _CodeSignature/
│ │ └── CodeResources
│ ├── clockwarp.gendsp
│ ├── cv.jit.resize.mxe64
│ ├── cv.jit.resize.mxo/
│ │ └── Contents/
│ │ ├── Info.plist
│ │ ├── MacOS/
│ │ │ └── cv.jit.resize
│ │ └── PkgInfo
│ ├── dyn-range-comp.genexpr
│ ├── hidecursor.maxpat
│ ├── jit.gl.spoutreceiver.mxe64
│ ├── jit.gl.spoutsender.mxe64
│ ├── moogLadderFilter.genexpr
│ ├── shortkeys.json
│ ├── th.clockwarp~.maxpat
│ ├── th.comp~.maxpat
│ ├── th.gl.editor.js
│ ├── th.gl.texteditor.maxpat
│ └── th.yafr~.maxpat
├── fonts/
│ ├── IBM_Plex_Mono/
│ │ └── OFL.txt
│ ├── Roboto_Mono/
│ │ └── LICENSE.txt
│ ├── Source_Code_Pro/
│ │ └── OFL.txt
│ ├── Space_Mono/
│ │ └── OFL.txt
│ ├── Ubuntu_Mono/
│ │ └── UFL.txt
│ └── VT323/
│ └── OFL.txt
├── icon/
│ ├── README.md
│ ├── icon.icns
│ └── mercury_icon.psd
├── media/
│ ├── README.md
│ └── images/
│ └── planet_colors.jit
├── mercury_ide.maxproj
└── patchers/
├── _mercury_main.maxpat
├── _mercury_visuals.maxpat
├── analyseDisplay.maxpat
├── argGetList.maxpat
├── argListLookup.maxpat
├── calcExpr.maxpat
├── consoleLog.maxpat
├── divToMs.maxpat
├── drywet~.maxpat
├── emptyScene.maxpat
├── envelopeGen.maxpat
├── eventSequencer.maxpat
├── fftCatch~.maxpat
├── fftCross~.maxpat
├── fftFreeze~.maxpat
├── fxChorus.maxpat
├── fxComb.maxpat
├── fxCompress.maxpat
├── fxDegrade.maxpat
├── fxDelay.maxpat
├── fxDrive.maxpat
├── fxEnvelopeFilter.maxpat
├── fxFilter.maxpat
├── fxFreeze.maxpat
├── fxFuzz.maxpat
├── fxKink.maxpat
├── fxLFO.maxpat
├── fxLadderFilter.maxpat
├── fxLoopDelay.maxpat
├── fxMorph.maxpat
├── fxPitchShift.maxpat
├── fxRetune.maxpat
├── fxReverb.maxpat
├── fxRing.maxpat
├── fxSquash.maxpat
├── fxStutter.maxpat
├── fxTriggerFilter.maxpat
├── fxVibrato.maxpat
├── fxVocoder.maxpat
├── fxVocoderBand.maxpat
├── fxVowel.maxpat
├── getVariables.maxpat
├── gtep.maxpat
├── keyPressed.maxpat
├── mcy.buffers~.maxpat
├── midiToOSC.maxpat
├── modulatorObject~.maxpat
├── newInstance.maxpat
├── noteToMidi.maxpat
├── planetaryMotion.maxpat
├── probList.maxpat
├── probTrig.maxpat
├── setupAudio.maxpat
├── setupEditor.maxpat
├── setupShortkeys.maxpat
├── setupVisuals.maxpat
├── soundObject.maxpat
├── srcExtension.maxpat
├── srcFmSynth.maxpat
├── srcInput.maxpat
├── srcKarplus.maxpat
├── srcKick.maxpat
├── srcNoise.maxpat
├── srcPolySample.maxpat
├── srcSample.maxpat
├── srcSampleRack.maxpat
├── srcSynth.maxpat
├── srcWavetable.maxpat
├── srcWrapper.maxpat
├── strange-attractor.maxpat
├── syncToScale.maxpat
├── synthPoly.maxpat
├── visual/
│ ├── circling.maxpat
│ ├── cubes.maxpat
│ ├── mesh.maxpat
│ ├── meshes.maxpat
│ ├── meshwave.maxpat
│ ├── pillars.maxpat
│ ├── plane.maxpat
│ ├── shape.maxpat
│ ├── syphon.maxpat
│ └── template.maxpat
├── visualObject.maxpat
└── wavetablePlayer.maxpat
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# ignore DS_Store
.DS_Store
# ignore the mercury.ini file, this is autogenerated
mercury_ide/mercury.ini
================================================
FILE: .gitmodules
================================================
[submodule "mercury-docs"]
path = docs/mercury-docs
url = https://github.com/tmhglnd/mercury-docs
[submodule "docs/mercury-docs"]
path = docs/mercury-docs
url = https://github.com/tmhglnd/mercury-docs
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: README.md
================================================
# 🌕 Mercury Live Coding Environment
**Welcome to Mercury! ✌️ ☮️ Make Music, Not War!** ☮️ ✌️
**Mercury is a free/open-source, beginner-friendly, minimal and human-readable language for the live coding of algorithmic electronic music performances**
Mercury currently has 2 versions:
* Original version running in Max8 (Windows/Mac only) (you're in the right place)
* Web version running in the browser (Windows/Mac/Linux) [go to this repo](https://github.com/tmhglnd/mercury-playground)
**🚀 Start coding with the latest version:**
`git clone https://github.com/tmhglnd/mercury.git`
[**👾 Start coding directly in the playground!** (recommended for beginners)](https://mercury.timohoogland.com/)
[**🙏 Support Mercury by buying me a coffee ko-fi**](https://ko-fi.com/tmhglnd)
[**💬 Join the Discord Community!**](https://discord.gg/vt59NYU)

## 📋 Table of Contents
<!-- - [Newest Features](#-newest-features) -->
- 📟 [Mercury?](#-about)
- 🎮 [What can I do with Mercury?](#-features-overview)
- 👩💻 [Code together with others!](#-collaborative-coding)
- 🚀 [Let's get started!](#-install)
- [Quick Start](#-install)
- [Tutorial](https://tmhglnd.github.io/mercury/docs/usage/coding)
- [External Editor](#️-external-editor)
- [Documentation](https://tmhglnd.github.io/mercury/docs/)
- [Troubleshooting](#-troubleshooting)
- [Sounds in Mercury](#-sounds)
<!-- - [Build Application](#-build-application) -->
- 🔎 [Read more](#-further-reading)
- 👾 [Hear what others made](#-made-with-mercury)
- 🤓 [I like to help](#-contribute)
- 🔋 [Powered By](#-powered-by)
- 🙏 [Thanks](#-thanks)
- ✨ [Inspiration](#-inspiration)
- 📄 [Licenses](#-licenses)
<!-- ## Newest Features
**Control external midi devices or send midi to other Applications with the new `midi` instrument**
```java
set midi getPorts
//=> prints the available devices to the console
new midi "Your Awesome Midi Device" time(1/4) note(7 1) length(100) gain(0.8)
```
**Input OSC addresses as arguments or output osc-messages in a similar way as using instruments**
```java
set osc default
new synth sine name(sn)
set sn note(/sine/pitch 0) shape(5 /sine/release)
set sn fx(reverb 1 /sine/verb)
new emitter osc name(myOSC) someParam(3.14)
// result => /myOsc/someParam 3.14
``` -->
## 📟 About
**Mercury is a free/open-source, beginner-friendly, minimal and human-readable language for the live coding of algorithmic electronic music**
All elements of the language are designed around making code more accessible and less obfuscating for the audience. This motivation stretches down to the coding style itself which uses clear descriptive names for functions and a clear syntax. Furthermore the editor is restricted to 30 lines of code, keeping all code always visible. Mercury provides the performer with an extensive library of algorithms to generate or transform numbersequences that can modulate parameters, such as melody and rhythm, over time. The environment produces sound in conjunction with visuals. Besides looking at the code, the audience is also looking at the visuals that are reactive to the sound or generated by the sound.
It is named after te planet Mercury. Mercury rules the creation and expression of our mental processes. The planet implores us to express ourselves. Mercury is about a quick wit, quick thinking. It lets us move from one thing to the next.

## 🎮 Features Overview
Quick access to playback of samples and change timing and tempo of samples or synthesizers
```java
set tempo 89
new sample kick_909 time(1/4)
new sample hat_909 time(3/16)
```
Make rhythmic patterns with sequences of numbers and probabilities
```java
list loBeat [1 0 0 1 0.5]
list hiBeat [0 1 0.2 0]
new sample tabla_lo time(1/8) play(loBeat)
new sample tabla_hi time(1/8) play(hiBeat)
```
Generate psuedorandom melodic content for a synthesizer in a range and set a scale
```java
set scale minor d
set randomSeed 31415
list melody random(16 0 24)
new synth saw note(melody) time(1/16) shape(4 100)
```
Design sounds with various effects
```java
new sample chimes time(2) speed(-0.25) fx(reverb 0.3 15) fx(drive 10) fx(lfo 1/8 sine)
```
Easily give multiple instruments the same effects
```java
new sample chimes time(2)
new sample harp_down time(3)
new sample gong_lo time(5)
set all fx(lfo 1/16) fx(delay) fx(reverb 0.5 11)
```
Generate sequences algorithmically to compose complex structures and choose from an extensive library of algorithms to work with
```java
set scale minor a
list rhythm euclidean(32 13)
list melody spread(5 0 24)
list melody palinedrome(melody)
list melody clone(melody 0 5 7 3)
list melody lace(melody melody)
new synth triangle note(melody 1) shape(1 80) play(rhythm)
```
Control external midi devices or send midi to other applications and use clock sync
```java
set midi getPorts
//=> prints the available devices to the console
new midi "Your Awesome Midi Device" time(1/4) note(7 1) length(100) sync(on)
```
Control other environments via OSC-messages
```java
list params [0.25 0.5 0.75]
new emitter osc address(yourDevice) theParam(params) time(1/4)
// emits => /yourDevice/theParam 0.25
// /yourDevice/theParam 0.5
// /yourDevice/theParam 0.75
// /yourDevice/theParam 0.25
// etc...
```
Easily control parameters in Mercury via external OSC-messages
```java
new synth triangle fx(reverb '/extOSC/verbAmount') fx(filter low '/extOSC/cutoff' 0.4) time(1) shape(1 1000)
```
**AND MANY MORE (TO COME...)**
⭐️ *watch and star this repo to keep up-to-date with the latest changes whenever they're made*
## 👩💻👨💻 Collaborative Coding
You can code together in Mercury by using the amazing [**Flok**](https://flok.cc/) live coding environment for the browser developed by Damián Silvani (a.k.a. Munshkr). Flok is a web-based P2P collaborative editor for live coding music and graphics. Similar to Etherpad, but focused on code evaluation for livecoding.
- [Start coding together here](https://tmhglnd.github.io/mercury/docs/collaborate)
## 💻 Install
- 📖 [I need some help installing](https://tmhglnd.github.io/mercury/docs/getting-started#-mercury4max)
- 🚀 [I'm an experienced computer user](https://tmhglnd.github.io/mercury/docs/getting-started#-mercury4max)
- 💻 [Is my computer powerful enough?](https://tmhglnd.github.io/mercury/docs/getting-started#-system-requirements)
OR
- 🤓 I'll just download and figure it out myself
```
$ cd ~/Documents/Max\ 8/Projects
$ git clone http://github.com/tmhglnd/mercury
$ cd mercury
$ open mercury_ide/mercury_ide.maxproj
```
### ⚠ Troubleshooting
It could be that you are having issues with Mercury. Please follow the steps below:
- [Open the Troubleshooting](https://tmhglnd.github.io/mercury/docs/usage/troubleshooting)
### ⌨️ External Editor
Instead of using the editor built in the Max Mercury version you can also load an external textfile or use a plugin for Pulsar (previously Atom).
- [Follow the instructions here for the Pulsar Plugin](https://tmhglnd.github.io/mercury/docs/usage/editors)
- [Follow the instructions here for other editors](https://tmhglnd.github.io/mercury/docs/usage/editors)
### 📖 Documentation
Full documentation of everything you can do in Mercury:
- [Open the documentation](https://tmhglnd.github.io/mercury/docs)
### 🎵 Sounds
Most of the sounds in Mercury are from [freesound.org](http://www.freesound.org) and are licensed with Creative Commons Attribution or Creative Commons 0 licenses. If not downloaded from freesound it is made sure that the license allows you to redistribute the sounds via the Mercury environment and that you can use them in your projects. All the sounds are listed below with their original source, license and credits.
- [List of sounds and credits](https://tmhglnd.github.io/mercury/docs/usage/sounds)
## 🔍 Further reading
[A list of other reading material and inspiration](https://tmhglnd.github.io/mercury/docs/about/inspiration#-further-reading)
## 👾 Made with Mercury
*Made something with Mercury? Please add a URL here and send a pull request!* 😎
[**See the full list here**](https://tmhglnd.github.io/mercury/docs/about/inspiration)
### Small selection
- [iTypeMusic - Electronic Music Stream with Live Coding](https://www.youtube.com/watch?v=x77RP20uWxA&ab_channel=itypemusic)
- [LXT @levoxtrip (at Solstice Stream December 2023)](https://www.youtube.com/watch?v=TzM-koWkRow&ab_channel=Eulerroom)
- [Linalab(Mercury) + Turbulente(p5Live) - Live at Algorave Lisbon](https://youtu.be/WSPNDC0a2X4)
- [T.mo - Liber Abaci (Mercury Coding Sessions)](https://youtu.be/syUL76qCV6w)
- [Roald van Dillewijn - Smashing Temparateness (Mercury Coding Sessions)](https://youtu.be/KJ4OpJ3-Ik0)
- [Guillem Góngora Moral - Transcription #1 (Mercury Coding Sessions)](https://youtu.be/wRVQHlghitM)
- [Anne Veinberg - CodeKlavier meets Mercury (Mercury Coding Sessions)](https://youtu.be/e4sPKOlaYS8)
- [Nick Levantis - Wake Up](https://youtu.be/UsfKF0ggn7k)
## 📝 Contribute
Contributions to the Mercury environment are much appreciated in whatever form they come! You can contribute in any many ways!
[Please follow the steps here](https://tmhglnd.github.io/mercury/docs/contribute)
## 🔋 Powered By
- Mercury has been granted funding from [**Creative Industries Fund NL**](https://stimuleringsfonds.nl/en/)
- Mercury has been granted in-kind funding from [**Creative Coding Utrecht**](https://creativecodingutrecht.nl/)
## 🙏 Thanks
- [Lina Bautista](https://axolot.cat/about/lina-bautista/) for working together on developing functionalities in Mercury to control modular synths via cv
- [SEMA/MIMIC project](https://mimicproject.com/about) team (Thor Magnusson, Chris Kiefer and Francisco Bernardo) for their awesome full week workshop at Sussex University in Brighton on designing a live coding language in the browser combined with machine learning
- [Roald van Dillewijn](https://roaldvandillewijn.nl/) for working together on osc and midi functionalities combined with his [Digilog modified guitar-pedals](https://roaldvandillewijn.nl/projects/digilog)
- [Guillem Gongora Moral](https://www.guillemgongora.com/) for using Mercury as a composition tool and sharing valuable feedback in the process
- [Anne Veinberg](https://anneveinberg.com/) for working with Mercury and a Mercury extensions for the [CodeKlavier](https://codeklavier.space/) project
- [Rafaele Maria Andrade](https://www.rafaele-andrade.com/) for collaboration on [networked performance](https://www.youtube.com/watch?v=7UWywv_DPHI&t=4s) between Mercury and Knurl
- Live performance image by Zuzanna Zgierska
## ✨ Inspiration
During the development of Mercury (both the playground and the full version) I've found inspiration in many other live coding environments, practices and platforms. Some of these are:
- [Hydra](https://hydra.ojack.xyz/) - Live coding visual synthesizer by Olivia Jack
- [Sema](https://sema.codes/about) - Live coding language design platform combined with Machine Learning
- [MIMIC Project](https://mimicproject.com/about) - a web platform for the artistic exploration of musical machine learning and machine listening.
- [Tidal](https://tidalcycles.org/index.php/Welcome) - Live coding of patterns
- [Sonic Pi](https://sonic-pi.net/) - The live coding synth for everyone
- [Tone.js](https://tonejs.github.io/) - Webaudio framework for programming synths and sequencers
- [Nearley](https://nearley.js.org/) - Parsing toolkit
## 📄 Licenses
- Main Source - [The GNU GPL v.3 License](https://choosealicense.com/licenses/gpl-3.0/) (c) Timo Hoogland 2019-2024
- Sound Files - Individually licensed, listed under [Sounds in Mercury](https://tmhglnd.github.io/mercury/docs/usage/sounds#sample-credits)
- Documentation - [The CC BY-SA 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/) (c) Timo Hoogland 2019-2024
- Examples - [The CC BY-SA 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/) (c) Timo Hoogland 2019-2024
- Max8 - Proprietary Software, Max (c) 1990-2024 Cycling'74 / IRCAM All rights reserved
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: docs/deprecated-docs/00-general.md
================================================
# General Syntax
## new
Create a new instance of an instrument or external output. This can be a `sample`, a `synth`, a `loop`, a `polySynth`, `midi`, `modulator` or an `emitter` for osc followed by the name of the sample, the name of the waveshape to use for the synth, the emitter type (currently only supports `osc`) or the midi device name. After that use functions to set parameters for the object.
**arguments**
- {Instrument} -> the instrument type (sample, synth, loop, polySynth, midi, modulator)
- {Type} -> selected sample or synth waveform (based on loaded files)
- {Functions+} -> instrument methods seperated by spaces (optional)
```java
new synth saw
new sample kick_909
new emitter osc
new midi "AU DLS Synth 1"
```
Alias: `make`, `sound`
By default Mercury has a small library of samples and single-cycle waveforms included in the environment. Follow these links to find out how to include samples and waveforms in Mercury or if you like to see the full list of available sounds.
- [How to load other sounds into Mercury](./07-environment.md#sounds)
- [How to load sounds in the Mercury Playground](./01-global.md#samples)
- [Full list of all the included sounds](https://github.com/tmhglnd/mercury/blob/master/mercury_ide/media/README.md)
- [How to load other waveforms into Mercury](./07-environment.md#sounds)
- [Full list of all the included waveforms](https://github.com/tmhglnd/mercury/blob/master/mercury_ide/media/README.md)
## list
Create a circular array, which is called a `ring` or `list`. (in older versions this was designed to be `ring` because it refers to a "circular array", but for ease of use with beginners `list` makes more sense). This ring can hold integers, floats, symbols and other rings (2-dimensional). Use these to change parameters over time for instruments. The `ring` must be declared with a name before it can be used as a variable in an instrument function.
**arguments**
- {Name} -> ring name
- {Values} -> one or more values
- {Function} -> a ring function
```java
ring someValues [0 1.618 21 3.14]
list someSamples [kick_909 hat_909 snare_909 hat_909]
list fromFunction random(20 0 100)
```
Alias: `list`, `array`
**Note:** Some variable names are not allowed because they are part of the built-in names for datastructures. These are: `bang, int, float, list, mode, zlclear, zlmaxsize`
Read more about all the algorithmic methods available for generating and transforming lists in Mercury under [Ring Methods](./05-ring.md#ring-methods).
## set
Use the set function to change Global Settings or call functions for an instrument-instance `name`, `group` or `all`. The instrument must be declared with a `name()` or `group()` before the `set` is called.
**arguments**
- {Name} -> parameter or instrument name to set value
- {Value} -> value to set
- {Function} -> instrument function to apply
global settings:
```java
set tempo 125
set volume 0.8
set scale pentatonic_major D
set random_seed 9876
```
Or for using with instruments:
```java
new synth saw name(bass)
new sample kick_909 group(drums)
new sample snare_909 group(drums)
set bass gain(0.5)
set drums fx(drive 10)
set all fx(reverb 0.8 10)
```
Alias: `give`, `apply`
## print
Print the output of a list to the console to see its output.
```java
console show
list rnd random(12)
list sin sine(10 5.4)
print rnd
print sin
//=> PRINT: rnd 11 7 21 11 9 8 4 6 3 8 23 10
//=> PRINT: sin 6 7 2 10 0 11 0 11 1 8 5 5
```
## console
Show the console to see the printed output or other error messages from the code. Clear the console as well.
```java
console show
console empty
```
## silence
Disable all sounds that are evaluated **before** this line. Alternatively you can hit the `Alt + .` shortkey to disable the instruments.
*Note* : Silencing the instruments is not the same as disabling the Audio (below). In this case the instruments are deleted, but the signal-chain is still processing in order to be able to quickly start the sound when a new instrument is generated.
```java
silence
```
Alias: `mute`, `killAll` (deprecated)
## audio
Disable/enable the Digital Signal Processing (DSP) engine. This can also be done via the interface and is usually not desirable to use during coding sessions.
```
audio <1-0>
```
================================================
FILE: docs/deprecated-docs/01-global.md
================================================
# Global Settings (set)
*Some settings are different between the Max and Browser version*
## tempo
Change the global tempo in Beats Per Minute (BPM), counted in quarter-notes. Second argument sets a ramptime in milliseconds to gradually change the tempo over the provided amount of time (*!WARNING: experimental and may lag/glitch!*)
**arguments**
- {Number+} -> The BPM as a positive number
- {Number/Division} -> The ramptime (optional/experimental)
```java
set tempo 128
set tempo 80 5000
```
## scale
Set the scale in a 12-TET system for which all the played notes will be mapped to. An optional second argument sets the tone-center (or root) for the scale. The default scale and root is `chromatic c`
**arguments**
- {Name} -> the scale name
- {Name} -> the root (optional, default=c)
```java
set scale major D#
set scale minor_harmonic Eb
```
Currently available scales are:
```
"chromatic" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
"major" : [0, 0, 2, 2, 4, 5, 5, 7, 7, 9, 9, 11],
"minor" : [0, 0, 2, 3, 3, 5, 7, 7, 8, 8, 10, 10],
"minor_melodic" : [0, 0, 2, 3, 3, 5, 7, 7, 9, 9, 11, 11],
"minor_harmonic" : [0, 0, 2, 3, 3, 5, 7, 7, 8, 8, 11, 11],
"dorian" : [0, 0, 2, 3, 3, 5, 5, 7, 7, 9, 10, 10],
"phrygian" : [0, 1, 1, 3, 3, 5, 7, 7, 8, 8, 10, 10],
"lydian" : [0, 0, 2, 4, 4, 6, 6, 7, 7, 9, 11, 11],
"myxolydian" : [0, 0, 2, 4, 4, 5, 5, 7, 7, 9, 10, 10],
"locrian" : [0, 1, 1, 3, 3, 5, 6, 6, 8, 8, 10, 10],
"hungarian" : [0, 0, 2, 3, 3, 6, 6, 7, 8, 8, 11, 11],
"gypsy" : [0, 1, 1, 4, 4, 5, 5, 7, 8, 8, 11, 11],
"major_neapolitan" : [0, 1, 1, 3, 3, 5, 7, 7, 8, 8, 11, 11],
"minor_neapolitan" : [0, 1, 1, 3, 3, 5, 7, 7, 9, 9, 11, 11],
"hexatonic" : [0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10],
"hexatonic_blues" : [0, 0, 2, 2, 4, 4, 6, 6, 7, 7, 10, 10],
"hexatonic_prometheus" : [0, 0, 2, 2, 4, 4, 6, 6, 9, 9, 10, 10],
"major_pentatonic" : [0, 0, 2, 2, 4, 4, 7, 7, 7, 9, 9, 9],
"minor_pentatonic" : [0, 0, 3, 3, 3, 5, 5, 7, 7, 10, 10, 10]
```
The naming convention and offsets for the roots are:
```
-6 gb Gb ges Ges
-5 g G
-4 g# G# gis Gis
-4 ab Ab as As
-3 a A
-2 a# A# ais Ais
-2 bb Bb bes Bes
-1 b B
-1 cb Cb ces Ces
+0 b# B# bis Bis
+0 c C
+1 c# C# cis Cis
+1 db Db des Des
+2 d D
+3 d# D# dis Dis
+3 eb Eb es Es
+4 e E
+4 fb Fb fes Fes
+5 e# E# eis Eis
+6 f F
```
## scalar
Scalar transposition, All the current notes are shifted up or down a certain amount of semitones but remaps the notes to the set scale. This is different from transposing the scales.
**arguments**
- {Int} -> scalar to shift notes by
```java
set scalar 2
```
## randomSeed
Set the random seed as integer for the psuedorandom number generators used in all functions across the environment. Setting the seed to a fixed integer will help make sure random values keep the same sequence every time you re-evaluate the code. A second optional argument resets the seed every n-bar, which can be useful for random arguments used outside list generation, such as `pan(random)` or `beat(0.5)`
**arguments**
- {Int+} -> the seed for the psudeorandom number generators (default=0)
- {Number} -> reset time in n-bars, or divisions (optional, default=null)
```java
set randomSeed 31415
set randomSeed 1618 2
```
## volume
Set the global volume in floating-point amplitude for all instruments across the entire environment. Additional ramptime in milliseconds can be provided to create fade-in/fade-out or smooth transitions to for dynamics.
**arguments**
- {Float} -> attenuate the total volume of all instruments (default=1)
- {Divison/Int+} -> ramptime in milliseconds or divisions (optional, default=0)
```java
set volume 0.5 5000
set volume 0.4 2/1
```
## highPass
Set the global highPass filter cutoff in Hz for all instruments across the entire environment. Additional ramptime in milliseconds can be provided to create smooth transitions from one value to another.
Alias: `hipass`
**arguments**
- {Float+} -> cutoff frequenzy in Hertz
- {Divison/Int+} -> ramptime in milliseconds or division (optional, default=1)
```java
set highPass 900 5000
set highPass 800 2/1
```
## lowPass
Set the global low-pass filter cutoff in Hz for all instruments across the entire environment. Additional ramptime in milliseconds can be provided to create smooth transitions from one value to another.
Alias: `lopass`
**arguments**
- {Float+} -> cutoff frequenzy in Hertz
- {Divison/Int+} -> ramptime in milliseconds or division (optional, default=1)
```java
set lowPass 900 5000
set lowPass 800 2/1
```
## beatRepeat
*Mercury4Max only*
A beatrepeating effect (sometimes called stutter) that continuously repeats a section of the entire sound that was last played. The repating interval is determined in divisions (`1/4`, `3/16`, etc). It immediately starts repeating at the moment of evaluating the code, so timing is key! You can switch to a different section of the beatrepeat recording with optional the second argument. Maximum recording length is 8 seconds (2x 4/4 bars at 60bpm).
Alias: `stutter`
**arguments**
- {Division} -> beatrepeat time interval in division
- {Division} -> beatrepeat offset time in division
```java
set beatRepeat 1/4
```
## osc
*Mercury4Max only*
Set the ip-address, in-port and out-port number for the network to transmit OSC-messages over using UDP. Default settings are 8000 (in-port), 9000 (out-port), localhost (127.0.0.1) (ip).
**arguments**
- {Int+} -> receiving port (default=8000)
- {Int+} -> sending port (default=9000)
- {Name} -> ip-address in the form of xxx.xxx.xxx.xxx or localhost (default=localhost)
```java
set osc default
set osc 8000 9000 127.0.0.1
set osc ip 127.0.0.1
set osc in 8000
set osc out 9000
```
## midi and midiClock
*Mercury4Max only*
With the midi object you can get the available devices (ports) that you can use to send midi notes to with a `new midi` instrument.
```java
set midi getPorts
// prints the available ports to the console
new midi "AU DLS Synth 1" note(7 0) duration(250) time(1/4) gain(0.8)
```
>More on the midi instrument under [instruments](./02-instrument.md)
Output midiClock sync messages to sync an external device to the tempo of Mercury. The device name can have spaces. Use the `getports` argument to automatically open the console and view the different portnames. Use the `off` message or `silence` or `alt + .` to stop the syncing and send a stop message.
**arguments**
- {Name} -> getPorts, the midi portname or off (default=off)
```java
set midiClock getPorts
// returns the port names in console and automatically opens the console
set midiClock midiPortName
// turn the clock on and
// outputs clock-sync to midiport of that name
set midiClock off
// turn the clock off (default)
```
## click
*Mercury4Max only*
Enable a clicktrack/metronome sound to allow you to easily play along with the music. You can adjust the interval for the low pitch separately from the interval of the accent. The accent sounds an octave higher. You can also adjust the channel output for the click so you can hear it separately from the main output. Reset the settings with `default`.
**arguments**
- {Name} -> `on`, `off` or `default` (default=off)
```java
set click on
// turn the click on/off (default=off)
set click freq 1000
// set the base frequency for the click (default=900)
set click length 0.9
// adjust the length of the tone (default=0.65)
set click time 1/8
// set the base interval for the low pitch (default=1/4)
set click accent 1/2
// set the accent interval for the high pitch (default=1/1)
set click gain 0.8
// adjust the volume of the click sound (default=0.75)
set click out 3 4
// set the output channel(s) for the click, can be mono or stereo (default=1 2)
set click default
// reset all attributes to the default settings
```
# crossFade
*Mercury Playground only*
Set the crossfade for the engine to fade from the previous running code to the newly evaluated code in x-amount of milliseconds or divisions. This feature is only applicable to the browser version because it works differently under the hood than the Max version.
**arguments**
- {Division/Int+} -> crossfade time in milliseconds or division (default=250)
```java
set crossFade 1000
set crossFade 2/1
```
# samples
*Mercury Playground only*
With `set samples` you can load samples in the playback buffer so they can be used with the `sample`, `loop` and `polySample` instruments. There are multiple ways to add samples, for example using a `url` from a freesound.org preview file, or by using a soundfile from a raw github content link. `set samples` can only be called **once** in the code, so it is important to add all the sounds you want in that single line. This can lead to a very long line of code, so there are some ways to work around this. For example it is possible to input a `.json` file that consists of name:url pairs for the soundfiles. You don't have to load the samples every time you evaluate, once at the beginning of a session is enough. So after loading you can comment the line and the samples are available until you refresh/restart the browser.
Below you can read various scenarios:
## single soundfile
### freesound
Load a single soundfile from for example freesound.org. Go to the site and find the file you like, right-click on the file and click 'inspect' (in chromium browser). Search for the `cdn.freesound.org/previews` url in the html, this is the soundfile that needs to be copy-pasted. By default the name of the soundfile will be the name you use in the code.
```java
// only evaluate set samples once, when loading is done you can comment the line
set samples 'https://cdn.freesound.org/previews/145/145778_2101444-lq.mp3'
new sample '145778_2101444-lq' time(1/4)
```
You can load a single soundfile and also adjust the name by creating a list. The first item in the list is the name you want to give the sample. The second item in the list is the url to the file.
```java
// only evaluate set samples once, when loading is done you can comment the line
set samples [ psykick 'https://cdn.freesound.org/previews/145/145778_2101444-lq.mp3' ]
new sample psykick time(1/4)
```
### github
Load a single soundfile from a source like github by locating the file in the repository. For example the url looks like this: `https://github.com/tmhglnd/mercury/blob/master/mercury_ide/media/samples/drums/kick/kick_house.wav`. Now construct a new url starting with `https://raw.githubusercontent.com/` then past the `user/repository/branch` after this but remove the `/blob`! For example the result should look like this: `https://raw.githubusercontent.com/tmhglnd/mercury/master/mercury_ide/media/samples/drums/kick/kick_house.wav`
```java
set samples [ housekick 'https://raw.githubusercontent.com/tmhglnd/mercury/master/mercury_ide/media/samples/drums/kick/kick_house.wav' ]
new sample housekick time(1/4)
```
## multiple soundfiles
### lists
There are two ways to load a larger collection of samples. The first option is by creating variables of `list`s that store the name and url combination. Then in one single `set samples` line you can add all the names of the lists
```java
list s1 [ snare_short 'https://cdn.freesound.org/previews/671/671221_3797507-lq.mp3' ]
list s2 [ psykick 'https://cdn.freesound.org/previews/145/145778_2101444-lq.mp3' ]
list s3 [ hat_short 'https://cdn.freesound.org/previews/222/222058_1676145-lq.mp3' ]
set samples s1 s2 s3
new sample psykick time(1/4)
new sample snare_short time(1/16) play(euclid(7 3)) gain(0.5)
new sample hat_short time(1/4 1/8) gain(1.3)
```
### json
The second option is creating a `.json` file. This file can be stored on the computer or on for example github. The json file is structured in the following way: `{ "sample-name" : "url-to-file" }`. When clicking `add sounds` the json file can be selected instead of a soundfile and it will be used to load the samples.
```json
{
"snare_short" : "https://cdn.freesound.org/previews/671/671221_3797507-lq.mp3",
"psykick" : "https://cdn.freesound.org/previews/145/145778_2101444-lq.mp3",
"hat_short" : "https://cdn.freesound.org/previews/222/222058_1676145-lq.mp3"
}
```
```java
set samples <url-to-raw-json-file>
new sample psykick time(1/4)
new sample snare_short time(1/16) play(euclid(7 3)) gain(0.5)
new sample hat_short time(1/4 1/8) gain(1.3)
```
### base
If the base url is the same for all the sample files, for example when loading samples via freesound, you can add a `"_base" :` key, followed by the part of the url that is the same for all the samples. Make sure you include the last `/` so the complete url is correct.
```json
{
"snare_short" : "671/671221_3797507-lq.mp3",
"psykick" : "145/145778_2101444-lq.mp3",
"hat_short" : "222/222058_1676145-lq.mp3",
"_base" : "https://cdn.freesound.org/previews/"
}
```
================================================
FILE: docs/deprecated-docs/02-instrument.md
================================================
# All Instruments
The following methods apply to all the types of instruments: `synth`, `sample`, `loop`, `polySynth`, `polySample`, `midi` and `input`.
For instrument specific functions see below:
- [Synth](#synth)
- [Sample / Loop](#sample-and-loop)
- [polySynth](#polysynth)
- [polySample](#polysample) *MercuryPlayground only*
- [Midi](#midi)
- [Input](#input)
- [Modulator](#modulator) *Mercury4Max only*
<!-- - text to speech -->
## name
Set the name for this instrument. This can be any string of 2 or more characters. The `name` is used as a reference to the instrument when the `set` method is used to call methods for a specific instrument. The name is also used to generate an OSC message that is send out from Mercury to trigger external things in sync with the instrument.
**arguments**
- {Name} -> an instrument name (default=null)
```js
new synth saw name(bob)
set bob gain(0.8) time(1/16)
new sample kick_909 name(alice)
set alice gain(1.2) time(1/4)
```
```
// expected osc messages:
/bob 1
/alice 1
```
## group
*MercuryPlayground only!*
Set one or more group-name(s) for this instrument. This can be any string of 3 or more characters. With the `group` you can apply a line of code to multiple instruments at the same time. The `group` is **not** like a mixing bus, so using for example `gain()` will overwrite the `gain()` function on the line of the instrument. If you use the `name()` function you have to make sure the name is set before the group is applied otherwise the reference won't work correctly.
**arguments**
- {Name} -> a group name used for multiple instruments (default=none)
```js
// the hihat is not included in the group so will
// not get the gain(0.8) and fx(reverb 0.9 11)
new sample hat_909 time(1/8)
new sample kick_909 group(drums) time(1/4)
new sample snare_909 group(drums) time(1/2 1/4)
set drums gain(0.8) fx(reverb 0.9 11)
```
## time
Set the time interval in which a synth or sample is triggered. This can be an integer, float or expression. `1 = bar`, `1/4 = quarter-note`, `1/12 = 8th triplet`, `3/16 = 3-16th notes` etc. Similarly you can set an offset in the timing. The `time()` will start an internal counter for this instrument, incremented every time it is triggerd (based on the `beat()` method). The counter is used as an index to lookup values from other `list`'s provided as argument in methods for this instrument. Setting the first argument to `free` allows to use external triggering via osc messages. The trigger reacts when a value greater than `0` is received. When another instrument in the code has a `name()` that name can be used as osc-message input trigger for another instrument to synchronize the triggering.
Alias: `timing()`
**arguments**
- {Number/Division} -> the timing division or `free` (default=1/4)
- {Number/Division} -> timing offset or osc-message when `free` (optional, default=0)
```js
set tempo 130
new sample kick_909 name(kick)
set kick time(1/4)
new synth saw name(syn)
set syn time(1/2 3/16)
new sample snare_dnb name(snare)
set snare time(free "/snareOSC/amplitude")
new sample kick_909 time(1/8) play(0.3) name(kick)
new synth saw note(0 0) time(free "/kick")
```
## play
Provide the beat function with a `list` consisting of ones and zeroes. For every time interval defined by the `time()` method, the next value in the list will be used. A one results in a trigger of the instrument and an increment of the internal counter. A zero results in no trigger. An optional second argument resets the internal instrument index after a certain amount of time in n-bars.
Alias: `beat() / rhythm()`
**arguments**
- {FloatList+/Float+} -> a rhythmic pattern of ones and zeroes to play (default=1)
```js
list aBeat [1 0 0 1 0 1 1 0 0]
new sample hat_909 name(ht)
set ht time(1/16) play(aBeat 2)
```
Alternatively you can use floating-point values in a list which result in a probability that the instrument will play. Here 0 means 0% chance, 1=100% and 0.5 is 50%. Inspired by Nick Collins paper on [Algorithmic Composition Methods for Breakbeat Science](https://www.dmu.ac.uk/documents/technology-documents/research/mtirc/nowalls/mww-collins.pdf).
```js
list aBeat [1 0.5 0.2 0.8 0.5]
new sample hat_909 name(ht)
set ht time(1/16) play(aBeat 2)
new sample kick_909 time(1/4)
```
## ratchet
Add a ratcheting effect (doubling/tripling of hits) with a probability. A technique that introduces some variety in rhythm that originated with electronic music of Tangerine Dream. The first argument sets the probality a note will be repeated. The second argument sets the amount of repetitions within the time, effectively doubling, tripling or more.
**arguments**
- {Float+} -> probability of ratchet happening (default=0.1)
- {Int+/IntList+} -> amount of repetitions (default=2)
```js
new sample hat_909 time(1/8) ratchet(0.3 2)
```
```js
list rtc [2 3 2 4 8]
new sample hat_909 time(1/4) ratchet(1 rtc)
```
## timediv
*MercuryPlayground only*
Documentation to do...
## warp
*Mercury4Max only*
Warp a rhythm in more complex ways. More documentation to do...
## wait
*MercuryPlayground only*
This function is similar to the offset parameter in the `time()` method except that it allows you to set an additional waiting time (or delay) for an instrument in milliseconds. This function is useful to allign/synchronize instruments with external peripherals such as sending MIDI notes or OSC messages.
**arguments**
- {Int+/Division} -> specify the waiting time in milliseconds or division (default=null)
```js
new sample kick_909 time(1/4)
// the hihat plays 100ms later than the kick
new sample hat_909 time(1/4) wait(100)
```
<!-- Alias: `delay` -->
## shape
Set the envelope generator of a sound. Various modes are possible depending on the amount of arguments. The attack time is the fade-in for the sound, the release is the fade-out for the sound both in milliseconds. The sustain time holds the sound at a static volume for a while. If the sound is triggered before the end of the envelope, the envelope is canceled, faded to 0 in 1ms and starts over. You can specify the times in absolute values using integer/floating points (in ms) or in relative values using beat divisions.
Alias: `length() / duration() / envelope() / env()`
**arguments**
- {Number+/Division/NumberList} -> Attack time in ms or division (optional, default=2)
- {Number+/Division/NumberList} -> Decay time in ms or division (optional, default=0)
- {Number+/Division/NumberList} -> Release time in ms or division
```js
new synth saw shape(1500) time(1)
//=> default attack of 2 ms, sustain of 0 ms and a release of 1500 ms
new synth saw shape(1000 250) time(1)
//=> attack of 1000 ms, default sustain of 0 ms and a release of 250 ms
new synth saw shape(10 500 50) time(1)
//=> attack of 10 ms, sustain of 500 ms and a release of 50 ms
```
with division:
```js
set tempo 100
new synth saw shape(1/2) time(1)
//=> default release of 1/2 (about 250 ms at 120 bpm)
new synth saw shape(1/4 1/32) time(1)
new synth saw shape(1/64 1/8 1/16) time(1)
```
## gain
Set the volume for the instrument in floating-point amplitude. Where `1` is the normalized amplitude, `0.5` is the half softer (-6 dBFS) and `2` is twice as loud (+ 6dBFS). An optional second argument sets the sliding time to go to the next gain value in milliseconds.
Alias: `amp() / volume() / velocity()`
**arguments**
- {Float+} -> the (start) volume of the instrument (default=1)
- {Number+} -> the sliding time in division or ms (optional, default=0)
- {Bool} -> mute the instrument but still use named sends (default=0)
<!-- - {Float+} -> the end volume of the instrument to generate a ramp (optional, default=previous-gain-value) -->
```js
new sample snare_909 name(sn)
set sn gain(0.8)
```
**Note:** When using the `midi` instrument the gain will be multiplied by `127` to construct a velocity message. A `gain(0.5)` therefore maps to `63` and a `gain(1)` to `127`
## pan
Set the panning position in floating-point for the sound in the stereo-image. `-1` is 100% left channel, `0` is center (both speakers), `1` is 100% right channel. Higher or lower values wrap between -1 and 1. Provide pan with the `random` argument to get a new random panning value every moment of the `time()` counter.
Alias: `panning()`
**arguments**
- {Float} -> the panning position between -1 and 1 (default=0)
```js
new sample clap_909 name(hand)
set hand pan(random)
```
## fx
Apply an effect to the sound of the instrument to manipulate your sounds timbre in many ways. The first argument is always the `effectname`. The following arguments depend on the selected effect. See [FX Documentation](./04-fx.md) for more details and an up-to-date list of all the available effects for both Mercury4Max and the Mercury Playground.
Alias: `effect() / with_fx() / add_fx()`
**arguments**
- {Name} -> the effect name
- {Value+} -> any values based on effectname arguments
```js
new synth square name(bass)
set bass fx(reverb 0.8 11)
```
# synth
The synth and polySynth instruments allow you to play synthesized sounds using a single cycle waveform. These waveforms are loaded in RAM and can be accessed by their filename (without the extension). The default waveforms are `sine`, `triangle`, `square` and `saw`.
- [How to load other waveforms into Mercury](./07-environment.md#sounds)
- [Full list of all the included waveforms](https://github.com/tmhglnd/mercury/blob/master/mercury_ide/media/README.md)
## note
Set the pitch for the instrument to play a note in a melody or chord. The note is specified as a 2-dimensional coordinate system, where the first argument is the semitone offset (can be positive or negative) and the second argument is the octave offset (can be positive or negative). The origin of the system, `note(0 0)`, corresponds by default with midi-pitch `36` or `C2`. Depending on the `set scale` the coordinate system will shift and result in a different pitch for the origin. A `note()` should therefore not be taken as an absolute value, but rather a relative direction where the melody is going to in relation to the scale and root. Detuning/pitchbending can be done by providing a floating-point note number. The value behind the decimal point is the amount of detuning from one semitone to the next. For example `7.5` results in `7` semitones (mapped to the scale if `set scale` is used) and then a `0.5` semitone is added (= 50 cents). Detuning is applied after mapping the integer semitone to a scale.
|`note(x y)`|-… |-3 |-2 |-1 |0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |10 |11 |12 |13 |… |
|---------|---|---|---|---|------|---|---|---|---|---|---|---|---|---|---|---|------|---|---|
|4 |… |A# |B |B# |C `84`|C# |D |D# |E |F |F# |G |G# |A |A# |B |C `96`|C# |… |
|3 |… |A# |B |B# |C `72`|C# |D |D# |E |F |F# |G |G# |A |A# |B |C `84`|C# |… |
|2 |… |A# |B |B# |C `60`|C# |D |D# |E |F |F# |G |G# |A |A# |B |C `72`|C# |… |
|1 |… |A# |B |B# |C `48`|C# |D |D# |E |F |F# |G |G# |A |A# |B |C `60`|C# |… |
|0 |… |A# |B |B# |C `36`|C# |D |D# |E |F |F# |G |G# |A |A# |B |C `48`|C# |… |
|-1 |… |A# |B |B# |C `24`|C# |D |D# |E |F |F# |G |G# |A |A# |B |C `36`|C# |… |
|-2 |… |A# |B |B# |C `12`|C# |D |D# |E |F |F# |G |G# |A |A# |B |C `24`|C# |… |
**arguments**
- {Value/ListValue} -> positive or negative semitone note value or list, x-coordinate (default=0)
- {Value/ListValue} -> positive or negative octave value or list, y-coordinate (default=0)
```js
set scale major D
new synth sine note(2 2)
//=> results in midi-note 64 > F4
```
Also excepts lists to play a melody over time:
```js
set scale minor A
list mel [0 5 7 3 2 -2 0]
new synth sine note(mel 1) time(1/16)
```
Alias: `pitch()`
## useDetune
**REMOVED**
Detune is now done in the `note()` method by providing a floating-point note number. The value behind the decimal point is the amount of detuning from one semitone to the next. For example `7.5` results in `7` semitones (mapped to the scale if `set scale` is used) and then a `0.5` semitone is added (= 50 cents). Detuning is applied after mapping the integer semitone to a scale.
## slide
A portamento/sliding/gliding effect. This will make the synthesizers oscillators slowly slide from one frequency to the next one over a defined period in milliseconds or division. The sliding is logarithmically (meaning it wil slide from midi note to midi note linearly, and when converted to frequency slide logarithmically. This sounds slightly different then when sliding linearly between two frequencies)
Alias: `glide`, `portamento`
**arguments**
- {Number/Division} -> sliding time in milliseconds or division (default=50)
```js
list notes [0 7 3]
new synth saw note(notes 1) time(1/2) slide(1/8)
```
## super
Add multiple oscillators in unison with a detuning factor to create a *SuperSaw* effect. One oscillator will always be the base frequency of the `note()`, the others are tuned above and below in incremental steps based on the detuning factor. The first argument sets the amount of oscillators (minum of 1, default=1), the second argument sets the detuning factor in semi-tones, the third optional argument sets the oscillator type for the odd numbered oscillators.
Alias: `unison`
**arguments**
- {Int+} -> number of oscillators (default=1, maximum=64)
- {Float/FloatList} -> detuning factor in semi-tone, 12=octave
- {Name} -> the name of the odd numbered oscillators (optional, default=main oscillator)
```js
new synth saw note(0 1) shape(-1) super(5 0.031415)
```
```js
new synth saw note(0 1) shape(-1) super(11 0.0618 square)
```
Detuning can be changed in time with a `list`
```js
list voices [3 5 9 21]
list detune [0.1 0.5 0.9 12.01 0.3]
new synth saw note(0 1) time(1/4) shape(-1) super(voices detune)
```
<!-- **backwards compatible with wave2()**
Using the previous syntax of `wave2()` now calls the `super()` method like so
```js
new synth saw note(0 1) wave2(square 0.998)
// is translated and equivalant to:
new synth saw note(0 1) super(2 -0.03 square)
``` -->
## sub
Add a second sinewave oscillator one octave lower than the note played for a sub frequency.
**arguments**
- {Float+} -> amplitude for the sub oscillator (default=0)
```js
new synth sine note(0 2) time(1/4) sub(0.8)
```
## wave2
**DEPRECATED, use super() instead**
Add a second oscillator to the synths sound. This can either be a sine, triangle, square or saw. The second argument sets a multiplication ratio for the second oscillators frequency.
**arguments**
- {Name} -> waveform to add as second wave
- {Float} -> tuning in ratio to note() frequency (default=1)
- {Float} -> tuning offset in Hertz (optional, default=0)
```js
new synth saw note(0 1) time(1/4) wave2(square 0.998)
```
Alias: `osc2()` `super`
## noise
Add a noise oscillator to the synth sound. The first argument is the amplitude (gain), the second argument is the "color" of the noise between 0 and 1 (1 = white noise, lower values give a more darker noise sound). When the modulation mode is turned on (with 1) the noise is modulated by the source of the oscillator (or oscillators if super and sub are used).
**arguments**
- {Float+} -> amplitude of the noise (default = 0)
- {Float+} -> color of the noise 0-1 (default = 0.8)
- {Bool} -> modulation mode (default = 0)
```js
new synth saw note(0 1) time(1/4) noise(0.3 0.8 1)
```
# Sample and Loop
The sample and loop instruments allow you to play sound-recordings and loops. These so called "samples" are loaded in RAM and can be accessed by their filename (without the extension).
- [How to load other sounds into Mercury](./07-environment.md#sounds)
- [How to load sounds in the Mercury Playground](./01-global.md#samples)
- [Full list of all the included sounds](https://github.com/tmhglnd/mercury/blob/master/mercury_ide/media/README.md)
## speed
Set the playback speed for the sample, where 1 = original speed, 0.5 = half the speed and 2 = twice as fast. Adjusting the playback speed will change the pitch of the sample. A negative value will play the sample backwards starting at the end (or at the `offset()` position)
Alias: `rate()`
**arguments**
- {Number} -> playback speed (default=1)
```js
new sample choir time(5) speed(0.5)
new sample choir time(5) speed(-0.5)
set all fx(reverb 2 17)
```
## start
Set the start (the offset position of the playback) of the sample. 0 = start at the beginning, 0.5 = start midway in the sample. With long decaying samples the offset is very useful if playing the sounds backwards when using for example `speed(-1)`.
Alias: `offset`
**arguments**
- {Float} -> the playback position between 0 and 1 (default=0)
```js
list positions randomFloat(8 0 0.5)
new sample choir time(1/16) start(positions)
```
## useNote
**REMOVED**
## note
<!-- *Mercury Playground only* -->
The `note` method allows you to tune the sample to a specific pitch instead of using the `speed()` function. The function works the same as the `note` function explained under the `synth`. Please look there for further information.
## tune
<!-- *Mercury Playground only* -->
Set the base note as a MIDI value for the sample to determine how the `note()` function changes the playback speed. For example if your sample was recorded as a `a4` then you will set tune to `69`. `note(0 2)` will be the same as the `tune()` value in the case of a scale set to have `c` as the root.
**arguments**
- {Number+} -> MIDI pitch as base for tuning (optional, default=60)
```js
set scale minor c
list notes [0 7 5 3]
// tune the kalimba to a3
new sample kalimba_a time(1/4) note(notes 2) tune(57)
```
## stretch
Stretch the entire sample to the length of a full bar. Useful for when working with beats that have to be looped. Stretching is the default when working with the `loop` instrument. This is basically a `new sample` with `stretch(1)`. Optionally you can turn timestrechting on with a second argument to preserve the original pitch of the sample. A third optional argument changes the mode of the stretching, choose from: basic, monophonic, rhythmic, general, extremestretch, efficient. The default is set to efficient.
**arguments**
- {Int} -> turn stretch to full bar on/off (default=0 for sample default=1 for loop)
- {Int} -> turn timestretching on when stretching to full bar, preservering the original pitch (default = 0)
- {Name} -> adjust the stretching mode (default=efficient)
```js
new sample chimes stretch(1 1 general) speed(-1)
```
### Stretching modes explained
*Mercury4Max only*
- `basic` : best option for real-time performance
- `monophonic` : best option for any monophonic source without ambience
- `rhythmic` : best option for drums and percussion when transient preservation is critical
- `general` : balances spectral integrity with transient preservaton
- `extremestretch` : optimized for stretching (slowing down) material, limited to a stretch factor between 0.5 and 4
- `effcient` : best option when CPU efficiency is critical
# polySynth
The polySynth functions the same as the synth in the sense that you choose a waveform, set a `note()`, add a `shape()`, etc. For explanation of those functions see above.
The extra feature of the polySynth is that it allows for overlapping notes to generate for example chords. Notes provided to the `note()` function as a 2-dimensional list will be played at the same time as a chord. By default there are 8 voices available at the same time. Voice stealing is `on` by default meaning if a new note is played while all voices are busy the oldest triggered note will be removed.
```js
// note the double [[ ]] to generate a 2d-list
list chord [ [ 0 4 5 7 8 10 12 ] ]
new polySynth sine note(chord 2) time(1/2) shape(1 1/4)
```
## steal
If new notes are triggered while all voices are still in use they will not be played. This behaviour can be changed by setting the stealing to `on` or `1`.
**arguments**
- {Bool/Name} -> turn voice stealing `on` or `off` (optional, default=on)
```js
list notes spread(16 0 36)
new polySynth sine note(notes 2) time(1/16) shape(1 1/1) steal(off)
```
## voices
**not implemented yet**
## spread
Use the spread function to add little delays with optional randomness between every note from a chord, resulting in the chord sounding broken up in time.
**arguments**
- {Number+/Division} -> the delaytime between note triggers in ms or division (default=0)
- {Number+/Division} -> random delaytime offset added to the delaytime in ms or division (default=0)
```js
list notes [[0 3 7 11 12]]
new polySynth sine note(notes 2) shape(1 1/1) time(1/1) spread(150 50)
```
# polySample
*Mercury Playground only*
The polySample functions the same as the sample in the sense that you choose a sample file, set a `speed()`, add a `shape()`, etc. For explanation of those functions see `sample` above.
The extra feature of the polySample is that it allows for overlapping sounds. For example useful when generating chords. Notes provided to the `note()` function as a 2-dimensional list will be played at the same time as a chord. By default there are 8 voices available at the same time.
For voice-stealing see `steal` under `polySynth`. For setting voice-amount see `voices` under `polySynth`.
```js
set tempo 100
set scale dorian eb
list notes shuffle(spread(24))
new polySample piano_e time(1/16) note(notes 1) shape(1 1/2) steal(off) tune(64)
```
# Midi
The midi instrument allows you to send midi-note messages to other devices or virtual devices on your computer. To setup a basic midi instrument use:
```js
set midi getPorts
//=> prints the available devices to the console
new midi "AU DLS Synth 1" time(1/4) note(0 0) length(100) gain(0.8)
```
## note
Set the pitch for the instrument to play a note in a melody or chord. The note is specified as a 2-dimensional coordinate system, where the first argument is the semitone offset (can be positive or negative) and the second argument is the octave offset (can be positive or negative). The origin of the system, `note(0 0)`, corresponds by default with midi-pitch `36` or `C2`. Depending on the `set scale` the coordinate system will shift and result in a different pitch for the origin. A `note()` should therefore not be taken as an absolute value, but rather a relative direction where the melody is going to in relation to the scale and root. For a detailed table of the note coordinates see `note` under [synth and polySynth only](#synth-and-polysynth-only).
**arguments**
- {Value/RingValue} -> positive or negative semitone note value or list, x-coordinate (default=0)
- {Value/RingValue} -> positive or negative octave value or list, y-coordinate (default=0)
```js
set scale major D
new midi "AU DLS Synth 1" note(2 2)
//=> results in midi-note 64 > F4
```
Also excepts lists to play a melody over time:
```js
set scale minor A
list mel [0 5 7 3 2 -2 0]
new midi "AU DLS Synth 1" note(mel 1) time(1/16)
```
## length
Replaces the `shape()` function for Synth and Sample. Set the duration of the midi note for it to send the note-off message in milliseconds or division. If the instrument is triggered before the end of the duration, the note-off is canceled and a new note-off is send.
**arguments**
- {Number/Division} -> Duration time in ms or division
```js
new midi "AU DLS Synth 1" length(1500) time(1)
//=> duration of 1500 ms triggered once per bar
```
with division:
```js
set tempo 100
new midi "AU DLS Synth 1" length(1/2) time(1)
//=> duration of 1/2 (1200 ms at 100 bpm)
```
Alias: `duration()`
## out
Set the channel output for the midi-note to be send to.
**arguments**
- {Number} -> Channel to send the midi-note to
```js
new midi "AU DLS Synth 1" note(7 2) out(1)
new midi "AU DLS Synth 1" note(0 0) out(2)
```
Alias: `channel()`
## chord
Turn the chord output (polyphony) on for a midi instrument. This allows you to use 2-dimensional lists where the 2nd dimension is used to generate chords.
**arguments**
- {Bool} -> Turn chord output on/off
```js
list chords [[0 4 7] [2 5 9] [5 9 0]]
new midi "AU DLS Synth 1" note(chords 1) chord(on)
```
Alias: `poly`
## program
Send program change messages to the specified midi channel of the instrument. The channel number is based on the `out()` method (see above). The default channel `1` is used if no channel is selected. The program change value is an integer from `0` - `127` and can be sequenced as a list. If no value is provided there is no program change send. The value is **only** send when it changes based on the previous value. This is done because some midi devices react every time a program change is received (for example cutting of notes), even if the value stays the same.
**arguments**
- {Int+} -> Program change value 0-127 (default=off)
```js
list notes spread(5 0 12)
list changes [0 10 20]
new midi default note(notes 1) out(1) program(changes)
```
<!-- Alias: `pgm`, `pc` -->
## sync
Turn midiclock syncing on/off for an individual instrument and send it to the selected port/device from that instrument.
**arguments**
- {Bool} -> Turn syncing on/off
```js
new midi "aMidiDevice" sync(on)
new midi "otherDevice" sync(off)
```
Alias: `clock()`
## change
Send control change messages to the midi device. This function can have multiple calls in the same instrument, every call can be a different control number. The first argument is the control number, the second argument is the controller value or a list of controller values.
**arguments**
- {Int+} -> Midi controller number between 0-127
- {Int+/RingInt+} -> Midi controller value between 0-127
```js
list ccValues [10 20 30 40 50]
new midi "device" change(13 100) change(21 ccValues)
```
Alias: `cc`
<!--
# Text to Speech (mac-only)
An experimental text-to-speech instrument is added. Using the Mac terminal speech capabilities with the help of the `aka.speech` object developed by Masayuki Akamatsu.
```js
new voice Alex speak("Hello world!") time(2)
new voice Samantha speak("Hi Alex!") time(2 1)
``` -->
# Input
Use the input from the soundcard (ADC) as the source for an instrument. The sound can be modified by all the various `fx()`. The volume can be adjusted with `gain()`. An envelope can also be applied on the sound with `shape()` and this envelope can be triggered with `time()` just as with the regular instruments `sample`, `synth`, etc. Use the words `in1`, `in2`, ..., `inx` to choose the input source.
*In the browser version you will need to give permission to use the microphone and afterwards you might need to refresh the page*
**arguments**
- {Name} -> `default` or the input channel number as a string `inX`
```js
// use the default input, in most cases channel 1
new input default gain(1)
// use a specific channel
new input in3 gain(0.9)
// add functions like shape, time and fx
new input in4 gain(0.9) time(1/16) shape(1 100) fx(reverb) fx(distort)
```
# Modulator
The modulator allows you to send a modulation signal as an argument to parameters from functions of other instruments. These parameters are continuously modulated at a specific rate with a specific waveform. The modulation rate is independent from the instruments `time()` (in comparison when using a list as an argument). It is also possible to send the modulation signal directly out to the connected soundcard on a specific channel. This can for example be used for cv modulations.
**arguments**
- {Name} -> waveform type: `sine`/`sin`, `sawUp`/`phasor`, `sawDown`/`saw`, `square`/`rect`, `triangle`/`tri`, `random`/`rand`, `randomLine`/`randL`, `trigger`/`gate`
```js
new modulator <waveform-type> name(<name>) range(<lo> <hi> <exp>) time(<division>) out(<channel>)
```
## modulator name
Set the name for the modulator, this name can be used as argument in the functions of an instrument like `synth` and `sample`
**arguments**
- {Name} -> the modulator name for reference in other functions
```js
// set the name to myModulator
new modulator sine name(myModulator)
// the synth uses the modulator in the gain function
new synth saw gain(myModulator)
```
## modulator time
Set the modulation speed in division. The default is `1/1` (one period per bar).
**arguments**
- {Division} -> The time interval for one period of the modulation waveform (optional, default=1/1)
- {Division} -> The time offset for the modulation (optional, default=0)
```js
// modulate a sinewave at a period of one per 4 bars
new modulator sine time(4/1)
```
## modulator range
Set the modulation range between a low and high value with an option exponential value. The default range is 0 to 1.
**arguments**
- {Number} -> The low output range (optional, default=0)
- {Number} -> The high output range (optional, default=1)
- {Number} -> The scaling exponent (optional, default=1)
```js
// set the range from 200 to 5000, for example to modulate a filter cutoff
new modulator sine range(200 5000)
// include the third argument to set the exponential in the scaling
new modulator sine range(200 5000 3)
```
## modulator out
**Warning: be careful when sending DC signals with large ranges to your DAC, this could damage your speakers if you choose the wrong output!**
Set the output channel from your connected soundcard to send the modulation signal directly to. The default is 0 (no output to DAC). Currently the maximum number of channels that can be used is 16. If the modulation signal is only used for direct output it is not necessary to also `name()` the modulator.
**arguments**
- {Number+} -> The channel number from 1 till number of outputs available, maximum of 16 (default=0)
```js
// send a sinewave modulator signal to DAC channel 3
new modulator sine range(-1 1) out(3)
```
## modulator trigger
When using the mode `trigger`/`gate` the modulator functions like the sequencer in the instruments. Meaning it is also possible to use `play()` to add a rhythm list, use `ratchet()` to add a list of timing subdivisions with probability, use `warp()` to add a list of time warpings.
**arguments**
- {Name} -> `trigger`/`gate` sets the intrument to use the stepsequencer
```js
// generate a euclidean rhythm and use it in the trigger
list rtm euclid(16 11)
new modulator trigger time(1/8) play(rtm) ratchet(0.1 2)
```
## modulator hold
The hold function transforms the `trigger` into a gate that goes open and closes after a certain amount of time. The time value can be either `ms` or a `division`. If the hold time is longer than the time interval between triggers the gate stays open. A hold of `0` results in the click from the default trigger.
**arguments**
- {Number+} -> hold time in ms or division (default=0)
```js
// trigger every 8th note, and leave the gate open for the length of 50ms
new modulator trigger time(1/8) hold(50)
// trigger every 8th note, and leave the gate open for the length of a 16th
new modulator trigger time(1/8) hold(1/16)
```
================================================
FILE: docs/deprecated-docs/03-emitter.md
================================================
# Emitter
Create an emitter object. Use this object to send messages to other platforms. The emitter objects works similarly to the [instruments](./02-instrument.md) in the sense that it also has the `time`, `beat` and `name` functions by default. The `time` determines the time-interval at which messages are send. The `beat` can turn send moments on or off. See under [Synth/Sample](#synthsample-functions) for further detail.
See the shared methods:
- [name](./02-instrument.md#name)
- [group](./02-instrument.md#group)
- [time](./02-instrument.md#time)
- [beat](./02-instrument.md#beat)
## osc
Create an emitter object of type `osc`. The `name(<name>)` method is used to set the opening address of the message to `/<name>`. Any arbitrary function name is used to set as second address in the osc-string. If no name is provided it will default to a unique number for every instrument instance. By adding other functions with any arbitrary name you can send a message with the address in the form of `/<name>/<function> <arguments>`
```java
new emitter osc name(<name>) time(<division><offset>)
```
example
```java
list params [0.25 0.5 0.75]
list values [3 1]
new emitter osc name(myOSC) time(1/4)
set myOSC someParam(params) anotherParam(values)
// emits => /myOSC/someParams 0.25
// /myOSC/anotherParam 3
// /myOSC/someParams 0.5
// /myOSC/anotherParam 1
// /myOSC/someParams 0.75
// /myOSC/anotherParam 3
// /myOSC/someParams 0.25
// etc...
```
The messages also support multiple arguments up to a length of 256. Multiple arguments can be provided as rings, symbols, floats or integers.
```java
list val1 [0.25 0.5 0.75]
list val2 [3 1]
new emitter osc name(myOSC) time(1/4)
set myOSC aMessage(0.1 val1 val2 100)
// emits => /myOSC/aMessage 0.1 0.25 3 100
// /myOSC/aMessage 0.1 0.5 1 100
// /myOSC/aMessage 0.1 0.75 3 100
// /myOSC/aMessage 0.1 0.25 1 100
// etc...
```
**Note:** Some variable names are not allowed because they are part of the built-in names for datastructures. These are: `bang, int, float, list, mode, zlclear, zlmaxsize`
## name
Set the name for the OSC emitter. This can be any string of 2 or more characters. The `name` is used as reference to the instrument when the `set` method is used to call methods for a specific object. The `name` is also prepended as first address in the osc-message of the format `/<name>/<function> argument`.
## address
Alternatively, if you want multiple emitters to send to the same address, you can use the `address()` method. The `address` is prepended as first address in the osc-message in the format: `/<address>/<function> argument`. Useful if you want to send messages to the same address, but with different timing-intervals.
```java
list params [0.25 0.5 0.75]
list values [3 1 4]
new emitter osc name(osc1) address(myOSC) time(1/4)
set osc1 someParam(params)
new emitter osc name(osc2) address(myOSC) time(1/2)
set osc2 anotherParam(values)
// emits => /myOSC/someParams 0.25
// /myOSC/someParams 0.5
// /myOSC/anotherParam 3
// /myOSC/someParams 0.75
// /myOSC/someParams 0.25
// /myOSC/anotherParam 1
// etc...
```
## sendOSC
You can enable/disable sending messages with the sendOSC function
```java
new emitter osc name(osc3) sendOSC(0)
```
## receiving
You can use osc adresses as arguments for other functions by putting the address as argument in the form: `/<address>/<tag>/<etc.>`. For example to control the `gain()` of a `sample` and the `note()` value of a `synth` enter the following:
```java
new sample kick_909 time(1/4) gain(/myOSC/sliderValue1)
new synth saw note(/myOSC/sliderValue2) shape(1 100) time(1/8)
```
It is possible to scale the incoming osc value to a different range by using `{}` after the address inputting a low and high output range separated by a colon `:`. The scaling function considers an incoming range of `0 - 1` floatingpoint values. For example to control the `note()` and `shape()` ranges in a `synth` enter the following:
```java
new synth saw note(/myOsc/sliderValue3{2:19} 0) shape(1 /myOsc/sliderValue4{50:500})
// => converts incoming slider values from 0-1 to 2-19 for note and 0-1 to 50-500 for note length
```
================================================
FILE: docs/deprecated-docs/04-fx.md
================================================
# Sound Effects (fx)
The sound FX currently have a fixed chain when using the Mercury standalone version in Max. The chain of effects is as following:
```
synth / sample / polySynth / loop (mono)
|
freeze (spectral freezer)
|
shift (pitchshifter)
|
vibrato (pitch modulation)
|
triggerFilter (envelope modulated filter)
|
kink (distortion)
|
drive (distortion)
|
filter (low/hi/band filter with optional LFO modulation)
|
comb (combfiltering)
|
degrade (downsampling)
|
squash (basic compression/distortion)
|
gain (the volume of the sound) -> sender
|
panning
||
double / chorus
||
|| >>====== vv
|| +
|| hall (stereo reverb)
++ <<====== <<
||
lfo (low frequency oscillator)
||
delay (stereo pingpong delay + drywet)
||
output
```
```
| mono
- mono
|| stereo
= stereo
++ sum
```
## reverb
Add a reverberation effect to the sound, making it sound like it's in a room or big hall. The effect has 2 arguments, the amplitude of the reverb and the reverb-size. The amplitude is specified as floating-point amplitude and the length is a value between `0` and `18` (choosing between 19 presets). The default is `0.5` amplitude and `10` length.
**arguments**
- {Float+} -> amplitude of reverb (default=0.5)
- {Number+} -> size of reverb 0-18 (default=10)
- {Number+} -> slide time in ms when size is changed (default=10)
- {Float+} -> drywet 0-1 (optional, 1=100% wet, default=0.5)
Alias: `fx(hall)`
```
fx(reverb)
fx(reverb <size>)
fx(reverb <amount> <size>)
fx(reverb <amount> <size> <slide> <dry-wet>)
```
```java
new sample snare_909 time(1) fx(reverb 0.93 15)
```
## delay
Add a pingpong delay effect to the sound. The effect has 4 arguments, the left delaytime, the right delaytime, the feedback and the damping. The delaytime is specified in bar time divisions, where `0.25` (or `1/4`) is a quarter note. The feedback is specified as a value between `0` and `1`. Positive feedback is allowed and internally compressed/distorted, but watch out for your ears just in case. The damping is a onepole lowpass filter for which the cutoff is specified between `0` and `1` where 0 means full damping, and 1 means none (filter open).
Alias: `fx(echo)`
**arguments**
- {Division} -> delaytime for left (optional, default=3/16)
- {Division} -> delaytime for right (optional, default=2/8)
- {Float+} -> feedback 0-1 (optional, default=0.8)
- {Float+} -> damping 0-1 (optional, default=0.5)
- {Float+} -> drywet 0-1 (optional, 1=100% wet, default=0.5)
```
fx(delay) (defaults)
fx(delay <timeLR>)
fx(delay <timeLR> <fb>)
fx(delay <timeL> <timeR> <fb>)
fx(delay <timeL> <timeR> <fb> <damp>)
fx(delay <timeL> <timeR> <fb> <damp> <drywet>)
```
```java
new sample hat_909 time(1/2) fx(delay 3/16 7/16 0.5 0.7)
```
## filter
Add a filter to the sound. This can be a static filter or a modulated filter depending on the amount of arguments you provide. The filter-type can be a `low`, `high` or `band`-pass filter. The second argument is the cutoff frequency in Hz and the third argument is the resonance between `0` and `1`. Passing a single argument only sets the cutoff, passing two arguments sets the cutoff and resonances. The filter then defaults to `lowpass`.
**arguments**
- {Name} -> filter type, low, high, band (default=low)
- {Number+} -> cutoff frequency in Hz (default=1200)
- {Float+} -> resonance between 0-1 (default=0.45)
```
fx(filter)
fx(filter <cutoff>)
fx(filter <cutoff> <resonance>)
fx(filter <type> <cutoff> <resonance>)
```
```java
new synth saw note(0 1) shape(-1) fx(filter low 800 0.6)
```
You can provide extra arguments to have the filter modulate between a low and high cutoff-frequency. In this case the arguments are as follows (in order): The filter-type `low / high / band`. The modulation speed in float/expression as musical time division where `0.25` or `1/4` = a quarter note. The high cutoff in Hz, the low cutoff in Hz the resonance between `0` and `1`. The modulation shape tilt between `0` and `1`, where 0 is ramp-down, 1 is ramp-up and 0.5 is triangle form. The exponential curve for the filter as floating point.
**arguments**
- {Name} -> filter type, low, high, band (default=low)
- {Division} -> modulation ratio (default=1/1)
- {Number+} -> low modulation frequency in Hz (default=200)
- {Number+} -> high modulation frequency in Hz (default=3000)
- {Float+} -> resonance between 0-1 (default=0.45)
- {Float+} -> modulation slope 0-1 up, down, triangle) (default=0.5)
- {Float+} -> exponential scaling (default=2)
```java
new synth saw note(0 0) fx(filter low 1/4 100 3500 0.55 0 4)
```
## triggerFilter
A filter with an envelope that is controlled by the trigger of the instrument. Whenever the sequencer triggers an event that would cause the instrument to sound this will also be the event that triggers the start of this filter. The filter has various types, a low and high frequency value for the envelope to move between, an attack and release time in ms or division value and an optional exponent for the slope of the filter.
**arguments**
- {Name} -> filter type, `low`, `high`, `band` (default=low)
- {Number+/Division} -> attack time in ms or division (default=1)
- {Number+/Division} -> release time in ms or division (default=1/16)
- {Number+} -> high frequency point in the envelope (default=4000)
- {Number+} -> low frequency point in the envelope (default=100)
- {Float+} -> exponent for the envelope curve (default=1)
```java
list beat euclid(8 3)
new synth saw note(0 1) time(1/8) play(beat) fx(triggerFilter low 10 1/4 1000 150 0.5)
```
## double / chorus
Add an Automated-Double-Tracking (ADT) or Chorus effect to the sound. When only typing double it will sound like two versions of the sound are created, one left and one right. When typing chorus the original sound is added and the delaytimes are longer. Arguments are the modulation speed in division, the modulation depth in milliseconds, the modulation wave `sine` or `random`, the dry-wet ratio between `0` and `1` and a detune factor between left and right modulation wave in floating.
**arguments**
- {Division} -> modulation rate (default=4/1)
- {Number+} -> modulation depth in ms (default=8 for double, default=45 for chorus)
- {Name} -> modulation wave, sine or random (default=random)
- {Float+} -> dry-wet (default=1 for double, default=0.5 for chorus)
- {Float+} -> modulation rate detune (default=0.94562)
```
fx(double)
fx(chorus)
fx(chorus <rate>)
fx(chorus <rate> <depth> <wave> <wet-dry> <detune>)
```
**browser version only:**
- {Division} -> modulation rate (default=8/1)
- {Number+} -> modulation depth in ms (default=8 for double, default=45 for chorus)
- {Float+} -> dry-wet (default=1 for double, default=0.5 for chorus)
```
fx(double)
fx(chorus)
fx(chorus <rate>)
fx(chorus <rate> <depth> <wet-dry>)
```
```java
new sample clap_808 fx(double)
new synth saw fx(chorus 5/1 30)
```
## freeze
Create an FFT-freeze effect on the sound. This will result in a "frozen-in-time"-like sound, where the timbre is still clearly audible. The freezer is triggered at the time interval of the `time()` function. The trigger can be set with a float to give it a probability of triggering, or a list can be provided to let the freezing occor in a rhythmic pattern. The second optional argument determines the sliding time between 2 freeze frames (in n-frames), and the third optional argument sets the amount of frames to store.
**arguments**
- {Number} -> freeze rhythm or probability (default=1)
- {Int} -> interpolation between frames (default=0)
- {Int} -> number of frames stored in freezer (default=8)
```java
list playHarp [1 0 0 0 0 0 0 0]
list trigger [1 0 0 0 0]
new sample harp_up time(1/4) beat(playHarp) name(harp)
set harp fx(freeze trigger)
```
## shift
Make a time-domain pitchshifting effect to change the pitch of the sound. The first argument sets the shift in semitones (this can also be a floating-point value to create microtonal shifts). The second value sets the wet-dry ratio (default = 1) to combine the original with the shifted sound. You can change the shifting quality (higher quality sounds better but uses more cpu).
**arguments**
- {Number} -> shifting factor (positive/negative) in semitones (optional, default=-12)
- {Float} -> dry-wet mix between 0-1 (optional, default=1)
- {Name} -> shifting settings `basic`, `good`, `better`, `best` (optional, default=basic)
```java
new sample violin_c time(1/4) fx(shift 7 0.5)
```
## vibrato
Add a vibrato effect to the incoming signal by modulating a short delayline with a sinewave. The depth sets the delayline length in ms, the rate sets the frequency of the sinewave in Hz.
**arguments**
- {Number+} -> vibrato rate in Hz (optional, default=2)
- {Number+} -> vibrato depth in ms (optional, default=5)
```java
new sample violin_c time(1/4) fx(vibrato 4 5)
```
## squash
A simple compression/distortion algorithm based on a design by Peter McCulloch. Raise the amount to squash the incoming signal, first creating some kind of simple compression, but quickly introduces nice distortion harmonics.
**arguments**
- {Number+} -> input gain amount, greater than 1 (optional, default=4)
- {Float+} -> dry-wet factor 0-1 (optional, default=1)
<!-- - {Float} -> compression factor greater than 0 (optional, default=0.28) -->
```java
new sample piano_e time(1) fx(squash 2.3)
```
## kink
A kink distortion algorithm. Creates a bend or "kink" in the audio signal.
**arguments**
- {Number+} -> distortion amount, greater then 0 (optional, default=5)
- {Float+} -> dry-wet factor 0-1 (optional, default=1)
```java
new sample violin_c time(1) fx(kink 15)
```
## distort
A distortion/overdrive/soft-clipping effect. Uses the `tanh()` algorithm.
Alias: `fx(drive)`
**arguments**
- {Number+} -> distortion amount, greater then 0 (optional, default=2)
- {Float+} -> dry-wet factor 0-1 (optional, default=1)
```java
new sample kick_909 fx(drive 15)
```
## degrade
A downsampling/8bit/chiptune effect. The signal is downsample by a factor, where 0 means no downsampling (original samplerate) and 0.5 is half the samplerate etc (e.g. 44100 * 0.5 = 22050).
Alias: `fx(chip)`
**arguments**
- {Float+} -> downsampling amount between 0-1 (default = 0.5)
- {Float+} -> dry-wet factor 0-1 (optional, default=1)
```java
new synth saw fx(degrade 0.75)
```
## comb
A combfilter effect. This combines a small delayed version of the sound with the original sound resulting in a combfilter, giving a metallic quality to the sound. The first argument is the semitone the filter is tuned at (synced to the scale and allowing for detuning with floating points), the second optional argument is a feedback amount.
**arguments**
- {Number+} -> filter frequency as note semiton (default=0)
- {Float+} -> filter feedback between 0 and 0.99 (default=0.8)
- {Float+} -> dry-wet factor 0-1 (optional, default=0.5)
```java
new synth saw fx(comb 82 0.4)
```
## lfo
Add a Low Frequency Oscillator effect to the sound. This results in a rapidly fading in/out sounding effect (helicopter sound). Various arguments allow to shape the speed and type of wave for modulation. The first argument is the rate in division. The second argument is the shape type `square`, `up`, `down` or `sine`. With the third argument you can change the lowest amplitude of the modulation and with the optional fourth argument you can change the width (only works with the square)
Alias: `fx(tremolo)`
**arguments**
- {Division} -> speed of the LFO (default=1/16)
- {Name} -> type of the wave, square, up, down or sine (default=square)
- {Float+} -> dry-wet factor 0-1 (optional, default=1)
- {Float+} -> width of the square wave between 0-1 (optional, default=0.5)
- {Float+} -> offset of the waveform 0-1 (optional, default=0)
```
fx(lfo)
fx(lfo <time-division>)
fx(lfo <time> <type>)
fx(lfo <time> <type> <range> <width>)
```
```java
new loop amen fx(lfo 1/16)
```
## vocoder
A classic vocoder effect consisting of 16 resonant bandpass filters spread logarithmically between a low and high frequency range with a specified resonance Q factor. The input sound will be analyzed through the bands with an amplitude follower (with variable release time) and the carrier sound will be used to output the synthesized result. The carrier is noise by default, but can be set to receive from an other named synth or sample. For this use the `name()` method. Optionally a threshold can adjust which bands are passed through, only if their amplitude is loud enough.
**arguments**
- {Name} -> carrier source name of other instrument (default=noise)
- {Number+} -> bandpass filter resonance 0-100 (default=15)
- {Number+} -> amplitude following release time in ms (default=50)
- {Float+} -> wet dry ratio 0-1 (default=1)
- {Number+} -> lowest frequency of the filterbank (default=50)
- {Number+} -> highest frequency of the filterbank (default=10000)
- {Float+} -> band threshold 0-1 (default=0)
```java
new synth saw name(bass) note(0 0) shape(-1) gain(1 0 1)
new loop amen fx(vocoder bass 20 100 1 50 5000)
```
================================================
FILE: docs/deprecated-docs/05-ring.md
================================================
# List Methods
Mercury uses the [`total-serialism`](https://www.npmjs.com/package/total-serialism) Node Package to generate and transform numbersequences that are used for melodies, rhythms, parameters and basically anything that can be sequenced in the environment. These numbersequences were originally refered to as `ring`'s, because the sequence (list) is a circular array, but now the keyword `list` can also be used for simplicity. Every step an instrument takes in the sequencer based on the time-interval from `time()` a counter increments (eg 0, 1, 2, 3...n) and uses that as an index to look up the value in the list. When the index is higher then the amount of values in the list it will return to the beginning of the list, hence a circular list or `ring`.
```
list <unique-list-name> [ value0 v1 v2 ... v-n ]
```
example
```java
list someNumbers [0 10 20 30]
list someFloats [1.618 3.1415]
list twoDimensional [0 1 [2 3] 4 [5 6 7]]
list someSamples [kick_909 hat_909 snare_909 hat_909]
list count spread(10)
list rands random(5 0 20)
```
**Note:** Some variable names are not allowed because they are part of the built-in namespace for datastructures. These are: ` set, new, list, bang, int, float, mode, zlclear, zlmaxsize`. Using names that are also a function is not advised (eg. `gain`, `shape`, `time` etc.)
[`total-serialism`](https://www.npmjs.com/package/total-serialism) is a set of methods used for procedurally generating and transforming number sequences. This library is mainly designed with algorithmic composition of music in mind, but can surely be useful for other purposes that involve generating and manipulating lists and numbers. The library is a result of my research in algorithmic composition, livecoding and electronic music and was first prototyped with Max/MSP in the Mercury livecoding environment.
# Table of Content
- [Param Glossary](#param-glossary)
- [Generative Methods](#generative-methods)
- [spread / spreadFloat](#spread-spreadfloat)
- [spreadInclusive / spreadInclusiveFloat](#spreadinclusive-spreadinclusivefloat)
- [fill](#fill)
- [sine / cosine](#sine-cosine)
- [sineFloat / cosineFloat](#sinefloat-cosinefloat)
- [saw / sawFloat](#saw-sawfloat)
- [square / squareFloat](#square-squarefloat)
- [binaryBeat](#binaryBeat)
- [spacingBeat](#spacingBeat)
- [Algorithmic Methods](#algorithmic-methods)
- [euclidean](#euclidean)
- [hexBeat](#hexbeat)
- [fibonacci](#fibonacci)
- [pisano](#pisano)
- [pell](#pell)
- [lucas](#lucas)
- [threeFibonacci](#threefibonacci)
- [Stochastic Methods](#stochastic-methods)
- [randomSeed](#randomseed)
- [random](#random)
- [randomFloat](#randomfloat)
- [drunk](#drunk)
- [drunkFloat](#drunkfloat)
- [urn](#urn)
- [coin](#coin)
- [dice](#dice)
- [clave](#clave)
- [twelveTone](#twelvetone)
- [choose](#choose)
- [pick](#pick)
- [shuffle](#shuffle)
- [expand](#expand)
- [markovTrain](#markovtrain) *MercuryPlayground Only*
- [markovChain](#markovchain) *MercuryPlayground Only*
- [Transformative Methods](#transformative-methods)
- [clone](#clone)
- [join](#join)
- [copy](#copy)
- [pad](#pad)
- [every](#every)
- [flat](#flat)
- [invert](#invert)
- [lace](#lace)
- [lookup](#lookup)
- [merge](#merge)
- [palindrome](#palindrome)
- [repeat](#repeat)
- [reverse](#reverse)
- [rotate](#rotate)
- [slice](#slice)
- [split](#split)
- [cut](#cut)
- [spray](#spray)
- [stretch](#stretch)
- [unique](#unique)
- [Utility Methods](#utility-methods)
- [wrap](#wrap)
- [clip](#clip)
- [fold](#fold)
- [map](#map)
- [mod](#mod)
- [add](#add)
- [subtract](#subtract)
- [multiply](#multiply)
- [divide](#divide)
- [normalize](#normalize)
- [equals](#equals) *MercuryPlayground Only*
- [notEquals](#notequals) *MercuryPlayground Only*
- [greater](#greater) *MercuryPlayground Only*
- [greaterEquals](#greaterequals) *MercuryPlayground Only*
- [less](#less) *MercuryPlayground Only*
- [lessEquals](#lessequals) *MercuryPlayground Only*
- [Translate Methods](#translate-methods)
- midiToNote
- midiToFreq
- noteToMidi
- noteToFreq
- freqToMidi
- freqToMidi
- freqToNote
- relativeToMidi
- relativeToFreq
- chromaToRelative
- ratioToCent
- chordsFromNumerals
- chordsFromNames
- [divisionToMs](#divisiontoms)
- divisionToRatio
- ratioToMs
- scaleNames
- toScale
- [textCode](#textCode)
# Param Glossary
**Values**
- `Value` -> Any Number or Name
- `Number` -> Int+, Int or Float
- `Bool` -> 0 or 1 (true or false)
- `Int+` -> A positive whole number, bigger than 0
- `Int` -> A whole number, negative or positive, including 0
- `Float` -> A floating-point number, negative or positive, including 0
- `Name` -> A combination of letter-characters, may include capital letter, underscores and digits
**Lists**
- `List` -> A list with `Value`'s
- `NumberList` -> A list with `Number`'s
- `IntList+` -> A list with `Int+`'s
- `IntList` -> A list with `Int`'s
- `FloatList` -> A list with `Float`'s
- `NameList` -> A list with `Name`'s
# Generative Methods
## spread spreadFloat
Generate a list of n-length of evenly spaced values between a starting number up untill (but excluding) the 3th argument. Flipping the low and high values results in a descending list.
**arguments**
- {Int+} -> Length of list
- {Int/Float} -> Low value
- {Int/Float} -> High value (excluded)
```java
list spr1 spread(5 0 12)
// => [0 2 4 7 9]
list spr2 spreadFloat(5 -1 1)
// => [-1 -0.6 -0.2 0.2 0.6]
list spr3 spreadF(5 0 2)
// => [0 0.4 0.8 1.2 1.6]
list spr4 spread(5 12 0)
// => [9 7 4 2 0]
```
## spreadInclusive spreadInclusiveFloat
Generate a list of n-length of evenly spaced values between a starting number up to (and including) the 3th argument. Flipping the low and high values results in a descending list.
**arguments**
- {Int+} -> Length of list
- {Number} -> Low value
- {Number} -> High value (included)
```java
list spi1 spreadInclusive(5 0 12)
// => [0 3 6 9 12]
list spi2 spreadInclusiveFloat(5 -1 1)
// => [-1 -0.5 0 0.5 1]
list spi3 spreadInclusiveF(5 0 2)
// => [0 0.5 1 1.5 2]
list spi4 spreadInclusive(5 12 0)
// => [12 9 6 3 0]
```
## fill
Fill a list with values. Arguments are in pairs. Every pair consists of `<value, amount>` The value is repeated n-amount of times in the list.
**arguments**
- {Value} -> value to duplicate
- {Int+} -> amount of duplicates
```java
list fll1 fill(10 2 15 3 20 4)
// => [10 10 15 15 15 20 20 20 20]
list fll2 fill(kick_min 2 hat_min 3)
// => [kick_min kick_min hat_min hat_min hat_min]
```
## sine cosine
Generate a list with n-periods of a (co)sine function. Optional last arguments set lo and hi range. Only setting first range argument sets the low-range to 0.
**arguments**
- {Int+} -> Length of list
- {Number} -> Periods of (co)sine-wave (optional, default=1)
- {Number} -> Low range of values (optional, default=0)
- {Number} -> High range of values (optional, default=12)
- {Number} -> Phase offset (optional, default=0)
```java
list sin1 sine(10)
// => [6 9 11 11 9 6 2 0 0 2]
list sin2 sine(10 1 -12 12)
// => [0 7 11 11 7 0 -7 -11 -11 -7]
list sin3 sine(10 2 0 5)
// => [2 4 3 1 0 2 4 3 1 0]
// generate 10 ints with 4 periods a sine function
list sin4 sine(11 4 0 7)
// 6.00 ┼╭╮ ╭╮ ╭╮
// 5.00 ┤││╭╮ ││ ││
// 4.00 ┤│││╰╮││ ││
// 3.00 ┼╯││ │││ ││
// 2.00 ┤ ││ ││╰╮││
// 1.00 ┤ ││ ││ ╰╯│
// 0.00 ┤ ╰╯ ╰╯ ╰
```
```java
list cos1 cosine(10)
// => [12 10 7 4 1 0 1 4 7 10]
list cos2 cosine(10 1 -12 12)
// => [12 9 3 -3 -9 -12 -9 -3 3 9]
list cos3 cosine(10 2 0 5)
// => [5 3 0 0 3 4 3 0 0 3]
```
## sineFloat cosineFloat
Generate a list with n-periods of a (co)sine function. Optional last arguments set lo and hi range. Only setting first range argument sets the low-range to 0.
**arguments**
- {Int+} -> Length of list
- {Number} -> Periods of (co)sine-wave (optional, default=1)
- {Number} -> Low range of values (optional, default=-1)
- {Number} -> High range of values (optional, default=1)
- {Number} -> Phase offset (optional, default=0)
```java
// generate 16 floats with 1 period of a cosine function
list cos4 cosineFloat(8)
// 1.00 ┼╮
// 0.60 ┤╰─╮ ╭─
// 0.20 ┼ ╰╮ ╭╯
// -0.20 ┤ ╰╮ ╭╯
// -0.60 ┤ ╰╮ ╭╯
// -1.00 ┤ ╰────╯
// frequency modulation of the period argument with another list
list sin5 sineFloat(40 sineFloat(40 4 1 5))
//=> 1.00 ┤ ╭╮ ╭──╮ ╭╮ ╭╮ ╭─╮
// 0.80 ┤ │╰╮╭╯ │ ╭╮ ╭╮ ││ ││ ╭╯ │
// 0.60 ┤╭╯ ││ ╰╮││ ││ ││ ││ │ │
// 0.40 ┤│ ╰╯ │││ ││ ││ ││ │ │
// 0.20 ┤│ ││╰╮╭╯│╭╮ ││ ││ │ │╭╮ ╭╮
// 0.00 ┼╯ ││ ││ ││╰╮╭╯│ ╭╮││ │ │││ ╭╯│
// -0.20 ┤ ││ ││ ││ ││ │ ││││ │ │││ │ │
// -0.40 ┤ ││ ││ ││ ││ │ ││││ │ ╰╯╰╮ │ │
// -0.60 ┤ ││ ╰╯ ││ ││ │ ││││ │ │ │ │
// -0.80 ┤ ││ ││ ╰╯ │ │╰╯│ │ ╰─╯ │
// -1.00 ┤ ╰╯ ╰╯ ╰─╯ ╰─╯ ╰
```
Alias: `sinF()`, `cosF()`
## saw sawFloat
Generate a list with n-periods of a saw/phasor function. Optional last arguments set lo and hi range and phase offset. Only setting first range argument sets the low-range to 0
**arguments**
- {Int} -> Length of output list (resolution)
- {Number/List} -> Periods of the wave (option, default=1)
- {Number} -> Low range of values (optional, default=-1)
- {Number} -> High range of values (optional, default=1)
- {Number} -> Phase offset (optional, default=0)
```java
list saw1 sawFloat(25 2.5)
//=> 0.80 ┤ ╭─╮ ╭─╮
// 0.44 ┤ ╭─╯ │ ╭─╯ │
// 0.08 ┤ ╭╯ │ ╭╯ │
// -0.28 ┼ ╭─╯ │ ╭─╯ │ ╭─
// -0.64 ┤╭─╯ │╭─╯ │╭─╯
// -1.00 ┼╯ ╰╯ ╰╯
// Modulation on frequency
list saw2 saw(34 sinF(30 2 0 100) 0 12)
//=> 11.00 ┼ ╭╮ ╭╮╭╮
// 10.00 ┤ ││╭─╮ ╭╮ ││││
// 9.00 ┤ │││ │ ││ ╭╮││││
// 8.00 ┤ ╭─╮ │││ │ ╭╯│ ││││││ ╭
// 7.00 ┤ ╭╯ │ │││ │ ╭╯ │ ││││││ │
// 6.00 ┤ │ │ │││ │ ╭╯ │ │╰╯││╰╮ │
// 5.00 ┤ │ │╭╮╭╯││ │ │ │ │ ││ │ │
// 4.00 ┤ │ ││││ ││ │ │ │ │ ││ │ │
// 3.00 ┤ │ ││╰╯ ││ │ │ │ │ ││ ╰╮ │
// 2.00 ┤ │ ││ ││ ╰╮ │ │ │ ╰╯ │ │
// 1.00 ┤ ╭╯ ││ ╰╯ │╭╯ │ │ ╰─╮│
// 0.00 ┼─╯ ╰╯ ╰╯ ╰─╯ ╰╯
```
Alias: `sawF()`
## square squareFloat
Generate a list with n-periods of a square/pulse wave function. Optional last arguments set lo and hi range and pulse width. Only setting first range argument sets the low-range to 0.
**arguments**
- {Int} -> Length of output list (resolution)
- {Number/List} -> Periods of the wave (option, default=1)
- {Number} -> Low range of values (optional, default=0)
- {Number} -> High range of values (optional, default=1)
- {Number} -> Pulse width (optional, default=0.5)
```java
list sqr1 square(30 4 0 1 0.2)
//=> 1.00 ┼─╮ ╭─╮ ╭─╮ ╭╮
// 0.00 ┤ ╰─────╯ ╰────╯ ╰─────╯╰─────
```
Alias: `rect()`
```java
// Frequency Modulation with Gen.sin
list sqr2 squareFloat(30 sinF(30 2 1 5))
//=> 1.00 ┼───╮ ╭──╮╭──╮ ╭─╮ ╭─╮ ╭─
// 0.80 ┤ │ │ ││ │ │ │ │ │ │
// 0.60 ┤ │ │ ││ │ │ │ │ │ │
// 0.40 ┤ │ │ ││ │ │ │ │ │ │
// 0.20 ┤ │ │ ││ │ │ │ │ │ │
// 0.00 ┤ ╰─────╯ ╰╯ ╰─╯ ╰──╯ ╰─╯
```
Alias: `squareF()`, `rectFloat()`, `rectF()`
## binaryBeat
Generate a binary rhythm from a positive integer number or an array of numbers. Returns the binary value as an array of separated 1's and 0's useful for representing rhythmical patterns.
Alias: `binary`
**arguments**
- {Int+/List} -> List of numbers to convert to binary representation
```js
// generate a binary array from a single number
list bny1 binaryBeat(358);
//=> [1 0 1 1 0 0 1 1 0]
// use an array of numbers and concatenate binary representations
list bny2 binaryBeat([4 3 5]);
//=> [1 0 0 1 1 1 0 1]
// negative values are clipped to 0
list bny3 binaryBeat([-4 4]);
//=> [0 1 0 0]
```
## spacingBeat
Generate an array of 1's and 0's based on a positive integer number or array. Every number in the array will be replaced by a 1 with a specified amount of 0's appended to it. Eg. a 2 => 1 0, a 4 => 1 0 0 0, etc. This technique is useful to generate a rhythm based on spacing length between onsets
Alias: `spacing`, `space`
**arguments**
- {Int+/List} -> List of numbers to convert to spaced rhythm
```js
// generate a rhythm based on numbered spacings
list spc1 spacingBeat(2 3 2)
//=> [1 0 1 0 0 1 0]
// also works with an array as input
list spc2 spacingBeat([4 2 0])
//=> [1 0 0 0 1 0 0]
```
# Algorithmic Methods
## euclidean
Generate a euclidean rhythm evenly spacing n-beats amongst n-steps.Inspired by Godfried Toussaints famous paper "The Euclidean Algorithm Generates Traditional Musical Rhythms".
**arguments**
- {Int+} -> length of list (optional, default=8)
- {Int+} -> beats (optional, default=4)
- {Int} -> rotate (optional, default=0)
```java
list euc1 euclidean()
// => [1 0 1 0 1 0 1 0]
list euc2 euclidean(7 5)
// => [1 1 0 1 1 0 1]
list euc3 euclidean(7 5 2)
// => [0 1 1 1 0 1 1]
```
Alias: `euclid()`
## hexBeat
Generate hexadecimal rhythms. Hexadecimal beats make use of hexadecimal values (0 - f) that are a base-16 number system. Because one digit in a base-16 number system has 16 possible values (0 - 15) these can be converted to 4 bits that therefore can be seen as groups of 4 16th notes. These hexadecimal values will then represent any permutation of 1's and 0's in a 4 bit number, where 0 = 0 0 0 0, 7 = 0 1 1 1, b = 1 0 1 1, f = 1 1 1 1 and all possible values in between.
**arguments**
- {Name} -> hexadecimal characters (0 t/m f) (optional, default=8)
```java
list hex1 hexBeat()
// => [1 0 0 0]
list hex2 hexBeat(a)
// => [1 0 1 0]
list hex3 hexBeat(f9cb)
// => [1 1 1 1 1 0 0 1 1 1 0 0 1 0 1 1]
```
Alias: `hex()`
- [Learn hex beats](https://kunstmusik.github.io/learn-hex-beats/)
## fibonacci
Generate the Fibonacci sequence `F(n) = F(n-1) + F(n-2)`. The ratio between consecutive numbers in the fibonacci sequence tends towards the Golden Ratio (1+√5)/2.
`OEIS: A000045` (Online Encyclopedia of Integer Sequences)
**arguments**
- {Int+} -> output length of list
- {Int+} -> offset, start the sequence at nth-fibonacci number (optional, default=0)
```java
list fib1 fibonacci(10)
// => [0 1 1 2 3 5 8 13 21 34]
list fib2 fibonacci(3 10)
// => [55 89 144]
```
## pisano
Generate the Pisano period sequence. The pisano period is a result of applying a modulo operation on the Fibonacci sequence `F[n] = (F[n-1] + F[n-2]) mod a`. The length of the period differs per modulus value, but the sequence will always have a repetition.
**arguments**
- {Int+} -> modulus for pisano period (optional, default=12)
- {Int+} -> output length of list (optional, defaults to pisano-period length)
```java
list psn1 pisano()
// => [0 1 1 2 3 5 8 1 9 10 7 5 0 5 5 10 3 1 4 5 9 2 11 1]
list psn2 pisano(3)
// => [0 1 1 2 0 2 2 1]
list psn3 pisano(11)
// => [0 1 1 2 3 5 8 2 10 1]
```
## pell
Generate the Pell numbers `F(n) = 2 * F(n-1) + F(n-2)`. The ratio between consecutive numbers in the pell sequence tends towards the Silver Ratio 1 + √2.
`OEIS: A006190` (Online Encyclopedia of Integer Sequences)
**arguments**
- {Int+} -> output length of list
```java
list pll1 pell(8)
// => [0 1 2 5 12 29 70 169]
```
## lucas
Generate the Lucas numbers `F(n) = F(n-1) + F(n-2), with F0=2 and F1=1`.
`OEIS: A000032` (Online Encyclopedia of Integer Sequences)
**arguments**
- {Int+} -> output length of list
```java
list luc1 lucas(8)
// => [2 1 3 4 7 11 18 29]
```
## threeFibonacci
Generate the Tribonacci numbers `F(n) = 2 * F(n-1) + F(n-2)`. The ratio between consecutive numbers in the 3-bonacci sequence tends towards the Bronze Ratio (3 + √13) / 2.
`OEIS: A000129` (Online Encyclopedia of Integer Sequences)
**arguments**
- {Int+} -> output length of list
```java
list tfi1 threeFibonacci(8)
// => [0 1 3 10 33 109 360 1189]
```
# Stochastic Methods
## randomSeed
Set the seed for the Random Number Genrators. A value of `0` sets to unpredictable seeding. The seed can only be set **once** in the code, and the last value will take effect.
```java
set randomSeed 31415
// ^^^^^^^^^^^ will be overwritten by 1618 before random() call
list randomValues random(10 0 100)
// ^^^^^^^^^^^ the random() will use the seed from below
set randomSeed 1618
// ^^^^^^^^^^^ 1618 overwrites 31415
```
## random
Generate a list of random integers between a specified range (excluding high value).
**arguments**
- {Int+} -> number of values to output
- {Int} -> minimum range (optional, default=0)
- {Int} -> maximum range (optional, default=2)
```java
set randomSeed 31415
list rnd1 random(5)
// => [1 0 0 1 1]
list rnd2 random(5 12)
// => [0 10 3 2 2]
list rnd3 random(5 -12 12)
// => [-2 -5 -8 -11 6]
```
Alias: `rand()`
## randomFloat
Generate a list of random floating-point values between a specified range (excluding high value).
**arguments**
- {Int+} -> number of values to output
- {Number} -> minimum range (optional, default=0)
- {Number} -> maximum range (optional, default=1)
```java
set randomSeed 31415
list rnf1 randomFloat(5)
// => [0.81 0.32 0.01 0.85 0.88]
list rnf2 randomFloat(5 0 12)
// => [0.16 10.72 3.16 262 2.34]
list rnf3 randomFloat(5 -12 12)
// => [-1.19 -4.21 -7.36 -10.31 6.82]
```
Alias: `randF()`
## drunk
Generate a list of random values but the next random value is within a limited range of the previous value generating a random "drunk" walk, also referred to as brownian motion.
**arguments**
- {Int+} -> number of values to output
- {Int} -> step range for next random value
- {Int} -> minimum range (optional, default=null)
- {Int} -> maximum range (optional, default=null)
- {Int} -> starting point (optional, default=(lo+hi)/2)
- {Bool} -> fold between lo and hi range (optional, default=true)
```java
list dr1 drunk(10 5 0 24)
//=> [ 13 10 14 13 14 13 15 10 8 4 ]
// 22.00 ┼ ╭╮
// 17.80 ┼─╮╭─╮ ││
// 13.60 ┤ ││ ╰╮╭╯│
// 9.40 ┤ ││ ╰╯ │
// 5.20 ┤ ╰╯ │
// 1.00 ┤ ╰
list dr2 drunk(10 4 0 12 6 false)
//=> [ 2 -2 2 1 -3 -1 -2 -1 3 6 ]
// 2.00 ┤╭╮
// -0.20 ┤│╰╮ ╭
// -2.40 ┼╯ ╰╮ │
// -4.60 ┤ │╭╮ ╭╯
// -6.80 ┼ ╰╯│╭╯
// -9.00 ┤ ╰╯
```
## drunkFloat
Generate a list of random floating-point values but the next random value is within a limited range of the previous value generating a random "drunk" walk, also referred to as brownian motion.
**arguments**
- {Int+} -> number of values to output
- {Number} -> step range for next random value
- {Number} -> minimum range (optional, default=null)
- {Number} -> maximum range (optional, default=null)
- {Number} -> starting point (optional, default=(lo+hi)/2)
- {Bool} -> fold between lo and hi range (optional, default=true)
```java
list dr1 drunkFloat(5)
//=> [ 0.493, 0.459, 0.846, 0.963, 0.400 ]
// 0.88 ┼╮╭╮
// 0.76 ┤╰╯│
// 0.63 ┤ │
// 0.51 ┤ ╰╮
// 0.39 ┤ │
// 0.26 ┤ ╰
```
Alias: `drunkF()`
## urn
Generate a list of unique random integer values between a certain specified range (excluding high val). An 'urn' is filled with values and when one is picked it is removed from the urn. If the outputlist is longer then the range, the urn refills when empty. On refill it is made sure no repeating value can be picked.
**arguments**
- {Int+} -> number of values to output
- {Number} -> maximum range (optional, default=12)
- {Number} -> minimum range (optional, defautl=0)
```java
set randomSeed 1618
list urn1 urn(5)
// => [3 7 10 0 2]
list urn2 urn(8 4)
// => [0 2 1 3 1 3 0 2]
list urn3 urn(8 10 14)
// => [13 10 12 11 12 10 13 11]
```
## coin
Generate a list of random integer values 0 or 1 like a coin toss, heads/tails. Or
**arguments**
- {Int+} -> number of coin tosses to output as list
```java
list coin1 coin(8)
// => [1 0 1 0 1 0 1 1]
```
## dice
Generate a list of random integer values 1 to 6 like the roll of a dice.
**arguments**
- {Int+} -> number of dice rolls to output as list
```java
list dice1 dice(8)
// => [5 4 6 4 4 5 4 2]
```
## clave
Generate random clave patterns. The output is a binary list that represents a rhythm, where 1's represent onsets and 0's rests. First argument sets the list length output, second argument sets the maximum gap between onsets, third argument the minimum gap.
**arguments**
- {Int+} -> output length of rhythm (default=8)
- {Int+} -> maximum gap between onsets (default=3)
- {Int+} -> minimum gap between onsets (default=2)
```java
list clv1 clave()
//=> [ 1 0 1 0 0 1 0 1 ]
//=> █ █ █ █
list clv2 clave(8)
//=> [ 1 0 0 1 0 1 0 1 ]
//=> █ █ █ █
list clv3 clave(16 4)
//=> [ 1 0 0 0 1 0 1 0 0 0 1 0 0 1 0 1 ]
//=> █ █ █ █ █ █
list clv4 clave(16 3 1)
//=> [ 1 0 0 1 0 0 1 1 0 0 1 0 1 0 0 1 ]
//=> █ █ ██ █ █ █
```
## twelveTone
Generate a list of 12 semitones then shuffle the list based on the random seed.
**arguments**
- {None}
```java
list twv1 twelveTone()
// => [10 7 6 3 2 9 8 4 1 5 0 11]
```
```java
//Basically a shorthand for:
list notes spread(12)
list notes shuffle(notes)
```
## choose
Choose random items from a list provided with uniform probability distribution. The default list is a list of 0 and 1.
**arguments**
- {Int+} -> length of list output
- {List} -> items to choose from (optional, default=[0 1])
```java
set randomSeed 62832
list samples [hat snare kick]
list sequence choose(10 samples)
// => [hat kick hat kick hat snare kick hat hat hat]
list notes [0 3 7 5 9 12]
list melody choose(10 notes)
// => [0 5 3 9 0 7 3 12 3 7]
```
## pick
Pick random items from a list provided. An "urn" is filled with values and when one is picked it is removed from the urn. If the outputlist is longer then the range, the urn refills when empty. On refill it is made sure no repeating value can be picked.
**arguments**
- {Int+} -> length of list output
- {List} -> items to choose from (optional, default=[0 1])
```java
set randomSeed 62832
list samples [hat snare kick tom]
list sequence pick(10 samples)
// => [hat kick tom snare tom hat snare kick tom hat]
list notes [0 3 7 5 9 12]
list melody pick(10 notes)
// => [3 0 7 9 12 5 0 7 12 9]
```
## shuffle
Shuffle a list, influenced by the random seed. Based on the Fisher-Yates shuffle algorithm by Ronald Fisher and Frank Yates in 1938. The algorithm has run time complexity of O(n)
**arguments**
- {List} -> List to shuffle
```java
set randomSeed 14142
list samples [hat snare kick tom]
list shf1 shuffle(samples)
// => [snare tom kick hat]
list notes [0 3 7 5 9 12]
list shf2 scramble(notes)
// => [12 0 3 7 5 9]
```
## expand
Expand a list based upon the pattern within a list. The pattern is derived from the rate in change between values by calculating the differences between every consecutive value. The newly generated values are selected randomly from the list of possible changes, but in such a way that every change occurs once in the sequence of total changes before reshuffling and selecting the next one (see the `pick` method for explanation). The resulting output starts with the input list.
**arguments**
- {Int+} -> length of list output
- {List} -> List to expand
```java
set randomSeed 3141
list notes [0 9 7 3 5 0 -1]
list exp expand(notes 30)
//=> 9.00 ┤╭╮ ╭╮
// 6.80 ┤│╰╮ ││
// 4.60 ┤│ │╭╮ ││
// 2.40 ┤│ ╰╯│ │╰─╮ ╭─╮
// 0.20 ┼╯ ╰─╮╭╯ │ │ │╭
// -2.00 ┤ ╰╯ ╰╮ ╭─╮ │ ╰╯
// -4.20 ┼ │ │ │ ╭╮│
// -6.40 ┤ ╰╮ │ │ │╰╯
// -8.60 ┤ │╭╮│ ╰─╮ │
// -10.80 ┤ ╰╯╰╯ │╭╮│
// -13.00 ┤ ╰╯╰╯
set randomSeed 6181
list exp2 expand(notes 30)
//=> 9.00 ┤╭╮
// 6.80 ┤│╰╮
// 4.60 ┤│ │╭╮
// 2.40 ┤│ ╰╯│ ╭╮╭╮
// 0.20 ┼╯ ╰─╮╭╮ │╰╯╰╮ ╭──
// -2.00 ┤ ╰╯│ ╭╮│ ╰╮ │
// -4.20 ┼ ╰╮ │││ ╰╮ ╭╮ │
// -6.40 ┤ │ │╰╯ │╭╮ ││ │
// -8.60 ┤ ╰╮│ ╰╯╰╮│╰╮│
// -10.80 ┤ ╰╯ ││ ╰╯
// -13.00 ┤ ╰╯
```
## markovTrain
Build a Markov Chain transition table from a set of datapoints (a list) and use it together with `markovChain()` to generate a new list of values based on the probabilities of the transitions in the provided training dataset. A Markov Chain is a model that describes possible next events based on a current state (first order) or multiple previous states (2nd, 3rd, ... n-order). The Markov Chain is a broadly used method in algorithmic music to generate new material (melodies, rhythms, but even words) based on a set of provided material, but can also be used in linguistics to analyze word or sentence structures. The first argument is the list to analyze, the second argument is the nth-order (default = 2). In theory, longer chains preserve the original structure of the model, but won't generate as diverse outputs. The output is a
Alias: `markov()`
**arguments**
- {List} -> List to analyze into transition table
- {Int+} -> Order of the markov-chain (optional, default=2)
- return -> Transition table as a string
```js
list melody [ 0 0 7 7 9 9 7 5 5 4 4 2 2 0 ]
list model markovTrain(melody 2)
```
## markovChain
Generate a list of values of n-length based on a markov transition table (a model) that was trained with `markovTrain()`. The first argument determines the output length, the second input is the reference to the markov model. The resulting output is based on the probabilities that are captured within the transition table. This means the output can also be directed by the `randomSeed`.
```js
list melody [ 0 0 7 7 9 9 7 5 5 4 4 2 2 0 ]
list model markovTrain(melody 3)
set randomSeed 3141
list markovMelody markovChain(16 model)
//=> [9 7 7 5 5 4 4 2 2 0 0 5 4 4 2 2]
```
# Transformative Methods
## clone
Duplicate a list with an offset added to every value
**arguments**
- {IntList} -> List to clone
- {Int, Int2, ... Int-n} -> amount of clones with integer offset
```java
list notes [0 3 7]
list melody clone(notes 0 12 7 -7)
// => [0 3 7 12 15 19 7 10 14 -7 -4 0]
```
## join
Join lists into one list. Using multiple lists as arguments is possible.
**arguments**
- {List-0, List-1, ..., List-n} -> List to combine
```java
list partA [0 3 7]
list partB [24 19 12]
list partC [-7 -3 -5]
list phrase join(partA partB partC)
// => [0 3 7 24 19 12 -7 -5 -3]
list partD [kick hat snare hat]
list partE [hat hat hat snare]
list sequence join(partD partE)
// => [kick hat snare hat hat hat hat snare]
```
Alias: `combine()`, `concat()`
## copy
Copy a list a certain amount of times.
**arguments**
- {List} -> List to duplicate
- {Int+} -> amount of duplicates (optional, default=2)
```java
list notes [0 3 7]
list phrase copy(notes 4)
// => [0 3 7 0 3 7 0 3 7 0 3 7]
```
Alias: `duplicate(), dup()`
## pad
Pad a list with zeroes (or any other value) up to the length specified. The padding value can optionally be changed and the shift argument rotates the list n-steps left or right (negative). This method is similar to `every()` except arguments are not specified in musical bars/divisions.
**arguments**
- {NumberList} -> List to use every n-bars
- {Int} -> output length of list (optional, default=16)
- {Value} -> padding value for the added items (optional, default=0)
- {Number} -> shift in steps (optional, default=0)
```java
list pad2 pad(pad1 9)
// [ 3 7 11 12 0 0 0 0 0]
list pad3 pad([c f g] 11 - 4)
// [ - - - - c f g - - - - ]
```
## every
Add zeroes to a list with a number sequence. The division determines the amount of values per bar. The total length = bars * div. Very useful for rhythms that must occur once in a while, but can also be use for melodic phrases.
**arguments**
- {IntList} -> List to use every n-bars
- {Int} -> amount of bars
- {Int} -> amount of values per bar
```java
list rhythm [1 0 1 1 0 1 1]
list sequence every(rhythm 2 8)
// => [1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0]
list melody [12 19 24 27 24]
list phrase every(melody 2 8)
// => [12 19 24 27 24 0 0 0 0 0 0 0 0 0 0 0]
```
## flat
Flatten a multidimensional list. Optionally set the depth for the flattening with the second argument.
**arguments**
- {List} -> list to flatten
- {Number} -> depth of flatten (default=Infinity)
```java
list fl1 flat([1 [2 3 [ 4 ] 5] 6])
//=> [ 1 2 3 4 5 6 ]
```
## invert
Invert a list of values by mapping the lowest value to the highest value and vice versa, flipping everything in between. Second optional argument sets the center to flip values against. Third optional argument sets a range to flip values against.
**arguments**
- {IntList} -> List to invert
- {Int} -> invert center / low range (optional)
- {Int} -> high range (optional)
```java
list notes [0 3 7 12]
list inv1 invert(notes)
// => [12 9 5 0]
list inv2 invert(notes 5)
// => [10 7 3 -2]
list inv3 invert(notes 3 10)
// => [13 10 6 1]
```
Alias: `inverse()`, `flip()`, `inv()`
## lace
Interleave two or more lists. The output length of the is always the length of the longest input list.
**arguments**
- {List0, List1, ..., List-n} -> Lists to interleave
```java
list partA [0 3 7 5 0]
list partB [12 19 15]
list partC [24 22]
list melody lace(partA partB)
// => [0 12 24 3 19 22 7 15 5 0]
```
Alias: `zip()`
## lookup
Build a list of items based on another list of indices
The values are wrapped within the length of the lookup list
**arguments**
- {NumberList} -> List with indeces to lookup
- {List} -> List with values returned from lookup
- {List} -> Looked up values
```java
list items [c e f g]
list indices [0 1 1 2 0 2 2 1]
// first list is the index, second list are the items to lookup
list notes lookup(indices items)
//=> [ c e e f c f f e ]
// indices are wrapped between listlength
list indices [8 -5 144 55]
list notes lookup(indices items)
//=> [ g e c e ]
```
Alias: `get()`
## merge
Merge all values of two lists on the same index into a 2-dimensional list. Preserves the length of longest input list.
**arguments**
- {List0, List1, ..., List-n} -> Lists to merge
```java
list partA [0 3 7 5 0]
list partB [12 19 15]
list merged merge(partA partB)
// => [[0 12] [3 19] [7 15] 5 0]
// mix()
```
Alias: `mix()`
## palindrome
Reverse a list and concatenating to the input, creating a palindrome of the list. A second argument 1 will remove the duplicates halfway through and at the end.
**arguments**
- {List} -> list to make palindrome of
- {Bool} -> no-double flag (optional, default=0)
```java
list notes [0 3 7 12]
list melodyA palindrome(notes)
// => [0 3 7 12 12 7 3 0]
list melodyB palindrome(notes 1)
// => [0 3 7 12 7 3]
// palin()
// mirror()
```
Alias: `palin()`, `mirror()`
## repeat
Repeats separate values in a list a certain amount of times. The repeats argument can be a list that will be iterated for every value in the to-repeat list.
**arguments**
- {List} -> List to repeat
- {Int+/IntList} -> amount of repeats per value
```java
list notes [0 3 7]
list phrase repeat(notes 4)
// => [0 0 0 0 3 3 3 3 7 7 7 7]
list repeats [2 5 3]
list phraseB repeat(notes repeats)
// => [0 0 3 3 3 3 3 7 7 7]
// also works with strings
list samples [kick snare hat]
list beats repeat(samples repeats)
// => [kick kick snare snare snare snare hat hat hat]
```
## reverse
Reverse the order of items in a list.
**arguments**
- {List} -> List to reverse
```java
list melody [0 3 7 5]
list rev reverse(melody)
// => [5 7 3 0]
// retrograde()
// rev()
```
Alias: `retrograde()`, `rev()`
## rotate
Rotate the position of items in a list. positive numbers = direction right, negative numbers = direction left
**arguments**
- {List} -> List to rotate
- {Int} -> Steps to rotate
```java
list melody [0 3 7 5 7 9 12]
list left rotate(melody -2)
// => [7 5 7 9 12 0 3]
list right rotate(melody 2)
// => [9 12 0 3 7 5 7]
// rotate()
// turn()
// rot()
```
Alias: `turn()`, `rot()`
## sort
Sort an list of numbers or strings. sorts ascending or descending in numerical and alphabetical order.
**arguments**
- {List} -> List to sort
- {Int} -> sort direction (positive value is ascending)
```java
list srt1 sort([-5 7 0 3 12 -7 9] -1)
//=> [ 12 9 7 3 0 -5 -7 ]
// works with strings (but alphabetical order!)
list srt2 sort([e4 g3 c4 f3 b5])
//=> [ b5 c4 e4 f3 g3 ]
```
## slice
Slice a list in one or multiple parts. Slice lengths are determined by the second argument list. Outputs a list of lists of the result
**arguments**
- {List} -> list to slice in parts
- {Number/List} -> slice lengths to slice list into
- {Bool} -> output rest flag (optional, default=false)
```java
list sl1 slice(spread(8) [3 2])
//=> [ [ 0 1 2 ] [ 3 4 ] [ 5 6 7 ] ]
// set rest-flag to false removes last slice
list sl2 slice(spread(24) [3 2 -1 5] 0)
//=> [ [ 0 1 2 ] [ 3 4 ] [ 5 6 7 8 9 ] ]
```
## split
Similar to slice in that it also splits a list, except that slice recursively splits until the list is completely empty. If a list is provided as split sizes it will iterate the lengths.
**arguments**
- {List} -> list to split in parts
- {Number/List} -> split lengths to split list into
```java
list sp1 split(spread(12) 3)
//=> [ [ 0 1 2 ] [ 3 4 5 ] [ 6 7 8 ] [ 9 10 11 ] ]
list sp2 split(spread(12) [3 2 -1])
//=> [ [ 0 1 2 ] [ 3 4 ] [ 5 6 7 ] [ 8 9 ] [ 10 11 ] ]
```
## cut
Cut the beginning of a list and return. Slice length is determined by the second argument number. Outputs a list of the result.
**arguments**
- {List} -> list to slice in parts
- {Number} -> slice length to cut list into
- {Bool} -> output rest flag (optional, default=false)
```java
list ct1 cut(spread(8) 3)
//=> [ 0 1 2 ]
```
## spray
"Spray" the values of one list on the places of values of another list if that value is greater than 0. Wraps input list if more places must be set then length of the list.
**arguments**
- {List} -> List to spray
- {List} -> Positions to spray on
```java
list notes [12 19 15 17]
list places [1 0 0 1 1 0 1 0 1 0]
list sprayed spray(notes places)
// => [12 0 0 19 15 0 17 0 12 0]
```
## stretch
Stretch (or shrink) a list to a specified length, linearly interpolating between all values within the list. Minimum output length is 2 (which will be the outmost values from the list). Third optional argument sets the interpolation mode. Available modes are `none` (or `null`, `false`) and `linear`.
**arguments**
```java
list notes [0 12 3 7]
list str stretch(notes 15)
//=> [ 0 2 5 7 10 11 9 7 5 3 3 4 5 6 7 ]
// 12.00 ┼ ╭╮
// 9.60 ┤ │╰╮
// 7.20 ┤ ╭╯ │ ╭
// 4.80 ┤╭╯ ╰╮╭─╯
// 2.40 ┤│ ╰╯
// 0.00 ┼╯
// use stretchFloat if you want the result to have more precision
list str stretchFloat(notes 15)
```
## unique
Filter duplicate items from a list. does not account for 2-dimensional lists in the list.
**arguments**
- {List} -> List to filter
```java
list notes [0 5 7 3 7 7 0 12 5]
list thinned unique(notes)
// => [0 5 7 3 12]
```
Alias: `thin()`
# Utility Methods
## wrap
Wrap values from a list within a specified low and high range.
**arguments**
- {List} -> List to wrap
- {Number} -> Low value (optional, default=12)
- {Number} -> High value (optional, default=0)
```java
list wr1 wrap([0 [1 [2 3]] [4 5] 6] 2 5)
//=> [ 3 [ 4 [ 2 3 ] ] [ 4 2 ] 3 ]
list wr2 wrap(spread(30) 2 8)
//=> 7.00 ┤╭╮ ╭╮ ╭╮ ╭╮ ╭╮
// 6.00 ┼╯│ ╭╯│ ╭╯│ ╭╯│ ╭╯│
// 5.00 ┤ │ ╭╯ │ ╭╯ │ ╭╯ │ ╭╯ │ ╭
// 4.00 ┤ │ ╭╯ │ ╭╯ │ ╭╯ │ ╭╯ │ ╭╯
// 3.00 ┤ │╭╯ │╭╯ │╭╯ │╭╯ │╭╯
// 2.00 ┤ ╰╯ ╰╯ ╰╯ ╰╯ ╰╯
```
## clip
Constrain values from a list within a specified low and high range.
**arguments**
- {List} -> List to constrain
- {Number} -> Low value (optional default=12)
- {Number} -> High value (optional default=0)
```java
list cn1 constrain([0 [1 [2 3]] [4 5] 6] 2 5)
//=> [ 2 [ 2 [ 2 3 ] ] [ 4 5 ] 5 ]
list cn2 constrain(cosine(30 1) 5 9)
//=> 9.00 ┼─────╮ ╭───
// 8.20 ┤ │ ╭╯
// 7.40 ┤ ╰╮ ╭╯
// 6.60 ┤ ╰╮ ╭╯
// 5.80 ┤ │ │
// 5.00 ┤ ╰──────────────╯
// Alias: constrain()
```
## fold
Fold values from a list within a specified low and high range.
**arguments**
- {List} -> List to fold
- {Number} -> Low value (optional, default=12)
- {Number} -> High value (optional, default=0)
```java
list fl1 fold([0 [1 [2 3]] [4 5] 6] 2 5)
//=> [ 4 [ 3 [ 2 3 ] ] [ 4 5 ] 4 ]
list fl2 fold(spreadFloat(30 -9 13) 0 1)
//=> 1.00 ┼╮ ╭╮ ╭╮
// 0.80 ┤│ ╭╮ ╭╮ ││ ╭╮╭╮ ││ ╭╮ ╭╮
// 0.60 ┤│ ││╭─╮││ ││╭╯││╰╮││ ││╭─╮││
// 0.40 ┤│╭╯││ ││╰─╯││ ││ ││╰─╯││ ││╰╮
// 0.20 ┤╰╯ ││ ╰╯ ╰╯ ││ ╰╯ ╰╯ ││ ╰
// 0.00 ┤ ╰╯ ╰╯ ╰╯
```
## map
Rescale values from a list from a specified input range to a specified low and high output range.
**arguments**
- {List} -> List to wrap
- {Number} -> Low value (optional, default=1)
- {Number} -> High value (optional, default=0)
- {Number} -> Low value (optional, default=1)
- {Number} -> High value (optional, default=0)
- {Number} -> Exponent value (optional, default=1)
```java
list sc1 scale([0 [1 [2 3]] 4] 0 4 -1 1)
//=> [ -1 [ -0.5 [ 0 0.5 ] ] 1 ]
```
## mod
Return the remainder after division. Also works in the negative direction, so wrap starts at 0
**arguments**
- {Int/List} -> input value
- {Int/List} -> divisor (optional, default=12)
- {Int/List} -> remainder after division
```js
list vals mod([-2 [4 [3 7]]] 5)
//=> [ 3 [ 4 [ 3 2 ] ] ]
```
## add
Add two lists sequentially
```java
list vals add([1 2 3 4] [1 2 3])
//=> [ 2 4 6 5 ]
// Works with n-dimensional lists
list vals add([1 [2 3]] [10 [20 30 40]])
//=> [ 11 [ 22 33 42 ] ]
```
## subtract
Subtract two lists sequentially
```java
list vals subtract([1 2 3 4] [1 2 3])
//=> [ 0 0 0 3 ]
list vals sub([1 [2 3]] [10 [20 30 40]])
//=> [ -9 [ -18 -27 -38 ] ]
```
Alias: `sub`
## multiply
Multiply two lists sequentially
```java
list vals multiply([1 2 3 4] [1 2 3])
//=> [ 1 4 9 4 ]
list vals mul([1 [2 3]] [10 [20 30 40]])
//=> [ 10 [ 40 90 80 ] ]
```
Alias: `mul`
## divide
Divide two lists sequentially
```java
list vals divide([1 2 3 4] [1 2 3])
//=> [ 1 1 1 4 ]
list vals div([1 [2 3]] [10 [20 30 40]])
//=> [ 0.1 [ 0.1 0.1 0.05 ] ]
```
Alias: `div`
## normalize
Normalize all the values in a list between 0. and 1. The highest value will be 1, the lowest value will be 0.
**arguments**
- {Number/List} -> input values
- {Int/List} -> normailzed values
```java
list vals normalize([0 1 2 3 4])
//=> [ 0 0.25 0.5 0.75 1 ]
// works with n-dimensional lists
list vals normalize([5 [12 [4 17]] 3 1])
//=> [ 0.25 [ 0.6875 [ 0.1875 1 ] ] 0.125 0 ]
```
Alias: `norm()`
## equals
Compare two lists for equals (==)
```js
list vals ([0 1 2 3] [1 10 20 30])
//=> [ ]
```
Alias: `eq`
## notEquals
Compare two list for not equals (!=)
```js
list vals ([0 1 2 3] [1 10 20 30])
//=> [ ]
```
Alias: `neq`
## greater
Compare two lists for left values are greater than right (>)
```js
list vals ([0 1 2 3] [1 10 20 30])
//=> [ ]
```
Alias: `gt`
## greaterEquals
Compare two lists for left values are greater than or equal to right (>=)
```js
list vals ([0 1 2 3] [1 10 20 30])
//=> [ ]
```
Alias: `gte`
## less
Compare two lists for left values are less than right (<)
```js
list vals ([0 1 2 3] [1 10 20 30])
//=> [ ]
```
Alias: `lt`
## lessEquals
Compare two lists for left values less than or equal to right (<=)
```js
list vals ([0 1 2 3] [1 10 20 30])
//=> [ ]
```
Alias: `lte`
# Translate Methods
## Conversion between pitch units
Convert easily between relative-semitones, midinotes, notenames, chord-numerals, chordnames and frequencies with the methods below. Thankfully using the amazing `Tonal.js` package by `@danigb` for various functions.
```java
// Convert Array or Int as midi-number to midi-notenames
midiToNote([60 [63 67 69] [57 65]])
//=> [ c4 [ eb4 g4 a4 ] [ a3 f4 ] ]
// Alias: mton()
// Convert midi-pitches to frequency (A4 = 440 Hz)
midiToFreq([60 [63 67 69] [57 65]])
//=> [ 261.63 [ 311.13 391.995 440 ] [ 220 349.23 ] ]
// Alias: mtof()
// Convert Array of String as midi-notenames to midi-pitch
noteToMidi([c4 [eb4 g4 a4] [a3 f4]])
//=> [ 60 [ 63 67 69 ] [ 57 65 ] ]
// Alias: ntom()
// Convert midi-notenames to frequency (A4 = 440 Hz)
noteToFreq([c4 [eb4 g4 a4] [a3 f4]])
//=> [ 261.63 [ 311.13 391.995 440 ] [ 220 349.23 ] ]
// Alias: ntof()
// Convert frequency to nearest midi note
freqToMidi([ 261 [ 311 391 440 ] [ 220 349 ] ])
//=> [ 60 [ 63 67 69 ] [ 57 65 ] ]
// Alias: ftom()
// Set detune flag to true to get floating midi output for pitchbend
freqToMidi([ 261 [ 311 391 440 ] [ 220 349 ] ] true)
//=> [ 59.959 [ 62.993 66.956 69 ] [ 57 64.989 ]]
// Convert frequency to nearest midi note name
freqToNote([ 261 [ 311 391 440 ] [ 220 349 ] ])
//=> [ c4 [ eb4 g4 a4 ] [ a3 f4 ] ]
// Alias: fton()
// Convert relative semitone values to midi-numbers
// specify the octave as second argument (default = C4 = 4 => 48)
relativeToMidi([[-12 -9 -5] [0 4 7] [2 5 9]] c4)
//=> [ [ 48 51 55 ] [ 60 64 67 ] [ 62 65 69 ] ]
// Alias: rtom()
// Convert relative semitone values to frequency (A4 = 440 Hz)
// specify the octave as second argument (default = C4 = 4 => 48)
relativeToFreq([[-12 -9 -5] [0 4 7] [2 5 9]] c4)
//=> [ [ 130.81 155.56 196 ] [ 261.62 329.63 392 ] [ 293.66 349.23 440 ] ]
// Alias: rtof()
// Convert a chroma value to a relative note number
// Can also include octave offsets with -/+ case-insensitive
chromaToRelative([c [eb G Ab] [a+ f-]])
//=> [ 0 [ 3 7 8 ] [ 21 -7 ] ]
// Alias: ctor()
// Convert ratio to relative cents
ratioToCent([2/1 [3/2 [4/3 5/4]] 9/8])
//=> [ 1200 [ 701.95 [ 498.04 386.31 ] ] 203.91 ]
// Alias: rtoc()
// Convert a chord progression from roman numerals to semitones
chordsFromNumerals([I IIm IVsus2 V7 VIm9])
// => [[ 0 4 7 ]
// [ 2 5 9 ]
// [ 5 7 0 ]
// [ 7 11 2 5 ]
// [ 9 0 4 7 11 ]]
// Alias: chords()
// Convert a chord progression from chordnames to semitones
chordsFromNames([C Dm Fsus2 G7 Am9])
//=> [[ 0 4 7 ]
// [ 2 5 9 ]
// [ 5 7 0 ]
// [ 7 11 2 5 ]
// [ 9 0 4 7 11 ]]
```
## Conversion between time units
Convert between rhythmic notation such as divisions or ratios and milliseconds based on the set tempo in the global settings.
### divisionToMs
Convert beat division strings or beat ratio floats to milliseconds using BPM from the global settings. Optional second argument sets BPM and ignores global setting.
**arguments**
- {List} -> beat division or ratio list
- {Number} -> set the BPM (optional, default = global tempo)
```java
set tempo 120
list divs [1/4 1/2 1/8 3/16 1/4 1/6 2]
list ms1 divisionToMs(divs)
// => [500 1000 250 375 500 333.33 4000]
list ms2 divisionToMs(divs 100)
// => [600 1200 300 450 600 400 4800]
list ratios [0.25 0.125 0.1875 0.25 0.16667 2]
list ms3 divisionToMs(ratios)
// => [500 1000 250 375 500 333.33 4000]
```
Alias: `dtoms()`
Other methods:
```java
// convert beat division strings to beat ratio floats
divisionToRatio([1/4 1/8 3/16 1/4 1/6 2])
//=> [ 0.25 0.125 0.1875 0.25 0.167 2 ]
// Alias: print dtor()
// convert beat ratio floats to milliseconds
ratioToMs([0.25 [0.125 [0.1875 0.25]] 0.1667 2] 100)
//=> [ 600 [ 300 [ 450 600 ] ] 400.08 4800 ]
// Alias: print rtoms()
```
## Working with fixed scale and root
Convert notes to a fixed scale based on the global settings.
```java
// Set the global scale used with toScale() and toMidi() methods
set scale minor a
// Set only the root for the global scale
set root c
// Return all the available scale names
print scaleNames()
//=> [ chromatic major etc... ]
// Map relative numbers to a specified scale class (excluding root)
toScale([0 1 2 3 4 5 6 7 8 9 10 11])
//=> [0 0 2 3 3 5 5 7 8 8 10 10]
// Works with negative relative values
toScale([8 13 -1 20 -6 21 -4 12])
//=> [8 12 -2 20 -7 20 -4 12]
// Preserves floating point for detune/microtonality
toScale([0 4.1 6.5 7.1 9.25])
//=> [0 3.1 5.5 7.1 8.25]
// Optionally add a scale name and root to use a scale other
// than the global one
toScale([0 1 2 3 4 5 6 7 8 9 10 11] major)
//=> [ 0 0 2 2 4 5 5 7 7 9 9 11 ]
toScale([0 1 2 3 4 5 6 7 8 9 10 11] minor eb);
//=> [ 3 3 5 6 6 8 8 10 11 11 13 13 ]
```
## textToCode
Convert a string or array of strings to their ASCII code integer representation. The ASCII code is the American Standard Code for Information Interchange. In this code every unique character/symbol/number is represented by a whole number (integer). For example `a=97`, but `A=65` and `SPACE=32`.
Alias: `textCode`, `ttoc`
**arguments**
- {String/Array} -> input to convert to ASCII
```js
// single string input
textCode('bach cage');
//=> [ 98 97 99 104 32 99 97 103 101 ]
// multiple strings in an array results in a 2D array output
textCode([bach cage]);
//=> [ [ 98 97 99 104 ] [ 99 97 103 101 ] ]
```
================================================
FILE: docs/deprecated-docs/06-shortkeys.md
================================================
# Shortkeys
Mercury has various shortkeys that help you navigate the editor quickly during liveperformances. At the moment shortkeys are default for Mac platforms, and might not all work on Windows platforms. There may also be some issues with non UK/US keyboards. If you encounter any issues with this, please file an issue.
## Default Arrow Key Navigation
```
UP = up one line
DOWN = down one line
LEFT = back one character
RIGHT = forward one character
```
```
Alt + UP = jump to top of editor (end of the line)
Alt + DOWN = jump to end of editor (end of the line)
Alt + LEFT = jump to beginning of the line
Alt + RIGHT = jump to end of the line
```
```
Alt + A = back one character
Alt + S = down one line
Alt + D = forward one character
Alt + W = up one line
```
## Default Copy/Paste/Delete
Copy/Paste/Paste-Replace/Delete only works inside the editor. In order to input or output code to a different application you have to save the file as a `.txt` or open a `.txt` file from disk.
```
Alt + X = delete the line where the cursor is located
Alt + C = copy the line where the cursor is located
Alt + V = paste insert a line of code where the cursor is located
Alt + P = paste replace a line where the cursor is located
```
## Default Code Commands
```
Alt + Return = execute code
Alt + . = silence the sound
Alt + / = (un)comment a line of code
Alt + , = disable/enable editor
```
## Customize Shortkeys
You can customize the shortkeys by opening the `Setup Shortkeys` under `Settings` in the menubar. You can also reset to the default key commands.
1. Select the key you would like to customize in the dropdown menu on the top.
2. Click `change keycommand`, it now displays `waiting for keys...`.
3. Hit the key combination you would like to use for this command and release the keys to store.
4. Check if stored correctly in the scroll-menu below. Every command displays the shortcut and keycode.
================================================
FILE: docs/deprecated-docs/07-environment.md
================================================
# Environment
- [Mercury Main Window](#mercury-main-window)
- [Editor / Visuals](#editor-visuals)
- [Sound](#sound)
- [FPS CPU Meter](#fps-and-cpu-meter)
- [Auto Log Sketch](#auto-log-sketch)
- [Auto Copy Sketch](#auto-copy-sketch)
- [Record Audio](#record-audio)
- [Show Variables](#show-variables)
- [Show Audiofiles](#show-audiofiles)
- [External Editor](#external-editor)
- [Menubar](#menubar)
- [File](#file)
- [Sounds](#sounds)
- [Settings](#settings)
- [Audio Setup](#audio-setup)
- [Visual Setup](#visual-setup)
- [Editor Setup](#editor-setup)
- [Shortkeys Setup](#shortkeys-setup)
- [Explanation](#explanation)
# Mercury Main Window
The Mercury main window gives you access to the most used settings in the Mercury Environment. For more detailed settings you can use the menubar.
## Editor / Visuals
Start or stop the rendering of the text-editor. This is an OpenGL environment that renders the responsive texteditor in the second window. The rendering is done at a framerate synced to the screen you use (which usually defaults to 60fps). This rendering is also necessary to use when coding visuals displayed behind the text.
## Sound
Start or stop the audio calculations (Digital Signal Processing). Turning this off will disable all processes that are considered audio.
## FPS and CPU Meter
The FPS meter shows the current Frames Per Second that the rendering engine is running at. If you experience a very slow framerate (less then 25fps) you can find some info under [Visual Setup](#visual-setup) to help you adjust settings for your computer.
This CPU meter shows the current CPU usage of the audio processes running in Mercury. If you experience a very high cpu-usage (more then 70) you can find some info under [Audio Setup](#audio-setup) to help you adjust settings for your computer.
## Auto Log Sketch
Enabling the Auto Log Code will store a version of your code to the folder `~/Documents/Mercury/Code Logs` for every time you execute your code. This can be helpful to create a history of your code and allow you to look back at your code after a performance.
## Auto Copy Sketch
When enabling the 'Auto Copy Sketch' Mercury will copy the full sketch to the clipboard everytime you execute your code. The copy will include a timestamp in the header of the snippet. Paste it in a different text-editor, or use it to send your code in a chat message to someone else.
## Record Audio
Start and stop the recording of the current sound output. The recorded file will be stored to the `~/Documents/Mercury/Recordings` folder with the date and time as the filename.
## Show Variables
View the current `ring`'s that are created from the code in a dictionary.
## Show Audiofiles
View the loaded soundfiles and waveforms as a system path in a dictionary with their associated name that can be used in Mercury code.
## External Editor
The external editor allows you to use a textfile from outside the Mercury environment to run as code. Generate a `.txt` file somewhere on your computer. Drag-n-drop the file in the box *drop code file here*. This will automatically enable the *Use External Editor* button. Now you can use a external editor such as Atom, VSCode or Sublime to edit your code. Upon saving the code Mercury will detect the changes and execute the current state of the file.
# Menubar
The menubar gives you access to more functionalities in Mercury such as opening a new file, opening an existing file, saving your code, executing or deleting your code, adding sounds to your library, changing settings for the audio, visuals, editor and keyboard shortcuts and opening examples, documentation and the list of sounds.
## File
Via the File menu you can:
- Create a new file (this will erase all code) : `CMD + N`
- Open a file with a `.txt` extension as a codefile : `CMD + O`
- Save a file from the current code in the editor window : `CMD + S`
- Execute Code : `ALT + RETURN`
- Silence Code : `ALT + .`
- Clear Code (same as new file) : `CMD + N`
- Load External Editor File (see [external editor](#external-editor))
## Sounds
Via the Sounds menu you can add folders of sounds and waveforms to the searchpath of the Mercury environment. The filenames of these sounds can then be used in the code to refer to. This works best if you rename your files to shorter filenames and **don't** use spaces in the name. It will recursively search for all the files that match `.wav`, `.aiff` or `.mp3`, so be careful with selecting a folder with many subdirectories and audiofiles. These files will be loaded into the RAM, so try to keep the loaded soundfiles under **4 GB**.
### Add
The **Add** option appends all the found audiofiles to the current list of already loaded files. A library with the loaded sounds is stored under `~/Documents/Mercury/Data`.
### Replace
The **Replace** option removes all the current loaded files from the library and only addes the files that are found in the currently selected folder. The library is updated accordingly.
### Default
The **Default** option resets the library to the files that are included in the Mercury project by default. These files can be found in the `mercury_ide/media` folder
### Show Loaded
The **Show Loaded** option opens the library of loaded soundfiles. This will give you insight in if your files were loaded correctly and also shows you the buffername, duration, number of channels and samplerate of the files.
### Example for file naming
I have a soundfile: `my cool Sound 05.wav` on the computer.
Using this in Mercury like so:
```java
new sample my cool Sound 05
```
will not work, since it will interpret the spaces as new keywords. Therefore I rename the file with underscores to: `my_cool_Sound_05.wav`. Now I can use this file like so:
```java
new sample my_cool_Sound_05
```
Since I find this filename a bit long to type during a live coding session I decide to rename it a bit shorter like so: `sound05.wav`. Now the code will look like this after importing the sound:
```java
new sample sound05
```
## Settings
### Audio Setup
The Audio Setup lets you adjust settings for the sound processing in the Mercury environment. You can hover your mouse over the settings to see a small description of the options and their default values.
#### Total Instruments
The Total Instruments determines how many instruments can be used in the code. An instrument is every line of code that starts with `new ...`. The default is 10 instruments, which is usually enough for live coding performances.
#### Driver
Adjust the Audio Driver. For Mac `Core Audio` is recommended, for Windows the `Asio4All` driver (if not available please install).
#### Device
Select your input and output devices for the sounds. This usually defaults to `Built-in Microphone` and `Built-in Output`, but can be changed if you are using an external sound card for example.
**Bluetooth headphones have been giving some troubles with the samplerate and processing up till now**
#### Samplerate
Adjust the samplerate for the audio processing. A higher samplerate gives a better sound quality but is heavier on the computer (cpu) to process. The default is `44100` Hz, which is in most applications more then enough.
#### Buffersize
Adjust the I/O (input/output) and Signal buffersize. This determines the blocksize of samples that are presented to the cpu to calculate at once. A lower buffersize gives less latency on the audio output, but a higher cpu usage. A higher buffersize gives a lower cpu usage, but there will be more latency. In most cases an buffersize of `256` samples is good.
#### Overdrive / Audio Interrupt
Turn Overdrive on to give priority over midi-events and scheduling. Enable this when audio is your highest priority, disable this when visuals are you highest priority. Enabling is recommended.
When Overdrive is enable the Audio Interrupt can also be enabled. This links the timing of events to the signal buffersize in the audio thread. Enabling this greatly improves the timing accuracy when working with lower buffersizes. Higher buffersize might make it drop a few beats when playing on high tempos. Enabling is recommended.
#### Troubleshoot
In case you are experiencing a very high cpu usage please try the following settings:
- Total instruments: `4`
- Driver: `Core Audio` or `Asio4All`
- Samplerate: `44100`
- I/O Buffersize: `1024`
- Signal Buffersize: `512`
- Overdrive: `on`
- Audio Interrupt: `on`
### Visual Setup
The Visual Setup lets you adjust settings for the visual output in the editor window of the Mercury environment. You can hover your mouse over the settings to see a small description of the options and their default values.
#### Aspect Ratio
Adjust the aspect ratio of the screen. You can choose between a variety of common used aspect ratios:
- 1:1 (Instagram)
- 5:4 (Early Television)
- 4:3 (Television)
- 11:8 (Academy Ratio 1.375:1)
- 1.414:1 (squareroot of 2 / √2)
- 3:2 (35mm Still Photograph)
- 14:9 (Compromise for 4:3 and 16:9)
- 16:10 (Computer Screen / Macbook)
- 1.6180:1 (Golden Ratio phi)
- 16:9 (Widescreen 1.78:1)
- 18:9 (Univisium 2:1)
- 22:10 (70 mm Film)
- 21:9 (Panavision 7:3)
- 47:20 (Cinemascope 2.35:1)
- 2.414:1 (Silver Ratio)
- 69:25 (Ultra Panavision 2.76:1)
- 36:10 (IMAX Ultra 3.6:1)
#### Resolution
Adjust the main visual resolution. This resolution is the height of the window in pixels and the width is adjust according to the aspect ratio. You can choose between a variety of commonly used resolutions such as 720p, 1080p and 4k.
#### Visual Resolution
The visual resolution allows you to keep a clear and sharp text on the foreground while rendering visuals on a lower resolution. This is useful for machines without a dedicated graphics card that still want to process visuals in the background.
#### Window Size
Adjust the size of the window with this message. For fullscreen you can click the toggle at [fullscreen](#fullscreen) or press `ESC` to go in and out of fullscreen.
#### Screens
The number in this box multiplies your width by this value which allows you to stretch the visuals over multiple screens.
#### Always in front
Enable this option to make sure the editor window is always in front of all the other Mercury windows.
#### Window visible
Disable this option if you don't need to see the editor window. For example when you're working with an external editor.
#### Sync to Refreshrate
Syncs the rendering framerate to the refreshrate of your computer display. Disable this option if you want to set the FramesPerSecond manually.
##### FPS
Set the FramesPerSecond for the rendering engine manually. Only possible when Sync to Refreshrate is disabled.
#### Auto Hide cursor
Enable this option if you want the mouse to disappear when it's been idle for 5 seconds.
#### Fullscreen
Go into fullscreen. You can leave fullscreen with the `ESC` key.
#### Syphon output
**Mac only**
Output the visual window as a texture via a syphonserver. This can be used to transfer the visuals to different capture software like OBS for livestream or recording.
#### Troubleshoot
In case you are experiencing a very laggy editor, slow cursor, low FPS and slow response try the following settings:
- Aspect Ratio: `16:10`
- Resolution: `540`
- Visual Resolution: `270`
- Window Size: `540`
- Sync to Refreshrate: `off`
- FPS: `30`
- Auto Hide Cursor: `off`
- Syphon Output: `off`
For Mac users with Retina display and Max version 8.1.0 or higher and MacOS 10.13 or older.
- Go to `Applications` in the Finder
- Right click `Max.app` (`CMD + Click`)
- Click `Get Info`
- Select `Open in Low Resolution`
- Restart Max and the Mercury project
### Editor Setup
Adjust the look of the texteditor. Change the font, color, blinking color, cursor color and characters and adjust scaling and position.
### Shortkeys Setup
You can customize the shortkeys by opening the `Setup Shortkeys` under `Settings` in the menubar. You can also reset to the default key commands.
For a full explanation see [Shortkeys](./06-shortkeys.md)
## Explanation
Open a random example, the documentation, the list of sounds and waveforms, the github repository and the published paper.
================================================
FILE: docs/deprecated-docs/08-troubleshooting.md
================================================
# ⚠ Troubleshooting
If you are having issues please follow the steps below:
1. Check this [troubleshooting page](#table-of-content)
2. Check if your problem was already reported in the [issues](https://github.com/tmhglnd/mercury/issues)
3. If not, please file a [new issue](https://github.com/tmhglnd/mercury/issues/new)
4. Ask help on the [Mercury Discord](https://discord.gg/vt59NYU)
5. Or fix the bug yourself and send me a pull request 🙏 (much appreciated!)
# Table of Content
- [My sounds are not playing](#my-sounds-are-not-playing)
- [I hear an Alert sound when I execute the code](#i-hear-an-alert-sound-when-i-execute-the-code)
- [My CPU usage is very high](#my-cpu-usage-is-very-high)
- [My editor is very laggy (low FPS)](#my-editor-is-very-laggy-low-fps)
- [Mercury keeps crashing when I execute code](#mercury-keeps-crashing-when-i-execute-code)
## My sounds are not playing
When the soundfiles don't load correctly the first time you start Mercury you will not hear any sounds playing (for both the `sample` and `synth`).
You can add the soundfiles manually by going to `Sounds > Replace Sounds`, then select the folder `/mercury_v.0.13.0-alpha/mercury_ide/media/samples`.
Do the same for the waveforms: `Sounds > Replace Waveforms`, then select the folder `/mercury_v.0.13.0-alpha/mercury_ide/media/waveforms`
## I hear an Alert sound when I execute the code
Most Mac users will hear an Alert sound when they hit keycommands that the operating system does not recognize. You can disable the Alert Volume in `System Preferences > Sounds > Sound Effects`.
## My CPU usage is very high
In case you are experiencing a very high cpu usage (resulting in clicks/pops/glitches) please try the following settings in `Settings > Audio`:
- Total instruments: `4`
- Driver: `Core Audio` or `Asio4All`
- Samplerate: `44100`
- I/O Buffersize: `1024`
- Signal Buffersize: `512`
- Overdrive: `on`
- Audio Interrupt: `on`
For a detailed explanation of all the Audio Settings please go [here](./07-environment.md#audio-setup)
## My editor is very laggy (low FPS)
In case you are experiencing a very laggy editor, slow cursor, low FPS and slow response try the following settings:
- Aspect Ratio: `16:10`
- Resolution: `540`
- Visual Resolution: `270`
- Window Size: `540`
- Sync to Refreshrate: `off`
- FPS: `30`
- Auto Hide Cursor: `off`
- Syphon Output: `off`
For Mac users with Retina display and Max version 8.1.0 or higher and MacOS 10.13 or older.
- Go to `Applications` in the Finder
- Right click `Max.app` (`CMD + Click`)
- Click `Get Info`
- Select `Open in Low Resolution`
- Restart Max and the Mercury project
For a detailed explanation of all the Visual Settings please go [here](./07-environment.md#visual-setup)
## Mercury keeps crashing when I execute code
This can indicate that the computer is not able to display the editor or visual extensions correctly. If you are using Mercury just for the sound/sequencing, please try to following steps:
1. Install an external texteditor software (like for example Atom, Visual Studio Code, Sublime)
2. Create a simple `.txt` file somewhere on the computer.
3. Drag-and-drop that file in the Mercury main window right from `Use External Editor`.
4. Once the file is loaded the toggle will enable.
Now every time you save your file after coding it will execute the current version of that code.
================================================
FILE: docs/deprecated-docs/09-visuals.md
================================================
# Visuals
Mercury has some options to add visuals to your live coding performance. These visuals are pre-coded and stored in seperate Max patch files. You can add extra visuals by putting the visual patches in the folder `~Documents/Mercury/Library`. For the visual to work you should make use of the `template.maxpat` provided in `mercury/mercury_ide/patchers/visual/`.
## new visual
Add a new visual with the keywords `new visual` followed by the name of the patcher file.
```java
new visual meshwave
```
## analyzer
The visuals make use of amplitude and frequency analysis of the played sounds for audioreactive results. The settings for this can be adjust in the analyzer. Also the responsiveness can be displayed via de analyzer.
#### gui
Display the gui of the analyzer (on/off)
```java
set analyzer gui on
```
#### gain
Adjust the input gain for the analyzer (default=1)
```java
set analyzer gain 0.9
```
#### lo
Adjust the cutoff, attack and release times in milliseconds for the lowpass audio analysis. Lowpass is the low frequency range of the sum of the Left and Right channels.
**arguments**
- cutoff -> (default = 120)
- attack -> (default = 2)
- release -> (default = 40)
```java
set analyzer lo cutoff 120
set analyzer lo attack 10
set analyzer lo release 150
```
#### hi
Adjust the cutoff, attack and release times in milliseconds for the highpass audio analysis. Highpass is the high frequency range of the sum of the Left and Right channels.
**arguments**
- cutoff -> (default = 1600)
- attack -> (default = 1)
- release -> (default = 150)
```
set analyzer mid attack 10
set analyzer mid release 150
```
#### mid
Adjust the attack and release times in milliseconds for the mid audio analysis. Mid is the sum of the Left and Right channels.
**arguments**
- attack (default = 5)
- release (default = 40)
```java
set analyzer mid attack 10
set analyzer mid release 150
```
#### side
Adjust the attack and release times in milliseconds for the side audio analysis. Side is the difference between the Left and Right channels.
**arguments**
- attack (default = 2)
- release (default = 110)
```java
set analyzer side attack 10
set analyzer side release 150
```
## set visual
Adjust settings for visuals or effects with the keywords `set visual` followed by what settting you would like to adjust
```java
set visual brightness 0.5
```
## external
Use an external texture via Syphon on some of the visuals that allow the usage of textures (for example `plane`).
```java
set visual external on
// turn on the texture input
set visual external getServers
// get available getServers
set visual external server Max
// set the server for Syphon
set visual external dim 512 512
// change the resolution of the texture
set visual external width 0.8
// adjust the width of the texture
```
================================================
FILE: docs/deprecated-docs/10-includes.md
================================================
# Includes
**⚠ EXPERIMENTAL ⚠**
You can extend Mercury with custom synths and other sound designing patches programmed with Max8. This requires knowledge/experience with the MaxMSP programming paradigm. It also requires you to have a Max8 license. Follow the steps below to setup your own patch.
## Create the patch
Create a new patch for your custom sound design. Save the patch in `~/Documents/Mercury/Library/Sound`, if you do not have this folder you should create it. Give the patch an appropriate name, this will also be the name used in the live coding environment. For example: if you name the patch `myCustomSynth.maxpat`, then in Mercury you will type `new synth myCustomSynth`.
## I/O
The patch will be loaded inside a `poly~` object. Therefore it is required to use an `[in 1]` object to receive incoming messages and an `[out~ 1]` message to send a signal out.
## Muting
Make sure you include a `[thispoly~]` and send it a `[loadmess mute 1]` to make sure the patcher is muted on initialization of Mercury. This prevents high cpu load and unwanted sound when not using the synth.
## Functions
Use the `[route]` object to route arguments from functions to parts of the patcher that you want to be able to control with the code. For example typing `new synth myCustomSynth freq(100)` will allow you to use `[route freq]` and retrieve the value `100`.
## Trigger
Use the `[route bang]` object to send a trigger to for example a `[line~]` or `[adsr~]` object in parts of the patcher that need to start the sound. The bang is send based on the combined results of the `time()`, `play()`, `warp()` and `ratchet()` methods.
## noteCount
Send a bang to `[pv noteCount]` to retrieve the current count the instrument is at. This count increments based on the rhythm of the combined results of the `time()`, `play()` and `warp()`.
## argListLookup
Use the `[argListLookup]` abstraction to allow Mercury to lookup values from a `list` created in the code. `[argListLookup]` expects the `value` or `name` on the left inlet, and the `[pv noteCount]` on the right inlet to index the correct value from the `list`.
## Example Patcher
Below is copy-compressed code of a example patcher that generates a short sinewave beep.
```
<pre><code>
----------begin_max5_patcher----------
1219.3oc0Y80aihCD+4jOEygtSpcUtJr4Ogtud5d79DTspxAbRYWhMmwzlrq
19Y+FaCsoWI.MkTo8EPdxX+ieyLdlwN+X9LuUxc7JO3yvMvrY+X9rYVQFAyZ
FOyaKaWZAqxplWpb6VtP6sv8aZ9NsUtrVWVqg7JfAU4aDrhG+sVkJY5z6xEa
tUwS0NvHAQW4u.hH9lWDRh4EEG.eoYRh5s3ZVv0Vb8ajtVJzqYobiLRir7L2
Wvpu9mj.ummdtnc1DireNet4wh2IQ02gbrjorbUvS4UUL0dPKAEOqNkCok0.
SCUZTm5x14Wji5JqE1EI73FFZPnwTDRLOShMOiG1rbfIf5OYl.A+AbEekEnP
xx1hzF1Vq4.oOuLw5kCsOI9VeMkdT1z5Pchz6K4tkwy6oIb.Qu9bySimtTVr
+wgY3RWzb7.DL3XDL2Dn8hWcwX5jw3RlfWzGsPeUzBHvs6LfXFjPGLLbkTkw
UoxBoxsN14+7CxAqfSWiZzN1Gurap1HbqLieHtLwlBq.5RCNM.r4EeHzEu3w
yeHkJYoToykB6RdUzDlrnthCZU9lMbErVI2BYRA2jqnUHCP3M4P.1ZsYbQAv
TapMqVEX1owy5LERPOoPhb62RbuVtztGb4aJIRz4dy0ZLaueOQfKSLwbMTwU
r3TxbrFMgcuYhz8tI5D68uo7dPH07+x339BvPGs.xEY7clvfBo7a0kv8rhZd
kKBA+YlRw1ehd8Vmebza2qSN6d8+.B5KqSbfkBt.W501HfSvoer7mjjIykeD
988hqZboXFTSDND0aTdCiCbUQHzgJfPOZExEGoJII9by4CCvGgy0EelLs8BP
9.Z6ii6O4+qqC200hTSECPeG1pWJtmcEGdPkq0bArVp.i54hJsxlIGJx+F+y
14eAFPbYm6soCmQOxY0BsuBBdSYzC9PLQqvRwFSTEWj4xmYjpy2xu3RXKWem
LCt.WfUHyyfGx02AkEr8Wb4B3AlpDUhgSTYLAbMN5jMUjCyF9FMUzyto5u2w
1VVvsgJnLzXgr.9Gr2oZ7rDVyBCRqqznArZu.sgU4eG6V5MVSHX4g8eGbJkD
BO2kDP7er2CQ35Dn4jhgzAxazAGB6sWxJ187raQ8P.ukowFyVgGqopgHMLAa
wD+kaacmlU1y9CVavDYIxE8ZGBOvWRSlzzmA+hXgTRyINs4Xr4hMcSOnEqsO
X5PkbB6s35h9Jx18YQCmNl+oGGtzZXCCO49lb2aS2LjLYsQXt5.1F9qnHAnf
O76jQztjywFQm1dH7O2cJYRaOB+XSVa2EAcJMC13GwnUyVkNI6YuS3dCXcoz
CiiNawqKO27KceZA+wQcH1lv033SMbsGdFMHOsyxF58+tmW62qQ9KIekrVk1
hby8rAO+Imwqz4BV60kbyS2LkQmNMuiEmjQfiIMzAJ8zUHQ9XPl7Zj8eWHub
DHGNA11nQfyxI.mfwXIudB.xtHjgPhNUHMHmlBfFUXX7TfT7XPxeJPhNBjhl
BfHiLBm7dAxeD.kLELZL9nWCjKcOqr7dtppQaKFXUsu5tM7jE1g4B2P64G8T
76ya021XgGSgkyzXsrZk86xaWr6jT1qeWIpyax7hrCgzVwTvvt6Ja9+4rEVm
+y4+Gd.sopC
-----------end_max5_patcher-----------
</code></pre>
```
================================================
FILE: docs/deprecated-docs/README.md
================================================
# 🌕 Mercury Live Coding Environment
**A minimal and human-readable language for the live coding of algorithmic electronic audiovisual performances.**
[**🙏 Support Mercury by becoming a Patron**](https://www.patreon.com/bePatron?u=9649817)
[**💬 Join the Discord Community!**](https://discord.gg/vt59NYU)
**🚀 Start coding with the latest version:**
[](https://github.com/tmhglnd/mercury/releases)

## 📋 Table of Contents
<!-- - [Newest Features](#-newest-features) -->
- 📟 [Mercury?](#-about)
- 🎮 [What can I do with Mercury?](#-features-overview)
- 🔭 [Who is it for?](#-vision--goals)
- 👩💻 [Code together with others!](#-collaborative-coding)
- 🚀 [Let's get started!](#-install)
- [Quick Start](./quick-start.md)
- [Tutorial](./tutorial.md)
- [Documentation](./table-of-content.md)
- [Troubleshooting](./08-troubleshooting.md)
- [System Requirements](#-system-requirements)
- [Sounds in Mercury](/mercury_ide/media/README.md)
<!-- - [Build Application](#-build-application) -->
- 🔎 [Read more](#-further-reading-and-listening)
- 👾 [Hear what others made](#-made-with-mercury)
- 🤓 [I like to help](#-contribute)
- 🔋 [Powered By](#-powered-by)
- 🙏 [Thanks](#-thanks)
- 📄 [Licenses](#-licenses)
<!-- ## Newest Features
**Control external midi devices or send midi to other Applications with the new `midi` instrument**
```java
set midi getPorts
//=> prints the available devices to the console
new midi "Your Awesome Midi Device" time(1/4) note(7 1) length(100) gain(0.8)
```
**Input OSC addresses as arguments or output osc-messages in a similar way as using instruments**
```java
set osc default
new synth sine name(sn)
set sn note(/sine/pitch 0) shape(5 /sine/release)
set sn fx(reverb 1 /sine/verb)
new emitter osc name(myOSC) someParam(3.14)
// result => /myOsc/someParam 3.14
``` -->
## 📟 About
**Mercury is a minimal and human-readable language for the live coding of algorithmic electronic music.**
All elements of the language are designed around making code more accessible and less obfuscating for the audience. This motivation stretches down to the coding style itself which uses clear descriptive names for functions and a clear syntax. Furthermore the editor is restricted to 30 lines of code, keeping all code always visible. Mercury provides the performer with an extensive library of algorithms to generate or transform numbersequences that can modulate parameters, such as melody and rhythm, over time. The environment produces sound in conjunction with visuals. Besides looking at the code, the audience is also looking at the visuals that are reactive to the sound or generated by the sound.
It is named after te planet Mercury. Mercury rules the creation and expression of our mental processes. The planet implores us to express ourselves. Mercury is about a quick wit, quick thinking. It lets us move from one thing to the next.
Mercury is programmed in the Cycling'74 Max8 node-based creative coding environment, as an abstracted layer on the Max/MSP audio engine and with the use of Node4Max for parsing, lexing and generative algorithms and Jitter/OpenGL for the visuals and the responsive texteditor.
Mercury uses the [Total Serialism NodeJS](https://github.com/tmhglnd/total-serialism#total-serialism) package available on npmjs.com. This package contains an extensive library of algorithmic composition methods.

## 🎮 Features Overview
Quick access to playback of samples and change timing and tempo of samples or synthesizers
```java
set tempo 89
new sample kick_909 time(1/4)
new sample hat_909 time(3/16)
```
Make rhythmic patterns with sequences of numbers and probabilities
```java
ring loBeat [1 0 0 1 0.5]
ring hiBeat [0 1 0.2 0]
new sample tabla_lo time(1/8) play(loBeat)
new sample tabla_hi time(1/8) play(hiBeat)
```
Generate psuedorandom melodic content for a synthesizer in a range and set a scale
```java
set scale minor d
set randomSeed 31415
ring melody random(16 0 24)
new synth saw note(melody) time(1/16) shape(4 100)
```
Design sounds with various effects
```java
new sample chimes time(2) speed(-0.25) fx(reverb 0.3 15) fx(drive 10) fx(lfo 1/8 sine)
```
Easily give multiple instruments the same effects
```java
new sample chimes time(2)
new sample harp_down time(3)
new sample gong_lo time(5)
set all fx(lfo 1/16) fx(delay) fx(reverb 0.5 11)
```
Generate sequences algorithmically to compose complex structures and choose from an extensive library of algorithms to work with
```java
set scale minor a
ring rhythm euclidean(32 13)
ring melody spread(5 0 24)
ring melody palinedrome(melody)
ring melody clone(melody 0 5 7 3)
ring melody lace(melody melody)
new synth triangle note(melody 1) shape(1 80) play(rhythm)
```
Control external midi devices or send midi to other applications and use clock sync
```java
set midi getPorts
//=> prints the available devices to the console
new midi "Your Awesome Midi Device" time(1/4) note(7 1) length(100) sync(on)
```
Control other environments via OSC-messages
```java
ring params [0.25 0.5 0.75]
new emitter osc address(yourDevice) theParam(params) time(1/4)
// emits => /yourDevice/theParam 0.25
// /yourDevice/theParam 0.5
// /yourDevice/theParam 0.75
// /yourDevice/theParam 0.25
// etc...
```
Easily control parameters in Mercury via external OSC-messages
```java
new synth triangle fx(reverb /extOSC/verbAmount) fx(filter low /extOSC/cutoff 0.4) time(1) shape(1 1000)
```
**AND MANY MORE (TO COME...)**
## 🔭 Vision / Goals
- Provide creatives with a quick and hands-on coding environment/language to expres, communicate and improvise livecoded works.
- Use the environment as a teaching environment for:
- introduction to (electronic) music
- algorithmic composition
- sequencing and pattern generating
- sound design
- creative coding and live coding
- Provide creatives with an hands-on language to create realtime processes
- code sound and music
- code visuals and let them react to sound
- Provide creatives with an extensive library of algorithmic composition techniques
- released as a seperate Node Package titled [Total-Serialism](https://www.npmjs.com/package/total-serialism)
- included in the Mercury environment through Node4Max
- Provide creatives with a multi-purpose non-linear-sequencer
- use OSC to communicate with other platforms
- use MIDI to communicate with other environments and devices
- Provide creatives with an easy sampler/synthesizer for sounddesign and composition
- use external OSC to control parameters in the sampler/synthesis
- use external MIDI devices and messages to play the sampler/synthesizers (coming soon...)
- Release a stand-alone application for MacOS and Windows, making installing and workflow easier (coming soon...)
- Collaborate in Mercury via the browser and code music together
- Extending the Mercury users-community and including extensions on the environment in the master-branch
⭐️ *watch and star this repo to keep up-to-date with the latest changes whenever they're made*
## 👩💻👨💻 Collaborative Coding
It is now possible to code together in Mercury using the amazing [**Flok**](https://flok.clic.cf/) live coding environment in the browser.
- [Start coding together here](./collaborate.md)
<!--
There are 3 options for how you can use Flok with Mercury:
1. Use Flok to combine Mercury with Hydra visuals (or other languages like Tidal, Foxdot and SuperCollider) on a localhost
2. Collaborate together in the same room (only requires 1 computer to run Mercury)
3. Collaborate remotely over a network (all computers need to run Mercury)
Install NodeJS v.12 [for Mac](https://nodejs.org/dist/latest-v12.x/node-v12.20.0.pkg) or [for Windows](https://nodejs.org/dist/latest-v12.x/node-v12.20.0-x64.msi).
Install the latest version of Mercury via the [quick start quide](https://github.com/tmhglnd/mercury/blob/master/docs/quick-start.md).
Install Flok via the Terminal with `npm install -g flok-web flok-repl`
**Localhost**
1. Run `flok-web` in the terminal
2. Open Google Chrome and go to `localhost:3000`
3. Setup Flok with target `mercury` (and optionally other targets like `hydra`) and click **Create session**.
4. Copy the `flok-repl -H xxx -s xxx -t mercury` command and run in the terminal.
5. **Join** the Flok with your nickname.
**Collaborate**
Now follow these steps for a succesful setup.
1. Open Google Chrome and go to [https://flok.clic.cf/](https://flok.clic.cf/)
1. Setup Flok with target `mercury` and click **Create session**.
2. Copy the `flok-repl -H xxx -s xxx -t mercury` command and run in the terminal.
4. **Join** the Flok with your nickname.
Now start typing some code! 🎵
- `Ctrl/Alt + Return` to evaluate
- `Ctrl/Alt + .` to silence
Flok will send the entire code via OSC messaging to port 4880. Mercury should be listening to this port automatically. Bug reports are very much welcome in the issues! -->
## 💻 Install
- 📖 [I need some help installing](./tutorial.md)
- 🚀 [I'm an experienced computer user](./quick-start.md)
- 💻 [Is my computer powerful enough?](#-system-requirements)
OR
- 🤓 I'll just [download](https://github.com/tmhglnd/mercury/releases) and figure it out myself
```
$ cd ~/Documents/Max\ 8/Projects
$ git clone http://github.com/tmhglnd/mercury
$ cd mercury
$ open mercury_ide/mercury_ide.maxproj
```
<!-- ### 🚀 Quick Start -->
<!-- [Open the Quick Start Guide](./docs/quick-start.md) -->
<!-- ### 📖 Tutorial -->
<!-- 🚧 (work in progress) 🚧 -->
<!-- If this is your first time with either the usage of creative coding software (like Max8), music theory, electronic music making and programming in general I highly recommend following the tutorial. -->
<!-- [Open the Tutorial](./docs/tutorial.md) -->
### ⚠ Troubleshooting
It could be that you are having issues with Mercury. Please follow the steps below:
- [Open the Troubleshooting](./08-troubleshooting.md)
### 📖 Documentation
Full explanation of all the possibilities in Mercury:
- [Open the documentation](./table-of-content.md)
### 💻 System Requirements
These system requirements are recommended to install and run Max and Mercury on your computer. Lower specs may work but it's not guaranteed. A dedicated Graphics Card (GPU) is also recommended to run the visual side of Mercury smoothly (the text-editor runs on the graphics card as well).
| OS | CPU | RAM |
| -- | --- | --- |
| Mac OSX 10.13 (at least 10.11.6+) | Intel i5 processor | 8 GB |
| Windows 10 (7 or 8 may work) | Intel i5 or AMD mult-core processor | 8 GB |
<!-- ### 🛠 Build Application
`Optional`
**Why?** - Building the Application is recommended when using Mercury with other MaxMSP projects. This will allow Mercury to have a seperate thread from the other Max processes, giving it enough RAM and CPU space. Also the application will probably run more stable because the project can not be editted anymore. This, of course, also dependents on your system specifications.
**How?** - The Cycling'74 Max8 coding environment is needed to build the application from the `mercury_ide_x.x.x.maxproj` file. Open the `.maxproj` file and select `Build Collective/Application` from the `Settings` menu on the bottom of the project window. *Building the Application is not necessary in order to run the environment!* -->
### 🎵 Sounds
Many sounds in Mercury are downloaded from [freesound.org](http://www.freesound.org) and are licensed with Creative Commons Attribution or Creative Commons 0 licenses. If not downloaded from freesound it is made sure that the license allows to redistribute the sounds via the Mercury environment and that you can use them in your projects. A list of all the available sounds and the original sample can be found here:
- [List of sounds and credits](././mercury_ide/media/README.md)
## 🔍 Further reading
- [Mercury homepage](http://www.timohoogland.com/mercury-livecoding)
- [Paper in ICLC 2019](http://iclc.livecodenetwork.org/2019/papers/paper67.pdf)
- [Total Serialism Library](https://github.com/tmhglnd/total-serialism#total-serialism)
## 👾 Made with Mercury
- *Made something with Mercury? Please add a URL here and send a pull request!* 😎
- [Nick Levantis - Wake Up](https://youtu.be/UsfKF0ggn7k)
- [Rafa & Timo - "Hello, off-world!" (Live at NMF)](https://www.youtube.com/watch?v=7UWywv_DPHI&t=4s)
- [Roald van Dillewijn - Mercury & DigiLog](https://www.youtube.com/watch?v=1v7xicXuSbo&t=346s)
- [Sasj & Timo - Amalgam (Live at Github Sattelite 2020)](https://www.youtube.com/watch?v=zzmgX4QSBMM)
- [Anne Veinberg - CodeKlaver & Mercury Extension](https://www.youtube.com/watch?v=VSoibHwQJ98&t=175s)
- [Timo - Live at NerdLab VR 2020](https://www.youtube.com/watch?v=EW9x68sxhvM)
- [T.mo - Live at Eulerroom Equinox 2020](https://www.youtube.com/watch?v=X0FFcdd1QEE)
- [T.mo - Live at Algo:Ritmi 2020](https://www.facebook.com/timohoogland/videos/3654187371320680/)
- [T.mo - Live at NLCL Meetup STEIM](https://www.youtube.com/watch?v=leckC_yUMss)
## 📝 Contribute
Contributions to the Mercury environment are much appreciated in whatever form they come! You can contribute in any of the following ways:
- Add suggestions, bugs or feature-requests to the [issues](https://github.com/tmhglnd/mercury/issues)
- Make additions or changes to the Documentation, Tutorials, Examples and any other text in this repository
- Adjust the source code or make bugfixes and add features by forking and sending a pull request (see the [Guidelines](#guidelines))
In order to make changes to various types of source code files you will need the following:
- `patchers` - Requires Max8 environment and license to edit/modify/save the patchers of this project.
- `JS code` - Requires a standard code-editor (eg. VSCode or Atom) to edit/modify/save the JS code.
- `GenExpr Code` - Requires a standard code-editor (eg. VSCode or Atom) to edit/modify/save the GenExpr code.
### Guidelines
In order to receive your contribution please follow these steps:
1. Fork this repository (click `fork` in the top right)
2. Clone the repository to your computer `git clone https://github.com/<this-is-you>/<forked-repo>.git`
3. Branch the Fork `git checkout -b <name-your-branch>`
4. Make any c
gitextract_ao7h6v4s/
├── .gitignore
├── .gitmodules
├── LICENSE
├── README.md
├── docs/
│ └── deprecated-docs/
│ ├── 00-general.md
│ ├── 01-global.md
│ ├── 02-instrument.md
│ ├── 03-emitter.md
│ ├── 04-fx.md
│ ├── 05-ring.md
│ ├── 06-shortkeys.md
│ ├── 07-environment.md
│ ├── 08-troubleshooting.md
│ ├── 09-visuals.md
│ ├── 10-includes.md
│ ├── README.md
│ ├── _config.yml
│ ├── collaborate.md
│ ├── linux-guide.md
│ ├── quick-start.md
│ ├── reference.md
│ ├── table-of-content.md
│ └── tutorial.md
├── examples/
│ ├── 00_sample-and-time.txt
│ ├── 01_offset-in-time.txt
│ ├── 02_linear-beat.txt
│ ├── 03_sample-scrubbing.txt
│ ├── 04_possibility-rhythm.txt
│ ├── 05_synth-and-note.txt
│ ├── 06_generative-melody.txt
│ └── 07_granular-playback.txt
├── examples-basic/
│ ├── 01-sample.txt
│ ├── 02-tempo.txt
│ ├── 03-time.txt
│ ├── 04-offset.txt
│ ├── 05-rhythm-ring.txt
│ ├── 06-probability.txt
│ ├── 07-synth.txt
│ ├── 08-two-notes.txt
│ ├── 09-melody-ring.txt
│ ├── 10-scale.txt
│ ├── 11-shape.txt
│ └── 12-fx.txt
├── grammar/
│ ├── .gitignore
│ ├── README.md
│ ├── data/
│ │ ├── bind-functions.json
│ │ ├── bind-instruments.json
│ │ ├── function-parse.js
│ │ ├── instrument-methods.json
│ │ ├── mini-functions.json
│ │ └── objects.js
│ ├── grammar.js
│ ├── mercury.ne
│ ├── mercuryIR.js
│ ├── package.json
│ ├── parser.js
│ ├── src/
│ │ └── dict.js
│ ├── test/
│ │ ├── grammar-example.txt
│ │ ├── mercuryAST.json
│ │ ├── mercuryIR.json
│ │ ├── ring-test.txt
│ │ └── synth-test.txt
│ └── totalSerialismIR.js
└── mercury_ide/
├── .vscode/
│ └── settings.json
├── _deprecated/
│ ├── argBindings.txt
│ ├── arr2dTo1d.maxpat
│ ├── beatSyncSystem.maxpat
│ ├── bind-functions.txt
│ ├── codeParser.js
│ ├── dspLib.genexpr
│ ├── ease.mxe64
│ ├── ease.mxo/
│ │ └── Contents/
│ │ ├── Info.plist
│ │ ├── MacOS/
│ │ │ └── ease
│ │ └── PkgInfo
│ ├── editor.maxpat
│ ├── fb-delay.gendsp
│ ├── ladder~.maxpat
│ ├── listLib.js
│ ├── moogLadderFilter.genexpr
│ ├── noise.genjit
│ ├── phasorRate.gendsp
│ ├── recursiveFolder.js
│ ├── samples.json
│ ├── soundObjectShapeJitter.maxpat
│ ├── textScale.maxpat
│ ├── textToMtx.js
│ └── tokens.txt
├── code/
│ ├── dictionary.js
│ ├── editor.js
│ ├── editorGL.js
│ ├── lexer.js
│ ├── mercury.js
│ ├── package.json
│ ├── parser.js
│ └── preferences.js
├── data/
│ ├── bind-functions.gen.json
│ ├── bind-functions.json
│ ├── binding-instruments.json
│ ├── initials.json
│ ├── mini-functions.json
│ ├── scales.txt
│ └── tonics.txt
├── dev/
│ ├── fx-dev.txt
│ ├── grammar-dev.txt
│ ├── kick-dev.txt
│ ├── midi-dev.txt
│ ├── new-list-functions.txt
│ ├── osc-dev-code.txt
│ ├── osc-digilog.txt
│ ├── osc-receive.maxpat
│ ├── osc-receive.txt
│ ├── osc-receiver.maxpat
│ ├── ring-dev-scale-map.txt
│ ├── ring-dev.txt
│ ├── sample-dev.txt
│ ├── sample-test.txt
│ ├── solo-instruments.maxpat
│ ├── string-dev.txt
│ ├── synth-dev.txt
│ ├── synth-test.txt
│ ├── util-dev.txt
│ └── visual-dev.txt
├── external/
│ ├── aka.speech.mxo/
│ │ └── Contents/
│ │ ├── Info.plist
│ │ ├── MacOS/
│ │ │ └── aka.speech
│ │ ├── PkgInfo
│ │ ├── Resources/
│ │ │ └── maxmspsdk.xcconfig
│ │ └── _CodeSignature/
│ │ └── CodeResources
│ ├── clockwarp.gendsp
│ ├── cv.jit.resize.mxe64
│ ├── cv.jit.resize.mxo/
│ │ └── Contents/
│ │ ├── Info.plist
│ │ ├── MacOS/
│ │ │ └── cv.jit.resize
│ │ └── PkgInfo
│ ├── dyn-range-comp.genexpr
│ ├── hidecursor.maxpat
│ ├── jit.gl.spoutreceiver.mxe64
│ ├── jit.gl.spoutsender.mxe64
│ ├── moogLadderFilter.genexpr
│ ├── shortkeys.json
│ ├── th.clockwarp~.maxpat
│ ├── th.comp~.maxpat
│ ├── th.gl.editor.js
│ ├── th.gl.texteditor.maxpat
│ └── th.yafr~.maxpat
├── fonts/
│ ├── IBM_Plex_Mono/
│ │ └── OFL.txt
│ ├── Roboto_Mono/
│ │ └── LICENSE.txt
│ ├── Source_Code_Pro/
│ │ └── OFL.txt
│ ├── Space_Mono/
│ │ └── OFL.txt
│ ├── Ubuntu_Mono/
│ │ └── UFL.txt
│ └── VT323/
│ └── OFL.txt
├── icon/
│ ├── README.md
│ ├── icon.icns
│ └── mercury_icon.psd
├── media/
│ ├── README.md
│ └── images/
│ └── planet_colors.jit
├── mercury_ide.maxproj
└── patchers/
├── _mercury_main.maxpat
├── _mercury_visuals.maxpat
├── analyseDisplay.maxpat
├── argGetList.maxpat
├── argListLookup.maxpat
├── calcExpr.maxpat
├── consoleLog.maxpat
├── divToMs.maxpat
├── drywet~.maxpat
├── emptyScene.maxpat
├── envelopeGen.maxpat
├── eventSequencer.maxpat
├── fftCatch~.maxpat
├── fftCross~.maxpat
├── fftFreeze~.maxpat
├── fxChorus.maxpat
├── fxComb.maxpat
├── fxCompress.maxpat
├── fxDegrade.maxpat
├── fxDelay.maxpat
├── fxDrive.maxpat
├── fxEnvelopeFilter.maxpat
├── fxFilter.maxpat
├── fxFreeze.maxpat
├── fxFuzz.maxpat
├── fxKink.maxpat
├── fxLFO.maxpat
├── fxLadderFilter.maxpat
├── fxLoopDelay.maxpat
├── fxMorph.maxpat
├── fxPitchShift.maxpat
├── fxRetune.maxpat
├── fxReverb.maxpat
├── fxRing.maxpat
├── fxSquash.maxpat
├── fxStutter.maxpat
├── fxTriggerFilter.maxpat
├── fxVibrato.maxpat
├── fxVocoder.maxpat
├── fxVocoderBand.maxpat
├── fxVowel.maxpat
├── getVariables.maxpat
├── gtep.maxpat
├── keyPressed.maxpat
├── mcy.buffers~.maxpat
├── midiToOSC.maxpat
├── modulatorObject~.maxpat
├── newInstance.maxpat
├── noteToMidi.maxpat
├── planetaryMotion.maxpat
├── probList.maxpat
├── probTrig.maxpat
├── setupAudio.maxpat
├── setupEditor.maxpat
├── setupShortkeys.maxpat
├── setupVisuals.maxpat
├── soundObject.maxpat
├── srcExtension.maxpat
├── srcFmSynth.maxpat
├── srcInput.maxpat
├── srcKarplus.maxpat
├── srcKick.maxpat
├── srcNoise.maxpat
├── srcPolySample.maxpat
├── srcSample.maxpat
├── srcSampleRack.maxpat
├── srcSynth.maxpat
├── srcWavetable.maxpat
├── srcWrapper.maxpat
├── strange-attractor.maxpat
├── syncToScale.maxpat
├── synthPoly.maxpat
├── visual/
│ ├── circling.maxpat
│ ├── cubes.maxpat
│ ├── mesh.maxpat
│ ├── meshes.maxpat
│ ├── meshwave.maxpat
│ ├── pillars.maxpat
│ ├── plane.maxpat
│ ├── shape.maxpat
│ ├── syphon.maxpat
│ └── template.maxpat
├── visualObject.maxpat
└── wavetablePlayer.maxpat
SYMBOL INDEX (276 symbols across 16 files)
FILE: grammar/grammar.js
function id (line 4) | function id(x) { return x[0]; }
FILE: grammar/mercuryIR.js
function identifier (line 24) | function identifier(obj){
function division (line 37) | function division(obj){
function num (line 43) | function num(obj){
function keyBind (line 50) | function keyBind(f){
function keywordBindings (line 56) | function keywordBindings(dict, obj){
function deepCopy (line 91) | function deepCopy(o){
function traverseTreeIR (line 95) | function traverseTreeIR(tree){
function traverseTree (line 103) | function traverseTree(tree, code, level){
FILE: grammar/parser.js
function parse (line 18) | function parse(code){
function parseFile (line 70) | function parseFile(f){
function parseNumbers (line 107) | function parseNumbers(){
function parseRhythm (line 127) | function parseRhythm(){
function parseComments (line 135) | function parseComments(){
function parseStrings (line 145) | function parseStrings(){
function parseIdentifier (line 157) | function parseIdentifier(){
function parseSignal (line 168) | function parseSignal(){
function parseOSC (line 177) | function parseOSC(){
function parseKeywords (line 184) | function parseKeywords(){
function parseRing (line 195) | function parseRing(){
function parseInst (line 213) | function parseInst(){
function parseSet (line 227) | function parseSet(){
function parseSettings (line 238) | function parseSettings(){
function parseMain (line 251) | function parseMain(){
FILE: grammar/src/dict.js
class Dictionary (line 9) | class Dictionary {
method constructor (line 10) | constructor() {
method has (line 14) | has(key) {
method get (line 18) | get(key) {
method set (line 34) | set(key, value) {
method delete (line 38) | delete(key) {
method clear (line 47) | clear() {
FILE: mercury_ide/_deprecated/codeParser.js
function jit_matrix (line 7) | function jit_matrix(mat){
function Array2D (line 31) | function Array2D(y, x){
FILE: mercury_ide/_deprecated/listLib.js
function list (line 25) | function list(){
function spread (line 36) | function spread(){
function spreadFloat (line 43) | function spreadFloat(){
function spreadInclusive (line 49) | function spreadInclusive(){
function spreadInclusiveFloat (line 56) | function spreadInclusiveFloat(){
function _spread (line 66) | function _spread(args){
function _spreadinclusive (line 102) | function _spreadinclusive(args){
function merge (line 137) | function merge(){
function euclid (line 168) | function euclid(){
function build (line 209) | function build(l){
function mod (line 229) | function mod(value, mod){
function constrain (line 235) | function constrain(value, min, max){
function getIndex (line 241) | function getIndex(v, arr){
function decodeArray (line 252) | function decodeArray(str){
function decodeRecursive (line 262) | function decodeRecursive(str){
function lookup (line 290) | function lookup(i){
function length (line 294) | function length(){
FILE: mercury_ide/_deprecated/recursiveFolder.js
function setSystem (line 12) | function setSystem(s){
function setPath (line 17) | function setPath(path){
function recursiveFolder (line 22) | function recursiveFolder(path){
function folder (line 41) | function folder(path){
function file (line 73) | function file(n, p){
function makeDir (line 79) | function makeDir(n){
FILE: mercury_ide/_deprecated/textToMtx.js
function loadbang (line 64) | function loadbang(){
function init (line 69) | function init(){
function emptyMatrix (line 100) | function emptyMatrix(lines){
function draw (line 110) | function draw(){
function keyPress (line 121) | function keyPress(k){
function addTab (line 166) | function addTab(){
function addChar (line 173) | function addChar(k){
function backSpace (line 190) | function backSpace(k){
function getCharCount (line 206) | function getCharCount(mat, line){
function countChars (line 218) | function countChars(){
function getMaxChar (line 228) | function getMaxChar(){
function gotoCharacter (line 236) | function gotoCharacter(k){
function gotoLine (line 250) | function gotoLine(k){
function jumpTo (line 266) | function jumpTo(k){
function newLine (line 281) | function newLine(){
function removeLine (line 325) | function removeLine(){
function deleteLine (line 359) | function deleteLine(){
function copyLine (line 398) | function copyLine(){
function drawCursor (line 436) | function drawCursor(){
function drawNumbers (line 457) | function drawNumbers(){
function drawHighlight (line 476) | function drawHighlight(){
function commentLine (line 487) | function commentLine(){
FILE: mercury_ide/code/dictionary.js
class Dictionary (line 3) | class Dictionary {
method constructor (line 4) | constructor() {
method has (line 8) | has(key) {
method get (line 12) | get(key) {
method set (line 29) | set(key, value) {
method delete (line 33) | delete(key) {
method clear (line 42) | clear() {
FILE: mercury_ide/code/editor.js
function loadbang (line 88) | function loadbang(){
function init (line 92) | function init(){
function emptyMatrix (line 131) | function emptyMatrix(lines){
function run (line 140) | function run(){
function output_matrix (line 148) | function output_matrix(v){
function mtxToSymbol (line 153) | function mtxToSymbol(mat){
function draw (line 168) | function draw(){
function keyPress (line 183) | function keyPress(k){
function addTab (line 245) | function addTab(){
function addChar (line 253) | function addChar(k){
function backSpace (line 274) | function backSpace(k){
function getCharCount (line 291) | function getCharCount(mat, line){
function countChars (line 303) | function countChars(){
function getMaxChar (line 313) | function getMaxChar(){
function gotoCharacter (line 320) | function gotoCharacter(k){
function gotoLine (line 349) | function gotoLine(k){
function jumpTo (line 365) | function jumpTo(k){
function newLine (line 380) | function newLine(){
function removeLine (line 417) | function removeLine(){
function deleteLine (line 446) | function deleteLine(){
function copyLine (line 484) | function copyLine(){
function pasteReplaceLine (line 492) | function pasteReplaceLine(){
function pasteInsertLine (line 505) | function pasteInsertLine(){
function endOfLines (line 514) | function endOfLines(){
function cursor (line 522) | function cursor(c){
function comment (line 532) | function comment(c){
function drawCursor (line 543) | function drawCursor(){
function drawNumbers (line 554) | function drawNumbers(){
function commentLine (line 581) | function commentLine(){
function readFile (line 620) | function readFile(mat){
function fillText (line 629) | function fillText(mat){
function drawto (line 686) | function drawto(v){
function position (line 698) | function position(x, y){
function scale (line 703) | function scale(s){
function color (line 720) | function color(){
function number_color (line 753) | function number_color(){
function blink (line 767) | function blink(){
function blink_enable (line 780) | function blink_enable(v){
function cursor_color (line 784) | function cursor_color(){
function blink_color (line 794) | function blink_color(){
function font (line 846) | function font(f){
function fontsize (line 852) | function fontsize(s){
function leadscale (line 862) | function leadscale(l){
function tracking (line 868) | function tracking(t){
function alpha (line 876) | function alpha(a){
function cull_face (line 886) | function cull_face(c){
function runBlink (line 892) | function runBlink(){
function disableText (line 897) | function disableText(){
function matrixToText (line 902) | function matrixToText(){
FILE: mercury_ide/code/editorGL.js
function loadbang (line 86) | function loadbang(){
function init (line 90) | function init(){
function println (line 116) | function println(){
function emptyMatrix (line 122) | function emptyMatrix(lines){
function runCode (line 131) | function runCode(){
function draw (line 136) | function draw(){
function keyPress (line 148) | function keyPress(k){
function addTab (line 201) | function addTab(){
function addChar (line 209) | function addChar(k){
function backSpace (line 230) | function backSpace(k){
function getCharCount (line 247) | function getCharCount(mat, line){
function countChars (line 259) | function countChars(){
function getMaxChar (line 269) | function getMaxChar(){
function gotoCharacter (line 277) | function gotoCharacter(k){
function gotoWord (line 291) | function gotoWord(k){
function gotoLine (line 306) | function gotoLine(k){
function jumpTo (line 322) | function jumpTo(k){
function newLine (line 337) | function newLine(){
function removeLine (line 376) | function removeLine(){
function deleteLine (line 405) | function deleteLine(){
function copyLine (line 444) | function copyLine(){
function pasteReplaceLine (line 452) | function pasteReplaceLine(){
function pasteInsertLine (line 464) | function pasteInsertLine(){
function endOfLines (line 473) | function endOfLines(){
function drawCursor (line 481) | function drawCursor(){
function drawNumbers (line 492) | function drawNumbers(){
function drawHighlight (line 510) | function drawHighlight(){
function commentLine (line 520) | function commentLine(){
function readFile (line 556) | function readFile(mat){
function fillText (line 564) | function fillText(mat){
function fillConsole (line 577) | function fillConsole(mess){
function emptyConsole (line 595) | function emptyConsole(){
function drawto (line 642) | function drawto(v){
function position (line 653) | function position(x, y, z){
function scale (line 657) | function scale(x, y, z){
function blink (line 706) | function blink(){
function positionCnsl (line 746) | function positionCnsl(x, y, z){
function scaleCnsl (line 750) | function scaleCnsl(x, y, z){
function setFont (line 778) | function setFont(f){
function setSize (line 785) | function setSize(s){
function setLeadScale (line 792) | function setLeadScale(l){
function setAlpha (line 800) | function setAlpha(a){
function runBlink (line 810) | function runBlink(){
function disableText (line 815) | function disableText(){
function matrixToText (line 820) | function matrixToText(){
function cam (line 841) | function cam(ortho, angle){
function blend (line 854) | function blend(b){
FILE: mercury_ide/code/lexer.js
function jit_matrix (line 12) | function jit_matrix(mat){
function matrixToString (line 17) | function matrixToString(code){
FILE: mercury_ide/code/mercury.js
constant DEBUG (line 27) | let DEBUG = false;
function mainParse (line 788) | function mainParse(lines){
function outputParse (line 1022) | function outputParse(){
function mapFunc (line 1105) | function mapFunc(f){
function evaluateParse (line 1113) | function evaluateParse(parse){
function hasFunc (line 1132) | function hasFunc(f){
function mainFunc (line 1138) | function mainFunc(func){
function parseNumber (line 1146) | function parseNumber(v){
function parseParam (line 1158) | function parseParam(v){
function parseString (line 1175) | function parseString(str){
function keywordBindings (line 1251) | function keywordBindings(dict, obj){
function post (line 1276) | function post(...v){
function date (line 1282) | function date(){
FILE: mercury_ide/code/parser.js
function anything (line 7) | function anything(){
function str_arr2d (line 64) | function str_arr2d(name, s){
function add_dict (line 127) | function add_dict(dct, nm, tk){
function toNumber (line 134) | function toNumber(str){
function arr2d_dict (line 138) | function arr2d_dict(name, arr){
function get (line 150) | function get(name, v){
function get_length (line 160) | function get_length(name, v){
function wrap (line 165) | function wrap(v, lo, hi){
FILE: mercury_ide/code/preferences.js
function loadSamplesFromIni (line 366) | function loadSamplesFromIni(){
function loadWaveformsFromIni (line 370) | function loadWaveformsFromIni(){
function loadAudioFromIni (line 375) | function loadAudioFromIni(type, dict, defaults, file){
function loadAudioFiles (line 390) | function loadAudioFiles(fold){
function loadFiles (line 397) | function loadFiles(fold, glob){
function writeJson (line 411) | function writeJson(file, obj){
function join (line 416) | function join(){
function writeConfig (line 421) | function writeConfig(){
FILE: mercury_ide/external/th.gl.editor.js
function loadbang (line 80) | function loadbang(){
function init (line 84) | function init(){
function clear (line 107) | function clear(){
function empty (line 128) | function empty(lines){
function run (line 138) | function run(){
function output_matrix (line 150) | function output_matrix(v){
function mtxToSymbol (line 155) | function mtxToSymbol(mat){
function draw (line 170) | function draw(){
function keybindings (line 189) | function keybindings(n){
function keyPress (line 194) | function keyPress(k){
function addTab (line 277) | function addTab(){
function addChar (line 285) | function addChar(k){
function backSpace (line 302) | function backSpace(){
function deleteChar (line 319) | function deleteChar(){
function getMaxChar (line 356) | function getMaxChar(){
function gotoCharacter (line 368) | function gotoCharacter(k){
function gotoLine (line 384) | function gotoLine(k){
function gotoWord (line 401) | function gotoWord(k){
function jumpTo (line 424) | function jumpTo(k){
function gotoIndex (line 443) | function gotoIndex(i){
function newLine (line 470) | function newLine(){
function removeLine (line 495) | function removeLine(){
function deleteLine (line 508) | function deleteLine(){
function copyLine (line 529) | function copyLine(){
function pasteReplaceLine (line 533) | function pasteReplaceLine(){
function pasteInsertLine (line 542) | function pasteInsertLine(){
function endOfLines (line 551) | function endOfLines(){
function cursor (line 560) | function cursor(c){
function comment (line 571) | function comment(c){
function commentLine (line 583) | function commentLine(){
function drawText (line 600) | function drawText(){
function drawCursor (line 615) | function drawCursor(){
function drawNumbers (line 629) | function drawNumbers(){
function readFile (line 658) | function readFile(mat){
function fillText (line 668) | function fillText(mat){
function set (line 688) | function set(){
function append (line 705) | function append(){
function prepend (line 720) | function prepend(){
function remove (line 735) | function remove(idx){
function insert (line 744) | function insert(){
function add (line 777) | function add(c){
function back (line 791) | function back(){
function del (line 796) | function del(){
function drawto (line 845) | function drawto(v){
function position (line 857) | function position(x, y){
function scale (line 862) | function scale(s){
function color (line 882) | function color(){
function run_color (line 892) | function run_color(){
function runBlink (line 901) | function runBlink(t){
function number_color (line 940) | function number_color(){
function blink (line 954) | function blink(){
function blink_enable (line 967) | function blink_enable(v){
function cursor_color (line 971) | function cursor_color(){
function blink_color (line 981) | function blink_color(){
function font (line 1033) | function font(f){
function fontsize (line 1039) | function fontsize(s){
function leadscale (line 1049) | function leadscale(l){
function tracking (line 1055) | function tracking(t){
function line_length (line 1061) | function line_length(l){
function line_width (line 1067) | function line_width(w){
function alpha (line 1075) | function alpha(a){
function cull_face (line 1085) | function cull_face(c){
function disableText (line 1091) | function disableText(){
function matrixToText (line 1096) | function matrixToText(){
Condensed preview — 239 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (9,502K chars).
[
{
"path": ".gitignore",
"chars": 106,
"preview": "# ignore DS_Store\n.DS_Store\n\n# ignore the mercury.ini file, this is autogenerated\nmercury_ide/mercury.ini\n"
},
{
"path": ".gitmodules",
"chars": 205,
"preview": "[submodule \"mercury-docs\"]\n\tpath = docs/mercury-docs\n\turl = https://github.com/tmhglnd/mercury-docs\n[submodule \"docs/mer"
},
{
"path": "LICENSE",
"chars": 35149,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "README.md",
"chars": 12666,
"preview": "# 🌕 Mercury Live Coding Environment \n\n**Welcome to Mercury! ✌️ ☮️ Make Music, Not War!** ☮️ ✌️\n\n**Mercury is a free/open"
},
{
"path": "docs/deprecated-docs/00-general.md",
"chars": 4283,
"preview": "# General Syntax\n\n## new\n\nCreate a new instance of an instrument or external output. This can be a `sample`, a `synth`, "
},
{
"path": "docs/deprecated-docs/01-global.md",
"chars": 13007,
"preview": "# Global Settings (set)\n\n*Some settings are different between the Max and Browser version*\n\n## tempo\n\nChange the global "
},
{
"path": "docs/deprecated-docs/02-instrument.md",
"chars": 30993,
"preview": "# All Instruments\n\nThe following methods apply to all the types of instruments: `synth`, `sample`, `loop`, `polySynth`, "
},
{
"path": "docs/deprecated-docs/03-emitter.md",
"chars": 4318,
"preview": "# Emitter\n\nCreate an emitter object. Use this object to send messages to other platforms. The emitter objects works simi"
},
{
"path": "docs/deprecated-docs/04-fx.md",
"chars": 13030,
"preview": "# Sound Effects (fx)\n\nThe sound FX currently have a fixed chain when using the Mercury standalone version in Max. The ch"
},
{
"path": "docs/deprecated-docs/05-ring.md",
"chars": 45246,
"preview": "# List Methods\n\nMercury uses the [`total-serialism`](https://www.npmjs.com/package/total-serialism) Node Package to gene"
},
{
"path": "docs/deprecated-docs/06-shortkeys.md",
"chars": 1930,
"preview": "# Shortkeys\n\nMercury has various shortkeys that help you navigate the editor quickly during liveperformances. At the mom"
},
{
"path": "docs/deprecated-docs/07-environment.md",
"chars": 12221,
"preview": "# Environment\n\n- [Mercury Main Window](#mercury-main-window)\n\t- [Editor / Visuals](#editor-visuals)\n\t- [Sound](#sound)\n\t"
},
{
"path": "docs/deprecated-docs/08-troubleshooting.md",
"chars": 3376,
"preview": "\n# ⚠ Troubleshooting\n\nIf you are having issues please follow the steps below:\n\n1. Check this [troubleshooting page](#tab"
},
{
"path": "docs/deprecated-docs/09-visuals.md",
"chars": 2836,
"preview": "# Visuals\n\nMercury has some options to add visuals to your live coding performance. These visuals are pre-coded and stor"
},
{
"path": "docs/deprecated-docs/10-includes.md",
"chars": 4010,
"preview": "# Includes\n\n**⚠ EXPERIMENTAL ⚠**\n\nYou can extend Mercury with custom synths and other sound designing patches programmed"
},
{
"path": "docs/deprecated-docs/README.md",
"chars": 16780,
"preview": "# 🌕 Mercury Live Coding Environment \n\n**A minimal and human-readable language for the live coding of algorithmic electro"
},
{
"path": "docs/deprecated-docs/_config.yml",
"chars": 26,
"preview": "theme: jekyll-theme-slate\n"
},
{
"path": "docs/deprecated-docs/collaborate.md",
"chars": 6178,
"preview": "# 👩💻👨💻 Collaborative Coding\n\nYou can code together in Mercury using the amazing [**Flok**](https://flok.clic.cf/) live"
},
{
"path": "docs/deprecated-docs/linux-guide.md",
"chars": 2018,
"preview": "# 🐧 Linux Guide\n\nWelcome Linux users! Unfortunately Cycling '74 doesn't provide a Linux version of Max8. However, we can"
},
{
"path": "docs/deprecated-docs/quick-start.md",
"chars": 3200,
"preview": "# 🏃 Quick Start\n\nHi! Welcome to the Quick Start guide. If you experience any issues with installing or running the code,"
},
{
"path": "docs/deprecated-docs/reference.md",
"chars": 7946,
"preview": "# 📖 Mercury Function Reference\n\n**Disclaimer: This documentation is not entirely finished and will subject to changes. I"
},
{
"path": "docs/deprecated-docs/table-of-content.md",
"chars": 638,
"preview": "# 📖 Mercury Documentation\n\n*Disclaimer: This documentation is not entirely finished and will subject to changes. If you "
},
{
"path": "docs/deprecated-docs/tutorial.md",
"chars": 30787,
"preview": "\n⚠️ **If you are a first time user of Mercury it is recommended to use the browser version instead of the Max version. P"
},
{
"path": "examples/00_sample-and-time.txt",
"chars": 248,
"preview": "// play different samples\n// at different time intervals\n\nset tempo 95\n\nnew sample bamboo_a time(1)\nnew sample bamboo_c "
},
{
"path": "examples/01_offset-in-time.txt",
"chars": 313,
"preview": "// multiple samples make up a beat\n// using a time offset as \n// second argument\n\nset tempo 131\n\nnew sample kick_909 tim"
},
{
"path": "examples/02_linear-beat.txt",
"chars": 419,
"preview": "// choose 15 random samples from a ring of\n// predefined samplename. Play those samples \n// sequentially for every time "
},
{
"path": "examples/03_sample-scrubbing.txt",
"chars": 549,
"preview": "// make 2 different position rings of 16 values \n// from a randomFloat() method and combine them\n// into one ring. Fade-"
},
{
"path": "examples/04_possibility-rhythm.txt",
"chars": 359,
"preview": "// make a rhythm with ones and zeroes\n// in a ring. A value between one and zero is\n// a probability (for example 0.5 = "
},
{
"path": "examples/05_synth-and-note.txt",
"chars": 410,
"preview": "// play a melody from a ring of semitones\n// use different octaves with the second\n// argument in the note() method\n\nset"
},
{
"path": "examples/06_generative-melody.txt",
"chars": 505,
"preview": "// generate a small theme from a sine \n// function and transform it with various \n// methods like invert(), join() and c"
},
{
"path": "examples/07_granular-playback.txt",
"chars": 491,
"preview": "// simple granular timestretching is achieved\n// by quickly playing short grains of a sample\n// and changing the offset "
},
{
"path": "examples-basic/01-sample.txt",
"chars": 102,
"preview": "\n// make a new instrument named bamboo_a\n// played 4 times per bar 1/4\n\nnew sample bamboo_a time(1/4)\n"
},
{
"path": "examples-basic/02-tempo.txt",
"chars": 113,
"preview": "\n// change the total tempo of the environment\n// in beats per minute\n\nset tempo 98\n\nnew sample bamboo_a time(1/4)"
},
{
"path": "examples-basic/03-time.txt",
"chars": 136,
"preview": "set tempo 98\n\n// add another instrument with different \n// timing division\n\nnew sample bamboo_a time(1/5)\nnew sample bam"
},
{
"path": "examples-basic/04-offset.txt",
"chars": 175,
"preview": "set tempo 105\n\n// many divisions are possible\n// and with offset as 2nd argument\n\nnew sample pluck_a time(1/2)\nnew sampl"
},
{
"path": "examples-basic/05-rhythm-ring.txt",
"chars": 175,
"preview": "set tempo 105\n\n// a list with 1's and 0's to play\n// as a rhythm\nring myRhythm [1 0 0 1 0 1 0 1]\n\nnew sample pluck_a tim"
},
{
"path": "examples-basic/06-probability.txt",
"chars": 268,
"preview": "set tempo 105\n\n// play the instruments 90%, 40%, \n// and 20% of the time\n\n// new sample pluck_a time(1/4) beat(0.9)\n// n"
},
{
"path": "examples-basic/07-synth.txt",
"chars": 49,
"preview": "set tempo 97\n\nnew synth sine time(1/8) note(0 2)\n"
},
{
"path": "examples-basic/08-two-notes.txt",
"chars": 86,
"preview": "set tempo 113\n\nnew synth sine time(1/4) note(0 2)\nnew synth sine time(1/5) note(7 2)\n\n"
},
{
"path": "examples-basic/09-melody-ring.txt",
"chars": 93,
"preview": "set tempo 113\n\nring myMelody [0 4 5 4 7 5 2 -1]\n\nnew synth sine time(1/16) note(myMelody 2)\n\n"
},
{
"path": "examples-basic/10-scale.txt",
"chars": 202,
"preview": "set tempo 97\n\n// hear how numbers are mapped\n// to the scale (resulting in doubles)\nset scale pentatonic_major g\n\nring m"
},
{
"path": "examples-basic/11-shape.txt",
"chars": 131,
"preview": "set tempo 83\n\nring myMelody [0 3 7 -1]\nring lengths [100 1000 20 20 20]\n\nnew synth sine time(1/16) note(myMelody 2) shap"
},
{
"path": "examples-basic/12-fx.txt",
"chars": 306,
"preview": "set tempo 83\n\nring myMelody [0 3 7 -1]\n\n// use names to have more space \n// for functions\n\nnew synth sine name(one)\n "
},
{
"path": "grammar/.gitignore",
"chars": 27,
"preview": "#node modules\n/node_modules"
},
{
"path": "grammar/README.md",
"chars": 782,
"preview": "# Mercury Grammar Design\n\nThis folder contains the work in progress of an updated grammar design for the Mercury tokeniz"
},
{
"path": "grammar/data/bind-functions.json",
"chars": 1381,
"preview": "{\n\t\"new\" : [\n\t\t\"make\",\n\t\t\"sound\"\n\t],\n\n\t\"ring\" : [\n\t\t\"list\",\n\t\t\"array\",\n\t\t\"items\"\n\t],\n\n\t\"set\" : [\n\t\t\"apply\",\n\t\t\"give\"\n\t],"
},
{
"path": "grammar/data/bind-instruments.json",
"chars": 3162,
"preview": "{\n\t\"emitter\" : {\n\t\t\"osc\" : [ \"osc_out\", 5 ],\n\t\t\"midi\" : [ \"midi_out\", 6 ]\n\t}\n,\n\t\"synth\" : \t{\n\t\t\"saw\" : [ \"synth_simple\","
},
{
"path": "grammar/data/function-parse.js",
"chars": 1956,
"preview": "//=======================================================================\n// function-parse.js\n// \n// Combine a method-f"
},
{
"path": "grammar/data/instrument-methods.json",
"chars": 1377,
"preview": "{\n\t\"midi\" : [\n\t\t\"name\",\n\t\t\"group\",\n\t\t\"beat\",\n\t\t\"time\",\n\t\t\"amp\",\n\t\t\"note\",\n\t\t\"env\",\n\t\t\"out\",\n\t\t\"clock\",\n\t\t\"poly\"\n\t],\n\n\t\"e"
},
{
"path": "grammar/data/mini-functions.json",
"chars": 191,
"preview": "{\n\t\"new\" : [ \"<<\" ],\n\t\"set\" : [ \">>\" ],\n\t\"ring\" : [ \"=\" ],\n\t\"time\" : [ \"%\" ],\n\t\"beat\" : [ \"!\" ],\n\t\"note\" : [ \"#\" ],\n\t\"am"
},
{
"path": "grammar/data/objects.js",
"chars": 744,
"preview": "\nconst objects = {\n\t'empty' : {\n\t\t'object' : '',\n\t\t'type' : '',\n\t\t'functions' : {\n\t\t\t'name' : `obj${String(Date.now())}`"
},
{
"path": "grammar/grammar.js",
"chars": 7643,
"preview": "// Generated automatically by nearley, version 2.20.1\n// http://github.com/Hardmath123/nearley\n(function () {\nfunction i"
},
{
"path": "grammar/mercury.ne",
"chars": 4181,
"preview": "# TOKENIZER\n@{%\nconst moo = require('moo');\nconst IR = require('./mercuryIR.js');\n\nconst lexer = moo.compile({\n\tcomment:"
},
{
"path": "grammar/mercuryIR.js",
"chars": 8483,
"preview": "//==========================================================================\n// Mercury Intermediate Language\n//\n// Retu"
},
{
"path": "grammar/package.json",
"chars": 683,
"preview": "{\n \"name\": \"mercury-grammar\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"parser.js\",\n \"scripts\": {\n \"sta"
},
{
"path": "grammar/parser.js",
"chars": 6389,
"preview": "\nconst fs = require('fs-extra');\nconst util = require('util');\nconst nearley = require('nearley');\n\nconst grammar = requ"
},
{
"path": "grammar/src/dict.js",
"chars": 1134,
"preview": "//=====================================================================\n// dict.js\n//\n// Build a JSON Dictionary with ha"
},
{
"path": "grammar/test/grammar-example.txt",
"chars": 930,
"preview": "\n// this is a comment\n\n// GLOBAL\nkillall\n\n// multiple keywords on one line\naudio on, record on, tempo 143\naudio(1) recor"
},
{
"path": "grammar/test/mercuryAST.json",
"chars": 24652,
"preview": "{\n \"@main\": [\n {\n \"@object\": {\n \"@set\": {\n \"@name\": \"volume\",\n "
},
{
"path": "grammar/test/mercuryIR.json",
"chars": 6524,
"preview": "{\n \"global\": {\n \"volume\": [\n 3,\n 5000\n ],\n \"tempo\": [\n 90\n "
},
{
"path": "grammar/test/ring-test.txt",
"chars": 7655,
"preview": "// set debug 0\n\n// possible arrays and datatypes with arbitrary spaces\nring ar1 [0 12 3.14 56 789]\nprint ar1\nring ar2 [1"
},
{
"path": "grammar/test/synth-test.txt",
"chars": 1133,
"preview": "set volume 3 5000\n// set tempo 143\n// set tempo random(1 80 120)\nset randomSeed 9123\nset scale pentatonic_minor c\n\nring "
},
{
"path": "grammar/totalSerialismIR.js",
"chars": 8811,
"preview": "\nconst Gen = require('total-serialism').Generative;\nconst Algo = require('total-serialism').Algorithmic;\nconst Mod = r"
},
{
"path": "mercury_ide/.vscode/settings.json",
"chars": 28,
"preview": "{\n\t\"cSpell.enabled\": false\n}"
},
{
"path": "mercury_ide/_deprecated/argBindings.txt",
"chars": 1087,
"preview": "amp, amp;\ngain, amp;\nvolume, amp;\na, amp;\ng, amp;\nv, amp;\nbeat, beat;\nrhythm, beat;\nb, beat;\nfilter, filter;\ncutoff, fil"
},
{
"path": "mercury_ide/_deprecated/arr2dTo1d.maxpat",
"chars": 9205,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 8,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/_deprecated/beatSyncSystem.maxpat",
"chars": 89901,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 2,\n\t\t\t\"revision\" : 2,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/_deprecated/bind-functions.txt",
"chars": 1087,
"preview": "amp, amp;\ngain, amp;\nvolume, amp;\na, amp;\ng, amp;\nv, amp;\nbeat, beat;\nrhythm, beat;\nb, beat;\nfilter, filter;\ncutoff, fil"
},
{
"path": "mercury_ide/_deprecated/codeParser.js",
"chars": 739,
"preview": "autowatch = 1;\ninlets = 1;\noutlets = 1;\n\nvar textArray = new Array();\n\nfunction jit_matrix(mat){\n\tcode = new JitterMatri"
},
{
"path": "mercury_ide/_deprecated/dspLib.genexpr",
"chars": 1398,
"preview": "//=====================================================================\n// dspLib.genexpr\n//\n// A library with different"
},
{
"path": "mercury_ide/_deprecated/ease.mxo/Contents/Info.plist",
"chars": 1551,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "mercury_ide/_deprecated/ease.mxo/Contents/PkgInfo",
"chars": 8,
"preview": "iLaX????"
},
{
"path": "mercury_ide/_deprecated/editor.maxpat",
"chars": 60861,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 1,\n\t\t\t\"revision\" : 3,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/_deprecated/fb-delay.gendsp",
"chars": 7566,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 8,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/_deprecated/ladder~.maxpat",
"chars": 3981,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 7,\n\t\t\t\"minor\" : 3,\n\t\t\t\"revision\" : 5,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/_deprecated/listLib.js",
"chars": 6506,
"preview": "//==============================================================================\n// listLib.js\n// \n// a library of algor"
},
{
"path": "mercury_ide/_deprecated/moogLadderFilter.genexpr",
"chars": 2438,
"preview": "/*\nThis GenExpr file is a port of the CSOUND Moogladder opcode, by Victor Lazzarini.\nHis original description follows be"
},
{
"path": "mercury_ide/_deprecated/noise.genjit",
"chars": 8052,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 7,\n\t\t\t\"minor\" : 3,\n\t\t\t\"revision\" : 5,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/_deprecated/phasorRate.gendsp",
"chars": 2981,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 7,\n\t\t\t\"minor\" : 3,\n\t\t\t\"revision\" : 5,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/_deprecated/recursiveFolder.js",
"chars": 2022,
"preview": "autowatch = 1;\n\ninlets = 1;\noutlets = 2;\nsetinletassist(0, \"(messages) functions to call\");\nsetoutletassist(0, \"(message"
},
{
"path": "mercury_ide/_deprecated/samples.json",
"chars": 13684,
"preview": "{\n\t\"drone_cymbal\" : \"Macintosh HD:/Users/timohoogland/Drive/work/code/max/major_projects/mercury_lc/mercury/mercury_ide_"
},
{
"path": "mercury_ide/_deprecated/soundObjectShapeJitter.maxpat",
"chars": 44133,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/_deprecated/textScale.maxpat",
"chars": 23329,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 1,\n\t\t\t\"revision\" : 3,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/_deprecated/textToMtx.js",
"chars": 12922,
"preview": "//======================================================================\n// textToMtx.js\n//\n// written by Timo Hoogland "
},
{
"path": "mercury_ide/_deprecated/tokens.txt",
"chars": 272,
"preview": "new\nsample\nsynth\nsaw\nsine\ntriangle\nsquare\ngain\nspeed\nshape\nfx\ntime\nbeat\nname\nspread\nspreadinclusive\nshuffle\nscramble\nrev"
},
{
"path": "mercury_ide/code/dictionary.js",
"chars": 1027,
"preview": "// A simple dictionary where arrays can be stored\n// With a key as variable name for reference in other functions\nclass "
},
{
"path": "mercury_ide/code/editor.js",
"chars": 22244,
"preview": "//====================================================================\n// th.gl.editor.js\n// A responsive texteditor for"
},
{
"path": "mercury_ide/code/editorGL.js",
"chars": 21041,
"preview": "//======================================================================\n// editorGL.js\n//\n// written by Timo Hoogland ©"
},
{
"path": "mercury_ide/code/lexer.js",
"chars": 1692,
"preview": "//=====================================================================\n// matrixToString.js\n//\n// written by Timo Hoogl"
},
{
"path": "mercury_ide/code/mercury.js",
"chars": 30892,
"preview": "//====================================================================\n// mercury.js\n// by Timo Hoogland (@t.mo / @tmhgl"
},
{
"path": "mercury_ide/code/package.json",
"chars": 449,
"preview": "{\n \"name\": \"mercury_ide\",\n \"version\": \"0.12.0\",\n \"description\": \"The mercury livecoding environment NodeJS methods\",\n"
},
{
"path": "mercury_ide/code/parser.js",
"chars": 3507,
"preview": "autowatch = 1;\ninlets = 1;\noutlets = 1;\n\nvar dict = new Dict(\"variables\");\n\nfunction anything(){\n\t// var line = arrayfro"
},
{
"path": "mercury_ide/code/preferences.js",
"chars": 12502,
"preview": "// \n// Mercury preferences and file loading script\n// \n\nconst max = require('max-api');\nconst os = require('os');\nconst "
},
{
"path": "mercury_ide/data/bind-functions.gen.json",
"chars": 7411,
"preview": "{\n \"midi\": {\n \"id\": \"name\",\n \"aux\": \"group\",\n \"bus\": \"group\",\n \"rhythm\": \"beat\",\n \"play\": \"beat\",\n \"t"
},
{
"path": "mercury_ide/data/bind-functions.json",
"chars": 1252,
"preview": "{\n\t\"new\" : [\n\t\t\"make\",\n\t\t\"sound\"\n\t],\n\n\t\"ring\" : [\n\t\t\"list\",\n\t\t\"array\",\n\t\t\"items\"\n\t],\n\n\t\"set\" : [\n\t\t\"apply\",\n\t\t\"give\"\n\t],"
},
{
"path": "mercury_ide/data/binding-instruments.json",
"chars": 601,
"preview": "{\n\t\"voice\" : {\n\t\t\"Alex\" : [ \"speak_out\", 7 ],\n\t\t\"Samantha\" : [ \"speak_out\", 7 ]\n\t}\n,\n\t\"emitter\" : \t{\n\t\t\"osc\" : [ \"osc_ou"
},
{
"path": "mercury_ide/data/initials.json",
"chars": 4024,
"preview": "{\n\t\"synth\" : \t{\n\t\t\"solo\" : 0,\n\t\t\"amp\" : 0.6,\n\t\t\"beat\" : 1,\n\t\t\"time\" : \"1/4\",\n\t\t\"once\" : 0,\n\t\t\"warp\" : 1,\n\t\t\"ratchet\" : ["
},
{
"path": "mercury_ide/data/mini-functions.json",
"chars": 191,
"preview": "{\n\t\"new\" : [ \"<<\" ],\n\t\"set\" : [ \">>\" ],\n\t\"ring\" : [ \"=\" ],\n\t\"time\" : [ \"%\" ],\n\t\"beat\" : [ \"!\" ],\n\t\"note\" : [ \"#\" ],\n\t\"am"
},
{
"path": "mercury_ide/data/scales.txt",
"chars": 703,
"preview": "0, 0 0 2 4 4 5 5 7 7 9 9 11 major;\n1, 0 0 2 3 3 5 7 7 8 8 10 10 minor;\n2, 0 0 2 3 3 5 7 7 8 8 11 11 minor_harmonic;\n3, 0"
},
{
"path": "mercury_ide/data/tonics.txt",
"chars": 623,
"preview": "ges, -6;\ng, -5;\ngis, -4;\nas, -4;\na, -3;\nais, -2;\nbes, -2;\nb, -1;\nbis, 0;\nces, -1;\nc, 0;\ncis, 1;\ndes, 1;\nd, 2;\ndis, 3;\nes"
},
{
"path": "mercury_ide/dev/fx-dev.txt",
"chars": 727,
"preview": "// set hipass 1000 1000\nset randomSeed 9482\nset tempo 135\n\nring bt hex(fca8b530)\nring chps spreadFloat(16 0.5 1)\nring ve"
},
{
"path": "mercury_ide/dev/grammar-dev.txt",
"chars": 1302,
"preview": "\n\t// ring nts random( 12 ) & \tring beat \thex() \n// set debug 1 & set tempo 98\n\n// set tempo 98 1500\n\n// set highPass"
},
{
"path": "mercury_ide/dev/kick-dev.txt",
"chars": 548,
"preview": "\nset tempo 100\n\nring lns pisano(7)\nring nps norm(lns)\nring nps subtract(1 nps)\nring lns multiply(lns 500)\n\nring att pisa"
},
{
"path": "mercury_ide/dev/midi-dev.txt",
"chars": 377,
"preview": "\nset tempo 100\n\nset debug 1\nset midi getPorts\nset scale minor_harmonic c\n\nring nts sine(32 16.774 0 24)\nring len cosine("
},
{
"path": "mercury_ide/dev/new-list-functions.txt",
"chars": 1113,
"preview": "\nset scale minor a\n\nlist cs cosine()\nprint cs\n\nlist sw saw(16 3.34 0 12)\nprint sw\n\nlist swf sawF(10)\nprint swf\n\nlist rc "
},
{
"path": "mercury_ide/dev/osc-dev-code.txt",
"chars": 1071,
"preview": "\naudio 1\n\n// default settings: 8000 9000 localhost\nset osc default\n\n// specify all: \n// set osc in-port out-port ip-addr"
},
{
"path": "mercury_ide/dev/osc-digilog.txt",
"chars": 700,
"preview": "\naudio 1\nset osc default\n\nset midiclock getports\nset midiclock 4\n// set midiclock volante\n\n// specify all: \n// set osc i"
},
{
"path": "mercury_ide/dev/osc-receive.maxpat",
"chars": 8445,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 1,\n\t\t\t\"revision\" : 3,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/dev/osc-receive.txt",
"chars": 987,
"preview": "set tempo 143\n// set lopass 500 1000\n// set osc default\n// set osc ip 127.0.0.1\nset osc ip localhost\nset osc in 4000\nset"
},
{
"path": "mercury_ide/dev/osc-receiver.maxpat",
"chars": 5604,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 8,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/dev/ring-dev-scale-map.txt",
"chars": 1118,
"preview": "\nset tempo 128\n\n// ring fib fibonacci(10)\n// ring pell pell(10)\n// ring lucas lucas(10)\n// ring tF threeFibonacci(10)\n\n/"
},
{
"path": "mercury_ide/dev/ring-dev.txt",
"chars": 7658,
"preview": "// set debug 0\n\n// possible arrays and datatypes with arbitrary spaces\nlist ar1 [0 12 3.14 56 789]\nprint ar1\nlist ar2 [1"
},
{
"path": "mercury_ide/dev/sample-dev.txt",
"chars": 368,
"preview": "\nset tempo 105\n\nring trig [1 0 0 0 0]\nring beat [1 0 0 0 0 0 0 0]\n\nnew sample harp_up time(1/4) gain(2) name(gng)\n\tset g"
},
{
"path": "mercury_ide/dev/sample-test.txt",
"chars": 1539,
"preview": "\nset tempo 152\n// set hipass 0 1000\n\nring cBt hexBeat(00ffcc92)\nring cBt hexBeat(f0f0adb5)\nring offs spreadFloat(32 0.3 "
},
{
"path": "mercury_ide/dev/solo-instruments.maxpat",
"chars": 5603,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/dev/string-dev.txt",
"chars": 1354,
"preview": "set scale minor_harmonic c\nset tempo 80\nset randomSeed 84932\n\nlist bt clave(7)\nlist nt cosine(16 5.1242 0 24)\nlist nt re"
},
{
"path": "mercury_ide/dev/synth-dev.txt",
"chars": 770,
"preview": "\nset tempo 100\n\nring notes [[0.3 1 5.5 7]]\n\n// new synth sine shape(3 2000) time(1) note(notes 2) useDetune(1)\n// new sy"
},
{
"path": "mercury_ide/dev/synth-test.txt",
"chars": 686,
"preview": "set volume 1\nset randomSeed 9123\nset scale pentatonic_minor c\n\nring bss fill(0 16 -3 16)\nring notes spread(5 0 12)\nring "
},
{
"path": "mercury_ide/dev/util-dev.txt",
"chars": 288,
"preview": "\n// utility test and development for ring methods\n\nring r [0 3 7]\nring r2 add(r 12)\n\nring r7 [0 3 7]\nring r8 subtract(r7"
},
{
"path": "mercury_ide/dev/visual-dev.txt",
"chars": 121,
"preview": "\n// set debug 0\n\n// new visual icosahedron\n// new visual icosahedron\n// new visual icosahedron\n// new visual icosahedron"
},
{
"path": "mercury_ide/external/aka.speech.mxo/Contents/Info.plist",
"chars": 1222,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "mercury_ide/external/aka.speech.mxo/Contents/PkgInfo",
"chars": 8,
"preview": "iLaX????"
},
{
"path": "mercury_ide/external/aka.speech.mxo/Contents/Resources/maxmspsdk.xcconfig",
"chars": 2571,
"preview": "// Xcode target configuration settings for the Max 6 SDK\n// Used as the basis for Xcode projects to build Max externals."
},
{
"path": "mercury_ide/external/aka.speech.mxo/Contents/_CodeSignature/CodeResources",
"chars": 2530,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "mercury_ide/external/clockwarp.gendsp",
"chars": 6347,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/external/cv.jit.resize.mxo/Contents/Info.plist",
"chars": 1076,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "mercury_ide/external/cv.jit.resize.mxo/Contents/PkgInfo",
"chars": 8,
"preview": "iLaXmax2"
},
{
"path": "mercury_ide/external/dyn-range-comp.genexpr",
"chars": 2918,
"preview": "//==============================================================================\n// dyn-range-comp.genexpr\n// Dynamic Ra"
},
{
"path": "mercury_ide/external/hidecursor.maxpat",
"chars": 10573,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/external/moogLadderFilter.genexpr",
"chars": 2438,
"preview": "/*\nThis GenExpr file is a port of the CSOUND Moogladder opcode, by Victor Lazzarini.\nHis original description follows be"
},
{
"path": "mercury_ide/external/shortkeys.json",
"chars": 626,
"preview": "{\n\t\"execute\" : [ \"alt-return\", 2044 ],\n\t\"comment\" : [ \"alt-/\", 247 ],\n\t\"silence\" : [ \"alt-.\", 8805 ],\n\t\"disable-editor\" "
},
{
"path": "mercury_ide/external/th.clockwarp~.maxpat",
"chars": 72077,
"preview": "{\n \"patcher\": {\n \"fileversion\": 1,\n \"appversion\": {\n \"major\": 9,\n \"minor\": 1,\n "
},
{
"path": "mercury_ide/external/th.comp~.maxpat",
"chars": 9138,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/external/th.gl.editor.js",
"chars": 25485,
"preview": "//===================================================================\n// th.gl.editor.js\n// A responsive texteditor for "
},
{
"path": "mercury_ide/external/th.gl.texteditor.maxpat",
"chars": 112877,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 4,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/external/th.yafr~.maxpat",
"chars": 144553,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 1,\n\t\t\t\"revision\" : 3,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/fonts/IBM_Plex_Mono/OFL.txt",
"chars": 4454,
"preview": "Copyright © 2017 IBM Corp. with Reserved Font Name \"Plex\"\r\n\r\nThis Font Software is licensed under the SIL Open Font Lice"
},
{
"path": "mercury_ide/fonts/Roboto_Mono/LICENSE.txt",
"chars": 11560,
"preview": "\r\n Apache License\r\n Version 2.0, January 2004\r\n "
},
{
"path": "mercury_ide/fonts/Source_Code_Pro/OFL.txt",
"chars": 4621,
"preview": "Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Re"
},
{
"path": "mercury_ide/fonts/Space_Mono/OFL.txt",
"chars": 4444,
"preview": "Copyright 2016 Google Inc. All Rights Reserved.\r\n\r\nThis Font Software is licensed under the SIL Open Font License, Versi"
},
{
"path": "mercury_ide/fonts/Ubuntu_Mono/UFL.txt",
"chars": 4769,
"preview": "-------------------------------\r\nUBUNTU FONT LICENCE Version 1.0\r\n-------------------------------\r\n\r\nPREAMBLE\r\nThis lice"
},
{
"path": "mercury_ide/fonts/VT323/OFL.txt",
"chars": 4461,
"preview": "Copyright 2011, The VT323 Project Authors (peter.hull@oikoi.com)\r\n\r\nThis Font Software is licensed under the SIL Open Fo"
},
{
"path": "mercury_ide/icon/README.md",
"chars": 187,
"preview": "# Mercury Icon\n\nOriginal image file from NASA:\n\n- https://images.nasa.gov/details-PIA15160\n\nFont is IBM Plex Mono from G"
},
{
"path": "mercury_ide/media/README.md",
"chars": 38497,
"preview": "# Sounds in Mercury\n\n- [Credits](#credits)\n- [One-shots](#one-shots)\n\t- [Drums](#drums)\n\t- [Percussion](#percussion)\n\t\t-"
},
{
"path": "mercury_ide/mercury_ide.maxproj",
"chars": 4184,
"preview": "{\n \"name\": \"mercury_ide\",\n \"version\": 1,\n \"creationdate\": 3615958543,\n \"modificationdate\": 3854436652,\n \""
},
{
"path": "mercury_ide/patchers/_mercury_main.maxpat",
"chars": 1258936,
"preview": "{\n \"patcher\": {\n \"fileversion\": 1,\n \"appversion\": {\n \"major\": 9,\n \"minor\": 1,\n "
},
{
"path": "mercury_ide/patchers/_mercury_visuals.maxpat",
"chars": 342695,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/analyseDisplay.maxpat",
"chars": 78814,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 8,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/argGetList.maxpat",
"chars": 5467,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 3,\n\t\t\t\"revision\" : 0,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/argListLookup.maxpat",
"chars": 10845,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/calcExpr.maxpat",
"chars": 5285,
"preview": "{\n \"patcher\": {\n \"fileversion\": 1,\n \"appversion\": {\n \"major\": 9,\n \"minor\": 1,\n "
},
{
"path": "mercury_ide/patchers/consoleLog.maxpat",
"chars": 3564,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 8,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/divToMs.maxpat",
"chars": 5249,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/drywet~.maxpat",
"chars": 7935,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 9,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 8,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/emptyScene.maxpat",
"chars": 5519,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 1,\n\t\t\t\"revision\" : 3,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/envelopeGen.maxpat",
"chars": 25995,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/eventSequencer.maxpat",
"chars": 48773,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 6,\n\t\t\t\"revision\" : 5,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fftCatch~.maxpat",
"chars": 6598,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 3,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fftCross~.maxpat",
"chars": 5515,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 4,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fftFreeze~.maxpat",
"chars": 17128,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxChorus.maxpat",
"chars": 35049,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxComb.maxpat",
"chars": 35574,
"preview": "{\n \"patcher\": {\n \"fileversion\": 1,\n \"appversion\": {\n \"major\": 9,\n \"minor\": 1,\n "
},
{
"path": "mercury_ide/patchers/fxCompress.maxpat",
"chars": 6656,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxDegrade.maxpat",
"chars": 14368,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxDelay.maxpat",
"chars": 56400,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 6,\n\t\t\t\"revision\" : 0,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxDrive.maxpat",
"chars": 12033,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 9,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 8,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxEnvelopeFilter.maxpat",
"chars": 8529,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 2,\n\t\t\t\"revision\" : 2,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxFilter.maxpat",
"chars": 38889,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxFreeze.maxpat",
"chars": 20078,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 2,\n\t\t\t\"revision\" : 2,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxFuzz.maxpat",
"chars": 37819,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 9,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 8,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxKink.maxpat",
"chars": 19296,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxLFO.maxpat",
"chars": 45511,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxLadderFilter.maxpat",
"chars": 7481,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxLoopDelay.maxpat",
"chars": 19318,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxMorph.maxpat",
"chars": 15477,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 4,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxPitchShift.maxpat",
"chars": 35655,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxRetune.maxpat",
"chars": 11072,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxReverb.maxpat",
"chars": 25899,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxRing.maxpat",
"chars": 34606,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 9,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 8,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxSquash.maxpat",
"chars": 18718,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxStutter.maxpat",
"chars": 17752,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxTriggerFilter.maxpat",
"chars": 27964,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxVibrato.maxpat",
"chars": 17271,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxVocoder.maxpat",
"chars": 20678,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxVocoderBand.maxpat",
"chars": 16395,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/fxVowel.maxpat",
"chars": 34445,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/getVariables.maxpat",
"chars": 26113,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/gtep.maxpat",
"chars": 7264,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 8,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/keyPressed.maxpat",
"chars": 11018,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 1,\n\t\t\t\"revision\" : 0,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/mcy.buffers~.maxpat",
"chars": 13405,
"preview": "{\n \"patcher\": {\n \"fileversion\": 1,\n \"appversion\": {\n \"major\": 9,\n \"minor\": 1,\n "
},
{
"path": "mercury_ide/patchers/midiToOSC.maxpat",
"chars": 9160,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/modulatorObject~.maxpat",
"chars": 74017,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/newInstance.maxpat",
"chars": 9916,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 6,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/noteToMidi.maxpat",
"chars": 4525,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/planetaryMotion.maxpat",
"chars": 93377,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 1,\n\t\t\t\"revision\" : 8,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/probList.maxpat",
"chars": 6210,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/probTrig.maxpat",
"chars": 2905,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 0,\n\t\t\t\"revision\" : 2,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/setupAudio.maxpat",
"chars": 381630,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/setupEditor.maxpat",
"chars": 138793,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 5,\n\t\t\t\"revision\" : 7,\n\t\t\t\"archi"
},
{
"path": "mercury_ide/patchers/setupShortkeys.maxpat",
"chars": 76277,
"preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 8,\n\t\t\t\"minor\" : 2,\n\t\t\t\"revision\" : 0,\n\t\t\t\"archi"
}
]
// ... and 39 more files (download for full content)
About this extraction
This page contains the full source code of the tmhglnd/mercury GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 239 files (7.2 MB), approximately 1.9M tokens, and a symbol index with 276 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.