~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to kmidi/effects.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *              effects.c
 
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
 
8
 */
 
9
#include "config.h"
 
10
 
 
11
#ifdef CHANNEL_EFFECT
 
12
 
 
13
#include <stdio.h>
 
14
#ifndef __WIN32__
 
15
#include <unistd.h>
 
16
#endif
 
17
#include <stdlib.h>
 
18
 
 
19
#ifndef NO_STRING_H
 
20
#include <string.h>
 
21
#else
 
22
#include <strings.h>
 
23
#endif
 
24
 
 
25
#include "common.h"
 
26
#include "instrum.h"
 
27
#include "playmidi.h"
 
28
#include "effects.h"
 
29
#include "output.h"
 
30
#include "mix.h"
 
31
#include "controls.h"
 
32
 
 
33
int XG_effect_chorus_is_celeste_flag = 0;
 
34
int XG_effect_chorus_is_flanger_flag = 0;
 
35
int XG_effect_chorus_is_phaser_flag = 0;
 
36
 
 
37
/**************************************************************************/
 
38
/**     null terminated list of effects types
 
39
extern Effect* ChorusCtor( int ) ;
 
40
extern Effect* PhaserCtor( int ) ;
 
41
extern Effect* CelesteCtor( int ) ;
 
42
extern Effect* ReverbCtor( int ) ;
 
43
 */
 
44
 
 
45
EFFECT_CTOR effect_type_list[]={
 
46
  ChorusCtor , PhaserCtor , CelesteCtor , ReverbCtor , 0
 
47
};
 
48
 
 
49
/* number of effects*/
 
50
#define NUM_EFFECTS (int)(( sizeof(effect_type_list) / sizeof(EFFECT_CTOR) ) - 1)
 
51
 
 
52
Effect* effect_list[ NUM_EFFECTS ][MAXCHAN] ; 
 
53
 
 
54
char effect_name[NUM_EFFECTS][MAXCHAN] ;
 
55
 
 
56
/**************************************************************************/
 
57
/**      channel buffers and empty flags
 
58
 */
 
59
static int32 channel_buffer[MAXCHAN][AUDIO_BUFFER_SIZE*2] ; /* stereo samples */
 
60
static int channel_buffer_state[MAXCHAN] ; /* 0 means null signal , 1 non null */
 
61
 
 
62
void do_compute_data_effect(uint32 count);
 
63
 
 
64
/**************************************************************************/
 
65
/**     c_buff structure helpers functions */
 
66
 
 
67
#define CIRCBUFF_PARAM  8 /* define factor between active content part and actual buffer */
 
68
 
 
69
void create_cirbuff( cirbuff* pThis , uint32 count ) 
 
70
{
 
71
        memset( pThis , 0 , sizeof( cirbuff ) ) ;
 
72
        if( count != 0 )
 
73
        {
 
74
                pThis->m_pBufLast = (int32 *) safe_malloc( count * CIRCBUFF_PARAM * 4 ) ;
 
75
                memset( pThis->m_pBufLast , 0 , count * CIRCBUFF_PARAM * 4 ) ;
 
76
                -- pThis->m_pBufLast ;
 
77
                pThis->m_pBufCur = pThis->m_pBufLast + count * CIRCBUFF_PARAM ;
 
78
                pThis->m_pCur = pThis->m_pBufLast + count ;
 
79
                pThis->m_count = count ;
 
80
        }
 
81
}
 
82
 
 
83
void delete_cirbuff( cirbuff* pThis ) 
 
84
{
 
85
        if( pThis->m_pBufLast != 0 )
 
86
        {
 
87
                ++ pThis->m_pBufLast ;
 
88
                free( pThis->m_pBufLast ) ;
 
89
        }
 
90
        memset( pThis , 0 , sizeof( cirbuff ) ) ;
 
91
}
 
92
 
 
93
void redim_cirbuff( cirbuff* pThis , uint32 count ) 
 
94
{
 
95
        if( count == 0 )
 
96
                delete_cirbuff( pThis ) ;
 
97
        else if( count <= pThis->m_count )
 
98
                pThis->m_count = count ;
 
99
        else
 
100
        {
 
101
                cirbuff CircTmp ;
 
102
                create_cirbuff( &CircTmp , count ) ;
 
103
                memcpy( CircTmp.m_pCur - pThis->m_count + 1 , pThis->m_pCur - pThis->m_count + 1, pThis->m_count * 4 ) ;
 
104
                delete_cirbuff( pThis ) ;
 
105
                memcpy( pThis , &CircTmp , sizeof( cirbuff ) ) ;
 
106
        }
 
107
}
 
108
 
 
109
void pushval_cirbuff( cirbuff* pThis , int32 newSample ) 
 
110
{
 
111
        if( pThis->m_pCur >= pThis->m_pBufCur )
 
112
        { 
 
113
                memcpy( pThis->m_pBufLast + 1 , pThis->m_pCur - pThis->m_count + 2 , ( pThis->m_count - 1 ) * 4 ) ;
 
114
                pThis->m_pCur = pThis->m_pBufLast + pThis->m_count - 1 ;
 
115
        }
 
116
        ++ pThis->m_pCur ;
 
117
        *(pThis->m_pCur) = newSample ;
 
118
}
 
119
 
 
120
void shift_cirbuff( cirbuff* pThis , uint32 uiShift )
 
121
{
 
122
        if( uiShift == 0 )
 
123
                return ;
 
124
        if( uiShift >= pThis->m_count )
 
125
        {
 
126
                memset( pThis->m_pBufLast + 1 , 0 , pThis->m_count  * 4 ) ;
 
127
                pThis->m_pCur = pThis->m_pBufLast + pThis->m_count ;
 
128
        }
 
129
        else
 
130
        {
 
131
                uint32 offset ; 
 
132
                if( pThis->m_pCur + uiShift <= pThis->m_pBufCur )
 
133
                        pThis->m_pCur += uiShift ;
 
134
                else
 
135
                {
 
136
                        offset = pThis->m_count - uiShift ;
 
137
                        memcpy( pThis->m_pBufLast + 1 
 
138
                                , pThis->m_pCur - offset + 1, offset * 4 );
 
139
                        pThis->m_pCur = pThis->m_pBufLast + pThis->m_count ;
 
140
                }
 
141
                memset( pThis->m_pCur - uiShift + 1 , 0 , uiShift * 4 );
 
142
        }
 
143
}
 
144
 
 
145
void dump_cirbuff( cirbuff* pThis , FILE* pOutFile ) 
 
146
{
 
147
        int32* pTest ;
 
148
        fprintf( pOutFile , "{ " ) ;
 
149
        for( pTest = pThis->m_pBufLast + 1 ; pTest <= pThis->m_pBufCur ; ++ pTest )
 
150
        {
 
151
                fprintf( pOutFile , " %lu " , *pTest ) ;
 
152
                if( pTest == pThis->m_pCur - pThis->m_count )
 
153
                        fprintf( pOutFile , "[ " ) ;
 
154
                if( pTest == pThis->m_pCur )
 
155
                        fprintf( pOutFile , " ]" ) ;
 
156
        }
 
157
        fprintf( pOutFile , " }\n\n" ) ;
 
158
}
 
159
 
 
160
/** performs various buffer manipulations */
 
161
#if 0
 
162
static void DebugCircBuffer()
 
163
{
 
164
        cirbuff         test ;
 
165
        FILE* pfTest ;
 
166
        pfTest = fopen("test.txt","w");
 
167
        create_cirbuff( &test , 4 ) ;
 
168
        pushval_cirbuff( &test , 1 ) ;
 
169
        dump_cirbuff( &test , pfTest ) ;
 
170
 
 
171
        pushval_cirbuff( &test , 2 ) ;
 
172
        dump_cirbuff( &test , pfTest ) ;
 
173
 
 
174
        pushval_cirbuff( &test , 3 ) ;
 
175
        dump_cirbuff( &test , pfTest ) ;
 
176
        
 
177
        pushval_cirbuff( &test , 4 ) ;
 
178
        dump_cirbuff( &test , pfTest ) ;
 
179
        
 
180
        shift_cirbuff( &test , 2 ) ;
 
181
        dump_cirbuff( &test , pfTest ) ;
 
182
        
 
183
        pushval_cirbuff( &test , 5 ) ;
 
184
        dump_cirbuff( &test , pfTest ) ;
 
185
 
 
186
        redim_cirbuff( &test , 6 ) ;
 
187
        dump_cirbuff( &test , pfTest ) ;
 
188
 
 
189
        pushval_cirbuff( &test , 6 ) ;
 
190
        dump_cirbuff( &test , pfTest ) ;
 
191
        
 
192
        shift_cirbuff( &test , 2 ) ;
 
193
        dump_cirbuff( &test , pfTest ) ;
 
194
        
 
195
        pushval_cirbuff( &test , 7 ) ;
 
196
        dump_cirbuff( &test , pfTest ) ;        
 
197
        
 
198
        pushval_cirbuff( &test , 8 ) ;
 
199
        dump_cirbuff( &test , pfTest ) ;
 
200
        
 
201
        shift_cirbuff( &test , 3 ) ;
 
202
        dump_cirbuff( &test , pfTest ) ;
 
203
        
 
204
        delete_cirbuff( &test ) ;
 
205
        fclose( pfTest ) ;
 
206
}
 
207
#endif
 
208
/**************************************************************************/
 
209
/** do_compute_data redefined from playmidi
 
210
 */ 
 
211
void do_compute_data_effect(uint32 count)
 
212
{
 
213
        int idChannel , idVoice , idEffect;
 
214
        uint32 byteCount;
 
215
        int32 *pBuffDestEnd ;
 
216
 
 
217
        if( play_mode->encoding & PE_MONO )
 
218
                byteCount = count * 4 ;
 
219
        else
 
220
                byteCount = count * 8 ;
 
221
 
 
222
/* mix voices into channel buffers*/
 
223
        for ( idVoice = 0; idVoice < voices; ++idVoice )
 
224
        {
 
225
                if( voice[ idVoice ].status != VOICE_FREE )
 
226
                {
 
227
                  idChannel = voice[ idVoice ].channel ;
 
228
                  if (!voice[ idVoice ].sample_offset && voice[ idVoice ].echo_delay_count)
 
229
                    {
 
230
                        if (voice[ idVoice ].echo_delay_count >= count) voice[ idVoice ].echo_delay_count -= count;
 
231
                        else
 
232
                          {
 
233
                            mix_voice( channel_buffer[ idChannel ] + voice[ idVoice ].echo_delay_count, idVoice,
 
234
                                                count - voice[ idVoice ].echo_delay_count);
 
235
                            voice[ idVoice ].echo_delay_count = 0;
 
236
                          }
 
237
                    }
 
238
                  else mix_voice( channel_buffer[ idChannel ] , idVoice , count );
 
239
                  channel_buffer_state[ idChannel ] = 1 ;
 
240
 
 
241
                }
 
242
        }
 
243
 
 
244
/* apply effects*/
 
245
        if( play_mode->encoding & PE_MONO )
 
246
        for( idEffect = 0 ; idEffect < NUM_EFFECTS ; ++ idEffect )
 
247
        {               
 
248
                for( idChannel = 0 ; idChannel < MAXCHAN ; ++ idChannel )               
 
249
                {
 
250
                if( effect_list[idEffect][idChannel] != 0 )
 
251
                        (( effect_list[idEffect][idChannel] )->m_pfnActionMono)
 
252
                                ( effect_list[idEffect][idChannel] , channel_buffer[ idChannel ] 
 
253
                                        , count , &(channel_buffer_state[ idChannel ]) ) ;
 
254
                }
 
255
        }
 
256
        else
 
257
        for( idEffect = 0 ; idEffect < NUM_EFFECTS ; ++ idEffect )
 
258
        {
 
259
                for( idChannel = 0 ; idChannel < MAXCHAN ; ++ idChannel )               
 
260
                {
 
261
                if( effect_list[idEffect][idChannel] != 0 )
 
262
                        (( effect_list[idEffect][idChannel] )->m_pfnActionStereo)
 
263
                                ( effect_list[idEffect][idChannel] , channel_buffer[ idChannel ] 
 
264
                                        , count , &(channel_buffer_state[ idChannel ]) ) ;
 
265
                }
 
266
        }
 
267
 
 
268
/* clear common buffer */
 
269
          memset(buffer_pointer, 0, byteCount );
 
270
 
 
271
/* mix channel buffers into common_buffer */
 
272
        if( play_mode->encoding & PE_MONO )
 
273
                pBuffDestEnd = buffer_pointer + count  ;
 
274
        else
 
275
                pBuffDestEnd = buffer_pointer + ( count * 2 ) ;
 
276
 
 
277
        for( idChannel = 0 ; idChannel < MAXCHAN ; ++ idChannel )
 
278
        {
 
279
                int32 *pBuffSrcCur , *pBuffDestCur ;
 
280
                if( channel_buffer_state[ idChannel ] )
 
281
                {       /* mix this channel if non empty */
 
282
                        pBuffSrcCur = channel_buffer[ idChannel ] ;
 
283
                        pBuffDestCur = buffer_pointer ;
 
284
                        for( ; pBuffDestCur != pBuffDestEnd ; ++ pBuffDestCur , ++ pBuffSrcCur )
 
285
                                *pBuffDestCur += *pBuffSrcCur ;
 
286
                }
 
287
        }
 
288
 
 
289
/* clear channel buffer */
 
290
        for( idChannel = 0 ; idChannel < MAXCHAN ; ++ idChannel )
 
291
        {
 
292
                if( channel_buffer_state[ idChannel ] )
 
293
                {
 
294
                        memset( channel_buffer[ idChannel ] , 0, byteCount ) ;
 
295
                        channel_buffer_state[ idChannel ] = 0 ;
 
296
                }
 
297
        }
 
298
 
 
299
        current_sample += count;
 
300
}
 
301
 
 
302
/** cut and paste from playmidi*/
 
303
 
 
304
static void do_compute_data_default(uint32 count)
 
305
{
 
306
  int i;
 
307
  if (!count) return; /* (gl) */
 
308
  memset(buffer_pointer, 0, 
 
309
         (play_mode->encoding & PE_MONO) ? (count * 4) : (count * 8));
 
310
  for (i=0; i<voices; i++)
 
311
    {
 
312
      if(voice[i].status != VOICE_FREE)
 
313
        {
 
314
          if (!voice[i].sample_offset && voice[i].echo_delay_count)
 
315
            {
 
316
                if (voice[i].echo_delay_count >= count) voice[i].echo_delay_count -= count;
 
317
                else
 
318
                  {
 
319
                    mix_voice(buffer_pointer+voice[i].echo_delay_count, i, count - voice[i].echo_delay_count);
 
320
                    voice[i].echo_delay_count = 0;
 
321
                  }
 
322
            }
 
323
          else mix_voice(buffer_pointer, i, count);
 
324
        }
 
325
    }
 
326
  current_sample += count;
 
327
}
 
328
/**************************************************************************/
 
329
/**     switch beetween effect / no_effect mixing mode */
 
330
void (*do_compute_data)(uint32) = &do_compute_data_default ;
 
331
 
 
332
 
 
333
/**************************************************************************/
 
334
/**     fct : effect_activate
 
335
 */
 
336
void effect_activate( int iSwitch ) 
 
337
{
 
338
        if( iSwitch )
 
339
        {
 
340
                do_compute_data = &do_compute_data_effect ;
 
341
                opt_effect = 1;
 
342
        }
 
343
        else
 
344
        {
 
345
                do_compute_data = &do_compute_data_default ;
 
346
                opt_effect = 0;
 
347
        }
 
348
 
349
 
 
350
/**************************************************************************/
 
351
/** initialize this file scope variables according to (TODO) command line
 
352
 *      switches , to be called prior any other processing
 
353
 *      return 1 if success 
 
354
 */
 
355
int init_effect()
 
356
{
 
357
        int idChannel ;
 
358
        for( idChannel = 0 ; idChannel < MAXCHAN ; ++ idChannel )
 
359
        {
 
360
                int idEffect ;
 
361
                memset( channel_buffer[ idChannel ] , 0, AUDIO_BUFFER_SIZE*8 ) ;
 
362
                channel_buffer_state[ idChannel ] = 0 ;
 
363
                for( idEffect = 0 ; idEffect < NUM_EFFECTS ; ++ idEffect ) 
 
364
                {
 
365
                        effect_list[ idEffect ][ idChannel ] = effect_type_list[idEffect]() ;
 
366
                        if( effect_list[ idEffect ][ idChannel ] == 0 )
 
367
                                return 0 ;                      
 
368
                        if( idChannel == 0 )
 
369
                                ((effect_list[ idEffect ][ idChannel ])->m_pfnName)( effect_name[idEffect] );
 
370
                }
 
371
                effect_list[ idEffect ][ idChannel ] = 0 ;
 
372
        }
 
373
        return 1 ;
 
374
}
 
375
 
 
376
 
 
377
/**************************************************************************/
 
378
/**     fct : effect_ctrl_change
 
379
 */
 
380
void effect_ctrl_change( MidiEvent* pCurrentEvent )
 
381
{
 
382
        int idEffect ;
 
383
        for( idEffect = 0 ; idEffect < NUM_EFFECTS ; ++ idEffect )
 
384
        {
 
385
                if( effect_list[idEffect][pCurrentEvent->channel] != 0 )
 
386
                        ( (effect_list[idEffect][pCurrentEvent->channel])->m_pfnCtrlChange )
 
387
                                ( effect_list[idEffect][pCurrentEvent->channel] , pCurrentEvent ) ;
 
388
        }
 
389
}
 
390
 
 
391
/**************************************************************************/
 
392
/**     get info about XG effects
 
393
 */
 
394
static void reset_XG_effect_info() {
 
395
 
 
396
        XG_effect_chorus_is_celeste_flag =
 
397
         XG_effect_chorus_is_flanger_flag =
 
398
         XG_effect_chorus_is_phaser_flag = 0;
 
399
 
 
400
        if (XG_System_chorus_type >= 0) {
 
401
            /* int subtype = XG_System_chorus_type & 0x07; */
 
402
            int chtype = 0x0f & (XG_System_chorus_type >> 3);
 
403
            switch (chtype) {
 
404
                case 0: /* no effect */
 
405
                  break;
 
406
                case 1: /* chorus */
 
407
                  break;
 
408
                case 2: /* celeste */
 
409
                  XG_effect_chorus_is_celeste_flag = 1;
 
410
                  break;
 
411
                case 3: /* flanger */
 
412
                  XG_effect_chorus_is_flanger_flag = 1;
 
413
                  break;
 
414
                case 4: /* symphonic : cf Children of the Night /128 bad, /1024 ok */
 
415
                  break;
 
416
                case 8: /* phaser */
 
417
                  XG_effect_chorus_is_phaser_flag = 1;
 
418
                  break;
 
419
              default:
 
420
                  break;
 
421
            }
 
422
        }
 
423
        if (XG_System_reverb_type >= 0) {
 
424
            /* int subtype = XG_System_reverb_type & 0x07; */
 
425
            int rtype = XG_System_reverb_type >>3;
 
426
            switch (rtype) {
 
427
                case 0: /* no effect */
 
428
                  break;
 
429
                case 1: /* hall */
 
430
                  break;
 
431
                case 2: /* room */
 
432
                  break;
 
433
                case 3: /* stage */
 
434
                  break;
 
435
                case 4: /* plate */
 
436
                  break;
 
437
                case 16: /* white room */
 
438
                  break;
 
439
                case 17: /* tunnel */
 
440
                  break;
 
441
                case 18: /* canyon */
 
442
                  break;
 
443
                case 19: /* basement */
 
444
                  break;
 
445
                default: break;
 
446
            }
 
447
        }
 
448
}
 
449
 
 
450
/**************************************************************************/
 
451
/**     fct : effect_ctrl_reset
 
452
 */
 
453
void effect_ctrl_reset( int idChannel )
 
454
{
 
455
        int idEffect ; 
 
456
 
 
457
        if (!idChannel) reset_XG_effect_info();
 
458
 
 
459
        for( idEffect = 0 ; idEffect < NUM_EFFECTS ; ++ idEffect )
 
460
        {
 
461
                if( effect_list[idEffect][idChannel] != 0 )
 
462
                        ( (effect_list[idEffect][idChannel])->m_pfnCtrlReset )( effect_list[idEffect][idChannel] ) ;
 
463
        }
 
464
}
 
465
 
 
466
#endif /*CHANNEL_EFFECT*/