Java Program

As mentioned in the Creating SoundFonts section, the Java Program presently generates an intermediate Input Specification File, which is used by the utility program SF2Comp to actually create SoundFont (.SF2) files. The Jave code will be modified soon to directly generate .SF2 files.

Java Source Code

I have included a link to Bendir.java, the current version of the Java Source Code File (9 KB). It is readable with any ASCII editor such as NotePad. However, I use 4-character <Tab> spacing, which may affect readability.

Program Structure

The Program Structure closely follows the structure of the Input Specification File, which is derived from the internal structure of the SoundFont file. Here, for example, is the code for the main() function:

    public static void main(String[] args)
    {

        printSamples();
        printInstruments();
        printPresets();
        printInfo();
    }

Similarly, each called function (or “method”, in Java-speak) loops and prints out Samples, Instruments and Presets, respectively. Here is the hard-coded printInfo() function:

    static void printInfo                        ()
    {

        System.out.println("[Info]");
        System.out.println("Version=2.1");
        System.out.println("Engine=E-mu 10K1");
        System.out.println("Name=User Bank");
        System.out.println("ROMName=");
        System.out.println("ROMVersion=0.0");
        System.out.println("Date=");
        System.out.println("Designer=");
        System.out.println("Product=");
        System.out.println("Copyright=");
        System.out.println("Editor=SFEDT v1.28:");
        System.out.println("Comments=");
    }

Currently, the code creates a separate SoundFont Instrument for each MIDI Velocity number, with the computed high-frequency cut filter (GZ_initialFilterFc) decreasing with velocity. Buried in the function printInstrument2 is the code to check if velocity crossfading is required, as described in the Strategy section:

            if (                    sampleDynamic1  ==
                                    sampleDynamic2  )
        printInstrumentSample(      sampleQuality   ,
                                    sampleDynamic1  ,
                                initialAttenuations
                            [j][index]              );
            else
            {
        printInstrumentSample(      sampleQuality   ,
                                    sampleDynamic1  ,
                                initialAttenuations
                            [j][index]              +
                                crossFade1          );
        printInstrumentSample(      sampleQuality   ,
                                    sampleDynamic2  ,
                                initialAttenuations
                            [j][index-1]            +
                                crossFade2          );
            }

Hard Coded Data During Initial Development

The following pre-initialized variables and arrays for Bendir\Slap and Bendir\Bass only, would need to be modified, and the code recompiled, as new “qualities” are added. They will soon be replaced with code

            static final String NAME="Bendir ";
            static       int MIDIbank   = 0;
            static       int MIDIpatch  =20;
            static       String[]   sampleQualities = {
            /*SLAP*/SLAP,
            /*BASS*/BASS};
            static       String[][] sampleDynamics  = {
            /*SLAP*/{_PPP,__PP,___P,__MP,__MF,___F,__FF,_FFF},
            /*BASS*/{_PPP,__PP,___P,__MF,__MF,___F,___F,___F}};
            static       int[][]initialAttenuations = {
            /*SLAP*/{-428,-239,-257,-210,-150, -55, -16,   0},
            /*BASS*/{ -93,-345,-275,  33,  33,-159,-159,-159}};

Batch Processing

Because the Java compiler and Java virtual machine (JVM) execution have to be initiated from the command line in a MS-DOS window, I have created a batch program, jb.bat, to hide the messy details. I just type jb<Enter> on the command line: the code is compiled and executed, resulting in the test Input Specification File Bendir.txt.

Further Program Development

Object-Oriented Programming Style

Although not necessary for straightforward printing loops, (slightly) reorganizing the code along the natural class hierarchies suggested by the SoundFont internal structure would be more elegant, and would make the analysis functionality (below) easier to implement.

Direct Creation of SoundFont files (instead of using SF2Comp)

This modification is straightforward but tricky, so I have delayed until after the course project is due.

Analysis and Processing of WAVE Files

The drum's folder will be scanned for WAVE files with the proper naming convention. The samples will be read in using the Java library package javax.sound.sampled.spi, and manipulated with library filters and other functions:

  1. Compute the overall RMS power of the samples in the mid frequency range; convert the results to initialAttenuations array values, which are -20 times the dB gain needed to give the samples the same subjective strength.
  2. Trim the sample length; synchronize peak positions.
  3. Fade out raw sample abrupt termination.
  4. Analyze pitch to normalize sample pitches.

Input Parameter File

An ASCII file of <name>=<value> pairs, such as:

bank=0
patch=20

Using JavaDoc for Code Documentation

When most of the code structure has stabilized, I will use a utility I once developed, to generate “skeleton” comments for each method and variable. JavaDoc takes the complete edited comments and generates a very easy-to-use set of HTML documentation, the same format that's used by the J2SE.