Audacious $Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
00001 /* 00002 * plugin.h 00003 * Copyright 2005-2010 Audacious Development Team 00004 * 00005 * This file is part of Audacious. 00006 * 00007 * Audacious is free software: you can redistribute it and/or modify it under 00008 * the terms of the GNU General Public License as published by the Free Software 00009 * Foundation, version 2 or version 3 of the License. 00010 * 00011 * Audacious is distributed in the hope that it will be useful, but WITHOUT ANY 00012 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00013 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along with 00016 * Audacious. If not, see <http://www.gnu.org/licenses/>. 00017 * 00018 * The Audacious team does not consider modular code linking to Audacious or 00019 * using our public API to be a derived work. 00020 */ 00021 00022 #ifndef AUDACIOUS_PLUGIN_H 00023 #define AUDACIOUS_PLUGIN_H 00024 00025 #include <glib.h> 00026 #include <gmodule.h> 00027 00028 #include <audacious/api.h> 00029 #include <audacious/types.h> 00030 #include <libaudcore/audio.h> 00031 #include <libaudcore/tuple.h> 00032 #include <libaudcore/vfs.h> 00033 00034 /* "Magic" bytes identifying an Audacious plugin header. */ 00035 #define _AUD_PLUGIN_MAGIC 0x8EAC8DE2 00036 00037 /* API version. Plugins are marked with this number at compile time. 00038 * 00039 * _AUD_PLUGIN_VERSION is the current version; _AUD_PLUGIN_VERSION_MIN is 00040 * the oldest one we are backward compatible with. Plugins marked older than 00041 * _AUD_PLUGIN_VERSION_MIN or newer than _AUD_PLUGIN_VERSION are not loaded. 00042 * 00043 * Before releases that add new pointers to the end of the API tables, increment 00044 * _AUD_PLUGIN_VERSION but leave _AUD_PLUGIN_VERSION_MIN the same. 00045 * 00046 * Before releases that break backward compatibility (e.g. remove pointers from 00047 * the API tables), increment _AUD_PLUGIN_VERSION *and* set 00048 * _AUD_PLUGIN_VERSION_MIN to the same value. */ 00049 00050 #define _AUD_PLUGIN_VERSION_MIN 18 /* 2.5-alpha1 */ 00051 #define _AUD_PLUGIN_VERSION 20 /* 2.5-beta2 */ 00052 00057 typedef const struct { 00058 gint magic; /* checked against _AUD_PLUGIN_MAGIC */ 00059 gint version; /* checked against _AUD_PLUGIN_VERSION */ 00060 const gchar * name; 00061 void (* init) (void); 00062 void (* fini) (void); 00063 00064 /* These are arrays of pointers, ending with NULL: */ 00065 InputPlugin * const * ip_list; 00066 OutputPlugin * const * op_list; 00067 EffectPlugin * const * ep_list; 00068 GeneralPlugin * const * gp_list; 00069 VisPlugin * const * vp_list; 00070 TransportPlugin * const * tp_list; 00071 PlaylistPlugin * const * pp_list; 00072 00073 Iface * iface; 00074 } PluginHeader; 00075 00076 #define DECLARE_PLUGIN(name, ...) \ 00077 AudAPITable * _aud_api_table = NULL; \ 00078 G_MODULE_EXPORT PluginHeader * get_plugin_info (AudAPITable * table) { \ 00079 static PluginHeader h = {_AUD_PLUGIN_MAGIC, _AUD_PLUGIN_VERSION, #name, \ 00080 __VA_ARGS__}; \ 00081 _aud_api_table = table; \ 00082 return & h; \ 00083 } 00084 00085 #define SIMPLE_TRANSPORT_PLUGIN(name, t) DECLARE_PLUGIN(name, .tp_list = t) 00086 #define SIMPLE_PLAYLIST_PLUGIN(name, p) DECLARE_PLUGIN(name, .pp_list = p) 00087 #define SIMPLE_INPUT_PLUGIN(name, i) DECLARE_PLUGIN (name, .ip_list = i) 00088 #define SIMPLE_EFFECT_PLUGIN(name, e) DECLARE_PLUGIN (name, .ep_list = e) 00089 #define SIMPLE_OUTPUT_PLUGIN(name, o) DECLARE_PLUGIN (name, .op_list = o) 00090 #define SIMPLE_VIS_PLUGIN(name, v) DECLARE_PLUGIN(name, .vp_list = v) 00091 #define SIMPLE_GENERAL_PLUGIN(name, g) DECLARE_PLUGIN (name, .gp_list = g) 00092 #define SIMPLE_IFACE_PLUGIN(name, i) DECLARE_PLUGIN(name, .iface = i) 00093 00094 #define SIMPLE_VISUAL_PLUGIN SIMPLE_VIS_PLUGIN /* deprecated */ 00095 00096 #define PLUGIN_COMMON_FIELDS \ 00097 gchar *description; \ 00098 gboolean (* init) (void); \ 00099 void (*cleanup) (void); \ 00100 void (*about) (void); \ 00101 void (*configure) (void); \ 00102 PluginPreferences *settings; 00103 00104 struct _Plugin { 00105 PLUGIN_COMMON_FIELDS 00106 }; 00107 00108 struct _TransportPlugin { 00109 PLUGIN_COMMON_FIELDS 00110 const gchar * const * schemes; /* array ending with NULL */ 00111 const VFSConstructor * vtable; 00112 }; 00113 00114 struct _PlaylistPlugin { 00115 PLUGIN_COMMON_FIELDS 00116 const gchar * const * extensions; /* array ending with NULL */ 00117 gboolean (* load) (const gchar * filename, gint list, gint at); 00118 gboolean (* save) (const gchar * filename, gint list); 00119 }; 00120 00121 struct _OutputPlugin { 00122 PLUGIN_COMMON_FIELDS 00123 00124 /* During probing, plugins with higher priority (10 to 0) are tried first. */ 00125 gint probe_priority; 00126 00127 /* Returns current volume for left and right channels (0 to 100). */ 00128 void (* get_volume) (gint * l, gint * r); 00129 00130 /* Changes volume for left and right channels (0 to 100). */ 00131 void (* set_volume) (gint l, gint r); 00132 00133 /* Begins playback of a PCM stream. <format> is one of the FMT_* 00134 * enumeration values defined in libaudcore/audio.h. Returns nonzero on 00135 * success. */ 00136 gboolean (* open_audio) (gint format, gint rate, gint chans); 00137 00138 /* Ends playback. Any buffered audio data is discarded. */ 00139 void (* close_audio) (void); 00140 00141 /* Returns how many bytes of data may be passed to a following write_audio() 00142 * call. NULL if the plugin supports only blocking writes (not recommended). */ 00143 gint (* buffer_free) (void); 00144 00145 /* Waits until buffer_free() will return a size greater than zero. 00146 * output_time(), pause(), and flush() may be called meanwhile; if flush() 00147 * is called, period_wait() should return immediately. NULL if the plugin 00148 * supports only blocking writes (not recommended). */ 00149 void (* period_wait) (void); 00150 00151 /* Buffers <size> bytes of data, in the format given to open_audio(). */ 00152 void (* write_audio) (void * data, gint size); 00153 00154 /* Waits until all buffered data has been heard by the user. */ 00155 void (* drain) (void); 00156 00157 /* Returns time count (in milliseconds) of how much data has been written. */ 00158 gint (* written_time) (void); 00159 00160 /* Returns time count (in milliseconds) of how much data has been heard by 00161 * the user. */ 00162 gint (* output_time) (void); 00163 00164 /* Pauses the stream if <p> is nonzero; otherwise unpauses it. 00165 * write_audio() will not be called while the stream is paused. */ 00166 void (* pause) (gboolean p); 00167 00168 /* Discards any buffered audio data and sets the time counter (in 00169 * milliseconds) of data written. */ 00170 void (* flush) (gint time); 00171 00172 /* Sets the time counter (in milliseconds) of data written without 00173 * discarding any buffered audio data. If <time> is less than the amount of 00174 * buffered data, following calls to output_time() will return negative 00175 * values. */ 00176 void (* set_written_time) (gint time); 00177 }; 00178 00179 struct _EffectPlugin { 00180 PLUGIN_COMMON_FIELDS 00181 00182 /* All processing is done in floating point. If the effect plugin wants to 00183 * change the channel count or sample rate, it can change the parameters 00184 * passed to start(). They cannot be changed in the middle of a song. */ 00185 void (* start) (gint * channels, gint * rate); 00186 00187 /* process() has two options: modify the samples in place and leave the data 00188 * pointer unchanged or copy them into a buffer of its own. If it sets the 00189 * pointer to dynamically allocated memory, it is the plugin's job to free 00190 * that memory. process() may return different lengths of audio than it is 00191 * passed, even a zero length. */ 00192 void (* process) (gfloat * * data, gint * samples); 00193 00194 /* A seek is taking place; any buffers should be discarded. */ 00195 void (* flush) (void); 00196 00197 /* Exactly like process() except that any buffers should be drained (i.e. 00198 * the data processed and returned). finish() will be called a second time 00199 * at the end of the last song in the playlist. */ 00200 void (* finish) (gfloat * * data, gint * samples); 00201 00202 /* For effects that change the length of the song, these functions allow the 00203 * correct time to be displayed. */ 00204 gint (* decoder_to_output_time) (gint time); 00205 gint (* output_to_decoder_time) (gint time); 00206 00207 /* Effects with lowest order (0 to 9) are applied first. */ 00208 gint order; 00209 00210 /* If the effect does not change the number of channels or the sampling 00211 * rate, it can be enabled and disabled more smoothly. */ 00212 gboolean preserves_format; 00213 }; 00214 00215 struct OutputAPI 00216 { 00217 /* In a multi-thread plugin, only one of these functions may be called at 00218 * once (but see pause and abort_write for exceptions to this rule). */ 00219 00220 /* Prepare the output system for playback in the specified format. Returns 00221 * nonzero on success. If the call fails, no other output functions may be 00222 * called. */ 00223 gint (* open_audio) (gint format, gint rate, gint channels); 00224 00225 /* Informs the output system of replay gain values for the current song so 00226 * that volume levels can be adjusted accordingly, if the user so desires. 00227 * This may be called at any time during playback should the values change. */ 00228 void (* set_replaygain_info) (ReplayGainInfo * info); 00229 00230 /* Pass audio data to the output system for playback. The data must be in 00231 * the format passed to open_audio, and the length (in bytes) must be an 00232 * integral number of frames. This function blocks until all the data has 00233 * been written (though it may not yet be heard by the user); if the output 00234 * system is paused; this may be indefinitely. See abort_write for a way to 00235 * interrupt a blocked call. */ 00236 void (* write_audio) (void * data, gint length); 00237 00238 /* End playback. Any audio data currently buffered by the output system 00239 * will be discarded. After the call, no other output functions, except 00240 * open_audio, may be called. */ 00241 void (* close_audio) (void); 00242 00243 /* Pause or unpause playback. This function may be called during a call to 00244 * write_audio, in which write_audio will block until playback is unpaused 00245 * (but see abort_write to prevent the call from blocking). */ 00246 void (* pause) (gboolean pause); 00247 00248 /* Discard any audio data currently buffered by the output system, and set 00249 * the time counter to a new value. This function is intended to be used 00250 * for seeking. */ 00251 void (* flush) (gint time); 00252 00253 /* Returns the time counter. Note that this represents the amount of audio 00254 * data passed to the output system, not the amount actually heard by the 00255 * user. This function is useful for handling a changed audio format: 00256 * First, save the time counter using this function. Second, call 00257 * close_audio and then open_audio with the new format (note that the call 00258 * may fail). Finally, restore the time counter using flush. */ 00259 gint (* written_time) (void); 00260 00261 /* Returns TRUE if there is data remaining in the output buffer; FALSE if 00262 * all data written to the output system has been heard by the user. This 00263 * function should be polled (1/50 second is a reasonable delay between 00264 * calls) at the end of a song before calling close_audio. Once it returns 00265 * FALSE, close_audio can be called without cutting off any of the end of 00266 * the song. */ 00267 gboolean (* buffer_playing) (void); 00268 00269 /* Interrupt a call to write_audio so that it returns immediately. This 00270 * works even when the call is blocked by pause. Buffered audio data is 00271 * discarded as in flush. Until flush is called or the output system is 00272 * reset, further calls to write_audio will have no effect and return 00273 * immediately. This function is intended to be used in seeking or 00274 * stopping in a multi-thread plugin. To seek, the handler function (called 00275 * in the main thread) should first set a flag for the decoding thread and 00276 * then call abort_write. When the decoding thread notices the flag, it 00277 * should do the actual seek, call flush, and finally clear the flag. Once 00278 * the flag is cleared, the handler function may return. */ 00279 void (* abort_write) (void); 00280 }; 00281 00282 typedef const struct _InputPlayback InputPlayback; 00283 00284 struct _InputPlayback { 00285 /* Pointer to the output API functions. */ 00286 const struct OutputAPI * output; 00287 00288 /* Allows the plugin to associate data with a playback instance. */ 00289 void (* set_data) (InputPlayback * p, void * data); 00290 00291 /* Returns the pointer passed to set_data. */ 00292 void * (* get_data) (InputPlayback * p); 00293 00294 /* Signifies that the plugin has started playback is ready to accept mseek, 00295 * pause, and stop calls. */ 00296 void (* set_pb_ready) (InputPlayback * p); 00297 00298 /* Updates attributes of the stream. "bitrate" is in bits per second. 00299 * "samplerate" is in hertz. */ 00300 void (* set_params) (InputPlayback * p, gint bitrate, gint samplerate, 00301 gint channels); 00302 00308 void (*set_tuple) (InputPlayback * playback, Tuple * tuple); 00309 00310 /* If replay gain settings are stored in the tuple associated with the 00311 * current song, this function can be called (after opening audio) to apply 00312 * those settings. If the settings are changed in a call to set_tuple, this 00313 * function must be called again to apply the updated settings. */ 00314 void (* set_gain_from_playlist) (InputPlayback * playback); 00315 }; 00316 00317 struct _InputPlugin { 00318 PLUGIN_COMMON_FIELDS 00319 00320 /* Nonzero if the files handled by the plugin may contain more than one 00321 * song. When reading the tuple for such a file, the plugin should set the 00322 * FIELD_SUBSONG_NUM field to the number of songs in the file. For all 00323 * other files, the field should be left unset. 00324 * 00325 * Example: 00326 * 1. User adds a file named "somefile.xxx" to the playlist. Having 00327 * determined that this plugin can handle the file, Audacious opens the file 00328 * and calls probe_for_tuple(). probe_for_tuple() sees that there are 3 00329 * songs in the file and sets FIELD_SUBSONG_NUM to 3. 00330 * 2. For each song in the file, Audacious opens the file and calls 00331 * probe_for_tuple() -- this time, however, a question mark and song number 00332 * are appended to the file name passed: "somefile.sid?2" refers to the 00333 * second song in the file "somefile.sid". 00334 * 3. When one of the songs is played, Audacious opens the file and calls 00335 * play() with a file name modified in this way. 00336 */ 00337 gboolean have_subtune; 00338 00339 /* Pointer to an array (terminated with NULL) of file extensions associated 00340 * with file types the plugin can handle. */ 00341 const gchar * const * vfs_extensions; 00342 00343 /* How quickly the plugin should be tried in searching for a plugin to 00344 * handle a file which could not be identified from its extension. Plugins 00345 * with priority 0 are tried first, 10 last. */ 00346 gint priority; 00347 00348 /* Must return nonzero if the plugin can handle this file. If the file 00349 * could not be opened, "file" will be NULL. (This is normal in the case of 00350 * special URI schemes like cdda:// that do not represent actual files.) */ 00351 gboolean (* is_our_file_from_vfs) (const gchar * filename, VFSFile * file); 00352 00353 /* Must return a tuple containing metadata for this file, or NULL if no 00354 * metadata could be read. If the file could not be opened, "file" will be 00355 * NULL. Audacious takes over one reference to the tuple returned. */ 00356 Tuple * (* probe_for_tuple) (const gchar * filename, VFSFile * file); 00357 00358 /* Optional. Must write metadata from a tuple to this file. Must return 00359 * nonzero on success or zero on failure. "file" will never be NULL. */ 00360 /* Bug: This function does not support special URI schemes like cdda://, 00361 * since no file name is passed. */ 00362 gboolean (* update_song_tuple) (const Tuple * tuple, VFSFile * file); 00363 00364 /* Optional, and not recommended. Must show a window with information about 00365 * this file. If this function is provided, update_song_tuple should not be. */ 00366 /* Bug: Implementing this function duplicates user interface code and code 00367 * to open the file in each and every plugin. */ 00368 void (* file_info_box) (const gchar * filename); 00369 00370 /* Optional. Must try to read an "album art" image embedded in this file. 00371 * Must return nonzero on success or zero on failure. If the file could not 00372 * be opened, "file" will be NULL. On success, must fill "data" with a 00373 * pointer to a block of data allocated with g_malloc and "size" with the 00374 * size in bytes of that block. The data may be in any format supported by 00375 * GTK. Audacious will free the data when it is no longer needed. */ 00376 gboolean (* get_song_image) (const gchar * filename, VFSFile * file, 00377 void * * data, gint * size); 00378 00379 /* Must try to play this file. "playback" is a structure containing output- 00380 * related functions which the plugin may make use of. It also contains a 00381 * "data" pointer which the plugin may use to refer private data associated 00382 * with the playback state. This pointer can then be used from pause, 00383 * mseek, and stop. If the file could not be opened, "file" will be NULL. 00384 * "start_time" is the position in milliseconds at which to start from, or 00385 * -1 to start from the beginning of the file. "stop_time" is the position 00386 * in milliseconds at which to end playback, or -1 to play to the end of the 00387 * file. "paused" specifies whether playback should immediately be paused. 00388 * Must return nonzero if some of the file was successfully played or zero 00389 * on failure. */ 00390 gboolean (* play) (InputPlayback * playback, const gchar * filename, 00391 VFSFile * file, gint start_time, gint stop_time, gboolean pause); 00392 00393 /* Must pause or unpause a file currently being played. This function will 00394 * be called from a different thread than play, but it will not be called 00395 * before the plugin calls set_pb_ready or after stop is called. */ 00396 void (* pause) (InputPlayback * playback, gboolean paused); 00397 00398 /* Optional. Must seek to the given position in milliseconds within a file 00399 * currently being played. This function will be called from a different 00400 * thread than play, but it will not be called before the plugin calls 00401 * set_pb_ready or after stop is called. */ 00402 void (* mseek) (InputPlayback * playback, gint time); 00403 00404 /* Must signal a currently playing song to stop and cause play to return. 00405 * This function will be called from a different thread than play. It will 00406 * only be called once. It should not join the thread from which play is 00407 * called. */ 00408 void (* stop) (InputPlayback * playback); 00409 00410 /* Advanced, for plugins that do not use Audacious's output system. Use at 00411 * your own risk. */ 00412 gint (* get_time) (InputPlayback * playback); 00413 gint (* get_volume) (gint * l, gint * r); 00414 gint (* set_volume) (gint l, gint r); 00415 }; 00416 00417 struct _GeneralPlugin { 00418 PLUGIN_COMMON_FIELDS 00419 00420 /* GtkWidget * (* get_widget) (void); */ 00421 void * (* get_widget) (void); 00422 }; 00423 00424 struct _VisPlugin { 00425 PLUGIN_COMMON_FIELDS 00426 00427 gint num_pcm_chs_wanted; 00428 gint num_freq_chs_wanted; 00429 00430 void (*playback_start) (void); 00431 void (*playback_stop) (void); 00432 void (*render_pcm) (gint16 pcm_data[2][512]); 00433 00434 /* The range of intensities is 0 - 32767 (though theoretically it is 00435 * possible for the FFT to result in bigger values, making the final 00436 * intensity negative due to overflowing the 16bit signed integer.) 00437 * 00438 * If output is mono, only freq_data[0] is filled. 00439 */ 00440 void (*render_freq) (gint16 freq_data[2][256]); 00441 00442 /* GtkWidget * (* get_widget) (void); */ 00443 void * (* get_widget) (void); 00444 }; 00445 00446 #undef PLUGIN_COMMON_FIELDS 00447 00448 #endif /* AUDACIOUS_PLUGIN_H */