Comments (14)
added exact byte of wrap to the output.
Add this code just before push in GatherInputSamples
UInt32 remaining = usbRing->size - usbRing->writehead;
if (size >= remaining ) {
debugIOLog("input wrap in list %d at frame %d byte %ld",currentFrameList,frameIndex, remaining);
}
and this in EMUUSBOutputStrema as first statement in if(thisFrameSize >= nuBytesToBufferEnd)
:
debugIOLog("write wrap in usbframe %lld list %d byte %d",nextUsableUsbFrameNr,n,numBytesToBufferEnd );
Here is short part of the output (48kHz rate)
note, the 492 numbers indicate a matching pair of input/output wraps, notice that the input wrap in list 2 referred to can be found a bit higher in the list where the corresponding read was started.
Jan 12 21:50:59 vlieland kernel[0]: READ framelist 3 in framenr 41129284 at 42843674137372
Jan 12 21:50:59 vlieland kernel[0]: READ framelist 0 in framenr 41129348 at 42843738130412
Jan 12 21:50:59 vlieland kernel[0]: input wrap in list 1 at frame 21 byte 276
Jan 12 21:50:59 vlieland kernel[0]: READ framelist 1 in framenr 41129412 at 42843802140518
Jan 12 21:50:59 vlieland kernel[0]: write wrap in usbframe 41129348 list 0 byte 84
Jan 12 21:50:59 vlieland kernel[0]: READ framelist 2 in framenr 41129476 at 42843866128146
Jan 12 21:50:59 vlieland kernel[0]: READ framelist 3 in framenr 41129540 at 42843930130317
Jan 12 21:50:59 vlieland kernel[0]: input wrap in list 0 at frame 0 byte 108 <------ difference 24 ------
Jan 12 21:51:00 vlieland kernel[0]: write wrap in usbframe 41129476 list 42 byte **492**
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 0 in framenr 41129604 at 42843994143594
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 1 in framenr 41129668 at 42844058125664
Jan 12 21:51:00 vlieland kernel[0]: input wrap in list 2 at frame 42 byte **492** (41129476)
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 2 in framenr 41129732 at 42844122129566
Jan 12 21:51:00 vlieland kernel[0]: write wrap in usbframe 41129668 list 21 byte 300
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 3 in framenr 41129796 at 42844186139679
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 0 in framenr 41129860 at 42844250128222
Jan 12 21:51:00 vlieland kernel[0]: input wrap in list 1 at frame 21 byte 300
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 1 in framenr 41129924 at 42844314133596
Jan 12 21:51:00 vlieland kernel[0]: write wrap in usbframe 41129860 list 0 byte 108
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 2 in framenr 41129988 at 42844378123573
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 3 in framenr 41130052 at 42844442138839
Jan 12 21:51:00 vlieland kernel[0]: input wrap in list 0 at frame 0 byte 108
Jan 12 21:51:00 vlieland kernel[0]: write wrap in usbframe 41129988 list 42 byte 492
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 0 in framenr 41130116 at 42844506100599
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 1 in framenr 41130180 at 42844570125000
Jan 12 21:51:00 vlieland kernel[0]: input wrap in list 2 at frame 42 byte 492
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 2 in framenr 41130244 at 42844634133223
Jan 12 21:51:00 vlieland kernel[0]: write wrap in usbframe 41130180 list 21 byte 300
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 3 in framenr 41130308 at 42844698137361
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 0 in framenr 41130372 at 42844762092630
Jan 12 21:51:00 vlieland kernel[0]: input wrap in list 1 at frame 21 byte 300
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 1 in framenr 41130436 at 42844826127069
Jan 12 21:51:00 vlieland kernel[0]: write wrap in usbframe 41130372 list 0 byte 108
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 2 in framenr 41130500 at 42844890138024
Jan 12 21:51:00 vlieland kernel[0]: READ framelist 3 in framenr 41130564 at 42844954127344
Jan 12 21:51:00 vlieland kernel[0]: input wrap in list 0 at frame 0 byte 108
Jan 12 21:51:01 vlieland kernel[0]: write wrap in usbframe 41130500 list 42 byte 492
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 0 in framenr 41130628 at 42845018140271
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 1 in framenr 41130692 at 42845082114698
Jan 12 21:51:01 vlieland kernel[0]: input wrap in list 2 at frame 42 byte 492
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 2 in framenr 41130756 at 42845146133263
Jan 12 21:51:01 vlieland kernel[0]: write wrap in usbframe 41130692 list 21 byte 300
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 3 in framenr 41130820 at 42845210022809
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 0 in framenr 41130884 at 42845274129761
Jan 12 21:51:01 vlieland kernel[0]: input wrap in list 1 at frame 21 byte 312 <---- diffference 12 ----
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 1 in framenr 41130948 at 42845338130733
Jan 12 21:51:01 vlieland kernel[0]: write wrap in usbframe 41130884 list 0 byte 120
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 2 in framenr 41131012 at 42845402134576
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 3 in framenr 41131076 at 42845466132018
Jan 12 21:51:01 vlieland kernel[0]: input wrap in list 0 at frame 0 byte 120
Jan 12 21:51:01 vlieland kernel[0]: write wrap in usbframe 41131012 list 42 byte 504
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 0 in framenr 41131140 at 42845530144123
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 1 in framenr 41131204 at 42845594083202
Jan 12 21:51:01 vlieland kernel[0]: input wrap in list 2 at frame 42 byte 504
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 2 in framenr 41131268 at 42845658134839
Jan 12 21:51:01 vlieland kernel[0]: write wrap in usbframe 41131204 list 21 byte 312
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 3 in framenr 41131332 at 42845722126040
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 0 in framenr 41131396 at 42845786129646
Jan 12 21:51:01 vlieland kernel[0]: input wrap in list 1 at frame 21 byte 312
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 1 in framenr 41131460 at 42845850131380
Jan 12 21:51:01 vlieland kernel[0]: write wrap in usbframe 41131396 list 0 byte 120
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 2 in framenr 41131524 at 42845914101124
Jan 12 21:51:01 vlieland kernel[0]: READ framelist 3 in framenr 41131588 at 42845978102680
Jan 12 21:51:01 vlieland kernel[0]: input wrap in list 0 at frame 0 byte 120
Jan 12 21:51:02 vlieland kernel[0]: write wrap in usbframe 41131524 list 42 byte 504
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 0 in framenr 41131652 at 42846042140811
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 1 in framenr 41131716 at 42846106130473
Jan 12 21:51:02 vlieland kernel[0]: input wrap in list 2 at frame 42 byte 528 <----- difference 24 ---
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 2 in framenr 41131780 at 42846170133244
Jan 12 21:51:02 vlieland kernel[0]: write wrap in usbframe 41131716 list 21 byte 336
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 3 in framenr 41131844 at 42846234137013
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 0 in framenr 41131908 at 42846298128973
Jan 12 21:51:02 vlieland kernel[0]: input wrap in list 1 at frame 21 byte 336
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 1 in framenr 41131972 at 42846362130821
Jan 12 21:51:02 vlieland kernel[0]: write wrap in usbframe 41131908 list 0 byte 144
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 2 in framenr 41132036 at 42846426137975
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 3 in framenr 41132100 at 42846490132361
Jan 12 21:51:02 vlieland kernel[0]: input wrap in list 0 at frame 0 byte 144
Jan 12 21:51:02 vlieland kernel[0]: write wrap in usbframe 41132036 list 42 byte 528
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 0 in framenr 41132164 at 42846554139515
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 1 in framenr 41132228 at 42846618128039
Jan 12 21:51:02 vlieland kernel[0]: input wrap in list 2 at frame 42 byte 528
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 2 in framenr 41132292 at 42846682127653
Jan 12 21:51:02 vlieland kernel[0]: write wrap in usbframe 41132228 list 21 byte 336
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 3 in framenr 41132356 at 42846746101697
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 0 in framenr 41132420 at 42846810128819
Jan 12 21:51:02 vlieland kernel[0]: input wrap in list 1 at frame 21 byte 336
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 1 in framenr 41132484 at 42846874137719
Jan 12 21:51:02 vlieland kernel[0]: write wrap in usbframe 41132420 list 0 byte 144
Jan 12 21:51:02 vlieland kernel[0]: READ framelist 2 in framenr 41132548 at 42846938139866
Jan 12 21:51:03 vlieland kernel[0]: READ framelist 3 in framenr 41132612 at 42847002129127
Jan 12 21:51:03 vlieland kernel[0]: input wrap in list 0 at frame 0 byte 144
Jan 12 21:51:03 vlieland kernel[0]: write wrap in usbframe 41132548 list 42 byte 528
Jan 12 21:51:03 vlieland kernel[0]: READ framelist 0 in framenr 41132676 at 42847066144448
Jan 12 21:51:03 vlieland kernel[0]: READ framelist 1 in framenr 41132740 at 42847130130412
Jan 12 21:51:03 vlieland kernel[0]: input wrap in list 2 at frame 42 byte 552 <------ 24 ------
Jan 12 21:51:03 vlieland kernel[0]: READ framelist 2 in framenr 41132804 at 42847194133757
Jan 12 21:51:03 vlieland kernel[0]: write wrap in usbframe 41132740 list 21 byte 360
Jan 12 21:51:03 vlieland kernel[0]: READ framelist 3 in framenr 41132868 at 42847258101562
Jan 12 21:51:03 vlieland kernel[0]: READ framelist 0 in framenr 41132932 at 42847322089354
Jan 12 21:51:03 vlieland kernel[0]: input wrap in list 1 at frame 21 byte 360
Jan 12 21:51:03 vlieland kernel[0]: READ framelist 1 in framenr 41132996 at 42847386121500
Jan 12 21:51:03 vlieland kernel[0]: write wrap in usbframe 41132932 list 0 byte 168
Jan 12 21:51:03 vlieland kernel[0]: READ framelist 2 in framenr 41133060 at 42847450149622
Jan 12 21:51:03 vlieland kernel[0]: READ framelist 3 in framenr 41133124 at 42847514128496
Jan 12 21:51:03 vlieland kernel[0]: input wrap in list 0 at frame 0 byte 168
Jan 12 21:51:03 vlieland kernel[0]: write wrap in usbframe 41133060 list 42 byte 552
Jan 12 21:51:03 vlieland kernel[0]: READ framelist 0 in framenr 41133188 at 42847578117311
Jan 12 21:51:03 vlieland kernel[0]: READ framelist 1 in framenr 41133252 at 42847642129078
Jan 12 21:51:03 vlieland kernel[0]: input wrap in list 2 at frame 42 byte 552
from emu-driver.
So the input and output are EXACTLY synchronized. Except for occasional offsets of 12 or 24 bytes.
I will use simple script to extract the differences (#bytes).
cat /Users/wouter/Desktop/96k.txt | awk '// { if ($6=="write") { L=$12; B1=$14; } else if ($6=="input" && L==$13) { B2=$15; print "wrap diff " B1-B2 } }'
from emu-driver.
Here is a plot of B1-B2 for 96kHz
from emu-driver.
And here the same plot for 48kHz
from emu-driver.
Note that for 48kHz we have 4 samples per frame so we have jumps of 4*3=12 bytes. The range and behiour seems similar: 1, 2, or 3 stereo(quad) samples off.
from emu-driver.
For 44kHz the picture is a bit worse
from emu-driver.
For 44k the pattern is similar but we are not at 0 most of the time but at 228. And we have offsets in 2 directions now.
I now realize the other pictures are probably also symmetric but I am plotting only 1 side because it's so close to 0 and my script has the requriement L==$13 meaning the framenrs have to match. So the odd data has been dropped in the pictures where the center is around 0.
from emu-driver.
The offset at 44.1 must be caused by initial 3 cycles where the write list has to guess the frame sizes, waiting for the reads to come in
You cxan also see that happen in the logs , in "frameSizeQueue empty, guessing some queue size. May need fix..
":
Jan 12 22:15:01 vlieland kernel[0]: +UsbInputRing::init bytesize=98304 byterate=529200
Jan 12 22:15:01 vlieland kernel[0]: -UsbInputRing::init 185759637
Jan 12 22:15:01 vlieland kernel[0]: create output pipe
Jan 12 22:15:01 vlieland kernel[0]: check for associated endpoint
Jan 12 22:15:01 vlieland kernel[0]: READ framelist 0 in framenr 42570526 at 44285045041467
Jan 12 22:15:01 vlieland kernel[0]: READ framelist 1 in framenr 42570590 at 44285045117215
Jan 12 22:15:01 vlieland kernel[0]: READ framelist 2 in framenr 42570654 at 44285045176191
Jan 12 22:15:01 vlieland kernel[0]: READ framelist 3 in framenr 42570718 at 44285045231161
Jan 12 22:15:01 vlieland kernel[0]: frameSizeQueue empty, guessing some queue size. May need fix..
Jan 12 22:15:01 --- last message repeated 127 times ---
Jan 12 22:15:01 vlieland kernel[0]: ++EMUUSBAudioEngine[0xffffff8034361800]::performEngineStart result is 0x0 direction 1
Jan 12 22:15:01 vlieland kernel[0]: USBF: 44285.108 AppleUSBXHCI[0xffffff81a21d5000]::PollEventRing2 - Isoc Transfer event with completion code (3) on pEP (0xffffff803579c800)
Jan 12 22:15:01 vlieland kernel[0]: USBF: 44285.109 AppleUSBXHCI[0xffffff81a21d5000]::PollEventRing2 - Isoc Transfer event with completion code (3) on pEP (0xffffff803579c800)
Jan 12 22:15:01 vlieland kernel[0]: frameSizeQueue empty, guessing some queue size. May need fix..
Jan 12 22:15:01 --- last message repeated 58 times ---
Jan 12 22:15:01 vlieland kernel[0]: write wrap in usbframe 42570654 list 58 byte 96
Jan 12 22:15:01 vlieland kernel[0]: frameSizeQueue empty, guessing some queue size. May need fix..
Jan 12 22:15:01 --- last message repeated 4 times ---
Jan 12 22:15:01 vlieland kernel[0]: READ framelist 0 in framenr 42570782 at 44285172276763
Jan 12 22:15:01 vlieland kernel[0]: READ framelist 1 in framenr 42570846 at 44285236119008
3 cycles = 3*64 = 192 samples. At 44.1kHz,we guess 44 so we are 1 off every 10, or 19 samples off in total.
19 quad samples = 228 bytes, exactly the amount we found. So we can compensate for this error.
from emu-driver.
At 192kHz the sync is not working ok it seems. Here a bit
Jan 12 22:35:09 vlieland kernel[0]: write wrap in usbframe 43779026 list 42 byte 366
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 1 in framenr 43779090 at 45493576453671
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 2 in framenr 43779122 at 45493608509714
Jan 12 22:35:09 vlieland kernel[0]: input wrap in list 3 at frame 63 byte 558
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 3 in framenr 43779154 at 45493640558442
Jan 12 22:35:09 vlieland kernel[0]: write wrap in usbframe 43779122 list 21 byte 174
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 0 in framenr 43779186 at 45493672544412
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 1 in framenr 43779218 at 45493704556480
Jan 12 22:35:09 vlieland kernel[0]: input wrap in list 2 at frame 42 byte 366
Jan 12 22:35:09 vlieland kernel[0]: write wrap in usbframe 43779186 list 63 byte 558
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 2 in framenr 43779250 at 45493736544442
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 3 in framenr 43779282 at 45493768453297 ***********
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 0 in framenr 43779314 at 45493800400955
Jan 12 22:35:09 vlieland kernel[0]: input wrap in list 1 at frame 21 byte 174
Jan 12 22:35:09 vlieland kernel[0]: write wrap in usbframe 43779282 list 42 byte 366 ********** (quite far from frame 63 byte 564)
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 1 in framenr 43779346 at 45493832516894
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 2 in framenr 43779378 at 45493864390459
Jan 12 22:35:09 vlieland kernel[0]: input wrap in list 3 at frame 63 byte 564 ********** (framenr 43779282 above)
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 3 in framenr 43779410 at 45493896504445
Jan 12 22:35:09 vlieland kernel[0]: write wrap in usbframe 43779378 list 21 byte 180
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 0 in framenr 43779442 at 45493928515278
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 1 in framenr 43779474 at 45493960563209
Jan 12 22:35:09 vlieland kernel[0]: input wrap in list 2 at frame 42 byte 378
Jan 12 22:35:09 vlieland kernel[0]: write wrap in usbframe 43779442 list 63 byte 564
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 2 in framenr 43779506 at 45493992474068
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 3 in framenr 43779538 at 45494024565908
Jan 12 22:35:09 vlieland kernel[0]: READ framelist 0 in framenr 43779570 at 45494056531349
Jan 12 22:35:09 vlieland kernel[0]: input wrap in list 1 at frame 21 byte 186
Jan 12 22:35:10 vlieland kernel[0]: write wrap in usbframe 43779538 list 42 byte 378
Jan 12 22:35:10 vlieland kernel[0]: READ framelist 1 in framenr 43779602 at 45494088463014
Jan 12 22:35:10 vlieland kernel[0]: READ framelist 2 in framenr 43779634 at 45494120512809
Jan 12 22:35:10 vlieland kernel[0]: input wrap in list 3 at frame 63 byte 570
Jan 12 22:35:10 vlieland kernel[0]: READ framelist 3 in framenr 43779666 at 45494152595618
Jan 12 22:35:10 vlieland kernel[0]: write wrap in usbframe 43779634 list 21 byte 186
Jan 12 22:35:10 vlieland kernel[0]: READ framelist 0 in framenr 43779698 at 45494184512247
Jan 12 22:35:10 vlieland kernel[0]: READ framelist 1 in framenr 43779730 at 45494216591087
Jan 12 22:35:10 vlieland kernel[0]: input wrap in list 2 at frame 42 byte 378
You can see that for example the marked wraps in read and write are way out of sync, 20 frames or so.
from emu-driver.
BTW strangely that the audio sounds perfect at 192kHz, in spite of this huge sync problem
from emu-driver.
Probably the timestamps used for the wrap are COMPLETION times. This means it's biased to the end of the wrap. This would cause a systematic error in the wrap time of 1/2 the usb frame length.
I tried to fix this bias by estimating the time that the byte came in from the distance to the end of the frame.
from emu-driver.
No, this approach is not working because we don't know (1) when exactly the USB did the transfer.
If we get timestamp 1ms the transfer may have happened anywhere between <0,1]. It's just that USB found at 1ms that the frame had been received.
But I can check the freedom USB has in the distribution of the packet. If I ask for bInterval 8, maybe USB is only allowed to use microframe 0, 8, 16, etc.
from emu-driver.
Checked WorkingWithUSB manual.
all isochronous transactions, including high-speed isochronous transactions, start on a frame boundary, not a microframe boundary
from emu-driver.
The async at 192k became apparent only when the eraseHead was enabled.
It's now fixed, see #30
The sync is at most 1 sample off in practice.
from emu-driver.
Related Issues (20)
- Build on XCode 11 HOT 3
- Catalina no sound HOT 45
- Catalina: Install not working - csrutil issue HOT 14
- cleanup updateWallTimePerUSBCycle etc
- installer work correctly if whitespace in path HOT 3
- Catalina installer finish properly HOT 36
- S/PDIF output intermittently disabling HOT 15
- After installing 5500 XT, the sound in the EMU 0404 audio card disappeared HOT 14
- El Capitan Crackling Distortion for entire playback HOT 6
- Testing noise levels HOT 44
- Big Sur installation HOT 29
- playback stops when I open Safari HOT 39
- IRQ Problem on non-Apple macs. HOT 7
- BIG SUR - 2errors HOT 9
- ARM M1 issue Incompatible architecture: Cannot find arm64e in fat binary HOT 91
- system integrity re-enable driver stops working HOT 8
- Working Properly - Big Sur HOT 4
- ventura 13.0.01 HOT 1
- OSX Monterey E-MU 0404 USB Success HOT 2
- EMU 2020 Hackintosh OSX Ventura 13.4 - working
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from emu-driver.