]> code.delx.au - pulseaudio/blob - src/polyp/channelmap.c
Clarify behaviour of deferred events.
[pulseaudio] / src / polyp / channelmap.c
1 /* $Id$ */
2
3 /***
4 This file is part of polypaudio.
5
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
10
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <assert.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include "channelmap.h"
32
33 pa_channel_map* pa_channel_map_init(pa_channel_map *m) {
34 unsigned c;
35 assert(m);
36
37 m->channels = 0;
38
39 for (c = 0; c < PA_CHANNELS_MAX; c++)
40 m->map[c] = PA_CHANNEL_POSITION_INVALID;
41
42 return m;
43 }
44
45 pa_channel_map* pa_channel_map_init_mono(pa_channel_map *m) {
46 assert(m);
47
48 pa_channel_map_init(m);
49
50 m->channels = 1;
51 m->map[0] = PA_CHANNEL_POSITION_MONO;
52 return m;
53 }
54
55 pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m) {
56 assert(m);
57
58 pa_channel_map_init(m);
59
60 m->channels = 2;
61 m->map[0] = PA_CHANNEL_POSITION_LEFT;
62 m->map[1] = PA_CHANNEL_POSITION_RIGHT;
63 return m;
64 }
65
66 pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels) {
67 assert(m);
68 assert(channels > 0);
69 assert(channels <= PA_CHANNELS_MAX);
70
71 pa_channel_map_init(m);
72
73 m->channels = channels;
74
75 /* This is somewhat compatible with RFC3551 */
76
77 switch (channels) {
78 case 1:
79 m->map[0] = PA_CHANNEL_POSITION_MONO;
80 return m;
81
82 case 6:
83 m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
84 m->map[1] = PA_CHANNEL_POSITION_SIDE_LEFT;
85 m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
86 m->map[3] = PA_CHANNEL_POSITION_FRONT_RIGHT;
87 m->map[4] = PA_CHANNEL_POSITION_SIDE_RIGHT;
88 m->map[5] = PA_CHANNEL_POSITION_LFE;
89 return m;
90
91 case 5:
92 m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
93 m->map[3] = PA_CHANNEL_POSITION_REAR_LEFT;
94 m->map[4] = PA_CHANNEL_POSITION_REAR_RIGHT;
95 /* Fall through */
96
97 case 2:
98 m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
99 m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
100 return m;
101
102 case 3:
103 m->map[0] = PA_CHANNEL_POSITION_LEFT;
104 m->map[1] = PA_CHANNEL_POSITION_RIGHT;
105 m->map[2] = PA_CHANNEL_POSITION_CENTER;
106 return m;
107
108 case 4:
109 m->map[0] = PA_CHANNEL_POSITION_LEFT;
110 m->map[1] = PA_CHANNEL_POSITION_CENTER;
111 m->map[2] = PA_CHANNEL_POSITION_RIGHT;
112 m->map[3] = PA_CHANNEL_POSITION_LFE;
113 return m;
114
115 default:
116 return NULL;
117 }
118 }
119
120 const char* pa_channel_position_to_string(pa_channel_position_t pos) {
121
122 const char *const table[] = {
123 [PA_CHANNEL_POSITION_MONO] = "mono",
124
125 [PA_CHANNEL_POSITION_FRONT_CENTER] = "front-center",
126 [PA_CHANNEL_POSITION_FRONT_LEFT] = "front-left",
127 [PA_CHANNEL_POSITION_FRONT_RIGHT] = "front-right",
128
129 [PA_CHANNEL_POSITION_REAR_CENTER] = "rear-center",
130 [PA_CHANNEL_POSITION_REAR_LEFT] = "rear-left",
131 [PA_CHANNEL_POSITION_REAR_RIGHT] = "rear-right",
132
133 [PA_CHANNEL_POSITION_LFE] = "lfe",
134
135 [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = "front-left-of-center",
136 [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = "front-right-of-center",
137
138 [PA_CHANNEL_POSITION_SIDE_LEFT] = "side-left",
139 [PA_CHANNEL_POSITION_SIDE_RIGHT] = "side-right",
140
141 [PA_CHANNEL_POSITION_AUX1] = "aux1",
142 [PA_CHANNEL_POSITION_AUX2] = "aux2",
143 [PA_CHANNEL_POSITION_AUX3] = "aux3",
144 [PA_CHANNEL_POSITION_AUX4] = "aux4",
145 [PA_CHANNEL_POSITION_AUX5] = "aux5",
146 [PA_CHANNEL_POSITION_AUX6] = "aux6",
147 [PA_CHANNEL_POSITION_AUX7] = "aux7",
148 [PA_CHANNEL_POSITION_AUX8] = "aux8",
149 [PA_CHANNEL_POSITION_AUX9] = "aux9",
150 [PA_CHANNEL_POSITION_AUX10] = "aux10",
151 [PA_CHANNEL_POSITION_AUX11] = "aux11",
152 [PA_CHANNEL_POSITION_AUX12] = "aux12"
153 };
154
155 if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX)
156 return NULL;
157
158 return table[pos];
159 }
160
161 int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) {
162 unsigned c;
163
164 assert(a);
165 assert(b);
166
167 if (a->channels != b->channels)
168 return 0;
169
170 for (c = 0; c < a->channels; c++)
171 if (a->map[c] != b->map[c])
172 return 0;
173
174 return 1;
175 }
176
177 char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) {
178 unsigned channel;
179 int first = 1;
180 char *e;
181
182 assert(s);
183 assert(l > 0);
184 assert(map);
185
186 *(e = s) = 0;
187
188 for (channel = 0; channel < map->channels && l > 1; channel++) {
189 l -= snprintf(e, l, "%s%u:%s",
190 first ? "" : " ",
191 channel,
192 pa_channel_position_to_string(map->map[channel]));
193
194 e = strchr(e, 0);
195 first = 0;
196 }
197
198 return s;
199 }
200
201 int pa_channel_map_valid(const pa_channel_map *map) {
202 unsigned c;
203
204 assert(map);
205
206 if (map->channels <= 0 || map->channels > PA_CHANNELS_MAX)
207 return 0;
208
209 for (c = 0; c < map->channels; c++)
210 if (map->map[c] < 0 ||map->map[c] >= PA_CHANNEL_POSITION_MAX)
211 return 0;
212
213 return 1;
214 }