1 /* 2 * Copyright 2003-2009 Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Marcus Overhagen 7 */ 8 9 10 #include <MediaDefs.h> 11 #include <OS.h> 12 #include <stdio.h> 13 #include <string.h> 14 #include <math.h> 15 16 #include "MixerUtils.h" 17 #include "MixerInput.h" 18 #include "MixerOutput.h" 19 #include "MixerCore.h" 20 #include "MixerDebug.h" 21 22 const char *StringForFormat(char *str, const media_format & format); 23 24 const char * 25 StringForChannelMask(char *str, uint32 mask) 26 { 27 if (mask == 0) { 28 strcpy(str, "<none>"); 29 return str; 30 } 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; 58 } 59 60 int 61 count_nonzero_bits(uint32 value) 62 { 63 int count = 0; 64 for (int i = 0; i < 32; i++) 65 if (value & (1 << i)) 66 count++; 67 return count; 68 } 69 70 void 71 fix_multiaudio_format(media_multi_audio_format *format) 72 { 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; 76 } 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; 86 } 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; 92 } 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; 98 } 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; 104 } 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; 110 } 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; 116 } 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; 122 } 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; 129 } 130 break; 131 132 default: 133 if (count_nonzero_bits(format->channel_mask) != (int)format->channel_count) { 134 format->channel_mask = 0xffffffff; 135 format->matrix_mask = 0; 136 } 137 break; 138 } 139 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; 148 } 149 } 150 151 uint32 152 GetChannelMask(int channel, uint32 all_channel_masks) 153 { 154 if (all_channel_masks == 0) { 155 debugger("Mixer: GetChannelMask: all_channel_masks == 0\n"); 156 return 0; 157 } 158 if (channel > count_nonzero_bits(all_channel_masks)) { 159 debugger("Mixer: GetChannelMask: channel > count_nonzero_bits(all_channel_masks)\n"); 160 return 0; 161 } 162 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; 174 } 175 } 176 177 int ChannelMaskToChannelType(uint32 mask) 178 { 179 for (int i = 0; i < 32; i++) 180 if (mask & (1 << i)) 181 return i; 182 return -1; 183 } 184 185 uint32 ChannelTypeToChannelMask(int type) 186 { 187 if (type < 0 || type > 31) 188 return 0; 189 return 1 << type; 190 } 191 192 int 193 GetChannelType(int channel, uint32 all_channel_masks) 194 { 195 return ChannelMaskToChannelType(GetChannelMask(channel, all_channel_masks)); 196 } 197 198 bool 199 HasKawamba() 200 { 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; 207 } 208 209 void 210 ZeroFill(float *_dst, int32 _dst_sample_offset, int32 _sample_count) 211 { 212 char * dst = (char *) _dst; 213 int32 sample_count = _sample_count; 214 int32 dst_sample_offset = _dst_sample_offset; 215 while (sample_count--) { 216 *(float *)dst = 0.0f; 217 dst += dst_sample_offset; 218 } 219 } 220 221 int64 222 frames_for_duration(double framerate, bigtime_t duration) 223 { 224 if (duration <= 0 || framerate <= 0.0) 225 return 0; 226 return (int64) ceil(framerate * double(duration) / 1000000.0); 227 } 228 229 bigtime_t 230 duration_for_frames(double framerate, int64 frames) 231 { 232 if (frames <= 0 || framerate <= 0.0) 233 return 0; 234 return (bigtime_t)((1000000.0 * frames) / framerate); 235 } 236 237 int 238 bytes_per_sample(const media_multi_audio_format & format) 239 { 240 return format.format & 0xf; 241 } 242 243 int 244 bytes_per_frame(const media_multi_audio_format & format) 245 { 246 return format.channel_count * (format.format & 0xf); 247 } 248 249 int 250 frames_per_buffer(const media_multi_audio_format & format) 251 { 252 int frames = 0; 253 if (bytes_per_frame(format) > 0) { 254 frames = format.buffer_size / bytes_per_frame(format); 255 } 256 return frames; 257 } 258 259 bigtime_t 260 buffer_duration(const media_multi_audio_format & format) 261 { 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); 265 } 266 return duration; 267 } 268 269 double 270 us_to_s(bigtime_t usecs) 271 { 272 return (usecs / 1000000.0); 273 } 274 275 bigtime_t 276 s_to_us(double secs) 277 { 278 return (bigtime_t) (secs * 1000000.0); 279 } 280 281 const char *StringForFormat(char *str, const media_format & format) 282 { 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"; 295 } 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; 309 } 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; 318 } 319 320 const char * 321 StringForFormat(char *buf, MixerOutput *output) 322 { 323 return StringForFormat(buf, output->MediaOutput().format); 324 } 325 326 const char * 327 StringForFormat(char *buf, MixerInput *input) 328 { 329 return StringForFormat(buf, input->MediaInput().format); 330 } 331 332 const char * 333 StringForChannelType(char *buf, int type) 334 { 335 return StringForChannelMask(buf, 1 << type); 336 } 337