diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/modules/organya.c | 35 | ||||
| -rw-r--r-- | src/portaudio.c | 18 | 
2 files changed, 47 insertions, 6 deletions
diff --git a/src/modules/organya.c b/src/modules/organya.c index 9d7bb67..d214ed2 100644 --- a/src/modules/organya.c +++ b/src/modules/organya.c @@ -9,7 +9,7 @@  #include "../include.h"  // assumes little endian architechture, sorry -// C port of the 250 SLoC of JS organya player https://github.com/alula/organya-js +// my C port of the 250 SLoC of JS organya player https://github.com/alula/organya-js  struct song {  	uint16_t wait; @@ -68,19 +68,28 @@ static struct drums {  	int samples;  } *drums = NULL; -void freefunc(void *ptr) { -	struct organya *self = ptr; +void freesong(struct song *song) {  	for (int i = 0; i < 16; i++) { -		free(self->song->tracks[i]); +		free(song->tracks[i]);  	} -	free(self->song); +	free(song); +} + +void freefunc(void *ptr) { +	struct organya *self = ptr; +	freesong(self->song);  	free(self);  }  struct song *song_constructor(struct blob *file) {  	char const *p = file->data; +	size_t bytes = file->size;  	// header check +	if (bytes < 6) { +		return NULL; +	} +	bytes -= 6;  	uint32_t const org1 = *(uint32_t *) p; p += sizeof (uint32_t);  	uint16_t const orgVersion = *(uint16_t *) p; p += sizeof (uint16_t);  	if (org1 != 0x2d67724f || orgVersion != 0x3230) { @@ -92,12 +101,20 @@ struct song *song_constructor(struct blob *file) {  		return NULL;  	} +	if (bytes < 12) { +		return NULL; +	} +	bytes -= 12;  	self->wait = *(uint16_t *) p; p += sizeof (uint16_t);  	self->meas[0] = *(uint8_t *) p; p += sizeof (uint8_t);  	self->meas[1] = *(uint8_t *) p; p += sizeof (uint8_t);  	self->start = *(int32_t *) p; p += sizeof (int32_t);  	self->end = *(int32_t *) p; p += sizeof (int32_t); +	if (bytes < 6 * 16) { +		return NULL; +	} +	bytes -= 6 * 16;  	for (int i = 0; i < 16; i++) {  		self->instruments[i].freq = *(uint16_t *) p; p+= sizeof (uint16_t);  		self->instruments[i].wave = *(uint8_t *) p; p += sizeof (uint8_t); @@ -113,10 +130,16 @@ struct song *song_constructor(struct blob *file) {  		size_t const length = self->instruments[i].notes;  		struct track *track = malloc(sizeof (track) * length);  		if (track == NULL && length != 0) { -			//freefunc(self); // TODO: this looks really wrong +			freesong(self);  			return NULL;  		} +		if (bytes < 8 * length) { +			freesong(self); +			return NULL; +		} +		bytes -= 8 * length; +  		for (unsigned j = 0; j < length; j++) {  			track[j].pos = *(int32_t *) p; p += sizeof (int32_t);  		} diff --git a/src/portaudio.c b/src/portaudio.c index 7ff6ca3..e5c5d92 100644 --- a/src/portaudio.c +++ b/src/portaudio.c @@ -36,6 +36,22 @@ int audio_callback(void const *inBuf, void *outBuf, unsigned long const frameCou  int (*file_ext(char *file))(struct blob *, struct userdata *); +#include <alsa/asoundlib.h> +#include <stdarg.h> +static void alsa_shut_up(char const *file, int line, char const *function, int err, char const *fmt, ...) { +	if (err == 0) { +		// duckGPT claims its not unsafe to return before using va_ functions +		return; +	} +	// ALSA lib (real) +	fprintf(stderr, "ALSA lib %s:%i:(%s) ", file, line, function); +	va_list list; +	va_start(list, fmt); +	vfprintf(stderr, fmt, list); +	va_end(list); +	putc('\n', stderr); +} +  int main(int argc, char **argv) {  	if (argc != 2) {  		eprintf("usage: %s audio-file.{mid,mod,xm,it,s3m}\n", argv[0]); @@ -59,11 +75,13 @@ int main(int argc, char **argv) {  	signal(SIGINT, sigint_handler); // signal(3) claims this method is deprecated, but.. +	snd_lib_error_set_handler(alsa_shut_up);  	PaError paErr;  	if ((paErr = Pa_Initialize()) != paNoError) {  		printf("error: Pa_Initialize: %s\n", Pa_GetErrorText(paErr));  		goto error;  	} +	snd_lib_error_set_handler(NULL);  	PaStream *stream;  	if ((paErr = Pa_OpenDefaultStream(  | 
