/* * Copyright (C) 2013 Darth Affe and contributors * * 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 . * * * This Code is based on the source provided with a tutorial by * http://www.badlogicgames.com (as of 16.05.2013). * The original source can be found here: * http://code.google.com/p/audio-analysis/source/browse/trunk/src/com/badlogic/audio/io/AudioDevice.java */ package org.wyrez.audio; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.SourceDataLine; /** * Class that allows directly passing PCM float data to the sound card for * playback. * * @author Darth Affe */ public class AudioDevice { private final SourceDataLine out; private byte[] buffer; /** * Constructor, initializes the audio system for 16-bit signed stereo output * with a sampling rate of 44100 and a buffer size of 2048. * * @throws Exception in case the audio system could not be initialized */ public AudioDevice() throws Exception { this(44100, 2); } /** * Constructor, initializes the audio system for 16-bit signed output. Sets * the buffer size to 1024*channels * * @param samplingRate The sampling rate * @param channels The number of channels * @throws Exception in case the audio system could not be initialized */ public AudioDevice(float samplingRate, int channels) throws Exception { this(samplingRate, channels, 1024 * channels); } /** * Constructor, initializes the audio system for 16-bit signed output. * * @param samplingRate The sampling rate * @param channels The number of channels * @param bufferSize The buffer size (have to be a even number) * @throws Exception in case the audio system could not be initialized */ public AudioDevice(float samplingRate, int channels, int bufferSize) throws Exception { AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, samplingRate, 16, channels, channels * 2, samplingRate, false); buffer = new byte[bufferSize * 2]; out = AudioSystem.getSourceDataLine(format); out.open(format); out.start(); } /** * Writes the given samples to the audio device. The samples have to be in * the range [-1,1]. * * @param samples The samples. */ public void writeSamples(float[] samples) { fillBuffer(samples); out.write(buffer, 0, buffer.length); } private void fillBuffer(float[] samples) { for (int i = 0, j = 0; i < samples.length; i++, j += 2) { short value = (short) (samples[i] * Short.MAX_VALUE); buffer[j] = (byte) (value | 0xff); buffer[j + 1] = (byte) (value >> 8); } } }