diff options
author | quou <quou@disroot.org> | 2024-06-04 21:42:04 +1000 |
---|---|---|
committer | quou <quou@disroot.org> | 2024-06-04 21:42:04 +1000 |
commit | 557e07876de0086b70e301b104547bf35ec57959 (patch) | |
tree | b2c9923ef989ea38d185d4598764a060c18f298e /library.c | |
parent | 6589107006fd4fc06bdb7d02cb4b1eef45395458 (diff) |
Loading album art, seeking, pause/play.
Diffstat (limited to 'library.c')
-rw-r--r-- | library.c | 152 |
1 files changed, 150 insertions, 2 deletions
@@ -5,6 +5,7 @@ #include <stdio.h> #include "dr_flac.h" +#include "stb_image.h" static unsigned hash(const char* s) { const unsigned char* p = (const unsigned char*)s; @@ -121,6 +122,68 @@ void flac_meta( } } +void conv_art( + Player* p, + unsigned char* pixels, + int w, + int h +) { + int tx, ty, i, j, k; + float rx, ry; + unsigned px; + rx = (float)w / (float)album_cover_w; + ry = (float)h / (float)album_cover_h; + for (j = 0; j < album_cover_h; j++) { + ty = (int)((float)j * ry); + for (i = 0; i < album_cover_w; i++) { + tx = (int)((float)i * rx); + px = 0; + px |= 0xff << 24; + k = (tx + ty * w) * 4; + px |= pixels[k + 0] << 16; + px |= pixels[k + 1] << 8; + px |= pixels[k + 2]; + p->cover[i + j * album_cover_w] = px; + } + } + p->has_art = 1; +} + +void load_cover(Player* p, const unsigned char* data, int size) { + unsigned char* pixels; + int w, h, c, rc = 4; + pixels = stbi_load_from_memory( + data, + size, + &w, + &h, + &c, + rc + ); + conv_art(p, pixels, w, h); + stbi_image_free(pixels); +} + +void art_meta( + void* uptr, + drflac_metadata* m +) { + switch (m->type) { + case DRFLAC_METADATA_BLOCK_TYPE_PICTURE: + if ( + m->data.picture.type == + DRFLAC_PICTURE_TYPE_COVER_FRONT + ) { + load_cover( + uptr, + m->data.picture.pPictureData, + m->data.picture.pictureDataSize + ); + } + break; + } +} + int get_song_meta(const char* path, Song* s) { drflac* f; f = drflac_open_file_with_metadata( @@ -147,12 +210,15 @@ int sound_mix( int r; (void)size; p = uptr; + if (!p->play) return 0; f = p->f; r = drflac_read_pcm_frames_s32( f, size / p->channels / 4, (int*)buf ); + if (!r) p->play = 0; + p->cs += r; return r * p->channels * 4; } @@ -162,20 +228,80 @@ void init_player(Player* p) { p->play = 0; } +void try_load_art(Player* p) { + const char* const tt[] = { + "cover.jpg", + "cover.png", + "Cover.jpg", + "Cover.png", + "folder.jpg", + "Folder.jpg", + "folder.png", + "Folder.png", + "../cover.jpg", + "../cover.png", + "../Cover.jpg", + "../Cover.png", + "../folder.jpg", + "../Folder.jpg", + "../folder.png", + "../Folder.png" + }; + unsigned char* pixels; + int w, h, c, rc = 4, end, i, len; + char buf[256]; + char* start; + strcpy(buf, p->song->path); + len = strlen(buf); + while (len > 0 && buf[len] != '/') { + buf[len] = 0; + len--; + } + end = sizeof tt / sizeof *tt; + for (i = 0; i < end; i++) { + start = buf + len; + strcat(start, tt[i]); + pixels = stbi_load( + buf, + &w, + &h, + &c, + rc + ); + if (pixels) { + conv_art(p, pixels, w, h); + stbi_image_free(pixels); + return; + } + buf[len + 1] = 0; + } +} + void play_song(Player* p, Song* song) { drflac* f; int sr, channels; - f = drflac_open_file( + p->has_art = 0; + f = drflac_open_file_with_metadata( song->path, + art_meta, + p, 0 ); /* todo errors and stuff */ if (!f) return; + if (p->f) + drflac_close(p->f); + stop_audio(); + p->song = song; channels = f->channels; sr = f->sampleRate; p->f = f; p->channels = channels; - stop_audio(); + p->play = 1; + p->cs = 0; + p->ms = f->totalPCMFrameCount; + if (!p->has_art) + try_load_art(p); init_audio( p, sr, @@ -183,5 +309,27 @@ void play_song(Player* p, Song* song) { ); } +void play_seek(Player* p, float v) { + unsigned long long fi; + if (!p->song) return; + /* probably want to protect against overflow/error */ + fi = (unsigned long long)((float)p->ms * v); + lock_audio(); + p->cs = fi; + drflac_seek_to_pcm_frame(p->f, fi); + unlock_audio(); +} + +void deinit_player(Player* p) { + if (p->song) { + stop_audio(); + wait_audio(); + drflac_close(p->f); + } +} + #define DR_FLAC_IMPLEMENTATION #include "dr_flac.h" + +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" |