Mercurial > hg > jslab
view src/samer/audio/FileSink.java @ 0:bf79fb79ee13
Initial Mercurial check in.
author | samer |
---|---|
date | Tue, 17 Jan 2012 17:50:20 +0000 |
parents | |
children |
line wrap: on
line source
/* * FileSink.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.core.util.*; import samer.tools.*; import javax.sound.sampled.*; import java.io.*; import org.tritonus.share.sampled.AudioSystemShadow; import org.tritonus.share.sampled.file.AudioOutputStream; /** An AudioSink that writes to a wav file. Viewable name: "wavewriter"<br> Properties read from current environment: <dl> <dt>filesink.current <dd>Current file (String) <dt>filesink.scale <dd>scale factor for converting floats/doubles (Double) </dl> */ public class FileSink extends Viewable implements AudioSink, Agent { VFile file; AudioOutputStream out=null; AudioFormat format; VDouble scale; public FileSink(String filename, AudioFormat fmt) throws Exception { this(fmt); file.setFile(new File(filename)); } public FileSink(AudioFormat fmt) { super("filessink"); Shell.push(node); file=new VFile("file","",0); scale=new VDouble("scale",1.0,0); Shell.push("audio"); format=fmt; Shell.pop(); Shell.pop(); setAgent(this); Shell.registerViewable(this); } public void dispose() { close(); Shell.deregisterViewable(this); file.dispose(); } public VDouble getScale() { return scale; } public void setFormat(AudioFormat f) { format=f; } public boolean isOpen() { return out!=null; } public void open() throws Exception { open(file.getFile()); } public synchronized void open(File file) throws Exception { Shell.trace("wave writer opening "+file+" as "+format); out=AudioSystemShadow.getAudioOutputStream( AudioFileFormat.Type.WAVE,format,AudioSystem.NOT_SPECIFIED, new BufferedOutputStream( new FileOutputStream(file))); this.file.setFile(file); } public synchronized void close() { try { if (out!=null) out.close(); out=null; } catch (IOException ex) { Shell.trace("*** Error closing: "+ex); } } public Task writer(final double [] dbuf, final int off, final int len) { return new AnonymousTask() { byte [] bbuf = new byte[2*len]; public void write(double dbuf[], int off, int len) throws Exception { synchronized (FileSink.this) { Util.doubleToShort(dbuf,bbuf,off,len,scale.value); writeBytes(bbuf, 2*len); } } public void run() throws Exception { synchronized (FileSink.this) { Util.doubleToShort(dbuf,bbuf,off,len,scale.value); writeBytes(bbuf, bbuf.length); } } }; } public Task writer(final float [] dbuf, final int off, final int len) { return new AnonymousTask() { byte [] bbuf = new byte[2*len]; public void write(float dbuf[], int off, int len) throws Exception { synchronized (FileSink.this) { Util.floatToShort(dbuf,bbuf,off,len,(float)scale.value); writeBytes(bbuf, 2*len); } } public void run() throws Exception { synchronized (FileSink.this) { Util.floatToShort(dbuf,bbuf,off,len,(float)scale.value); writeBytes(bbuf, bbuf.length); } } }; } private void writeBytes(byte [] buf,int len) throws Exception { int count = out.write(buf, 0, len); for (int n=count; n<len; n+=count) { count = out.write(buf, n, len - n); if (count<=0) throw new Exception("Write failed"); } } public void getCommands(Agent.Registry r) { r.add("open").add("close").add("set scale"); } public void execute(String cmd, Environment env) throws Exception { if (cmd.equals("open")) {close(); open(); } else if (cmd.equals("close")) close(); else if (cmd.equals("set scale")) { env.datum().get(scale); } } // Viewable public Viewer getViewer() { DefaultViewer vwr=new DefaultViewer(this); vwr.add(file); vwr.add(Shell.createButtonsFor(this)); return vwr; } }