]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Add support of little-endian on i386/x86_64 dmix
authorTakashi Iwai <tiwai@suse.de>
Tue, 3 Jul 2007 17:52:33 +0000 (19:52 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 3 Jul 2007 17:52:33 +0000 (19:52 +0200)
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
src/pcm/pcm_dmix_generic.c
src/pcm/pcm_dmix_i386.c
src/pcm/pcm_dmix_x86_64.c

index c18bc6a83b196c45e0308d1f26e06760c187db28..9eed9e7ec43607a68b46b360e01823554b6b8218 100644 (file)
@@ -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,
index 3f39ba4d5dc95feaf19d03d9f008eb7a00a804c5..d6cb0eb1f09b2d4e91ba5ca4081047cc0653a5e4 100644 (file)
@@ -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 <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)
@@ -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
index 3ea206c633ba54c812e9087285dcff8801de2881..09d19bbbc19ad8faedf50a24758fec559a093b00 100644 (file)
 #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 {
index 7632388c51d0aa0190f60176f34e7e1043d703e7..343fee86e58dd246d19c1305a0c54730fa656cfa 100644 (file)
 #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;