Skip to content

Commit

Permalink
BPM metadata support
Browse files Browse the repository at this point in the history
  • Loading branch information
jayay authored and flyingmutant committed Jan 26, 2016
1 parent 2f169cc commit 976c10d
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 6 deletions.
3 changes: 2 additions & 1 deletion Doc/cmus.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,7 @@ Special Keys:
%F %{filename} @br
%{originaldate} @br
%{maxdate} @br
%{bpm} @br
%{bitrate} @br
%{codec} @br
%{codec_profile} @br
Expand Down Expand Up @@ -1181,7 +1182,7 @@ Sort option (lib_sort, pl_sort) value is space separated list of the following
sort keys:

artist, album, title, tracknumber, play_count, discnumber, date,
originaldate, genre, comment, albumartist, filename, filemtime,
originaldate, genre, comment, albumartist, filename, filemtime, bpm,
bitrate, codec, media, codec_profile, rg_track_gain, rg_track_peak,
rg_album_gain, rg_album_peak

Expand Down
9 changes: 6 additions & 3 deletions cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@
#include <errno.h>
#include <sys/mman.h>

#define CACHE_VERSION 0x0c
#define CACHE_VERSION 0x0d

#define CACHE_64_BIT 0x01
#define CACHE_BE 0x02

#define CACHE_RESERVED_PATTERN 0xff

#define CACHE_ENTRY_USED_SIZE 24
#define CACHE_ENTRY_RESERVED_SIZE 56
#define CACHE_ENTRY_USED_SIZE 28
#define CACHE_ENTRY_RESERVED_SIZE 52
#define CACHE_ENTRY_TOTAL_SIZE (CACHE_ENTRY_RESERVED_SIZE + CACHE_ENTRY_USED_SIZE)

// Cmus Track Cache version X + 4 bytes flags
Expand All @@ -61,6 +61,7 @@ struct cache_entry {
int64_t mtime;
int32_t duration;
int32_t bitrate;
int32_t bpm;

// when introducing new fields decrease the reserved space accordingly
uint8_t _reserved[CACHE_ENTRY_RESERVED_SIZE];
Expand Down Expand Up @@ -131,6 +132,7 @@ static struct track_info *cache_entry_to_ti(struct cache_entry *e)
ti->bitrate = e->bitrate;
ti->mtime = e->mtime;
ti->play_count = e->play_count;
ti->bpm = e->bpm;

// count strings (filename + codec + codec_profile + key/val pairs)
count = 0;
Expand Down Expand Up @@ -328,6 +330,7 @@ static void write_ti(int fd, struct gbuf *buf, struct track_info *ti, unsigned i
e.bitrate = ti->bitrate;
e.mtime = ti->mtime;
e.play_count = ti->play_count;
e.bpm = ti->bpm;
len[count] = strlen(ti->filename) + 1;
e.size += len[count++];
len[count] = (ti->codec ? strlen(ti->codec) : 0) + 1;
Expand Down
2 changes: 2 additions & 0 deletions comment.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ static const char *interesting[] = {
"replaygain_album_peak",
"musicbrainz_trackid",
"comment",
"bpm",
"arranger", "composer", "conductor", "lyricist", "performer",
"remixer", "label", "publisher", "work", "opus", "partnumber", "part",
"subtitle", "media",
Expand All @@ -198,6 +199,7 @@ static struct {
{ "album_artist", "albumartist" },
{ "album artist", "albumartist" },
{ "disc", "discnumber" },
{ "tempo", "bpm" },
{ "track", "tracknumber" },
{ "WM/Year", "date" },
{ "WM/ArtistSortOrder", "artistsort" },
Expand Down
5 changes: 4 additions & 1 deletion expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,11 +438,12 @@ static const struct {
{ "albumartist",EXPR_STR },
{ "artist", EXPR_STR },
{ "bitrate", EXPR_INT },
{ "bpm", EXPR_INT },
{ "codec", EXPR_STR },
{ "codec_profile",EXPR_STR },
{ "comment", EXPR_STR },
{ "date", EXPR_INT },
{ "discnumber", EXPR_INT },
{ "discnumber", EXPR_INT },
{ "duration", EXPR_INT },
{ "filename", EXPR_STR },
{ "genre", EXPR_STR },
Expand Down Expand Up @@ -924,6 +925,8 @@ static int int_val(const char *key, struct track_info *ti)
val = (ti->bitrate >= 0) ? (int) (ti->bitrate / 1000. + 0.5) : -1;
} else if (strcmp(key, "play_count") == 0) {
val = ti->play_count;
} else if (strcmp(key, "bpm") == 0) {
val = ti->bpm;
} else {
val = comments_get_int(ti->comments, key);
}
Expand Down
3 changes: 3 additions & 0 deletions id3.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ const char * const id3_key_names[NUM_ID3_KEYS] = {
"comment",
"musicbrainz_trackid",
"media",
"bpm",
};

static int utf16_is_lsurrogate(uchar uch)
Expand Down Expand Up @@ -571,6 +572,7 @@ static struct {
{ "TPUB", ID3_PUBLISHER }, // TPUB can be both publisher or label
{ "TIT3", ID3_SUBTITLE },
{ "TMED", ID3_MEDIA },
{ "TBPM", ID3_BPM},

/* obsolete frames (2.2.0) */
{ "TP1", ID3_ARTIST },
Expand All @@ -585,6 +587,7 @@ static struct {
{ "TS2", ID3_ALBUMARTISTSORT },
{ "TSA", ID3_ALBUMSORT },
{ "TCP", ID3_COMPILATION },
{ "TBP", ID3_BPM },
};

static int frame_tab_index(const char *id)
Expand Down
1 change: 1 addition & 0 deletions id3.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ enum id3_key {
ID3_COMMENT,
ID3_MUSICBRAINZ_TRACKID,
ID3_MEDIA,
ID3_BPM,

NUM_ID3_KEYS
};
Expand Down
4 changes: 3 additions & 1 deletion options.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ static const struct {
[FMT_CURRENT] = { "format_current" , " %a - %l -%3n. %t%= %y " },
[FMT_STATUSLINE] = { "format_statusline" ,
" %{status} %{?show_playback_position?%{position} %{?duration?/ %{duration} }?%{?duration?%{duration} }}"
"- %{total} "
"- %{total} %{?bpm>0?at %{bpm} BPM }"
"%{?volume>=0?vol: %{?lvolume!=rvolume?%{lvolume},%{rvolume} ?%{volume} }}"
"%{?stream?buf: %{buffer} }"
"%{?show_current_bitrate & bitrate>=0? %{bitrate} kbps }"
Expand Down Expand Up @@ -352,6 +352,7 @@ static const struct {
{ "codec", SORT_CODEC },
{ "codec_profile", SORT_CODEC_PROFILE },
{ "media", SORT_MEDIA },
{ "bpm", SORT_BPM },
{ "-artist", REV_SORT_ARTIST },
{ "-album", REV_SORT_ALBUM },
{ "-title", REV_SORT_TITLE },
Expand All @@ -373,6 +374,7 @@ static const struct {
{ "-codec", REV_SORT_CODEC },
{ "-codec_profile", REV_SORT_CODEC_PROFILE },
{ "-media", REV_SORT_MEDIA },
{ "-bpm", REV_SORT_BPM },
{ NULL, SORT_INVALID }
};

Expand Down
7 changes: 7 additions & 0 deletions track_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct track_info *track_info_new(const char *filename)
ti->ref = 1;
ti->play_count = 0;
ti->comments = NULL;
ti->bpm = -1;
ti->codec = NULL;
ti->codec_profile = NULL;
return ti;
Expand All @@ -75,6 +76,11 @@ void track_info_set_comments(struct track_info *ti, struct keyval *comments) {
ti->is_va_compilation = track_is_va_compilation(comments);
ti->media = keyvals_get_val(comments, "media");

int bpm = comments_get_int(comments, "bpm");
if (ti->bpm == 0 || ti->bpm == -1) {
ti->bpm = bpm;
}

if (ti->artist == NULL && ti->albumartist != NULL) {
/* best guess */
ti->artist = ti->albumartist;
Expand Down Expand Up @@ -205,6 +211,7 @@ int track_info_cmp(const struct track_info *a, const struct track_info *b, const
case SORT_DATE:
case SORT_ORIGINALDATE:
case SORT_PLAY_COUNT:
case SORT_BPM:
res = getentry(a, key, int) - getentry(b, key, int);
break;
case SORT_FILEMTIME:
Expand Down
3 changes: 3 additions & 0 deletions track_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct track_info {
unsigned int play_count;

int is_va_compilation : 1;
int bpm;
};

typedef size_t sort_key_t;
Expand All @@ -90,6 +91,7 @@ typedef size_t sort_key_t;
#define SORT_CODEC offsetof(struct track_info, codec)
#define SORT_CODEC_PROFILE offsetof(struct track_info, codec_profile)
#define SORT_MEDIA offsetof(struct track_info, media)
#define SORT_BPM offsetof(struct track_info, bpm)
#define REV_SORT__START sizeof(struct track_info)
#define REV_SORT_ARTIST (REV_SORT__START + offsetof(struct track_info, collkey_artist))
#define REV_SORT_ALBUM (REV_SORT__START + offsetof(struct track_info, collkey_album))
Expand All @@ -112,6 +114,7 @@ typedef size_t sort_key_t;
#define REV_SORT_CODEC (REV_SORT__START + offsetof(struct track_info, codec))
#define REV_SORT_CODEC_PROFILE (REV_SORT__START + offsetof(struct track_info, codec_profile))
#define REV_SORT_MEDIA (REV_SORT__START + offsetof(struct track_info, media))
#define REV_SORT_BPM (REV_SORT__START + offsetof(struct track_info, bpm))

#define TI_MATCH_ARTIST (1 << 0)
#define TI_MATCH_ALBUM (1 << 1)
Expand Down
3 changes: 3 additions & 0 deletions ui_curses.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ enum {
TF_FOLLOW,
TF_SHUFFLE,
TF_PLAYLISTMODE,
TF_BPM,

NR_TFS
};
Expand Down Expand Up @@ -351,6 +352,7 @@ static struct format_option track_fopts[NR_TFS + 1] = {
DEF_FO_STR('\0', "follow", 0),
DEF_FO_STR('\0', "shuffle", 0),
DEF_FO_STR('\0', "playlist_mode", 0),
DEF_FO_INT('\0', "bpm", 0),
DEF_FO_END
};

Expand Down Expand Up @@ -613,6 +615,7 @@ static void fill_track_fopts_track_info(struct track_info *info)
} else {
fopt_set_str(&track_fopts[TF_FILE], path_basename(filename));
}
fopt_set_int(&track_fopts[TF_BPM], info->bpm, info->bpm == -1);
}

static void fill_track_fopts_album(struct album *album)
Expand Down

0 comments on commit 976c10d

Please sign in to comment.