package turgen.generator;

/**
 * Buffered audio signal writer
 * This signal writer uses internal buffer to reduce number
 * of round-trips between TS and operating system's native
 * sound facilities.
 */
public class AudioSignalBufferedWriter extends AudioSignalWriter {

    private final byte[] internalBuffer;
    private int internalBufferAvail;
    private int internalBufferPos;
    
    public AudioSignalBufferedWriter(int bitsPerSample, int channels, boolean signed, int bufferSize) {
        super(bitsPerSample, channels, signed, bufferSize);
        internalBuffer = new byte[bufferSize];
        internalBufferAvail=bufferSize;
        internalBufferPos=0;
    }
    
    public void write(byte[] signal) throws Exception {
        
        int remainingBytes = signal.length;
        int inputPos=0;
        
        while(remainingBytes>0) {
            
            /*How many bytes will fit into buffer*/
            int bytesToCopy = Math.min(internalBufferAvail,remainingBytes);
            
            /*Copy whatever fits into the buffer*/
            System.arraycopy(signal, inputPos,internalBuffer, internalBufferPos,bytesToCopy);
            inputPos+=bytesToCopy;
            remainingBytes-=bytesToCopy;
            internalBufferPos+=bytesToCopy;
            internalBufferAvail-=bytesToCopy;
            
            /*If buffer is full, then flush and reset buffer*/
            if (internalBufferAvail==0) {
                line.write(internalBuffer,0,internalBuffer.length);
                internalBufferPos=0;
                internalBufferAvail=internalBuffer.length;
            }
            
        }
        
    }
    public void prepareForClose() throws Exception {
        if (internalBufferPos!=0) {
            line.write(internalBuffer,0,internalBuffer.length-internalBufferAvail);
        }
        line.drain();
        line.stop();
    }

}
