TomHarte / CLK

A latency-hating emulator of: the Acorn Electron and Archimedes, Amstrad CPC, Apple II/II+/IIe and early Macintosh, Atari 2600 and ST, ColecoVision, Enterprise 64/128, Commodore Vic-20 and Amiga, MSX 1/2, Oric 1/Atmos, early PC compatibles, Sega Master System, Sinclair ZX80/81 and ZX Spectrum.
MIT License
936 stars 52 forks source link

threading and headless machines in a so/dll #780

Closed jariseon closed 4 years ago

jariseon commented 4 years ago

Tom, I've two questions for a rather specific use case / fork:

Q1: i'd like to implement a new OSBinding that compiles CLK as a so/dll, and without SDL. looking at the existing main loop implementation this seems doable. in my use case the host provides audio and gui threads, while the actual emulation is run in a custom thread which i start from the gui thread. question: can i pull CLK audio from the host provided audio thread, or should audio chips reside in the emulation thread? pulling would remove the need for ring buffering, but i guess it probably makes more sense to emulate all chips in a single thread.

Q2: is it possible to implement headless machines, i.e., ones without a CRTMachine? in the use case front panels are remoted into a webview.

my plan is to replace the MAME engine with CLK in this repo, and port the serial and audio chips from MAME into CLK's format. the concept works well with MAME but i'm not entirely happy with the latency. MAME (while wonderful) is also bit of an overkill for my needs, and being able to drag'n'drop samples and patch banks to launch a specific synth would be simply brilliant. CLK is really cool.

thanks!

TomHarte commented 4 years ago

Cool; as you'll already have spotted I'm still in the very minor leagues in terms of implementing audio chips; I have my eye on an OPL2 sometime soon (plus an OPLL front-end, as I have two machines that could take advantage of that already) but I digress.

Q1: Yes, there should be no SDL dependencies whatsoever in the main emulation code — e.g. the macOS build doesn't use SDL.

All the audio stuff is currently built to support two threads: one that the underlying machine operates on, and another that audio is generated and resampled on, though I guess it wouldn't be too hard to eliminate that assumption. But right now all the machines have three members:

The deferring async task queue is something you enqueue lambdas to. It just queues them up. When you tell it to, it'll dispatch them onto its separate thread, performing them asynchronously from the caller but synchronously in order with regard to each other. Normally that ends up being a bunch of 'run_for's that advance time on the lowpass speaker plus whatever instantaneous changes should be applied to the sample source in between.

Whenever the lowpass speaker has enough source samples to produce a new buffer of output, of whatever size and sampling rate the host asked for, it'll do that and post it onward, on its owned asynchronous thread.

I guess that technically the lowpass speaker could keep its own ring buffer and provide inspection of that, or keep the existing delegate relationship but modify the lifecycle so that a buffer pointer it has provided remains valid until revoked? Then the receiver would just need a queue of pointers rather than copying all of the samples.

Q2: The fantastically terse "TODO: rename" atop the CRTMachine namespace doesn't really explain itself, but I've been unhappy with the way I've bundled things in CRTMachine for a while. It's not just about being headless, it's also about providing for alternative types of head, like a Vectrex-style vector display, or a seven-segment display as on something like the KIM-1.

So, yeah, I want to get that done. I'll take a look at it this week. Coming up with good naming has defeated me in the past, but I guess I want it broken into three independent things: anything that fits the existing ScanTarget-style video output stuff; anything that produces audio; and anything that requires 'time' as an input.

jariseon commented 4 years ago

thanks a lot for the info and the update, much appreciated! i'll start with a yamaha fb-01. it uses OPP for audio and upd71051 / 8251 for midi and the front panel. pls close the issue as you see best.

TomHarte commented 4 years ago

Okay, I'll shut for now in the hope that the removal of CRTMachine has unblocked you, but if absolutely anything else comes up then please don't hesitate to file another ticket. As per the above I'm still very much in the kiddie's end of the pool in terms of audio chips I've implemented so I don't know if any further pitfalls might be lurking. Good luck!