added libjson-c. added driver, webinterface and userspace daemon for the fonera mp3...
[oweals/openwrt.git] / package / fonera-mp3 / src / lib / mp3_file.c
1 /*
2 * FOXMP3 
3 * Copyright (c) 2006 acmesystems.it - john@acmesystems.it
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
18 *
19 * Feedback, Bugs...  info@acmesystems.it 
20 *
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <string.h>
29
30 #include "mp3.h"
31
32
33 #define MP3_PRE_BUFFER_COUNT    ((128 * 1024) / MP3_CHUNK_SIZE)
34
35
36 typedef struct _MP3_FILE {
37         unsigned char filename[2048];
38         MP3_DATA mp3_data;
39         FILE *fd;       
40         unsigned char file_end_found;
41         MP3_FILE_ID3 *id3;
42 } MP3_FILE;
43
44 static MP3_FILE mp3_file;
45
46 void mp3_load_id3(FILE *fp){
47         unsigned char *buf = malloc(1024);
48         
49         mp3_file.id3->album[0] = '\0';
50         mp3_file.id3->artist[0] = '\0';
51         mp3_file.id3->track[0] = '\0';
52         
53         
54         fgets(buf, 1024, fp);
55         if( (buf[0] == 'I') &&
56                 (buf[1] == 'D') &&
57                 (buf[2] == '3')){
58                 unsigned int id3_size;
59                 unsigned int i;
60                 unsigned int id3_version = buf[3];
61                 id3_version <<= 8;
62                 id3_version += buf[4];
63                 
64                 id3_size = 0;
65                 
66                 for(i = 0; i<4; i++){
67                         id3_size += buf[5 + i];
68                         id3_size <<= 7;
69                 };              
70                 if(id3_version>>8 == 3){
71                         unsigned int id3_pos = 10;
72                         unsigned int id3_tag_size;
73                         unsigned char tag_name[5];
74                         unsigned char tag_data[257];
75                         tag_name[4] = '\0';
76                         tag_data[256] = '\0';
77                         unsigned int count = 0;
78                         while(count < 10){
79                                 strncpy(tag_name, &buf[id3_pos], 4);
80                                 id3_tag_size = buf[id3_pos + 4];
81                                 id3_tag_size <<= 8;
82                                 id3_tag_size = buf[id3_pos + 5];
83                                 id3_tag_size <<= 8;
84                                 id3_tag_size = buf[id3_pos + 6];
85                                 id3_tag_size <<= 8;
86                                 id3_tag_size = buf[id3_pos + 7];
87                                 if(id3_tag_size == 0){
88                                         break;
89                                 };
90                                 if(id3_tag_size > 256){
91                                         memcpy(&tag_data[0], &buf[id3_pos + 11] , 256);
92                                 } else {
93                                         memcpy(&tag_data[0], &buf[id3_pos + 11] , 
94                                                         id3_tag_size -1);
95                                         tag_data[id3_tag_size-1] = '\0';
96                                 };
97                                 id3_pos += 10 + id3_tag_size;
98                                 if(strcmp(tag_name, "TPE1") == 0){
99                                         strncpy(mp3_file.id3->artist, tag_data, 255);
100                                 };
101                                 if(strcmp(tag_name, "TALB") == 0){
102                                         strncpy(mp3_file.id3->album, tag_data, 255);
103                                 };
104                                 if(strcmp(tag_name, "TIT2") == 0){
105                                         strncpy(mp3_file.id3->track, tag_data, 255);
106                                 };
107                                 if(id3_pos >= id3_size){
108                                         break;
109                                 };
110                                 count ++;
111                         };
112                 };
113                 printf("ID3 tag found Version 2.%d.%d / size %d\n%s -- %s -- %s\n", 
114                                 id3_version>>8, 
115                                 id3_version&0xff, 
116                                 id3_size,
117                                 mp3_file.id3->artist, 
118                                 mp3_file.id3->album,
119                                 mp3_file.id3->track);
120         } else {
121                 printf("No ID3 Tag was found\n");
122         };
123         free(buf);
124 };
125
126
127 int mp3_file_setup(unsigned char *filename, MP3_FILE_ID3 *id3){
128         unsigned int i;
129         mp3_file.id3 = id3;
130         mp3_file.file_end_found = 0;
131         strcpy(mp3_file.filename, filename);            
132         mp3_file.fd = fopen(mp3_file.filename, "rb");
133         if(!mp3_file.fd){
134                 mp3_file.fd = 0;
135                 printf("error opening file %s\n", mp3_file.filename);
136                 return MP3_ERROR;
137         };
138         printf("File %s opened Ok\n", mp3_file.filename);
139         printf("Reading id3 tag\n");
140         mp3_load_id3(mp3_file.fd);
141         fseek(mp3_file.fd, 0, SEEK_SET);
142         
143         mp3_reset();
144         
145         printf("Buffering MP3 Data\n");
146         mp3_file.mp3_data.state = MP3_BUFFERING;
147         for(i = 0; i < MP3_PRE_BUFFER_COUNT - 1; i++){
148                 fread(mp3_file.mp3_data.mp3, MP3_CHUNK_SIZE, 1, mp3_file.fd);
149                 mp3_file.mp3_data.state = MP3_PLAYING;
150                 mp3_send_data_to_buffer(mp3_file.mp3_data);
151         };
152
153         printf("Starting to play file : %s\n", mp3_file.filename);
154         return MP3_OK;  
155 };
156
157 int mp3_file_handle(void){
158         unsigned char transmit_success = 1;
159         if (!feof(mp3_file.fd)) {
160                 fread(mp3_file.mp3_data.mp3, MP3_CHUNK_SIZE, 1, mp3_file.fd);
161                 transmit_success = 0;
162                 while(!transmit_success){
163                         if(!mp3_send_data_to_buffer(mp3_file.mp3_data)){
164                                 usleep(1);
165                                 transmit_success = 0;
166                         } else {
167                                 transmit_success = 1;
168                         };      
169                 };
170                 return MP3_OK;
171         } else {
172                 if(!mp3_file.file_end_found){
173                         mp3_file.mp3_data.state = MP3_BUFFER_FINISHED;
174                         mp3_send_data_to_buffer(mp3_file.mp3_data);
175                         printf("File end reached. Wait till kernel buffer has cleared.\n");
176                         mp3_file.file_end_found = 1;
177                 };
178                 if(!mp3_buffer_finished()){
179                         return MP3_OK;
180                 } else {
181                         return MP3_END;
182                 };
183         };
184 };
185         
186 int mp3_file_cleanup(void){
187         if(mp3_file.fd){
188                 fclose(mp3_file.fd);
189         };
190         return MP3_OK;
191 };