Author: titmuss
Date: Wed Oct 29 06:05:04 2008
New Revision: 3225

URL: http://svn.slimdevices.com?rev=3225&root=Jive&view=rev
Log:
Bug: N/A
Description:
Added volume control for alsa playback.
Use real-time priority for audio thread for alsa playback (where possible).
Tweaked buffer and period sizes for lower latency (for sound effects).


Modified:
    7.3/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_alsa.c
    7.3/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.h

Modified: 7.3/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_alsa.c
URL: 
http://svn.slimdevices.com/7.3/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_alsa.c?rev=3225&root=Jive&r1=3224&r2=3225&view=diff
==============================================================================
--- 7.3/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_alsa.c 
(original)
+++ 7.3/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_alsa.c Wed 
Oct 29 06:05:04 2008
@@ -9,6 +9,7 @@
 #include "common.h"
 
 #include "audio/fifo.h"
+#include "audio/fixed_math.h"
 #include "audio/mqueue.h"
 #include "audio/decode/decode.h"
 #include "audio/decode/decode_priv.h"
@@ -16,6 +17,7 @@
 
 #ifdef HAVE_LIBASOUND
 
+#include <pthread.h>
 #include <alsa/asoundlib.h>
 
 /* Stream sample rate */
@@ -25,15 +27,19 @@
 
 /* alsa */
 static char *device = "default";
+//static char *device = "plughw:0,0";
 
 static snd_output_t *output;
 static snd_pcm_t *handle;
 static snd_pcm_hw_params_t *hwparams;
 
 static snd_pcm_sframes_t period_size;
-
-static SDL_Thread *audio_thread;
-
+static fft_fixed lgain, rgain;
+
+static pthread_t audio_thread;
+
+
+static void decode_alsa_gain(s32_t lgain, s32_t rgain);
 
 
 /*
@@ -123,7 +129,8 @@
        }
 
        while (bytes_used) {
-               size_t wrap, bytes_write;
+               size_t wrap, bytes_write, samples_write;
+               sample_t *output_ptr, *decode_ptr;
 
                wrap = fifo_bytes_until_rptr_wrap(&decode_fifo);
 
@@ -132,7 +139,15 @@
                        bytes_write = wrap;
                }
 
-               memcpy(outputArray, decode_fifo_buf + decode_fifo.rptr, 
bytes_write);
+               samples_write = BYTES_TO_SAMPLES(bytes_write);
+
+               output_ptr = (sample_t *)outputArray;
+               decode_ptr = (sample_t *)(decode_fifo_buf + decode_fifo.rptr);
+               while (samples_write--) {
+                       *(output_ptr++) = fixed_mul(lgain, *(decode_ptr++));
+                       *(output_ptr++) = fixed_mul(rgain, *(decode_ptr++));
+               }
+
                fifo_rptr_incby(&decode_fifo, bytes_write);
                decode_elapsed_samples += BYTES_TO_SAMPLES(bytes_write);
 
@@ -152,17 +167,17 @@
 static int pcm_open() {
        int err, dir;
        snd_pcm_uframes_t size;
-       unsigned int buffer_time = 250000; // FIXME low latency
-       unsigned int period_time = buffer_time / 4;
+#define BUFFER_SIZE (8291 / 4)
+#define PERIOD_SIZE (BUFFER_SIZE / 8)
 
        /* Close existing pcm (if any) */
        if (handle) {
                if ((err = snd_pcm_drain(handle)) < 0) {
-                       DEBUG_ERROR("Drain error: %s", snd_strerror(err));
+                       DEBUG_ERROR("snd_pcm_drain error: %s", 
snd_strerror(err));
                }
 
                if ((err = snd_pcm_close(handle)) < 0) {
-                       DEBUG_ERROR("Drain error: %s", snd_strerror(err));
+                       DEBUG_ERROR("snd_pcm_close error: %s", 
snd_strerror(err));
                }
 
                handle = NULL;
@@ -216,13 +231,15 @@
        }
 
        /* set buffer and period times */
-       if ((err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, 
&buffer_time, &dir)) < 0) {
-               DEBUG_ERROR("Unable to set  buffer time %s", snd_strerror(err));
-               return err;
-       }
-
-       if ((err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, 
&period_time, &dir)) < 0) {
-               DEBUG_ERROR("Unable to set period time %s", snd_strerror(err));
+       size = BUFFER_SIZE;
+       if ((err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, 
&size)) < 0) {
+               DEBUG_ERROR("Unable to set  buffer size %s", snd_strerror(err));
+               return err;
+       }
+
+       size = PERIOD_SIZE;
+       if ((err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, 
&size, &dir)) < 0) {
+               DEBUG_ERROR("Unable to set period size %s", snd_strerror(err));
                return err;
        }
 
@@ -266,7 +283,7 @@
 }
 
 
-static int audio_thread_execute(void *unused) {
+static void *audio_thread_execute(void *unused) {
        snd_pcm_state_t state;
        const snd_pcm_channel_area_t *areas;
        snd_pcm_uframes_t offset;
@@ -285,7 +302,7 @@
                if (new_sample_rate) {
                        if ((err = pcm_open()) < 0) {
                                DEBUG_ERROR("Open failed: %s", 
snd_strerror(err));
-                               return -1;
+                               return (void *)-1;
                        }
                        first = 1;
                }
@@ -412,6 +429,8 @@
 
 static int decode_alsa_init(void) {
        int err;
+       pthread_attr_t thread_attr;
+       struct sched_param thread_param;
 
        if ((err = snd_output_stdio_attach(&output, stdout, 0)) < 0) {
                DEBUG_ERROR("Output failed: %s", snd_strerror(err));
@@ -425,8 +444,34 @@
        }
 
        /* start audio thread */
-       // XXXX fixme thread priority
-       audio_thread = SDL_CreateThread(audio_thread_execute, NULL);
+       if ((err = pthread_attr_init(&thread_attr)) != 0) {
+               DEBUG_ERROR("pthread_attr_init: %s", strerror(err));
+               return 0;
+       }
+
+       if ((err = pthread_attr_setdetachstate(&thread_attr, 
PTHREAD_CREATE_DETACHED)) != 0) {
+               DEBUG_ERROR("pthread_attr_setdetachstate: %s", strerror(err));
+               return 0;
+       }
+
+       if ((err = pthread_create(&audio_thread, &thread_attr, 
audio_thread_execute, NULL)) != 0) {
+               DEBUG_ERROR("pthread_create: %s", strerror(err));
+               return 0;
+       }
+
+       /* set realtime scheduler policy, with a high priority */
+       thread_param.sched_priority = sched_get_priority_max(SCHED_FIFO);
+
+       err = pthread_setschedparam(audio_thread, SCHED_FIFO, &thread_param);
+       if (err) {
+               if (err == EPERM) {
+                       DEBUG_ERROR("Can't set audio thread priority\n");
+               }
+               else {
+                       DEBUG_ERROR("pthread_create: %s", strerror(err));
+                       return 0;
+               }
+       }
 
        return 1;
 }
@@ -447,9 +492,10 @@
 }
 
 
-static void decode_alsa_gain(s32_t lgain, s32_t rgain)
+static void decode_alsa_gain(s32_t left_gain, s32_t right_gain)
 {
-       printf("fixme gain %d,%d\n", lgain, rgain);
+       lgain = left_gain;
+       rgain = right_gain;
 }
 
 

Modified: 7.3/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.h
URL: 
http://svn.slimdevices.com/7.3/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.h?rev=3225&root=Jive&r1=3224&r2=3225&view=diff
==============================================================================
--- 7.3/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.h (original)
+++ 7.3/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.h Wed Oct 29 
06:05:04 2008
@@ -37,28 +37,28 @@
 #define FIXED_ONE 0x10000
 #define FIXED_FRAC_BITS 16
 
-inline s32_t fixed_to_s32(fft_fixed x) {
+static inline s32_t fixed_to_s32(fft_fixed x) {
        return x >> 16;
 }
 
-inline fft_fixed s32_to_fixed(s32_t x) {
+static inline fft_fixed s32_to_fixed(s32_t x) {
        return x << 16;
 }
 
-inline double fixed_to_double(fft_fixed x) {
+static inline double fixed_to_double(fft_fixed x) {
        return ((double)((x) / (double) (1L << 16)));
 }
 
-inline fft_fixed double_to_fixed(double x) {
+static inline fft_fixed double_to_fixed(double x) {
        return ((fft_fixed) ((x) * (double) (1L << 16) + 0.5));
 }
 
-inline fft_fixed fixed_mul(fft_fixed x, fft_fixed y) {
+static inline fft_fixed fixed_mul(fft_fixed x, fft_fixed y) {
        s64_t z = (s64_t)x * (s64_t)y;
        return (s32_t) (z >> 16);
 }
 
-inline fft_fixed fixed_div(fft_fixed x, fft_fixed y) {
+static inline fft_fixed fixed_div(fft_fixed x, fft_fixed y) {
        s64_t z = ((s64_t)x << 32);
        return (s32_t) ((z / y) >> 16);
 }

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

Reply via email to