00001 /* Audacious 00002 * Copyright (C) 2005-2010 Audacious team. 00003 * 00004 * BMP - Cross-platform multimedia player 00005 * Copyright (C) 2003-2004 BMP development team. 00006 * 00007 * Based on XMMS: 00008 * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies 00009 * 00010 * Redistribution and use in source and binary forms, with or without 00011 * modification, are permitted provided that the following conditions are 00012 * met: 00013 * 00014 * 1. Redistributions of source code must retain the above copyright 00015 * notice, this list of conditions and the following disclaimer. 00016 * 00017 * 2. Redistributions in binary form must reproduce the above copyright 00018 * notice, this list of conditions and the following disclaimer in 00019 * the documentation and/or other materials provided with the 00020 * distribution. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY 00023 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00024 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00025 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 00026 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00027 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00028 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00031 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00032 * SUCH DAMAGE. 00033 */ 00039 #ifndef AUDACIOUS_PLUGIN_H 00040 #define AUDACIOUS_PLUGIN_H 00041 00042 #include <glib.h> 00043 #include <gmodule.h> 00044 00045 #include <audacious/api.h> 00046 #include <audacious/types.h> 00047 #include <libaudcore/audio.h> 00048 #include <libaudcore/tuple.h> 00049 #include <libaudcore/vfs.h> 00050 00052 00053 #define __AUDACIOUS_PLUGIN_API__ 17 00055 00056 typedef enum { 00057 PLUGIN_MESSAGE_ERROR = 0, 00058 PLUGIN_MESSAGE_OK = 1, 00059 PLUGIN_MESSAGE_DEFERRED = 2 00060 } PluginMessageResponse; 00061 00062 typedef struct _InputPlayback InputPlayback; 00063 00065 typedef struct { 00066 gfloat track_gain; 00067 gfloat track_peak; 00068 gfloat album_gain; 00069 gfloat album_peak; 00070 } ReplayGainInfo; 00071 00076 typedef struct { 00077 gint magic; 00078 gint api_version; 00080 gchar *name; 00081 void (* init) (void); 00082 void (* fini) (void); 00083 Plugin *priv_assoc; 00084 InputPlugin **ip_list; 00085 OutputPlugin **op_list; 00086 EffectPlugin **ep_list; 00087 GeneralPlugin **gp_list; 00088 VisPlugin **vp_list; 00089 Interface *interface; 00090 } PluginHeader; 00091 00092 #define PLUGIN_MAGIC 0x8EAC8DE2 00093 00094 #define DECLARE_PLUGIN(name, init, fini, ...) \ 00095 G_BEGIN_DECLS \ 00096 static PluginHeader _pluginInfo = { PLUGIN_MAGIC, __AUDACIOUS_PLUGIN_API__, \ 00097 (gchar *)#name, init, fini, NULL, __VA_ARGS__ }; \ 00098 AudAPITable * _aud_api_table = NULL; \ 00099 G_MODULE_EXPORT PluginHeader * get_plugin_info (AudAPITable * table) { \ 00100 _aud_api_table = table; \ 00101 return &_pluginInfo; \ 00102 } \ 00103 G_END_DECLS 00104 00105 #define SIMPLE_INPUT_PLUGIN(name, ip_list) \ 00106 DECLARE_PLUGIN(name, NULL, NULL, ip_list) 00107 00108 #define SIMPLE_OUTPUT_PLUGIN(name, op_list) \ 00109 DECLARE_PLUGIN(name, NULL, NULL, NULL, op_list) 00110 00111 #define SIMPLE_EFFECT_PLUGIN(name, ep_list) \ 00112 DECLARE_PLUGIN(name, NULL, NULL, NULL, NULL, ep_list) 00113 00114 #define SIMPLE_GENERAL_PLUGIN(name, gp_list) \ 00115 DECLARE_PLUGIN(name, NULL, NULL, NULL, NULL, NULL, gp_list) 00116 00117 #define SIMPLE_VISUAL_PLUGIN(name, vp_list) \ 00118 DECLARE_PLUGIN(name, NULL, NULL, NULL, NULL, NULL, NULL, vp_list) 00119 00120 #define SIMPLE_INTERFACE_PLUGIN(name, interface) \ 00121 DECLARE_PLUGIN(name, NULL, NULL, NULL, NULL, NULL, NULL, NULL, interface) 00122 00123 00124 #define PLUGIN_COMMON_FIELDS \ 00125 gpointer handle; \ 00126 gchar *filename; \ 00127 gchar *description; \ 00128 void (*init) (void); \ 00129 void (*cleanup) (void); \ 00130 void (*about) (void); \ 00131 void (*configure) (void); \ 00132 PluginPreferences *settings; \ 00133 PluginMessageResponse (*sendmsg)(gint msgtype, gpointer msgdata); 00134 00135 /* Sadly, this is the most we can generalize out of the disparate 00136 plugin structs usable with typecasts - descender */ 00137 struct _Plugin { 00138 PLUGIN_COMMON_FIELDS 00139 }; 00140 00141 typedef enum { 00142 OUTPUT_PLUGIN_INIT_FAIL, 00143 OUTPUT_PLUGIN_INIT_NO_DEVICES, 00144 OUTPUT_PLUGIN_INIT_FOUND_DEVICES, 00145 } OutputPluginInitStatus; 00146 00147 struct _OutputPlugin { 00148 gpointer handle; 00149 gchar *filename; 00150 gchar *description; 00151 00152 OutputPluginInitStatus (*init) (void); 00153 void (*cleanup) (void); 00154 void (*about) (void); 00155 void (*configure) (void); 00156 00157 gint probe_priority; 00158 00159 void (*get_volume) (gint * l, gint * r); 00160 void (*set_volume) (gint l, gint r); 00161 00162 gint (*open_audio) (gint fmt, gint rate, gint nch); 00163 void (*write_audio) (gpointer ptr, gint length); 00164 void (*close_audio) (void); 00165 00166 void (* set_written_time) (gint time); 00167 void (*flush) (gint time); 00168 void (*pause) (gshort paused); 00169 gint (* buffer_free) (void); 00170 gint (*buffer_playing) (void); /* obsolete */ 00171 gint (*output_time) (void); 00172 gint (*written_time) (void); 00173 00174 void (*tell_audio) (gint * fmt, gint * rate, gint * nch); /* obsolete */ 00175 void (* drain) (void); 00176 void (* period_wait) (void); 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 struct _InputPlayback { 00283 gchar *filename; 00284 void *data; 00285 00286 gint playing; 00287 gboolean error; 00288 gboolean eof; 00290 InputPlugin *plugin; 00291 struct OutputAPI * output; 00292 GThread *thread; 00293 00294 GMutex *pb_ready_mutex; 00295 GCond *pb_ready_cond; 00296 gint pb_ready_val; 00297 gint (*set_pb_ready) (InputPlayback*); 00298 00299 gint nch; 00300 gint rate; 00301 gint freq; 00302 gint length; 00303 gchar *title; 00304 00310 void (*set_params) (InputPlayback * playback, const gchar * title, gint 00311 length, gint bitrate, gint samplerate, gint channels); 00312 00318 void (*set_tuple) (InputPlayback * playback, Tuple * tuple); 00319 00320 /* If replay gain settings are stored in the tuple associated with the 00321 * current song, this function can be called (after opening audio) to apply 00322 * those settings. If the settings are changed in a call to set_tuple, this 00323 * function must be called again to apply the updated settings. */ 00324 void (* set_gain_from_playlist) (InputPlayback * playback); 00325 00326 /* deprecated */ 00327 void (*pass_audio) (InputPlayback *, gint, gint, gint, gpointer, gint *); 00328 void (*set_replaygain_info) (InputPlayback *, ReplayGainInfo *); 00329 }; 00330 00334 struct _InputPlugin { 00335 PLUGIN_COMMON_FIELDS 00336 00337 /* Nonzero if the files handled by the plugin may contain more than one 00338 * song. When reading the tuple for such a file, the plugin should set the 00339 * FIELD_SUBSONG_NUM field to the number of songs in the file. For all 00340 * other files, the field should be left unset. 00341 * 00342 * Example: 00343 * 1. User adds a file named "somefile.xxx" to the playlist. Having 00344 * determined that this plugin can handle the file, Audacious opens the file 00345 * and calls probe_for_tuple(). probe_for_tuple() sees that there are 3 00346 * songs in the file and sets FIELD_SUBSONG_NUM to 3. 00347 * 2. For each song in the file, Audacious opens the file and calls 00348 * probe_for_tuple() -- this time, however, a question mark and song number 00349 * are appended to the file name passed: "somefile.sid?2" refers to the 00350 * second song in the file "somefile.sid". 00351 * 3. When one of the songs is played, Audacious opens the file and calls 00352 * play() with a file name modified in this way. 00353 */ 00354 gboolean have_subtune; 00355 00356 /* Pointer to an array (terminated with NULL) of file extensions associated 00357 * with file types the plugin can handle. */ 00358 const gchar * const * vfs_extensions; 00359 00360 /* How quickly the plugin should be tried in searching for a plugin to 00361 * handle a file which could not be identified from its extension. Plugins 00362 * with priority 0 are tried first, 10 last. */ 00363 gint priority; 00364 00365 /* Must return nonzero if the plugin can handle this file. If the file 00366 * could not be opened, "file" will be NULL. (This is normal in the case of 00367 * special URI schemes like cdda:// that do not represent actual files.) */ 00368 /* Bug: The return value should be a gboolean, not a gint. */ 00369 gint (* is_our_file_from_vfs) (const gchar * filename, VFSFile * file); 00370 00371 /* Deprecated. */ 00372 Tuple * (* get_song_tuple) (const gchar * filename); /* Use probe_for_tuple. */ 00373 00374 /* Must return a tuple containing metadata for this file, or NULL if no 00375 * metadata could be read. If the file could not be opened, "file" will be 00376 * NULL. Audacious takes over one reference to the tuple returned. */ 00377 Tuple * (* probe_for_tuple) (const gchar * filename, VFSFile * file); 00378 00379 /* Optional. Must write metadata from a tuple to this file. Must return 00380 * nonzero on success or zero on failure. "file" will never be NULL. */ 00381 /* Bug: This function does not support special URI schemes like cdda://, 00382 * since no file name is passed. */ 00383 gboolean (* update_song_tuple) (const Tuple * tuple, VFSFile * file); 00384 00385 /* Optional, and not recommended. Must show a window with information about 00386 * this file. If this function is provided, update_song_tuple should not be. */ 00387 /* Bug: Implementing this function duplicates user interface code and code 00388 * to open the file in each and every plugin. */ 00389 void (* file_info_box) (const gchar * filename); 00390 00391 /* Optional. Must try to read an "album art" image embedded in this file. 00392 * Must return nonzero on success or zero on failure. If the file could not 00393 * be opened, "file" will be NULL. On success, must fill "data" with a 00394 * pointer to a block of data allocated with g_malloc and "size" with the 00395 * size in bytes of that block. The data may be in any format supported by 00396 * GTK. Audacious will free the data when it is no longer needed. */ 00397 gboolean (* get_song_image) (const gchar * filename, VFSFile * file, 00398 void * * data, gint * size); 00399 00400 /* Must try to play this file. "playback" is a structure containing output- 00401 * related functions which the plugin may make use of. It also contains a 00402 * "data" pointer which the plugin may use to refer private data associated 00403 * with the playback state. This pointer can then be used from pause, 00404 * mseek, and stop. If the file could not be opened, "file" will be NULL. 00405 * "start_time" is the position in milliseconds at which to start from, or 00406 * -1 to start from the beginning of the file. "stop_time" is the position 00407 * in milliseconds at which to end playback, or -1 to play to the end of the 00408 * file. "paused" specifies whether playback should immediately be paused. 00409 * Must return nonzero if some of the file was successfully played or zero 00410 * on failure. */ 00411 gboolean (* play) (InputPlayback * playback, const gchar * filename, 00412 VFSFile * file, gint start_time, gint stop_time, gboolean pause); 00413 00414 /* Must pause or unpause a file currently being played. This function will 00415 * be called from a different thread than play, but it will not be called 00416 * before the plugin calls set_pb_ready or after stop is called. */ 00417 /* Bug: paused should be a gboolean, not a gshort. */ 00418 /* Bug: There is no way to indicate success or failure. */ 00419 void (* pause) (InputPlayback * playback, gshort paused); 00420 00421 /* Optional. Must seek to the given position in milliseconds within a file 00422 * currently being played. This function will be called from a different 00423 * thread than play, but it will not be called before the plugin calls 00424 * set_pb_ready or after stop is called. */ 00425 /* Bug: time should be a gint, not a gulong. */ 00426 /* Bug: There is no way to indicate success or failure. */ 00427 void (* mseek) (InputPlayback * playback, gulong time); 00428 00429 /* Must signal a currently playing song to stop and cause play to return. 00430 * This function will be called from a different thread than play. It will 00431 * only be called once. It should not join the thread from which play is 00432 * called. */ 00433 void (* stop) (InputPlayback * playback); 00434 00435 /* Advanced, for plugins that do not use Audacious's output system. Use at 00436 * your own risk. */ 00437 gint (* get_time) (InputPlayback * playback); 00438 gint (* get_volume) (gint * l, gint * r); 00439 gint (* set_volume) (gint l, gint r); 00440 00441 /* Deprecated. */ 00442 gint (* is_our_file) (const gchar * filename); /* Use is_our_file_from_vfs. */ 00443 void (* play_file) (InputPlayback * playback); /* Use play. */ 00444 void (* seek) (InputPlayback * playback, gint time); /* Use mseek. */ 00445 }; 00446 00447 struct _GeneralPlugin { 00448 PLUGIN_COMMON_FIELDS 00449 }; 00450 00451 struct _VisPlugin { 00452 PLUGIN_COMMON_FIELDS 00453 00454 gint num_pcm_chs_wanted; 00455 gint num_freq_chs_wanted; 00456 00457 void (*disable_plugin) (struct _VisPlugin *); 00458 void (*playback_start) (void); 00459 void (*playback_stop) (void); 00460 void (*render_pcm) (gint16 pcm_data[2][512]); 00461 00462 /* The range of intensities is 0 - 32767 (though theoretically it is 00463 * possible for the FFT to result in bigger values, making the final 00464 * intensity negative due to overflowing the 16bit signed integer.) 00465 * 00466 * If output is mono, only freq_data[0] is filled. 00467 */ 00468 void (*render_freq) (gint16 freq_data[2][256]); 00469 00470 /* GtkWidget * (* get_widget) (void); */ 00471 void * (* get_widget) (void); 00472 }; 00473 00474 /* undefine the macro -- struct Plugin should be used instead. */ 00475 #undef PLUGIN_COMMON_FIELDS 00476 00477 #endif /* AUDACIOUS_PLUGIN_H */