Advanced 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);
Powered by Savane 3.14-8aba.
Corresponding source code