1 /* libmpdclient
2 * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
3 * This project's homepage is: http://www.musicpd.org
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
20 #ifndef LIBMPDCLIENT_H
21 #define LIBMPDCLIENT_H
23 #include <sys/time.h>
25 #define MPD_BUFFER_MAX_LENGTH 50000
26 #define MPD_WELCOME_MESSAGE "OK MPD "
28 #define MPD_ERROR_TIMEOUT 10 /* timeout trying to talk to mpd */
29 #define MPD_ERROR_SYSTEM 11 /* system error */
30 #define MPD_ERROR_UNKHOST 12 /* unknown host */
31 #define MPD_ERROR_CONNPORT 13 /* problems connecting to port on host */
32 #define MPD_ERROR_NOTMPD 14 /* mpd not running on port at host */
33 #define MPD_ERROR_NORESPONSE 15 /* no response on attempting to connect */
34 #define MPD_ERROR_SENDING 16 /* error sending command */
35 #define MPD_ERROR_CONNCLOSED 17 /* connection closed by mpd */
36 #define MPD_ERROR_ACK 18 /* ACK returned! */
37 #define MPD_ERROR_BUFFEROVERRUN 19 /* Buffer was overrun! */
39 #define MPD_ACK_ERROR_UNK -1
40 #define MPD_ERROR_AT_UNK -1
42 #define MPD_ACK_ERROR_NOT_LIST 1
43 #define MPD_ACK_ERROR_ARG 2
44 #define MPD_ACK_ERROR_PASSWORD 3
45 #define MPD_ACK_ERROR_PERMISSION 4
46 #define MPD_ACK_ERROR_UNKNOWN_CMD 5
47 #define MPD_ACK_ERROR_NO_EXIST 6
48 #define MPD_ACK_ERROR_PLAYLIST_MAX 7
49 #define MPD_ACK_ERROR_SYSTEM 8
50 #define MPD_ACK_ERROR_PLAYLIST_LOAD 9
51 #define MPD_ACK_ERROR_UPDATE_ALREADY 10
52 #define MPD_ACK_ERROR_PLAYER_SYNC 11
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
58 /* internal stuff don't touch this struct */
59 typedef struct _mpd_ReturnElement {
60 char * name;
61 char * value;
62 } mpd_ReturnElement;
64 /* mpd_Connection
65 * holds info about connection to mpd
66 * use error, and errorStr to detect errors
67 */
68 typedef struct _mpd_Connection {
69 /* use this to check the version of mpd */
70 int version[3];
71 /* IMPORTANT, you want to get the error messages from here */
72 char errorStr[MPD_BUFFER_MAX_LENGTH+1];
73 int errorCode;
74 int errorAt;
75 /* this will be set to MPD_ERROR_* if there is an error, 0 if not */
76 int error;
77 /* DON'T TOUCH any of the rest of this stuff */
78 int sock;
79 char buffer[MPD_BUFFER_MAX_LENGTH+1];
80 int buflen;
81 int bufstart;
82 int doneProcessing;
83 int listOks;
84 int doneListOk;
85 int commandList;
86 mpd_ReturnElement * returnElement;
87 struct timeval timeout;
88 } mpd_Connection;
90 /* mpd_newConnection
91 * use this to open a new connection
92 * you should use mpd_closeConnection, when your done with the connection,
93 * even if an error has occurred
94 * _timeout_ is the connection timeout period in seconds
95 */
96 mpd_Connection * mpd_newConnection(const char * host, int port, float timeout);
98 void mpd_setConnectionTimeout(mpd_Connection * connection, float timeout);
100 /* mpd_closeConnection
101 * use this to close a connection and free'ing subsequent memory
102 */
103 void mpd_closeConnection(mpd_Connection * connection);
105 /* mpd_clearError
106 * clears error
107 */
108 void mpd_clearError(mpd_Connection * connection);
110 /* STATUS STUFF */
112 /* use these with status.state to determine what state the player is in */
113 #define MPD_STATUS_STATE_UNKNOWN 0
114 #define MPD_STATUS_STATE_STOP 1
115 #define MPD_STATUS_STATE_PLAY 2
116 #define MPD_STATUS_STATE_PAUSE 3
118 /* us this with status.volume to determine if mpd has volume support */
119 #define MPD_STATUS_NO_VOLUME -1
121 /* mpd_Status
122 * holds info return from status command
123 */
124 typedef struct mpd_Status {
125 /* 0-100, or MPD_STATUS_NO_VOLUME when there is no volume support */
126 int volume;
127 /* 1 if repeat is on, 0 otherwise */
128 int repeat;
129 /* 1 if random is on, 0 otherwise */
130 int random;
131 /* playlist length */
132 int playlistLength;
133 /* playlist, use this to determine when the playlist has changed */
134 long long playlist;
135 /* use with MPD_STATUS_STATE_* to determine state of player */
136 int state;
137 /* crossfade setting in seconds */
138 int crossfade;
139 /* if in PLAY or PAUSE state, this is the position of the currently
140 * playing song in the playlist, beginning with 0
141 */
142 int song;
143 int songid;
144 /* time in seconds that have elapsed in the currently playing/paused
145 * song
146 */
147 int elapsedTime;
148 /* length in seconds of the currently playing/paused song */
149 int totalTime;
150 /* current bit rate in kbs */
151 int bitRate;
152 /* audio sample rate */
153 unsigned int sampleRate;
154 /* audio bits */
155 int bits;
156 /* audio channels */
157 int channels;
158 /* 1 if mpd is updating, 0 otherwise */
159 int updatingDb;
160 /* error */
161 char * error;
162 } mpd_Status;
164 void mpd_sendStatusCommand(mpd_Connection * connection);
166 /* mpd_getStatus
167 * returns status info, be sure to free it with mpd_freeStatus()
168 */
169 mpd_Status * mpd_getStatus(mpd_Connection * connection);
171 /* mpd_freeStatus
172 * free's status info malloc'd and returned by mpd_getStatus
173 */
174 void mpd_freeStatus(mpd_Status * status);
176 typedef struct _mpd_Stats {
177 int numberOfArtists;
178 int numberOfAlbums;
179 int numberOfSongs;
180 unsigned long uptime;
181 unsigned long dbUpdateTime;
182 unsigned long playTime;
183 unsigned long dbPlayTime;
184 } mpd_Stats;
186 void mpd_sendStatsCommand(mpd_Connection * connection);
188 mpd_Stats * mpd_getStats(mpd_Connection * connection);
190 void mpd_freeStats(mpd_Stats * stats);
192 /* SONG STUFF */
194 #define MPD_SONG_NO_TIME -1
195 #define MPD_SONG_NO_NUM -1
196 #define MPD_SONG_NO_ID -1
198 /* mpd_Song
199 * for storing song info returned by mpd
200 */
201 typedef struct _mpd_Song {
202 /* filename of song */
203 char * file;
204 /* artist, maybe NULL if there is no tag */
205 char * artist;
206 /* title, maybe NULL if there is no tag */
207 char * title;
208 /* album, maybe NULL if there is no tag */
209 char * album;
210 /* track, maybe NULL if there is no tag */
211 char * track;
212 /* name, maybe NULL if there is no tag; it's the name of the current
213 * song, f.e. the icyName of the stream */
214 char * name;
215 /* length of song in seconds, check that it is not MPD_SONG_NO_TIME */
216 int time;
217 /* if plchanges or playlistinfo used, is the position of the song in
218 * the playlist */
219 int pos;
220 int id;
221 } mpd_Song;
223 /* mpd_newSong
224 * use to allocate memory for a new mpd_Song
225 * file, artist, etc all initialized to NULL
226 * if your going to assign values to file, artist, etc
227 * be sure to malloc or strdup the memory
228 * use mpd_freeSong to free the memory for the mpd_Song, it will also
229 * free memory for file, artist, etc, so don't do it yourself
230 */
231 mpd_Song * mpd_newSong();
233 /* mpd_freeSong
234 * use to free memory allocated by mpd_newSong
235 * also it will free memory pointed to by file, artist, etc, so be careful
236 */
237 void mpd_freeSong(mpd_Song * song);
239 /* mpd_songDup
240 * works like strDup, but for a mpd_Song
241 */
242 mpd_Song * mpd_songDup(mpd_Song * song);
244 /* DIRECTORY STUFF */
246 /* mpd_Directory
247 * used to store info fro directory (right now that just the path)
248 */
249 typedef struct _mpd_Directory {
250 char * path;
251 } mpd_Directory;
253 /* mpd_newDirectory
254 * allocates memory for a new directory
255 * use mpd_freeDirectory to free this memory
256 */
257 mpd_Directory * mpd_newDirectory ();
259 /* mpd_freeDirectory
260 * used to free memory allocated with mpd_newDirectory, and it frees
261 * path of mpd_Directory, so be careful
262 */
263 void mpd_freeDirectory(mpd_Directory * directory);
265 /* mpd_directoryDup
266 * works like strdup, but for mpd_Directory
267 */
268 mpd_Directory * mpd_directoryDup(mpd_Directory * directory);
270 /* PLAYLISTFILE STUFF */
272 /* mpd_PlaylistFile
273 * stores info about playlist file returned by lsinfo
274 */
275 typedef struct _mpd_PlaylistFile {
276 char * path;
277 } mpd_PlaylistFile;
279 /* mpd_newPlaylistFile
280 * allocates memory for new mpd_PlaylistFile, path is set to NULL
281 * free this memory with mpd_freePlaylistFile
282 */
283 mpd_PlaylistFile * mpd_newPlaylistFile();
285 /* mpd_freePlaylist
286 * free memory allocated for freePlaylistFile, will also free
287 * path, so be careful
288 */
289 void mpd_freePlaylistFile(mpd_PlaylistFile * playlist);
291 /* mpd_playlistFileDup
292 * works like strdup, but for mpd_PlaylistFile
293 */
294 mpd_PlaylistFile * mpd_playlistFileDup(mpd_PlaylistFile * playlist);
296 /* INFO ENTITY STUFF */
298 /* the type of entity returned from one of the commands that generates info
299 * use in conjunction with mpd_InfoEntity.type
300 */
301 #define MPD_INFO_ENTITY_TYPE_DIRECTORY 0
302 #define MPD_INFO_ENTITY_TYPE_SONG 1
303 #define MPD_INFO_ENTITY_TYPE_PLAYLISTFILE 2
305 /* mpd_InfoEntity
306 * stores info on stuff returned info commands
307 */
308 typedef struct mpd_InfoEntity {
309 /* the type of entity, use with MPD_INFO_ENTITY_TYPE_* to determine
310 * what this entity is (song, directory, etc...)
311 */
312 int type;
313 /* the actual data you want, mpd_Song, mpd_Directory, etc */
314 union {
315 mpd_Directory * directory;
316 mpd_Song * song;
317 mpd_PlaylistFile * playlistFile;
318 } info;
319 } mpd_InfoEntity;
321 mpd_InfoEntity * mpd_newInfoEntity();
323 void mpd_freeInfoEntity(mpd_InfoEntity * entity);
325 /* INFO COMMANDS AND STUFF */
327 /* use this function to loop over after calling Info/Listall functions */
328 mpd_InfoEntity * mpd_getNextInfoEntity(mpd_Connection * connection);
330 void mpd_sendCurrentSongCommand(mpd_Connection * connection);
332 /* songNum of -1, means to display the whole list */
333 void mpd_sendPlaylistInfoCommand(mpd_Connection * connection, int songNum);
335 /* use this to get the changes in the playlist since version _playlist_ */
336 void mpd_sendPlChangesCommand(mpd_Connection * connection, long long playlist);
338 void mpd_sendListallCommand(mpd_Connection * connection, const char * dir);
340 void mpd_sendListallInfoCommand(mpd_Connection * connection, const char * dir);
342 void mpd_sendLsInfoCommand(mpd_Connection * connection, const char * dir);
344 #define MPD_TABLE_ARTIST 0
345 #define MPD_TABLE_ALBUM 1
346 #define MPD_TABLE_TITLE 2
347 #define MPD_TABLE_FILENAME 3
349 void mpd_sendSearchCommand(mpd_Connection * connection, int table,
350 const char * str);
352 void mpd_sendFindCommand(mpd_Connection * connection, int table,
353 const char * str);
355 /* LIST TAG COMMANDS */
357 /* use this function fetch next artist entry, be sure to free the returned
358 * string. NULL means there are no more. Best used with sendListArtists
359 */
360 char * mpd_getNextArtist(mpd_Connection * connection);
362 char * mpd_getNextAlbum(mpd_Connection * connection);
364 /* list artist or albums by artist, arg1 should be set to the artist if
365 * listing albums by a artist, otherwise NULL for listing all artists or albums
366 */
367 void mpd_sendListCommand(mpd_Connection * connection, int table,
368 const char * arg1);
370 /* SIMPLE COMMANDS */
372 void mpd_sendAddCommand(mpd_Connection * connection, const char * file);
374 void mpd_sendDeleteCommand(mpd_Connection * connection, int songNum);
376 void mpd_sendDeleteIdCommand(mpd_Connection * connection, int songNum);
378 void mpd_sendSaveCommand(mpd_Connection * connection, const char * name);
380 void mpd_sendLoadCommand(mpd_Connection * connection, const char * name);
382 void mpd_sendRmCommand(mpd_Connection * connection, const char * name);
384 void mpd_sendShuffleCommand(mpd_Connection * connection);
386 void mpd_sendClearCommand(mpd_Connection * connection);
388 /* use this to start playing at the beginning, useful when in random mode */
389 #define MPD_PLAY_AT_BEGINNING -1
391 void mpd_sendPlayCommand(mpd_Connection * connection, int songNum);
393 void mpd_sendPlayIdCommand(mpd_Connection * connection, int songNum);
395 void mpd_sendStopCommand(mpd_Connection * connection);
397 void mpd_sendPauseCommand(mpd_Connection * connection, int pauseMode);
399 void mpd_sendNextCommand(mpd_Connection * connection);
401 void mpd_sendPrevCommand(mpd_Connection * connection);
403 void mpd_sendMoveCommand(mpd_Connection * connection, int from, int to);
405 void mpd_sendMoveIdCommand(mpd_Connection * connection, int from, int to);
407 void mpd_sendSwapCommand(mpd_Connection * connection, int song1, int song2);
409 void mpd_sendSwapIdCommand(mpd_Connection * connection, int song1, int song2);
411 void mpd_sendSeekCommand(mpd_Connection * connection, int song, int time);
413 void mpd_sendSeekIdCommand(mpd_Connection * connection, int song, int time);
415 void mpd_sendRepeatCommand(mpd_Connection * connection, int repeatMode);
417 void mpd_sendRandomCommand(mpd_Connection * connection, int randomMode);
419 void mpd_sendSetvolCommand(mpd_Connection * connection, int volumeChange);
421 /* WARNING: don't use volume command, its depreacted */
422 void mpd_sendVolumeCommand(mpd_Connection * connection, int volumeChange);
424 void mpd_sendCrossfadeCommand(mpd_Connection * connection, int seconds);
426 void mpd_sendUpdateCommand(mpd_Connection * connection);
428 /* returns the update job id, call this after a update command*/
429 int mpd_getUpdateId(mpd_Connection * connection);
431 void mpd_sendPasswordCommand(mpd_Connection * connection, const char * pass);
433 /* after executing a command, when your done with it to get its status
434 * (you want to check connection->error for an error)
435 */
436 void mpd_finishCommand(mpd_Connection * connection);
438 /* command list stuff, use this to do things like add files very quickly */
439 void mpd_sendCommandListBegin(mpd_Connection * connection);
441 void mpd_sendCommandListOkBegin(mpd_Connection * connection);
443 void mpd_sendCommandListEnd(mpd_Connection * connection);
445 int mpd_nextListOkCommand(mpd_Connection * connection);
447 #ifdef __cplusplus
448 }
449 #endif
451 #endif