Here are the main key points:
On most platforms, audio I/O is performed through a single I2S (or similar) bus, and individual samples are handled by a DMA, and the CPU receives an interrupt when a "block" is ready. Analogs and digitals are sampled at a much lower rate, and handled separately.
In our case
- we have an heterogeneous I/O stream of analog, digital and audio samples, clocked by the audio clock.
- there are one SPI read stream (analog in), one SPI out stream (analog out), one bidirectional I2S stream (audio) and then some register poking to get the CPU's GPIOs to do digital I/O
- the PRU does all these things in a very tight loop, with 5nanosecond accuracy.
without a PRU, you would need one CPU core dedicated to do the PRU job to pull all the streams together. This is in principle possible on multi-CPU platforms, such core would have to run full-speed the whole time, busy waiting where appropriate, in order to avoid being pre-empted by the OS, as the timing requirements here are so tight (let's say down to 1us) that even Xenomai-level thread wakeup latency (~30us) would be insufficient. However, heat dissipation then comes into play, and having multiple cores running full speed the whole time (e.g.: one for I/O(PRU-style) and one for the actual audio processing), could easily hit thermal limit and require huge heatsinks/fans and/or downclocking.
So, Bela is not bound to the PRU specifically. More in general, it is bound to the presence of an on-board, low-power microcontroller that has access to SPI, I2S and GPIO peripherals. Only a few low-end SoCs provide that, and many mainstream ones, such as the Pi or Odroid don't.
Also, check out these: https://forum.bela.io/d/46-24-bit-audio-input-output-48khz/13 https://forum.bela.io/d/313-audio-cape-and-analog-inputs/7