summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/lang/english.lang6
-rw-r--r--apps/settings.c12
-rw-r--r--apps/settings.h4
-rw-r--r--apps/settings_menu.c18
-rw-r--r--firmware/export/pcm_playback.h1
-rw-r--r--firmware/pcm_playback.c33
6 files changed, 60 insertions, 14 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 423215c830..2c54a9c77b 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -3087,3 +3087,9 @@ desc: in info menu; name for external disk with multivolume (Ondio; keep short!
3087eng: "MMC:" 3087eng: "MMC:"
3088voice: "Multimedia card" 3088voice: "Multimedia card"
3089new: 3089new:
3090
3091id: LANG_CROSSFADE
3092desc: in playback settings
3093eng: "Crossfade"
3094voice: "Crossfade"
3095new:
diff --git a/apps/settings.c b/apps/settings.c
index 03b2dc5113..312a40e9f9 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -72,7 +72,9 @@ struct user_settings global_settings;
72#ifdef HAVE_RECORDING 72#ifdef HAVE_RECORDING
73const char rec_base_directory[] = REC_BASE_DIR; 73const char rec_base_directory[] = REC_BASE_DIR;
74#endif 74#endif
75 75#if CONFIG_HWCODEC == MASNONE
76#include "pcm_playback.h"
77#endif
76 78
77#define CONFIG_BLOCK_VERSION 21 79#define CONFIG_BLOCK_VERSION 21
78#define CONFIG_BLOCK_SIZE 512 80#define CONFIG_BLOCK_SIZE 512
@@ -382,6 +384,10 @@ static const struct bit_entry hd_bits[] =
382 {4, S_O(rec_trigger_mode ), 1, "trigger mode", "off,no rearm,rearm"}, 384 {4, S_O(rec_trigger_mode ), 1, "trigger mode", "off,no rearm,rearm"},
383#endif 385#endif
384 386
387#if CONFIG_HWCODEC == MASNONE
388 {1, S_O(crossfade), false, "crossfade", off_on},
389#endif
390
385 /* new stuff to be added at the end */ 391 /* new stuff to be added at the end */
386 392
387 /* Sum of all bit sizes must not grow beyond 0xB8*8 = 1472 */ 393 /* Sum of all bit sizes must not grow beyond 0xB8*8 = 1472 */
@@ -812,6 +818,10 @@ void settings_apply(void)
812 lang_load(buf); 818 lang_load(buf);
813 talk_init(); /* use voice of same language */ 819 talk_init(); /* use voice of same language */
814 } 820 }
821
822#if CONFIG_HWCODEC == MASNONE && !defined(SIMULATOR)
823 pcm_crossfade_enable(global_settings.crossfade);
824#endif
815} 825}
816 826
817 827
diff --git a/apps/settings.h b/apps/settings.h
index 853dc41628..325009eddb 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -152,6 +152,10 @@ struct user_settings
152 bool mdb_enable; /* true/false */ 152 bool mdb_enable; /* true/false */
153 bool superbass; /* true/false */ 153 bool superbass; /* true/false */
154 154
155#if CONFIG_HWCODEC == MASNONE
156 bool crossfade;
157#endif
158
155 int rec_quality; /* 0-7 */ 159 int rec_quality; /* 0-7 */
156 int rec_source; /* 0=mic, 1=line, 2=S/PDIF */ 160 int rec_source; /* 0=mic, 1=line, 2=S/PDIF */
157 int rec_frequency; /* 0 = 44.1kHz 161 int rec_frequency; /* 0 = 44.1kHz
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index e4002615dd..9826058202 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -60,6 +60,10 @@ void dac_line_in(bool enable);
60#include "lcd-remote.h" 60#include "lcd-remote.h"
61#endif 61#endif
62 62
63#if CONFIG_HWCODEC == MASNONE
64#include "pcm_playback.h"
65#endif
66
63#ifdef HAVE_CHARGING 67#ifdef HAVE_CHARGING
64static bool car_adapter_mode(void) 68static bool car_adapter_mode(void)
65{ 69{
@@ -1055,6 +1059,17 @@ static bool id3_order(void)
1055 mpeg_id3_options); 1059 mpeg_id3_options);
1056} 1060}
1057 1061
1062#if CONFIG_HWCODEC == MASNONE
1063static bool crossfade(void)
1064{
1065 bool rc = set_bool( str(LANG_CROSSFADE), &global_settings.crossfade );
1066#ifndef SIMULATOR
1067 pcm_crossfade_enable(global_settings.crossfade);
1068#endif
1069 return rc;
1070}
1071#endif
1072
1058static bool playback_settings_menu(void) 1073static bool playback_settings_menu(void)
1059{ 1074{
1060 int m; 1075 int m;
@@ -1068,6 +1083,9 @@ static bool playback_settings_menu(void)
1068 { ID2P(LANG_WIND_MENU), ff_rewind_settings_menu }, 1083 { ID2P(LANG_WIND_MENU), ff_rewind_settings_menu },
1069 { ID2P(LANG_MP3BUFFER_MARGIN), buffer_margin }, 1084 { ID2P(LANG_MP3BUFFER_MARGIN), buffer_margin },
1070 { ID2P(LANG_FADE_ON_STOP), set_fade_on_stop }, 1085 { ID2P(LANG_FADE_ON_STOP), set_fade_on_stop },
1086#if CONFIG_HWCODEC == MASNONE
1087 { ID2P(LANG_CROSSFADE), crossfade },
1088#endif
1071 { ID2P(LANG_ID3_ORDER), id3_order }, 1089 { ID2P(LANG_ID3_ORDER), id3_order },
1072 }; 1090 };
1073 1091
diff --git a/firmware/export/pcm_playback.h b/firmware/export/pcm_playback.h
index d101c823ba..0f2de83224 100644
--- a/firmware/export/pcm_playback.h
+++ b/firmware/export/pcm_playback.h
@@ -45,5 +45,6 @@ bool pcm_is_lowdata(void);
45void pcm_crossfade_start(void); 45void pcm_crossfade_start(void);
46unsigned int audiobuffer_get_latency(void); 46unsigned int audiobuffer_get_latency(void);
47bool audiobuffer_insert(char *buf, size_t length); 47bool audiobuffer_insert(char *buf, size_t length);
48void pcm_crossfade_enable(bool on_off);
48 49
49#endif 50#endif
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c
index ab4f0c0375..e5d6f4218b 100644
--- a/firmware/pcm_playback.c
+++ b/firmware/pcm_playback.c
@@ -56,6 +56,7 @@ static volatile size_t audiobuffer_free;
56static size_t audiobuffer_fillpos; 56static size_t audiobuffer_fillpos;
57static bool boost_mode; 57static bool boost_mode;
58 58
59static bool crossfade_enabled;
59static bool crossfade_active; 60static bool crossfade_active;
60static int crossfade_pos; 61static int crossfade_pos;
61static int crossfade_amount; 62static int crossfade_amount;
@@ -432,18 +433,7 @@ bool audiobuffer_insert(char *buf, size_t length)
432 } 433 }
433 434
434 while (length > 0) { 435 while (length > 0) {
435 if (!crossfade_active) { 436 if (crossfade_enabled && crossfade_active) {
436 copy_n = MIN(length, PCMBUF_SIZE - audiobuffer_pos -
437 audiobuffer_fillpos);
438 copy_n = MIN(CHUNK_SIZE, copy_n);
439
440 memcpy(&audiobuffer[audiobuffer_pos+audiobuffer_fillpos],
441 buf, copy_n);
442 buf += copy_n;
443 audiobuffer_free -= copy_n;
444 length -= copy_n;
445
446 } else {
447 copy_n = MIN(length, PCMBUF_SIZE - (unsigned int)crossfade_pos); 437 copy_n = MIN(length, PCMBUF_SIZE - (unsigned int)crossfade_pos);
448 438
449 crossfade((short *)&audiobuffer[crossfade_pos], 439 crossfade((short *)&audiobuffer[crossfade_pos],
@@ -453,7 +443,17 @@ bool audiobuffer_insert(char *buf, size_t length)
453 crossfade_pos += copy_n; 443 crossfade_pos += copy_n;
454 if (crossfade_pos >= PCMBUF_SIZE) 444 if (crossfade_pos >= PCMBUF_SIZE)
455 crossfade_pos -= PCMBUF_SIZE; 445 crossfade_pos -= PCMBUF_SIZE;
456 continue ; 446 continue ;
447 } else {
448 copy_n = MIN(length, PCMBUF_SIZE - audiobuffer_pos -
449 audiobuffer_fillpos);
450 copy_n = MIN(CHUNK_SIZE, copy_n);
451
452 memcpy(&audiobuffer[audiobuffer_pos+audiobuffer_fillpos],
453 buf, copy_n);
454 buf += copy_n;
455 audiobuffer_free -= copy_n;
456 length -= copy_n;
457 } 457 }
458 458
459 /* Pre-buffer to meet CHUNK_SIZE requirement */ 459 /* Pre-buffer to meet CHUNK_SIZE requirement */
@@ -501,6 +501,13 @@ void pcm_play_init(void)
501 memset(&audiobuffer[0], 0, audiobuffer_pos); 501 memset(&audiobuffer[0], 0, audiobuffer_pos);
502 pcm_play_add_chunk(&audiobuffer[0], audiobuffer_pos, NULL); 502 pcm_play_add_chunk(&audiobuffer[0], audiobuffer_pos, NULL);
503 pcm_play_start(); 503 pcm_play_start();
504
505 crossfade_enabled = false;
506}
507
508void pcm_crossfade_enable(bool on_off)
509{
510 crossfade_enabled = on_off;
504} 511}
505 512
506void pcm_play_start(void) 513void pcm_play_start(void)