summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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) {