1 /* MPEG/WAVE Sound library
2
3 (C) 1997 by Jung woo-jae */
4
5 // Mpegtoraw.cc
6 // Server which get mpeg format and put raw format.
7 // Patched by Bram Avontuur to support more mp3 formats and to play mp3's
8 // with bogus (?) headers.
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13
14 #include <math.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <string.h>
18
19 #include "mpegsound.h"
20 #include "mpegsound_locals.h"
21 #include "xingheader.h"
22
23 #ifdef NEWTHREAD
24 #include <sys/types.h>
25 #include <sys/ipc.h>
26 #include <sys/shm.h>
27 #include <signal.h>
28 #include <sys/time.h>
29 #include <errno.h>
30
31 pth_mutex_t queue_mutex;
32
33 Mpegtoraw *decoder;
34 #define THREAD_TIMES 10
35 #define THREAD_LIMIT 512
36 #endif
37
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41
42 #ifdef __cplusplus
43 }
44 #endif
45
46 #define MY_PI 3.14159265358979323846
47 #undef DEBUG
48
49 #ifdef NEWTHREAD
50 void
settotalbuffers(short amount)51 Mpegtoraw::settotalbuffers(short amount)
52 {
53 short bla=0;
54 #if 0
55 int shm_id; /* Shared memory ID */
56 do{
57 shm_id=shmget(IPC_PRIVATE,sizeof(mpeg_buffer)*amount,IPC_CREAT | IPC_EXCL |
58 0666);
59 amount-=10;
60 } while (shm_id==-1 && (bla+10)>0);
61 amount+=10;
62
63 if(amount<=0)
64 {
65 fprintf(stderr,"Can't create shared memory!\n");
66 exit(1);
67 }
68 buffers=(mpeg_buffer *)shmat(shm_id,NULL,0);
69 if(buffers==(mpeg_buffer *)-1)
70 {
71 perror("shmat");
72 exit(1);
73 }
74 if(shmctl(shm_id,IPC_RMID,NULL))
75 {
76 perror("shmctl");
77 exit(1);
78 }
79 #else
80 buffers = (mpeg_buffer*)malloc(amount * sizeof(mpeg_buffer));
81 if (!buffers)
82 {
83 //very blunt.
84 fprintf(stderr, "Can't allocate buffer memory!\n");
85 exit(1);
86 }
87 #endif
88
89 while(bla != amount)
90 buffers[bla++].claimed=0;
91 no_buffers=amount;
92 free_buffers=no_buffers;
93 }
94
95 int
getfreebuffers(void)96 Mpegtoraw::getfreebuffers(void)
97 {
98 return free_buffers;
99 }
100
101 short
request_buffer(void)102 Mpegtoraw::request_buffer(void)
103 {
104 short temp=0;
105 for(temp=0;temp!=no_buffers;temp++)
106 {
107 if(!buffers[temp].claimed)
108 {
109 buffers[temp].claimed=1;
110 free_buffers--;
111 return temp;
112 }
113 }
114 return -1;
115 }
116
117 void
release_buffer(short index)118 Mpegtoraw::release_buffer(short index)
119 {
120 if(index>=no_buffers) return;
121 buffers[index].claimed=0;
122 free_buffers++;
123 }
124
125 void
queue_buf(short index)126 Mpegtoraw::queue_buf(short index)
127 {
128 buffer_node *bla;
129 buffer_node *search;
130 search=queue;
131 bla=(buffer_node *)malloc(sizeof(buffer_node));
132 if(!bla)
133 {
134 seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH);
135 return;
136 }
137 bla->index=index;
138 bla->next=NULL;
139
140 if(search==NULL)
141 {
142 queue=bla;
143 return;
144 }
145 while(search->next!=NULL)
146 search=search->next;
147 search->next=bla;
148 return;
149 }
150
151 void
dequeue_first(void)152 Mpegtoraw::dequeue_first(void)
153 {
154 buffer_node *temp;
155 temp=queue;
156 if(!temp)
157 {
158 return;
159 }
160 release_buffer(queue->index);
161 queue=queue->next;
162 free(temp);
163 }
164
165
166
167 void
dequeue_buf(short index)168 Mpegtoraw::dequeue_buf(short index)
169 {
170 buffer_node *temp;
171 buffer_node *temp2;
172 temp=queue;
173 if(temp==NULL)
174 {
175 return;
176 }
177 if(temp->index==index)
178 {
179 release_buffer(index);
180 queue=queue->next;
181 free(temp);
182 }
183 else
184 {
185 while(temp!=NULL&&temp->next!=NULL&&temp->next->index!=index)
186 temp=temp->next;
187 if(temp==NULL||temp->next==NULL)
188 {
189 return;
190 }
191 release_buffer(temp->next->index);
192 temp2=temp->next;
193 temp->next=temp->next->next;
194 free(temp2);
195 }
196 }
197
threadplay(void * bla)198 void Mpegtoraw::threadplay(void *bla)
199 {
200 struct mpeg_buffer *bufje;
201 int offset=0;
202 int remaining=RAWDATASIZE*THREAD_TIMES*sizeof(short int);
203 bla=bla;
204 int processed=0;
205 /* This has to be a static array, otherwise it is allocated from the
206 * stack. threadplay() is called within a pth|pthreads thread, so stack
207 * is scarce. Leads to very nasty (and very untrackable) segmentation
208 * faults, happening at very odd places (since the stack has been
209 * corrupted). Under normal conditions, the stack is automagically
210 * expanded if so required, or a segmentation fault is generated when
211 * stack and heap collide in case of an OS with a somewhat 'less
212 * modern' memory system. MacOS prior to OS X comes to mind.
213 *
214 * Or a modern system when using threads....
215 *
216 * Another option would be to make this a global variable, but that's
217 * even more yucky.
218 */
219
220 bufje=NULL; /* So gcc will not complain. Pfft. */
221 /* Enable other threads to kill us */
222 /* But only if we feel like it! */
223 pth_cancel_state(PTH_CANCEL_ENABLE|PTH_CANCEL_DEFERRED, NULL);
224
225 /* Yes, I know that these are the defaults at this particular point
226 in time/space. Linux and GNU-libc are doing a fine job in changing
227 defaults and compliances these days, though. */
228 while(1)
229 {
230 pth_cancel_point(); /* Are we "requested" to sod off and die? */
231 pth_mutex_acquire(&queue_mutex, FALSE, NULL); /* Enter critical zone */
232 if(!player_run || !queue)
233 {
234 pth_event_t ev;
235 pth_mutex_release(&queue_mutex); /* Leave critical zone */
236 ev=pth_event(PTH_EVENT_TIME,pth_timeout(0,100000));
237 pth_wait(ev);
238 pth_event_free(ev,PTH_FREE_THIS);
239 /* Player is either paused, or has a buffer
240 underrun.Pause 100 msec. */
241 }
242 else
243 {
244 /* Fill buffer as much as possible */
245 while (queue &&
246 (bufje=get_buffer(queue->index)) &&
247 bufje->framesize <= remaining )
248 {
249 int modifiedsize;
250 //amplify(bufje->data,bufje->framesize);
251 memcpy(sound_buf+offset,bufje->data,bufje->framesize);
252 modifiedsize=player->fix_samplesize(
253 sound_buf+offset, bufje->framesize);
254 offset+=modifiedsize;
255 remaining-=modifiedsize;
256 currentframe=bufje->framenumber;
257 dequeue_first();
258 }
259 pth_mutex_release(&queue_mutex); /* Leave critical zone */
260
261 /* So, the actual sound output is done -outside- the
262 * critical zone. This means that the data is copied
263 * once too much, but it prevents the decoding thread
264 * from blocking because the playing thread is blocked
265 * by the sound hardware while in the critical zone.*/
266 debug("Starting loop\n");
267 do
268 {
269 processed=player->putblock_nt(sound_buf,offset);
270 debug("mpegtoraw.cc:putblock_nt: Wrote %d bytes.\n",processed);
271 /* move processed data out of the way */
272 if (processed==-1)
273 {
274 if(errno!=EAGAIN)
275 debug("putblock_nt: %s", strerror(errno));
276 }
277 else
278 {
279 int tomove= offset - processed;
280 memmove(sound_buf, sound_buf + processed,
281 tomove);
282 /* Patch offset and remaining */
283 offset=tomove;
284 remaining=THREAD_TIMES*RAWDATASIZE * sizeof(short int) - offset;
285 #if 0
286 /* enabling this code on my system totally prevents -1 writes. */
287 if (processed > 1024)
288 {
289 debug("Breaking, wrote enough for now.\n");
290 break;
291 }
292 #endif
293 }
294 } while (remaining > 0 && processed >= THREAD_LIMIT);
295
296 pth_event_t ev;
297 /* I really hoped to use something like
298
299 ev=pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_WRITEABLE,
300 player->audiohandle);
301
302 * But this doesn't seem to work. The event occurs
303 * immediately. Such a shame. */
304
305 ev=pth_event(PTH_EVENT_TIME,pth_timeout(0,5000));
306 pth_wait(ev);
307 pth_event_free(ev,PTH_FREE_THIS);
308 }
309 }
310 /* The playing thread never quits */
311 }
312
tp_hack(void * bla)313 void *tp_hack(void *bla)
314 {
315 decoder->threadplay(bla);
316
317 /* The moron who decided that this should be a C++ class should be shot,
318 if he hasn't been by now already.. */
319 return NULL;
320 }
321
322 struct mpeg_buffer *
get_buffer(short index)323 Mpegtoraw::get_buffer(short index)
324 {
325 return &buffers[index];
326 }
327
328 void
createplayer(void)329 Mpegtoraw::createplayer(void)
330 {
331 pth_attr_t attr;
332 if(play_thread)
333 return;
334 attr = pth_attr_new();
335 pth_attr_set(attr, PTH_ATTR_PRIO, PTH_PRIO_MAX);
336 this->play_thread = pth_spawn(attr, tp_hack, NULL);
337 }
338
339 void
continueplaying(void)340 Mpegtoraw::continueplaying(void)
341 {
342 this->player_run=1;
343 }
344
345 void
abortplayer(void)346 Mpegtoraw::abortplayer(void)
347 {
348 pth_cancel(play_thread);
349 if(!play_thread)
350 return;
351 if(!pth_join(play_thread,NULL)) /* Wait for the playthread to die! */
352 {
353 perror("pth_join");
354 exit(1);
355 }
356 play_thread=(pth_t)NULL;
357 }
358
359 void
pauseplaying(void)360 Mpegtoraw::pauseplaying(void)
361 {
362 //why would you abort the player here??
363 //player->abort();
364 this->player_run=0;
365 }
366
setdecodeframe(int framenumber)367 void Mpegtoraw::setdecodeframe(int framenumber)
368 {
369 int pos=0;
370 char d[100];
371
372 sprintf(d, "Framenumber = %d\n", framenumber);
373 debug(d);
374
375 if(frameoffsets==NULL)return;
376 if(framenumber<=0)
377 {
378 pos=frameoffsets[0];
379 framenumber=0;
380 }
381 else
382 {
383 if (framenumber >= totalframe)
384 framenumber=totalframe-1;
385
386 pos = frameoffsets[framenumber];
387
388 if(pos==0)
389 {
390 int i;
391
392 sprintf(d,"Bumped into an unset frame position (%d)!\n", framenumber);
393 debug(d);
394 for(i=framenumber-1;i>0;i--)
395 if(frameoffsets[i]!=0)break;
396
397 loader->setposition(frameoffsets[i]);
398
399 sprintf(d,"Found first initialized frame at %d bytes (framenumber %d)\n",
400 loader->getposition(), i);
401 debug(d);
402
403 while( i < framenumber )
404 {
405 loadheader();
406 i++;
407 frameoffsets[i]=loader->getposition();
408 }
409 pos=frameoffsets[framenumber];
410 }
411 }
412
413 loader->setposition(pos);
414 decodeframe=framenumber;
415 }
416
makeroom(int size)417 void Mpegtoraw::makeroom(int size)
418 {
419 int clean;
420 int queuesize;
421 buffer_node *temp,*temp2;
422 if(free_buffers >= size) /* No need to throw away things ! */
423 return;
424 clean=size-free_buffers;
425 if(spare) /* Begin releasing from spare buffer */
426 {
427 queuesize=0;
428 temp=spare;
429
430 while(temp)
431 {
432 queuesize++;
433 temp=temp->next;
434 }
435
436 temp = spare;
437
438 if(clean <= queuesize)
439 {
440 /* It fits !*/
441 queuesize-=clean;
442 clean=0;
443
444 while(queuesize-1)
445 {
446 temp=temp->next;
447 queuesize--;
448 }
449 temp2=temp->next;
450 temp->next=NULL;
451 temp=temp2;
452 }
453 else
454 {
455 clean-=queuesize;
456 spare=NULL;
457 }
458
459 while(temp)
460 {
461 release_buffer(temp->index);
462 temp2=temp;
463 temp=temp->next;
464 free(temp2);
465 }
466 }
467 if(clean&&queue) /* Begin releasing from spare buffer */
468 {
469 queuesize=0;
470 temp=queue;
471
472 while(temp)
473 {
474 queuesize++;
475 temp=temp->next;
476 }
477
478 temp = queue;
479
480 if(clean <= queuesize)
481 {
482 /* It fits !*/
483 queuesize-=clean;
484 clean=0;
485
486 while(queuesize-1)
487 {
488 temp=temp->next;
489 queuesize--;
490 }
491
492 temp2=temp->next;
493 temp->next=NULL;
494 temp=temp2;
495 }
496 else
497 {
498 clean-=queuesize;
499 queue=NULL;
500 }
501
502 while(temp)
503 {
504 release_buffer(temp->index);
505 temp2=temp;
506 temp=temp->next;
507 free(temp2);
508 }
509 }
510 }
511 #endif
512
Mpegtoraw(Soundinputstream * loader,Soundplayer * player)513 Mpegtoraw::Mpegtoraw(Soundinputstream *loader,Soundplayer *player)
514 {
515 __errorcode=SOUND_ERROR_OK;
516 frameoffsets=NULL;
517
518 forcetomonoflag = 0;
519 downfrequency = 0;
520 scan_mp3 = 1;
521
522 this->loader=loader;
523 this->player=player;
524 #ifdef NEWTHREAD
525 skip=5;
526 //pre_amp=10;
527 this->buffers=NULL;
528 this->sound_buf=(unsigned char *)malloc(RAWDATASIZE*THREAD_TIMES*sizeof(short int));
529 this->settotalbuffers(1000);
530 this->queue=NULL;
531 this->spare=NULL;
532 decoder=this;
533 this->player_run=0;
534 pth_mutex_init(&queue_mutex);
535 play_thread=(pth_t)NULL;
536 createplayer();
537 continueplaying();
538 #endif
539 }
540
~Mpegtoraw()541 Mpegtoraw::~Mpegtoraw()
542 {
543 if(frameoffsets)
544 {
545 delete [] frameoffsets;
546 }
547 #ifdef NEWTHREAD
548 buffer_node *temp;
549 abortplayer();
550 free(sound_buf);
551 /*
552 if(pthread_mutex_destroy(&queue_mutex))
553 {
554 perror("pthread_mutex_destroy");
555 exit(1);
556 }
557 */
558 //shmdt((char *)buffers);
559 if (buffers)
560 {
561 delete[] buffers;
562 buffers = NULL;
563 }
564 while(queue)
565 {
566 temp=queue;
567 queue=queue->next;
568 free(temp);
569 }
570 while(spare)
571 {
572 temp=spare;
573 spare=spare->next;
574 free(temp);
575 }
576 #endif
577 }
578
579 #ifndef WORDS_BIGENDIAN
580 #define _KEY 0
581 #else
582 #define _KEY 3
583 #endif
584
getbits(int bits)585 int Mpegtoraw::getbits(int bits)
586 {
587 union
588 {
589 char store[4];
590 int current;
591 }u;
592 int bi;
593
594 if(!bits)return 0;
595
596 u.current=0;
597 bi=(bitindex&7);
598 u.store[_KEY]=buffer[bitindex>>3]<<bi;
599 bi=8-bi;
600 bitindex+=bi;
601
602 while(bits)
603 {
604 if(!bi)
605 {
606 u.store[_KEY]=buffer[bitindex>>3];
607 bitindex+=8;
608 bi=8;
609 }
610
611 if(bits>=bi)
612 {
613 u.current<<=bi;
614 bits-=bi;
615 bi=0;
616 }
617 else
618 {
619 u.current<<=bits;
620 bi-=bits;
621 bits=0;
622 }
623 }
624 bitindex-=bi;
625
626 return (u.current>>8);
627 }
628
setforcetomono(short flag)629 void Mpegtoraw::setforcetomono(short flag)
630 {
631 forcetomonoflag=flag;
632 }
633
setdownfrequency(int value)634 void Mpegtoraw::setdownfrequency(int value)
635 {
636 downfrequency = (value ? 1 : 0);
637 }
638
getforcetomono(void)639 short Mpegtoraw::getforcetomono(void)
640 {
641 return forcetomonoflag;
642 }
643
getdownfrequency(void)644 int Mpegtoraw::getdownfrequency(void)
645 {
646 return downfrequency;
647 }
648
getpcmperframe(void)649 int Mpegtoraw::getpcmperframe(void)
650 {
651 int s;
652
653 s=32;
654 if(layer==3)
655 {
656 s*=18;
657 if(version==0)s*=2;
658 }
659 else
660 {
661 s*=SCALEBLOCK;
662 if(layer==2)s*=3;
663 }
664
665 return s;
666 }
667
668 #ifdef NEWTHREAD
flushrawdata(short index)669 inline void Mpegtoraw::flushrawdata(short index)
670 {
671 struct mpeg_buffer *bufje;
672 bufje=get_buffer(index);
673 bufje->framenumber=decodeframe;
674 bufje->framesize=rawdataoffset<<1;
675 memcpy(bufje->data,rawdata,bufje->framesize);
676 queue_buf(index);
677 rawdataoffset=0;
678 }
679 #else
flushrawdata(void)680 inline void Mpegtoraw::flushrawdata(void)
681 #ifdef PTHREADEDMPEG
682 {
683 if(threadflags.thread)
684 {
685 if(((threadqueue.tail+1)%threadqueue.framenumber)==threadqueue.head)
686 {
687 while(((threadqueue.tail+1)%threadqueue.framenumber)==threadqueue.head)
688 USLEEP(200);
689 }
690 memcpy(threadqueue.buffer+(threadqueue.tail*RAWDATASIZE),rawdata,
691 RAWDATASIZE*sizeof(short int));
692 threadqueue.sizes[threadqueue.tail]=(rawdataoffset<<1);
693
694 if(threadqueue.tail>=threadqueue.frametail)
695 threadqueue.tail=0;
696 else threadqueue.tail++;
697 }
698 else
699 {
700 player->putblock((char *)rawdata,rawdataoffset<<1);
701 currentframe++;
702 }
703 rawdataoffset=0;
704 }
705 #else
706 {
707 player->putblock((char *)rawdata,rawdataoffset<<1);
708 currentframe++;
709 rawdataoffset=0;
710 }
711 #endif
712 #endif /* NEWTHREAD */
713
714 typedef struct
715 {
716 char *songname;
717 char *artist;
718 char *album;
719 char *year;
720 char *comment;
721 unsigned char genre;
722 }ID3;
723
strman(char * str,int max)724 static void strman(char *str,int max)
725 {
726 int i;
727
728 str[max]=0;
729
730 for(i=max-1;i>=0;i--)
731 if(((unsigned char)str[i])<26 || str[i]==' ')str[i]=0; else break;
732 }
733
parseID3(Soundinputstream * fp,ID3 * data)734 inline void parseID3(Soundinputstream *fp,ID3 *data)
735 {
736 int tryflag=0;
737
738 data->songname[0]=0;
739 data->artist [0]=0;
740 data->album [0]=0;
741 data->year [0]=0;
742 data->comment [0]=0;
743 data->genre=255;
744
745 fp->setposition(fp->getsize()-128);
746
747 for(;;)
748 {
749 if(fp->getbytedirect()==0x54)
750 {
751 if(fp->getbytedirect()==0x41)
752 {
753 if(fp->getbytedirect()==0x47)
754 {
755 char tmp;
756 fp->_readbuffer(data->songname,30);strman(data->songname,30);
757 fp->_readbuffer(data->artist ,30);strman(data->artist, 30);
758 fp->_readbuffer(data->album ,30);strman(data->album, 30);
759 fp->_readbuffer(data->year , 4);strman(data->year, 4);
760 fp->_readbuffer(data->comment ,30);strman(data->comment, 30);
761 fp->_readbuffer(&tmp,1);
762 data->genre = (unsigned char)tmp;
763 break;
764 }
765 }
766 }
767
768 tryflag++;
769 if (tryflag == 1)
770 fp->setposition(fp->getsize() - 125); // for mpd 0.1, Sorry..
771 else
772 break;
773 }
774
775 fp->setposition(0);
776 }
777
778 // Convert mpeg to raw
779 // Mpeg header class
initialize(const char * filename)780 bool Mpegtoraw::initialize(const char *filename)
781 {
782 register int i;
783 register REAL *s1,*s2;
784 REAL *s3,*s4;
785 static bool initialized=false;
786
787 if (!filename)
788 return false;
789
790 scalefactor = SCALE;
791 calcbufferoffset = 15;
792 currentcalcbuffer = 0;
793
794 s1 = calcbufferL[0]; s2 = calcbufferR[0];
795 s3 = calcbufferL[1]; s4 = calcbufferR[1];
796 for(i=CALCBUFFERSIZE-1;i>=0;i--)
797 {
798 calcbufferL[0][i] = calcbufferL[1][i] =
799 calcbufferR[0][i] = calcbufferR[1][i] = 0.0;
800 }
801
802 if(!initialized)
803 {
804 for(i=0;i<16;i++)hcos_64[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/64.0));
805 for(i=0;i< 8;i++)hcos_32[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/32.0));
806 for(i=0;i< 4;i++)hcos_16[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/16.0));
807 for(i=0;i< 2;i++)hcos_8 [i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/ 8.0));
808 hcos_4=1.0/(2.0*cos(MY_PI*1.0/4.0));
809 initialized=true;
810 }
811
812 layer3initialize();
813
814 currentframe=decodeframe=0;
815 is_vbr = 0;
816 int headcount = 0, first_offset = 0;
817 bool found_first_frame = false;
818 int frameinfo_layer = 0;
819 int frameinfo_version = 0;
820 int frameinfo_samplerate = 0;
821 int frame_start;
822
823 sync();
824
825
826 /* Try to find at least 3 valid mp3 frames at a position where we
827 * expect it, with consistent data. If they can't be found, we don't
828 * consider it to be an mp3.
829 */
830 while (headcount < 3 && geterrorcode() != SOUND_ERROR_FINISH)
831 {
832 frame_start = loader->getposition();
833
834 if (!loadheader(false))
835 {
836 debug("Found a bogus header (or EOF?) Resetting..\n");
837 /* found a bogus header. Reset header counter */
838 headcount = 0;
839 found_first_frame = false;
840
841 if (loader->canseek())
842 loader->setposition(frame_start + 1);
843 /* for streams in which cannot be seeked, we just keep on searching
844 * forward from where we are now, and hope we didn't just halfway into
845 * what's really a valid header. Doesn't matter much though, eventually
846 * we'll bump into a correct header.
847 */
848 continue;
849 }
850
851 if (!found_first_frame)
852 {
853 /* we haven't found the first, valid frame yet.
854 * Maybe this is the one!
855 */
856 debug("Hopefully found the first valid frame at position %d\n", frame_start);
857 first_offset = frame_start;
858 found_first_frame = true;
859 /* store frameinfo which must remain constant */
860 frameinfo_layer = layer;
861 frameinfo_version = version;
862 frameinfo_samplerate = frequency;
863
864 }
865
866 /* after a successful loadheader(), the loader is positioned at the
867 * start of the next expected frame header.
868 */
869
870 /* are the new frame settings consistent with the first found frame?
871 */
872 if ((frameinfo_layer != layer ||
873 frameinfo_version != version ||
874 frameinfo_samplerate != frequency) )
875 {
876 debug("Frame info inconsistent, finding new First Frame\n");
877 found_first_frame = false;
878 headcount = 0;
879 if (loader->canseek())
880 loader->setposition(frame_start + 1);
881 continue;
882 }
883
884 headcount++; /* yay, valid frame */
885
886 if (headcount > 1)
887 {
888 debug("Found %d valid headers so far.\n", headcount);
889 }
890 }
891
892 if (headcount != 3)
893 {
894 debug("Couldn't find 3 consecutive, valid mp3 frames!\n");
895 return false; /* invalid MP3 */
896 }
897
898 /* store this mp3's frame info, for future error checking */
899 header_one.version = version;
900 header_one.mode = mode;
901 header_one.layer = layer;
902 header_one.frequency = frequency;
903
904 /* rewind to first valid frame and read info from it */
905 if (loader->canseek())
906 {
907 loader->setposition(first_offset);
908 loadheader();
909 loader->setposition(first_offset);
910 }
911
912 bool found_xing = false;
913 XHEADDATA xingheader;
914
915 xingheader.toc = NULL;
916
917 /* Try to find a XING header to determine total song length first.
918 * Note that this method only works if the FIRST valid mp3 frame found
919 * contains the XING header. Order of headers in front of mp3's is not
920 * specified though.
921 */
922 /* framesize is set by loadheader, and is the size of the first frame */
923 unsigned char *buffer = new unsigned char[framesize * sizeof(char)];
924 if (loader->canseek() && (loader->getblock((char *)buffer, framesize * sizeof(char)) ==
925 (int)(framesize * sizeof(char))) &&
926 GetXingHeader(&xingheader, buffer))
927 {
928 totalframe = xingheader.frames;
929 found_xing = true;
930 debug("Found XING header, and set total frames to %d.\n", totalframe);
931 }
932 else
933 {
934 debug("No XING header found, assuming CBR mp3.\n");
935 totalframe = (loader->getsize() + framesize - 1) / framesize;
936 }
937 delete[] buffer;
938 buffer = NULL;
939
940 if (loader->canseek())
941 loader->setposition(first_offset);
942
943 if(frameoffsets)
944 delete[] frameoffsets;
945
946 songinfo.name[0]=0;
947 if (totalframe > 0)
948 {
949 frameoffsets=new int[totalframe];
950 for(i=totalframe-1;i>=0;i--)
951 frameoffsets[i]=0;
952
953 //Bram Avontuur: I added this. The original author figured an mp3
954 //would always start with a valid header (which is false if there's a
955 //sequence of 3 0xf's that's not part of a valid header)
956 frameoffsets[0] = first_offset;
957 //till here. And a loader->setposition later in this function.
958
959 {
960 ID3 data;
961
962 data.songname=songinfo.name;
963 data.artist =songinfo.artist;
964 data.album =songinfo.album;
965 data.year =songinfo.year;
966 data.comment =songinfo.comment;
967 //data.genre =songinfo.genre;
968 parseID3(loader,&data);
969 songinfo.genre = data.genre;
970 }
971 }
972 else frameoffsets=NULL;
973
974 #ifndef NEWTHREAD
975 #ifdef PTHREADEDMPEG
976 threadflags.thread=false;
977 threadqueue.buffer=NULL;
978 threadqueue.sizes=NULL;
979 #endif
980 #endif /* NEWTHREAD */
981
982 if (loader->canseek() && totalframe)
983 {
984 /*Calculate length of [vbr] mp3. Neat if you don't have XING headers,
985 bad if you stream mp3's over a slow network connection/disk (since
986 it seeks through the entire file)
987 Note that it doesn't work well, since it uses a bogusly calculated
988 totalframe, which means it can never detect songs that actually have
989 *more* frames than that.
990 */
991 if (scan_mp3 && !found_xing)
992 {
993 // Get frame offsets, by calculating all offsets of the headers.
994 setframe(totalframe - 1);
995
996 // Cut off last frame until there is an offset change
997 int i;
998 int lastOffset = frameoffsets[totalframe - 1];
999 for(i = totalframe - 2;i > 0;i--)
1000 {
1001 if(frameoffsets[i] != lastOffset)
1002 {
1003 break;
1004 }
1005 }
1006 totalframe = i;
1007
1008 debug("Manually calculated total frames : %d\n", totalframe);
1009
1010 // Reset position
1011 setframe(0);
1012 }
1013
1014 loader->setposition(first_offset);
1015 seterrorcode(SOUND_ERROR_OK);
1016 }
1017
1018 /* set loader to start of first valid frame.
1019 * Maybe it should point to the bytes FOLLOWING the header, I'm not sure..
1020 * ::run() loads its own header first, so let's assume this is correct.
1021 */
1022 if (loader->canseek())
1023 loader->setposition(first_offset);
1024
1025 return (totalframe != 0);
1026 }
1027
1028 #ifdef NEWTHREAD
setframe(int framenumber)1029 void Mpegtoraw::setframe(int framenumber)
1030 {
1031 buffer_node *temp;
1032 abortplayer();
1033 player->abort();
1034 if(queue)
1035 {
1036 if(buffers[queue->index].framenumber < framenumber)
1037 {
1038 while(queue && buffers[queue->index].framenumber < framenumber)
1039 {
1040 dequeue_first();
1041 }
1042 }
1043 else
1044 {
1045 makeroom(buffers[queue->index].framenumber - framenumber);
1046
1047 if(spare)
1048 {
1049 temp=queue;
1050 while(temp->next)
1051 temp=temp->next;
1052 temp->next=spare;
1053 }
1054 spare=queue;
1055 queue=NULL;
1056 }
1057 }
1058 if(!queue) /* Hint: This is -not- the same as an 'else' from the previous if*/
1059 {
1060 //can't skip 2 frames because initialization of frameoffsets[] in
1061 //setdecodeframe will fail to set the last 2 indices then.
1062 //setdecodeframe(framenumber-2);
1063 //skip=2;
1064 setdecodeframe(framenumber);
1065 skip=0;
1066 }
1067 createplayer();
1068 }
1069 #else /* NEWTHREAD */
setframe(int framenumber)1070 void Mpegtoraw::setframe(int framenumber)
1071 {
1072 int pos=0;
1073 char d[100];
1074
1075 if (frameoffsets==NULL)
1076 return;
1077
1078 if (framenumber==0)
1079 pos = frameoffsets[0];
1080 else
1081 {
1082 if (framenumber >= totalframe)
1083 framenumber = totalframe - 1;
1084
1085 pos=frameoffsets[framenumber];
1086
1087 if(pos==0)
1088 {
1089 int i;
1090
1091 for (i = framenumber - 1; i > 0; i--)
1092 {
1093 if (frameoffsets[i] != 0)
1094 break;
1095 }
1096
1097 loader->setposition(frameoffsets[i]);
1098
1099 sprintf(d, "Found first offset at %d (%d/%d)\n", loader->getposition(),
1100 i, framenumber);
1101 debug(d);
1102
1103 while(i < framenumber)
1104 {
1105 i++;
1106 loadheader();
1107 frameoffsets[i] = loader->getposition();
1108 }
1109 pos = frameoffsets[framenumber];
1110 }
1111 }
1112
1113 clearbuffer();
1114 loader->setposition(pos);
1115 decodeframe=currentframe=framenumber;
1116 }
1117 #endif /* NEWTHREAD */
1118
clearbuffer(void)1119 void Mpegtoraw::clearbuffer(void)
1120 {
1121 debug("clearbuffer\n");
1122 #ifndef NEWTHREAD
1123 #ifdef PTHREADEDMPEG
1124 if(threadflags.thread)
1125 {
1126 /* stop the playback loop */
1127 threadflags.criticalflag=false;
1128 threadflags.criticallock=true;
1129 while(!threadflags.criticalflag)USLEEP(1);
1130 threadqueue.head=threadqueue.tail=0;
1131 }
1132 #endif
1133 #endif /* NEWTHREAD */
1134
1135 //give player the chance to reset itself
1136 player->abort();
1137 player->resetsoundtype();
1138
1139 #ifndef NEWTHREAD
1140 #ifdef PTHREADEDMPEG
1141 if(threadflags.thread)
1142 {
1143 threadflags.criticallock=false;
1144 }
1145 #endif
1146 #endif /* NEWTHREAD */
1147 }
1148
1149 //find a valid frame. If an invalid frame is found, the filepointer
1150 //points to the location where the next frame is to be expected, and 'true'
1151 //is returned.
1152 //if 'lookahead' is false, loadheader will return false if the expected
1153 //header is not found at the exact location of the filepointer at call time.
loadheader(bool lookahead)1154 bool Mpegtoraw::loadheader(bool lookahead)
1155 {
1156 register int c;
1157 bool flag;
1158 int bytes_read = 0;
1159
1160 sync();
1161
1162 // Synchronize
1163 flag=false;
1164 do
1165 {
1166 if ( (c = loader->getbytedirect()) < 0 )
1167 break;
1168
1169 bytes_read++;
1170
1171 if (c == 0xff)
1172 {
1173 if ( (c = loader->getbytedirect()) < 0)
1174 break;
1175
1176 bytes_read++;
1177
1178 if ( (c&0xf0) == 0xf0 )
1179 flag=true;
1180 else if (!lookahead)
1181 return seterrorcode(SOUND_ERROR_BAD);
1182 }
1183 else if (!lookahead)
1184 {
1185 return seterrorcode(SOUND_ERROR_BAD);
1186 }
1187 } while (!flag);
1188
1189 if (c < 0)
1190 return seterrorcode(SOUND_ERROR_FINISH);
1191
1192 // Analyzing
1193 c &= 0xf; /* c = 0 0 0 0 bit13 bit14 bit15 bit16 */
1194 protection = c&1; /* bit16 */
1195 layer = 4 - ( (c>>1)&3 ); /* bit 14 bit 15: 1..4, 4=invalid */
1196 if (layer == 4)
1197 return seterrorcode(SOUND_ERROR_BAD);
1198
1199 version = (_mpegversion)((c>>3)^1); /* bit 13 */
1200
1201 if ((c = loader->getbytedirect()) < 0)
1202 return seterrorcode(SOUND_ERROR_FINISH);
1203
1204 bytes_read++;
1205
1206 c >>= 1; /* c = 0 bit17 .. bit23 */
1207 padding = (c&1);
1208 c >>= 1;
1209
1210 frequency = (_frequency)(c&3);
1211 c >>= 2;
1212
1213 if (frequency > 2)
1214 return seterrorcode(SOUND_ERROR_BAD);
1215
1216 bitrateindex = (int)c;
1217 if (bitrateindex == 15 || !bitrateindex)
1218 return seterrorcode(SOUND_ERROR_BAD);
1219
1220 if ((c = loader->getbytedirect()) < 0)
1221 return seterrorcode(SOUND_ERROR_FINISH);
1222
1223 bytes_read++;
1224
1225 c = ((unsigned int)c)>>4;
1226 /* c = 0 0 0 0 bit25 bit26 bit27 bit27 bit28 */
1227 extendedmode = c&3;
1228 mode = (_mode)(c>>2);
1229
1230 // Making information
1231 inputstereo = ( (mode==single) ? 0 : 1 );
1232 if (forcetomonoflag)
1233 outputstereo = 0;
1234 else
1235 outputstereo = inputstereo;
1236
1237 channelbitrate = bitrateindex;
1238 if (inputstereo)
1239 {
1240 if (channelbitrate == 4)
1241 channelbitrate = 1;
1242 else
1243 channelbitrate-=4;
1244 }
1245
1246 if(channelbitrate == 1 || channelbitrate == 2)
1247 tableindex = 0;
1248 else
1249 tableindex = 1;
1250
1251 if (layer == 1)
1252 subbandnumber = MAXSUBBAND;
1253 else
1254 {
1255 if(!tableindex)
1256 {
1257 if(frequency==frequency32000)
1258 subbandnumber=12;
1259 else
1260 subbandnumber=8;
1261 }
1262 else if (frequency==frequency48000 ||
1263 (channelbitrate>=3 && channelbitrate<=5))
1264 {
1265 subbandnumber=27;
1266 }
1267 else
1268 subbandnumber=30;
1269 }
1270
1271 if (mode==single)
1272 stereobound=0;
1273 else if(mode==joint)
1274 stereobound = (extendedmode+1)<<2;
1275 else
1276 stereobound = subbandnumber;
1277
1278 if (stereobound>subbandnumber)
1279 stereobound = subbandnumber;
1280
1281 // framesize & slots
1282 if (layer==1)
1283 {
1284 framesize=(12000*bitrate[version][0][bitrateindex])/
1285 frequencies[version][frequency];
1286 if (frequency==frequency44100 && padding)
1287 framesize++;
1288 framesize<<=2;
1289 }
1290 else
1291 {
1292 framesize=(144000*bitrate[version][layer-1][bitrateindex])/
1293 (frequencies[version][frequency]<<version);
1294 if(padding)
1295 framesize++;
1296 if(layer==3)
1297 {
1298 if(version)
1299 layer3slots = framesize - ((mode==single)?9:17) - (protection?0:2) - 4;
1300 else
1301 layer3slots = framesize-((mode==single)?17:32) - (protection?0:2) - 4;
1302 }
1303 }
1304
1305 if(!fillbuffer(framesize-4))
1306 seterrorcode(SOUND_ERROR_FILEREADFAIL);
1307
1308 bytes_read += (framesize - 4);
1309
1310 if(!protection)
1311 {
1312 getbyte(); // ignore CRC
1313 getbyte();
1314 }
1315
1316 if (loader->eof())
1317 return seterrorcode(SOUND_ERROR_FINISH);
1318
1319 return true;
1320 }
1321
1322 /***************************/
1323 /* Playing in multi-thread */
1324 /***************************/
1325 #ifndef NEWTHREAD
1326 #ifdef PTHREADEDMPEG
1327 /* Player routine */
threadedplayer(void)1328 void Mpegtoraw::threadedplayer(void)
1329 {
1330 while(!threadflags.quit)
1331 {
1332 while(threadflags.pause || threadflags.criticallock)
1333 {
1334 threadflags.criticalflag=true;
1335 USLEEP(200);
1336 }
1337
1338 if(threadqueue.head!=threadqueue.tail)
1339 {
1340 player->putblock(threadqueue.buffer+threadqueue.head*RAWDATASIZE,
1341 threadqueue.sizes[threadqueue.head]);
1342 currentframe++;
1343 if(threadqueue.head==threadqueue.frametail)
1344 threadqueue.head=0;
1345 else threadqueue.head++;
1346 }
1347 else
1348 {
1349 if(threadflags.done)break; // Terminate when done
1350 USLEEP(200);
1351 }
1352 }
1353 threadflags.thread=false;
1354 }
1355
threadlinker(void * arg)1356 static void *threadlinker(void *arg)
1357 {
1358 ((Mpegtoraw *)arg)->threadedplayer();
1359
1360 return NULL;
1361 }
1362
makethreadedplayer(int framenumbers)1363 bool Mpegtoraw::makethreadedplayer(int framenumbers)
1364 {
1365 pthread_attr_t attrs;
1366
1367 threadqueue.buffer=
1368 (short int *)malloc(sizeof(short int)*RAWDATASIZE*framenumbers);
1369 if(threadqueue.buffer==NULL)
1370 seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH);
1371 threadqueue.sizes=(int *)malloc(sizeof(int)*framenumbers);
1372 if(threadqueue.sizes==NULL)
1373 seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH);
1374 threadqueue.framenumber=framenumbers;
1375 threadqueue.frametail=framenumbers-1;
1376 threadqueue.head=threadqueue.tail=0;
1377
1378
1379 threadflags.quit=threadflags.done=
1380 threadflags.pause=threadflags.criticallock=false;
1381
1382 threadflags.thread=true;
1383 (void)pthread_attr_init(&attrs);
1384 (void)pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
1385 if(pthread_create(&thread,&attrs,threadlinker,this))
1386 {
1387 seterrorcode(SOUND_ERROR_THREADFAIL);
1388 return false;
1389 }
1390
1391 return true;
1392 }
1393
freethreadedplayer(void)1394 void Mpegtoraw::freethreadedplayer(void)
1395 {
1396 threadflags.criticallock=
1397 threadflags.pause=false;
1398 threadflags.done=true; // Terminate thread player
1399 while(threadflags.thread)USLEEP(10); // Wait for done...
1400 if(threadqueue.buffer)
1401 {
1402 free(threadqueue.buffer);
1403 threadqueue.buffer = NULL;
1404 }
1405 if(threadqueue.sizes)
1406 {
1407 free(threadqueue.sizes);
1408 threadqueue.sizes = NULL;
1409 }
1410 }
1411
stopthreadedplayer(void)1412 void Mpegtoraw::stopthreadedplayer(void)
1413 {
1414 threadflags.quit=true;
1415 };
1416
pausethreadedplayer(void)1417 void Mpegtoraw::pausethreadedplayer(void)
1418 {
1419 threadflags.pause=true;
1420 };
1421
unpausethreadedplayer(void)1422 void Mpegtoraw::unpausethreadedplayer(void)
1423 {
1424 threadflags.pause=false;
1425 };
1426
1427
existthread(void)1428 bool Mpegtoraw::existthread(void)
1429 {
1430 return threadflags.thread;
1431 }
1432
getframesaved(void)1433 int Mpegtoraw::getframesaved(void)
1434 {
1435 if(threadqueue.framenumber)
1436 return
1437 ((threadqueue.tail+threadqueue.framenumber-threadqueue.head)
1438 %threadqueue.framenumber);
1439 return 0;
1440 }
1441
1442 #endif
1443 #endif /* NEWTHREAD */
1444
1445
1446
1447 // Convert mpeg to raw
run(int frames)1448 bool Mpegtoraw::run(int frames)
1449 {
1450 #ifdef NEWTHREAD
1451 short buffer_number = -1;
1452 buffer_node *temp;
1453 #endif
1454 clearrawdata();
1455
1456 for(;frames;frames--)
1457 {
1458 #ifdef NEWTHREAD
1459 if(spare) /* There are frames in the spare buffer! */
1460 {
1461 pth_mutex_acquire(&queue_mutex,FALSE,NULL);
1462 if(buffers[spare->index].framenumber < decodeframe)
1463 {
1464 /* Houston, we have a problem! */
1465 while(spare && buffers[spare->index].framenumber < decodeframe)
1466 {
1467 release_buffer(spare->index);
1468 temp=spare;
1469 spare=spare->next;
1470 free(temp);
1471 }
1472 pth_mutex_release(&queue_mutex);
1473 continue;
1474 }
1475 if(buffers[spare->index].framenumber==decodeframe)
1476 {
1477 while(spare && buffers[spare->index].framenumber==decodeframe)
1478 {
1479 queue_buf(spare->index);
1480 spare=spare->next;
1481 decodeframe++;
1482 }
1483 setdecodeframe(decodeframe-5); /* Not that stupid as it seems */
1484 skip=4;
1485 }
1486 pth_mutex_release(&queue_mutex);
1487 } /* If(spare) */
1488
1489 if(!skip)
1490 {
1491 pth_mutex_acquire(&queue_mutex,FALSE,NULL);
1492 buffer_number=request_buffer();
1493 pth_mutex_release(&queue_mutex);
1494 if(buffer_number==-1) /* No free buffers available */
1495 break;
1496 }
1497 else
1498 #endif
1499 if(totalframe>0)
1500 {
1501 if(decodeframe<totalframe)
1502 frameoffsets[decodeframe]=loader->getposition();
1503 }
1504
1505 bool found_frame = false;
1506
1507 while (!found_frame && !loader->eof())
1508 {
1509 if(loadheader()==false)
1510 {
1511 /* loadheader advances the file stream pointer, so it's safe to
1512 * keep on calling it.
1513 */
1514 debug("Invalid frame found (pos ~= %d)\n", loader->getposition());
1515 continue;
1516 }
1517
1518 if (version != header_one.version || mode != header_one.mode ||
1519 layer != header_one.layer || frequency != header_one.frequency)
1520 {
1521 /* argh. Bogus frame. */
1522 debug("Invalid frame found (pos ~= %d)\n", loader->getposition());
1523 continue;
1524 }
1525
1526 found_frame = true;
1527 }
1528
1529 if(loader->eof())
1530 {
1531 #ifdef NEWTHREAD
1532 if(!skip)
1533 {
1534 pth_mutex_acquire(&queue_mutex,FALSE,NULL);
1535 release_buffer(buffer_number);
1536 pth_mutex_release(&queue_mutex);
1537 }
1538 #endif
1539 seterrorcode(SOUND_ERROR_FINISH);
1540 break;
1541 }
1542
1543 if (frames < 0)
1544 {
1545 if (!player->setsoundtype(outputstereo,16,
1546 frequencies[version][frequency]>>downfrequency))
1547 {
1548 debug("Error in (re)setting sound type.\n");
1549 return seterrorcode(player->geterrorcode());
1550 }
1551 }
1552
1553 if(frames<0)
1554 {
1555 frames=-frames;
1556 totaltime = (totalframe * framesize) / (getbitrate() * 125);
1557 }
1558
1559 decodeframe++;
1560
1561 if (layer==3)extractlayer3();
1562 else if(layer==2)extractlayer2();
1563 else if(layer==1)extractlayer1();
1564
1565 #ifdef NEWTHREAD
1566 if(skip)
1567 {
1568 skip--;
1569 rawdataoffset=0;
1570 }
1571 else
1572 {
1573 pth_mutex_acquire(&queue_mutex,FALSE,NULL);
1574 flushrawdata(buffer_number);
1575 pth_mutex_release(&queue_mutex);
1576 }
1577 #else
1578 flushrawdata();
1579 #endif
1580 if(player->geterrorcode())seterrorcode(geterrorcode());
1581 }
1582
1583 #ifdef NEWTHREAD
1584 if (geterrorcode() != SOUND_ERROR_OK && queue)
1585 {
1586 /* Done decoding, but there's still music in the buffer */
1587 USLEEP(10000);
1588 seterrorcode(SOUND_ERROR_OK);
1589 }
1590 if (getfreebuffers() < 10) //buffer is quite full, let's wait a bit
1591 USLEEP(10000);
1592 #endif
1593
1594 if (geterrorcode()==SOUND_ERROR_OK ||
1595 geterrorcode() == SOUND_ERROR_BAD ||
1596 geterrorcode() == SOUND_ERROR_BADHEADER)
1597 return true;
1598 else
1599 return false;
1600 }
1601