
jm.audio.AudioObject Maven / Gradle / Ivy
/*
Copyright (C) 2000 Andrew Sorensen & Andrew Brown
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or any
later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package jm.audio;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.InterruptedException;
import jm.music.data.Note;
/**
* Audio Object is the super class of all audio reading, writing, processing
* and generating units. An AudioObject in the jMusic audio architecture
* is any class which is used to form part of an audio chain, be that a
* generator object (such as a wavetable), a reader object (such as an audio
* file reader), a processor object (such as a filter), or a writer object (
* such as a file writer).
* Audio chains are created by linking together AudioObjects into lists
* where every AudioObject knows which AudioObjects come before and after it.
* This link is achieved by passing an AudioObjects immediate predicesors in
* to its constructor as an array of AudioObjects. The number of inputs
* accepted by an AudioObject is a direct relation to the size of the
* AudioObject array passed to an AudioObject's constructor. AudioObjects also
* know who their successor is so that information (such as sample rate)
* can be deceminated from the top to the bottom of the audio chain.
*
* The chain works using a pull mechanism where the final AudioObject
* (defined in an Instrument object as the finalAO object) requests a
* number of samples from it's previous AudioObject(s). This request is then
* passed on up the chain until the requested number of samples is retrieved
* from each chains first AudioObject (defined in an Instrument as an array of
* primaryAO objects). These requests for samples are made by passing
* a float[] to each AudioObjects work() method and requesting that it fill the
* float[] with sample data (if it is a primary AudioObject) or process that
* float[] in some manner.
*
* @author Andrew Sorensen
* @version 1.0,Sun Feb 25 18:42:44 2001
*/
public abstract class AudioObject implements jm.JMC{
//----------------------------------------------
// Attributes
//----------------------------------------------
/** the AudioObject previous to this one */
protected AudioObject[] previous;
/** the AudioObject following to this one */
protected AudioObject[] next;
/** The name of this Audio Object. */
protected String name;
/** This audio objects sampling rate */
protected int sampleRate;
/** The number of audio channels for this audio object. */
protected int channels;
/** how many inputs are attached to this object */
protected int inputs=0;
/** the note currently being rendered */
protected Note currentNote = null;
/** the currentNotes startTime */
protected double currentNoteStartTime;
/** the number of samples which need to be processed for this note
* to be rendered (in mono, for stereo multiply by 2 etc.)
*/
protected int numOfSamples = 0;
/** The Instrument which currently implements this AudioObject */
protected Instrument inst = null;
/* Is this audio object finished */
protected boolean finished = true;
/* Local buffer counter */
private int returned;
//----------------------------------------------
// Constructors
//----------------------------------------------
/**
* This constructor is used for all audio processors and writers
* that need to accept input from a single stream (ie Audio Object).
* @param previous The AudioObject previous to this one
* @param name A name to associate with this Audio Object
*/
protected AudioObject(AudioObject previous, String name){
AudioObject[] tmp = {previous};
this.name = name;
this.previous = tmp;
this.previous[0].setNext(this);
this.inputs=1;
}
/**
* This constructor is used for all audio processors and writers
* that need to accept input from multiple streams (ie Audio Objects).
* @param previous The AudioObjects previous to this one
* @param name A name to associate with this Audio Object.
*/
protected AudioObject(AudioObject[] previous, String name){
this.name = name;
this.previous = previous;
for(int i=0;i
* @throws AOException
*/
public abstract int work(float[] buffer)throws AOException;
//----------------------------------------------
// Private Methods
//----------------------------------------------
/**
* The setNext method is called from the constructor
* to set the next variable for the previous object
* in the object chain (essentially this creates a
* double linked list so every object in the chain
* knows which objects came before and which are
* to follow.
* @param next The audio object which follows this Audio Object.
*/
private void setNext(AudioObject next){
if(this.next == null){
this.next = new AudioObject[1];
this.next[0] = next;
}else{
AudioObject[] tmp = new AudioObject[this.next.length+1];
for(int i=0;i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy