Orinj version 9.0.0
Note: This page is not for the users of Orinj, but for developers who want to create digital signal processing effects for Orinj.
Downloads
oreffect.jar | July 2, 2025 | The basis for all effects in Orinj. This JAR file contains the compiled interfaces that all Orinj effects should implement (12 KB). |
oreffect.zip | July 2, 2025 | The source code for oreffect.jar (21 KB). |
oreffect.jar
This Java JAR file resides in the "orinj" folder of the Orinj installation. It specifies the two interfaces that an Orinj effect should implement in Java – EffectInterface and EffectPanelInterface.
- EffectInterface.java: This interface is the actual effect. For example, this interface specifies that an Orinj effect should implement a function "apply" with a specific syntax, so that Orinj can send buffers with audio data to this effect and this effect can be applied to these audio data.
- EffectPanelInterface.java: This interface must be implemented by the graphical user interface for the effect. The graphical user interface itself should contain the controls that the user can change to modify the effect. For example, this interface specifies that the graphical user interface for the Orinj effect should implement the function "updateData" so that Orinj can tell the effect when its user controls should be updated with the effect values.
When you design Orinj effects, you will at a minimum develop two Java classes – one of the effect and one for the graphical user interface of the effect. These two classes must implement the two interfaces above respectively.
Effects that automate one or more of their parameters will also implement the following interface.
- AutomationOwnerInterface: This interface allows Orinj to access each of the automations in the effect.
Effects that do not automate any parameters do not have to implement this interface.
The other classes in the JAR are as follows.
- Automation: An automation is a list of two-dimensional points some values at a different time. For example, if an effect automates a delay parameter measured in milliseconds and has three points with values (0, 0), (1, 100), and (2, 0), then the delay parameter will remain as is at time 0, gradually increase to the same value plus 100 ms at time 1 second, and decrease back to its original value at 2 seconds. An automation also specifies its minimum and maximum automation value, the number of decimals to be displayed, the display label (e.g., "ms" in this example) and a title (e.g., "Delay automation").
- AutomationEvent: An automation event is generated by an automation owner (e.g., the effect) when an automation is activated or deactivated. All automations in Orinj effects are always present, but they may be active, displayed, and used or not active and not displayed or used.
- AutomationListener: Various components of Orinj will listen for automation events to display or hide automations.
- AutomationPoint: An automation point is a two-dimensional point that defines the value of the automation (y-value of the point) at certain time (x-value of the point).
- EffectChannels: Static values to define the Orinj channels: left, right, or both. Orinj sends a channel parameter to each effect with each sound buffer. The effect can then choose to process the appropriate channel.
- EffectFont: This class contains static fonts of class java.awt.Font. For some Orinj skins, these fonts will be changed by Orinj to match the fonts used by the skin. You can use these fonts for the graphical user interface for your effect, so that the look and feel of your effect is the same as the look and feel of the rest of Orinj. You are not required to use these fonts.
- EffectGraph: This class contains colors used by Orinj graphs. You can use these colors for any effect graphs. You are not required to use these colors.
- EffectSkin: This class shows whether the current skin is dark (with light fonts and borders) or light (with dark fonts and borders). You can use this value accordingly. You are not required to use this value.
- ReadInterface: This is an interface that should be used similarly to java.io.ObjectInputStream. It helps with the reading of effect parameters stored in saved sessions or loops or stored for future undo.
- Undo: All effects (the actual effect and not its graphical user interface) should extend this class. This class contains an array of event listeners and can be used to fire undo events, which Orinj uses to store undo information for your effect. With this, the Orinj user can undo changes made to the controls in your effect.
- UndoEvent: The event that should be fired so that Orinj stores undo information and displays an undo message in its menus.
- UndoListener: An interface that is implemented by the listener for undo events. This interface will be implemented by components of Orinj, who will listen for events fired by effects.
- WorkingFolder: This class contains the path to orinj.jar. Effects should not typically access this class. The Orinj installation stock effects use this class to obtain information about language translation.
- WriteInterface: This is an interface that should be used similarly to java.io.ObjectOutputStream. It helps with the storing of effect parameters when saving sessions, loops, or undo information.
The following is additional information about the three interfaces listed above.
AutomationOwnerInterface.java
Only effects that automate parameters should implement this interface. The following are the member functions of this interface.
- public abstract int getNumAutomations():This function returns the number of automated parameters in the effect.
- public abstract Automation getAutomation(int index) : This function returns the automation at the specified index. Orinj expects that automations are indexed starting from 0. If there are three automations in the effect, Orinj will ask for automations with the indices 0, 1, and 2. It is up to the effect to decide how automations should be ordered.
EffectInterface.java
All Orinj effects must implement this interface. The following is a description of the member functions of this interface.
- public abstract boolean apply(int [] buffer, int [] controlbuffer, int channels, int channel, float samplingRate, double time, double timeStart, double timeEnd): This function takes incoming audio data and modifies these data to apply the effect.
- buffer – this buffer contains the incoming audio data and is also used to store the effect output audio data. This is an array of 32-bit signed integers (that is, 32-bit signed integer PCM data) with values between Integer.MIN_VALUE and Integer.MAX_VALUE.
- This argument contains 32-bit signed integer PCM data for any sampling resolution that may be used in the rest of Orinj. This applies to both the incoming data and the outgoing data. It is up to Orinj and not up to the effect to convert audio data into a 32-bit integer buffer before sending the audio data to the effect and to convert the output of the effect back to whatever is used by sound devices.
- The audio data in buffer buffer may be for one or two channels as specified by the argument channels. With two channels, the first integer is the first sample for the left channel, the next integer is the first sample for the right channel, the integer after that is the second sample for the left channel and so on.
- buffer does not contain all audio data that will be sent to the effect. As playback progresses, audio data is sent to the effect in pieces. It is up to the effect to store, keep, and discard audio data as needed. The Orinj echo, for example, looks at previous audio data, as the current value of the echo repetitions depends on the past values of the signal. This echo stores previous audio data, uses it, and discards it when it is no longer necessary (i.e., when the audio data is too far in the past to be used by the echo).
- controlbuffer – the control buffer should be used by effects that allow side chaining, such as a side chained compressor. A side chained compressor changes the dynamics of one track based on the dynamics of a second track. The audio data contained in the second track would be sent to the effect in this argument.
- An effect that uses this argument should also return true in allowsSideChaining. If the effect does not allow side chaining, this argument may be null and should not be used.
- Orinj controls which track is to be used as a control track. There is no need to implement controls in the graphical user interface for the effect for this. Orinj will provide these controls, as long as the effect returns true in allowsSideChaining.
- If controlbuffer is not null, then the length of controlbuffer is the same as the length of buffer. The format of audio data in controlbuffer is the same as the format of audio data in buffer.
- channels – the number of audio channels in buffer.
- channel – the channel to which this effect applies. Possible values are specified in EffectChannels.java and can be both, left, or right.
- samplingRate – the sampling rate of the audio in buffer.
- time – the start time of the audio buffers (buffer and controlbuffer) in the session, wave, or loop that is being played, in seconds. For example, if playback starts at 10 seconds into the multitrack session, time will be equal to 10 in the first call to this function.
- This argument is used usually to compute the current values of automations. Some effects may need to know the precise playback time. For example, a wah wah will sound better if its oscillation coincides with the rhythm of the song. The wah wah thus must know the time of playback. In general, effects that use low frequency oscillation – oscillation with frequency that can be created or perceived by humans – may need to use the playback time.
- timeStart – the beginning of when the effect should be applied, in seconds, from the beginning of the session or wave. This function will not be called if the sound buffers are outside of the interval between timeEnd and timeStart.
- timeEnd – the end of when the effect should be applied, in seconds, from the beginning of the session or wave.
- The function returns true if there were no errors. It returns false if there were errors.
- public abstract boolean allowsSideChaining(): To implement this function, return true, if your effect allows side chaining, and false, if it does not.
- public abstract boolean startPlay(): Use this function to implement any preparations that must occur at the start of playback. The Orinj graphic equalizer, for example, implements this function to compute its frequency filters (although these filters may be recomputed again during playback, if the user changes the equalizer controls). This function returns true if there were no errors and false otherwise.
- public abstract void stopPlay(): Use this function to implement any cleanup actions that must take place at the stop of playback. You should be careful with implementing this function as playback may continue for a small amount of time even after this function is called, depending on the size of audio buffers in Orinj. You should not, for example, use this function to remove stored incoming audio data (rather, remove these data at the start of the next playback). Very few effects distributed with the Orinj installation use this function.
- public abstract boolean hasData(): This function should return true, if the effect has not finished processing and false otherwise. Imagine a simple delay (see Orinj Effect framework Example delay Delay.java). It creates a single repetition of the original signal. Even if the original signal has ended (e.g., at the end of the last wave in the track), the repetition of the signal created by the effect may continue shortly after that. Orinj will first check whether there is original signal. If not, it will ask the effect whether the effect itself will produce a signal. If yes, the effect will be processed. If not, the effect will not be processed. This is a way of saving computations in Orinj so that the effects can be processed faster. To create its repetition, the Example Delay stores a portion of the original signal. After the original signal is finished, Example Delay will return true with this function only if it still has a portion of the original signal stored. This means that it can still produce the end of the repeated signal. When the saved portion of the original signal is also finished in the effect itself, Example Delay will no longer produce the repeated signal and will return false here. Note that it is always safe to simply return false. If you so do, however, the wet (processed) signal from your effect may stop prematurely at the end of a wave. Most effects will, in fact, produce a delay in the signal that should be accounted for.
- public abstract boolean readObject(ReadInterface stream): This function and the function below allow Orinj to save the effect controls in the session files, loop files, or for undo. Orinj expects that each object (tracks, effects, volume envelopes) implements its own serialization methods (i.e., the standard Java serialization via Serializable is not used). The following is (a simplified version of) the readObject implementation for the Orinj delay.
- public boolean readObject(ReadInterface ar)
- {
- try
- {
- m_leftDelay = ar.readFloat();
- m_rightDelay = ar.readFloat();
- m_leftPolarity = ar.readBoolean();
- m_rightPolarity = ar.readBoolean();
- m_leftDecay = ar.readFloat();
- m_rightDecay = ar.readFloat();
- m_lockChannels = ar.readBoolean();
- }
- catch (IOException e)
- {
- System.out.println("Exception in Delay::readObject: " + e);
- return false;
- }
- return true;
- }
- Note that, in addition to storing and reading effect controls, you can also store and read a version number for your effect that is independent of the Orinj version. In this way, you can implement some version control.
- public abstract boolean writeObject(WriteInterface stream): This is the function that Orinj uses to save effects in the Orinj session, loop, or for undo. This function should be implemented similarly to the one above, but values would be stored, rather than read.
- public abstract void setLanguage(String languageCode): Implement this function if the graphical user interface for your effect supports different languages. This function changes the current language to the one specified by languageCode. The languageCode argument is the three letter ISO 639-2 language.
- In Orinj, strings for labels, tooltips, and other are stored in XML files (see, for example, the orinj/languages folder of your Orinj installation). However, you can implement languages differently and you do not have to implement languages at all.
EffectPanelInterface.java
The graphical user interface for Orinj effects should typically be an extension of the class javax.swing.JPanel and should implement this interface.
Orinj effects are processed during runtime (during playback) and the dialogs that Orinj uses so that the user can modify the effect controls are non-modal. That is, the user can work with the rest of Orinj while the effect dialog is opened. In Orinj, all effect dialogs are standard. The actual dialog (of class JDialog) is already implemented and you should not implement it. This dialog has:
- A Close button
- A bypass check box
- A text field to change the name of the effect
- A drop-down box to select presets
- Buttons to save or delete presets.
- A drop-down box to select a control track, if the effect allows side chaining.
These are already implemented and you should not implement them. You should only implement controls that are specific to the effect. For the Orinj delay, for example, these controls would be the left and right channel delays, decays, and polarity, as in the example above. When you implement the effect specific controls, place them in a class that extends javax.swing.JPanel. Orinj will take this pane and place it inside a dialog that already contains the Close button and the bypass checkbox.
The EffectPanelInterface interface contains a single function:
- public abstract void updateData(): This function should set the values of the effect panel controls to the values of the member data of the effect itself.
See also:
Orinj Effect framework
Add new comment