summaryrefslogtreecommitdiff
authorharlekin <harlekin>2002-04-21 12:00:04 (UTC)
committer harlekin <harlekin>2002-04-21 12:00:04 (UTC)
commitc7a23ea04b627db855934fac5061d7e291cdf230 (patch) (unidiff)
tree1c9e8d615e70f53a17f7dfb055a7aee5b4912d12
parent6cf7106e761ed81c28f73338f2e431b41d54ed4e (diff)
downloadopie-c7a23ea04b627db855934fac5061d7e291cdf230.zip
opie-c7a23ea04b627db855934fac5061d7e291cdf230.tar.gz
opie-c7a23ea04b627db855934fac5061d7e291cdf230.tar.bz2
added udp support
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmad/libmadplugin.cpp72
-rw-r--r--core/multimedia/opieplayer/libmad/libmadplugin.h2
2 files changed, 69 insertions, 5 deletions
diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.cpp b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
index 7bb6541..6793773 100644
--- a/core/multimedia/opieplayer/libmad/libmadplugin.cpp
+++ b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
@@ -1,766 +1,828 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved. 2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#include <stdio.h> 20#include <stdio.h>
21#include <stdarg.h> 21#include <stdarg.h>
22#include <stdlib.h> 22#include <stdlib.h>
23#include <sys/types.h> 23#include <sys/types.h>
24#include <sys/stat.h> 24#include <sys/stat.h>
25#include <fcntl.h> 25#include <fcntl.h>
26#include <unistd.h> 26#include <unistd.h>
27#include <string.h> 27#include <string.h>
28#include <ctype.h> 28#include <ctype.h>
29#include <errno.h> 29#include <errno.h>
30#include <time.h> 30#include <time.h>
31#include <locale.h> 31#include <locale.h>
32#include <math.h> 32#include <math.h>
33#include <assert.h> 33#include <assert.h>
34#include <qapplication.h> 34#include <qapplication.h>
35#include <qpe/config.h> 35#include <qpe/config.h>
36 36
37// for network handling 37// for network handling
38#include <netinet/in.h> 38#include <netinet/in.h>
39#include <netdb.h> 39#include <netdb.h>
40#include <sys/socket.h> 40#include <sys/socket.h>
41#include <arpa/inet.h> 41#include <arpa/inet.h>
42#include <unistd.h> 42#include <unistd.h>
43 43
44 44
45//#define HAVE_MMAP 45//#define HAVE_MMAP
46 46
47#if defined(HAVE_MMAP) 47#if defined(HAVE_MMAP)
48# include <sys/mman.h> 48# include <sys/mman.h>
49#endif 49#endif
50#include "libmadplugin.h" 50#include "libmadplugin.h"
51 51
52 52
53extern "C" { 53extern "C" {
54#include "mad.h" 54#include "mad.h"
55} 55}
56 56
57 57
58#define MPEG_BUFFER_SIZE 65536 58#define MPEG_BUFFER_SIZE 65536
59//#define MPEG_BUFFER_SIZE 32768 //16384 // 8192 59//#define MPEG_BUFFER_SIZE 32768 //16384 // 8192
60//#define debugMsg(a) qDebug(a) 60//#define debugMsg(a) qDebug(a)
61#define debugMsg(a) 61#define debugMsg(a)
62 62
63 63
64class Input { 64class Input {
65public: 65public:
66 char const *path; 66 char const *path;
67 int fd; 67 int fd;
68#if defined(HAVE_MMAP) 68#if defined(HAVE_MMAP)
69 void *fdm; 69 void *fdm;
70#endif 70#endif
71 unsigned char *data; 71 unsigned char *data;
72 unsigned long length; 72 unsigned long length;
73 int eof; 73 int eof;
74}; 74};
75 75
76 76
77class Output { 77class Output {
78public: 78public:
79 mad_fixed_t attenuate; 79 mad_fixed_t attenuate;
80 struct filter *filters; 80 struct filter *filters;
81 unsigned int channels_in; 81 unsigned int channels_in;
82 unsigned int channels_out; 82 unsigned int channels_out;
83 unsigned int speed_in; 83 unsigned int speed_in;
84 unsigned int speed_out; 84 unsigned int speed_out;
85 const char *path; 85 const char *path;
86}; 86};
87 87
88 88
89# if defined(HAVE_MMAP) 89# if defined(HAVE_MMAP)
90static void *map_file(int fd, unsigned long *length) 90static void *map_file(int fd, unsigned long *length)
91{ 91{
92 void *fdm; 92 void *fdm;
93 93
94 *length += MAD_BUFFER_GUARD; 94 *length += MAD_BUFFER_GUARD;
95 95
96 fdm = mmap(0, *length, PROT_READ, MAP_SHARED, fd, 0); 96 fdm = mmap(0, *length, PROT_READ, MAP_SHARED, fd, 0);
97 if (fdm == MAP_FAILED) 97 if (fdm == MAP_FAILED)
98 return 0; 98 return 0;
99 99
100# if defined(HAVE_MADVISE) 100# if defined(HAVE_MADVISE)
101 madvise(fdm, *length, MADV_SEQUENTIAL); 101 madvise(fdm, *length, MADV_SEQUENTIAL);
102# endif 102# endif
103 103
104 return fdm; 104 return fdm;
105} 105}
106 106
107 107
108static int unmap_file(void *fdm, unsigned long length) 108static int unmap_file(void *fdm, unsigned long length)
109{ 109{
110 if (munmap(fdm, length) == -1) 110 if (munmap(fdm, length) == -1)
111 return -1; 111 return -1;
112 112
113 return 0; 113 return 0;
114} 114}
115# endif 115# endif
116 116
117 117
118static inline QString tr( const char *str ) { 118static inline QString tr( const char *str ) {
119 // Apparently this is okay from a plugin as it runs in the process space of the owner of the plugin 119 // Apparently this is okay from a plugin as it runs in the process space of the owner of the plugin
120 return qApp->translate( "OpiePlayer", str, "libmad strings for mp3 file info" ); 120 return qApp->translate( "OpiePlayer", str, "libmad strings for mp3 file info" );
121} 121}
122 122
123 123
124class LibMadPluginData { 124class LibMadPluginData {
125public: 125public:
126 Input input; 126 Input input;
127 Output output; 127 Output output;
128 int bad_last_frame; 128 int bad_last_frame;
129 struct mad_stream stream; 129 struct mad_stream stream;
130 struct mad_frame frame; 130 struct mad_frame frame;
131 struct mad_synth synth; 131 struct mad_synth synth;
132 bool flush; 132 bool flush;
133}; 133};
134 134
135 135
136LibMadPlugin::LibMadPlugin() { 136LibMadPlugin::LibMadPlugin() {
137 d = new LibMadPluginData; 137 d = new LibMadPluginData;
138 d->input.fd = 0; 138 d->input.fd = 0;
139#if defined(HAVE_MMAP) 139#if defined(HAVE_MMAP)
140 d->input.fdm = 0; 140 d->input.fdm = 0;
141#endif 141#endif
142 d->input.data = 0; 142 d->input.data = 0;
143 d->flush = TRUE; 143 d->flush = TRUE;
144 info = tr( "No Song Open" ); 144 info = tr( "No Song Open" );
145} 145}
146 146
147 147
148LibMadPlugin::~LibMadPlugin() { 148LibMadPlugin::~LibMadPlugin() {
149 close(); 149 close();
150 delete d; 150 delete d;
151} 151}
152 152
153 153
154bool LibMadPlugin::isFileSupported( const QString& path ) { 154bool LibMadPlugin::isFileSupported( const QString& path ) {
155 debugMsg( "LibMadPlugin::isFileSupported" ); 155 debugMsg( "LibMadPlugin::isFileSupported" );
156 156
157 // Mpeg file extensions 157 // Mpeg file extensions
158 // "mp2","mp3","m1v","m2v","m2s","mpg","vob","mpeg","ac3" 158 // "mp2","mp3","m1v","m2v","m2s","mpg","vob","mpeg","ac3"
159 // Other media extensions 159 // Other media extensions
160 // "wav","mid","mod","s3m","ogg","avi","mov","sid" 160 // "wav","mid","mod","s3m","ogg","avi","mov","sid"
161 161
162 char *ext = strrchr( path.latin1(), '.' ); 162 char *ext = strrchr( path.latin1(), '.' );
163 163
164 // Test file extension 164 // Test file extension
165 if ( ext ) { 165 if ( ext ) {
166 if ( strncasecmp(ext, ".mp2", 4) == 0 ) 166 if ( strncasecmp(ext, ".mp2", 4) == 0 )
167 return TRUE; 167 return TRUE;
168 if ( strncasecmp(ext, ".mp3", 4) == 0 ) 168 if ( strncasecmp(ext, ".mp3", 4) == 0 )
169 return TRUE; 169 return TRUE;
170 } 170 }
171
171 // UGLY - just for fast testing 172 // UGLY - just for fast testing
172 if ( path.left(4) == "http") { 173 if ( path.left(4) == "http") {
173 return TRUE; 174 return TRUE;
174 } 175 }
175 176
177 return FALSE;
178}
179
176 180
177 return FALSE; 181
182int LibMadPlugin::is_address_multicast(unsigned long address) {
183 if ((address & 255) >= 224 && (address & 255) <= 239)
184 return (1);
185 return (0);
178} 186}
179 187
180 188
189int LibMadPlugin::udp_open(char *address, int port) {
190
191 int enable = 1L;
192 struct sockaddr_in stAddr;
193 struct sockaddr_in stLclAddr;
194 struct ip_mreq stMreq;
195 struct hostent *host;
196 int sock;
197
198 stAddr.sin_family = AF_INET;
199 stAddr.sin_port = htons(port);
200
201 if ((host = gethostbyname(address)) == NULL)
202 return (0);
203
204 stAddr.sin_addr = *((struct in_addr *)host->h_addr_list[0]);
205
206 /* Create a UDP socket */
207 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
208 return (0);
209
210 /* Allow multiple instance of the client to share the same address and port */
211 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&enable, sizeof(unsigned long int)) < 0)
212 return (0);
213
214 /* If the address is multicast, register to the multicast group */
215 if (is_address_multicast(stAddr.sin_addr.s_addr))
216 {
217 /* Bind the socket to port */
218 stLclAddr.sin_family = AF_INET;
219 stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY);
220 stLclAddr.sin_port = stAddr.sin_port;
221 if (bind(sock, (struct sockaddr *)&stLclAddr, sizeof(stLclAddr)) < 0)
222 return (0);
223
224 /* Register to a multicast address */
225 stMreq.imr_multiaddr.s_addr = stAddr.sin_addr.s_addr;
226 stMreq.imr_interface.s_addr = INADDR_ANY;
227 if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&stMreq, sizeof(stMreq)) < 0)
228 return (0);
229 }
230 else
231 {
232 /* Bind the socket to port */
233 stLclAddr.sin_family = AF_INET;
234 stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY);
235 stLclAddr.sin_port = htons(0);
236 if (bind(sock, (struct sockaddr *)&stLclAddr, sizeof(stLclAddr)) < 0)
237 return (0);
238 }
239
240 return (sock);
241}
242
181int LibMadPlugin::tcp_open(char *address, int port) { 243int LibMadPlugin::tcp_open(char *address, int port) {
182 struct sockaddr_in stAddr; 244 struct sockaddr_in stAddr;
183 struct hostent *host; 245 struct hostent *host;
184 int sock; 246 int sock;
185 struct linger l; 247 struct linger l;
186 248
187 memset(&stAddr, 0, sizeof(stAddr)); 249 memset(&stAddr, 0, sizeof(stAddr));
188 stAddr.sin_family = AF_INET; 250 stAddr.sin_family = AF_INET;
189 stAddr.sin_port = htons(port); 251 stAddr.sin_port = htons(port);
190 252
191 if ((host = gethostbyname(address)) == NULL) 253 if ((host = gethostbyname(address)) == NULL)
192 return (0); 254 return (0);
193 255
194 stAddr.sin_addr = *((struct in_addr *)host->h_addr_list[0]); 256 stAddr.sin_addr = *((struct in_addr *)host->h_addr_list[0]);
195 257
196 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 258 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
197 return (0); 259 return (0);
198 260
199 l.l_onoff = 1; 261 l.l_onoff = 1;
200 l.l_linger = 5; 262 l.l_linger = 5;
201 if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l)) < 0) 263 if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l)) < 0)
202 return (0); 264 return (0);
203 265
204 if (connect(sock, (struct sockaddr *)&stAddr, sizeof(stAddr)) < 0) 266 if (connect(sock, (struct sockaddr *)&stAddr, sizeof(stAddr)) < 0)
205 return (0); 267 return (0);
206 268
207 return (sock); 269 return (sock);
208} 270}
209 271
210 272
211/** 273/**
212 * Read a http line header. 274 * Read a http line header.
213 * This function read character by character. 275 * This function read character by character.
214 * @param tcp_sock the socket use to read the stream 276 * @param tcp_sock the socket use to read the stream
215 * @param buf a buffer to receive the data 277 * @param buf a buffer to receive the data
216 * @param size size of the buffer 278 * @param size size of the buffer
217 * @return the size of the stream read or -1 if an error occured 279 * @return the size of the stream read or -1 if an error occured
218 */ 280 */
219int LibMadPlugin::http_read_line(int tcp_sock, char *buf, int size) { 281int LibMadPlugin::http_read_line(int tcp_sock, char *buf, int size) {
220 int offset = 0; 282 int offset = 0;
221 283
222 do 284 do
223 { 285 {
224 if (std::read(tcp_sock, buf + offset, 1) < 0) 286 if (std::read(tcp_sock, buf + offset, 1) < 0)
225 return -1; 287 return -1;
226 if (buf[offset] != '\r') /* Strip \r from answer */ 288 if (buf[offset] != '\r') /* Strip \r from answer */
227 offset++; 289 offset++;
228 } 290 }
229 while (offset < size - 1 && buf[offset - 1] != '\n'); 291 while (offset < size - 1 && buf[offset - 1] != '\n');
230 292
231 buf[offset] = 0; 293 buf[offset] = 0;
232 return offset; 294 return offset;
233} 295}
234 296
235int LibMadPlugin::http_open(const QString& path ) { 297int LibMadPlugin::http_open(const QString& path ) {
236 char *host; 298 char *host;
237 int port; 299 int port;
238 char *request; 300 char *request;
239 int tcp_sock; 301 int tcp_sock;
240 char http_request[PATH_MAX]; 302 char http_request[PATH_MAX];
241 char filename[PATH_MAX]; 303 char filename[PATH_MAX];
242 char c; 304 char c;
243 char *arg =strdup(path.latin1()); 305 char *arg =strdup(path.latin1());
244 306
245 /* Check for URL syntax */ 307 /* Check for URL syntax */
246 if (strncmp(arg, "http://", strlen("http://"))) 308 if (strncmp(arg, "http://", strlen("http://")))
247 return (0); 309 return (0);
248 310
249 /* Parse URL */ 311 /* Parse URL */
250 port = 80; 312 port = 80;
251 host = arg + strlen("http://"); 313 host = arg + strlen("http://");
252 if ((request = strchr(host, '/')) == NULL) 314 if ((request = strchr(host, '/')) == NULL)
253 return (0); 315 return (0);
254 *request++ = 0; 316 *request++ = 0;
255 317
256 if (strchr(host, ':') != NULL) /* port is specified */ 318 if (strchr(host, ':') != NULL) /* port is specified */
257 { 319 {
258 port = atoi(strchr(host, ':') + 1); 320 port = atoi(strchr(host, ':') + 1);
259 *strchr(host, ':') = 0; 321 *strchr(host, ':') = 0;
260 } 322 }
261 323
262 /* Open a TCP socket */ 324 /* Open a TCP socket */
263 if (!(tcp_sock = tcp_open(host, port))) 325 if (!(tcp_sock = tcp_open(host, port)))
264 { 326 {
265 perror("http_open"); 327 perror("http_open");
266 return (0); 328 return (0);
267 } 329 }
268 330
269 snprintf(filename, sizeof(filename) - strlen(host) - 75, "%s", request); 331 snprintf(filename, sizeof(filename) - strlen(host) - 75, "%s", request);
270 332
271 /* Send HTTP GET request */ 333 /* Send HTTP GET request */
272 /* Please don't use a Agent know by shoutcast (Lynx, Mozilla) seems to be reconized and print 334 /* Please don't use a Agent know by shoutcast (Lynx, Mozilla) seems to be reconized and print
273 * a html page and not the stream */ 335 * a html page and not the stream */
274 snprintf(http_request, sizeof(http_request), "GET /%s HTTP/1.0\r\n" 336 snprintf(http_request, sizeof(http_request), "GET /%s HTTP/1.0\r\n"
275/* "User-Agent: Mozilla/2.0 (Win95; I)\r\n" */ 337/* "User-Agent: Mozilla/2.0 (Win95; I)\r\n" */
276 "Pragma: no-cache\r\n" "Host: %s\r\n" "Accept: */*\r\n" "\r\n", filename, host); 338 "Pragma: no-cache\r\n" "Host: %s\r\n" "Accept: */*\r\n" "\r\n", filename, host);
277 339
278 send(tcp_sock, http_request, strlen(http_request), 0); 340 send(tcp_sock, http_request, strlen(http_request), 0);
279 341
280 /* Parse server reply */ 342 /* Parse server reply */
281#if 0 343#if 0
282 do 344 do
283 read(tcp_sock, &c, sizeof(char)); 345 read(tcp_sock, &c, sizeof(char));
284 while (c != ' '); 346 while (c != ' ');
285 read(tcp_sock, http_request, 4 * sizeof(char)); 347 read(tcp_sock, http_request, 4 * sizeof(char));
286 http_request[4] = 0; 348 http_request[4] = 0;
287 if (strcmp(http_request, "200 ")) 349 if (strcmp(http_request, "200 "))
288 { 350 {
289 fprintf(stderr, "http_open: "); 351 fprintf(stderr, "http_open: ");
290 do 352 do
291 { 353 {
292 read(tcp_sock, &c, sizeof(char)); 354 read(tcp_sock, &c, sizeof(char));
293 fprintf(stderr, "%c", c); 355 fprintf(stderr, "%c", c);
294 } 356 }
295 while (c != '\r'); 357 while (c != '\r');
296 fprintf(stderr, "\n"); 358 fprintf(stderr, "\n");
297 return (0); 359 return (0);
298 } 360 }
299#endif 361#endif
300 362
301 do 363 do
302 { 364 {
303 int len; 365 int len;
304 366
305 len = http_read_line(tcp_sock, http_request, sizeof(http_request)); 367 len = http_read_line(tcp_sock, http_request, sizeof(http_request));
306 368
307 if (len == -1) 369 if (len == -1)
308 { 370 {
309 fprintf(stderr, "http_open: %s\n", strerror(errno)); 371 fprintf(stderr, "http_open: %s\n", strerror(errno));
310 return 0; 372 return 0;
311 } 373 }
312 374
313 if (strncmp(http_request, "Location:", 9) == 0) 375 if (strncmp(http_request, "Location:", 9) == 0)
314 { 376 {
315 /* redirect */ 377 /* redirect */
316 std::close(tcp_sock); 378 std::close(tcp_sock);
317 379
318 http_request[strlen(http_request) - 1] = '\0'; 380 http_request[strlen(http_request) - 1] = '\0';
319 381
320 return http_open(&http_request[10]); 382 return http_open(&http_request[10]);
321 } 383 }
322 384
323 if (strncmp(http_request, "ICY ", 4) == 0) 385 if (strncmp(http_request, "ICY ", 4) == 0)
324 { 386 {
325 /* This is icecast streaming */ 387 /* This is icecast streaming */
326 if (strncmp(http_request + 4, "200 ", 4)) 388 if (strncmp(http_request + 4, "200 ", 4))
327 { 389 {
328 fprintf(stderr, "http_open: %s\n", http_request); 390 fprintf(stderr, "http_open: %s\n", http_request);
329 return 0; 391 return 0;
330 } 392 }
331 } 393 }
332 else if (strncmp(http_request, "icy-", 4) == 0) 394 else if (strncmp(http_request, "icy-", 4) == 0)
333 { 395 {
334 /* we can have: icy-noticeX, icy-name, icy-genre, icy-url, icy-pub, icy-metaint, icy-br */ 396 /* we can have: icy-noticeX, icy-name, icy-genre, icy-url, icy-pub, icy-metaint, icy-br */
335 /* Don't print these - mpg123 doesn't */ 397 /* Don't print these - mpg123 doesn't */
336 /* fprintf(stderr,"%s\n",http_request); */ 398 /* fprintf(stderr,"%s\n",http_request); */
337 } 399 }
338 } 400 }
339 while (strcmp(http_request, "\n") != 0); 401 while (strcmp(http_request, "\n") != 0);
340 402
341 return (tcp_sock); 403 return (tcp_sock);
342} 404}
343 405
344 406
345bool LibMadPlugin::open( const QString& path ) { 407bool LibMadPlugin::open( const QString& path ) {
346 debugMsg( "LibMadPlugin::open" ); 408 debugMsg( "LibMadPlugin::open" );
347 Config cfg("MediaPlayer"); 409 Config cfg("MediaPlayer");
348 cfg.setGroup("Options"); 410 cfg.setGroup("Options");
349 bufferSize = cfg.readNumEntry("MPeg_BufferSize",MPEG_BUFFER_SIZE); 411 bufferSize = cfg.readNumEntry("MPeg_BufferSize",MPEG_BUFFER_SIZE);
350 qDebug("buffer size is %d", bufferSize); 412 qDebug("buffer size is %d", bufferSize);
351 d->bad_last_frame = 0; 413 d->bad_last_frame = 0;
352 d->flush = TRUE; 414 d->flush = TRUE;
353 info = QString( "" ); 415 info = QString( "" );
354 416
355 //qDebug( "Opening %s", path.latin1() ); 417 //qDebug( "Opening %s", path.latin1() );
356 418
357 419
358 if (path.left( 4 ) == "http" ) { 420 if (path.left( 4 ) == "http" ) {
359 d->input.fd = http_open(path); 421 d->input.fd = http_open(path);
360 422
361 } else { 423 } else {
362 d->input.path = path.latin1(); 424 d->input.path = path.latin1();
363 d->input.fd = ::open( d->input.path, O_RDONLY ); 425 d->input.fd = ::open( d->input.path, O_RDONLY );
364 } 426 }
365 if (d->input.fd == -1) { 427 if (d->input.fd == -1) {
366 qDebug("error opening %s", d->input.path ); 428 qDebug("error opening %s", d->input.path );
367 return FALSE; 429 return FALSE;
368 } 430 }
369 431
370 printID3Tags(); 432 printID3Tags();
371 433
372#if defined(HAVE_MMAP) 434#if defined(HAVE_MMAP)
373 struct stat stat; 435 struct stat stat;
374 if (fstat(d->input.fd, &stat) == -1) { 436 if (fstat(d->input.fd, &stat) == -1) {
375 qDebug("error calling fstat"); return FALSE; 437 qDebug("error calling fstat"); return FALSE;
376 } 438 }
377 if (S_ISREG(stat.st_mode) && stat.st_size > 0) { 439 if (S_ISREG(stat.st_mode) && stat.st_size > 0) {
378 d->input.length = stat.st_size; 440 d->input.length = stat.st_size;
379 d->input.fdm = map_file(d->input.fd, &d->input.length); 441 d->input.fdm = map_file(d->input.fd, &d->input.length);
380 if (d->input.fdm == 0) { 442 if (d->input.fdm == 0) {
381 qDebug("error mmapping file"); return FALSE; 443 qDebug("error mmapping file"); return FALSE;
382 } 444 }
383 d->input.data = (unsigned char *)d->input.fdm; 445 d->input.data = (unsigned char *)d->input.fdm;
384 } 446 }
385#endif 447#endif
386 448
387 if (d->input.data == 0) { 449 if (d->input.data == 0) {
388 d->input.data = (unsigned char *)malloc( bufferSize /*MPEG_BUFFER_SIZE*/); 450 d->input.data = (unsigned char *)malloc( bufferSize /*MPEG_BUFFER_SIZE*/);
389 if (d->input.data == 0) { 451 if (d->input.data == 0) {
390 qDebug("error allocating input buffer"); 452 qDebug("error allocating input buffer");
391 return FALSE; 453 return FALSE;
392 } 454 }
393 d->input.length = 0; 455 d->input.length = 0;
394 } 456 }
395 457
396 d->input.eof = 0; 458 d->input.eof = 0;
397 459
398 mad_stream_init(&d->stream); 460 mad_stream_init(&d->stream);
399 mad_frame_init(&d->frame); 461 mad_frame_init(&d->frame);
400 mad_synth_init(&d->synth); 462 mad_synth_init(&d->synth);
401 463
402 return TRUE; 464 return TRUE;
403} 465}
404 466
405 467
406bool LibMadPlugin::close() { 468bool LibMadPlugin::close() {
407 debugMsg( "LibMadPlugin::close" ); 469 debugMsg( "LibMadPlugin::close" );
408 470
409 int result = TRUE; 471 int result = TRUE;
410 472
411 mad_synth_finish(&d->synth); 473 mad_synth_finish(&d->synth);
412 mad_frame_finish(&d->frame); 474 mad_frame_finish(&d->frame);
413 mad_stream_finish(&d->stream); 475 mad_stream_finish(&d->stream);
414 476
415#if defined(HAVE_MMAP) 477#if defined(HAVE_MMAP)
416 if (d->input.fdm) { 478 if (d->input.fdm) {
417 if (unmap_file(d->input.fdm, d->input.length) == -1) { 479 if (unmap_file(d->input.fdm, d->input.length) == -1) {
418 qDebug("error munmapping file"); 480 qDebug("error munmapping file");
419 result = FALSE; 481 result = FALSE;
420 } 482 }
421 d->input.fdm = 0; 483 d->input.fdm = 0;
422 d->input.data = 0; 484 d->input.data = 0;
423 } 485 }
424#endif 486#endif
425 487
426 if (d->input.data) { 488 if (d->input.data) {
427 free(d->input.data); 489 free(d->input.data);
428 d->input.data = 0; 490 d->input.data = 0;
429 } 491 }
430 492
431 if (::close(d->input.fd) == -1) { 493 if (::close(d->input.fd) == -1) {
432 qDebug("error closing file %s", d->input.path); 494 qDebug("error closing file %s", d->input.path);
433 result = FALSE; 495 result = FALSE;
434 } 496 }
435 497
436 d->input.fd = 0; 498 d->input.fd = 0;
437 499
438 return result; 500 return result;
439} 501}
440 502
441 503
442bool LibMadPlugin::isOpen() { 504bool LibMadPlugin::isOpen() {
443 debugMsg( "LibMadPlugin::isOpen" ); 505 debugMsg( "LibMadPlugin::isOpen" );
444 return ( d->input.fd != 0 ); 506 return ( d->input.fd != 0 );
445} 507}
446 508
447 509
448int LibMadPlugin::audioStreams() { 510int LibMadPlugin::audioStreams() {
449 debugMsg( "LibMadPlugin::audioStreams" ); 511 debugMsg( "LibMadPlugin::audioStreams" );
450 return 1; 512 return 1;
451} 513}
452 514
453 515
454int LibMadPlugin::audioChannels( int ) { 516int LibMadPlugin::audioChannels( int ) {
455 debugMsg( "LibMadPlugin::audioChannels" ); 517 debugMsg( "LibMadPlugin::audioChannels" );
456/* 518/*
457 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); 519 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
458 qDebug( "LibMadPlugin::audioChannels: %i", d->frame.header.mode > 0 ? 2 : 1 ); 520 qDebug( "LibMadPlugin::audioChannels: %i", d->frame.header.mode > 0 ? 2 : 1 );
459 return d->frame.header.mode > 0 ? 2 : 1; 521 return d->frame.header.mode > 0 ? 2 : 1;
460*/ 522*/
461 return 2; 523 return 2;
462} 524}
463 525
464 526
465int LibMadPlugin::audioFrequency( int ) { 527int LibMadPlugin::audioFrequency( int ) {
466 debugMsg( "LibMadPlugin::audioFrequency" ); 528 debugMsg( "LibMadPlugin::audioFrequency" );
467 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); 529 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
468 qDebug( "LibMadPlugin::audioFrequency: %i", d->frame.header.samplerate ); 530 qDebug( "LibMadPlugin::audioFrequency: %i", d->frame.header.samplerate );
469 return d->frame.header.samplerate; 531 return d->frame.header.samplerate;
470} 532}
471 533
472 534
473int LibMadPlugin::audioSamples( int ) { 535int LibMadPlugin::audioSamples( int ) {
474 debugMsg( "LibMadPlugin::audioSamples" ); 536 debugMsg( "LibMadPlugin::audioSamples" );
475/* 537/*
476 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); 538 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
477 mad_header_decode( (struct mad_header *)&d->frame.header, &d->stream ); 539 mad_header_decode( (struct mad_header *)&d->frame.header, &d->stream );
478 qDebug( "LibMadPlugin::audioSamples: %i*%i", d->frame.header.duration.seconds, d->frame.header.samplerate ); 540 qDebug( "LibMadPlugin::audioSamples: %i*%i", d->frame.header.duration.seconds, d->frame.header.samplerate );
479 return d->frame.header.duration.seconds * d->frame.header.samplerate; 541 return d->frame.header.duration.seconds * d->frame.header.samplerate;
480*/ 542*/
481 return 10000000; 543 return 10000000;
482} 544}
483 545
484 546
485bool LibMadPlugin::audioSetSample( long, int ) { 547bool LibMadPlugin::audioSetSample( long, int ) {
486 debugMsg( "LibMadPlugin::audioSetSample" ); 548 debugMsg( "LibMadPlugin::audioSetSample" );
487 return FALSE; 549 return FALSE;
488} 550}
489 551
490 552
491long LibMadPlugin::audioGetSample( int ) { 553long LibMadPlugin::audioGetSample( int ) {
492 debugMsg( "LibMadPlugin::audioGetSample" ); 554 debugMsg( "LibMadPlugin::audioGetSample" );
493 return 0; 555 return 0;
494} 556}
495 557
496/* 558/*
497bool LibMadPlugin::audioReadSamples( short *, int, long, int ) { 559bool LibMadPlugin::audioReadSamples( short *, int, long, int ) {
498 debugMsg( "LibMadPlugin::audioReadSamples" ); 560 debugMsg( "LibMadPlugin::audioReadSamples" );
499 return FALSE; 561 return FALSE;
500} 562}
501 563
502 564
503bool LibMadPlugin::audioReReadSamples( short *, int, long, int ) { 565bool LibMadPlugin::audioReReadSamples( short *, int, long, int ) {
504 debugMsg( "LibMadPlugin::audioReReadSamples" ); 566 debugMsg( "LibMadPlugin::audioReReadSamples" );
505 return FALSE; 567 return FALSE;
506} 568}
507*/ 569*/
508 570
509bool LibMadPlugin::read() { 571bool LibMadPlugin::read() {
510 debugMsg( "LibMadPlugin::read" ); 572 debugMsg( "LibMadPlugin::read" );
511 int len; 573 int len;
512 574
513 if (d->input.eof) 575 if (d->input.eof)
514 return FALSE; 576 return FALSE;
515 577
516#if defined(HAVE_MMAP) 578#if defined(HAVE_MMAP)
517 if (d->input.fdm) { 579 if (d->input.fdm) {
518 unsigned long skip = 0; 580 unsigned long skip = 0;
519 581
520 if (d->stream.next_frame) { 582 if (d->stream.next_frame) {
521 struct stat stat; 583 struct stat stat;
522 584
523 if (fstat(d->input.fd, &stat) == -1) 585 if (fstat(d->input.fd, &stat) == -1)
524 return FALSE; 586 return FALSE;
525 587
526 if (stat.st_size + MAD_BUFFER_GUARD <= (signed)d->input.length) 588 if (stat.st_size + MAD_BUFFER_GUARD <= (signed)d->input.length)
527 return FALSE; 589 return FALSE;
528 590
529 // file size changed; update memory map 591 // file size changed; update memory map
530 skip = d->stream.next_frame - d->input.data; 592 skip = d->stream.next_frame - d->input.data;
531 593
532 if (unmap_file(d->input.fdm, d->input.length) == -1) { 594 if (unmap_file(d->input.fdm, d->input.length) == -1) {
533 d->input.fdm = 0; 595 d->input.fdm = 0;
534 d->input.data = 0; 596 d->input.data = 0;
535 return FALSE; 597 return FALSE;
536 } 598 }
537 599
538 d->input.length = stat.st_size; 600 d->input.length = stat.st_size;
539 601
540 d->input.fdm = map_file(d->input.fd, &d->input.length); 602 d->input.fdm = map_file(d->input.fd, &d->input.length);
541 if (d->input.fdm == 0) { 603 if (d->input.fdm == 0) {
542 d->input.data = 0; 604 d->input.data = 0;
543 return FALSE; 605 return FALSE;
544 } 606 }
545 607
546 d->input.data = (unsigned char *)d->input.fdm; 608 d->input.data = (unsigned char *)d->input.fdm;
547 } 609 }
548 610
549 mad_stream_buffer(&d->stream, d->input.data + skip, d->input.length - skip); 611 mad_stream_buffer(&d->stream, d->input.data + skip, d->input.length - skip);
550 612
551 } else 613 } else
552#endif 614#endif
553 { 615 {
554 if (d->stream.next_frame) { 616 if (d->stream.next_frame) {
555 memmove(d->input.data, d->stream.next_frame, 617 memmove(d->input.data, d->stream.next_frame,
556 d->input.length = &d->input.data[d->input.length] - d->stream.next_frame); 618 d->input.length = &d->input.data[d->input.length] - d->stream.next_frame);
557 } 619 }
558 620
559 do { 621 do {
560 len = ::read(d->input.fd, d->input.data + d->input.length, bufferSize /* MPEG_BUFFER_SIZE*/ - d->input.length); 622 len = ::read(d->input.fd, d->input.data + d->input.length, bufferSize /* MPEG_BUFFER_SIZE*/ - d->input.length);
561 } 623 }
562 while (len == -1 && errno == EINTR); 624 while (len == -1 && errno == EINTR);
563 625
564 if (len == -1) { 626 if (len == -1) {
565 qDebug("error reading audio"); 627 qDebug("error reading audio");
566 return FALSE; 628 return FALSE;
567 } 629 }
568 else if (len == 0) { 630 else if (len == 0) {
569 d->input.eof = 1; 631 d->input.eof = 1;
570 632
571 assert(bufferSize /*MPEG_BUFFER_SIZE*/ - d->input.length >= MAD_BUFFER_GUARD); 633 assert(bufferSize /*MPEG_BUFFER_SIZE*/ - d->input.length >= MAD_BUFFER_GUARD);
572 634
573 while (len < MAD_BUFFER_GUARD) 635 while (len < MAD_BUFFER_GUARD)
574 d->input.data[d->input.length + len++] = 0; 636 d->input.data[d->input.length + len++] = 0;
575 } 637 }
576 638
577 mad_stream_buffer(&d->stream, d->input.data, d->input.length += len); 639 mad_stream_buffer(&d->stream, d->input.data, d->input.length += len);
578 } 640 }
579 641
580 return TRUE; 642 return TRUE;
581} 643}
582 644
583 645
584static mad_fixed_t left_err, right_err; 646static mad_fixed_t left_err, right_err;
585static const int bits = 16; 647static const int bits = 16;
586static const int shift = MAD_F_FRACBITS + 1 - bits; 648static const int shift = MAD_F_FRACBITS + 1 - bits;
587 649
588 650
589inline long audio_linear_dither( mad_fixed_t sample, mad_fixed_t& error ) 651inline long audio_linear_dither( mad_fixed_t sample, mad_fixed_t& error )
590{ 652{
591 sample += error; 653 sample += error;
592 mad_fixed_t quantized = (sample >= MAD_F_ONE) ? MAD_F_ONE - 1 : ( (sample < -MAD_F_ONE) ? -MAD_F_ONE : sample ); 654 mad_fixed_t quantized = (sample >= MAD_F_ONE) ? MAD_F_ONE - 1 : ( (sample < -MAD_F_ONE) ? -MAD_F_ONE : sample );
593 quantized &= ~((1L << shift) - 1); 655 quantized &= ~((1L << shift) - 1);
594 error = sample - quantized; 656 error = sample - quantized;
595 return quantized >> shift; 657 return quantized >> shift;
596} 658}
597 659
598 660
599inline void audio_pcm( short *data, unsigned int nsamples, mad_fixed_t *left, mad_fixed_t *right ) 661inline void audio_pcm( short *data, unsigned int nsamples, mad_fixed_t *left, mad_fixed_t *right )
600{ 662{
601 if ( right ) { 663 if ( right ) {
602 while (nsamples--) { 664 while (nsamples--) {
603 data[0] = audio_linear_dither( *left++, left_err ); 665 data[0] = audio_linear_dither( *left++, left_err );
604 data[1] = audio_linear_dither( *right++, right_err ); 666 data[1] = audio_linear_dither( *right++, right_err );
605 data += 2; 667 data += 2;
606 } 668 }
607 } else { 669 } else {
608 while (nsamples--) { 670 while (nsamples--) {
609 data[0] = data[1] = audio_linear_dither( *left++, left_err ); 671 data[0] = data[1] = audio_linear_dither( *left++, left_err );
610 data += 2; 672 data += 2;
611 } 673 }
612 } 674 }
613} 675}
614 676
615 677
616bool LibMadPlugin::decode( short *output, long samples, long& samplesMade ) { 678bool LibMadPlugin::decode( short *output, long samples, long& samplesMade ) {
617 debugMsg( "LibMadPlugin::decode" ); 679 debugMsg( "LibMadPlugin::decode" );
618 680
619 static int buffered = 0; 681 static int buffered = 0;
620 static mad_fixed_t buffer[2][65536 * 2]; 682 static mad_fixed_t buffer[2][65536 * 2];
621 int offset = buffered; 683 int offset = buffered;
622 samplesMade = 0; 684 samplesMade = 0;
623 685
624 static int maxBuffered = 8000; // 65536; 686 static int maxBuffered = 8000; // 65536;
625 687
626 if ( samples > maxBuffered ) 688 if ( samples > maxBuffered )
627 samples = maxBuffered; 689 samples = maxBuffered;
628 690
629 if ( d->flush ) { 691 if ( d->flush ) {
630 buffered = 0; 692 buffered = 0;
631 offset = 0; 693 offset = 0;
632 d->flush = FALSE; 694 d->flush = FALSE;
633 } 695 }
634 696
635 while ( buffered < maxBuffered ) { 697 while ( buffered < maxBuffered ) {
636 698
637 while (mad_frame_decode(&d->frame, &d->stream) == -1) { 699 while (mad_frame_decode(&d->frame, &d->stream) == -1) {
638 if (!MAD_RECOVERABLE(d->stream.error)) { 700 if (!MAD_RECOVERABLE(d->stream.error)) {
639 debugMsg( "feed me" ); 701 debugMsg( "feed me" );
640 return FALSE; // Feed me 702 return FALSE; // Feed me
641 } 703 }
642 if ( d->stream.error == MAD_ERROR_BADCRC ) { 704 if ( d->stream.error == MAD_ERROR_BADCRC ) {
643 mad_frame_mute(&d->frame); 705 mad_frame_mute(&d->frame);
644 qDebug( "error decoding, bad crc" ); 706 qDebug( "error decoding, bad crc" );
645 } 707 }
646 } 708 }
647 709
648 mad_synth_frame(&d->synth, &d->frame); 710 mad_synth_frame(&d->synth, &d->frame);
649 int decodedSamples = d->synth.pcm.length; 711 int decodedSamples = d->synth.pcm.length;
650 memcpy( &(buffer[0][offset]), d->synth.pcm.samples[0], decodedSamples * sizeof(mad_fixed_t) ); 712 memcpy( &(buffer[0][offset]), d->synth.pcm.samples[0], decodedSamples * sizeof(mad_fixed_t) );
651 if ( d->synth.pcm.channels == 2 ) 713 if ( d->synth.pcm.channels == 2 )
652 memcpy( &(buffer[1][offset]), d->synth.pcm.samples[1], decodedSamples * sizeof(mad_fixed_t) ); 714 memcpy( &(buffer[1][offset]), d->synth.pcm.samples[1], decodedSamples * sizeof(mad_fixed_t) );
653 offset += decodedSamples; 715 offset += decodedSamples;
654 buffered += decodedSamples; 716 buffered += decodedSamples;
655 } 717 }
656//qApp->processEvents(); 718//qApp->processEvents();
657 audio_pcm( output, samples, buffer[0], (d->synth.pcm.channels == 2) ? buffer[1] : 0 ); 719 audio_pcm( output, samples, buffer[0], (d->synth.pcm.channels == 2) ? buffer[1] : 0 );
658// audio_pcm( output, samples, buffer[1], buffer[0] ); 720// audio_pcm( output, samples, buffer[1], buffer[0] );
659// audio_pcm( output, samples, buffer[0], buffer[1] ); 721// audio_pcm( output, samples, buffer[0], buffer[1] );
660 samplesMade = samples; 722 samplesMade = samples;
661 memmove( buffer[0], &(buffer[0][samples]), (buffered - samples) * sizeof(mad_fixed_t) ); 723 memmove( buffer[0], &(buffer[0][samples]), (buffered - samples) * sizeof(mad_fixed_t) );
662 if ( d->synth.pcm.channels == 2 ) 724 if ( d->synth.pcm.channels == 2 )
663 memmove( buffer[1], &(buffer[1][samples]), (buffered - samples) * sizeof(mad_fixed_t) ); 725 memmove( buffer[1], &(buffer[1][samples]), (buffered - samples) * sizeof(mad_fixed_t) );
664 buffered -= samples; 726 buffered -= samples;
665 727
666 return TRUE; 728 return TRUE;
667} 729}
668 730
669/* 731/*
670bool LibMadPlugin::audioReadMonoSamples( short *, long, long&, int ) { 732bool LibMadPlugin::audioReadMonoSamples( short *, long, long&, int ) {
671 debugMsg( "LibMadPlugin::audioReadMonoSamples" ); 733 debugMsg( "LibMadPlugin::audioReadMonoSamples" );
672 return FALSE; 734 return FALSE;
673} 735}
674 736
675 737
676bool LibMadPlugin::audioReadStereoSamples( short *output, long samples, long& samplesMade, int ) { 738bool LibMadPlugin::audioReadStereoSamples( short *output, long samples, long& samplesMade, int ) {
677*/ 739*/
678bool LibMadPlugin::audioReadSamples( short *output, int /*channels*/, long samples, long& samplesMade, int ) { 740bool LibMadPlugin::audioReadSamples( short *output, int /*channels*/, long samples, long& samplesMade, int ) {
679 debugMsg( "LibMadPlugin::audioReadStereoSamples" ); 741 debugMsg( "LibMadPlugin::audioReadStereoSamples" );
680 742
681 static bool needInput = TRUE; 743 static bool needInput = TRUE;
682 744
683 if ( samples == 0 ) 745 if ( samples == 0 )
684 return FALSE; 746 return FALSE;
685 747
686 do { 748 do {
687 if ( needInput ) 749 if ( needInput )
688 if ( !read() ) { 750 if ( !read() ) {
689// if ( d->input.eof ) 751// if ( d->input.eof )
690// needInput = FALSE; 752// needInput = FALSE;
691// else 753// else
692 return FALSE; 754 return FALSE;
693 } 755 }
694 756
695 needInput = FALSE; 757 needInput = FALSE;
696 758
697 if ( decode( output, samples, samplesMade ) ) 759 if ( decode( output, samples, samplesMade ) )
698 return TRUE; 760 return TRUE;
699 else 761 else
700 needInput = TRUE; 762 needInput = TRUE;
701 } 763 }
702 while ( ( samplesMade < samples ) && ( !d->input.eof ) ); 764 while ( ( samplesMade < samples ) && ( !d->input.eof ) );
703/* 765/*
704 static bool firstTimeThru = TRUE; 766 static bool firstTimeThru = TRUE;
705 767
706 if ( firstTimeThru ) { 768 if ( firstTimeThru ) {
707 firstTimeThru = FALSE; 769 firstTimeThru = FALSE;
708 decode( output, samples, samplesMade ); 770 decode( output, samples, samplesMade );
709 return FALSE; 771 return FALSE;
710 } else 772 } else
711*/ 773*/
712 return FALSE; 774 return FALSE;
713} 775}
714 776
715 777
716double LibMadPlugin::getTime() { 778double LibMadPlugin::getTime() {
717 debugMsg( "LibMadPlugin::getTime" ); 779 debugMsg( "LibMadPlugin::getTime" );
718 return 0.0; 780 return 0.0;
719} 781}
720 782
721 783
722void LibMadPlugin::printID3Tags() { 784void LibMadPlugin::printID3Tags() {
723 debugMsg( "LibMadPlugin::printID3Tags" ); 785 debugMsg( "LibMadPlugin::printID3Tags" );
724 786
725 char id3v1[128 + 1]; 787 char id3v1[128 + 1];
726 788
727 if ( ::lseek( d->input.fd, -128, SEEK_END ) == -1 ) { 789 if ( ::lseek( d->input.fd, -128, SEEK_END ) == -1 ) {
728 qDebug( "error seeking to id3 tags" ); 790 qDebug( "error seeking to id3 tags" );
729 return; 791 return;
730 } 792 }
731 793
732 if ( ::read( d->input.fd, id3v1, 128 ) != 128 ) { 794 if ( ::read( d->input.fd, id3v1, 128 ) != 128 ) {
733 qDebug( "error reading in id3 tags" ); 795 qDebug( "error reading in id3 tags" );
734 return; 796 return;
735 } 797 }
736 798
737 if ( ::strncmp( (const char *)id3v1, "TAG", 3 ) != 0 ) { 799 if ( ::strncmp( (const char *)id3v1, "TAG", 3 ) != 0 ) {
738 debugMsg( "sorry, no id3 tags" ); 800 debugMsg( "sorry, no id3 tags" );
739 } else { 801 } else {
740 int len[5] = { 30, 30, 30, 4, 30 }; 802 int len[5] = { 30, 30, 30, 4, 30 };
741 QString label[5] = { tr( "Title" ), tr( "Artist" ), tr( "Album" ), tr( "Year" ), tr( "Comment" ) }; 803 QString label[5] = { tr( "Title" ), tr( "Artist" ), tr( "Album" ), tr( "Year" ), tr( "Comment" ) };
742 char *ptr = id3v1 + 3, *ptr2 = ptr + len[0]; 804 char *ptr = id3v1 + 3, *ptr2 = ptr + len[0];
743 qDebug( "ID3 tags in file:" ); 805 qDebug( "ID3 tags in file:" );
744 info = ""; 806 info = "";
745 for ( int i = 0; i < 5; ptr += len[i], i++, ptr2 += len[i] ) { 807 for ( int i = 0; i < 5; ptr += len[i], i++, ptr2 += len[i] ) {
746 char push = *ptr2; 808 char push = *ptr2;
747 *ptr2 = '\0'; 809 *ptr2 = '\0';
748 char *ptr3 = ptr2; 810 char *ptr3 = ptr2;
749 while ( ptr3-1 >= ptr && isspace(ptr3[-1]) ) ptr3--; 811 while ( ptr3-1 >= ptr && isspace(ptr3[-1]) ) ptr3--;
750 char push2 = *ptr3; *ptr3 = '\0'; 812 char push2 = *ptr3; *ptr3 = '\0';
751 if ( strcmp( ptr, "" ) ) 813 if ( strcmp( ptr, "" ) )
752 info += ( i != 0 ? ", " : "" ) + label[i] + ": " + ptr; 814 info += ( i != 0 ? ", " : "" ) + label[i] + ": " + ptr;
753 //qDebug( info.latin1() ); 815 //qDebug( info.latin1() );
754 *ptr3 = push2; 816 *ptr3 = push2;
755 *ptr2 = push; 817 *ptr2 = push;
756 } 818 }
757 if (id3v1[126] == 0 && id3v1[127] != 0) 819 if (id3v1[126] == 0 && id3v1[127] != 0)
758 info += tr( ", Track: " ) + id3v1[127]; 820 info += tr( ", Track: " ) + id3v1[127];
759 } 821 }
760 822
761 if ( ::lseek(d->input.fd, 0, SEEK_SET) == -1 ) { 823 if ( ::lseek(d->input.fd, 0, SEEK_SET) == -1 ) {
762 qDebug( "error seeking back to beginning" ); 824 qDebug( "error seeking back to beginning" );
763 return; 825 return;
764 } 826 }
765} 827}
766 828
diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.h b/core/multimedia/opieplayer/libmad/libmadplugin.h
index ee1ca9d..6747712 100644
--- a/core/multimedia/opieplayer/libmad/libmadplugin.h
+++ b/core/multimedia/opieplayer/libmad/libmadplugin.h
@@ -1,115 +1,117 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved. 2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#ifndef LIBMAD_PLUGIN_H 20#ifndef LIBMAD_PLUGIN_H
21#define LIBMAD_PLUGIN_H 21#define LIBMAD_PLUGIN_H
22 22
23#include <qstring.h> 23#include <qstring.h>
24#include <qpe/mediaplayerplugininterface.h> 24#include <qpe/mediaplayerplugininterface.h>
25/* #include "../mediaplayerplugininterface.h" */ 25/* #include "../mediaplayerplugininterface.h" */
26 26
27 27
28// #define OLD_MEDIAPLAYER_API 28// #define OLD_MEDIAPLAYER_API
29 29
30 30
31class LibMadPluginData; 31class LibMadPluginData;
32 32
33 33
34class LibMadPlugin : public MediaPlayerDecoder { 34class LibMadPlugin : public MediaPlayerDecoder {
35 35
36public: 36public:
37 LibMadPlugin(); 37 LibMadPlugin();
38 ~LibMadPlugin(); 38 ~LibMadPlugin();
39 39
40 const char *pluginName() { return "LibMadPlugin"; } 40 const char *pluginName() { return "LibMadPlugin"; }
41 const char *pluginComment() { return "This is the libmad library that has been wrapped as a plugin"; } 41 const char *pluginComment() { return "This is the libmad library that has been wrapped as a plugin"; }
42 double pluginVersion() { return 1.0; } 42 double pluginVersion() { return 1.0; }
43 43
44 bool isFileSupported( const QString& ); 44 bool isFileSupported( const QString& );
45 bool open( const QString& ); 45 bool open( const QString& );
46 46
47 bool close(); 47 bool close();
48 bool isOpen(); 48 bool isOpen();
49 const QString &fileInfo() { return info; } 49 const QString &fileInfo() { return info; }
50 50
51 // If decoder doesn't support audio then return 0 here 51 // If decoder doesn't support audio then return 0 here
52 int audioStreams(); 52 int audioStreams();
53 int audioChannels( int stream ); 53 int audioChannels( int stream );
54 int audioFrequency( int stream ); 54 int audioFrequency( int stream );
55 int audioSamples( int stream ); 55 int audioSamples( int stream );
56 bool audioSetSample( long sample, int stream ); 56 bool audioSetSample( long sample, int stream );
57/* int audioBitsPerSample(int) {return 0;} */ 57/* int audioBitsPerSample(int) {return 0;} */
58 long audioGetSample( int stream ); 58 long audioGetSample( int stream );
59#ifdef OLD_MEDIAPLAYER_API 59#ifdef OLD_MEDIAPLAYER_API
60 bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ); 60 bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream );
61 bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ); 61 bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream );
62 bool audioReadSamples( short *output, int channel, long samples, int stream ); 62 bool audioReadSamples( short *output, int channel, long samples, int stream );
63 bool audioReReadSamples( short *output, int channel, long samples, int stream ); 63 bool audioReReadSamples( short *output, int channel, long samples, int stream );
64#else 64#else
65 bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ); 65 bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream );
66#endif 66#endif
67 67
68 68
69 bool read(); 69 bool read();
70 bool decode( short *output, long samples, long& samplesRead ); 70 bool decode( short *output, long samples, long& samplesRead );
71 void printID3Tags(); 71 void printID3Tags();
72 72
73 73
74 // If decoder doesn't support video then return 0 here 74 // If decoder doesn't support video then return 0 here
75 int videoStreams() { return 0; } 75 int videoStreams() { return 0; }
76 int videoWidth( int ) { return 0; } 76 int videoWidth( int ) { return 0; }
77 int videoHeight( int ) { return 0; } 77 int videoHeight( int ) { return 0; }
78 double videoFrameRate( int ) { return 0.0; } 78 double videoFrameRate( int ) { return 0.0; }
79 int videoFrames( int ) { return 0; } 79 int videoFrames( int ) { return 0; }
80 bool videoSetFrame( long, int ) { return FALSE; } 80 bool videoSetFrame( long, int ) { return FALSE; }
81 long videoGetFrame( int ) { return 0; } 81 long videoGetFrame( int ) { return 0; }
82 bool videoReadFrame( unsigned char **, int, int, int, int, ColorFormat, int ) { return FALSE; } 82 bool videoReadFrame( unsigned char **, int, int, int, int, ColorFormat, int ) { return FALSE; }
83 bool videoReadScaledFrame( unsigned char **, int, int, int, int, int, int, ColorFormat, int ) { return FALSE; } 83 bool videoReadScaledFrame( unsigned char **, int, int, int, int, int, int, ColorFormat, int ) { return FALSE; }
84 bool videoReadYUVFrame( char *, char *, char *, int, int, int, int, int ) { return FALSE; } 84 bool videoReadYUVFrame( char *, char *, char *, int, int, int, int, int ) { return FALSE; }
85 85
86 // Profiling 86 // Profiling
87 double getTime(); 87 double getTime();
88 88
89 // Ignore if these aren't supported 89 // Ignore if these aren't supported
90 bool setSMP( int ) { return FALSE; } 90 bool setSMP( int ) { return FALSE; }
91 bool setMMX( bool ) { return FALSE; } 91 bool setMMX( bool ) { return FALSE; }
92 92
93 // Capabilities 93 // Capabilities
94 bool supportsAudio() { return TRUE; } 94 bool supportsAudio() { return TRUE; }
95 bool supportsVideo() { return FALSE; } 95 bool supportsVideo() { return FALSE; }
96 bool supportsYUV() { return FALSE; } 96 bool supportsYUV() { return FALSE; }
97 bool supportsMMX() { return TRUE; } 97 bool supportsMMX() { return TRUE; }
98 bool supportsSMP() { return FALSE; } 98 bool supportsSMP() { return FALSE; }
99 bool supportsStereo() { return TRUE; } 99 bool supportsStereo() { return TRUE; }
100 bool supportsScaling() { return FALSE; } 100 bool supportsScaling() { return FALSE; }
101 101
102 long getPlayTime() { return -1; } 102 long getPlayTime() { return -1; }
103 103
104private: 104private:
105 int is_address_multicast(unsigned long address);
106 int udp_open(char *address, int port);
105 int tcp_open(char *address, int port); 107 int tcp_open(char *address, int port);
106 int http_read_line(int tcp_sock, char *buf, int size) ; 108 int http_read_line(int tcp_sock, char *buf, int size) ;
107 int http_open(const QString& path ); 109 int http_open(const QString& path );
108 110
109 LibMadPluginData *d; 111 LibMadPluginData *d;
110 QString info; 112 QString info;
111int bufferSize; 113int bufferSize;
112}; 114};
113 115
114 116
115#endif 117#endif