diff --git a/include/mpd/song.h b/include/mpd/song.h index 9323f53..c4f9063 100644 --- a/include/mpd/song.h +++ b/include/mpd/song.h @@ -100,6 +100,15 @@ const char * mpd_song_get_tag(const struct mpd_song *song, enum mpd_tag_type type, unsigned idx); +/** + * Returns the "real" URI of the song, the one to be used for opening + * the resource. If this attribute is nullptr, then #mpd_song_get_uri + * shall be used. + */ +mpd_pure +const char * +mpd_song_get_real_uri(const struct mpd_song *song); + /** * Returns the duration of this song in seconds. 0 means the duration * is unknown. @@ -128,6 +137,14 @@ mpd_pure unsigned mpd_song_get_start(const struct mpd_song *song); +/** + * Returns the start of the virtual song within the physical file in + * milliseconds. + */ +mpd_pure +unsigned +mpd_song_get_start_ms(const struct mpd_song *song); + /** * Returns the end of the virtual song within the physical file in * seconds. 0 means that the physical song file is played to the end. @@ -138,6 +155,14 @@ mpd_pure unsigned mpd_song_get_end(const struct mpd_song *song); +/** + * Returns the end of the virtual song within the physical file in + * milliseconds. 0 means that the physical song file is played to the end. + */ +mpd_pure +unsigned +mpd_song_get_end_ms(const struct mpd_song *song); + /** * @return the POSIX UTC time stamp of the last modification, or 0 if * that is unknown diff --git a/libmpdclient.ld b/libmpdclient.ld index f3633b4..98ca371 100644 --- a/libmpdclient.ld +++ b/libmpdclient.ld @@ -362,10 +362,13 @@ global: mpd_song_dup; mpd_song_get_uri; mpd_song_get_tag; + mpd_song_get_real_uri; mpd_song_get_duration; mpd_song_get_duration_ms; mpd_song_get_start; + mpd_song_get_start_ms; mpd_song_get_end; + mpd_song_get_end_ms; mpd_song_get_last_modified; mpd_song_set_pos; mpd_song_get_pos; diff --git a/src/song.c b/src/song.c index a0d18ec..2fea65a 100644 --- a/src/song.c +++ b/src/song.c @@ -55,6 +55,13 @@ struct mpd_song { struct mpd_tag_value tags[MPD_TAG_COUNT]; + /** + * The "real" URI, the one to be used for opening the + * resource. If this attribute is nullptr, then #uri + * shall be used. + */ + char *real_uri; + /** * Duration of the song in seconds, or 0 for unknown. */ @@ -71,6 +78,12 @@ struct mpd_song { */ unsigned start; + /** + * Start of the virtual song within the physical file in + * milliseconds. + */ + unsigned start_ms; + /** * End of the virtual song within the physical file in * seconds. Zero means that the physical song file is @@ -78,6 +91,13 @@ struct mpd_song { */ unsigned end; + /** + * End of the virtual song within the physical file in + * milliseconds. Zero means that the physical song + * file is played to the end. + */ + unsigned end_ms; + /** * The POSIX UTC time stamp of the last modification, or 0 if * that is unknown. @@ -136,10 +156,13 @@ mpd_song_new(const char *uri) for (unsigned i = 0; i < MPD_TAG_COUNT; ++i) song->tags[i].value = NULL; + song->real_uri = NULL; song->duration = 0; song->duration_ms = 0; song->start = 0; + song->start_ms = 0; song->end = 0; + song->end_ms = 0; song->last_modified = 0; song->pos = 0; song->id = 0; @@ -179,6 +202,8 @@ void mpd_song_free(struct mpd_song *song) { } } + free(song->real_uri); + free(song); } @@ -216,10 +241,13 @@ mpd_song_dup(const struct mpd_song *song) } while (src_tag != NULL); } + ret->real_uri = strdup(song->real_uri); ret->duration = song->duration; ret->duration_ms = song->duration_ms; ret->start = song->start; + ret->start_ms = song->start_ms; ret->end = song->end; + ret->end_ms = song->end_ms; ret->last_modified = song->last_modified; ret->pos = song->pos; ret->id = song->id; @@ -331,6 +359,20 @@ mpd_song_get_tag(const struct mpd_song *song, return tag->value; } +static void +mpd_song_set_real_uri(struct mpd_song *song, char *real_uri) +{ + song->real_uri = real_uri; +} + +const char * +mpd_song_get_real_uri(const struct mpd_song *song) +{ + assert(song != NULL); + + return song->real_uri; +} + static void mpd_song_set_duration(struct mpd_song *song, unsigned duration) { @@ -371,6 +413,14 @@ mpd_song_get_start(const struct mpd_song *song) return song->start; } +unsigned +mpd_song_get_start_ms(const struct mpd_song *song) +{ + assert(song != NULL); + + return song->start_ms; +} + unsigned mpd_song_get_end(const struct mpd_song *song) { @@ -379,6 +429,14 @@ mpd_song_get_end(const struct mpd_song *song) return song->end; } +unsigned +mpd_song_get_end_ms(const struct mpd_song *song) +{ + assert(song != NULL); + + return song->end_ms; +} + static void mpd_song_set_last_modified(struct mpd_song *song, time_t mtime) { @@ -483,15 +541,19 @@ mpd_song_parse_range(struct mpd_song *song, const char *value) } song->start = start > 0.0 ? (unsigned)start : 0; + song->start_ms = start > 0.0 ? (unsigned)(start * 1000) : 0; if (end > 0.0) { song->end = (unsigned)end; + song->end_ms = (unsigned)(end * 1000); if (song->end == 0) /* round up, because the caller must sees that there's an upper limit */ song->end = 1; - } else + } else { song->end = 0; + song->end_ms = 0; + } } static void @@ -546,6 +608,8 @@ mpd_song_feed(struct mpd_song *song, const struct mpd_pair *pair) mpd_song_set_prio(song, strtoul(pair->value, NULL, 10)); else if (strcmp(pair->name, "Format") == 0) mpd_song_parse_audio_format(song, pair->value); + else if (strcmp(pair->name, "RealUri") == 0) + mpd_song_set_real_uri(song, strdup(pair->value)); return true; }