Orinj Effect framework Example delay Delay.java

Orinj version 4.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.

The class Delay.java is a part of the example Orinj effect Example Delay.

Delay.java

The member data of the class is as follows.

MINDELAY – a final static variable that defines the minimum delay in seconds
MAXDELAY – a final static variable that defines the maximum delay in seconds
MINDECAY – a final static variable that defines the minimum decay ratio
MAXDECAY – a final static variable that defines the maximum decay ratio
m_delay – the actual delay specified by the user, in seconds
m_decay – the actual decay specified by the user, ratio of the amplitude of the delayed signal repetition to the amplitude of the original signal
m_storeBuffers – an array of byte buffers necessary to store past audio data
m_delayOriginal – the amount of delay that will be stored for undo, needed to limit the number of undo operations as described below
m_decayOriginal – the amount of decay that will be stored for undo, needed to limit the number of undo operations as described below

This class extends Undo and implements EffectInterface (see Orinj Effect framework oreffect JAR). Both are required so that Orinj can create the effect. You should extend Undo even if you do not actually implement undo (do not fire undo events).

The static declarations for the minimum and maximum delay and decay are not necessary, but are a good idea if the code is to consistently check for potential errors in delay and decay amounts. These are used both in the Delay.java class, to check for incoming data when setting m_delay and m_decay, as well as in the DelayPanel.java class, to check the user input.

m_storeBuffers is necessary in this effect (and in most other effects), as this effect must look in the past and as the audio data is sent to the effect in chunks. The current values of the repetition – the delayed and decayed signal – is equal to some past value (with decay) of the original signal, which may be in some chunk that was sent to the effect in the past. The effect uses m_storeBuffers to save this past audio chunks, so that they can be used in current computations. This variable is further discussed below.

The functions in this class are as follows.

  • Delay() – the one and only constructor. This constructor initializes the delay and decay amounts and the array of byte buffers.
  • float getDelay() – this function returns m_delay, the amount of user defined delay
  • void setDelay(float delay) – this function sets m_delay, the amount of user defined delay, to the value of its argument delay. The code for this function is as follows.
    •  
    • public void setDelay(float delay, boolean storeUndo)
    • {
    •    if (delay MAXDELAY)
    •       System.out.println("Error in Delay::setDelay: Error in delay");
    •    delay = Math.min(MAXDELAY, Math.max(MINDELAY, delay));
    •    m_delay = delay;
    •  
    •    if (m_delayOriginal != delay && storeUndo)
    •    {
    •       m_delay = m_delayOriginal;
    •       fireEffectUndoEvent(new EffectUndoEvent(this, "Undo Delay"));
    •       m_delay = delay;
    •       m_delayOriginal = m_delay;
    •    }
    • }
    •  
    • Note first that this function takes two arguments.
    •  
      • delay – the amount of (user defined) delay.
      • storeUndo – true, if the effect should store its data for future undo; false, otherwise
    •  
    • In the first two lines above, the function checks whether the incoming delay is between the allowed limits. The function then limits the amount of delay to be within the allowed limits and sets m_delay in the effect.
    •  
    • The following lines store undo information. Note that the amount of delay in the effect is set by the graphical user interface and may be set either by a text field or by a slider (as we designed the graphical user interface to have both a text field and a slider). The graphical user interface handles changes in the text fields and sliders in various ways (e.g., actionPerformed, focusLost), but a choice was made in the design of this effect to store undo information only when the user moves the focus away from the specific control. Thus, the storing of undo is only done occasionally. For example, the user can move the slider up and down several times, which will change the amount of delay in the effect and the results will be heard during playback, but undo will only be stored when the user moves away from the slider.
    •  
    • In the first instance, the function checks whether the current amount of delay is different than m_delayOriginal. m_delayOriginal is only set when a previous storing of undo information took place. Thus, the value right after the previous undo storage will be stored for undo, rather than the current value of m_delay. The function then fires an undo event, which prompts Orinj to store undo information. Finally, the function sets the value of m_delay at the appropriate level.
    •  
    • Handling undo is not required. Using sliders or multiple controls for the same effect value is also not required. Thus, the implementation of this function could be much simpler, depending on the design.
    •  
  • float getDecay() – this function returns m_decay, the amount of user defined decay
  • void setDecay(float decay) – this function sets m_decay, the amount of user defined decay, to the value of its argument decay. This function is implemented similarly to setDelay above.
  • void allowsDryWetMix() – this function should simply return true, if the effect allows dry and wet mix, and false, if the effect does not allow dry and wet mix (see Orinj Effect framework oreffect JAR). Orinj will separately allow the user the specify the amounts of dry and wet mix (between 0% and 100% of the signal amplitude).
  • void allowsSideChaining() – this function should simply return true, if the effect allows side chaining, and false, if the effect does not allow side chaining (see Orinj Effect framework oreffect JAR).
  • void startPlay() – this function should implement any processing that must be performed at the beginning of playback. For this effect, this function simply empties m_storeBuffer to remove any audio data from previous playback, so that these data are not heard during the current playback.
  • void startPlay() – this function should implement any processing that must be performed at the end of playback. This should be rare. Most Orinj effects leave this function empty.
  • void setLanguage(String language) – this function sets the language of strings that are used in the graphical user interface for the effect and for error messages that may be shown to the user. The argument language is the three-letter ISO 693-2 language code of the language that should be chosen. In this example, this function is empty and the user will always see all text in English. Orinj effects and Orinj itself, on the other hand, contain XML files that translate each character string in Orinj in the languages that Orinj supports. This link contains the XML schema for the XML language files. It is not required that you implement multiple languages. If you implement languages, it is not necessary to implement the languages that Orinj supports, but you should choose a default language, in case Orinj chooses a language that your effect does not support.
  • boolean writeObject(WriteInterface ar) – Orinj does not rely on the Java Serializable interfaces, but implements its own serialization. Thus, this function is necessary so that effect data can be saved as part of the session or loop and as presets. This function is also used to save effect information for undo. This function should return true if writing did not encounter errors and false if there was an error.
  • boolean readObject(ReadInterface ar) – similarly to the previous function, this function must be implemented so that effect data can be read from sessions, loops, presets, and undo. This function should return true if reading did not encounter errors and false if there was an error.
  • void setEqual(EffectInterface effect) – this function is not currently used by Orinj, but should be implemented in case Orinj uses it in the future. This function sets the data of the effect equal to the data of another effect, the one represent by the argument effect. This function must check whether the argument effect is of the same class as the current effect.
  • void apply(int [] buffer, int [] controlbuffer, int channels, float samplingRate, double time, float drymix, float wetmix, Envelope dryMixEnvelope, Envelope wetMixEnvelope) – this function computes the effect. It takes an original signal (buffer) and returns the sum of the original signal a delayed and decayed signal (also buffer).
  • Note the way this apply function stores audio data with the following code.
    •  
    • byte [] storeBuffer = new byte [dry.length];
    • System.arraycopy(buffer, 0, storeBuffer, 0, buffer.length);
    • m_storeBuffers.add(storeBuffer);
  •  
  • The function creates a new buffer and copies the audio data into the new buffer. The audio buffer (the variable buffer) is passed to this function by reference and, after this function is executed, will be reused by Orinj. Its audio data will change. Thus, the audio data must be copied into a new buffer.
  •  
  • Note that stored buffers are removed when they are no longer needed. This is necessary as audio data can be large and should not be all kept in memory. The function computes the first buffer that will be used in the array m_storeBuffers (the index curBuffer). As long as curBuffer is greater than zero, the first buffer in the array is not needed and should be removed. The following is the relevant code.
    •  
    • while (curBuffer > 0)
    • {
    •    m_storeBuffers.remove(0);
    •    curBuffer--;
    • }
    •  

See also:
Orinj Effect framework

Add new comment

Filtered HTML

  • Freelinking helps you easily create HTML links. Links take the form of [[indicator:target|Title]]. By default (no indicator): Click to view a local node.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.