Latest Work...

Using JASIOHost

JASIOHost is based upon the observer model of software design. In order to successfully gather audio data from an Audio Input – one must write a class that is able to handle the data returned – in a similar fashion to how you may handle UI events:


        import com.synthbot.jasiohost.*;
import java.util.HashSet;

// Simple class to handle audio data from an ASIO compatible Audio Interface.
// Uses JASIOHost (c) M. H. Roth 2010
//Alastair Barber - 2012
public class AudioManager implements AsioDriverListener
{
  HashSet<AsioChannel> inputChannels,outputChannels;
  public AudioManager() throws AsioException
  {
    // Enumerate available ASIO Drivers
    ArrayList<String> driverList = (ArrayList<String>)AsioDriver.getDriverNames();
    //Select the first one
    AsioDriver selectedDriver = AsioDriver.getDriver(driverList.get(0));
   //Create 2 'Sets' of channels, input and output
    activeChannels = new HashSet<AsioChannel>();
    int inputChannelCount = driver.getNumChannelsInput();
    int outputChannelCount = driver.getNumChannelsOutput();
    for(int i = 0; i < inputChannelCount; i ++)
    {
      activeChannels.add(driver.getChannelInput(i));
    }
    for(int i = 0; i < inputChannelCount; i ++)
    {
      activeChannels.add(driver.getChannelOutput(i));
    }
    //Activate these channels and assign this class as the listener
    driver.addAsioDriverListener(this);
    driver.createBuffers(activeChannles);
    driver.start();
  }

  public void bufferSwitch(long sampleTime, long samplePosition,
     Set<AsioChannel> switchActiveChannels)
  {
    float[] outputLeftArray = new float[bufferSize];
    float[] outputRightArray = new float[bufferSize];

    for(AsioChannel activeChannel : switchActiveChannels)
    {
      if(activeChannel.isInput())
      {
         for(int i = 0; i < bufferSize; i++)
         {
            outputLeftArray[i] += ((float) activeChannel.getByteBuffer().getInt()) / Integer.MAX_VALUE;
            outputRightArray[i] += ((float) activeChannel.getByteBuffer().getInt()) / Integer.MAX_VALUE;
         }
     }
   }
   // We shall do a separate loop of the channels as there is no guarantee that all the input
   // channels will be returned before the outputs.
   boolean sideSwitch = false;
   for(AsioChannel activeChannel : switchActiveChannels)
   {
     if(!activeChannel.isInput())
     {
        if(sideSwitch)  activeChannel.write(outputLeftArray);
        else activeChannel.write(outputRightArray);
        sideSwitch = !sideSwitch;
     }
   }
  }
}

That’s all there is to it! This basic class simply initialises the interface, and then writes out whatever sound is received by the inputs unchanged to the output channels. A couple of assumptions are made:

There are exactly two outputs (stereo) – adjusting the program logic would allow more or less.
Input gain is set by the hardware
The necessary JNI files are correctly configured on the system.
This is all very well, but quite boring – how do we manipulate the sound, and visualise the incoming audio?
Coming Shortly – Manipulating Sounds with JEQ

<< Go back to the previous page