//! Functionality to mix and forward different audio streams.
#![warn(missing_docs)]

use cortex_m::interrupt;

use super::audio_buffer::AudioBuffer;

/// The mixer connects several upstream audio ports (i.e., USB audio device interface) to one
/// downstream audio port.
///
/// The audio from the upstream ports is mixed and forwarded to the downstream port. The audio from
/// the downstream port (i.e., microphone) is forwarded to all upstream ports.
pub struct Mixer {
    usb1: AudioPort,
    amp: AudioPort,
}

impl Mixer {
    /// Creates a new mixer for the specified audio ports.
    pub fn new(usb1: AudioPort, amp: AudioPort) -> Mixer {
        Mixer { usb1, amp }
    }

    /// Checks whether data can be read from the audio ports and mixes/forwards it as required.
    ///
    /// The function returns true if any data was sent to any audio port.
    pub fn poll(&mut self) -> bool {
        interrupt::free(|cs| {
            if self.usb1.in_.can_read(cs) {
                // TODO
            }
            if self.amp.in_.can_read(cs) {
                // TODO
            }
            // TODO
        });
        false
    }
}

/// The connection between an audio source/sink and the mixer.
///
/// The connection is made via two buffers (one for input, one for output).
pub struct AudioPort {
    // TODO: Fields and functions to set the volume and to mute the port.
    in_: &'static AudioBuffer,
    out: &'static AudioBuffer,
}

impl AudioPort {
    /// Creates a new audio port.
    ///
    /// The port is initially muted and set to maximum volume.
    pub fn new(in_: &'static AudioBuffer, out: &'static AudioBuffer) -> AudioPort {
        AudioPort { in_, out }
    }
}
