Home | History | Annotate | Download | only in pcm
      1 /*
      2  * optimized mixing code for i386
      3  */
      4 
      5 #define MIX_AREAS_16 mix_areas_16
      6 #define MIX_AREAS_16_MMX mix_areas_16_mmx
      7 #define MIX_AREAS_32 mix_areas_32
      8 #define MIX_AREAS_24 mix_areas_24
      9 #define MIX_AREAS_24_CMOV mix_areas_24_cmov
     10 #define LOCK_PREFIX ""
     11 #define XADD "addl"
     12 #define XSUB "subl"
     13 #include "pcm_dmix_i386.h"
     14 #undef MIX_AREAS_16
     15 #undef MIX_AREAS_16_MMX
     16 #undef MIX_AREAS_32
     17 #undef MIX_AREAS_24
     18 #undef MIX_AREAS_24_CMOV
     19 #undef LOCK_PREFIX
     20 #undef XADD
     21 #undef XSUB
     22 
     23 #define MIX_AREAS_16 remix_areas_16
     24 #define MIX_AREAS_16_MMX remix_areas_16_mmx
     25 #define MIX_AREAS_32 remix_areas_32
     26 #define MIX_AREAS_24 remix_areas_24
     27 #define MIX_AREAS_24_CMOV remix_areas_24_cmov
     28 #define LOCK_PREFIX ""
     29 #define XADD "subl"
     30 #define XSUB "addl"
     31 #include "pcm_dmix_i386.h"
     32 #undef MIX_AREAS_16
     33 #undef MIX_AREAS_16_MMX
     34 #undef MIX_AREAS_32
     35 #undef MIX_AREAS_24
     36 #undef MIX_AREAS_24_CMOV
     37 #undef LOCK_PREFIX
     38 #undef XADD
     39 #undef XSUB
     40 
     41 #define MIX_AREAS_16 mix_areas_16_smp
     42 #define MIX_AREAS_16_MMX mix_areas_16_smp_mmx
     43 #define MIX_AREAS_32 mix_areas_32_smp
     44 #define MIX_AREAS_24 mix_areas_24_smp
     45 #define MIX_AREAS_24_CMOV mix_areas_24_smp_cmov
     46 #define LOCK_PREFIX "lock ; "
     47 #define XADD "addl"
     48 #define XSUB "subl"
     49 #include "pcm_dmix_i386.h"
     50 #undef MIX_AREAS_16
     51 #undef MIX_AREAS_16_MMX
     52 #undef MIX_AREAS_32
     53 #undef MIX_AREAS_24
     54 #undef MIX_AREAS_24_CMOV
     55 #undef LOCK_PREFIX
     56 #undef XADD
     57 #undef XSUB
     58 
     59 #define MIX_AREAS_16 remix_areas_16_smp
     60 #define MIX_AREAS_16_MMX remix_areas_16_smp_mmx
     61 #define MIX_AREAS_32 remix_areas_32_smp
     62 #define MIX_AREAS_24 remix_areas_24_smp
     63 #define MIX_AREAS_24_CMOV remix_areas_24_smp_cmov
     64 #define LOCK_PREFIX "lock ; "
     65 #define XADD "subl"
     66 #define XSUB "addl"
     67 #include "pcm_dmix_i386.h"
     68 #undef MIX_AREAS_16
     69 #undef MIX_AREAS_16_MMX
     70 #undef MIX_AREAS_32
     71 #undef MIX_AREAS_24
     72 #undef MIX_AREAS_24_CMOV
     73 #undef LOCK_PREFIX
     74 #undef XADD
     75 #undef XSUB
     76 
     77 #define i386_dmix_supported_format \
     78 	((1ULL << SND_PCM_FORMAT_S16_LE) |\
     79 	 (1ULL << SND_PCM_FORMAT_S32_LE) |\
     80 	 (1ULL << SND_PCM_FORMAT_S24_3LE))
     81 
     82 #define dmix_supported_format \
     83 	(i386_dmix_supported_format | generic_dmix_supported_format)
     84 
     85 static void mix_select_callbacks(snd_pcm_direct_t *dmix)
     86 {
     87 	static int smp = 0, mmx = 0, cmov = 0;
     88 
     89 	if (!((1ULL<< dmix->shmptr->s.format) & i386_dmix_supported_format)) {
     90 		generic_mix_select_callbacks(dmix);
     91 		return;
     92 	}
     93 
     94 	if (!smp) {
     95 		FILE *in;
     96 		char line[255];
     97 
     98 		/* try to determine the capabilities of the CPU */
     99 		in = fopen("/proc/cpuinfo", "r");
    100 		if (in) {
    101 			while (!feof(in)) {
    102 				fgets(line, sizeof(line), in);
    103 				if (!strncmp(line, "processor", 9))
    104 					smp++;
    105 				else if (!strncmp(line, "flags", 5)) {
    106 					if (strstr(line, " mmx"))
    107 						mmx = 1;
    108 					if (strstr(line, " cmov"))
    109 						cmov = 1;
    110 				}
    111 			}
    112 			fclose(in);
    113 		}
    114 	}
    115 
    116 	if (mmx) {
    117 		dmix->u.dmix.mix_areas_16 = smp > 1 ? mix_areas_16_smp_mmx : mix_areas_16_mmx;
    118 		dmix->u.dmix.remix_areas_16 = smp > 1 ? remix_areas_16_smp_mmx : remix_areas_16_mmx;
    119 	} else {
    120 		dmix->u.dmix.mix_areas_16 = smp > 1 ? mix_areas_16_smp : mix_areas_16;
    121 		dmix->u.dmix.remix_areas_16 = smp > 1 ? remix_areas_16_smp : remix_areas_16;
    122 	}
    123 	dmix->u.dmix.mix_areas_32 = smp > 1 ? mix_areas_32_smp : mix_areas_32;
    124 	dmix->u.dmix.remix_areas_32 = smp > 1 ? remix_areas_32_smp : remix_areas_32;
    125 	if (cmov) {
    126 		dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp_cmov : mix_areas_24_cmov;
    127 		dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp_cmov : remix_areas_24_cmov;
    128 	} else {
    129 		dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp: mix_areas_24;
    130 		dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp: remix_areas_24;
    131 	}
    132 }
    133