The way effects are applied to sound data has been completely re-designed with the advent of the 0.5.0 version of Peep. The effects architecture uses flags to determine which effects to apply. These flags are defined in mixer.h. Currently, only one dynamic effect has been implemented: linear fading. The definition of these flags in the header are as follows:
/* Filter flag definitions. Not that both event and state filter flags * should have a MAX_*_FLAG at the end of the bunch */ #define MAX_EVENT_FLAG (1 << 0) #define STATE_LINEAR_FADE_FLAG (1 << 0) #define MAX_STATE_FLAG (1 << 1)
The max flag is provided for speed so that the mixer code need not search continuously through all possible flags in a 32-bit integer while processing the sound code. To add a new flag, the max flag need only be increased and the new flag inserted in it's place.
Effects are called in the mixerApplyEventFilters and mixerApplyStatFilters functions in mixer.c. These functions, when called, have access to the array of sound data to process, the current possition in the data, and index of the actual sound buffer (ebuff or sbuff) record. This function then iterates through the flags and using a case statement, determines which effects to apply.
Each effect has full access to all the sound data during play and can follow the current position of the mixer in the sound. This allows for a wide-range of real-time processing and considerable flexibility in structuring effect algorithms. The currently implemented linear fading effect is a good example, and it suggested looking at the three functions that are part of the implementation in
short mixerFadeEffect (short data, unsigned int pos, unsigned int j);
for details.
Adding a new effect is easy. First, a new flag is defined in mixer.h, as well as the appropriate function prototypes. A new case statement is added to the switch statement in either mixerApplyEventFilters or mixerApplyStateFilters. New effects will probably want to add initialization functions and shutdown functions, which should be added to the mixerInit and mixerShutdown functions respectively. The effect function can then store any state information and should always return the newly processed short that representes the currently sound value.