summaryrefslogtreecommitdiff
path: root/firmware/mpeg.c
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2002-07-26 14:32:24 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2002-07-26 14:32:24 +0000
commit42faf56472cbd803d4746d0d0866871c101050df (patch)
tree123c638283bd77f67dc375ead34de5c080b4b7e6 /firmware/mpeg.c
parentd5d38f120b458182a5c9c0f0b799f8f949376e45 (diff)
downloadrockbox-42faf56472cbd803d4746d0d0866871c101050df.tar.gz
rockbox-42faf56472cbd803d4746d0d0866871c101050df.zip
New and improved ID3 and track change handling
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1455 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/mpeg.c')
-rw-r--r--firmware/mpeg.c203
1 files changed, 152 insertions, 51 deletions
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 00b2d660a3..359db614ce 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -23,6 +23,8 @@
23#include "id3.h" 23#include "id3.h"
24#include "mpeg.h" 24#include "mpeg.h"
25#include "ata.h" 25#include "ata.h"
26#include "malloc.h"
27#include "string.h"
26#ifndef SIMULATOR 28#ifndef SIMULATOR
27#include "i2c.h" 29#include "i2c.h"
28#include "mas.h" 30#include "mas.h"
@@ -139,15 +141,93 @@ int mpeg_sound_default(int setting)
139} 141}
140 142
141/* list of tracks in memory */ 143/* list of tracks in memory */
142#define MAX_ID3_TAGS 12 144#define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */
143static struct { 145#define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1)
146
147struct id3tag
148{
144 struct mp3entry id3; 149 struct mp3entry id3;
145 int mempos; 150 int mempos;
146} id3tags[MAX_ID3_TAGS]; 151};
152
153static struct id3tag *id3tags[MAX_ID3_TAGS];
154
147static unsigned int current_track_counter = 0; 155static unsigned int current_track_counter = 0;
148static unsigned int last_track_counter = 0; 156static unsigned int last_track_counter = 0;
149 157
150#ifndef SIMULATOR 158#ifndef SIMULATOR
159
160static int tag_read_idx = 0;
161static int tag_write_idx = 0;
162
163static int num_tracks_in_memory(void)
164{
165 return (tag_write_idx - tag_read_idx) & MAX_ID3_TAGS_MASK;
166}
167#endif
168
169#ifndef SIMULATOR
170static void debug_tags(void)
171{
172#ifdef DEBUG
173 int i;
174
175 for(i = 0;i < MAX_ID3_TAGS;i++)
176 {
177 DEBUGF("id3tags[%d]: %08x", i, id3tags[i]);
178 if(id3tags[i])
179 DEBUGF(" - %s", id3tags[i]->id3.path);
180 DEBUGF("\n");
181 }
182 DEBUGF("read: %d, write :%d\n", tag_read_idx, tag_write_idx);
183 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
184#endif
185}
186
187static bool append_tag(struct id3tag *tag)
188{
189 if(num_tracks_in_memory() < MAX_ID3_TAGS - 1)
190 {
191 id3tags[tag_write_idx] = tag;
192 tag_write_idx = (tag_write_idx+1) & MAX_ID3_TAGS_MASK;
193 debug_tags();
194 return true;
195 }
196 else
197 {
198 DEBUGF("Tag memory is full\n");
199 return false;
200 }
201}
202
203static void remove_current_tag(void)
204{
205 int oldidx = tag_read_idx;
206 struct id3tag *tag = id3tags[tag_read_idx];
207
208 if(num_tracks_in_memory() > 0)
209 {
210 /* First move the index, so nobody tries to access the tag */
211 tag_read_idx = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
212
213 /* Now delete it */
214 id3tags[oldidx] = NULL;
215 free(tag);
216 debug_tags();
217 }
218}
219
220static void remove_all_tags(void)
221{
222 int i;
223
224 for(i = 0;i < MAX_ID3_TAGS;i++)
225 remove_current_tag();
226 debug_tags();
227}
228#endif
229
230#ifndef SIMULATOR
151static int last_tag = 0; 231static int last_tag = 0;
152static int last_dma_tick = 0; 232static int last_dma_tick = 0;
153static int pause_tick = 0; 233static int pause_tick = 0;
@@ -380,7 +460,8 @@ static void dma_tick(void)
380 if(!(SCR0 & 0x80)) 460 if(!(SCR0 & 0x80))
381 start_dma(); 461 start_dma();
382 } 462 }
383 id3tags[0].id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ; 463 id3tags[tag_read_idx]->id3.elapsed +=
464 (current_tick - last_dma_tick) * 1000 / HZ;
384 last_dma_tick = current_tick; 465 last_dma_tick = current_tick;
385 } 466 }
386} 467}
@@ -412,7 +493,7 @@ void DEI3(void)
412{ 493{
413 int unplayed_space_left; 494 int unplayed_space_left;
414 int space_until_end_of_buffer; 495 int space_until_end_of_buffer;
415 int track_offset = 0; 496 int track_offset = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
416 497
417 if(playing) 498 if(playing)
418 { 499 {
@@ -421,12 +502,12 @@ void DEI3(void)
421 mp3buf_read = 0; 502 mp3buf_read = 0;
422 503
423 /* First, check if we are on a track boundary */ 504 /* First, check if we are on a track boundary */
424 if (last_tag > 1) 505 if (num_tracks_in_memory() > 0)
425 { 506 {
426 if (mp3buf_read == id3tags[1].mempos) 507 if (mp3buf_read == id3tags[track_offset]->mempos)
427 { 508 {
428 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0); 509 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
429 track_offset = 1; 510 track_offset = (track_offset+1) & MAX_ID3_TAGS_MASK;
430 } 511 }
431 } 512 }
432 513
@@ -449,15 +530,15 @@ void DEI3(void)
449 space_until_end_of_buffer); 530 space_until_end_of_buffer);
450 531
451 /* several tracks loaded? */ 532 /* several tracks loaded? */
452 if ((last_tag - track_offset) > 1) 533 if (num_tracks_in_memory() > 1)
453 { 534 {
454 /* will we move across the track boundary? */ 535 /* will we move across the track boundary? */
455 if (( mp3buf_read < id3tags[1+track_offset].mempos ) && 536 if (( mp3buf_read < id3tags[track_offset]->mempos ) &&
456 ((mp3buf_read+last_dma_chunk_size) > 537 ((mp3buf_read+last_dma_chunk_size) >
457 id3tags[1+track_offset].mempos )) 538 id3tags[track_offset]->mempos ))
458 { 539 {
459 /* Make sure that we end exactly on the boundary */ 540 /* Make sure that we end exactly on the boundary */
460 last_dma_chunk_size = id3tags[1+track_offset].mempos 541 last_dma_chunk_size = id3tags[track_offset]->mempos
461 - mp3buf_read; 542 - mp3buf_read;
462 } 543 }
463 } 544 }
@@ -468,6 +549,7 @@ void DEI3(void)
468 else 549 else
469 { 550 {
470 DEBUGF("No more MP3 data. Stopping.\n"); 551 DEBUGF("No more MP3 data. Stopping.\n");
552 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
471 CHCR3 = 0; /* Stop DMA interrupt */ 553 CHCR3 = 0; /* Stop DMA interrupt */
472 playing = false; 554 playing = false;
473 } 555 }
@@ -483,11 +565,34 @@ void IMIA1(void)
483 TSR1 &= ~0x01; 565 TSR1 &= ~0x01;
484} 566}
485 567
568static void add_track_to_tag_list(char *filename)
569{
570 struct id3tag *t;
571
572 /* grab id3 tag of new file and
573 remember where in memory it starts */
574 t = malloc(sizeof(struct id3tag));
575 if(t)
576 {
577 mp3info(&(t->id3), filename);
578 t->mempos = mp3buf_write;
579 t->id3.elapsed = 0;
580 if(!append_tag(t))
581 {
582 free(t);
583 DEBUGF("Tag list is full\n");
584 }
585 }
586 else
587 {
588 DEBUGF("No memory available for id3 tag");
589 }
590}
591
486/* If next_track is true, opens the next track, if false, opens prev track */ 592/* If next_track is true, opens the next track, if false, opens prev track */
487static int new_file(bool next_track) 593static int new_file(bool next_track)
488{ 594{
489 char *trackname; 595 char *trackname;
490 int i;
491 596
492 do { 597 do {
493 trackname = peek_next_track( next_track ? 1 : -1 ); 598 trackname = peek_next_track( next_track ? 1 : -1 );
@@ -500,18 +605,9 @@ static int new_file(bool next_track)
500 if(mpeg_file < 0) { 605 if(mpeg_file < 0) {
501 DEBUGF("Couldn't open file: %s\n",trackname); 606 DEBUGF("Couldn't open file: %s\n",trackname);
502 } 607 }
503 else { 608 else
504 /* grab id3 tag of new file and remember where 609 {
505 in memory it starts */ 610 add_track_to_tag_list(trackname);
506 if ( last_tag < MAX_ID3_TAGS ) {
507 mp3info(&(id3tags[last_tag].id3), trackname);
508 id3tags[last_tag].mempos = mp3buf_write;
509 last_tag++;
510 for(i = 0;i < last_tag;i++)
511 {
512 DEBUGF("nf: %d, %x\n", i, id3tags[i].mempos);
513 }
514 }
515 } 611 }
516 } while ( mpeg_file < 0 ); 612 } while ( mpeg_file < 0 );
517 613
@@ -527,6 +623,7 @@ static void stop_playing(void)
527 close(mpeg_file); 623 close(mpeg_file);
528 mpeg_file = -1; 624 mpeg_file = -1;
529 stop_dma(); 625 stop_dma();
626 remove_all_tags();
530} 627}
531 628
532static void mpeg_thread(void) 629static void mpeg_thread(void)
@@ -537,7 +634,6 @@ static void mpeg_thread(void)
537 int unplayed_space_left; 634 int unplayed_space_left;
538 int amount_to_read; 635 int amount_to_read;
539 int amount_to_swap; 636 int amount_to_swap;
540 int i;
541 637
542 play_pending = false; 638 play_pending = false;
543 playing = false; 639 playing = false;
@@ -559,6 +655,7 @@ static void mpeg_thread(void)
559 stop_dma(); 655 stop_dma();
560 656
561 reset_mp3_buffer(); 657 reset_mp3_buffer();
658 remove_all_tags();
562 659
563 if(mpeg_file >= 0) 660 if(mpeg_file >= 0)
564 close(mpeg_file); 661 close(mpeg_file);
@@ -569,13 +666,8 @@ static void mpeg_thread(void)
569 if ( new_file(true) == -1 ) 666 if ( new_file(true) == -1 )
570 return; 667 return;
571 } 668 }
572 669
573 /* grab id3 tag of new file and 670 add_track_to_tag_list((char *)ev.data);
574 remember where in memory it starts */
575 mp3info(&(id3tags[0].id3), ev.data);
576 id3tags[0].mempos = mp3buf_write;
577 last_tag=1;
578 id3tags[0].id3.elapsed = 0;
579 671
580 /* Make it read more data */ 672 /* Make it read more data */
581 filling = true; 673 filling = true;
@@ -618,12 +710,13 @@ static void mpeg_thread(void)
618 stop_dma(); 710 stop_dma();
619 711
620 reset_mp3_buffer(); 712 reset_mp3_buffer();
713
621 /* Open the next file */ 714 /* Open the next file */
622 if (mpeg_file >= 0) 715 if (mpeg_file >= 0)
623 close(mpeg_file); 716 close(mpeg_file);
624 last_tag=0; 717 last_tag=0;
625 if (new_file(true) < 0) { 718 if (new_file(true) < 0) {
626 DEBUGF("Finished Playing!\n"); 719 DEBUGF("No more files to play\n");
627 filling = false; 720 filling = false;
628 } else { 721 } else {
629 /* Make it read more data */ 722 /* Make it read more data */
@@ -651,7 +744,7 @@ static void mpeg_thread(void)
651 close(mpeg_file); 744 close(mpeg_file);
652 last_tag=0; 745 last_tag=0;
653 if (new_file(false) < 0) { 746 if (new_file(false) < 0) {
654 DEBUGF("Finished Playing!\n"); 747 DEBUGF("No more files to play\n");
655 filling = false; 748 filling = false;
656 } else { 749 } else {
657 /* Make it read more data */ 750 /* Make it read more data */
@@ -701,7 +794,11 @@ static void mpeg_thread(void)
701 playing yet. If not, do it. */ 794 playing yet. If not, do it. */
702 if(play_pending) 795 if(play_pending)
703 { 796 {
704 if((mp3buf_swapwrite - mp3buf_read) >= MPEG_LOW_WATER) 797 /* If the filling has stopped, and we still haven't reached
798 the watermark, the file must be smaller than the
799 watermark. We must still play it. */
800 if(((mp3buf_swapwrite - mp3buf_read) >= MPEG_LOW_WATER) ||
801 !filling)
705 { 802 {
706 DEBUGF("P\n"); 803 DEBUGF("P\n");
707 play_pending = false; 804 play_pending = false;
@@ -779,11 +876,8 @@ static void mpeg_thread(void)
779 DEBUGF("W\n"); 876 DEBUGF("W\n");
780 } 877 }
781 878
782 if(!play_pending) 879 /* Tell ourselves that we want more data */
783 { 880 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
784 /* Tell ourselves that we want more data */
785 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
786 }
787 } 881 }
788 else 882 else
789 { 883 {
@@ -802,7 +896,7 @@ static void mpeg_thread(void)
802 if(new_file(1) < 0) 896 if(new_file(1) < 0)
803 { 897 {
804 /* No more data to play */ 898 /* No more data to play */
805 DEBUGF("Finished playing\n"); 899 DEBUGF("No more files to play\n");
806 filling = false; 900 filling = false;
807 } 901 }
808 else 902 else
@@ -821,13 +915,7 @@ static void mpeg_thread(void)
821 /* Reset the AVC */ 915 /* Reset the AVC */
822 mpeg_sound_set(SOUND_AVC, -1); 916 mpeg_sound_set(SOUND_AVC, -1);
823#endif 917#endif
824 /* shift array so index 0 is current track */ 918 remove_current_tag();
825 for (i=0; i<last_tag-1; i++)
826 {
827 id3tags[i] = id3tags[i+1];
828 DEBUGF("tc: %d, %x\n", i, id3tags[i].mempos);
829 }
830 last_tag--;
831 919
832 current_track_counter++; 920 current_track_counter++;
833 break; 921 break;
@@ -890,9 +978,20 @@ static void setup_sci0(void)
890} 978}
891#endif /* SIMULATOR */ 979#endif /* SIMULATOR */
892 980
981#ifdef SIMULATOR
982static struct mp3entry taginfo;
983#endif
984
893struct mp3entry* mpeg_current_track(void) 985struct mp3entry* mpeg_current_track(void)
894{ 986{
895 return &(id3tags[0].id3); 987#ifdef SIMULATOR
988 return &taginfo;
989#else
990 if(num_tracks_in_memory())
991 return &(id3tags[tag_read_idx]->id3);
992 else
993 return NULL;
994#endif
896} 995}
897 996
898bool mpeg_has_changed_track(void) 997bool mpeg_has_changed_track(void)
@@ -908,7 +1007,7 @@ bool mpeg_has_changed_track(void)
908void mpeg_play(char* trackname) 1007void mpeg_play(char* trackname)
909{ 1008{
910#ifdef SIMULATOR 1009#ifdef SIMULATOR
911 mp3info(&(id3tags[0].id3), trackname); 1010 mp3info(&taginfo, trackname);
912#else 1011#else
913 queue_post(&mpeg_queue, MPEG_PLAY, trackname); 1012 queue_post(&mpeg_queue, MPEG_PLAY, trackname);
914#endif 1013#endif
@@ -1217,4 +1316,6 @@ void mpeg_init(int volume, int bass, int treble, int loudness, int bass_boost, i
1217 mpeg_sound_set(SOUND_AVC, avc); 1316 mpeg_sound_set(SOUND_AVC, avc);
1218#endif 1317#endif
1219#endif /* !SIMULATOR */ 1318#endif /* !SIMULATOR */
1319
1320 memset(id3tags, sizeof(id3tags), 0);
1220} 1321}