/* * myLib - https://github.com/taktod/myLib * Copyright (c) 2014 ttProject. All rights reserved. * * Licensed under GNU GENERAL PUBLIC LICENSE Version 3. */ package com.ttProject.xuggle.test; import java.nio.ByteBuffer; import java.nio.ByteOrder; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.SourceDataLine; import org.apache.log4j.Logger; import org.junit.Test; import com.xuggle.xuggler.IAudioResampler; import com.xuggle.xuggler.IAudioSamples; import com.xuggle.xuggler.ICodec; import com.xuggle.xuggler.IPacket; import com.xuggle.xuggler.IStream; import com.xuggle.xuggler.IStreamCoder; import com.xuggle.xuggler.IAudioSamples.Format; import com.xuggle.xuggler.IContainer; /** * make beep sound. * @author taktod */ public class BeepSoundTest { /** logger */ private Logger logger = Logger.getLogger(BeepSoundTest.class); /** * play beep test. * @throws Exception */ // @Test public void playTest() throws Exception { logger.info("start playTest"); SourceDataLine audioLine = null; IAudioSamples samples = beepSamples(); AudioFormat format = new AudioFormat((float)samples.getSampleRate(), (int)samples.getSampleBitDepth(), samples.getChannels(), true, false); DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); audioLine = (SourceDataLine)AudioSystem.getLine(info); audioLine.open(format); logger.info("beepstart"); audioLine.start(); audioLine.write(samples.getData().getByteArray(0, samples.getSize()), 0, samples.getSize()); audioLine.drain(); logger.info("beepend"); audioLine.close(); audioLine = null; } /** * make flv(nellymoser)test. * @throws Exception */ @Test public void flvNellymoserTest() throws Exception { logger.info("flvNellymoserTest"); IContainer container = IContainer.make(); if(container.open("flv_nellymoser.flv", IContainer.Type.WRITE, null) < 0) { throw new Exception("failed to open container."); } IStream stream = container.addNewStream(ICodec.ID.CODEC_ID_NELLYMOSER); IStreamCoder encoder = stream.getStreamCoder(); encoder.setSampleRate(44100); encoder.setChannels(1); encoder.setBitRate(96000); processConvert(container, encoder); logger.info("end"); } @Test public void oggVorbisTest() throws Exception { logger.info("oggVorbisTest"); IContainer container = IContainer.make(); if(container.open("ogg_vorbis.ogg", IContainer.Type.WRITE, null) < 0) { throw new Exception("failed to open container."); } IStream stream = container.addNewStream(ICodec.ID.CODEC_ID_VORBIS); IStreamCoder encoder = stream.getStreamCoder(); encoder.setSampleRate(44100); encoder.setChannels(2); encoder.setBitRate(96000); processConvert(container, encoder); logger.info("end"); } @Test public void flvMp3Test() throws Exception { logger.info("flvMp3Test"); IContainer container = IContainer.make(); if(container.open("flv_mp3.flv", IContainer.Type.WRITE, null) < 0) { throw new Exception("failed to open container."); } IStream stream = container.addNewStream(ICodec.ID.CODEC_ID_MP3); IStreamCoder encoder = stream.getStreamCoder(); encoder.setSampleRate(44100); encoder.setChannels(2); encoder.setBitRate(96000); processConvert(container, encoder); logger.info("end"); } /** * process convertTask. * @param container * @param encoder * @throws Exception */ public void processConvert(IContainer container, IStreamCoder encoder) throws Exception { ICodec codec = encoder.getCodec(); Format findFormat = null; for(Format format : codec.getSupportedAudioSampleFormats()) { if(findFormat == null) { findFormat = format; } if(findFormat == Format.FMT_S16) { findFormat = format; break; } } if(findFormat == null) { throw new Exception("audioSampleFormat is unknwon."); } logger.info("found format:" + findFormat); encoder.setSampleFormat(findFormat); if(encoder.open(null, null) < 0) { throw new Exception("failed to open audioEncoder"); } if(container.writeHeader() < 0) { throw new Exception("failed to write header."); } IPacket packet = IPacket.make(); IAudioSamples samples = beepSamples(); if(samples.getSampleRate() != encoder.getSampleRate() || samples.getFormat() != encoder.getSampleFormat() || samples.getChannels() != encoder.getChannels()) { IAudioResampler resampler = IAudioResampler.make( encoder.getChannels(), samples.getChannels(), encoder.getSampleRate(), samples.getSampleRate(), encoder.getSampleFormat(), samples.getFormat()); IAudioSamples spl = IAudioSamples.make(samples.getNumSamples(), encoder.getChannels()); int retVal = resampler.resample(spl, samples, samples.getNumSamples()); if(retVal <= 0) { throw new Exception("failed to audio resample."); } samples = spl; } int samplesConsumed = 0; while(samplesConsumed < samples.getNumSamples()) { int retVal = encoder.encodeAudio(packet, samples, samplesConsumed); if(retVal < 0) { throw new Exception("failed to audio encode."); } samplesConsumed += retVal; if(packet.isComplete()) { if(container.writePacket(packet) < 0) { throw new Exception("failed to write container."); } } } if(container.writeTrailer() < 0) { throw new Exception("failed to write trailer."); } } /** * make sine wave xuggler IAudioSamples. * @return */ private IAudioSamples beepSamples() { int sampleRate = 44100; // 44.1KHz int sampleNum = 44100; // 44100 samples(1sec) int channel = 2; // 2channel(stereo) int tone = 440; // 440Hz tone. int bit = 16; // 16bit ByteBuffer buffer = ByteBuffer.allocate((int)sampleNum * bit * channel / 8); double rad = tone * 2 * Math.PI / sampleRate; // radian for each sample. double max = (1 << (bit - 2)) - 1; // ampletude buffer.order(ByteOrder.LITTLE_ENDIAN); for(int i = 0;i < sampleNum;i ++) { short data = (short)(Math.sin(rad * i) * max); for(int j = 0;j < channel;j ++) { buffer.putShort(data); } } buffer.flip(); IAudioSamples samples = IAudioSamples.make(sampleNum, channel, Format.FMT_S16); samples.getData().put(buffer.array(), 0, 0, buffer.remaining()); samples.setComplete(true, sampleNum, sampleRate, channel, Format.FMT_S16, 0); samples.setTimeStamp(0); samples.setPts(0); return samples; } }