{"id":13433431,"url":"https://github.com/FedericoDiMarzo/GravityDrumMachine","last_synced_at":"2025-03-17T12:31:49.094Z","repository":{"id":73306424,"uuid":"237652998","full_name":"FedericoDiMarzo/GravityDrumMachine","owner":"FedericoDiMarzo","description":"A web application developed in Javascript,  that implements a polyrhythmic drum machine, based on the Web Audio Api. It provides a physical based sound generation system that lets the user play with gravity, to create unusual percussive and melodic patterns.","archived":false,"fork":false,"pushed_at":"2020-11-09T11:51:11.000Z","size":1985,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-28T16:12:14.550Z","etag":null,"topics":["audio","audio-game","drum-machine","gravity","physics-2d","polyrhythms","synth","synthesizer","web-audio","web-audio-api"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FedericoDiMarzo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-02-01T17:43:42.000Z","updated_at":"2023-12-14T08:04:42.000Z","dependencies_parsed_at":"2024-01-21T03:25:42.004Z","dependency_job_id":null,"html_url":"https://github.com/FedericoDiMarzo/GravityDrumMachine","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedericoDiMarzo%2FGravityDrumMachine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedericoDiMarzo%2FGravityDrumMachine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedericoDiMarzo%2FGravityDrumMachine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedericoDiMarzo%2FGravityDrumMachine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FedericoDiMarzo","download_url":"https://codeload.github.com/FedericoDiMarzo/GravityDrumMachine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244033834,"owners_count":20387012,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio","audio-game","drum-machine","gravity","physics-2d","polyrhythms","synth","synthesizer","web-audio","web-audio-api"],"created_at":"2024-07-31T02:01:25.705Z","updated_at":"2025-03-17T12:31:47.571Z","avatar_url":"https://github.com/FedericoDiMarzo.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Gravity Drum Machine\n\n*Jacopo Piccirillo*\n\n*Federico Di Marzo*\n\n*February 2020*\n\nhttps://youtu.be/1Tvgzuj7Sq0\n\nhttps://federicodimarzo.github.io/GravityDrumMachine/\n\nhttps://github.com/FedericoDiMarzo/GravityDrumMachine/tree/master/Presets\n\n\n## Introduction\nLinearity is not the most enjoyed parameterization when it comes to perception of sound. *Complex* is -*somehow*- a more enjoyed and natural behavior. \n\nEven if modern drum-machines offer many different and inspiring tools devoted to rhythm, they seldom allow to explore sound generation in a *chaotic* \nfashion.\nTo create interesting and everchanging percussive textures, we thought it could be particularly useful to superimpose different chaotic rhythmic elements \nto simpler patterns.\n\nThe concept of unpredictability has already been covered from hardware and software drum-machine manufactures in terms of conditional step triggering or \ngeometrical pseudo randomization.\nAnyway, we wandered more and thought about: *what if we could develop a system that automates sound morphing and generation according to the laws of nature?* \n\nFrom these main ideas the gravity drum machine concept was born.\n\n   \u003cimg src = \"resources/images/galaxy.jpg\" width = \"600\" \u003e\n\n* ### Main features\n \n    *Gravity field*\n    \n   * The basic concept of this software is to simulate a universe in which motion is determined by a **gravity field**. The universe has a signature \n   associated (*e.g. 3/4:5/8*) which can be determined by the user. Every step in the signature is associated to a different system which starts its motion \n   when tempo triggers the associated step. In every system there is a black ball which generates a gravity field and, when not muted, gets triggered \n   emitting a sound every time the simulation starts. User can put other (*randomly coloured*) balls inside which will move according to the laws of gravitational \n   motion and sound when they'll collide with the black ball. \n   \n   *Physical motion*\n       \n    * Every kind of (*complex esponential, solution of a second order differential equation, ..*) physical motion can be simulated with this software, from circular motion to damped oscillation, as better specified later.\n    \n   *Polyrhythms*\n    \n   * The software can simulate more than a galaxy at the same time, each associated with his own time signature. This will result in the capability of \n   generating a universe sounding as every kind of **polyrhythm**, whith the possibility of the superposition of **linear** and **non-linear** behaviours with \n   the addition of moving balls by the user.\n   \n    *Positional panning*\n     \n    * Sound emitted by moving objects are **panned as their position** in the simulation, resulting in a dynamic stereo pan effect, improving audio/video \n    perception.\n    \n     *Motion modulation*\n     \n    * Behaviours can be automated following **gravity-motion equations patterns**, resulting in complex exponential behaviours. There will be damped \n    behaviours in colliding balls, which will go subject also to a friction force. Non-colliding balls will not be subject to friction. \n    \n     *Double view*\n     \n    * There are two views in this drum machine, the first called **Galaxy view** which has a standard -*sequencer fashioned*- architecture. Inside the \n    **Galaxy view** there will be one or more systems (*e.g. three for a 3/4 galaxy, one for every step of the sequence*), and all of them will be \n    accessible via the **System view**. Inside the **System view** gravity motion happens. Systems get triggered, starting and ending their sound and \n    motion, by the **metronome**.\n    \n    *Dynamic forces*\n         \n     * Amplitude of gravitational and frictional forces can be changed (*via force constants scaling*), resulting in a **dynamic** physical model.\n \n* ### Limits and future features\n   Along with the physical impossibility of subdividing time under certain orders, the \"**tone.js**\" library we used does not support infinitely dense time \n   subdivisions. Supporting polyrhythms leads to frequencies of the order from *pow(2,n)* to *pow(n,n)*, n being how many prime numbers are divisors of at \n   least one denominator, which tone magnifies 127 times by the \"**tone.js**\" library object used to handle tempo. Frequencies can become very high especially \n   when metric measure subdivisions (*i.e. denominator of metric signatures*) **are (or are divided by) lots of different prime numbers**, leading to very \n   small time subdivisions and possible errors.  \n   \n   *Hardware limits warning*: if one implements particularly complex sound patterns using this software having a not very powerful hardware on his machine, application can lag, especially if Operating System implements **GPU audio processing**. If so, try reducing size of the window in which application is loaded to avoid lagging. **If one has powerful hardware this is not an issue**.\n \n   We are currently focused on doppler-effect features, enhancement of modulation possibilities, harmonic and melodic sound pattern generation and overall \n   interface improvement.\n  \n  *More will come*\n\n## Overview\n\n\u003cfigure\u003e\n  \u003cfigcaption\u003e--\u003eFigure 1: New project\u003c-- \u003c/figcaption\u003e\n  \u003cimg src = \"resources/images/gdm.PNG\" width = \"600\" \u003e\n\u003c/figure\u003e\n\nWhen loaded the software will display a black screen in which the universe will be composed of a single **galaxy** associated with a 1/4 signature. Therefore \nthe newborn universe will be started containing one single galaxy which will itself contain one single system, this represented by the single green-margined \ncentral square shown in the center of Figure 1. We will call in this text what is shown in Figure 1 and 2 \"***Galaxy view***\" to distinguish it from the \n\"***System view***\", which usage will become clear later in this overview.\n\nOn the top right corner we find an icon that will show a menu when clicked, giving the option of **saving** the current project or **loading** a previously \nsaved one, along with the option of **creating** or destroying **sequences** (*i.e. **galaxies***). \n\nUnder that icon we find the rhythmic metric associated with the newborn **galaxy**, which can be modified by clicking on it: a popup will appear in which the \nmetric can be reset. By doing that new systems will be spawned (or canceled if the numerator of the metric gets decreased), all of them composed in the \nbeginning just by a central, gravity attracting, black ball.\n\n\u003cfigure\u003e\n  \u003cfigcaption\u003e--\u003eFigure 2: 3/4 galaxy\u003c-- \u003c/figcaption\u003e\n  \u003cimg src = \"resources/images/3_4.PNG\" width = \"600\" \u003e\n\u003c/figure\u003e\n\nMoving towards the bottom right corner we find **play** and **stop** buttons, which can be toggled also by pressing the **spacebar**. **BPMs** are located \nleft of them; a pop-up will spawn when clicking  giving the possibility of changing them. On the bottom left we find the **galaxy name**, which can be reset \nby clicking on it and typing the desired name in the pop-up that will appear.\n\nOn the top-left we find just the name of the software and under that -*i.e. center left*- a thin **bar**. Usage of aforementioned **bar** will be clear when \nhow to generate **polyrhythms** will be discussed.\n\n\n\nWe have so covered the **galaxy view** and move now forward towards the **system view**.\n\n\u003cfigure\u003e\n  \u003cfigcaption\u003e--\u003eFigure 3: System view\u003c-- \u003c/figcaption\u003e\n  \u003cimg src = \"resources/images/empty.PNG\" width = \"600\" \u003e\n\u003c/figure\u003e\n\nClicking on one of the systems user will be projected into the **system view** which will appear as a blank space populated initially only by the central gravity ball.\n\nWe here find the same already described features of the **galaxy view**, with no thin bar displayed and with the software name substituted by a left-pointing \narrow, which gives the possibility of going back to galaxy view when clicked on.\n\nThe central ball will emit a sound when the **metronome** triggers its system. Central balls can also be muted: when in pause, clicking on the central ball \nwill cause it to go empty, representing the fact that the ball is now muted (but still attracting other balls). Clicking on it again will unmute it. \n\n\u003cfigure\u003e\n  \u003cfigcaption\u003e--\u003eFigure 5: Muted gravity ball\u003c-- \u003c/figcaption\u003e\n  \u003cimg src = \"resources/images/muted.PNG\" width = \"600\" \u003e\n\u003c/figure\u003e\n\nAlways \nwhen in pause, clicking everywhere in the blank space will generate other balls, that will be attracted by the central ball, emitting a sound when colliding. \nClicking on them again will remove them, clicking and holding will give the possibility of dragging them around.\n\nRight clicking on a ball generates a pop-up menu which gives, among the other options, possibilities of choosing from a wide range of possible motions,\n choosing between a sampler and a monosynth and choosing triggered note. This menu will be better explained later in \nthe **Sound Module** section.\n\n\u003cfigure\u003e\n  \u003cfigcaption\u003e--\u003eFigure 4: Adding balls\u003c-- \u003c/figcaption\u003e\n  \u003cimg src = \"resources/images/niceballs.PNG\" width = \"600\" \u003e\n\u003c/figure\u003e\n\nYou are now **Up\u0026Going**! Open your software, set your rhythmic signature, place balls inside the system and hit play to watch them sound as systems evolve, or enjoy a more broad view stepping in the galaxy. Have fun! \n\n## Advanced usage\n\n\u003cfigure\u003e\n  \u003cfigcaption\u003e--\u003eFigure 6: Menu\u003c-- \u003c/figcaption\u003e\n  \u003cimg src = \"resources/images/menu.PNG\" width = \"600\" \u003e\n\u003c/figure\u003e\n\nWe until now have understood how to initiate and make a single galaxy sound. Now we will focus on a deeper usage.\n\n### Multiple galaxies and polyrhythms\nWe already talked about the possibility of simulating more than one galaxy in order to obtain a more-complex, polyrhythmical behaviour. To do so, all we have \nto do is to add other galaxies, set all of them as we already discussed previously for a single one and hit play.\n\n\u003cfigure\u003e\n  \u003cfigcaption\u003e--\u003eFigure 7: 3/4 galaxy in a 3/4:5/8 universe\u003c-- \u003c/figcaption\u003e\n  \u003cimg src = \"resources/images/3_4_2.PNG\" width = \"600\" \u003e\n\u003c/figure\u003e\n\nTo create a new galaxy we have to click on \"***New Sequence***\" from the menu (Fig.6). This will generate an entire new galaxy, superimposed  with the previous\n one. We will see the white bar in the middle left now having the possibility of moving through 2 different states, indexing the two currently existing \n galaxies. Every time we want to create a galaxy we have to iterate the process. States will increase by one every time a new galaxy gets created in the universe and decrease by one when destroyed. *Currently there is no limit for the number of states*. \n\nTo remove a galaxy scroll to it and click \"***Delete Sequence***\" from the menu.\n\n\u003cfigure\u003e\n  \u003cfigcaption\u003e--\u003eFigure 8: 5/8 galaxy in a 3/4:5/8 universe\u003c-- \u003c/figcaption\u003e\n  \u003cimg src = \"resources/images/5_8.PNG\" width = \"600\" \u003e\n\u003c/figure\u003e\n\nHitting up and down arrow will scroll through the index, currispondent galaxy showing on the screen. \n\n### Sound FX settings\n\nSelecting \"**Sound FX settings**\" from the **main menu** will spawn a pop-up containing three sliders: \n\n* *Delay time*\n\n* *Delay feedback*\n\n* *Reverb size*\n\nThese will be parameters of a shared **FX Channel Bus** to which sound signal can be sent from every **Sound module**, as described in next section. \nThe *Fx Channel* is connected to **master channel** and user will perceive the superposition of the two signals. The send **gain** \nwill be controlled via reverb and delay *send sliders* from the **Sound Module**'s setting menu.  \n\n### Sound modules and their menu\nEither attracting and moving balls contain a **sound module**. This will contain a sound source along with the possibilities of \nchanging some of its parameters and automating them over time. Attack of sources will be triggered by **collisions** or **metronome**.\n\n**Right clicking** on a ball will pop-up a menu which will give the possibility of changing ball's size\n(*we remind here that an increased size will not affect acceleration of the object*), triggered note, audio module contained \n(sample or monosynth right now). Along with the size slider there will be another two, one regulating delay send and the other reverb send. \n\nFinally we find two drop-down menus: one for selecting desired trajectory and one for choosing between different sources.\n\n* #### Every audio module will have some other options inside this menu:\n\n   *Sampler*\n    \n   * Selectable sample via drop-down menu.\n   \n   * Release slider.\n   \n   * Randomize checkbox: selecting will trigger every time a random note.\n   \n   * Dynamic pitch checkbox: selecting will shift pitch according to distance from the gravity ball.\n   \n   *Mono Synth*\n   \n   * Amp attack slider.\n   \n   * Amp release slider.\n   \n   * Filter attack slider.\n   \n   * Filter release slider.\n   \n   * Filter cutoff slider.\n   \n   * Filter envelope amount slider.\n   \n   * Detune slider.\n   \n   * Dynamic filter checkbox: selecting will change the cutoff frequency according to distance from the gravity ball.\n   \n### Copy-paste\nHitting left and right arrow in the galaxy view will scroll through galaxy's systems, the selected one being surrounded by a green margin. Pressing \n**cmd(ctrl) + c** will copy the selected system, which can be pasted in another one by moving over it and pressing **cmd(ctrl) + v**.\n\n### Saving and loading universes\nIt is possible to save the configuration obtained for future usages, by clicking on \"***Save Universe***\" from the menu. Doing so will spawn a pop-up containing \na link which will download a \"***.galaxy***\" object. Name of the object will be the same as the universe.\n\nTo reload the configuration, it is sufficient to click on \"***Load Universe***\" from the menu and load the object back from where it was stored through the \npop-up that will appear. \n\n### Keyboard shortcuts\n\n   - Press \"***u***\" to switch from **system** to **galaxy view** and vice-versa.\n   - Press \"***spacebar***\" to toggle play and stop.\n   - Press \"***cmd(ctrl) + c***\" to copy a system and \"***cmd(ctrl) + v***\" to paste it.\n   - Select **System** with **left** and **right** arrow.\n   - Select **Galaxy** with **up** and **down** arrow.\n   \n### Motion parameters\n\nSelecting \"**Motion Parameters**\" from **main menu** will make appear a pop-up menu containing two sliders, giving the possibility to modify **gravity** and \n**friction**'s intensity.\n\n\"**G constant**\" will modify **gravity**, while \"**friction**\" will modify **friction**.\n   \n## Physics' insights\n\nEverything here works under rigorous physical laws. For a deeper understanding of the automation possibility of this software it is worth having a look at its \nphysics. We will enumerate the different possible types of motion and what kind of automation one can get from it.\n\nAutomations can be taken in this software as the temporal evolution of coordinates and velocities of the objects. The graph **coordinate(velocity)-time**\n will correspond to the **envelope** obtained.\n\n* #### Colliding Motions\n   This motion will be an *harmonic damped oscillator*. An exact **harmonic damped envelope** can be found in the time-evolution of the radius of a colliding \n   ball.\n   \n   We currently implemented three options for collisions:\n   \n   *Free fall*\n   \n   *  Ball will have zero initial velocity and simply fall towards the gravity ball.\n   \n   *Collision hard (coll-hard in sound module menu)*\n   \n   *  Energy will be above zero in this case and ball will be shooted with high velocity pointing to gravity ball, colliding only one time and then moving away without falling again (since Energy \u003e 0).\n   \n   *Collision soft (coll-soft in sound module menu)*\n   \n   *  Energy will be below amount needed to orbit, so ball will collide more than one time. Initial velocity will have a random-generated angle between (-PI, PI) with respect to radius direction, since Energy balance allows us to be sure that shooting in every direction will make the ball collide, if it has enough time to do that (*if tempo is too fast it could happen that system resets its motion before ball actually falls*). This will result in lots of possibilities of trajectories and peculiar automations.\n   \n**All aforementioned trajectories will resent of friction and result in a damped oscillation behaviour; belove non-colliding orbits are described, which will not resent of friction**.\n   \n* #### Circular motion \n   Both x and y coordinates follow a periodic sine-cosine behaviour. From x and y coordinates we can get a **sine wave** behaviour (**y**) and a \n   **cosine wave** one (**x**), so the second one having PI/2 phase shift from the first one. Frequency will be the frequency of the motion.\n   \n   *More*, from the angle we can get a linear behaviour, wich will result in a **sawtooth-wave modulation**. Frequency of the wave will be proportional \n   directly to velocity and inversely to radius of the ball, slope inverting according to clockwise/conuter-clockwise motion. \n   \n* #### Elliptical motion\n   Elliptical motion can be decomposed over the superposition of two perpendicular harmonic motions at different frequencies. This means that in general \n   one will get linear combinations of two different sine-fashioned waves in the time evolution of x and y, and so an automatization following a pattern of \n   the sum (or difference) of **two sine oscillators with a different gain**.\n   \n  Radius and angle will follow more complex (and worth exploring) **periodic** patterns. Same can be said about the slope of the angular evolution as in the \n  circular case.\n  \n* #### Hyperbolic motion\n   The ball will describe a parabola with one focus situated where the gravity ball is. Radius will be equivalent to the distance of the ball by the focus. \n   From this case  can be computed a non.linear **hyperbolic** behaviour.\n   \n* #### Parabolic motion\n   In this case balls follow the pattern of a parabola in which the radius represents the distance from its focus. From this case can be computed a non-linear \n   ***pow(x,2)*** behaviour.\n   \n**Excepting collision hard, initial velocities are computed with inverse proportionality with respect to the radius, so velocity will be higher when near and slower when far. The opposite stands for collision hard**.\n\n*In future we will implement the possibility for the user to decide velocity magnitude himself*.\n   \n##### Dynamic forces notes:\n\nInitial velocity when selecting peculiar trajectory will be computed at the time one clicks on the desired one from the drop-down menu.\nWhen scaling through the menu  gravity and friction it is suggestable first to scale forces and then select desired trajectory. Doing otherwise will compute\nthe trajectory using old data which will result in an unpredictable motion. \n   \n##### Selectable trajectories notes:\n\nEvery aforementioned trajectory can be selected fom the drop-down trajectory menu. These will all have a random component, either in the angle or in\ninitial velocity or both. We used a trick in order not to have collisions from every point in which a ball can be dropped: under certain radiuses elliptic\norbit will decade in a circular one. This because motion's computations are made considering every ball as a single point in space. When placing a ball too near the gravity one,\nelliptic orbits will be computed going through the portion of space occupied by the gravity ball and this will result in a collision.\n\nThis is not entirely resolvable if not by widening more the minor axis and compriming more the major one of the ellipsis, so in the end selecting elliptical motion\nbeing too close to the gravity center will make the trajectory collapse in a circular one, in order to avoid collisions. \n\n*The possibility of collision when not desired is minimum but there is a tight area in which this could still happen, under very unfortunate conditions.\nIf so, try reducing ball's size in order to avoid it.*\n   \n## Code architecture\nOur **Gravity Drum Machine** has been developed as a dynamic web application, based on the *Web Audio API*.\nThe application is delivered to the user from the server as an index html page, connected to many styles and javascript modules.\n\nIn this section the code architecture is depicted broadly, to introduce the main interrelated components that form the final product.\n\n* #### MVC structure\nScalability was one of our main concern during development; we aimed to gradually add new components and options to our drum machine, avoiding unnecessary complexity in the code structure.\n\nTo pursue this intention, we arranged our code in a MVC fashion, exploiting many useful tools and proper schemes of web apps.\n\nOur **view** is defined in many *html* pages, that can be composed in a modular way, allowing us to create a single isolated file for every component of the product.   \nThe graphical style has been enhanced with css style files.\n\nThe **model** comprises many javascript modules, each one containing information about physical properties or audio parameters.\n\nAll the logic in the application, that connects the user interaction in the view, with model updating, is delegated to two *controller* modules.\nTo allow an automatic update of model properties, most html input tags have an *auto-update* class, used inside the controller to send input's values to a model object, that updates independently.\nThis design choice offers a clean and easy way to add functionalities to the application without worrying about updating the controller's code every time.  \n\n* #### Graphical rendering\nThe drum machine was designed to be fun to interact with and graphically appealing; to support these principles, we needed as much freedom as a web environment could offer.\nWe used an **html canvas** component to draw our evolving universes, all the rendering process delegated to the **GraphicRenderer** class.\n\nThis class takes all the information needed for showing the evolution of the universe directly from the model. The rendering is completely independent from the rate at which the model is updated.\n \nThe standard **window.requestAnimationFrame** function is used to exploit GPU acceleration, allowing for smooth animations even on high CPU load.   \n\n* #### Physical modeling\nOur project started from a physical modeling of **gravity motion**, to which we added the possibility of **frictional forces**.\n\nWe hand-coded all the logic behind the simulation, without using external libraries, because we felt the need to design our model over our very specific needs, allowing for a **better integration** and **performance optimization**.  \n\n* #### Step sequencing\nAside from the *GraphicRenderer*, many other components needed some mechanism to handle regular time updates.\nTo accomplish the task, we developed the **Metronome** class, that internally uses **Tone.Transport** (*a Tone.js component*) with a custom **event handling system**.\n \nEvery drum-machine is based on the concept of rhythmic **step triggering**; a *clock system* designed in order to synchronize sequencing correctly.\nFor our *Gravity Drum Machine* we took advantage of the clever design of the *Tone.Transport*  utility to implement a polyrhythmic step sequencer.\n\n*Tone.Transport* contains an event handling system based on a single *time signature* and *bpm*. \nIn order to allow this component to fire step events, considering the possible presence of polyrhythms, our *Metronome* class performs a computation of a common *time signature* in a recursive fashion:\n\nN3/D3 = mcm(N1xK1, N2xK2)/mcm(N1, N2)\n\nK1 = mcm(N1, N2) / D1\n\nK2 = mcm(N1, N2) / D2\n\nwhere N1/D1 and N2/D2 are two different time divisions, N3/D3 is the new subdivision to be compared to the next one.\n\nThe resulting quarter note (*ie. \"4n\" in Tone.js alphabet*), becomes the **tatum** of the step sequencer.\nFor every independent sequence than, the *Metronome* calculate a multiplier *Mi*, that indicates the number of *tatum* needed to continue to the next step.\n\nMi = D / Di\n\n* #### State update\nThe **state evolution** of the model, is performed through the class **GridStateUpdater**. \nThe metronome fires a *state update* event every *5ms*, calling a method inside *GridStateUpdater*, that updates the model according to the physical simulation.\n\nBefore every cycle, collisions checks between orbiting balls and the gravity center are performed, triggering a ball's *sound module* in case of impact.\n\n* #### Saving and loading\nThe application offers the possibility to *save* the current universe's configuration locally in a file with a *.galaxy* extension. \nThese files can be *loaded* later, allowing the users to recall a previous state for further editing, or just to enjoy again their complex creations.\n\nAll the process is handled by the **Screenshot** module. \nEvery model's class, has a method to perform a *deep copy* of the object, used by the *Screenshot* module to create a JSON file, that can be downloaded by the user.  \nThis file, is used in the loading phase, to reconstruct all the objects that compose the model.\n\nThe *Screenshot* module is also used to perform a **copy/paste** operation between *systems*.\n   \n* #### Sound modules\nWe chose to use **Tone.js** to develop all the audio features of our application.\nIn order to adapt the library to our codebase, we designed the interface **SoundModule**.\nThrough this interface, we handled the problem of maintaining all the references between the connections of all *audio nodes*.\n\nEvery *SoundModule* is associated with a ball and it's directly connected to the *master output*.\nIn addiction, each of them is also connected with an **fx-bus** that contains a *delay* and a *reverb* module through two gain nodes (acting as a send gain).\n  \n\u003cfigure\u003e\n  \u003cimg src = \"resources/images/SoundM.png\"  \u003e\n  \u003cfigcaption\u003e--\u003eFigure 9: Audio flux scheme\u003c-- \u003c/figcaption\u003e\n\u003c/figure\u003e\n\n\n## Authors' notes\n\nThis project started as an examination and ended up in something we will further develop and expand; believing its potential much bigger than the amount this first version is exploiting, and being a perfect playground for sound/gravity-motion experiments. \n\n*Jacopo Piccirillo*\n\n*Federico Di Marzo*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FFedericoDiMarzo%2FGravityDrumMachine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FFedericoDiMarzo%2FGravityDrumMachine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FFedericoDiMarzo%2FGravityDrumMachine/lists"}