Author: agrundman
Date: Thu May 27 07:11:36 2010
New Revision: 8831

URL: http://svn.slimdevices.com/jive?rev=8831&view=rev
Log:
Bug 16256, ALSA fade-out implementation

Modified:
    7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_alsa_backend.c
    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_alsa_backend.c
URL: 
http://svn.slimdevices.com/jive/7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_alsa_backend.c?rev=8831&r1=8830&r2=8831&view=diff
==============================================================================
--- 
7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_alsa_backend.c 
(original)
+++ 
7.6/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_alsa_backend.c 
Thu May 27 07:11:36 2010
@@ -209,7 +209,6 @@
        }
 }
 
-
 static void decode_alsa_copyright(struct decode_alsa *state,
                                  bool_t copyright)
 {
@@ -363,6 +362,10 @@
 
        while (decode_frames) {
                size_t wrap_frames, frames_write, frames_cnt;
+               s32_t lgain, rgain;
+               
+               lgain = decode_audio->lgain;
+               rgain = decode_audio->rgain;
 
                wrap_frames = 
BYTES_TO_SAMPLES(fifo_bytes_until_rptr_wrap(&decode_audio->fifo));
 
@@ -372,6 +375,45 @@
                }
 
                frames_cnt = frames_write;
+               
+               /* Handle fading and delayed fading */
+               if (decode_audio->samples_to_fade) {
+                       if (decode_audio->samples_until_fade > frames_write) {
+                               decode_audio->samples_until_fade -= 
frames_write;
+                       }
+                       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("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 */
+                               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 += 
frames_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;
+                               }
+                       }
+               }
 
                if (PCM_SAMPLE_WIDTH() == 24) {
                        sample_t *decode_ptr;
@@ -380,8 +422,8 @@
                        output_ptr = (Sint32 *)(void *)output_buffer;
                        decode_ptr = (sample_t *)(void *)(decode_fifo_buf + 
decode_audio->fifo.rptr);
                        while (frames_cnt--) {
-                               *(output_ptr++) = 
fixed_mul(decode_audio->lgain, *(decode_ptr++)) >> 8;
-                               *(output_ptr++) = 
fixed_mul(decode_audio->rgain, *(decode_ptr++)) >> 8;
+                               *(output_ptr++) = fixed_mul(lgain, 
*(decode_ptr++)) >> 8;
+                               *(output_ptr++) = fixed_mul(rgain, 
*(decode_ptr++)) >> 8;
                        }
                }
                else {
@@ -391,8 +433,8 @@
                        output_ptr = (Sint16 *)(void *)output_buffer;
                        decode_ptr = (sample_t *)(void *)(decode_fifo_buf + 
decode_audio->fifo.rptr);
                        while (frames_cnt--) {
-                               *(output_ptr++) = 
fixed_mul(decode_audio->lgain, *(decode_ptr++)) >> 16;
-                               *(output_ptr++) = 
fixed_mul(decode_audio->rgain, *(decode_ptr++)) >> 16;
+                               *(output_ptr++) = fixed_mul(lgain, 
*(decode_ptr++)) >> 16;
+                               *(output_ptr++) = fixed_mul(rgain, 
*(decode_ptr++)) >> 16;
                        }
                }
 
@@ -405,6 +447,9 @@
 
        reached_start_point = decode_check_start_point();
        if (reached_start_point) {
+               decode_audio->samples_to_fade = 0;
+               decode_audio->transition_gain_step = 0;
+               
                if (decode_audio->track_sample_rate != state->pcm_sample_rate) {
                        decode_audio->set_sample_rate = 
decode_audio->track_sample_rate;
                }

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=8831&r1=8830&r2=8831&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 Thu 
May 27 07:11:36 2010
@@ -197,43 +197,6 @@
                *buffer = track_inversion[1] * volume_mul(*buffer, track_gain, 
track_clip_range);
                buffer++;
        }
-}
-
-
-/* Determine whether we have enough audio in the output buffer to do
- * a transition. Start at the requested transition interval and go
- * down till we find an interval that we have enough audio for.
- */
-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;
-
-       ASSERT_AUDIO_LOCKED();
-
-       if (sample_rate != decode_audio->track_sample_rate) {
-               LOG_DEBUG(log_audio_decode, "Can't CROSSFADE different sample 
rates %d != %d", sample_rate, decode_audio->track_sample_rate);
-               return 0;
-       }
-
-       bytes_used = fifo_bytes_used(&decode_audio->fifo);
-       *nbytes = SAMPLES_TO_BYTES(TRANSITION_MINIMUM_SECONDS * sample_rate);
-       if (bytes_used < *nbytes) {
-               return 0;
-       }
-
-       *nbytes = SAMPLES_TO_BYTES(transition_period * sample_rate);
-       transition_sample_step = sample_rate / TRANSITION_STEPS_PER_SECOND;
-       sample_step_bytes = SAMPLES_TO_BYTES(transition_sample_step);
-
-       interval = s32_to_fixed(transition_period);
-       interval_step = fixed_div(FIXED_ONE, TRANSITION_STEPS_PER_SECOND);
-
-       while (bytes_used < (*nbytes + sample_step_bytes)) {
-               *nbytes -= sample_step_bytes;
-               interval -= interval_step;
-       }
-
-       return interval;
 }
 
 /* How many bytes till we're done with the transition.

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=8831&r1=8830&r2=8831&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 
Thu May 27 07:11:36 2010
@@ -169,7 +169,6 @@
                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;
@@ -193,7 +192,6 @@
                                }
                                
                                /* 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);
                                

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=8831&r1=8830&r2=8831&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 Thu 
May 27 07:11:36 2010
@@ -195,9 +195,6 @@
 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))
@@ -219,5 +216,41 @@
 /* Decode message queue */
 extern struct mqueue decode_mqueue;
 
+/* This is here because it's needed in decode_alsa_backend.
+ * Determine whether we have enough audio in the output buffer to do
+ * 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) {
+       size_t bytes_used, sample_step_bytes;
+       fft_fixed interval, interval_step;
+       u32_t transition_sample_step;
+
+       ASSERT_AUDIO_LOCKED();
+
+       if (sample_rate != decode_audio->track_sample_rate) {
+               return 0;
+       }
+
+       bytes_used = fifo_bytes_used(&decode_audio->fifo);
+       *nbytes = SAMPLES_TO_BYTES(TRANSITION_MINIMUM_SECONDS * sample_rate);
+       if (bytes_used < *nbytes) {
+               return 0;
+       }
+
+       *nbytes = SAMPLES_TO_BYTES(transition_period * sample_rate);
+       transition_sample_step = sample_rate / TRANSITION_STEPS_PER_SECOND;
+       sample_step_bytes = SAMPLES_TO_BYTES(transition_sample_step);
+
+       interval = s32_to_fixed(transition_period);
+       interval_step = fixed_div(FIXED_ONE, TRANSITION_STEPS_PER_SECOND);
+
+       while (bytes_used < (*nbytes + sample_step_bytes)) {
+               *nbytes -= sample_step_bytes;
+               interval -= interval_step;
+       }
+
+       return interval;
+}
 
 #endif // AUDIO_DECODE_PRIV

_______________________________________________
Jive-checkins mailing list
[email protected]
http://lists.slimdevices.com/mailman/listinfo/jive-checkins

Reply via email to