From f93eb992ecb945d0fe0a551bfa441c55fc778140 Mon Sep 17 00:00:00 2001
From: Peter Wang <tjaden@users.sourceforge.net>
Date: Sun, 17 Nov 2013 10:01:43 +1100
Subject: [PATCH] fix al_fill_silence

---
 addons/acodec/ogg.c                   | 10 ++--
 addons/audio/allegro5/allegro_audio.h |  3 +-
 addons/audio/alsa.c                   |  3 --
 addons/audio/audio.c                  | 95 ++++++++++++++---------------------
 addons/audio/dsound.cpp               | 10 ++--
 addons/audio/kcm_stream.c             |  9 ++--
 addons/audio/oss.c                    | 30 +++++++----
 docs/src/refman/audio.txt             |  8 +++
 8 files changed, 85 insertions(+), 83 deletions(-)

diff --git a/addons/acodec/ogg.c b/addons/acodec/ogg.c
index 915e1f6..57f13e1 100644
--- a/addons/acodec/ogg.c
+++ b/addons/acodec/ogg.c
@@ -419,10 +419,12 @@ static size_t ogg_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data,
 	   
       /* If nothing read then now to silence from here to the end. */
       if (read == 0) {
-         unsigned long silence_samples=(buf_size - pos)/
-            (al_get_audio_depth_size(stream->spl.spl_data.depth)*al_get_channel_count(stream->spl.spl_data.chan_conf));
-         al_fill_silence((char*)data + pos, silence_samples, stream->spl.spl_data.depth, stream->spl.spl_data.chan_conf);
-         /* return the number of usefull byes written */
+         unsigned long silence_samples = (buf_size - pos) /
+            (al_get_audio_depth_size(stream->spl.spl_data.depth) *
+             al_get_channel_count(stream->spl.spl_data.chan_conf));
+         al_fill_silence((char *)data + pos, silence_samples,
+            stream->spl.spl_data.depth, stream->spl.spl_data.chan_conf);
+         /* Return the number of useful bytes written. */
          return pos;
       }
    }
diff --git a/addons/audio/allegro5/allegro_audio.h b/addons/audio/allegro5/allegro_audio.h
index 51cd4a2..89711f4 100644
--- a/addons/audio/allegro5/allegro_audio.h
+++ b/addons/audio/allegro5/allegro_audio.h
@@ -339,7 +339,8 @@ ALLEGRO_KCM_AUDIO_FUNC(uint32_t, al_get_allegro_audio_version, (void));
 ALLEGRO_KCM_AUDIO_FUNC(size_t, al_get_channel_count, (ALLEGRO_CHANNEL_CONF conf));
 ALLEGRO_KCM_AUDIO_FUNC(size_t, al_get_audio_depth_size, (ALLEGRO_AUDIO_DEPTH conf));
 
-ALLEGRO_KCM_AUDIO_FUNC(void, al_fill_silence, (void * buf, unsigned int samples, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf));
+ALLEGRO_KCM_AUDIO_FUNC(void, al_fill_silence, (void *buf, unsigned int samples,
+      ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf));
 
 /* Simple audio layer */
 ALLEGRO_KCM_AUDIO_FUNC(bool, al_reserve_samples, (int reserve_samples));
diff --git a/addons/audio/alsa.c b/addons/audio/alsa.c
index 72e605c..62220c2 100644
--- a/addons/audio/alsa.c
+++ b/addons/audio/alsa.c
@@ -346,7 +346,6 @@ static void *alsa_update_mmap(ALLEGRO_THREAD *self, void *arg)
          memcpy(mmap, data, frames * alsa_voice->frame_size);
       }
       else {
-         int silence;
 silence:
          /* If stopped just fill with silence. */
          al_fill_silence(mmap, frames, voice->depth, voice->chan_conf);
@@ -450,11 +449,9 @@ static void *alsa_update_rw(ALLEGRO_THREAD *self, void *arg)
          buf = (void *)_al_voice_update(voice, &iframes);
          if (buf == NULL)
             goto silence;
-         
          frames = iframes;
       }
       else {
-         int silence;
 silence:
          /* If stopped just fill with silence. */
          al_fill_silence(data, frames, voice->depth, voice->chan_conf);
diff --git a/addons/audio/audio.c b/addons/audio/audio.c
index c8ee127..0121ca4 100644
--- a/addons/audio/audio.c
+++ b/addons/audio/audio.c
@@ -119,66 +119,47 @@ ALLEGRO_AUDIO_DEPTH _al_word_size_to_depth_conf(int word_size)
    }
 }
 
-void al_fill_silence(void * buf, unsigned int samples, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)
+/* Function: al_fill_silence
+ */
+void al_fill_silence(void *buf, unsigned int samples,
+   ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)
 {
-   size_t buffersize=al_get_audio_depth_size(depth)*al_get_channel_count(chan_conf)*samples;
-   
-   switch(depth)
-   {
-   case ALLEGRO_AUDIO_DEPTH_INT8:
-   case ALLEGRO_AUDIO_DEPTH_INT16:
-   case ALLEGRO_AUDIO_DEPTH_INT24:
-   case ALLEGRO_AUDIO_DEPTH_FLOAT32:
-      memset(buf, 0, buffersize);
-      break;
-   case ALLEGRO_AUDIO_DEPTH_UINT8:
-      memset(buf, 128, buffersize);
-      break;
-#ifdef ALLEGRO_BIG_ENDIAN
-   case ALLEGRO_AUDIO_DEPTH_UINT16:  
-      {
-         size_t i=0;
-         unsigned char * buffer=(unsigned char*)buf;
-         while(i<buffersize) {
-            buffer[i++]=128;
-            buffer[i++]=0;
-         }
-      }      
-      break;
-   case ALLEGRO_AUDIO_DEPTH_UINT24:
-      {
-         size_t i=0;
-         unsigned char * buffer=(unsigned char*)buf;
-         while(i<buffersize) {
-            buffer[i++]=128;
-            buffer[i++]=0;
-            buffer[i++]=0;
-         }
-      }      
-      break;
-#else
-   case ALLEGRO_AUDIO_DEPTH_UINT16:  
-      {
-         size_t i=0;
-         unsigned char * buffer=(unsigned char*)buf;
-         while(i<buffersize) {
-            buffer[i++]=0;
-            buffer[i++]=128;
+   size_t bytes = samples * al_get_audio_depth_size(depth) *
+      al_get_channel_count(chan_conf);
+
+   switch (depth) {
+      case ALLEGRO_AUDIO_DEPTH_INT8:
+      case ALLEGRO_AUDIO_DEPTH_INT16:
+      case ALLEGRO_AUDIO_DEPTH_INT24:
+      case ALLEGRO_AUDIO_DEPTH_FLOAT32:
+         memset(buf, 0, bytes);
+         break;
+      case ALLEGRO_AUDIO_DEPTH_UINT8:
+         memset(buf, 0x80, bytes);
+         break;
+      case ALLEGRO_AUDIO_DEPTH_UINT16:
+         {
+            uint16_t *buffer = buf;
+            size_t n = bytes / sizeof(uint16_t);
+            size_t i;
+
+            for (i = 0; i < n; i++)
+               buffer[i] = 0x8000;
          }
-      }      
-      break;
-   case ALLEGRO_AUDIO_DEPTH_UINT24:
-      {
-         size_t i=0;
-         unsigned char * buffer=(unsigned char*)buf;
-         while(i<buffersize) {
-            buffer[i++]=0;
-            buffer[i++]=0;
-            buffer[i++]=128;
+         break;
+      case ALLEGRO_AUDIO_DEPTH_UINT24:
+         {
+            uint32_t *buffer = buf;
+            size_t n = bytes / sizeof(uint32_t);
+            size_t i;
+
+            for (i = 0; i < n; i++)
+               buffer[i] = 0x800000;
          }
-      }      
-      break;
-#endif
+         break;
+      default:
+         ASSERT(false);
+         break;
    }
 }
 
diff --git a/addons/audio/dsound.cpp b/addons/audio/dsound.cpp
index 71042a9..4f51c35 100644
--- a/addons/audio/dsound.cpp
+++ b/addons/audio/dsound.cpp
@@ -153,12 +153,14 @@ static void* _dsound_update(ALLEGRO_THREAD *self, void *arg)
    LPVOID ptr1, ptr2;
    DWORD block1_bytes, block2_bytes;
    unsigned char *data;
+   unsigned char *silence;
    HRESULT hr;
-
    (void)self;
-   
-   unsigned char *silence = (unsigned char *)al_malloc(buffer_size);
-   al_fill_silence(silence, buffer_size_in_samples, voice->depth, voice->chan_conf);
+
+   /* Make a buffer full of silence. */
+   silence = (unsigned char *)al_malloc(buffer_size);
+   samples = buffer_size / bytes_per_sample / ex_data->channels;
+   al_fill_silence(silence, samples, voice->depth, voice->chan_conf);
 
    /* Fill buffer */
    hr = ex_data->ds8_buffer->Lock(0, buffer_size,
diff --git a/addons/audio/kcm_stream.c b/addons/audio/kcm_stream.c
index 205a5f6..8bfcda3 100644
--- a/addons/audio/kcm_stream.c
+++ b/addons/audio/kcm_stream.c
@@ -121,10 +121,10 @@ ALLEGRO_AUDIO_STREAM *al_create_audio_stream(size_t fragment_count,
    }
 
    for (i = 0; i < fragment_count; i++) {
-      char*buffer=(char *) stream->main_buffer
-         + i * (MAX_LAG*bytes_per_sample + bytes_per_frag_buf);
+      char *buffer = (char *)stream->main_buffer
+         + i * (MAX_LAG * bytes_per_sample + bytes_per_frag_buf);
       al_fill_silence(buffer, MAX_LAG, depth, chan_conf);
-      stream->used_bufs[i] = buffer + MAX_LAG*bytes_per_sample;
+      stream->used_bufs[i] = buffer + MAX_LAG * bytes_per_sample;
    }
 
    al_init_user_event_source(&stream->spl.es);
@@ -478,7 +478,8 @@ static void reset_stopped_stream(ALLEGRO_AUDIO_STREAM *stream)
     * user should be OK.
     */
    for (i = 0; i < stream->buf_count; ++i) {
-      al_fill_silence((char*)stream->main_buffer + i * fragment_buffer_size, MAX_LAG, stream->spl.spl_data.depth, stream->spl.spl_data.chan_conf);
+      al_fill_silence((char *)stream->main_buffer + i * fragment_buffer_size,
+         MAX_LAG, stream->spl.spl_data.depth, stream->spl.spl_data.chan_conf);
    }
 
    /* Get the current number of entries in the used_buf list. */
diff --git a/addons/audio/oss.c b/addons/audio/oss.c
index b355679..15c2bd0 100644
--- a/addons/audio/oss.c
+++ b/addons/audio/oss.c
@@ -406,6 +406,21 @@ static int oss_update_nonstream_voice(ALLEGRO_VOICE *voice, void **buf, int *byt
 }
 
 
+static void oss_update_silence(ALLEGRO_VOICE *voice, OSS_VOICE *oss_voice)
+{
+   char sil_buf[SIL_BUF_SIZE];
+   unsigned int silent_samples;
+
+   silent_samples = SIL_BUF_SIZE /
+      (al_get_audio_depth_size(voice->depth) *
+       al_get_channel_count(voice->chan_conf));
+   al_fill_silence(sil_buf, silent_samples, voice->depth, voice->chan_conf);
+   if (write(oss_voice->fd, sil_buf, SIL_BUF_SIZE) == -1) {
+      ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno));
+   }
+}
+
+
 static void* oss_update(ALLEGRO_THREAD *self, void *arg)
 {
    ALLEGRO_VOICE *voice = arg;
@@ -452,9 +467,10 @@ static void* oss_update(ALLEGRO_THREAD *self, void *arg)
       }
       else if (voice->is_streaming && !oss_voice->stopped) {
          const void *data = _al_voice_update(voice, &frames);
-         if (data == NULL)
-            goto silence;
-
+         if (data == NULL) {
+            oss_update_silence(voice, oss_voice);
+            continue;
+         }
          if (write(oss_voice->fd, data, frames * oss_voice->frame_size) == -1) {
             ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno));
             if (errno != EINTR)
@@ -462,14 +478,8 @@ static void* oss_update(ALLEGRO_THREAD *self, void *arg)
          }
       }
       else {
-silence:
          /* If stopped just fill with silence. */
-         char sil_buf[SIL_BUF_SIZE];
-         const unsigned int silent_samples=SIL_BUF_SIZE/(al_get_audio_depth_size(voice->depth)*al_get_channel_count(voice->chan_conf));
-         al_fill_silence(sil_buf, silent_samples, voice->depth, voice->chan_conf);
-         if (write(oss_voice->fd, sil_buf, SIL_BUF_SIZE) == -1) {
-            ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno));
-         }
+         oss_update_silence(voice, oss_voice);
       }
    }
 
diff --git a/docs/src/refman/audio.txt b/docs/src/refman/audio.txt
index 7bd4f53..96d4093 100644
--- a/docs/src/refman/audio.txt
+++ b/docs/src/refman/audio.txt
@@ -217,6 +217,14 @@ of the values listed under [ALLEGRO_AUDIO_DEPTH].
 Return the number of channels for the given channel configuration, which is one
 of the values listed under [ALLEGRO_CHANNEL_CONF].
 
+### API: al_fill_silence
+
+Fill a buffer with silence, for the given format and channel configuration.
+The buffer must have enough space for the given number of samples,
+and be properly aligned.
+
+Since: 5.1.8
+
 
 ## Voice functions
 
-- 
1.7.12.1

