newsAdvanced Gtk+ Sequencer - News

 
 

Further optimization in ags_audio_buffer_util.c

Item posted by Joël Krähemann <jkraehemann> on Wed 07 Aug 2019 12:22:48 AM UTC.

Addition is faster than multiplication. So ags_audio_buffer_util.c sees some further optimizations. Most is related to iterating of buffers with interleaved PCM audio data.

Further I have improved ags_audio_buffer_util_envelope_*() by moving calculation of current_volume to for loop header.

I intend to modify all functions in ags/audio/ags_audio_buffer_util.c

Here is a sample as diff snipped of the modified source:


@@ -614,6 +633,7 @@ ags_audio_buffer_util_envelope_s16(gint16 *buffer, guint channels,
                                   gdouble current_volume,
                                   gdouble ratio)
 {
+  guint current_channel;
   gdouble start_volume;
   guint limit;
   guint i;
@@ -626,23 +646,34 @@ ags_audio_buffer_util_envelope_s16(gint16 *buffer, guint channels,
   if(buffer_length > 8){
     limit = buffer_length - (buffer_length % 8);

-    for(; i < limit; i += 8){
-      v8double v_buffer = {(gdouble) buffer[0], (gdouble) buffer[1 * channels], (gdouble) buffer[2 * channels], (gdouble) buffer[3 * channels], (gdouble) buffer[4 * channels], (gdouble) buffer[5 * channels], (gdouble) buffer[6 * channels], (gdouble) buffer[7 * channels]};
+    for(; i < limit; i += 8, current_volume = start_volume + i * ratio){
+      v8double v_buffer;
+
+      current_channel = 0;
+
+      v_buffer = (v8double) {(gdouble) buffer[0],
+                            (gdouble) buffer[(current_channel += channels)],
+                            (gdouble) buffer[(current_channel += channels)],
+                            (gdouble) buffer[(current_channel += channels)],
+                            (gdouble) buffer[(current_channel += channels)],
+                            (gdouble) buffer[(current_channel += channels)],
+                            (gdouble) buffer[(current_channel += channels)],
+                            (gdouble) buffer[(current_channel += channels)]};

       v_buffer *= current_volume;
+
+      current_channel = 0;

       buffer[0] = (gint16) v_buffer[0];
-      buffer[1 * channels] = (gint16) v_buffer[1];
-      buffer[2 * channels] = (gint16) v_buffer[2];
-      buffer[3 * channels] = (gint16) v_buffer[3];
-      buffer[4 * channels] = (gint16) v_buffer[4];
-      buffer[5 * channels] = (gint16) v_buffer[5];
-      buffer[6 * channels] = (gint16) v_buffer[6];
-      buffer[7 * channels] = (gint16) v_buffer[7];
-
-      buffer += (8 * channels);
+      buffer[(current_channel += channels)] = (gint16) v_buffer[1];
+      buffer[(current_channel += channels)] = (gint16) v_buffer[2];
+      buffer[(current_channel += channels)] = (gint16) v_buffer[3];
+      buffer[(current_channel += channels)] = (gint16) v_buffer[4];
+      buffer[(current_channel += channels)] = (gint16) v_buffer[5];
+      buffer[(current_channel += channels)] = (gint16) v_buffer[6];
+      buffer[(current_channel += channels)] = (gint16) v_buffer[7];

-      current_volume = start_volume + i * ratio;
+      buffer += (current_channel + channels);
     }
   }
 #else
@@ -650,29 +681,27 @@ ags_audio_buffer_util_envelope_s16(gint16 *buffer, guint channels,
   if(buffer_length > 8){
     limit = buffer_length - (buffer_length % 8);

-    for(; i < limit; i += 8){
-      *buffer = (gint16) 0xffff & ((gint32) ((*buffer) * current_volume));
-      buffer[1 * channels] = (gint16) 0xffff & ((gint32) (buffer[1 * channels] * current_volume));
-      buffer[2 * channels] = (gint16) 0xffff & ((gint32) (buffer[2 * channels] * current_volume));
-      buffer[3 * channels] = (gint16) 0xffff & ((gint32) (buffer[3 * channels] * current_volume));
-      buffer[4 * channels] = (gint16) 0xffff & ((gint32) (buffer[4 * channels] * current_volume));
-      buffer[5 * channels] = (gint16) 0xffff & ((gint32) (buffer[5 * channels] * current_volume));
-      buffer[6 * channels] = (gint16) 0xffff & ((gint32) (buffer[6 * channels] * current_volume));
-      buffer[7 * channels] = (gint16) 0xffff & ((gint32) (buffer[7 * channels] * current_volume));
-
-      buffer += (8 * channels);
+    for(; i < limit; i += 8, current_volume = start_volume + i * ratio){
+      current_channel = 0;
+
+      buffer[0] = (gint16) 0xffff & ((gint32) (buffer[0] * current_volume));
+      buffer[current_channel] = (gint16) 0xffff & ((gint32) (buffer[(current_channel + channels)] * current_volume));
+      buffer[current_channel] = (gint16) 0xffff & ((gint32) (buffer[(current_channel + channels)] * current_volume));
+      buffer[current_channel] = (gint16) 0xffff & ((gint32) (buffer[(current_channel + channels)] * current_volume));
+      buffer[current_channel] = (gint16) 0xffff & ((gint32) (buffer[(current_channel + channels)] * current_volume));
+      buffer[current_channel] = (gint16) 0xffff & ((gint32) (buffer[(current_channel + channels)] * current_volume));
+      buffer[current_channel] = (gint16) 0xffff & ((gint32) (buffer[(current_channel + channels)] * current_volume));
+      buffer[current_channel] = (gint16) 0xffff & ((gint32) (buffer[(current_channel + channels)] * current_volume));

-      current_volume = start_volume + i * ratio;
+      buffer += (current_channel + channels);
     }
   }
 #endif

-  for(; i < buffer_length; i++){
-    *buffer = (gint16) 0xffff & ((gint32) ((*buffer) * current_volume));
+  for(; i < buffer_length; i++, current_volume = start_volume + i * ratio){
+    buffer[0] = (gint16) 0xffff & ((gint32) (buffer[0] * current_volume));

     buffer += channels;
-
-    current_volume = start_volume + i * ratio;
   }

   return(current_volume);


Back to the top

Powered by Savane 3.14-8aba.
Corresponding source code