December . 1997 by da JaWavedit-Team

Note that this is subject to change for future versions.


How to make JWModules

1.JWModules - What is that ? and Why ?
2.How to make a JWModule
3.SimpleModule
4.StereoModule
5.Exit module
6.Compiling
7.Test
8.Debugging
9.Useful JaWavedit methods
10.Evolution of JWModules
11.Thank You
12.Existing JWModules



1.JWModules - What is that ? and Why ?

JWModules provide an easy and yet powerful way to enhance JaWavedit's features - to modify the sound data in any way. You create your own classes which will make use of a collection of basic methods to access, convert and store sound data (see Useful JaWavedit methods ). JWModules are loaded automatically from the JWModules directory structure. You can change this structure like you want. The Modules menu corresponds to it. Just click on the menu entry of your module to run your class.

back to the top !

2.How to make a JWModule

Step by Step

back to the top !

3.SimpleModule
If you start from zero, you will start with a class body which looks like this:

public class MyJWModule implements SimpleModule
{
    public void apply(WaveFile wf,int SelStart, int SelEnd); {
    }
} 

The Method apply is called by JaWavedit whenever your class is chosen.
You get class Wavefile and the beginning and end sample of the selection as parameters. You will use WaveFile to access the array where the sound data is stored. The most important field of WaveFile is short[]Wave (only Simple Module). You can read and modify this array which represent a mono voice.
Your module is called automatically twice for stereo voices.
To limit your modifications to the current selection (marked red in the graph) use int SelStart and int SelEnd. These values hold the current selection.
A very simple example of how to implement a SimpleModule is the Clear module. It creates a new array which includes the old wave but the current selection:

public class Clear implements SimpleModule {
    public void apply(WaveFile wf,int SelStart, int SelEnd){
    short temp[];
    temp=new short[SelStart+(wf.getSize()-1-SelEnd)];
    if (SelStart>0)
    System.arraycopy(wf.Wave,0,temp,0,SelStart);
    if (SelEnd<wf.getSize()-1)
    System.arraycopy(wf.Wave,SelEnd+1,temp,SelStart,(wf.getSize()-1-SelEnd));
    wf.Wave=temp;
}

back to the top !

4.StereoModule
We provide another way to access the sound. If you implement StereoModule instead of SinmpleModule, you can separately modify the two voices short[]WaveLeft and short[] WaveRight. In addition to that, you may set up a graphical user interface, as you may use in your constructor a parameter of type "Frame" to get the parent Frame. This is necessary to instantiate a Dialog class, which is proposed to use for an interface.

See the documentation of WaveFile for more info about it.
Here is an example of an implementation of a StereoModule:

// Include awt classes:
import java.awt.*;
import java.awt.event.*;
// inherit from Dialog and implement any optional Listeners you need:
public class MyJWModule extends Dialog implements StereoModule,
AdjustmentListener, ActionListener, WindowListener
{
    // set up some fields with awt elements
    private Label lab;
    private Scrollbar bar;
    private Checkbox choice;
    private Button go;
    private Button stop;
    private Button test;
    //fields to store wave data:
    private WaveFile wf;
    private short[] leftWave;
    private short[] rightWave;
    private int selStart;
    private int selEnd;
    // create your constructor which takes a frame as parameter
    // this constructor is only called once
    public MyJWModule(Frame parent) {
    // call the constructor of dialog
    super (parent,true);
    setTitle ("MyJWModule by Ernie and Bert");
    addWindowListener(this);
    setResizable(true);
    // see the Java dokumentation for more information about
    // positioning of awt elements
    Panel p = new Panel();
    add (p);
    // initialise your elements
    lab = new Label("this scrollbar will ...");
    p.add (lab);
    bar = new Scrollbar();
    bar.addAdjustmentListener (this);
    p.add (bar);
    choice = new Checkbox ("select to ...");
    p.add (choice);
    go = new Button ("GO !");
    go.addActionListener (this);
    p.add (go);
    stop = new Button ("NO STOP");
    stop.addActionListener (this);
    p.add (stop);
    test = new Button ("What will happen ?");
    test.addActionListener (this);
    p.add (test);

    // pack 'em
    pack();
}

//function which is called when selecting its menu:
public void apply(WaveFile waveFile,Selection sel) {
    //copy parameters to be treated when the right button is pressed:
    leftWave=waveFile.getLeftWave();
    rightWave=waveFile.getRightWave();
    wf=waveFile;
    selStart=sel.start;
    selEnd=sel.end;
    // display this dialog
    setVisible(true);
}

public void actionPerformed (ActionEvent e) {
    if (e.getSource()== go) {
        // action:
        // treat the arrays leftWave[] and rightWave[]
    }
    if (e.getSource()== stop) {
        // stop it
        // don't forget to set modifications before leaving
        wf.setWaves(leftWave,rightWave);
        // you can leave at this point
        setVisible(false);
    }
    if (e.getSource()== test) {
        // apply with buffer
    }
}

public void windowClosed(WindowEvent event) {}
public void windowDeiconified(WindowEvent event) {}
public void windowIconified(WindowEvent event) {}
public void windowActivated(WindowEvent event) {}
public void windowDeactivated(WindowEvent event) {}
public void windowOpened(WindowEvent event) {}
public void windowClosing(WindowEvent event) { setVisible(false);}
}

See examples of JWModules in the JWModules directory for further information.

back to the top !

5.Exit module
You leave the module by calling setVisible(false). As a modal Dialog, it now finishes and gives the flow of execution back to JaWavedit. In a JWModule without a graphical user interface, your module is finished when the method apply is left.

back to the top !

6.Compiling
Your .java should be in a sub-directory of JWModules. You compile it by selecting it in the menu structure of Options|Modules|Compile. If it does not appear there, select first Reload Modules.

If compiling from within JaWavedit is not possible (e.g. you don't use the JDK), compile it with JaWavedit.jar in your classpath (see jw for Unix or JaWavedit_run.bat for more details)

back to the top !

7.Test
Start JaWavedit or choose reload modules to include your module in the Modules menu. From there you simply start it by clicking ist menu entry.

back to the top !

8.Debugging
I admit, debugging is not very easy. Very helpful is the Debug window. Select Windows|Debug to see it. When you compile modules, you'll see there the progress of compilation and eventually the errors.

While reloading the Modules, information relative to loading the modules is output.And finally, any errors that occur during execution of a module is also printed to Debug.

You have also the possibility to output your own error messages: Make a call to Globals.debugOut .
These parameters are supported:

Globals.debugOut(String) // outputs this String
Globals.debugOut(Throwable) // prints information about this Throwable ( Base class of Exception)
Globals.debugOut(Throwable,String) // adds an informational String

So, for example, simple error-protection could look like this:

try {
   // do something dangerous here
} catch (Throwable t) {
    Globals.debugOut(t);
}

back to the top !

9.Useful JaWavedit methods
To see all available methods of the class WaveFile have a look at its documentation. In the directory MCK you'll find as well the documentation of Selection and Player, which you might want to use in order to play sound in your module. However, at present, this class is only documented in french. Refer to the source code of SimpleModule, StereoModule, WaveFileException to get to know them. We now provide also other sources and classes that you can use in your JWModules. Most of the comments are in French, but we hope to translate them and add also some examples of using them.

There are also the 2 classes LangBase.java and Lang.java. You can access their public functions in your Modules, as they are static. For example, this gets the string for "File" in the current language:

String aString=Lang.getStr(Lang.FILE)

If you'd like to translate Lang and LangBase to your language, go ahead ! Send it to us per email and we'll include in the next version.

back to the top !

10.Evolution of JWModules
In the near future, three major enhancements will be done:

  1. A new JWodule type
    This will receive as parameter a "ModuleContext" class. This class contains many fields that provide even more possibilities to the module. Also, this class will evolve with JaWavedit, and new fields can be added.
  2. A real time module type
    These modules virtually act between JaWavedit and the sound card. When playing, the audio data is passed through them before outputting the sound.
  3. Load/Save modules
    This type of module permits to add different types and codecs of audio files so that they can be loaded and saved. For example, a mpeg module would extend JaWavedit so that it can load mp3 files.

back to the top !

11.Thank You
When your JWModule is ready to see the wide world (web), send it to us per email. We will include it to the web-page. Like this, we hope to construct a small database of JWModules and therefore making JaWavedit an unlimited Wave-Editor. We'll keep on working on enhancing the application.

Also, of course, ideas for future versions are greatly appreciated.

back to the top !

12.Existing JWModules
Update soon :)

•Delay : Various filters which apply delay effects - listen to hear the effect. They are included in the JWModules directory.  • Pong    SimpleModule which applies an "ping-
pong"-effect to the wavefile.
It is just a long delay.
• Echo :  SimpleModule which applies an echo-effect
to the wavefile.

• Robotz   try it !

•Volume : Modifications on volume •Volume : StereoModule to change volume with sliders - needs some enhancement to change the Volume according to logarithmic function. Source included. •FadeOut : guess what .
•FadeIn: fading the sound in the selection from 0 to original value
•Base : SimpleModules with simple modifications. Source in the JWModules directory.
•Reverse : reverses the sound - sounds like playing in the other direction

•CreateTones : Create sine, square, triangle and saw waves. (not perfect though...)

•Trim : erases everything but the selection
•Clear : erases the selection
•Info : StereoModules that are not directly related to sound modifications


•Codage : Module to encode any written message in the data without changing the sound. Password protection. For understandable reasons the source code is not available. •Info : Read and modify the text string which is in the header of any .au file.

back to the top !

to contact us mail to : JaWavedit@bome.com
Phone : +49 621 1564614 (Florian and Niels)