summaryrefslogtreecommitdiff
path: root/library.c
diff options
context:
space:
mode:
Diffstat (limited to 'library.c')
-rw-r--r--library.c84
1 files changed, 78 insertions, 6 deletions
diff --git a/library.c b/library.c
index 350789a..3d5aaa4 100644
--- a/library.c
+++ b/library.c
@@ -29,6 +29,14 @@ Song* find_song(Library* l, const char* path) {
return 0;
}
+void init_song(Song* s) {
+ s->track = 0;
+ s->path[0] = 0;
+ s->name[0] = 0;
+ s->artist[0] = 0;
+ s->album[0] = 0;
+}
+
static void cap_iter(
void* uptr,
const char* path
@@ -45,6 +53,7 @@ static void adder_iter(
Song* s;
Library* lib = uptr;
s = find_song(lib, path);
+ init_song(s);
if (get_song_meta(path, s)) {
strcpy(s->path, path);
lib->indices[lib->cnt++] = s - lib->songs;
@@ -57,7 +66,7 @@ void build_library(
const char* path
) {
int i;
- lib->cnt = lib->cap = 0;
+ lib->cnt = lib->cap = lib->fcnt = 0;
iter_dir(path, cap_iter, lib);
lib->cap += 16;
lib->songs = arena_alloc(
@@ -68,20 +77,76 @@ void build_library(
a,
lib->cap * sizeof *lib->indices
);
+ lib->filtered = arena_alloc(
+ a,
+ lib->cap * sizeof *lib->filtered
+ );
for (i = 0; i < lib->cap; i++)
lib->songs[i].path[0] = 0;
iter_dir(path, adder_iter, lib);
}
+char upper(char c) {
+ return c >= 'a' && c <= 'z'? c - ('a' - 'A'): c;
+}
+
+int string_eq(
+ const char* a,
+ const char* b
+) {
+ for (; *a && *b; a++, b++)
+ if (upper(*a) != upper(*b)) return 0;
+ return *b == 0;
+}
+
+int string_match(
+ const char* h,
+ const char* n
+) {
+ const char* c;
+ for (c = h; *c; c++) {
+ if (string_eq(c, n)) return 1;
+ }
+ return 0;
+}
+
+int song_match(
+ const Song* s,
+ const char* str
+) {
+#define check(n) \
+ (s->n[0] && string_match(s->n, str))
+ return s->path[0] && (
+ check(path) ||
+ check(name) ||
+ check(artist) ||
+ check(album)
+ );
+#undef check
+}
+
+void filter_library(
+ Library* l,
+ const char* str
+) {
+ int i;
+ Song* s;
+ l->fcnt = 0;
+ for (i = 0; i < l->cap; i++) {
+ s = &l->songs[i];
+ if (song_match(s, str))
+ l->filtered[l->fcnt++] = i;
+ }
+}
+
void parse_vorbis_comment(
Song* s,
const char* com,
int len
) {
/* this is not safe xDDDD idrc */
- if (len > 64) {
+ if (len > 64)
len = 64;
- }
if (!memcmp(com, "ARTIST=", 7)) {
len -= 7;
memcpy(s->artist, com + 7, len);
@@ -94,6 +159,9 @@ void parse_vorbis_comment(
len -= 6;
memcpy(s->album, com + 6, len);
s->album[len] = 0;
+ } else if (!memcmp(com, "TRACKNUMBER=", 12)) {
+ len -= 6;
+ s->track = (int)strtol(com + 12, 0, 10);
}
}
@@ -200,6 +268,8 @@ int get_song_meta(const char* path, Song* s) {
return 0;
}
+void ui_update_seek(void);
+
int sound_mix(
void* uptr,
unsigned char* buf,
@@ -219,7 +289,8 @@ int sound_mix(
);
if (!r) p->play = 0;
p->cs += r;
- ui_update_seek(p);
+ /* todo fix race condition here */
+ ui_update_seek();
return r * p->channels * 4;
}
@@ -278,7 +349,7 @@ void try_load_art(Player* p) {
}
}
-void play_song(Player* p, Song* song) {
+int play_song(Player* p, Song* song) {
drflac* f;
int sr, channels;
p->has_art = 0;
@@ -289,7 +360,7 @@ void play_song(Player* p, Song* song) {
0
);
/* todo errors and stuff */
- if (!f) return;
+ if (!f) return 0;
if (p->f)
drflac_close(p->f);
stop_audio();
@@ -308,6 +379,7 @@ void play_song(Player* p, Song* song) {
sr,
channels
);
+ return 1;
}
void play_seek(Player* p, float v) {