annotate 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
rev   line source
samer@0 1 /*
samer@0 2 * LineSink.java
samer@0 3 *
samer@0 4 * Copyright (c) 2000, Samer Abdallah, King's College London.
samer@0 5 * All rights reserved.
samer@0 6 *
samer@0 7 * This software is provided AS iS and WITHOUT ANY WARRANTY;
samer@0 8 * without even the implied warranty of MERCHANTABILITY or
samer@0 9 * FITNESS FOR A PARTICULAR PURPOSE.
samer@0 10 */
samer@0 11
samer@0 12 package samer.audio;
samer@0 13 import samer.core.*;
samer@0 14 import samer.core.types.*;
samer@0 15 import samer.tools.*;
samer@0 16 import java.io.*;
samer@0 17 import javax.sound.sampled.*;
samer@0 18
samer@0 19 /**
samer@0 20 An AudioSink that sends samples to a Java Sound SourceDataLine.
samer@0 21 Audio format can be determined in several ways (see below).
samer@0 22 <p> Object is a Viewable, and is called "lineout".
samer@0 23 Reads property "scale" from current environment, but scale
samer@0 24 can be adjusted afterwards.
samer@0 25 @see samer.audio.AudioSink
samer@0 26 */
samer@0 27
samer@0 28 public class LineSink extends VLine implements AudioSink
samer@0 29 {
samer@0 30 private SourceDataLine line;
samer@0 31 private AudioFormat fmt;
samer@0 32 private int bufsize=0;
samer@0 33 private VDouble scale;
samer@0 34
samer@0 35 /** Create LineSink reading from given TargetDataLine */
samer@0 36 public LineSink(SourceDataLine l, AudioFormat f) throws Exception {
samer@0 37 super("lineout");
samer@0 38 line=l; fmt=f;
samer@0 39 Shell.push(getNode());
samer@0 40 scale=new VDouble("scale",1.0,0);
samer@0 41 Shell.pop();
samer@0 42 }
samer@0 43
samer@0 44 public DataLine getLine() { return line; }
samer@0 45 public boolean isOpen() { return line.isOpen(); }
samer@0 46 public void setBufferSize(int b) { bufsize=b; }
samer@0 47
samer@0 48 /**
samer@0 49 * Returns the object used to store the scale factor for conversion from
samer@0 50 * doubles/floats to shorts/bytes. This is multiplied by 128 for conversion
samer@0 51 * to 8 bit audio, or 32768 for conversion to 16 bit audio.
samer@0 52 */
samer@0 53 public VDouble getScale() { return scale; }
samer@0 54
samer@0 55 public void dispose() { scale.dispose(); super.dispose(); }
samer@0 56
samer@0 57 /** Open the line using either the current format or the line's default format if
samer@0 58 * none has been set.
samer@0 59 */
samer@0 60 public void openImpl() throws Exception {
samer@0 61 if (bufsize==0) line.open(fmt); else line.open(fmt,bufsize);
samer@0 62 }
samer@0 63
samer@0 64 public void closeImpl() throws Exception { line.close(); }
samer@0 65
samer@0 66 /** Commands are :"set scale". */
samer@0 67 public void getCommands(Registry r) {
samer@0 68 r.add("set scale").group();
samer@0 69 super.getCommands(r);
samer@0 70 }
samer@0 71
samer@0 72 public void execute(String cmd, Environment env) throws Exception {
samer@0 73 if (cmd.equals("set scale")) { env.datum().get(scale); }
samer@0 74 else super.execute(cmd,env);
samer@0 75 }
samer@0 76
samer@0 77 public Task writer(final double dbuf[], final int off, final int len) {
samer@0 78 return new Writer(2*len) {
samer@0 79 public void write(double dbuf[], int off, int len) throws Exception {
samer@0 80 Util.doubleToShort(dbuf,buf,off,len,scale.value);
samer@0 81 super.write(2*len);
samer@0 82 }
samer@0 83 public void run() throws Exception {
samer@0 84 super.run(); Util.doubleToShort(dbuf,buf,off,len,scale.value);
samer@0 85 }
samer@0 86 };
samer@0 87 }
samer@0 88
samer@0 89 public Task writer(final float dbuf[], final int off, final int len) {
samer@0 90 return new Writer(2*len) {
samer@0 91 public void write(float dbuf[], int off, int len) throws Exception {
samer@0 92 Util.floatToShort(dbuf,buf,off,len,(float)scale.value);
samer@0 93 super.write(2*len);
samer@0 94 }
samer@0 95 public void run() throws Exception {
samer@0 96 super.run(); Util.floatToShort(dbuf,buf,off,len,(float)scale.value);
samer@0 97 }
samer@0 98 };
samer@0 99 }
samer@0 100
samer@0 101 protected class Writer implements Task {
samer@0 102 byte buf[];
samer@0 103 int size;
samer@0 104
samer@0 105 public Writer(int bufsize) { size=bufsize; buf=new byte[size]; }
samer@0 106
samer@0 107 public void starting() { start(); }
samer@0 108 public void stopping() { stop(); }
samer@0 109 public void dispose() {}
samer@0 110 public void run() throws Exception {
samer@0 111 if (line.write(buf,0,size)<=0) throw new EOFException();
samer@0 112 changed();
samer@0 113 }
samer@0 114
samer@0 115 public void write(int size) throws Exception {
samer@0 116 if (line.write(buf,0,size)<=0) throw new EOFException();
samer@0 117 changed();
samer@0 118 }
samer@0 119 }
samer@0 120
samer@0 121 public static DataLine.Info lineInfo(AudioFormat fmt) {
samer@0 122 return new DataLine.Info( SourceDataLine.class, fmt);
samer@0 123 }
samer@0 124
samer@0 125 public static DataLine.Info lineInfo(AudioFormat fmt, int bufsize) {
samer@0 126 return new DataLine.Info( SourceDataLine.class, fmt, bufsize);
samer@0 127 }
samer@0 128 }
samer@0 129