Giter Club home page Giter Club logo

tsynth-teensy4.1's Introduction

Teensy 4.1 based synthesizer using PJRC Audio Board and Audio Lib

Website: electrotechnique.cc

The pcb and front panel to build TSynth are available from Tindie with SMD 4067 multiplexers, 6N137 opto-isolator, capacitors and resistors fitted. The entire cost of parts to build TSynth will be around $99 if you buy components from the cheaper suppliers and the build time around two hours to solder. Plans for a 3D printed/laser cut enclosure are also available. Questions: [email protected]

Preset Patches

Format your SD card using the SD Association formatter. Copy all the presets straight on to the card with no other files or folders.

Instructions

The source code requires the latest Teensyduino from PJRC to compile. You also need CircularBuffer from Agileware and Adafruit_GFX, which are available in the Arduino Library Manager.

tsynth-teensy4.1's People

Contributors

aztorius avatar cdw2000 avatar electrotechnique avatar fab672000 avatar vipear avatar winder 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

tsynth-teensy4.1's Issues

Blank sccreen issue

I just finieshd building mine, I connect a USB cable to the Teesny4.1 or a USB cable to the USB connector on the board,, the display lihgts up, but it stays completely blank.
Any idea of what/where to troubleshoot?

Typo in voice1On? Re-Read please

In voic1One there is

voiceMixer1.gain(0, VELOCITY[velocitySens][velocity] * level);

In all other voices it is:

voiceMixer1.gain(1, VELOCITY[velocitySens][velocity] * VOICEMIXERLEVEL);

`
void voice1On(byte note, byte velocity, float level) {
keytracking1.amplitude(note * DIV127 * keytrackingAmount);
voices[0].note = note;
voices[0].timeOn = millis();
voiceMixer1.gain(0, VELOCITY[velocitySens][velocity] * level);
filterEnvelope1.noteOn();
ampEnvelope1.noteOn();
voices[0].voiceOn = 1;
if (glideSpeed > 0 && note != prevNote) {
glide1.amplitude((prevNote - note) * DIV24); //Set glide to previous note frequency (limited to 1 octave max)
glide1.amplitude(0, glideSpeed * GLIDEFACTOR); //Glide to current note
}
if (unison == 0)prevNote = note;
}

void voice2On(byte note, byte velocity, float level) {
keytracking2.amplitude(note * DIV127 * keytrackingAmount);
voices[1].note = note;
voices[1].timeOn = millis();
voiceMixer1.gain(1, VELOCITY[velocitySens][velocity] * VOICEMIXERLEVEL);
filterEnvelope2.noteOn();
ampEnvelope2.noteOn();
voices[1].voiceOn = 1;
if (glideSpeed > 0 && note != prevNote) {
glide2.amplitude((prevNote - note) * DIV24); //Set glide to previous note frequency (limited to 1 octave max)
glide2.amplitude(0, glideSpeed * GLIDEFACTOR); //Glide to current note
}
if (unison == 0)prevNote = note;
}

`

BandLimitedWaveform step_table conflict and compiler note

Hallo Tsynth :)

Looks like the linker is failing with lots of duplicate symbols.

For example step_table:
You have defined in data_bandlimit_step.c.

But you are also using Audio librar and bringing in that same symbol, in it's data_bandlimit_step.c
I have renamed the table to data_bandlimit_step.c now.

Adding reverb?

I have no idea if there is processing power left and if it could be done easily, but it would be great a have a reverb effect available globally in the setting maybe?

What a cool sounding synth! (happy builder from just yesterday)

teensy 4.1 usb client wires pads

Note to be extra careful when soldering the USB jumper wires to the Teensy 4.1 D+ and D- pads. Compared to previous Teensy boards, the 4.1 pads are tiny and very weak. any movement of the wires will likely result in the pads pulling off.

parts_placement_teensy41_bottom
parts_placement_teensy41_top
schematic41

Make sure audio objects are created in order

I was reading about the audio connections here:
https://www.pjrc.com/teensy/td_libs_AudioConnection.html

At the end it says:

Audio objects should be created in the order data is processed, inputs, playback and synthesis, then effects, filters, mixers, and lastly outputs.

Connections are most efficient when made from an earlier object (in the order they are created) to a later one. Connections from a later object back to an earlier object can be made, but they add a 1-block delay and consume more memory to implement taht delay.

Most of the objects at the top of AudioPatching.h are not used until the end of the processing, so they should probably be rearranged.

11th Voice not working ??

Today I tried the Master-MT branch (9298d69) and I just played 1 note several tie and I realized that every 11th note was missing. I see on the voice grid that it is always the same voice (11th) which is missing. Could someone try if they have the same problem with this build ?

Unable to Compile Firmware v2.33

I have the BLACKTAB display issue, so whenever a new firmware becomes available, I need to edit the ST7735Display.h file and recompile.

Running into the following issue when compiling for v2.33...

From the Teensyduino IDE

`Arduino: 1.8.13 (Mac OS X), TD: 1.53, Board: "Teensy 4.1, Serial + MIDI + Audio, 600 MHz, Faster, US English"

/var/folders/d5/5n5zgcmd6svfhnzwcqx2jjdc0000gn/T/arduino_build_91510/sketch/synth_waveform.cpp.o: In function BandLimitedWaveformTS::lookup(int)': **/var/folders/d5/5n5zgcmd6svfhnzwcqx2jjdc0000gn/T/arduino_build_91510/sketch/synth_waveform.cpp:526: undefined reference to step_table'
collect2: error: ld returned 1 exit status**

Using library Audio at version 1.3 in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/Audio
Using library SPI at version 1.0 in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/SPI
Using library Adafruit_GFX_Library at version 1.11.3 in folder: /Users/dwestbury/Documents/Tech_Stuff/Electronics/Arduino/libraries/Adafruit_GFX_Library
Using library Adafruit_BusIO at version 1.6.0 in folder: /Users/dwestbury/Documents/Tech_Stuff/Electronics/Arduino/libraries/Adafruit_BusIO
Using library Wire at version 1.0 in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/Wire
Using library SD at version 1.2.2 in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/SD
Using library MIDI at version 5.0.2 in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/MIDI
Using library USBHost_t36 at version 0.1 in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/USBHost_t36
Using library TeensyThreads at version 1.0.1 in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/TeensyThreads
Using library CircularBuffer at version 1.3.3 in folder: /Users/dwestbury/Documents/Tech_Stuff/Electronics/Arduino/libraries/CircularBuffer
Using library Encoder at version 1.4.1 in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/Encoder
Using library Bounce in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/Bounce (legacy)
Using library ADC at version 8.0 in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/ADC
Using library EEPROM at version 2.0 in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/EEPROM
Using library SerialFlash at version 0.5 in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/SerialFlash
Error compiling for board Teensy 4.1.
`

Potentiometers

Information about the potis is quite cluttered. Maybe just put in the exact Type(s)?

Splined ALPS RVXX seems to be have a "K" (KNOB) in the end i.e RVXXK for splined axle

The "15mm long shaft" is not a measurement in the most drawings. Do you mean "L" (LM1 in ALPS drawings)? Or the part of the splined Axle? Or really the lenght of the axle without the housing?

error: ordered comparison of pointer with integer zero ('char* (*)(const char*, int)' and 'int')

Trying to verify this project and getting this error and another one. Some info

  • Arduino IDE 2.2.1
  • Teensyduino 1.58.1
  • Using latest main commit e2fd7cd
  • Arduino IDE Tools Settings:
    • Board: "Teensy4.1"
    • USB Type: "Serial + MIDI + Audio"
    • CPU Speed: "600MHz"
    • Optimize: "Faster"
  • CircularBuffer - AgileWare: 1.3.3
  • Adafruit GFX Library: 1.11.8
  • Windows 11

Full error message:

C:\TSynth-Teensy4.1\TSynth\effect_ensemble.cpp: In member function 'int16_t AudioEffectEnsemble::interpBuffer(float)':
C:\TSynth-Teensy4.1\TSynth\effect_ensemble.cpp:267:16: error: ordered comparison of pointer with integer zero ('char* (*)(const char*, int)' and 'int')
  267 |   else if(index<0) index2+=ENSEMBLE_BUFFER_SIZE;
      |           ~~~~~^~
In file included from C:\TSynth-Teensy4.1\TSynth\Audio.h:67,
                 from C:\TSynth-Teensy4.1\TSynth\TSynth.ino:48:
C:\TSynth-Teensy4.1\TSynth\synth_dc.h: In member function 'void AudioSynthWaveformDcTS::amplitude(float, float)':
C:\TSynth-Teensy4.1\TSynth\synth_dc.h:118:17: error: 'void AudioSynthWaveformDcTS::amplitude(float, float)' causes a section type conflict with 'int compare(const void*, const void*)'
  118 |   FLASHMEM void amplitude(float n, float milliseconds) {
      |                 ^~~~~~~~~
In file included from C:\TSynth-Teensy4.1\TSynth\TSynth.ino:60:
C:\TSynth-Teensy4.1\TSynth\PatchMgr.h:74:14: note: 'int compare(const void*, const void*)' was declared here
   74 | FLASHMEM int compare(const void *a, const void *b) {
      |              ^~~~~~~

Sustain Pedal support

There is a Midi cc# 64 which is mostly used for sustain pedals.

I was able to hack that in. However as I am not digged deep into the code I just made a proof that I am more a hacker than a developer. I just setting release to the decay value when the pedal is pressed. And restore it when released. This works for the piano type sound (well Rhodes) besides that I did not manage to stop the releasing when the pedal is left off (allNotesOff(); seems not to do it) so I use closeEnvelopes(); but that just cuts (ok for me here).

Of course a Hold should put the envelopes into the Decay phase I guess. I only can imagine that this could be done by not sending NoteOff()s but I did not found a way to do it right now.

The other thing in this context is that maybe a hardware port for a sustain pedal should be supported? I think this is a nice thing to have for a 12 voices synth.

[SOLVED] Display Image is Skewed on ST7735

Has anyone experienced a skewed image on their LCD display?

IMG_2044

The display doesn't appear to have any physical adjustments, so wondering if there's a way to fix this within the code?

Using library Audio at version 1.3...
Using library SPI at version 1.0...
Using library Adafruit_GFX_Library at version 1.6.1...
Using library Wire at version 1.0...
Using library SD at version 1.2.2...
Using library MIDI at version 5.0.2...
Using library USBHost_t36 at version 0.1...
Using library TeensyThreads at version 1.0.1...
Using library CircularBuffer at version 1.3.3...
Using library Encoder at version 1.4.1...
Using library Bounce...
Using library ADC at version 8.0...
Using library EEPROM at version 2.0...
Using library SerialFlash at version 0.5...
Using library Adafruit_BusIO at version 1.6.0...

-Darrell

Loss of voices 10 & 11 (also 9)

Voices 10 and 11 are lost and sometimes 9. Difficult to reproduce but occurs enough times to be a concern. Panic and patch changing doesn't solve.

Oscilloscope updating speed

Oscilloscope function needs more work to make updates faster. It's slowed by the zero crossing code that only updates when zero is crossed from positive to negative and then there is a delay while it looks for this again.

Would be nice to get it as good as Korg 'logue synths, with x-axis scaling to show whole waveform.

PRIORITY - Crashes

Seem to be getting crashes, usually when changing patches. Could be on accessing SD card and loading patch data. Teensyduino 1.54 has improved SD card performance (Bill Greiman's SdFat library).

Never saw these crashes on T3.6 (PCB rev 1.1), but the code is different!

SD card features

I am still waiting for my parts to arrive, so it might be an obvious thing, but: what kind of features require SD card? I see that provided presets take only 16k of space so any card size would be ok and speed rating does not matter at all? Also, can SD card files be accessed via USB or would I need to disassemble the case to insert/remove the card?

[Solved] Error compiling for board Teensy 4.1

Can't seem to get the Teensyduino sketch to compile?

IDE Tools Settings: (all confirmed)
Board: "Teensy4.1"
USB Type: "Serial + MIDI + Audio"
CPU Speed: "600MHz"
Optimize: "Faster"

Am I using all the right library versions?

`
collect2: error: ld returned 1 exit status

Using library Audio at version 1.3...
Using library SPI at version 1.0...
Using library Adafruit_GFX_Library at version 1.10.2...
Using library Wire at version 1.0...
Using library SD at version 1.2.2...
Using library MIDI at version 5.0.2...
Using library USBHost_t36 at version 0.1...
Using library TeensyThreads at version 1.0.1...
Using library CircularBuffer at version 1.3.3...
Using library Encoder at version 1.4.1...
Using library Bounce...
Using library ADC at version 8.0...
Using library EEPROM at version 2.0...
Using library SerialFlash at version 0.5...
Using library Adafruit_BusIO at version 1.6.0...

Error compiling for board Teensy 4.1.
`

Remembering last Patch used

I tink it would be a good idea to start with the last patch used (at least for me)

I hacked(!) this and it somehow works :) No cleanup and this language is way out of my comfort zone...

master...callimero:Carsten

Things:

  • After start the last patch is showed and works, however the list is not updated, so turning the Encoder switches to 1 or 3 I think
  • Massive writing to EEprom should be avoided right? So there needs to be a mechanism to detect if the patch is not changed some time and only then write to eeprom, so scrollng through the list is not writing constantly to eeprom
  • Should there be a Setting to enable this functionality

First Voice in Unisono Mode 1

I have a question about Unisono Mode1 in TSynth 4.1. In the old Firmware (Version 2.00 ) you don't use DETUNE for the 1st voice. The Oscillator Frequency for Midi Note A4 is always 440Hz.

Firmware 2.00
void updateVoice1() { if (unison == 1) { waveformMod1a.frequency(NOTEFREQS[voices[0].note + oscPitchA]); waveformMod1b.frequency(NOTEFREQS[voices[0].note + oscPitchB] * (detune + ((1 - detune) * DETUNE[notesOn - 1][1]))); } else if (unison == 2) { waveformMod1a.frequency(NOTEFREQS[voices[0].note + oscPitchA + CHORD_DETUNE[0][chordDetune]]) ; waveformMod1b.frequency(NOTEFREQS[voices[0].note + oscPitchB + CHORD_DETUNE[0][chordDetune]] * CDT_DETUNE); } else { waveformMod1a.frequency(NOTEFREQS[voices[0].note + oscPitchA]); waveformMod1b.frequency(NOTEFREQS[voices[0].note + oscPitchB] * detune); } }

In the latest firmware version 2.33, the oscillator frequency for the 1st voice changes with the DETUNE.

Firmware 2.33
` void updateVoice(VoiceParams &params, uint8_t notesOn) {
Patch& osc = this->patch();

        if (params.unisonMode == 1) {
            int offset = 2 * this->index();
            osc.waveformMod_a.frequency(NOTEFREQS[this->_note + params.oscPitchA] * (params.detune + ((1 - params.detune) * DETUNE[notesOn - 1][offset])));
            osc.waveformMod_b.frequency(NOTEFREQS[this->_note + params.oscPitchB] * (params.detune + ((1 - params.detune) * DETUNE[notesOn - 1][offset + 1])));
        } else if (params.unisonMode == 2) {
            // TODO: This approach doesn't make sense with voices spread across multiple timbres.
            osc.waveformMod_a.frequency(NOTEFREQS[this->_note + params.oscPitchA + CHORD_DETUNE[this->index()][params.chordDetune]]) ;
            osc.waveformMod_b.frequency(NOTEFREQS[this->_note + params.oscPitchB + CHORD_DETUNE[this->index()][params.chordDetune]] * CDT_DETUNE);
        } else {
            osc.waveformMod_a.frequency(NOTEFREQS[this->_note + params.oscPitchA]);
            osc.waveformMod_b.frequency(NOTEFREQS[this->_note + params.oscPitchB] * params.detune);
        }
    }`

The base frequency of oscillator 1 in voice 1 (440 Hz) changes with the DETUNE setting. Is that correct ?

Greetings from germany and have a nice time :)

Pots

It looks like all the pots are used as voltage dividers so 100k pots should work just as well right?
I ask in Issues because I have 100+ 100k RV09s on hand and zero in 33k, and I suspect that others who usually work in the Kosmo synth format likely also have a bunch of 100k RV09s, so it would be nice for everyone to be able to see an answer.

Thanks!

What features are possible?

Sorry for the vague open-ended question, let me explain. I'm a programmer by day with some electronics and audio hobbies, recently I've been interested in playing with different sounds and stumbled upon the TSynth project. Looking at the code as a software developer I see a lot of opportunity for additional features (i.e. arpeggiator, mono mode + note priorities, etc).

If I spent the time on the code, what sort of features could the teensy handle it? An arpeggiator? What about a split mode?

In general, if you had all the time and inspiration in the world, what other features would be possible/reasonable?

I'm new to this hobby, so I was specifically looking at what some other polysynths have, like the Korg Minilogue:

100 Ohm Resistor on Display SCK is Not Eliminating Audio Noise?

I was hearing the popping and static noise that others were complaining about, so I went ahead and cut the PCB trace for the display clock (SCK) and added in a 100 Ohm resistor as noise reduction bridge, but to my ears there's nearly no difference?

IMG_2111

Curious whether any other potential sources of noise are being investigated? In my case it's not terrible, but it is clearly perceptible.

No USB-MIDI on Mac?

I can program the Teensy of my TSynth using the latest .hex (2.10) successfully.
When I connect the Teensy to my PC, it is seen as a MIDI device and I can play it using MIDI-USB.
On Mac (High Sierra) , the TSynth is NOT seen as a MIDI device but as an Audio device (?!?!?)
(I am simply connecting the Tsynth using the Micro-USB port on the Teensy...)
Using the 5-pin DIN Connector for MIDI works on both platforms.

Feature Request: ability to select screen "type" without uploading different versions of firmware

I was thinking about a method of configuring the display during initial boot instead of having to upload different versions of the firmware.

There are three buttons below the display: "Settings", "Save", and "Back" and to the right of the display is the rotary encoder which has the ability to be pressed to "confirm" a selection.

Binary math provides us with eight (8) different "settings" on power-up:

   3 2 1*
0: 0 0 0 no buttons pressed power-up == no state change
1: 0 0 1 default
2: 0 1 0
3: 0 1 1
4: 1 0 0
5: 0 1 0
6: 1 1 0
7: 1 1 1

*Buttons:
1 == Settings
2 == Save
3 == Back

On initial boot-up, what if the three buttons were used to select one of seven possible screen settings (not that there are 7 current display setting possibilities, but there is the ability to select that many different config options on initial power-up).

Here is my pseudo code:

1. If any of the three buttons are pressed on power-up: 
   a. based on the button pressed, choose the configuration setting and configure display
   b. initialize screen with setting chosen
   c. on the display, ask confirmation question "Is display correct/viewable?"
      1. 10 second loop count down
      2. during loop, press down on rotary to confirm
      3. If rotary pressed down, 
         a. if SD card exists, then
            1. create file screen setting (or write-over existing file)
            2. write screen configuration setting (assumes one file used the screen setting)
            3. close file
         b. else exit loop & continue
      4. after 10 second loop (rotary never pressed), continue  w/o saving
         (perhaps the logic could it loop into a sequence where you can try another key combo,
          or would it be better to revert to the "default" screen config and continue booting?)

3. if no buttons pressed on initial power-up
   a. look for config file on SD card for screen configuration file
   b. if file found
       1. parse contents
       2. validate setting:
          a. if valid, set screen config to setting chosen
          b. if invalid, use "default" screen setting (from a previously set constant variable)
          
4. On boot, the initial 'splash-screen' would display the screen-configuration selected.

Held note silenced

Hold voice 1 and play 12 notes. Instead of taking a no longer held voice, it steals voice1 and silences it.
Originally posted by @biamau962 in #135

Cheap ST7735 Color display issues

If a display that appears to be compatible is used, but purchased from inexpensive vendors, such as Aliexpress, there could be malfunction issues. I was able to fix all the problems by making a small change to some definitions in a couple of files.

The first problem is a 1 pixel shift that bends the image. To fix this problem, I modified the function: ST7735_t3::initR in the file: ST7735_t3.cpp

if (options == INITR_GREENTAB) {
commandList(Rcmd2green);
_colstart = 2;
_rowstart = 0; // modified from 1 to 0 by Davide Gatti to fix cheap display

A second problem is the color inversion, to fix this I modified two define in the file: ST7735_t3.h

#define ST7735_INVOFF 0x21 // Changed from 20 to 21 By Davide Gatti for cheap display
#define ST7735_INVON 0x20 // Changed from 21 to 20 By Davide Gatti for cheap Display

These 2 simple changes fixed the compatible display.

AudioProcessorUsageMax() with new exp envelope

Hallo Tsynt

I use the exp envelopes and read AudioProcessorUsageMax() It increases with each note. I can not be reset with AudioProcessorUsageMaxReset(). If I load another patch, the AudioProcessorUsageMax() drops again.
If I set set EnvType() to -128 it works correctly.

// CPU Audio Memory --------------------------------------------------- if ((millis() - timer_CPUmon) > 500){ CPUaudioMem = AudioMemoryUsageMax(); printCPUmon(); AudioMemoryUsageMaxReset(); }

Can you still build one of these for $99?

The README says it costs $99 to build, but stuff can't find singles of PCB or Front Panel. Does anyone know how to build less than the $355 for the full tindie kit.

Release is "weird"

Sorry for the fuzzy title.

The release seems to end a bit sudden especially when using relative short release times (0.2-1.0s). It seems then the release is maybe linear and that gives the ear the sudden end. Which does not sound natural.

I compared it with my other synths and there it seems more exponential leading to a smoother end.

When using a longer release (>2s or so) it is better. Havn't looked at the code, maybe it is in the audio lib?

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.