format: Add some properties and internal API
[platform/upstream/pulseaudio.git] / src / pulse / format.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2011 Intel Corporation
5   Copyright 2011 Collabora Multimedia
6   Copyright 2011 Arun Raghavan <arun.raghavan@collabora.co.uk>
7
8   PulseAudio is free software; you can redistribute it and/or modify
9   it under the terms of the GNU Lesser General Public License as published
10   by the Free Software Foundation; either version 2.1 of the License,
11   or (at your option) any later version.
12
13   PulseAudio is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with PulseAudio; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21   USA.
22 ***/
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <pulse/internal.h>
29 #include <pulse/xmalloc.h>
30
31 #include <pulsecore/core-util.h>
32 #include <pulsecore/macro.h>
33
34 #include "format.h"
35
36 pa_format_info* pa_format_info_new(void) {
37     pa_format_info *f = pa_xnew(pa_format_info, 1);
38
39     f->encoding = PA_ENCODING_INVALID;
40     f->plist = pa_proplist_new();
41
42     return f;
43 }
44
45 pa_format_info* pa_format_info_copy(const pa_format_info *src) {
46     pa_format_info *dest;
47
48     pa_assert(src);
49
50     dest = pa_xnew(pa_format_info, 1);
51
52     dest->encoding = src->encoding;
53
54     if (src->plist)
55         dest->plist = pa_proplist_copy(src->plist);
56     else
57         dest->plist = NULL;
58
59     return dest;
60 }
61
62 void pa_format_info_free(pa_format_info *f) {
63     pa_assert(f);
64
65     pa_proplist_free(f->plist);
66     pa_xfree(f);
67 }
68
69 int pa_format_info_valid(pa_format_info *f) {
70     return (f->encoding >= 0 && f->encoding < PA_ENCODING_MAX && f->plist != NULL);
71 }
72
73 pa_bool_t pa_format_info_is_compatible(pa_format_info *first, pa_format_info *second) {
74     const char *key;
75     void *state = NULL;
76
77     pa_assert(first);
78     pa_assert(second);
79
80     if (first->encoding != second->encoding)
81         return FALSE;
82
83     while ((key = pa_proplist_iterate(first->plist, &state))) {
84         const char *value_one, *value_two;
85
86         value_one = pa_proplist_gets(first->plist, key);
87         value_two = pa_proplist_gets(second->plist, key);
88
89         if (!value_two || !pa_streq(value_one, value_two))
90             return FALSE;
91     }
92
93     return TRUE;
94 }
95
96 pa_format_info* pa_format_info_from_sample_spec(pa_sample_spec *ss, pa_channel_map *map) {
97     char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
98     pa_format_info *f;
99
100     pa_assert(ss && pa_sample_spec_valid(ss));
101     pa_assert(!map || pa_channel_map_valid(map));
102
103     f = pa_format_info_new();
104     f->encoding = PA_ENCODING_PCM;
105
106     pa_proplist_sets(f->plist, PA_PROP_FORMAT_SAMPLE_FORMAT, pa_sample_format_to_string(ss->format));
107     pa_proplist_setf(f->plist, PA_PROP_FORMAT_RATE, "%u", (unsigned int) ss->rate);
108     pa_proplist_setf(f->plist, PA_PROP_FORMAT_CHANNELS, "%u", (unsigned int) ss->channels);
109
110     if (map) {
111         pa_channel_map_snprint(cm, sizeof(cm), map);
112         pa_proplist_setf(f->plist, PA_PROP_FORMAT_CHANNEL_MAP, "%s", cm);
113     }
114
115     return f;
116 }
117
118 /* For PCM streams */
119 void pa_format_info_to_sample_spec(pa_format_info *f, pa_sample_spec *ss, pa_channel_map *map) {
120     const char *sf, *r, *ch;
121     uint32_t channels;
122
123     pa_assert(f);
124     pa_assert(ss);
125     pa_assert(f->encoding == PA_ENCODING_PCM);
126
127     pa_assert(sf = pa_proplist_gets(f->plist, PA_PROP_FORMAT_SAMPLE_FORMAT));
128     pa_assert(r = pa_proplist_gets(f->plist, PA_PROP_FORMAT_RATE));
129     pa_assert(ch = pa_proplist_gets(f->plist, PA_PROP_FORMAT_CHANNELS));
130
131     pa_assert((ss->format = pa_parse_sample_format(sf)) != PA_SAMPLE_INVALID);
132     pa_assert(pa_atou(r, &ss->rate) == 0);
133     pa_assert(pa_atou(ch, &channels) == 0);
134     ss->channels = (uint8_t) channels;
135
136     if (map) {
137         const char *m = pa_proplist_gets(f->plist, PA_PROP_FORMAT_CHANNEL_MAP);
138         pa_channel_map_init(map);
139
140         if (m)
141             pa_assert(pa_channel_map_parse(map, m) != NULL);
142     }
143 }
144
145 /* For compressed streams */
146 void pa_format_info_to_sample_spec_fake(pa_format_info *f, pa_sample_spec *ss) {
147     const char *r;
148
149     pa_assert(f);
150     pa_assert(ss);
151     pa_assert(f->encoding != PA_ENCODING_PCM);
152
153     ss->format = PA_SAMPLE_S16LE;
154     ss->channels = 2;
155
156     pa_assert(r = pa_proplist_gets(f->plist, PA_PROP_FORMAT_RATE));
157     pa_assert(pa_atou(r, &ss->rate) == 0);
158 }