diff options
Diffstat (limited to 'library.c')
-rw-r--r-- | library.c | 84 |
1 files changed, 78 insertions, 6 deletions
@@ -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) { |