Mercurial > hg > jslab
view src/samer/audio/LineSink.java @ 8:5e3cbbf173aa tip
Reorganise some more
author | samer |
---|---|
date | Fri, 05 Apr 2019 22:41:58 +0100 |
parents | bf79fb79ee13 |
children |
line wrap: on
line source
/* * LineSink.java * * Copyright (c) 2000, Samer Abdallah, King's College London. * All rights reserved. * * This software is provided AS iS and WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. */ package samer.audio; import samer.core.*; import samer.core.types.*; import samer.tools.*; import java.io.*; import javax.sound.sampled.*; /** An AudioSink that sends samples to a Java Sound SourceDataLine. Audio format can be determined in several ways (see below). <p> Object is a Viewable, and is called "lineout". Reads property "scale" from current environment, but scale can be adjusted afterwards. @see samer.audio.AudioSink */ public class LineSink extends VLine implements AudioSink { private SourceDataLine line; private AudioFormat fmt; private int bufsize=0; private VDouble scale; /** Create LineSink reading from given TargetDataLine */ public LineSink(SourceDataLine l, AudioFormat f) throws Exception { super("lineout"); line=l; fmt=f; Shell.push(getNode()); scale=new VDouble("scale",1.0,0); Shell.pop(); } public DataLine getLine() { return line; } public boolean isOpen() { return line.isOpen(); } public void setBufferSize(int b) { bufsize=b; } /** * Returns the object used to store the scale factor for conversion from * doubles/floats to shorts/bytes. This is multiplied by 128 for conversion * to 8 bit audio, or 32768 for conversion to 16 bit audio. */ public VDouble getScale() { return scale; } public void dispose() { scale.dispose(); super.dispose(); } /** Open the line using either the current format or the line's default format if * none has been set. */ public void openImpl() throws Exception { if (bufsize==0) line.open(fmt); else line.open(fmt,bufsize); } public void closeImpl() throws Exception { line.close(); } /** Commands are :"set scale". */ public void getCommands(Registry r) { r.add("set scale").group(); super.getCommands(r); } public void execute(String cmd, Environment env) throws Exception { if (cmd.equals("set scale")) { env.datum().get(scale); } else super.execute(cmd,env); } public Task writer(final double dbuf[], final int off, final int len) { return new Writer(2*len) { public void write(double dbuf[], int off, int len) throws Exception { Util.doubleToShort(dbuf,buf,off,len,scale.value); super.write(2*len); } public void run() throws Exception { super.run(); Util.doubleToShort(dbuf,buf,off,len,scale.value); } }; } public Task writer(final float dbuf[], final int off, final int len) { return new Writer(2*len) { public void write(float dbuf[], int off, int len) throws Exception { Util.floatToShort(dbuf,buf,off,len,(float)scale.value); super.write(2*len); } public void run() throws Exception { super.run(); Util.floatToShort(dbuf,buf,off,len,(float)scale.value); } }; } protected class Writer implements Task { byte buf[]; int size; public Writer(int bufsize) { size=bufsize; buf=new byte[size]; } public void starting() { start(); } public void stopping() { stop(); } public void dispose() {} public void run() throws Exception { if (line.write(buf,0,size)<=0) throw new EOFException(); changed(); } public void write(int size) throws Exception { if (line.write(buf,0,size)<=0) throw new EOFException(); changed(); } } public static DataLine.Info lineInfo(AudioFormat fmt) { return new DataLine.Info( SourceDataLine.class, fmt); } public static DataLine.Info lineInfo(AudioFormat fmt, int bufsize) { return new DataLine.Info( SourceDataLine.class, fmt, bufsize); } }