The (Potential) Bad News
Without more detail on how complex the LCD screen is (graphical, or a few lines of text), how often it's updated, what kind of data you are getting from the esp8266 (or how often), it's hard to formulate a very specific strategy, but here are some general tips. Also, I assume you are "listening" to real-time audio with the ADC, processing it based on commands (WiFi->ESP8366->USART->AVR), buffering and such with the external RAM (SPI), outputting the processed audio with the DAC, and displaying current operation info on the LCD (also SPI).
This is a lot for an 8-bit MCU to do, even maxed out at 20Mhz. This DigiKey article discusses choosing an MCU for audio-applications and mentions a minimum of 32kHz sampling rate for music. That means you have 625 clock cycles between samples to do something useful with them. Also of note, anything involving 32-bit variables (like a floating point number) will require multiple clock cycles that normally only take 1 cycle for an 8-bit operation. I imagine you'll be doing some complicated math, even with "simple" audio effects. Any sort of division (even 8-bit) will be ridiculously slow.
Also, the tiny816 has a 10-bit ADC, but an 8-bit DAC, so you will loose some precision in the processed audio quality.
Multi-Tasking Concepts
Multi-tasking on AVR microcontrollers is done using interrupts and timers. There is no multi-threading or processing available. Only one command can be executed my the core processor at once. Of course, many of the hardware peripherals can do things independently of the core. You can use a complicated strategy to time-split the operation (do one thing for so long, then give up control to another task), but this involves saving the entire state to memory in order to switch to another task. It's much simpler to let the processor handle the most time intensive tasks nonstop until it's interrupted by something else, then temporarily perform some other operation or set a flag telling the main loop to handle it on the next cycle.
Here's an application note on "Core Independent Peripherals" which focuses on the tinyAVR 1-Series (including the tiny816). Newer AVR like the tiny816 also have the Event System (see section 14 of the datasheet). To help prioritize and manage the program. I don't believe the tiny816 has true DMA, which could be used to auto-buffer the sampled data. It does have peripheral-peripheral signalling though, so that could be used to trigger data-buffering.
Also, here's an application note on recording audio with the tiny817. There's an Atmel START project for it as well: search here for AVR42777. This project just records (a very limited about) of audio (8-bit, low-ish quality) in raw format to an SD card using SPI with playback.
Example Strategy
- When enabled, the ADC is auto-triggered to sample incoming audio at the highest frequency your MCU can manage/process.
- Sampled data is buffered in the external RAM (SPI, don't know the baud for your RAM).
- The "Main Loop" tries to process buffered audio data from RAM as it is available, checking status flags in between cycles. A status flag will cause a jump to some sub-routine (like handling a new command or updating the LCD).
- USART Rx from the ESP8266 triggers an ISR. It is buffered until a complete package is received, and a status flag tells MAIN to do something with it. Otherwise, the state of the package can be stored (statically) in the ISR and handled from there, but it's best to keep the ISR as compact as possible.
- A hardware timer triggers an ISR to prepare to update the LCD as often as deemed necessary - this rate depends on the screen and the data being shown, but you'll want to avoid it flickering. LCD data should be written from a function call in main, not the timer ISR (buffered data can be auto-transmitted from the SPI Tx ISR as well).
- Another timer can trigger the DAC audio output (this rate is a combination of your sampling rate and the effects you want on that audio), and this must the highest priority event, or the output will sound like garbage.