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

Reply via email to