diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2005-07-02 16:52:30 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2005-07-02 16:52:30 +0000 |
commit | d54811fe22c274ed31d897864ac0a33349f460e0 (patch) | |
tree | b8c7928c46c4989f43eb1b63db07408daa70b4bb /apps/playback.c | |
parent | a8cadd8181e53320109d2af61f0c7edea262d325 (diff) | |
download | rockbox-d54811fe22c274ed31d897864ac0a33349f460e0.tar.gz rockbox-d54811fe22c274ed31d897864ac0a33349f460e0.zip |
Fixed mono playback support for mp3. Added two other event handlers in
playback.c.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6986 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/playback.c')
-rw-r--r-- | apps/playback.c | 96 |
1 files changed, 92 insertions, 4 deletions
diff --git a/apps/playback.c b/apps/playback.c index 70cb36341b..3a5eeb328f 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -165,6 +165,8 @@ static int new_track; | |||
165 | 165 | ||
166 | /* Callback function to call when current track has really changed. */ | 166 | /* Callback function to call when current track has really changed. */ |
167 | void (*track_changed_callback)(struct track_info *ti); | 167 | void (*track_changed_callback)(struct track_info *ti); |
168 | void (*track_buffer_callback)(struct mp3entry *id3, bool last_track); | ||
169 | void (*track_unbuffer_callback)(struct mp3entry *id3, bool disk_spinning); | ||
168 | 170 | ||
169 | /* Configuration */ | 171 | /* Configuration */ |
170 | static int conf_bufferlimit; | 172 | static int conf_bufferlimit; |
@@ -266,10 +268,14 @@ bool codec_audiobuffer_insert_callback(char *buf, long length) | |||
266 | int factor; | 268 | int factor; |
267 | int next_channel = 0; | 269 | int next_channel = 0; |
268 | int processed_length; | 270 | int processed_length; |
271 | int mono = 0; | ||
269 | 272 | ||
270 | /* If non-interleaved stereo mode. */ | 273 | /* If non-interleaved stereo mode. */ |
271 | if (dsp_config.stereo_mode == STEREO_NONINTERLEAVED) { | 274 | if (dsp_config.stereo_mode == STEREO_NONINTERLEAVED) |
272 | next_channel = length / 2; | 275 | next_channel = length / 2; |
276 | else if (dsp_config.stereo_mode == STEREO_MONO) { | ||
277 | length *= 2; | ||
278 | mono = 1; | ||
273 | } | 279 | } |
274 | 280 | ||
275 | if (dsp_config.sample_depth > 16) { | 281 | if (dsp_config.sample_depth > 16) { |
@@ -296,11 +302,11 @@ bool codec_audiobuffer_insert_callback(char *buf, long length) | |||
296 | processed_length = dsp_process(dest, buf, realsize / 4) * 2; | 302 | processed_length = dsp_process(dest, buf, realsize / 4) * 2; |
297 | dsp_process(dest, buf + next_channel, realsize / 4); | 303 | dsp_process(dest, buf + next_channel, realsize / 4); |
298 | } else { | 304 | } else { |
299 | processed_length = dsp_process(dest, buf, realsize / 2); | 305 | processed_length = dsp_process(dest, buf, realsize >> (mono + 1)); |
300 | } | 306 | } |
301 | pcm_flush_buffer(processed_length); | 307 | pcm_flush_buffer(processed_length); |
302 | length -= realsize; | 308 | length -= realsize; |
303 | buf += realsize << factor; | 309 | buf += realsize << (factor + mono); |
304 | } | 310 | } |
305 | 311 | ||
306 | return true; | 312 | return true; |
@@ -589,6 +595,18 @@ void codec_configure_callback(int setting, void *value) | |||
589 | } | 595 | } |
590 | } | 596 | } |
591 | 597 | ||
598 | void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3, | ||
599 | bool last_track)) | ||
600 | { | ||
601 | track_buffer_callback = handler; | ||
602 | } | ||
603 | |||
604 | void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3, | ||
605 | bool disk_spinning)) | ||
606 | { | ||
607 | track_unbuffer_callback = handler; | ||
608 | } | ||
609 | |||
592 | void audio_set_track_changed_event(void (*handler)(struct track_info *ti)) | 610 | void audio_set_track_changed_event(void (*handler)(struct track_info *ti)) |
593 | { | 611 | { |
594 | track_changed_callback = handler; | 612 | track_changed_callback = handler; |
@@ -934,6 +952,10 @@ void audio_play_start(int offset) | |||
934 | last_peek_offset = 0; | 952 | last_peek_offset = 0; |
935 | if (audio_load_track(offset, true, 0)) { | 953 | if (audio_load_track(offset, true, 0)) { |
936 | last_peek_offset++; | 954 | last_peek_offset++; |
955 | if (track_buffer_callback) { | ||
956 | cur_ti->event_sent = true; | ||
957 | track_buffer_callback(&cur_ti->id3, true); | ||
958 | } | ||
937 | ata_sleep(); | 959 | ata_sleep(); |
938 | } else { | 960 | } else { |
939 | logf("Failure"); | 961 | logf("Failure"); |
@@ -950,10 +972,46 @@ void audio_clear_track_entries(void) | |||
950 | for (i = 0; i < MAX_TRACK - track_count; i++) { | 972 | for (i = 0; i < MAX_TRACK - track_count; i++) { |
951 | if (++cur_idx >= MAX_TRACK) | 973 | if (++cur_idx >= MAX_TRACK) |
952 | cur_idx = 0; | 974 | cur_idx = 0; |
975 | |||
976 | /* Send event to notify that track has finished. */ | ||
977 | if (track_unbuffer_callback && tracks[cur_idx].event_sent) | ||
978 | track_unbuffer_callback(&tracks[cur_idx].id3, filling); | ||
953 | memset(&tracks[cur_idx], 0, sizeof(struct track_info)); | 979 | memset(&tracks[cur_idx], 0, sizeof(struct track_info)); |
954 | } | 980 | } |
955 | } | 981 | } |
956 | 982 | ||
983 | /* Send callback events to notify about new tracks. */ | ||
984 | static void generate_postbuffer_events(void) | ||
985 | { | ||
986 | int i; | ||
987 | int cur_ridx, event_count; | ||
988 | |||
989 | if (!track_buffer_callback) | ||
990 | return ; | ||
991 | |||
992 | /* At first determine how many unsent events we have. */ | ||
993 | cur_ridx = track_ridx; | ||
994 | event_count = 0; | ||
995 | for (i = 0; i < track_count; i++) { | ||
996 | if (!tracks[cur_ridx].event_sent) | ||
997 | event_count++; | ||
998 | if (++cur_ridx >= MAX_TRACK) | ||
999 | cur_ridx -= MAX_TRACK; | ||
1000 | } | ||
1001 | |||
1002 | /* Now sent these events. */ | ||
1003 | cur_ridx = track_ridx; | ||
1004 | for (i = 0; i < track_count; i++) { | ||
1005 | if (!tracks[cur_ridx].event_sent) { | ||
1006 | tracks[cur_ridx].event_sent = true; | ||
1007 | event_count--; | ||
1008 | track_buffer_callback(&tracks[cur_ridx].id3, event_count == 0); | ||
1009 | } | ||
1010 | if (++cur_ridx >= MAX_TRACK) | ||
1011 | cur_ridx -= MAX_TRACK; | ||
1012 | } | ||
1013 | } | ||
1014 | |||
957 | void initialize_buffer_fill(void) | 1015 | void initialize_buffer_fill(void) |
958 | { | 1016 | { |
959 | int cur_idx, i; | 1017 | int cur_idx, i; |
@@ -1014,6 +1072,7 @@ void audio_check_buffer(void) | |||
1014 | if (audio_load_track(0, false, last_peek_offset)) { | 1072 | if (audio_load_track(0, false, last_peek_offset)) { |
1015 | last_peek_offset++; | 1073 | last_peek_offset++; |
1016 | } else if (tracks[track_widx].filerem == 0 || fill_bytesleft == 0) { | 1074 | } else if (tracks[track_widx].filerem == 0 || fill_bytesleft == 0) { |
1075 | generate_postbuffer_events(); | ||
1017 | filling = false; | 1076 | filling = false; |
1018 | conf_bufferlimit = 0; | 1077 | conf_bufferlimit = 0; |
1019 | pcm_set_boost_mode(false); | 1078 | pcm_set_boost_mode(false); |
@@ -1069,6 +1128,8 @@ void audio_change_track(void) | |||
1069 | logf("No more tracks"); | 1128 | logf("No more tracks"); |
1070 | while (pcm_is_playing()) | 1129 | while (pcm_is_playing()) |
1071 | yield(); | 1130 | yield(); |
1131 | track_count = 0; | ||
1132 | audio_clear_track_entries(); | ||
1072 | playing = false; | 1133 | playing = false; |
1073 | return ; | 1134 | return ; |
1074 | } | 1135 | } |
@@ -1206,6 +1267,8 @@ void audio_thread(void) | |||
1206 | } | 1267 | } |
1207 | pcm_play_stop(); | 1268 | pcm_play_stop(); |
1208 | pcm_play_pause(true); | 1269 | pcm_play_pause(true); |
1270 | track_count = 0; | ||
1271 | audio_clear_track_entries(); | ||
1209 | break ; | 1272 | break ; |
1210 | 1273 | ||
1211 | case AUDIO_PAUSE: | 1274 | case AUDIO_PAUSE: |
@@ -1233,6 +1296,8 @@ void audio_thread(void) | |||
1233 | 1296 | ||
1234 | #ifndef SIMULATOR | 1297 | #ifndef SIMULATOR |
1235 | case SYS_USB_CONNECTED: | 1298 | case SYS_USB_CONNECTED: |
1299 | track_count = 0; | ||
1300 | audio_clear_track_entries(); | ||
1236 | playing = false; | 1301 | playing = false; |
1237 | filling = false; | 1302 | filling = false; |
1238 | ci.stop_codec = true; | 1303 | ci.stop_codec = true; |
@@ -1269,6 +1334,8 @@ void codec_thread(void) | |||
1269 | codecsize = cur_ti->codecsize; | 1334 | codecsize = cur_ti->codecsize; |
1270 | if (codecsize == 0) { | 1335 | if (codecsize == 0) { |
1271 | logf("Codec slot is empty!"); | 1336 | logf("Codec slot is empty!"); |
1337 | track_count = 0; | ||
1338 | audio_clear_track_entries(); | ||
1272 | playing = false; | 1339 | playing = false; |
1273 | break ; | 1340 | break ; |
1274 | } | 1341 | } |
@@ -1296,6 +1363,8 @@ void codec_thread(void) | |||
1296 | if (status != CODEC_OK) { | 1363 | if (status != CODEC_OK) { |
1297 | logf("Codec failure"); | 1364 | logf("Codec failure"); |
1298 | splash(HZ*2, true, "Codec failure"); | 1365 | splash(HZ*2, true, "Codec failure"); |
1366 | track_count = 0; | ||
1367 | audio_clear_track_entries(); | ||
1299 | playing = false; | 1368 | playing = false; |
1300 | } else { | 1369 | } else { |
1301 | logf("Codec finished"); | 1370 | logf("Codec finished"); |
@@ -1597,6 +1666,18 @@ void mpeg_id3_options(bool _v1first) | |||
1597 | v1first = _v1first; | 1666 | v1first = _v1first; |
1598 | } | 1667 | } |
1599 | 1668 | ||
1669 | /* | ||
1670 | void test_buffer_event(struct mp3entry *id3, bool last_track) | ||
1671 | { | ||
1672 | logf("be:%d%s", last_track, id3->title); | ||
1673 | } | ||
1674 | |||
1675 | void test_unbuffer_event(struct mp3entry *id3, bool disk_spinning) | ||
1676 | { | ||
1677 | logf("ube:%d%s", disk_spinning, id3->title); | ||
1678 | } | ||
1679 | */ | ||
1680 | |||
1600 | void audio_init(void) | 1681 | void audio_init(void) |
1601 | { | 1682 | { |
1602 | logf("audio api init"); | 1683 | logf("audio api init"); |
@@ -1611,12 +1692,19 @@ void audio_init(void) | |||
1611 | paused = false; | 1692 | paused = false; |
1612 | track_changed = false; | 1693 | track_changed = false; |
1613 | current_fd = -1; | 1694 | current_fd = -1; |
1695 | track_buffer_callback = NULL; | ||
1696 | track_unbuffer_callback = NULL; | ||
1614 | track_changed_callback = NULL; | 1697 | track_changed_callback = NULL; |
1615 | 1698 | ||
1616 | logf("abuf:%0x", PCMBUF_SIZE); | 1699 | logf("abuf:%0x", PCMBUF_SIZE); |
1617 | logf("fbuf:%0x", codecbuflen); | 1700 | logf("fbuf:%0x", codecbuflen); |
1618 | logf("mbuf:%0x", MALLOC_BUFSIZE); | 1701 | logf("mbuf:%0x", MALLOC_BUFSIZE); |
1619 | 1702 | ||
1703 | /* | ||
1704 | audio_set_track_buffer_event(test_buffer_event); | ||
1705 | audio_set_track_unbuffer_event(test_unbuffer_event); | ||
1706 | */ | ||
1707 | |||
1620 | /* Initialize codec api. */ | 1708 | /* Initialize codec api. */ |
1621 | ci.read_filebuf = codec_filebuf_callback; | 1709 | ci.read_filebuf = codec_filebuf_callback; |
1622 | ci.audiobuffer_insert = pcm_insert_buffer; | 1710 | ci.audiobuffer_insert = pcm_insert_buffer; |