summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Low <lostlogic@rockbox.org>2006-04-05 04:27:16 +0000
committerBrandon Low <lostlogic@rockbox.org>2006-04-05 04:27:16 +0000
commit33a62e8a8ebe8039101a2333e71bc2c2de8e5225 (patch)
tree6bb12311091a554738f992ccdf76a60504b859eb
parent4ff8744e55da1cbd6da70033dd6cdcff50d55cae (diff)
downloadrockbox-33a62e8a8ebe8039101a2333e71bc2c2de8e5225.tar.gz
rockbox-33a62e8a8ebe8039101a2333e71bc2c2de8e5225.zip
More work on swcodec. No significant pcmbuf functions are called from the audio thread now. Do not be surprised if seek or skip behavior gets weird after this, but it Works for Me (TM), and is a significant step in the right direction.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9510 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/abrepeat.c6
-rw-r--r--apps/pcmbuf.c13
-rw-r--r--apps/playback.c52
-rw-r--r--firmware/export/audio.h1
-rw-r--r--firmware/pcm_playback.c2
5 files changed, 29 insertions, 45 deletions
diff --git a/apps/abrepeat.c b/apps/abrepeat.c
index b83a7b6aa3..fc1913d37b 100644
--- a/apps/abrepeat.c
+++ b/apps/abrepeat.c
@@ -111,13 +111,13 @@ reasonable amount of time for the typical user to react */
111 111
112void ab_jump_to_A_marker(void) 112void ab_jump_to_A_marker(void)
113{ 113{
114#if (CONFIG_CODEC == SWCODEC) 114#if (CONFIG_CODEC != SWCODEC)
115 audio_seamless_seek(ab_A_marker);
116#else
117 bool paused = (audio_status() & AUDIO_STATUS_PAUSE) != 0; 115 bool paused = (audio_status() & AUDIO_STATUS_PAUSE) != 0;
118 if ( ! paused ) 116 if ( ! paused )
119 audio_pause(); 117 audio_pause();
118#endif
120 audio_ff_rewind(ab_A_marker); 119 audio_ff_rewind(ab_A_marker);
120#if (CONFIG_CODEC != SWCODEC)
121 if ( ! paused ) 121 if ( ! paused )
122 audio_resume(); 122 audio_resume();
123#endif 123#endif
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index c0791987ce..7a261fecbe 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -61,8 +61,6 @@ static bool crossfade_init IDATA_ATTR;
61static size_t crossfade_pos IDATA_ATTR; 61static size_t crossfade_pos IDATA_ATTR;
62static size_t crossfade_rem IDATA_ATTR; 62static size_t crossfade_rem IDATA_ATTR;
63 63
64static struct mutex pcmbuf_mutex IDATA_ATTR;
65
66/* Crossfade modes. If CFM_CROSSFADE is selected, normal 64/* Crossfade modes. If CFM_CROSSFADE is selected, normal
67 * crossfader will activate. Selecting CFM_FLUSH is a special 65 * crossfader will activate. Selecting CFM_FLUSH is a special
68 * operation that only overwrites the pcm buffer without crossfading. 66 * operation that only overwrites the pcm buffer without crossfading.
@@ -297,7 +295,6 @@ bool pcmbuf_crossfade_init(bool manual_skip)
297 295
298void pcmbuf_play_stop(void) 296void pcmbuf_play_stop(void)
299{ 297{
300 mutex_lock(&pcmbuf_mutex);
301 /** Prevent a very tiny pop from happening by muting audio 298 /** Prevent a very tiny pop from happening by muting audio
302 * until dma has been initialized. */ 299 * until dma has been initialized. */
303 pcm_mute(true); 300 pcm_mute(true);
@@ -320,7 +317,6 @@ void pcmbuf_play_stop(void)
320 pcmbuf_set_boost_mode(false); 317 pcmbuf_set_boost_mode(false);
321 pcmbuf_boost(false); 318 pcmbuf_boost(false);
322 319
323 mutex_unlock(&pcmbuf_mutex);
324} 320}
325 321
326int pcmbuf_used_descs(void) { 322int pcmbuf_used_descs(void) {
@@ -356,7 +352,6 @@ static void pcmbuf_init_pcmbuffers(void) {
356 * ...CODECBUFFER|---------PCMBUF---------|GUARDBUF|DESCS| */ 352 * ...CODECBUFFER|---------PCMBUF---------|GUARDBUF|DESCS| */
357void pcmbuf_init(size_t bufsize) 353void pcmbuf_init(size_t bufsize)
358{ 354{
359 mutex_init(&pcmbuf_mutex);
360 pcmbuf_size = bufsize; 355 pcmbuf_size = bufsize;
361 pcmbuf_descsize = pcmbuf_descs()*sizeof(struct pcmbufdesc); 356 pcmbuf_descsize = pcmbuf_descs()*sizeof(struct pcmbufdesc);
362 audiobuffer = (char *)&audiobuf[(audiobufend - audiobuf) - 357 audiobuffer = (char *)&audiobuf[(audiobufend - audiobuf) -
@@ -401,8 +396,6 @@ void pcmbuf_pause(bool pause) {
401/* Force playback. */ 396/* Force playback. */
402void pcmbuf_play_start(void) 397void pcmbuf_play_start(void)
403{ 398{
404 mutex_lock(&pcmbuf_mutex);
405
406 if (!pcm_is_playing() && pcmbuf_unplayed_bytes) 399 if (!pcm_is_playing() && pcmbuf_unplayed_bytes)
407 { 400 {
408 /** Prevent a very tiny pop from happening by muting audio 401 /** Prevent a very tiny pop from happening by muting audio
@@ -417,8 +410,6 @@ void pcmbuf_play_start(void)
417 /* Now unmute the audio. */ 410 /* Now unmute the audio. */
418 pcm_mute(false); 411 pcm_mute(false);
419 } 412 }
420
421 mutex_unlock(&pcmbuf_mutex);
422} 413}
423 414
424/** 415/**
@@ -426,8 +417,6 @@ void pcmbuf_play_start(void)
426 */ 417 */
427static void pcmbuf_flush_fillpos(void) 418static void pcmbuf_flush_fillpos(void)
428{ 419{
429 mutex_lock(&pcmbuf_mutex);
430
431 if (audiobuffer_fillpos) { 420 if (audiobuffer_fillpos) {
432 /* Never use the last buffer descriptor */ 421 /* Never use the last buffer descriptor */
433 while (pcmbuf_write == pcmbuf_write_end) { 422 while (pcmbuf_write == pcmbuf_write_end) {
@@ -444,8 +433,6 @@ static void pcmbuf_flush_fillpos(void)
444 } 433 }
445 pcmbuf_add_chunk(); 434 pcmbuf_add_chunk();
446 } 435 }
447
448 mutex_unlock(&pcmbuf_mutex);
449} 436}
450 437
451/** 438/**
diff --git a/apps/playback.c b/apps/playback.c
index 9f8fc5a71b..aa48dd9bae 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -70,6 +70,7 @@
70static volatile bool audio_codec_loaded; 70static volatile bool audio_codec_loaded;
71static volatile bool voice_codec_loaded; 71static volatile bool voice_codec_loaded;
72static volatile bool playing; 72static volatile bool playing;
73static volatile bool seeking;
73 74
74#define CODEC_VORBIS "/.rockbox/codecs/vorbis.codec" 75#define CODEC_VORBIS "/.rockbox/codecs/vorbis.codec"
75#define CODEC_MPA_L3 "/.rockbox/codecs/mpa.codec" 76#define CODEC_MPA_L3 "/.rockbox/codecs/mpa.codec"
@@ -102,7 +103,6 @@ enum {
102 Q_AUDIO_TRACK_CHANGED, 103 Q_AUDIO_TRACK_CHANGED,
103 Q_AUDIO_DIR_NEXT, 104 Q_AUDIO_DIR_NEXT,
104 Q_AUDIO_DIR_PREV, 105 Q_AUDIO_DIR_PREV,
105 Q_AUDIO_SEAMLESS_SEEK,
106 Q_AUDIO_POSTINIT, 106 Q_AUDIO_POSTINIT,
107 107
108 Q_CODEC_LOAD, 108 Q_CODEC_LOAD,
@@ -679,7 +679,12 @@ off_t codec_mp3_get_filepos_callback(int newtime)
679void codec_seek_complete_callback(void) 679void codec_seek_complete_callback(void)
680{ 680{
681 /* assume we're called from non-voice codec, as they shouldn't seek */ 681 /* assume we're called from non-voice codec, as they shouldn't seek */
682 if (pcm_is_paused()) {
683 /* If this is not a seamless seek, clear the buffer */
684 pcmbuf_play_stop();
685 }
682 ci.seek_time = 0; 686 ci.seek_time = 0;
687 seeking = false;
683} 688}
684 689
685bool codec_seek_buffer_callback(size_t newpos) 690bool codec_seek_buffer_callback(size_t newpos)
@@ -1329,10 +1334,10 @@ static void audio_clear_track_entries(bool buffered_only)
1329static void stop_codec_flush(void) 1334static void stop_codec_flush(void)
1330{ 1335{
1331 ci.stop_codec = true; 1336 ci.stop_codec = true;
1332 pcmbuf_play_stop(); 1337 pcmbuf_pause(true);
1333 while (audio_codec_loaded) 1338 while (audio_codec_loaded)
1334 yield(); 1339 yield();
1335 pcmbuf_play_stop(); 1340 pcmbuf_pause(false);
1336} 1341}
1337 1342
1338static void audio_stop_playback(bool resume) 1343static void audio_stop_playback(bool resume)
@@ -1343,7 +1348,6 @@ static void audio_stop_playback(bool resume)
1343 playing = false; 1348 playing = false;
1344 filling = false; 1349 filling = false;
1345 stop_codec_flush(); 1350 stop_codec_flush();
1346 pcmbuf_pause(false);
1347 if (current_fd >= 0) { 1351 if (current_fd >= 0) {
1348 close(current_fd); 1352 close(current_fd);
1349 current_fd = -1; 1353 current_fd = -1;
@@ -1768,11 +1772,11 @@ static void initiate_track_change(int peek_index)
1768{ 1772{
1769 /* Detect if disk is spinning or already loading. */ 1773 /* Detect if disk is spinning or already loading. */
1770 if (filling || ci.reload_codec || !audio_codec_loaded) { 1774 if (filling || ci.reload_codec || !audio_codec_loaded) {
1771 if (pcmbuf_is_crossfade_enabled()) 1775 if (pcmbuf_is_crossfade_enabled()) {
1772 pcmbuf_crossfade_init(true); 1776 pcmbuf_crossfade_init(true);
1773 else 1777 ci.stop_codec = true;
1774 pcmbuf_play_stop(); 1778 } else
1775 ci.stop_codec = true; 1779 stop_codec_flush();
1776 queue_post(&audio_queue, Q_AUDIO_PLAY, 0); 1780 queue_post(&audio_queue, Q_AUDIO_PLAY, 0);
1777 } else { 1781 } else {
1778 new_track = peek_index; 1782 new_track = peek_index;
@@ -1836,10 +1840,6 @@ void audio_thread(void)
1836 play_pending = false; 1840 play_pending = false;
1837 last_tick = current_tick; 1841 last_tick = current_tick;
1838 1842
1839 /* Do not start crossfading if audio is paused. */
1840 if (pcm_is_paused())
1841 pcmbuf_play_stop();
1842
1843#ifdef CONFIG_TUNER 1843#ifdef CONFIG_TUNER
1844 /* check if radio is playing */ 1844 /* check if radio is playing */
1845 if (get_radio_status() != FMRADIO_OFF) { 1845 if (get_radio_status() != FMRADIO_OFF) {
@@ -1848,6 +1848,7 @@ void audio_thread(void)
1848#endif 1848#endif
1849 1849
1850 logf("starting..."); 1850 logf("starting...");
1851
1851 playing = true; 1852 playing = true;
1852 ci.stop_codec = true; 1853 ci.stop_codec = true;
1853 ci.reload_codec = false; 1854 ci.reload_codec = false;
@@ -1898,19 +1899,13 @@ void audio_thread(void)
1898 case Q_AUDIO_FF_REWIND: 1899 case Q_AUDIO_FF_REWIND:
1899 if (!playing) 1900 if (!playing)
1900 break ; 1901 break ;
1901 pcmbuf_play_stop();
1902 ci.seek_time = (long)ev.data+1;
1903 break ;
1904
1905 case Q_AUDIO_SEAMLESS_SEEK:
1906 if (!playing)
1907 break ;
1908 ci.seek_time = (long)ev.data+1; 1902 ci.seek_time = (long)ev.data+1;
1909 break ; 1903 break ;
1910 1904
1911 case Q_AUDIO_DIR_NEXT: 1905 case Q_AUDIO_DIR_NEXT:
1912 logf("audio_dir_next"); 1906 logf("audio_dir_next");
1913 playlist_end = false; 1907 playlist_end = false;
1908 /* pcmbuf_beep may or may not be safe on audio thread */
1914 if (global_settings.beep) 1909 if (global_settings.beep)
1915 pcmbuf_beep(5000, 100, 2500*global_settings.beep); 1910 pcmbuf_beep(5000, 100, 2500*global_settings.beep);
1916 initiate_dir_change(1); 1911 initiate_dir_change(1);
@@ -1919,6 +1914,7 @@ void audio_thread(void)
1919 case Q_AUDIO_DIR_PREV: 1914 case Q_AUDIO_DIR_PREV:
1920 logf("audio_dir_prev"); 1915 logf("audio_dir_prev");
1921 playlist_end = false; 1916 playlist_end = false;
1917 /* pcmbuf_beep may or may not be safe on audio thread */
1922 if (global_settings.beep) 1918 if (global_settings.beep)
1923 pcmbuf_beep(5000, 100, 2500*global_settings.beep); 1919 pcmbuf_beep(5000, 100, 2500*global_settings.beep);
1924 initiate_dir_change(-1); 1920 initiate_dir_change(-1);
@@ -2010,6 +2006,9 @@ void codec_thread(void)
2010#endif 2006#endif
2011 } 2007 }
2012 2008
2009 if (ci.stop_codec && pcm_is_paused())
2010 pcmbuf_play_stop();
2011
2013 audio_codec_loaded = false; 2012 audio_codec_loaded = false;
2014 2013
2015 switch (ev.id) { 2014 switch (ev.id) {
@@ -2191,7 +2190,6 @@ void audio_play(long offset)
2191 else 2190 else
2192 { 2191 {
2193 stop_codec_flush(); 2192 stop_codec_flush();
2194 pcmbuf_play_stop();
2195 } 2193 }
2196 2194
2197 queue_post(&audio_queue, Q_AUDIO_PLAY, (void *)offset); 2195 queue_post(&audio_queue, Q_AUDIO_PLAY, (void *)offset);
@@ -2268,14 +2266,14 @@ void audio_prev_dir(void)
2268 2266
2269void audio_ff_rewind(long newpos) 2267void audio_ff_rewind(long newpos)
2270{ 2268{
2271 logf("rewind: %d", newpos); 2269 logf("ff/rewind: %d", newpos);
2270 seeking = true;
2272 queue_post(&audio_queue, Q_AUDIO_FF_REWIND, (int *)newpos); 2271 queue_post(&audio_queue, Q_AUDIO_FF_REWIND, (int *)newpos);
2273} 2272 /* This is a hack, the correct solution is to report back to
2274 2273 * the caller when the seek is complete. */
2275void audio_seamless_seek(long newpos) 2274 while (seeking) {
2276{ 2275 yield();
2277 logf("seamless_seek: %d", newpos); 2276 }
2278 queue_post(&audio_queue, Q_AUDIO_SEAMLESS_SEEK, (int *)newpos);
2279} 2277}
2280 2278
2281void audio_flush_and_reload_tracks(void) 2279void audio_flush_and_reload_tracks(void)
diff --git a/firmware/export/audio.h b/firmware/export/audio.h
index 62dec73078..d1421ce9a3 100644
--- a/firmware/export/audio.h
+++ b/firmware/export/audio.h
@@ -71,7 +71,6 @@ void audio_next(void);
71void audio_prev(void); 71void audio_prev(void);
72int audio_status(void); 72int audio_status(void);
73void audio_ff_rewind(long newtime); 73void audio_ff_rewind(long newtime);
74void audio_seamless_seek(long newtime);
75void audio_flush_and_reload_tracks(void); 74void audio_flush_and_reload_tracks(void);
76struct mp3entry* audio_current_track(void); 75struct mp3entry* audio_current_track(void);
77struct mp3entry* audio_next_track(void); 76struct mp3entry* audio_next_track(void);
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c
index d6dc41cdde..8210276c48 100644
--- a/firmware/pcm_playback.c
+++ b/firmware/pcm_playback.c
@@ -638,7 +638,7 @@ void pcm_play_pause(bool play)
638 /* nothing yet */ 638 /* nothing yet */
639#endif 639#endif
640 } 640 }
641 } 641 } /* pcm_playing && needs_change */
642} 642}
643 643
644bool pcm_is_playing(void) { 644bool pcm_is_playing(void) {