mockspotify 0.1.4 → 0.1.5

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