summaryrefslogtreecommitdiff
path: root/src/pcm/pcm_dmix_i386.c
blob: 82a91c5c2897ca3eebd4c66c10806f9328884d94 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * optimized mixing code for i386
 */

#define MIX_AREAS_16 mix_areas_16
#define MIX_AREAS_16_MMX mix_areas_16_mmx
#define MIX_AREAS_32 mix_areas_32
#define MIX_AREAS_24 mix_areas_24
#define MIX_AREAS_24_CMOV mix_areas_24_cmov
#define LOCK_PREFIX ""
#define XADD "addl"
#define XSUB "subl"
#include "pcm_dmix_i386.h"
#undef MIX_AREAS_16
#undef MIX_AREAS_16_MMX
#undef MIX_AREAS_32
#undef MIX_AREAS_24
#undef MIX_AREAS_24_CMOV
#undef LOCK_PREFIX
#undef XADD
#undef XSUB

#define MIX_AREAS_16 remix_areas_16
#define MIX_AREAS_16_MMX remix_areas_16_mmx
#define MIX_AREAS_32 remix_areas_32
#define MIX_AREAS_24 remix_areas_24
#define MIX_AREAS_24_CMOV remix_areas_24_cmov
#define LOCK_PREFIX ""
#define XADD "subl"
#define XSUB "addl"
#include "pcm_dmix_i386.h"
#undef MIX_AREAS_16
#undef MIX_AREAS_16_MMX
#undef MIX_AREAS_32
#undef MIX_AREAS_24
#undef MIX_AREAS_24_CMOV
#undef LOCK_PREFIX
#undef XADD
#undef XSUB

#define MIX_AREAS_16 mix_areas_16_smp
#define MIX_AREAS_16_MMX mix_areas_16_smp_mmx
#define MIX_AREAS_32 mix_areas_32_smp
#define MIX_AREAS_24 mix_areas_24_smp
#define MIX_AREAS_24_CMOV mix_areas_24_smp_cmov
#define LOCK_PREFIX "lock ; "
#define XADD "addl"
#define XSUB "subl"
#include "pcm_dmix_i386.h"
#undef MIX_AREAS_16
#undef MIX_AREAS_16_MMX
#undef MIX_AREAS_32
#undef MIX_AREAS_24
#undef MIX_AREAS_24_CMOV
#undef LOCK_PREFIX
#undef XADD
#undef XSUB
 
#define MIX_AREAS_16 remix_areas_16_smp
#define MIX_AREAS_16_MMX remix_areas_16_smp_mmx
#define MIX_AREAS_32 remix_areas_32_smp
#define MIX_AREAS_24 remix_areas_24_smp
#define MIX_AREAS_24_CMOV remix_areas_24_smp_cmov
#define LOCK_PREFIX "lock ; "
#define XADD "subl"
#define XSUB "addl"
#include "pcm_dmix_i386.h"
#undef MIX_AREAS_16
#undef MIX_AREAS_16_MMX
#undef MIX_AREAS_32
#undef MIX_AREAS_24
#undef MIX_AREAS_24_CMOV
#undef LOCK_PREFIX
#undef XADD
#undef XSUB
 
#define i386_dmix_supported_format \
	((1ULL << SND_PCM_FORMAT_S16_LE) |\
	 (1ULL << SND_PCM_FORMAT_S32_LE) |\
	 (1ULL << SND_PCM_FORMAT_S24_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)
{
	static int smp = 0, mmx = 0, cmov = 0;

	if (!dmix->direct_memory_access) {
		generic_mix_select_callbacks(dmix);
		return;
	}

	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;
				}
			}
			fclose(in);
		}
	}
	
	if (mmx) {
		dmix->u.dmix.mix_areas_16 = smp > 1 ? mix_areas_16_smp_mmx : mix_areas_16_mmx;
		dmix->u.dmix.remix_areas_16 = smp > 1 ? remix_areas_16_smp_mmx : remix_areas_16_mmx;
	} else {
		dmix->u.dmix.mix_areas_16 = smp > 1 ? mix_areas_16_smp : mix_areas_16;
		dmix->u.dmix.remix_areas_16 = smp > 1 ? remix_areas_16_smp : remix_areas_16;
	}
	dmix->u.dmix.mix_areas_32 = smp > 1 ? mix_areas_32_smp : mix_areas_32;
	dmix->u.dmix.remix_areas_32 = smp > 1 ? remix_areas_32_smp : remix_areas_32;
	if (cmov) {
		dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp_cmov : mix_areas_24_cmov;
		dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp_cmov : remix_areas_24_cmov;
	} else {
		dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp: mix_areas_24;
		dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp: remix_areas_24;
	}
	dmix->u.dmix.use_sem = 0;
}