Public SiteDocumentation

jPatch - Codecs


The jPatch API not only has to deal with the in-memory representation of the patch object model but also has to handle different representations of a patch and the necessary transformations.


preliminary note: the transformations can be subdivided into two tasks corresponding the tasks of a decoder and an encoder.

  • transformation from an unknown source to the in-memory patch model
  • transformation from the in-memory patch model to a unknown target

usage requirements:

  • an application should be able to handle different source/target representations without knowledge of implementation details.
  • a common case is that the application has to deal with different file formats (or different midi message formats) in both directions (import/export).
    Thus it should be possible to add new encoder and decoder implementations to an application without the need of recompiling the application. This also requires the managment of installed encoders and decoders.
  • extension management: encoders/decoders have to provide information that allowes an application to decide which one can/should be used with a specific synthesizer model/version and patch format/version.

technical requirements:

  • some data sources (especially when the data source are midi messages) only provide portions of the required information. Thus it should be possible to handle the case that not all data is available at once.


The solution we provide for the previously described requirements uses the mentioned

  • decoder - for the transformation from a specified source to the in-memory patch model
  • encoder - for the transformation from the in-memory patch model to a specified target

Note: it is not necessary to provide a complete codec (encoder/decoder pair).

For representing the source and the target we provide the Source and the Target interface.

known implementations

interface Sourceinterface Targetcomment
FileSourceFileTargetfor reading/writing files
BitStreamSourceBitStreamTargetfor reading/writing bit streams
(Nord Modular implementation)

The decoder/encoder interfaces handle the specified Source/Target implementations:

public interface PatchDecoder 
    void decode(Source source) throws
        UnsupportedSourceException // specified source not supported
        PatchDecoderException // an exception while decoding happened

    Patch getPatch() throws // returns the resulting patch
        PatchDecoderException // probably the result is not available

public interface PatchEncoder
    void encode(Target target) throws
        UnsupportedTargetException // specified target not supported
        PatchEncoderException // an exception while encoding happened


The encoder creates a new representation of a patch for a specified target. The target is represented by the interface

developing a custom encoder

A custom encoder requires the implementation of

  • net.sf.nmedit.jpatch.spi.PatchEncoderProvider

and a text file named 'net.sf.nmedit.jpatch.spi.PatchEncoderProvider' in the 'META-INF/services' directory containing the class names of the custom PatchEncoderProvider implementations.

See also:

The jar package file hierarchy:


text file 'net.sf.nmedit.jpatch.spi.PatchEncoderProvider':

# my patch encoder provider

package packagename.encoder;
public class MyPatchEncoder implements PatchEncoder
	// see javadoc for implementation details

package packagename.encoder.spi;
import net.sf.nmedit.jpatch.spi.PatchEncoderProvider;
public class PatchEncoderProvider extends PatchEncoderProvider
	// see javadoc for implementation details	

Example: file reading

import net.sf.nmedit.jpatch.spi.PatchImplementation;
import net.sf.nmedit.jpatch.Patch;
public Patch load(String file) throws 
	PatchDecoderException, // error while encoding
	UnsupportedSourceException, // source not supported
    String patchFormat = "Clavia Nord Modular Patch";
    String patchVersion = "3.03";
    PatchImplementation pImpl = 
    PatchImplementation.getImplementation(patchFormat, patchVersion);
    // get encoder 
    PatchDecoder decoder = pImpl.createPatchDecoder(FileSource.class);

	// create file reader
    FileReader fr = new FileReader(file);
    // create file source
    Source source = new FileSource(fr);
	// read patch file and create patch
    decoder.decode( source );

	// return patch
    return decoder.getPatch();


The decoder creates a new patch from a specified source. The source is represented by the interface

developing a custom decoder

Similar to the 'developing a custom encoder' description - just substitute encoder with decoder.

Example: file writing

import net.sf.nmedit.jpatch.spi.PatchImplementation;
import net.sf.nmedit.jpatch.Patch;
public void save(String file, Patch patch) throws 
	PatchEncoderException, // error while encoding
	UnsupportedTargetException, // target not supported
	// create encoder for FileTarget
	PatchEncoder encoder =

	// set source patch
	// create writer
	Writer writer = new FileWriter(file);
	// create target
	Target target = new FileTarget(writer);
	// write file