diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/playback.c | 65 | ||||
-rw-r--r-- | apps/plugins/codecmpa.c | 1 |
2 files changed, 43 insertions, 23 deletions
diff --git a/apps/playback.c b/apps/playback.c index 3a9f229e15..c0c71a173d 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -68,7 +68,7 @@ static volatile bool paused; | |||
68 | #define CODEC_WAV "/.rockbox/codecs/codecwav.rock"; | 68 | #define CODEC_WAV "/.rockbox/codecs/codecwav.rock"; |
69 | 69 | ||
70 | #define AUDIO_WATERMARK 0x70000 | 70 | #define AUDIO_WATERMARK 0x70000 |
71 | #define AUDIO_FILE_CHUNK (1024*256) | 71 | #define AUDIO_FILE_CHUNK (1024*512) |
72 | 72 | ||
73 | #define AUDIO_PLAY 1 | 73 | #define AUDIO_PLAY 1 |
74 | #define AUDIO_STOP 2 | 74 | #define AUDIO_STOP 2 |
@@ -107,6 +107,9 @@ static const char codec_thread_name[] = "codec"; | |||
107 | /* Is file buffer currently being refilled? */ | 107 | /* Is file buffer currently being refilled? */ |
108 | static volatile bool filling; | 108 | static volatile bool filling; |
109 | 109 | ||
110 | /* Interrupts buffer filling. */ | ||
111 | static volatile bool interrupt; | ||
112 | |||
110 | /* Ring buffer where tracks and codecs are loaded. */ | 113 | /* Ring buffer where tracks and codecs are loaded. */ |
111 | char *codecbuf; | 114 | char *codecbuf; |
112 | 115 | ||
@@ -398,8 +401,8 @@ int probe_file_format(const char *filename) | |||
398 | 401 | ||
399 | void yield_codecs(void) | 402 | void yield_codecs(void) |
400 | { | 403 | { |
401 | #ifndef SIMULATOR | ||
402 | yield(); | 404 | yield(); |
405 | #ifndef SIMULATOR | ||
403 | if (!pcm_is_playing()) | 406 | if (!pcm_is_playing()) |
404 | sleep(5); | 407 | sleep(5); |
405 | while (pcm_is_lowdata()) | 408 | while (pcm_is_lowdata()) |
@@ -420,7 +423,7 @@ void audio_fill_file_buffer(void) | |||
420 | /* Give codecs some processing time. */ | 423 | /* Give codecs some processing time. */ |
421 | yield_codecs(); | 424 | yield_codecs(); |
422 | 425 | ||
423 | if (!playing) { | 426 | if (interrupt) { |
424 | logf("Filling interrupted"); | 427 | logf("Filling interrupted"); |
425 | close(current_fd); | 428 | close(current_fd); |
426 | current_fd = -1; | 429 | current_fd = -1; |
@@ -540,7 +543,7 @@ bool loadcodec(const char *trackname, bool start_play) | |||
540 | i = 0; | 543 | i = 0; |
541 | while (i < size) { | 544 | while (i < size) { |
542 | yield_codecs(); | 545 | yield_codecs(); |
543 | if (!playing) { | 546 | if (interrupt) { |
544 | logf("Buffering interrupted"); | 547 | logf("Buffering interrupted"); |
545 | close(fd); | 548 | close(fd); |
546 | return false; | 549 | return false; |
@@ -610,7 +613,7 @@ bool audio_load_track(int offset, bool start_play, int peek_offset) | |||
610 | logf("%s", trackname); | 613 | logf("%s", trackname); |
611 | logf("Buffering track:%d/%d", track_widx, track_ridx); | 614 | logf("Buffering track:%d/%d", track_widx, track_ridx); |
612 | 615 | ||
613 | if (!playing) { | 616 | if (interrupt) { |
614 | close(fd); | 617 | close(fd); |
615 | return false; | 618 | return false; |
616 | } | 619 | } |
@@ -717,7 +720,7 @@ bool audio_load_track(int offset, bool start_play, int peek_offset) | |||
717 | while (i < size) { | 720 | while (i < size) { |
718 | /* Give codecs some processing time to prevent glitches. */ | 721 | /* Give codecs some processing time to prevent glitches. */ |
719 | yield_codecs(); | 722 | yield_codecs(); |
720 | if (!playing) { | 723 | if (interrupt) { |
721 | logf("Buffering interrupted"); | 724 | logf("Buffering interrupted"); |
722 | close(fd); | 725 | close(fd); |
723 | return false; | 726 | return false; |
@@ -803,8 +806,14 @@ void audio_check_buffer(void) | |||
803 | int i; | 806 | int i; |
804 | int cur_idx; | 807 | int cur_idx; |
805 | 808 | ||
809 | /* Fill buffer as full as possible for cross-fader. */ | ||
810 | #ifndef SIMULATOR | ||
811 | if (cur_ti->id3.length - cur_ti->id3.elapsed < 20000) | ||
812 | pcm_set_boost_mode(true); | ||
813 | #endif | ||
814 | |||
806 | /* Start buffer filling as necessary. */ | 815 | /* Start buffer filling as necessary. */ |
807 | if (codecbufused > AUDIO_WATERMARK || !playing) | 816 | if (codecbufused > AUDIO_WATERMARK || !interrupt) |
808 | return ; | 817 | return ; |
809 | 818 | ||
810 | filling = true; | 819 | filling = true; |
@@ -863,6 +872,9 @@ void audio_update_trackinfo(void) | |||
863 | buf_ridx += cur_ti->codecsize; | 872 | buf_ridx += cur_ti->codecsize; |
864 | if (buf_ridx >= codecbuflen) | 873 | if (buf_ridx >= codecbuflen) |
865 | buf_ridx -= codecbuflen; | 874 | buf_ridx -= codecbuflen; |
875 | pcm_crossfade_start(); | ||
876 | if (!filling) | ||
877 | pcm_set_boost_mode(false); | ||
866 | } else { | 878 | } else { |
867 | buf_ridx -= ci.curpos; | 879 | buf_ridx -= ci.curpos; |
868 | codecbufused += ci.curpos; | 880 | codecbufused += ci.curpos; |
@@ -978,14 +990,13 @@ void audio_thread(void) | |||
978 | queue_wait_w_tmo(&audio_queue, &ev, 0); | 990 | queue_wait_w_tmo(&audio_queue, &ev, 0); |
979 | switch (ev.id) { | 991 | switch (ev.id) { |
980 | case AUDIO_PLAY: | 992 | case AUDIO_PLAY: |
993 | interrupt = false; | ||
981 | ci.stop_codec = true; | 994 | ci.stop_codec = true; |
982 | ci.reload_codec = false; | 995 | ci.reload_codec = false; |
983 | ci.seek_time = 0; | 996 | ci.seek_time = 0; |
984 | #ifndef SIMULATOR | 997 | #ifndef SIMULATOR |
985 | pcm_play_stop(); | 998 | pcm_play_stop(); |
986 | pcm_play_pause(true); | ||
987 | #endif | 999 | #endif |
988 | playing = true; | ||
989 | paused = false; | 1000 | paused = false; |
990 | audio_play_start((int)ev.data); | 1001 | audio_play_start((int)ev.data); |
991 | break ; | 1002 | break ; |
@@ -993,8 +1004,8 @@ void audio_thread(void) | |||
993 | case AUDIO_STOP: | 1004 | case AUDIO_STOP: |
994 | #ifndef SIMULATOR | 1005 | #ifndef SIMULATOR |
995 | pcm_play_stop(); | 1006 | pcm_play_stop(); |
1007 | pcm_play_pause(true); | ||
996 | #endif | 1008 | #endif |
997 | paused = false; | ||
998 | break ; | 1009 | break ; |
999 | 1010 | ||
1000 | case AUDIO_PAUSE: | 1011 | case AUDIO_PAUSE: |
@@ -1017,6 +1028,7 @@ void audio_thread(void) | |||
1017 | ci.stop_codec = true; | 1028 | ci.stop_codec = true; |
1018 | logf("USB Connection"); | 1029 | logf("USB Connection"); |
1019 | pcm_play_stop(); | 1030 | pcm_play_stop(); |
1031 | pcm_play_pause(true); | ||
1020 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | 1032 | usb_acknowledge(SYS_USB_CONNECTED_ACK); |
1021 | usb_wait_for_disconnect(&audio_queue); | 1033 | usb_wait_for_disconnect(&audio_queue); |
1022 | break ; | 1034 | break ; |
@@ -1076,12 +1088,14 @@ void codec_thread(void) | |||
1076 | logf("Codec finished"); | 1088 | logf("Codec finished"); |
1077 | } | 1089 | } |
1078 | 1090 | ||
1079 | queue_post(&audio_queue, AUDIO_CODEC_DONE, (void *)status); | ||
1080 | if (playing && !ci.stop_codec && !ci.reload_codec) { | 1091 | if (playing && !ci.stop_codec && !ci.reload_codec) { |
1081 | audio_change_track(); | 1092 | audio_change_track(); |
1093 | } else if (ci.reload_codec) { | ||
1094 | interrupt = true; | ||
1082 | } else { | 1095 | } else { |
1083 | playing = false; | 1096 | playing = false; |
1084 | } | 1097 | } |
1098 | queue_post(&audio_queue, AUDIO_CODEC_DONE, (void *)status); | ||
1085 | } | 1099 | } |
1086 | } | 1100 | } |
1087 | } | 1101 | } |
@@ -1129,17 +1143,17 @@ bool audio_has_changed_track(void) | |||
1129 | void audio_play(int offset) | 1143 | void audio_play(int offset) |
1130 | { | 1144 | { |
1131 | logf("audio_play"); | 1145 | logf("audio_play"); |
1132 | playing = false; | ||
1133 | ci.stop_codec = true; | 1146 | ci.stop_codec = true; |
1147 | playing = false; | ||
1148 | #ifndef SIMULATOR | ||
1149 | pcm_play_pause(true); | ||
1150 | #endif | ||
1134 | queue_post(&audio_queue, AUDIO_PLAY, (void *)offset); | 1151 | queue_post(&audio_queue, AUDIO_PLAY, (void *)offset); |
1135 | } | 1152 | } |
1136 | 1153 | ||
1137 | void audio_stop(void) | 1154 | void audio_stop(void) |
1138 | { | 1155 | { |
1139 | logf("audio_stop"); | 1156 | logf("audio_stop"); |
1140 | if (!playing) | ||
1141 | return ; | ||
1142 | |||
1143 | playing = false; | 1157 | playing = false; |
1144 | ci.stop_codec = true; | 1158 | ci.stop_codec = true; |
1145 | if (current_fd) { | 1159 | if (current_fd) { |
@@ -1147,6 +1161,9 @@ void audio_stop(void) | |||
1147 | current_fd = -1; | 1161 | current_fd = -1; |
1148 | } | 1162 | } |
1149 | queue_post(&audio_queue, AUDIO_STOP, 0); | 1163 | queue_post(&audio_queue, AUDIO_STOP, 0); |
1164 | #ifndef SIMULATOR | ||
1165 | pcm_play_pause(true); | ||
1166 | #endif | ||
1150 | } | 1167 | } |
1151 | 1168 | ||
1152 | void audio_pause(void) | 1169 | void audio_pause(void) |
@@ -1174,16 +1191,17 @@ void audio_next(void) | |||
1174 | logf("audio_next"); | 1191 | logf("audio_next"); |
1175 | new_track = 1; | 1192 | new_track = 1; |
1176 | ci.reload_codec = true; | 1193 | ci.reload_codec = true; |
1177 | #ifndef SIMULATOR | ||
1178 | pcm_play_stop(); | ||
1179 | #endif | ||
1180 | 1194 | ||
1181 | /* Detect if disk is spinning.. */ | 1195 | /* Detect if disk is spinning.. */ |
1182 | if (filling) { | 1196 | if (filling) { |
1183 | playlist_next(1); | 1197 | interrupt = true; |
1184 | playing = false; | ||
1185 | ci.stop_codec = true; | 1198 | ci.stop_codec = true; |
1199 | playlist_next(1); | ||
1186 | queue_post(&audio_queue, AUDIO_PLAY, 0); | 1200 | queue_post(&audio_queue, AUDIO_PLAY, 0); |
1201 | } else { | ||
1202 | #ifndef SIMULATOR | ||
1203 | pcm_play_stop(); | ||
1204 | #endif | ||
1187 | } | 1205 | } |
1188 | } | 1206 | } |
1189 | 1207 | ||
@@ -1197,9 +1215,9 @@ void audio_prev(void) | |||
1197 | #endif | 1215 | #endif |
1198 | 1216 | ||
1199 | if (filling) { | 1217 | if (filling) { |
1200 | playlist_next(-1); | 1218 | interrupt = true; |
1201 | playing = false; | ||
1202 | ci.stop_codec = true; | 1219 | ci.stop_codec = true; |
1220 | playlist_next(-1); | ||
1203 | queue_post(&audio_queue, AUDIO_PLAY, 0); | 1221 | queue_post(&audio_queue, AUDIO_PLAY, 0); |
1204 | } | 1222 | } |
1205 | //queue_post(&audio_queue, AUDIO_PREV, 0); | 1223 | //queue_post(&audio_queue, AUDIO_PREV, 0); |
@@ -1377,7 +1395,8 @@ void audio_init(void) | |||
1377 | - MALLOC_BUFSIZE - GUARD_BUFSIZE; | 1395 | - MALLOC_BUFSIZE - GUARD_BUFSIZE; |
1378 | //codecbuflen = 2*512*1024; | 1396 | //codecbuflen = 2*512*1024; |
1379 | codecbufused = 0; | 1397 | codecbufused = 0; |
1380 | filling = 0; | 1398 | filling = false; |
1399 | interrupt = false; | ||
1381 | codecbuf = &audiobuf[MALLOC_BUFSIZE]; | 1400 | codecbuf = &audiobuf[MALLOC_BUFSIZE]; |
1382 | playing = false; | 1401 | playing = false; |
1383 | paused = false; | 1402 | paused = false; |
diff --git a/apps/plugins/codecmpa.c b/apps/plugins/codecmpa.c index 1125b4bf18..46014127b8 100644 --- a/apps/plugins/codecmpa.c +++ b/apps/plugins/codecmpa.c | |||
@@ -381,6 +381,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm) | |||
381 | /* Flush the buffer if it is full. */ | 381 | /* Flush the buffer if it is full. */ |
382 | if(OutputPtr==OutputBufferEnd) | 382 | if(OutputPtr==OutputBufferEnd) |
383 | { | 383 | { |
384 | rb->yield(); | ||
384 | #ifdef DEBUG_GAPLESS | 385 | #ifdef DEBUG_GAPLESS |
385 | rb->write(fd, OutputBuffer, OUTPUT_BUFFER_SIZE); | 386 | rb->write(fd, OutputBuffer, OUTPUT_BUFFER_SIZE); |
386 | #endif | 387 | #endif |