diff options
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"  |