/** * Copyright (c) 2014-2017 by the respective copyright holders. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.smarthome.io.javasound.internal; import java.util.Collections; import java.util.Locale; import java.util.Set; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.TargetDataLine; import org.eclipse.smarthome.core.audio.AudioException; import org.eclipse.smarthome.core.audio.AudioFormat; import org.eclipse.smarthome.core.audio.AudioSource; import org.eclipse.smarthome.core.audio.AudioStream; /** * This is an AudioSource from an input channel of the host. * * @author Kelly Davis - Initial contribution and API * @author Kai Kreuzer - Refactored and stabilized * */ public class JavaSoundAudioSource implements AudioSource { /** * Java Sound audio format */ private final javax.sound.sampled.AudioFormat format = new javax.sound.sampled.AudioFormat(16000.0f, 16, 1, true, false); /** * AudioFormat of the JavaSoundAudioSource */ private final AudioFormat audioFormat = convertAudioFormat(format); /** * TargetDataLine for the mic */ private TargetDataLine microphone; /** * Constructs a JavaSoundAudioSource */ public JavaSoundAudioSource() { } private void initMicrophone(javax.sound.sampled.AudioFormat format) throws AudioException { try { TargetDataLine microphone; microphone = AudioSystem.getTargetDataLine(format); DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); microphone = (TargetDataLine) AudioSystem.getLine(info); microphone.open(format); this.microphone = microphone; } catch (Exception e) { throw new AudioException("Error creating the audio input stream.", e); } } @Override public synchronized AudioStream getInputStream(AudioFormat expectedFormat) throws AudioException { if (!expectedFormat.isCompatible(audioFormat)) { throw new AudioException("Cannot produce streams in format " + expectedFormat); } if (microphone == null) { initMicrophone(format); } return new JavaSoundInputStream(this.microphone, audioFormat); } @Override public String toString() { return "javasound"; } /** * Converts a javax.sound.sampled.AudioFormat to a org.eclipse.smarthome.core.audio.AudioFormat * * @param audioFormat the AudioFormat to convert * @return The converted AudioFormat */ private static AudioFormat convertAudioFormat(javax.sound.sampled.AudioFormat audioFormat) { String container = AudioFormat.CONTAINER_WAVE; String codec = audioFormat.getEncoding().toString(); Boolean bigEndian = new Boolean(audioFormat.isBigEndian()); int frameSize = audioFormat.getFrameSize(); // In bytes int bitsPerFrame = frameSize * 8; Integer bitDepth = ((AudioSystem.NOT_SPECIFIED == frameSize) ? null : new Integer(bitsPerFrame)); float frameRate = audioFormat.getFrameRate(); Integer bitRate = ((AudioSystem.NOT_SPECIFIED == frameRate) ? null : new Integer((int) (frameRate * bitsPerFrame))); float sampleRate = audioFormat.getSampleRate(); Long frequency = ((AudioSystem.NOT_SPECIFIED == sampleRate) ? null : new Long((long) sampleRate)); return new AudioFormat(container, codec, bigEndian, bitDepth, bitRate, frequency); } @Override public String getId() { return "javasound"; } @Override public String getLabel(Locale locale) { return "System Microphone"; } @Override public Set<AudioFormat> getSupportedFormats() { return Collections.singleton(audioFormat); } }