summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmad/libmadplugin.cpp2
1 files changed, 1 insertions, 1 deletions
diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.cpp b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
index 7bb6541..46f2450 100644
--- a/core/multimedia/opieplayer/libmad/libmadplugin.cpp
+++ b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
@@ -91,513 +91,513 @@ static 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 // UGLY - just for fast testing 171 // UGLY - just for fast testing
172 if ( path.left(4) == "http") { 172 if ( path.left(4) == "http") {
173 return TRUE; 173 return TRUE;
174 } 174 }
175 175
176 176
177 return FALSE; 177 return FALSE;
178} 178}
179 179
180 180
181int LibMadPlugin::tcp_open(char *address, int port) { 181int LibMadPlugin::tcp_open(char *address, int port) {
182 struct sockaddr_in stAddr; 182 struct sockaddr_in stAddr;
183 struct hostent *host; 183 struct hostent *host;
184 int sock; 184 int sock;
185 struct linger l; 185 struct linger l;
186 186
187 memset(&stAddr, 0, sizeof(stAddr)); 187 memset(&stAddr, 0, sizeof(stAddr));
188 stAddr.sin_family = AF_INET; 188 stAddr.sin_family = AF_INET;
189 stAddr.sin_port = htons(port); 189 stAddr.sin_port = htons(port);
190 190
191 if ((host = gethostbyname(address)) == NULL) 191 if ((host = gethostbyname(address)) == NULL)
192 return (0); 192 return (0);
193 193
194 stAddr.sin_addr = *((struct in_addr *)host->h_addr_list[0]); 194 stAddr.sin_addr = *((struct in_addr *)host->h_addr_list[0]);
195 195
196 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 196 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
197 return (0); 197 return (0);
198 198
199 l.l_onoff = 1; 199 l.l_onoff = 1;
200 l.l_linger = 5; 200 l.l_linger = 5;
201 if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l)) < 0) 201 if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l)) < 0)
202 return (0); 202 return (0);
203 203
204 if (connect(sock, (struct sockaddr *)&stAddr, sizeof(stAddr)) < 0) 204 if (connect(sock, (struct sockaddr *)&stAddr, sizeof(stAddr)) < 0)
205 return (0); 205 return (0);
206 206
207 return (sock); 207 return (sock);
208} 208}
209 209
210 210
211/** 211/**
212 * Read a http line header. 212 * Read a http line header.
213 * This function read character by character. 213 * This function read character by character.
214 * @param tcp_sock the socket use to read the stream 214 * @param tcp_sock the socket use to read the stream
215 * @param buf a buffer to receive the data 215 * @param buf a buffer to receive the data
216 * @param size size of the buffer 216 * @param size size of the buffer
217 * @return the size of the stream read or -1 if an error occured 217 * @return the size of the stream read or -1 if an error occured
218 */ 218 */
219int LibMadPlugin::http_read_line(int tcp_sock, char *buf, int size) { 219int LibMadPlugin::http_read_line(int tcp_sock, char *buf, int size) {
220 int offset = 0; 220 int offset = 0;
221 221
222 do 222 do
223 { 223 {
224 if (std::read(tcp_sock, buf + offset, 1) < 0) 224 if (std::read(tcp_sock, buf + offset, 1) < 0)
225 return -1; 225 return -1;
226 if (buf[offset] != '\r') /* Strip \r from answer */ 226 if (buf[offset] != '\r') /* Strip \r from answer */
227 offset++; 227 offset++;
228 } 228 }
229 while (offset < size - 1 && buf[offset - 1] != '\n'); 229 while (offset < size - 1 && buf[offset - 1] != '\n');
230 230
231 buf[offset] = 0; 231 buf[offset] = 0;
232 return offset; 232 return offset;
233} 233}
234 234
235int LibMadPlugin::http_open(const QString& path ) { 235int LibMadPlugin::http_open(const QString& path ) {
236 char *host; 236 char *host;
237 int port; 237 int port;
238 char *request; 238 char *request;
239 int tcp_sock; 239 int tcp_sock;
240 char http_request[PATH_MAX]; 240 char http_request[PATH_MAX];
241 char filename[PATH_MAX]; 241 char filename[PATH_MAX];
242 char c; 242 char c;
243 char *arg =strdup(path.latin1()); 243 char *arg =strdup(path.latin1());
244 244
245 /* Check for URL syntax */ 245 /* Check for URL syntax */
246 if (strncmp(arg, "http://", strlen("http://"))) 246 if (strncmp(arg, "http://", strlen("http://")))
247 return (0); 247 return (0);
248 248
249 /* Parse URL */ 249 /* Parse URL */
250 port = 80; 250 port = 80;
251 host = arg + strlen("http://"); 251 host = arg + strlen("http://");
252 if ((request = strchr(host, '/')) == NULL) 252 if ((request = strchr(host, '/')) == NULL)
253 return (0); 253 return (0);
254 *request++ = 0; 254 *request++ = 0;
255 255
256 if (strchr(host, ':') != NULL) /* port is specified */ 256 if (strchr(host, ':') != NULL) /* port is specified */
257 { 257 {
258 port = atoi(strchr(host, ':') + 1); 258 port = atoi(strchr(host, ':') + 1);
259 *strchr(host, ':') = 0; 259 *strchr(host, ':') = 0;
260 } 260 }
261 261
262 /* Open a TCP socket */ 262 /* Open a TCP socket */
263 if (!(tcp_sock = tcp_open(host, port))) 263 if (!(tcp_sock = tcp_open(host, port)))
264 { 264 {
265 perror("http_open"); 265 perror("http_open");
266 return (0); 266 return (0);
267 } 267 }
268 268
269 snprintf(filename, sizeof(filename) - strlen(host) - 75, "%s", request); 269 snprintf(filename, sizeof(filename) - strlen(host) - 75, "%s", request);
270 270
271 /* Send HTTP GET request */ 271 /* Send HTTP GET request */
272 /* Please don't use a Agent know by shoutcast (Lynx, Mozilla) seems to be reconized and print 272 /* 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 */ 273 * a html page and not the stream */
274 snprintf(http_request, sizeof(http_request), "GET /%s HTTP/1.0\r\n" 274 snprintf(http_request, sizeof(http_request), "GET /%s HTTP/1.0\r\n"
275/* "User-Agent: Mozilla/2.0 (Win95; I)\r\n" */ 275/* "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); 276 "Pragma: no-cache\r\n" "Host: %s\r\n" "Accept: */*\r\n" "\r\n", filename, host);
277 277
278 send(tcp_sock, http_request, strlen(http_request), 0); 278 send(tcp_sock, http_request, strlen(http_request), 0);
279 279
280 /* Parse server reply */ 280 /* Parse server reply */
281#if 0 281#if 0
282 do 282 do
283 read(tcp_sock, &c, sizeof(char)); 283 read(tcp_sock, &c, sizeof(char));
284 while (c != ' '); 284 while (c != ' ');
285 read(tcp_sock, http_request, 4 * sizeof(char)); 285 read(tcp_sock, http_request, 4 * sizeof(char));
286 http_request[4] = 0; 286 http_request[4] = 0;
287 if (strcmp(http_request, "200 ")) 287 if (strcmp(http_request, "200 "))
288 { 288 {
289 fprintf(stderr, "http_open: "); 289 fprintf(stderr, "http_open: ");
290 do 290 do
291 { 291 {
292 read(tcp_sock, &c, sizeof(char)); 292 read(tcp_sock, &c, sizeof(char));
293 fprintf(stderr, "%c", c); 293 fprintf(stderr, "%c", c);
294 } 294 }
295 while (c != '\r'); 295 while (c != '\r');
296 fprintf(stderr, "\n"); 296 fprintf(stderr, "\n");
297 return (0); 297 return (0);
298 } 298 }
299#endif 299#endif
300 300
301 do 301 do
302 { 302 {
303 int len; 303 int len;
304 304
305 len = http_read_line(tcp_sock, http_request, sizeof(http_request)); 305 len = http_read_line(tcp_sock, http_request, sizeof(http_request));
306 306
307 if (len == -1) 307 if (len == -1)
308 { 308 {
309 fprintf(stderr, "http_open: %s\n", strerror(errno)); 309 fprintf(stderr, "http_open: %s\n", strerror(errno));
310 return 0; 310 return 0;
311 } 311 }
312 312
313 if (strncmp(http_request, "Location:", 9) == 0) 313 if (strncmp(http_request, "Location:", 9) == 0)
314 { 314 {
315 /* redirect */ 315 /* redirect */
316 std::close(tcp_sock); 316 std::close(tcp_sock);
317 317
318 http_request[strlen(http_request) - 1] = '\0'; 318 http_request[strlen(http_request) - 1] = '\0';
319 319
320 return http_open(&http_request[10]); 320 return http_open(&http_request[10]);
321 } 321 }
322 322
323 if (strncmp(http_request, "ICY ", 4) == 0) 323 if (strncmp(http_request, "ICY ", 4) == 0)
324 { 324 {
325 /* This is icecast streaming */ 325 /* This is icecast streaming */
326 if (strncmp(http_request + 4, "200 ", 4)) 326 if (strncmp(http_request + 4, "200 ", 4))
327 { 327 {
328 fprintf(stderr, "http_open: %s\n", http_request); 328 fprintf(stderr, "http_open: %s\n", http_request);
329 return 0; 329 return 0;
330 } 330 }
331 } 331 }
332 else if (strncmp(http_request, "icy-", 4) == 0) 332 else if (strncmp(http_request, "icy-", 4) == 0)
333 { 333 {
334 /* we can have: icy-noticeX, icy-name, icy-genre, icy-url, icy-pub, icy-metaint, icy-br */ 334 /* 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 */ 335 /* Don't print these - mpg123 doesn't */
336 /* fprintf(stderr,"%s\n",http_request); */ 336 /* fprintf(stderr,"%s\n",http_request); */
337 } 337 }
338 } 338 }
339 while (strcmp(http_request, "\n") != 0); 339 while (strcmp(http_request, "\n") != 0);
340 340
341 return (tcp_sock); 341 return (tcp_sock);
342} 342}
343 343
344 344
345bool LibMadPlugin::open( const QString& path ) { 345bool LibMadPlugin::open( const QString& path ) {
346 debugMsg( "LibMadPlugin::open" ); 346 debugMsg( "LibMadPlugin::open" );
347 Config cfg("MediaPlayer"); 347 Config cfg("OpiePlayer");
348 cfg.setGroup("Options"); 348 cfg.setGroup("Options");
349 bufferSize = cfg.readNumEntry("MPeg_BufferSize",MPEG_BUFFER_SIZE); 349 bufferSize = cfg.readNumEntry("MPeg_BufferSize",MPEG_BUFFER_SIZE);
350 qDebug("buffer size is %d", bufferSize); 350 qDebug("buffer size is %d", bufferSize);
351 d->bad_last_frame = 0; 351 d->bad_last_frame = 0;
352 d->flush = TRUE; 352 d->flush = TRUE;
353 info = QString( "" ); 353 info = QString( "" );
354 354
355 //qDebug( "Opening %s", path.latin1() ); 355 //qDebug( "Opening %s", path.latin1() );
356 356
357 357
358 if (path.left( 4 ) == "http" ) { 358 if (path.left( 4 ) == "http" ) {
359 d->input.fd = http_open(path); 359 d->input.fd = http_open(path);
360 360
361 } else { 361 } else {
362 d->input.path = path.latin1(); 362 d->input.path = path.latin1();
363 d->input.fd = ::open( d->input.path, O_RDONLY ); 363 d->input.fd = ::open( d->input.path, O_RDONLY );
364 } 364 }
365 if (d->input.fd == -1) { 365 if (d->input.fd == -1) {
366 qDebug("error opening %s", d->input.path ); 366 qDebug("error opening %s", d->input.path );
367 return FALSE; 367 return FALSE;
368 } 368 }
369 369
370 printID3Tags(); 370 printID3Tags();
371 371
372#if defined(HAVE_MMAP) 372#if defined(HAVE_MMAP)
373 struct stat stat; 373 struct stat stat;
374 if (fstat(d->input.fd, &stat) == -1) { 374 if (fstat(d->input.fd, &stat) == -1) {
375 qDebug("error calling fstat"); return FALSE; 375 qDebug("error calling fstat"); return FALSE;
376 } 376 }
377 if (S_ISREG(stat.st_mode) && stat.st_size > 0) { 377 if (S_ISREG(stat.st_mode) && stat.st_size > 0) {
378 d->input.length = stat.st_size; 378 d->input.length = stat.st_size;
379 d->input.fdm = map_file(d->input.fd, &d->input.length); 379 d->input.fdm = map_file(d->input.fd, &d->input.length);
380 if (d->input.fdm == 0) { 380 if (d->input.fdm == 0) {
381 qDebug("error mmapping file"); return FALSE; 381 qDebug("error mmapping file"); return FALSE;
382 } 382 }
383 d->input.data = (unsigned char *)d->input.fdm; 383 d->input.data = (unsigned char *)d->input.fdm;
384 } 384 }
385#endif 385#endif
386 386
387 if (d->input.data == 0) { 387 if (d->input.data == 0) {
388 d->input.data = (unsigned char *)malloc( bufferSize /*MPEG_BUFFER_SIZE*/); 388 d->input.data = (unsigned char *)malloc( bufferSize /*MPEG_BUFFER_SIZE*/);
389 if (d->input.data == 0) { 389 if (d->input.data == 0) {
390 qDebug("error allocating input buffer"); 390 qDebug("error allocating input buffer");
391 return FALSE; 391 return FALSE;
392 } 392 }
393 d->input.length = 0; 393 d->input.length = 0;
394 } 394 }
395 395
396 d->input.eof = 0; 396 d->input.eof = 0;
397 397
398 mad_stream_init(&d->stream); 398 mad_stream_init(&d->stream);
399 mad_frame_init(&d->frame); 399 mad_frame_init(&d->frame);
400 mad_synth_init(&d->synth); 400 mad_synth_init(&d->synth);
401 401
402 return TRUE; 402 return TRUE;
403} 403}
404 404
405 405
406bool LibMadPlugin::close() { 406bool LibMadPlugin::close() {
407 debugMsg( "LibMadPlugin::close" ); 407 debugMsg( "LibMadPlugin::close" );
408 408
409 int result = TRUE; 409 int result = TRUE;
410 410
411 mad_synth_finish(&d->synth); 411 mad_synth_finish(&d->synth);
412 mad_frame_finish(&d->frame); 412 mad_frame_finish(&d->frame);
413 mad_stream_finish(&d->stream); 413 mad_stream_finish(&d->stream);
414 414
415#if defined(HAVE_MMAP) 415#if defined(HAVE_MMAP)
416 if (d->input.fdm) { 416 if (d->input.fdm) {
417 if (unmap_file(d->input.fdm, d->input.length) == -1) { 417 if (unmap_file(d->input.fdm, d->input.length) == -1) {
418 qDebug("error munmapping file"); 418 qDebug("error munmapping file");
419 result = FALSE; 419 result = FALSE;
420 } 420 }
421 d->input.fdm = 0; 421 d->input.fdm = 0;
422 d->input.data = 0; 422 d->input.data = 0;
423 } 423 }
424#endif 424#endif
425 425
426 if (d->input.data) { 426 if (d->input.data) {
427 free(d->input.data); 427 free(d->input.data);
428 d->input.data = 0; 428 d->input.data = 0;
429 } 429 }
430 430
431 if (::close(d->input.fd) == -1) { 431 if (::close(d->input.fd) == -1) {
432 qDebug("error closing file %s", d->input.path); 432 qDebug("error closing file %s", d->input.path);
433 result = FALSE; 433 result = FALSE;
434 } 434 }
435 435
436 d->input.fd = 0; 436 d->input.fd = 0;
437 437
438 return result; 438 return result;
439} 439}
440 440
441 441
442bool LibMadPlugin::isOpen() { 442bool LibMadPlugin::isOpen() {
443 debugMsg( "LibMadPlugin::isOpen" ); 443 debugMsg( "LibMadPlugin::isOpen" );
444 return ( d->input.fd != 0 ); 444 return ( d->input.fd != 0 );
445} 445}
446 446
447 447
448int LibMadPlugin::audioStreams() { 448int LibMadPlugin::audioStreams() {
449 debugMsg( "LibMadPlugin::audioStreams" ); 449 debugMsg( "LibMadPlugin::audioStreams" );
450 return 1; 450 return 1;
451} 451}
452 452
453 453
454int LibMadPlugin::audioChannels( int ) { 454int LibMadPlugin::audioChannels( int ) {
455 debugMsg( "LibMadPlugin::audioChannels" ); 455 debugMsg( "LibMadPlugin::audioChannels" );
456/* 456/*
457 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); 457 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
458 qDebug( "LibMadPlugin::audioChannels: %i", d->frame.header.mode > 0 ? 2 : 1 ); 458 qDebug( "LibMadPlugin::audioChannels: %i", d->frame.header.mode > 0 ? 2 : 1 );
459 return d->frame.header.mode > 0 ? 2 : 1; 459 return d->frame.header.mode > 0 ? 2 : 1;
460*/ 460*/
461 return 2; 461 return 2;
462} 462}
463 463
464 464
465int LibMadPlugin::audioFrequency( int ) { 465int LibMadPlugin::audioFrequency( int ) {
466 debugMsg( "LibMadPlugin::audioFrequency" ); 466 debugMsg( "LibMadPlugin::audioFrequency" );
467 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); 467 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
468 qDebug( "LibMadPlugin::audioFrequency: %i", d->frame.header.samplerate ); 468 qDebug( "LibMadPlugin::audioFrequency: %i", d->frame.header.samplerate );
469 return d->frame.header.samplerate; 469 return d->frame.header.samplerate;
470} 470}
471 471
472 472
473int LibMadPlugin::audioSamples( int ) { 473int LibMadPlugin::audioSamples( int ) {
474 debugMsg( "LibMadPlugin::audioSamples" ); 474 debugMsg( "LibMadPlugin::audioSamples" );
475/* 475/*
476 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); 476 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
477 mad_header_decode( (struct mad_header *)&d->frame.header, &d->stream ); 477 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 ); 478 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; 479 return d->frame.header.duration.seconds * d->frame.header.samplerate;
480*/ 480*/
481 return 10000000; 481 return 10000000;
482} 482}
483 483
484 484
485bool LibMadPlugin::audioSetSample( long, int ) { 485bool LibMadPlugin::audioSetSample( long, int ) {
486 debugMsg( "LibMadPlugin::audioSetSample" ); 486 debugMsg( "LibMadPlugin::audioSetSample" );
487 return FALSE; 487 return FALSE;
488} 488}
489 489
490 490
491long LibMadPlugin::audioGetSample( int ) { 491long LibMadPlugin::audioGetSample( int ) {
492 debugMsg( "LibMadPlugin::audioGetSample" ); 492 debugMsg( "LibMadPlugin::audioGetSample" );
493 return 0; 493 return 0;
494} 494}
495 495
496/* 496/*
497bool LibMadPlugin::audioReadSamples( short *, int, long, int ) { 497bool LibMadPlugin::audioReadSamples( short *, int, long, int ) {
498 debugMsg( "LibMadPlugin::audioReadSamples" ); 498 debugMsg( "LibMadPlugin::audioReadSamples" );
499 return FALSE; 499 return FALSE;
500} 500}
501 501
502 502
503bool LibMadPlugin::audioReReadSamples( short *, int, long, int ) { 503bool LibMadPlugin::audioReReadSamples( short *, int, long, int ) {
504 debugMsg( "LibMadPlugin::audioReReadSamples" ); 504 debugMsg( "LibMadPlugin::audioReReadSamples" );
505 return FALSE; 505 return FALSE;
506} 506}
507*/ 507*/
508 508
509bool LibMadPlugin::read() { 509bool LibMadPlugin::read() {
510 debugMsg( "LibMadPlugin::read" ); 510 debugMsg( "LibMadPlugin::read" );
511 int len; 511 int len;
512 512
513 if (d->input.eof) 513 if (d->input.eof)
514 return FALSE; 514 return FALSE;
515 515
516#if defined(HAVE_MMAP) 516#if defined(HAVE_MMAP)
517 if (d->input.fdm) { 517 if (d->input.fdm) {
518 unsigned long skip = 0; 518 unsigned long skip = 0;
519 519
520 if (d->stream.next_frame) { 520 if (d->stream.next_frame) {
521 struct stat stat; 521 struct stat stat;
522 522
523 if (fstat(d->input.fd, &stat) == -1) 523 if (fstat(d->input.fd, &stat) == -1)
524 return FALSE; 524 return FALSE;
525 525
526 if (stat.st_size + MAD_BUFFER_GUARD <= (signed)d->input.length) 526 if (stat.st_size + MAD_BUFFER_GUARD <= (signed)d->input.length)
527 return FALSE; 527 return FALSE;
528 528
529 // file size changed; update memory map 529 // file size changed; update memory map
530 skip = d->stream.next_frame - d->input.data; 530 skip = d->stream.next_frame - d->input.data;
531 531
532 if (unmap_file(d->input.fdm, d->input.length) == -1) { 532 if (unmap_file(d->input.fdm, d->input.length) == -1) {
533 d->input.fdm = 0; 533 d->input.fdm = 0;
534 d->input.data = 0; 534 d->input.data = 0;
535 return FALSE; 535 return FALSE;
536 } 536 }
537 537
538 d->input.length = stat.st_size; 538 d->input.length = stat.st_size;
539 539
540 d->input.fdm = map_file(d->input.fd, &d->input.length); 540 d->input.fdm = map_file(d->input.fd, &d->input.length);
541 if (d->input.fdm == 0) { 541 if (d->input.fdm == 0) {
542 d->input.data = 0; 542 d->input.data = 0;
543 return FALSE; 543 return FALSE;
544 } 544 }
545 545
546 d->input.data = (unsigned char *)d->input.fdm; 546 d->input.data = (unsigned char *)d->input.fdm;
547 } 547 }
548 548
549 mad_stream_buffer(&d->stream, d->input.data + skip, d->input.length - skip); 549 mad_stream_buffer(&d->stream, d->input.data + skip, d->input.length - skip);
550 550
551 } else 551 } else
552#endif 552#endif
553 { 553 {
554 if (d->stream.next_frame) { 554 if (d->stream.next_frame) {
555 memmove(d->input.data, d->stream.next_frame, 555 memmove(d->input.data, d->stream.next_frame,
556 d->input.length = &d->input.data[d->input.length] - d->stream.next_frame); 556 d->input.length = &d->input.data[d->input.length] - d->stream.next_frame);
557 } 557 }
558 558
559 do { 559 do {
560 len = ::read(d->input.fd, d->input.data + d->input.length, bufferSize /* MPEG_BUFFER_SIZE*/ - d->input.length); 560 len = ::read(d->input.fd, d->input.data + d->input.length, bufferSize /* MPEG_BUFFER_SIZE*/ - d->input.length);
561 } 561 }
562 while (len == -1 && errno == EINTR); 562 while (len == -1 && errno == EINTR);
563 563
564 if (len == -1) { 564 if (len == -1) {
565 qDebug("error reading audio"); 565 qDebug("error reading audio");
566 return FALSE; 566 return FALSE;
567 } 567 }
568 else if (len == 0) { 568 else if (len == 0) {
569 d->input.eof = 1; 569 d->input.eof = 1;
570 570
571 assert(bufferSize /*MPEG_BUFFER_SIZE*/ - d->input.length >= MAD_BUFFER_GUARD); 571 assert(bufferSize /*MPEG_BUFFER_SIZE*/ - d->input.length >= MAD_BUFFER_GUARD);
572 572
573 while (len < MAD_BUFFER_GUARD) 573 while (len < MAD_BUFFER_GUARD)
574 d->input.data[d->input.length + len++] = 0; 574 d->input.data[d->input.length + len++] = 0;
575 } 575 }
576 576
577 mad_stream_buffer(&d->stream, d->input.data, d->input.length += len); 577 mad_stream_buffer(&d->stream, d->input.data, d->input.length += len);
578 } 578 }
579 579
580 return TRUE; 580 return TRUE;
581} 581}
582 582
583 583
584static mad_fixed_t left_err, right_err; 584static mad_fixed_t left_err, right_err;
585static const int bits = 16; 585static const int bits = 16;
586static const int shift = MAD_F_FRACBITS + 1 - bits; 586static const int shift = MAD_F_FRACBITS + 1 - bits;
587 587
588 588
589inline long audio_linear_dither( mad_fixed_t sample, mad_fixed_t& error ) 589inline long audio_linear_dither( mad_fixed_t sample, mad_fixed_t& error )
590{ 590{
591 sample += error; 591 sample += error;
592 mad_fixed_t quantized = (sample >= MAD_F_ONE) ? MAD_F_ONE - 1 : ( (sample < -MAD_F_ONE) ? -MAD_F_ONE : sample ); 592 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); 593 quantized &= ~((1L << shift) - 1);
594 error = sample - quantized; 594 error = sample - quantized;
595 return quantized >> shift; 595 return quantized >> shift;
596} 596}
597 597
598 598
599inline void audio_pcm( short *data, unsigned int nsamples, mad_fixed_t *left, mad_fixed_t *right ) 599inline void audio_pcm( short *data, unsigned int nsamples, mad_fixed_t *left, mad_fixed_t *right )
600{ 600{
601 if ( right ) { 601 if ( right ) {
602 while (nsamples--) { 602 while (nsamples--) {
603 data[0] = audio_linear_dither( *left++, left_err ); 603 data[0] = audio_linear_dither( *left++, left_err );