package org.jcodec.player.filters.audio; import java.io.IOException; import java.nio.ByteBuffer; import javax.sound.sampled.AudioFormat; import org.jcodec.common.model.AudioFrame; import org.jcodec.common.model.ChannelLabel; import org.jcodec.common.model.RationalLarge; import org.jcodec.player.filters.MediaInfo; /** * This class is part of JCodec ( www.jcodec.org ) This software is distributed * under FreeBSD License * * Generates audio tones * * Audio format: PCM 16bit stereo signed little endian * * @author The JCodec project * */ public class ToneAudioSource implements AudioSource { private static final int FRAMES_PER_PACKET = 2048; private static final int SAMPLE_RATE = 48000; private long lastSample; private AudioFormat format; public ToneAudioSource() { } @Override public MediaInfo.AudioInfo getAudioInfo() { format = new AudioFormat(SAMPLE_RATE, 16, 2, true, false); return new MediaInfo.AudioInfo("pcm", SAMPLE_RATE, Long.MAX_VALUE, Long.MAX_VALUE, "Main Stereo", null, format, new ChannelLabel[] { ChannelLabel.STEREO_LEFT, ChannelLabel.STEREO_LEFT }); } @Override public AudioFrame getFrame(ByteBuffer result) throws IOException { if (result.remaining() < (FRAMES_PER_PACKET << 2)) throw new IllegalArgumentException("Data won't fit into the buffer"); ByteBuffer dd = result.duplicate(); long ss = lastSample; for (int i = 0; i < FRAMES_PER_PACKET; i++) { int fr = (int) (((ss + i) / SAMPLE_RATE) % 50); short sl = (short) (Short.MAX_VALUE * Math.sin(((150 + fr * 10) * 2 * Math.PI * (ss + i)) / SAMPLE_RATE)); dd.put((byte) (sl & 0xff)); dd.put((byte) (sl >> 8)); short sr = (short) (Short.MAX_VALUE * Math.sin(((150 + fr * 10) * 2 * Math.PI * (ss + i)) / SAMPLE_RATE)); dd.put((byte) (sr & 0xff)); dd.put((byte) (sr >> 8)); } lastSample += FRAMES_PER_PACKET; dd.flip(); return new AudioFrame(dd, format, FRAMES_PER_PACKET, lastSample, FRAMES_PER_PACKET, SAMPLE_RATE, (int) (lastSample / FRAMES_PER_PACKET)); } @Override public boolean drySeek(RationalLarge second) throws IOException { return true; } @Override public void seek(RationalLarge second) { lastSample = second.multiplyS(SAMPLE_RATE); } @Override public void close() throws IOException { } }