2 * Copyright 2003-2009 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
10 #include <MediaDefs.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
);
25 StringForChannelMask(char *str
, uint32 mask
)
28 strcpy(str
, "<none>");
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");
56 sprintf(str
+ strlen(str
), "0x%08" B_PRIx32
, mask
);
61 count_nonzero_bits(uint32 value
)
64 for (int i
= 0; i
< 32; i
++)
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
) {
79 format
->channel_mask
= 0;
80 format
->matrix_mask
= 0;
83 if (count_nonzero_bits(format
->channel_mask
) != 1) {
84 format
->channel_mask
= B_CHANNEL_LEFT
;
85 format
->matrix_mask
= 0;
89 if (count_nonzero_bits(format
->channel_mask
) != 2) {
90 format
->channel_mask
= B_CHANNEL_LEFT
| B_CHANNEL_RIGHT
;
91 format
->matrix_mask
= 0;
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;
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;
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;
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;
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;
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;
133 if (count_nonzero_bits(format
->channel_mask
) != (int)format
->channel_count
) {
134 format
->channel_mask
= 0xffffffff;
135 format
->matrix_mask
= 0;
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;
152 GetChannelMask(int channel
, uint32 all_channel_masks
)
154 if (all_channel_masks
== 0) {
155 debugger("Mixer: GetChannelMask: all_channel_masks == 0\n");
158 if (channel
> count_nonzero_bits(all_channel_masks
)) {
159 debugger("Mixer: GetChannelMask: channel > count_nonzero_bits(all_channel_masks)\n");
166 while ((all_channel_masks
& mask
) == 0)
177 int ChannelMaskToChannelType(uint32 mask
)
179 for (int i
= 0; i
< 32; i
++)
185 uint32
ChannelTypeToChannelMask(int type
)
187 if (type
< 0 || type
> 31)
193 GetChannelType(int channel
, uint32 all_channel_masks
)
195 return ChannelMaskToChannelType(GetChannelMask(channel
, all_channel_masks
));
203 while (!get_next_team_info(&c
, &i
))
204 if (i
.argc
&& strstr(i
.args
, "\x42\x65\x54\x75\x6e\x65\x73"))
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
;
222 frames_for_duration(double framerate
, bigtime_t duration
)
224 if (duration
<= 0 || framerate
<= 0.0)
226 return (int64
) ceil(framerate
* double(duration
) / 1000000.0);
230 duration_for_frames(double framerate
, int64 frames
)
232 if (frames
<= 0 || framerate
<= 0.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
)
253 if (bytes_per_frame(format
) > 0) {
254 frames
= format
.buffer_size
/ bytes_per_frame(format
);
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
);
270 us_to_s(bigtime_t usecs
)
272 return (usecs
/ 1000000.0);
278 return (bigtime_t
) (secs
* 1000000.0);
281 const char *StringForFormat(char *str
, const media_format
& format
)
285 switch (format
.u
.raw_audio
.format
) {
286 case media_raw_audio_format::B_AUDIO_FLOAT
:
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
);
297 case media_raw_audio_format::B_AUDIO_SHORT
:
300 case media_raw_audio_format::B_AUDIO_CHAR
:
303 case media_raw_audio_format::B_AUDIO_UCHAR
:
304 fmt
= "8 bit unsigned";
311 a
= int(format
.u
.raw_audio
.frame_rate
+ 0.05) / 1000;
312 b
= int(format
.u
.raw_audio
.frame_rate
+ 0.05) % 1000;
314 sprintf(str
, "%d.%d kHz %s", a
, b
/ 100, fmt
);
316 sprintf(str
, "%d kHz %s", a
, fmt
);
321 StringForFormat(char *buf
, MixerOutput
*output
)
323 return StringForFormat(buf
, output
->MediaOutput().format
);
327 StringForFormat(char *buf
, MixerInput
*input
)
329 return StringForFormat(buf
, input
->MediaInput().format
);
333 StringForChannelType(char *buf
, int type
)
335 return StringForChannelMask(buf
, 1 << type
);