patroclos / pamix Goto Github PK
View Code? Open in Web Editor NEWncurses/curses pulseaudio mixer in c++ similar to pavucontrol
License: MIT License
ncurses/curses pulseaudio mixer in c++ similar to pavucontrol
License: MIT License
Trying to update 1.5->1.6.
Turns out we have no source for <ncursesw/ncurses.h>
, though we do supply ncurses.h
.
=> PAmix-1.6_1: running do_configure ...
-- The C compiler identification is GNU 7.2.0
-- The CXX compiler identification is GNU 7.2.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/g++
-- Check for working CXX compiler: /usr/bin/g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
CMake Warning:
Manually-specified variables were not used by the project:
CMAKE_INSTALL_LIBDIR
CMAKE_INSTALL_SBINDIR
-- Build files have been written to: /builddir/PAmix-1.6/build
=> PAmix-1.6_1: running pre-build hook: 02-script-wrapper ...
=> PAmix-1.6_1: running do_build ...
Scanning dependencies of target pamix
[ 7%] Building CXX object CMakeFiles/pamix.dir/src/cardentry.cpp.o
[ 15%] Building CXX object CMakeFiles/pamix.dir/src/configuration.cpp.o
In file included from /builddir/PAmix-1.6/include/pamix.hpp:3:0,
from /builddir/PAmix-1.6/include/configuration.hpp:3,
from /builddir/PAmix-1.6/src/configuration.cpp:1:
/builddir/PAmix-1.6/include/../config.hpp:3:10: fatal error: ncursesw/ncurses.h: No such file or directory
#include <ncursesw/ncurses.h>
^~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/pamix.dir/build.make:87: CMakeFiles/pamix.dir/src/configuration.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/pamix.dir/all] Error 2
make: *** [Makefile:130: all] Error 2
Ran into a slight issue when compiling on opensuse 42.1. didnt get past the ./configure part in the compile. The following is the steps i took up to the point of the error. Note i did edit my computer username and hostname . Any suggestions are appreciated. Will try compiling on a ubuntu or debian based Arm Device as well.
~/bin> git clone https://github.com/patroclos/PAmix.git
Cloning into 'PAmix'...
remote: Counting objects: 464, done.
remote: Total 464 (delta 0), reused 0 (delta 0), pack-reused 464
Receiving objects: 100% (464/464), 124.46 KiB | 0 bytes/s, done.
Resolving deltas: 100% (268/268), done.
Checking connectivity... done.
~/bin> cd PAmix/
~/bin/PAmix> ls
configure.ac include LICENSE Makefile.am man pamix.conf README.md src
~/bin/PAmix> autoreconf -i
configure.ac:10: installing 'tools/install-sh'
configure.ac:10: installing 'tools/missing'
Makefile.am: installing 'tools/depcomp'
~/bin/PAmix> ./configure
configure: loading site script /usr/share/site/x86_64-unknown-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
./configure: line 2861: syntax error near unexpected token ac_ext=cpp' ./configure: line 2861:
ac_ext=cpp'
~/bin/PAmix>
build options and --version commandline argument, version injection etc
Hey, noticed 1.6 went up and now it's gone, which is causing builds to fail.
Please give option to hide monitors
Most similar apps can be closed by hitting the Escape key while pamix only responds to q
by default.
I've tried to configure this in pamix.conf
but couldn't figure out how to map that specific key to this action. Regardless, I think Escape should be supported by default.
./configure: line 2900: syntax error near unexpected token `,mandatory'
./configure: line 2900: `AX_CXX_COMPILE_STDCXX_11(,mandatory)'
This appears to be due to one of the first lines in ./configure.ac
.
Steps to reproduce:
q
in case of mpv)Fx
or to restart pamix.this issue is also listed on the AUR https://aur.archlinux.org/packages/pamix-git/ is this package going to be updated?
src/pamix.cpp:8:10: fatal error: ncursesw/ncurses.h: No such file or directory
#include <ncursesw/ncurses.h>
^~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [Makefile:569: src/pamix-pamix.o] Error 1
make[1]: Leaving directory '/home/coldfire/.cache/pacaur/pamix-git/src/PAmix'
make: *** [Makefile:350: all] Error 2
==> ERROR: A failure occurred in build().
Aborting...
:: failed to build pamix-git package(s)
Hello,
It seems the source for the aur release of Pamix needs to be updated to use https.
This is the output I get when trying to install it with Paru:
❯ paru pamix --verbose
1 community/pamixer 1.5-3 [0B 106.68KiB] [Installed]
Pulseaudio command-line mixer like amixer
2 aur/pamixer-git 20211011-1 [+69 ~0.00]
Pulseaudio command-line mixer like amixer
3 aur/ncpamixer 1.3.3.1-1 [+25 ~0.00]
ncurses PulseAudio Mixer
4 aur/ncpamixer-git a-3 [+10 ~0.00]
ncurses PulseAudio Mixer
5 aur/pamix-git 1.6.r10.gea4ab3b.0.gea4ab3b-1 [+4 ~0.00]
PAMix - the pulseaudio terminal mixer
:: Packages to install (eg: 1 2 3, 1-3):
:: 5
:: Resolving dependencies...
:: Calculating conflicts...
:: Calculating inner conflicts...
Aur (1) pamix-git-1.6.r10.gea4ab3b.0.gea4ab3b-1
:: Proceed to review? [Y/n]:
:: Downloading PKGBUILDs...
PKGBUILDs up to date
nothing new to review
fetching devel info...
error: failed to lookup: pamix-git: fatal: remote error:
The unauthenticated git protocol on port 9418 is no longer supported.
Please see https://github.blog/2021-09-01-improving-git-protocol-security-github/ for more information.
==> Making package: pamix-git 1.6.r10.gea4ab3b.0.gea4ab3b-1 (Sun 08 May 2022 10:22:10 AM)
==> Retrieving sources...
-> Cloning PAmix git repo...
Cloning into bare repository '/home/pvautour/.cache/paru/clone/pamix-git/PAmix'...
fatal: remote error:
The unauthenticated git protocol on port 9418 is no longer supported.
Please see https://github.blog/2021-09-01-improving-git-protocol-security-github/ for more information.
==> ERROR: Failure while downloading PAmix git repo
Aborting...
error: failed to download sources for 'pamix-git-1.6.r10.gea4ab3b.0.gea4ab3b-1':
error: packages failed to build: pamix-git-1.6.r10.gea4ab3b.0.gea4ab3b-1
The error points to this url for more information on the change.
Hopefully this is an easy fix!
Thank you for your time and efforts. Feel free to tell me if I can help out :)
So i tried compiling on Opensuse 13.2 64bit and ran into an issue when issuing the make command.
~/bin/PAmix> make g++ -Wall -O2 -std=c++11 -Iinclude -g -pthread -c src/pamix.cpp -o build/pamix.o g++ -Wall -O2 -std=c++11 -Iinclude -g -pthread -c src/painterface.cpp -o build/painterface.o g++ -Wall -O2 -std=c++11 -Iinclude -g -pthread -lncursesw -lpulse build/pamix.o build/painterface.o -o bin/pamix /usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: /lib64/libncursesw.so.5: undefined reference to symbol 'LINES' /usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../lib64/libtinfo.so: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status Makefile:20: recipe for target 'bin/pamix' failed make: *** [bin/pamix] Error 1
I will check to see if i have the devel for libtinfo as i know i have the ncurses devel files.
EDIT: Checked and that isnt it.
If you keep it running, eventually it uses 100% CPU. Even if you don't touch anything.
Debian testing here
When pulseaudio shuts down or crashes we should display a message and try to reconnect
refer to repology for the list of repositories
This is all I get when running pamix in either bash or zsh:
pamix: src/painterface.cpp:67: PAInterface::PAInterface(const char*): Assertion `pa_context_connect(m_Context, __null, PA_CONTEXT_NOAUTOSPAWN, __null) == 0' failed.
zsh: abort LANG="C" pamix
pamix from debian sid, 1.6~git20180112.ea4ab3b-3
Both installed in 18.04 32-bit ubuntu via apt and by building 1.6.
Consumes all available memory (> 1 GB) within seconds.
I've been unable to bind the Tab key in PAmix, how can it be done?
Also I haven't found any command to cycle between tabs. Can it be added?
I find it a little confusing that volume control and signal displays are colored in the same colors. I guess this is only due to personal preference, though. Thus I wonder whether having configurable foreground colors for the individual parts of the bars could be beneficial?
A patch for bf4acb3 acting as a proof-of-concept is attached.
In case it looks good enough, it is of course also possible to apply it; in case it is easier to handle, I can of course alternatively try to open a pull request instead :)
Hi.
Apologies for the weird question: what font are you using in the screenshot ? I am asking as I can't find anything monospace with both U+1F512 ("LOCK") and U+1F507 ("SPEAKER WITH CANCELLATION STROKE") glyphs, but clearly you have!
Thank you.
pavucontrol shows the System Sounds
control permanently
(for the bell voulme for exmaple, that it configured so:
% cat .config/pulse/default.pa
.include /etc/pulse/default.pa
load-sample bell /usr/share/sounds/freedesktop/stereo/bell.oga
load-module module-x11-bell sample=bell
)
PAmix shows bell volume only during the short time of the bell, so it's impossible to modify.
Please add support to show track name, same as pavucontrol does.
Hi,
The current man page has one syntax error at the line 1 of the /man/pamix.1
file, the correct syntax for comments is \" <comment>
instead of /" <comment>
Regards
Sometimes it stops work and I see just a blank screen. PAmix doesn't crash, it continues to be running.
I don't know how to reproduce this. Just leave it working for a long time.
This should probably only cause a warning to be printed to the console similar to how vim deals
with bad configuration, where we have to press enter to confirm and then the program starts up.
I have a loopback connected to a null sink, like so:
pacmd load-module module-null-sink sink_name=screen_recording
pacmd load-module module-loopback source=screen_recording.monitor source_dont_move=true sink=alsa_output.hw_au8830_0 sink_dont_move=true
When I do that, GDB says:
#0 0x0000003878481f66 in strlen () from /lib64/libc.so.6
No symbol table info available.
#1 0x000000000040bea6 in SourceOutputEntry::update(pa_source_output_info const*) ()
No symbol table info available.
#2 0x0000000000411e84 in PAInterface::cb_source_output_info(pa_context*, pa_source_output_info const*, int, void*) ()
No symbol table info available.
#3 0x00007ffff7d9e4cd in context_get_source_output_info_callback (pd=pd@entry=0x7fffec0015e0,
command=command@entry=2, tag=tag@entry=10, t=t@entry=0x7fffec002790, userdata=userdata@entry=0x6bc830)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulse/introspect.c:1348
cb = <optimized out>
i = {index = 72, name = 0x7fffec00f260 "Loopback to Vortex 2 (Montego II)", owner_module = 17,
client = 4294967295, source = 3, sample_spec = {format = PA_SAMPLE_S16LE, rate = 44100,
channels = 2 '\002'}, channel_map = {channels = 2 '\002', map = {PA_CHANNEL_POSITION_FRONT_LEFT,
PA_CHANNEL_POSITION_FRONT_RIGHT, PA_CHANNEL_POSITION_MONO <repeats 30 times>}}, buffer_usec = 0,
source_usec = 0, resample_method = 0x7fffec00f2af "speex-float-1",
driver = 0x7fffec00f2be "module-loopback.c", proplist = 0x7fffec010470, corked = 0, volume = {
channels = 2 '\002', values = {65536, 65536, 0 <repeats 30 times>}}, mute = 0, has_volume = 1,
volume_writable = 1, format = 0x7fffec00c000}
corked = false
volume_writable = true
mute = false
has_volume = true
o = 0x6bc830
eol = 1
__func__ = "context_get_source_output_info_callback"
__PRETTY_FUNCTION__ = "context_get_source_output_info_callback"
#4 0x00007ffff7b451a2 in run_action (pd=pd@entry=0x7fffec0015e0, r=0x7fffd8000a20, command=2,
ts=ts@entry=0x7fffec002790)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulsecore/pdispatch.c:288
callback = 0x7ffff7d9e127 <context_get_source_output_info_callback>
userdata = 0x6bc830
tag = 10
__func__ = "run_action"
__PRETTY_FUNCTION__ = "run_action"
#5 0x00007ffff7b4554f in pa_pdispatch_run (pd=0x7fffec0015e0, packet=packet@entry=0x7fffd0000950,
ancil_data=ancil_data@entry=0x7fffec000c48, userdata=userdata@entry=0x6bdbe0)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulsecore/pdispatch.c:341
r = <optimized out>
tag = 10
command = 2
ts = 0x7fffec002790
ret = -1
pdata = <optimized out>
plen = 4619
__func__ = "pa_pdispatch_run"
__PRETTY_FUNCTION__ = "pa_pdispatch_run"
#6 0x00007ffff7d93bd7 in pstream_packet_callback (p=<optimized out>, packet=0x7fffd0000950,
ancil_data=0x7fffec000c48, userdata=0x6bdbe0)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulse/context.c:349
c = 0x6bdbe0
__func__ = "pstream_packet_callback"
__PRETTY_FUNCTION__ = "pstream_packet_callback"
#7 0x00007ffff7b4819f in do_read (p=p@entry=0x7fffec0009b0, re=re@entry=0x7fffec000b78)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulsecore/pstream.c:1012
d = <optimized out>
l = <optimized out>
r = <optimized out>
release_memblock = 0x0
__func__ = "do_read"
__PRETTY_FUNCTION__ = "do_read"
#8 0x00007ffff7b4ac2b in do_pstream_read_write (p=p@entry=0x7fffec0009b0)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulsecore/pstream.c:248
__func__ = "do_pstream_read_write"
__PRETTY_FUNCTION__ = "do_pstream_read_write"
#9 0x00007ffff7b4b04c in srb_callback (srb=0x7fffec00af80, userdata=0x7fffec0009b0)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulsecore/pstream.c:287
b = <optimized out>
p = 0x7fffec0009b0
__func__ = "srb_callback"
__PRETTY_FUNCTION__ = "srb_callback"
#10 0x00007ffff7b4b923 in srbchannel_rwloop (sr=sr@entry=0x7fffec00af80)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulsecore/srbchannel.c:190
No locals.
#11 0x00007ffff7b4b94b in semread_cb (m=<optimized out>, e=<optimized out>, fd=<optimized out>,
events=<optimized out>, userdata=0x7fffec00af80)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulsecore/srbchannel.c:210
sr = 0x7fffec00af80
#12 0x00007ffff7da7848 in dispatch_pollfds (m=m@entry=0x6bc3e0)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulse/mainloop.c:655
e = 0x7fffec00b030
r = 0
k = 1
__func__ = "dispatch_pollfds"
__PRETTY_FUNCTION__ = "dispatch_pollfds"
#13 0x00007ffff7da900a in pa_mainloop_dispatch (m=m@entry=0x6bc3e0)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulse/mainloop.c:898
dispatched = 0
__func__ = "pa_mainloop_dispatch"
__PRETTY_FUNCTION__ = "pa_mainloop_dispatch"
#14 0x00007ffff7da9119 in pa_mainloop_iterate (m=m@entry=0x6bc3e0, block=block@entry=1, retval=retval@entry=0x0)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulse/mainloop.c:929
r = 1
__func__ = "pa_mainloop_iterate"
__PRETTY_FUNCTION__ = "pa_mainloop_iterate"
#15 0x00007ffff7da915e in pa_mainloop_run (m=0x6bc3e0, retval=retval@entry=0x0)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulse/mainloop.c:944
r = <optimized out>
#16 0x00007ffff7db7bc4 in thread (userdata=0x6bc3a0)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulse/thread-mainloop.c:100
m = 0x6bc3a0
mask = {__val = {18446744067267100671, 18446744073709551615 <repeats 15 times>}}
prev_mask = {__val = {0, 206158430211, 0, 2, 4, 64, 0, 206158430210, 0, 0, 472446402651, 0, 0,
532575944823, 242533679104, 140737152811040}}
sa = {__sigaction_handler = {sa_handler = 0x0, sa_sigaction = 0x0}, sa_mask = {__val = {
0 <repeats 16 times>}}, sa_flags = 0, sa_restorer = 0x0}
#17 0x00007ffff7b5a8e7 in internal_thread_func (userdata=0x6bc590)
at /var/tmp/portage/media-sound/pulseaudio-10.0/work/pulseaudio-10.0/src/pulsecore/thread-posix.c:81
t = 0x6bc590
__func__ = "internal_thread_func"
__PRETTY_FUNCTION__ = "internal_thread_func"
#18 0x00000038788072e6 in start_thread () from /lib64/libpthread.so.0
No symbol table info available.
#19 0x00000038784ea59f in clone () from /lib64/libc.so.6
No symbol table info available.
This happens when pulseaudio is not running, but at the same time happens when pavucontrol is able to connect to pulse audio. I am happy to help debug exactly when this happens.
When running speaker-test
I found out that occasionally, pamix
will hang at a black screen i.e. no longer update the display and also no longer react to input (except CTRL-C, CTRL-\ to quit the program). Upon debugging this with valgrind, I get the following output:
==20675== Invalid read of size 8
==20675== at 0x4A68487: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==20675== by 0x155A94: pamix_ui::getEntryDisplayName[abi:cxx11](Entry*) (pamix_ui.cpp:207)
==20675== by 0x155145: pamix_ui::redrawAll() (pamix_ui.cpp:116)
==20675== by 0x15117B: main (pamix.cpp:249)
==20675== Address 0x10 is not stack'd, malloc'd or (recently) free'd
As far as I can tell, it is related to the maps accessed from pamix_ui
being concurrently written to by painterface
or possibly by the data behind the pointers from the map being deleted/overwritten just while being processed in pamix_ui
.
speaker-test
is not reliable in reproducing this issue, however, I found a means to reproduce it within less than a minute here (running two concurrent pamix
instances increases chances of the problem to appear, running more than four concurrently seems to reduce the chance as processing slows down..)
Steps to reproduce:
test.wav
with just about a second of content.pamix
in a terminalwhile true; do mpv test.wav; done
in another terminalExpected behaviour: New outputs will appear in pamix for short time and then vanish in short sequence. Pamix is expected to continue to function.
Observed behaviour: After some point, the terminal with pamix
blackens and no further interaction with pamix
is possible. Stopping the loop of mpv
process does not recover pamix
.
Suggested fix:
(a) Use locking for concurrent read-write accesses (not only for write-write as it seems to be at the moment?) or
(b) switch to concurrent data structures. I am not much of a C++ expert and I do not understand the idea behind the various locks in painterface.cpp
thus am not sure wheter I could come up with a patch...
I am currently using version bf4acb3 but the old version from Debian (1.6~git20180112.ea4ab3b-3) seems to be affected by this bug, too.
Edit: It can be reproduced with fbdb806 (dev), too.
I also found out that there is already an existing issue about it: #59
It'd be very helpful and make it easy to install on fedora and fedora like distros
#19 Still not resolved.
~/bin/PAmix> autoreconf -i
~/bin/PAmix> ./configure
configure: loading site script /usr/share/site/x86_64-unknown-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for style of include used by make... GNU
checking for g++... g++
checking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking dependency style of g++... gcc3
checking whether g++ supports C++11 features by default... no
checking whether g++ supports C++11 features with -std=gnu++11... yes
checking whether we are using the GNU C++ compiler... (cached) yes
checking whether g++ -std=gnu++11 accepts -g... (cached) yes
checking dependency style of g++ -std=gnu++11... (cached) gcc3
checking --enable-unicode argument... yes
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for NCURSES... no
configure: error: Package requirements (ncursesw) were not met:
No package 'ncursesw' found
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
Alternatively, you may set the environment variables NCURSES_CFLAGS
and NCURSES_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
~/bin/PAmix> sudo zypper search --provides ncursesw
Loading repository data...
Reading installed packages...
S | Name | Summary | Type
--+-------------------+--------------------------+--------
i | libncurses5 | The New curses Libraries | package
i | libncurses5-32bit | The New curses Libraries | package
i | libncurses6 | The New curses Libraries | package
i | libncurses6-32bit | The New curses Libraries | package
Sometimes, when aggressively resizing the terminal, the application will clear it's screen and become unresponsive.
This seems related to #43, as the screen gets cleared before the loss of control.
What the title says. This is on the latest release version of pamix.
maybe this could be related to the autospawn setting
Can you get an even higher input level than the 10dB boost that the tool provides? Thank you!
please add support to change volume by 1 percent
When no pulseaudio is running and PAmix is being started the whole terminal turns blank and no key event seems to work. Pressing q
to quit PAmix has no effect. Only pressing CTRL+C
exits PAmix. Please let PAmix exit gracefully when it cannot find or connect to any pulseaudio instance/daemon preferrably with a user-friendly (error)message.
The program works flawlesly but sound bar is not showing at all, instead is displaying '~_TR'
I don't know how to reproduce this, but it just crashes with the subject.
Sometimes pamix stops react on keyboard input; it's become impossible to change volume or mute; while it continues to show channels activity (so this issue dieefers from #59) and I need to kill and restart it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.