3
* experimental channel effects processing
4
* provided under GNU General Public License
5
* contents : channel pre-mix , effect struct definition
6
* Nicolas Witczak juillet 1998
7
* witczak@geocities.com
11
remarks about occured changes
13
+ each note from a voice was directly mixed in the common_buffer
14
in order to add channel effect we need to insert an extra and inefficient mixing
15
so implementing the scheme :
16
voice -> channel_buffer -> common_buffer -> output_buffer
18
the only optimisation I see from now is to keep track of empty
19
channel_buffer in order to skip them from processing and mixing
21
+ I tried to keep the C but yet modular style of prog , hope it'll be usefull
23
+ this experimental add on can be switched on and off with the define CHANNEL_EFFECT
30
extern int XG_effect_chorus_is_celeste_flag;
31
extern int XG_effect_chorus_is_flanger_flag;
32
extern int XG_effect_chorus_is_phaser_flag;
34
/**************************************************************************/
35
/** exported from playmidi.c
37
extern MidiEvent *event_list, *current_event;
38
extern uint32 sample_count, current_sample;
39
extern int32 *buffer_pointer;
41
/**************************************************************************/
42
/** helpers functions : circular buffer impl */
44
/** used in several effect that need phase modulation */
45
#define FRACTION ( 1 << FRACTION_BITS )
47
/**************************************************************************/
48
/** cirbuff structure : manage a circular buffer : given x it retreives x * z-1 , x * z-2 ...
49
* accesible values are (ptr->m_pCur)[0] , (ptr->m_pCur)[-1] ... (ptr->m_pCur)[ -m_count + 1 ]
53
/** m_count : active content sample count */
56
/** m_pCur : represent the past sample content ] pLast , m_pCur ]
57
* transient should not be stored
61
/** m_pBufCur , m_pBufLast represent the actual buffer ] m_pBufLast , m_pBufCur ] such that
62
* m_pBufLast <= m_pLast < m_pCur <= m_pBufCur
69
/** create_cirbuff : initialize a circular buffer given as pThis with an active size of count */
70
void create_cirbuff( cirbuff* pThis , uint32 count ) ;
72
/** delete_cirbuff : delete a circular buffer given as pThis */
73
void delete_cirbuff( cirbuff* pThis ) ;
75
/** redim_cirbuff : resize a circular buffer given as pThis with an new size of count
78
void redim_cirbuff( cirbuff* pThis , uint32 count ) ;
80
/** pushval_cirbuff : insert newSample inside pThis */
81
void pushval_cirbuff( cirbuff* pThis , int32 newSample ) ;
83
/** shift_cirbuff : shift past samples inside pThis of uiShift complete with 0 sample val */
84
void shift_cirbuff( cirbuff* pThis , uint32 uiShift ) ;
86
/* dump_cirbuff : output a ascii dump of this buffer ( for debugging) */
87
void dump_cirbuff( cirbuff* pThis , FILE* pOutFile ) ;
89
/**************************************************************************/
91
* this structure represent a particuliar kind of effect
92
* ie rev , chorus, acting on a single channel buffer
96
/** called each time a new mono data chunk is to be processed
97
* PARAM : this Effect derived structure
98
* PARAM : the channel buffer to process
99
* PARAM : number of samples to process
100
* PARAM : 1 if this buffer is not null signal, may be set to 1 by this function
101
* RELATED GLOBAL VAR : sample_count, current_sample (current sample counter)
103
void (*m_pfnActionMono)( void* , int32* , uint32 , int* ) ;
105
/** called each time a new stereo data chunk is to be processed
106
* PARAM : this Effect derived structure
107
* PARAM : the channel buffer to process
108
* PARAM : number of samples to process
109
* PARAM : 1 if this buffer is not null signal, may be set to 1 by this function
110
* RELATED GLOBAL VAR : sample_count, current_sample (current sample counter)
111
* RQ : sample buffer contains 2 * PARAM2 samples
113
void (*m_pfnActionStereo)( void* , int32* , uint32 , int* ) ;
115
/** hook function : called when a controller have changed
116
* PARAM : this Effect derived structure
118
void (*m_pfnCtrlChange)( void* , MidiEvent* pCurrentEvent );
120
/** hook function : called when a controller must be reseted in a inactive state
121
* PARAM : this Effect derived structure
123
void (*m_pfnCtrlReset)( void* );
125
/** accessor : give the name of this effect
126
* fill the buffer given as argument ( max size 16 char including \0 )
128
void (*m_pfnName)( char* );
130
/** destructor function
131
* PARAM : this Effect derived structure
133
void (*m_pfnDestruct)( void* );
137
/**************************************************************************/
138
/** Effect construction function prototype
139
* this function is called once for each effect on each channel upon
141
* PARAM : channel attached to the newly constructed Effect obj
142
* may be used to access the channel array
143
* RELATED GLOBAL VAR : channel array
144
* RETURN : shall return an allocated effect object whose structure is compatible
145
* whith the Effect one
147
typedef Effect* (*EFFECT_CTOR)(void) ;
149
/**************************************************************************/
150
/** null terminated list effects types contructors
152
extern EFFECT_CTOR effect_type_list[] ;
154
/* effect_list[effect type][channel] , list of
155
* active effects for each channel in the same order than former list
156
* RQ1 : may contains 0 if not activated
157
* RQ2 : placed in the same than for the effect_type_list array
159
extern Effect* effect_list[][MAXCHAN] ;
163
extern char effect_name[][MAXCHAN] ;
165
/**************************************************************************/
166
/** effect_ctrl_change
167
* this function is called in order to give a chance to ctrl effect
168
* object to update their parameters
169
* PARAM pCurrentEvent : midi event reflecting changes
171
void effect_ctrl_change( MidiEvent* pCurrentEvent );
173
/**************************************************************************/
174
/** effect_ctrl_reset
175
* this function is called in order to reset all ctrl effect attached to a channel
176
* object to update their parameters
177
* PARAM idChannel : midi channel number
179
void effect_ctrl_reset( int idChannel );
181
/**************************************************************************/
183
* this function turns on or off effect processing according to iSwitch
185
void effect_activate( int iSwitch ) ;
188
/****************************************************************************************/
189
extern int opt_effect;
190
extern Effect* ChorusCtor(void) ;
191
extern Effect* PhaserCtor(void) ;
192
extern Effect* CelesteCtor(void) ;
193
extern Effect* ReverbCtor(void) ;
194
extern int init_effect(void) ;