1d5ac70f0Sopenharmony_ci#if 0 2d5ac70f0Sopenharmony_ci//#if defined(__i386__) || defined(__x86_64__) 3d5ac70f0Sopenharmony_ci#define LOCK_PREFIX "lock ; " 4d5ac70f0Sopenharmony_ci#define ARCH_ADD(p,a) \ 5d5ac70f0Sopenharmony_ci __asm__ __volatile__(LOCK_PREFIX "addl %1,%0" \ 6d5ac70f0Sopenharmony_ci :"=m" (*p) \ 7d5ac70f0Sopenharmony_ci :"ir" (a), "m" (*p)) 8d5ac70f0Sopenharmony_cistruct __xchg_dummy { unsigned long a[100]; }; 9d5ac70f0Sopenharmony_ci#define __xg(x) ((struct __xchg_dummy *)(x)) 10d5ac70f0Sopenharmony_cistatic inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, 11d5ac70f0Sopenharmony_ci unsigned long new, int size) 12d5ac70f0Sopenharmony_ci{ 13d5ac70f0Sopenharmony_ci unsigned long prev; 14d5ac70f0Sopenharmony_ci switch (size) { 15d5ac70f0Sopenharmony_ci case 1: 16d5ac70f0Sopenharmony_ci __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2" 17d5ac70f0Sopenharmony_ci : "=a"(prev) 18d5ac70f0Sopenharmony_ci : "q"(new), "m"(*__xg(ptr)), "0"(old) 19d5ac70f0Sopenharmony_ci : "memory"); 20d5ac70f0Sopenharmony_ci return prev; 21d5ac70f0Sopenharmony_ci case 2: 22d5ac70f0Sopenharmony_ci __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2" 23d5ac70f0Sopenharmony_ci : "=a"(prev) 24d5ac70f0Sopenharmony_ci : "q"(new), "m"(*__xg(ptr)), "0"(old) 25d5ac70f0Sopenharmony_ci : "memory"); 26d5ac70f0Sopenharmony_ci return prev; 27d5ac70f0Sopenharmony_ci case 4: 28d5ac70f0Sopenharmony_ci __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2" 29d5ac70f0Sopenharmony_ci : "=a"(prev) 30d5ac70f0Sopenharmony_ci : "q"(new), "m"(*__xg(ptr)), "0"(old) 31d5ac70f0Sopenharmony_ci : "memory"); 32d5ac70f0Sopenharmony_ci return prev; 33d5ac70f0Sopenharmony_ci } 34d5ac70f0Sopenharmony_ci return old; 35d5ac70f0Sopenharmony_ci} 36d5ac70f0Sopenharmony_ci 37d5ac70f0Sopenharmony_ci#define ARCH_CMPXCHG(ptr,o,n)\ 38d5ac70f0Sopenharmony_ci ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ 39d5ac70f0Sopenharmony_ci (unsigned long)(n),sizeof(*(ptr)))) 40d5ac70f0Sopenharmony_ci#define IS_CONCURRENT 1 /* check race */ 41d5ac70f0Sopenharmony_ci#endif 42d5ac70f0Sopenharmony_ci 43d5ac70f0Sopenharmony_ci#ifndef ARCH_ADD 44d5ac70f0Sopenharmony_ci#define ARCH_ADD(p,a) (*(p) += (a)) 45d5ac70f0Sopenharmony_ci#define ARCH_CMPXCHG(p,a,b) (*(p)) /* fake */ 46d5ac70f0Sopenharmony_ci#define IS_CONCURRENT 0 /* no race check */ 47d5ac70f0Sopenharmony_ci#endif 48d5ac70f0Sopenharmony_ci 49d5ac70f0Sopenharmony_ci#if IS_CONCURRENT 50d5ac70f0Sopenharmony_cistatic void mix_areas_16(unsigned int size, 51d5ac70f0Sopenharmony_ci volatile signed short *dst, signed short *src, 52d5ac70f0Sopenharmony_ci volatile signed int *sum, size_t dst_step, 53d5ac70f0Sopenharmony_ci size_t src_step, size_t sum_step) 54d5ac70f0Sopenharmony_ci{ 55d5ac70f0Sopenharmony_ci register signed int sample, old_sample; 56d5ac70f0Sopenharmony_ci 57d5ac70f0Sopenharmony_ci for (;;) { 58d5ac70f0Sopenharmony_ci sample = *src; 59d5ac70f0Sopenharmony_ci old_sample = *sum; 60d5ac70f0Sopenharmony_ci if (ARCH_CMPXCHG(dst, 0, 1) == 0) 61d5ac70f0Sopenharmony_ci sample -= old_sample; 62d5ac70f0Sopenharmony_ci ARCH_ADD(sum, sample); 63d5ac70f0Sopenharmony_ci do { 64d5ac70f0Sopenharmony_ci old_sample = *sum; 65d5ac70f0Sopenharmony_ci if (old_sample > 0x7fff) 66d5ac70f0Sopenharmony_ci sample = 0x7fff; 67d5ac70f0Sopenharmony_ci else if (old_sample < -0x8000) 68d5ac70f0Sopenharmony_ci sample = -0x8000; 69d5ac70f0Sopenharmony_ci else 70d5ac70f0Sopenharmony_ci sample = old_sample; 71d5ac70f0Sopenharmony_ci *dst = sample; 72d5ac70f0Sopenharmony_ci } while (IS_CONCURRENT && *sum != old_sample); 73d5ac70f0Sopenharmony_ci if (!--size) 74d5ac70f0Sopenharmony_ci return; 75d5ac70f0Sopenharmony_ci src = (signed short *) ((char *)src + src_step); 76d5ac70f0Sopenharmony_ci dst = (signed short *) ((char *)dst + dst_step); 77d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 78d5ac70f0Sopenharmony_ci } 79d5ac70f0Sopenharmony_ci} 80d5ac70f0Sopenharmony_ci 81d5ac70f0Sopenharmony_cistatic void mix_areas_32(unsigned int size, 82d5ac70f0Sopenharmony_ci volatile signed int *dst, signed int *src, 83d5ac70f0Sopenharmony_ci volatile signed int *sum, size_t dst_step, 84d5ac70f0Sopenharmony_ci size_t src_step, size_t sum_step) 85d5ac70f0Sopenharmony_ci{ 86d5ac70f0Sopenharmony_ci register signed int sample, old_sample; 87d5ac70f0Sopenharmony_ci 88d5ac70f0Sopenharmony_ci for (;;) { 89d5ac70f0Sopenharmony_ci sample = *src >> 8; 90d5ac70f0Sopenharmony_ci old_sample = *sum; 91d5ac70f0Sopenharmony_ci if (ARCH_CMPXCHG(dst, 0, 1) == 0) 92d5ac70f0Sopenharmony_ci sample -= old_sample; 93d5ac70f0Sopenharmony_ci ARCH_ADD(sum, sample); 94d5ac70f0Sopenharmony_ci do { 95d5ac70f0Sopenharmony_ci old_sample = *sum; 96d5ac70f0Sopenharmony_ci if (old_sample > 0x7fffff) 97d5ac70f0Sopenharmony_ci sample = 0x7fffffff; 98d5ac70f0Sopenharmony_ci else if (old_sample < -0x800000) 99d5ac70f0Sopenharmony_ci sample = -0x80000000; 100d5ac70f0Sopenharmony_ci else 101d5ac70f0Sopenharmony_ci sample = old_sample * 256; 102d5ac70f0Sopenharmony_ci *dst = sample; 103d5ac70f0Sopenharmony_ci } while (IS_CONCURRENT && *sum != old_sample); 104d5ac70f0Sopenharmony_ci if (!--size) 105d5ac70f0Sopenharmony_ci return; 106d5ac70f0Sopenharmony_ci src = (signed int *) ((char *)src + src_step); 107d5ac70f0Sopenharmony_ci dst = (signed int *) ((char *)dst + dst_step); 108d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 109d5ac70f0Sopenharmony_ci } 110d5ac70f0Sopenharmony_ci} 111d5ac70f0Sopenharmony_ci 112d5ac70f0Sopenharmony_cistatic void mix_select_callbacks(snd_pcm_direct_t *dmix) 113d5ac70f0Sopenharmony_ci{ 114d5ac70f0Sopenharmony_ci dmix->u.dmix.mix_areas_16 = mix_areas_16; 115d5ac70f0Sopenharmony_ci dmix->u.dmix.mix_areas_32 = mix_areas_32; 116d5ac70f0Sopenharmony_ci} 117d5ac70f0Sopenharmony_ci 118d5ac70f0Sopenharmony_ci#else 119d5ac70f0Sopenharmony_ci 120d5ac70f0Sopenharmony_ci/* non-concurrent version, supporting both endians */ 121d5ac70f0Sopenharmony_ci#define generic_dmix_supported_format \ 122d5ac70f0Sopenharmony_ci ((1ULL << SND_PCM_FORMAT_S16_LE) | (1ULL << SND_PCM_FORMAT_S32_LE) |\ 123d5ac70f0Sopenharmony_ci (1ULL << SND_PCM_FORMAT_S16_BE) | (1ULL << SND_PCM_FORMAT_S32_BE) |\ 124d5ac70f0Sopenharmony_ci (1ULL << SND_PCM_FORMAT_S24_LE) | (1ULL << SND_PCM_FORMAT_S24_3LE) | \ 125d5ac70f0Sopenharmony_ci (1ULL << SND_PCM_FORMAT_U8)) 126d5ac70f0Sopenharmony_ci 127d5ac70f0Sopenharmony_ci#include "bswap.h" 128d5ac70f0Sopenharmony_ci 129d5ac70f0Sopenharmony_cistatic void generic_mix_areas_16_native(unsigned int size, 130d5ac70f0Sopenharmony_ci volatile signed short *dst, 131d5ac70f0Sopenharmony_ci signed short *src, 132d5ac70f0Sopenharmony_ci volatile signed int *sum, 133d5ac70f0Sopenharmony_ci size_t dst_step, 134d5ac70f0Sopenharmony_ci size_t src_step, 135d5ac70f0Sopenharmony_ci size_t sum_step) 136d5ac70f0Sopenharmony_ci{ 137d5ac70f0Sopenharmony_ci register signed int sample; 138d5ac70f0Sopenharmony_ci 139d5ac70f0Sopenharmony_ci for (;;) { 140d5ac70f0Sopenharmony_ci sample = *src; 141d5ac70f0Sopenharmony_ci if (! *dst) { 142d5ac70f0Sopenharmony_ci *sum = sample; 143d5ac70f0Sopenharmony_ci *dst = *src; 144d5ac70f0Sopenharmony_ci } else { 145d5ac70f0Sopenharmony_ci sample += *sum; 146d5ac70f0Sopenharmony_ci *sum = sample; 147d5ac70f0Sopenharmony_ci if (sample > 0x7fff) 148d5ac70f0Sopenharmony_ci sample = 0x7fff; 149d5ac70f0Sopenharmony_ci else if (sample < -0x8000) 150d5ac70f0Sopenharmony_ci sample = -0x8000; 151d5ac70f0Sopenharmony_ci *dst = sample; 152d5ac70f0Sopenharmony_ci } 153d5ac70f0Sopenharmony_ci if (!--size) 154d5ac70f0Sopenharmony_ci return; 155d5ac70f0Sopenharmony_ci src = (signed short *) ((char *)src + src_step); 156d5ac70f0Sopenharmony_ci dst = (signed short *) ((char *)dst + dst_step); 157d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 158d5ac70f0Sopenharmony_ci } 159d5ac70f0Sopenharmony_ci} 160d5ac70f0Sopenharmony_ci 161d5ac70f0Sopenharmony_cistatic void generic_remix_areas_16_native(unsigned int size, 162d5ac70f0Sopenharmony_ci volatile signed short *dst, 163d5ac70f0Sopenharmony_ci signed short *src, 164d5ac70f0Sopenharmony_ci volatile signed int *sum, 165d5ac70f0Sopenharmony_ci size_t dst_step, 166d5ac70f0Sopenharmony_ci size_t src_step, 167d5ac70f0Sopenharmony_ci size_t sum_step) 168d5ac70f0Sopenharmony_ci{ 169d5ac70f0Sopenharmony_ci register signed int sample; 170d5ac70f0Sopenharmony_ci 171d5ac70f0Sopenharmony_ci for (;;) { 172d5ac70f0Sopenharmony_ci sample = *src; 173d5ac70f0Sopenharmony_ci if (! *dst) { 174d5ac70f0Sopenharmony_ci *sum = -sample; 175d5ac70f0Sopenharmony_ci *dst = -sample; 176d5ac70f0Sopenharmony_ci } else { 177d5ac70f0Sopenharmony_ci *sum = sample = *sum - sample; 178d5ac70f0Sopenharmony_ci if (sample > 0x7fff) 179d5ac70f0Sopenharmony_ci sample = 0x7fff; 180d5ac70f0Sopenharmony_ci else if (sample < -0x8000) 181d5ac70f0Sopenharmony_ci sample = -0x8000; 182d5ac70f0Sopenharmony_ci *dst = sample; 183d5ac70f0Sopenharmony_ci } 184d5ac70f0Sopenharmony_ci if (!--size) 185d5ac70f0Sopenharmony_ci return; 186d5ac70f0Sopenharmony_ci src = (signed short *) ((char *)src + src_step); 187d5ac70f0Sopenharmony_ci dst = (signed short *) ((char *)dst + dst_step); 188d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 189d5ac70f0Sopenharmony_ci } 190d5ac70f0Sopenharmony_ci} 191d5ac70f0Sopenharmony_ci 192d5ac70f0Sopenharmony_cistatic void generic_mix_areas_32_native(unsigned int size, 193d5ac70f0Sopenharmony_ci volatile signed int *dst, 194d5ac70f0Sopenharmony_ci signed int *src, 195d5ac70f0Sopenharmony_ci volatile signed int *sum, 196d5ac70f0Sopenharmony_ci size_t dst_step, 197d5ac70f0Sopenharmony_ci size_t src_step, 198d5ac70f0Sopenharmony_ci size_t sum_step) 199d5ac70f0Sopenharmony_ci{ 200d5ac70f0Sopenharmony_ci register signed int sample; 201d5ac70f0Sopenharmony_ci 202d5ac70f0Sopenharmony_ci for (;;) { 203d5ac70f0Sopenharmony_ci sample = *src >> 8; 204d5ac70f0Sopenharmony_ci if (! *dst) { 205d5ac70f0Sopenharmony_ci *sum = sample; 206d5ac70f0Sopenharmony_ci *dst = *src; 207d5ac70f0Sopenharmony_ci } else { 208d5ac70f0Sopenharmony_ci sample += *sum; 209d5ac70f0Sopenharmony_ci *sum = sample; 210d5ac70f0Sopenharmony_ci if (sample > 0x7fffff) 211d5ac70f0Sopenharmony_ci sample = 0x7fffffff; 212d5ac70f0Sopenharmony_ci else if (sample < -0x800000) 213d5ac70f0Sopenharmony_ci sample = -0x80000000; 214d5ac70f0Sopenharmony_ci else 215d5ac70f0Sopenharmony_ci sample *= 256; 216d5ac70f0Sopenharmony_ci *dst = sample; 217d5ac70f0Sopenharmony_ci } 218d5ac70f0Sopenharmony_ci if (!--size) 219d5ac70f0Sopenharmony_ci return; 220d5ac70f0Sopenharmony_ci src = (signed int *) ((char *)src + src_step); 221d5ac70f0Sopenharmony_ci dst = (signed int *) ((char *)dst + dst_step); 222d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 223d5ac70f0Sopenharmony_ci } 224d5ac70f0Sopenharmony_ci} 225d5ac70f0Sopenharmony_ci 226d5ac70f0Sopenharmony_cistatic void generic_remix_areas_32_native(unsigned int size, 227d5ac70f0Sopenharmony_ci volatile signed int *dst, 228d5ac70f0Sopenharmony_ci signed int *src, 229d5ac70f0Sopenharmony_ci volatile signed int *sum, 230d5ac70f0Sopenharmony_ci size_t dst_step, 231d5ac70f0Sopenharmony_ci size_t src_step, 232d5ac70f0Sopenharmony_ci size_t sum_step) 233d5ac70f0Sopenharmony_ci{ 234d5ac70f0Sopenharmony_ci register signed int sample; 235d5ac70f0Sopenharmony_ci 236d5ac70f0Sopenharmony_ci for (;;) { 237d5ac70f0Sopenharmony_ci sample = *src >> 8; 238d5ac70f0Sopenharmony_ci if (! *dst) { 239d5ac70f0Sopenharmony_ci *sum = -sample; 240d5ac70f0Sopenharmony_ci *dst = -*src; 241d5ac70f0Sopenharmony_ci } else { 242d5ac70f0Sopenharmony_ci *sum = sample = *sum - sample; 243d5ac70f0Sopenharmony_ci if (sample > 0x7fffff) 244d5ac70f0Sopenharmony_ci sample = 0x7fffffff; 245d5ac70f0Sopenharmony_ci else if (sample < -0x800000) 246d5ac70f0Sopenharmony_ci sample = -0x80000000; 247d5ac70f0Sopenharmony_ci else 248d5ac70f0Sopenharmony_ci sample *= 256; 249d5ac70f0Sopenharmony_ci *dst = sample; 250d5ac70f0Sopenharmony_ci } 251d5ac70f0Sopenharmony_ci if (!--size) 252d5ac70f0Sopenharmony_ci return; 253d5ac70f0Sopenharmony_ci src = (signed int *) ((char *)src + src_step); 254d5ac70f0Sopenharmony_ci dst = (signed int *) ((char *)dst + dst_step); 255d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 256d5ac70f0Sopenharmony_ci } 257d5ac70f0Sopenharmony_ci} 258d5ac70f0Sopenharmony_ci 259d5ac70f0Sopenharmony_cistatic void generic_mix_areas_16_swap(unsigned int size, 260d5ac70f0Sopenharmony_ci volatile signed short *dst, 261d5ac70f0Sopenharmony_ci signed short *src, 262d5ac70f0Sopenharmony_ci volatile signed int *sum, 263d5ac70f0Sopenharmony_ci size_t dst_step, 264d5ac70f0Sopenharmony_ci size_t src_step, 265d5ac70f0Sopenharmony_ci size_t sum_step) 266d5ac70f0Sopenharmony_ci{ 267d5ac70f0Sopenharmony_ci register signed int sample; 268d5ac70f0Sopenharmony_ci 269d5ac70f0Sopenharmony_ci for (;;) { 270d5ac70f0Sopenharmony_ci sample = (signed short) bswap_16(*src); 271d5ac70f0Sopenharmony_ci if (! *dst) { 272d5ac70f0Sopenharmony_ci *sum = sample; 273d5ac70f0Sopenharmony_ci *dst = *src; 274d5ac70f0Sopenharmony_ci } else { 275d5ac70f0Sopenharmony_ci sample += *sum; 276d5ac70f0Sopenharmony_ci *sum = sample; 277d5ac70f0Sopenharmony_ci if (sample > 0x7fff) 278d5ac70f0Sopenharmony_ci sample = 0x7fff; 279d5ac70f0Sopenharmony_ci else if (sample < -0x8000) 280d5ac70f0Sopenharmony_ci sample = -0x8000; 281d5ac70f0Sopenharmony_ci *dst = (signed short) bswap_16((signed short) sample); 282d5ac70f0Sopenharmony_ci } 283d5ac70f0Sopenharmony_ci if (!--size) 284d5ac70f0Sopenharmony_ci return; 285d5ac70f0Sopenharmony_ci src = (signed short *) ((char *)src + src_step); 286d5ac70f0Sopenharmony_ci dst = (signed short *) ((char *)dst + dst_step); 287d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 288d5ac70f0Sopenharmony_ci } 289d5ac70f0Sopenharmony_ci} 290d5ac70f0Sopenharmony_ci 291d5ac70f0Sopenharmony_cistatic void generic_remix_areas_16_swap(unsigned int size, 292d5ac70f0Sopenharmony_ci volatile signed short *dst, 293d5ac70f0Sopenharmony_ci signed short *src, 294d5ac70f0Sopenharmony_ci volatile signed int *sum, 295d5ac70f0Sopenharmony_ci size_t dst_step, 296d5ac70f0Sopenharmony_ci size_t src_step, 297d5ac70f0Sopenharmony_ci size_t sum_step) 298d5ac70f0Sopenharmony_ci{ 299d5ac70f0Sopenharmony_ci register signed int sample; 300d5ac70f0Sopenharmony_ci 301d5ac70f0Sopenharmony_ci for (;;) { 302d5ac70f0Sopenharmony_ci sample = (signed short) bswap_16(*src); 303d5ac70f0Sopenharmony_ci if (! *dst) { 304d5ac70f0Sopenharmony_ci *sum = -sample; 305d5ac70f0Sopenharmony_ci *dst = (signed short) bswap_16((signed short) -sample); 306d5ac70f0Sopenharmony_ci } else { 307d5ac70f0Sopenharmony_ci *sum = sample = *sum - sample; 308d5ac70f0Sopenharmony_ci if (sample > 0x7fff) 309d5ac70f0Sopenharmony_ci sample = 0x7fff; 310d5ac70f0Sopenharmony_ci else if (sample < -0x8000) 311d5ac70f0Sopenharmony_ci sample = -0x8000; 312d5ac70f0Sopenharmony_ci *dst = (signed short) bswap_16((signed short) sample); 313d5ac70f0Sopenharmony_ci } 314d5ac70f0Sopenharmony_ci if (!--size) 315d5ac70f0Sopenharmony_ci return; 316d5ac70f0Sopenharmony_ci src = (signed short *) ((char *)src + src_step); 317d5ac70f0Sopenharmony_ci dst = (signed short *) ((char *)dst + dst_step); 318d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 319d5ac70f0Sopenharmony_ci } 320d5ac70f0Sopenharmony_ci} 321d5ac70f0Sopenharmony_ci 322d5ac70f0Sopenharmony_cistatic void generic_mix_areas_32_swap(unsigned int size, 323d5ac70f0Sopenharmony_ci volatile signed int *dst, 324d5ac70f0Sopenharmony_ci signed int *src, 325d5ac70f0Sopenharmony_ci volatile signed int *sum, 326d5ac70f0Sopenharmony_ci size_t dst_step, 327d5ac70f0Sopenharmony_ci size_t src_step, 328d5ac70f0Sopenharmony_ci size_t sum_step) 329d5ac70f0Sopenharmony_ci{ 330d5ac70f0Sopenharmony_ci register signed int sample; 331d5ac70f0Sopenharmony_ci 332d5ac70f0Sopenharmony_ci for (;;) { 333d5ac70f0Sopenharmony_ci sample = (signed int) bswap_32(*src) >> 8; 334d5ac70f0Sopenharmony_ci if (! *dst) { 335d5ac70f0Sopenharmony_ci *sum = sample; 336d5ac70f0Sopenharmony_ci *dst = *src; 337d5ac70f0Sopenharmony_ci } else { 338d5ac70f0Sopenharmony_ci sample += *sum; 339d5ac70f0Sopenharmony_ci *sum = sample; 340d5ac70f0Sopenharmony_ci if (sample > 0x7fffff) 341d5ac70f0Sopenharmony_ci sample = 0x7fffffff; 342d5ac70f0Sopenharmony_ci else if (sample < -0x800000) 343d5ac70f0Sopenharmony_ci sample = -0x80000000; 344d5ac70f0Sopenharmony_ci else 345d5ac70f0Sopenharmony_ci sample *= 256; 346d5ac70f0Sopenharmony_ci *dst = bswap_32(sample); 347d5ac70f0Sopenharmony_ci } 348d5ac70f0Sopenharmony_ci if (!--size) 349d5ac70f0Sopenharmony_ci return; 350d5ac70f0Sopenharmony_ci src = (signed int *) ((char *)src + src_step); 351d5ac70f0Sopenharmony_ci dst = (signed int *) ((char *)dst + dst_step); 352d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 353d5ac70f0Sopenharmony_ci } 354d5ac70f0Sopenharmony_ci} 355d5ac70f0Sopenharmony_ci 356d5ac70f0Sopenharmony_cistatic void generic_remix_areas_32_swap(unsigned int size, 357d5ac70f0Sopenharmony_ci volatile signed int *dst, 358d5ac70f0Sopenharmony_ci signed int *src, 359d5ac70f0Sopenharmony_ci volatile signed int *sum, 360d5ac70f0Sopenharmony_ci size_t dst_step, 361d5ac70f0Sopenharmony_ci size_t src_step, 362d5ac70f0Sopenharmony_ci size_t sum_step) 363d5ac70f0Sopenharmony_ci{ 364d5ac70f0Sopenharmony_ci register signed int sample; 365d5ac70f0Sopenharmony_ci 366d5ac70f0Sopenharmony_ci for (;;) { 367d5ac70f0Sopenharmony_ci sample = (signed int) bswap_32(*src) >> 8; 368d5ac70f0Sopenharmony_ci if (! *dst) { 369d5ac70f0Sopenharmony_ci *sum = -sample; 370d5ac70f0Sopenharmony_ci *dst = bswap_32(-sample); 371d5ac70f0Sopenharmony_ci } else { 372d5ac70f0Sopenharmony_ci *sum = sample = *sum - sample; 373d5ac70f0Sopenharmony_ci if (sample > 0x7fffff) 374d5ac70f0Sopenharmony_ci sample = 0x7fffffff; 375d5ac70f0Sopenharmony_ci else if (sample < -0x800000) 376d5ac70f0Sopenharmony_ci sample = -0x80000000; 377d5ac70f0Sopenharmony_ci else 378d5ac70f0Sopenharmony_ci sample *= 256; 379d5ac70f0Sopenharmony_ci *dst = bswap_32(sample); 380d5ac70f0Sopenharmony_ci } 381d5ac70f0Sopenharmony_ci if (!--size) 382d5ac70f0Sopenharmony_ci return; 383d5ac70f0Sopenharmony_ci src = (signed int *) ((char *)src + src_step); 384d5ac70f0Sopenharmony_ci dst = (signed int *) ((char *)dst + dst_step); 385d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 386d5ac70f0Sopenharmony_ci } 387d5ac70f0Sopenharmony_ci} 388d5ac70f0Sopenharmony_ci 389d5ac70f0Sopenharmony_ci/* always little endian */ 390d5ac70f0Sopenharmony_cistatic void generic_mix_areas_24(unsigned int size, 391d5ac70f0Sopenharmony_ci volatile unsigned char *dst, 392d5ac70f0Sopenharmony_ci unsigned char *src, 393d5ac70f0Sopenharmony_ci volatile signed int *sum, 394d5ac70f0Sopenharmony_ci size_t dst_step, 395d5ac70f0Sopenharmony_ci size_t src_step, 396d5ac70f0Sopenharmony_ci size_t sum_step) 397d5ac70f0Sopenharmony_ci{ 398d5ac70f0Sopenharmony_ci register signed int sample; 399d5ac70f0Sopenharmony_ci 400d5ac70f0Sopenharmony_ci for (;;) { 401d5ac70f0Sopenharmony_ci sample = src[0] | (src[1] << 8) | (((signed char *)src)[2] << 16); 402d5ac70f0Sopenharmony_ci if (!(dst[0] | dst[1] | dst[2])) { 403d5ac70f0Sopenharmony_ci *sum = sample; 404d5ac70f0Sopenharmony_ci } else { 405d5ac70f0Sopenharmony_ci sample += *sum; 406d5ac70f0Sopenharmony_ci *sum = sample; 407d5ac70f0Sopenharmony_ci if (sample > 0x7fffff) 408d5ac70f0Sopenharmony_ci sample = 0x7fffff; 409d5ac70f0Sopenharmony_ci else if (sample < -0x800000) 410d5ac70f0Sopenharmony_ci sample = -0x800000; 411d5ac70f0Sopenharmony_ci } 412d5ac70f0Sopenharmony_ci dst[0] = sample; 413d5ac70f0Sopenharmony_ci dst[1] = sample >> 8; 414d5ac70f0Sopenharmony_ci dst[2] = sample >> 16; 415d5ac70f0Sopenharmony_ci if (!--size) 416d5ac70f0Sopenharmony_ci return; 417d5ac70f0Sopenharmony_ci dst += dst_step; 418d5ac70f0Sopenharmony_ci src += src_step; 419d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 420d5ac70f0Sopenharmony_ci } 421d5ac70f0Sopenharmony_ci} 422d5ac70f0Sopenharmony_ci 423d5ac70f0Sopenharmony_cistatic void generic_remix_areas_24(unsigned int size, 424d5ac70f0Sopenharmony_ci volatile unsigned char *dst, 425d5ac70f0Sopenharmony_ci unsigned char *src, 426d5ac70f0Sopenharmony_ci volatile signed int *sum, 427d5ac70f0Sopenharmony_ci size_t dst_step, 428d5ac70f0Sopenharmony_ci size_t src_step, 429d5ac70f0Sopenharmony_ci size_t sum_step) 430d5ac70f0Sopenharmony_ci{ 431d5ac70f0Sopenharmony_ci register signed int sample; 432d5ac70f0Sopenharmony_ci 433d5ac70f0Sopenharmony_ci for (;;) { 434d5ac70f0Sopenharmony_ci sample = src[0] | (src[1] << 8) | (((signed char *)src)[2] << 16); 435d5ac70f0Sopenharmony_ci if (!(dst[0] | dst[1] | dst[2])) { 436d5ac70f0Sopenharmony_ci sample = -sample; 437d5ac70f0Sopenharmony_ci *sum = sample; 438d5ac70f0Sopenharmony_ci } else { 439d5ac70f0Sopenharmony_ci *sum = sample = *sum - sample; 440d5ac70f0Sopenharmony_ci if (sample > 0x7fffff) 441d5ac70f0Sopenharmony_ci sample = 0x7fffff; 442d5ac70f0Sopenharmony_ci else if (sample < -0x800000) 443d5ac70f0Sopenharmony_ci sample = -0x800000; 444d5ac70f0Sopenharmony_ci } 445d5ac70f0Sopenharmony_ci dst[0] = sample; 446d5ac70f0Sopenharmony_ci dst[1] = sample >> 8; 447d5ac70f0Sopenharmony_ci dst[2] = sample >> 16; 448d5ac70f0Sopenharmony_ci if (!--size) 449d5ac70f0Sopenharmony_ci return; 450d5ac70f0Sopenharmony_ci dst += dst_step; 451d5ac70f0Sopenharmony_ci src += src_step; 452d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 453d5ac70f0Sopenharmony_ci } 454d5ac70f0Sopenharmony_ci} 455d5ac70f0Sopenharmony_ci 456d5ac70f0Sopenharmony_cistatic void generic_mix_areas_u8(unsigned int size, 457d5ac70f0Sopenharmony_ci volatile unsigned char *dst, 458d5ac70f0Sopenharmony_ci unsigned char *src, 459d5ac70f0Sopenharmony_ci volatile signed int *sum, 460d5ac70f0Sopenharmony_ci size_t dst_step, 461d5ac70f0Sopenharmony_ci size_t src_step, 462d5ac70f0Sopenharmony_ci size_t sum_step) 463d5ac70f0Sopenharmony_ci{ 464d5ac70f0Sopenharmony_ci for (;;) { 465d5ac70f0Sopenharmony_ci register int sample = *src - 0x80; 466d5ac70f0Sopenharmony_ci if (*dst == 0x80) { 467d5ac70f0Sopenharmony_ci *sum = sample; 468d5ac70f0Sopenharmony_ci } else { 469d5ac70f0Sopenharmony_ci sample += *sum; 470d5ac70f0Sopenharmony_ci *sum = sample; 471d5ac70f0Sopenharmony_ci if (sample > 0x7f) 472d5ac70f0Sopenharmony_ci sample = 0x7f; 473d5ac70f0Sopenharmony_ci else if (sample < -0x80) 474d5ac70f0Sopenharmony_ci sample = -0x80; 475d5ac70f0Sopenharmony_ci } 476d5ac70f0Sopenharmony_ci *dst = sample + 0x80; 477d5ac70f0Sopenharmony_ci if (!--size) 478d5ac70f0Sopenharmony_ci return; 479d5ac70f0Sopenharmony_ci dst += dst_step; 480d5ac70f0Sopenharmony_ci src += src_step; 481d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 482d5ac70f0Sopenharmony_ci } 483d5ac70f0Sopenharmony_ci} 484d5ac70f0Sopenharmony_ci 485d5ac70f0Sopenharmony_cistatic void generic_remix_areas_u8(unsigned int size, 486d5ac70f0Sopenharmony_ci volatile unsigned char *dst, 487d5ac70f0Sopenharmony_ci unsigned char *src, 488d5ac70f0Sopenharmony_ci volatile signed int *sum, 489d5ac70f0Sopenharmony_ci size_t dst_step, 490d5ac70f0Sopenharmony_ci size_t src_step, 491d5ac70f0Sopenharmony_ci size_t sum_step) 492d5ac70f0Sopenharmony_ci{ 493d5ac70f0Sopenharmony_ci for (;;) { 494d5ac70f0Sopenharmony_ci register int sample = *src - 0x80; 495d5ac70f0Sopenharmony_ci if (*dst == 0x80) { 496d5ac70f0Sopenharmony_ci sample = -sample; 497d5ac70f0Sopenharmony_ci *sum = sample; 498d5ac70f0Sopenharmony_ci } else { 499d5ac70f0Sopenharmony_ci *sum = sample = *sum - sample; 500d5ac70f0Sopenharmony_ci if (sample > 0x7f) 501d5ac70f0Sopenharmony_ci sample = 0x7f; 502d5ac70f0Sopenharmony_ci else if (sample < -0x80) 503d5ac70f0Sopenharmony_ci sample = -0x80; 504d5ac70f0Sopenharmony_ci } 505d5ac70f0Sopenharmony_ci *dst = sample + 0x80; 506d5ac70f0Sopenharmony_ci if (!--size) 507d5ac70f0Sopenharmony_ci return; 508d5ac70f0Sopenharmony_ci dst += dst_step; 509d5ac70f0Sopenharmony_ci src += src_step; 510d5ac70f0Sopenharmony_ci sum = (signed int *) ((char *)sum + sum_step); 511d5ac70f0Sopenharmony_ci } 512d5ac70f0Sopenharmony_ci} 513d5ac70f0Sopenharmony_ci 514d5ac70f0Sopenharmony_ci 515d5ac70f0Sopenharmony_cistatic void generic_mix_select_callbacks(snd_pcm_direct_t *dmix) 516d5ac70f0Sopenharmony_ci{ 517d5ac70f0Sopenharmony_ci if (snd_pcm_format_cpu_endian(dmix->shmptr->s.format)) { 518d5ac70f0Sopenharmony_ci dmix->u.dmix.mix_areas_16 = generic_mix_areas_16_native; 519d5ac70f0Sopenharmony_ci dmix->u.dmix.mix_areas_32 = generic_mix_areas_32_native; 520d5ac70f0Sopenharmony_ci dmix->u.dmix.remix_areas_16 = generic_remix_areas_16_native; 521d5ac70f0Sopenharmony_ci dmix->u.dmix.remix_areas_32 = generic_remix_areas_32_native; 522d5ac70f0Sopenharmony_ci } else { 523d5ac70f0Sopenharmony_ci dmix->u.dmix.mix_areas_16 = generic_mix_areas_16_swap; 524d5ac70f0Sopenharmony_ci dmix->u.dmix.mix_areas_32 = generic_mix_areas_32_swap; 525d5ac70f0Sopenharmony_ci dmix->u.dmix.remix_areas_16 = generic_remix_areas_16_swap; 526d5ac70f0Sopenharmony_ci dmix->u.dmix.remix_areas_32 = generic_remix_areas_32_swap; 527d5ac70f0Sopenharmony_ci } 528d5ac70f0Sopenharmony_ci dmix->u.dmix.mix_areas_24 = generic_mix_areas_24; 529d5ac70f0Sopenharmony_ci dmix->u.dmix.mix_areas_u8 = generic_mix_areas_u8; 530d5ac70f0Sopenharmony_ci dmix->u.dmix.remix_areas_24 = generic_remix_areas_24; 531d5ac70f0Sopenharmony_ci dmix->u.dmix.remix_areas_u8 = generic_remix_areas_u8; 532d5ac70f0Sopenharmony_ci dmix->u.dmix.use_sem = 1; 533d5ac70f0Sopenharmony_ci} 534d5ac70f0Sopenharmony_ci 535d5ac70f0Sopenharmony_ci#endif 536