3rdparty/licenseReport: Add seperate LGPL checks
[haiku.git] / src / add-ons / media / media-add-ons / mixer / MixerUtils.cpp
bloba050bea7eb3fb5e29dd277bcad436a430a079e61
1 /*
2 * Copyright 2003-2009 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Marcus Overhagen
7 */
10 #include <MediaDefs.h>
11 #include <OS.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <math.h>
16 #include "MixerUtils.h"
17 #include "MixerInput.h"
18 #include "MixerOutput.h"
19 #include "MixerCore.h"
20 #include "MixerDebug.h"
22 const char *StringForFormat(char *str, const media_format & format);
24 const char *
25 StringForChannelMask(char *str, uint32 mask)
27 if (mask == 0) {
28 strcpy(str, "<none>");
29 return str;
31 str[0] = 0;
32 #define DECODE(type, text) if (mask & (type)) \
33 do { strcat(str, text); mask &= ~(type); if (mask != 0) strcat(str, ", "); } while (0)
34 DECODE(B_CHANNEL_LEFT, "Left");
35 DECODE(B_CHANNEL_RIGHT, "Right");
36 DECODE(B_CHANNEL_CENTER, "Center");
37 DECODE(B_CHANNEL_SUB, "Sub");
38 DECODE(B_CHANNEL_REARLEFT, "Rear-Left");
39 DECODE(B_CHANNEL_REARRIGHT, "Rear-Right");
40 DECODE(B_CHANNEL_FRONT_LEFT_CENTER, "Front-Left-Center");
41 DECODE(B_CHANNEL_FRONT_RIGHT_CENTER, "Front-Right-Center");
42 DECODE(B_CHANNEL_BACK_CENTER, "Back-Center");
43 DECODE(B_CHANNEL_SIDE_LEFT, "Side-Left");
44 DECODE(B_CHANNEL_SIDE_RIGHT, "Side-Right");
45 // XXX disabled for mono workaround
46 // DECODE(B_CHANNEL_TOP_CENTER, "Top-Center");
47 DECODE(B_CHANNEL_TOP_FRONT_LEFT, "Top-Front-Left");
48 DECODE(B_CHANNEL_TOP_FRONT_CENTER, "Top-Front-Center");
49 DECODE(B_CHANNEL_TOP_FRONT_RIGHT, "Top-Front-Right");
50 DECODE(B_CHANNEL_TOP_BACK_LEFT, "Top-Back-Left");
51 DECODE(B_CHANNEL_TOP_BACK_CENTER, "Top-Back-Center");
52 DECODE(B_CHANNEL_TOP_BACK_RIGHT, "Top-Back-Right");
53 DECODE(B_CHANNEL_MONO, "Mono");
54 #undef DECODE
55 if (mask)
56 sprintf(str + strlen(str), "0x%08" B_PRIx32, mask);
57 return str;
60 int
61 count_nonzero_bits(uint32 value)
63 int count = 0;
64 for (int i = 0; i < 32; i++)
65 if (value & (1 << i))
66 count++;
67 return count;
70 void
71 fix_multiaudio_format(media_multi_audio_format *format)
73 if (format->format == media_raw_audio_format::B_AUDIO_INT) {
74 if (format->valid_bits != 0 && (format->valid_bits < 16 || format->valid_bits >= 32))
75 format->valid_bits = 0;
77 switch (format->channel_count) {
78 case 0:
79 format->channel_mask = 0;
80 format->matrix_mask = 0;
81 break;
82 case 1:
83 if (count_nonzero_bits(format->channel_mask) != 1) {
84 format->channel_mask = B_CHANNEL_LEFT;
85 format->matrix_mask = 0;
87 break;
88 case 2:
89 if (count_nonzero_bits(format->channel_mask) != 2) {
90 format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
91 format->matrix_mask = 0;
93 break;
94 case 3:
95 if (count_nonzero_bits(format->channel_mask) != 3) {
96 format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_CENTER;
97 format->matrix_mask = 0;
99 break;
100 case 4:
101 if (count_nonzero_bits(format->channel_mask) != 4) {
102 format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT;
103 format->matrix_mask = 0;
105 break;
106 case 5:
107 if (count_nonzero_bits(format->channel_mask) != 5) {
108 format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT | B_CHANNEL_CENTER;
109 format->matrix_mask = 0;
111 break;
112 case 6:
113 if (count_nonzero_bits(format->channel_mask) != 6) {
114 format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT | B_CHANNEL_CENTER | B_CHANNEL_SUB;
115 format->matrix_mask = 0;
117 break;
118 case 7:
119 if (count_nonzero_bits(format->channel_mask) != 7) {
120 format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT | B_CHANNEL_CENTER | B_CHANNEL_SUB | B_CHANNEL_BACK_CENTER;
121 format->matrix_mask = 0;
123 break;
124 case 8:
125 if (count_nonzero_bits(format->channel_mask) != 8) {
126 // XXX not sure if 7.1 is like that:
127 format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT | B_CHANNEL_CENTER | B_CHANNEL_SUB | B_CHANNEL_SIDE_LEFT | B_CHANNEL_SIDE_RIGHT;
128 format->matrix_mask = 0;
130 break;
132 default:
133 if (count_nonzero_bits(format->channel_mask) != (int)format->channel_count) {
134 format->channel_mask = 0xffffffff;
135 format->matrix_mask = 0;
137 break;
140 // XXX Workaround for broken BeOS R5 quicktime extractor media node
141 if (format->channel_count == 1
142 && format->format == media_multi_audio_format::B_AUDIO_UCHAR
143 && int(format->frame_rate + 0.5) == 11025
144 && format->byte_order == B_MEDIA_BIG_ENDIAN
145 && format->buffer_size == 548) {
146 ERROR("Mixer: quicktime extractor bug workaround activated, changing buffer size from 548 into 4096\n");
147 format->buffer_size = 4096;
151 uint32
152 GetChannelMask(int channel, uint32 all_channel_masks)
154 if (all_channel_masks == 0) {
155 debugger("Mixer: GetChannelMask: all_channel_masks == 0\n");
156 return 0;
158 if (channel > count_nonzero_bits(all_channel_masks)) {
159 debugger("Mixer: GetChannelMask: channel > count_nonzero_bits(all_channel_masks)\n");
160 return 0;
163 uint32 mask = 1;
164 int pos = 0;
165 for (;;) {
166 while ((all_channel_masks & mask) == 0)
167 mask <<= 1;
168 if (pos == channel)
169 return mask;
170 pos++;
171 mask <<= 1;
172 if (mask == 0)
173 return 0;
177 int ChannelMaskToChannelType(uint32 mask)
179 for (int i = 0; i < 32; i++)
180 if (mask & (1 << i))
181 return i;
182 return -1;
185 uint32 ChannelTypeToChannelMask(int type)
187 if (type < 0 || type > 31)
188 return 0;
189 return 1 << type;
193 GetChannelType(int channel, uint32 all_channel_masks)
195 return ChannelMaskToChannelType(GetChannelMask(channel, all_channel_masks));
198 bool
199 HasKawamba()
201 team_info i;
202 int32 c = 0;
203 while (!get_next_team_info(&c, &i))
204 if (i.argc && strstr(i.args, "\x42\x65\x54\x75\x6e\x65\x73"))
205 return true;
206 return false;
209 void
210 ZeroFill(float *_dst, int32 _dst_sample_offset, int32 _sample_count)
212 register char * dst = (char *) _dst;
213 register int32 sample_count = _sample_count;
214 register int32 dst_sample_offset = _dst_sample_offset;
215 while (sample_count--) {
216 *(float *)dst = 0.0f;
217 dst += dst_sample_offset;
221 int64
222 frames_for_duration(double framerate, bigtime_t duration)
224 if (duration <= 0 || framerate <= 0.0)
225 return 0;
226 return (int64) ceil(framerate * double(duration) / 1000000.0);
229 bigtime_t
230 duration_for_frames(double framerate, int64 frames)
232 if (frames <= 0 || framerate <= 0.0)
233 return 0;
234 return (bigtime_t)((1000000.0 * frames) / framerate);
238 bytes_per_sample(const media_multi_audio_format & format)
240 return format.format & 0xf;
244 bytes_per_frame(const media_multi_audio_format & format)
246 return format.channel_count * (format.format & 0xf);
250 frames_per_buffer(const media_multi_audio_format & format)
252 int frames = 0;
253 if (bytes_per_frame(format) > 0) {
254 frames = format.buffer_size / bytes_per_frame(format);
256 return frames;
259 bigtime_t
260 buffer_duration(const media_multi_audio_format & format)
262 bigtime_t duration = 0;
263 if (format.buffer_size > 0 && format.frame_rate > 0 && bytes_per_frame(format) > 0) {
264 duration = s_to_us((format.buffer_size / bytes_per_frame(format)) / format.frame_rate);
266 return duration;
269 double
270 us_to_s(bigtime_t usecs)
272 return (usecs / 1000000.0);
275 bigtime_t
276 s_to_us(double secs)
278 return (bigtime_t) (secs * 1000000.0);
281 const char *StringForFormat(char *str, const media_format & format)
283 char fmtstr[20];
284 const char *fmt;
285 switch (format.u.raw_audio.format) {
286 case media_raw_audio_format::B_AUDIO_FLOAT:
287 fmt = "float";
288 break;
289 case media_raw_audio_format::B_AUDIO_INT:
290 if (format.u.raw_audio.valid_bits != 0) {
291 sprintf(fmtstr, "%d bit", format.u.raw_audio.valid_bits);
292 fmt = fmtstr;
293 } else {
294 fmt = "32 bit";
296 break;
297 case media_raw_audio_format::B_AUDIO_SHORT:
298 fmt = "16 bit";
299 break;
300 case media_raw_audio_format::B_AUDIO_CHAR:
301 fmt = "8 bit";
302 break;
303 case media_raw_audio_format::B_AUDIO_UCHAR:
304 fmt = "8 bit unsigned";
305 break;
306 default:
307 fmt = "unknown";
308 break;
310 int a,b;
311 a = int(format.u.raw_audio.frame_rate + 0.05) / 1000;
312 b = int(format.u.raw_audio.frame_rate + 0.05) % 1000;
313 if (b)
314 sprintf(str, "%d.%d kHz %s", a, b / 100, fmt);
315 else
316 sprintf(str, "%d kHz %s", a, fmt);
317 return str;
320 const char *
321 StringForFormat(char *buf, MixerOutput *output)
323 return StringForFormat(buf, output->MediaOutput().format);
326 const char *
327 StringForFormat(char *buf, MixerInput *input)
329 return StringForFormat(buf, input->MediaInput().format);
332 const char *
333 StringForChannelType(char *buf, int type)
335 return StringForChannelMask(buf, 1 << type);