samer@0: /*
samer@0: * FileSink.java
samer@0: *
samer@0: * Copyright (c) 2000, Samer Abdallah, King's College London.
samer@0: * All rights reserved.
samer@0: *
samer@0: * This software is provided AS iS and WITHOUT ANY WARRANTY;
samer@0: * without even the implied warranty of MERCHANTABILITY or
samer@0: * FITNESS FOR A PARTICULAR PURPOSE.
samer@0: */
samer@0:
samer@0: package samer.audio;
samer@0:
samer@0: import samer.core.*;
samer@0: import samer.core.types.*;
samer@0: import samer.core.util.*;
samer@0: import samer.tools.*;
samer@0: import javax.sound.sampled.*;
samer@0: import java.io.*;
samer@0:
samer@0: import org.tritonus.share.sampled.AudioSystemShadow;
samer@0: import org.tritonus.share.sampled.file.AudioOutputStream;
samer@0:
samer@0: /**
samer@0: An AudioSink that writes to a wav file.
samer@0: Viewable name: "wavewriter"
samer@0: Properties read from current environment:
samer@0:
samer@0: - filesink.current
samer@0:
- Current file (String)
samer@0:
- filesink.scale
samer@0:
- scale factor for converting floats/doubles (Double)
samer@0:
samer@0: */
samer@0:
samer@0: public class FileSink extends Viewable implements AudioSink, Agent
samer@0: {
samer@0: VFile file;
samer@0: AudioOutputStream out=null;
samer@0: AudioFormat format;
samer@0: VDouble scale;
samer@0:
samer@0: public FileSink(String filename, AudioFormat fmt) throws Exception {
samer@0: this(fmt); file.setFile(new File(filename));
samer@0: }
samer@0:
samer@0: public FileSink(AudioFormat fmt)
samer@0: {
samer@0: super("filessink");
samer@0:
samer@0: Shell.push(node);
samer@0: file=new VFile("file","",0);
samer@0: scale=new VDouble("scale",1.0,0);
samer@0: Shell.push("audio");
samer@0: format=fmt;
samer@0: Shell.pop();
samer@0: Shell.pop();
samer@0:
samer@0: setAgent(this);
samer@0: Shell.registerViewable(this);
samer@0: }
samer@0:
samer@0: public void dispose() {
samer@0: close();
samer@0: Shell.deregisterViewable(this);
samer@0: file.dispose();
samer@0: }
samer@0:
samer@0: public VDouble getScale() { return scale; }
samer@0: public void setFormat(AudioFormat f) { format=f; }
samer@0:
samer@0: public boolean isOpen() { return out!=null; }
samer@0: public void open() throws Exception { open(file.getFile()); }
samer@0: public synchronized void open(File file) throws Exception
samer@0: {
samer@0: Shell.trace("wave writer opening "+file+" as "+format);
samer@0:
samer@0: out=AudioSystemShadow.getAudioOutputStream(
samer@0: AudioFileFormat.Type.WAVE,format,AudioSystem.NOT_SPECIFIED,
samer@0: new BufferedOutputStream(
samer@0: new FileOutputStream(file)));
samer@0: this.file.setFile(file);
samer@0: }
samer@0:
samer@0: public synchronized void close() {
samer@0: try { if (out!=null) out.close(); out=null; }
samer@0: catch (IOException ex) { Shell.trace("*** Error closing: "+ex); }
samer@0: }
samer@0:
samer@0: public Task writer(final double [] dbuf, final int off, final int len) {
samer@0: return new AnonymousTask() {
samer@0: byte [] bbuf = new byte[2*len];
samer@0:
samer@0: public void write(double dbuf[], int off, int len) throws Exception {
samer@0: synchronized (FileSink.this) {
samer@0: Util.doubleToShort(dbuf,bbuf,off,len,scale.value);
samer@0: writeBytes(bbuf, 2*len);
samer@0: }
samer@0: }
samer@0: public void run() throws Exception {
samer@0: synchronized (FileSink.this) {
samer@0: Util.doubleToShort(dbuf,bbuf,off,len,scale.value);
samer@0: writeBytes(bbuf, bbuf.length);
samer@0: }
samer@0: }
samer@0: };
samer@0: }
samer@0:
samer@0: public Task writer(final float [] dbuf, final int off, final int len) {
samer@0: return new AnonymousTask() {
samer@0: byte [] bbuf = new byte[2*len];
samer@0:
samer@0: public void write(float dbuf[], int off, int len) throws Exception {
samer@0: synchronized (FileSink.this) {
samer@0: Util.floatToShort(dbuf,bbuf,off,len,(float)scale.value);
samer@0: writeBytes(bbuf, 2*len);
samer@0: }
samer@0: }
samer@0: public void run() throws Exception {
samer@0: synchronized (FileSink.this) {
samer@0: Util.floatToShort(dbuf,bbuf,off,len,(float)scale.value);
samer@0: writeBytes(bbuf, bbuf.length);
samer@0: }
samer@0: }
samer@0: };
samer@0: }
samer@0:
samer@0: private void writeBytes(byte [] buf,int len) throws Exception {
samer@0: int count = out.write(buf, 0, len);
samer@0: for (int n=count; n