00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <glib.h>
00023
00024 #include "debug.h"
00025 #include "effect.h"
00026 #include "playback.h"
00027 #include "plugin.h"
00028 #include "plugins.h"
00029
00030 typedef struct {
00031 PluginHandle * plugin;
00032 EffectPlugin * header;
00033 gint channels_returned, rate_returned;
00034 gboolean remove_flag;
00035 } RunningEffect;
00036
00037 static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
00038 static GList * running_effects = NULL;
00039 static gint input_channels, input_rate;
00040
00041 typedef struct {
00042 gint * channels, * rate;
00043 } EffectStartState;
00044
00045 static gboolean effect_start_cb (PluginHandle * plugin, EffectStartState * state)
00046 {
00047 AUDDBG ("Starting %s at %d channels, %d Hz.\n", plugin_get_name (plugin),
00048 * state->channels, * state->rate);
00049 EffectPlugin * header = plugin_get_header (plugin);
00050 g_return_val_if_fail (header != NULL, TRUE);
00051 header->start (state->channels, state->rate);
00052
00053 RunningEffect * effect = g_malloc (sizeof (RunningEffect));
00054 effect->plugin = plugin;
00055 effect->header = header;
00056 effect->channels_returned = * state->channels;
00057 effect->rate_returned = * state->rate;
00058 effect->remove_flag = FALSE;
00059
00060 running_effects = g_list_prepend (running_effects, effect);
00061 return TRUE;
00062 }
00063
00064 void effect_start (gint * channels, gint * rate)
00065 {
00066 g_static_mutex_lock (& mutex);
00067
00068 AUDDBG ("Starting effects.\n");
00069 g_list_foreach (running_effects, (GFunc) g_free, NULL);
00070 g_list_free (running_effects);
00071 running_effects = NULL;
00072
00073 input_channels = * channels;
00074 input_rate = * rate;
00075
00076 EffectStartState state = {channels, rate};
00077 plugin_for_enabled (PLUGIN_TYPE_EFFECT, (PluginForEachFunc) effect_start_cb,
00078 & state);
00079 running_effects = g_list_reverse (running_effects);
00080
00081 g_static_mutex_unlock (& mutex);
00082 }
00083
00084 typedef struct {
00085 gfloat * * data;
00086 gint * samples;
00087 } EffectProcessState;
00088
00089 static void effect_process_cb (RunningEffect * effect, EffectProcessState *
00090 state)
00091 {
00092 if (effect->remove_flag)
00093 {
00094 effect->header->finish (state->data, state->samples);
00095
00096 running_effects = g_list_remove (running_effects, effect);
00097 g_free (effect);
00098 }
00099 else
00100 effect->header->process (state->data, state->samples);
00101 }
00102
00103 void effect_process (gfloat * * data, gint * samples)
00104 {
00105 g_static_mutex_lock (& mutex);
00106
00107 EffectProcessState state = {data, samples};
00108 g_list_foreach (running_effects, (GFunc) effect_process_cb, & state);
00109
00110 g_static_mutex_unlock (& mutex);
00111 }
00112
00113 void effect_flush (void)
00114 {
00115 g_static_mutex_lock (& mutex);
00116
00117 for (GList * node = running_effects; node != NULL; node = node->next)
00118 ((RunningEffect *) node->data)->header->flush ();
00119
00120 g_static_mutex_unlock (& mutex);
00121 }
00122
00123 void effect_finish (gfloat * * data, gint * samples)
00124 {
00125 g_static_mutex_lock (& mutex);
00126
00127 for (GList * node = running_effects; node != NULL; node = node->next)
00128 ((RunningEffect *) node->data)->header->finish (data, samples);
00129
00130 g_static_mutex_unlock (& mutex);
00131 }
00132
00133 gint effect_decoder_to_output_time (gint time)
00134 {
00135 g_static_mutex_lock (& mutex);
00136
00137 for (GList * node = running_effects; node != NULL; node = node->next)
00138 {
00139 if (PLUGIN_HAS_FUNC (((RunningEffect *) node->data)->header, decoder_to_output_time))
00140 time = ((RunningEffect *) node->data)->header->decoder_to_output_time (time);
00141 }
00142
00143 g_static_mutex_unlock (& mutex);
00144 return time;
00145 }
00146
00147 gint effect_output_to_decoder_time (gint time)
00148 {
00149 g_static_mutex_lock (& mutex);
00150
00151 for (GList * node = g_list_last (running_effects); node != NULL; node = node->prev)
00152 {
00153 if (PLUGIN_HAS_FUNC (((RunningEffect *) node->data)->header, output_to_decoder_time))
00154 time = ((RunningEffect *) node->data)->header->output_to_decoder_time (time);
00155 }
00156
00157 g_static_mutex_unlock (& mutex);
00158 return time;
00159 }
00160
00161 static gint effect_find_cb (RunningEffect * effect, PluginHandle * plugin)
00162 {
00163 return (effect->plugin == plugin) ? 0 : -1;
00164 }
00165
00166 static gint effect_compare (RunningEffect * a, RunningEffect * b)
00167 {
00168 return plugin_compare (a->plugin, b->plugin);
00169 }
00170
00171 static void effect_insert (PluginHandle * plugin, EffectPlugin * header)
00172 {
00173 if (g_list_find_custom (running_effects, plugin, (GCompareFunc)
00174 effect_find_cb) != NULL)
00175 return;
00176
00177 AUDDBG ("Adding %s without reset.\n", plugin_get_name (plugin));
00178 RunningEffect * effect = g_malloc (sizeof (RunningEffect));
00179 effect->plugin = plugin;
00180 effect->header = header;
00181 effect->remove_flag = FALSE;
00182
00183 running_effects = g_list_insert_sorted (running_effects, effect,
00184 (GCompareFunc) effect_compare);
00185 GList * node = g_list_find (running_effects, effect);
00186
00187 gint channels, rate;
00188 if (node->prev != NULL)
00189 {
00190 RunningEffect * prev = node->prev->data;
00191 AUDDBG ("Added %s after %s.\n", plugin_get_name (plugin),
00192 plugin_get_name (prev->plugin));
00193 channels = prev->channels_returned;
00194 rate = prev->rate_returned;
00195 }
00196 else
00197 {
00198 AUDDBG ("Added %s as first effect.\n", plugin_get_name (plugin));
00199 channels = input_channels;
00200 rate = input_rate;
00201 }
00202
00203 AUDDBG ("Starting %s at %d channels, %d Hz.\n", plugin_get_name (plugin),
00204 channels, rate);
00205 header->start (& channels, & rate);
00206 effect->channels_returned = channels;
00207 effect->rate_returned = rate;
00208 }
00209
00210 static void effect_remove (PluginHandle * plugin)
00211 {
00212 GList * node = g_list_find_custom (running_effects, plugin, (GCompareFunc)
00213 effect_find_cb);
00214 if (node == NULL)
00215 return;
00216
00217 AUDDBG ("Removing %s without reset.\n", plugin_get_name (plugin));
00218 ((RunningEffect *) node->data)->remove_flag = TRUE;
00219 }
00220
00221 static void effect_enable (PluginHandle * plugin, EffectPlugin * ep, gboolean
00222 enable)
00223 {
00224 if (ep->preserves_format)
00225 {
00226 g_static_mutex_lock (& mutex);
00227
00228 if (enable)
00229 effect_insert (plugin, ep);
00230 else
00231 effect_remove (plugin);
00232
00233 g_static_mutex_unlock (& mutex);
00234 }
00235 else
00236 {
00237 AUDDBG ("Reset to add/remove %s.\n", plugin_get_name (plugin));
00238 gint time = playback_get_time ();
00239 gboolean paused = playback_get_paused ();
00240 playback_stop ();
00241 playback_play (time, paused);
00242 }
00243 }
00244
00245 gboolean effect_plugin_start (PluginHandle * plugin)
00246 {
00247 if (playback_get_playing ())
00248 {
00249 EffectPlugin * ep = plugin_get_header (plugin);
00250 g_return_val_if_fail (ep != NULL, FALSE);
00251 effect_enable (plugin, ep, TRUE);
00252 }
00253
00254 return TRUE;
00255 }
00256
00257 void effect_plugin_stop (PluginHandle * plugin)
00258 {
00259 if (playback_get_playing ())
00260 {
00261 EffectPlugin * ep = plugin_get_header (plugin);
00262 g_return_if_fail (ep != NULL);
00263 effect_enable (plugin, ep, FALSE);
00264 }
00265 }