From 267d7c728196286726b47df45736eba18d78822a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 3 Jul 2007 19:52:33 +0200 Subject: [PATCH] Add support of little-endian on i386/x86_64 dmix 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. --- src/pcm/pcm_dmix.c | 4 ++- src/pcm/pcm_dmix_generic.c | 30 +++++++++++----------- src/pcm/pcm_dmix_i386.c | 52 +++++++++++++++++++++++--------------- src/pcm/pcm_dmix_x86_64.c | 41 +++++++++++++++++++----------- 4 files changed, 76 insertions(+), 51 deletions(-) diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c index c18bc6a8..9eed9e7e 100644 --- a/src/pcm/pcm_dmix.c +++ b/src/pcm/pcm_dmix.c @@ -139,12 +139,14 @@ static void dmix_server_free(snd_pcm_direct_t *dmix) * 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, diff --git a/src/pcm/pcm_dmix_generic.c b/src/pcm/pcm_dmix_generic.c index 3f39ba4d..d6cb0eb1 100644 --- a/src/pcm/pcm_dmix_generic.c +++ b/src/pcm/pcm_dmix_generic.c @@ -119,14 +119,14 @@ static void mix_select_callbacks(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 -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) @@ -155,7 +155,7 @@ static void mix_areas1_native(unsigned int size, } } -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) @@ -186,7 +186,7 @@ static void mix_areas2_native(unsigned int size, } } -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) @@ -215,7 +215,7 @@ static void mix_areas1_swap(unsigned int size, } } -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) @@ -247,7 +247,7 @@ static void mix_areas2_swap(unsigned int size, } /* 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) @@ -278,16 +278,16 @@ static void mix_areas3(unsigned int size, } -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 diff --git a/src/pcm/pcm_dmix_i386.c b/src/pcm/pcm_dmix_i386.c index 3ea206c6..09d19bbb 100644 --- a/src/pcm/pcm_dmix_i386.c +++ b/src/pcm/pcm_dmix_i386.c @@ -30,33 +30,45 @@ #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 { diff --git a/src/pcm/pcm_dmix_x86_64.c b/src/pcm/pcm_dmix_x86_64.c index 7632388c..343fee86 100644 --- a/src/pcm/pcm_dmix_x86_64.c +++ b/src/pcm/pcm_dmix_x86_64.c @@ -22,26 +22,37 @@ #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; -- 2.47.1