1 #include <MediaDefs.h> 2 #include <OS.h> 3 #include <stdio.h> 4 #include <string.h> 5 #include <math.h> 6 7 #include "MixerUtils.h" 8 #include "MixerInput.h" 9 #include "MixerOutput.h" 10 #include "MixerCore.h" 11 #include "MixerDebug.h" 12 13 const char *StringForFormat(char *str, const media_format & format); 14 15 const char * 16 StringForChannelMask(char *str, uint32 mask) 17 { 18 if (mask == 0) { 19 strcpy(str, "<none>"); 20 return str; 21 } 22 str[0] = 0; 23 #define DECODE(type, text) if (mask & (type)) \ 24 do { strcat(str, text); mask &= ~(type); if (mask != 0) strcat(str, ", "); } while (0) 25 DECODE(B_CHANNEL_LEFT, "Left"); 26 DECODE(B_CHANNEL_RIGHT, "Right"); 27 DECODE(B_CHANNEL_CENTER, "Center"); 28 DECODE(B_CHANNEL_SUB, "Sub"); 29 DECODE(B_CHANNEL_REARLEFT, "Rear-Left"); 30 DECODE(B_CHANNEL_REARRIGHT, "Rear-Right"); 31 DECODE(B_CHANNEL_FRONT_LEFT_CENTER, "Front-Left-Center"); 32 DECODE(B_CHANNEL_FRONT_RIGHT_CENTER, "Front-Right-Center"); 33 DECODE(B_CHANNEL_BACK_CENTER, "Back-Center"); 34 DECODE(B_CHANNEL_SIDE_LEFT, "Side-Left"); 35 DECODE(B_CHANNEL_SIDE_RIGHT, "Side-Right"); 36 // XXX disabled for mono workaround 37 // DECODE(B_CHANNEL_TOP_CENTER, "Top-Center"); 38 DECODE(B_CHANNEL_TOP_FRONT_LEFT, "Top-Front-Left"); 39 DECODE(B_CHANNEL_TOP_FRONT_CENTER, "Top-Front-Center"); 40 DECODE(B_CHANNEL_TOP_FRONT_RIGHT, "Top-Front-Right"); 41 DECODE(B_CHANNEL_TOP_BACK_LEFT, "Top-Back-Left"); 42 DECODE(B_CHANNEL_TOP_BACK_CENTER, "Top-Back-Center"); 43 DECODE(B_CHANNEL_TOP_BACK_RIGHT, "Top-Back-Right"); 44 DECODE(B_CHANNEL_MONO, "Mono"); 45 #undef DECODE 46 if (mask) 47 sprintf(str + strlen(str), "0x%08lX", mask); 48 return str; 49 } 50 51 int 52 count_nonzero_bits(uint32 value) 53 { 54 int count = 0; 55 for (int i = 0; i < 32; i++) 56 if (value & (1 << i)) 57 count++; 58 return count; 59 } 60 61 void 62 fix_multiaudio_format(media_multi_audio_format *format) 63 { 64 if (format->format == media_raw_audio_format::B_AUDIO_INT) { 65 if (format->valid_bits != 0 && (format->valid_bits < 16 || format->valid_bits >= 32)) 66 format->valid_bits = 0; 67 } 68 switch (format->channel_count) { 69 case 0: 70 format->channel_mask = 0; 71 format->matrix_mask = 0; 72 break; 73 case 1: 74 if (count_nonzero_bits(format->channel_mask) != 1) { 75 format->channel_mask = B_CHANNEL_LEFT; 76 format->matrix_mask = 0; 77 } 78 break; 79 case 2: 80 if (count_nonzero_bits(format->channel_mask) != 2) { 81 format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT; 82 format->matrix_mask = 0; 83 } 84 break; 85 case 3: 86 if (count_nonzero_bits(format->channel_mask) != 3) { 87 format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_CENTER; 88 format->matrix_mask = 0; 89 } 90 break; 91 case 4: 92 if (count_nonzero_bits(format->channel_mask) != 4) { 93 format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT; 94 format->matrix_mask = 0; 95 } 96 break; 97 case 5: 98 if (count_nonzero_bits(format->channel_mask) != 5) { 99 format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT | B_CHANNEL_CENTER; 100 format->matrix_mask = 0; 101 } 102 break; 103 case 6: 104 if (count_nonzero_bits(format->channel_mask) != 6) { 105 format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT | B_CHANNEL_CENTER | B_CHANNEL_SUB; 106 format->matrix_mask = 0; 107 } 108 break; 109 case 7: 110 if (count_nonzero_bits(format->channel_mask) != 7) { 111 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; 112 format->matrix_mask = 0; 113 } 114 break; 115 case 8: 116 if (count_nonzero_bits(format->channel_mask) != 8) { 117 // XXX not sure if 7.1 is like that: 118 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; 119 format->matrix_mask = 0; 120 } 121 break; 122 123 default: 124 if (count_nonzero_bits(format->channel_mask) != (int)format->channel_count) { 125 format->channel_mask = 0xffffffff; 126 format->matrix_mask = 0; 127 } 128 break; 129 } 130 131 // XXX Workaround for broken BeOS R5 quicktime extractor media node 132 if (format->channel_count == 1 133 && format->format == media_multi_audio_format::B_AUDIO_UCHAR 134 && int(format->frame_rate + 0.5) == 11025 135 && format->byte_order == B_MEDIA_BIG_ENDIAN 136 && format->buffer_size == 548) { 137 ERROR("Mixer: quicktime extractor bug workaround activated, changing buffer size from 548 into 4096\n"); 138 format->buffer_size = 4096; 139 } 140 } 141 142 uint32 143 GetChannelMask(int channel, uint32 all_channel_masks) 144 { 145 if (all_channel_masks == 0) { 146 debugger("Mixer: GetChannelMask: all_channel_masks == 0\n"); 147 return 0; 148 } 149 if (channel > count_nonzero_bits(all_channel_masks)) { 150 debugger("Mixer: GetChannelMask: channel > count_nonzero_bits(all_channel_masks)\n"); 151 return 0; 152 } 153 154 uint32 mask = 1; 155 int pos = 0; 156 for (;;) { 157 while ((all_channel_masks & mask) == 0) 158 mask <<= 1; 159 if (pos == channel) 160 return mask; 161 pos++; 162 mask <<= 1; 163 if (mask == 0) 164 return 0; 165 } 166 } 167 168 int ChannelMaskToChannelType(uint32 mask) 169 { 170 for (int i = 0; i < 32; i++) 171 if (mask & (1 << i)) 172 return i; 173 return -1; 174 } 175 176 uint32 ChannelTypeToChannelMask(int type) 177 { 178 if (type < 0 || type > 31) 179 return 0; 180 return 1 << type; 181 } 182 183 int 184 GetChannelType(int channel, uint32 all_channel_masks) 185 { 186 return ChannelMaskToChannelType(GetChannelMask(channel, all_channel_masks)); 187 } 188 189 bool 190 HasKawamba() 191 { 192 team_info i; 193 int32 c = 0; 194 while (!get_next_team_info(&c, &i)) 195 if (i.argc && strstr(i.args, "\x42\x65\x54\x75\x6e\x65\x73")) 196 return true; 197 return false; 198 } 199 200 void 201 ZeroFill(float *_dst, int32 _dst_sample_offset, int32 _sample_count) 202 { 203 register char * dst = (char *) _dst; 204 register int32 sample_count = _sample_count; 205 register int32 dst_sample_offset = _dst_sample_offset; 206 while (sample_count--) { 207 *(float *)dst = 0.0f; 208 dst += dst_sample_offset; 209 } 210 } 211 212 int64 213 frames_for_duration(double framerate, bigtime_t duration) 214 { 215 if (duration <= 0 || framerate <= 0.0) 216 return 0; 217 return (int64) ceil(framerate * double(duration) / 1000000.0); 218 } 219 220 bigtime_t 221 duration_for_frames(double framerate, int64 frames) 222 { 223 if (frames <= 0 || framerate <= 0.0) 224 return 0; 225 return (bigtime_t)((1000000.0 * frames) / framerate); 226 } 227 228 int 229 bytes_per_sample(const media_multi_audio_format & format) 230 { 231 return format.format & 0xf; 232 } 233 234 int 235 bytes_per_frame(const media_multi_audio_format & format) 236 { 237 return format.channel_count * (format.format & 0xf); 238 } 239 240 int 241 frames_per_buffer(const media_multi_audio_format & format) 242 { 243 int frames = 0; 244 if (bytes_per_frame(format) > 0) { 245 frames = format.buffer_size / bytes_per_frame(format); 246 } 247 return frames; 248 } 249 250 bigtime_t 251 buffer_duration(const media_multi_audio_format & format) 252 { 253 bigtime_t duration = 0; 254 if (format.buffer_size > 0 && format.frame_rate > 0 && bytes_per_frame(format) > 0) { 255 duration = s_to_us((format.buffer_size / bytes_per_frame(format)) / format.frame_rate); 256 } 257 return duration; 258 } 259 260 double 261 us_to_s(bigtime_t usecs) 262 { 263 return (usecs / 1000000.0); 264 } 265 266 bigtime_t 267 s_to_us(double secs) 268 { 269 return (bigtime_t) (secs * 1000000.0); 270 } 271 272 const char *StringForFormat(char *str, const media_format & format) 273 { 274 char fmtstr[20]; 275 const char *fmt; 276 switch (format.u.raw_audio.format) { 277 case media_raw_audio_format::B_AUDIO_FLOAT: 278 fmt = "float"; 279 break; 280 case media_raw_audio_format::B_AUDIO_INT: 281 if (format.u.raw_audio.valid_bits != 0) { 282 sprintf(fmtstr, "%d bit", format.u.raw_audio.valid_bits); 283 fmt = fmtstr; 284 } else { 285 fmt = "32 bit"; 286 } 287 break; 288 case media_raw_audio_format::B_AUDIO_SHORT: 289 fmt = "16 bit"; 290 break; 291 case media_raw_audio_format::B_AUDIO_CHAR: 292 fmt = "8 bit"; 293 break; 294 case media_raw_audio_format::B_AUDIO_UCHAR: 295 fmt = "8 bit unsigned"; 296 break; 297 default: 298 fmt = "unknown"; 299 break; 300 } 301 int a,b; 302 a = int(format.u.raw_audio.frame_rate + 0.05) / 1000; 303 b = int(format.u.raw_audio.frame_rate + 0.05) % 1000; 304 if (b) 305 sprintf(str, "%d.%d kHz %s", a, b / 100, fmt); 306 else 307 sprintf(str, "%d kHz %s", a, fmt); 308 return str; 309 } 310 311 const char * 312 StringForFormat(char *buf, MixerOutput *output) 313 { 314 return StringForFormat(buf, output->MediaOutput().format); 315 } 316 317 const char * 318 StringForFormat(char *buf, MixerInput *input) 319 { 320 return StringForFormat(buf, input->MediaInput().format); 321 } 322 323 const char * 324 StringForChannelType(char *buf, int type) 325 { 326 return StringForChannelMask(buf, 1 << type); 327 } 328