spotify 0.0.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
1
  module Spotify
2
- VERSION = [0, 0, 0].join('.')
2
+ VERSION = [7, 0, 0].join('.')
3
3
  end
@@ -0,0 +1,3096 @@
1
+ /*
2
+ * Copyright (c) 2006-2010 Spotify Ltd
3
+ *
4
+ * The terms of use for this and related files can be read in
5
+ * the associated LICENSE file, usually stored in share/doc/libspotify/LICENSE.
6
+ */
7
+
8
+ /**
9
+ * @file api.h Public API for libspotify
10
+ *
11
+ * @note All input strings are expected to be in UTF-8
12
+ * @note All output strings are in UTF-8.
13
+ *
14
+ * @note All usernames are valid XMPP nodeprep identifiers:
15
+ * http://tools.ietf.org/html/rfc3920#appendix-A
16
+ * If you need to store user data, we strongly advise you
17
+ * to use the canonical form of the username.
18
+ */
19
+
20
+ #ifndef PUBLIC_API_H
21
+ #define PUBLIC_API_H
22
+
23
+ #ifdef __cplusplus
24
+ extern "C" {
25
+ #endif
26
+
27
+ #ifndef SP_CALLCONV
28
+ #ifdef _WIN32
29
+ #define SP_CALLCONV __stdcall
30
+ #else
31
+ #define SP_CALLCONV
32
+ #endif
33
+ #endif
34
+
35
+ #ifndef SP_LIBEXPORT
36
+ #ifdef _WIN32
37
+ #define SP_LIBEXPORT(x) x __stdcall
38
+ #else
39
+ #define SP_LIBEXPORT(x) x
40
+ #endif
41
+ #endif
42
+
43
+ /* Includes */
44
+ #include <stddef.h>
45
+
46
+ #ifdef _WIN32
47
+ typedef unsigned __int64 sp_uint64;
48
+ #else
49
+ #include <stdint.h>
50
+ typedef uint64_t sp_uint64;
51
+ #endif
52
+
53
+ /* General types */
54
+
55
+ #if !defined(__cplusplus) && !defined(__bool_true_false_are_defined)
56
+ typedef unsigned char bool;
57
+ #endif
58
+
59
+ typedef unsigned char byte;
60
+
61
+ /**
62
+ * @defgroup types Spotify types & structs
63
+ *
64
+ * @{
65
+ */
66
+
67
+ typedef struct sp_session sp_session; ///< Representation of a session
68
+ typedef struct sp_track sp_track; ///< A track handle
69
+ typedef struct sp_album sp_album; ///< An album handle
70
+ typedef struct sp_artist sp_artist; ///< An artist handle
71
+ typedef struct sp_artistbrowse sp_artistbrowse; ///< A handle to an artist browse result
72
+ typedef struct sp_albumbrowse sp_albumbrowse; ///< A handle to an album browse result
73
+ typedef struct sp_toplistbrowse sp_toplistbrowse; ///< A handle to a toplist browse result
74
+ typedef struct sp_search sp_search; ///< A handle to a search result
75
+ typedef struct sp_link sp_link; ///< A handle to the libspotify internal representation of a URI
76
+ typedef struct sp_image sp_image; ///< A handle to an image
77
+ typedef struct sp_user sp_user; ///< A handle to a user
78
+ typedef struct sp_playlist sp_playlist; ///< A playlist handle
79
+ typedef struct sp_playlistcontainer sp_playlistcontainer; ///< A playlist container (playlist containing other playlists) handle
80
+ typedef struct sp_inbox sp_inbox; ///< Add to inbox request handle
81
+ /** @} */
82
+
83
+ /**
84
+ * @defgroup error Error Handling
85
+ *
86
+ * All functions in libspotify use the same set of error codes. Most of them return
87
+ * an error code, and let the result of the operation be stored in an out-parameter.
88
+ *
89
+ * @{
90
+ */
91
+
92
+ /**
93
+ * Error codes returned by various functions
94
+ */
95
+ typedef enum sp_error {
96
+ SP_ERROR_OK = 0, ///< No errors encountered
97
+ SP_ERROR_BAD_API_VERSION = 1, ///< The library version targeted does not match the one you claim you support
98
+ SP_ERROR_API_INITIALIZATION_FAILED = 2, ///< Initialization of library failed - are cache locations etc. valid?
99
+ SP_ERROR_TRACK_NOT_PLAYABLE = 3, ///< The track specified for playing cannot be played
100
+ SP_ERROR_RESOURCE_NOT_LOADED = 4, ///< One or several of the supplied resources is not yet loaded
101
+ SP_ERROR_BAD_APPLICATION_KEY = 5, ///< The application key is invalid
102
+ SP_ERROR_BAD_USERNAME_OR_PASSWORD = 6, ///< Login failed because of bad username and/or password
103
+ SP_ERROR_USER_BANNED = 7, ///< The specified username is banned
104
+ SP_ERROR_UNABLE_TO_CONTACT_SERVER = 8, ///< Cannot connect to the Spotify backend system
105
+ SP_ERROR_CLIENT_TOO_OLD = 9, ///< Client is too old, library will need to be updated
106
+ SP_ERROR_OTHER_PERMANENT = 10, ///< Some other error occured, and it is permanent (e.g. trying to relogin will not help)
107
+ SP_ERROR_BAD_USER_AGENT = 11, ///< The user agent string is invalid or too long
108
+ SP_ERROR_MISSING_CALLBACK = 12, ///< No valid callback registered to handle events
109
+ SP_ERROR_INVALID_INDATA = 13, ///< Input data was either missing or invalid
110
+ SP_ERROR_INDEX_OUT_OF_RANGE = 14, ///< Index out of range
111
+ SP_ERROR_USER_NEEDS_PREMIUM = 15, ///< The specified user needs a premium account
112
+ SP_ERROR_OTHER_TRANSIENT = 16, ///< A transient error occured.
113
+ SP_ERROR_IS_LOADING = 17, ///< The resource is currently loading
114
+ SP_ERROR_NO_STREAM_AVAILABLE = 18, ///< Could not find any suitable stream to play
115
+ SP_ERROR_PERMISSION_DENIED = 19, ///< Requested operation is not allowed
116
+ SP_ERROR_INBOX_IS_FULL = 20, ///< Target inbox is full
117
+ SP_ERROR_NO_CACHE = 21, ///< Cache is not enabled
118
+ SP_ERROR_NO_SUCH_USER = 22, ///< Requested user does not exist
119
+ } sp_error;
120
+
121
+ /**
122
+ * Convert a numeric libspotify error code to a text string
123
+ *
124
+ * @param[in] error The error code to lookup
125
+ */
126
+ SP_LIBEXPORT(const char*) sp_error_message(sp_error error);
127
+
128
+ /** @} */
129
+
130
+
131
+ /**
132
+ * @defgroup session Session handling
133
+ *
134
+ * The concept of a session is fundamental for all communication with the Spotify ecosystem - it is the
135
+ * object responsible for communicating with the Spotify service. You will need to instantiate a
136
+ * session that then can be used to request artist information, perform searches etc.
137
+ *
138
+ * @{
139
+ */
140
+
141
+ /**
142
+ * Current version of the application interface, that is, the API described by this file.
143
+ *
144
+ * This value should be set in the sp_session_config struct passed to sp_session_create().
145
+ *
146
+ * If an (upgraded) library is no longer compatible with this version the error #SP_ERROR_BAD_API_VERSION will be
147
+ * returned from sp_session_create(). Future versions of the library will provide you with some kind of mechanism
148
+ * to request an updated version of the library.
149
+ */
150
+ #define SPOTIFY_API_VERSION 7
151
+
152
+ /**
153
+ * Describes the current state of the connection
154
+ */
155
+ typedef enum sp_connectionstate {
156
+ SP_CONNECTION_STATE_LOGGED_OUT = 0, ///< User not yet logged in
157
+ SP_CONNECTION_STATE_LOGGED_IN = 1, ///< Logged in against a Spotify access point
158
+ SP_CONNECTION_STATE_DISCONNECTED = 2, ///< Was logged in, but has now been disconnected
159
+ SP_CONNECTION_STATE_UNDEFINED = 3, ///< The connection state is undefined
160
+ } sp_connectionstate;
161
+
162
+
163
+ /**
164
+ * Sample type descriptor
165
+ */
166
+ typedef enum sp_sampletype {
167
+ SP_SAMPLETYPE_INT16_NATIVE_ENDIAN = 0, ///< 16-bit signed integer samples
168
+ } sp_sampletype;
169
+
170
+ /**
171
+ * Audio format descriptor
172
+ */
173
+ typedef struct sp_audioformat {
174
+ sp_sampletype sample_type; ///< Sample type enum,
175
+ int sample_rate; ///< Audio sample rate, in samples per second.
176
+ int channels; ///< Number of channels. Currently 1 or 2.
177
+ } sp_audioformat;
178
+
179
+ /**
180
+ * Bitrate definitions for music streaming
181
+ */
182
+ typedef enum sp_bitrate {
183
+ SP_BITRATE_160k = 0,
184
+ SP_BITRATE_320k = 1,
185
+ } sp_bitrate;
186
+
187
+ /**
188
+ * Playlist types
189
+ */
190
+ typedef enum sp_playlist_type {
191
+ SP_PLAYLIST_TYPE_PLAYLIST = 0, ///< A normal playlist.
192
+ SP_PLAYLIST_TYPE_START_FOLDER = 1, ///< Marks a folder starting point,
193
+ SP_PLAYLIST_TYPE_END_FOLDER = 2, ///< and ending point.
194
+ SP_PLAYLIST_TYPE_PLACEHOLDER = 3, ///< Unknown entry.
195
+ } sp_playlist_type;
196
+
197
+ /**
198
+ * Buffer stats used by get_audio_buffer_stats callback
199
+ */
200
+ typedef struct sp_audio_buffer_stats {
201
+ int samples; ///< Samples in buffer
202
+ int stutter; ///< Number of stutters (audio dropouts) since last query
203
+ } sp_audio_buffer_stats;
204
+
205
+ /**
206
+ * List of subscribers returned by sp_playlist_subscribers()
207
+ */
208
+ typedef struct sp_subscribers {
209
+ unsigned int count;
210
+ char *subscribers[1]; ///< Actual size is 'count'. Array of pointers to canonical usernames
211
+ } sp_subscribers;
212
+
213
+
214
+ /**
215
+ * Session callbacks
216
+ *
217
+ * Registered when you create a session.
218
+ * If some callbacks should not be of interest, set them to NULL.
219
+ */
220
+ typedef struct sp_session_callbacks {
221
+
222
+ /**
223
+ * Called when login has been processed and was successful
224
+ *
225
+ * @param[in] session Session
226
+ * @param[in] error One of the following errors, from ::sp_error
227
+ * SP_ERROR_OK
228
+ * SP_ERROR_CLIENT_TOO_OLD
229
+ * SP_ERROR_UNABLE_TO_CONTACT_SERVER
230
+ * SP_ERROR_BAD_USERNAME_OR_PASSWORD
231
+ * SP_ERROR_USER_BANNED
232
+ * SP_ERROR_USER_NEEDS_PREMIUM
233
+ * SP_ERROR_OTHER_TRANSIENT
234
+ * SP_ERROR_OTHER_PERMANENT
235
+ */
236
+ void (SP_CALLCONV *logged_in)(sp_session *session, sp_error error);
237
+
238
+ /**
239
+ * Called when logout has been processed. Either called explicitly
240
+ * if you initialize a logout operation, or implicitly if there
241
+ * is a permanent connection error
242
+ *
243
+ * @param[in] session Session
244
+ */
245
+ void (SP_CALLCONV *logged_out)(sp_session *session);
246
+
247
+ /**
248
+ * Called whenever metadata has been updated
249
+ *
250
+ * If you have metadata cached outside of libspotify, you should purge
251
+ * your caches and fetch new versions.
252
+ *
253
+ * @param[in] session Session
254
+ */
255
+ void (SP_CALLCONV *metadata_updated)(sp_session *session);
256
+
257
+ /**
258
+ * Called when there is a connection error, and the library has problems
259
+ * reconnecting to the Spotify service. Could be called multiple times (as
260
+ * long as the problem is present)
261
+ *
262
+ *
263
+ * @param[in] session Session
264
+ * @param[in] error One of the following errors, from ::sp_error
265
+ * SP_ERROR_OK
266
+ * SP_ERROR_CLIENT_TOO_OLD
267
+ * SP_ERROR_UNABLE_TO_CONTACT_SERVER
268
+ * SP_ERROR_BAD_USERNAME_OR_PASSWORD
269
+ * SP_ERROR_USER_BANNED
270
+ * SP_ERROR_USER_NEEDS_PREMIUM
271
+ * SP_ERROR_OTHER_TRANSIENT
272
+ * SP_ERROR_OTHER_PERMANENT
273
+ */
274
+ void (SP_CALLCONV *connection_error)(sp_session *session, sp_error error);
275
+
276
+ /**
277
+ * Called when the access point wants to display a message to the user
278
+ *
279
+ * In the desktop client, these are shown in a blueish toolbar just below the
280
+ * search box.
281
+ *
282
+ * @param[in] session Session
283
+ * @param[in] message String in UTF-8 format.
284
+ */
285
+ void (SP_CALLCONV *message_to_user)(sp_session *session, const char *message);
286
+
287
+ /**
288
+ * Called when processing needs to take place on the main thread.
289
+ *
290
+ * You need to call sp_session_process_events() in the main thread to get
291
+ * libspotify to do more work. Failure to do so may cause request timeouts,
292
+ * or a lost connection.
293
+ *
294
+ * @param[in] session Session
295
+ *
296
+ * @note This function is called from an internal session thread - you need to have proper synchronization!
297
+ */
298
+ void (SP_CALLCONV *notify_main_thread)(sp_session *session);
299
+
300
+ /**
301
+ * Called when there is decompressed audio data available.
302
+ *
303
+ * @param[in] session Session
304
+ * @param[in] format Audio format descriptor sp_audioformat
305
+ * @param[in] frames Points to raw PCM data as described by \p format
306
+ * @param[in] num_frames Number of available samples in \p frames.
307
+ * If this is 0, a discontinuity has occured (such as after a seek). The application
308
+ * should flush its audio fifos, etc.
309
+ *
310
+ * @return Number of frames consumed.
311
+ * This value can be used to rate limit the output from the library if your
312
+ * output buffers are saturated. The library will retry delivery in about 100ms.
313
+ *
314
+ * @note This function is called from an internal session thread - you need to have proper synchronization!
315
+ *
316
+ * @note This function must never block. If your output buffers are full you must return 0 to signal
317
+ * that the library should retry delivery in a short while.
318
+ */
319
+ int (SP_CALLCONV *music_delivery)(sp_session *session, const sp_audioformat *format, const void *frames, int num_frames);
320
+
321
+ /**
322
+ * Music has been paused because only one account may play music at the same time.
323
+ *
324
+ * @param[in] session Session
325
+ */
326
+ void (SP_CALLCONV *play_token_lost)(sp_session *session);
327
+
328
+ /**
329
+ * Logging callback.
330
+ *
331
+ * @param[in] session Session
332
+ * @param[in] data Log data
333
+ */
334
+ void (SP_CALLCONV *log_message)(sp_session *session, const char *data);
335
+
336
+ /**
337
+ * End of track.
338
+ * Called when the currently played track has reached its end.
339
+ *
340
+ * @note This function is invoked from the same internal thread
341
+ * as the music delivery callback
342
+ *
343
+ * @param[in] session Session
344
+ */
345
+ void (SP_CALLCONV *end_of_track)(sp_session *session);
346
+
347
+ /**
348
+ * Streaming error.
349
+ * Called when streaming cannot start or continue
350
+ *
351
+ * @note This function is invoked from the main thread
352
+ *
353
+ * @param[in] session Session
354
+ * @param[in] error One of the following errors, from ::sp_error
355
+ * SP_ERROR_NO_STREAM_AVAILABLE
356
+ * SP_ERROR_OTHER_TRANSIENT
357
+ * SP_ERROR_OTHER_PERMANENT
358
+ */
359
+ void (SP_CALLCONV *streaming_error)(sp_session *session, sp_error error);
360
+
361
+ /**
362
+ * Called after user info (anything related to sp_user objects) have been updated.
363
+ *
364
+ * @param[in] session Session
365
+ */
366
+ void (SP_CALLCONV *userinfo_updated)(sp_session *session);
367
+
368
+ /**
369
+ * Called when audio playback should start
370
+ *
371
+ * @note For this to work correctly the application must also implement get_audio_buffer_stats()
372
+ *
373
+ * @note This function is called from an internal session thread - you need to have proper synchronization!
374
+ *
375
+ * @note This function must never block.
376
+ *
377
+ * @param[in] session Session
378
+ */
379
+ void (SP_CALLCONV *start_playback)(sp_session *session);
380
+
381
+
382
+ /**
383
+ * Called when audio playback should stop
384
+ *
385
+ * @note For this to work correctly the application must also implement get_audio_buffer_stats()
386
+ *
387
+ * @note This function is called from an internal session thread - you need to have proper synchronization!
388
+ *
389
+ * @note This function must never block.
390
+ *
391
+ * @param[in] session Session
392
+ */
393
+ void (SP_CALLCONV *stop_playback)(sp_session *session);
394
+
395
+ /**
396
+ * Called to query application about its audio buffer
397
+ *
398
+ * @note This function is called from an internal session thread - you need to have proper synchronization!
399
+ *
400
+ * @note This function must never block.
401
+ *
402
+ * @param[in] session Session
403
+ * @param[out] stats Stats struct to be filled by application
404
+ */
405
+ void (SP_CALLCONV *get_audio_buffer_stats)(sp_session *session, sp_audio_buffer_stats *stats);
406
+
407
+ } sp_session_callbacks;
408
+
409
+ /**
410
+ * Session config
411
+ */
412
+ typedef struct sp_session_config {
413
+ int api_version; ///< The version of the Spotify API your application is compiled with. Set to #SPOTIFY_API_VERSION
414
+ const char *cache_location; /**< The location where Spotify will write cache files.
415
+ * This cache include tracks, cached browse results and coverarts
416
+ * Set to empty string ("") to disable cache
417
+ */
418
+ const char *settings_location; /**< The location where Spotify will write setting files and per-user
419
+ * cache items. This includes playlists, track metadata, etc
420
+ */
421
+ const void *application_key; ///< Your application key
422
+ size_t application_key_size; ///< The size of the application key in bytes
423
+ const char *user_agent; /**< "User-Agent" for your application - max 255 characters long
424
+ The User-Agent should be a relevant, customer facing identification of your application
425
+ */
426
+
427
+ const sp_session_callbacks *callbacks; ///< Delivery callbacks for session events, or NULL if you are not interested in any callbacks (not recommended!)
428
+ void *userdata; ///< User supplied data for your application
429
+
430
+ /**
431
+ * Compress local copy of playlists, reduces disk space usage
432
+ */
433
+ bool compress_playlists;
434
+
435
+ /**
436
+ * Don't save metadata for local copies of playlists
437
+ * Reduces disk space usage at the expence of needing
438
+ * to request metadata from Spotify backend when loading list
439
+ */
440
+ bool dont_save_metadata_for_playlists;
441
+
442
+ /**
443
+ * Avoid loading playlists into RAM on startup.
444
+ * See sp_playlist_is_in_ram() for more details.
445
+ */
446
+ bool initially_unload_playlists;
447
+ } sp_session_config;
448
+
449
+ /**
450
+ * Initialize a session. The session returned will be initialized, but you will need
451
+ * to log in before you can perform any other operation
452
+ *
453
+ * Here is a snippet from \c spshell.c:
454
+ * @dontinclude spshell.c
455
+ * @skip config.api_version
456
+ * @until }
457
+ *
458
+ * @param[in] config The configuration to use for the session
459
+ * @param[out] sess If successful, a new session - otherwise NULL
460
+ *
461
+ * @return One of the following errors, from ::sp_error
462
+ * SP_ERROR_OK
463
+ * SP_ERROR_BAD_API_VERSION
464
+ * SP_ERROR_BAD_USER_AGENT
465
+ * SP_ERROR_BAD_APPLICATION_KEY
466
+ * SP_ERROR_API_INITIALIZATION_FAILED
467
+ */
468
+ SP_LIBEXPORT(sp_error) sp_session_create(const sp_session_config *config, sp_session **sess);
469
+
470
+ /**
471
+ * Release the session. This will clean up all data and connections associated with the session
472
+ *
473
+ * @param[in] sess Session object returned from sp_session_create()
474
+ */
475
+ SP_LIBEXPORT(void) sp_session_release(sp_session *sess);
476
+
477
+ /**
478
+ * Logs in the specified username/password combo. This initiates the download in the background.
479
+ * A callback is called when login is complete
480
+ *
481
+ * Here is a snippet from \c spshell.c:
482
+ * @dontinclude spshell.c
483
+ * @skip sp_session_login
484
+ * @until }
485
+ *
486
+ * @param[in] session Your session object
487
+ * @param[in] username The username to log in
488
+ * @param[in] password The password for the specified username
489
+ *
490
+ */
491
+ SP_LIBEXPORT(void) sp_session_login(sp_session *session, const char *username, const char *password);
492
+
493
+ /**
494
+ * Fetches the currently logged in user
495
+ *
496
+ * @param[in] session Your session object
497
+ *
498
+ * @return The logged in user (or NULL if not logged in)
499
+ */
500
+ SP_LIBEXPORT(sp_user *) sp_session_user(sp_session *session);
501
+
502
+ /**
503
+ * Logs out the currently logged in user
504
+ *
505
+ * Always call this before terminating the application and libspotify is currently
506
+ * logged in. Otherwise, the settings and cache may be lost.
507
+ *
508
+ * @param[in] session Your session object
509
+ */
510
+ SP_LIBEXPORT(void) sp_session_logout(sp_session *session);
511
+
512
+ /**
513
+ * The connection state of the specified session.
514
+ *
515
+ * @param[in] session Your session object
516
+ *
517
+ * @return The connection state - see the sp_connectionstate enum for possible values
518
+ */
519
+ SP_LIBEXPORT(sp_connectionstate) sp_session_connectionstate(sp_session *session);
520
+
521
+ /**
522
+ * The userdata associated with the session
523
+ *
524
+ * @param[in] session Your session object
525
+ *
526
+ * @return The userdata that was passed in on session creation
527
+ */
528
+ SP_LIBEXPORT(void *) sp_session_userdata(sp_session *session);
529
+
530
+ /**
531
+ * Set maximum cache size.
532
+ *
533
+ * @param[in] session Your session object
534
+ * @param[in] size Maximum cache size in megabytes.
535
+ * Setting it to 0 (the default) will let libspotify automatically
536
+ * resize the cache (10% of disk free space)
537
+ */
538
+ SP_LIBEXPORT(void) sp_session_set_cache_size(sp_session *session, size_t size);
539
+
540
+ /**
541
+ * Make the specified session process any pending events
542
+ *
543
+ * @param[in] session Your session object
544
+ * @param[out] next_timeout Stores the time (in milliseconds) until you should call this function again
545
+ */
546
+ SP_LIBEXPORT(void) sp_session_process_events(sp_session *session, int *next_timeout);
547
+
548
+ /**
549
+ * Loads the specified track
550
+ *
551
+ * After successfully loading the track, you have the option of running
552
+ * sp_session_player_play() directly, or using sp_session_player_seek() first.
553
+ * When this call returns, the track will have been loaded, unless an error occurred.
554
+ *
555
+ * @param[in] session Your session object
556
+ * @param[in] track The track to be loaded
557
+ *
558
+ * @return One of the following errors, from ::sp_error
559
+ * SP_ERROR_OK
560
+ * SP_ERROR_MISSING_CALLBACK
561
+ * SP_ERROR_RESOURCE_NOT_LOADED
562
+ * SP_ERROR_TRACK_NOT_PLAYABLE
563
+ *
564
+ */
565
+ SP_LIBEXPORT(sp_error) sp_session_player_load(sp_session *session, sp_track *track);
566
+
567
+ /**
568
+ * Seek to position in the currently loaded track
569
+ *
570
+ * @param[in] session Your session object
571
+ * @param[in] offset Track position, in milliseconds.
572
+ *
573
+ */
574
+ SP_LIBEXPORT(void) sp_session_player_seek(sp_session *session, int offset);
575
+
576
+ /**
577
+ * Play or pause the currently loaded track
578
+ *
579
+ * @param[in] session Your session object
580
+ * @param[in] play If set to true, playback will occur. If set to false, the playback will be paused.
581
+ *
582
+ */
583
+ SP_LIBEXPORT(void) sp_session_player_play(sp_session *session, bool play);
584
+
585
+ /**
586
+ * Stops the currently playing track
587
+ *
588
+ * This frees some resources held by libspotify to identify the currently
589
+ * playing track.
590
+ *
591
+ * @param[in] session Your session object
592
+ *
593
+ */
594
+ SP_LIBEXPORT(void) sp_session_player_unload(sp_session *session);
595
+
596
+ /**
597
+ * Prefetch a track
598
+ *
599
+ * Instruct libspotify to start loading of a track into its cache.
600
+ * This could be done by an application just before the current track ends.
601
+ *
602
+ * @param[in] session Your session object
603
+ * @param[in] track The track to be prefetched
604
+ *
605
+ * @return One of the following errors, from ::sp_error
606
+ * SP_ERROR_NO_CACHE
607
+ * SP_ERROR_OK
608
+ *
609
+ * @note Prefetching is only possible if a cache is configured
610
+ *
611
+ */
612
+ SP_LIBEXPORT(sp_error) sp_session_player_prefetch(sp_session *session, sp_track *track);
613
+
614
+ /**
615
+ * Returns the playlist container for the currently logged in user.
616
+ *
617
+ * @param[in] session Your session object
618
+ *
619
+ * @return Playlist container object, NULL if not logged in
620
+ */
621
+ SP_LIBEXPORT(sp_playlistcontainer *) sp_session_playlistcontainer(sp_session *session);
622
+
623
+ /**
624
+ * Returns an inbox playlist for the currently logged in user
625
+ *
626
+ * @param[in] session Session object
627
+ *
628
+ * @return A playlist.
629
+ * @note You need to release the playlist when you are done with it.
630
+ * @see sp_playlist_release()
631
+ */
632
+ SP_LIBEXPORT(sp_playlist *) sp_session_inbox_create(sp_session *session);
633
+
634
+ /**
635
+ * Returns the starred list for the current user
636
+ *
637
+ * @param[in] session Session object
638
+ *
639
+ * @return A playlist.
640
+ * @note You need to release the playlist when you are done with it.
641
+ * @see sp_playlist_release()
642
+ */
643
+ SP_LIBEXPORT(sp_playlist *) sp_session_starred_create(sp_session *session);
644
+
645
+ /**
646
+ * Returns the starred list for a user
647
+ *
648
+ * @param[in] session Session object
649
+ * @param[in] canonical_username Canonical username
650
+ *
651
+ * @return A playlist.
652
+ * @note You need to release the playlist when you are done with it.
653
+ * @see sp_playlist_release()
654
+ */
655
+ SP_LIBEXPORT(sp_playlist *) sp_session_starred_for_user_create(sp_session *session, const char *canonical_username);
656
+
657
+ /**
658
+ * Return the published container for a given @a canonical_username,
659
+ * or the currently logged in user if @a canonical_username is NULL.
660
+ *
661
+ * When done with the list you should call sp_playlistconatiner_release() to
662
+ * decrese the reference you own by having created it.
663
+ *
664
+ * @param[in] session Your session object.
665
+ * @param[in] canonical_username The canonical username, or NULL.
666
+ *
667
+ * @return Playlist container object, NULL if not logged in or not found.
668
+ */
669
+ SP_LIBEXPORT(sp_playlistcontainer *) sp_session_publishedcontainer_for_user_create(sp_session *session, const char *canonical_username);
670
+
671
+
672
+ /**
673
+ * Set preferred bitrate for music streaming
674
+ *
675
+ * @param[in] session Session object
676
+ * @param[in] bitrate Preferred bitrate, see ::sp_bitrate for possible values
677
+ *
678
+ */
679
+ SP_LIBEXPORT(void) sp_session_preferred_bitrate(sp_session *session, sp_bitrate bitrate);
680
+
681
+ /**
682
+ * Return number of friends in the currently logged in users friends list.
683
+ *
684
+ * @param[in] session Session object
685
+ *
686
+ * @return Number of users in friends. Each user can be extracted using the sp_session_friend() method
687
+ * The number of users in the list will not be updated nor change order between calls to
688
+ * sp_session_process_events()
689
+ */
690
+ SP_LIBEXPORT(int) sp_session_num_friends(sp_session *session);
691
+
692
+ /**
693
+ * Retrun the given user from the currently logged in users list of friends
694
+ *
695
+ * @param[in] session Session object
696
+ * @param[in] index Index in list
697
+ *
698
+ * @return A user. The object is owned by the session so the caller should not release it.
699
+ */
700
+ SP_LIBEXPORT(sp_user *) sp_session_friend(sp_session *session, int index);
701
+
702
+ /** @} */
703
+
704
+
705
+ /**
706
+ * @defgroup link Links (Spotify URIs)
707
+ *
708
+ * These functions handle links to Spotify entities in a way that allows you to
709
+ * not care about the textual representation of the link.
710
+ * @{
711
+ */
712
+
713
+ /**
714
+ * Link types
715
+ */
716
+ typedef enum {
717
+ SP_LINKTYPE_INVALID = 0, ///< Link type not valid - default until the library has parsed the link, or when parsing failed
718
+ SP_LINKTYPE_TRACK = 1, ///< Link type is track
719
+ SP_LINKTYPE_ALBUM = 2, ///< Link type is album
720
+ SP_LINKTYPE_ARTIST = 3, ///< Link type is artist
721
+ SP_LINKTYPE_SEARCH = 4, ///< Link type is search
722
+ SP_LINKTYPE_PLAYLIST = 5, ///< Link type is playlist
723
+ SP_LINKTYPE_PROFILE = 6, ///< Link type is profile
724
+ SP_LINKTYPE_STARRED = 7, ///< Link type is starred
725
+ SP_LINKTYPE_LOCALTRACK = 8, ///< Link type is a local file
726
+ } sp_linktype;
727
+
728
+ /**
729
+ * Create a Spotify link given a string
730
+ *
731
+ * @param[in] link A string representation of a Spotify link
732
+ *
733
+ * @return A link representation of the given string representation.
734
+ * If the link could not be parsed, this function returns NULL.
735
+ *
736
+ * @note You need to release the link when you are done with it.
737
+ * @see sp_link_type()
738
+ * @see sp_link_release()
739
+ */
740
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_string(const char *link);
741
+
742
+ /**
743
+ * Generates a link object from a track
744
+ *
745
+ * @param[in] track A track object
746
+ * @param[in] offset Offset in track in ms.
747
+ *
748
+ * @return A link representing the track
749
+ *
750
+ * @note You need to release the link when you are done with it.
751
+ * @see sp_link_release()
752
+ */
753
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_track(sp_track *track, int offset);
754
+
755
+ /**
756
+ * Create a link object from an album
757
+ *
758
+ * @param[in] album An album object
759
+ *
760
+ * @return A link representing the album
761
+ *
762
+ * @note You need to release the link when you are done with it.
763
+ * @see sp_link_release()
764
+ */
765
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_album(sp_album *album);
766
+
767
+ /**
768
+ * Creates a link object from an artist
769
+ *
770
+ * @param[in] artist An artist object
771
+ *
772
+ * @return A link object representing the artist
773
+ *
774
+ * @note You need to release the link when you are done with it.
775
+ * @see sp_link_release()
776
+ */
777
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_artist(sp_artist *artist);
778
+
779
+ /**
780
+ * Generate a link object representing the current search
781
+ *
782
+ * @param[in] search Search object
783
+ *
784
+ * @return A link representing the search
785
+ *
786
+ * @note You need to release the link when you are done with it.
787
+ * @see sp_link_release()
788
+ */
789
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_search(sp_search *search);
790
+
791
+ /**
792
+ * Create a link object representing the given playlist
793
+ *
794
+ * @param[in] playlist Playlist object
795
+ *
796
+ * @return A link representing the playlist
797
+ *
798
+ * @note You need to release the link when you are done with it.
799
+ * @see sp_link_release()
800
+ *
801
+ * @note Due to reasons in the playlist backend design and the Spotify URI
802
+ * scheme you need to wait for the playlist to be loaded before you can
803
+ * successfully construct an URI. If sp_link_create_from_playlist() returns
804
+ * NULL, try again after teh playlist_state_changed callback has fired.
805
+ */
806
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_playlist(sp_playlist *playlist);
807
+
808
+ /**
809
+ * Create a link object representing the given playlist
810
+ *
811
+ * @param[in] user User object
812
+ *
813
+ * @return A link representing the profile.
814
+ *
815
+ * @note You need to release the link when you are done with it.
816
+ * @see sp_link_release()
817
+ */
818
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_user(sp_user *user);
819
+
820
+ /**
821
+ * Create a string representation of the given Spotify link
822
+ *
823
+ * @param[in] link The Spotify link whose string representation you are interested in
824
+ * @param[out] buffer The buffer to hold the string representation of link
825
+ * @param[in] buffer_size The max size of the buffer that will hold the string representation
826
+ * The resulting string is guaranteed to always be null terminated if
827
+ * buffer_size > 0
828
+ *
829
+ * @return The number of characters in the string representation of the link. If this
830
+ * value is greater or equal than \p buffer_size, output was truncated.
831
+ */
832
+ SP_LIBEXPORT(int) sp_link_as_string(sp_link *link, char *buffer, int buffer_size);
833
+
834
+ /**
835
+ * The link type of the specified link
836
+ *
837
+ * @param[in] link The Spotify link whose type you are interested in
838
+ *
839
+ * @return The link type of the specified link - see the sp_linktype enum for possible values
840
+ */
841
+ SP_LIBEXPORT(sp_linktype) sp_link_type(sp_link *link);
842
+
843
+ /**
844
+ * The track representation for the given link
845
+ *
846
+ * @param[in] link The Spotify link whose track you are interested in
847
+ *
848
+ * @return The track representation of the given track link
849
+ * If the link is not of track type then NULL is returned.
850
+ */
851
+ SP_LIBEXPORT(sp_track *) sp_link_as_track(sp_link *link);
852
+
853
+ /**
854
+ * The track and offset into track representation for the given link
855
+ *
856
+ * @param[in] link The Spotify link whose track you are interested in
857
+ * @param[out] offset Pointer to offset into track (in seconds). If the link
858
+ * does not contain an offset this will be set to 0.
859
+ *
860
+ * @return The track representation of the given track link
861
+ * If the link is not of track type then NULL is returned.
862
+ */
863
+ SP_LIBEXPORT(sp_track *) sp_link_as_track_and_offset(sp_link *link, int *offset);
864
+
865
+ /**
866
+ * The album representation for the given link
867
+ *
868
+ * @param[in] link The Spotify link whose album you are interested in
869
+ *
870
+ * @return The album representation of the given album link
871
+ * If the link is not of album type then NULL is returned
872
+ */
873
+ SP_LIBEXPORT(sp_album *) sp_link_as_album(sp_link *link);
874
+
875
+ /**
876
+ * The artist representation for the given link
877
+ *
878
+ * @param[in] link The Spotify link whose artist you are interested in
879
+ *
880
+ * @return The artist representation of the given link
881
+ * If the link is not of artist type then NULL is returned
882
+ */
883
+ SP_LIBEXPORT(sp_artist *) sp_link_as_artist(sp_link *link);
884
+
885
+
886
+ /**
887
+ * The user representation for the given link
888
+ *
889
+ * @param[in] link The Spotify link whose user you are interested in
890
+ *
891
+ * @return The user representation of the given link
892
+ * If the link is not of user type then NULL is returned
893
+ */
894
+ SP_LIBEXPORT(sp_user *) sp_link_as_user(sp_link *link);
895
+
896
+
897
+ /**
898
+ * Increase the reference count of a link
899
+ *
900
+ * @param[in] link The link object
901
+ */
902
+ SP_LIBEXPORT(void) sp_link_add_ref(sp_link *link);
903
+
904
+ /**
905
+ * Decrease the reference count of a link
906
+ *
907
+ * @param[in] link The link object
908
+ */
909
+ SP_LIBEXPORT(void) sp_link_release(sp_link *link);
910
+
911
+ /** @} */
912
+
913
+
914
+
915
+ /**
916
+ * @defgroup track Track subsystem
917
+ * @{
918
+ */
919
+
920
+ /**
921
+ * Return whether or not the track metadata is loaded.
922
+ *
923
+ * @param[in] track The track
924
+ *
925
+ * @return True if track is loaded
926
+ *
927
+ * @note This is equivivalent to checking if sp_track_error() not returns SP_ERROR_IS_LOADING.
928
+ */
929
+ SP_LIBEXPORT(bool) sp_track_is_loaded(sp_track *track);
930
+
931
+ /**
932
+ * Return an error code associated with a track. For example if it could not load
933
+ *
934
+ * @param[in] track The track
935
+ *
936
+ * @return One of the following errors, from ::sp_error
937
+ * SP_ERROR_OK
938
+ * SP_ERROR_IS_LOADING
939
+ * SP_ERROR_OTHER_PERMANENT
940
+ */
941
+ SP_LIBEXPORT(sp_error) sp_track_error(sp_track *track);
942
+
943
+ /**
944
+ * Return true if the track is available for playback.
945
+ *
946
+ * @param[in] session Session
947
+ * @param[in] track The track
948
+ *
949
+ * @return True if track is available for playback, otherwise false.
950
+ *
951
+ * @note The track must be loaded or this function will always return false.
952
+ * @see sp_track_is_loaded()
953
+ */
954
+ SP_LIBEXPORT(bool) sp_track_is_available(sp_session *session, sp_track *track);
955
+
956
+ /**
957
+ * Return true if the track is a local file.
958
+ *
959
+ * @param[in] session Session
960
+ * @param[in] track The track
961
+ *
962
+ * @return True if track is a local file.
963
+ *
964
+ * @note The track must be loaded or this function will always return false.
965
+ * @see sp_track_is_loaded()
966
+ */
967
+ SP_LIBEXPORT(bool) sp_track_is_local(sp_session *session, sp_track *track);
968
+
969
+ /**
970
+ * Return true if the track is autolinked to another track.
971
+ *
972
+ * @param[in] session Session
973
+ * @param[in] track The track
974
+ *
975
+ * @return True if track is autolinked.
976
+ *
977
+ * @note The track must be loaded or this function will always return false.
978
+ * @see sp_track_is_loaded()
979
+ */
980
+ SP_LIBEXPORT(bool) sp_track_is_autolinked(sp_session *session, sp_track *track);
981
+
982
+ /**
983
+ * Return true if the track is starred by the currently logged in user.
984
+ *
985
+ * @param[in] session Session
986
+ * @param[in] track The track
987
+ *
988
+ * @return True if track is starred.
989
+ *
990
+ * @note The track must be loaded or this function will always return false.
991
+ * @see sp_track_is_loaded()
992
+ */
993
+ SP_LIBEXPORT(bool) sp_track_is_starred(sp_session *session, sp_track *track);
994
+
995
+ /**
996
+ * Star/Unstar the specified track
997
+ *
998
+ * @param[in] session Session
999
+ * @param[in] tracks Array of pointer to tracks.
1000
+ * @param[in] num_tracks Length of \p tracks array
1001
+ * @param[in] star Starred status of the track
1002
+ *
1003
+ * @note This will fail silently if playlists are disabled.
1004
+ * @see sp_set_playlists_enabled()
1005
+ */
1006
+ SP_LIBEXPORT(void) sp_track_set_starred(sp_session *session, const sp_track **tracks, int num_tracks, bool star);
1007
+
1008
+ /**
1009
+ * The number of artists performing on the specified track
1010
+ *
1011
+ * @param[in] track The track whose number of participating artists you are interested in
1012
+ *
1013
+ * @return The number of artists performing on the specified track.
1014
+ * If no metadata is available for the track yet, this function returns 0.
1015
+ */
1016
+ SP_LIBEXPORT(int) sp_track_num_artists(sp_track *track);
1017
+
1018
+ /**
1019
+ * The artist matching the specified index performing on the current track.
1020
+ *
1021
+ * @param[in] track The track whose participating artist you are interested in
1022
+ * @param[in] index The index for the participating artist. Should be in the interval [0, sp_track_num_artists() - 1]
1023
+ *
1024
+ * @return The participating artist, or NULL if invalid index
1025
+ */
1026
+ SP_LIBEXPORT(sp_artist *) sp_track_artist(sp_track *track, int index);
1027
+
1028
+ /**
1029
+ * The album of the specified track
1030
+ *
1031
+ * @param[in] track A track object
1032
+ *
1033
+ * @return The album of the given track. You need to increase the refcount
1034
+ * if you want to keep the pointer around.
1035
+ * If no metadata is available for the track yet, this function returns 0.
1036
+ */
1037
+ SP_LIBEXPORT(sp_album *) sp_track_album(sp_track *track);
1038
+
1039
+ /**
1040
+ * The string representation of the specified track's name
1041
+ *
1042
+ * @param[in] track A track object
1043
+ *
1044
+ * @return The string representation of the specified track's name.
1045
+ * Returned string is valid as long as the album object stays allocated
1046
+ * and no longer than the next call to sp_session_process_events()
1047
+ * If no metadata is available for the track yet, this function returns empty string.
1048
+ */
1049
+ SP_LIBEXPORT(const char *) sp_track_name(sp_track *track);
1050
+
1051
+ /**
1052
+ * The duration, in milliseconds, of the specified track
1053
+ *
1054
+ * @param[in] track A track object
1055
+ *
1056
+ * @return The duration of the specified track, in milliseconds
1057
+ * If no metadata is available for the track yet, this function returns 0.
1058
+ */
1059
+ SP_LIBEXPORT(int) sp_track_duration(sp_track *track);
1060
+
1061
+ /**
1062
+ * Returns popularity for track
1063
+ *
1064
+ * @param[in] track A track object
1065
+ *
1066
+ * @return Popularity in range 0 to 100, 0 if undefined
1067
+ * If no metadata is available for the track yet, this function returns 0.
1068
+ */
1069
+ SP_LIBEXPORT(int) sp_track_popularity(sp_track *track);
1070
+
1071
+ /**
1072
+ * Returns the disc number for a track
1073
+ *
1074
+ * @param[in] track A track object
1075
+ *
1076
+ * @return Disc index. Possible values are [1, total number of discs on album]
1077
+ * This function returns valid data only for tracks appearing in a browse
1078
+ * artist or browse album result (otherwise returns 0).
1079
+ */
1080
+ SP_LIBEXPORT(int) sp_track_disc(sp_track *track);
1081
+
1082
+ /**
1083
+ * Returns the position of a track on its disc
1084
+ *
1085
+ * @param[in] track A track object
1086
+ *
1087
+ * @return Track position, starts at 1 (relative the corresponding disc)
1088
+ * This function returns valid data only for tracks appearing in a browse
1089
+ * artist or browse album result (otherwise returns 0).
1090
+ */
1091
+ SP_LIBEXPORT(int) sp_track_index(sp_track *track);
1092
+
1093
+ /**
1094
+ * Returns the newly created local track
1095
+ *
1096
+ * @param[in] artist Name of the artist
1097
+ * @param[in] title Song title
1098
+ * @param[in] album Name of the album, or an empty string if not available
1099
+ * @param[in] length Length in MS, or -1 if not available.
1100
+ *
1101
+ * @return A track.
1102
+ */
1103
+ SP_LIBEXPORT(sp_track *) sp_localtrack_create(const char *artist, const char *title, const char *album, int length);
1104
+
1105
+ /**
1106
+ * Increase the reference count of a track
1107
+ *
1108
+ * @param[in] track The track object
1109
+ */
1110
+ SP_LIBEXPORT(void) sp_track_add_ref(sp_track *track);
1111
+
1112
+ /**
1113
+ * Decrease the reference count of a track
1114
+ *
1115
+ * @param[in] track The track object
1116
+ */
1117
+ SP_LIBEXPORT(void) sp_track_release(sp_track *track);
1118
+
1119
+ /** @} */
1120
+
1121
+
1122
+
1123
+ /**
1124
+ * @defgroup album Album subsystem
1125
+ * @{
1126
+ */
1127
+
1128
+ /**
1129
+ * Album types
1130
+ */
1131
+ typedef enum {
1132
+ SP_ALBUMTYPE_ALBUM = 0, ///< Normal album
1133
+ SP_ALBUMTYPE_SINGLE = 1, ///< Single
1134
+ SP_ALBUMTYPE_COMPILATION = 2, ///< Compilation
1135
+ SP_ALBUMTYPE_UNKNOWN = 3, ///< Unknown type
1136
+ } sp_albumtype;
1137
+
1138
+ /**
1139
+ * Check if the album object is populated with data
1140
+ *
1141
+ * @param[in] album Album object
1142
+ * @return True if metadata is present, false if not
1143
+ */
1144
+ SP_LIBEXPORT(bool) sp_album_is_loaded(sp_album *album);
1145
+
1146
+
1147
+ /**
1148
+ * Return true if the album is available in the current region.
1149
+ *
1150
+ * @param[in] album The album
1151
+ *
1152
+ * @return True if album is available for playback, otherwise false.
1153
+ *
1154
+ * @note The album must be loaded or this function will always return false.
1155
+ * @see sp_album_is_loaded()
1156
+ */
1157
+ SP_LIBEXPORT(bool) sp_album_is_available(sp_album *album);
1158
+
1159
+ /**
1160
+ * Get the artist associated with the given album
1161
+ *
1162
+ * @param[in] album Album object
1163
+ * @return A reference to the artist. NULL if the metadata has not been loaded yet
1164
+ */
1165
+ SP_LIBEXPORT(sp_artist *) sp_album_artist(sp_album *album);
1166
+
1167
+ /**
1168
+ * Return image ID representing the album's coverart.
1169
+ *
1170
+ * @param[in] album Album object
1171
+ *
1172
+ * @return ID byte sequence that can be passed to sp_image_create()
1173
+ * If the album has no image or the metadata for the album is not
1174
+ * loaded yet, this function returns NULL.
1175
+ *
1176
+ * @see sp_image_create
1177
+ */
1178
+ SP_LIBEXPORT(const byte *) sp_album_cover(sp_album *album);
1179
+
1180
+ /**
1181
+ * Return name of album
1182
+ *
1183
+ * @param[in] album Album object
1184
+ *
1185
+ * @return Name of album.
1186
+ * Returned string is valid as long as the album object stays allocated
1187
+ * and no longer than the next call to sp_session_process_events()
1188
+ */
1189
+ SP_LIBEXPORT(const char *) sp_album_name(sp_album *album);
1190
+
1191
+ /**
1192
+ * Return release year of specified album
1193
+ *
1194
+ * @param[in] album Album object
1195
+ *
1196
+ * @return Release year
1197
+ */
1198
+ SP_LIBEXPORT(int) sp_album_year(sp_album *album);
1199
+
1200
+
1201
+ /**
1202
+ * Return type of specified album
1203
+ *
1204
+ * @param[in] album Album object
1205
+ *
1206
+ * @return sp_albumtype
1207
+ */
1208
+ SP_LIBEXPORT(sp_albumtype) sp_album_type(sp_album *album);
1209
+
1210
+
1211
+ /**
1212
+ * Increase the reference count of an album
1213
+ *
1214
+ * @param[in] album The album object
1215
+ */
1216
+ SP_LIBEXPORT(void) sp_album_add_ref(sp_album *album);
1217
+
1218
+ /**
1219
+ * Decrease the reference count of an album
1220
+ *
1221
+ * @param[in] album The album object
1222
+ */
1223
+ SP_LIBEXPORT(void) sp_album_release(sp_album *album);
1224
+
1225
+ /** @} */
1226
+
1227
+
1228
+
1229
+ /**
1230
+ * @defgroup artist Artist subsystem
1231
+ * @{
1232
+ */
1233
+
1234
+ /**
1235
+ * Return name of artist
1236
+ *
1237
+ * @param[in] artist Artist object
1238
+ *
1239
+ * @return Name of artist.
1240
+ * Returned string is valid as long as the artist object stays allocated
1241
+ * and no longer than the next call to sp_session_process_events()
1242
+ */
1243
+ SP_LIBEXPORT(const char *) sp_artist_name(sp_artist *artist);
1244
+
1245
+ /**
1246
+ * Check if the artist object is populated with data
1247
+ *
1248
+ * @param[in] artist An artist object
1249
+ *
1250
+ * @return True if metadata is present, false if not
1251
+ *
1252
+ */
1253
+ SP_LIBEXPORT(bool) sp_artist_is_loaded(sp_artist *artist);
1254
+
1255
+
1256
+ /**
1257
+ * Increase the reference count of a artist
1258
+ *
1259
+ * @param[in] artist The artist object
1260
+ */
1261
+ SP_LIBEXPORT(void) sp_artist_add_ref(sp_artist *artist);
1262
+
1263
+ /**
1264
+ * Decrease the reference count of a artist
1265
+ *
1266
+ * @param[in] artist The artist object
1267
+ */
1268
+ SP_LIBEXPORT(void) sp_artist_release(sp_artist *artist);
1269
+
1270
+ /** @} */
1271
+
1272
+
1273
+ /**
1274
+ * @defgroup albumbrowse Album browsing
1275
+ *
1276
+ * Browsing adds additional information to what an ::sp_album holds. It retrieves
1277
+ * copyrights, reviews and tracks of the album.
1278
+ *
1279
+ * @{
1280
+ */
1281
+
1282
+ /**
1283
+ * The type of a callback used in sp_albumbrowse_create()
1284
+ *
1285
+ * When the callback is called, the metadata of all tracks belonging to it will have
1286
+ * been loaded, so sp_track_is_loaded() will return non-zero. The ::sp_artist of the
1287
+ * album will also have been fully loaded.
1288
+ *
1289
+ * @param[in] result The same pointer returned by sp_albumbrowse_create()
1290
+ * @param[in] userdata The opaque pointer given to sp_albumbrowse_create()
1291
+ */
1292
+ typedef void SP_CALLCONV albumbrowse_complete_cb(sp_albumbrowse *result, void *userdata);
1293
+
1294
+ /**
1295
+ * Initiate a request for browsing an album
1296
+ *
1297
+ * The user is responsible for freeing the returned album browse using sp_albumbrowse_release(). This can be done in the callback.
1298
+ *
1299
+ * @param[in] session Session object
1300
+ * @param[in] album Album to be browsed. The album metadata does not have to be loaded
1301
+ * @param[in] callback Callback to be invoked when browsing has been completed. Pass NULL if you are not interested in this event.
1302
+ * @param[in] userdata Userdata passed to callback.
1303
+ *
1304
+ * @return Album browse object
1305
+ *
1306
+ * @see ::albumbrowse_complete_cb
1307
+ */
1308
+ SP_LIBEXPORT(sp_albumbrowse *) sp_albumbrowse_create(sp_session *session, sp_album *album, albumbrowse_complete_cb *callback, void *userdata);
1309
+
1310
+ /**
1311
+ * Check if an album browse request is completed
1312
+ *
1313
+ * @param[in] alb Album browse object
1314
+ *
1315
+ * @return True if browsing is completed, false if not
1316
+ */
1317
+ SP_LIBEXPORT(bool) sp_albumbrowse_is_loaded(sp_albumbrowse *alb);
1318
+
1319
+
1320
+ /**
1321
+ * Check if browsing returned an error code.
1322
+ *
1323
+ * @param[in] alb Album browse object
1324
+ *
1325
+ * @return One of the following errors, from ::sp_error
1326
+ * SP_ERROR_OK
1327
+ * SP_ERROR_IS_LOADING
1328
+ * SP_ERROR_OTHER_PERMANENT
1329
+ * SP_ERROR_OTHER_TRANSIENT
1330
+ */
1331
+ SP_LIBEXPORT(sp_error) sp_albumbrowse_error(sp_albumbrowse *alb);
1332
+
1333
+ /**
1334
+ * Given an album browse object, return the pointer to its album object
1335
+ *
1336
+ * @param[in] alb Album browse object
1337
+ *
1338
+ * @return Album object
1339
+ */
1340
+ SP_LIBEXPORT(sp_album *) sp_albumbrowse_album(sp_albumbrowse *alb);
1341
+
1342
+ /**
1343
+ * Given an album browse object, return the pointer to its artist object
1344
+ *
1345
+ * @param[in] alb Album browse object
1346
+ *
1347
+ * @return Artist object
1348
+ */
1349
+ SP_LIBEXPORT(sp_artist *) sp_albumbrowse_artist(sp_albumbrowse *alb);
1350
+
1351
+ /**
1352
+ * Given an album browse object, return number of copyright strings
1353
+ *
1354
+ * @param[in] alb Album browse object
1355
+ *
1356
+ * @return Number of copyright strings available, 0 if unknown
1357
+ */
1358
+ SP_LIBEXPORT(int) sp_albumbrowse_num_copyrights(sp_albumbrowse *alb);
1359
+
1360
+ /**
1361
+ * Given an album browse object, return one of its copyright strings
1362
+ *
1363
+ * @param[in] alb Album browse object
1364
+ * @param[in] index The index for the copyright string. Should be in the interval [0, sp_albumbrowse_num_copyrights() - 1]
1365
+ *
1366
+ * @return Copyright string in UTF-8 format, or NULL if the index is invalid.
1367
+ * Returned string is valid as long as the album object stays allocated
1368
+ * and no longer than the next call to sp_session_process_events()
1369
+ */
1370
+ SP_LIBEXPORT(const char *) sp_albumbrowse_copyright(sp_albumbrowse *alb, int index);
1371
+
1372
+ /**
1373
+ * Given an album browse object, return number of tracks
1374
+ *
1375
+ * @param[in] alb Album browse object
1376
+ *
1377
+ * @return Number of tracks on album
1378
+ */
1379
+ SP_LIBEXPORT(int) sp_albumbrowse_num_tracks(sp_albumbrowse *alb);
1380
+
1381
+ /**
1382
+ * Given an album browse object, return a pointer to one of its tracks
1383
+ *
1384
+ * @param[in] alb Album browse object
1385
+ * @param[in] index The index for the track. Should be in the interval [0, sp_albumbrowse_num_tracks() - 1]
1386
+ *
1387
+ * @return A track.
1388
+ *
1389
+ * @see track
1390
+ */
1391
+ SP_LIBEXPORT(sp_track *) sp_albumbrowse_track(sp_albumbrowse *alb, int index);
1392
+
1393
+ /**
1394
+ * Given an album browse object, return its review
1395
+ *
1396
+ * @param[in] alb Album browse object
1397
+ *
1398
+ * @return Review string in UTF-8 format.
1399
+ * Returned string is valid as long as the album object stays allocated
1400
+ * and no longer than the next call to sp_session_process_events()
1401
+ */
1402
+ SP_LIBEXPORT(const char *) sp_albumbrowse_review(sp_albumbrowse *alb);
1403
+
1404
+
1405
+ /**
1406
+ * Increase the reference count of an album browse result
1407
+ *
1408
+ * @param[in] alb The album browse result object
1409
+ */
1410
+ SP_LIBEXPORT(void) sp_albumbrowse_add_ref(sp_albumbrowse *alb);
1411
+
1412
+ /**
1413
+ * Decrease the reference count of an album browse result
1414
+ *
1415
+ * @param[in] alb The album browse result object
1416
+ */
1417
+ SP_LIBEXPORT(void) sp_albumbrowse_release(sp_albumbrowse *alb);
1418
+
1419
+ /** @} */
1420
+
1421
+
1422
+ /**
1423
+ * @defgroup artistbrowse Artist browsing
1424
+ *
1425
+ * Artist browsing initiates the fetching of information for a certain artist.
1426
+ *
1427
+ * @note There is currently no built-in functionality available for getting the albums belonging
1428
+ * to an artist. For now, just iterate over all tracks and note the album to build a list of all albums.
1429
+ * This feature will be added in a future version of the library.
1430
+ *
1431
+ * @{
1432
+ */
1433
+
1434
+ /**
1435
+ * The type of a callback used in sp_artistbrowse_create()
1436
+ *
1437
+ * When the callback is called, the metadata of all tracks belonging to it will have
1438
+ * been loaded, so sp_track_is_loaded() will return non-zero. The same goes for the
1439
+ * similar artist data.
1440
+ *
1441
+ * @param[in] result The same pointer returned by sp_artistbrowse_create()
1442
+ * @param[in] userdata The opaque pointer given to sp_artistbrowse_create()
1443
+ */
1444
+ typedef void SP_CALLCONV artistbrowse_complete_cb(sp_artistbrowse *result, void *userdata);
1445
+
1446
+ /**
1447
+ * Initiate a request for browsing an artist
1448
+ *
1449
+ * The user is responsible for freeing the returned artist browse using sp_artistbrowse_release(). This can be done in the callback.
1450
+ *
1451
+ * @param[in] session Session object
1452
+ * @param[in] artist Artist to be browsed. The artist metadata does not have to be loaded
1453
+ * @param[in] callback Callback to be invoked when browsing has been completed. Pass NULL if you are not interested in this event.
1454
+ * @param[in] userdata Userdata passed to callback.
1455
+ *
1456
+ * @return Artist browse object
1457
+ *
1458
+ * @see ::artistbrowse_complete_cb
1459
+ */
1460
+ SP_LIBEXPORT(sp_artistbrowse *) sp_artistbrowse_create(sp_session *session, sp_artist *artist, artistbrowse_complete_cb *callback, void *userdata);
1461
+
1462
+ /**
1463
+ * Check if an artist browse request is completed
1464
+ *
1465
+ * @param[in] arb Artist browse object
1466
+ *
1467
+ * @return True if browsing is completed, false if not
1468
+ */
1469
+ SP_LIBEXPORT(bool) sp_artistbrowse_is_loaded(sp_artistbrowse *arb);
1470
+
1471
+ /**
1472
+ * Check if browsing returned an error code.
1473
+ *
1474
+ * @param[in] arb Artist browse object
1475
+ *
1476
+ * @return One of the following errors, from ::sp_error
1477
+ * SP_ERROR_OK
1478
+ * SP_ERROR_IS_LOADING
1479
+ * SP_ERROR_OTHER_PERMANENT
1480
+ * SP_ERROR_OTHER_TRANSIENT
1481
+ */
1482
+ SP_LIBEXPORT(sp_error) sp_artistbrowse_error(sp_artistbrowse *arb);
1483
+
1484
+ /**
1485
+ * Given an artist browse object, return a pointer to its artist object
1486
+ *
1487
+ * @param[in] arb Artist browse object
1488
+ *
1489
+ * @return Artist object
1490
+ */
1491
+ SP_LIBEXPORT(sp_artist *) sp_artistbrowse_artist(sp_artistbrowse *arb);
1492
+
1493
+ /**
1494
+ * Given an artist browse object, return number of portraits available
1495
+ *
1496
+ * @param[in] arb Artist browse object
1497
+ *
1498
+ * @return Number of portraits for given artist
1499
+ */
1500
+ SP_LIBEXPORT(int) sp_artistbrowse_num_portraits(sp_artistbrowse *arb);
1501
+
1502
+ /**
1503
+ * Return image ID representing a portrait of the artist
1504
+ *
1505
+ * @param[in] arb Artist object
1506
+ * @param[in] index The index of the portrait. Should be in the interval [0, sp_artistbrowse_num_portraits() - 1]
1507
+ *
1508
+ * @return ID byte sequence that can be passed to sp_image_create()
1509
+ *
1510
+ * @see sp_image_create
1511
+ */
1512
+ SP_LIBEXPORT(const byte *) sp_artistbrowse_portrait(sp_artistbrowse *arb, int index);
1513
+
1514
+ /**
1515
+ * Given an artist browse object, return number of tracks
1516
+ *
1517
+ * @param[in] arb Artist browse object
1518
+ *
1519
+ * @return Number of tracks for given artist
1520
+ */
1521
+ SP_LIBEXPORT(int) sp_artistbrowse_num_tracks(sp_artistbrowse *arb);
1522
+
1523
+ /**
1524
+ * Given an artist browse object, return one of its tracks
1525
+ *
1526
+ * @param[in] arb Album browse object
1527
+ * @param[in] index The index for the track. Should be in the interval [0, sp_artistbrowse_num_tracks() - 1]
1528
+ *
1529
+ * @return A track object, or NULL if the index is out of range.
1530
+ *
1531
+ * @see track
1532
+ */
1533
+ SP_LIBEXPORT(sp_track *) sp_artistbrowse_track(sp_artistbrowse *arb, int index);
1534
+
1535
+ /**
1536
+ * Given an artist browse object, return number of albums
1537
+ *
1538
+ * @param[in] arb Artist browse object
1539
+ *
1540
+ * @return Number of albums for given artist
1541
+ */
1542
+ SP_LIBEXPORT(int) sp_artistbrowse_num_albums(sp_artistbrowse *arb);
1543
+
1544
+ /**
1545
+ * Given an artist browse object, return one of its albums
1546
+ *
1547
+ * @param[in] arb Album browse object
1548
+ * @param[in] index The index for the album. Should be in the interval [0, sp_artistbrowse_num_albums() - 1]
1549
+ *
1550
+ * @return A album object, or NULL if the index is out of range.
1551
+ *
1552
+ * @see album
1553
+ */
1554
+ SP_LIBEXPORT(sp_album *) sp_artistbrowse_album(sp_artistbrowse *arb, int index);
1555
+
1556
+ /**
1557
+ * Given an artist browse object, return number of similar artists
1558
+ *
1559
+ * @param[in] arb Artist browse object
1560
+ *
1561
+ * @return Number of similar artists for given artist
1562
+ */
1563
+ SP_LIBEXPORT(int) sp_artistbrowse_num_similar_artists(sp_artistbrowse *arb);
1564
+
1565
+ /**
1566
+ * Given an artist browse object, return a similar artist by index
1567
+ *
1568
+ * @param[in] arb Album browse object
1569
+ * @param[in] index The index for the artist. Should be in the interval [0, sp_artistbrowse_num_similar_artists() - 1]
1570
+ *
1571
+ * @return A pointer to an artist object.
1572
+ *
1573
+ * @see artist
1574
+ */
1575
+ SP_LIBEXPORT(sp_artist *) sp_artistbrowse_similar_artist(sp_artistbrowse *arb, int index);
1576
+
1577
+ /**
1578
+ * Given an artist browse object, return the artists biography
1579
+ *
1580
+ * @note This function must be called from the same thread that did sp_session_create()
1581
+ * @param[in] arb Artist browse object
1582
+ *
1583
+ * @return Biography string in UTF-8 format.
1584
+ * Returned string is valid as long as the album object stays allocated
1585
+ * and no longer than the next call to sp_session_process_events()
1586
+ */
1587
+ SP_LIBEXPORT(const char *) sp_artistbrowse_biography(sp_artistbrowse *arb);
1588
+
1589
+
1590
+ /**
1591
+ * Increase the reference count of an artist browse result
1592
+ *
1593
+ * @param[in] arb The artist browse result object
1594
+ */
1595
+ SP_LIBEXPORT(void) sp_artistbrowse_add_ref(sp_artistbrowse *arb);
1596
+
1597
+ /**
1598
+ * Decrease the reference count of an artist browse result
1599
+ *
1600
+ * @param[in] arb The artist browse result object
1601
+ */
1602
+ SP_LIBEXPORT(void) sp_artistbrowse_release(sp_artistbrowse *arb);
1603
+
1604
+ /** @} */
1605
+
1606
+
1607
+
1608
+ /**
1609
+ * @defgroup image Image handling
1610
+ * @{
1611
+ */
1612
+
1613
+ /**
1614
+ * Image format
1615
+ */
1616
+ typedef enum {
1617
+ SP_IMAGE_FORMAT_UNKNOWN = -1, ///< Unknown image format
1618
+ SP_IMAGE_FORMAT_JPEG = 0, ///< JPEG image
1619
+ } sp_imageformat;
1620
+
1621
+ /**
1622
+ * The type of a callback used to notify the application that an image
1623
+ * is done loading.
1624
+ */
1625
+ typedef void SP_CALLCONV image_loaded_cb(sp_image *image, void *userdata);
1626
+
1627
+ /**
1628
+ * Create an image object
1629
+ *
1630
+ * @param[in] session Session
1631
+ * @param[in] image_id Spotify image ID
1632
+ *
1633
+ * @return Pointer to an image object. To free the object, use
1634
+ * sp_image_release()
1635
+ *
1636
+ * @see sp_album_cover
1637
+ * @see sp_artistbrowse_portrait
1638
+ */
1639
+ SP_LIBEXPORT(sp_image *) sp_image_create(sp_session *session, const byte image_id[20]);
1640
+
1641
+ /**
1642
+ * Add a callback that will be invoked when the image is loaded
1643
+ *
1644
+ * If an image is loaded, and loading fails, the image will behave like an
1645
+ * empty image.
1646
+ *
1647
+ * @param[in] image Image object
1648
+ * @param[in] callback Callback that will be called when image has been
1649
+ * fetched.
1650
+ * @param[in] userdata Opaque pointer passed to \p callback
1651
+ *
1652
+ */
1653
+ SP_LIBEXPORT(void) sp_image_add_load_callback(sp_image *image, image_loaded_cb *callback, void *userdata);
1654
+
1655
+ /**
1656
+ * Remove an image load callback previously added with sp_image_add_load_callback()
1657
+ *
1658
+ * @param[in] image Image object
1659
+ * @param[in] callback Callback that will not be called when image has been
1660
+ * fetched.
1661
+ * @param[in] userdata Opaque pointer passed to \p callback
1662
+ *
1663
+ */
1664
+ SP_LIBEXPORT(void) sp_image_remove_load_callback(sp_image *image, image_loaded_cb *callback, void *userdata);
1665
+
1666
+ /**
1667
+ * Check if an image is loaded. Before the image is loaded, the rest of the
1668
+ * methods will behave as if the image is empty.
1669
+ *
1670
+ * @param[in] image Image object
1671
+ *
1672
+ * @return True if image is loaded, false otherwise
1673
+ */
1674
+ SP_LIBEXPORT(bool) sp_image_is_loaded(sp_image *image);
1675
+
1676
+ /**
1677
+ * Check if image retrieval returned an error code.
1678
+ *
1679
+ * @param[in] image Image object
1680
+ *
1681
+ * @return One of the following errors, from ::sp_error
1682
+ * SP_ERROR_OK
1683
+ * SP_ERROR_IS_LOADING
1684
+ * SP_ERROR_OTHER_PERMANENT
1685
+ * SP_ERROR_OTHER_TRANSIENT
1686
+ */
1687
+ SP_LIBEXPORT(sp_error) sp_image_error(sp_image *image);
1688
+
1689
+ /**
1690
+ * Get image format
1691
+ *
1692
+ * @param[in] image Image object
1693
+ *
1694
+ * @return Image format as described by sp_imageformat
1695
+ */
1696
+ SP_LIBEXPORT(sp_imageformat) sp_image_format(sp_image *image);
1697
+
1698
+ /**
1699
+ * Get image data
1700
+ *
1701
+ * @param[in] image Image object
1702
+ * @param[out] data_size Size of raw image data
1703
+ *
1704
+ * @return Pointer to raw image data
1705
+ */
1706
+
1707
+ SP_LIBEXPORT(const void *) sp_image_data(sp_image *image, size_t *data_size);
1708
+
1709
+ /**
1710
+ * Get image ID
1711
+ *
1712
+ * @param[in] image Image object
1713
+ *
1714
+ * @return Image ID
1715
+ */
1716
+ SP_LIBEXPORT(const byte *) sp_image_image_id(sp_image *image);
1717
+
1718
+
1719
+ /**
1720
+ * Increase the reference count of an image
1721
+ *
1722
+ * @param[in] image The image object
1723
+ */
1724
+ SP_LIBEXPORT(void) sp_image_add_ref(sp_image *image);
1725
+
1726
+ /**
1727
+ * Decrease the reference count of an image
1728
+ *
1729
+ * @param[in] image The image object
1730
+ */
1731
+ SP_LIBEXPORT(void) sp_image_release(sp_image *image);
1732
+
1733
+ /** @} */
1734
+
1735
+
1736
+
1737
+
1738
+ /**
1739
+ * @defgroup search Search subsysten
1740
+ * @{
1741
+ */
1742
+
1743
+ /**
1744
+ * List of genres for radio query. Multiple genres can be combined by OR:ing the genres together
1745
+ */
1746
+ typedef enum sp_radio_genre {
1747
+ SP_RADIO_GENRE_ALT_POP_ROCK = 0x1,
1748
+ SP_RADIO_GENRE_BLUES = 0x2,
1749
+ SP_RADIO_GENRE_COUNTRY = 0x4,
1750
+ SP_RADIO_GENRE_DISCO = 0x8,
1751
+ SP_RADIO_GENRE_FUNK = 0x10,
1752
+ SP_RADIO_GENRE_HARD_ROCK = 0x20,
1753
+ SP_RADIO_GENRE_HEAVY_METAL = 0x40,
1754
+ SP_RADIO_GENRE_RAP = 0x80,
1755
+ SP_RADIO_GENRE_HOUSE = 0x100,
1756
+ SP_RADIO_GENRE_JAZZ = 0x200,
1757
+ SP_RADIO_GENRE_NEW_WAVE = 0x400,
1758
+ SP_RADIO_GENRE_RNB = 0x800,
1759
+ SP_RADIO_GENRE_POP = 0x1000,
1760
+ SP_RADIO_GENRE_PUNK = 0x2000,
1761
+ SP_RADIO_GENRE_REGGAE = 0x4000,
1762
+ SP_RADIO_GENRE_POP_ROCK = 0x8000,
1763
+ SP_RADIO_GENRE_SOUL = 0x10000,
1764
+ SP_RADIO_GENRE_TECHNO = 0x20000,
1765
+ } sp_radio_genre;
1766
+
1767
+ /**
1768
+ * The type of a callback used in sp_search_create()
1769
+ *
1770
+ * When this callback is called, the sp_track_is_loaded(), sp_album_is_loaded(),
1771
+ * and sp_artist_is_loaded() functions will return non-zero for the objects
1772
+ * contained in the search result.
1773
+ *
1774
+ * @param[in] result The same pointer returned by sp_search_create()
1775
+ * @param[in] userdata The opaque pointer given to sp_search_create()
1776
+ */
1777
+ typedef void SP_CALLCONV search_complete_cb(sp_search *result, void *userdata);
1778
+
1779
+ /**
1780
+ * Create a search object from the given query
1781
+ *
1782
+ * @param[in] session Session
1783
+ * @param[in] query Query search string, e.g. 'The Rolling Stones' or 'album:"The Black Album"'
1784
+ * @param[in] track_offset The offset among the tracks of the result
1785
+ * @param[in] track_count The number of tracks to ask for
1786
+ * @param[in] album_offset The offset among the albums of the result
1787
+ * @param[in] album_count The number of albums to ask for
1788
+ * @param[in] artist_offset The offset among the artists of the result
1789
+ * @param[in] artist_count The number of artists to ask for
1790
+ * @param[in] callback Callback that will be called once the search operation is complete. Pass NULL if you are not interested in this event.
1791
+ * @param[in] userdata Opaque pointer passed to \p callback
1792
+ *
1793
+ * @return Pointer to a search object. To free the object, use sp_search_release()
1794
+ */
1795
+ SP_LIBEXPORT(sp_search *) sp_search_create(sp_session *session, const char *query, int track_offset, int track_count, int album_offset, int album_count, int artist_offset, int artist_count, search_complete_cb *callback, void *userdata);
1796
+
1797
+ /**
1798
+ * Create a search object from the radio channel
1799
+ *
1800
+ * @param[in] session Session
1801
+ * @param[in] from_year Include tracks starting from this year
1802
+ * @param[in] to_year Include tracks up to this year
1803
+ * @param[in] genres Bitmask of genres to include
1804
+ * @param[in] callback Callback that will be called once the search operation is complete. Pass NULL if you are not interested in this event.
1805
+ * @param[in] userdata Opaque pointer passed to \p callback
1806
+ *
1807
+ * @return Pointer to a search object. To free the object, use sp_search_release()
1808
+ */
1809
+ SP_LIBEXPORT(sp_search *) sp_radio_search_create(sp_session *session, unsigned int from_year, unsigned int to_year, sp_radio_genre genres, search_complete_cb *callback, void *userdata);
1810
+
1811
+
1812
+ /**
1813
+ * Get load status for the specified search. Before it is loaded, it will behave as an empty search result.
1814
+ *
1815
+ * @param[in] search Search object
1816
+ *
1817
+ * @return True if search is loaded, otherwise false
1818
+ */
1819
+ SP_LIBEXPORT(bool) sp_search_is_loaded(sp_search *search);
1820
+
1821
+ /**
1822
+ * Check if search returned an error code.
1823
+ *
1824
+ * @param[in] search Search object
1825
+ *
1826
+ * @return One of the following errors, from ::sp_error
1827
+ * SP_ERROR_OK
1828
+ * SP_ERROR_IS_LOADING
1829
+ * SP_ERROR_OTHER_PERMANENT
1830
+ * SP_ERROR_OTHER_TRANSIENT
1831
+ */
1832
+ SP_LIBEXPORT(sp_error) sp_search_error(sp_search *search);
1833
+
1834
+ /**
1835
+ * Get the number of tracks for the specified search
1836
+ *
1837
+ * @param[in] search Search object
1838
+ *
1839
+ * @return The number of tracks for the specified search
1840
+ */
1841
+ SP_LIBEXPORT(int) sp_search_num_tracks(sp_search *search);
1842
+
1843
+ /**
1844
+ * Return the track at the given index in the given search object
1845
+ *
1846
+ * @param[in] search Search object
1847
+ * @param[in] index Index of the wanted track. Should be in the interval [0, sp_search_num_tracks() - 1]
1848
+ *
1849
+ * @return The track at the given index in the given search object
1850
+ */
1851
+ SP_LIBEXPORT(sp_track *) sp_search_track(sp_search *search, int index);
1852
+
1853
+ /**
1854
+ * Get the number of albums for the specified search
1855
+ *
1856
+ * @param[in] search Search object
1857
+ *
1858
+ * @return The number of albums for the specified search
1859
+ */
1860
+ SP_LIBEXPORT(int) sp_search_num_albums(sp_search *search);
1861
+
1862
+ /**
1863
+ * Return the album at the given index in the given search object
1864
+ *
1865
+ * @param[in] search Search object
1866
+ * @param[in] index Index of the wanted album. Should be in the interval [0, sp_search_num_albums() - 1]
1867
+ *
1868
+ * @return The album at the given index in the given search object
1869
+ */
1870
+ SP_LIBEXPORT(sp_album *) sp_search_album(sp_search *search, int index);
1871
+
1872
+ /**
1873
+ * Get the number of artists for the specified search
1874
+ *
1875
+ * @param[in] search Search object
1876
+ *
1877
+ * @return The number of artists for the specified search
1878
+ */
1879
+ SP_LIBEXPORT(int) sp_search_num_artists(sp_search *search);
1880
+
1881
+ /**
1882
+ * Return the artist at the given index in the given search object
1883
+ *
1884
+ * @param[in] search Search object
1885
+ * @param[in] index Index of the wanted artist. Should be in the interval [0, sp_search_num_artists() - 1]
1886
+ *
1887
+ * @return The artist at the given index in the given search object
1888
+ */
1889
+ SP_LIBEXPORT(sp_artist *) sp_search_artist(sp_search *search, int index);
1890
+
1891
+ /**
1892
+ * Return the search query for the given search object
1893
+ *
1894
+ * @param[in] search Search object
1895
+ *
1896
+ * @return The search query for the given search object
1897
+ */
1898
+ SP_LIBEXPORT(const char *) sp_search_query(sp_search *search);
1899
+
1900
+ /**
1901
+ * Return the "Did you mean" query for the given search object
1902
+ *
1903
+ * @param[in] search Search object
1904
+ *
1905
+ * @return The "Did you mean" query for the given search object, or the empty string if no such info is available
1906
+ */
1907
+ SP_LIBEXPORT(const char *) sp_search_did_you_mean(sp_search *search);
1908
+
1909
+ /**
1910
+ * Return the total number of tracks for the search query - regardless of the interval requested at creation.
1911
+ * If this value is larger than the interval specified at creation of the search object, more search results are available.
1912
+ * To fetch these, create a new search object with a new interval.
1913
+ *
1914
+ * @param[in] search Search object
1915
+ *
1916
+ * @return The total number of tracks matching the original query
1917
+ */
1918
+ SP_LIBEXPORT(int) sp_search_total_tracks(sp_search *search);
1919
+
1920
+ /**
1921
+ * Return the total number of albums for the search query - regardless of the interval requested at creation.
1922
+ * If this value is larger than the interval specified at creation of the search object, more search results are available.
1923
+ * To fetch these, create a new search object with a new interval.
1924
+ *
1925
+ * @param[in] search Search object
1926
+ *
1927
+ * @return The total number of albums matching the original query
1928
+ */
1929
+ SP_LIBEXPORT(int) sp_search_total_albums(sp_search *search);
1930
+
1931
+ /**
1932
+ * Return the total number of artists for the search query - regardless of the interval requested at creation.
1933
+ * If this value is larger than the interval specified at creation of the search object, more search results are available.
1934
+ * To fetch these, create a new search object with a new interval.
1935
+ *
1936
+ * @param[in] search Search object
1937
+ *
1938
+ * @return The total number of artists matching the original query
1939
+ */
1940
+ SP_LIBEXPORT(int) sp_search_total_artists(sp_search *search);
1941
+
1942
+ /**
1943
+ * Increase the reference count of a search result
1944
+ *
1945
+ * @param[in] search The search result object
1946
+ */
1947
+ SP_LIBEXPORT(void) sp_search_add_ref(sp_search *search);
1948
+
1949
+ /**
1950
+ * Decrease the reference count of a search result
1951
+ *
1952
+ * @param[in] search The search result object
1953
+ */
1954
+ SP_LIBEXPORT(void) sp_search_release(sp_search *search);
1955
+
1956
+ /** @} */
1957
+
1958
+
1959
+
1960
+ /**
1961
+ * @defgroup playlist Playlist subsystem
1962
+ *
1963
+ * The playlist subsystem handles playlists and playlist containers (list of playlists).
1964
+ *
1965
+ * The playlist container functions are always valid, but your playlists are not
1966
+ * guaranteed to be loaded until the sp_session_callbacks#logged_in callback has
1967
+ * been issued.
1968
+ *
1969
+ * @{
1970
+ */
1971
+
1972
+ /**
1973
+ * Playlist callbacks
1974
+ *
1975
+ * Used to get notifications when playlists are updated.
1976
+ * If some callbacks should not be of interest, set them to NULL.
1977
+ */
1978
+ typedef struct sp_playlist_callbacks {
1979
+
1980
+ /**
1981
+ * Called when one or more tracks have been added to a playlist
1982
+ *
1983
+ * @param[in] pl Playlist object
1984
+ * @param[in] tracks Array of pointers to track objects
1985
+ * @param[in] num_tracks Number of entries in \p tracks
1986
+ * @param[in] position Position in the playlist for the first track.
1987
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
1988
+ */
1989
+ void (SP_CALLCONV *tracks_added)(sp_playlist *pl, sp_track * const *tracks, int num_tracks, int position, void *userdata);
1990
+
1991
+ /**
1992
+ * Called when one or more tracks have been removed from a playlist
1993
+ *
1994
+ * @param[in] pl Playlist object
1995
+ * @param[in] tracks Array of positions representing the tracks that were removed
1996
+ * @param[in] num_tracks Number of entries in \p tracks
1997
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
1998
+ */
1999
+ void (SP_CALLCONV *tracks_removed)(sp_playlist *pl, const int *tracks, int num_tracks, void *userdata);
2000
+
2001
+ /**
2002
+ * Called when one or more tracks have been moved within a playlist
2003
+ *
2004
+ * @param[in] pl Playlist object
2005
+ * @param[in] tracks Array of positions representing the tracks that were moved
2006
+ * @param[in] num_tracks Number of entries in \p tracks
2007
+ * @param[in] position New position in the playlist for the first track.
2008
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2009
+ */
2010
+ void (SP_CALLCONV *tracks_moved)(sp_playlist *pl, const int *tracks, int num_tracks, int new_position, void *userdata);
2011
+
2012
+ /**
2013
+ * Called when a playlist has been renamed. sp_playlist_name() can be used to find out the new name
2014
+ *
2015
+ * @param[in] pl Playlist object
2016
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2017
+ */
2018
+ void (SP_CALLCONV *playlist_renamed)(sp_playlist *pl, void *userdata);
2019
+
2020
+ /**
2021
+ * Called when state changed for a playlist.
2022
+ *
2023
+ * There are three states that trigger this callback:
2024
+ * - Collaboration for this playlist has been turned on or off
2025
+ * - The playlist started having pending changes, or all pending changes have now been committed
2026
+ * - The playlist started loading, or finished loading
2027
+ *
2028
+ * @param[in] pl Playlist object
2029
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2030
+ * @sa sp_playlist_is_collaborative
2031
+ * @sa sp_playlist_has_pending_changes
2032
+ * @sa sp_playlist_is_loaded
2033
+ */
2034
+ void (SP_CALLCONV *playlist_state_changed)(sp_playlist *pl, void *userdata);
2035
+
2036
+ /**
2037
+ * Called when a playlist is updating or is done updating
2038
+ *
2039
+ * This is called before and after a series of changes are applied to the
2040
+ * playlist. It allows e.g. the user interface to defer updating until the
2041
+ * entire operation is complete.
2042
+ *
2043
+ * @param[in] pl Playlist object
2044
+ * @param[in] done True iff the update is completed
2045
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2046
+ */
2047
+ void (SP_CALLCONV *playlist_update_in_progress)(sp_playlist *pl, bool done, void *userdata);
2048
+
2049
+ /**
2050
+ * Called when metadata for one or more tracks in a playlist has been updated.
2051
+ *
2052
+ * @param[in] pl Playlist object
2053
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2054
+ */
2055
+ void (SP_CALLCONV *playlist_metadata_updated)(sp_playlist *pl, void *userdata);
2056
+
2057
+ /**
2058
+ * Called when create time and/or creator for a playlist entry changes
2059
+ *
2060
+ * @param[in] pl Playlist object
2061
+ * @param[in] position Position in playlist
2062
+ * @param[in] user User object
2063
+ * @param[in] time When entry was created, seconds since the unix epoch.
2064
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2065
+ */
2066
+ void (SP_CALLCONV *track_created_changed)(sp_playlist *pl, int position, sp_user *user, int when, void *userdata);
2067
+
2068
+ /**
2069
+ * Called when seen attribute for a playlist entry changes.
2070
+ *
2071
+ * @param[in] pl Playlist object
2072
+ * @param[in] position Position in playlist
2073
+ * @param[in] seen Set if entry it marked as seen
2074
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2075
+ */
2076
+ void (SP_CALLCONV *track_seen_changed)(sp_playlist *pl, int position, bool seen, void *userdata);
2077
+
2078
+ /**
2079
+ * Called when playlist description has changed
2080
+ *
2081
+ * @param[in] pl Playlist object
2082
+ * @param[in] desc New description
2083
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2084
+ */
2085
+ void (SP_CALLCONV *description_changed)(sp_playlist *pl, const char *desc, void *userdata);
2086
+
2087
+
2088
+ /**
2089
+ * Called when playlist image has changed
2090
+ *
2091
+ * @param[in] pl Playlist object
2092
+ * @param[in] image New image
2093
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2094
+ */
2095
+ void (SP_CALLCONV *image_changed)(sp_playlist *pl, const byte *image, void *userdata);
2096
+
2097
+
2098
+ /**
2099
+ * Called when message attribute for a playlist entry changes.
2100
+ *
2101
+ * @param[in] pl Playlist object
2102
+ * @param[in] position Position in playlist
2103
+ * @param[in] message UTF-8 encoded message
2104
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2105
+ */
2106
+ void (SP_CALLCONV *track_message_changed)(sp_playlist *pl, int position, const char *message, void *userdata);
2107
+
2108
+
2109
+ /**
2110
+ * Called when playlist subscribers changes (count or list of names)
2111
+ *
2112
+ * @param[in] pl Playlist object
2113
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2114
+ */
2115
+ void (SP_CALLCONV *subscribers_changed)(sp_playlist *pl, void *userdata);
2116
+
2117
+ } sp_playlist_callbacks;
2118
+
2119
+
2120
+ /**
2121
+ * Get load status for the specified playlist. If it's false, you have to wait until
2122
+ * playlist_state_changed happens, and check again if is_loaded has changed
2123
+ *
2124
+ * @param[in] playlist Playlist object
2125
+ *
2126
+ * @return True if playlist is loaded, otherwise false
2127
+ */
2128
+ SP_LIBEXPORT(bool) sp_playlist_is_loaded(sp_playlist *playlist);
2129
+
2130
+ /**
2131
+ * Register interest in the given playlist
2132
+ *
2133
+ * Here is a snippet from \c jukebox.c:
2134
+ * @dontinclude jukebox.c
2135
+ * @skipline sp_playlist_add_callbacks
2136
+ *
2137
+ * @param[in] playlist Playlist object
2138
+ * @param[in] callbacks Callbacks, see #sp_playlist_callbacks
2139
+ * @param[in] userdata Userdata to be passed to callbacks
2140
+ * @sa sp_playlist_remove_callbacks
2141
+ *
2142
+ */
2143
+ SP_LIBEXPORT(void) sp_playlist_add_callbacks(sp_playlist *playlist, sp_playlist_callbacks *callbacks, void *userdata);
2144
+
2145
+ /**
2146
+ * Unregister interest in the given playlist
2147
+ *
2148
+ * The combination of (\p callbacks, \p userdata) is used to find the entry to be removed
2149
+ *
2150
+ * Here is a snippet from \c jukebox.c:
2151
+ * @dontinclude jukebox.c
2152
+ * @skipline sp_playlist_remove_callbacks
2153
+ *
2154
+ * @param[in] playlist Playlist object
2155
+ * @param[in] callbacks Callbacks, see #sp_playlist_callbacks
2156
+ * @param[in] userdata Userdata to be passed to callbacks
2157
+ * @sa sp_playlist_add_callbacks
2158
+ *
2159
+ */
2160
+ SP_LIBEXPORT(void) sp_playlist_remove_callbacks(sp_playlist *playlist, sp_playlist_callbacks *callbacks, void *userdata);
2161
+
2162
+ /**
2163
+ * Return number of tracks in the given playlist
2164
+ *
2165
+ * @param[in] playlist Playlist object
2166
+ *
2167
+ * @return The number of tracks in the playlist
2168
+ */
2169
+ SP_LIBEXPORT(int) sp_playlist_num_tracks(sp_playlist *playlist);
2170
+
2171
+ /**
2172
+ * Return the track at the given index in a playlist
2173
+ *
2174
+ * @param[in] playlist Playlist object
2175
+ * @param[in] index Index into playlist container. Should be in the interval [0, sp_playlist_num_tracks() - 1]
2176
+ *
2177
+ * @return The track at the given index
2178
+ */
2179
+ SP_LIBEXPORT(sp_track *) sp_playlist_track(sp_playlist *playlist, int index);
2180
+
2181
+ /**
2182
+ * Return when the given index was added to the playlist
2183
+ *
2184
+ * @param[in] playlist Playlist object
2185
+ * @param[in] index Index into playlist container. Should be in the interval [0, sp_playlist_num_tracks() - 1]
2186
+ *
2187
+ * @return Time, Seconds since unix epoch.
2188
+ */
2189
+ SP_LIBEXPORT(int) sp_playlist_track_create_time(sp_playlist *playlist, int index);
2190
+
2191
+ /**
2192
+ * Return user that added the given index in the playlist
2193
+ *
2194
+ * @param[in] playlist Playlist object
2195
+ * @param[in] index Index into playlist container. Should be in the interval [0, sp_playlist_num_tracks() - 1]
2196
+ *
2197
+ * @return User object
2198
+ */
2199
+ SP_LIBEXPORT(sp_user *) sp_playlist_track_creator(sp_playlist *playlist, int index);
2200
+
2201
+ /**
2202
+ * Return if a playlist entry is marked as seen or not
2203
+ *
2204
+ * @param[in] playlist Playlist object
2205
+ * @param[in] index Index into playlist container. Should be in the interval [0, sp_playlist_num_tracks() - 1]
2206
+ *
2207
+ * @return Seen state
2208
+ */
2209
+ SP_LIBEXPORT(bool) sp_playlist_track_seen(sp_playlist *playlist, int index);
2210
+
2211
+ /**
2212
+ * Set seen status of a playlist entry
2213
+ *
2214
+ * @param[in] playlist Playlist object
2215
+ * @param[in] index Index into playlist container. Should be in the interval [0, sp_playlist_num_tracks() - 1]
2216
+ * @param[in] seen Seen status to be set
2217
+ *
2218
+ * @return error One of the following errors, from ::sp_error
2219
+ * SP_ERROR_OK
2220
+ * SP_ERROR_INDEX_OUT_OF_RANGE
2221
+ */
2222
+ SP_LIBEXPORT(sp_error) sp_playlist_track_set_seen(sp_playlist *playlist, int index, bool seen);
2223
+
2224
+ /**
2225
+ * Return a message attached to a playlist item. Typically used on inbox.
2226
+ *
2227
+ * @param[in] playlist Playlist object
2228
+ * @param[in] index Index into playlist container. Should be in the interval [0, sp_playlist_num_tracks() - 1]
2229
+ *
2230
+ * @return UTF-8 encoded message, or NULL if no message is present
2231
+ */
2232
+ SP_LIBEXPORT(const char *) sp_playlist_track_message(sp_playlist *playlist, int index);
2233
+
2234
+ /**
2235
+ * Return name of given playlist
2236
+ *
2237
+ * @param[in] playlist Playlist object
2238
+ *
2239
+ * @return The name of the given playlist
2240
+ */
2241
+ SP_LIBEXPORT(const char *) sp_playlist_name(sp_playlist *playlist);
2242
+
2243
+ /**
2244
+ * Rename the given playlist
2245
+ * The name must not consist of only spaces and it must be shorter than 256 characters.
2246
+ *
2247
+ * @param[in] playlist Playlist object
2248
+ * @param[in] new_name New name for playlist
2249
+ *
2250
+ * @return One of the following errors, from ::sp_error
2251
+ * SP_ERROR_OK
2252
+ * SP_ERROR_INVALID_INDATA
2253
+ * SP_ERROR_PERMISSION_DENIED
2254
+ */
2255
+ SP_LIBEXPORT(sp_error) sp_playlist_rename(sp_playlist *playlist, const char *new_name);
2256
+
2257
+ /**
2258
+ * Return a pointer to the user for the given playlist
2259
+ *
2260
+ * @param[in] playlist Playlist object
2261
+ *
2262
+ * @return User object
2263
+ */
2264
+ SP_LIBEXPORT(sp_user *) sp_playlist_owner(sp_playlist *playlist);
2265
+
2266
+ /**
2267
+ * Return collaborative status for a playlist.
2268
+ *
2269
+ * A playlist in collaborative state can be modifed by all users, not only the user owning the list
2270
+ *
2271
+ * @param[in] playlist Playlist object
2272
+ *
2273
+ * @return true if playlist is collaborative, otherwise false
2274
+ */
2275
+ SP_LIBEXPORT(bool) sp_playlist_is_collaborative(sp_playlist *playlist);
2276
+
2277
+ /**
2278
+ * Set collaborative status for a playlist.
2279
+ *
2280
+ * A playlist in collaborative state can be modifed by all users, not only the user owning the list
2281
+ *
2282
+ * @param[in] playlist Playlist object
2283
+ * @param[in] collaborative True or false
2284
+ *
2285
+ */
2286
+ SP_LIBEXPORT(void) sp_playlist_set_collaborative(sp_playlist *playlist, bool collaborative);
2287
+
2288
+ /**
2289
+ * Set autolinking state for a playlist.
2290
+ *
2291
+ * If a playlist is autolinked, unplayable tracks will be made playable
2292
+ * by linking them to other Spotify tracks, where possible.
2293
+ *
2294
+ * @param[in] playlist Playlist object
2295
+ * @param[in] link True or false
2296
+ *
2297
+ */
2298
+ SP_LIBEXPORT(void) sp_playlist_set_autolink_tracks(sp_playlist *playlist, bool link);
2299
+
2300
+
2301
+ /**
2302
+ * Get description for a playlist
2303
+ *
2304
+ * @param[in] playlist Playlist object
2305
+ *
2306
+ * @return Playlist description or NULL if unset
2307
+ *
2308
+ */
2309
+ SP_LIBEXPORT(const char *) sp_playlist_get_description(sp_playlist *playlist);
2310
+
2311
+
2312
+ /**
2313
+ * Get description for a playlist
2314
+ *
2315
+ * @param[in] playlist Playlist object
2316
+ * @param[out] image 20 byte image id
2317
+
2318
+ * @return TRUE if playlist has an image, FALSE if not
2319
+ *
2320
+ */
2321
+ SP_LIBEXPORT(bool) sp_playlist_get_image(sp_playlist *playlist, byte image[20]);
2322
+
2323
+
2324
+ /**
2325
+ * Check if a playlist has pending changes
2326
+ *
2327
+ * Pending changes are local changes that have not yet been acknowledged by the server.
2328
+ *
2329
+ * @param[in] playlist Playlist object
2330
+ *
2331
+ * @return A flag representing if there are pending changes or not
2332
+ */
2333
+ SP_LIBEXPORT(bool) sp_playlist_has_pending_changes(sp_playlist *playlist);
2334
+
2335
+ /**
2336
+ * Add tracks to a playlist
2337
+ *
2338
+ * @param[in] playlist Playlist object
2339
+ * @param[in] tracks Array of pointer to tracks.
2340
+ * @param[in] num_tracks Length of \p tracks array
2341
+ * @param[in] position Start position in playlist where to insert the tracks
2342
+ * @param[in] session Your session object
2343
+ *
2344
+ * @return One of the following errors, from ::sp_error
2345
+ * SP_ERROR_OK
2346
+ * SP_ERROR_INVALID_INDATA - position is > current playlist length
2347
+ * SP_ERROR_PERMISSION_DENIED
2348
+ */
2349
+ SP_LIBEXPORT(sp_error) sp_playlist_add_tracks(sp_playlist *playlist, const sp_track **tracks, int num_tracks, int position, sp_session *session);
2350
+
2351
+ /**
2352
+ * Remove tracks from a playlist
2353
+ *
2354
+ * @param[in] playlist Playlist object
2355
+ * @param[in] tracks Array of pointer to track indices.
2356
+ * A certain track index should be present at most once, e.g. [0, 1, 2] is valid indata,
2357
+ * whereas [0, 1, 1] is invalid.
2358
+ * @param[in] num_tracks Length of \p tracks array
2359
+ *
2360
+ * @return One of the following errors, from ::sp_error
2361
+ * SP_ERROR_OK
2362
+ * SP_ERROR_PERMISSION_DENIED
2363
+ */
2364
+ SP_LIBEXPORT(sp_error) sp_playlist_remove_tracks(sp_playlist *playlist, const int *tracks, int num_tracks);
2365
+
2366
+ /**
2367
+ * Move tracks in playlist
2368
+ *
2369
+ * @param[in] playlist Playlist object
2370
+ * @param[in] tracks Array of pointer to track indices to be moved.
2371
+ * A certain track index should be present at most once, e.g. [0, 1, 2] is valid indata,
2372
+ * whereas [0, 1, 1] is invalid.
2373
+ * @param[in] num_tracks Length of \p tracks array
2374
+ * @param[in] new_position New position for tracks
2375
+ *
2376
+ * @return One of the following errors, from ::sp_error
2377
+ * SP_ERROR_OK
2378
+ * SP_ERROR_INVALID_INDATA - position is > current playlist length
2379
+ * SP_ERROR_PERMISSION_DENIED
2380
+ */
2381
+ SP_LIBEXPORT(sp_error) sp_playlist_reorder_tracks(sp_playlist *playlist, const int *tracks, int num_tracks, int new_position);
2382
+
2383
+
2384
+ /**
2385
+ * Return number of subscribers for a given playlist
2386
+ *
2387
+ * @param[in] playlist Playlist object
2388
+ *
2389
+ * @return Number of subscribers
2390
+ *
2391
+ */
2392
+ SP_LIBEXPORT(unsigned int) sp_playlist_num_subscribers(sp_playlist *playlist);
2393
+
2394
+ /**
2395
+ * Return subscribers for a playlist
2396
+ *
2397
+ * @param[in] playlist Playlist object
2398
+ *
2399
+ * @return sp_subscribers struct with array of canonical usernames.
2400
+ * This object should be free'd using sp_playlist_subscribers_free()
2401
+ *
2402
+ * @note The count returned for this function may be less than those
2403
+ * returned by sp_playlist_num_subscribers(). Spotify does not
2404
+ * track each user subscribed to a playlist for playlist with
2405
+ * many (>500) subscribers.
2406
+ */
2407
+ SP_LIBEXPORT(sp_subscribers *) sp_playlist_subscribers(sp_playlist *playlist);
2408
+
2409
+ /**
2410
+ * Free object returned from sp_playlist_subscribers()
2411
+ *
2412
+ * @param[in] subscribers Subscribers object
2413
+ */
2414
+ SP_LIBEXPORT(void) sp_playlist_subscribers_free(sp_subscribers *subscribers);
2415
+
2416
+ /**
2417
+ * Ask library to update the subscription count for a playlist
2418
+ *
2419
+ * When the subscription info has been fetched from the Spotify backend
2420
+ * the playlist subscribers_changed() callback will be invoked.
2421
+ * In that callback use sp_playlist_num_subscribers() and/or
2422
+ * sp_playlist_subscribers() to get information about the subscribers.
2423
+ * You can call those two functions anytime you want but the information
2424
+ * might not be up to date in such cases
2425
+ *
2426
+ * @param[in] session Session object
2427
+ * @param[in] playlist Playlist object
2428
+ */
2429
+ SP_LIBEXPORT(void) sp_playlist_update_subscribers(sp_session *session, sp_playlist *playlist);
2430
+
2431
+ /**
2432
+ * Return whether a playlist is loaded in RAM (as opposed to only
2433
+ * stored on disk)
2434
+ *
2435
+ * @param[in] session Session object
2436
+ * @param[in] playlist Playlist object
2437
+ *
2438
+ * @return True iff playlist is in RAM, False otherwise
2439
+ *
2440
+ * @note When a playlist is no longer in RAM it will appear empty.
2441
+ * However, libspotify will retain information about the
2442
+ * list metadata (owner, title, picture, etc) in RAM.
2443
+ * There is one caveat tough: If libspotify has never seen the
2444
+ * playlist before this metadata will also be unset.
2445
+ * In order for libspotify to get the metadata the playlist
2446
+ * needs to be loaded atleast once.
2447
+ * In order words, if libspotify starts with an empty playlist
2448
+ * cache and the application has set 'initially_unload_playlists'
2449
+ * config parameter to True all playlists will be empty.
2450
+ * It will not be possible to generate URI's to the playlists
2451
+ * nor extract playlist title until the application calls
2452
+ * sp_playlist_set_in_ram(..., true). So an application
2453
+ * that needs to stay within a low memory profile would need to
2454
+ * cycle thru all new playlists in order to extract metadata.
2455
+ *
2456
+ * The easiest way to detect this case is when
2457
+ * sp_playlist_is_in_ram() returns false and
2458
+ * sp_link_create_from_playlist() returns NULL
2459
+ */
2460
+ SP_LIBEXPORT(bool) sp_playlist_is_in_ram(sp_session *session, sp_playlist *playlist);
2461
+
2462
+ /**
2463
+ * Return whether a playlist is loaded in RAM (as opposed to only
2464
+ * stored on disk)
2465
+ *
2466
+ * @param[in] session Session object
2467
+ * @param[in] playlist Playlist object
2468
+ * @param[in] in_ram Controls whether or not to keep the list in RAM
2469
+ */
2470
+ SP_LIBEXPORT(void) sp_playlist_set_in_ram(sp_session *session, sp_playlist *playlist, bool in_ram);
2471
+
2472
+ /**
2473
+ * Load an already existing playlist without adding it to a playlistcontainer.
2474
+ *
2475
+ * @param[in] session Session object
2476
+ * @param[in] link Link object referring to a playlist
2477
+ *
2478
+ * @return A playlist. The reference is owned by the caller and should be released with sp_playlist_release()
2479
+ *
2480
+ */
2481
+ SP_LIBEXPORT(sp_playlist *) sp_playlist_create(sp_session *session, sp_link *link);
2482
+
2483
+ /**
2484
+ * Increase the reference count of a playlist
2485
+ *
2486
+ * @param[in] playlist The playlist object
2487
+ */
2488
+ SP_LIBEXPORT(void) sp_playlist_add_ref(sp_playlist *playlist);
2489
+
2490
+ /**
2491
+ * Decrease the reference count of a playlist
2492
+ *
2493
+ * @param[in] playlist The playlist object
2494
+ */
2495
+ SP_LIBEXPORT(void) sp_playlist_release(sp_playlist *playlist);
2496
+
2497
+
2498
+ /**
2499
+ * Playlist container callbacks.
2500
+ * If some callbacks should not be of interest, set them to NULL.
2501
+ *
2502
+ * @see sp_playlistcontainer_add_callbacks
2503
+ * @see sp_playlistcontainer_remove_callbacks
2504
+ */
2505
+ typedef struct sp_playlistcontainer_callbacks {
2506
+ /**
2507
+ * Called when a new playlist has been added to the playlist container.
2508
+ *
2509
+ * @param[in] pc Playlist container
2510
+ * @param[in] playlist Playlist object.
2511
+ * @param[in] position Position in list
2512
+ * @param[in] userdata Userdata as set in sp_playlistcontainer_add_callbacks()
2513
+ */
2514
+ void (SP_CALLCONV *playlist_added)(sp_playlistcontainer *pc, sp_playlist *playlist, int position, void *userdata);
2515
+
2516
+
2517
+ /**
2518
+ * Called when a new playlist has been removed from playlist container
2519
+ *
2520
+ * @param[in] pc Playlist container
2521
+ * @param[in] playlist Playlist object.
2522
+ * @param[in] position Position in list
2523
+ * @param[in] userdata Userdata as set in sp_playlistcontainer_add_callbacks()
2524
+ */
2525
+ void (SP_CALLCONV *playlist_removed)(sp_playlistcontainer *pc, sp_playlist *playlist, int position, void *userdata);
2526
+
2527
+
2528
+ /**
2529
+ * Called when a playlist has been moved in the playlist container
2530
+ *
2531
+ * @param[in] pc Playlist container
2532
+ * @param[in] playlist Playlist object.
2533
+ * @param[in] position Previous position in playlist container list
2534
+ * @param[in] new_position New position in playlist container list
2535
+ * @param[in] userdata Userdata as set in sp_playlistcontainer_add_callbacks()
2536
+ */
2537
+ void (SP_CALLCONV *playlist_moved)(sp_playlistcontainer *pc, sp_playlist *playlist, int position, int new_position, void *userdata);
2538
+
2539
+ /**
2540
+ * Called when the playlist container is loaded
2541
+ *
2542
+ * @param[in] pc Playlist container
2543
+ * @param[in] userdata Userdata as set in sp_playlistcontainer_add_callbacks()
2544
+ */
2545
+ void (SP_CALLCONV *container_loaded)(sp_playlistcontainer *pc, void *userdata);
2546
+ } sp_playlistcontainer_callbacks;
2547
+
2548
+
2549
+ /**
2550
+ * Register interest in changes to a playlist container
2551
+ *
2552
+ * @param[in] pc Playlist container
2553
+ * @param[in] callbacks Callbacks, see sp_playlistcontainer_callbacks
2554
+ * @param[in] userdata Opaque value passed to callbacks.
2555
+ *
2556
+ * @note Every sp_playlistcontainer_add_callbacks() needs to be paried with a corresponding
2557
+ * sp_playlistcontainer_remove_callbacks() that is invoked before releasing the
2558
+ * last reference you own for the container. In other words, you must make sure
2559
+ * to have removed all the callbacks before the container gets destroyed.
2560
+ *
2561
+ * @sa sp_session_playlistcontainer()
2562
+ * @sa sp_playlistcontainer_remove_callbacks
2563
+ */
2564
+ SP_LIBEXPORT(void) sp_playlistcontainer_add_callbacks(sp_playlistcontainer *pc, sp_playlistcontainer_callbacks *callbacks, void *userdata);
2565
+
2566
+
2567
+ /**
2568
+ * Unregister interest in changes to a playlist container
2569
+ *
2570
+ * @param[in] pc Playlist container
2571
+ * @param[in] callbacks Callbacks, see sp_playlistcontainer_callbacks
2572
+ * @param[in] userdata Opaque value passed to callbacks.
2573
+ *
2574
+ * @sa sp_session_playlistcontainer()
2575
+ * @sa sp_playlistcontainer_add_callbacks
2576
+ */
2577
+ SP_LIBEXPORT(void) sp_playlistcontainer_remove_callbacks(sp_playlistcontainer *pc, sp_playlistcontainer_callbacks *callbacks, void *userdata);
2578
+
2579
+ /**
2580
+ * Return the number of playlists in the given playlist container
2581
+ *
2582
+ * @param[in] pc Playlist container
2583
+ *
2584
+ * @return Number of playlists, -1 if undefined
2585
+ *
2586
+ * @sa sp_session_playlistcontainer()
2587
+ */
2588
+ SP_LIBEXPORT(int) sp_playlistcontainer_num_playlists(sp_playlistcontainer *pc);
2589
+
2590
+ /**
2591
+ * Return a pointer to the playlist at a specific index
2592
+ *
2593
+ * @param[in] pc Playlist container
2594
+ * @param[in] index Index in playlist container. Should be in the interval [0, sp_playlistcontainer_num_playlists() - 1]
2595
+ *
2596
+ * @return Number of playlists.
2597
+ *
2598
+ * @sa sp_session_playlistcontainer()
2599
+ */
2600
+ SP_LIBEXPORT(sp_playlist *) sp_playlistcontainer_playlist(sp_playlistcontainer *pc, int index);
2601
+
2602
+ /**
2603
+ * Return the type of the playlist at a @a index
2604
+ *
2605
+ * @param[in] pc Playlist container
2606
+ * @param[in] index Index in playlist container. Should be in the interval [0, sp_playlistcontainer_num_playlists() - 1]
2607
+ *
2608
+ * @return Type of the playlist, @see sp_playlist_type
2609
+ *
2610
+ * @sa sp_session_playlistcontainer()
2611
+ */
2612
+ SP_LIBEXPORT(sp_playlist_type) sp_playlistcontainer_playlist_type(sp_playlistcontainer *pc, int index);
2613
+
2614
+ /**
2615
+ * Return the folder name at @a index
2616
+ *
2617
+ * @param[in] pc Playlist container
2618
+ * @param[in] index Index in playlist container. Should be in the interval [0, sp_playlistcontainer_num_playlists() - 1]
2619
+ * @param[in] buffer Pointer to char[] where to store folder name
2620
+ * @param[in] buffer_size Size of array
2621
+ *
2622
+ * @return error One of the following errors, from ::sp_error
2623
+ * SP_ERROR_OK
2624
+ * SP_ERROR_INDEX_OUT_OF_RANGE
2625
+ *
2626
+ * @sa sp_session_playlistcontainer()
2627
+ */
2628
+ SP_LIBEXPORT(sp_error) sp_playlistcontainer_playlist_folder_name(sp_playlistcontainer *pc, int index, char *buffer, int buffer_size);
2629
+
2630
+ /**
2631
+ * Return the folder id at @a index
2632
+ *
2633
+ * @param[in] pc Playlist container
2634
+ * @param[in] index Index in playlist container. Should be in the interval [0, sp_playlistcontainer_num_playlists() - 1]
2635
+ *
2636
+ * @return The group ID
2637
+ *
2638
+ * @sa sp_session_playlistcontainer()
2639
+ */
2640
+ SP_LIBEXPORT(sp_uint64) sp_playlistcontainer_playlist_folder_id(sp_playlistcontainer *pc, int index);
2641
+
2642
+ /**
2643
+ * Add an empty playlist at the end of the playlist container.
2644
+ * The name must not consist of only spaces and it must be shorter than 256 characters.
2645
+ *
2646
+ * @param[in] pc Playlist container
2647
+ * @param[in] name Name of new playlist
2648
+ *
2649
+ * @return Pointer to the new playlist. Can be NULL if the operation fails.
2650
+ */
2651
+ SP_LIBEXPORT(sp_playlist *) sp_playlistcontainer_add_new_playlist(sp_playlistcontainer *pc, const char *name);
2652
+
2653
+ /**
2654
+ * Add an existing playlist at the end of the given playlist container
2655
+ *
2656
+ * @param[in] pc Playlist container
2657
+ * @param[in] link Link object pointing to a playlist
2658
+ *
2659
+ * @return Pointer to the new playlist. Will be NULL if the playlist already exists.
2660
+ */
2661
+ SP_LIBEXPORT(sp_playlist *) sp_playlistcontainer_add_playlist(sp_playlistcontainer *pc, sp_link *link);
2662
+
2663
+ /**
2664
+ * Remove playlist at index from the given playlist container
2665
+ *
2666
+ * @param[in] pc Playlist container
2667
+ * @param[in] index Index of playlist to be removed
2668
+ *
2669
+ * @return error One of the following errors, from ::sp_error
2670
+ * SP_ERROR_OK
2671
+ * SP_ERROR_INDEX_OUT_OF_RANGE
2672
+ */
2673
+ SP_LIBEXPORT(sp_error) sp_playlistcontainer_remove_playlist(sp_playlistcontainer *pc, int index);
2674
+
2675
+ /**
2676
+ * Move a playlist in the playlist container
2677
+ *
2678
+ * @param[in] pc Playlist container
2679
+ * @param[in] index Index of playlist to be moved
2680
+ * @param[in] new_position New position for the playlist
2681
+ * @param[in] dry_run Do not execute the move, only check if it possible
2682
+
2683
+ * @return error One of the following errors, from ::sp_error
2684
+ * SP_ERROR_OK
2685
+ * SP_ERROR_INDEX_OUT_OF_RANGE
2686
+ * SP_ERROR_INVALID_INDATA - If trying to move a folder into itself
2687
+ */
2688
+ SP_LIBEXPORT(sp_error) sp_playlistcontainer_move_playlist(sp_playlistcontainer *pc, int index, int new_position, bool dry_run);
2689
+
2690
+
2691
+ /**
2692
+ * Add a playlist folder
2693
+ *
2694
+ * @param[in] pc Playlist container
2695
+ * @param[in] index Position of SP_PLAYLIST_TYPE_START_FOLDER entry
2696
+ * @param[in] name Name of group
2697
+
2698
+ * @return error One of the following errors, from ::sp_error
2699
+ * SP_ERROR_OK
2700
+ * SP_ERROR_INDEX_OUT_OF_RANGE
2701
+ *
2702
+ * @note This operation will actually create two playlists. One of
2703
+ * type SP_PLAYLIST_TYPE_START_FOLDER and immediately following a
2704
+ * SP_PLAYLIST_TYPE_END_FOLDER one.
2705
+ *
2706
+ * To remove a playlist folder both of these must be deleted or the list
2707
+ * will be left in an inconsistant state.
2708
+ *
2709
+ * There is no way to rename a playlist folder. Instead you need to remove
2710
+ * the folder and recreate it again.
2711
+ */
2712
+ SP_LIBEXPORT(sp_error) sp_playlistcontainer_add_folder(sp_playlistcontainer *pc, int index, const char *name);
2713
+
2714
+
2715
+ /**
2716
+ * Return a pointer to the user object of the owner.
2717
+ *
2718
+ * @param[in] pc Playlist container.
2719
+ * @return The user object or NULL if unknown or none.
2720
+ */
2721
+ SP_LIBEXPORT(sp_user *) sp_playlistcontainer_owner(sp_playlistcontainer *pc);
2722
+
2723
+
2724
+ /**
2725
+ * Increase reference count on playlistconatiner object
2726
+ *
2727
+ * @param[in] pc Playlist container.
2728
+ */
2729
+ SP_LIBEXPORT(void) sp_playlistcontainer_add_ref(sp_playlistcontainer *pc);
2730
+
2731
+ /**
2732
+ * Release reference count on playlistconatiner object
2733
+ *
2734
+ * @param[in] pc Playlist container.
2735
+ */
2736
+ SP_LIBEXPORT(void) sp_playlistcontainer_release(sp_playlistcontainer *pc);
2737
+
2738
+ /** @} */
2739
+
2740
+
2741
+ /**
2742
+ * @defgroup user User handling
2743
+ * @{
2744
+ */
2745
+
2746
+
2747
+ /**
2748
+ * User relation type
2749
+ */
2750
+ typedef enum sp_relation_type {
2751
+ SP_RELATION_TYPE_UNKNOWN = 0, ///< Not yet known
2752
+ SP_RELATION_TYPE_NONE = 1, ///< No relation
2753
+ SP_RELATION_TYPE_UNIDIRECTIONAL = 2, ///< The currently logged in user is following this uer
2754
+ SP_RELATION_TYPE_BIDIRECTIONAL = 3, ///< Bidirectional friendship established
2755
+ } sp_relation_type;
2756
+
2757
+
2758
+
2759
+ /**
2760
+ * Get a pointer to a string representing the user's canonical username.
2761
+ *
2762
+ * @param[in] user The Spotify user whose canonical username you would like a string representation of
2763
+ *
2764
+ * @return A string representing the canonical username.
2765
+ */
2766
+ SP_LIBEXPORT(const char *) sp_user_canonical_name(sp_user *user);
2767
+
2768
+ /**
2769
+ * Get a pointer to a string representing the user's displayable username.
2770
+ * If there is no difference between the canonical username and the display name,
2771
+ * or if the library does not know about the display name yet, the canonical username will
2772
+ * be returned.
2773
+ *
2774
+ * @param[in] user The Spotify user whose displayable username you would like a string representation of
2775
+ *
2776
+ * @return A string
2777
+ */
2778
+ SP_LIBEXPORT(const char *) sp_user_display_name(sp_user *user);
2779
+
2780
+ /**
2781
+ * Get load status for a user object. Before it is loaded, only the user's canonical username
2782
+ * is known.
2783
+ *
2784
+ * @param[in] user Spotify user object
2785
+ *
2786
+ * @return True if user object is loaded, otherwise false
2787
+ */
2788
+ SP_LIBEXPORT(bool) sp_user_is_loaded(sp_user *user);
2789
+
2790
+ /**
2791
+ * Get a pointer to a string representing the user's full name as returned from social networks.
2792
+ *
2793
+ * @param[in] user The Spotify user whose displayable username you would like a string representation of
2794
+ *
2795
+ * @return A string, NULL if the full name is not known.
2796
+ */
2797
+ SP_LIBEXPORT(const char *) sp_user_full_name(sp_user *user);
2798
+
2799
+ /**
2800
+ * Get a pointer to an URL for an picture representing the user
2801
+ *
2802
+ * @param[in] user The Spotify user whose displayable username you would like a string representation of
2803
+ *
2804
+ * @return A string, NULL if the URL is not known.
2805
+ */
2806
+ SP_LIBEXPORT(const char *) sp_user_picture(sp_user *user);
2807
+
2808
+ /**
2809
+ * Get relation type for a given user
2810
+ *
2811
+ * @param[in] session Session
2812
+ * @param[in] user The Spotify user you want to query relation type for
2813
+ *
2814
+ * @return ::sp_relation_type
2815
+ */
2816
+ SP_LIBEXPORT(sp_relation_type) sp_user_relation_type(sp_session *session, sp_user *user);
2817
+
2818
+ /**
2819
+ * Increase the reference count of an user
2820
+ *
2821
+ * @param[in] user The user object
2822
+ */
2823
+ SP_LIBEXPORT(void) sp_user_add_ref(sp_user *user);
2824
+
2825
+ /**
2826
+ * Decrease the reference count of an user
2827
+ *
2828
+ * @param[in] user The user object
2829
+ */
2830
+ SP_LIBEXPORT(void) sp_user_release(sp_user *user);
2831
+
2832
+ /** @} */
2833
+
2834
+
2835
+ /**
2836
+ * @defgroup toplist Toplist handling
2837
+ * @{
2838
+ */
2839
+
2840
+ /**
2841
+ * Toplist types
2842
+ */
2843
+ typedef enum {
2844
+ SP_TOPLIST_TYPE_ARTISTS = 0, ///< Top artists
2845
+ SP_TOPLIST_TYPE_ALBUMS = 1, ///< Top albums
2846
+ SP_TOPLIST_TYPE_TRACKS = 2, ///< Top tracks
2847
+ } sp_toplisttype;
2848
+
2849
+
2850
+ /**
2851
+ * Convenience macro to create a toplist region. Toplist regions are ISO 3166-1
2852
+ * country codes (in uppercase) encoded in an integer. There are also some reserved
2853
+ * codes used to denote non-country regions. See sp_toplistregion
2854
+ *
2855
+ * Example: SP_TOPLIST_REGION('S', 'E') // for sweden
2856
+ */
2857
+ #define SP_TOPLIST_REGION(a, b) ((a) << 8 | (b))
2858
+
2859
+ /**
2860
+ * Special toplist regions
2861
+ */
2862
+ typedef enum {
2863
+ SP_TOPLIST_REGION_EVERYWHERE = 0, ///< Global toplist
2864
+ SP_TOPLIST_REGION_USER = 1, ///< Toplist for a given user
2865
+ } sp_toplistregion;
2866
+
2867
+
2868
+ /**
2869
+ * The type of a callback used in sp_toplistbrowse_create()
2870
+ *
2871
+ * When the callback is called, the metadata of all tracks belonging to it will have
2872
+ * been loaded, so sp_track_is_loaded() will return non-zero. The same goes for the
2873
+ * similar toplist data.
2874
+ *
2875
+ * @param[in] result The same pointer returned by sp_toplistbrowse_create()
2876
+ * @param[in] userdata The opaque pointer given to sp_toplistbrowse_create()
2877
+ */
2878
+ typedef void SP_CALLCONV toplistbrowse_complete_cb(sp_toplistbrowse *result, void *userdata);
2879
+
2880
+ /**
2881
+ * Initiate a request for browsing an toplist
2882
+ *
2883
+ * The user is responsible for freeing the returned toplist browse using sp_toplistbrowse_release(). This can be done in the callback.
2884
+ *
2885
+ * @param[in] session Session object
2886
+ * @param[in] type Type of toplist to be browsed. see the sp_toplisttype enum for possible values
2887
+ * @param[in] region Region. see sp_toplistregion enum. Country specific regions are coded as two chars in an integer.
2888
+ * Sweden would correspond to 'S' << 8 | 'E'
2889
+ * @param[in] username If region is SP_TOPLIST_REGION_USER this specifies which user to get toplists for. NULL means the logged in user.
2890
+ * @param[in] callback Callback to be invoked when browsing has been completed. Pass NULL if you are not interested in this event.
2891
+ * @param[in] userdata Userdata passed to callback.
2892
+ *
2893
+ * @return Toplist browse object
2894
+ *
2895
+ * @see ::toplistbrowse_complete_cb
2896
+ */
2897
+ SP_LIBEXPORT(sp_toplistbrowse *) sp_toplistbrowse_create(sp_session *session, sp_toplisttype type, sp_toplistregion region, const char *username, toplistbrowse_complete_cb *callback, void *userdata);
2898
+
2899
+
2900
+ /**
2901
+ * Check if an toplist browse request is completed
2902
+ *
2903
+ * @param[in] tlb Toplist browse object
2904
+ *
2905
+ * @return True if browsing is completed, false if not
2906
+ */
2907
+ SP_LIBEXPORT(bool) sp_toplistbrowse_is_loaded(sp_toplistbrowse *tlb);
2908
+
2909
+ /**
2910
+ * Check if browsing returned an error code.
2911
+ *
2912
+ * @param[in] tlb Toplist browse object
2913
+ *
2914
+ * @return One of the following errors, from ::sp_error
2915
+ * SP_ERROR_OK
2916
+ * SP_ERROR_IS_LOADING
2917
+ * SP_ERROR_OTHER_PERMANENT
2918
+ * SP_ERROR_OTHER_TRANSIENT
2919
+ */
2920
+ SP_LIBEXPORT(sp_error) sp_toplistbrowse_error(sp_toplistbrowse *tlb);
2921
+
2922
+
2923
+
2924
+ /**
2925
+ * Increase the reference count of an toplist browse result
2926
+ *
2927
+ * @param[in] tlb The toplist browse result object
2928
+ */
2929
+ SP_LIBEXPORT(void) sp_toplistbrowse_add_ref(sp_toplistbrowse *tlb);
2930
+
2931
+ /**
2932
+ * Decrease the reference count of an toplist browse result
2933
+ *
2934
+ * @param[in] tlb The toplist browse result object
2935
+ */
2936
+ SP_LIBEXPORT(void) sp_toplistbrowse_release(sp_toplistbrowse *tlb);
2937
+
2938
+ /**
2939
+ * Given an toplist browse object, return number of artists
2940
+ *
2941
+ * @param[in] tlb Toplist browse object
2942
+ *
2943
+ * @return Number of artists on toplist
2944
+ */
2945
+ SP_LIBEXPORT(int) sp_toplistbrowse_num_artists(sp_toplistbrowse *tlb);
2946
+
2947
+ /**
2948
+ * Return the artist at the given index in the given toplist browse object
2949
+ *
2950
+ * @param[in] tlb Toplist object
2951
+ * @param[in] index Index of the wanted artist. Should be in the interval [0, sp_toplistbrowse_num_artists() - 1]
2952
+ *
2953
+ * @return The artist at the given index in the given toplist browse object
2954
+ */
2955
+ SP_LIBEXPORT(sp_artist *) sp_toplistbrowse_artist(sp_toplistbrowse *tlb, int index);
2956
+
2957
+
2958
+ /**
2959
+ * Given an toplist browse object, return number of albums
2960
+ *
2961
+ * @param[in] tlb Toplist browse object
2962
+ *
2963
+ * @return Number of albums on toplist
2964
+ */
2965
+ SP_LIBEXPORT(int) sp_toplistbrowse_num_albums(sp_toplistbrowse *tlb);
2966
+
2967
+
2968
+ /**
2969
+ * Return the album at the given index in the given toplist browse object
2970
+ *
2971
+ * @param[in] tlb Toplist object
2972
+ * @param[in] index Index of the wanted album. Should be in the interval [0, sp_toplistbrowse_num_albums() - 1]
2973
+ *
2974
+ * @return The album at the given index in the given toplist browse object
2975
+ */
2976
+ SP_LIBEXPORT(sp_album *) sp_toplistbrowse_album(sp_toplistbrowse *tlb, int index);
2977
+
2978
+
2979
+ /**
2980
+ * Given an toplist browse object, return number of tracks
2981
+ *
2982
+ * @param[in] tlb Toplist browse object
2983
+ *
2984
+ * @return Number of tracks on toplist
2985
+ */
2986
+ SP_LIBEXPORT(int) sp_toplistbrowse_num_tracks(sp_toplistbrowse *tlb);
2987
+
2988
+
2989
+ /**
2990
+ * Return the track at the given index in the given toplist browse object
2991
+ *
2992
+ * @param[in] tlb Toplist object
2993
+ * @param[in] index Index of the wanted track. Should be in the interval [0, sp_toplistbrowse_num_tracks() - 1]
2994
+ *
2995
+ * @return The track at the given index in the given toplist browse object
2996
+ */
2997
+ SP_LIBEXPORT(sp_track *) sp_toplistbrowse_track(sp_toplistbrowse *tlb, int index);
2998
+
2999
+
3000
+ /** @} */
3001
+
3002
+ /**
3003
+ * @defgroup inbox Inbox subsysten
3004
+ * @{
3005
+ */
3006
+
3007
+ /**
3008
+ * The type of a callback used in sp_inbox_post()
3009
+ *
3010
+ * When this callback is called, the sp_track_is_loaded(), sp_album_is_loaded(),
3011
+ * and sp_artist_is_loaded() functions will return non-zero for the objects
3012
+ * contained in the search result.
3013
+ *
3014
+ * @param[in] result The same pointer returned by sp_search_create()
3015
+ * @param[in] userdata The opaque pointer given to sp_search_create()
3016
+ */
3017
+ typedef void SP_CALLCONV inboxpost_complete_cb(sp_inbox *result, void *userdata);
3018
+
3019
+ /**
3020
+ * Add to inbox
3021
+ *
3022
+ * @param[in] session Session object
3023
+ * @param[in] user Canonical username of recipient
3024
+ * @param[in] tracks Array of trancks to post
3025
+ * @param[in] num_tracks Number of tracks in \p tracks
3026
+ * @param[in] message Message to attach to tracks. UTF-8
3027
+ * @param[in] callback Callback to be invoked when the request has completed
3028
+ * @param[in] userdata Userdata passed to callback
3029
+ *
3030
+ * @return sp_inbox object if the request has been sent, NULL if request failed to initialize
3031
+ */
3032
+ SP_LIBEXPORT(sp_inbox *) sp_inbox_post_tracks(sp_session *session, const char *user, sp_track * const *tracks, int num_tracks, const char *message, inboxpost_complete_cb *callback, void *userdata);
3033
+
3034
+
3035
+ /**
3036
+ * Check if inbox operation returned an error code.
3037
+ *
3038
+ * @param[in] inbox Inbox object
3039
+ *
3040
+ * @return One of the following errors, from ::sp_error
3041
+ * SP_ERROR_OK
3042
+ * SP_ERROR_OTHER_TRANSIENT
3043
+ * SP_ERROR_PERMISSION_DENIED
3044
+ * SP_ERROR_INVALID_INDATA
3045
+ * SP_ERROR_INBOX_IS_FULL
3046
+ * SP_ERROR_NO_SUCH_USER
3047
+ * SP_ERROR_OTHER_PERMANENT
3048
+ */
3049
+ SP_LIBEXPORT(sp_error) sp_inbox_error(sp_inbox *inbox);
3050
+
3051
+ /**
3052
+ * Increase the reference count of a inbox result
3053
+ *
3054
+ * @param[in] inbox The inbox result object
3055
+ */
3056
+ SP_LIBEXPORT(void) sp_inbox_add_ref(sp_inbox *inbox);
3057
+
3058
+ /**
3059
+ * Decrease the reference count of a inbox result
3060
+ *
3061
+ * @param[in] inbox The inbox result object
3062
+ */
3063
+ SP_LIBEXPORT(void) sp_inbox_release(sp_inbox *inbox);
3064
+
3065
+ /** @} */
3066
+
3067
+
3068
+ #ifdef __cplusplus
3069
+ }
3070
+ #endif
3071
+
3072
+ #endif /* PUBLIC_API_H */
3073
+ /**
3074
+ * @example browse.c
3075
+ *
3076
+ * The browse.c example shows how you can use the album, artist, and browse functions.
3077
+ * The example also include some rudimentary playlist browsing.
3078
+ * It is part of the spshell program
3079
+ */
3080
+ /**
3081
+ * @example search.c
3082
+ *
3083
+ * The search.c example shows how you can use search functions.
3084
+ * It is part of the spshell program
3085
+ */
3086
+ /**
3087
+ * @example toplist.c
3088
+ *
3089
+ * The toplist.c example shows how you can use toplist functions.
3090
+ * It is part of the spshell program
3091
+ */
3092
+ /**
3093
+ * @example jukebox.c
3094
+ *
3095
+ * The jukebox.c example shows how you can use playback and playlist functions.
3096
+ */