Crossfade: crossfaded manual skips now start fading immediately
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23622 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
29d2711115
commit
d1963e14de
1 changed files with 45 additions and 21 deletions
|
@ -92,6 +92,7 @@ static char *fadebuf IDATA_ATTR;
|
||||||
static bool crossfade_enabled;
|
static bool crossfade_enabled;
|
||||||
static bool crossfade_enable_request;
|
static bool crossfade_enable_request;
|
||||||
static bool crossfade_mixmode;
|
static bool crossfade_mixmode;
|
||||||
|
static bool crossfade_auto_skip;
|
||||||
static bool crossfade_active IDATA_ATTR;
|
static bool crossfade_active IDATA_ATTR;
|
||||||
static bool crossfade_track_change_started IDATA_ATTR;
|
static bool crossfade_track_change_started IDATA_ATTR;
|
||||||
|
|
||||||
|
@ -538,6 +539,8 @@ void pcmbuf_start_track_change(bool auto_skip)
|
||||||
/* Don't enable mix mode when skipping tracks manually. */
|
/* Don't enable mix mode when skipping tracks manually. */
|
||||||
crossfade_mixmode = auto_skip && global_settings.crossfade_fade_out_mixmode;
|
crossfade_mixmode = auto_skip && global_settings.crossfade_fade_out_mixmode;
|
||||||
|
|
||||||
|
crossfade_auto_skip = auto_skip;
|
||||||
|
|
||||||
crossfade_track_change_started = crossfade;
|
crossfade_track_change_started = crossfade;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -702,6 +705,27 @@ static size_t find_chunk(size_t length, struct chunkdesc **chunk)
|
||||||
return length / 2;
|
return length / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fade samples in the PCM buffer */
|
||||||
|
static void fade_block(int factor, size_t length, size_t *fade_sample,
|
||||||
|
struct chunkdesc **fade_chunk)
|
||||||
|
{
|
||||||
|
while (length > 0 && *fade_chunk != NULL)
|
||||||
|
{
|
||||||
|
/* Fade one sample */
|
||||||
|
int16_t *buf = (int16_t *)((*fade_chunk)->addr);
|
||||||
|
int32_t sample = buf[*fade_sample];
|
||||||
|
buf[(*fade_sample)++] = (sample * factor) >> 8;
|
||||||
|
length -= 2;
|
||||||
|
|
||||||
|
/* Move to the next chunk as needed */
|
||||||
|
if (*fade_sample * 2 >= (*fade_chunk)->size)
|
||||||
|
{
|
||||||
|
*fade_chunk = (*fade_chunk)->link;
|
||||||
|
*fade_sample = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Initializes crossfader, calculates all necessary parameters and performs
|
/* Initializes crossfader, calculates all necessary parameters and performs
|
||||||
* fade-out with the PCM buffer. */
|
* fade-out with the PCM buffer. */
|
||||||
static void crossfade_start(void)
|
static void crossfade_start(void)
|
||||||
|
@ -737,15 +761,25 @@ static void crossfade_start(void)
|
||||||
NATIVE_FREQUENCY * global_settings.crossfade_fade_out_duration * 4;
|
NATIVE_FREQUENCY * global_settings.crossfade_fade_out_duration * 4;
|
||||||
|
|
||||||
crossfade_need = fade_out_delay + fade_out_rem;
|
crossfade_need = fade_out_delay + fade_out_rem;
|
||||||
/* We want only to modify the last part of the buffer, so find
|
|
||||||
* the right chunk and sample to start the crossfade */
|
|
||||||
if (crossfade_rem > crossfade_need)
|
if (crossfade_rem > crossfade_need)
|
||||||
|
{
|
||||||
|
if (crossfade_auto_skip)
|
||||||
|
/* Automatic track changes only modify the last part of the buffer,
|
||||||
|
* so find the right chunk and sample to start the crossfade */
|
||||||
{
|
{
|
||||||
crossfade_sample = find_chunk(crossfade_rem - crossfade_need,
|
crossfade_sample = find_chunk(crossfade_rem - crossfade_need,
|
||||||
&crossfade_chunk);
|
&crossfade_chunk);
|
||||||
|
crossfade_rem = crossfade_need;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* Manual skips occur immediately, but give time to process */
|
||||||
|
{
|
||||||
|
crossfade_rem -= crossfade_chunk->size;
|
||||||
|
crossfade_chunk = crossfade_chunk->link;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Truncate fade out duration if necessary. */
|
/* Truncate fade out duration if necessary. */
|
||||||
else if (crossfade_rem < crossfade_need)
|
if (crossfade_rem < crossfade_need)
|
||||||
{
|
{
|
||||||
size_t crossfade_short = crossfade_need - crossfade_rem;
|
size_t crossfade_short = crossfade_need - crossfade_rem;
|
||||||
if (fade_out_rem >= crossfade_short)
|
if (fade_out_rem >= crossfade_short)
|
||||||
|
@ -756,6 +790,7 @@ static void crossfade_start(void)
|
||||||
fade_out_rem = 0;
|
fade_out_rem = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
crossfade_rem -= fade_out_delay + fade_out_rem;
|
||||||
|
|
||||||
/* Completely process the crossfade fade-out effect with current PCM buffer */
|
/* Completely process the crossfade fade-out effect with current PCM buffer */
|
||||||
if (!crossfade_mixmode)
|
if (!crossfade_mixmode)
|
||||||
|
@ -777,23 +812,11 @@ static void crossfade_start(void)
|
||||||
|
|
||||||
fade_out_rem -= block_rem;
|
fade_out_rem -= block_rem;
|
||||||
|
|
||||||
/* Fade this block */
|
fade_block(factor, block_rem, &fade_out_sample, &fade_out_chunk);
|
||||||
while (block_rem > 0 && fade_out_chunk != NULL)
|
}
|
||||||
{
|
|
||||||
/* Fade one sample */
|
|
||||||
int16_t *buf = (int16_t *)fade_out_chunk->addr;
|
|
||||||
int32_t sample = buf[fade_out_sample];
|
|
||||||
buf[fade_out_sample++] = (sample * factor) >> 8;
|
|
||||||
|
|
||||||
block_rem -= 2;
|
/* zero out the rest of the buffer */
|
||||||
/* Move to the next chunk as needed */
|
fade_block(0, crossfade_rem, &fade_out_sample, &fade_out_chunk);
|
||||||
if (fade_out_sample * 2 >= fade_out_chunk->size)
|
|
||||||
{
|
|
||||||
fade_out_chunk = fade_out_chunk->link;
|
|
||||||
fade_out_sample = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize fade-in counters */
|
/* Initialize fade-in counters */
|
||||||
|
@ -890,6 +913,7 @@ static void write_to_crossfade(char *buf, size_t length)
|
||||||
{
|
{
|
||||||
/* Mix the data */
|
/* Mix the data */
|
||||||
size_t mix_total = length;
|
size_t mix_total = length;
|
||||||
|
/* A factor of 256 means no fading */
|
||||||
length = crossfade_mix(256, buf, length);
|
length = crossfade_mix(256, buf, length);
|
||||||
buf += mix_total - length;
|
buf += mix_total - length;
|
||||||
if (!length)
|
if (!length)
|
||||||
|
|
Loading…
Reference in a new issue