Speed up id3v1 genre usage.
authorGustavo Sverzut Barbieri <barbieri@gmail.com>
Thu, 6 Mar 2008 23:16:24 +0000 (20:16 -0300)
committerGustavo Sverzut Barbieri <barbieri@gmail.com>
Fri, 7 Mar 2008 15:25:33 +0000 (12:25 -0300)
This uses just one memory block containing all the strings and an
array with the offsets to its base, this also enables one to know the
string size with a simple calc.

By using just one memory block for strings should help with
relocations, by using the offsets we can save strlen() and strdup(),
using malloc() + memcpy() directly.

src/plugins/id3/.gitignore [new file with mode: 0644]
src/plugins/id3/Makefile.am
src/plugins/id3/id3.c
src/plugins/id3/id3v1_genres.def [new file with mode: 0644]
src/plugins/id3/id3v1_genres_gen.awk [new file with mode: 0644]

diff --git a/src/plugins/id3/.gitignore b/src/plugins/id3/.gitignore
new file mode 100644 (file)
index 0000000..87deef4
--- /dev/null
@@ -0,0 +1 @@
+id3v1_genres.c
index ede48f5..0e21898 100644 (file)
@@ -4,7 +4,14 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/plugins/id3
 
 pkgdir = $(pluginsdir)
 pkg_LTLIBRARIES = id3.la
-id3_la_SOURCES = id3.c
-id3_la_DEPENDENCIES = $(top_builddir)/config.h
+id3_la_SOURCES = id3.c id3v1_genres.c
+id3_la_DEPENDENCIES = $(top_builddir)/config.h id3v1_genres.def
 id3_la_LIBADD = $(top_builddir)/src/lib/liblightmediascanner.la
 id3_la_LDFLAGS = -module -avoid-version
+
+id3v1_genres.c: $(srcdir)/id3v1_genres.def $(srcdir)/id3v1_genres_gen.awk
+       $(AWK) -f $(srcdir)/id3v1_genres_gen.awk $(srcdir)/id3v1_genres.def > $@
+
+EXTRA_DIST = id3v1_genres.def id3v1_genres_gen.awk
+BUILT_SOURCES = id3v1_genres.c
+CLEANFILES = $(BUILT_SOURCES)
index 207764a..54b5332 100644 (file)
@@ -56,157 +56,7 @@ enum ID3Encodings {
 #define ID3_NUM_ENCODINGS ID3_ENCODING_LAST
 
 
-static const char *id3v1_genres[] = {
-    "Blues",
-    "Classic Rock",
-    "Country",
-    "Dance",
-    "Disco",
-    "Funk",
-    "Grunge",
-    "Hip-Hop",
-    "Jazz",
-    "Metal",
-    "New Age",
-    "Oldies",
-    "Other",
-    "Pop",
-    "R&B",
-    "Rap",
-    "Reggae",
-    "Rock",
-    "Techno",
-    "Industrial",
-    "Alternative",
-    "Ska",
-    "Death Metal",
-    "Pranks",
-    "Soundtrack",
-    "Euro-Techno",
-    "Ambient",
-    "Trip-Hop",
-    "Vocal",
-    "Jazz+Funk",
-    "Fusion",
-    "Trance",
-    "Classical",
-    "Instrumental",
-    "Acid",
-    "House",
-    "Game",
-    "Sound Clip",
-    "Gospel",
-    "Noise",
-    "Alternative Rock",
-    "Bass",
-    "Soul",
-    "Punk",
-    "Space",
-    "Meditative",
-    "Instrumental Pop",
-    "Instrumental Rock",
-    "Ethnic",
-    "Gothic",
-    "Darkwave",
-    "Techno-Industrial",
-    "Electronic",
-    "Pop-Folk",
-    "Eurodance",
-    "Dream",
-    "Southern Rock",
-    "Comedy",
-    "Cult",
-    "Gangsta",
-    "Top 40",
-    "Christian Rap",
-    "Pop/Funk",
-    "Jungle",
-    "Native American",
-    "Cabaret",
-    "New Wave",
-    "Psychedelic",
-    "Rave",
-    "Showtunes",
-    "Trailer",
-    "Lo-Fi",
-    "Tribal",
-    "Acid Punk",
-    "Acid Jazz",
-    "Polka",
-    "Retro",
-    "Musical",
-    "Rock & Roll",
-    "Hard Rock",
-    "Folk",
-    "Folk/Rock",
-    "National Folk",
-    "Swing",
-    "Fusion",
-    "Bebob",
-    "Latin",
-    "Revival",
-    "Celtic",
-    "Bluegrass",
-    "Avantgarde",
-    "Gothic Rock",
-    "Progressive Rock",
-    "Psychedelic Rock",
-    "Symphonic Rock",
-    "Slow Rock",
-    "Big Band",
-    "Chorus",
-    "Easy Listening",
-    "Acoustic",
-    "Humour",
-    "Speech",
-    "Chanson",
-    "Opera",
-    "Chamber Music",
-    "Sonata",
-    "Symphony",
-    "Booty Bass",
-    "Primus",
-    "Porn Groove",
-    "Satire",
-    "Slow Jam",
-    "Club",
-    "Tango",
-    "Samba",
-    "Folklore",
-    "Ballad",
-    "Power Ballad",
-    "Rhythmic Soul",
-    "Freestyle",
-    "Duet",
-    "Punk Rock",
-    "Drum Solo",
-    "A Cappella",
-    "Euro-House",
-    "Dance Hall",
-    "Goa",
-    "Drum & Bass",
-    "Club-House",
-    "Hardcore",
-    "Terror",
-    "Indie",
-    "BritPop",
-    "Negerpunk",
-    "Polsk Punk",
-    "Beat",
-    "Christian Gangsta Rap",
-    "Heavy Metal",
-    "Black Metal",
-    "Crossover",
-    "Contemporary Christian",
-    "Christian Rock",
-    "Merengue",
-    "Salsa",
-    "Thrash Metal",
-    "Anime",
-    "Jpop",
-    "Synthpop"
-};
-#define ID3V1_NUM_GENRES (sizeof(id3v1_genres) / sizeof(char *))
+#include "id3v1_genres.c"
 
 struct id3_info {
     struct lms_string_size title;
@@ -430,11 +280,17 @@ _get_id3v2_frame_info(const char *frame_data, unsigned int frame_size, struct lm
 }
 
 static int
-_get_id3v1_genre(int genre, struct lms_string_size *out)
+_get_id3v1_genre(unsigned int genre, struct lms_string_size *out)
 {
-    if (genre >= 0 && genre < ID3V1_NUM_GENRES) {
-        out->str = strdup(id3v1_genres[genre]);
-        out->len = strlen(out->str);
+    if (genre < ID3V1_NUM_GENRES) {
+        unsigned int size, base;
+
+        base = id3v1_genres_offsets[genre];
+        size = id3v1_genres_offsets[genre + 1] - base;
+        out->str = malloc(size);
+        out->len = size - 1;
+        memcpy(out->str, id3v1_genres_mem + base, size);
+
         return 0;
     }
     return -1;
diff --git a/src/plugins/id3/id3v1_genres.def b/src/plugins/id3/id3v1_genres.def
new file mode 100644 (file)
index 0000000..2bbd99f
--- /dev/null
@@ -0,0 +1,148 @@
+Blues
+Classic Rock
+Country
+Dance
+Disco
+Funk
+Grunge
+Hip-Hop
+Jazz
+Metal
+New Age
+Oldies
+Other
+Pop
+R&B
+Rap
+Reggae
+Rock
+Techno
+Industrial
+Alternative
+Ska
+Death Metal
+Pranks
+Soundtrack
+Euro-Techno
+Ambient
+Trip-Hop
+Vocal
+Jazz+Funk
+Fusion
+Trance
+Classical
+Instrumental
+Acid
+House
+Game
+Sound Clip
+Gospel
+Noise
+Alternative Rock
+Bass
+Soul
+Punk
+Space
+Meditative
+Instrumental Pop
+Instrumental Rock
+Ethnic
+Gothic
+Darkwave
+Techno-Industrial
+Electronic
+Pop-Folk
+Eurodance
+Dream
+Southern Rock
+Comedy
+Cult
+Gangsta
+Top 40
+Christian Rap
+Pop/Funk
+Jungle
+Native American
+Cabaret
+New Wave
+Psychedelic
+Rave
+Showtunes
+Trailer
+Lo-Fi
+Tribal
+Acid Punk
+Acid Jazz
+Polka
+Retro
+Musical
+Rock & Roll
+Hard Rock
+Folk
+Folk/Rock
+National Folk
+Swing
+Fusion
+Bebob
+Latin
+Revival
+Celtic
+Bluegrass
+Avantgarde
+Gothic Rock
+Progressive Rock
+Psychedelic Rock
+Symphonic Rock
+Slow Rock
+Big Band
+Chorus
+Easy Listening
+Acoustic
+Humour
+Speech
+Chanson
+Opera
+Chamber Music
+Sonata
+Symphony
+Booty Bass
+Primus
+Porn Groove
+Satire
+Slow Jam
+Club
+Tango
+Samba
+Folklore
+Ballad
+Power Ballad
+Rhythmic Soul
+Freestyle
+Duet
+Punk Rock
+Drum Solo
+A Cappella
+Euro-House
+Dance Hall
+Goa
+Drum & Bass
+Club-House
+Hardcore
+Terror
+Indie
+BritPop
+Negerpunk
+Polsk Punk
+Beat
+Christian Gangsta Rap
+Heavy Metal
+Black Metal
+Crossover
+Contemporary Christian
+Christian Rock
+Merengue
+Salsa
+Thrash Metal
+Anime
+Jpop
+Synthpop
diff --git a/src/plugins/id3/id3v1_genres_gen.awk b/src/plugins/id3/id3v1_genres_gen.awk
new file mode 100644 (file)
index 0000000..9a01015
--- /dev/null
@@ -0,0 +1,39 @@
+BEGIN {
+  line=1;
+  total_bytes=0;
+}
+
+{
+  if (NF != 0) {
+    sub(/[ \t]+$/, ""); # no trailing whitespace
+
+    offsets[line] = total_bytes;
+    genre[line] = $0;
+    total_bytes += length($0) + 1;
+    line++;
+  }
+}
+
+END {
+  print "static const unsigned ID3V1_NUM_GENRES = " (line - 1) ";";
+
+  old_ORS=ORS;
+  ORS="";
+  print "static const char id3v1_genres_mem[] = \"";
+  ORS="\\0";
+  for (i = 1; i < line; i++)
+    print genre[i];
+
+  ORS=old_ORS;
+  print "\";";
+
+  ORS="";
+  print "static const unsigned short id3v1_genres_offsets[] = {";
+  for (i = 1; i < line; i++)
+    print offsets[i] ", ";
+
+  print total_bytes;
+
+  ORS=old_ORS;
+  print "};";
+}