diff --git a/addons/audio/allegro5/allegro_audio.h b/addons/audio/allegro5/allegro_audio.h
index 2fd9a82..03e707e 100644
--- a/addons/audio/allegro5/allegro_audio.h
+++ b/addons/audio/allegro5/allegro_audio.h
@@ -260,6 +260,7 @@ ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_PLAYMODE, al_get_audio_stream_playmode, (const AL
 
 ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_audio_stream_playing, (const ALLEGRO_AUDIO_STREAM *spl));
 ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_audio_stream_attached, (const ALLEGRO_AUDIO_STREAM *spl));
+ALLEGRO_KCM_AUDIO_FUNC(uint64_t, al_get_audio_stream_played_samples, (const ALLEGRO_AUDIO_STREAM *stream));
 
 ALLEGRO_KCM_AUDIO_FUNC(void *, al_get_audio_stream_fragment, (const ALLEGRO_AUDIO_STREAM *stream));
 
@@ -275,6 +276,7 @@ ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_fragment, (ALLEGRO_AUDIO_STREAM
 
 ALLEGRO_KCM_AUDIO_FUNC(bool, al_rewind_audio_stream, (ALLEGRO_AUDIO_STREAM *stream));
 ALLEGRO_KCM_AUDIO_FUNC(bool, al_seek_audio_stream_secs, (ALLEGRO_AUDIO_STREAM *stream, double time));
+ALLEGRO_KCM_AUDIO_FUNC(uint64_t, al_get_audio_stream_position, (const ALLEGRO_AUDIO_STREAM *stream));
 ALLEGRO_KCM_AUDIO_FUNC(double, al_get_audio_stream_position_secs, (ALLEGRO_AUDIO_STREAM *stream));
 ALLEGRO_KCM_AUDIO_FUNC(double, al_get_audio_stream_length_secs, (ALLEGRO_AUDIO_STREAM *stream));
 ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_loop_secs, (ALLEGRO_AUDIO_STREAM *stream, double start, double end));
diff --git a/addons/audio/allegro5/internal/aintern_audio.h b/addons/audio/allegro5/internal/aintern_audio.h
index cf6f899..af92d8a 100644
--- a/addons/audio/allegro5/internal/aintern_audio.h
+++ b/addons/audio/allegro5/internal/aintern_audio.h
@@ -246,6 +246,11 @@ struct ALLEGRO_AUDIO_STREAM {
                           * played.
                           */
 
+   uint64_t              consumed_fragments;
+                         /* Number of complete fragment buffers consumed since
+                          * the stream was started.
+                          */
+
    ALLEGRO_THREAD        *feed_thread;
    volatile bool         quit_feed_thread;
    unload_feeder_t       unload_feeder;
@@ -255,6 +260,12 @@ struct ALLEGRO_AUDIO_STREAM {
    get_feeder_length_t   get_feeder_length;
    set_feeder_loop_t     set_feeder_loop;
    stream_callback_t     feeder;
+
+   uint64_t              start_sample_pos;   //sample position from which the self-updating stream started the last time
+   uint64_t              loop_start;         //loop start in samples
+   uint64_t              loop_end;           //loop end in samples
+   uint64_t              loop_count;         //number of times the loop position has been reset to loop_start
+
                          /* If ALLEGRO_AUDIO_STREAM has been created by
                           * al_load_audio_stream(), the stream will be fed
                           * by a thread using the 'feeder' callback. Such
diff --git a/addons/audio/kcm_stream.c b/addons/audio/kcm_stream.c
index c2835fc..2b848d5 100644
--- a/addons/audio/kcm_stream.c
+++ b/addons/audio/kcm_stream.c
@@ -302,6 +302,66 @@ bool al_get_audio_stream_attached(const ALLEGRO_AUDIO_STREAM *stream)
    return (stream->spl.parent.u.ptr != NULL);
 }
 
+/* Function: al_get_audio_stream_played_samples
+*/
+uint64_t al_get_audio_stream_played_samples(const ALLEGRO_AUDIO_STREAM *stream)
+{
+   uint64_t result;
+   ASSERT(stream);
+
+   maybe_lock_mutex(stream->spl.mutex);
+   if (stream->spl.spl_data.buffer.ptr) {
+      result = stream->consumed_fragments * stream->spl.spl_data.len +
+         stream->spl.pos;
+   }
+   else {
+      result = 0;
+   }
+   maybe_unlock_mutex(stream->spl.mutex);
+
+   return result;
+}
+
+
+/* Function: al_get_audio_stream_position
+*/
+uint64_t al_get_audio_stream_position(const ALLEGRO_AUDIO_STREAM *stream)
+{
+   uint64_t result;
+   ASSERT(stream);
+   if (!stream->feeder)
+      return 0;
+
+   maybe_lock_mutex(stream->spl.mutex);
+   if (stream->spl.spl_data.buffer.ptr) {
+      result = stream->consumed_fragments * stream->spl.spl_data.len +
+         stream->spl.pos;
+   }
+   else {
+      result = 0;
+   }   
+  
+   result+=stream->start_sample_pos;
+
+   if (result > stream->loop_end  &&  stream->loop_count > 0) {
+      uint64_t samples_since_loop_start = result - stream->loop_end;
+      uint64_t loopSize = stream->loop_end - stream->loop_start;
+      uint64_t loopedSamples=stream->loop_count*loopSize;
+
+      if (samples_since_loop_start < loopedSamples) {
+         samples_since_loop_start %= loopSize;
+         result = stream->loop_start + samples_since_loop_start;
+      } else {
+         samples_since_loop_start -= loopedSamples;
+         result = stream->loop_end + samples_since_loop_start;
+      }
+   }
+
+   maybe_unlock_mutex(stream->spl.mutex);
+
+   return result;
+}
+
 
 /* Function: al_get_audio_stream_fragment
 */
@@ -502,6 +562,7 @@ static void reset_stopped_stream(ALLEGRO_AUDIO_STREAM *stream)
    stream->spl.spl_data.buffer.ptr = NULL;
    stream->spl.pos = stream->spl.spl_data.len;
    stream->spl.pos_bresenham_error = 0;
+   stream->consumed_fragments = 0;
 }
 
 
@@ -627,6 +688,8 @@ bool _al_kcm_refill_stream(ALLEGRO_AUDIO_STREAM *stream)
          (char *) new_buf - bytes_per_sample * MAX_LAG,
          (char *) old_buf + bytes_per_sample * (spl->pos-MAX_LAG),
          bytes_per_sample * MAX_LAG);
+
+      stream->consumed_fragments++;
    }
 
    stream->spl.pos = 0;
@@ -678,6 +741,7 @@ void *_al_kcm_feed_stream(ALLEGRO_THREAD *self, void *vstream)
          bytes_written = stream->feeder(stream, fragment, bytes);
          maybe_unlock_mutex(stream->spl.mutex);
 
+         maybe_lock_mutex(stream->spl.mutex);
         /* In case it reaches the end of the stream source, stream feeder will
          * fill the remaining space with silence. If we should loop, rewind the
          * stream and override the silence with the beginning.
@@ -686,13 +750,16 @@ void *_al_kcm_feed_stream(ALLEGRO_THREAD *self, void *vstream)
          while (bytes_written < bytes &&
                   stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR) {
             size_t bw;
-            al_rewind_audio_stream(stream);
-            maybe_lock_mutex(stream->spl.mutex);
+            //al_rewind_audio_stream(stream);
+            if (stream->rewind_feeder) {
+               stream->rewind_feeder(stream);
+               ++stream->loop_count;
+            }
             bw = stream->feeder(stream, fragment + bytes_written,
                bytes - bytes_written);
-            bytes_written += bw;
-            maybe_unlock_mutex(stream->spl.mutex);
+            bytes_written += bw;            
          }
+         maybe_unlock_mutex(stream->spl.mutex);
 
          if (!al_set_audio_stream_fragment(stream, fragment)) {
             ALLEGRO_ERROR("Error setting stream buffer.\n");
@@ -754,9 +821,17 @@ bool al_rewind_audio_stream(ALLEGRO_AUDIO_STREAM *stream)
    bool ret;
 
    if (stream->rewind_feeder) {
+      bool was_playing=al_get_audio_stream_playing(stream);
+
       maybe_lock_mutex(stream->spl.mutex);
       ret = stream->rewind_feeder(stream);
+      stream->start_sample_pos = stream->get_feeder_position(stream)*stream->spl.spl_data.frequency;
+      stream->loop_count = 0;
       maybe_unlock_mutex(stream->spl.mutex);
+
+      if (was_playing)
+         al_set_audio_stream_playing(stream, true);
+
       return ret;
    }
 
@@ -767,13 +842,21 @@ bool al_rewind_audio_stream(ALLEGRO_AUDIO_STREAM *stream)
 /* Function: al_seek_audio_stream_secs
  */
 bool al_seek_audio_stream_secs(ALLEGRO_AUDIO_STREAM *stream, double time)
-{
-   bool ret;
-
+{  
+   ASSERT(stream);
    if (stream->seek_feeder) {
+      bool ret;
+      bool was_playing=al_get_audio_stream_playing(stream);
+      al_set_audio_stream_playing(stream, false);
+
       maybe_lock_mutex(stream->spl.mutex);
       ret = stream->seek_feeder(stream, time);
+      stream->start_sample_pos = stream->get_feeder_position(stream)*stream->spl.spl_data.frequency;
+      stream->loop_count = 0;
       maybe_unlock_mutex(stream->spl.mutex);
+      if (was_playing)
+         al_set_audio_stream_playing(stream, true);
+
       return ret;
    }
 
@@ -785,16 +868,12 @@ bool al_seek_audio_stream_secs(ALLEGRO_AUDIO_STREAM *stream, double time)
  */
 double al_get_audio_stream_position_secs(ALLEGRO_AUDIO_STREAM *stream)
 {
-   double ret;
-
-   if (stream->get_feeder_position) {
-      maybe_lock_mutex(stream->spl.mutex);
-      ret = stream->get_feeder_position(stream);
-      maybe_unlock_mutex(stream->spl.mutex);
-      return ret;
-   }
-
-   return 0.0;
+   uint64_t sample_pos=al_get_audio_stream_position(stream);
+   ASSERT(stream);
+   if (stream->spl.spl_data.frequency)
+      return (double)sample_pos/stream->spl.spl_data.frequency;
+   else
+      return 0;
 }
 
 
@@ -821,18 +900,37 @@ bool al_set_audio_stream_loop_secs(ALLEGRO_AUDIO_STREAM *stream,
    double start, double end)
 {
    bool ret;
+   double length;
+   bool playing;
 
-   if (start >= end)
+   if (start >= end || !stream->set_feeder_loop)
       return false;
 
-   if (stream->set_feeder_loop) {
-      maybe_lock_mutex(stream->spl.mutex);
-      ret = stream->set_feeder_loop(stream, start, end);
-      maybe_unlock_mutex(stream->spl.mutex);
-      return ret;
-   }
+   playing=al_get_audio_stream_playing(stream);
+   al_set_audio_stream_playing(stream, false);
 
-   return false;
+   length=al_get_audio_stream_length_secs(stream);
+   if (start>length)
+      start=length;
+
+   if (end>length)
+      end=length;
+
+   maybe_lock_mutex(stream->spl.mutex);
+   ret = stream->set_feeder_loop(stream, start, end);
+
+   stream->loop_start=start*stream->spl.spl_data.frequency;
+   stream->loop_end=end*stream->spl.spl_data.frequency;
+
+   stream->start_sample_pos=0;
+   if (stream->get_feeder_position)
+      stream->start_sample_pos = stream->get_feeder_position(stream)*stream->spl.spl_data.frequency;
+
+   maybe_unlock_mutex(stream->spl.mutex);
+   if (playing)
+      al_set_audio_stream_playing(stream, true);
+
+   return ret;
 }
 
 
diff --git a/docs/src/refman/audio.txt b/docs/src/refman/audio.txt
index 7bd4f53..b65adcc 100644
--- a/docs/src/refman/audio.txt
+++ b/docs/src/refman/audio.txt
@@ -1011,6 +1011,13 @@ if anything.
 See also: [al_attach_audio_stream_to_mixer], [al_attach_audio_stream_to_voice],
 [al_get_audio_stream_attached].
 
+### API: al_get_audio_stream_played_samples
+
+Get the number of samples consumed by the parent since the audio stream was
+started.
+
+Since: 5.1.8
+
 ### API: al_get_audio_stream_fragment
 
 When using Allegro's audio streaming, you will use this function to continuously
@@ -1073,6 +1080,12 @@ Currently this can only be called on streams created with
 
 See also: [al_get_audio_stream_length_secs]
 
+
+### API: al_get_audio_stream_position
+Return the position of the stream in samples.
+Currently this can only be called on streams created with
+[al_load_audio_stream].
+
 ### API: al_get_audio_stream_length_secs
 
 Return the length of the stream in seconds, if known.
