package org.geogebra.web.html5.sound; import org.geogebra.common.kernel.geos.GeoFunction; import org.geogebra.common.sound.FunctionSound; import org.geogebra.common.util.debug.Log; import org.geogebra.web.html5.sound.WebAudioWrapper.FunctionAudioListener; /** * Class for playing function-generated sounds. * * @author Laszlo Gal * */ public final class FunctionSoundW extends FunctionSound implements FunctionAudioListener { public static final FunctionSoundW INSTANCE = new FunctionSoundW(); private WebAudioWrapper waw = WebAudioWrapper.INSTANCE; /** * Constructs instance of FunctionSound * */ public FunctionSoundW() { super(); if (WebAudioWrapper.INSTANCE.init()) { Log.debug("[WEB AUDIO] Initialization is OK."); } else { Log.debug("[WEB AUDIO] Initialization has FAILED."); } if (!initStreamingAudio(getSampleRate(), getBitDepth())) { Log.error("Cannot initialize streaming audio"); } } /** * Initializes instances of AudioFormat and SourceDataLine * * @param sampleRate * = 8000, 16000, 11025, 16000, 22050, or 44100 * @param bitDepth * = 8 or 16 * @return */ @Override protected boolean initStreamingAudio(int sampleRate, int bitDepth) { if (!super.initStreamingAudio(sampleRate, bitDepth)) { return false; } waw.setListener(this); return true; } /** * Plays a sound generated by the time valued GeoFunction f(t), from t = min * to t = max in seconds. The function is assumed to have range [-1,1] and * will be clipped to this range otherwise. * * @param geoFunction * @param min * @param max * @param sampleRate * @param bitDepth */ @Override public void playFunction(final GeoFunction geoFunction, final double min, final double max, final int sampleRate, final int bitDepth) { if (!checkFunction(geoFunction, min, max, sampleRate, bitDepth)) { return; } Log.debug("FunctionSound"); waw.setListener(this); generateFunctionSound(); } /** * Pauses/resumes sound generation * * @param doPause */ @Override public void pause(boolean resume) { if (resume) { Log.debug("Resume"); playFunction(getF(), getMin(), getMax(), getSampleRate(), getBitDepth()); } else { Log.debug("Pause"); setMin(getT()); stopSound(); } } private void generateFunctionSound() { waw.start(getMin(), getMax(), getSampleRate()); } /** * Stops function sound */ public void stopSound() { waw.stop(); } @Override public double getValueAt(double t) { double value = getF().value(t + 1.0 * getSamplePeriod()); if (value > 1.0) { value = 1.0; } if (value < -1.0) { value = -1.0; } return value; } }