Projects

New Music



Blog Roll



Support This Site

How to Code a Basic Sampler in Java

This week, I'm taking on the basics of programming a music application in Java. In this tutorial, we're going to build a basic sampler in java and learn about the Java sound and timing objects.

The Plan

As in the sampler we built in .Net, we will need three basic elements in this program.
1. A control for toggling samples on and off
2. A timing mechanism
3. Sample playback routines

1. A control for toggling samples on and off

For this control, we're going to use a control that I built for another project called toggleButton. This class works like a light switch. It is either true or false.

Custom controls in java are pretty similar to custom controls in any other language. Like any GUI component, toggleButton has three basic sections, properties, event handling and drawing code. The control's properties allow programmers to get and set necessary information. The event handling code tells the control how to respond when it is clicked. The drawing code is required for drawing the component on the screen.

The only two routines that we need to know about for this project are getValue() and setValue(). These get and set the state of the control. Is it on or off? It is very similar to a checkbox.

Take time to browse the toggleButton code if you think you need a better understanding of what is going on.

2. A timing mechanism

The two classes we will use for timing are Timer and TimerTask.

Timer objects are used to execute a piece of code on a regular interval. In our case, we will want to play the appropriate samples on each tick of the sequencer. Our timer will have to run at even intervals that we will calculate in milliseconds according to this formula: (60000 / tempo) / ticksPerBeat

TimerTask objects are containers for the code that is executed by the timer. We will extend the TimerTask class to create a new class that will be executed by the Timer. Here is the pseudo-code for our TimerTask.

1. Increment the tick counter. If we have passed ticksPerBeat * beatsInAMeasure then reset to 0.
2. For each track in our sampler, if the toggle for the current tick has a value of true, then play the appropriate sample.

That's pretty straightforward. See line 249 of javaSampler.java for the actual code.

3. Sample playback routines

Playing audio in java is incredibly easy. In fact this incredibly short example shows that it can be done in just 3 lines of code. We will be using a slightly more complicated approach that uses the AudioInputStream, DataLine and Clip classes.

First, we use the AudioInputStream and DataLine objects to open the clip.

// load the clip
public Clip loadClip(String filename)
{
 Clip clip = null;
 try
 {
  // open a link to the wav file
  AudioInputStream stream = AudioSystem.getAudioInputStream(new File(filename));
  AudioFormat format = stream.getFormat(); // read the file details
  if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED)
  {
   format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), format.getSampleSizeInBits()*2, format.getChannels(), format.getFrameSize()*2, format.getFrameRate(), true);
   stream = AudioSystem.getAudioInputStream(format, stream);
  }
  // Create the clip
  DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat(), ((int)stream.getFrameLength()*format.getFrameSize()));
  clip = (Clip) AudioSystem.getLine(info);
  // finally, load the data into the Clip object
  clip.open(stream);
 } catch (IOException e) {
 } catch (LineUnavailableException e) {
 } catch (UnsupportedAudioFileException e) {
 }
 // return the new clip
 return clip;
}

Then, playing the clip is quite simple.

// play a clip through the speakers
public void playClip(Clip clip)
{
 if( clip != null )
 {
  // first, reset the clip to play from the beginning
  clip.stop();
  clip.setFramePosition(0); // this routine can be used to start a wav file from an arbitrary position
  // play the wav file
  clip.start();
 }
}

Putting it All Together

Download the complete source code for this example, then unzip all the files to the same directory. Assuming that you already have the latest Java SDK, you should then be able to open a command prompt and compile the program. Do so by typing "javac javaSampler.java", then run the program with "java javaSampler".

The GUI is certainly not the prettiest thing I have ever created, but the code for creating it is in the constructor labeled "javaSampler()".

An Audio Sampler in Java

If you have any questions, or you catch any bugs, post them in the comments!


Posted by Evan on August 07, 2008
Sharing:
at 2008-10-23 06:57:52
hi
Hayden at 2009-09-10 12:16:10help
hi, thanks so much for posting this.  i am learning java, and so far i have been able to place my own sounds in the app, but i am trying to add a 5th track.  it seems like everything is correct (no errors during compile), but the 5th track does not appear in the GUI.

any suggestions??? thanks again!

at 2010-02-15 01:27:58
NOT GOOD CONTENTS

Speak
Handle:
Title:
Comment:
Enter this text:
username: password: