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