Package com.noisepages.nettoyeur.libpd.sample

Source Code of com.noisepages.nettoyeur.libpd.sample.JavaSoundThread

/**
*
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
*
*/

package com.noisepages.nettoyeur.libpd.sample;

import java.nio.ByteBuffer;
import java.nio.ShortBuffer;

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 org.puredata.core.PdBase;

/**
*
* Simple example of how to use libpd with JavaSound.  This example currently only does audio output,
* but it's easy enough to add support for audio input.
*
* Note that the simple expedient of requesting a source data line from AudioSystem may not be sound on systems
* with multiple sound cards or other complications.  In general, you will need to deal with mixers and other
* subtleties.
*
* @author Peter Brinkmann (peter.brinkmann@gmail.com)
*
*/
public class JavaSoundThread extends Thread {

  private final float sampleRate;  // Sample rate in Hz.
  private final int outChans;      // Number of output channels.
  private final int ticks;         // Number of Pd ticks per buffer.
  private volatile boolean terminated;

  public JavaSoundThread(float sampleRate, int outChans, int ticks) {
    this.sampleRate = sampleRate;
    this.outChans = outChans;
    this.ticks = ticks;
    PdBase.openAudio(0, outChans, (int) sampleRate);
    PdBase.computeAudio(true);
    setPriority(Thread.MAX_PRIORITY);
  }
 
  @Override
  public void run() {
    terminated = false;
    try {
      perform();
    } catch (LineUnavailableException e) {
      e.printStackTrace();
    }
  }
 
  @Override
  public void interrupt() {
    terminated = true// Needed since the interrupted flag is cleared by JavaSound.
    super.interrupt();
  }
 
  private void perform() throws LineUnavailableException {
    // JavaSound setup.
    int sampleSize = 2;
    AudioFormat audioFormat = new AudioFormat(sampleRate, 8 * sampleSize, outChans, true, true);
    DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
    SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(info);
    sourceDataLine.open(audioFormat);
    sourceDataLine.start();

    // Buffer setup for exchanging samples between libpd and JavaSound.
    // Question: Is this the best possible solution?  It seems to involve too
    // much copying.
    int frames = PdBase.blockSize() * ticks;
    short[] dummy = new short[0];
    short[] samples = new short[frames * outChans];
    byte[] rawSamples = new byte[samples.length * sampleSize];
    ByteBuffer buf = ByteBuffer.wrap(rawSamples);
    ShortBuffer shortBuf = buf.asShortBuffer();

    while (!terminated) {  // Note: sourceDataLine.write seems to clear the interrupted flag, and so Thread.interrupted() doesn't work here.
      PdBase.process(ticks, dummy, samples);
      shortBuf.rewind();
      shortBuf.put(samples);
      sourceDataLine.write(rawSamples, 0, rawSamples.length);
    }

    // Shutdown.
    sourceDataLine.drain();
    sourceDataLine.stop();
    sourceDataLine.close();
  }
}
TOP

Related Classes of com.noisepages.nettoyeur.libpd.sample.JavaSoundThread

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.