/* * Copyright (C) 2017 たんらる */ package fourthline.mabiicco.midi; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Control; import javax.sound.sampled.Control.Type; import javax.sound.sampled.LineListener; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import fourthline.mmlTools.core.NanoTime; public final class WavoutDataLine implements SourceDataLine, IWavoutState { private final SourceDataLine parent; private final AudioFormat format = new AudioFormat(44100, 16, 2, true, false); private boolean rec = false; private OutputStream outputStream = null; private File tempFile = null; private OutputStream tempOutputStream = null; private Runnable endNotify; public WavoutDataLine() throws LineUnavailableException { this.parent = AudioSystem.getSourceDataLine(format); } private long time; private long curLen; @Override public long getTime() { return time; } @Override public long getLen() { return curLen; } public void startRec(OutputStream outputStream, Runnable endNotify) { try { tempFile = new File("wavout_"+(int)(Math.random()*100)+".raw"); System.out.println("startRec:" + tempFile); tempOutputStream = new BufferedOutputStream(new FileOutputStream(tempFile)); this.rec = true; this.outputStream = outputStream; this.endNotify = endNotify; time = 0; curLen = 0; } catch (IOException e) { e.printStackTrace(); } } public void stopRec() { if (this.rec && (this.endNotify != null)) { this.rec = false; this.endNotify.run(); this.endNotify = null; } this.rec = false; } @Override public void drain() { parent.drain(); } @Override public void flush() { parent.flush(); } @Override public void start() { parent.start(); } @Override public void stop() { parent.stop(); } @Override public boolean isRunning() { return parent.isRunning(); } @Override public boolean isActive() { return parent.isActive(); } @Override public AudioFormat getFormat() { return parent.getFormat(); } @Override public int getBufferSize() { return parent.getBufferSize(); } @Override public int available() { return available(); } @Override public int getFramePosition() { return parent.getFramePosition(); } @Override public long getLongFramePosition() { return parent.getLongFramePosition(); } @Override public long getMicrosecondPosition() { return parent.getMicrosecondPosition(); } @Override public float getLevel() { return parent.getLevel(); } @Override public javax.sound.sampled.Line.Info getLineInfo() { return parent.getLineInfo(); } @Override public void open() throws LineUnavailableException { parent.open(); } @Override public void close() { parent.close(); } @Override public boolean isOpen() { return parent.isOpen(); } @Override public Control[] getControls() { return parent.getControls(); } @Override public boolean isControlSupported(Type control) { return parent.isControlSupported(control); } @Override public Control getControl(Type control) { return parent.getControl(control); } @Override public void addLineListener(LineListener listener) { parent.addLineListener(listener); } @Override public void removeLineListener(LineListener listener) { parent.removeLineListener(listener); } @Override public void open(AudioFormat format, int bufferSize) throws LineUnavailableException { parent.open(format, bufferSize); } @Override public void open(AudioFormat format) throws LineUnavailableException { parent.open(format); } private void wavoutEndCheck(byte[] b, int off, int len) { if (!rec && (tempOutputStream != null)) { boolean stop = true; for (int i = 0; i < len; i++) { if (b[i] != 0) { stop = false; break; } } if (stop) { try { tempOutputStream.close(); long size = tempFile.length()/format.getFrameSize(); AudioInputStream in = new AudioInputStream(new FileInputStream(tempFile), format, size); AudioSystem.write(in, AudioFileFormat.Type.WAVE, outputStream); in.close(); tempFile.delete(); System.out.println("stopRec: "+size); } catch (IOException e) { e.printStackTrace(); } tempOutputStream = null; } } } @Override public int write(byte[] b, int off, int len) { wavoutEndCheck(b, off, len); if (tempOutputStream != null) { NanoTime time = NanoTime.start(); curLen += len; try { tempOutputStream.write(b, off, len); } catch (IOException e) { e.printStackTrace(); } this.time += time.ms(); } return parent.write(b, off, len); } }