1 /*
2  * optimized mixing code for x86-64
3  */
4 
5 #define MIX_AREAS_16 mix_areas_16
6 #define MIX_AREAS_32 mix_areas_32
7 #define MIX_AREAS_24 mix_areas_24
8 #define LOCK_PREFIX ""
9 #define XADD "addl"
10 #define XSUB "subl"
11 #include "pcm_dmix_x86_64.h"
12 #undef MIX_AREAS_16
13 #undef MIX_AREAS_32
14 #undef MIX_AREAS_24
15 #undef LOCK_PREFIX
16 #undef XADD
17 #undef XSUB
18 
19 #define MIX_AREAS_16 remix_areas_16
20 #define MIX_AREAS_32 remix_areas_32
21 #define MIX_AREAS_24 remix_areas_24
22 #define LOCK_PREFIX ""
23 #define XADD "subl"
24 #define XSUB "addl"
25 #include "pcm_dmix_x86_64.h"
26 #undef MIX_AREAS_16
27 #undef MIX_AREAS_32
28 #undef MIX_AREAS_24
29 #undef LOCK_PREFIX
30 #undef XADD
31 #undef XSUB
32 
33 #define MIX_AREAS_16 mix_areas_16_smp
34 #define MIX_AREAS_32 mix_areas_32_smp
35 #define MIX_AREAS_24 mix_areas_24_smp
36 #define LOCK_PREFIX "lock ; "
37 #define XADD "addl"
38 #define XSUB "subl"
39 #include "pcm_dmix_x86_64.h"
40 #undef MIX_AREAS_16
41 #undef MIX_AREAS_32
42 #undef MIX_AREAS_24
43 #undef LOCK_PREFIX
44 #undef XADD
45 #undef XSUB
46 
47 #define MIX_AREAS_16 remix_areas_16_smp
48 #define MIX_AREAS_32 remix_areas_32_smp
49 #define MIX_AREAS_24 remix_areas_24_smp
50 #define LOCK_PREFIX "lock ; "
51 #define XADD "subl"
52 #define XSUB "addl"
53 #include "pcm_dmix_x86_64.h"
54 #undef MIX_AREAS_16
55 #undef MIX_AREAS_32
56 #undef MIX_AREAS_24
57 #undef LOCK_PREFIX
58 #undef XADD
59 #undef XSUB
60 
61 #define x86_64_dmix_supported_format \
62 	((1ULL << SND_PCM_FORMAT_S16_LE) |\
63 	 (1ULL << SND_PCM_FORMAT_S32_LE) |\
64 	 (1ULL << SND_PCM_FORMAT_S24_3LE))
65 
66 #define dmix_supported_format \
67 	(x86_64_dmix_supported_format | generic_dmix_supported_format)
68 
mix_select_callbacks(snd_pcm_direct_t * dmix)69 static void mix_select_callbacks(snd_pcm_direct_t *dmix)
70 {
71 	static int smp = 0;
72 
73 	if (!dmix->direct_memory_access) {
74 		generic_mix_select_callbacks(dmix);
75 		return;
76 	}
77 
78 	if (!((1ULL<< dmix->shmptr->s.format) & x86_64_dmix_supported_format)) {
79 		generic_mix_select_callbacks(dmix);
80 		return;
81 	}
82 
83 	if (!smp) {
84 		FILE *in;
85 		char line[255];
86 
87 		/* try to determine, if we have SMP */
88 		in = fopen("/proc/cpuinfo", "r");
89 		if (in) {
90 			while (!feof(in)) {
91 				fgets(line, sizeof(line), in);
92 				if (!strncmp(line, "processor", 9))
93 					smp++;
94 			}
95 			fclose(in);
96 		}
97 	}
98 	// printf("SMP: %i\n", smp);
99 	dmix->u.dmix.mix_areas_16 = smp > 1 ? mix_areas_16_smp : mix_areas_16;
100 	dmix->u.dmix.remix_areas_16 = smp > 1 ? remix_areas_16_smp : remix_areas_16;
101 	dmix->u.dmix.mix_areas_32 = smp > 1 ? mix_areas_32_smp : mix_areas_32;
102 	dmix->u.dmix.remix_areas_32 = smp > 1 ? remix_areas_32_smp : remix_areas_32;
103 	dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp : mix_areas_24;
104 	dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp : remix_areas_24;
105 }
106