summaryrefslogtreecommitdiff
path: root/apps/playback.c
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2005-07-02 16:52:30 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2005-07-02 16:52:30 +0000
commitd54811fe22c274ed31d897864ac0a33349f460e0 (patch)
treeb8c7928c46c4989f43eb1b63db07408daa70b4bb /apps/playback.c
parenta8cadd8181e53320109d2af61f0c7edea262d325 (diff)
downloadrockbox-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.c96
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. */
167void (*track_changed_callback)(struct track_info *ti); 167void (*track_changed_callback)(struct track_info *ti);
168void (*track_buffer_callback)(struct mp3entry *id3, bool last_track);
169void (*track_unbuffer_callback)(struct mp3entry *id3, bool disk_spinning);
168 170
169/* Configuration */ 171/* Configuration */
170static int conf_bufferlimit; 172static 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
598void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3,
599 bool last_track))
600{
601 track_buffer_callback = handler;
602}
603
604void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3,
605 bool disk_spinning))
606{
607 track_unbuffer_callback = handler;
608}
609
592void audio_set_track_changed_event(void (*handler)(struct track_info *ti)) 610void 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. */
984static 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
957void initialize_buffer_fill(void) 1015void 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/*
1670void test_buffer_event(struct mp3entry *id3, bool last_track)
1671{
1672 logf("be:%d%s", last_track, id3->title);
1673}
1674
1675void test_unbuffer_event(struct mp3entry *id3, bool disk_spinning)
1676{
1677 logf("ube:%d%s", disk_spinning, id3->title);
1678}
1679*/
1680
1600void audio_init(void) 1681void 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;