New 'Track Skip Only' option for Crossfading; crossfading is disabled except for manual track changes. NOTE: If you were using 'Always' mode previously, check again after updating: you'll now be in the new 'Track Skip Only' mode.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9353 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
dbcc9c25d5
commit
8bdd92b05e
5 changed files with 243 additions and 235 deletions
|
@ -3898,3 +3898,9 @@ desc: spoken only, for file extension
|
|||
eng: ""
|
||||
voice: "keyboard"
|
||||
new:
|
||||
|
||||
id: LANG_TRACKSKIP
|
||||
desc: in crossfade settings
|
||||
eng: "Track Skip Only"
|
||||
voice: "Track Skip Only"
|
||||
new:
|
||||
|
|
|
@ -116,10 +116,10 @@ static bool boost_mode;
|
|||
void pcmbuf_boost(bool state)
|
||||
{
|
||||
static bool boost_state = false;
|
||||
|
||||
|
||||
if (crossfade_init || crossfade_active || boost_mode)
|
||||
return;
|
||||
|
||||
|
||||
if (state != boost_state) {
|
||||
cpu_boost(state);
|
||||
boost_state = state;
|
||||
|
@ -138,7 +138,7 @@ void pcmbuf_set_boost_mode(bool state)
|
|||
/* This function has 2 major logical parts (separated by brackets both for
|
||||
* readability and variable scoping). The first part performs the
|
||||
* operastions related to finishing off the last buffer we fed to the DMA.
|
||||
* The second part performs the operations involved in sending a new buffer
|
||||
* The second part performs the operations involved in sending a new buffer
|
||||
* to the DMA. Finally the function checks the status of the buffer and
|
||||
* boosts if necessary */
|
||||
static void pcmbuf_callback(unsigned char** start, size_t* size) ICODE_ATTR;
|
||||
|
@ -267,7 +267,7 @@ bool pcmbuf_is_lowdata(void)
|
|||
if (!pcm_is_playing() || pcm_is_paused() ||
|
||||
crossfade_init || crossfade_active)
|
||||
return false;
|
||||
|
||||
|
||||
/* 0.5 seconds of buffer is low data */
|
||||
return LOW_DATA(2);
|
||||
}
|
||||
|
@ -290,9 +290,9 @@ bool pcmbuf_crossfade_init(bool manual_skip)
|
|||
crossfade_mode = global_settings.crossfade_fade_out_mixmode
|
||||
? CFM_MIX : CFM_CROSSFADE;
|
||||
crossfade_init = true;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void pcmbuf_play_stop(void)
|
||||
|
@ -303,7 +303,7 @@ void pcmbuf_play_stop(void)
|
|||
pcm_mute(true);
|
||||
pcm_play_stop();
|
||||
pcm_mute(false);
|
||||
|
||||
|
||||
pcmbuf_unplayed_bytes = 0;
|
||||
pcmbuf_mix_used_bytes = 0;
|
||||
if (pcmbuf_read) {
|
||||
|
@ -316,7 +316,7 @@ void pcmbuf_play_stop(void)
|
|||
audiobuffer_free = pcmbuf_size;
|
||||
crossfade_init = false;
|
||||
crossfade_active = false;
|
||||
|
||||
|
||||
pcmbuf_set_boost_mode(false);
|
||||
pcmbuf_boost(false);
|
||||
|
||||
|
@ -340,7 +340,7 @@ int pcmbuf_descs(void) {
|
|||
size_t get_pcmbuf_descsize(void) {
|
||||
return pcmbuf_descsize;
|
||||
}
|
||||
|
||||
|
||||
static void pcmbuf_init_pcmbuffers(void) {
|
||||
struct pcmbufdesc *next = pcmbuf_write;
|
||||
next++;
|
||||
|
@ -351,7 +351,7 @@ static void pcmbuf_init_pcmbuffers(void) {
|
|||
next++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the pcmbuffer the structure looks like this:
|
||||
* ...CODECBUFFER|---------PCMBUF---------|GUARDBUF|DESCS| */
|
||||
void pcmbuf_init(size_t bufsize)
|
||||
|
@ -383,7 +383,7 @@ static void pcmbuf_flush_audio(void)
|
|||
pcmbuf_play_stop();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
pcmbuf_boost(true);
|
||||
crossfade_mode = CFM_FLUSH;
|
||||
crossfade_init = true;
|
||||
|
@ -408,10 +408,10 @@ void pcmbuf_play_start(void)
|
|||
/** Prevent a very tiny pop from happening by muting audio
|
||||
* until dma has been initialized. */
|
||||
pcm_mute(true);
|
||||
|
||||
|
||||
last_chunksize = pcmbuf_read->size;
|
||||
pcmbuf_unplayed_bytes -= last_chunksize;
|
||||
pcm_play_data(pcmbuf_callback,
|
||||
pcm_play_data(pcmbuf_callback,
|
||||
(unsigned char *)pcmbuf_read->addr, last_chunksize);
|
||||
|
||||
/* Now unmute the audio. */
|
||||
|
@ -470,7 +470,7 @@ static void crossfade_process_buffer(size_t fade_in_delay,
|
|||
size_t block_rem = MIN(NATIVE_FREQUENCY * 2 / 10, fade_out_rem);
|
||||
unsigned int factor = (fade_out_rem << 8) / total_fade_out;
|
||||
short *block_end = buf + block_rem;
|
||||
|
||||
|
||||
fade_out_rem -= block_rem;
|
||||
|
||||
/* Fade this block */
|
||||
|
@ -508,7 +508,7 @@ static void crossfade_start(void)
|
|||
size_t fade_out_rem = 0;
|
||||
unsigned int fade_out_delay = 0;
|
||||
unsigned fade_in_delay = 0;
|
||||
|
||||
|
||||
crossfade_init = 0;
|
||||
/* Reject crossfade if less than .5s of data */
|
||||
if (LOW_DATA(2)) {
|
||||
|
@ -556,7 +556,7 @@ static void crossfade_start(void)
|
|||
|
||||
fade_in_delay = NATIVE_FREQUENCY
|
||||
* global_settings.crossfade_fade_in_delay * 2;
|
||||
|
||||
|
||||
/* Decrease the fade out delay if necessary. */
|
||||
if (crossfade_rem < fade_out_rem + fade_out_delay)
|
||||
fade_out_delay -=
|
||||
|
@ -568,16 +568,16 @@ static void crossfade_start(void)
|
|||
crossfade_fade_in_amount = 0;
|
||||
break ;
|
||||
}
|
||||
|
||||
|
||||
if (crossfade_pos < crossfade_rem * 2)
|
||||
crossfade_pos += pcmbuf_size;
|
||||
crossfade_pos -= crossfade_rem*2;
|
||||
|
||||
|
||||
if (crossfade_mode != CFM_FLUSH) {
|
||||
/* Process the fade out part of the crossfade. */
|
||||
crossfade_process_buffer(fade_in_delay, fade_out_delay, fade_out_rem);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -590,7 +590,7 @@ static void fade_insert(const short *inbuf, size_t length)
|
|||
int factor;
|
||||
unsigned int i, samples;
|
||||
short *buf;
|
||||
|
||||
|
||||
factor = ((crossfade_fade_in_amount-crossfade_fade_in_rem)<<8)
|
||||
/crossfade_fade_in_amount;
|
||||
|
||||
|
@ -600,7 +600,7 @@ static void fade_insert(const short *inbuf, size_t length)
|
|||
sleep(1);
|
||||
}
|
||||
audiobuffer_free -= length;
|
||||
|
||||
|
||||
while (length > 0) {
|
||||
unsigned int audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos;
|
||||
/* Flush as needed */
|
||||
|
@ -609,14 +609,14 @@ static void fade_insert(const short *inbuf, size_t length)
|
|||
pcmbuf_flush_fillpos();
|
||||
audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos;
|
||||
}
|
||||
|
||||
|
||||
copy_n = MIN(length, pcmbuf_size - audiobuffer_index);
|
||||
|
||||
buf = (short *)&audiobuffer[audiobuffer_index];
|
||||
samples = copy_n / 2;
|
||||
for (i = 0; i < samples; i++)
|
||||
buf[i] = (inbuf[i] * factor) >> 8;
|
||||
|
||||
|
||||
inbuf += samples;
|
||||
audiobuffer_fillpos += copy_n;
|
||||
length -= copy_n;
|
||||
|
@ -632,7 +632,7 @@ static int crossfade(short *buf, const short *buf2, unsigned int length)
|
|||
unsigned int i;
|
||||
size_t size_insert = 0;
|
||||
int factor;
|
||||
|
||||
|
||||
size = MIN(length, crossfade_rem);
|
||||
switch (crossfade_mode) {
|
||||
/* Fade in the current stream and mix it. */
|
||||
|
@ -640,9 +640,9 @@ static int crossfade(short *buf, const short *buf2, unsigned int length)
|
|||
case CFM_CROSSFADE:
|
||||
factor = ((crossfade_fade_in_amount-crossfade_fade_in_rem)<<8) /
|
||||
crossfade_fade_in_amount;
|
||||
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
buf[i] = MIN(32767, MAX(-32768,
|
||||
buf[i] = MIN(32767, MAX(-32768,
|
||||
buf[i] + ((buf2[i] * factor) >> 8)));
|
||||
}
|
||||
break ;
|
||||
|
@ -670,7 +670,7 @@ static int crossfade(short *buf, const short *buf2, unsigned int length)
|
|||
fade_insert(&buf2[size], size_insert*2);
|
||||
crossfade_fade_in_rem -= size_insert;
|
||||
}
|
||||
|
||||
|
||||
if (crossfade_fade_in_rem == 0)
|
||||
crossfade_active = false;
|
||||
}
|
||||
|
@ -726,7 +726,7 @@ static bool prepare_insert(size_t length)
|
|||
&& pcm_is_playing())
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Need to save PCMBUF_MIN_CHUNK to prevent wrapping overwriting */
|
||||
if (audiobuffer_free < length + PCMBUF_MIN_CHUNK && !crossfade_active)
|
||||
{
|
||||
|
@ -835,7 +835,7 @@ static inline short* get_mix_insert_pos(void) {
|
|||
/* Give at least 1/8s clearance here */
|
||||
size_t pcmbuf_mix_back_pos =
|
||||
pcmbuf_unplayed_bytes - NATIVE_FREQUENCY * 4 / 8;
|
||||
|
||||
|
||||
if (audiobuffer_pos < pcmbuf_mix_back_pos)
|
||||
return (short *)&audiobuffer[pcmbuf_size +
|
||||
audiobuffer_pos - pcmbuf_mix_back_pos];
|
||||
|
@ -854,7 +854,7 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
|
|||
short *pcmbuf_end = (short *)guardbuf;
|
||||
bool playing = pcm_is_playing();
|
||||
size_t samples = NATIVE_FREQUENCY / 1000 * duration;
|
||||
|
||||
|
||||
if (playing) {
|
||||
buf = get_mix_insert_pos();
|
||||
} else {
|
||||
|
@ -876,7 +876,7 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
|
|||
sample = *buf;
|
||||
*buf++ = MIN(MAX(sample - amplitude, -32768), 32767);
|
||||
}
|
||||
|
||||
|
||||
if (++count >= interval)
|
||||
{
|
||||
count = 0;
|
||||
|
@ -914,7 +914,7 @@ void pcmbuf_mix(char *buf, size_t length)
|
|||
|
||||
if (pcmbuf_mix_used_bytes == 0)
|
||||
pcmbuf_reset_mixpos();
|
||||
|
||||
|
||||
pcmbuf_mix_used_bytes += length;
|
||||
length /= 2;
|
||||
|
||||
|
|
379
apps/playback.c
379
apps/playback.c
File diff suppressed because it is too large
Load diff
|
@ -203,7 +203,7 @@ static const struct bit_entry rtc_bits[] =
|
|||
/* sound */
|
||||
#if CONFIG_CODEC == MAS3507D
|
||||
{8 | SIGNED, S_O(volume), -18, "volume", NULL }, /* -78...+18 */
|
||||
#else
|
||||
#else
|
||||
{8 | SIGNED, S_O(volume), -25, "volume", NULL }, /* -100...+12 / -84...0 */
|
||||
#endif
|
||||
{8 | SIGNED, S_O(balance), 0, "balance", NULL }, /* -100...100 */
|
||||
|
@ -300,7 +300,7 @@ static const struct bit_entry rtc_bits[] =
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_BACKLIGHT
|
||||
{1, S_O(bl_filter_first_keypress),
|
||||
{1, S_O(bl_filter_first_keypress),
|
||||
#ifdef HAVE_LCD_COLOR
|
||||
true,
|
||||
#else
|
||||
|
@ -308,9 +308,9 @@ static const struct bit_entry rtc_bits[] =
|
|||
#endif
|
||||
"backlight filters first keypress", off_on },
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
{1, S_O(remote_bl_filter_first_keypress), false,
|
||||
{1, S_O(remote_bl_filter_first_keypress), false,
|
||||
"backlight filters first remote keypress", off_on },
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -475,7 +475,7 @@ static const struct bit_entry hd_bits[] =
|
|||
{1, S_O(replaygain_noclip), false, "replaygain noclip", off_on },
|
||||
{8 | SIGNED, S_O(replaygain_preamp), 0, "replaygain preamp", NULL },
|
||||
{2, S_O(beep), 0, "beep", "off,weak,moderate,strong" },
|
||||
{2, S_O(crossfade), 0, "crossfade", "off,shuffle,always"},
|
||||
{2, S_O(crossfade), 0, "crossfade", "off,shuffle,track skip,always"},
|
||||
{3, S_O(crossfade_fade_in_delay), 0, "crossfade fade in delay", NULL},
|
||||
{3, S_O(crossfade_fade_out_delay), 0, "crossfade fade out delay", NULL},
|
||||
{4, S_O(crossfade_fade_in_duration), 0, "crossfade fade in duration", NULL},
|
||||
|
@ -511,13 +511,13 @@ static const struct bit_entry hd_bits[] =
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
{1, S_O(remote_caption_backlight), false,
|
||||
{1, S_O(remote_caption_backlight), false,
|
||||
"remote caption backlight", off_on },
|
||||
#endif
|
||||
{4, S_O(default_codepage), 0, "default codepage", "iso8859-1,iso8859-7,iso8859-8,cp1251,iso8859-11,cp1256,iso8859-9,iso8859-2,sjis,gb2312,ksx1001,big5,utf-8,cp1256" },
|
||||
|
||||
|
||||
#ifdef HAVE_BACKLIGHT_BRIGHTNESS
|
||||
{4, S_O(brightness), 9, "brightness", NULL },
|
||||
{4, S_O(brightness), 9, "brightness", NULL },
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
|
@ -565,8 +565,8 @@ static const struct bit_entry hd_bits[] =
|
|||
#endif /* CONFIG_BACKLIGHT */
|
||||
#endif /*HAVE_RECORDING*/
|
||||
#ifdef HAVE_LCD_COLOR
|
||||
{LCD_DEPTH,S_O(fg_color),LCD_DEFAULT_FG,"foreground color","rgb"},
|
||||
{LCD_DEPTH,S_O(bg_color),LCD_DEFAULT_BG,"background color","rgb"},
|
||||
{LCD_DEPTH,S_O(fg_color),LCD_DEFAULT_FG,"foreground color","rgb"},
|
||||
{LCD_DEPTH,S_O(bg_color),LCD_DEFAULT_BG,"background color","rgb"},
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DIRCACHE
|
||||
|
@ -1148,7 +1148,7 @@ void settings_apply(void)
|
|||
dsp_set_crossfeed(global_settings.crossfeed);
|
||||
|
||||
dsp_set_eq(global_settings.eq_enabled);
|
||||
dsp_set_eq_precut(global_settings.eq_precut);
|
||||
dsp_set_eq_precut(global_settings.eq_precut);
|
||||
/* Update all EQ bands */
|
||||
for(i = 0; i < 5; i++) {
|
||||
dsp_set_eq_coefs(i);
|
||||
|
@ -1525,7 +1525,7 @@ static void save_cfg_table(const struct bit_entry* p_table, int count, int fd)
|
|||
#ifdef HAVE_LCD_COLOR
|
||||
else if (!strcasecmp(p_run->cfg_val, "rgb"))
|
||||
{
|
||||
fdprintf(fd, "%s: %02x%02x%02x\r\n", p_run->cfg_name,
|
||||
fdprintf(fd, "%s: %02x%02x%02x\r\n", p_run->cfg_name,
|
||||
(int)RGB_UNPACK_RED(value),
|
||||
(int)RGB_UNPACK_GREEN(value),
|
||||
(int)RGB_UNPACK_BLUE(value));
|
||||
|
@ -1693,7 +1693,7 @@ void settings_reset(void) {
|
|||
global_settings.lang_file[0] = '\0';
|
||||
#ifdef HAVE_LCD_COLOR
|
||||
global_settings.backdrop_file[0] = '\0';
|
||||
|
||||
|
||||
global_settings.fg_color = LCD_DEFAULT_FG;
|
||||
global_settings.bg_color = LCD_DEFAULT_BG;
|
||||
#endif
|
||||
|
|
|
@ -1375,13 +1375,14 @@ static bool crossfade(void)
|
|||
static const struct opt_items names[] = {
|
||||
{ STR(LANG_OFF) },
|
||||
{ STR(LANG_SHUFFLE) },
|
||||
{ STR(LANG_TRACKSKIP) },
|
||||
{ STR(LANG_ALWAYS) },
|
||||
};
|
||||
|
||||
bool ret;
|
||||
|
||||
ret=set_option( str(LANG_CROSSFADE_ENABLE),
|
||||
&global_settings.crossfade, INT, names, 3, NULL);
|
||||
&global_settings.crossfade, INT, names, 4, NULL);
|
||||
|
||||
audio_set_crossfade(global_settings.crossfade);
|
||||
|
||||
|
|
Loading…
Reference in a new issue