1 /***************************************************
2 *
3 * These functions below rarely get changed, so
4 * I'm going to put them here so there's less
5 * clutter in the main C file.
6 *
7 ****************************************************/
8 
9 // Function prototypes go here
10 inline int	cmp_str(const char *full_str, const char *chk_str, int full_str_offset);
11 int		check_header_value(unsigned int *header, char *filename, frame_info *FI);
12 int		check_vbr_and_time(frame_info *mp3_i, vbr_data *vbr_info, gen_info *file_info);
13 int		copy_int_array_to_str(char *possible_mp3_tag, char *tag_field, int offset, int length, int max_length);
14 int		dump_id3_tag(id3_tag_info *id3_tag);
15 int		get_last_char_offset(char *fat_string);
16 int		print_frame_info(frame_info *mp3_i, gen_info *file_info);
17 int		rotate_char_array(char *byte_list, int *new_byte, gen_info *file_info);
18 int		transform_char_array(char *byte_list, gen_info *file_info);
19 int		validate_id3_tag(char *possible_mp3_tag, id3_tag_info *id3_tag);
20 void		init_id3_tag_struct(id3_tag_info *TAG);
21 void		init_vbr_tag_struct(vbr_data *vbr_info);
22 void		init_mp3_time_struct(mp3_time *song_time);
23 void		init_gen_info_struct(gen_info *file_info);
24 void		print_sys_usage(void);
25 void		translate_time(gen_info *file_info, mp3_time *song_time);
26 
27 
28 void
init_vbr_tag_struct(vbr_info)29 init_vbr_tag_struct(vbr_info)
30 	vbr_data	*vbr_info;
31 {
32 	vbr_info->high_rate	= 0;
33 	vbr_info->low_rate	= 0;
34 	vbr_info->ave_rate	= 0;
35 	vbr_info->sum_rate	= 0;
36 }
37 
38 void
init_gen_info_struct(file_info)39 init_gen_info_struct(file_info)
40 	gen_info	*file_info;
41 {
42 	file_info->file_pos 		= 0;
43 	file_info->good_frame_count	= 0;
44 	file_info->bad_frame_count	= 0;
45 	file_info->frame_sequence_count	= 0;
46 	file_info->byte_count		= 0;
47 	file_info->next_expected_frame	= 4;
48 	file_info->time_in_seconds 	= 0;
49 }
50 
51 void
init_mp3_time_struct(song_time)52 init_mp3_time_struct(song_time)
53 	mp3_time	*song_time;
54 {
55 	song_time->minutes	= 0;
56 	song_time->seconds	= 0;
57 	song_time->frac_second	= 0;
58 }
59 
60 inline int
cmp_str(full_str,chk_str,full_str_offset)61 cmp_str (full_str, chk_str, full_str_offset)
62 	register const char * full_str;
63 	register const char * chk_str;
64 	int full_str_offset;
65 {
66 	int     check_state     = FAIL;
67 	int     start           = 31 - full_str_offset; /* ?? */
68 
69 	if (!memcmp (full_str+start, chk_str, strlen(chk_str)))
70 		return PASS;
71 
72 	return check_state;
73 }
74 
75 int
copy_int_array_to_str(possible_mp3_tag,tag_field,offset,length,max_length)76 copy_int_array_to_str(possible_mp3_tag, tag_field, offset, length, max_length)
77 	char		*possible_mp3_tag;
78 	char		*tag_field;
79 	int		offset;
80 	int		length;
81 	int		max_length;
82 {
83 	int 	counter = 0;
84 	int 	position = 0;
85 
86 	if (max_length < (offset + length))
87 		return(FAIL);
88 
89 	for (position = offset ; position < (offset + length) ; position++) {
90 		*(tag_field + counter) = (char)*(possible_mp3_tag + position);
91 		counter++;
92 	}
93 
94 	return(PASS);
95 }
96 
97 int
validate_id3_tag(possible_mp3_tag,id3_tag)98 validate_id3_tag(possible_mp3_tag, id3_tag)
99 	char		*possible_mp3_tag;
100 	id3_tag_info 	*id3_tag;
101 {
102 	//  The first 3 characters must be "TAG" for it
103 	//  to be an id3 tag.
104 
105 	//
106 	//  This section is just to see the 128 bit buffer in numerical format
107 	//
108 
109 	if ((possible_mp3_tag[0] == 'T') && (possible_mp3_tag[1] == 'A') && (possible_mp3_tag[2] == 'G')) {
110 		id3_tag->TAG_PRESENT = YES;
111 
112 		if (possible_mp3_tag[126] != '\0') {
113 			id3_tag->TRACK_NUMBER = possible_mp3_tag[126];
114 			id3_tag->ID3_311_VERSION = YES;
115 		} else {
116 			id3_tag->TRACK_NUMBER = 0;
117 			id3_tag->ID3_311_VERSION = NO;
118 		}
119 
120 
121 		id3_tag->GENRE = possible_mp3_tag[127];
122 
123 		copy_int_array_to_str(possible_mp3_tag, id3_tag->TITLE, 3, 30, 128);
124 		copy_int_array_to_str(possible_mp3_tag, id3_tag->ARTIST, 33, 30, 128);
125 		copy_int_array_to_str(possible_mp3_tag, id3_tag->ALBUM, 63, 30, 128);
126 		copy_int_array_to_str(possible_mp3_tag, id3_tag->YEAR, 93, 4, 128);
127 		copy_int_array_to_str(possible_mp3_tag, id3_tag->COMMENT, 97, 30, 128);
128 
129 
130 		//  This section below does not work because I am working with an
131 		//  integer array and not a character array. The reason for that is that
132 		//  with a character array, if there are any nulls, the array shortens and
133 		//  I need the (null)s to find out certain info...
134 
135 		// memcpy(id3_tag->TITLE, possible_mp3_tag + 3, 30);
136 		// memcpy(id3_tag->ARTIST, possible_mp3_tag + 33, 30);
137 		// memcpy(id3_tag->ALBUM, possible_mp3_tag + 63, 30);
138 		// memcpy(id3_tag->YEAR, possible_mp3_tag + 93, 4);
139 		// memcpy(id3_tag->COMMENT, possible_mp3_tag + 97, 30);
140 	} else {
141 		id3_tag->TAG_PRESENT = NO;
142 		return(FAIL);
143 	}
144 
145 	return(PASS);
146 }
147 
148 void
init_id3_tag_struct(TAG)149 init_id3_tag_struct(TAG)
150 	id3_tag_info *TAG;
151 {
152 	TAG->TAG_PRESENT = NO;
153 	TAG->ID3_311_VERSION = NO;
154 
155 	memset(TAG->TITLE, '\0', sizeof(TAG->TITLE));
156 	memset(TAG->ARTIST, '\0', sizeof(TAG->ARTIST));
157 	memset(TAG->ALBUM, '\0', sizeof(TAG->ALBUM));
158 	memset(TAG->YEAR, '\0', sizeof(TAG->YEAR));
159 	memset(TAG->COMMENT, '\0', sizeof(TAG->COMMENT));
160 
161 	TAG->GENRE = 0;
162 	TAG->TRACK_NUMBER = 0;
163 	TAG->COMPLIANT_PAD_FIELDS = NO;
164 }
165 
166 int
check_header_value(header,filename,FI)167 check_header_value(header, filename, FI)
168 	unsigned int	*header;
169 	char		*filename;
170 	frame_info	*FI;
171 {
172 	//
173 	//  This is the one function that truely will make this a
174 	//  bad-ass proggie. Lots of logic can go in here to check
175 	//  for compliant mp3s.
176 	//
177 
178 	char	bin_string[33] = {0};
179 	int	i = 0;
180 	int	value_part = 0;
181 	int	column_part = 0;
182 
183 
184 	//  The last column makes it easy to trap the 'everything else' stuff...
185 	static int bitrate_matrix[6][16] = {
186 		{1, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0},
187 		{1, 32, 48, 56, 64,  80,  96,  112, 128, 160, 192, 224, 256, 320, 384, 0},
188 		{1, 32, 40, 48, 56,  64,  80,  96,  112, 128, 160, 192, 224, 256, 320, 0},
189 		{1, 32, 48, 56, 64,  80,  96,  112, 128, 144, 160, 176, 192, 224, 256, 0},
190 		{1, 8,	16, 24, 32,  40,  48,  56,  64,	 80,  96,  112, 128, 144, 160, 0},
191 		{0, 0,	0,  0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0}
192 	};
193 
194 	static int sampling_rate_matrix[4][3] = {
195 		{44100,	22050,	11025},
196 		{48000,	24000,	12000},
197 		{32000,	16000,	8000},
198 		{0,	0,	0}
199 	};
200 
201 	//  For debugging purposes
202 	// printf("HV: %d\n", *header);
203 
204 	//
205 	//  Set the default return value of this funtion to FAIL
206 	//  in case of a invalid header.
207 	//
208 	FI->check_state = FAIL;
209 
210 	bin_string[32] = '\0';
211 
212 	for (i=0 ; i < 32 ; i++) {
213 		bin_string[i] = '0';
214 	}
215 
216 
217 	//
218 	//  Convert 32bit integer to binary.
219 	//
220 	for (i=0 ; i < 32 ; i++){
221 		if (((*header >> i) & 1) == 1){
222 			bin_string[31 - i] = '1';
223 		}
224 	}
225 
226 	//  Store this data in case I want to print it
227 	//  out for debugging stuff.
228 
229 	strcpy(FI->BIN_STRING, bin_string);
230 	FI->INT_HEADER = *header;
231 
232 	//
233 	//  Is it a mp3 sync bit?
234 	//
235 	//  Don't even continue if it doesn't pass this one.
236 	//
237 
238 	if (cmp_str(bin_string, "11111111111", 31))
239 		FI->check_state = PASS;
240 	else
241 		return FI->check_state;
242 
243 
244 	//
245 	//  Get the MPEG version
246 	//
247 	if (cmp_str(bin_string, "00", 20))
248 		FI->MPV_25 = TRUE;
249 
250 	else if (cmp_str(bin_string, "01", 20))
251 		FI->MPV_RESERVED = TRUE;
252 
253 	else if (cmp_str(bin_string, "10", 20))
254 		FI->MPV_2 = TRUE;
255 
256 	else if (cmp_str(bin_string, "11", 20))
257 		FI->MPV_1 = TRUE;
258 
259 
260 	//
261 	//  Layer Version
262 	//
263 	if (cmp_str(bin_string, "00", 18)) {
264 		FI->L_RESERVED = TRUE;
265 		FI->SAMPLES_PER_FRAME = 0;
266 
267 	} else if (cmp_str(bin_string, "01", 18)) {
268 		FI->L3 = TRUE;
269 		FI->SAMPLES_PER_FRAME = 1152;
270 
271 	} else if (cmp_str(bin_string, "10", 18)) {
272 		FI->L2 = TRUE;
273 		FI->SAMPLES_PER_FRAME = 1152;
274 
275 	} else if (cmp_str(bin_string, "11", 18)) {
276 		FI->L1 = TRUE;
277 		FI->SAMPLES_PER_FRAME = 384;
278 	}
279 
280 
281 	//
282 	//  CRC Bit
283 	//
284 	if (cmp_str(bin_string, "0", 16))
285 		FI->PROT_BIT = TRUE;
286 
287 
288 	//
289 	//  BITRATE
290 	//
291 	//  Grab the specific integer from the "header"
292 	//  that I need.
293 	//
294 	//  Truncate at the 12th bit (0xf), and shift right 12 bits
295 	//  to just get bitrange 15 -> 12.
296 
297 	value_part = ((*header >> 12 ) & 0xf);
298 
299 	//  Column 5 is for everything else (junk)
300 	if (FI->MPV_1 && FI->L1)
301 		column_part = 0;
302 
303 	else if (FI->MPV_1 && FI->L2)
304 		column_part = 1;
305 
306 	else if (FI->MPV_1 && FI->L3)
307 		column_part = 2;
308 
309 	else if ((FI->MPV_2 || FI->MPV_25) && FI->L1)
310 		column_part = 3;
311 
312 	else if ((FI->MPV_2 || FI->MPV_25) && (FI->L2 || FI->L3))
313 		column_part = 4;
314 
315 	else
316 		column_part = 5;
317 
318 
319 	FI->BIT_RATE = bitrate_matrix[column_part][value_part];
320 
321 
322 	//
323 	//  Sampling Rate
324 	//
325 	//  Truncate at the 2nd bit (0x3), and shift right 9 bits
326 	//  to just get bitrange 11 -> 10.
327 
328 	value_part = ((*header >> 10) & 0x3);
329 
330 	if (FI->MPV_1)
331 		FI->SAMPLE_FREQ = sampling_rate_matrix[value_part][0];
332 
333 	else if (FI->MPV_2)
334 		FI->SAMPLE_FREQ = sampling_rate_matrix[value_part][1];
335 
336 	else if (FI->MPV_25)
337 		FI->SAMPLE_FREQ = sampling_rate_matrix[value_part][2];
338 
339 	else
340 		FI->SAMPLE_FREQ = 0;
341 
342 
343 	//
344 	//  Padding Bit
345 	//
346 	if (cmp_str(bin_string, "1", 9))
347 		FI->PAD_BIT = TRUE;
348 
349 
350 	//
351 	//  Private Bit
352 	//
353 	if (cmp_str(bin_string, "1", 8))
354 		FI->PRIV_BIT = TRUE;
355 
356 
357 	//
358 	//  Get the channel mode
359 	//
360 	//  The 'mode_extension' will be added later
361 	//  perhaps in V2.0.
362 	//
363 	if (cmp_str(bin_string, "00", 7))
364 		FI->STEREO = TRUE;
365 
366 	else if (cmp_str(bin_string, "01", 7))
367 		{
368 		FI->JOINT_STEREO = TRUE;
369 		FI->MODE_EXTENSION = TRUE;
370 		}
371 
372 	else if (cmp_str(bin_string, "10", 7))
373 		FI->DUAL_STEREO = TRUE;
374 
375 	else if (cmp_str(bin_string, "11", 7))
376 		FI->SINGLE_CHANNEL = TRUE;
377 
378 
379 	//
380 	//  Copyright Bit
381 	//
382 	if (cmp_str(bin_string, "1", 3))
383 		FI->COPYRIGHT = TRUE;
384 
385 
386 	//
387 	//  Original Bit
388 	//
389 	if (cmp_str(bin_string, "1", 2))
390 		FI->ORIGINAL = TRUE;
391 
392 
393 	//
394 	//  Emphasis
395 	//
396 	if (cmp_str(bin_string, "00", 1))
397 		FI->EMPH_NONE = TRUE;
398 
399 	else if (cmp_str(bin_string, "01", 1))
400 		FI->EMPH_5015 = TRUE;
401 
402 	else if (cmp_str(bin_string, "10", 1))
403 		FI->EMPH_RESERV = TRUE;
404 
405 	else if (cmp_str(bin_string, "11", 1))
406 		FI->EMPH_CCIT = TRUE;
407 
408 
409 	//
410 	//  FRAME LENGTH
411 	//
412 	if (FI->SAMPLE_FREQ > 0) {
413 		if (FI->MPV_1) {
414 			if (FI->L1 && FI->PAD_BIT == TRUE) {
415 				FI->FRAME_LENGTH = (12 * FI->BIT_RATE * 1000 / FI->SAMPLE_FREQ + 4) * 4;
416 
417 			} else if (FI->L1 && FI->PAD_BIT == FALSE) {
418 				FI->FRAME_LENGTH = (12 * FI->BIT_RATE * 1000 / FI->SAMPLE_FREQ) * 4;
419 
420 			} else if ((FI->L2 || FI->L3) && FI->PAD_BIT == TRUE) {
421 				FI->FRAME_LENGTH = (144 * FI->BIT_RATE * 1000 / FI->SAMPLE_FREQ + 1);
422 
423 			} else if ((FI->L2 || FI->L3) && FI->PAD_BIT == FALSE) {
424 				FI->FRAME_LENGTH = (144 * FI->BIT_RATE * 1000 / FI->SAMPLE_FREQ);
425 			}
426 		} else if (FI->MPV_2 || FI->MPV_25) {
427 			if (FI->L1 && FI->PAD_BIT == TRUE) {
428 				FI->FRAME_LENGTH = (240 * FI->BIT_RATE * 1000 / FI->SAMPLE_FREQ + 4) * 4;
429 
430 			} else if (FI->L1 && FI->PAD_BIT == FALSE) {
431 				FI->FRAME_LENGTH = (240 * FI->BIT_RATE * 1000 / FI->SAMPLE_FREQ) * 4;
432 
433 			} else if ((FI->L2 || FI->L3) && FI->PAD_BIT == TRUE) {
434 				FI->FRAME_LENGTH = (72 * FI->BIT_RATE * 1000 / FI->SAMPLE_FREQ + 1);
435 
436 			} else if ((FI->L2 || FI->L3) && FI->PAD_BIT == FALSE) {
437 				FI->FRAME_LENGTH = (72 * FI->BIT_RATE * 1000 / FI->SAMPLE_FREQ);
438 			}
439 		}
440 	} else
441 		FI->FRAME_LENGTH = 0;
442 
443 
444 
445 	//
446 	//  ERROR TRAPPING HAPPENS HERE.
447 	//  IN FUTURE VERSIONS, I WILL CHECK FOR
448 	//  JOINT STEREO and INTENSITY STEREO.
449 	//
450 	if (FI->L_RESERVED || FI->BIT_RATE == 0 || FI->BIT_RATE == 1 || FI->SAMPLE_FREQ == 0)
451 		FI->check_state = FAIL;
452 
453 	else if (FI->L2 && FI->BIT_RATE == 32 && FI->SINGLE_CHANNEL == FALSE)
454 		FI->check_state = FAIL;
455 
456 	else if (FI->L2 && FI->BIT_RATE == 48 && FI->SINGLE_CHANNEL == FALSE)
457 		FI->check_state = FAIL;
458 
459 	else if (FI->L2 && FI->BIT_RATE == 56 && FI->SINGLE_CHANNEL == FALSE)
460 		FI->check_state = FAIL;
461 
462 	else if (FI->L2 && FI->BIT_RATE == 80 && FI->SINGLE_CHANNEL == FALSE)
463 		FI->check_state = FAIL;
464 
465 	else if (FI->L2 && FI->BIT_RATE == 32 && FI->SINGLE_CHANNEL == FALSE)
466 		FI->check_state = FAIL;
467 
468 	else if (FI->L2 && FI->BIT_RATE == 224 && !(FI->STEREO || FI->DUAL_STEREO))
469 		FI->check_state = FAIL;
470 
471 	else if (FI->L2 && FI->BIT_RATE == 256 && !(FI->STEREO || FI->DUAL_STEREO))
472 		FI->check_state = FAIL;
473 
474 	else if (FI->L2 && FI->BIT_RATE == 320 && !(FI->STEREO || FI->DUAL_STEREO))
475 		FI->check_state = FAIL;
476 
477 	else if (FI->L2 && FI->BIT_RATE == 384 && !(FI->STEREO || FI->DUAL_STEREO))
478 		FI->check_state = FAIL;
479 
480 
481 	return FI->check_state;
482 }
483 
484 void
print_sys_usage(void)485 print_sys_usage(void)
486 {
487 	struct	rusage	process_usage;
488 
489 	if (getrusage(RUSAGE_SELF, &process_usage))
490 		(void)fprintf(stderr, "Could not get system usage for myself.");
491 	else {
492 		printf("\n");
493 		printf("%-20s%1ld.%02lds\n", "USER_TIME", process_usage.ru_utime.tv_sec, process_usage.ru_utime.tv_usec / 10000);
494 		printf("%-20s%1ld.%02lds\n", "SYS_TIME", process_usage.ru_stime.tv_sec, process_usage.ru_stime.tv_usec / 10000);
495 	}
496 }
497 
498 int
rotate_char_array(byte_list,new_byte,file_info)499 rotate_char_array(byte_list, new_byte, file_info)
500 	char	*byte_list;
501 	int	*new_byte;
502 	gen_info *file_info;
503 {
504 	int	place_holder = 0;
505 
506 	//  I don't think it'll get any faster than this.
507 	place_holder = file_info->byte_count % 128;
508 
509 	*(byte_list + place_holder) = *new_byte;
510 
511 	return(TRUE);
512 }
513 
514 int
transform_char_array(byte_list,file_info)515 transform_char_array(byte_list, file_info)
516 	char	*byte_list;
517 	gen_info *file_info;
518 {
519 	int	place_holder = 0;
520 	int	counter;
521 	char	trans_list[128] = {'*'};
522 
523 	place_holder = file_info->byte_count % 128 + 1;
524 
525 	//  This is going to be a little confusing
526 	//  at the 'place_holder' mark, the data from place_holder to 127
527 	//  is the oldest, and data from 0 to place_holder is newest
528 
529 	//  Get the oldest stuff first, and put it at the beginning
530 	//  of the array.
531 	for(counter = place_holder; counter < 128; counter++)
532 		*(trans_list + (counter - place_holder)) = *(byte_list + counter);
533 
534 	// Now, grab the newest stuff, and slap it at the end of the array.
535 	for(counter = 0; counter < place_holder; counter++)
536 		*(trans_list + (128 - place_holder + counter)) = *(byte_list + counter);
537 
538 	memcpy(byte_list, trans_list, 128);
539 
540 	return(TRUE);
541 }
542 
543 void
translate_time(file_info,song_time)544 translate_time(file_info, song_time)
545 	mp3_time 	*song_time;
546 	gen_info	*file_info;
547 {
548 	double float_minute = 0.0;
549 	double float_second = 0.0;
550 
551 	float_minute = file_info->time_in_seconds / 60.0;
552 	float_second = 60.0 * (float_minute - (int)float_minute);
553 
554 	//  Return the values.
555 	song_time->frac_second = 100.0 * (float_second - (int)float_second);
556 	song_time->minutes = (int)float_minute;
557 	song_time->seconds = (int)float_second;
558 }
559 
560 int
dump_id3_tag(id3_tag)561 dump_id3_tag(id3_tag)
562 	id3_tag_info    *id3_tag;
563 {
564 	char	title[30];
565 	char	artist[30];
566 	char	album[30];
567 	char	year[4];
568 	char	comment[30];
569 	int	i = 0;
570 
571 
572 	memset(title, '\0', sizeof(title));
573 	memset(artist, '\0', sizeof(artist));
574 	memset(album, '\0', sizeof(album));
575 	memset(year, '\0', sizeof(year));
576 	memset(comment, '\0', sizeof(comment));
577 
578 	// The rules state, that nulls should pad the fields,
579 	// so, that is what I am doing here.
580 
581 	strncpy(title, id3_tag->TITLE, get_last_char_offset(id3_tag->TITLE));
582 	strncpy(artist, id3_tag->ARTIST, get_last_char_offset(id3_tag->ARTIST));
583 	strncpy(album, id3_tag->ALBUM, get_last_char_offset(id3_tag->ALBUM));
584 	strncpy(year, id3_tag->YEAR, get_last_char_offset(id3_tag->YEAR));
585 	strncpy(comment, id3_tag->COMMENT, get_last_char_offset(id3_tag->COMMENT));
586 
587 
588 	// Now, I am going to send the null-pointed fields to the file pointer.
589 	// This below is not very elegant. It works though,
590 	// so I will revisit this at a later time.
591 	//
592 	// The problem is that I need to print the null values,
593 	// if I didn't need to do that, it would be much cleaner.
594 
595 
596 	fputs("TAG", stdout);
597 
598 	for(i=0; i < 30; i++)
599 		fputc(*(title + i), stdout);
600 
601 	for(i=0; i < 30; i++)
602 		fputc(*(artist + i), stdout);
603 
604 	for(i=0; i < 30; i++)
605 		fputc(*(album + i), stdout);
606 
607 	for(i=0; i < 4; i++)
608 		fputc(*(year + i), stdout);
609 
610 
611 	// It's 29 because the last byte may
612 	// be the track number.
613 
614 	for(i=0; i < 29; i++)
615 		fputc(*(comment + i), stdout);
616 
617 	if(id3_tag->TRACK_NUMBER != 0)
618 		fputc(id3_tag->TRACK_NUMBER, stdout);
619 	else
620 		fputc(*(comment + 29), stdout);
621 
622 
623 	fputc(id3_tag->GENRE, stdout);
624 
625 	return(TRUE);
626 }
627 
628 int
get_last_char_offset(fat_string)629 get_last_char_offset(fat_string)
630 	char *fat_string;
631 {
632 	int	i = 0;
633 
634 	for (i = strlen(fat_string) - 1 ; i >= 0 ; i--) {
635 		if (isgraph((int)*(fat_string + i)))
636 			return(i + 1);
637 	}
638 
639 	return(strlen(fat_string));
640 }
641 
642 int
check_vbr_and_time(mp3_i,vbr_info,file_info)643 check_vbr_and_time(mp3_i, vbr_info, file_info)
644 	frame_info	*mp3_i;
645 	vbr_data	*vbr_info;
646 	gen_info	*file_info;
647 {
648 	//
649 	//  Lets get the time of this frame, and
650 	//  add it to the total length of the mp3 file
651 	//
652 	file_info->time_in_seconds += (mp3_i->SAMPLES_PER_FRAME * 1.0) / (mp3_i->SAMPLE_FREQ * 1.0);
653 
654 	//
655 	//  Time to do some nifty VBR checking.
656 	//
657 	if (vbr_info->high_rate < mp3_i->BIT_RATE)
658 		vbr_info->high_rate = mp3_i->BIT_RATE;
659 
660 	if ((mp3_i->BIT_RATE < vbr_info->low_rate) || (vbr_info->low_rate == 0))
661 		vbr_info->low_rate = mp3_i->BIT_RATE;
662 
663 
664 	//  Get a running total for division at the end.
665 	vbr_info->sum_rate += mp3_i->BIT_RATE;
666 
667 	return(TRUE);
668 }
669 
670 int
print_frame_info(mp3_i,file_info)671 print_frame_info(mp3_i, file_info)
672 	frame_info	*mp3_i;
673 	gen_info	*file_info;
674 {
675 	printf("\n");
676 	printf("%-20s%d\n", "FRAME", file_info->good_frame_count);
677 	printf("%-20s%d\n", "FrameOffset", file_info->byte_count);
678 	printf("%-20s%d\n", "FrameLength", mp3_i->FRAME_LENGTH);
679 	printf("%-20s%d\n", "FrameDataLength", mp3_i->FRAME_DATA_LENGTH);
680 	printf("%-20s%d\n", "BitRate", mp3_i->BIT_RATE);
681 	printf("%-20s%d\n", "SampRate", mp3_i->SAMPLE_FREQ);
682 	printf("%-20s%s\n", "BinString", mp3_i->BIN_STRING);
683 	printf("%-20s%d\n", "BinLen", strlen(mp3_i->BIN_STRING));
684 	printf("%-20s%u\n", "IntHeader", mp3_i->INT_HEADER);
685 	printf("%-20s0x%x\n", "CRC16Value", mp3_i->CRC16_VALUE);
686 	printf("%-20s0x%x\n", "Correct_CRC16Value", mp3_i->CORRECT_CRC16_VALUE);
687 	printf("%-20s%d\n", "NEXT_FRAME", file_info->byte_count + mp3_i->FRAME_LENGTH);
688 
689 	return(TRUE);
690 }
691