1 /* 2 deadbeef.d -- plugin API of the DeaDBeeF audio player 3 http://deadbeef.sourceforge.net 4 5 Copyright (C) 2009-2013 Alexey Yakovenko 6 7 This software is provided 'as-is', without any express or implied 8 warranty. In no event will the authors be held liable for any damages 9 arising from the use of this software. 10 11 Permission is granted to anyone to use this software for any purpose, 12 including commercial applications, and to alter it and redistribute it 13 freely, subject to the following restrictions: 14 15 1. The origin of this software must not be misrepresented; you must not 16 claim that you wrote the original software. If you use this software 17 in a product, an acknowledgment in the product documentation would be 18 appreciated but is not required. 19 2. Altered source versions must be plainly marked as such, and must not be 20 misrepresented as being the original software. 21 3. This notice may not be removed or altered from any source distribution. 22 */ 23 module deadbeef.deadbeef; 24 25 import core.stdc.time: time_t; 26 import core.stdc.stdint: uintptr_t, intptr_t; 27 import core.stdc.stdio: FILE; 28 import core.sys.posix.dirent: dirent; 29 30 extern (C): 31 @trusted: 32 @nogc: 33 nothrow: 34 35 36 // every plugin must define the following entry-point: 37 // extern "C" DB_plugin_t* $MODULENAME_load (DB_functions_t *api); 38 // where $MODULENAME is a name of module 39 // e.g. if your plugin is called "myplugin.so", $MODULENAME is "myplugin" 40 // this function should return pointer to DB_plugin_t structure 41 // that is enough for both static and dynamic modules 42 43 // backwards compatibility is supported since API version 1.0 44 // that means that the plugins which use the API 1.0 will work without recompiling until API 2.0. 45 // 46 // increments in the major version number mean that there are API breaks, and 47 // plugins must be recompiled to be compatible. 48 // 49 // add DDB_REQUIRE_API_VERSION(x,y) macro when you define the plugin structure 50 // like this: 51 // static DB_decoder_t plugin = { 52 // DDB_REQUIRE_API_VERSION(1,0) 53 // ............ 54 // } 55 // this is required for versioning 56 // if you don't do it -- no version checking will be done (useful for debugging/development) 57 // 58 // please DON'T release plugins without version requirement 59 // 60 // to ensure compatibility, use the following before including deadbeef.h: 61 // #define DDB_API_LEVEL x 62 // where x is the minor API version number. 63 // that way, you'll get errors or warnings when using incompatible stuff. 64 // 65 // if you also want to get the deprecation warnings, use the following: 66 // #define DDB_WARN_DEPRECATED 1 67 // 68 // NOTE: deprecation doesn't mean the API is going to be removed, it just means 69 // that there's a better replacement in the newer deadbeef versions. 70 71 // api version history: 72 // 1.9 -- deadbeef-0.7.2 73 // 1.8 -- deadbeef-0.7.0 74 // 1.7 -- deadbeef-0.6.2 75 // 1.6 -- deadbeef-0.6.1 76 // 1.5 -- deadbeef-0.6 77 // 1.4 -- deadbeef-0.5.5 78 // 1.3 -- deadbeef-0.5.3 79 // 1.2 -- deadbeef-0.5.2 80 // 1.1 -- deadbeef-0.5.1 81 // adds pass_through method to dsp plugins for optimization purposes 82 // 1.0 -- deadbeef-0.5.0 83 // 0.10 -- deadbeef-0.4.4-portable-r1 (note: 0.4.4 uses api v0.9) 84 // 0.9 -- deadbeef-0.4.3-portable-build3 85 // 0.8 -- deadbeef-0.4.2 86 // 0.7 -- deabdeef-0.4.0 87 // 0.6 -- deadbeef-0.3.3 88 // 0.5 -- deadbeef-0.3.2 89 // 0.4 -- deadbeef-0.3.0 90 // 0.3 -- deadbeef-0.2.3.2 91 // 0.2 -- deadbeef-0.2.3 92 // 0.1 -- deadbeef-0.2.0 93 94 enum DB_API_VERSION_MAJOR = 1; 95 enum DB_API_VERSION_MINOR = 9; 96 97 enum DDB_API_LEVEL = DB_API_VERSION_MINOR; 98 /+ … +/ 99 100 //////////////////////////// 101 // default values for some common config variables should go here 102 103 // network.ctmapping : content-type to plugin mapping 104 enum DDB_DEFAULT_CTMAPPING = "audio/mpeg {stdmpg ffmpeg} audio/x-mpeg {stdmpg ffmpeg} application/ogg {stdogg ffmpeg} audio/ogg {stdogg ffmpeg} audio/aac {aac ffmpeg} audio/aacp {aac ffmpeg} audio/x-m4a {aac ffmpeg} audio/wma {wma ffmpeg}"; 105 106 enum { 107 DDB_IS_SUBTRACK = (1<<0), // file is not single-track, might have metainfo in external file 108 DDB_IS_READONLY = (1<<1), // check this flag to block tag writing (e.g. in iso.wv) 109 DDB_HAS_EMBEDDED_CUESHEET = (1<<2), 110 111 DDB_TAG_ID3V1 = (1<<8), 112 DDB_TAG_ID3V22 = (1<<9), 113 DDB_TAG_ID3V23 = (1<<10), 114 DDB_TAG_ID3V24 = (1<<11), 115 DDB_TAG_APEV2 = (1<<12), 116 DDB_TAG_VORBISCOMMENTS = (1<<13), 117 DDB_TAG_CUESHEET = (1<<14), 118 DDB_TAG_ICY = (1<<15), 119 DDB_TAG_ITUNES = (1<<16), 120 121 DDB_TAG_MASK = 0x000fff00 122 } 123 124 // playlist item 125 // these are "public" fields, available to plugins 126 struct DB_playItem_s { 127 int startsample; // start sample of track, or -1 for auto 128 int endsample; // end sample of track, or -1 for auto 129 int shufflerating; // sort order for shuffle mode 130 } 131 alias ddb_playItem_t = DB_playItem_s; 132 alias DB_playItem_t = ddb_playItem_t; 133 134 struct ddb_playlist_t { 135 } 136 137 struct DB_metaInfo_s { 138 DB_metaInfo_s *next; 139 immutable char *key; 140 immutable char *value; 141 } 142 alias DB_metaInfo_t = DB_metaInfo_s; 143 144 // FIXME: that needs to be in separate plugin 145 146 enum JUNK_STRIP_ID3V2 = 1; 147 enum JUNK_STRIP_APEV2 = 2; 148 enum JUNK_STRIP_ID3V1 = 4; 149 enum JUNK_WRITE_ID3V2 = 8; 150 enum JUNK_WRITE_APEV2 = 16; 151 enum JUNK_WRITE_ID3V1 = 32; 152 153 struct DB_id3v2_frame_s { 154 DB_id3v2_frame_s *next; 155 char[5] id; 156 uint size; 157 ubyte[2] flags; 158 ubyte[0] data; 159 } 160 alias DB_id3v2_frame_t = DB_id3v2_frame_s; 161 162 struct DB_id3v2_tag_s { 163 ubyte[2] ver; 164 ubyte flags; 165 DB_id3v2_frame_t *frames; 166 } 167 alias DB_id3v2_tag_t = DB_id3v2_tag_s; 168 169 struct DB_apev2_frame_s { 170 DB_apev2_frame_s *next; 171 uint flags; 172 char[256] key; 173 uint size; // size of data 174 ubyte *data; /+uint8_t data[0]; — don't know how to implement it in D+/ 175 } 176 alias DB_apev2_frame_t = DB_apev2_frame_s; 177 178 struct DB_apev2_tag_s { 179 uint ver; 180 uint flags; 181 DB_apev2_frame_t *frames; 182 } 183 alias DB_apev2_tag_t = DB_apev2_tag_s; 184 185 // plugin types 186 enum { 187 DB_PLUGIN_DECODER = 1, 188 DB_PLUGIN_OUTPUT = 2, 189 DB_PLUGIN_DSP = 3, 190 DB_PLUGIN_MISC = 4, 191 DB_PLUGIN_VFS = 5, 192 DB_PLUGIN_PLAYLIST = 6, 193 DB_PLUGIN_GUI = 7, 194 } 195 196 // output plugin states 197 enum output_state_t { 198 OUTPUT_STATE_STOPPED = 0, 199 OUTPUT_STATE_PLAYING = 1, 200 OUTPUT_STATE_PAUSED = 2, 201 } 202 203 // playback order 204 enum playback_order_t { 205 PLAYBACK_ORDER_LINEAR = 0, 206 PLAYBACK_ORDER_SHUFFLE_TRACKS = 1, 207 PLAYBACK_ORDER_RANDOM = 2, 208 PLAYBACK_ORDER_SHUFFLE_ALBUMS = 3, 209 } 210 211 // playback modes 212 enum playback_mode_t { 213 PLAYBACK_MODE_LOOP_ALL = 0, // loop playlist 214 PLAYBACK_MODE_NOLOOP = 1, // don't loop 215 PLAYBACK_MODE_LOOP_SINGLE = 2, // loop single track 216 } 217 218 static if (DDB_API_LEVEL >= 8) { 219 // playlist change info, used in the DB_EV_PLAYLISTCHANGED p1 argument 220 enum ddb_playlist_change_t { 221 DDB_PLAYLIST_CHANGE_CONTENT, // this is the most generic one, will work for the cases when p1 was omitted (0) 222 DDB_PLAYLIST_CHANGE_CREATED, 223 DDB_PLAYLIST_CHANGE_DELETED, 224 DDB_PLAYLIST_CHANGE_POSITION, 225 DDB_PLAYLIST_CHANGE_TITLE, 226 DDB_PLAYLIST_CHANGE_SELECTION, 227 DDB_PLAYLIST_CHANGE_SEARCHRESULT, 228 DDB_PLAYLIST_CHANGE_PLAYQUEUE, 229 } 230 } 231 232 struct ddb_event_t { 233 int event; 234 int size; 235 } 236 237 struct ddb_event_track_t { 238 ddb_event_t ev; 239 DB_playItem_t *track; 240 float playtime; // for SONGFINISHED event -- for how many seconds track was playing 241 time_t started_timestamp; // time when "track" started playing 242 } 243 244 struct ddb_event_trackchange_t { 245 ddb_event_t ev; 246 DB_playItem_t *from; 247 DB_playItem_t *to; 248 float playtime; // for SONGCHANGED event -- for how many seconds prev track was playing 249 time_t started_timestamp; // time when "from" started playing 250 } 251 252 struct ddb_event_state_t { 253 ddb_event_t ev; 254 int state; 255 } 256 257 struct ddb_event_playpos_t { 258 ddb_event_t ev; 259 DB_playItem_t *track; 260 float playpos; 261 } 262 263 struct DB_conf_item_s { 264 char *key; 265 char *value; 266 DB_conf_item_s *next; 267 } 268 alias DB_conf_item_t = DB_conf_item_s; 269 270 // event callback type 271 alias DB_callback_t = int function(ddb_event_t *, uintptr_t data); 272 273 // events 274 enum { 275 DB_EV_NEXT = 1, // switch to next track 276 DB_EV_PREV = 2, // switch to prev track 277 DB_EV_PLAY_CURRENT = 3, // play current track (will start/unpause if stopped or paused) 278 DB_EV_PLAY_NUM = 4, // play track nr. p1 279 DB_EV_STOP = 5, // stop current track 280 DB_EV_PAUSE = 6, // pause playback 281 DB_EV_PLAY_RANDOM = 7, // play random track 282 DB_EV_TERMINATE = 8, // must be sent to player thread to terminate 283 DB_EV_PLAYLIST_REFRESH = 9, // [DEPRECATED IN API LEVEL 8, use DB_EV_PLAYLISTCHANGED instead] save and redraw current playlist 284 DB_EV_REINIT_SOUND = 10, // reinitialize sound output with current output_plugin config value 285 DB_EV_CONFIGCHANGED = 11, // one or more config options were changed 286 DB_EV_TOGGLE_PAUSE = 12, 287 DB_EV_ACTIVATED = 13, // will be fired every time player is activated 288 DB_EV_PAUSED = 14, // player was paused or unpaused 289 290 DB_EV_PLAYLISTCHANGED = 15, // playlist contents were changed (e.g. metadata in any track) 291 // DB_EV_PLAYLISTCHANGED NOTE: it's usually sent on LARGE changes, 292 // when multiple tracks are affected, while for single tracks 293 // the DB_EV_TRACKINFOCHANGED is preferred 294 // added in API level 8: 295 // p1 is one of ddb_playlist_change_t enum values, detailing what exactly has been changed. 296 297 DB_EV_VOLUMECHANGED = 16, // volume was changed 298 DB_EV_OUTPUTCHANGED = 17, // sound output plugin changed 299 DB_EV_PLAYLISTSWITCHED = 18, // playlist switch occured 300 DB_EV_SEEK = 19, // seek current track to position p1 (ms) 301 DB_EV_ACTIONSCHANGED = 20, // plugin actions were changed, e.g. for reinitializing gui 302 DB_EV_DSPCHAINCHANGED = 21, // emitted when any parameter of the main dsp chain has been changed 303 } 304 305 // since 1.5 306 static if (DDB_API_LEVEL >= 5) { 307 enum { 308 DB_EV_SELCHANGED = 22, // selection changed in playlist p1 iter p2, ctx should be a pointer to playlist viewer instance, which caused the change, or NULL 309 DB_EV_PLUGINSLOADED = 23, // after all plugins have been loaded and connected 310 } 311 } 312 313 static if (DDB_API_LEVEL >= 8) { 314 enum { 315 DB_EV_FOCUS_SELECTION = 24, // tell playlist viewer to focus on selection 316 } 317 } 318 319 enum { 320 // ----------------- 321 // structured events 322 323 DB_EV_FIRST = 1000, 324 DB_EV_SONGCHANGED = 1000, // current song changed from one to another, ctx=ddb_event_trackchange_t 325 DB_EV_SONGSTARTED = 1001, // song started playing, ctx=ddb_event_track_t 326 DB_EV_SONGFINISHED = 1002, // song finished playing, ctx=ddb_event_track_t 327 328 DB_EV_TRACKINFOCHANGED = 1004, // trackinfo was changed (included medatata, playback status, playqueue state, etc), ctx=ddb_event_track_t 329 // DB_EV_TRACKINFOCHANGED NOTE: when multiple tracks change, DB_EV_PLAYLISTCHANGED may be sent instead, 330 // for speed reasons, so always handle both events. 331 332 DB_EV_SEEKED = 1005, // seek happened, ctx=ddb_event_playpos_t 333 } 334 335 // since 1.5 336 static if (DDB_API_LEVEL >= 5) { 337 enum { 338 // NOTE: this is not a structured event, but too late to fix, needs to stay here for backwards compat 339 DB_EV_TRACKFOCUSCURRENT = 1006, // user wants to highlight/find the current playing track 340 } 341 } 342 343 enum { 344 DB_EV_MAX = 1007 345 } 346 347 // preset columns, working using IDs 348 // DON'T add new ids in range 2-7, they are reserved for backwards compatibility 349 enum pl_column_t { 350 DB_COLUMN_FILENUMBER = 0, 351 DB_COLUMN_PLAYING = 1, 352 DB_COLUMN_ALBUM_ART = 8, 353 }; 354 355 // replaygain constants 356 enum { 357 DDB_REPLAYGAIN_ALBUMGAIN, 358 DDB_REPLAYGAIN_ALBUMPEAK, 359 DDB_REPLAYGAIN_TRACKGAIN, 360 DDB_REPLAYGAIN_TRACKPEAK, 361 } 362 363 // sort order constants 364 enum { 365 DDB_SORT_DESCENDING = 0, 366 DDB_SORT_ASCENDING = 1, 367 } 368 369 // since 1.3 370 static if (DDB_API_LEVEL >= 3) { 371 enum DDB_SORT_RANDOM = 2; 372 } 373 374 enum ddb_sys_directory_t { 375 DDB_SYS_DIR_CONFIG = 1, 376 DDB_SYS_DIR_PREFIX = 2, 377 DDB_SYS_DIR_DOC = 3, 378 DDB_SYS_DIR_PLUGIN = 4, 379 DDB_SYS_DIR_PIXMAP = 5, 380 DDB_SYS_DIR_CACHE = 6, 381 } 382 383 /+ do we really need it in D? 384 // typecasting macros 385 #define DB_PLUGIN(x) ((DB_plugin_t *)(x)) 386 #define DB_CALLBACK(x) ((DB_callback_t)(x)) 387 #define DB_EVENT(x) ((ddb_event_t *)(x)) 388 #define DB_PLAYITEM(x) ((DB_playItem_t *)(x)) 389 +/ 390 391 // FILE object wrapper for vfs access 392 struct DB_FILE { 393 DB_vfs_s *vfs; 394 }; 395 396 // md5 calc control structure (see md5/md5.h) 397 struct DB_md5_s { 398 char[88] data; 399 } 400 alias DB_md5_t = DB_md5_s; 401 402 struct ddb_waveformat_t { 403 int bps; 404 int channels; 405 int samplerate; 406 uint channelmask; 407 int is_float; // bps must be 32 if this is true 408 int is_bigendian; 409 } 410 411 // since 1.5 412 static if (DDB_API_LEVEL >= 5) { 413 enum DDB_FREQ_BANDS = 256; 414 enum DDB_FREQ_MAX_CHANNELS = 9; 415 struct ddb_audio_data_s { 416 immutable ddb_waveformat_t *fmt; 417 immutable float *data; 418 int nframes; 419 } 420 alias ddb_audio_data_t = ddb_audio_data_s; 421 422 struct ddb_fileadd_data_s { 423 int visibility; 424 ddb_playlist_t *plt; 425 ddb_playItem_t *track; 426 } 427 alias ddb_fileadd_data_t = ddb_fileadd_data_s; 428 } 429 430 // since 1.8 431 static if (DDB_API_LEVEL >= 8) { 432 enum { 433 DDB_TF_CONTEXT_HAS_INDEX = 1, 434 DDB_TF_CONTEXT_HAS_ID = 2, 435 DDB_TF_CONTEXT_NO_DYNAMIC = 4, // skip dynamic fields (%playback_time%) 436 } 437 static if (DDB_API_LEVEL >= 9) { 438 // Don't convert linebreaks to semicolons 439 enum DDB_TF_CONTEXT_MULTILINE = 8; 440 } 441 442 // context for title formatting interpreter 443 struct ddb_tf_context_t { 444 int _size; // must be set to sizeof(tf_context_t) 445 uint flags; // DDB_TF_CONTEXT_ flags 446 ddb_playItem_t *it; // track to get information from, or NULL 447 ddb_playlist_t *plt; // playlist in which the track resides, or NULL 448 449 // NOTE: when plt is NULL, it means that the track is not in any playlist, 450 // that is -- playlist will never be automatically guessed, for performance 451 // reasons. 452 453 // index of the track in playlist the track belongs to 454 // if present, DDB_TF_CONTEXT_HAS_INDEX flag must be set 455 int idx; 456 457 // predefined column id, one of the DB_COLUMN_ 458 // if present, DDB_TF_CONTEXT_HAS_ID flag must be set 459 int id; 460 461 int iter; // playlist iteration (PL_MAIN, PL_SEARCH) 462 463 // update is a returned value 464 // meaning: 465 // 0: no automatic updates 466 // <0: updates on every call 467 // >0: number of milliseconds between updates / until next update 468 int update; 469 } 470 } 471 472 // player api definition 473 struct DB_functions_t { 474 // versioning 475 int vmajor; 476 int vminor; 477 478 // md5sum calc 479 void function(ubyte[16] sig, in char *input, int len) nothrow @nogc md5; 480 void function(char *str, in ubyte[16] sig) nothrow @nogc md5_to_str; 481 void function(DB_md5_t *s) nothrow @nogc md5_init; 482 void function(DB_md5_t *s, in ubyte *data, int nbytes) nothrow @nogc md5_append; 483 void function(DB_md5_t *s, ubyte[16] digest) nothrow @nogc md5_finish; 484 485 // playback control 486 DB_output_s* function() nothrow @nogc get_output; 487 float function() nothrow @nogc playback_get_pos; // [0..100] 488 void function(float pos) nothrow @nogc playback_set_pos; // [0..100] 489 490 // streamer access 491 DB_playItem_t *function() nothrow @nogc streamer_get_playing_track; 492 DB_playItem_t *function() nothrow @nogc streamer_get_streaming_track; 493 float function() nothrow @nogc streamer_get_playpos; 494 int function(int len) nothrow @nogc streamer_ok_to_read; 495 void function(int full) nothrow @nogc streamer_reset; 496 int function(char *bytes, int size) nothrow @nogc streamer_read; 497 void function(int bitrate) nothrow @nogc streamer_set_bitrate; 498 int function() nothrow @nogc streamer_get_apx_bitrate; 499 DB_fileinfo_s *function() nothrow @nogc streamer_get_current_fileinfo; 500 int function() nothrow @nogc streamer_get_current_playlist; 501 ddb_dsp_context_s * function() nothrow @nogc streamer_get_dsp_chain; 502 void function(ddb_dsp_context_s *chain) nothrow @nogc streamer_set_dsp_chain; 503 void function() nothrow @nogc streamer_dsp_refresh; // call after changing parameters 504 505 // system folders 506 // normally functions will return standard folders derived from --prefix 507 // portable version will return pathes specified in comments below 508 /+static if (DDB_API_LEVEL < 8) {+/ 509 immutable char* function() nothrow @nogc get_config_dir; // installdir/config | $XDG_CONFIG_HOME/.config/deadbeef 510 immutable char* function() nothrow @nogc get_prefix; // installdir | PREFIX 511 immutable char* function() nothrow @nogc get_doc_dir; // installdir/doc | DOCDIR 512 immutable char* function() nothrow @nogc get_plugin_dir; // installdir/plugins | LIBDIR/deadbeef 513 immutable char* function() nothrow @nogc get_pixmap_dir; // installdir/pixmaps | PREFIX "/share/deadbeef/pixmaps" 514 /+}+/ 515 516 // process control 517 void function() quit; 518 519 // threading 520 intptr_t function(void function(void *ctx) fn, void *ctx) nothrow @nogc thread_start; 521 intptr_t function(void function(void *ctx) fn, void *ctx) nothrow @nogc thread_start_low_priority; 522 int function(intptr_t tid) nothrow @nogc thread_join; 523 int function(intptr_t tid) nothrow @nogc thread_detach; 524 void function(void *retval) nothrow @nogc thread_exit; 525 uintptr_t function() nothrow @nogc mutex_create; 526 uintptr_t function() nothrow @nogc mutex_create_nonrecursive; 527 void function(uintptr_t mtx) nothrow @nogc mutex_free; 528 int function(uintptr_t mtx) nothrow @nogc mutex_lock; 529 int function(uintptr_t mtx) nothrow @nogc mutex_unlock; 530 uintptr_t function() nothrow @nogc cond_create; 531 void function(uintptr_t cond) nothrow @nogc cond_free; 532 int function(uintptr_t cond, uintptr_t mutex) nothrow @nogc cond_wait; 533 int function(uintptr_t cond) nothrow @nogc cond_signal; 534 int function(uintptr_t cond) nothrow @nogc cond_broadcast; 535 536 /////// playlist management ////// 537 void function(ddb_playlist_t *plt) nothrow @nogc plt_ref; 538 void function(ddb_playlist_t *plt) nothrow @nogc plt_unref; 539 540 // total number of playlists 541 int function() nothrow @nogc plt_get_count; 542 543 544 // 1st item in playlist nr. 'plt' 545 DB_playItem_t * function(int plt) nothrow @nogc plt_get_head; 546 547 // nr. of selected items in playlist nr. 'plt' 548 int function(int plt) nothrow @nogc plt_get_sel_count; 549 550 // add new playlist into position before nr. 'before', with title='title' 551 // returns index of new playlist 552 int function(int before, in char *title) nothrow @nogc plt_add; 553 554 // remove playlist nr. plt 555 void function(int plt) nothrow @nogc plt_remove; 556 557 // clear playlist 558 void function(ddb_playlist_t *plt) nothrow @nogc plt_clear; 559 void function() nothrow @nogc pl_clear; 560 561 // set current playlist 562 void function(ddb_playlist_t *plt) nothrow @nogc plt_set_curr; 563 void function(int plt) nothrow @nogc plt_set_curr_idx; 564 565 // get current playlist 566 // note: caller is responsible to call plt_unref after using pointer 567 // returned by plt_get_curr 568 ddb_playlist_t* function() nothrow @nogc plt_get_curr; 569 int function() nothrow @nogc plt_get_curr_idx; 570 571 // move playlist nr. 'from' into position before nr. 'before', where 572 // before=-1 means last position 573 void function(int from, int before) nothrow @nogc plt_move; 574 575 // playlist saving and loading 576 /+static if (DDB_API_LEVEL < 5) {+/ 577 DB_playItem_t* function(ddb_playlist_t *plt, DB_playItem_t *after, in char *fname, int *pabort, int function(DB_playItem_t *it, void *data) cb, void *user_data) nothrow @nogc plt_load; 578 /+}+/ 579 int function(ddb_playlist_t *plt, DB_playItem_t *first, DB_playItem_t *last, in char *fname, int *pabort, int function(DB_playItem_t *it, void *data) cb, void *user_data) nothrow @nogc plt_save; 580 581 ddb_playlist_t* function(int idx) nothrow @nogc plt_get_for_idx; 582 int function(ddb_playlist_t *plt, char *buffer, int bufsize) nothrow @nogc plt_get_title; 583 int function(ddb_playlist_t *plt, in char *title) nothrow @nogc plt_set_title; 584 585 // increments modification index 586 void function(ddb_playlist_t *handle) nothrow @nogc plt_modified; 587 588 // returns modication index 589 // the index is incremented by 1 every time playlist changes 590 int function(ddb_playlist_t *handle) nothrow @nogc plt_get_modification_idx; 591 592 // return index of an item in specified playlist, or -1 if not found 593 int function(ddb_playlist_t *plt, DB_playItem_t *it, int iter) nothrow @nogc plt_get_item_idx; 594 595 // playlist metadata 596 // this kind of metadata is stored in playlist (dbpl) files 597 // that is, this is the properties of playlist itself, 598 // not of the tracks in the playlist. 599 // for example, playlist tab color can be stored there, etc 600 601 // add meta if it doesn't exist yet 602 void function(ddb_playlist_t *handle, in char *key, in char *value) nothrow @nogc plt_add_meta; 603 604 // replace (or add) existing meta 605 void function(ddb_playlist_t *handle, in char *key, in char *value) nothrow @nogc plt_replace_meta; 606 607 // append meta to existing one, or add if doesn't exist 608 void function(ddb_playlist_t *handle, in char *key, in char *value) nothrow @nogc plt_append_meta; 609 610 // set integer meta (works same as replace) 611 void function(ddb_playlist_t *handle, in char *key, int value) nothrow @nogc plt_set_meta_int; 612 613 // set float meta (works same as replace) 614 void function(ddb_playlist_t *handle, in char *key, float value) nothrow @nogc plt_set_meta_float; 615 616 // plt_find_meta must always be used in the pl_lock/unlock block 617 immutable char* function(ddb_playlist_t *handle, in char *key) nothrow @nogc plt_find_meta; 618 619 // returns head of metadata linked list, for direct access 620 // remember pl_lock/unlock 621 DB_metaInfo_t* function(ddb_playlist_t *handle) nothrow @nogc plt_get_metadata_head; 622 623 // delete meta item from list 624 void function(ddb_playlist_t *handle, DB_metaInfo_t *meta) nothrow @nogc plt_delete_metadata; 625 626 // returns integer value of requested meta, def is the default value if not found 627 int function(ddb_playlist_t *handle, in char *key, int def) nothrow @nogc plt_find_meta_int; 628 629 // returns float value of requested meta, def is the default value if not found 630 float function(ddb_playlist_t *handle, in char *key, float def) nothrow @nogc plt_find_meta_float; 631 632 // delete all metadata 633 void function(ddb_playlist_t *handle) nothrow @nogc plt_delete_all_meta; 634 635 // operating on playlist items 636 DB_playItem_t* function(ddb_playlist_t *playlist, DB_playItem_t *after, DB_playItem_t *it) nothrow @nogc plt_insert_item; 637 /+static if (DDB_API_LEVEL < 5) {+/ 638 DB_playItem_t* function(ddb_playlist_t *playlist, DB_playItem_t *after, in char *fname, int *pabort, int function(DB_playItem_t *it, void *data) cb, void *user_data) nothrow @nogc plt_insert_file; 639 DB_playItem_t* function(ddb_playlist_t *plt, DB_playItem_t *after, in char *dirname, int *pabort, int function(DB_playItem_t *it, void *data) cb, void *user_data) nothrow @nogc plt_insert_dir; 640 /+}+/ 641 void function(ddb_playlist_t *plt, DB_playItem_t *it, float duration) nothrow @nogc plt_set_item_duration; 642 int function(ddb_playlist_t *playlist, DB_playItem_t *it) nothrow @nogc plt_remove_item; 643 int function(ddb_playlist_t *playlist) nothrow @nogc plt_getselcount; 644 float function(ddb_playlist_t *plt) nothrow @nogc plt_get_totaltime; 645 int function(ddb_playlist_t *plt, int iter) nothrow @nogc plt_get_item_count; 646 int function(ddb_playlist_t *plt) nothrow @nogc plt_delete_selected; 647 void function(ddb_playlist_t *plt, int iter, int cursor) nothrow @nogc plt_set_cursor; 648 int function(ddb_playlist_t *plt, int iter) nothrow @nogc plt_get_cursor; 649 void function(ddb_playlist_t *plt) nothrow @nogc plt_select_all; 650 void function(ddb_playlist_t *plt) nothrow @nogc plt_crop_selected; 651 DB_playItem_t* function(ddb_playlist_t *plt, int iter) nothrow @nogc plt_get_first; 652 DB_playItem_t* function(ddb_playlist_t *plt, int iter) nothrow @nogc plt_get_last; 653 DB_playItem_t* function(ddb_playlist_t *playlist, int idx, int iter) nothrow @nogc plt_get_item_for_idx; 654 void function(ddb_playlist_t *to, int iter, ddb_playlist_t *from, DB_playItem_t *drop_before, uint *indexes, int count) nothrow @nogc plt_move_items; 655 void function(ddb_playlist_t *to, int iter, ddb_playlist_t * from, DB_playItem_t *before, uint *indices, int cnt) nothrow @nogc plt_copy_items; 656 void function(ddb_playlist_t *plt) nothrow @nogc plt_search_reset; 657 void function(ddb_playlist_t *plt, in char *text) nothrow @nogc plt_search_process; 658 659 // sort using the title formatting v1 (deprecated) 660 /+static if (DDB_API_LEVEL < 8) {+/ 661 void function(ddb_playlist_t *plt, int iter, int id, in char *format, int order) nothrow @nogc plt_sort; 662 /+}+/ 663 664 /+static if (DDB_API_LEVEL < 5) {+/ 665 // add files and folders to current playlist 666 int function(ddb_playlist_t *plt, in char *fname, int function(DB_playItem_t *it, void *data) cb, void *user_data) nothrow @nogc plt_add_file; 667 int function(ddb_playlist_t *plt, in char *dirname, int function(DB_playItem_t *it, void *data) cb, void *user_data) nothrow @nogc plt_add_dir; 668 /+}+/ 669 670 // cuesheet support 671 DB_playItem_t* function(ddb_playlist_t *plt, DB_playItem_t *after, DB_playItem_t *origin, in ubyte *buffer, int buffersize, int numsamples, int samplerate) nothrow @nogc plt_insert_cue_from_buffer; 672 DB_playItem_t* function(ddb_playlist_t *plt, DB_playItem_t *after, DB_playItem_t *origin, int numsamples, int samplerate) nothrow @nogc plt_insert_cue; 673 674 // playlist locking 675 void function() nothrow @nogc pl_lock; 676 void function() nothrow @nogc pl_unlock; 677 678 // playlist tracks access 679 DB_playItem_t* function() nothrow @nogc pl_item_alloc; 680 DB_playItem_t* function(in char *fname, in char *decoder_id) nothrow @nogc pl_item_alloc_init; 681 void function(DB_playItem_t *it) nothrow @nogc pl_item_ref; 682 void function(DB_playItem_t *it) nothrow @nogc pl_item_unref; 683 void function(DB_playItem_t *output, DB_playItem_t *input) nothrow @nogc pl_item_copy; 684 685 // request lock for adding files to playlist 686 // this function may return -1 if it is not possible to add files right now. 687 // caller must cancel operation in this case, 688 // or wait until previous operation finishes 689 /+static if (DDB_API_LEVEL < 5) {+/ 690 int function(ddb_playlist_t *plt) nothrow @nogc pl_add_files_begin; 691 692 // release the lock for adding files to playlist 693 // end must be called when add files operation is finished 694 void function() nothrow @nogc pl_add_files_end; 695 /+}+/ 696 697 // most of this functions are self explanatory 698 // if you don't get what they do -- look in the code 699 700 // --- the following functions work with current playlist --- 701 702 // get index of the track in MAIN 703 int function(DB_playItem_t *it) nothrow @nogc pl_get_idx_of; 704 705 // get index of the track in MAIN or SEARCH 706 int function(DB_playItem_t *it, int iter) nothrow @nogc pl_get_idx_of_iter; 707 708 // get track for index in MAIN 709 DB_playItem_t* function(int idx) nothrow @nogc pl_get_for_idx; 710 711 // get track for index in MAIN or SEARCH 712 DB_playItem_t* function(int idx, int iter) nothrow @nogc pl_get_for_idx_and_iter; 713 714 // get total play time of all tracks in MAIN 715 float function() nothrow @nogc pl_get_totaltime; 716 717 // get number of tracks in MAIN or SEARCH 718 int function(int iter) nothrow @nogc pl_getcount; 719 720 // delete selected tracks 721 int function() nothrow @nogc pl_delete_selected; 722 723 // set cursor position in MAIN or SEARCH 724 void function(int iter, int cursor) nothrow @nogc pl_set_cursor; 725 726 // get cursor position in MAIN 727 int function(int iter) nothrow @nogc pl_get_cursor; 728 729 // remove all except selected tracks 730 void function() nothrow @nogc pl_crop_selected; 731 732 // get number of selected tracks 733 int function() nothrow @nogc pl_getselcount; 734 735 // get first track in MAIN or SEARCH 736 DB_playItem_t* function(int iter) nothrow @nogc pl_get_first; 737 738 // get last track in MAIN or SEARCH 739 DB_playItem_t* function(int iter) nothrow @nogc pl_get_last; 740 741 // --- misc functions --- 742 743 // mark the track as selected or unselected (1 or 0 respectively) 744 void function(DB_playItem_t *it, int sel) nothrow @nogc pl_set_selected; 745 746 // test whether the track is selected 747 int function(DB_playItem_t *it) nothrow @nogc pl_is_selected; 748 749 // save current playlist 750 int function() nothrow @nogc pl_save_current; 751 752 // save all playlists 753 int function() nothrow @nogc pl_save_all; 754 755 // select all tracks in current playlist 756 void function() nothrow @nogc pl_select_all; 757 758 // get next track 759 DB_playItem_t* function(DB_playItem_t *it, int iter) nothrow @nogc pl_get_next; 760 761 // get previous track 762 DB_playItem_t* function(DB_playItem_t *it, int iter) nothrow @nogc pl_get_prev; 763 764 /* 765 pl_format_title formats the line for display in playlist 766 @it pointer to playlist item 767 @idx number of that item in playlist (or -1) 768 @s output buffer 769 @size size of output buffer 770 @id one of IDs defined in pl_column_id_t enum, can be -1 771 @fmt format string, used if id is -1 772 format is printf-alike. specification: 773 %a artist 774 %t title 775 %b album 776 %B band / album artist 777 %n track 778 %l length (duration) 779 %y year 780 %g genre 781 %c comment 782 %r copyright 783 %T tags 784 %f filename without path 785 %F full pathname/uri 786 %d directory without path (e.g. /home/user/file.mp3 -> user) 787 %D directory name with full path (e.g. /home/user/file.mp3 -> /home/user) 788 more to come 789 */ 790 /+static if (DDB_API_LEVEL < 8) {+/ 791 int function(DB_playItem_t *it, int idx, char *s, int size, int id, in char *fmt) nothrow @nogc pl_format_title; 792 793 // _escaped version wraps all conversions with '' and replaces every ' in conversions with \' 794 int function(DB_playItem_t *it, int idx, char *s, int size, int id, in char *fmt) nothrow @nogc pl_format_title_escaped; 795 /+}+/ 796 // format duration 't' (fractional seconds) into string, for display in playlist 797 void function(float t, char *dur, int size) nothrow @nogc pl_format_time; 798 799 // find which playlist the specified item belongs to, returns NULL if none 800 ddb_playlist_t* function(DB_playItem_t *it) nothrow @nogc pl_get_playlist; 801 802 // direct access to metadata structures 803 // not thread-safe, make sure to wrap with pl_lock/pl_unlock 804 DB_metaInfo_t* function(DB_playItem_t *it) nothrow @nogc pl_get_metadata_head; // returns head of metadata linked list 805 void function(DB_playItem_t *it, DB_metaInfo_t *meta) nothrow @nogc pl_delete_metadata; 806 807 // high-level access to metadata 808 void function(DB_playItem_t *it, in char *key, in char *value) nothrow @nogc pl_add_meta; 809 void function(DB_playItem_t *it, in char *key, in char *value) nothrow @nogc pl_append_meta; 810 void function(DB_playItem_t *it, in char *key, int value) nothrow @nogc pl_set_meta_int; 811 void function(DB_playItem_t *it, in char *key, float value) nothrow @nogc pl_set_meta_float; 812 void function(DB_playItem_t *it, in char *key) nothrow @nogc pl_delete_meta; 813 814 // this function is not thread-safe 815 // make sure to wrap it with pl_lock/pl_unlock block 816 immutable char* function(DB_playItem_t *it, in char *key) nothrow @nogc pl_find_meta; 817 818 // following functions are thread-safe 819 int function(DB_playItem_t *it, in char *key, int def) nothrow @nogc pl_find_meta_int; 820 float function(DB_playItem_t *it, in char *key, float def) nothrow @nogc pl_find_meta_float; 821 void function(DB_playItem_t *it, in char *key, in char *value) nothrow @nogc pl_replace_meta; 822 void function(DB_playItem_t *it) nothrow @nogc pl_delete_all_meta; 823 float function(DB_playItem_t *it) nothrow @nogc pl_get_item_duration; 824 uint function(DB_playItem_t *it) nothrow @nogc pl_get_item_flags; 825 void function(DB_playItem_t *it, uint flags) nothrow @nogc pl_set_item_flags; 826 void function(DB_playItem_t *from, DB_playItem_t *first, DB_playItem_t *last) nothrow @nogc pl_items_copy_junk; 827 // idx is one of DDB_REPLAYGAIN_* constants 828 void function(DB_playItem_t *it, int idx, float value) nothrow @nogc pl_set_item_replaygain; 829 float function(DB_playItem_t *it, int idx) nothrow @nogc pl_get_item_replaygain; 830 831 // playqueue support (obsolete since API 1.8) 832 /+static if (DDB_API_LEVEL < 8) {+/ 833 int function(DB_playItem_t *it) nothrow @nogc pl_playqueue_push; 834 void function() nothrow @nogc pl_playqueue_clear; 835 void function() nothrow @nogc pl_playqueue_pop; 836 void function(DB_playItem_t *it) nothrow @nogc pl_playqueue_remove; 837 int function(DB_playItem_t *it) nothrow @nogc pl_playqueue_test; 838 /+}+/ 839 840 // volume control 841 void function(float dB) nothrow @nogc volume_set_db; 842 float function() nothrow @nogc volume_get_db; 843 void function(float amp) nothrow @nogc volume_set_amp; 844 float function() nothrow @nogc volume_get_amp; 845 float function() nothrow @nogc volume_get_min_db; 846 847 // junk reading/writing 848 int function(DB_playItem_t *it, DB_FILE *fp) nothrow @nogc junk_id3v1_read; 849 int function(DB_FILE *fp) nothrow @nogc junk_id3v1_find; 850 int function(FILE *fp, DB_playItem_t *it, in char *enc) nothrow @nogc junk_id3v1_write; 851 int function(DB_FILE *fp, int *psize) nothrow @nogc junk_id3v2_find; 852 int function(DB_playItem_t *it, DB_FILE *fp) nothrow @nogc junk_id3v2_read; 853 int function(DB_playItem_t *it, DB_id3v2_tag_t *tag, DB_FILE *fp) nothrow @nogc junk_id3v2_read_full; 854 int function(DB_id3v2_tag_t *tag24, DB_id3v2_tag_t *tag23) nothrow @nogc junk_id3v2_convert_24_to_23; 855 int function(DB_id3v2_tag_t *tag23, DB_id3v2_tag_t *tag24) nothrow @nogc junk_id3v2_convert_23_to_24; 856 int function(DB_id3v2_tag_t *tag22, DB_id3v2_tag_t *tag24) nothrow @nogc junk_id3v2_convert_22_to_24; 857 void function(DB_id3v2_tag_t *tag) nothrow @nogc junk_id3v2_free; 858 int function(FILE *file, DB_id3v2_tag_t *tag) nothrow @nogc junk_id3v2_write; 859 DB_id3v2_frame_t* function(DB_id3v2_tag_t *tag, in char *frame_id, in char *value) nothrow @nogc junk_id3v2_add_text_frame; 860 int function(DB_id3v2_tag_t *tag, in char *frame_id) nothrow @nogc junk_id3v2_remove_frames; 861 int function(DB_playItem_t *it, DB_FILE *fp) nothrow @nogc junk_apev2_read; 862 int function(DB_playItem_t *it, char *mem, int size) nothrow @nogc junk_apev2_read_mem; 863 int function(DB_playItem_t *it, DB_apev2_tag_t *tag_store, DB_FILE *fp) nothrow @nogc junk_apev2_read_full; 864 int function(DB_playItem_t *it, DB_apev2_tag_t *tag_store, char *mem, int memsize) nothrow @nogc junk_apev2_read_full_mem; 865 int function(DB_FILE *fp, int *psize, uint *pflags, uint *pnumitems) nothrow @nogc junk_apev2_find; 866 int function(DB_apev2_tag_t *tag, in char *frame_id) nothrow @nogc junk_apev2_remove_frames; 867 DB_apev2_frame_t* function(DB_apev2_tag_t *tag, in char *frame_id, in char *value) nothrow @nogc junk_apev2_add_text_frame; 868 void function(DB_apev2_tag_t *tag) nothrow @nogc junk_apev2_free; 869 int function(FILE *fp, DB_apev2_tag_t *tag, int write_header, int write_footer) nothrow @nogc junk_apev2_write; 870 int function(DB_FILE *fp) nothrow @nogc junk_get_leading_size; 871 int function(FILE *fp) nothrow @nogc junk_get_leading_size_stdio; 872 void function(DB_playItem_t *from, DB_playItem_t *first, DB_playItem_t *last) nothrow @nogc junk_copy; 873 immutable char * function(in char *s) nothrow @nogc junk_detect_charset; 874 int function(in char *input, int inlen, char *output, int outlen, in char *cs) nothrow @nogc junk_recode; 875 int function(in char *input, int inlen, char *output, int outlen, in char *cs_in, in char *cs_out) nothrow @nogc junk_iconv; 876 int function(DB_playItem_t *it, uint flags, int id3v2_version, in char *id3v1_encoding) nothrow @nogc junk_rewrite_tags; 877 878 // vfs 879 DB_FILE* function(in char *fname) nothrow @nogc fopen; 880 void function(DB_FILE *f) nothrow @nogc fclose; 881 size_t function(void *ptr, size_t size, size_t nmemb, DB_FILE *stream) nothrow @nogc fread; 882 int function(DB_FILE *stream, long offset, int whence) nothrow @nogc fseek; 883 long function(DB_FILE *stream) nothrow @nogc ftell; 884 void function(DB_FILE *stream) nothrow @nogc rewind; 885 long function(DB_FILE *stream) nothrow @nogc fgetlength; 886 immutable char * function(DB_FILE *stream) nothrow @nogc fget_content_type; 887 void function(DB_FILE *stream, DB_playItem_t *it) nothrow @nogc fset_track; 888 void function(DB_FILE *stream) nothrow @nogc fabort; 889 890 // message passing 891 int function(uint id, uintptr_t ctx, uint p1, uint p2) nothrow @nogc sendmessage; 892 893 // convenience functions to send events, uses sendmessage internally 894 ddb_event_t * function(uint id) nothrow @nogc event_alloc; 895 void function(ddb_event_t *ev) nothrow @nogc event_free; 896 int function(ddb_event_t *ev, uint p1, uint p2) nothrow @nogc event_send; 897 898 // configuration access 899 // 900 // conf_get_str_fast is not thread-safe, and 901 // must only be used from within conf_lock/conf_unlock block 902 // it should be preferred for fast non-blocking lookups 903 // 904 // all the other config access functions are thread safe 905 void function() nothrow @nogc conf_lock; 906 void function() nothrow @nogc conf_unlock; 907 immutable char * function(in char *key, in char *def) nothrow @nogc conf_get_str_fast; 908 void function(in char *key, in char *def, char *buffer, int buffer_size) nothrow @nogc conf_get_str; 909 float function(in char *key, float def) nothrow @nogc conf_get_float; 910 int function(in char *key, int def) nothrow @nogc conf_get_int; 911 long function(in char *key, long def) nothrow @nogc conf_get_int64; 912 void function(in char *key, in char *val) nothrow @nogc conf_set_str; 913 void function(in char *key, int val) nothrow @nogc conf_set_int; 914 void function(in char *key, long val) nothrow @nogc conf_set_int64; 915 void function(in char *key, float val) nothrow @nogc conf_set_float; 916 DB_conf_item_t* function(in char *group, DB_conf_item_t *prev) nothrow @nogc conf_find; 917 void function(in char *key) nothrow @nogc conf_remove_items; 918 int function() nothrow @nogc conf_save; 919 920 // plugin communication 921 DB_decoder_s** function() nothrow @nogc plug_get_decoder_list; 922 DB_vfs_s** function() nothrow @nogc plug_get_vfs_list; 923 DB_output_s** function() nothrow @nogc plug_get_output_list; 924 DB_dsp_s** function() nothrow @nogc plug_get_dsp_list; 925 DB_playlist_s** function() nothrow @nogc plug_get_playlist_list; 926 DB_plugin_s** function() nothrow @nogc plug_get_list; 927 immutable char** function() nothrow @nogc plug_get_gui_names; 928 immutable char * function(in char *id) nothrow @nogc plug_get_decoder_id; 929 void function(in char *id) nothrow @nogc plug_remove_decoder_id; 930 DB_plugin_s* function(in char *id) nothrow @nogc plug_get_for_id; 931 932 // misc utilities 933 // returns 1 if the track is represented as a local file 934 // returns 0 if it's a remote file, e.g. a network stream 935 // since API 1.5 it also returns 1 for vfs tracks, e.g. from ZIP files 936 int function(in char *fname) nothrow @nogc is_local_file; 937 938 // pcm utilities 939 int function(in ddb_waveformat_t * inputfmt, in char *input, in ddb_waveformat_t *outputfmt, char *output, int inputsize) nothrow @nogc pcm_convert; 940 941 // dsp preset management 942 int function(in char *fname, ddb_dsp_context_s **head) nothrow @nogc dsp_preset_load; 943 int function(in char *fname, ddb_dsp_context_s *head) nothrow @nogc dsp_preset_save; 944 void function(ddb_dsp_context_s *head) nothrow @nogc dsp_preset_free; 945 946 // since 1.2 947 static if (DDB_API_LEVEL >= 2) { 948 ddb_playlist_t* function(in char *title) nothrow @nogc plt_alloc; 949 void function(ddb_playlist_t *plt) nothrow @nogc plt_free; 950 951 void function(ddb_playlist_t *plt, int fast) nothrow @nogc plt_set_fast_mode; 952 int function(ddb_playlist_t *plt) nothrow @nogc plt_is_fast_mode; 953 954 immutable char * function(in char *str) nothrow @nogc metacache_add_string; 955 void function(in char *str) nothrow @nogc metacache_remove_string; 956 void function(in char *str) nothrow @nogc metacache_ref; 957 void function(in char *str) nothrow @nogc metacache_unref; 958 959 // this function must return original un-overriden value (ignoring the keys prefixed with '!') 960 // it's not thread-safe, and must be used under the same conditions as the 961 // pl_find_meta 962 immutable char * function(DB_playItem_t *it, in char *key) nothrow @nogc pl_find_meta_raw; 963 } 964 965 // since 1.3 966 static if (DDB_API_LEVEL >= 3) { 967 int function() nothrow @nogc streamer_dsp_chain_save; 968 } 969 970 // since 1.4 971 static if (DDB_API_LEVEL >= 4) { 972 int function(DB_playItem_t *it, in char *key, char *val, int size) nothrow @nogc pl_get_meta; 973 int function(DB_playItem_t *it, in char *key, char *val, int size) nothrow @nogc pl_get_meta_raw; 974 int function(ddb_playlist_t *handle, in char *key, char *val, int size) nothrow @nogc plt_get_meta; 975 976 // fast way to test if a field exists in playitem 977 int function(DB_playItem_t *it, in char *key) nothrow @nogc pl_meta_exists; 978 } 979 980 // since 1.5 981 static if (DDB_API_LEVEL >= 5) { 982 // register/unregister for getting continuous wave data 983 // mainly for visualization 984 // ctx must be unique 985 // the waveform data can be arbitrary size 986 // the samples are interleaved 987 void function(void *ctx, void function(void *ctx, ddb_audio_data_t *data) callback) nothrow @nogc vis_waveform_listen; 988 void function(void *ctx) nothrow @nogc vis_waveform_unlisten; 989 990 // register/unregister for getting continuous spectrum (frequency domain) data 991 // mainly for visualization 992 // ctx must be unique 993 // the data always contains DDB_FREQ_BANDS frames 994 // max number of channels is DDB_FREQ_MAX_CHANNELS 995 // the samples are non-interleaved 996 void function(void *ctx, void function(void *ctx, ddb_audio_data_t *data) callback) nothrow @nogc vis_spectrum_listen; 997 void function(void *ctx) nothrow @nogc vis_spectrum_unlisten; 998 999 // this is useful to mute/unmute audio, and query the muted status, from 1000 // plugins, without touching the volume control 1001 void function(int mute) nothrow @nogc audio_set_mute; 1002 int function() nothrow @nogc audio_is_mute; 1003 1004 // this is useful for prompting a user when he attempts to quit the player 1005 // while something is working in background, e.g. the Converter, 1006 // and let him finish or cancel the background jobs. 1007 void function() nothrow @nogc background_job_increment; 1008 void function() nothrow @nogc background_job_decrement; 1009 int function() nothrow @nogc have_background_jobs; 1010 1011 // utility function to get plt idx from handle 1012 int function(ddb_playlist_t *plt) nothrow @nogc plt_get_idx; 1013 1014 // save referenced playlist in config 1015 // same as pl_save_current, but for index 1016 int function(int n) nothrow @nogc plt_save_n; 1017 1018 // same as pl_save_current, but for playlist pointer 1019 int function(ddb_playlist_t *plt) nothrow @nogc plt_save_config; 1020 1021 // register file added callback 1022 // the callback will be called for each file 1023 // the visibility is taken from plt_add_* arguments 1024 // the callback must return 0 to continue, or -1 to abort the operation. 1025 // returns ID 1026 int function(int function(ddb_fileadd_data_t *data, void *user_data) callback, void *user_data) nothrow @nogc listen_file_added; 1027 void function(int id) nothrow @nogc unlisten_file_added; 1028 1029 int function(void function(ddb_fileadd_data_t *data, void *user_data) callback_begin, void function(ddb_fileadd_data_t *data, void *user_data) callback_end, void *user_data) nothrow @nogc listen_file_add_beginend; 1030 void function(int id) nothrow @nogc unlisten_file_add_beginend; 1031 1032 // visibility is a number, which tells listeners about the caller. 1033 // the value DDB_FILEADD_VISIBILITY_GUI (or 0) is reserved for callers which 1034 // want the GUI to intercept the calls and show visual updates. 1035 // 1036 // this is the default value passed from plt_load, plt_add_dir, plt_add_file. 1037 // 1038 // the values up to 10 are registered for deadbeef itself, so please avoid 1039 // using them in your plugins, unless you really know what you're doing. 1040 // any values above 10 are free for any use. 1041 // 1042 // the "callback", if not NULL, will be called with the passed "user_data", 1043 // for each track. 1044 // 1045 // the registered listeners will be called too, the ddb_fileadd_data_t 1046 // has the visibility 1047 DB_playItem_t* function(int visibility, ddb_playlist_t *plt, ddb_playItem_t *after, in char *fname, int *pabort, int function(DB_playItem_t *it, void *user_data) callback, void *user_data) nothrow @nogc plt_load2; 1048 int function(int visibility, ddb_playlist_t *plt, in char *fname, int function(DB_playItem_t *it, void *user_data) callback, void *user_data) nothrow @nogc plt_add_file2; 1049 int function(int visibility, ddb_playlist_t *plt, in char *dirname, int function(DB_playItem_t *it, void *user_data) callback, void *user_data) nothrow @nogc plt_add_dir2; 1050 ddb_playItem_t* function(int visibility, ddb_playlist_t *playlist, ddb_playItem_t *after, in char *fname, int *pabort, int function(DB_playItem_t *it, void *user_data) callback, void *user_data) nothrow @nogc plt_insert_file2; 1051 ddb_playItem_t* function(int visibility, ddb_playlist_t *plt, ddb_playItem_t *after, in char *dirname, int *pabort, int function(DB_playItem_t *it, void *user_data) callback, void *user_data) nothrow @nogc plt_insert_dir2; 1052 1053 // request lock for adding files to playlist 1054 // returns 0 on success 1055 // this function may return -1 if it is not possible to add files right now. 1056 // caller must cancel operation in this case, 1057 // or wait until previous operation finishes 1058 // NOTE: it's not guaranteed that all deadbeef versions support 1059 // adding the files to different playlists in parallel. 1060 int function(ddb_playlist_t *plt, int visibility) nothrow @nogc plt_add_files_begin; 1061 1062 // release the lock for adding files to playlist 1063 // end must be called when add files operation is finished 1064 void function(ddb_playlist_t *plt, int visibility) nothrow @nogc plt_add_files_end; 1065 1066 // deselect all tracks in playlist 1067 void function(ddb_playlist_t *plt) nothrow @nogc plt_deselect_all; 1068 } 1069 // since 1.6 1070 static if (DDB_API_LEVEL >= 6) { 1071 void function(ddb_playlist_t *plt, int scroll) nothrow @nogc plt_set_scroll; 1072 int function(ddb_playlist_t *plt) nothrow @nogc plt_get_scroll; 1073 } 1074 1075 // since 1.8 1076 static if (DDB_API_LEVEL >= 8) { 1077 // **** title formatting v2 **** 1078 1079 // compile the input title formatting string into bytecode 1080 // script: freeform string with title formatting special characters in it 1081 // returns the pointer to compiled bytecode, which must be tf_free'd by the caller. 1082 char * function(in char *script) nothrow @nogc tf_compile; 1083 1084 // free the code returned by tf_compile 1085 void function(char *code) nothrow @nogc tf_free; 1086 1087 // evaluate the titleformatting script in a given context 1088 // ctx: a pointer to ddb_tf_context_t structure initialized by the caller 1089 // code: the bytecode data created by tf_compile 1090 // out: buffer allocated by the caller, must be big enough to fit the output string 1091 // outlen: the size of out buffer 1092 // returns -1 on fail, output size on success 1093 int function(ddb_tf_context_t *ctx, in char *code, char *output, int outlen) nothrow @nogc tf_eval; 1094 1095 // sort using title formatting v2 1096 void function(ddb_playlist_t *plt, int iter, int id, in char *format, int order) nothrow @nogc plt_sort_v2; 1097 1098 // playqueue APIs 1099 int function(DB_playItem_t *it) nothrow @nogc playqueue_push; 1100 void function() nothrow @nogc playqueue_pop; 1101 void function(DB_playItem_t *it) nothrow @nogc playqueue_remove; 1102 void function() nothrow @nogc playqueue_clear; 1103 int function(DB_playItem_t *it) nothrow @nogc playqueue_test; 1104 int function() nothrow @nogc playqueue_get_count; 1105 DB_playItem_t* function(int n) nothrow @nogc playqueue_get_item; 1106 int function(int n) nothrow @nogc playqueue_remove_nth; 1107 void function(int n, DB_playItem_t *it) nothrow @nogc playqueue_insert_at; 1108 1109 // system directory API, returns path by id from ddb_sys_directory_t enum 1110 immutable char * function(int dir_id) nothrow @nogc get_system_dir; 1111 1112 // set the selected playlist for the ongoing plugin action. 1113 // the "set" function is expected to be called by the UI plugin, 1114 // while the "get" is expected to be called by the action code. 1115 void function(ddb_playlist_t *plt) nothrow @nogc action_set_playlist; 1116 1117 // returns one of: 1118 // selected playlist for context menu for the DDB_ACTION_CTX_PLAYLIST, 1119 // or the current active playlist for any other context. 1120 // returned value cannot be NULL 1121 // returned value is refcounted, so remember to call plt_unref. 1122 ddb_playlist_t* function() nothrow @nogc action_get_playlist; 1123 1124 // convert legacy title formatting to the new format, usable with tf_compile 1125 void function(in char *fmt, char *output, int outsize) nothrow @nogc tf_import_legacy; 1126 } 1127 } 1128 1129 // NOTE: an item placement must be selected like this 1130 // if (flags & DB_ACTION_COMMON) -> main menu, or nowhere, or where GUI plugin wants 1131 // basically, to put it into main menu, prefix the item title with the menu name 1132 // e.g. title = "File/MyItem" --> this will add the item under File menu 1133 // 1134 // if (flags & PLAYLIST) -> playlist (tab) context menu 1135 // 1136 // if (none of the above) -> track context menu 1137 1138 enum { 1139 /* Action in main menu (or whereever ui prefers) */ 1140 DB_ACTION_COMMON = 1 << 0, 1141 1142 /* Can handle single track */ 1143 DB_ACTION_SINGLE_TRACK = 1 << 1, 1144 1145 /* Can handle multiple tracks */ 1146 DB_ACTION_MULTIPLE_TRACKS = 1 << 2, 1147 1148 /* DEPRECATED in API 1.5 */ 1149 DB_ACTION_ALLOW_MULTIPLE_TRACKS = 1 << 2, 1150 1151 /* DEPRECATED in API 1.5, ignored in callback2 */ 1152 /* Action can (and prefer) traverse multiple tracks by itself */ 1153 DB_ACTION_CAN_MULTIPLE_TRACKS = 1 << 3, 1154 1155 /* Action is inactive */ 1156 DB_ACTION_DISABLED = 1 << 4, 1157 1158 /* DEPRECATED in API 1.5, ignored in callback2 */ 1159 /* since 1.2 */ 1160 /* Action for the playlist (tab) */ 1161 DB_ACTION_PLAYLIST = 1 << 5, 1162 1163 /* add item to menu(s), if contains slash symbol(s) */ 1164 DB_ACTION_ADD_MENU = 1 << 6 1165 }; 1166 1167 // action contexts 1168 // since 1.5 1169 static if (DDB_API_LEVEL >= 5) { 1170 enum { 1171 DDB_ACTION_CTX_MAIN, 1172 DDB_ACTION_CTX_SELECTION, 1173 // NOTE: starting with API 1.8, plugins should be using the 1174 // action_get_playlist function for getting the playlist pointer. 1175 DDB_ACTION_CTX_PLAYLIST, 1176 DDB_ACTION_CTX_NOWPLAYING, 1177 DDB_ACTION_CTX_COUNT 1178 }; 1179 } 1180 1181 alias DB_plugin_action_callback_t = int function(DB_plugin_action_s *action, void *userdata); 1182 static if (DDB_API_LEVEL >= 5) { 1183 alias DB_plugin_action_callback2_t = int function(DB_plugin_action_s *action, int ctx); 1184 } 1185 1186 struct DB_plugin_action_s { 1187 const char *title; 1188 const char *name; 1189 uint flags; 1190 // the use of "callback" is deprecated, 1191 // only use it if the code must be compatible with API 1.4 1192 // otherwise switch to callback2 1193 DB_plugin_action_callback_t callback; 1194 DB_plugin_action_s *next; 1195 static if (DDB_API_LEVEL >= 5) { 1196 DB_plugin_action_callback2_t callback2; 1197 } 1198 } 1199 alias DB_plugin_action_t = DB_plugin_action_s; 1200 1201 // base plugin interface 1202 struct DB_plugin_s { 1203 // type must be one of DB_PLUGIN_ types 1204 int type; 1205 // api version 1206 short api_vmajor; 1207 short api_vminor; 1208 // plugin version 1209 short version_major; 1210 short version_minor; 1211 1212 uint flags; // currently unused 1213 uint reserved1; 1214 uint reserved2; 1215 uint reserved3; 1216 1217 // any of those can be left NULL 1218 // though it's much better to fill them with something useful 1219 immutable char *id; // id used for serialization and runtime binding 1220 immutable char *name; // short name 1221 immutable char *descr; // short description (what the plugin is doing) 1222 immutable char *copyright; // copyright notice(s), list of developers, links to original works, etc 1223 immutable char *website; // plugin website 1224 1225 // plugin-specific command interface; can be NULL 1226 int function(int cmd, ...) command; 1227 1228 // start is called to start plugin; can be NULL 1229 int function() start; 1230 1231 // stop is called to deinit plugin; can be NULL 1232 int function() stop; 1233 1234 // connect is called to setup connections between different plugins 1235 // it is called after all plugin's start method was executed 1236 // can be NULL 1237 // NOTE for GUI plugin developers: don't initialize your widgets/windows in 1238 // the connect method. look for up-to-date information on wiki: 1239 // http://github.com/Alexey-Yakovenko/deadbeef/wiki/Porting-GUI-plugins-to-deadbeef-from-0.5.x-to-0.6.0 1240 int function() connect; 1241 1242 // opposite of connect, will be called before stop, while all plugins are still 1243 // in "started" state 1244 int function() disconnect; 1245 1246 // exec_cmdline may be called at any moment when user sends commandline to player 1247 // can be NULL if plugin doesn't support commandline processing 1248 // cmdline is 0-separated list of strings, guaranteed to have 0 at the end 1249 // cmdline_size is number of bytes pointed by cmdline 1250 int function(in char *cmdline, int cmdline_size) exec_cmdline; 1251 1252 // @returns linked list of actions for the specified track 1253 // when it is NULL -- the plugin must return list of all actions 1254 DB_plugin_action_t* function(DB_playItem_t *it) get_actions; 1255 1256 // mainloop will call this function for every plugin 1257 // so that plugins may handle all events; 1258 // can be NULL 1259 int function(uint id, uintptr_t ctx, uint p1, uint p2) message; 1260 1261 // plugin configuration dialog is constructed from this data 1262 // can be NULL 1263 immutable char *configdialog; 1264 } 1265 alias DB_plugin_t = DB_plugin_s; 1266 1267 // file format stuff 1268 1269 // channel mask - combine following flags to tell streamer which channels are 1270 // present in input/output streams 1271 enum { 1272 DDB_SPEAKER_FRONT_LEFT = 0x1, 1273 DDB_SPEAKER_FRONT_RIGHT = 0x2, 1274 DDB_SPEAKER_FRONT_CENTER = 0x4, 1275 DDB_SPEAKER_LOW_FREQUENCY = 0x8, 1276 DDB_SPEAKER_BACK_LEFT = 0x10, 1277 DDB_SPEAKER_BACK_RIGHT = 0x20, 1278 DDB_SPEAKER_FRONT_LEFT_OF_CENTER = 0x40, 1279 DDB_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80, 1280 DDB_SPEAKER_BACK_CENTER = 0x100, 1281 DDB_SPEAKER_SIDE_LEFT = 0x200, 1282 DDB_SPEAKER_SIDE_RIGHT = 0x400, 1283 DDB_SPEAKER_TOP_CENTER = 0x800, 1284 DDB_SPEAKER_TOP_FRONT_LEFT = 0x1000, 1285 DDB_SPEAKER_TOP_FRONT_CENTER = 0x2000, 1286 DDB_SPEAKER_TOP_FRONT_RIGHT = 0x4000, 1287 DDB_SPEAKER_TOP_BACK_LEFT = 0x8000, 1288 DDB_SPEAKER_TOP_BACK_CENTER = 0x10000, 1289 DDB_SPEAKER_TOP_BACK_RIGHT = 0x20000 1290 } 1291 1292 struct DB_fileinfo_s { 1293 DB_decoder_s *plugin; 1294 1295 // these parameters should be set in decoder->open 1296 ddb_waveformat_t fmt; 1297 1298 // readpos should be updated to current decoder time (in seconds) 1299 float readpos; 1300 1301 // this is the (optional) file handle, that can be used by streamer to 1302 // request interruption of current read operation 1303 DB_FILE *file; 1304 } 1305 alias DB_fileinfo_t = DB_fileinfo_s; 1306 1307 // Decoders should try to output 16 bit stream when this flag is set, for 1308 // performance reasons. 1309 enum DDB_DECODER_HINT_16BIT = 0x1; 1310 static if (DDB_API_LEVEL >= 8) { 1311 enum { 1312 // Decoders should only call the streamer_set_bitrate from plugin.read function, 1313 // and only when this flag is set. 1314 DDB_DECODER_HINT_NEED_BITRATE = 0x2, 1315 // Decoders can do their own infinite looping when this flag is set, in the 1316 // "Loop Single" looping mode. 1317 DDB_DECODER_HINT_CAN_LOOP = 0x4, 1318 } 1319 } 1320 1321 // decoder plugin 1322 struct DB_decoder_s { 1323 DB_plugin_t plugin; 1324 1325 DB_fileinfo_t* function(uint hints) open; 1326 1327 // init is called to prepare song to be started 1328 int function(DB_fileinfo_t *info, DB_playItem_t *it) init; 1329 1330 // free is called after decoding is finished 1331 void function(DB_fileinfo_t *info) free; 1332 1333 // read is called by streamer to decode specified number of bytes 1334 // must return number of bytes that were successfully decoded (sample aligned) 1335 int function(DB_fileinfo_t *info, char *buffer, int nbytes) read; 1336 1337 int function(DB_fileinfo_t *info, float seconds) seek; 1338 1339 // perform seeking in samples (if possible) 1340 // return -1 if failed, or 0 on success 1341 // if -1 is returned, that will mean that streamer must skip that song 1342 int function(DB_fileinfo_t *info, int sample) seek_sample; 1343 1344 // 'insert' is called to insert new item to playlist 1345 // decoder is responsible to calculate duration, split it into subsongs, load cuesheet, etc 1346 // after==NULL means "prepend before 1st item in playlist" 1347 DB_playItem_t* function(ddb_playlist_t *plt, DB_playItem_t *after, in char *fname) insert; 1348 1349 int function(DB_fileinfo_t *info) numvoices; 1350 void function(DB_fileinfo_t *info, int voice, int mute) mutevoice; 1351 1352 int function(DB_playItem_t *it) read_metadata; 1353 int function(DB_playItem_t *it) write_metadata; 1354 1355 // NULL terminated array of all supported extensions 1356 // examples: 1357 // { "aac", "wma", "tak", NULL } -- supports 3 file extensions 1358 // since API 1.9: { "*", NULL } -- supports any file extensions 1359 immutable char **exts; 1360 1361 // NULL terminated array of all supported prefixes (UADE support needs that) 1362 // e.g. "mod.song_title" 1363 immutable char **prefixes; 1364 1365 static if (DDB_API_LEVEL >= 7) { 1366 // This function's purpose is to open the file, so that the file handle is 1367 // immediately accessible via DB_fileinfo_t, and can be used with fabort. 1368 // If a plugin is using open2, it should not reopen the file from init. 1369 // Plugins _must_ implement open even if open2 is present, 1370 // because existing code may rely on it. 1371 DB_fileinfo_t* function(uint hints, DB_playItem_t *it) open2; 1372 } 1373 } 1374 alias DB_decoder_t = DB_decoder_s; 1375 1376 // output plugin 1377 struct DB_output_s { 1378 DB_plugin_t plugin; 1379 // init is called once at plugin activation 1380 int function() init; 1381 // free is called if output plugin was changed to another, or unload is about to happen 1382 int function() free; 1383 // reconfigure output to another format 1384 int function(ddb_waveformat_t *fmt) setformat; 1385 // play, stop, pause, unpause are called by deadbeef in response to user 1386 // events, or as part of streaming process 1387 int function() play; 1388 int function() stop; 1389 int function() pause; 1390 int function() unpause; 1391 // one of output_state_t enum values 1392 int function() state; 1393 // soundcard enumeration (can be NULL) 1394 void function(void function(in char *name, in char *desc, void*) callback, void *userdata) enum_soundcards; 1395 1396 // parameters of current output 1397 ddb_waveformat_t fmt; 1398 1399 // set to 1 if volume control is done internally by plugin 1400 int has_volume; 1401 } 1402 alias DB_output_t = DB_output_s; 1403 1404 /+ 1405 // dsp plugin 1406 // see also: examples/dsp_template.c in git 1407 #define DDB_INIT_DSP_CONTEXT(var,type,plug) {\ 1408 memset(var,0,sizeof(type));\ 1409 var->ctx.plugin=plug;\ 1410 var->ctx.enabled=1;\ 1411 } 1412 +/ 1413 1414 struct ddb_dsp_context_s { 1415 // pointer to DSP plugin which created this context 1416 DB_dsp_s *plugin; 1417 1418 // pointer to the next DSP plugin context in the chain 1419 ddb_dsp_context_s *next; 1420 1421 /+ wut? +/ 1422 // read only flag; set by DB_dsp_t::enable 1423 //unsigned enabled : 1; 1424 } 1425 alias ddb_dsp_context_t = ddb_dsp_context_s; 1426 1427 struct DB_dsp_s { 1428 DB_plugin_t plugin; 1429 1430 ddb_dsp_context_t* function() open; 1431 1432 void function(ddb_dsp_context_t *ctx) close; 1433 1434 // samples are always interleaved floating point 1435 // returned value is number of output frames (multichannel samples) 1436 // plugins are allowed to modify channels, samplerate, channelmask in the fmt structure 1437 // buffer size can fit up to maxframes frames 1438 // by default ratio=1, and plugins don't need to touch it unless they have to 1439 int function(ddb_dsp_context_t *ctx, float *samples, int frames, int maxframes, ddb_waveformat_t *fmt, float *ratio) process; 1440 1441 void function(ddb_dsp_context_t *ctx) reset; 1442 1443 // num_params can be NULL, to indicate that plugin doesn't expose any params 1444 // 1445 // if num_params is non-NULL -- get_param_name, set_param and get_param must 1446 // all be implemented 1447 // 1448 // param names are for display-only, and are allowed to contain spaces 1449 int function() num_params; 1450 immutable char * function(int p) get_param_name; 1451 void function(ddb_dsp_context_t *ctx, int p, in char *val) set_param; 1452 void function(ddb_dsp_context_t *ctx, int p, char *str, int len) get_param; 1453 1454 // config dialog implementation uses set/get param, so they must be 1455 // implemented if this is nonzero 1456 immutable char *configdialog; 1457 1458 // since 1.1 1459 static if (DDB_API_LEVEL >= 1) { 1460 // can be NULL 1461 // should return 1 if the DSP plugin will not touch data with the current parameters; 1462 // 0 otherwise 1463 int function(ddb_dsp_context_t *ctx, ddb_waveformat_t *fmt) can_bypass; 1464 } 1465 } 1466 alias DB_dsp_t = DB_dsp_s; 1467 1468 // misc plugin 1469 // purpose is to provide extra services 1470 // e.g. scrobbling, converting, tagging, custom gui, etc. 1471 // misc plugins should be mostly event driven, so no special entry points in them 1472 struct DB_misc_t { 1473 DB_plugin_t plugin; 1474 } ; 1475 1476 // vfs plugin 1477 // provides means for reading, seeking, etc 1478 // api is based on stdio 1479 struct DB_vfs_s { 1480 DB_plugin_t plugin; 1481 1482 // capabilities 1483 immutable char ** function() get_schemes; // NULL-terminated list of supported schemes, e.g. {"http://", "ftp://", NULL}; can be NULL 1484 1485 int function() is_streaming; // return 1 if the plugin streaming data over slow connection, e.g. http; plugins will avoid scanning entire files if this is the case 1486 1487 int function(in char *fname) is_container; // should return 1 if this plugin can parse specified file 1488 1489 // this allows interruption of hanging network streams 1490 void function(DB_FILE *stream) abort; 1491 1492 // file access, follows stdio API with few extension 1493 DB_FILE* function(in char *fname) open; 1494 void function(DB_FILE *f) close; 1495 size_t function(void *ptr, size_t size, size_t nmemb, DB_FILE *stream) read; 1496 int function(DB_FILE *stream, long offset, int whence) seek; 1497 long function(DB_FILE *stream) tell; 1498 void function(DB_FILE *stream) rewind; 1499 long function(DB_FILE *stream) getlength; 1500 1501 // should return mime-type of a stream, if known; can be NULL 1502 immutable char * function(DB_FILE *stream) get_content_type; 1503 1504 // associates stream with a track, to allow dynamic metadata updating, like 1505 // in icy protocol 1506 void function(DB_FILE *f, DB_playItem_t *it) set_track; 1507 1508 // folder access, follows dirent API, and uses dirent data structures 1509 int function(in char *dir, dirent ***namelist, int function(in dirent *) selector, int function(in dirent **, in dirent **) cmp) scandir; 1510 1511 static if (DDB_API_LEVEL >= 6) { 1512 // returns URI scheme for a given file name, e.g. "zip://" 1513 // can be NULL 1514 // can return NULL 1515 immutable char * function(in char *fname) get_scheme_for_name; 1516 } 1517 } 1518 alias DB_vfs_t = DB_vfs_s; 1519 1520 // gui plugin 1521 // only one gui plugin can be running at the same time 1522 // should provide GUI services to other plugins 1523 1524 // this structure represents a gui dialog with callbacks to set/get params 1525 // documentation should be available here: 1526 // http://github.com/Alexey-Yakovenko/deadbeef/wiki/GUI-Script-Syntax 1527 struct ddb_dialog_t { 1528 immutable char *title; 1529 immutable char *layout; 1530 void function(in char *key, in char *value) set_param; 1531 void function(in char *key, char *value, int len, in char *def) get_param; 1532 1533 static if (DDB_API_LEVEL >= 4) { 1534 void *parent; 1535 } 1536 } 1537 1538 enum { 1539 ddb_button_ok, 1540 ddb_button_cancel, 1541 ddb_button_close, 1542 ddb_button_apply, 1543 ddb_button_yes, 1544 ddb_button_no, 1545 ddb_button_max, 1546 }; 1547 1548 struct DB_gui_s { 1549 DB_plugin_t plugin; 1550 1551 // returns response code (ddb_button_*) 1552 // buttons is a bitset, e.g. (1<<ddb_button_ok)|(1<<ddb_button_cancel) 1553 int function(ddb_dialog_t *dlg, uint buttons, int function(int button, void *ctx) callback, void *ctx) run_dialog; 1554 } 1555 alias DB_gui_t = DB_gui_s; 1556 1557 // playlist plugin 1558 struct DB_playlist_s { 1559 DB_plugin_t plugin; 1560 1561 DB_playItem_t* function(ddb_playlist_t *plt, DB_playItem_t *after, in char *fname, int *pabort, int function(DB_playItem_t *it, void *data) cb, void *user_data) load; 1562 1563 // will save items from first to last (inclusive) 1564 // format is determined by extension 1565 // playlist is protected from changes during the call 1566 int function(ddb_playlist_t *plt, in char *fname, DB_playItem_t *first, DB_playItem_t *last) save; 1567 1568 immutable char **extensions; // NULL-terminated list of supported file extensions, e.g. {"m3u", "pls", NULL} 1569 1570 // since 1.5 1571 static if (DDB_API_LEVEL >= 5) { 1572 DB_playItem_t* function(int visibility, ddb_playlist_t *plt, DB_playItem_t *after, in char *fname, int *pabort) load2; 1573 } 1574 } 1575 alias DB_playlist_t = DB_playlist_s;