diff options
author | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-01-10 15:39:56 +0000 |
---|---|---|
committer | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-01-10 15:39:56 +0000 |
commit | ec5d44627fb8a409c445741264cc4f2995a17721 (patch) | |
tree | 757a89bd1a7bff52f302df77c5db22bb63759c34 | |
parent | 1e32b94441afd344a250efec1450c86a83c297d1 (diff) | |
download | rockbox-ec5d44627fb8a409c445741264cc4f2995a17721.tar.gz rockbox-ec5d44627fb8a409c445741264cc4f2995a17721.zip |
next round of playback function split: everything in place, working and used; except for the playtime
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4218 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/export/mp3_playback.h | 8 | ||||
-rw-r--r-- | firmware/export/mpeg.h | 4 | ||||
-rw-r--r-- | firmware/mp3_playback.c | 156 | ||||
-rw-r--r-- | firmware/mpeg.c | 276 |
4 files changed, 256 insertions, 188 deletions
diff --git a/firmware/export/mp3_playback.h b/firmware/export/mp3_playback.h index 2767092b75..3c190f2691 100644 --- a/firmware/export/mp3_playback.h +++ b/firmware/export/mp3_playback.h | |||
@@ -40,6 +40,12 @@ int mpeg_sound_numdecimals(int setting); | |||
40 | void mpeg_set_pitch(int percent); | 40 | void mpeg_set_pitch(int percent); |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | |||
44 | /* exported just for mpeg.c, to keep the recording there */ | ||
45 | #ifdef HAVE_MAS3587F | ||
46 | void demand_irq_enable(bool on); | ||
47 | #endif | ||
48 | |||
43 | /* new functions, to be exported to plugin API */ | 49 | /* new functions, to be exported to plugin API */ |
44 | void mp3_play_init(void); | 50 | void mp3_play_init(void); |
45 | void mp3_play_data(unsigned char* start, int size, | 51 | void mp3_play_data(unsigned char* start, int size, |
@@ -47,6 +53,8 @@ void mp3_play_data(unsigned char* start, int size, | |||
47 | ); | 53 | ); |
48 | void mp3_play_pause(bool play); | 54 | void mp3_play_pause(bool play); |
49 | void mp3_play_stop(void); | 55 | void mp3_play_stop(void); |
56 | long mp3_get_playtime(void); | ||
57 | void mp3_reset_playtime(void); | ||
50 | 58 | ||
51 | 59 | ||
52 | #define SOUND_VOLUME 0 | 60 | #define SOUND_VOLUME 0 |
diff --git a/firmware/export/mpeg.h b/firmware/export/mpeg.h index 2a629f4b45..ff003e62f5 100644 --- a/firmware/export/mpeg.h +++ b/firmware/export/mpeg.h | |||
@@ -90,6 +90,10 @@ void mpeg_set_buffer_margin(int seconds); | |||
90 | unsigned int mpeg_error(void); | 90 | unsigned int mpeg_error(void); |
91 | void mpeg_error_clear(void); | 91 | void mpeg_error_clear(void); |
92 | 92 | ||
93 | /* in order to keep the recording here, I have to expose this */ | ||
94 | void rec_tick(void); | ||
95 | void playback_tick(void); /* FixMe: get rid of this, use mp3_get_playtime() */ | ||
96 | |||
93 | #define MPEG_STATUS_PLAY 1 | 97 | #define MPEG_STATUS_PLAY 1 |
94 | #define MPEG_STATUS_PAUSE 2 | 98 | #define MPEG_STATUS_PAUSE 2 |
95 | #define MPEG_STATUS_RECORD 4 | 99 | #define MPEG_STATUS_RECORD 4 |
diff --git a/firmware/mp3_playback.c b/firmware/mp3_playback.c index 9930f10824..fe16676624 100644 --- a/firmware/mp3_playback.c +++ b/firmware/mp3_playback.c | |||
@@ -34,6 +34,30 @@ | |||
34 | #include "hwcompat.h" | 34 | #include "hwcompat.h" |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | /* hacking into mpeg.c, recording is still there */ | ||
38 | #ifdef HAVE_MAS3587F | ||
39 | enum | ||
40 | { | ||
41 | MPEG_DECODER, | ||
42 | MPEG_ENCODER | ||
43 | } mpeg_mode; | ||
44 | #endif /* #ifdef HAVE_MAS3587F */ | ||
45 | |||
46 | /**** globals ****/ | ||
47 | |||
48 | /* own version, independent of mpeg.c */ | ||
49 | static bool paused; /* playback is paused */ | ||
50 | static bool playing; /* We are playing an MP3 stream */ | ||
51 | |||
52 | #ifndef SIMULATOR | ||
53 | /* for measuring the play time */ | ||
54 | static long playstart_tick; | ||
55 | static long cumulative_ticks; | ||
56 | |||
57 | /* the registered callback function to ask for more mp3 data */ | ||
58 | static void (*callback_for_more)(unsigned char**, int*); | ||
59 | #endif /* #ifndef SIMULATOR */ | ||
60 | |||
37 | static char *units[] = | 61 | static char *units[] = |
38 | { | 62 | { |
39 | "%", /* Volume */ | 63 | "%", /* Volume */ |
@@ -283,10 +307,65 @@ static void mas_poll_start(int interval_in_ms) | |||
283 | 307 | ||
284 | TSTR |= 0x02; /* Start timer 1 */ | 308 | TSTR |= 0x02; /* Start timer 1 */ |
285 | } | 309 | } |
310 | #else | ||
311 | static void postpone_dma_tick(void) | ||
312 | { | ||
313 | unsigned int count; | ||
314 | |||
315 | count = FREQ / 1000 / 8; | ||
316 | |||
317 | /* We are using timer 1 */ | ||
318 | |||
319 | TSTR &= ~0x02; /* Stop the timer */ | ||
320 | TSNC &= ~0x02; /* No synchronization */ | ||
321 | TMDR &= ~0x02; /* Operate normally */ | ||
322 | |||
323 | TCNT1 = 0; /* Start counting at 0 */ | ||
324 | GRA1 = count; | ||
325 | TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */ | ||
326 | |||
327 | /* Enable interrupt on level 5 */ | ||
328 | IPRC = (IPRC & ~0x000f) | 0x0005; | ||
329 | |||
330 | TSR1 &= ~0x02; | ||
331 | TIER1 = 0xf9; /* Enable GRA match interrupt */ | ||
332 | |||
333 | TSTR |= 0x02; /* Start timer 1 */ | ||
334 | } | ||
286 | #endif | 335 | #endif |
287 | 336 | ||
288 | /* the registered callback function ta ask for more mp3 data */ | 337 | |
289 | static void (*callback_for_more)(unsigned char**, int*); | 338 | #ifdef HAVE_MAS3587F |
339 | void demand_irq_enable(bool on) | ||
340 | { | ||
341 | int oldlevel = set_irq_level(15); | ||
342 | |||
343 | if(on) | ||
344 | { | ||
345 | IPRA = (IPRA & 0xfff0) | 0x000b; | ||
346 | ICR &= ~0x0010; /* IRQ3 level sensitive */ | ||
347 | } | ||
348 | else | ||
349 | IPRA &= 0xfff0; | ||
350 | |||
351 | set_irq_level(oldlevel); | ||
352 | } | ||
353 | #endif /* #ifdef HAVE_MAS3587F */ | ||
354 | |||
355 | |||
356 | void play_tick(void) | ||
357 | { | ||
358 | if(playing && !paused) | ||
359 | { | ||
360 | /* Start DMA if it is disabled and the DEMAND pin is high */ | ||
361 | if(!(SCR0 & 0x80) && (PBDR & 0x4000)) | ||
362 | { | ||
363 | SCR0 |= 0x80; | ||
364 | } | ||
365 | |||
366 | playback_tick(); /* dirty call to mpeg.c */ | ||
367 | } | ||
368 | } | ||
290 | 369 | ||
291 | #pragma interrupt | 370 | #pragma interrupt |
292 | void DEI3(void) | 371 | void DEI3(void) |
@@ -313,10 +392,36 @@ void DEI3(void) | |||
313 | } | 392 | } |
314 | 393 | ||
315 | #pragma interrupt | 394 | #pragma interrupt |
395 | void IMIA1(void) /* Timer 1 interrupt */ | ||
396 | { | ||
397 | if(playing) | ||
398 | play_tick(); | ||
399 | TSR1 &= ~0x01; | ||
400 | #ifdef HAVE_MAS3587F | ||
401 | /* Disable interrupt */ | ||
402 | IPRC &= ~0x000f; | ||
403 | #endif /* #ifdef HAVE_MAS3587F */ | ||
404 | } | ||
405 | |||
406 | #pragma interrupt | ||
316 | void IRQ6(void) /* PB14: MAS stop demand IRQ */ | 407 | void IRQ6(void) /* PB14: MAS stop demand IRQ */ |
317 | { | 408 | { |
318 | mp3_play_pause(false); | 409 | SCR0 &= ~0x80; |
410 | } | ||
411 | |||
412 | #ifdef HAVE_MAS3587F | ||
413 | #pragma interrupt | ||
414 | void IRQ3(void) /* PA15: MAS demand IRQ */ | ||
415 | { | ||
416 | /* Begin with setting the IRQ to edge sensitive */ | ||
417 | ICR |= 0x0010; | ||
418 | |||
419 | if(mpeg_mode == MPEG_ENCODER) | ||
420 | rec_tick(); | ||
421 | else | ||
422 | postpone_dma_tick(); | ||
319 | } | 423 | } |
424 | #endif /* #ifdef HAVE_MAS3587F */ | ||
320 | 425 | ||
321 | static void setup_sci0(void) | 426 | static void setup_sci0(void) |
322 | { | 427 | { |
@@ -404,6 +509,8 @@ static void init_playback(void) | |||
404 | 509 | ||
405 | mpeg_sound_channel_config(MPEG_SOUND_STEREO); | 510 | mpeg_sound_channel_config(MPEG_SOUND_STEREO); |
406 | 511 | ||
512 | mpeg_mode = MPEG_DECODER; | ||
513 | |||
407 | /* set IRQ6 to edge detect */ | 514 | /* set IRQ6 to edge detect */ |
408 | ICR |= 0x02; | 515 | ICR |= 0x02; |
409 | 516 | ||
@@ -893,6 +1000,9 @@ void mp3_init(int volume, int bass, int treble, int balance, int loudness, | |||
893 | mpeg_sound_set(SOUND_AVC, avc); | 1000 | mpeg_sound_set(SOUND_AVC, avc); |
894 | #endif | 1001 | #endif |
895 | #endif /* !SIMULATOR */ | 1002 | #endif /* !SIMULATOR */ |
1003 | |||
1004 | playing = false; | ||
1005 | paused = true; | ||
896 | } | 1006 | } |
897 | 1007 | ||
898 | 1008 | ||
@@ -905,7 +1015,10 @@ void mp3_play_init(void) | |||
905 | #ifdef HAVE_MAS3587F | 1015 | #ifdef HAVE_MAS3587F |
906 | init_playback(); | 1016 | init_playback(); |
907 | #endif | 1017 | #endif |
1018 | playing = false; | ||
1019 | paused = true; | ||
908 | callback_for_more = NULL; | 1020 | callback_for_more = NULL; |
1021 | mp3_reset_playtime(); | ||
909 | } | 1022 | } |
910 | 1023 | ||
911 | void mp3_play_data(unsigned char* start, int size, | 1024 | void mp3_play_data(unsigned char* start, int size, |
@@ -923,21 +1036,54 @@ void mp3_play_data(unsigned char* start, int size, | |||
923 | SAR3 = (unsigned int)start; | 1036 | SAR3 = (unsigned int)start; |
924 | DTCR3 = size & 0xffff; | 1037 | DTCR3 = size & 0xffff; |
925 | 1038 | ||
1039 | playing = true; | ||
1040 | paused = true; | ||
1041 | |||
926 | CHCR3 |= 0x0001; /* Enable DMA IRQ */ | 1042 | CHCR3 |= 0x0001; /* Enable DMA IRQ */ |
1043 | |||
1044 | #ifdef HAVE_MAS3587F | ||
1045 | demand_irq_enable(true); | ||
1046 | #endif | ||
927 | } | 1047 | } |
928 | 1048 | ||
929 | void mp3_play_pause(bool play) | 1049 | void mp3_play_pause(bool play) |
930 | { | 1050 | { |
931 | if (play) | 1051 | if (paused && play) |
1052 | { /* resume playback */ | ||
932 | SCR0 |= 0x80; | 1053 | SCR0 |= 0x80; |
933 | else | 1054 | paused = false; |
1055 | playstart_tick = current_tick; | ||
1056 | } | ||
1057 | else if (!paused && !play) | ||
1058 | { /* stop playback */ | ||
934 | SCR0 &= 0x7f; | 1059 | SCR0 &= 0x7f; |
1060 | paused = true; | ||
1061 | cumulative_ticks += current_tick - playstart_tick; | ||
1062 | } | ||
935 | } | 1063 | } |
936 | 1064 | ||
937 | void mp3_play_stop(void) | 1065 | void mp3_play_stop(void) |
938 | { | 1066 | { |
1067 | playing = false; | ||
939 | mp3_play_pause(false); | 1068 | mp3_play_pause(false); |
940 | CHCR3 &= ~0x0001; /* Disable the DMA interrupt */ | 1069 | CHCR3 &= ~0x0001; /* Disable the DMA interrupt */ |
1070 | #ifdef HAVE_MAS3587F | ||
1071 | demand_irq_enable(false); | ||
1072 | #endif | ||
1073 | } | ||
1074 | |||
1075 | long mp3_get_playtime(void) | ||
1076 | { | ||
1077 | if (paused) | ||
1078 | return cumulative_ticks; | ||
1079 | else | ||
1080 | return cumulative_ticks + current_tick - playstart_tick; | ||
1081 | } | ||
1082 | |||
1083 | void mp3_reset_playtime(void) | ||
1084 | { | ||
1085 | cumulative_ticks = 0; | ||
1086 | playstart_tick = current_tick; | ||
941 | } | 1087 | } |
942 | 1088 | ||
943 | #endif /* #ifndef SIMULATOR */ | 1089 | #endif /* #ifndef SIMULATOR */ |
diff --git a/firmware/mpeg.c b/firmware/mpeg.c index 29836dd14e..12d71a1dbd 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c | |||
@@ -74,7 +74,7 @@ static int get_unswapped_space(void); | |||
74 | #define MPEG_STOP_DONE 103 | 74 | #define MPEG_STOP_DONE 103 |
75 | 75 | ||
76 | #ifdef HAVE_MAS3587F | 76 | #ifdef HAVE_MAS3587F |
77 | static enum | 77 | extern enum /* from mp3_playback.c */ |
78 | { | 78 | { |
79 | MPEG_DECODER, | 79 | MPEG_DECODER, |
80 | MPEG_ENCODER | 80 | MPEG_ENCODER |
@@ -371,33 +371,6 @@ void mpeg_get_debugdata(struct mpeg_debug *dbgdata) | |||
371 | dbgdata->lowest_watermark_level = lowest_watermark_level; | 371 | dbgdata->lowest_watermark_level = lowest_watermark_level; |
372 | } | 372 | } |
373 | 373 | ||
374 | #ifndef HAVE_MAS3507D | ||
375 | static void postpone_dma_tick(void) | ||
376 | { | ||
377 | unsigned int count; | ||
378 | |||
379 | count = FREQ / 1000 / 8; | ||
380 | |||
381 | /* We are using timer 1 */ | ||
382 | |||
383 | TSTR &= ~0x02; /* Stop the timer */ | ||
384 | TSNC &= ~0x02; /* No synchronization */ | ||
385 | TMDR &= ~0x02; /* Operate normally */ | ||
386 | |||
387 | TCNT1 = 0; /* Start counting at 0 */ | ||
388 | GRA1 = count; | ||
389 | TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */ | ||
390 | |||
391 | /* Enable interrupt on level 5 */ | ||
392 | IPRC = (IPRC & ~0x000f) | 0x0005; | ||
393 | |||
394 | TSR1 &= ~0x02; | ||
395 | TIER1 = 0xf9; /* Enable GRA match interrupt */ | ||
396 | |||
397 | TSTR |= 0x02; /* Start timer 1 */ | ||
398 | } | ||
399 | #endif /* #ifndef HAVE_MAS3507D */ | ||
400 | |||
401 | #ifdef DEBUG | 374 | #ifdef DEBUG |
402 | static void dbg_timer_start(void) | 375 | static void dbg_timer_start(void) |
403 | { | 376 | { |
@@ -524,134 +497,122 @@ static void drain_dma_buffer(void) | |||
524 | 497 | ||
525 | #endif /* #ifdef HAVE_MAS3587F */ | 498 | #endif /* #ifdef HAVE_MAS3587F */ |
526 | 499 | ||
527 | static void dma_tick (void) __attribute__ ((section (".icode"))); | 500 | void rec_tick (void) __attribute__ ((section (".icode"))); |
528 | static void dma_tick(void) | 501 | void rec_tick(void) |
529 | { | 502 | { |
530 | #ifdef HAVE_MAS3587F | 503 | #ifdef HAVE_MAS3587F |
531 | if(mpeg_mode == MPEG_DECODER) | 504 | int i; |
532 | { | 505 | int num_bytes; |
533 | #endif /* #ifdef HAVE_MAS3587F */ | 506 | if(is_recording && (PBDR & 0x4000)) |
534 | if(playing && !paused) | ||
535 | { | ||
536 | /* Start DMA if it is disabled and the DEMAND pin is high */ | ||
537 | if(!(SCR0 & 0x80) && (PBDR & 0x4000)) | ||
538 | { | ||
539 | mp3_play_pause(true); | ||
540 | } | ||
541 | id3tags[tag_read_idx]->id3.elapsed += | ||
542 | (current_tick - last_dma_tick) * 1000 / HZ; | ||
543 | last_dma_tick = current_tick; | ||
544 | } | ||
545 | #ifdef HAVE_MAS3587F | ||
546 | } | ||
547 | else /* MPEG_ENCODER */ | ||
548 | { | 507 | { |
549 | int i; | ||
550 | int num_bytes; | ||
551 | if(is_recording && (PBDR & 0x4000)) | ||
552 | { | ||
553 | #ifdef DEBUG | 508 | #ifdef DEBUG |
554 | timing_info[timing_info_index++] = current_tick; | 509 | timing_info[timing_info_index++] = current_tick; |
555 | TCNT2 = 0; | 510 | TCNT2 = 0; |
556 | #endif /* #ifdef DEBUG */ | 511 | #endif /* #ifdef DEBUG */ |
557 | /* We read as long as EOD is high, but max 30 bytes. | 512 | /* We read as long as EOD is high, but max 30 bytes. |
558 | This code is optimized, and should probably be | 513 | This code is optimized, and should probably be |
559 | written in assembler instead. */ | 514 | written in assembler instead. */ |
560 | if(inverted_pr) | 515 | if(inverted_pr) |
516 | { | ||
517 | i = 0; | ||
518 | while((*((volatile unsigned char *)PBDR_ADDR) & 0x40) | ||
519 | && i < 30) | ||
561 | { | 520 | { |
562 | i = 0; | 521 | or_b(0x08, &PADRH); |
563 | while((*((volatile unsigned char *)PBDR_ADDR) & 0x40) | ||
564 | && i < 30) | ||
565 | { | ||
566 | or_b(0x08, &PADRH); | ||
567 | 522 | ||
568 | while(*((volatile unsigned char *)PBDR_ADDR) & 0x80); | 523 | while(*((volatile unsigned char *)PBDR_ADDR) & 0x80); |
569 | 524 | ||
570 | /* It must take at least 5 cycles before | 525 | /* It must take at least 5 cycles before |
571 | the data is read */ | 526 | the data is read */ |
572 | asm(" nop\n nop\n nop\n"); | 527 | asm(" nop\n nop\n nop\n"); |
573 | mp3buf[mp3buf_write++] = *(unsigned char *)0x4000000; | 528 | mp3buf[mp3buf_write++] = *(unsigned char *)0x4000000; |
574 | 529 | ||
575 | if(mp3buf_write >= mp3buflen) | 530 | if(mp3buf_write >= mp3buflen) |
576 | mp3buf_write = 0; | 531 | mp3buf_write = 0; |
577 | 532 | ||
578 | i++; | 533 | i++; |
579 | 534 | ||
580 | and_b(~0x08, &PADRH); | 535 | and_b(~0x08, &PADRH); |
581 | 536 | ||
582 | /* No wait for /RTW, cause it's not necessary */ | 537 | /* No wait for /RTW, cause it's not necessary */ |
583 | } | ||
584 | } | 538 | } |
585 | else /* !inverted_pr */ | 539 | } |
540 | else /* !inverted_pr */ | ||
541 | { | ||
542 | i = 0; | ||
543 | while((*((volatile unsigned char *)PBDR_ADDR) & 0x40) | ||
544 | && i < 30) | ||
586 | { | 545 | { |
587 | i = 0; | 546 | and_b(~0x08, &PADRH); |
588 | while((*((volatile unsigned char *)PBDR_ADDR) & 0x40) | 547 | |
589 | && i < 30) | 548 | while(*((volatile unsigned char *)PBDR_ADDR) & 0x80); |
590 | { | 549 | |
591 | and_b(~0x08, &PADRH); | 550 | /* It must take at least 5 cycles before |
592 | 551 | the data is read */ | |
593 | while(*((volatile unsigned char *)PBDR_ADDR) & 0x80); | 552 | asm(" nop\n nop\n nop\n"); |
594 | 553 | mp3buf[mp3buf_write++] = *(unsigned char *)0x4000000; | |
595 | /* It must take at least 5 cycles before | 554 | |
596 | the data is read */ | 555 | if(mp3buf_write >= mp3buflen) |
597 | asm(" nop\n nop\n nop\n"); | 556 | mp3buf_write = 0; |
598 | mp3buf[mp3buf_write++] = *(unsigned char *)0x4000000; | ||
599 | |||
600 | if(mp3buf_write >= mp3buflen) | ||
601 | mp3buf_write = 0; | ||
602 | 557 | ||
603 | i++; | 558 | i++; |
604 | 559 | ||
605 | or_b(0x08, &PADRH); | 560 | or_b(0x08, &PADRH); |
606 | 561 | ||
607 | /* No wait for /RTW, cause it's not necessary */ | 562 | /* No wait for /RTW, cause it's not necessary */ |
608 | } | ||
609 | } | 563 | } |
564 | } | ||
610 | #ifdef DEBUG | 565 | #ifdef DEBUG |
611 | timing_info[timing_info_index++] = TCNT2 + (i << 16); | 566 | timing_info[timing_info_index++] = TCNT2 + (i << 16); |
612 | timing_info_index &= 0x3ff; | 567 | timing_info_index &= 0x3ff; |
613 | #endif /* #ifdef DEBUG */ | 568 | #endif /* #ifdef DEBUG */ |
614 | 569 | ||
615 | num_rec_bytes += i; | 570 | num_rec_bytes += i; |
616 | 571 | ||
617 | if(is_prerecording) | 572 | if(is_prerecording) |
573 | { | ||
574 | if(TIME_AFTER(current_tick, prerecord_timeout)) | ||
618 | { | 575 | { |
619 | if(TIME_AFTER(current_tick, prerecord_timeout)) | 576 | prerecord_timeout = current_tick + HZ; |
620 | { | ||
621 | prerecord_timeout = current_tick + HZ; | ||
622 | 577 | ||
623 | /* Store the write pointer every second */ | 578 | /* Store the write pointer every second */ |
624 | prerecord_buffer[prerecord_index++] = mp3buf_write; | 579 | prerecord_buffer[prerecord_index++] = mp3buf_write; |
625 | 580 | ||
626 | /* Wrap if necessary */ | 581 | /* Wrap if necessary */ |
627 | if(prerecord_index == prerecording_max_seconds) | 582 | if(prerecord_index == prerecording_max_seconds) |
628 | prerecord_index = 0; | 583 | prerecord_index = 0; |
629 | 584 | ||
630 | /* Update the number of seconds recorded */ | 585 | /* Update the number of seconds recorded */ |
631 | if(prerecord_count < prerecording_max_seconds) | 586 | if(prerecord_count < prerecording_max_seconds) |
632 | prerecord_count++; | 587 | prerecord_count++; |
633 | } | ||
634 | } | 588 | } |
635 | else | 589 | } |
590 | else | ||
591 | { | ||
592 | /* Signal to save the data if we are running out of buffer | ||
593 | space */ | ||
594 | num_bytes = mp3buf_write - mp3buf_read; | ||
595 | if(num_bytes < 0) | ||
596 | num_bytes += mp3buflen; | ||
597 | |||
598 | if(mp3buflen - num_bytes < MPEG_RECORDING_LOW_WATER && !saving) | ||
636 | { | 599 | { |
637 | /* Signal to save the data if we are running out of buffer | 600 | saving = true; |
638 | space */ | 601 | queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0); |
639 | num_bytes = mp3buf_write - mp3buf_read; | 602 | wake_up_thread(); |
640 | if(num_bytes < 0) | ||
641 | num_bytes += mp3buflen; | ||
642 | |||
643 | if(mp3buflen - num_bytes < MPEG_RECORDING_LOW_WATER && !saving) | ||
644 | { | ||
645 | saving = true; | ||
646 | queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0); | ||
647 | wake_up_thread(); | ||
648 | } | ||
649 | } | 603 | } |
650 | } | 604 | } |
651 | } | 605 | } |
652 | #endif /* #ifdef HAVE_MAS3587F */ | 606 | #endif /* #ifdef HAVE_MAS3587F */ |
653 | } | 607 | } |
654 | 608 | ||
609 | void playback_tick(void) | ||
610 | { | ||
611 | id3tags[tag_read_idx]->id3.elapsed += | ||
612 | (current_tick - last_dma_tick) * 1000 / HZ; | ||
613 | last_dma_tick = current_tick; | ||
614 | } | ||
615 | |||
655 | static void reset_mp3_buffer(void) | 616 | static void reset_mp3_buffer(void) |
656 | { | 617 | { |
657 | mp3buf_read = 0; | 618 | mp3buf_read = 0; |
@@ -751,48 +712,6 @@ static void transfer_end(unsigned char** ppbuf, int* psize) | |||
751 | wake_up_thread(); | 712 | wake_up_thread(); |
752 | } | 713 | } |
753 | 714 | ||
754 | #ifdef HAVE_MAS3587F | ||
755 | static void demand_irq_enable(bool on) | ||
756 | { | ||
757 | int oldlevel = set_irq_level(15); | ||
758 | |||
759 | if(on) | ||
760 | { | ||
761 | IPRA = (IPRA & 0xfff0) | 0x000b; | ||
762 | ICR &= ~0x0010; /* IRQ3 level sensitive */ | ||
763 | } | ||
764 | else | ||
765 | IPRA &= 0xfff0; | ||
766 | |||
767 | set_irq_level(oldlevel); | ||
768 | } | ||
769 | #endif /* #ifdef HAVE_MAS3587F */ | ||
770 | |||
771 | #pragma interrupt | ||
772 | void IMIA1(void) /* Timer 1 interrupt */ | ||
773 | { | ||
774 | dma_tick(); | ||
775 | TSR1 &= ~0x01; | ||
776 | #ifdef HAVE_MAS3587F | ||
777 | /* Disable interrupt */ | ||
778 | IPRC &= ~0x000f; | ||
779 | #endif /* #ifdef HAVE_MAS3587F */ | ||
780 | } | ||
781 | |||
782 | #ifdef HAVE_MAS3587F | ||
783 | #pragma interrupt | ||
784 | void IRQ3(void) /* PA15: MAS demand IRQ */ | ||
785 | { | ||
786 | /* Begin with setting the IRQ to edge sensitive */ | ||
787 | ICR |= 0x0010; | ||
788 | |||
789 | if(mpeg_mode == MPEG_ENCODER) | ||
790 | dma_tick(); | ||
791 | else | ||
792 | postpone_dma_tick(); | ||
793 | } | ||
794 | #endif /* #ifdef HAVE_MAS3587F */ | ||
795 | |||
796 | static int add_track_to_tag_list(char *filename) | 715 | static int add_track_to_tag_list(char *filename) |
797 | { | 716 | { |
798 | struct id3tag *t = NULL; | 717 | struct id3tag *t = NULL; |
@@ -892,15 +811,12 @@ static int new_file(int steps) | |||
892 | static void stop_playing(void) | 811 | static void stop_playing(void) |
893 | { | 812 | { |
894 | /* Stop the current stream */ | 813 | /* Stop the current stream */ |
895 | #ifdef HAVE_MAS3587F | 814 | mp3_play_stop(); |
896 | demand_irq_enable(false); | ||
897 | #endif /* #ifdef HAVE_MAS3587F */ | ||
898 | playing = false; | 815 | playing = false; |
899 | filling = false; | 816 | filling = false; |
900 | if(mpeg_file >= 0) | 817 | if(mpeg_file >= 0) |
901 | close(mpeg_file); | 818 | close(mpeg_file); |
902 | mpeg_file = -1; | 819 | mpeg_file = -1; |
903 | mp3_play_pause(false); | ||
904 | remove_all_tags(); | 820 | remove_all_tags(); |
905 | } | 821 | } |
906 | 822 | ||
@@ -967,17 +883,14 @@ static void start_playback_if_ready(void) | |||
967 | play_pending = false; | 883 | play_pending = false; |
968 | playing = true; | 884 | playing = true; |
969 | 885 | ||
970 | last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); | ||
971 | mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end); | ||
972 | dma_underrun = false; | ||
973 | |||
974 | if (!paused) | 886 | if (!paused) |
975 | { | 887 | { |
888 | last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); | ||
889 | mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end); | ||
890 | dma_underrun = false; | ||
891 | |||
976 | last_dma_tick = current_tick; | 892 | last_dma_tick = current_tick; |
977 | mp3_play_pause(true); | 893 | mp3_play_pause(true); |
978 | #ifdef HAVE_MAS3587F | ||
979 | demand_irq_enable(true); | ||
980 | #endif /* #ifdef HAVE_MAS3587F */ | ||
981 | } | 894 | } |
982 | 895 | ||
983 | /* Tell ourselves that we need more data */ | 896 | /* Tell ourselves that we need more data */ |
@@ -2002,10 +1915,7 @@ static void mpeg_thread(void) | |||
2002 | case MPEG_INIT_PLAYBACK: | 1915 | case MPEG_INIT_PLAYBACK: |
2003 | /* Stop the prerecording */ | 1916 | /* Stop the prerecording */ |
2004 | stop_recording(); | 1917 | stop_recording(); |
2005 | |||
2006 | mp3_play_init(); | 1918 | mp3_play_init(); |
2007 | mpeg_mode = MPEG_DECODER; | ||
2008 | |||
2009 | init_playback_done = true; | 1919 | init_playback_done = true; |
2010 | break; | 1920 | break; |
2011 | 1921 | ||