]> code.delx.au - pulseaudio/blob - src/polyp/channelmap.c
Reorganised the source tree. We now have src/ with a couple of subdirs:
[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 switch (channels) {
76 case 1:
77 m->map[0] = PA_CHANNEL_POSITION_MONO;
78 return m;
79
80 case 8:
81 m->map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
82 m->map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
83 /* Fall through */
84
85 case 6:
86 m->map[5] = PA_CHANNEL_POSITION_LFE;
87 /* Fall through */
88
89 case 5:
90 m->map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
91 /* Fall through */
92
93 case 4:
94 m->map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
95 m->map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
96 /* Fall through */
97
98 case 2:
99 m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
100 m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
101 return m;
102
103 default:
104 return NULL;
105 }
106 }
107
108 const char* pa_channel_position_to_string(pa_channel_position_t pos) {
109
110 const char *const table[] = {
111 [PA_CHANNEL_POSITION_MONO] = "mono",
112
113 [PA_CHANNEL_POSITION_FRONT_CENTER] = "front-center",
114 [PA_CHANNEL_POSITION_FRONT_LEFT] = "front-left",
115 [PA_CHANNEL_POSITION_FRONT_RIGHT] = "front-right",
116
117 [PA_CHANNEL_POSITION_REAR_CENTER] = "rear-center",
118 [PA_CHANNEL_POSITION_REAR_LEFT] = "rear-left",
119 [PA_CHANNEL_POSITION_REAR_RIGHT] = "rear-right",
120
121 [PA_CHANNEL_POSITION_LFE] = "lfe",
122
123 [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = "front-left-of-center",
124 [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = "front-right-of-center",
125
126 [PA_CHANNEL_POSITION_SIDE_LEFT] = "side-left",
127 [PA_CHANNEL_POSITION_SIDE_RIGHT] = "side-right",
128
129 [PA_CHANNEL_POSITION_AUX1] = "aux1",
130 [PA_CHANNEL_POSITION_AUX2] = "aux2",
131 [PA_CHANNEL_POSITION_AUX3] = "aux3",
132 [PA_CHANNEL_POSITION_AUX4] = "aux4",
133 [PA_CHANNEL_POSITION_AUX5] = "aux5",
134 [PA_CHANNEL_POSITION_AUX6] = "aux6",
135 [PA_CHANNEL_POSITION_AUX7] = "aux7",
136 [PA_CHANNEL_POSITION_AUX8] = "aux8",
137 [PA_CHANNEL_POSITION_AUX9] = "aux9",
138 [PA_CHANNEL_POSITION_AUX10] = "aux10",
139 [PA_CHANNEL_POSITION_AUX11] = "aux11",
140 [PA_CHANNEL_POSITION_AUX12] = "aux12"
141 };
142
143 if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX)
144 return NULL;
145
146 return table[pos];
147 }
148
149 int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) {
150 unsigned c;
151
152 assert(a);
153 assert(b);
154
155 if (a->channels != b->channels)
156 return 0;
157
158 for (c = 0; c < a->channels; c++)
159 if (a->map[c] != b->map[c])
160 return 0;
161
162 return 1;
163 }
164
165 char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) {
166 unsigned channel;
167 int first = 1;
168 char *e;
169
170 assert(s);
171 assert(l > 0);
172 assert(map);
173
174 *(e = s) = 0;
175
176 for (channel = 0; channel < map->channels && l > 1; channel++) {
177 l -= snprintf(e, l, "%s%u:%s",
178 first ? "" : " ",
179 channel,
180 pa_channel_position_to_string(map->map[channel]));
181
182 e = strchr(e, 0);
183 first = 0;
184 }
185
186 return s;
187 }
188
189 int pa_channel_map_valid(const pa_channel_map *map) {
190 unsigned c;
191
192 assert(map);
193
194 if (map->channels <= 0 || map->channels > PA_CHANNELS_MAX)
195 return 0;
196
197 for (c = 0; c < map->channels; c++)
198 if (map->map[c] < 0 ||map->map[c] >= PA_CHANNEL_POSITION_MAX)
199 return 0;
200
201 return 1;
202 }