Alastair Barber

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

Here’s an example…

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.