Code Monkey home page Code Monkey logo

frontieres's Introduction

Frontières est un échantillonneur granulaire.

Ceci est une reprise non-officielle de la version 0.4 libre du logiciel Borderlands. Voir sa page sur linuxmao.org. Vous trouverez des tas de notes concernant le logiciel originel en version 0.4 dans les fichiers README.txt et README-2.txt.

Construction

Build Status

Téléchargement

Version en développement

Généralités

Le système de construction est cmake, et le cadriciel visuel est Qt5.

Debian Buster

Vous aurez besoin des paquets suivants : cmake build-essential libasound2-dev libglu1-mesa-dev libjack-jackd2-dev ou libjack-dev libsndfile1-dev libsoxr-dev liblo-dev mesa-common-dev libpulse-dev et pkg-config.

Ainsi que les paquets Qt5 suivants : libqt5opengl5-dev, libqt5x11extras5-dev, qtbase5-dev, qttools5-dev, et qttools5-dev-tools.

Debian Stretch

Vous aurez besoin des paquets suivants : cmake build-essential libasound2-dev libglu1-mesa-dev libjack-jackd2-dev ou libjack-dev libsndfile1-dev libsoxr-dev liblo-dev mesa-common-dev libpulse-dev et pkg-config.

Ainsi que les paquets Qt5 suivants : libqt5opengl5-dev, libqt5x11extras5-dev, qtbase5-dev, qttools5-dev, et qttools5-dev-tools.

(note : certains sont peut être non-nécessaires)

frontieres's People

Contributors

fpesari avatar jpcima avatar olof29 avatar trebmuh 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

jpcima stilnat

frontieres's Issues

Ergonomie du logiciel

@trebmuh À détailler.

développer une méthode d'utilisation permettant de se rapprocher de l'ergonomie de ce logiciel sur une tablette, car pour l'instant, l'utilisation des touches de clavier n'est pas des plus faciles pour le logiciel, surtout quand on voit comment ce logiciel est utilisé sur iPad.

cmake ask for Qt5LinguistTools in debian

Is we build it with cmake ?
On my debian unstable, it ask to me Qt5LinguistTools, but theses tools seem to be in the qttools5-dev-tools package :

dpkg -L qttools5-dev-tools | grep linguist
/usr/lib/qt5/bin/linguist
/usr/share/applications/linguist-qt5.desktop
/usr/share/pixmaps/linguist-qt5.png
/usr/lib/x86_64-linux-gnu/qt5/bin/linguist

pouvoir memoriser des cloud type et à la creation de nouveau cloud, les utiliser

il serait bon de pouvoir enregistrer les parametres d'un cloud (a part sa localisation).
et de pouvoir creer de nouveaux cloud avec ces parametres, et non ceux par defaut qui sont toujours les memes.
pour ça il faudrait qu'à la creation d'un cloud, on n'affecte pas des valeurs constantes, mais celles d'un objet de type cloud qui pourrait etre lu depuis une sauvegarde, initialisé avec les valeurs par défaut.

organisation des sources

Suggestion d'organiser les sources du logiciel (*.cpp, *.h,...) dans un répertoire src/, histoire d'y voir un peu plus clair.

Format de traductions

Puisque désormais le logiciel est bâti sur Qt, mieux vaut utiliser ses méthodes de traduction plutôt que Gettext.

Par ailleurs, je suspecte que désormais il soit possible d'écrire le texte accentué, à cause du changement du moteur de rendu de texte.À vérifier.

ne peux plus compiler dans qt

j'ai un message d'eereur maintenant à la compilation :

/home/olivier/developpement/Frontieres/libraries/QtFont3D/QtFont3D.h:13: erreur : QOpenGLFunctions: No such file or directory #include <QOpenGLFunctions> ^

une histoire de version de qt ?

probleme de "rémanance" du son d'un cloud

il y a un probleme qui m'etait déja apparu lors de mes premiers essais d'envelopes qui est toujours présent et me semble etre vraiment tres impactant sur le son de la polyphonie midi :
c'est comme si un buffer subsistait aprés l'arret du son d'un cloud. et celui ci est joué au redémarrage du cloud.
pour le mettre en évidence, c'est tres simple :

  • creer un cloud
  • le desactiver
  • deplacer le cloud
  • le reactiver

le son commencera avec celui de la place precededente

il me semble que la durée de ce fantome est variable (selon le contenu du buffer, peut etre)

dans les notes midi cela a pour effet de creer une sorte de "portamento" entre les notes d'une mélodie, et je le soupsonne aussi fortement d'etre à l'origine d'e l'effet de vivrato qui se declenche lorsque plusieurs notes midi sont presentes simultanement sur le meme cloud.

j'ai vraiment besoin de bien comprendre le principe de production sonore pour pouvoir resoudre ce probleme.

comment cela marche t'il exactement ? voici ce qu'il me semble comprendre :

  • on met des infos de son dans un buffer
  • rtAudio lit à frequence réguliere ce buffer
  • s'il est plein, ou contient un certain flag de fin d'echantillon, il le joue puis le vide.

est ce bien ça ?

si oui, qu'advient il donc d'un buffer qui ne serait pas plein au moment où l'envelope d'un son passe à off ?

mais le probleme est peut etre ailleurs, dans le principe des grains, car j'ai le sentiment que si le suoci etait du au buffer, le son serait tres faible dans le fantome, car venant d'une fin d'envelope. or, parfois ce fantome survit clairment jusqu'a ce que le niveau maximum de l'attaque ait ete atteint au redeclenchement.

décodage de format audio MP3

On ne peut pas charger les fichiers de format MP3.
La bibliothèque sndfile ne gère pas le format.

Une solution consiste à intégrer audio_decoder de Robin Gareus, qui permet d'utiliser à la fois les décodeurs sndfile et ffmpeg.

Choisir la longeur de l'échantillon dans l'IGU

Actuellement, les échantillons affichés avec lesquels on peut jouer ne sont qu'une partie des échantillons chargés. il suffit pour s'en convaincre d'écouter les échantillons en dehors du logiciel.

Ça serait intéressant de pouvoir choisir la taille/longueur de l'échantillon à afficher dans le logiciel grâce à un clic-droit par exemple.

site web et forum frontieres

Est ce que la communautée serait interessée à un site web et forum de discussion autour de frontieres? C'est un des seuls outils de granular synth sur linux et je pense que cela pourrait aider à la communeauté. J'offrirais le nom de domaines et l'hébergement gratuitement si il y à un intéret.

Faire passer Frontieres en version entièrement Qt

pour pouvoir gérer simplement l'interface utilisateur des sessions Frontières, mais aussi donner des alternatives à la gestion des paramêtres des clouds, et pouvoir proposer un paramétrage midi, ne serait il pas préférable de faire passer intégralement le projet sous Qt creator ?
J'ai pour ma part réussi à charger le projet Frontieres dans Qt creator en chargeant le fichier cmake.txt dans celui ci, mais la forme du projet n'est pas celle d'un projet typique de Qt creator avec widgets.
Mes tentatives pour incorporer Frontieres dans un nouveau projet Qt creator avec Widgets se sont pour le moment soldées par des erreurs de compilations, dont la plupart sont simplement des erreurs liées à des chemins d'accès à certains entetes qui sont dans le sous repertoire librairies, mais d'autres me laissent pour le moment sans réponses.

appliquer une enveloppe ADSR aux clouds

la démarche consisterait à appliquer une attaque et un decay à la création d'un cloud, puis rester au niveau du sustain tant que le cloud est actif, et appliquer un release si on desactive le cloud.
de meme à la réactivation d'un cloud, on appliquerait attaque et decay.
les parametres d'enveloppe seraient des proprietes supplementaires des clouds, et pourraient donc etre aussi memorisés dans les parametres de clouds par defaut, et modifiés.
l'enveloppe pourrait etre definie ainsi :

  • attack en milisecondes
  • decay en milisecondes
  • sustain, un float negatif qui est le niveau en Db a soustraire du niveau général du cloud
  • release en milisecondes

à ce stade, je vois bien comment créer et integrer cette strucure à Frontières, mais je ne vois pas comment l'appliquer au son, car la creation sonore elle meme reste tres trouble pour moi dans Frontieres

Ajouter/supprimer des échantillons depuis l'IGU

Ça serait chouette de pouvoir ajouter/supprimer des échantillons depuis l'IGU.

Pour l'instant en cliquant-droit sur le rectangle d'un échantillon, on peut le sélectionner.

J'imagine un menu déroulant lors d'un clic droit sur un rectangle d'échantillon avec plusieurs options :

  • copier
  • supprimer
  • choisir la taille de l'échantillon à utiliser (voir #15)

Et un menu déroulant avec un clic-droit sur un espace vide (pas sur un rectangle d'échantillon) avec plusieurs options :

  • coller
  • charger un son

créer une sortie audio stereo séparée par nuage en plus du master

dans le but de pouvoir appliquer des traitements separes sur chaque nuage, je voudrais creer une sortie audio stereo unique pour chaque nouveau nuage, qui serait une copie conforme de ce que ce nuage envoit au master.
mes besoins : savoir comment creer ces sorties audio, ou les creer, et comment y assigner la production sonore du nuage

fenetre regroupant tous les parametres d'un cloud

je suis en train de commencer à créer une fenêtre éditable regourpant tous les parametres d'un cloud.
je m'interroge sur la bonne façon de l'intégrer à frontières :

  • est-ce que je la rends dépendante du cloud, auquel cas chaque cloud peut avoir sa fenetre.
    avantage, on peut modifier les parametres d'un cloud même s'il n'est pas sélectionné dans la fenêtre principale.
    inconvéniant, tout ça finira par être susceptible de prendre beaucoup de place mémoire, non ?
  • est ce que je la rends unique, et son contenu change selon le cloud sélectionné ?
    avantage, cela prend moins de place mémoire
    inconvéniant, je ne sais pas trop à quel niveau du programme la creer (je pense qu'au niveau de MyGlWindow pourrait etre logique, mais n'en suis pas sur)

Pilotage MIDI

@trebmuh À détailler.

développer une entrée MIDI et une contrôlabilité MIDI pour pouvoir automatiser tout ça, voire jouer avec les potards d'une BCF 2000 ce qui améliorerait probablement l'ergonomie du logiciel. Ne pas oublier d'y adjoindre une fonctionnalité de MIDI-learn.

la nouvelle logique de repertoire de travail pose plusieurs problemes

superbes fonctions que celles qui permettent de charger et enlever des echantillons à la volée.
mais du coup, la logique de travail en rapport avec le repertoire de travail se retrouve avec plusieurs lourdeurs

  • on ne peut plus chosir son repertoire de travail au depart. cela amene à avoir systematiquement le repertoire par defaut des echantillons chargé. meme s'il n'y a que 4 echantillons dedans, ça va vite devenir gavant de devoir a chaque fois les supprimer, car il serait bien etonnant que l'on en veuille dans toutes nos scenes.
  • on ne peut charger à la volée qu'un echantillon a la fois, donc vu que l'on ne peut plus choisir son repertoire de travail de base, si on veut charger les 120 echantillons qui sont dans un repertoire donné, par exemple, ça va prendre 120 manips...

je pense que la fonction de chargement a la volée, si elle permettait des selections multiples, resoudrait quasiment tout ça, pour peu qu'on ne mette plus de repertoire de travail par defaut du tout, qu'on laisse une scene vide au depart.

la fenetre de depart demandant si on veut charger une scene ou en creer une nouvelle n'a plus non plus de sens

il va aussi devenir tres vite important de pouvoir afficher le nom des echantillons etant donné les origines multiples de ceux ci, sous peine de se perdre

[feature request] onglet de menu "à propos"

maintenant qu'il y a un menu, ça serait chouette d'avoir un onglet "à propos" traditionnel avec comme info :

  • le fait que ce soit une reprise de borderlands (+ n° de version de borderlands au moment du fork) + le nom du dev de bordelands + un lien vers le site de borderlands
  • les noms des développeurs et contributeurs de frontières
  • un lien vers la forge (ici quoi)
  • la licence utilisée

probleme de performances évident

Frontieres (tout comme Borderlands) a de serieux problemes de performances :
au dela de 3 clouds ou de 3 voix de polyphonie midi, ou de 24 grains dans un cloud, c'est les xruns quasi garantis, et ce meme sur un machine avec 8Go de memoire, et 512 en buffer pour jack en 44000.

il ya donc surement des choses faisables pour ameliorer ça, mais ce n'est pas dans mon domaine de competance actuel

pouvoir gerer un buffer audio entrant

j'aimerais pouvoir disposer de deux entrées dans Frontières, et de pouvoir accéder à un buffer contenant l'audio qui y est reçu, afin de gérer celui ci comme des echantillons qui seraient constament mis à jour.
mais je ne sais pas encore comment faire ça...

Problème de logique au chargement d'une scene

superbe boulot que la mouture "propre" de la gestion des scenes.
il subsite neanmoins un problème qui n'exisatait pas dans la mouture non afinée :

  • si on choisit de charger une scene au lancement, on ne devrait pas ensuite passer par la fenetre de demande du repertoire de travail, c'est le repertoire de la scene qui doit etre pris en compte.
  • là on passe par la fenetre de choix de la fenetre de travail, et en plus elle est branchée par defaut sur le repertoire par defaut et non sur celui de la scene. du coup si on valide, on a une scene vide de tout echantillon (ce qui n'est pas non plus normal)

Mettre en place un suivi de numéros de version et viser la distribution

depuis le départ de cette aventure, Frontières a maintenant beaucoup évolué.

  • ne serait il pas bon que maintenant il y ait une numerotation de versions en rapport avec les evolutions apportées et un suivi de ceux ci ?
  • que manque t'il au projet pour en permettre la diffusion dans des distributions ?

normalisation des noms d'entités

ce travail a ete deja commencé avec l'entrée en jeu de l'entité scène. il merite d'etre approfondi.
par exemple, la meme entité est parfois appelée cluster, parfois cloud, une autre parfois voice, parfois grain, une autre parfois sound, parfois audiofile, parfois sample.
il y a aussi une visualisation appelee Rect, et l'autre Vis, il ya cloud et cloudVis, ne faudrait il pas l'equivalent pour les sons (sound et soundVis, ou audiofile et audiofileVis) ?
normailser tout cela clarifierait bien le code

de plus, quels sont les regles pour les noms de classes, variables globales, locales, constantes, enums, etc ? (certains enums sont tout en majuscules, d'autres non)

Support du protocol NSM

Je viens de tester Frontières, il a beaucoup évolué depuis mes dernièrs ouvertures du logiciel, chouette boulot.
L'implémentation du protocole NSM serait bienvenue pour une utilisation conjointe de Frontières avec d'autres applications JACK, comme Carla et Non-Mixer. Cela permettrait de rappeler directement à l'ouverture de la session NSM le projet Frontières.

Problèmes de programmation divers

  1. problème d'accès concurrent pouvant occasionner un plantage

La routine de calcul audio fait appel à la collection de grainCloud ici.
Au même instant, l'interface graphique peut manipuler la même collection sans synchroniser l'accès, lorsqu'il y a un appui sur la touche "G".

Frontieres/Frontieres.cpp

Lines 243 to 245 in db77e38

for (int i = 0; i < grainCloud->size(); i++) {
grainCloud->at(i)->nextBuffer(out, numFrames);
}

Frontieres/MyGLWindow.cpp

Lines 659 to 660 in db77e38

// create audio
grainCloud->push_back(new GrainCluster(mySounds, numVoices));

La solution la plus simple consiste à mettre en place un mutex à utiliser de chaque côté.
Du côté audio, il vaut mieux faire appel à try_lock afin de ne pas générer de underrun au moment de l'éventuel accès concurrent. Par contre une coupure du signal sonore pourra se faire entendre, inconvénient de ce type de solution.

Dès la synchronisation des données sera en place, on pourra manipuler l'ensemble d'échantillons chargés avec sûreté. Afin d'améliorer, il faudra étudier les structures de données sans verrou (lock-free).

  1. pratiques de programmation à revoir

On ne fait pas new sur vector en C++, mais cette pratique est présente à de nombreux endroits.
J'ai repéré aussi un new Mutex, également à éliminer. (un GTime aussi mais d'importance moindre, ce dernier étant singleton)

Par ailleurs il faudrait si possible éliminer les classes Mutex et Thread, qui sont des éléments standards de C++ à partir du standard de 2011.

(ensuite, il est envisageable de passer le tout en RAII.. à voir)

pouvoir mémoriser une configuration

pour que Frontieres soit un instrument complet, il faudrait, à mon avis, pouvoir mémoriser entièrement une configuration :

  • les echantillons concernés
  • la place des échantillons
  • la taille, et l'orientation des echantillons
  • la place des clouds
  • les paramètres des clouds

ce n'est qu'ainsi qu'on peut etre à meme de reproduire une oeuvre musicale avec frontieres, sinon, on reste toujours dans le jet unique
cela aurait des consequences sur la question des repertoires utilisateur (il faudrait en fait laisser l'utilisateur mettre un projet musicalsous forme d'un repertoire ou il veut, et y mettre un fichier de configuration et les echantillons dans un sous repertoire loops)

polyphonie midi, probleme de comprehention dans la gestion des envelopes

j'ai implémenté la polyphonie midi dans la branche olofmidi de mon fork.
j'ai tout testé jusqu'à la production sonore dans nextbuffer.
et là il y a quelque chose qui a du m'echapper dans ma gestion des enveloppes, j'ai des envelopesaction qui se retrouvent à 0 , donc ni trigger, ni release, et ne peux donc pas prendre en compte les messages midi note off.

je passe par un tableau qui contient 32 CloudMidi avec chacun une note, un pitch, une velocité, une envelope, un buffer d'envelope (classe CloudMidi dans Cloud.cpp), que je gère au niveau de la fonction setActiveMidiState dans Cloud.cpp.
je precise que je n'ai pas encore traité la sauvegarde des banques et combinaisons midi, ni la question du pitch des notes, mais tout est en place pour le faire.
pour tester, il faut creer un cloud, creer une combinaison , l'affecter à un canal midi (menu midi), et mettre un clavier virtuel derriere sur le meme canal.

qu'ai je mal fait ?

Renommage du logiciel en "Frontières"

Pour information, j'ai envoyé un courriel au développeur originel hier dont voici une copie :

Hi Christopher,

Since you didn't answer to my previous message (about Borderlands and LibraZiK) back in December 2016, I kind of assume that you're not working anymore on Borderlands. Please, let me know if this is a wrong assumption.

We (3 persons from the French linux audio community called "linuxmao.org") have started a fork of Borderlands to integrate some improvements of us which consist so far in:

  • added manpages (English and French),
  • added a menu item file,
  • updated rtaudio libraries,
  • possibility to start the software other than in 44.1 kHz,
  • adding a patch to check for the samples in different locations (a user location, and a system location),
  • added a translation system (gettext),
  • added a French translation,
  • use of cmake as a construction system.

You can find this fork here : https://github.com/jpcima/Borderlands
(jpcima is copied to this email)
This fork is based on the 0.4 GNU-GPL-3 version available on your website.

We are planning to continue further development and we'd like to check with you how do you feel with that.

We've got 2 questions here:

  • it does look that you're not developing it actively since 2015, are you planning to develop it later?
  • are you fine with us keeping the same name ("Borderlands") or would you prefer us to take another name?
  • if you're fine with us keeping the same name, what if we'd like to publish a 0.5 version?
  • would you like to work on it as a team with us?

Hope you'll answer to this email.

Anyway, thanks for providing Borderlands which is such a funny and uncommon sampler!
(my niece liked play with it a few days ago!)

Sincerely,
Olivier

Puisque @jpcima enchaîne les commits et que j'enchaîne les demandes de fonctionnalité, et étant donné que le logiciel amont non-libre est commercialisé, il est probablement souhaitable de ne pas réutiliser le même nom pour cette reprise.

Cette reprise de Borderlands va donc être nommée "Frontières", lui donnant au passage un côté "french touch" 😄

Liste des tâches à faire :

  • renommer le dépôt
  • renommer le titre au lancement du logiciel
  • renommer dans de code-source si besoin
  • renommer dans les docs si besoin
  • publier une version 0.4.1

retour d'expérience d'utilisation de frontieres

je mets ici un lien vers linuxmao pour le retour d'experience d'utilisation de frontières en cession de composition MAO avec une trentaines de gamins :
https://linuxmao.org/tiki-view_forum_thread.php?comments_parentId=89523&forumId=27

et j'en profite pour ajouter quelques commentaires de debuggage :

  • la sauvegarde des clouds ne sauve pas l'envelope, ce qui fait que à la recharge des parametres de clouds par défaut, on a une enveloppe avec des valeurs à 0 et des temps enormes, donc aucun son
  • la manipulation des fenetres de parametres de clouds demande quelques afinages, lorsqu'on se retrouve avec 6 ou 7 presentes, on ne sait plus laquelle on veut utiliser, et retaper "P" sur le cloud ne fait pas repasser celle lui correspondant au premier plan, on est donc obligé de fermer toutes les fenetres pour reafficher celle qui nous interesse, perte de temps et de souplesse enorme
  • lorsqu'on reaffiche la fenetre de parametres de clouds, elle ne se remet pas là ou on l'avait envoyéee à l'ecran, mais au milieu sur l'ecran ou se trouve la fenetre base (j'utilisais l'ecran du portable et un video projecteur comme deuxieme ecran)
  • certaines manipulations de parametres font disparaitre tout bonnement le son de maniere assez incompreensible. (que ce soit depuis la fenetre des parametres ou depuis celle des echantillons)
  • manipuler les parametres depuis la fenetre de dialogue s'est avéré bien plus pratique pour les enfants.
  • quelques situations amènent a voir les valeurs de certains parametres evoluer plus ou moins que ce qu'on avait demandé depuis la fenetre clouddialog
    (apres tests poussés, il s'agit d'un bug du widget qdoublespinbow)
  • certains parametres affichés dans cloudDialog à sa crétion ne correspondent pas à ceux qu'on a dans la fenetre openGL
  • la sauvegarde de scene, et sa recharge changent les parametres d'envelopes
  • plantage a l'execution dans certaines circonstances apres avoir rechargé une scene enregistree, et que plusieurs fenetres de parametres sont affichées avant cette recharge. (il faudrait penser à detruire les fenetres de parametres quant on charge une scene)
  • si on ferme la fenetre principale sans avoir fermé un fenetre de parametres, le programme tourne toujours jusqu'a ce que l'on ferme la fenetre de parametres

je précise que j'ai travaillé avec ma version de developpement, un tout petit peu en avance sur le master actuel, integrant le pr que j'ai fait recemment, et une autre modif que je n'ai pas encore jointe reparant un bug sur l'ajout ou la supression de grains dans cloud.
les vus que j'ai rajoutés sont liés aux pr qui ont suivi.

ajout de trajectoires des clouds

salut tout le monde,
j'adore ce projet et je suis en train de bosser sur ma premiere contribution sur github !
Je trouve qu'il serait cool qu'on ait la possibilité de définir des trajectoire pour les clouds de façon à automatiser des dynamiques dans la production du son.
J'ai un peu travaillé dessus déjà, je vais essayer de le mettre sur github .

J'ai ajouté une classe abstraite trajectory de laquelle héritera toute les autres trajectoires
une premiere classe qui implemente trajectory appellée "Bouncing"
j'ai ajouté à la classe CloudVis un pointeur de type Trajectory
j'ai ajouté une méthode permettant de créer un cloud qui bouge quand on appuie sur I (pour l'instant que d'une seule façon)
J'ai modifié la méthode Draw de Cloudvis pour qu'il prenne en compte la trajectoire si il bouge.

Plus tard, j'aimerais ajouter d'autre type de trajectoires (circulaire, b-splines, à la main), la possibilité d'activer ou désactiver le mouvement d'un cloud, la possibilité de modifier les paramètres des trajectoires dans le logiciel et peut être d'autres fonctions auquels je n'ai pas encore pensé.

N'hésitez pas à me donner des retours sur mon code, en matière de code coopératif je suis débutant je vais surement faire des erreurs, et ça fait un moment que je n'ai plus fait de C++ je ne suis plus très a l'aise avec.

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.