summaryrefslogtreecommitdiff
path: root/apps/plugins/mikmod/virtch.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mikmod/virtch.c')
-rw-r--r--apps/plugins/mikmod/virtch.c652
1 files changed, 342 insertions, 310 deletions
diff --git a/apps/plugins/mikmod/virtch.c b/apps/plugins/mikmod/virtch.c
index 6e8174016c..f2fd528b00 100644
--- a/apps/plugins/mikmod/virtch.c
+++ b/apps/plugins/mikmod/virtch.c
@@ -6,12 +6,12 @@
6 it under the terms of the GNU Library General Public License as 6 it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of 7 published by the Free Software Foundation; either version 2 of
8 the License, or (at your option) any later version. 8 the License, or (at your option) any later version.
9 9
10 This program is distributed in the hope that it will be useful, 10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Library General Public License for more details. 13 GNU Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public 15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software 16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -20,7 +20,7 @@
20 20
21/*============================================================================== 21/*==============================================================================
22 22
23 $Id: virtch.c,v 1.4 2005/05/18 13:42:23 raphassenat Exp $ 23 $Id$
24 24
25 Sample mixing routines, using a 32 bits mixing buffer. 25 Sample mixing routines, using a 32 bits mixing buffer.
26 26
@@ -33,28 +33,23 @@
33 (b) Interpolation of sample data during mixing 33 (b) Interpolation of sample data during mixing
34 (c) Dolby Surround Sound 34 (c) Dolby Surround Sound
35*/ 35*/
36#if 0
37#include <assert.h>
38#endif
39 36
40#ifdef HAVE_CONFIG_H 37#ifdef HAVE_CONFIG_H
41#include "config.h" 38#include "config.h"
42#endif 39#endif
43 40
44#include <stddef.h>
45#ifdef HAVE_MEMORY_H 41#ifdef HAVE_MEMORY_H
46#include <memory.h> 42#include <memory.h>
47#endif 43#endif
48#include <string.h> 44#include <string.h>
49 45
50#include "mikmod_internals.h" 46#include "mikmod_internals.h"
51#include "mikmod.h"
52 47
53/* 48/*
54 Constant definitions 49 Constant definitions
55 ==================== 50 ====================
56 51
57 BITSHIFT 52 BITSHIFT
58 Controls the maximum volume of the sound output. All data is shifted 53 Controls the maximum volume of the sound output. All data is shifted
59 right by BITSHIFT after being mixed. Higher values result in quieter 54 right by BITSHIFT after being mixed. Higher values result in quieter
60 sound and less chance of distortion. 55 sound and less chance of distortion.
@@ -130,164 +125,176 @@ static SLONG *RVbufR1=NULL,*RVbufR2=NULL,*RVbufR3=NULL,*RVbufR4=NULL,
130#else 125#else
131#define NATIVE SLONG 126#define NATIVE SLONG
132#endif 127#endif
128
133#if defined HAVE_SSE2 || defined HAVE_ALTIVEC 129#if defined HAVE_SSE2 || defined HAVE_ALTIVEC
134 130
135static size_t MixSIMDMonoNormal(const SWORD* srce,SLONG* dest,size_t index, size_t increment,size_t todo) 131# if !defined(NATIVE_64BIT_INT)
132static SINTPTR_T MixSIMDMonoNormal(const SWORD* srce,SLONG* dest,SINTPTR_T idx,SINTPTR_T increment,SINTPTR_T todo)
136{ 133{
137 // TODO: 134 /* TODO: */
138 SWORD sample; 135 SWORD sample;
139 SLONG lvolsel = vnf->lvolsel; 136 SLONG lvolsel = vnf->lvolsel;
140 137
141 while(todo--) { 138 while(todo--) {
142 sample = srce[index >> FRACBITS]; 139 sample = srce[idx >> FRACBITS];
143 index += increment; 140 idx += increment;
144 141
145 *dest++ += lvolsel * sample; 142 *dest++ += lvolsel * sample;
146 } 143 }
147 return index; 144 return idx;
148} 145}
146# endif /* !NATIVE_64BIT_INT */
149 147
150static size_t MixSIMDStereoNormal(const SWORD* srce, SLONG* dest, size_t index, size_t increment,size_t todo) 148static SINTPTR_T MixSIMDStereoNormal(const SWORD* srce,SLONG* dest,SINTPTR_T idx,SINTPTR_T increment,SINTPTR_T todo)
151{ 149{
152 SWORD vol[8] = {vnf->lvolsel, vnf->rvolsel}; 150 SWORD vol[8] = {vnf->lvolsel, vnf->rvolsel};
153 SWORD sample; 151 SWORD sample;
154 SLONG remain = todo; 152 SLONG remain = todo;
155 153
156 // Dest can be misaligned ... 154 /* Dest can be misaligned */
157 while(!IS_ALIGNED_16(dest)) { 155 while(!IS_ALIGNED_16(dest)) {
158 sample=srce[(index += increment) >> FRACBITS]; 156 sample=srce[idx >> FRACBITS];
157 idx += increment;
159 *dest++ += vol[0] * sample; 158 *dest++ += vol[0] * sample;
160 *dest++ += vol[1] * sample; 159 *dest++ += vol[1] * sample;
161 todo--; 160 todo--;
161 if(!todo) return idx;
162 } 162 }
163 163
164 // Srce is always aligned ... 164 /* Srce is always aligned */
165 165
166#if defined HAVE_SSE2 166#if defined HAVE_SSE2
167 remain = todo&3; 167 remain = todo&3;
168 { 168 {
169 __m128i v0 = _mm_set_epi16(0, vol[1], 169 __m128i v0 = _mm_set_epi16(0, vol[1],
170 0, vol[0], 170 0, vol[0],
171 0, vol[1], 171 0, vol[1],
172 0, vol[0]); 172 0, vol[0]);
173 for(todo>>=2;todo; todo--) 173 for(todo>>=2;todo; todo--)
174 { 174 {
175 SWORD s0 = srce[(index += increment) >> FRACBITS]; 175 SWORD s0 = srce[idx >> FRACBITS];
176 SWORD s1 = srce[(index += increment) >> FRACBITS]; 176 SWORD s1 = srce[(idx += increment) >> FRACBITS];
177 SWORD s2 = srce[(index += increment) >> FRACBITS]; 177 SWORD s2 = srce[(idx += increment) >> FRACBITS];
178 SWORD s3 = srce[(index += increment) >> FRACBITS]; 178 SWORD s3 = srce[(idx += increment) >> FRACBITS];
179 __m128i v1 = _mm_set_epi16(0, s1, 0, s1, 0, s0, 0, s0); 179 __m128i v1 = _mm_set_epi16(0, s1, 0, s1, 0, s0, 0, s0);
180 __m128i v2 = _mm_set_epi16(0, s3, 0, s3, 0, s2, 0, s2); 180 __m128i v2 = _mm_set_epi16(0, s3, 0, s3, 0, s2, 0, s2);
181 __m128i v3 = _mm_load_si128((__m128i*)(dest+0)); 181 __m128i v3 = _mm_load_si128((__m128i*)(dest+0));
182 __m128i v4 = _mm_load_si128((__m128i*)(dest+4)); 182 __m128i v4 = _mm_load_si128((__m128i*)(dest+4));
183 _mm_store_si128((__m128i*)(dest+0), _mm_add_epi32(v3, _mm_madd_epi16(v0, v1))); 183 _mm_store_si128((__m128i*)(dest+0), _mm_add_epi32(v3, _mm_madd_epi16(v0, v1)));
184 _mm_store_si128((__m128i*)(dest+4), _mm_add_epi32(v4, _mm_madd_epi16(v0, v2))); 184 _mm_store_si128((__m128i*)(dest+4), _mm_add_epi32(v4, _mm_madd_epi16(v0, v2)));
185 dest+=8; 185 dest+=8;
186 idx += increment;
186 } 187 }
187 } 188 }
188 189
189#elif defined HAVE_ALTIVEC 190#elif defined HAVE_ALTIVEC
190 remain = todo&3; 191 remain = todo&3;
191 { 192 {
192 vector signed short r0 = vec_ld(0, vol);
193 vector signed short v0 = vec_perm(r0, r0, (vector unsigned char)(0, 1, // l
194 0, 1, // l
195 2, 3, // r
196 2, 1, // r
197 0, 1, // l
198 0, 1, // l
199 2, 3, // r
200 2, 3 // r
201 ));
202 SWORD s[8]; 193 SWORD s[8];
203 194 vector signed short r0 = vec_ld(0, vol);
195 vector signed short v0 = vec_perm(r0, r0, (vector unsigned char)(0, 1, /* l */
196 0, 1, /* l */
197 2, 3, /* r */
198 2, 1, /* r */
199 0, 1, /* l */
200 0, 1, /* l */
201 2, 3, /* r */
202 2, 3 /* r */
203 ));
204
204 for(todo>>=2;todo; todo--) 205 for(todo>>=2;todo; todo--)
205 { 206 {
206 // Load constants 207 vector short int r1;
207 s[0] = srce[(index += increment) >> FRACBITS]; 208 vector signed short v1, v2;
208 s[1] = srce[(index += increment) >> FRACBITS]; 209 vector signed int v3, v4, v5, v6;
209 s[2] = srce[(index += increment) >> FRACBITS]; 210
210 s[3] = srce[(index += increment) >> FRACBITS]; 211 /* Load constants */
212 s[0] = srce[idx >> FRACBITS];
213 s[1] = srce[(idx += increment) >> FRACBITS];
214 s[2] = srce[(idx += increment) >> FRACBITS];
215 s[3] = srce[(idx += increment) >> FRACBITS];
211 s[4] = 0; 216 s[4] = 0;
212 217
213 vector short int r1 = vec_ld(0, s); 218 r1 = vec_ld(0, s);
214 vector signed short v1 = vec_perm(r1, r1, (vector unsigned char)(0*2, 0*2+1, // s0 219 v1 = vec_perm(r1, r1, (vector unsigned char)
215 4*2, 4*2+1, // 0 220 (0*2, 0*2+1, /* s0 */
216 0*2, 0*2+1, // s0 221 4*2, 4*2+1, /* 0 */
217 4*2, 4*2+1, // 0 222 0*2, 0*2+1, /* s0 */
218 1*2, 1*2+1, // s1 223 4*2, 4*2+1, /* 0 */
219 4*2, 4*2+1, // 0 224 1*2, 1*2+1, /* s1 */
220 1*2, 1*2+1, // s1 225 4*2, 4*2+1, /* 0 */
221 4*2, 4*2+1 // 0 226 1*2, 1*2+1, /* s1 */
222 )); 227 4*2, 4*2+1 /* 0 */
223 228 ) );
224 vector signed short v2 = vec_perm(r1, r1, (vector unsigned char)(2*2, 2*2+1, // s2 229 v2 = vec_perm(r1, r1, (vector unsigned char)
225 4*2, 4*2+1, // 0 230 (2*2, 2*2+1, /* s2 */
226 2*2, 2*2+1, // s2 231 4*2, 4*2+1, /* 0 */
227 4*2, 4*2+1, // 0 232 2*2, 2*2+1, /* s2 */
228 3*2, 3*2+1, // s3 233 4*2, 4*2+1, /* 0 */
229 4*2, 4*2+1, // 0 234 3*2, 3*2+1, /* s3 */
230 3*2, 3*2+1, // s3 235 4*2, 4*2+1, /* 0 */
231 4*2, 4*2+1 // 0 236 3*2, 3*2+1, /* s3 */
232 )); 237 4*2, 4*2+1 /* 0 */
233 vector signed int v3 = vec_ld(0, dest); 238 ) );
234 vector signed int v4 = vec_ld(0, dest + 4); 239
235 vector signed int v5 = vec_mule(v0, v1); 240 v3 = vec_ld(0, dest);
236 vector signed int v6 = vec_mule(v0, v2); 241 v4 = vec_ld(0, dest + 4);
237 242 v5 = vec_mule(v0, v1);
238 vec_st(vec_add(v3, v5), 0, dest); 243 v6 = vec_mule(v0, v2);
244
245 vec_st(vec_add(v3, v5), 0, dest);
239 vec_st(vec_add(v4, v6), 0x10, dest); 246 vec_st(vec_add(v4, v6), 0x10, dest);
240 247
241 dest+=8; 248 dest+=8;
249 idx += increment;
242 } 250 }
243 } 251 }
244#endif // HAVE_ALTIVEC 252#endif /* HAVE_ALTIVEC */
245 253
246 // Remaining bits ... 254 /* Remaining bits */
247 while(remain--) { 255 while(remain--) {
248 sample=srce[(index += increment) >> FRACBITS]; 256 sample=srce[idx >> FRACBITS];
257 idx += increment;
249 258
250 *dest++ += vol[0] * sample; 259 *dest++ += vol[0] * sample;
251 *dest++ += vol[1] * sample; 260 *dest++ += vol[1] * sample;
252 } 261 }
253 return index; 262 return idx;
254} 263}
255#endif 264#endif
256 265
257/*========== 32 bit sample mixers - only for 32 bit platforms */ 266/*========== 32 bit sample mixers - only for 32 bit platforms */
258#ifndef NATIVE_64BIT_INT 267#ifndef NATIVE_64BIT_INT
259 268
260static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) 269static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
261{ 270{
262#if defined HAVE_ALTIVEC || defined HAVE_SSE2 271#if defined HAVE_ALTIVEC || defined HAVE_SSE2
263 if (md_mode & DMODE_SIMDMIXER) 272 if (md_mode & DMODE_SIMDMIXER) {
264 { 273 return MixSIMDMonoNormal(srce, dest, idx, increment, todo);
265 return MixSIMDMonoNormal(srce, dest, index, increment, todo);
266 } 274 }
267 else 275 else
268#endif 276#endif
269 { 277 {
270 SWORD sample; 278 SWORD sample;
271 SLONG lvolsel = vnf->lvolsel; 279 SLONG lvolsel = vnf->lvolsel;
272 280
273 while(todo--) { 281 while(todo--) {
274 sample = srce[index >> FRACBITS]; 282 sample = srce[idx >> FRACBITS];
275 index += increment; 283 idx += increment;
276 284
277 *dest++ += lvolsel * sample; 285 *dest++ += lvolsel * sample;
278 } 286 }
279 } 287 }
280 return index; 288 return idx;
281} 289}
282 290
283// FIXME: This mixer should works also on 64-bit platform 291/* FIXME: This mixer should works also on 64-bit platform */
284// Hint : changes SLONG / SLONGLONG mess with size_t 292/* Hint : changes SLONG / SLONGLONG mess with intptr */
285static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) 293static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
286{ 294{
287#if defined HAVE_ALTIVEC || defined HAVE_SSE2 295#if defined HAVE_ALTIVEC || defined HAVE_SSE2
288 if (md_mode & DMODE_SIMDMIXER) 296 if (md_mode & DMODE_SIMDMIXER) {
289 { 297 return MixSIMDStereoNormal(srce, dest, idx, increment, todo);
290 return MixSIMDStereoNormal(srce, dest, index, increment, todo);
291 } 298 }
292 else 299 else
293#endif 300#endif
@@ -297,17 +304,17 @@ static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG i
297 SLONG rvolsel = vnf->rvolsel; 304 SLONG rvolsel = vnf->rvolsel;
298 305
299 while(todo--) { 306 while(todo--) {
300 sample=srce[(index += increment) >> FRACBITS]; 307 sample=srce[idx >> FRACBITS];
308 idx += increment;
301 309
302 *dest++ += lvolsel * sample; 310 *dest++ += lvolsel * sample;
303 *dest++ += rvolsel * sample; 311 *dest++ += rvolsel * sample;
304 } 312 }
305 } 313 }
306 return index; 314 return idx;
307} 315}
308 316
309 317static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
310static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo)
311{ 318{
312 SWORD sample; 319 SWORD sample;
313 SLONG lvolsel = vnf->lvolsel; 320 SLONG lvolsel = vnf->lvolsel;
@@ -315,25 +322,26 @@ static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG
315 322
316 if (lvolsel>=rvolsel) { 323 if (lvolsel>=rvolsel) {
317 while(todo--) { 324 while(todo--) {
318 sample = srce[index >> FRACBITS]; 325 sample = srce[idx >> FRACBITS];
319 index += increment; 326 idx += increment;
320 327
321 *dest++ += lvolsel*sample; 328 *dest++ += lvolsel*sample;
322 *dest++ -= lvolsel*sample; 329 *dest++ -= lvolsel*sample;
323 } 330 }
324 } else { 331 }
332 else {
325 while(todo--) { 333 while(todo--) {
326 sample = srce[index >> FRACBITS]; 334 sample = srce[idx >> FRACBITS];
327 index += increment; 335 idx += increment;
328 336
329 *dest++ -= rvolsel*sample; 337 *dest++ -= rvolsel*sample;
330 *dest++ += rvolsel*sample; 338 *dest++ += rvolsel*sample;
331 } 339 }
332 } 340 }
333 return index; 341 return idx;
334} 342}
335 343
336static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) 344static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
337{ 345{
338 SLONG sample; 346 SLONG sample;
339 SLONG lvolsel = vnf->lvolsel; 347 SLONG lvolsel = vnf->lvolsel;
@@ -342,33 +350,33 @@ static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG inc
342 if (rampvol) { 350 if (rampvol) {
343 SLONG oldlvol = vnf->oldlvol - lvolsel; 351 SLONG oldlvol = vnf->oldlvol - lvolsel;
344 while(todo--) { 352 while(todo--) {
345 sample=(SLONG)srce[index>>FRACBITS]+ 353 sample=(SLONG)srce[idx>>FRACBITS]+
346 ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) 354 ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
347 *(index&FRACMASK)>>FRACBITS); 355 *(idx&FRACMASK)>>FRACBITS);
348 index += increment; 356 idx += increment;
349 357
350 *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) 358 *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol)
351 * sample >> CLICK_SHIFT; 359 * sample >> CLICK_SHIFT;
352 if (!--rampvol) 360 if (!--rampvol)
353 break; 361 break;
354 } 362 }
355 vnf->rampvol = rampvol; 363 vnf->rampvol = rampvol;
356 if (todo < 0) 364 if (todo < 0)
357 return index; 365 return idx;
358 } 366 }
359 367
360 while(todo--) { 368 while(todo--) {
361 sample=(SLONG)srce[index>>FRACBITS]+ 369 sample=(SLONG)srce[idx>>FRACBITS]+
362 ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) 370 ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
363 *(index&FRACMASK)>>FRACBITS); 371 *(idx&FRACMASK)>>FRACBITS);
364 index += increment; 372 idx += increment;
365 373
366 *dest++ += lvolsel * sample; 374 *dest++ += lvolsel * sample;
367 } 375 }
368 return index; 376 return idx;
369} 377}
370 378
371static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) 379static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
372{ 380{
373 SLONG sample; 381 SLONG sample;
374 SLONG lvolsel = vnf->lvolsel; 382 SLONG lvolsel = vnf->lvolsel;
@@ -379,13 +387,13 @@ static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG i
379 SLONG oldlvol = vnf->oldlvol - lvolsel; 387 SLONG oldlvol = vnf->oldlvol - lvolsel;
380 SLONG oldrvol = vnf->oldrvol - rvolsel; 388 SLONG oldrvol = vnf->oldrvol - rvolsel;
381 while(todo--) { 389 while(todo--) {
382 sample=(SLONG)srce[index>>FRACBITS]+ 390 sample=(SLONG)srce[idx>>FRACBITS]+
383 ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) 391 ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
384 *(index&FRACMASK)>>FRACBITS); 392 *(idx&FRACMASK)>>FRACBITS);
385 index += increment; 393 idx += increment;
386 394
387 *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) 395 *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol)
388 * sample >> CLICK_SHIFT; 396 * sample >> CLICK_SHIFT;
389 *dest++ += ((rvolsel << CLICK_SHIFT) + oldrvol * rampvol) 397 *dest++ += ((rvolsel << CLICK_SHIFT) + oldrvol * rampvol)
390 * sample >> CLICK_SHIFT; 398 * sample >> CLICK_SHIFT;
391 if (!--rampvol) 399 if (!--rampvol)
@@ -393,22 +401,22 @@ static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG i
393 } 401 }
394 vnf->rampvol = rampvol; 402 vnf->rampvol = rampvol;
395 if (todo < 0) 403 if (todo < 0)
396 return index; 404 return idx;
397 } 405 }
398 406
399 while(todo--) { 407 while(todo--) {
400 sample=(SLONG)srce[index>>FRACBITS]+ 408 sample=(SLONG)srce[idx>>FRACBITS]+
401 ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) 409 ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
402 *(index&FRACMASK)>>FRACBITS); 410 *(idx&FRACMASK)>>FRACBITS);
403 index += increment; 411 idx += increment;
404 412
405 *dest++ += lvolsel * sample; 413 *dest++ += lvolsel * sample;
406 *dest++ += rvolsel * sample; 414 *dest++ += rvolsel * sample;
407 } 415 }
408 return index; 416 return idx;
409} 417}
410 418
411static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) 419static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
412{ 420{
413 SLONG sample; 421 SLONG sample;
414 SLONG lvolsel = vnf->lvolsel; 422 SLONG lvolsel = vnf->lvolsel;
@@ -427,13 +435,13 @@ static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG
427 if (rampvol) { 435 if (rampvol) {
428 oldvol -= vol; 436 oldvol -= vol;
429 while(todo--) { 437 while(todo--) {
430 sample=(SLONG)srce[index>>FRACBITS]+ 438 sample=(SLONG)srce[idx>>FRACBITS]+
431 ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) 439 ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
432 *(index&FRACMASK)>>FRACBITS); 440 *(idx&FRACMASK)>>FRACBITS);
433 index += increment; 441 idx += increment;
434 442
435 sample=((vol << CLICK_SHIFT) + oldvol * rampvol) 443 sample=((vol << CLICK_SHIFT) + oldvol * rampvol)
436 * sample >> CLICK_SHIFT; 444 * sample >> CLICK_SHIFT;
437 *dest++ += sample; 445 *dest++ += sample;
438 *dest++ -= sample; 446 *dest++ -= sample;
439 447
@@ -442,55 +450,55 @@ static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG
442 } 450 }
443 vnf->rampvol = rampvol; 451 vnf->rampvol = rampvol;
444 if (todo < 0) 452 if (todo < 0)
445 return index; 453 return idx;
446 } 454 }
447 455
448 while(todo--) { 456 while(todo--) {
449 sample=(SLONG)srce[index>>FRACBITS]+ 457 sample=(SLONG)srce[idx>>FRACBITS]+
450 ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) 458 ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
451 *(index&FRACMASK)>>FRACBITS); 459 *(idx&FRACMASK)>>FRACBITS);
452 index += increment; 460 idx += increment;
453 461
454 *dest++ += vol*sample; 462 *dest++ += vol*sample;
455 *dest++ -= vol*sample; 463 *dest++ -= vol*sample;
456 } 464 }
457 return index; 465 return idx;
458} 466}
459#endif 467#endif
460 468
461/*========== 64 bit sample mixers - all platforms */ 469/*========== 64 bit sample mixers - all platforms */
462 470
463static SLONGLONG MixMonoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) 471static SLONGLONG MixMonoNormal(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
464{ 472{
465 SWORD sample; 473 SWORD sample;
466 SLONG lvolsel = vnf->lvolsel; 474 SLONG lvolsel = vnf->lvolsel;
467 475
468 while(todo--) { 476 while(todo--) {
469 sample = srce[index >> FRACBITS]; 477 sample = srce[idx >> FRACBITS];
470 index += increment; 478 idx += increment;
471 479
472 *dest++ += lvolsel * sample; 480 *dest++ += lvolsel * sample;
473 } 481 }
474 return index; 482 return idx;
475} 483}
476 484
477static SLONGLONG MixStereoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) 485static SLONGLONG MixStereoNormal(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
478{ 486{
479 SWORD sample; 487 SWORD sample;
480 SLONG lvolsel = vnf->lvolsel; 488 SLONG lvolsel = vnf->lvolsel;
481 SLONG rvolsel = vnf->rvolsel; 489 SLONG rvolsel = vnf->rvolsel;
482 490
483 while(todo--) { 491 while(todo--) {
484 sample=srce[index >> FRACBITS]; 492 sample=srce[idx >> FRACBITS];
485 index += increment; 493 idx += increment;
486 494
487 *dest++ += lvolsel * sample; 495 *dest++ += lvolsel * sample;
488 *dest++ += rvolsel * sample; 496 *dest++ += rvolsel * sample;
489 } 497 }
490 return index; 498 return idx;
491} 499}
492 500
493static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) 501static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
494{ 502{
495 SWORD sample; 503 SWORD sample;
496 SLONG lvolsel = vnf->lvolsel; 504 SLONG lvolsel = vnf->lvolsel;
@@ -498,25 +506,26 @@ static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG index
498 506
499 if(vnf->lvolsel>=vnf->rvolsel) { 507 if(vnf->lvolsel>=vnf->rvolsel) {
500 while(todo--) { 508 while(todo--) {
501 sample = srce[index >> FRACBITS]; 509 sample = srce[idx >> FRACBITS];
502 index += increment; 510 idx += increment;
503 511
504 *dest++ += lvolsel*sample; 512 *dest++ += lvolsel*sample;
505 *dest++ -= lvolsel*sample; 513 *dest++ -= lvolsel*sample;
506 } 514 }
507 } else { 515 }
516 else {
508 while(todo--) { 517 while(todo--) {
509 sample = srce[index >> FRACBITS]; 518 sample = srce[idx >> FRACBITS];
510 index += increment; 519 idx += increment;
511 520
512 *dest++ -= rvolsel*sample; 521 *dest++ -= rvolsel*sample;
513 *dest++ += rvolsel*sample; 522 *dest++ += rvolsel*sample;
514 } 523 }
515 } 524 }
516 return index; 525 return idx;
517} 526}
518 527
519static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) 528static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
520{ 529{
521 SLONG sample; 530 SLONG sample;
522 SLONG lvolsel = vnf->lvolsel; 531 SLONG lvolsel = vnf->lvolsel;
@@ -525,10 +534,10 @@ static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLO
525 if (rampvol) { 534 if (rampvol) {
526 SLONG oldlvol = vnf->oldlvol - lvolsel; 535 SLONG oldlvol = vnf->oldlvol - lvolsel;
527 while(todo--) { 536 while(todo--) {
528 sample=(SLONG)srce[index>>FRACBITS]+ 537 sample=(SLONG)srce[idx>>FRACBITS]+
529 ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) 538 ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
530 *(index&FRACMASK)>>FRACBITS); 539 *(idx&FRACMASK)>>FRACBITS);
531 index += increment; 540 idx += increment;
532 541
533 *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) 542 *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol)
534 * sample >> CLICK_SHIFT; 543 * sample >> CLICK_SHIFT;
@@ -537,21 +546,21 @@ static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLO
537 } 546 }
538 vnf->rampvol = rampvol; 547 vnf->rampvol = rampvol;
539 if (todo < 0) 548 if (todo < 0)
540 return index; 549 return idx;
541 } 550 }
542 551
543 while(todo--) { 552 while(todo--) {
544 sample=(SLONG)srce[index>>FRACBITS]+ 553 sample=(SLONG)srce[idx>>FRACBITS]+
545 ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) 554 ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
546 *(index&FRACMASK)>>FRACBITS); 555 *(idx&FRACMASK)>>FRACBITS);
547 index += increment; 556 idx += increment;
548 557
549 *dest++ += lvolsel * sample; 558 *dest++ += lvolsel * sample;
550 } 559 }
551 return index; 560 return idx;
552} 561}
553 562
554static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) 563static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
555{ 564{
556 SLONG sample; 565 SLONG sample;
557 SLONG lvolsel = vnf->lvolsel; 566 SLONG lvolsel = vnf->lvolsel;
@@ -562,10 +571,10 @@ static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,S
562 SLONG oldlvol = vnf->oldlvol - lvolsel; 571 SLONG oldlvol = vnf->oldlvol - lvolsel;
563 SLONG oldrvol = vnf->oldrvol - rvolsel; 572 SLONG oldrvol = vnf->oldrvol - rvolsel;
564 while(todo--) { 573 while(todo--) {
565 sample=(SLONG)srce[index>>FRACBITS]+ 574 sample=(SLONG)srce[idx>>FRACBITS]+
566 ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) 575 ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
567 *(index&FRACMASK)>>FRACBITS); 576 *(idx&FRACMASK)>>FRACBITS);
568 index += increment; 577 idx += increment;
569 578
570 *dest++ +=((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) 579 *dest++ +=((lvolsel << CLICK_SHIFT) + oldlvol * rampvol)
571 * sample >> CLICK_SHIFT; 580 * sample >> CLICK_SHIFT;
@@ -576,22 +585,22 @@ static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,S
576 } 585 }
577 vnf->rampvol = rampvol; 586 vnf->rampvol = rampvol;
578 if (todo < 0) 587 if (todo < 0)
579 return index; 588 return idx;
580 } 589 }
581 590
582 while(todo--) { 591 while(todo--) {
583 sample=(SLONG)srce[index>>FRACBITS]+ 592 sample=(SLONG)srce[idx>>FRACBITS]+
584 ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) 593 ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
585 *(index&FRACMASK)>>FRACBITS); 594 *(idx&FRACMASK)>>FRACBITS);
586 index += increment; 595 idx += increment;
587 596
588 *dest++ += lvolsel * sample; 597 *dest++ += lvolsel * sample;
589 *dest++ += rvolsel * sample; 598 *dest++ += rvolsel * sample;
590 } 599 }
591 return index; 600 return idx;
592} 601}
593 602
594static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) 603static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
595{ 604{
596 SLONG sample; 605 SLONG sample;
597 SLONG lvolsel = vnf->lvolsel; 606 SLONG lvolsel = vnf->lvolsel;
@@ -610,13 +619,13 @@ static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index
610 if (rampvol) { 619 if (rampvol) {
611 oldvol -= vol; 620 oldvol -= vol;
612 while(todo--) { 621 while(todo--) {
613 sample=(SLONG)srce[index>>FRACBITS]+ 622 sample=(SLONG)srce[idx>>FRACBITS]+
614 ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) 623 ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
615 *(index&FRACMASK)>>FRACBITS); 624 *(idx&FRACMASK)>>FRACBITS);
616 index += increment; 625 idx += increment;
617 626
618 sample=((vol << CLICK_SHIFT) + oldvol * rampvol) 627 sample=((vol << CLICK_SHIFT) + oldvol * rampvol)
619 * sample >> CLICK_SHIFT; 628 * sample >> CLICK_SHIFT;
620 *dest++ += sample; 629 *dest++ += sample;
621 *dest++ -= sample; 630 *dest++ -= sample;
622 if (!--rampvol) 631 if (!--rampvol)
@@ -624,19 +633,19 @@ static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index
624 } 633 }
625 vnf->rampvol = rampvol; 634 vnf->rampvol = rampvol;
626 if (todo < 0) 635 if (todo < 0)
627 return index; 636 return idx;
628 } 637 }
629 638
630 while(todo--) { 639 while(todo--) {
631 sample=(SLONG)srce[index>>FRACBITS]+ 640 sample=(SLONG)srce[idx>>FRACBITS]+
632 ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) 641 ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
633 *(index&FRACMASK)>>FRACBITS); 642 *(idx&FRACMASK)>>FRACBITS);
634 index += increment; 643 idx += increment;
635 644
636 *dest++ += vol*sample; 645 *dest++ += vol*sample;
637 *dest++ -= vol*sample; 646 *dest++ -= vol*sample;
638 } 647 }
639 return index; 648 return idx;
640} 649}
641 650
642static void (*MixReverb)(SLONG* srce,NATIVE count); 651static void (*MixReverb)(SLONG* srce,NATIVE count);
@@ -673,7 +682,7 @@ static void MixReverb_Normal(SLONG* srce,NATIVE count)
673 682
674 /* left channel */ 683 /* left channel */
675 *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ 684 *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+
676 RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; 685 RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8];
677 } 686 }
678} 687}
679 688
@@ -710,10 +719,10 @@ static void MixReverb_Stereo(SLONG* srce,NATIVE count)
710 719
711 /* left channel then right channel */ 720 /* left channel then right channel */
712 *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ 721 *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+
713 RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; 722 RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8];
714 723
715 *srce++ +=RVbufR1[loc1]-RVbufR2[loc2]+RVbufR3[loc3]-RVbufR4[loc4]+ 724 *srce++ +=RVbufR1[loc1]-RVbufR2[loc2]+RVbufR3[loc3]-RVbufR4[loc4]+
716 RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8]; 725 RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8];
717 } 726 }
718} 727}
719 728
@@ -839,58 +848,56 @@ static void Mix32To8(SBYTE* dste,const SLONG *srce,NATIVE count)
839 848
840#if defined HAVE_ALTIVEC || defined HAVE_SSE2 849#if defined HAVE_ALTIVEC || defined HAVE_SSE2
841 850
842// Mix 32bit input to floating point. 32 samples per iteration 851/* Mix 32bit input to floating point. 32 samples per iteration */
843// PC: ?, Mac OK 852/* PC: ?, Mac OK */
844static void Mix32ToFP_SIMD(float* dste,SLONG* srce,NATIVE count) 853static void Mix32ToFP_SIMD(float* dste,const SLONG* srce,NATIVE count)
845{ 854{
846 int remain=count; 855 const float k = ((1.0f / 32768.0f) / (1 << FP_SHIFT));
856 int remain=count;
857 simd_m128 x1, x2, xk;
847 858
848 while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce)) 859 while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce))
849 { 860 {
850 float x1; 861 float xf;
851 EXTRACT_SAMPLE_FP(x1,FP_SHIFT); 862 EXTRACT_SAMPLE_FP(xf,FP_SHIFT);
852 CHECK_SAMPLE_FP(x1,1.0f); 863 CHECK_SAMPLE_FP(xf,1.0f);
853 PUT_SAMPLE_FP(x1); 864 PUT_SAMPLE_FP(xf);
854 count--; 865 count--;
855 if (!count) 866 if (!count) return;
856 {
857 return;
858 }
859 } 867 }
860 868
861 remain = count&7; 869 remain = count&7;
862 870
863 const float k = ((1.0f / 32768.0f) / (1 << FP_SHIFT)); 871 xk = LOAD_PS1_SIMD(&k); /* Scale factor */
864 simd_m128 x1, x2;
865 simd_m128 xk = LOAD_PS1_SIMD(&k); // Scale factor
866 872
867 for(count>>=3;count;count--) { 873 for(count>>=3;count;count--) {
868 EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); // Load 4 samples 874 EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); /* Load 4 samples */
869 EXTRACT_SAMPLE_SIMD_F(srce+4, x2, FP_SHIFT, xk); // Load 4 samples 875 EXTRACT_SAMPLE_SIMD_F(srce+4, x2, FP_SHIFT, xk); /* Load 4 samples */
870 PUT_SAMPLE_SIMD_F(dste, x1); // Store 4 samples 876 PUT_SAMPLE_SIMD_F(dste, x1); /* Store 4 samples */
871 PUT_SAMPLE_SIMD_F(dste+4, x2); // Store 4 samples 877 PUT_SAMPLE_SIMD_F(dste+4, x2); /* Store 4 samples */
872 srce+=8; 878 srce+=8;
873 dste+=8; 879 dste+=8;
874 } 880 }
875 881
876 if (remain&4) { 882 if (remain&4) {
877 EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); // Load 4 samples 883 EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); /* Load 4 samples */
878 PUT_SAMPLE_SIMD_F(dste, x1); // Store 4 samples 884 PUT_SAMPLE_SIMD_F(dste, x1); /* Store 4 samples */
879 srce+=4; 885 srce+=4;
880 dste+=4; 886 dste+=4;
881 remain &= 3; 887 remain &= 3;
882 } 888 }
883 889
884 while(remain--) { 890 while(remain--) {
885 float x1; 891 float xf;
886 EXTRACT_SAMPLE_FP(x1,FP_SHIFT); 892 EXTRACT_SAMPLE_FP(xf,FP_SHIFT);
887 CHECK_SAMPLE_FP(x1,1.0f); 893 CHECK_SAMPLE_FP(xf,1.0f);
888 PUT_SAMPLE_FP(x1); 894 PUT_SAMPLE_FP(xf);
889 } 895 }
890} 896}
891// PC: Ok, Mac Ok 897
892static void Mix32To16_SIMD(SWORD* dste,SLONG* srce,NATIVE count) 898/* PC: Ok, Mac Ok */
893{ 899static void Mix32To16_SIMD(SWORD* dste,const SLONG* srce,NATIVE count)
900{
894 int remain = count; 901 int remain = count;
895 902
896 while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce)) 903 while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce))
@@ -900,34 +907,31 @@ static void Mix32To16_SIMD(SWORD* dste,SLONG* srce,NATIVE count)
900 CHECK_SAMPLE(x1,32768); 907 CHECK_SAMPLE(x1,32768);
901 PUT_SAMPLE(x1); 908 PUT_SAMPLE(x1);
902 count--; 909 count--;
903 if (!count) 910 if (!count) return;
904 {
905 return;
906 }
907 } 911 }
908 912
909 remain = count&7; 913 remain = count&7;
910 914
911 for(count>>=3;count;count--) 915 for(count>>=3;count;count--)
912 { 916 {
913 simd_m128i x1,x2; 917 simd_m128i x1,x2;
914 EXTRACT_SAMPLE_SIMD_16(srce, x1); // Load 4 samples 918 EXTRACT_SAMPLE_SIMD_16(srce, x1); /* Load 4 samples */
915 EXTRACT_SAMPLE_SIMD_16(srce+4, x2); // Load 4 samples 919 EXTRACT_SAMPLE_SIMD_16(srce+4, x2); /* Load 4 samples */
916 PUT_SAMPLE_SIMD_W(dste, x1, x2); // Store 8 samples 920 PUT_SAMPLE_SIMD_W(dste, x1, x2); /* Store 8 samples */
917 srce+=8; 921 srce+=8;
918 dste+=8; 922 dste+=8;
919 } 923 }
920 924
921 if (remain) 925 if (remain)
922 Mix32To16(dste, srce, remain); 926 Mix32To16(dste, srce, remain);
923} 927}
924 928
925// Mix 32bit input to 8bit. 128 samples per iteration 929/* Mix 32bit input to 8bit. 128 samples per iteration */
926// PC:OK, Mac: Ok 930/* PC:OK, Mac: Ok */
927static void Mix32To8_SIMD(SBYTE* dste,SLONG* srce,NATIVE count) 931static void Mix32To8_SIMD(SBYTE* dste,const SLONG* srce,NATIVE count)
928{ 932{
929 int remain=count; 933 int remain=count;
930 934
931 while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce)) 935 while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce))
932 { 936 {
933 SWORD x1; 937 SWORD x1;
@@ -935,32 +939,29 @@ static void Mix32To8_SIMD(SBYTE* dste,SLONG* srce,NATIVE count)
935 CHECK_SAMPLE(x1,128); 939 CHECK_SAMPLE(x1,128);
936 PUT_SAMPLE(x1+128); 940 PUT_SAMPLE(x1+128);
937 count--; 941 count--;
938 if (!count) 942 if (!count) return;
939 {
940 return;
941 }
942 } 943 }
943 944
944 remain = count&15; 945 remain = count&15;
945 946
946 for(count>>=4;count;count--) { 947 for(count>>=4;count;count--) {
947 simd_m128i x1,x2,x3,x4; 948 simd_m128i x1,x2,x3,x4;
948 EXTRACT_SAMPLE_SIMD_8(srce, x1); // Load 4 samples 949 EXTRACT_SAMPLE_SIMD_8(srce, x1); /* Load 4 samples */
949 EXTRACT_SAMPLE_SIMD_8(srce+4, x2); // Load 4 samples 950 EXTRACT_SAMPLE_SIMD_8(srce+4, x2); /* Load 4 samples */
950 EXTRACT_SAMPLE_SIMD_8(srce+8, x3); // Load 4 samples 951 EXTRACT_SAMPLE_SIMD_8(srce+8, x3); /* Load 4 samples */
951 EXTRACT_SAMPLE_SIMD_8(srce+12, x4); // Load 4 samples 952 EXTRACT_SAMPLE_SIMD_8(srce+12, x4); /* Load 4 samples */
952 PUT_SAMPLE_SIMD_B(dste, x1, x2, x3, x4); // Store 16 samples 953 PUT_SAMPLE_SIMD_B(dste, x1, x2, x3, x4); /* Store 16 samples */
953 srce+=16; 954 srce+=16;
954 dste+=16; 955 dste+=16;
955 } 956 }
957
956 if (remain) 958 if (remain)
957 Mix32To8(dste, srce, remain); 959 Mix32To8(dste, srce, remain);
958} 960}
959 961
960#endif 962#endif
961 963
962 964
963
964static void AddChannel(SLONG* ptr,NATIVE todo) 965static void AddChannel(SLONG* ptr,NATIVE todo)
965{ 966{
966 SLONGLONG end,done; 967 SLONGLONG end,done;
@@ -1050,65 +1051,64 @@ static void AddChannel(SLONG* ptr,NATIVE todo)
1050 if(vc_mode & DMODE_STEREO) { 1051 if(vc_mode & DMODE_STEREO) {
1051 if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) 1052 if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND))
1052 vnf->current=Mix32SurroundInterp 1053 vnf->current=Mix32SurroundInterp
1053 (s,ptr,vnf->current,vnf->increment,done); 1054 (s,ptr,vnf->current,vnf->increment,done);
1054 else 1055 else
1055 vnf->current=Mix32StereoInterp 1056 vnf->current=Mix32StereoInterp
1056 (s,ptr,vnf->current,vnf->increment,done); 1057 (s,ptr,vnf->current,vnf->increment,done);
1057 } else 1058 } else
1058 vnf->current=Mix32MonoInterp 1059 vnf->current=Mix32MonoInterp
1059 (s,ptr,vnf->current,vnf->increment,done); 1060 (s,ptr,vnf->current,vnf->increment,done);
1060 } else if(vc_mode & DMODE_STEREO) { 1061 } else if(vc_mode & DMODE_STEREO) {
1061 if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) 1062 if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND))
1062 vnf->current=Mix32SurroundNormal 1063 vnf->current=Mix32SurroundNormal
1063 (s,ptr,vnf->current,vnf->increment,done); 1064 (s,ptr,vnf->current,vnf->increment,done);
1064 else 1065 else
1065 { 1066 {
1066#if defined HAVE_ALTIVEC || defined HAVE_SSE2 1067#if defined HAVE_ALTIVEC || defined HAVE_SSE2
1067 if (md_mode & DMODE_SIMDMIXER) 1068 if (md_mode & DMODE_SIMDMIXER)
1068 vnf->current=MixSIMDStereoNormal 1069 vnf->current=MixSIMDStereoNormal
1069 (s,ptr,vnf->current,vnf->increment,done); 1070 (s,ptr,vnf->current,vnf->increment,done);
1070 1071 else
1071 else
1072#endif 1072#endif
1073 vnf->current=Mix32StereoNormal 1073 vnf->current=Mix32StereoNormal
1074 (s,ptr,vnf->current,vnf->increment,done); 1074 (s,ptr,vnf->current,vnf->increment,done);
1075 } 1075 }
1076 } else 1076 } else
1077 vnf->current=Mix32MonoNormal 1077 vnf->current=Mix32MonoNormal
1078 (s,ptr,vnf->current,vnf->increment,done); 1078 (s,ptr,vnf->current,vnf->increment,done);
1079 } else 1079 }
1080 else
1080#endif 1081#endif
1081 { 1082 {
1082 if((md_mode & DMODE_INTERP)) { 1083 if((md_mode & DMODE_INTERP)) {
1083 if(vc_mode & DMODE_STEREO) { 1084 if(vc_mode & DMODE_STEREO) {
1084 if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) 1085 if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND))
1085 vnf->current=MixSurroundInterp 1086 vnf->current=MixSurroundInterp
1086 (s,ptr,vnf->current,vnf->increment,done); 1087 (s,ptr,vnf->current,vnf->increment,done);
1087 else 1088 else
1088 vnf->current=MixStereoInterp 1089 vnf->current=MixStereoInterp
1089 (s,ptr,vnf->current,vnf->increment,done); 1090 (s,ptr,vnf->current,vnf->increment,done);
1090 } else 1091 } else
1091 vnf->current=MixMonoInterp 1092 vnf->current=MixMonoInterp
1092 (s,ptr,vnf->current,vnf->increment,done); 1093 (s,ptr,vnf->current,vnf->increment,done);
1093 } else if(vc_mode & DMODE_STEREO) { 1094 } else if(vc_mode & DMODE_STEREO) {
1094 if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) 1095 if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND))
1095 vnf->current=MixSurroundNormal 1096 vnf->current=MixSurroundNormal
1096 (s,ptr,vnf->current,vnf->increment,done); 1097 (s,ptr,vnf->current,vnf->increment,done);
1097 else 1098 else
1098 { 1099 {
1099#if defined HAVE_ALTIVEC || defined HAVE_SSE2 1100#if defined HAVE_ALTIVEC || defined HAVE_SSE2
1100 if (md_mode & DMODE_SIMDMIXER) 1101 if (md_mode & DMODE_SIMDMIXER)
1101 vnf->current=MixSIMDStereoNormal 1102 vnf->current=MixSIMDStereoNormal
1102 (s,ptr,vnf->current,vnf->increment,done); 1103 (s,ptr,vnf->current,vnf->increment,done);
1103 1104 else
1104 else
1105#endif 1105#endif
1106 vnf->current=MixStereoNormal 1106 vnf->current=MixStereoNormal
1107 (s,ptr,vnf->current,vnf->increment,done); 1107 (s,ptr,vnf->current,vnf->increment,done);
1108 } 1108 }
1109 } else 1109 } else
1110 vnf->current=MixMonoNormal 1110 vnf->current=MixMonoNormal
1111 (s,ptr,vnf->current,vnf->increment,done); 1111 (s,ptr,vnf->current,vnf->increment,done);
1112 } 1112 }
1113 } else 1113 } else
1114 /* update sample position */ 1114 /* update sample position */
@@ -1119,6 +1119,33 @@ static void AddChannel(SLONG* ptr,NATIVE todo)
1119 } 1119 }
1120} 1120}
1121 1121
1122#ifdef NO_HQMIXER
1123#define VC_SetupPointers() do{}while(0)
1124#define VC1_Init VC_Init
1125#define VC1_Exit VC_Exit
1126#define VC1_PlayStart VC_PlayStart
1127#define VC1_PlayStop VC_PlayStop
1128#define VC1_SampleLength VC_SampleLength
1129#define VC1_SampleSpace VC_SampleSpace
1130#define VC1_SampleLoad VC_SampleLoad
1131#define VC1_SampleUnload VC_SampleUnload
1132#define VC1_SetNumVoices VC_SetNumVoices
1133#define VC1_SilenceBytes VC_SilenceBytes
1134#define VC1_VoicePlay VC_VoicePlay
1135#define VC1_VoiceStop VC_VoiceStop
1136#define VC1_VoiceGetFrequency VC_VoiceGetFrequency
1137#define VC1_VoiceGetPanning VC_VoiceGetPanning
1138#define VC1_VoiceGetPosition VC_VoiceGetPosition
1139#define VC1_VoiceGetVolume VC_VoiceGetVolume
1140#define VC1_VoiceRealVolume VC_VoiceRealVolume
1141#define VC1_VoiceSetFrequency VC_VoiceSetFrequency
1142#define VC1_VoiceSetPanning VC_VoiceSetPanning
1143#define VC1_VoiceSetVolume VC_VoiceSetVolume
1144#define VC1_VoiceStopped VC_VoiceStopped
1145#define VC1_WriteBytes VC_WriteBytes
1146#define VC1_WriteSamples VC_WriteSamples
1147#endif
1148
1122#define _IN_VIRTCH_ 1149#define _IN_VIRTCH_
1123#include "virtch_common.c" 1150#include "virtch_common.c"
1124#undef _IN_VIRTCH_ 1151#undef _IN_VIRTCH_
@@ -1190,7 +1217,6 @@ void VC1_WriteSamples(SBYTE* buf,ULONG todo)
1190 vc_callback((unsigned char*)vc_tickbuf, portion); 1217 vc_callback((unsigned char*)vc_tickbuf, portion);
1191 } 1218 }
1192 1219
1193
1194#if defined HAVE_ALTIVEC || defined HAVE_SSE2 1220#if defined HAVE_ALTIVEC || defined HAVE_SSE2
1195 if (md_mode & DMODE_SIMDMIXER) 1221 if (md_mode & DMODE_SIMDMIXER)
1196 { 1222 {
@@ -1219,20 +1245,23 @@ void VC1_WriteSamples(SBYTE* buf,ULONG todo)
1219 1245
1220int VC1_Init(void) 1246int VC1_Init(void)
1221{ 1247{
1248#ifndef NO_HQMIXER
1222 VC_SetupPointers(); 1249 VC_SetupPointers();
1223
1224 //if (md_mode&DMODE_HQMIXER)
1225 // return VC2_Init();
1226 1250
1227 if(!(Samples=(SWORD**)MikMod_calloc(MAXSAMPLEHANDLES,sizeof(SWORD*)))) { 1251 if (md_mode&DMODE_HQMIXER)
1252 return VC2_Init();
1253#endif
1254
1255 if(!(Samples=(SWORD**)MikMod_amalloc(MAXSAMPLEHANDLES*sizeof(SWORD*)))) {
1228 _mm_errno = MMERR_INITIALIZING_MIXER; 1256 _mm_errno = MMERR_INITIALIZING_MIXER;
1229 return 1; 1257 return 1;
1230 } 1258 }
1231 if(!vc_tickbuf) 1259 if(!vc_tickbuf) {
1232 if(!(vc_tickbuf=(SLONG*)MikMod_malloc((TICKLSIZE+32)*sizeof(SLONG)))) { 1260 if(!(vc_tickbuf=(SLONG*)MikMod_amalloc((TICKLSIZE+32)*sizeof(SLONG)))) {
1233 _mm_errno = MMERR_INITIALIZING_MIXER; 1261 _mm_errno = MMERR_INITIALIZING_MIXER;
1234 return 1; 1262 return 1;
1235 } 1263 }
1264 }
1236 1265
1237 MixReverb=(md_mode&DMODE_STEREO)?MixReverb_Stereo:MixReverb_Normal; 1266 MixReverb=(md_mode&DMODE_STEREO)?MixReverb_Stereo:MixReverb_Normal;
1238 MixLowPass=(md_mode&DMODE_STEREO)?MixLowPass_Stereo:MixLowPass_Normal; 1267 MixLowPass=(md_mode&DMODE_STEREO)?MixLowPass_Stereo:MixLowPass_Normal;
@@ -1264,14 +1293,17 @@ int VC1_PlayStart(void)
1264 if(!(RVbufL7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; 1293 if(!(RVbufL7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1;
1265 if(!(RVbufL8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; 1294 if(!(RVbufL8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1;
1266 1295
1267 if(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1; 1296 /* allocate reverb buffers for the right channel if in stereo mode only. */
1268 if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1; 1297 if (vc_mode & DMODE_STEREO) {
1269 if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1; 1298 if(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1;
1270 if(!(RVbufR4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1; 1299 if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1;
1271 if(!(RVbufR5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1; 1300 if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1;
1272 if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1; 1301 if(!(RVbufR4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1;
1273 if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; 1302 if(!(RVbufR5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1;
1274 if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; 1303 if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1;
1304 if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1;
1305 if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1;
1306 }
1275 1307
1276 RVRindex = 0; 1308 RVRindex = 0;
1277 return 0; 1309 return 0;
@@ -1279,23 +1311,23 @@ int VC1_PlayStart(void)
1279 1311
1280void VC1_PlayStop(void) 1312void VC1_PlayStop(void)
1281{ 1313{
1282 if(RVbufL1) MikMod_free(RVbufL1); 1314 MikMod_free(RVbufL1);
1283 if(RVbufL2) MikMod_free(RVbufL2); 1315 MikMod_free(RVbufL2);
1284 if(RVbufL3) MikMod_free(RVbufL3); 1316 MikMod_free(RVbufL3);
1285 if(RVbufL4) MikMod_free(RVbufL4); 1317 MikMod_free(RVbufL4);
1286 if(RVbufL5) MikMod_free(RVbufL5); 1318 MikMod_free(RVbufL5);
1287 if(RVbufL6) MikMod_free(RVbufL6); 1319 MikMod_free(RVbufL6);
1288 if(RVbufL7) MikMod_free(RVbufL7); 1320 MikMod_free(RVbufL7);
1289 if(RVbufL8) MikMod_free(RVbufL8); 1321 MikMod_free(RVbufL8);
1290 RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL; 1322 RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL;
1291 if(RVbufR1) MikMod_free(RVbufR1); 1323 MikMod_free(RVbufR1);
1292 if(RVbufR2) MikMod_free(RVbufR2); 1324 MikMod_free(RVbufR2);
1293 if(RVbufR3) MikMod_free(RVbufR3); 1325 MikMod_free(RVbufR3);
1294 if(RVbufR4) MikMod_free(RVbufR4); 1326 MikMod_free(RVbufR4);
1295 if(RVbufR5) MikMod_free(RVbufR5); 1327 MikMod_free(RVbufR5);
1296 if(RVbufR6) MikMod_free(RVbufR6); 1328 MikMod_free(RVbufR6);
1297 if(RVbufR7) MikMod_free(RVbufR7); 1329 MikMod_free(RVbufR7);
1298 if(RVbufR8) MikMod_free(RVbufR8); 1330 MikMod_free(RVbufR8);
1299 RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL; 1331 RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL;
1300} 1332}
1301 1333
@@ -1305,8 +1337,8 @@ int VC1_SetNumVoices(void)
1305 1337
1306 if(!(vc_softchn=md_softchn)) return 0; 1338 if(!(vc_softchn=md_softchn)) return 0;
1307 1339
1308 if(vinf) MikMod_free(vinf); 1340 MikMod_free(vinf);
1309 if(!(vinf= MikMod_calloc(sizeof(VINFO),vc_softchn))) return 1; 1341 if(!(vinf=(VINFO*)MikMod_calloc(vc_softchn,sizeof(VINFO)))) return 1;
1310 1342
1311 for(t=0;t<vc_softchn;t++) { 1343 for(t=0;t<vc_softchn;t++) {
1312 vinf[t].frq=10000; 1344 vinf[t].frq=10000;