comparison src/samer/audio/FileSink.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 * FileSink.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
14 import samer.core.*;
15 import samer.core.types.*;
16 import samer.core.util.*;
17 import samer.tools.*;
18 import javax.sound.sampled.*;
19 import java.io.*;
20
21 import org.tritonus.share.sampled.AudioSystemShadow;
22 import org.tritonus.share.sampled.file.AudioOutputStream;
23
24 /**
25 An AudioSink that writes to a wav file.
26 Viewable name: "wavewriter"<br>
27 Properties read from current environment:
28 <dl>
29 <dt>filesink.current
30 <dd>Current file (String)
31 <dt>filesink.scale
32 <dd>scale factor for converting floats/doubles (Double)
33 </dl>
34 */
35
36 public class FileSink extends Viewable implements AudioSink, Agent
37 {
38 VFile file;
39 AudioOutputStream out=null;
40 AudioFormat format;
41 VDouble scale;
42
43 public FileSink(String filename, AudioFormat fmt) throws Exception {
44 this(fmt); file.setFile(new File(filename));
45 }
46
47 public FileSink(AudioFormat fmt)
48 {
49 super("filessink");
50
51 Shell.push(node);
52 file=new VFile("file","",0);
53 scale=new VDouble("scale",1.0,0);
54 Shell.push("audio");
55 format=fmt;
56 Shell.pop();
57 Shell.pop();
58
59 setAgent(this);
60 Shell.registerViewable(this);
61 }
62
63 public void dispose() {
64 close();
65 Shell.deregisterViewable(this);
66 file.dispose();
67 }
68
69 public VDouble getScale() { return scale; }
70 public void setFormat(AudioFormat f) { format=f; }
71
72 public boolean isOpen() { return out!=null; }
73 public void open() throws Exception { open(file.getFile()); }
74 public synchronized void open(File file) throws Exception
75 {
76 Shell.trace("wave writer opening "+file+" as "+format);
77
78 out=AudioSystemShadow.getAudioOutputStream(
79 AudioFileFormat.Type.WAVE,format,AudioSystem.NOT_SPECIFIED,
80 new BufferedOutputStream(
81 new FileOutputStream(file)));
82 this.file.setFile(file);
83 }
84
85 public synchronized void close() {
86 try { if (out!=null) out.close(); out=null; }
87 catch (IOException ex) { Shell.trace("*** Error closing: "+ex); }
88 }
89
90 public Task writer(final double [] dbuf, final int off, final int len) {
91 return new AnonymousTask() {
92 byte [] bbuf = new byte[2*len];
93
94 public void write(double dbuf[], int off, int len) throws Exception {
95 synchronized (FileSink.this) {
96 Util.doubleToShort(dbuf,bbuf,off,len,scale.value);
97 writeBytes(bbuf, 2*len);
98 }
99 }
100 public void run() throws Exception {
101 synchronized (FileSink.this) {
102 Util.doubleToShort(dbuf,bbuf,off,len,scale.value);
103 writeBytes(bbuf, bbuf.length);
104 }
105 }
106 };
107 }
108
109 public Task writer(final float [] dbuf, final int off, final int len) {
110 return new AnonymousTask() {
111 byte [] bbuf = new byte[2*len];
112
113 public void write(float dbuf[], int off, int len) throws Exception {
114 synchronized (FileSink.this) {
115 Util.floatToShort(dbuf,bbuf,off,len,(float)scale.value);
116 writeBytes(bbuf, 2*len);
117 }
118 }
119 public void run() throws Exception {
120 synchronized (FileSink.this) {
121 Util.floatToShort(dbuf,bbuf,off,len,(float)scale.value);
122 writeBytes(bbuf, bbuf.length);
123 }
124 }
125 };
126 }
127
128 private void writeBytes(byte [] buf,int len) throws Exception {
129 int count = out.write(buf, 0, len);
130 for (int n=count; n<len; n+=count) {
131 count = out.write(buf, n, len - n);
132 if (count<=0) throw new Exception("Write failed");
133 }
134 }
135
136 public void getCommands(Agent.Registry r) { r.add("open").add("close").add("set scale"); }
137 public void execute(String cmd, Environment env) throws Exception {
138 if (cmd.equals("open")) {close(); open(); }
139 else if (cmd.equals("close")) close();
140 else if (cmd.equals("set scale")) { env.datum().get(scale); }
141 }
142
143 // Viewable
144 public Viewer getViewer() {
145 DefaultViewer vwr=new DefaultViewer(this);
146 vwr.add(file);
147 vwr.add(Shell.createButtonsFor(this));
148 return vwr;
149 }
150 }