1 
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <sys/ioctl.h>
5 #include <unistd.h>
6 #include <ctype.h>
7 
8 #define A8HZ_MP3_OUTPUT_BUF_LENGTH  1024
9 #define A8HZ_MP3_OUTPUT_LINE_LENGTH 32
10 
11 #define CD_SECTORS_PER_FRAME        (float)1.959
12 
13 #define PRINTOUT_INTERVAL           0.5
14 
15 int a8hz_mp3_read_stat (unsigned *current);
16 int find_a8hz_mp3_output_read_offset (char *buf, int begin, int end);
17 void print_msg (int length, int current);
18 
19 int
a8hz_mp3_read_stat(unsigned * current)20 a8hz_mp3_read_stat (unsigned *current)
21 {
22 	static char buf[A8HZ_MP3_OUTPUT_BUF_LENGTH];
23 	int temp_offset, read_offset;
24 	ssize_t bytes_read;
25 	int bytes_avail, count;
26 	static int prev_bytes_avail;
27 
28 	ioctl (0, FIONREAD, &bytes_avail);
29 	if (bytes_avail < 4 * A8HZ_MP3_OUTPUT_LINE_LENGTH) {
30 		if (bytes_avail == prev_bytes_avail)
31 			/* nothing available, let's wait */
32 			return -1;
33 		else {
34 			/* Record available bytes, and let's just wait */
35 			prev_bytes_avail = bytes_avail;
36 			return -1;
37 		}
38 	}
39 	prev_bytes_avail = -1;
40 
41 	count = 0;
42 	do {
43 		bytes_read = read (0, (void *) buf, sizeof (buf));
44 		temp_offset = bytes_read - 4 * A8HZ_MP3_OUTPUT_LINE_LENGTH - 1;
45 		read_offset = find_a8hz_mp3_output_read_offset (buf,
46 		              temp_offset,
47 		              sizeof (buf) - 1);
48 		if (read_offset < 0
49 			        || read_offset > sizeof (buf) - A8HZ_MP3_OUTPUT_LINE_LENGTH) {
50 			if (count == 0)
51 				return -1;
52 			else
53 				break;
54 		}
55 		sscanf (buf + read_offset, "%u", current);
56 		/* Convert it to cd sector unit */
57 		*current *= CD_SECTORS_PER_FRAME;
58 		count++;
59 	} while (bytes_read == sizeof (buf));
60 
61 	return 0;
62 }
63 
64 int
find_a8hz_mp3_output_read_offset(char * buf,int begin,int end)65 find_a8hz_mp3_output_read_offset (char *buf, int begin, int end)
66 {
67 	int i;
68 
69 	i = begin;
70 
71 	do {
72 		while (buf[i] != 'F' && i <= end - 5)
73 			i++;
74 
75 		if (buf[i + 1] == 'r' && isdigit (buf[i + 11]))
76 			return i + 5;
77 		else
78 			i++;
79 	} while (i <= end - 5);
80 	return -1;
81 }
82 
83 // print out [P 0.xxxx]\n
84 void
print_msg(int length,int current)85 print_msg (int length, int current)
86 {
87 	printf ("[P ");
88 	printf ("%f]\n", (double) current / (double) length);
89 }
90 
91 int
main(int argc,char ** argv)92 main (int argc, char **argv)
93 {
94 	int begin, length;
95 	int current;
96 
97 	if (argc != 3) {
98 		fprintf (stderr, "This is ripperX plugin for 8hz-mp3. Syntax is\n"
99 		         "ripperX_plugin-8hz-mp3 beginning_sector length_in_sector\n");
100 		exit (1);
101 	}
102 
103 	sscanf (argv[1], "%d", &begin);
104 	sscanf (argv[2], "%d", &length);
105 
106 	while (1) {
107 		if (a8hz_mp3_read_stat (&current) == 0)
108 			print_msg (length, current);
109 		usleep (PRINTOUT_INTERVAL * 1000000);
110 	}
111 }
112