package vermilion;

import java.util.ArrayList;

/**
 * An interface class dynamic classes can implement in order to register 
 * themselves as the mixer for the program. The mixer's responsibilty is
 * to fill the audio buffer as requested.
 *
 * This means that the audio provider is essentially stateless, and only
 * serves to hold and implement the audio chain as it is built by the user.
 *
 * There is an unavoidable coupling between the event and audio providers,
 * since the audio provider holds the actual instances of the machines in the
 * audio chain, and the event provider will provide events in a format that
 * feed the audio chain. Most of the work can be done through the document
 * so it is only during playback that this coupling occurs.
 */
public interface AudioProvider
{
    /**
     * Called by the audio thread when it wants some audio to play. The number
     * of samples to process will be at most the size of the internal audio
     * buffer. The number may vary as the system processes events at the closest
     * sample and then asks for the number of samples remaining until the next
     * event.
     */
    public void fillBuffer(int samplesToProcess);

    /**
     * Called by the audio thread to pass events from the event provider. The
     * format of the events will be agreed upon by the audio and event providers
     * in use.
     * 
     * Note that this is only called during playback between buffer fills, and
     * then only if events are due to occur.
     */
    public void processEvents(ArrayList<Object> events);

    /**
     * Called by the audio thread to tell the provider about the buffer
     * and pass a reference to it. This means the audio provider will write
     * directly to the audio thread's buffer.
     * @param audioBuffer The buffer where we will place audio.
     * @param numSamples The number of samples (per channel) in the buffer.
     */
    public void setBufferRef(float[][] audioBuffer, int numSamples);
}
