Java Sinus Generator

package de.sambalmueslie.sine_generator;

/**
 * Generate a sine.
 * 
 * Copyright (C) 2012 Oliver Eckle
 * 
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 */
public class SineGenerator {

	/** the maximum samples per oscillation. */
	private static final int MAX_SAMPLES_PER_OSCILLATION = 160;
	/** the minimum samples per oscillation. */
	private static final int MIN_SAMPLES_PER_OSCILLATION = 2;

	/**
	 * Constructor.
	 * 
	 * @param theSampleRate
	 *            the sample rate
	 * @param theMaximumAmplitude
	 *            the maximum amplitude
	 */
	public SineGenerator(final int theSampleRate,
			final short theMaximumAmplitude) {
		sampleRate = theSampleRate;
		maximumAmplitude = theMaximumAmplitude;
	}

	/**
	 * Generate sine oscillation samples for a defined total length.
	 * 
	 * @param frequency
	 *            the freqency
	 * @param totalSamples
	 *            the total samples
	 * @return the result
	 */
	public short[] generateSineOscillationSamples(final int frequency,
			final int totalSamples) {
		final short[] result = new short[totalSamples];
		final short[] singleResult = generateSingleSineOscillationSamples(frequency);
		for (int i = 0; i < totalSamples; i++) {
			final int j = i % singleResult.length;
			result[i] = singleResult[j];
		}
		return result;
	}

	/**
	 * Generate the samples for one single sine oscillation.
	 * 
	 * @param frequency
	 *            the frequency
	 * @return the generated samples
	 */
	public short[] generateSingleSineOscillationSamples(final int frequency) {
		final int samples = calculateSamplesPerOscillation(frequency);
		final short[] result = new short[samples];
		final int samplesMiddle = samples / 2;
		for (int i = 0; i < samples; i++) {
			if (i < samplesMiddle) {
				final double c = (i == 0) ? 0 : 2 * Math.PI * i / samples;
				final double sineVal = Math.sin(c);
				result[i] = (short) (sineVal * maximumAmplitude);
			} else {
				result[i] = (short) (result[i - samplesMiddle] * -1);
			}
		}
		return result;
	}

	/**
	 * Calculate the total samples per oscillation.
	 * 
	 * @param frequency
	 *            the frequency
	 * @return the calculated samples
	 */
	private int calculateSamplesPerOscillation(final int frequency) {
		if (frequency <= 0) {
			return MAX_SAMPLES_PER_OSCILLATION;
		}
		final int samples = sampleRate / frequency;
		if (samples > MAX_SAMPLES_PER_OSCILLATION) {
			return MAX_SAMPLES_PER_OSCILLATION;
		} else if (samples < MIN_SAMPLES_PER_OSCILLATION) {
			return MIN_SAMPLES_PER_OSCILLATION;
		}
		return samples;
	}

	/** the amplitude. */
	private final int maximumAmplitude;
	/** the sample rate. */
	private final int sampleRate;

}

 

SineGenerator