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