Git Product home page Git Product logo

sigmadsp's Introduction

SigmaDSP

SigmaDSP is an intuitive library used for controlling an Analog Devices Sigma DSP over i2c using an Arduino or an Arduino compatible board.

Table of contents

What is SigmaDSP and why do we need a library for it?

SigmaDSP is a product lineup of programble DSPs for audio use by Analog Devices Inc. SigmaDSPs are known for their easy to use programming environment SigmaStudio, where the firmware is built in a graphical enviroment where you add "blocks" or "modules" to the program flow. Such blocks may be volume sliders, EQs, signal generators and so on. This is great if you want to get started quickly, but sadly Analog Devices have not focused on how to control these module parameters from external devices. Some of the "modules" are even based on closed source alorithms and will (most likely) never be possible to control outside of SigmaStudio.

On the other side many of the modules are fairly easy to reverse engineer, and control of these can therefore be implemented in a library like this. Thanks the enourmous effort the AidaDSP team have put into this reverse engineering. This library would have existed if it weren't for them.

Supported DSPs

Only the ADAU1701, ADAU1702 and ADAU1401 are supported.

Exporting a SigmaStudio project for use with the SigmaDSP library

Even though Analog Devices haven't focused much on external control over i2c it is possible to export the SigmaStudio project. This result in a bunch of header files where important data and parameter macros are spread across these files. This makes it a pain to keep track of everything.

To solve this issue I've created a script that extract the necessary information in these files and formats it into a single header file that can be used with this library. I call this script DSP_parameter_generator. Windows users may use the PowerShell version (DSP_parameter_generator.ps1), while Mac and Linux users may use the shell version (DSP_parameter_generator.sh).

The parameter generator script

First let's talk about what this script expects in order to function properly. The SigmaDSP does not contain a non-volatile memory, so the entire program must be loaded into RAM on boot. If the DSP is power cycled or gets reset, the program must be loaded again. This loading can be done in two ways and this library support both. See the examples on how this may be implemented.

  • The first option is to store the entire DSP program in the microcontroller flash memory. The microcontroller will have to load the program over i2c when the DSP is powered or resat.
  • The other option is to use an external i2c EEPROM memory such as the 24C64. SigmaDSPs are able to load frimware from an external i2c EEPROM into RAM on the condition that the EEPROM i2c address is known and the physical SELFBOOT pin on the DSP is tied high.

There are some rules you need to follow in order for the script to work as intended:

  • The DSP in the SigmaStudio project must be called IC 1
  • The i2c EEPROM in the SigmaStudio project (if present) must be called IC 2
  • DO NOT edit any of the exported files. The script depends on lines and spaces from the exported files. Editing any of the files may cause the script to malfunction.

Exporting a SigmaStudio project

This guide assumes you created your project based on the 0_Template project file, which is a blank project with a few pre-configured settings.

  • Start out by adding all the blocks you want in your project
  • Locate your SigmaStudio project folder. Open this and create a folder called export
  • (Skip this step if not using EEPROM) Open the Hardware configuration tab and add an external EEPROM device by draging the E2PROM symbol into the work space and connect it to USBi's second wire connector. Make sure the EEPROM size and address matches the actual address of the EEPROM. The EEPROM module has to be named IC_2!
  • Compile the project by clicking the Link Compile Download button Link Compile Download
  • Click the diskette icon and store the files in the export folder you just created Diskette icon
  • In the Hardware Configuration tab, right click on the SigmaDSP (called IC_1) and select the option "Write Latest Compilation to EEPROM. Don't worry if you get any connection error messages, we're only looking for the generated files.
  • Open the project folder again and move the subfolder called [project name]_IC_2 into export.
  • Copy the script (DSP_parameter_generator.ps1 or .sh) into the Arduino project folder

Now the project files are ready to be handled by the DSP parameter generator script. Continue reading for more information on how this is done.

Executing the parameter generator script

As already mentioned, this script has to be placed in the Arduino project folder. It will search for exported project files in the same folder or in any subdirectory. A recommended folder structure for your Arduino project looks something like this:

My_Arduino_DSP_Project/
  ↳ My_Arduino_DSP_Project.ino
  ↳ DSP_parameter_generator.sh
  ↳ DSP_parameter_generator.ps1
  ↳ [SS_projectName]/
    ↳ [SS_projectName].dspproj
    ↳ export
      ↳ [SS_ProjectName]_IC_1_PARAM.h
      ↳ [SS_ProjectName]_IC_1.h
      ↳ [SS_ProjectName]_IC_2.h
      ↳ E2Prom.Hex                    

Windows

Windows users may use the DSP_parameter_generator.ps1 PowerShell script. Simply double click the DSP_parameter_generator.ps1 file and it will output a header file in the same directory as the script is located. If you're not able to execute the scrit it may be because you'll have to enable execution of unsigned Powershell scripts. You can do this by seaching for Powershell, right clicking on it and select "Run as administrator". Then paste and run the following line:
set-executionpolicy remotesigned
Close the PowerShell window. You should now be able to run the script by double clicking it.

Mac/Linux

*NIX users may use the DSP_parameter_generator.sh script, which is built using bash and awk. Simply double click the DSP_parameter_generator.h file and it will output a header file in the same directory as the script is located. If you can't execute the script it may be because the file itself isn't executable. Open your terminal, cd into the directory where the script is located. Paste and run the following line:
chmod +x DSP_parameter_generator.sh
Close the terminal window. You should now be able to run the script by double clicking it.

sigmadsp's People

Contributors

bw3 avatar djamps avatar heapx avatar mcudude avatar sitrucl 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

sigmadsp's Issues

Question to safeload_write

Hello,

I want to write some own function for controlling the blocks into the dsp,bBut can't test this at the moment, so I am asking here before.
I don't understand correctly how to use the data block in safeload_write.

As example the mute-block. SigmaStudio says:
grafik
which of them is now the correct method?

  dsp.safeload_write(startMemoryAddress, 0x80 );
  dsp.safeload_write(startMemoryAddress, 0x00, 0x80, 0x00, 0x00 );
  dsp.safeload_write(startMemoryAddress, 0x00800000 );

Thanks and greet work with this library!
fmvoxa

Failing when compile with for ESP32

Hi, i've tried use the library with a ESP32 S3 and i'm got some compile erros of override ambiguity. I think the define that changes the parameter from uint16_t to int is unnecessary and without then the code compile successfully.

This code causes ambiguity error on call of the function "safeload_writeRegister" at line: 184

#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  void safeload_writeRegister(uint16_t memoryAddress, int16_t data, bool finished);
#else
  void safeload_writeRegister(uint16_t memoryAddress,     int data, bool finished);
#endif

Other question:
Using that library is capable of to read the signal in realtime to create a level meter with a Fourier transform?

Thanks so much.

I2C doesn't communicate with adau1401

I've tried to upload my sigmaDSP project to adau1401 AliExpress module in both selfboot and direct (from MCU) boot modes. The library returning that the device doesn't present (code 2).
I've made tests on teensy 4.0, the standard wire library didn't work (was returning code 4), then I've tried special library from teensy official webpage, and it's returning something like connection time over with the same code 4.
The I've switched to esp8266 using standard wire library and it's still nothing just code 2, device is not present...

Is there any ways to find out what's wrong?

Thank you

Linear volume option

Hi, could you please, add Slew volume linear option?
This will be very handy for balance left-right channels. Something like this:

void SigmaDSP::volume_slew(uint16_t startMemoryAddress, float dB, int mode, uint8_t slew)
{
	float volume;
	if ( mode == 0 ){
		volume = pow(10, dB / 20); // 10^(dB / 20)
	} else {
		volume = dB; // Direct value
	};
  
  int32_t slewrate = 0x400000 / (1 << (slew - 1)); // 0x400000/2^(slew - 1))

  safeload_write(startMemoryAddress, volume, slewrate);
}

I2C Scanner vs ee.ping()

I've been using the library successfully on several identical boards. During the startup sequence I issue an ee.ping() as a sanity check and halt if it returns non-zero.

I have one board in particular that is halting due to ee.ping returning 4. However I2C Scanner on the same board shows the EEPROM present at the usual address 50 with no error.

Any idea where to look or what to try? I realize this is probably nothing to do with your code.

Convert some of the functions from floating point to integer math

Since most low-end microcontrollers don't have a floating point unit built-in, working with floats is both slow and space hungry. With some clever programming, many of the functions provided in this library should be able to be converted into integer based functions.

@Jackjan4 you did a wonderful job with the millis() function in MCUdude_corefiles. Maybe you could help me out with a few examples? 🙂

Let's take a very simple function, a sine wave generator. At the moment it looks like this. Don't worry about the 0xff and 1.0 parameters. These are just needed parameters.

void SigmaDSP::sineSource(uint16_t startMemoryAddress, float frequency)
{
  float value = (1.00/24000.00)*frequency;
  
  safeload_write(startMemoryAddress, 0xff, value, 1.0);
}

The thing is that this DSP doesn't really need floats at all! before everything is sent to the DSP the data (value in this case) is multiplied by a bitshift, converted to an int32 and chopped up in 4 bytes.

The function above can be rewritten into this:

void SigmaDSP::sineSource(uint16_t startMemoryAddress, float frequency)
{
  float value = (1.00/24000.00)*frequency;
  int32_t converted_value = floatToInt(value);
  safeload_write(startMemoryAddress, 0xff, converted_value, 1.0);
}

int32_t SigmaDSP::floatToInt(float value)
{
  // Convert float 5.23 to int 28.0
  return (value * ((int32_t)1 << 23));
}

And, the 1.0 parameter could actually be replaced by the number 0x800000. In case you're wondering what kind of function safeload_write is, it is simply a template based function that calls one of these functions based on the parameters:

    void safeload_writeRegister(uint16_t memoryAddress, int32_t data, bool finished);
    void safeload_writeRegister(uint16_t memoryAddress, int16_t data, bool finished);
    void safeload_writeRegister(uint16_t memoryAddress, uint8_t data, bool finished);
    void safeload_writeRegister(uint16_t memoryAddress, float data, bool finished);

So the big question is: how can the function above be replaced with integer based math? Can the same bitshift magic be used here as well @Jackjan4?

EDIT:
If you don't know what a Sigma DSP is it is an audio DSP family from Analog Devices. The one this library is targeted at, the ADAU1701, is small (48-pin), cheap, versatile and easy to program through Analog Devices' SigmaStudio software. However they never really provided a good way of controlling this DSP using an external microcontroller. No API, only some exported arrays in a c file. IMO this is a terrible solution, so this is why this library exists.

48 FS question

Hi, I see FS = 48 in parameters.h, if that is a constant, does it mean that all the sigma studio blocks in your code are calculate coefficients for projects generated from sigma in 48kHz? If I'm wrong in that assumption, how and where this coefficients recalculated for different sampling rates, like 96kHz, 192kHz, etc? I'm asking because if I change parameters in sigma studio, for instance in Volume slew, I don't see any changes in values while change project sampling rates, but I see some changes in EQ Second Order, for instance. Is I change project sampling rate, I see different values in capture window in sigma. So, please, shed the light what happening under the hood of your code, is there anything what re-calculate those values for different sampling rates?

Control mono envelope peak?

Hi,
is there any way to control the mono envelope peak block? There isnt any function for ot I believe.
Cheers,
Jens

SigmaDSP with ESP32

Hello,

I am having problems compiling and loading any of the examples to ESP32. Arduino Uno and Nano works very well. However due to lack of memory in them I swapped to ESP32. Which now fails to compile.

`Arduino: 1.8.5 (Windows 10), Board: "DOIT ESP32 DEVKIT V1, 80MHz, 921600, None"

In file included from C:\Users***\Documents\Arduino\libraries\SigmaDSP-master\examples\1_Volume\1_Volume.ino:13:0:

C:\Users***\Documents\Arduino\libraries\SigmaDSP-master\src/SigmaDSP.h:145:10: error: 'void SigmaDSP::safeload_writeRegister(uint16_t, int, bool)' cannot be overloaded

 void safeload_writeRegister(uint16_t memoryAddress,      int data, bool finished) { safeload_writeRegister(memoryAddress, (int32_t)data, finished); }

      ^

C:\Users***\Documents\Arduino\libraries\SigmaDSP-master\src/SigmaDSP.h:143:10: error: with 'void SigmaDSP::safeload_writeRegister(uint16_t, int32_t, bool)'

 void safeload_writeRegister(uint16_t memoryAddress,  int32_t data, bool finished);

      ^

Using library SigmaDSP-master at version 1.0 in folder: C:\Users*\Documents\Arduino\libraries\SigmaDSP-master
Using library Wire at version 1.0.1 in folder: C:\Users*
\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\Wire
exit status 1
Error compiling for board DOIT ESP32 DEVKIT V1.`

I hope you can help me

Pin connections

Hi,

I am looking to this repo. I don’t see any images to connect those two devices. Is it available?

Thanks

Change FS while running

Hello, first of all a huge thanks for these joby ;)
Then i have a custom board with an ADAU1701, an esp12f as master, an stm32 as usb audio device and an si5153c as master clock reference.
The stm32 can change its own fs clock (in windows) and telling the esp12 the new FS
So the question is: how can i change the fs clock of the adau1701 in the code:
I've tried something like that:

      SigmaDSP dsp(Wire, DSP_I2C_ADDRESS, 48000.00f /*,12*/);
      SigmaDSP dsp2(Wire, DSP_I2C_ADDRESS, 44100.00f /*,12*/);

      setup() {
             Wire.begin();	    
             Init_Clock (); 
             dsp.begin();
             dsp2.begin();
             loadProgram(dsp);
             }

       switch (frame_rate){
		case 0 :
			pcf20.write(Pin_expander_ADAU,0);
			si5351.set_freq(1128960000ULL, SI5351_CLK1);
			delay(50);
			pcf20.write(Pin_expander_ADAU,1);
			delay(50);
			loadProgram(dsp2);
			
		break;

		case 1 :
			pcf20.write(Pin_expander_ADAU,0);
			si5351.set_freq(1228800000ULL, SI5351_CLK1);
			delay(50);
			pcf20.write(Pin_expander_ADAU,1);
			delay(50);
			loadProgram(dsp);	
		break;
                    }

But it's doesn't work ...

Compressor Example

I've been getting a lot out of your SigmaDSP library. I'd like to give something back.

The attached is SigmaDSP and MCU code for a compressor example. I am not a github maven, and I don't know how to submit it properly for release, but you surely do.

The functions in the .ino file would potentially replace your compressorRMS function, and operate a bit faster. The code also includes an example for creating a compression I/O curve that implements a one knob setting for curve, gain, etc..., based on the analog implementation by THAT corp.

Please let me know if these are useful, and feel free to redistribute.

CompressorMCU.zip

ADAU1467

Hello
Cool project. Is the library also compatible for ADAU1467 or is a corresponding adaptation planned?
Thx

Writing EEPROM bricks the DSP

Hello,

I have had good success so far, except for writing new EEPROMs. While using ee.writeFirmware(), the write appears a success (it no longer attempts writes until version is increased), however the DSP now fails to self boot. I have to hook up a EZ-USB and rewrite the EEPROM from Sigma Studio to restore the program. I made 100% sure nothing else on the I2C bus is interfering and DSP is held in reset during write.

I tried to dump copies of the good and bad EEPROM contents but while Sigma Studio displays them without issue, it refuses to write them to files for some reason. I have attached my project files, generated from Sigma Studio 4.6, so hopefully that is useful.

ghetto.zip

Using Mighty Core to create an ATmega32 bootloader for Adau1701

Would it be possible to program an ATmega32 (using MightyCore) as a bootloader for Adau1701?
I'm trying to bring to life a pair of Powersoft DigiMod 3004PFC4 amps with Powersoft DSP-D cards.
Powersoft offers a programming board which is both expensive and not supported in SigmaStudio any more.
The architecture of the DSP-D looks like this:
image

Seems like all the important pins are exposed:
image

Thank you!

noob guide

Hello if you have the time is it possible to make a video that explains it all

Thanks

Ps if you cant

can you send me the code for arduino to use the adau1701 for 3 way speaker system

and to use the potentiometers that are on the wondom board ( bass,mid,high,gain )

Use 2 output ADAU1701

Hi,

I'm using an ADAU1701 and I can't find how to set different parameters on output 1 and output 2.

Do I need to use writeRegister or something is already develop ?

Thanks

ESP32-C3

Hi is this library compatible with an ESP32-C3? Would like to control sigma studio parameters on an ADAU1701 through Bluetooth.

Additionally, does this library support changing FIR filter coefficients?
Thanks!

Trouble with Wondom / Sure Electronics DSP (ADAU1701)

I've stumbled upon your library and hooked up my Wondom DSP via I2C (the connector which usually goes to the USB programmer) to an ESP32. When I run a I2C scan, I can see a device at 0x50.

Afaic, the Wondom DSP has an EEPROM and can also start from bootstraping.
Question is: why do I only see 1 device on I2C and why do the examples report

Pinging i2c bus...
0 -> deveice is present
2 -> device is not present
DSP response: 2

To be sure, I've added 2 x 4.7k pull-ups to 3.3v.

ADAU1452 Support?

The ADAU1452 is a much more powerful DSP and I was wondering if there is a possibility to add support for it.

Crossover

hi, I need help how to control ADAU1701 crossover ?
thanks for respond..

Reducing memory usage

Is there a way to omit the DSP program data from the c headers? I'm currently self booting so it's really not needed, and the arduino's program memory is on a tight budget given the existing program in place. Ideally, I'd like to use this library for control of a few registers, but the parameter data is overflowing my memory. Thanks in advance.

Licensing

Hey there, me and my buddy are working with the ADAU1701 and arduino to do a senior project and stumbled across the SigmaDSP repo. We were wondering what your plan for licensing this code was since there is a small chance we could take or project to market. Thanks!

demux

Hey
great work I love to work with it
at the moment with an ttgo t-display and a adau1701 as preamp xover eq 3d
volume and input select MUX works perfect.

i am struggling with the demux syntax
its 1 2xn so 2 in 3 out

 dsp.demux(MOD_2XN_1_ALG0_STEREODEMUXSLEW10_ADDR, 1, 4); 
    dsp.demux(MOD_2XN_1_ALG0_STEREODEMUXSLEW11_ADDR, 0, 4);
    dsp.demux(MOD_2XN_1_ALG0_STEREODEMUXSLEW12_ADDR, 0, 4);

Can you explain howto use the parameters?

Thanks

Help cascading 2nd order filters to form 6th order filter

Hi,

I've been attempting to implement 6th order filters using this library but haven't had any success. I've attached a screenshot of my sigma program and I know the program works as I've tested it using SigmaDSP and a programmer.

image

I'm struggling to figure out how to initialise the stacked EQ bands within the code. Based on the examples I assumed I could do something along the lines of this for each half of my filter:

    dsp.EQsecondOrder(MOD_LOW_D_ALG0_STAGE0_B0_ADDR, Low_D);
    dsp.EQsecondOrder(MOD_LOW_D_2_ALG0_STAGE0_B0_ADDR, Low_D_2);
    dsp.EQsecondOrder(MOD_LOW_D_3_ALG0_STAGE0_B0_ADDR, Low_D_3);

image

image

However this hasnt worked as expected - the dsp just emits a high frequency sound and the occasional pop when trying to control it via an MCU (adjusting gain or muting the EQ bands) . Is anyone able to advise on how to proceed or see anything I've done wrong from the screenshots?

Let me know if I need to attach more info & thanks in advance

Please, add support for stm32duino

Hi. Since Arduino nano has not enough memory, I've got Black pill, with stm32duino support. With that configuration I could add different additional libraries like Adafruit for IPS screen for the musical center project without worrying of free memory (black pill stm32 has more that arduino nano with similar size and form). But somehow compillation finished with the errors. It doesn't like reusable functions with different type of arguments.
Good thing is that you don't need any black pull for the test. It fires the error even without connected stm32.
Thanks, Alex.

Implementing custom crossovers

Hi,

I've recently come across this library and it seems to be the ideal tool for attempting to create a hardware controlled variable cross over however I've been struggling to understand how I would go about implementing these blocks (see attached image) in code. My aim is to have an input split and then fed through 4 cross overs and have 4 outputs at the end

The generated dsp params file (zipped and attached below ) is a lot more complicated compared to the examples and Im not quite sure how to go about feeding one filter into another (cascading them).

Is anyone able to offer any help as to how I can implement my sigma studio project using this library? Is there a simpler way to achieve my objective with different sigma studio blocks?

Thanks in advance

image

SigmaDSP_parameters.zip)

Talk with two adau1701 simultaneously

Hi, im building a small mixer using a couple of adau1701 connected on the i2s and i2c bus as well,
is there any possibility to be able to talk with two (or more) adau1701 connected simultaneously on i2c bus in order to control different processing stages from each one? Regards.

Real time variable frequency adjustment of secondOrderEQ blocks

Hi all,

I've been attempting to adjust the frequency of the secondOrderEQ instance using a potentiometer however, doing so causes the DSP to not output anything other than a high pitched sound on one of the four DAC outputs. I'm aware that the MCU is having to perform several calculations (found within SigmaDSP::EQsecondOrder of SigmaDSP.cpp) for the coefficients but after logging out the results, it looks as though these are coming through as expected.

For context, I've got three 2nd order EQ blocks feeding into one another to form a 6th order eq

 dsp.EQsecondOrder(MOD_LOW_A_ALG0_STAGE0_B0_ADDR, Low_A);
 dsp.EQsecondOrder(MOD_LOW_A_2_ALG0_STAGE0_B0_ADDR, Low_A_2);
 dsp.EQsecondOrder(MOD_LOW_A_3_ALG0_STAGE0_B0_ADDR, Low_A_3);

image

When I use a fixed value for the frequency rather than the potentiometer value, things work as expected however I would ideally like to have the ability to adjust the frequency of the blocks in real time. Any thoughts and suggestions as to how this might be possible or what's causing my current issue?

Thanks in advance

example for dummies

Hi,
first of all thanks a lot for sharing your work with everyone.
Is there any example online which documents the whole process of including buttons or encoders on an arduino to control parameters? I know that this is a dumb question resulting of a lack of knowledge. Unfortunately I am more of a musician than a person who is able to program and would just be really happy to have a useable and especially computer independent unit (i am in the process of optimizing my studio and due to the lack of space i have to think of alternatives than huge porous absorbers to get room resonances under control - i want to use the 1701 with a mic attached to an active subwoofer for a kind of low frequency noise canceling system. Unfortunately this system needs a lot of trial an error to find the right spot for it to work, prevent feedback etc and this just isn't possible with a computer attached to it)

No "Tutorial_0"

Hello, I'm not sure if this is the appropriate place to post this, but the readme says

"This guide assumes you created your project based on the Tutorial_0 project file, which is a blank project with a few pre-configured settings."

Where is Tutorial_0?

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.