Git Product home page Git Product logo

bschaffl's Introduction

B.Schaffl

Groove quantizer LV2 MIDI plugin.

B.Schaffl is a slider / shape-controlled MIDI amp & time stretch plugin to vitalize sequencer-controlled MIDI instruments and to produce shuffle / swing effects.

Key features:

  • MIDI velocity amplification and timing manipulation plugin
  • Swing and shuffle rhythms
  • Pre-generator dynamics
  • Tempo rubato
  • Pattern (sliders) or shape-controlled
  • MIDI filters
  • Smart quantization
  • Group / link individual instances of B.Schaffl
  • Free and open source

screenshot

Installation

a) Install the bschaffl package for your system

Note: This will NOT necessarily install the latest version of B.Schaffl. The version provided depends on the packagers.

b) Use the latest provided binaries

Unpack the provided bschaffl-*.zip or bschaffl-*.tar.xz from the latest release and copy the BSchaffl.lv2 folder to your lv2 directory (depending on your system settings, ~/.lv2/, /usr/lib/lv2/, /usr/local/lib/lv2/, or ...).

c) Build your own binaries in the following three steps.

Step 1: Download the latest published version of B.Schaffl. Or clone or download the master of this repository.

Step 2: Install pkg-config and the development packages for x11, cairo, and lv2 if not done yet. If you don't have already got the build tools (compilers, make, libraries) then install them too.

On Debian-based systems you may run:

sudo apt-get install build-essential
sudo apt-get install pkg-config libx11-dev libcairo2-dev lv2-dev

On Arch-based systems you may run:

sudo pacman -S base-devel
sudo pacman -S pkg-config libx11 cairo lv2

Step 3: Building and installing into the default lv2 directory (/usr/local/lib/lv2/) is easy using make and make install. Simply call:

make
sudo make install

Optional: Standard make and make install parameters are supported. Alternatively, you may build a debugging version using make CPPFLAGS+=-g. For installation into an alternative directory (e.g., /usr/lib/lv2/), change the variable PREFIX while installing: sudo make install PREFIX=/usr. If you want to freely choose the install target directory, change the variable LV2DIR (e.g., make install LV2DIR=~/.lv2) or even define DESTDIR.

Optional: Further supported parameters include LANGUAGE (usually two letters code) to change the GUI language (see customize).

Running

After the installation Ardour, Carla, and any other LV2 host should automatically detect B.Schaffl.

If jalv is installed, you can also call it using one of the supported jalv flavours (jalv.gtk, jalv.gtk3, jalv.qt4, jalv.qt5), like

jalv.gtk https://www.jahnichen.de/plugins/lv2/BSchaffl

to run it (pseudo) stand-alone and connect it to the JACK system.

Note: Jack transport is required to get information about beat / position in the beat(s) or bar(s) mode!

Usage

B.Schaffl is a MIDI converting plugin. It needs a MIDI input and a MIDI output. Thus, it must be placed before an instrument (synth or sampler).

The graphical user interface is divided into thee parts. In the top right you can find the core of the plugin, the sequence editor. The sequence editor contains a visualization of the full sequence from MIDI input (IN), over controls (or a shape) to change the step amplification (AMP) and markers to stretch or shrink the step size (STR) to MIDI output (OUT).

In the bottom right are controllers to directly effect the MIDI editing (sequence size, nr of steps, amp swing, amp randomness, amp process, step swing, step swing randomness, step swing process). The left part contains a menu for global settings (MIDI channel filter, MIDI message filter, smart quantization, latency).

Sequence editor

Amp control mode

The sequence editor supports two different modes. Select between step controlled (sliders) and shape controlled mode. The step controlled mode uses constant amp values for the whole respective step. If you want more flexibility and change the amp value during a step (e. g., for accents), you can use the shape mode.

Slider-controlled amp mode: Step amp controls

Drag (or scroll) the sliders to reduce the velocity of MIDI notes for the respective step.

Shape-controlled amp mode: Amp shape

Alternatively, draw a shape for the reduction of velocity of MIDI notes. Use tools (see toolbox) to set different types of nodes, to cut, copy or paste nodes, to undo, redo or reset changes, and to hide, show or snap to the grid.

Step stretch markers

Drag the stretch markers to manually shrink or stretch the step size.

All stretch markers are set to "auto" by default. This means that all markers are homogeneously distributed and are automatically re-positioned after changes. The markers status is changed to "manual" once a marker is dragged. You can also change the markers status by right-clicking on it. Then you can choose between "auto", "manual" and "enter". This third option allows to enter a new marker position (either as fraction of a sequence or as number of steps) or a new step length (again, either as fraction of a sequence or as number of steps). The marker is set to the new position upon clicking "Apply" and switched to the manual mode. Finally, you can also set all markers at once by pressing the "All markers" buttons in the toolbox.

Toolbox

Symbols Description
convert_to_sliders convert_to_shape Convert shape to sliders or vice versa
marker_tools Set all markers to auto or manual
node_tools Node tools (only in shape-controlled mode)
edit_tools Edit tools: cut, copy and paste (only in shape-controlled mode)
history_tools History: reset, undo and redo
grid_tools Grid: show grid or snap to grid

Sequence size

Set the size of a full sequence ranging from 1/8 to 4 second(s), beat(s), or bar(s). You need Jack transport to get position information to use beat(s) or bar(s) as base.

Number of steps

You can divide each sequence into up to 16 steps.

Amp swing

Step amplification swing. This feature can be used to either reduce velocity of MIDI notes for odd steps or for even steps. Values lower than 1 (down to 1/128) mean reduction of odd step MIDI velocity. Values higher than 1 (up to 128) mean reduction of even step MIDI velocity.

Amp randomness

Symmetrically randomizes the amplification for each MIDI note velocity. An amp randomization value of 0.0 means no randomization. An amp randomization value of 1.0 means full randomization and the resulting MIDI note velocity will be in the range between 0 and two times the unrandomized velocity.

Amp process

Applies plugin amp effects (amp sliders, amp swing, amp randomness) to the MIDI note velocity. A value of 0.0 results in unchanged MIDI note velocity. A value of 1.0 fully applies the plugin amp effects to the MIDI note velocity. Also values outside the 0.0 .. 1.0 range are allowed. A value of -1.0 inversely applies the plugin amp effects to the MIDI note velocity. And a value of 2.0 applies the double plugin amp effects to the MIDI note velocity.

Step swing

Step stretch swing. This feature can be used to compress or to stretch even and odd steps. Values lower than 1 (down to 1/3) mean compression of odd steps for the benefit of the following even step. Values higher than 1 (up to 3) mean stretching of odd steps to the disadvantage of the following even step.

Step swing randomness

Randomizes the start and end positions for each step to both directions. A step swing randomization value of 0.0 means no randomization. A step swing randomization value of 0.5 means half randomization and the step start and end positions are left or rightward-shifted in the range between 0 and the half distance to the respective neighbor step.

Step swing process

Applies plugin amp effects (amp sliders, amp swing, amp randomness) to the step stretch. A value of 0.0 results in unchanged temporal MIDI signal positions. A value of 1.0 fully applies the plugin step stretch effects to the respective MIDI signal positions.

MIDI channel filter

Select the MIDI channels to be processed by the plugin. All non-selected channels are bypassed.

MIDI message filter

Select the MIDI messages (MIDI status byte) to be processed by the plugin. All non-selected messages are bypassed.

MIDI note options

Keep note position

Keeps the note position unaffected from step stretch. Take care, this may cause overlapping notes.

Keep note duration

Keeps the note duration unaffected from step stretch. Take care, this may cause overlapping notes.

If notes overlap

B.Schaffl may temporarily produce overlapping notes if either the note position or the note duration is kept unaffected from step stretch. Overlapping MIDI notes usually end at the first MIDI NOTE_OFF. You may change this behavior to merge both notes or to split to two (ore more) discreet notes.

Note off amp

There are two options to amplify the NOTE_OFF velocity signal. Either amplification with the same value as the NOTE_ON signal or amplification with the amp value for the step/position of the NOTE_OFF signal.

Smart quantization

During live playing and even if in computer-generated sequences, MIDI signals often do not exactly fit into the host-communicated beat/bar pattern. The smart quantization algorithm synchronizes not exactly fitting MIDI input signals (e.g., notes) with the step pattern if the signal is within a user-defined range from the step start or end.

It is recommended to set the range (in steps) to the half size of the shortest expected note for the start.

MIDI input signals can be synchronized just by assignment to a step or by fitting into a step or both. Assignment means that the MIDI input signal is re-assigned to the just starting step if a step starts within the range. Fitting means that all MIDI input signals except NOTE_OFF are moved to the start of a step if the start is within the range. NOTE_OFF signals are moved to the end of a step if the end is within the range. You should combine both for quantization.

Latency

Latency is required if a marker is automatically or manually dragged to the left. The plugin itself calculates the latency by default. This value (in ms) is shown in the top right of the plugin. Alternatively, the user may manually set a fixed latency of up to 192000 frames. It is recommended to manually set this parameter to the maximally expected latency if you automate and/or change step markers, step swing, and/or step swing process during playback.

Latency-correction of time/position data (time, bar, beat) is required for the proper work of B.Schaffl. However, hosts may differently handle latency and time/position data. Some correct it by themselves (as in Ardour 6) others not (Ardour 5). Switch on latency-correction of time/position if the host doesn't correct it by itself.

๐Ÿ”— Shared data

If you use multiple instances of B.Schaffl you may be interested in sharing the plugin settings between the instances. Click on one of the four shared data fields and the respective plugin instance is linked to the shared data. The plugin instance data are copied to the shared data field if no other plugin instance is linked to this shared data field before (otherwise vise versa).

If you now click on the same shared data box in another plugin instance, both plugin instances get the same data.

Click again on the selected box to unlink the plugin instance from shared data. The plugin now shows the host-provided data.

Note: Shared data are unlinked from host automation.

Customize

You can create customized builds of B.Schaffl using the parameter LANGUAGE (e.g., make LANGUAGE=DE). To create a new language pack, copy src/Locale_EN.hpp and edit the text for the respective definitions. But do not change or delete any definition symbol!

What's new

  • Enter absolute or relative maker positions and step lengths
  • Support keys HOME, END

Acknowledgments

  • Bart Brouns for the original idea plus subsequent ideas about principle and features
  • Robin Gareus for ideas to technically solve rubato-related problems
  • Jatin Chowdhury for ideas to technically solve shared data storage

Links

bschaffl's People

Contributors

sjaehn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

bschaffl's Issues

feature request: all controls visible all the time

The plugin is not big enough to show both the help text and the controls at the same time, and if you'd make it bigger, it would be a bit overwhelming.
Especially if you keep implementing all the extra controls I keep asking for! ;)

The current solution with different categories of controls shown together with the help may be ideal for newcomers, but leads to unneeded clicking, hence a slower creative process.

I propose to have all the controls visible all the time, but have the help text pop in and out of existence, either by floating over the controls with the mouse, as x42-plugins does it, or by clicking on a button, like in the wonderful Uhhyou Plugins.

feature request: layers

You can get magnificent effects by using multiple B.Schaffl's in series.
For example one with a little regular shuffle, one with an uneven number of steps for a little polyrythmic dynamic variation and one with a 1 beat length and the middle STR slider dragged a bit left, for a pushed feel, or dragged right for a laid back feel.

It would be very handy if you could do that all in one plugin and save it all as one preset.
I'm imagining tabs like in B.Shapr and inside each tab would be a complete instance of B.Schaffl as it is now.

I've been experimenting with this for a while now, and for me this feature would also fix #10, as you can quickly and easily add true human like variation, in a controlled manner.

The amount controls from #11 would be great to have both per layer and for the whole plugin

Here is a small Ardour 6 session, that hopefully demonstrates the usefulness of multiple instances in series:

BSchafflSeries.zip
.
I don't know if a-Fluidsynth uses absolute or relative paths.
You might have to set the instrument to /path/to/BSchafflSeries/Instruments/industrializer/industrializer.sf2
This instrument has lots of different samples on different velocity layers, so nicely demonstrates the subtle dynamics.

Fitting MIDI signals to steps

Tricky part (and TODO): Incoming MIDI signals are not 100% synchronous to host time/beat information. Therefore, a MIDI signal (e.g., NOTE_ON) that should start at the beginning of a step may appear at the end of the previous step. And a MIDI signal (e.g., NOTE_OFF) that should end at the end of a step may end at start of the next step.

By now, amplification is for a whole step. If a MIDI signal dropped into an incorrect step (as described above), it will be amplified with an incorrect value.

feature request: (semi) fixed latency

Currently, B.Schaffl updates the latency as you tweak the sliders.
That way it becomes impossible for the DAW to compensate while you tweak.
You have to restart the transport for the timing to be correct, preventing you from effectively tweaking timing related sliders while other tracks are playing.

It would be great if B.Schaffl had a fixed latency, but that would mean either the latency is too high, or the pattern can only be tweaked within a certain range.

A possible compromise would be for the user to set the maximum latency, preferably in bars/beats.
Ideally there would be a snapping effect of the max latency slider, when it is close to the latency needed for the current pattern.

I would like to stress again how much fun this thing is!!! ๐Ÿ˜„
Have you had a chance to give it a good workout yet, or am I taking up all of your free time with my requests and bugs? ;)

UX issues with floating point inputs

There are a couple of UX issues with numeric input controls recently employed to implement #19.

  1. The controls don't seem to handle Home, End and arrow key events. In order to position the caret on the desired digit, one must use the mouse. The unhandled key events propagate to the main DAW window (Ardour6 in my case) and move the playhead around.

  2. Possibly locale related (I'm using Polish locale): I cannot enter a decimal comma if I accidentally erase it. Neither the period key (letter block or numeric block) nor the comma key works. This makes the comma "precious", and combined with point 1. it makes using mouse for positioning the caret unavoidable.

I'm on Linux/KDE.

Feature request: automation.

Would it be possible to automate the "main" parameters that don't affect latency, like "step process" and the amp parameters?
In Ardour, all parameters show up in the list of automateable parameters, but they don't actually change when you move them.

[x86_64-glib] build issue

Hm, head scratching moment..

=> BSchaffl-1.4.6_1: building [gnu-makefile] for x86_64...
   [host] pkg-config-0.29.2_3: found (https://alpha.de.repo.voidlinux.org/current)
   [target] libX11-devel-1.7.2_3: found (https://alpha.de.repo.voidlinux.org/current)
   [target] cairo-devel-1.16.0_2: found (https://alpha.de.repo.voidlinux.org/current)
   [target] lv2-1.18.2_1: found (https://alpha.de.repo.voidlinux.org/current)
.
.
=> BSchaffl-1.4.6_1: running do_build ...
Build BSchaffl.lv2 DSP...Build BSchaffl.lv2 GUI.../usr/bin/ld: /usr/lib64/gcc/x86_64-unknown-linux-gnu/10.2.1/../../../../lib64/Scrt1.o: in function `_start':
/builddir/glibc-2.32/csu/../sysdeps/x86_64/start.S:104: undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [makefile:116: BSchaffl.so] Error 1
make: *** Waiting for unfinished jobs....
/usr/bin/ld: /usr/lib64/gcc/x86_64-unknown-linux-gnu/10.2.1/../../../../lib64/Scrt1.o: in function `_start':
/builddir/glibc-2.32/csu/../sysdeps/x86_64/start.S:104: undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [makefile:125: BSchafflGUI.so] Error 1

Probabilities

I have a feature request for this great tool: the ability to specify a probability for each step whether the MIDI note is played or not. This would be a very easy way to create constantly changing patterns.

It could be displayed graphically with faders. Either with a second fader per step or with a switch for AMP and probability. Or in another line with a small knob.

What do you think?

feature request: linked instances

It would be great if we could link up the controls of various instances of the plugin.
That way you could, for example, tweak the swing amount of a whole song at once.

CHOWTapeModel has this, and calls it "mix groups".
It works as follows: the plugin has a "mix group" drop-down, with the choices "none, 1, 2, 3 and 4".
By default it's one "none" and no controls are linked.
When you set it to "1", the controls are linked to all other plugin instances that have it set to "1" as well.

Thank you for considering!

Unwanted midi changes.

Wow, you got that done incredibly quick!
It looks great, and seems to have all the important functionality.

Except, on my system, it doesn't work yet. :(
When I input a straight 16th note pattern, and leave all the controls at default, I get a sort of shuffle out, with lots of dropped notes.

Attached is an Ardour 6 test session.
Does that work for you?

BSchaffl_test.zip

No velocity change

After some more playing I found out I couldn't change the velocity, no matter what setting I tried.
Is that already implemented?

Feature request: level before timing.

From my experimentation, it seems the notes are first moved in time and then the plugin looks which step they fall under.
I would expect it to work the other way around, so that I can change the timing of a pattern over the course of a song, but still have the same notes accentuated.
It also makes it easier to predict what the plugin will do to your notes.

If you want to go all out, you could make it configurable, but that's not an important feature, imho.

Step shapes

@magnetophon and me discussed about a step shape option to define how to handle note velocities for notes in the middle of a step before. @magnetophon had the initial idea to take the shape feature from B.Choppr. My idea was to use the shape editor from B.Shapr. However, I now think the whole shape editor will be too much. Therefore I now prefer a given set of simple shapes to select (similar to B.Choppr).

However, there is an other problem to think about:

shapes
Part of the plugin GUI. White lines shall symbolize the course of amplification.

Fig. a) The present situation is rather simple. The step amp is applied to the whole step in the same way. It doesn't matter if the note is at the start or in the middle of a step. The amplification is constant during a step.

Fig. b and c) What if amplification should follow a (triangular) shape. Should the note in the middle of a step get the full step amp (as in Fig. b) or the note at the start of a step (Fig. c). Or shall we provide both options and let the user decide?

The same can be done with sinusoidal and trapezoid shapes.

Start of a loop misses notes

As you can hear in BSchafflSeries.ardour from #12, every time ardour loops, there are a few notes missing in the first part of each repetition.
When you play the loop for the first time, the notes are not missing.

Steps processing in Ardour 8.1 pretty much completely borked

In Ardour 8.1 (Arch Linux package) I am experiencing the following symptoms:

  1. The timing calculations seem to be very broken; the resulting groove sounds randomly garbled.
  2. The errors are highly sensitive to notes being very close to the beat but not exactly; two nearly simultaneous notes at :0000 and :0016 can end up nearly a whole :1:0000 apart.
  3. The errors are consistent between replays at the same tempo. Whether they are (proportionally) consistent between different tempos or not seems to depend in a complicated way on the latency compensation settings.
  4. Exactly how the timings are garbled also depends on the plugin's latency compensation settings.
  5. The errors are rendered when exporting the song, which means that they probably aren't due to insufficient realtime capabilities of the audio/MIDI subsystem.

Attached is a session archive with which you can perform the following steps to reproduce:

  1. Play the song, noticing that there is absolutely no groove in spite of the plugin being enabled, groove having been entered into the plugin, and steps process set to 1.0.
  2. Try different step process amounts, observing that it has no effect on what you hear.
  3. Dial step process back to 1.0 and nudge the MIDI segment on the track named "click" one nudge unit to the right (the unit is configured as :0016 in the session).
  4. Replay the song, noticing that now when notes begin ever so slightly after the exact beats, the groove is present but thoroughly garbled.
  5. Dial steps process down to 0.
  6. Replay the song, noticing that the groove is now garbled differently . Try different steps process amounts.
  7. Disable the plugin and replay the song to convince yourself that nudging the notes to go slightly after the beat doesn't cause these symptoms by itself (i.e. not an Ardour bug)
  8. Try different latency compensation settings for interesting effects.

Session archive

Soundfont used

Build error on Fedora 32

I build Bschaffl on Fedora 32.
I met the following error message:

Build BOops.lv2 DSP...src/BOops.cpp: In member function 'LV2_State_Status BOops::state_save(LV2_State_Store_Function, LV2_State_Handle, uint32_t, const LV2_Feature* const*)':
src/BOops.cpp:1176:3: error: 'LV2_State_Free_Path' was not declared in this scope; did you mean 'LV2_State_Make_Path'?
 1176 |   LV2_State_Free_Path* freePath = NULL;
      |   ^~~~~~~~~~~~~~~~~~~
      |   LV2_State_Make_Path
src/BOops.cpp:1176:24: error: 'freePath' was not declared in this scope
 1176 |   LV2_State_Free_Path* freePath = NULL;
      |                        ^~~~~~~~
src/BOops.cpp:1181:4: error: 'LV2_STATE__freePath' was not declared in this scope; did you mean 'LV2_STATE__makePath'?
 1181 |    LV2_STATE__freePath, &freePath, false,
      |    ^~~~~~~~~~~~~~~~~~~
      |    LV2_STATE__makePath
src/BOops.cpp: In member function 'LV2_State_Status BOops::state_restore(LV2_State_Retrieve_Function, LV2_State_Handle, uint32_t, const LV2_Feature* const*)':
src/BOops.cpp:1306:2: error: 'LV2_State_Free_Path' was not declared in this scope; did you mean 'LV2_State_Make_Path'?
 1306 |  LV2_State_Free_Path* freePath = nullptr;
      |  ^~~~~~~~~~~~~~~~~~~
      |  LV2_State_Make_Path
src/BOops.cpp:1306:23: error: 'freePath' was not declared in this scope
 1306 |  LV2_State_Free_Path* freePath = nullptr;
      |                       ^~~~~~~~
src/BOops.cpp:1311:3: error: 'LV2_STATE__freePath' was not declared in this scope; did you mean 'LV2_STATE__makePath'?
 1311 |   LV2_STATE__freePath, &freePath, false,
      |   ^~~~~~~~~~~~~~~~~~~
      |   LV2_STATE__makePath
In file included from src/Slot.hpp:26,
                 from src/Slot.cpp:22:
src/Stereo.hpp: In member function 'virtual Stereo FxRingModulator::play(double, double, double)':
src/Stereo.hpp:79:8: warning: 'f' may be used uninitialized in this function [-Wmaybe-uninitialized]
   79 |   left *= rhs;
      |   ~~~~~^~~~~~
In file included from src/Slot.cpp:48:
src/FxRingModulator.hpp:61:9: note: 'f' was declared here
   61 |   float f;
      |         ^

Assign to step changes timing

Maybe I misunderstood what it is supposed to do.
I thought it would assign a note to a step in order to apply that step's level to it.
It seems to change the timing too.

feature request: overall amount controls

It would be very handy to have 2 new sliders:

  • one for the overall amp change amount, from 0 to say 4, default 1
  • one for the overall time change amount, same range.

When the (time/amp) amount is 0, the (time/amp) data is unchanged, just the latency is applied.
When the amount is 1, the plugin functions as it does now.
When the amount is higher than 1, the changes are scaled by the slider, clipping the velocity at 127.

The main use cases are:

  • Automation. You could get the same effect without this feature, but just like with the swing sliders, it can be nice to automate from no change to full effect without having to automate all the sliders.
  • For subtle changes: design a pattern with amount turned up a bit and then use it at 1.

In case the only change you made is one or both of the swing sliders, these new sliders are superfluous, they are only needed when there are other changes.

edit: I guess negative amounts could come in useful as well.

Feature request: enter relative pulse lengths numerically

A simple way to represent many different quantization grooves is to specify relative lengths of the pulses numerically, e.g. [1,2,1,2,2] (for a particular 5/16 groove). The software would then divide each value by their sum, and compute running totals to obtain the onset times of the pulses.

This way of representing grooves can approximate any groove / inflection pattern arbitrarily well, and would have surprisingly good expressive power, esp. when combined with the amount slider (i.e. STEPS PROCESS).

Feature request: level swing

This would do for level what the current swing slider does for time.

With the slider in the middle, the midi is unchanged.
With the slider all the way to the left, notes falling in the period of the even notes of the pattern have velocity 0 and the notes falling in the period of the uneven notes have unchanged velocity.
With the slider all the way to the right, the even notes are unchanged and the uneven notes are 0.

Its easy enough to do by hand, at most move 8 sliders, but this new slider would be great for automating.

You can probably come up with a better name for this feature. ;)

Of course it would be just as useful for B.Choppr.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.