GithubHelp home page GithubHelp logo

pierreguillot / camomile Goto Github PK

View Code? Open in Web Editor NEW
877.0 64.0 61.0 10.42 MB

An audio plugin with Pure Data embedded that allows to load and to control patches

License: GNU General Public License v3.0

C++ 64.35% C 30.15% Shell 2.02% CMake 3.48%
vst audio pure-data plugin pd audio-unit vst3 lv2 libpd juce

camomile's People

Contributors

aviloff avatar eliottparis avatar hyperpenelope avatar jmaibaum avatar josef-n avatar pierreguillot 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  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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

camomile's Issues

fft ? block~?

Hi,
I tried to use a pd patch with fft. ( http://www.pd-tutorial.com/english/ch03s08.html )
It works good in pd vanilla and there is no error or warning in the camomile console.
no external abstractions involved.
The patch does not produce any sound as a vst-plugin ( a simple osc~ added to the patch works however)
Is FFT and block~ expected to work inside Camomile?
I cannot find a reason why the pd patch does not work inside Camomile.
I'm using Ableton live 9
Here is the .pd patch: https://drive.google.com/open?id=0ByVfkxBnSX-ATkJWc09fdHVHdDQ
(Just check the test - toggle to play a sound.)

Linux support ?

How about it ?

this project looks awesome and I see that a windows version is planned but I would really love to see a linux version too.

Note off issue

Dear Pierre,

First of all, thanks for this very cool piece of software :)

A very simple pd patch is attached to this bug report. I'm using Camomile-V0.0.7-beta.zip and especially the 64 bits .so for Linux (ubuntu + kxstudio).

Camomile is loading fine on Carla but the problem is that camomile is not getting the note off.

Do you think that it might be related to issue #27 ?

Cheers
Erwan

synth-pd.txt

Number ID for parameters

Hi Pierre,
many many thanks for this great tool, at least i can incorporate my max-ish things in hosts different than Ableton Live!
The way parameter id is managed makes very difficult to design patches on the go.
Instead of order of creation could it be possible to incorporate an ID as for example
"1_gain_dB" where the first number is the ID, second string is parameter name and third string is the kind of unit used by the paramenter. I guess would be the easiest way to rearrange parameter order when a patch design change over time.
best!
a.

Compilation Linux

from Oscar:

Hi Pierre:
I work with GNU/Linux for 32 bits.

First

make
Compiling LookAndFeel.cpp
In file included from ../../Source/../JuceLibraryCode/JuceHeader.h:17:0,
from ../../Source/LookAndFeel.hpp:28,
from ../../Source/LookAndFeel.cpp:25:
../../Source/../JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.h:4:82: fatal error: ../../../ThirdParty/Juce/modules/juce_audio_basics/juce_audio_basics.h: No existe el archivo o el directorio
#include "../../../ThirdParty/Juce/modules/juce_audio_basics/juce_audio_basics.h"
^
compilation terminated.
make: *** [build/intermediate/Debug/LookAndFeel_40552bdf.o] Error 1

then i copy files from JuiceLibraryCode ro ThirdParty/Juce and type make

/usr/include/c++/4.8/exception:35:37: error: expected declaration before end of line
#pragma GCC visibility push(default)
^
make: *** [build/intermediate/Debug/LookAndFeel_40552bdf.o] Error 1

Thre are two terminal screenshots attached to this message

Thanks

screenshot - 030416 - 09_51_16
screenshot - 030416 - 10_02_48

Unable to get information about track or playhead from DAW

Hi Pierre,

Thank you so much for this project. I'm looking forward to integrating PD more closely with my DAW (MuLab). I'm having difficulty getting information about the track and playhead. One question is that the instructions (https://github.com/pierreguillot/Camomile/wiki/How-to-create-patches-for-the-plugin) refer to $0-receive while the graphic example uses $0-playhead. I've tried both with no success. Here is one version of the simple PD patch I'm trying: camomile_test1.zip. I expect it to mimic the "tempo" setting inside the DAW. But, it does nothing. This issue has been confirmed by one other user in both MuLab and other DAWs: https://www.kvraudio.com/forum/viewtopic.php?f=79&t=482492&sid=2167123175a884d450d0b10cbe62399a

Could you provide an example patch to receive the track and playhead information? I'm trying to get a simple (but flexible) sequencer working. Thank you!

-d. vyd

Extras

I forgot to call the extras initializer !

Channel Confusion on Live

Only with Ableton Live (don't know why)
Stereo seems to be sum into 1 mono channel.
Patches : floyd -> stereogain

Parameter controls in visible area do not work when patched

It seems that Pd and Camomile are broken in an opposite way when it comes to gui controls.

Controls within the visible area which use direct connections do work in Pd, but do not work in Camomile.

Controls within the visible area that use a receive object do not work within Pd, but these controls do work in Camomile.

And in Pd, any controls outside of the visible area seem to work fine, whether directly connected or using a receive object.

I am using Pd 0.46.7 and Camomille 0.0.7.

Midi Noteoff issue

Hi, I am really enjoying Camomile, thank you!
I have a Miditech midi keyboard that sends a note-off velocity of 100 (which is apparently not unusual). When using Camomile in Reaper I am getting a note-on event with a velocity of 100 instead of a note-off
I'm using Windows 10

fatal error during compilation on Linux 64 (archlinux)

I got this error when trying to compile

$ make
Compiling LookAndFeel.cpp
In file included from ../../Source/../JuceLibraryCode/JuceHeader.h:17:0,
                 from ../../Source/LookAndFeel.hpp:28,
                 from ../../Source/LookAndFeel.cpp:25:
../../Source/../JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.h:4:82: fatal error: ../../../ThirdParty/Juce/modules/juce_audio_basics/juce_audio_basics.h: No such file or directory

                                                                                  ^
compilation terminated.
make: *** [Makefile:190: build/intermediate/Debug/LookAndFeel_40552bdf.o] Error 1

However, files tree looks like there is a file reported to be missing.

├── Builds
│   ├── LinuxMakefile
│   │   ├── build
│   │   │   └── intermediate
│   │   │       └── Debug
│   │   └── Makefile
│   ├── MacOSX
│   │   └── Camomile.xcodeproj
│   │       └── project.xcworkspace
│   │           └── xcshareddata
│   │               ├── Camomile.xccheckout
│   │               └── Camomile.xcscmblueprint
│   └── VisualStudio2015
│       ├── Camomile.sln
│       ├── Camomile.vcxproj
│       ├── Camomile.vcxproj.filters
│       └── resources.rc
├── Camomile.jucer
├── JuceLibraryCode
│   ├── AppConfig.h
│   ├── BinaryData.cpp
│   ├── BinaryData.h
│   ├── JuceHeader.h
│   ├── modules
│   │   ├── juce_audio_basics
│   │   │   └── juce_audio_basics.h
│   │   ├── juce_audio_plugin_client
│   │   │   └── juce_audio_plugin_client.h
│   │   ├── juce_audio_processors
│   │   │   └── juce_audio_processors.h
│   │   ├── juce_core
│   │   │   └── juce_core.h
│   │   ├── juce_data_structures
│   │   │   └── juce_data_structures.h
│   │   ├── juce_events
│   │   │   └── juce_events.h
│   │   ├── juce_graphics
│   │   │   └── juce_graphics.h
│   │   ├── juce_gui_basics
│   │   │   └── juce_gui_basics.h
│   │   └── juce_gui_extra
│   │       └── juce_gui_extra.h
│   └── ReadMe.txt
├── LICENSE
├── Patches
│   ├── camo.almond~.pd
│   ├── camo.am~.pd
│   ├── camo.chorus~.pd
│   ├── camo.cornetto.pd
│   ├── camo.dependencies.pd
│   ├── camo.flanger~.pd
│   ├── camo.floyd~.pd
│   ├── camo.minimock~.pd
│   ├── camo.netreceive.pd
│   ├── camo.netsend.pd
│   ├── camo.noise~.pd
│   ├── camo.ringmod~.pd
│   ├── camo.subpatch.pd
│   ├── camo.test.pd
│   ├── camo.tremolo~.pd
│   └── camo.vibrato~.pd
├── README.md
├── Ressources
│   ├── clear1.png
│   ├── clear2.png
│   ├── copy1.png
│   ├── copy2.png
│   ├── flower1.png
│   ├── flower2.png
│   ├── flowerP.png
│   └── option.png
├── Source
│   ├── Gui
│   │   ├── GuiAbout.cpp
│   │   ├── GuiAbout.hpp
│   │   ├── GuiComment.cpp
│   │   ├── GuiComment.hpp
│   │   ├── GuiConsole.cpp
│   │   ├── GuiConsole.hpp
│   │   ├── Gui.cpp
│   │   ├── GuiFlowerButton.cpp
│   │   ├── GuiFlowerButton.hpp
│   │   ├── Gui.hpp
│   │   ├── GuiLabel.cpp
│   │   ├── GuiLabel.hpp
│   │   ├── GuiNumbox.cpp
│   │   ├── GuiNumbox.hpp
│   │   ├── GuiParameter.cpp
│   │   ├── GuiParameter.hpp
│   │   ├── GuiPatcher.cpp
│   │   ├── GuiPatcher.hpp
│   │   ├── GuiRadio.cpp
│   │   ├── GuiRadio.hpp
│   │   ├── GuiSlider.cpp
│   │   ├── GuiSlider.hpp
│   │   ├── GuiToggle.cpp
│   │   ├── GuiToggle.hpp
│   │   ├── GuiWindow.cpp
│   │   └── GuiWindow.hpp
│   ├── InstanceEditor.cpp
│   ├── InstanceEditor.hpp
│   ├── InstanceProcessor.cpp
│   ├── InstanceProcessor.hpp
│   ├── LookAndFeel.cpp
│   ├── LookAndFeel.hpp
│   └── Pd
│       ├── PdConsole.cpp
│       ├── PdConsole.hpp
│       ├── PdEnvironment.cpp
│       ├── PdEnvironment.hpp
│       ├── Pd.hpp
│       ├── PdInstance.cpp
│       ├── PdInstance.hpp
│       ├── PdObject.cpp
│       ├── PdObject.hpp
│       ├── PdParameter.cpp
│       ├── PdParameter.hpp
│       ├── PdPatch.cpp
│       ├── PdPatch.hpp
│       ├── PdPatchManager.cpp
│       ├── PdPatchManager.hpp
│       ├── PdTypes.cpp
│       ├── PdTypes.hpp
│       ├── z_pd.c
│       └── z_pd.h
├── Tests
│   ├── MaxTest.maxpat
│   ├── MaxTestTremolo.fxp
│   ├── ReaperTest.RPP
│   ├── ReaperTest.RPP-bak
│   ├── TestOSC.RPP
│   ├── TestOSC.RPP-bak
│   └── TestTracktion
│       ├── TestTracktion Edit 1.tracktionedit
│       └── TestTracktion.tracktion
└── ThirdParty
    ├── Juce
    ├── PthreadWindows
    │   └── README.txt
    ├── PureData
    └── Vst
        └── README.txt

33 directories, 109 files

Any ideas why it happens?

Sample position from $0-playhead

Hi Pierre,
would be great to retrieve sample position from the playhead structure.
This is required for timing precision when dealing with audio buffers and the likes.
best
a.

gui does not appear (v0.0.8 OSX)

Hi,
this first: great work!
I tried to get rid of this note-off bug in v0.07 and compiled v0.0.8 with XCode (OSX 10.11.6).
After setting the vst-path manually it built successful with about 500 warnings about unused variables. The audio part of the .vst works, the organ test patch sounds good and does proper note offs in ableton live using the keyboard as midi-input now, but the plugin window does not show anything.
The window-title changes to the last patch-name after I load a new patch, thats all.
The console shows messages send to a print object also
but there is no gui, no objects, no connections, just sad gray...

Export plugins

On of the biggest problem with VST & Au is that the plugin are not meant to be dynamic. The current version is highly sufficient to create a plugin. But when you use several instances of the plugin in your DAW and the DAW doesn't allow to change its name, the project becomes a mess. So the idea is to add an option that exports or consolidates the plugin. This option should:

  • Copy the binary file of the plugin.
  • Rename the file (myplugin.vst for example).
  • Create a textual description of the plugin (myplugin.json).
  • Add the patch and dependencies.

All of this, can be easily but it could become really expansive on Windows and Linux because there is no bunble, perhaps a zip file would be the solution in this case.

When the copy of the plugin is loaded for the first time, the plugin should first load the description and retrieve the name of the plugin, the number of parameters, their names, ect.

Xcode project file missing

There seems to be a file missing for the Xcode project. When i try to open the Builds/MacOSX/Camomile.xcodeproj file the following error is shown in a pop-up window:

"Project /Users/thomas/Documents/dev/Camomile/Builds/MacOSX/Camomile.xcodeproj cannot be opened because it is missing its project.pbxproj file."

Metro object

Hello,
It seems that the metro object doesn't respond correctly.
Here is a simple test with a [metro] applying a random frequency to an [osc~] object : it seems impossible to change its rate.

Tried with Renoise(x64) 3.1, Camomille 0.7 VST 32bit, Windows10 64bit
metro-test.zip

Trouble with [loadbang]

I am having some troubles with [loadbang]. I wanted to use it to send initial messages to the sliders to set the initial positions. It works fine in Pd, but all my sliders start at 0.0 in Camomile.

nbx limits

There is a problem if the user use the default limits for the [nbx] because the range is too big so in the plugin the value is always zero.

libPD

try to use at least the libPD c wrapper.

32 channels version

In the file InstanceProcessor.cpp

line 23 & 24, replace

busArrangement.inputBuses.getReference(0).channels = AudioChannelSet::discreteChannels(16);
busArrangement.outputBuses.getReference(0).channels = AudioChannelSet::discreteChannels(16);

with

busArrangement.inputBuses.getReference(0).channels = AudioChannelSet::discreteChannels(32);
busArrangement.outputBuses.getReference(0).channels = AudioChannelSet::discreteChannels(32);

Later, perhaps we'll find a way to manage specific configurations (5.1, 7.1, etc.)

Parameter not available to MIDI learn with Ableton

Hello Pierre, thanks for this awesome project !

Camomille works well with Live, but I can't seem to map plugin controls on a MIDI controller using the MIDI learn function from Ableton. Is it not implemented or am I missing something here ?
Automations work fine though so parameters are transfered to Live, but not to MIDI learn.

I'm running Live 9.6.1 under Mac osx 10.10.5.

Loïc

Manage array

See if it is possible to display and play with an array.

File open causes freeze of plugin and host on Linux (Tracktion)

Hi, I compiled the plugin on ubuntu 16.04 moved the .so file from the build folder to my ~/.vst folder and tried Tracktion to load the plugin. Plugin scans and loading is fine (gui shows up), but doesn't respond any more to user input after clicking file open. Other menu items are not affected.

edit: same happens in renoise.
edit2: also Tried the v0.0.8 branch with same result.

Numbers and symbols

Hello Pierre,
Many thanks for this nice plugin and the work done.
I am not sure the following are issues : symbol and numbers do not react in the GUI.
I tried the following very simple patch (with [number2] is the same) to intercept which note is played. In the following, not all connectors are showed :
[notein]
|
[Number] Properties of Number : send message $0-notevalue
|
[noteout]

Gui object :
                                                 |

[Number] | with properties : receive message : $0-notevalue , label : NoteNumber
------------------------------------|

  1. the GUI [number] labelled NoteNumber does not show in the window
  2. when using [number2] instead of [number], the item is there but there is no sign that it is being triggered whenever I am sure that the midi notes are passing thru the plugin in the DAW (reaper) .
  3. same thing happens with [symbol]. They do not show in the GUI window.

Would you be so kind to help ?
Many thanks.

Unable to send out MIDI events

I'm trying to send some random midi notes out to a plugin in reaper. Using loop midi as a midi output from PurrData and into Reaper works, but i can't get the notes to be recognized using camomile. I just started using this today, so i tend to think it's something I'm doing wrong. Any thoughts?

Camomile 0.0.7
Reaper 5.4
Windows 10
Pd-L2Ork (Purr-Data)

2017-06-22 15_09_26-midirand pd - e__sk lib_user

2017-06-22 15_11_11-fx_ track 4

ctlout?

Is the object ctlout supposed to work? Can't get a patch with that object to output control change midi data.

:((( ubuntu version crash when i try open patch

I trying use camomile on different version of linux and different software and always plugin normal load but crashing when i try open patch, help me please? may be i did something wrong? for example bitwig try save plugin state, may be problem in permissions?

Automatic reload of changed patches

It would be really nice if changed / saved patches could be automatically reloaded.
Cross-platform file watching does not seem to be available in JUCE (correct me if I'm wrong here) but https://pocoproject.org/docs/Poco.DirectoryWatcher.html seems to make this easy but I'm not a C++ coder so I can't really tell wether that would work.

After a patch or subpatch has changed

  • the state should be saved (needs thinking about what the state actually is and how to save it)
  • audio should be faded out (like 1ms) to prevent clicking
  • the new patch should be loaded
  • the previously saved state should be restored
  • audio should be faded in

That's probably not too easy to implement but would make patching so much more fun!

Thanks!

netreceive on Windows 7

First: Congrats and thanx a bunch for this great work !

Some Issue i encountered: (Windows 7 64bit, Camomille 32bit, Ableton Live 8)

1.) is "netreceive" inside a camomile patch supposed to work ?

your example patch "camo.netsend.pd" that sends messages over netsend to a receiving PD patch works alright, but how about the other way round ?
i had no luck when i tried it.

the camomile console says :

"Camomile 0.0.7 for Pure Data 0.47.0
netreceive: failed to sett SO_BROADCAST"
Warning in patch camo.netsend_receive_test.pd: Connect parameter is duplicated !

i attached my patches in this post

camo.netsend_receive_test.zip

2.) is there any hope of 3rd party externals being supported soon ?

best

oliver

Relative/absolute path

Hi,
It seems that Camomille use absolute paths only to load pd~patches, which makes the files organization quite delicate as it's very relying on the file tree.
Would it be a good (and feasible!) idea to use also relative paths from the DAW project file to load patches?
In this way, we could move folders easily without modifying the relative path between patches and the project file.

To go further, we could imagine a "plugin maker" which would create a new totally independent and functional .dll with the patch algorithm already "in it" with no need to load it from elsewhere.
In fact, exactly like pluggo was used with maxmsp4.

Anyway, those suggestions are only ideas to make the file management or sharing more flexible/robust, and to have a more 'compact' use of this excellent application.
Hope that was clear enough, and sorry for my childish english.

Alex

Change object

Bonjour,
Un grand merci pour les immenses possibilités qu'ouvre votre plugin.

I use Windows 7 64bits and Reaper 32 and 64bits. I have been trying to control a [metro] with a toggle (and a slider for speed) for quite a while, then I understood I needed a [change] object after the toggle : otherwise the metro is restarted continuously and it gets impossible to control its speed. Maybe this necessity could be made a little clearer in your FAQ and tutorial. You mention it in the FAQ, but the implications were not obvious (to me at least!).
Also the number-1 box and bang object are invisible in the GUI with my machine, is this normal?

Bravo encore et merci!

presets?

Thank You for awesome project! Plan you add opportunity save/load presets?

Camomile as Midi Effect

Thank you so much for taking the time to create this, I have been hoping someone would do it for years!
I have not been able to get Ableton or Logic to recognize camomile as a midi effect so that I can use it as a sequencer. It has been working perfectly as an audio effect. I suspect I am missing something very simple. Does anyone know of a way to get this working?

latest git build error

Build fails with JUCE 4.2.4 on Fedora 21 x86_64 GCC 4.9.2.

Compiling InstanceProcessor.cpp
../../Source/InstanceProcessor.cpp: In function ‘juce::AudioProcessor* createPluginFilter()’:
../../Source/InstanceProcessor.cpp:467:28: error: cannot declare variable ‘lookAndFeel’ to be of abstract type ‘CamoLookAndFeel’
static CamoLookAndFeel lookAndFeel;
^
In file included from ../../Source/InstanceProcessor.cpp:9:0:
../../Source/LookAndFeel.hpp:35:7: note: because the following virtual functions are pure within ‘CamoLookAndFeel’:
class JUCE_API CamoLookAndFeel : public LookAndFeel
^
In file included from ../../../JUCE-code/modules/juce_gui_basics/juce_gui_basics.h:215:0,
from ../../../JUCE-code/modules/juce_audio_plugin_client/juce_audio_plugin_client.h:52,
from ../../Source/../JuceLibraryCode/JuceHeader.h:19,
from ../../Source/InstanceProcessor.hpp:11,
from ../../Source/InstanceProcessor.cpp:7:
../../../JUCE-code/modules/juce_gui_basics/menus/juce_PopupMenu.h:709:28: note: virtual juce::Component* juce::PopupMenu::LookAndFeelMethods::getParentComponentForMenuOptions(const juce::PopupMenu::Options&)
virtual Component* getParentComponentForMenuOptions (const PopupMenu::Options& options) = 0;
^
../../../JUCE-code/modules/juce_gui_basics/menus/juce_PopupMenu.h:711:22: note: virtual void juce::PopupMenu::LookAndFeelMethods::preparePopupMenuWindow(juce::Component&)
virtual void preparePopupMenuWindow (Component& newWindow) = 0;
^
Makefile:204: recipe for target 'build/intermediate/Debug/InstanceProcessor_bc7e525e.o' failed
make: *** [build/intermediate/Debug/InstanceProcessor_bc7e525e.o] Error 1

autoload 'Camomile.pd'

Hi,

I would like to ship a pd patch to a friend using Camomile + savihost like this:

Camomile.dll
Camomile.exe
Camomile.pd

Camomile.exe (savihost) will search for Camomile.dll.
It would be great if Camomile.dll would automatically load 'Camomile.pd' too if present.
Is this something you would consider implementing?

The big win is:

  • other users dont have to install PD
  • other users can just load Camomile.dll into their VST host (and it works immediately)
  • other users can just load Camomile.exe if they don't have VST host (and it works immediately)

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.