i386/x86_64 alsa-lib may need to handle big-endian formats, e.g.
when running via qemu on PPC. The generic dmix code already has
both endian support, so let's use it as fallback.
* FIXME: optimize it for different architectures
*/
+#include "pcm_dmix_generic.c"
#if defined(__i386__)
#include "pcm_dmix_i386.c"
#elif defined(__x86_64__)
#include "pcm_dmix_x86_64.c"
#else
-#include "pcm_dmix_generic.c"
+#define mix_select_callbacks(x) generic_mix_select_callbacks(x)
+#define dmix_supported_format generic_dmix_supported_format
#endif
static void mix_areas(snd_pcm_direct_t *dmix,
#else
/* non-concurrent version, supporting both endians */
-static unsigned long long dmix_supported_format =
- (1ULL << SND_PCM_FORMAT_S16_LE) | (1ULL << SND_PCM_FORMAT_S32_LE) |
- (1ULL << SND_PCM_FORMAT_S16_BE) | (1ULL << SND_PCM_FORMAT_S32_BE) |
- (1ULL << SND_PCM_FORMAT_S24_3LE);
+#define generic_dmix_supported_format \
+ ((1ULL << SND_PCM_FORMAT_S16_LE) | (1ULL << SND_PCM_FORMAT_S32_LE) |\
+ (1ULL << SND_PCM_FORMAT_S16_BE) | (1ULL << SND_PCM_FORMAT_S32_BE) |\
+ (1ULL << SND_PCM_FORMAT_S24_3LE))
#include <byteswap.h>
-static void mix_areas1_native(unsigned int size,
+static void generic_mix_areas1_native(unsigned int size,
volatile signed short *dst, signed short *src,
volatile signed int *sum, size_t dst_step,
size_t src_step, size_t sum_step)
}
}
-static void mix_areas2_native(unsigned int size,
+static void generic_mix_areas2_native(unsigned int size,
volatile signed int *dst, signed int *src,
volatile signed int *sum, size_t dst_step,
size_t src_step, size_t sum_step)
}
}
-static void mix_areas1_swap(unsigned int size,
+static void generic_mix_areas1_swap(unsigned int size,
volatile signed short *dst, signed short *src,
volatile signed int *sum, size_t dst_step,
size_t src_step, size_t sum_step)
}
}
-static void mix_areas2_swap(unsigned int size,
+static void generic_mix_areas2_swap(unsigned int size,
volatile signed int *dst, signed int *src,
volatile signed int *sum, size_t dst_step,
size_t src_step, size_t sum_step)
}
/* always little endian */
-static void mix_areas3(unsigned int size,
+static void generic_mix_areas3(unsigned int size,
volatile unsigned char *dst, unsigned char *src,
volatile signed int *sum, size_t dst_step,
size_t src_step, size_t sum_step)
}
-static void mix_select_callbacks(snd_pcm_direct_t *dmix)
+static void generic_mix_select_callbacks(snd_pcm_direct_t *dmix)
{
if (snd_pcm_format_cpu_endian(dmix->shmptr->s.format)) {
- dmix->u.dmix.mix_areas1 = mix_areas1_native;
- dmix->u.dmix.mix_areas2 = mix_areas2_native;
+ dmix->u.dmix.mix_areas1 = generic_mix_areas1_native;
+ dmix->u.dmix.mix_areas2 = generic_mix_areas2_native;
} else {
- dmix->u.dmix.mix_areas1 = mix_areas1_swap;
- dmix->u.dmix.mix_areas2 = mix_areas2_swap;
+ dmix->u.dmix.mix_areas1 = generic_mix_areas1_swap;
+ dmix->u.dmix.mix_areas2 = generic_mix_areas2_swap;
}
- dmix->u.dmix.mix_areas3 = mix_areas3;
+ dmix->u.dmix.mix_areas3 = generic_mix_areas3;
}
#endif
#undef MIX_AREAS3_CMOV
#undef LOCK_PREFIX
-static unsigned long long dmix_supported_format =
- (1ULL << SND_PCM_FORMAT_S16_LE) |
- (1ULL << SND_PCM_FORMAT_S32_LE) |
- (1ULL << SND_PCM_FORMAT_S24_3LE);
+#define i386_dmix_supported_format \
+ ((1ULL << SND_PCM_FORMAT_S16_LE) |\
+ (1ULL << SND_PCM_FORMAT_S32_LE) |\
+ (1ULL << SND_PCM_FORMAT_S24_3LE))
+
+#define dmix_supported_format \
+ (i386_dmix_supported_format | generic_dmix_supported_format)
static void mix_select_callbacks(snd_pcm_direct_t *dmix)
{
- FILE *in;
- char line[255];
- int smp = 0, mmx = 0, cmov = 0;
+ static int smp = 0, mmx = 0, cmov = 0;
+
+ if (!((1ULL<< dmix->shmptr->s.format) & i386_dmix_supported_format)) {
+ generic_mix_select_callbacks(dmix);
+ return;
+ }
+
+ if (!smp) {
+ FILE *in;
+ char line[255];
- /* try to determine the capabilities of the CPU */
- in = fopen("/proc/cpuinfo", "r");
- if (in) {
- while (!feof(in)) {
- fgets(line, sizeof(line), in);
- if (!strncmp(line, "processor", 9))
- smp++;
- else if (!strncmp(line, "flags", 5)) {
- if (strstr(line, " mmx"))
- mmx = 1;
- if (strstr(line, " cmov"))
- cmov = 1;
+ /* try to determine the capabilities of the CPU */
+ in = fopen("/proc/cpuinfo", "r");
+ if (in) {
+ while (!feof(in)) {
+ fgets(line, sizeof(line), in);
+ if (!strncmp(line, "processor", 9))
+ smp++;
+ else if (!strncmp(line, "flags", 5)) {
+ if (strstr(line, " mmx"))
+ mmx = 1;
+ if (strstr(line, " cmov"))
+ cmov = 1;
+ }
}
+ fclose(in);
}
- fclose(in);
}
+
if (mmx) {
dmix->u.dmix.mix_areas1 = smp > 1 ? mix_areas1_smp_mmx : mix_areas1_mmx;
} else {
#undef MIX_AREAS3
#undef LOCK_PREFIX
-static unsigned long long dmix_supported_format =
- (1ULL << SND_PCM_FORMAT_S16_LE) |
- (1ULL << SND_PCM_FORMAT_S32_LE) |
- (1ULL << SND_PCM_FORMAT_S24_3LE);
+#define x86_64_dmix_supported_format \
+ ((1ULL << SND_PCM_FORMAT_S16_LE) |\
+ (1ULL << SND_PCM_FORMAT_S32_LE) |\
+ (1ULL << SND_PCM_FORMAT_S24_3LE))
+
+#define dmix_supported_format \
+ (x86_64_dmix_supported_format | generic_dmix_supported_format)
static void mix_select_callbacks(snd_pcm_direct_t *dmix)
{
- FILE *in;
- char line[255];
- int smp = 0;
+ static int smp = 0;
- /* try to determine, if we have SMP */
- in = fopen("/proc/cpuinfo", "r");
- if (in) {
- while (!feof(in)) {
- fgets(line, sizeof(line), in);
- if (!strncmp(line, "processor", 9))
- smp++;
+ if (!((1ULL<< dmix->shmptr->s.format) & x86_64_dmix_supported_format)) {
+ generic_mix_select_callbacks(dmix);
+ return;
+ }
+
+ if (!smp) {
+ FILE *in;
+ char line[255];
+
+ /* try to determine, if we have SMP */
+ in = fopen("/proc/cpuinfo", "r");
+ if (in) {
+ while (!feof(in)) {
+ fgets(line, sizeof(line), in);
+ if (!strncmp(line, "processor", 9))
+ smp++;
+ }
+ fclose(in);
}
- fclose(in);
}
// printf("SMP: %i\n", smp);
dmix->u.dmix.mix_areas1 = smp > 1 ? mix_areas1_smp : mix_areas1;