Package me.rjdj.zengarden

Source Code of me.rjdj.zengarden.ExampleGarden

/*
*  Copyright 2009 Reality Jockey, Ltd.
*                 info@rjdj.me
*                 http://rjdj.me/
*
*  This file is part of ZenGarden.
*
*  ZenGarden is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Lesser General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  ZenGarden 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 Lesser General Public License for more details.
*  You should have received a copy of the GNU Lesser General Public License
*  along with ZenGarden.  If not, see <http://www.gnu.org/licenses/>.
*
*/

package me.rjdj.zengarden;

import java.io.File;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;

/**
* <code>ExampleGarden</code> is a a simple test class used to quickly test <code>ZenGarden</code>.
* It contains a <code>main()</code> method and is not instantiable. Invoke the <code>main()</code>
* method with:<br>
* <pre>java -jar ZenGarden.jar path/to/zengarden/pd-patches/simple-osc.pd</pre>
* Some patches may require microphone input. Make sure that your computer has one attached.
*
* @author Martin Roth (mhroth@rjdj.me)
*/
public class ExampleGarden {
 
  // A huge block size is selected because the the Java Sound API is very slow on most platforms.
  private static final int BLOCK_SIZE = 2048;
 
  // 22050 Hz is chosen (somewhat arbitrarily) because this is the sample rate that RjDj runs at.
  private static final int SAMPLE_RATE = 44100;
  private static final int NUM_INPUT_CHANNELS = 2;
  private static final int NUM_OUTPUT_CHANNELS = 2;
 
  private static volatile boolean shouldContinuePlaying = true;
 
  private ExampleGarden() {
    // no instances of ExampleGarden allowed
  }
 
  public static void main(String[] args) {
    if (args.length == 0) {
      System.out.println("java ExampleGarden testpatch.pd");
    } else {
      // install a shutdown hook so that JVM shutdown (e.g., via CTRL-C) can be reacted to
      Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
          shouldContinuePlaying = false;
        }
      });
     
      // configure the audio input and output lines
      AudioFormat inputAudioFormat = new AudioFormat(
          SAMPLE_RATE, 16, NUM_OUTPUT_CHANNELS, true, true);
      AudioFormat outputAudioFormat = new AudioFormat(
          SAMPLE_RATE, 16, NUM_INPUT_CHANNELS, true, true);
      DataLine.Info inputLineInfo = new DataLine.Info(TargetDataLine.class, inputAudioFormat);
      DataLine.Info outputLineInfo = new DataLine.Info(SourceDataLine.class, outputAudioFormat);
     
      short[] inputBuffer = new short[BLOCK_SIZE * NUM_INPUT_CHANNELS];
      short[] outputBuffer = new short[BLOCK_SIZE * NUM_OUTPUT_CHANNELS];
      byte[] bInputBuffer = new byte[inputBuffer.length * 2]; // 2 bytes per sample
      byte[] bOutputBuffer = new byte[outputBuffer.length * 2];
  
      TargetDataLine targetDataLine = null;
      SourceDataLine sourceDataLine = null;
      try {
        // TODO(mhroth): ensure that stereo input and output lines are actually being returned
        // by the system.
       
        // open the audio input (line-in or microphone)
        targetDataLine = (TargetDataLine) AudioSystem.getLine(inputLineInfo);
        targetDataLine.open(inputAudioFormat, bInputBuffer.length);
        targetDataLine.start();
       
        // open the audio output
        sourceDataLine = (SourceDataLine) AudioSystem.getLine(outputLineInfo);
        sourceDataLine.open(outputAudioFormat, bOutputBuffer.length);
        sourceDataLine.start();
      } catch (LineUnavailableException lue) {
        lue.printStackTrace(System.err);
        System.exit(1);
      }
     
      // load the Pd patch
      File pdFile = new File(args[0]);
      ZenGarden pdPatch = null;
      ZenGardenAdapter zgAdapter = new ZenGardenAdapter();
      try {
        pdPatch = new ZenGarden(pdFile, BLOCK_SIZE, NUM_INPUT_CHANNELS, NUM_OUTPUT_CHANNELS,
            (float) SAMPLE_RATE);
        pdPatch.addListener(zgAdapter);
      } catch (NativeLoadException nle) {
        nle.printStackTrace(System.err);
        System.exit(2);
      }
     
      while (shouldContinuePlaying) {
        // run the patch in an infinite loop
        targetDataLine.read(bInputBuffer, 0, bInputBuffer.length); // read from the input
        // convert the byte buffer to a short buffer
        for (int i = 0, j = 0; i < inputBuffer.length; i++) {
          inputBuffer[i] = (short) (((int) bInputBuffer[j++]) << 8);
          inputBuffer[i] |= ((short) bInputBuffer[j++]) & 0x00FF;
        }
       
        pdPatch.process(inputBuffer, outputBuffer);
       
        // convert short buffer to byte buffer
        for (int i = 0, j = 0; i < outputBuffer.length; i++) {
          bOutputBuffer[j++] = (byte) ((outputBuffer[i] & 0xFF00) >> 8);
          bOutputBuffer[j++] = (byte) (outputBuffer[i] & 0x00FF);
        }
        // write to the output
        sourceDataLine.write(bOutputBuffer, 0, bOutputBuffer.length);
      }
     
      // release all audio resources
      targetDataLine.drain();
      targetDataLine.close();
      sourceDataLine.drain();
      sourceDataLine.close();
    }
  }

}
TOP

Related Classes of me.rjdj.zengarden.ExampleGarden

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.