]> code.delx.au - pulseaudio/blob - src/pulsecore/mime-type.c
remap: Change remapping function argument type from void to int16_t / float as approp...
[pulseaudio] / src / pulsecore / mime-type.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2005-2009 Lennart Poettering
5
6 PulseAudio 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.1 of the License,
9 or (at your option) any later version.
10
11 PulseAudio 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 PulseAudio; 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 <pulse/xmalloc.h>
27 #include <pulsecore/core-util.h>
28
29 #include "mime-type.h"
30
31 bool pa_sample_spec_is_mime(const pa_sample_spec *ss, const pa_channel_map *cm) {
32
33 pa_assert(pa_channel_map_compatible(cm, ss));
34
35 switch (ss->format) {
36 case PA_SAMPLE_S16BE:
37 case PA_SAMPLE_S24BE:
38 case PA_SAMPLE_U8:
39
40 if (ss->rate != 8000 &&
41 ss->rate != 11025 &&
42 ss->rate != 16000 &&
43 ss->rate != 22050 &&
44 ss->rate != 24000 &&
45 ss->rate != 32000 &&
46 ss->rate != 44100 &&
47 ss->rate != 48000)
48 return false;
49
50 if (ss->channels != 1 &&
51 ss->channels != 2)
52 return false;
53
54 if ((cm->channels == 1 && cm->map[0] != PA_CHANNEL_POSITION_MONO) ||
55 (cm->channels == 2 && (cm->map[0] != PA_CHANNEL_POSITION_LEFT || cm->map[1] != PA_CHANNEL_POSITION_RIGHT)))
56 return false;
57
58 return true;
59
60 case PA_SAMPLE_ULAW:
61
62 if (ss->rate != 8000)
63 return false;
64
65 if (ss->channels != 1)
66 return false;
67
68 if (cm->map[0] != PA_CHANNEL_POSITION_MONO)
69 return false;
70
71 return true;
72
73 default:
74 return false;
75 }
76 }
77
78 void pa_sample_spec_mimefy(pa_sample_spec *ss, pa_channel_map *cm) {
79
80 pa_assert(pa_channel_map_compatible(cm, ss));
81
82 /* Turns the sample type passed in into the next 'better' one that
83 * can be encoded for HTTP. If there is no 'better' one we pick
84 * the 'best' one that is 'worse'. */
85
86 if (ss->channels > 2)
87 ss->channels = 2;
88
89 if (ss->rate > 44100)
90 ss->rate = 48000;
91 else if (ss->rate > 32000)
92 ss->rate = 44100;
93 else if (ss->rate > 24000)
94 ss->rate = 32000;
95 else if (ss->rate > 22050)
96 ss->rate = 24000;
97 else if (ss->rate > 16000)
98 ss->rate = 22050;
99 else if (ss->rate > 11025)
100 ss->rate = 16000;
101 else if (ss->rate > 8000)
102 ss->rate = 11025;
103 else
104 ss->rate = 8000;
105
106 switch (ss->format) {
107 case PA_SAMPLE_S24BE:
108 case PA_SAMPLE_S24LE:
109 case PA_SAMPLE_S24_32LE:
110 case PA_SAMPLE_S24_32BE:
111 case PA_SAMPLE_S32LE:
112 case PA_SAMPLE_S32BE:
113 case PA_SAMPLE_FLOAT32LE:
114 case PA_SAMPLE_FLOAT32BE:
115 ss->format = PA_SAMPLE_S24BE;
116 break;
117
118 case PA_SAMPLE_S16BE:
119 case PA_SAMPLE_S16LE:
120 ss->format = PA_SAMPLE_S16BE;
121 break;
122
123 case PA_SAMPLE_ULAW:
124 case PA_SAMPLE_ALAW:
125
126 if (ss->rate == 8000 && ss->channels == 1)
127 ss->format = PA_SAMPLE_ULAW;
128 else
129 ss->format = PA_SAMPLE_S16BE;
130 break;
131
132 case PA_SAMPLE_U8:
133 ss->format = PA_SAMPLE_U8;
134 break;
135
136 case PA_SAMPLE_MAX:
137 case PA_SAMPLE_INVALID:
138 pa_assert_not_reached();
139 }
140
141 pa_channel_map_init_auto(cm, ss->channels, PA_CHANNEL_MAP_DEFAULT);
142
143 pa_assert(pa_sample_spec_is_mime(ss, cm));
144 }
145
146 char *pa_sample_spec_to_mime_type(const pa_sample_spec *ss, const pa_channel_map *cm) {
147 pa_assert(pa_channel_map_compatible(cm, ss));
148 pa_assert(pa_sample_spec_valid(ss));
149
150 if (!pa_sample_spec_is_mime(ss, cm))
151 return NULL;
152
153 switch (ss->format) {
154
155 case PA_SAMPLE_S16BE:
156 case PA_SAMPLE_S24BE:
157 case PA_SAMPLE_U8:
158 /* Stupid UPnP implementations (PS3...) choke on spaces in
159 * the mime type, that's why we write only ';' here,
160 * instead of '; '. */
161 return pa_sprintf_malloc("audio/%s;rate=%u;channels=%u",
162 ss->format == PA_SAMPLE_S16BE ? "L16" :
163 (ss->format == PA_SAMPLE_S24BE ? "L24" : "L8"),
164 ss->rate, ss->channels);
165
166 case PA_SAMPLE_ULAW:
167 return pa_xstrdup("audio/basic");
168
169 default:
170 pa_assert_not_reached();
171 }
172 }
173
174 char *pa_sample_spec_to_mime_type_mimefy(const pa_sample_spec *_ss, const pa_channel_map *_cm) {
175 pa_sample_spec ss = *_ss;
176 pa_channel_map cm = *_cm;
177
178 pa_sample_spec_mimefy(&ss, &cm);
179
180 return pa_sample_spec_to_mime_type(&ss, &cm);
181 }