comparison src/samer/audio/LineSink.java @ 0:bf79fb79ee13

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