Author: agrundman
Date: Wed May 26 19:21:54 2010
New Revision: 8829
URL: http://svn.slimdevices.com/jive?rev=8829&view=rev
Log:
Bug 16256, first half of moving fade-out code from decode_output to the audio
modules, this contains only portaudio support
Modified:
7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_output.c
7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_portaudio.c
7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_priv.h
Modified: 7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_output.c
URL:
http://svn.slimdevices.com/jive/7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_output.c?rev=8829&r1=8828&r2=8829&view=diff
==============================================================================
--- 7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_output.c
(original)
+++ 7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_output.c Wed
May 26 19:21:54 2010
@@ -26,18 +26,6 @@
static fft_fixed transition_gain_step;
static u32_t transition_sample_step;
static u32_t transition_samples_in_step;
-
-
-#define TRANSITION_NONE 0x0
-#define TRANSITION_CROSSFADE 0x1
-#define TRANSITION_FADE_IN 0x2
-#define TRANSITION_FADE_OUT 0x4
-
-/* Transition steps per second should be a common factor
- * of all supported sample rates.
- */
-#define TRANSITION_STEPS_PER_SECOND 10
-#define TRANSITION_MINIMUM_SECONDS 1
/* Per-track gain (ReplayGain) */
@@ -201,6 +189,8 @@
return;
}
+ LOG_DEBUG(log_audio_output, "Applying track gain %d for %d samples\n",
track_gain, nsamples);
+
for (s = 0; s < nsamples; s++) {
*buffer = track_inversion[0] * volume_mul(*buffer, track_gain,
track_clip_range);
buffer++;
@@ -214,7 +204,7 @@
* a transition. Start at the requested transition interval and go
* down till we find an interval that we have enough audio for.
*/
-static fft_fixed determine_transition_interval(u32_t sample_rate, u32_t
transition_period, size_t *nbytes) {
+fft_fixed determine_transition_interval(u32_t sample_rate, u32_t
transition_period, size_t *nbytes) {
size_t bytes_used, sample_step_bytes;
fft_fixed interval, interval_step;
@@ -253,67 +243,6 @@
return (ptr >= decode_audio->fifo.wptr) ? (ptr -
decode_audio->fifo.wptr) : (decode_audio->fifo.wptr - ptr +
decode_audio->fifo.size);
}
-
-
-/* Called to fade out the already decoded track. Depending on how
- * much of the track is left, we apply gain in place.
- */
-static void decode_fade_out(void) {
- size_t nbytes, ptr;
- fft_fixed interval;
-
- ASSERT_AUDIO_LOCKED();
-
- interval =
determine_transition_interval(decode_audio->track_sample_rate,
decode_transition_period, &nbytes);
-
- LOG_DEBUG(log_audio_decode, "Starting FADEOUT over %d seconds,
requiring %d bytes", fixed_to_s32(interval), (unsigned int)nbytes);
-
- if (!interval) {
- return;
- }
-
- ptr = decode_audio->fifo.wptr;
- decode_audio->fifo.wptr = (nbytes <= decode_audio->fifo.wptr) ?
(decode_audio->fifo.wptr - nbytes) : (decode_audio->fifo.wptr - nbytes +
decode_audio->fifo.size);
-
- transition_gain_step = fixed_div(FIXED_ONE, fixed_mul(interval,
s32_to_fixed(TRANSITION_STEPS_PER_SECOND)));
- transition_gain = FIXED_ONE;
- transition_sample_step = decode_audio->track_sample_rate /
TRANSITION_STEPS_PER_SECOND;
- transition_samples_in_step = 0;
-
- while (decode_audio->fifo.wptr != ptr) {
- size_t s, bytes_read, samples_read, wrap, bytes_remaining;
- sample_t *sptr;
-
- bytes_read = SAMPLES_TO_BYTES(transition_sample_step -
transition_samples_in_step);
- wrap = fifo_bytes_until_wptr_wrap(&decode_audio->fifo);
- bytes_remaining = decode_transition_bytes_remaining(ptr);
-
- if (bytes_remaining < wrap) {
- wrap = bytes_remaining;
- }
-
- if (bytes_read > wrap) {
- bytes_read = wrap;
- }
-
- samples_read = BYTES_TO_SAMPLES(bytes_read);
-
- sptr = (sample_t *)(void *)(decode_fifo_buf +
decode_audio->fifo.wptr);
- for (s = 0; s < samples_read * 2; s++) {
- *sptr = fixed_mul(transition_gain, *sptr);
- sptr++;
- }
-
- fifo_wptr_incby(&decode_audio->fifo, bytes_read);
-
- transition_samples_in_step += samples_read;
- while (transition_gain && transition_samples_in_step >=
transition_sample_step) {
- transition_samples_in_step -= transition_sample_step;
- transition_gain -= transition_gain_step;
- }
- }
-}
-
/* Called to copy samples to the decode fifo when we are doing
* a transition - crossfade or fade in. This method applies gain
@@ -535,12 +464,10 @@
if (decode_transition_type & TRANSITION_FADE_OUT
&& decode_transition_period
&& decode_audio->state & DECODE_STATE_RUNNING) {
- /*
- XXX Bug 16256, fade-out can take too long and stall the audio,
- disabling this until a proper fix is implemented.
-
- decode_fade_out();
- */
+ // Signal audio module to begin fade-out
+ decode_audio->samples_until_fade =
decode_audio->track_sample_rate * (TRANSITION_MAXIMUM_SECONDS -
decode_transition_period);
+ decode_audio->samples_to_fade = decode_audio->track_sample_rate
* decode_transition_period;
+ decode_audio->transition_sample_rate =
decode_audio->track_sample_rate;
}
}
Modified:
7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_portaudio.c
URL:
http://svn.slimdevices.com/jive/7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_portaudio.c?rev=8829&r1=8828&r2=8829&view=diff
==============================================================================
--- 7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_portaudio.c
(original)
+++ 7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_portaudio.c
Wed May 26 19:21:54 2010
@@ -23,7 +23,6 @@
/* Stream sample rate */
static u32_t stream_sample_rate;
-
static void decode_portaudio_openstream(void);
@@ -152,6 +151,10 @@
while (bytes_used) {
size_t wrap, bytes_write, samples_write;
sample_t *output_ptr, *decode_ptr;
+ s32_t lgain, rgain;
+
+ lgain = decode_audio->lgain;
+ rgain = decode_audio->rgain;
wrap = fifo_bytes_until_rptr_wrap(&decode_audio->fifo);
@@ -161,12 +164,53 @@
}
samples_write = BYTES_TO_SAMPLES(bytes_write);
+
+ /* Handle fading and delayed fading */
+ if (decode_audio->samples_to_fade) {
+ if (decode_audio->samples_until_fade > samples_write) {
+ decode_audio->samples_until_fade -=
samples_write;
+ LOG_DEBUG(log_audio_output, "samples_until_fade
%d", decode_audio->samples_until_fade);
+ }
+ else {
+ decode_audio->samples_until_fade = 0;
+
+ /* initialize transition parameters */
+ if (!decode_audio->transition_gain_step) {
+ size_t nbytes;
+ fft_fixed interval;
+
+ interval =
determine_transition_interval(decode_audio->transition_sample_rate,
(u32_t)(decode_audio->samples_to_fade / decode_audio->transition_sample_rate),
&nbytes);
+ if (!interval)
+ interval = 1;
+
+ decode_audio->transition_gain_step =
fixed_div(FIXED_ONE, fixed_mul(interval,
s32_to_fixed(TRANSITION_STEPS_PER_SECOND)));
+ decode_audio->transition_gain =
FIXED_ONE;
+ decode_audio->transition_sample_step =
decode_audio->transition_sample_rate / TRANSITION_STEPS_PER_SECOND;
+
decode_audio->transition_samples_in_step = 0;
+
+ LOG_DEBUG(log_audio_output, "Starting
FADEOUT over %d seconds, transition_gain_step %d, transition_sample_step %d",
+ fixed_to_s32(interval),
decode_audio->transition_gain_step, decode_audio->transition_sample_step);
+ }
+
+ /* Apply transition gain to left/right gain
values */
+ LOG_DEBUG(log_audio_output, "transition_gain
%d", decode_audio->transition_gain);
+ lgain = fixed_mul(lgain,
decode_audio->transition_gain);
+ rgain = fixed_mul(rgain,
decode_audio->transition_gain);
+
+ /* Reduce transition gain when we've processed
enough samples */
+ decode_audio->transition_samples_in_step +=
samples_write;
+ while (decode_audio->transition_gain &&
decode_audio->transition_samples_in_step >=
decode_audio->transition_sample_step) {
+
decode_audio->transition_samples_in_step -=
decode_audio->transition_sample_step;
+ decode_audio->transition_gain -=
decode_audio->transition_gain_step;
+ }
+ }
+ }
output_ptr = (sample_t *)outputArray;
decode_ptr = (sample_t *)(decode_fifo_buf +
decode_audio->fifo.rptr);
while (samples_write--) {
- *(output_ptr++) = fixed_mul(decode_audio->lgain,
*(decode_ptr++));
- *(output_ptr++) = fixed_mul(decode_audio->rgain,
*(decode_ptr++));
+ *(output_ptr++) = fixed_mul(lgain, *(decode_ptr++));
+ *(output_ptr++) = fixed_mul(rgain, *(decode_ptr++));
}
fifo_rptr_incby(&decode_audio->fifo, bytes_write);
@@ -177,10 +221,15 @@
}
reached_start_point = decode_check_start_point();
- if (reached_start_point && decode_audio->track_sample_rate !=
stream_sample_rate) {
- LOG_DEBUG(log_audio_output, "Sample rate changed from %d to
%d\n", stream_sample_rate, decode_audio->track_sample_rate);
- decode_audio->set_sample_rate = decode_audio->track_sample_rate;
- ret = paComplete; // will trigger the finished callback to
change the samplerate
+ if (reached_start_point) {
+ decode_audio->samples_to_fade = 0;
+ decode_audio->transition_gain_step = 0;
+
+ if (decode_audio->track_sample_rate != stream_sample_rate) {
+ LOG_DEBUG(log_audio_output, "Sample rate changed from
%d to %d\n", stream_sample_rate, decode_audio->track_sample_rate);
+ decode_audio->set_sample_rate =
decode_audio->track_sample_rate;
+ ret = paComplete; // will trigger the finished callback
to change the samplerate
+ }
}
mixin_effects:
@@ -245,6 +294,8 @@
ASSERT_AUDIO_LOCKED();
decode_audio->set_sample_rate = 44100;
+ decode_audio->samples_to_fade = 0;
+ decode_audio->transition_gain_step = 0;
decode_portaudio_openstream();
}
Modified: 7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_priv.h
URL:
http://svn.slimdevices.com/jive/7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_priv.h?rev=8829&r1=8828&r2=8829&view=diff
==============================================================================
--- 7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_priv.h
(original)
+++ 7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_priv.h Wed
May 26 19:21:54 2010
@@ -1,7 +1,7 @@
/*
** Copyright 2007-2008 Logitech. All Rights Reserved.
**
-** This file is licensed under BSD. Please see the LICENSE file for details.
+** This file is licensed under BSD. Please see the LICENSE file for details.
*/
@@ -16,6 +16,17 @@
extern LOG_CATEGORY *log_audio_codec;
extern LOG_CATEGORY *log_audio_output;
+#define TRANSITION_NONE 0x0
+#define TRANSITION_CROSSFADE 0x1
+#define TRANSITION_FADE_IN 0x2
+#define TRANSITION_FADE_OUT 0x4
+
+/* Transition steps per second should be a common factor
+ * of all supported sample rates.
+ */
+#define TRANSITION_STEPS_PER_SECOND 10
+#define TRANSITION_MINIMUM_SECONDS 1
+#define TRANSITION_MAXIMUM_SECONDS 10
/* Audio sample, 32-bits. */
typedef s32_t sample_t;
@@ -142,6 +153,15 @@
/* device info */
u32_t max_rate;
+
+ /* fading state */
+ u32_t samples_until_fade;
+ u32_t samples_to_fade;
+ u32_t transition_sample_rate;
+ fft_fixed transition_gain;
+ fft_fixed transition_gain_step;
+ u32_t transition_sample_step;
+ u32_t transition_samples_in_step;
};
extern struct decode_audio *decode_audio;
@@ -168,14 +188,16 @@
/* Sample playback api (sound effects) */
extern int decode_sample_init(lua_State *L);
extern void decode_sample_fill_buffer(void);
-
-
-/* visualizers */
-extern int decode_vumeter(lua_State *L);
-extern int decode_spectrum(lua_State *L);
-extern int decode_spectrum_init(lua_State *L);
-
-
+
+
+/* visualizers */
+extern int decode_vumeter(lua_State *L);
+extern int decode_spectrum(lua_State *L);
+extern int decode_spectrum_init(lua_State *L);
+
+/* Transitions */
+extern fft_fixed determine_transition_interval(u32_t sample_rate, u32_t
transition_period, size_t *nbytes);
+
/* Internal state */
#define SAMPLES_TO_BYTES(n) (2 * (n) * sizeof(sample_t))
_______________________________________________
Jive-checkins mailing list
[email protected]
http://lists.slimdevices.com/mailman/listinfo/jive-checkins