Mercurial > hg > jslab
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 } |