5 * Software based MIDI synthsesizer driver, the actual mixing loop.
6 * Keep the loop as simple as possible to make it easier to rewrite this
10 * Copyright (C) by Hannu Savolainen 1993-1997
12 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
13 * Version 2 (June 1991). See the "COPYING" file distributed with this software
16 #include <linux/config.h>
19 #include "sound_config.h"
24 void softsynth_resample_loop(short *buf
, int loops
)
27 volatile voice_info
*v
;
30 unsigned char *cbuf
= (unsigned char *) buf
;
34 for (iloop
= 0; iloop
< loops
; iloop
++)
35 { /* Mix one sample */
36 int accum
, left
= 0, right
= 0;
39 for (voice
= 0; voice
< devc
->maxvoice
; voice
++)
41 if (voice_active
[voice
])
43 v
= &softoss_voices
[voice
];
48 ix
= (position
= v
->ptr
) >> 9;
50 /* Interpolation (resolution of 512 steps) */
52 int fract
= v
->ptr
& 0x1ff; /* 9 bits */
54 /* This method works with less arithmetic operations */
55 register int v1
= v
->wave
[ix
];
56 accum
= v1
+ ((((v
->wave
[ix
+ 1] - v1
)) * (fract
)) >> 9);
59 left
+= (accum
* v
->leftvol
);
60 right
+= (accum
* v
->rightvol
);
62 /* Update sample pointer */
64 if (position
<= v
->endloop
)
66 else if (v
->mode
& WAVE_LOOPING
)
68 if (v
->mode
& WAVE_BIDIR_LOOP
)
69 { v
->mode
^= WAVE_LOOP_BACK
; /* Turn around */
74 position
-= v
->looplen
;
78 /* else leave the voice looping the current sample */
80 if (v
->mode
& WAVE_LOOP_BACK
&& position
< v
->startloop
)
82 if (v
->mode
& WAVE_BIDIR_LOOP
)
83 { v
->mode
^= WAVE_LOOP_BACK
; /* Turn around */
88 position
+= v
->looplen
;
95 left
+= left_delay
[delayp
];
96 right
+= right_delay
[delayp
];
98 left_delay
[delayp
] = right
>> 2;
99 right_delay
[delayp
] = left
>> 2;
100 delayp
= (delayp
+ 1) % devc
->delay_size
;
103 #define AFTERSCALE devc->afterscale;
106 right
>>= AFTERSCALE
;
117 #ifdef OSS_BIG_ENDIAN
118 *cbuf
++ = left
& 0xff;
119 *cbuf
++ = (left
>> 8) & 0xff;
120 *cbuf
++ = right
& 0xff;
121 *cbuf
++ = (right
>> 8) & 0xff;
126 if (devc
->control_counter
++ >= devc
->control_rate
)
128 devc
->control_counter
= 0;
129 softsyn_control_loop();
131 } /* Mix one sample */