Sending audio data in chunks using visible light communication
Your overall approach looks good but its missing a few elements.

Unless the light received from the LED by the photodiode is much more powerful than the ambient light, you will need some way to reject ambient light.  Typically ambient light is going to be more powerful than your LED.

850nm (near IR) LEDs are often used specifically because there is not very much sunlight near that wavelength.  You would then use a photodiode that is matched to the frequency of your LED.

Using an LED with an narrow beam angle will concentrate the light in a smaller area.  Narrower angles will give you correspondingly more flux for a given wattage, but will be correspondingly harder to aim at the receiver.

Using the right LED and photodiode will help a lot but it may not get you all the way there.  You may need to add a high pass filter as part of your photodiode amplifier.  The cutoff frequency should be much higher than 60Hz to avoid picking up flicker from light bulbs.

You need to consider what sample rate and bit depth you want for the audio stream.  For example 32Ksps 16-bit audio would need to transmit at 512kbps.  If you were using a micro-controller that could execute 32 million instructions per second, then you would only have 64 instruction cycles to process each bit.  That's a pretty tight timing budget considering that you need to do an ADC conversion, possibly send each bit multiple times as part of some modulation scheme, and manage buffers.

Telephone quality audio has a bandwidth of 3.4kHz.  If transmitted at 8 bits per sample it would need  need to transmit 27.2kbps.  In that case the same 32 MIPS microcontroller would have closer to 1200 cycles to process each sample, which is far more manageable.

You need to decide if you want the transmission to be loss-less or if you are willing to accept some loss.  The additional overhead of acknowledged transmission may force a tradeoff that lowers your sample rate or bit depth in order to meet timing.

You don't really need two way communication to send to music.  The success of broadcast radio proves that.  Just accepting a few bad bits could just mean that occasionally you get a blip of static from the speaker (the same as you do from broadcast radio).  Using the proper encoding scheme for the transmitted bits (such as delta-sigma or similar) would reduce he effects of any single bit errors.

Adding packet overhead to verify that the data is correct will require more CPU clock cycles to process checksums or CRCs.  Acknowledgement of packets could take additional time while the CPU waits for the reply.  It would double the number of transmitters / receivers you need.  But for all its down sides you could at least guarantee with very high certainty that the data was correct.

You need to consider the effect of clock drift between the two MCUs.  For example if your first MCU sends a bit every 100 clock cycles and the second MCU samples a bit every 100 cycles and the clocks frequencies are different by say 1%, then every 100 bits you may get an extra bit (or loose a bit).  A UART is a common way of synchronizing timing when sending bytes between two systems.  Other methods such as delta sigma modulation (mentioned above) are tolerant of single bit errors.