/* Sonic library
   Copyright 2010, 2011
   Bill Cox
   This file is part of the Sonic Library.

   This file is licensed under the Apache 2.0 license.
*/

package sonic;

public class Sonic {

	private static final int SONIC_MIN_PITCH = 65;
	private static final int SONIC_MAX_PITCH = 400;
	/* This is used to down-sample some inputs to improve speed */
	private static final int SONIC_AMDF_FREQ = 4000;

    private short inputBuffer[];
    private short outputBuffer[];
    private short pitchBuffer[];
    private short downSampleBuffer[];
    private float speed;
    private float volume;
    private float pitch;
    private float rate;
    private int oldRatePosition;
    private int newRatePosition;
    private boolean useChordPitch;
    private int quality;
    private int numChannels;
    private int inputBufferSize;
    private int pitchBufferSize;
    private int outputBufferSize;
    private int numInputSamples;
    private int numOutputSamples;
    private int numPitchSamples;
    private int minPeriod;
    private int maxPeriod;
    private int maxRequired;
    private int remainingInputToCopy;
    private int sampleRate;
    private int prevPeriod;
    private int prevMinDiff;

    // Resize the array.
    private short[] resize(
    	short[] oldArray,
    	int newLength)
    {
    	newLength *= numChannels;
        short[]	newArray = new short[newLength];
        int length = oldArray.length <= newLength? oldArray.length : newLength;
        
        
        for(int x = 0; x < length; x++) {
            newArray[x] = oldArray[x];
        }
        return newArray;
    }

    // Move samples from one array to another.  May move samples down within an array, but not up.
    private void move(
    	short dest[],
    	int destPos,
    	short source[],
    	int sourcePos,
    	int numSamples)
    {
    	for(int xSample = 0; xSample < numSamples*numChannels; xSample++) {
    	    dest[destPos*numChannels + xSample] = source[sourcePos*numChannels + xSample];
    	}
    }

    // Scale the samples by the factor.
    private void scaleSamples(
        short samples[],
        int position,
        int numSamples,
        float volume)
    {
        int fixedPointVolume = (int)(volume*4096.0f);
        int start = position*numChannels;
        int stop = start + numSamples*numChannels;

        for(int xSample = start; xSample < stop; xSample++) {
            int value = (samples[xSample]*fixedPointVolume) >> 12;
            if(value > 32767) {
                value = 32767;
            } else if(value < -32767) {
                value = -32767;
            }
            samples[xSample] = (short)value;
        }
    }

    // Get the speed of the stream.
    public float getSpeed()
    {
        return speed;
    }

    // Set the speed of the stream.
    public void setSpeed(
        float speed)
    {
        this.speed = speed;
    }

    // Get the pitch of the stream.
    public float getPitch()
    {
        return pitch;
    }

    // Set the pitch of the stream.
    public void setPitch(
        float pitch)
    {
        this.pitch = pitch;
    }

    // Get the rate of the stream.
    public float getRate()
    {
        return rate;
    }

    // Set the playback rate of the stream. This scales pitch and speed at the same time.
    public void setRate(
        float rate)
    {
        this.rate = rate;
        this.oldRatePosition = 0;
        this.newRatePosition = 0;
    }

    // Get the vocal chord pitch setting.
    public boolean getChordPitch()
    {
        return useChordPitch;
    }

    // Set the vocal chord mode for pitch computation.  Default is off.
    public void setChordPitch(
        boolean useChordPitch)
    {
        this.useChordPitch = useChordPitch;
    }

    // Get the quality setting.
    public int getQuality()
    {
        return quality;
    }

    // Set the "quality".  Default 0 is virtually as good as 1, but very much faster.
    public void setQuality(
        int quality)
    {
        this.quality = quality;
    }

    // Get the scaling factor of the stream.
    public float getVolume()
    {
        return volume;
    }

    // Set the scaling factor of the stream.
    public void setVolume(
        float volume)
    {
        this.volume = volume;
    }

    // Allocate stream buffers.
    private void allocateStreamBuffers(
        int sampleRate,
        int numChannels)
    {
        minPeriod = sampleRate/SONIC_MAX_PITCH;
        maxPeriod = sampleRate/SONIC_MIN_PITCH;
        maxRequired = 2*maxPeriod;
        inputBufferSize = maxRequired;
        inputBuffer = new short[maxRequired*numChannels];
        outputBufferSize = maxRequired;
        outputBuffer = new short[maxRequired*numChannels];
        pitchBufferSize = maxRequired;
        pitchBuffer = new short[maxRequired*numChannels];
        downSampleBuffer = new short[maxRequired];
        this.sampleRate = sampleRate;
        this.numChannels = numChannels;
        oldRatePosition = 0;
        newRatePosition = 0;
        prevPeriod = 0;
    }

    // Create a sonic stream.
    public Sonic(
        int sampleRate,
        int numChannels)
    {
        allocateStreamBuffers(sampleRate, numChannels);
        speed = 1.0f;
        pitch = 1.0f;
        volume = 1.0f;
        rate = 1.0f;
        oldRatePosition = 0;
        newRatePosition = 0;
        useChordPitch = false;
        quality = 0;
    }

    // Get the sample rate of the stream.
    public int getSampleRate()
    {
        return sampleRate;
    }

    // Set the sample rate of the stream.  This will cause samples buffered in the stream to be lost.
    public void setSampleRate(
        int sampleRate)
    {
        allocateStreamBuffers(sampleRate, numChannels);
    }

    // Get the number of channels.
    public int getNumChannels()
    {
        return numChannels;
    }

    // Set the num channels of the stream.  This will cause samples buffered in the stream to be lost.
    public void setNumChannels(
        int numChannels)
    {
        allocateStreamBuffers(sampleRate, numChannels);
    }

    // Enlarge the output buffer if needed.
    private void enlargeOutputBufferIfNeeded(
        int numSamples)
    {
        if(numOutputSamples + numSamples > outputBufferSize) {
            outputBufferSize += (outputBufferSize >> 1) + numSamples;
            outputBuffer = resize(outputBuffer, outputBufferSize);
        }
    }

    // Enlarge the input buffer if needed.
    private void enlargeInputBufferIfNeeded(
        int numSamples)
    {
        if(numInputSamples + numSamples > inputBufferSize) {
            inputBufferSize += (inputBufferSize >> 1) + numSamples;
            inputBuffer = resize(inputBuffer, inputBufferSize);
        }
    }

    // Add the input samples to the input buffer.
    private void addFloatSamplesToInputBuffer(
        float samples[],
        int numSamples)
    {
        if(numSamples == 0) {
            return;
        }
        enlargeInputBufferIfNeeded(numSamples);
        int xBuffer = numInputSamples*numChannels;
        for(int xSample = 0; xSample < numSamples*numChannels; xSample++) {
            inputBuffer[xBuffer++] = (short)(samples[xSample]*32767.0f);
        }
        numInputSamples += numSamples;
    }

    // Add the input samples to the input buffer.
    private void addShortSamplesToInputBuffer(
        short samples[],
        int numSamples)
    {
        if(numSamples == 0) {
            return;
        }
        enlargeInputBufferIfNeeded(numSamples);
        move(inputBuffer, numInputSamples, samples, 0, numSamples);
        numInputSamples += numSamples;
    }

    // Add the input samples to the input buffer.
    private void addUnsignedByteSamplesToInputBuffer(
        byte samples[],
        int numSamples)
    {
        short sample;

        enlargeInputBufferIfNeeded(numSamples);
        int xBuffer = numInputSamples*numChannels;
        for(int xSample = 0; xSample < numSamples*numChannels; xSample++) {
        	sample = (short)((samples[xSample] & 0xff) - 128); // Convert from unsigned to signed
            inputBuffer[xBuffer++] = (short) (sample << 8);
        }
        numInputSamples += numSamples;
    }

    // Add the input samples to the input buffer.  They must be 16-bit little-endian encoded in a byte array.
    private void addBytesToInputBuffer(
        byte inBuffer[],
        int numBytes)
    {
    	int numSamples = numBytes/(2*numChannels);
        short sample;

        enlargeInputBufferIfNeeded(numSamples);
        int xBuffer = numInputSamples*numChannels;
        for(int xByte = 0; xByte + 1 < numBytes; xByte += 2) {
        	sample = (short)((inBuffer[xByte] & 0xff) | (inBuffer[xByte + 1] << 8));
            inputBuffer[xBuffer++] = sample;
        }
        numInputSamples += numSamples;
    }

    // Remove input samples that we have already processed.
    private void removeInputSamples(
        int position)
    {
        int remainingSamples = numInputSamples - position;

        move(inputBuffer, 0, inputBuffer, position, remainingSamples);
        numInputSamples = remainingSamples;
    }

    // Just copy from the array to the output buffer
    private void copyToOutput(
        short samples[],
        int position,
        int numSamples)
    {
        enlargeOutputBufferIfNeeded(numSamples);
        move(outputBuffer, numOutputSamples, samples, position, numSamples);
        numOutputSamples += numSamples;
    }

    // Just copy from the input buffer to the output buffer.  Return num samples copied.
    private int copyInputToOutput(
        int position)
    {
        int numSamples = remainingInputToCopy;

        if(numSamples > maxRequired) {
            numSamples = maxRequired;
        }
        copyToOutput(inputBuffer, position, numSamples);
        remainingInputToCopy -= numSamples;
        return numSamples;
    }

    // Read data out of the stream.  Sometimes no data will be available, and zero
    // is returned, which is not an error condition.
    public int readFloatFromStream(
        float samples[],
        int maxSamples)
    {
        int numSamples = numOutputSamples;
        int remainingSamples = 0;

        if(numSamples == 0) {
            return 0;
        }
        if(numSamples > maxSamples) {
            remainingSamples = numSamples - maxSamples;
            numSamples = maxSamples;
        }
        for(int xSample = 0; xSample < numSamples*numChannels; xSample++) {
            samples[xSample++] = (outputBuffer[xSample])/32767.0f;
        }
        move(outputBuffer, 0, outputBuffer, numSamples, remainingSamples);
        numOutputSamples = remainingSamples;
        return numSamples;
    }

    // Read short data out of the stream.  Sometimes no data will be available, and zero
    // is returned, which is not an error condition.
    public int readShortFromStream(
        short samples[],
        int maxSamples)
    {
        int numSamples = numOutputSamples;
        int remainingSamples = 0;

        if(numSamples == 0) {
            return 0;
        }
        if(numSamples > maxSamples) {
            remainingSamples = numSamples - maxSamples;
            numSamples = maxSamples;
        }
        move(samples, 0, outputBuffer, 0, numSamples);
        move(outputBuffer, 0, outputBuffer, numSamples, remainingSamples);
        numOutputSamples = remainingSamples;
        return numSamples;
    }

    // Read unsigned byte data out of the stream.  Sometimes no data will be available, and zero
    // is returned, which is not an error condition.
    public int readUnsignedByteFromStream(
        byte samples[],
        int maxSamples)
    {
        int numSamples = numOutputSamples;
        int remainingSamples = 0;

        if(numSamples == 0) {
            return 0;
        }
        if(numSamples > maxSamples) {
            remainingSamples = numSamples - maxSamples;
            numSamples = maxSamples;
        }
        for(int xSample = 0; xSample < numSamples*numChannels; xSample++) {
        	samples[xSample] = (byte)((outputBuffer[xSample] >> 8) + 128);
        }
        move(outputBuffer, 0, outputBuffer, numSamples, remainingSamples);
        numOutputSamples = remainingSamples;
        return numSamples;
    }

    // Read unsigned byte data out of the stream.  Sometimes no data will be available, and zero
    // is returned, which is not an error condition.
    public int readBytesFromStream(
        byte outBuffer[],
        int maxBytes)
    {
    	int maxSamples = maxBytes/(2*numChannels);
        int numSamples = numOutputSamples;
        int remainingSamples = 0;

        if(numSamples == 0 || maxSamples == 0) {
            return 0;
        }
        if(numSamples > maxSamples) {
            remainingSamples = numSamples - maxSamples;
            numSamples = maxSamples;
        }
        for(int xSample = 0; xSample < numSamples*numChannels; xSample++) {
        	short sample = outputBuffer[xSample];
        	outBuffer[xSample << 1] = (byte)(sample & 0xff);
        	outBuffer[(xSample << 1) + 1] = (byte)(sample >> 8);
        }
        move(outputBuffer, 0, outputBuffer, numSamples, remainingSamples);
        numOutputSamples = remainingSamples;
        return 2*numSamples*numChannels;
    }

    // Force the sonic stream to generate output using whatever data it currently
    // has.  No extra delay will be added to the output, but flushing in the middle of
    // words could introduce distortion.
    public void flushStream()
    {
        int remainingSamples = numInputSamples;
        float s = speed/pitch;
        float r = rate*pitch;
        int expectedOutputSamples = numOutputSamples + (int)((remainingSamples/s + numPitchSamples)/r + 0.5f);

        // Add enough silence to flush both input and pitch buffers.
        enlargeInputBufferIfNeeded(remainingSamples + 2*maxRequired);
        for(int xSample = 0; xSample < 2*maxRequired*numChannels; xSample++) {
            inputBuffer[remainingSamples*numChannels + xSample] = 0;
        }
        numInputSamples += 2*maxRequired;
        writeShortToStream(null, 0);
        // Throw away any extra samples we generated due to the silence we added.
        if(numOutputSamples > expectedOutputSamples) {
            numOutputSamples = expectedOutputSamples;
        }
        // Empty input and pitch buffers.
        numInputSamples = 0;
        remainingInputToCopy = 0;
        numPitchSamples = 0;
    }

    // Return the number of samples in the output buffer
    public int samplesAvailable()
    {
        return numOutputSamples;
    }

    // If skip is greater than one, average skip samples together and write them to
    // the down-sample buffer.  If numChannels is greater than one, mix the channels
    // together as we down sample.
    private void downSampleInput(
        short samples[],
        int position,
        int skip)
    {
        int numSamples = maxRequired/skip;
        int samplesPerValue = numChannels*skip;
        int value;

        position *= numChannels;
        for(int i = 0; i < numSamples; i++) {
            value = 0;
            for(int j = 0; j < samplesPerValue; j++) {
                value += samples[position + i*samplesPerValue + j];
            }
            value /= samplesPerValue;
            downSampleBuffer[i] = (short)value;
        }
    }

    // Find the best frequency match in the range, and given a sample skip multiple.
    // For now, just find the pitch of the first channel.  Note that retMinDiff and
    // retMaxDiff are Int objects, which the caller will need to create with new.
    private int findPitchPeriodInRange(
        short samples[],
        int position,
        int minPeriod,
        int maxPeriod,
        Integer retMinDiff,
        Integer retMaxDiff)
    {
        int bestPeriod = 0, worstPeriod = 255;
        int minDiff = 1, maxDiff = 0;

        position *= numChannels;
        for(int period = minPeriod; period <= maxPeriod; period++) {
            int diff = 0;
            for(int i = 0; i < period; i++) {
                short sVal = samples[position + i];
                short pVal = samples[position + period + i];
                diff += sVal >= pVal? sVal - pVal : pVal - sVal;
            }
            /* Note that the highest number of samples we add into diff will be less
               than 256, since we skip samples.  Thus, diff is a 24 bit number, and
               we can safely multiply by numSamples without overflow */
            if(diff*bestPeriod < minDiff*period) {
                minDiff = diff;
                bestPeriod = period;
            }
            if(diff*worstPeriod > maxDiff*period) {
                maxDiff = diff;
                worstPeriod = period;
            }
        }
        retMinDiff = minDiff/bestPeriod;
        retMaxDiff = maxDiff/worstPeriod;
        return bestPeriod;
    }

    // At abrupt ends of voiced words, we can have pitch periods that are better
    // approximated by the previous pitch period estimate.  Try to detect this case.
    private boolean prevPeriodBetter(
        int period,
        int minDiff,
        int maxDiff,
        boolean preferNewPeriod)
    {
        if(minDiff == 0 || prevPeriod == 0) {
            return false;
        }
        if(preferNewPeriod) {
            if(maxDiff > minDiff*3) {
                // Got a reasonable match this period
                return false;
            }
            if(minDiff*2 <= prevMinDiff*3) {
                // Mismatch is not that much greater this period
                return false;
            }
        } else {
            if(minDiff <= prevMinDiff) {
                return false;
            }
        }
        return true;
    }

    // Find the pitch period.  This is a critical step, and we may have to try
    // multiple ways to get a good answer.  This version uses AMDF.  To improve
    // speed, we down sample by an integer factor get in the 11KHz range, and then
    // do it again with a narrower frequency range without down sampling
    private int findPitchPeriod(
        short samples[],
        int position,
        boolean preferNewPeriod)
    {
        Integer minDiff = new Integer(0);
        Integer maxDiff = new Integer(0);
        int period, retPeriod;
        int skip = 1;

        if(sampleRate > SONIC_AMDF_FREQ && quality == 0) {
            skip = sampleRate/SONIC_AMDF_FREQ;
        }
        if(numChannels == 1 && skip == 1) {
            period = findPitchPeriodInRange(samples, position, minPeriod, maxPeriod, minDiff, maxDiff);
        } else {
            downSampleInput(samples, position, skip);
            period = findPitchPeriodInRange(downSampleBuffer, 0, minPeriod/skip,
                maxPeriod/skip, minDiff, maxDiff);
            if(skip != 1) {
                period *= skip;
                int minP = period - (skip << 2);
                int maxP = period + (skip << 2);
                if(minP < minPeriod) {
                    minP = minPeriod;
                }
                if(maxP > maxPeriod) {
                    maxP = maxPeriod;
                }
                if(numChannels == 1) {
                    period = findPitchPeriodInRange(samples, position, minP, maxP, minDiff, maxDiff);
                } else {
                    downSampleInput(samples, position, 1);
                    period = findPitchPeriodInRange(downSampleBuffer, 0, minP, maxP, minDiff, maxDiff);
                }
            }
        }
        if(prevPeriodBetter(period, minDiff, maxDiff, preferNewPeriod)) {
            retPeriod = prevPeriod;
        } else {
            retPeriod = period;
        }
        prevMinDiff = minDiff;
        prevPeriod = period;
        return retPeriod;
    }

    // Overlap two sound segments, ramp the volume of one down, while ramping the
    // other one from zero up, and add them, storing the result at the output.
    private void overlapAdd(
        int numSamples,
        int numChannels,
        short out[],
        int outPos,
        short rampDown[],
        int rampDownPos,
        short rampUp[],
        int rampUpPos)
    {
         for(int i = 0; i < numChannels; i++) {
            int o = outPos*numChannels + i;
            int u = rampUpPos*numChannels + i;
            int d = rampDownPos*numChannels + i;
            for(int t = 0; t < numSamples; t++) {
                out[o] = (short)((rampDown[d]*(numSamples - t) + rampUp[u]*t)/numSamples);
                o += numChannels;
                d += numChannels;
                u += numChannels;
            }
        }
    }

    // Overlap two sound segments, ramp the volume of one down, while ramping the
    // other one from zero up, and add them, storing the result at the output.
    private void overlapAddWithSeparation(
        int numSamples,
        int numChannels,
        int separation,
        short out[],
        int outPos,
        short rampDown[],
        int rampDownPos,
        short rampUp[],
        int rampUpPos)
    {
        for(int i = 0; i < numChannels; i++) {
            int o = outPos*numChannels + i;
            int u = rampUpPos*numChannels + i;
            int d = rampDownPos*numChannels + i;
            for(int t = 0; t < numSamples + separation; t++) {
                if(t < separation) {
                    out[o] = (short)(rampDown[d]*(numSamples - t)/numSamples);
                    d += numChannels;
                } else if(t < numSamples) {
                    out[o] = (short)((rampDown[d]*(numSamples - t) + rampUp[u]*(t - separation))/numSamples);
                    d += numChannels;
                    u += numChannels;
                } else {
                    out[o] = (short)(rampUp[u]*(t - separation)/numSamples);
                    u += numChannels;
                }
                o += numChannels;
            }
        }
    }

    // Just move the new samples in the output buffer to the pitch buffer
    private void moveNewSamplesToPitchBuffer(
        int originalNumOutputSamples)
    {
        int numSamples = numOutputSamples - originalNumOutputSamples;

        if(numPitchSamples + numSamples > pitchBufferSize) {
            pitchBufferSize += (pitchBufferSize >> 1) + numSamples;
            pitchBuffer = resize(pitchBuffer, pitchBufferSize);
        }
        move(pitchBuffer, numPitchSamples, outputBuffer, originalNumOutputSamples, numSamples);
        numOutputSamples = originalNumOutputSamples;
        numPitchSamples += numSamples;
    }

    // Remove processed samples from the pitch buffer.
    private void removePitchSamples(
        int numSamples)
    {
        if(numSamples == 0) {
            return;
        }
        move(pitchBuffer, 0, pitchBuffer, numSamples, numPitchSamples - numSamples);
        numPitchSamples -= numSamples;
    }

    // Change the pitch.  The latency this introduces could be reduced by looking at
    // past samples to determine pitch, rather than future.
    private void adjustPitch(
        int originalNumOutputSamples)
    {
        int period, newPeriod, separation;
        int position = 0;

        if(numOutputSamples == originalNumOutputSamples) {
            return;
        }
        moveNewSamplesToPitchBuffer(originalNumOutputSamples);
        while(numPitchSamples - position >= maxRequired) {
            period = findPitchPeriod(pitchBuffer, position, false);
            newPeriod = (int)(period/pitch);
            enlargeOutputBufferIfNeeded(newPeriod);
            if(pitch >= 1.0f) {
                overlapAdd(newPeriod, numChannels, outputBuffer, numOutputSamples, pitchBuffer,
                	position, pitchBuffer, position + period - newPeriod);
            } else {
                separation = newPeriod - period;
                overlapAddWithSeparation(period, numChannels, separation, outputBuffer, numOutputSamples,
                	pitchBuffer, position, pitchBuffer, position);
            }
            numOutputSamples += newPeriod;
            position += period;
        }
        removePitchSamples(position);
    }

    // Interpolate the new output sample.
    private short interpolate(
        short in[],
        int inPos,
        int oldSampleRate,
        int newSampleRate)
    {
        short left = in[inPos*numChannels];
        short right = in[inPos*numChannels + numChannels];
        int position = newRatePosition*oldSampleRate;
        int leftPosition = oldRatePosition*newSampleRate;
        int rightPosition = (oldRatePosition + 1)*newSampleRate;
        int ratio = rightPosition - position;
        int width = rightPosition - leftPosition;

        return (short)((ratio*left + (width - ratio)*right)/width);
    }

    // Change the rate.
    private void adjustRate(
        float rate,
        int originalNumOutputSamples)
    {
        int newSampleRate = (int)(sampleRate/rate);
        int oldSampleRate = sampleRate;
        int position;

        // Set these values to help with the integer math
        while(newSampleRate > (1 << 14) || oldSampleRate > (1 << 14)) {
            newSampleRate >>= 1;
            oldSampleRate >>= 1;
        }
        if(numOutputSamples == originalNumOutputSamples) {
            return;
        }
        moveNewSamplesToPitchBuffer(originalNumOutputSamples);
        // Leave at least one pitch sample in the buffer
        for(position = 0; position < numPitchSamples - 1; position++) {
            while((oldRatePosition + 1)*newSampleRate > newRatePosition*oldSampleRate) {
                enlargeOutputBufferIfNeeded(1);
                for(int i = 0; i < numChannels; i++) {
                    outputBuffer[numOutputSamples*numChannels + i] = interpolate(pitchBuffer, position + i,
                    	oldSampleRate, newSampleRate);
                }
                newRatePosition++;
                numOutputSamples++;
            }
            oldRatePosition++;
            if(oldRatePosition == oldSampleRate) {
                oldRatePosition = 0;
                if(newRatePosition != newSampleRate) {
                    System.out.printf("Assertion failed: newRatePosition != newSampleRate\n");
                    assert false;
                }
                newRatePosition = 0;
            }
        }
        removePitchSamples(position);
    }


    // Skip over a pitch period, and copy period/speed samples to the output
    private int skipPitchPeriod(
        short samples[],
        int position,
        float speed,
        int period)
    {
        int newSamples;

        if(speed >= 2.0f) {
            newSamples = (int)(period/(speed - 1.0f));
        } else {
            newSamples = period;
            remainingInputToCopy = (int)(period*(2.0f - speed)/(speed - 1.0f));
        }
        enlargeOutputBufferIfNeeded(newSamples);
        overlapAdd(newSamples, numChannels, outputBuffer, numOutputSamples, samples, position,
        	samples, position + period);
        numOutputSamples += newSamples;
        return newSamples;
    }

    // Insert a pitch period, and determine how much input to copy directly.
    private int insertPitchPeriod(
        short samples[],
        int position,
        float speed,
        int period)
    {
        int newSamples;

        if(speed < 0.5f) {
            newSamples = (int)(period*speed/(1.0f - speed));
        } else {
            newSamples = period;
            remainingInputToCopy = (int)(period*(2.0f*speed - 1.0f)/(1.0f - speed));
        }
        enlargeOutputBufferIfNeeded(period + newSamples);
        move(outputBuffer, numOutputSamples, samples, position, period);
        overlapAdd(newSamples, numChannels, outputBuffer, numOutputSamples + period, samples,
        	position + period, samples, position);
        numOutputSamples += period + newSamples;
        return newSamples;
    }

    // Resample as many pitch periods as we have buffered on the input.  Return 0 if
    // we fail to resize an input or output buffer.  Also scale the output by the volume.
    private void changeSpeed(
        float speed)
    {
        int numSamples = numInputSamples;
        int position = 0, period, newSamples;

        if(numInputSamples < maxRequired) {
            return;
        }
        do {
            if(remainingInputToCopy > 0) {
                newSamples = copyInputToOutput(position);
                position += newSamples;
            } else {
                period = findPitchPeriod(inputBuffer, position, true);
                if(speed > 1.0) {
                    newSamples = skipPitchPeriod(inputBuffer, position, speed, period);
                    position += period + newSamples;
                } else {
                    newSamples = insertPitchPeriod(inputBuffer, position, speed, period);
                    position += newSamples;
                }
            }
        } while(position + maxRequired <= numSamples);
        removeInputSamples(position);
    }

    // Resample as many pitch periods as we have buffered on the input.  Scale the output by the volume.
    private void processStreamInput()
    {
        int originalNumOutputSamples = numOutputSamples;
        float s = speed/pitch;
        float r = rate;

        if(!useChordPitch) {
            r *= pitch;
        }
        if(s > 1.00001 || s < 0.99999) {
            changeSpeed(s);
        } else {
            copyToOutput(inputBuffer, 0, numInputSamples);
            numInputSamples = 0;
        }
        if(useChordPitch) {
            if(pitch != 1.0f) {
                adjustPitch(originalNumOutputSamples);
            }
        } else if(r != 1.0f) {
            adjustRate(r, originalNumOutputSamples);
        }
        if(volume != 1.0f) {
            // Adjust output volume.
            scaleSamples(outputBuffer, originalNumOutputSamples, numOutputSamples - originalNumOutputSamples,
                volume);
        }
    }

    // Write floating point data to the input buffer and process it.
    public void writeFloatToStream(
        float samples[],
        int numSamples)
    {
        addFloatSamplesToInputBuffer(samples, numSamples);
        processStreamInput();
    }

    // Write the data to the input stream, and process it.
    public void writeShortToStream(
        short samples[],
        int numSamples)
    {
        addShortSamplesToInputBuffer(samples, numSamples);
        processStreamInput();
    }

    // Simple wrapper around sonicWriteFloatToStream that does the unsigned byte to short
    // conversion for you.
    public void writeUnsignedByteToStream(
        byte samples[],
        int numSamples)
    {
        addUnsignedByteSamplesToInputBuffer(samples, numSamples);
        processStreamInput();
    }

    // Simple wrapper around sonicWriteBytesToStream that does the byte to 16-bit LE conversion.
    public void writeBytesToStream(
        byte inBuffer[],
        int numBytes)
    {
        addBytesToInputBuffer(inBuffer, numBytes);
        processStreamInput();
    }

    // This is a non-stream oriented interface to just change the speed of a sound sample
    public static int changeFloatSpeed(
        float samples[],
        int numSamples,
        float speed,
        float pitch,
        float rate,
        float volume,
        boolean useChordPitch,
        int sampleRate,
        int numChannels)
    {
        Sonic stream = new Sonic(sampleRate, numChannels);

        stream.setSpeed(speed);
        stream.setPitch(pitch);
        stream.setRate(rate);
        stream.setVolume(volume);
        stream.setChordPitch(useChordPitch);
        stream.writeFloatToStream(samples, numSamples);
        stream.flushStream();
        numSamples = stream.samplesAvailable();
        stream.readFloatFromStream(samples, numSamples);
        return numSamples;
    }

    /* This is a non-stream oriented interface to just change the speed of a sound sample */
    public int sonicChangeShortSpeed(
        short samples[],
        int numSamples,
        float speed,
        float pitch,
        float rate,
        float volume,
        boolean useChordPitch,
        int sampleRate,
        int numChannels)
    {
        Sonic stream = new Sonic(sampleRate, numChannels);

        stream.setSpeed(speed);
        stream.setPitch(pitch);
        stream.setRate(rate);
        stream.setVolume(volume);
        stream.setChordPitch(useChordPitch);
        stream.writeShortToStream(samples, numSamples);
        stream.flushStream();
        numSamples = stream.samplesAvailable();
        stream.readShortFromStream(samples, numSamples);
        return numSamples;
    }
}
