summaryrefslogtreecommitdiff
path: root/library.c
diff options
context:
space:
mode:
Diffstat (limited to 'library.c')
-rw-r--r--library.c135
1 files changed, 114 insertions, 21 deletions
diff --git a/library.c b/library.c
index 7459579..4eb4ab0 100644
--- a/library.c
+++ b/library.c
@@ -1,14 +1,9 @@
-#include <string.h>
-
#include "library.h"
#include "plat.h"
+#include <string.h>
+#include <stdio.h>
-void init_library(Library* l) {
- int i;
- l->song_count = 0;
- for (i = 0; i < max_songs; i++)
- l->songs[i].file[0] = 0;
-}
+#include "dr_flac.h"
static unsigned hash(const char* s) {
const unsigned char* p = (const unsigned char*)s;
@@ -19,30 +14,128 @@ static unsigned hash(const char* s) {
}
Song* find_song(Library* l, const char* path) {
- int i = hash(path) % max_songs;
+ int i = hash(path) % l->cap;
int c;
Song* s;
- for (c = 0; c < max_songs; c++) {
+ for (c = 0; c < l->cap; c++) {
s = &l->songs[i];
- if (!s->file[0] || !strcmp(path, s->file))
+ if (!s->path[0] || !strcmp(path, s->path))
return s;
i++;
- i %= max_songs;
+ i %= l->cap;
}
return 0;
}
-void add_song(void* l, const char* path) {
+static void cap_iter(
+ void* uptr,
+ const char* path
+) {
+ Library* lib = uptr;
+ (void)path;
+ lib->cap++;
+}
+
+static void adder_iter(
+ void* uptr,
+ const char* path
+) {
Song* s;
- s = find_song(l, path);
- if (!s) {
- print_err("Too many songs!");
- return;
+ Library* lib = uptr;
+ s = find_song(lib, path);
+ if (get_song_meta(path, s)) {
+ strcpy(s->path, path);
+ lib->indices[lib->cnt++] = s - lib->songs;
+ }
+}
+
+void build_library(
+ Arena* a,
+ Library* lib,
+ const char* path
+) {
+ int i;
+ lib->cnt = lib->cap = 0;
+ iter_dir(path, cap_iter, lib);
+ lib->cap += 16;
+ lib->songs = arena_alloc(
+ a,
+ lib->cap * sizeof *lib->songs
+ );
+ lib->indices = arena_alloc(
+ a,
+ lib->cap * sizeof *lib->indices
+ );
+ for (i = 0; i < lib->cap; i++)
+ lib->songs[i].path[0] = 0;
+ iter_dir(path, adder_iter, lib);
+}
+
+void parse_vorbis_comment(
+ Song* s,
+ const char* com,
+ int len
+) {
+ /* this is not safe xDDDD idrc */
+ if (len > 64) {
+ len = 64;
+ }
+ if (!memcmp(com, "ARTIST=", 7)) {
+ len -= 7;
+ memcpy(s->artist, com + 7, len);
+ s->artist[len] = 0;
+ } else if (!memcmp(com, "TITLE=", 6)) {
+ len -= 6;
+ memcpy(s->name, com + 6, len);
+ s->name[len] = 0;
+ } else if (!memcmp(com, "ALBUM=", 6)) {
+ len -= 6;
+ memcpy(s->album, com + 6, len);
+ s->album[len] = 0;
+ }
+}
+
+void flac_meta(
+ void* uptr,
+ drflac_metadata* m
+) {
+ Song* s = uptr;
+ drflac_vorbis_comment_iterator i;
+ drflac_uint32 len;
+ const char* c;
+ int size;
+ switch (m->type) {
+ case DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT:
+ drflac_init_vorbis_comment_iterator(
+ &i,
+ m->data.vorbis_comment.commentCount,
+ m->data.vorbis_comment.pComments
+ );
+ while ((c = drflac_next_vorbis_comment(
+ &i,
+ &len
+ ))) {
+ parse_vorbis_comment(s, c, len);
+ }
+ break;
}
- strcpy(s->file, path);
- strcpy(s->name, path);
}
-void build_library(Library* l, const char* path) {
- iter_dir(path, add_song, l);
+int get_song_meta(const char* path, Song* s) {
+ drflac* f;
+ f = drflac_open_file_with_metadata(
+ path,
+ flac_meta,
+ s,
+ 0
+ );
+ if (f) {
+ drflac_close(f);
+ return 1;
+ }
+ s->path[0] = 0;
+ return 0;
}
+
+#define DR_FLAC_IMPLEMENTATION
+#include "dr_flac.h"