Package com.meapsoft

Source Code of com.meapsoft.AudioWriter

/*
*  Copyright 2006-2007 Columbia University.
*
*  This file is part of MEAPsoft.
*
*  MEAPsoft is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License version 2 as
*  published by the Free Software Foundation.
*
*  MEAPsoft is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with MEAPsoft; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
*  02110-1301 USA
*
*  See the file "COPYING" for the text of the license.
*/

package com.meapsoft;

import java.io.File;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.SourceDataLine;

/**
* Can write to a file or to an audio stream.  For some reason this
* appears to be difficult to do in the JavaSound framework.  This is
* just a wrapper class to unify the interface.
*
* @author Mike Mandel (mim@ee.columbia.edu)
*/

public class AudioWriter implements Runnable {
  AudioFormat format;
  File file;
  AudioFileFormat.Type targetType;

  SourceDataLine sdl;
  PipedOutputStream pos;
  PipedInputStream pis;
  AudioInputStream ais;
  byte[] bytes;

  // Write to a source data line.  The line should be open before
  // passing it in here.
  public AudioWriter(SourceDataLine sdl) {
    this.sdl = sdl;
    format = sdl.getFormat();
    sdl.start();
  }

  // Write to a file
  public AudioWriter(File file, AudioFormat format,
         AudioFileFormat.Type targetType) throws IOException {
    //System.out.println("AudioWriter File constructor");
    this.format = format;
    this.targetType = targetType;
    this.file = file;

    // Write to the output stream
    pos = new PipedOutputStream();

    // It will then go to the file via the input streams
    pis = new PipedInputStream(pos);
    ais = new AudioInputStream(pis, format, AudioSystem.NOT_SPECIFIED);
   
    new Thread(this).start();
  }

  public void run() {
    try {
      AudioSystem.write(ais, targetType, file);
    } catch(Exception e) {
      e.printStackTrace();
    }
  }

  public void write(double[] data) throws IOException {
      write(data, data.length);
  }

  public void write(double[] data, int length) throws IOException {
    // Allocate a new bytes array if necessary.  If bytes is too long,
    // don't worry about it, just use as much as is needed.
    int numBytes = length * format.getFrameSize();
    if(bytes == null || numBytes > bytes.length)
      bytes = new byte[numBytes];

    // Limit data to [-1, 1]
    limit(data);

    // Convert doubles to bytes using format
    doubles2bytes(data, bytes, length);

    // write it
    if(pos != null)
      pos.write(bytes, 0, numBytes);
    if(sdl != null)
      sdl.write(bytes, 0, numBytes);
  }

  // Perform memoryless limiting on the audio data to keep all samples
  // in [-1,1]
  public static void limit(double[] data) {
    double t = 0.8;
    double c = 2*(1-t)/Math.PI;

    for(int i=0; i<data.length; i++) {
      if(data[i] > t) {
  data[i] = c*Math.atan((data[i]-t)/c)+t;
      } else if(data[i] < -t) {
  data[i] = c*Math.atan((data[i]+t)/c)-t;
      }
    }
  }

  public void write(byte[] bytes) throws IOException {
    if(pos != null)
      pos.write(bytes, 0, bytes.length);
    if(sdl != null)
      sdl.write(bytes, 0, bytes.length);
  }

  public void close() throws IOException {
    if(pos != null) {
      ais.close();
      pis.close();
      pos.close();
    }
    if(sdl != null)
      sdl.close();
  }
 
  public AudioFormat getFormat() { return format; }


  public void doubles2bytes(double[] audioData, byte[] audioBytes) {
      doubles2bytes(audioData, audioBytes, audioData.length);
  }

  public void doubles2bytes(double[] audioData, byte[] audioBytes, int length) {
    int in;
    if (format.getSampleSizeInBits() == 16) {
      if (format.isBigEndian()) {
  for (int i = 0; i < length; i++) {
    in = (int)(audioData[i]*32767);
    /* First byte is MSB (high order) */
    audioBytes[2*i] = (byte)(in >> 8);
    /* Second byte is LSB (low order) */
    audioBytes[2*i+1] = (byte)(in & 255);
  }
      } else {
  for (int i = 0; i < length; i++) {
    in = (int)(audioData[i]*32767);
    /* First byte is LSB (low order) */
    audioBytes[2*i] = (byte)(in & 255);
    /* Second byte is MSB (high order) */
    audioBytes[2*i+1] = (byte)(in >> 8);
  }
      }
    } else if (format.getSampleSizeInBits() == 8) {
      if (format.getEncoding().toString().startsWith("PCM_SIGN")) {
  for (int i = 0; i < length; i++) {
    audioBytes[i] = (byte)(audioData[i]*127);
  }
      } else {
  for (int i = 0; i < length; i++) {
    audioBytes[i] = (byte)(audioData[i]*127 + 127);
  }
      }
    }
  }


  // From http://www.jsresources.org/examples/AudioRecorder.java.html
//   private void writeJSR() {
//     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//     OutputStream outputStream = byteArrayOutputStream;
//     // TODO: intelligent size
//     byte[] abBuffer = new byte[65536];
//     AudioFormat  format = m_line.getFormat();
//     int  nFrameSize = format.getFrameSize();
//     int  nBufferFrames = abBuffer.length / nFrameSize;
//     m_bRecording = true;
//     while (m_bRecording) {
//       if (sm_bDebug)
//   out("BufferingRecorder.run(): trying to read: " + nBufferFrames);
//       int nFramesRead = m_line.read(abBuffer, 0, nBufferFrames);
//       if (sm_bDebug)
//   out("BufferingRecorder.run(): read: " + nFramesRead);
//       int nBytesToWrite = nFramesRead * nFrameSize;
//       try {
//   outputStream.write(abBuffer, 0, nBytesToWrite);
//       }
//       catch (IOException e) {
//   e.printStackTrace();
//       }
//     }
   
//     // We close the ByteArrayOutputStream
//     try {
//       byteArrayOutputStream.close();
//     } catch (IOException e) {
//       e.printStackTrace();
//     }


//     byte[] abData = byteArrayOutputStream.toByteArray();
//     ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(abData);

//     AudioInputStream audioInputStream =
//       new AudioInputStream(byteArrayInputStream, format,
//          abData.length / format.getFrameSize());
//     try {
//       AudioSystem.write(audioInputStream,  m_targetType, m_file);
//     } catch (IOException e) {
//       e.printStackTrace();
//     }
//   }
}
TOP

Related Classes of com.meapsoft.AudioWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.