diff --git a/main.c b/main.c index c0bef2c..31421c3 100644 --- a/main.c +++ b/main.c @@ -94,3 +94,88 @@ void unigi_ext_rect_dimensions( *height = abs(bounds.y2 - bounds.y1); } +unigi_ext_type_sound_sample * unigi_ext_sound_open(char * path) { + unigi_ext_type_sound_sample * sample = malloc(sizeof(unigi_ext_type_sound_sample)); + if (sample == NULL) { goto fail; } + int fd = open(path,O_RDONLY); + if (fd == -1) { goto fail; } + size_t size = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + uint8_t * data = malloc(size); + if (data == NULL) { goto fail_sample; } + if (read(fd,data,size) != size) { goto fail_data; } + close(fd); + sample->size = size; + sample->data = data; + return sample; + + fail_data:; + free(data); + fail_sample:; + free(sample); + close(fd); + fail:; + return NULL; +} + +// TODO: add channel cap (+ static stack allocation, instead of dynamic malloc?) +unigi_ext_type_sound_channel * unigi_ext_sound_channel_create(unigi_ext_type_sound_sample * sample) { + size_t i = 0; + unigi_ext_type_sound_channel * channel = NULL; + while (i < unigi_ext_sound_channels_size) { + if (unigi_ext_sound_channels[i].sound == NULL) { + channel = &unigi_ext_sound_channels[i]; + } + ++i; + } + + if (channel == NULL) { + unigi_ext_type_sound_channel * newchannels = realloc(unigi_ext_sound_channels,(unigi_ext_sound_channels_size + 1) * sizeof(unigi_ext_type_sound_channel)); + if (newchannels == NULL) { goto fail; } + unigi_ext_sound_channels = newchannels; + channel = &unigi_ext_sound_channels[unigi_ext_sound_channels_size]; + ++unigi_ext_sound_channels_size; + } + + channel->sound = sample; + channel->volume = 1.0; + channel->start = 0; + channel->stop = sample->size; + channel->progress = 0; + channel->loop = 1; + return channel; + fail:; + return NULL; +} + +void unigi_ext_sound_channel_play(unigi_ext_type_sound_channel * channel, uint8_t * buffer, size_t size) { + size_t i = 0; + while (i < size) { // TODO: make proper for loop + buffer[i] += (channel->sound->data[channel->progress] * (channel->volume / 2)); // TODO: cap volume (?) + remove the "/ 2" (SDL specific) + channel->progress += 1; + if (channel->progress >= channel->stop) { + if (channel->loop == 0) { + channel->sound = NULL; + return; + } else { + channel->progress = channel->start; + } + } + ++i; + } +} + +void unigi_ext_sound_handle(uint8_t * buffer, size_t size) { + memset(buffer, 0, size); + size_t i = 0; + while (i < unigi_ext_sound_channels_size) { // TODO: make proper for loop + if (unigi_ext_sound_channels[i].sound != NULL) { + unigi_ext_sound_channel_play(&unigi_ext_sound_channels[i],buffer,size); + } + ++i; + } +} + +void unigi_ext_sound_init() { + unigi_sound_init(unigi_ext_sound_handle); +} diff --git a/main.h b/main.h index 745cc5e..74a2806 100644 --- a/main.h +++ b/main.h @@ -14,5 +14,11 @@ void unigi_ext_rect_dimensions(unigi_ext_type_rect bounds, unigi_ext_type_2d_coo unigi_ext_type_texture * unigi_ext_texture_create(unigi_type_resolution_2d_coord width, unigi_type_resolution_2d_coord height); void unigi_ext_texture_destroy(unigi_ext_type_texture * texture); unigi_ext_type_texture * unigi_ext_texture_open(char * path); - +unigi_ext_type_sound_sample * unigi_ext_sound_open(char * path); +unigi_ext_type_sound_channel * unigi_ext_sound_channels; +size_t unigi_ext_sound_channels_size = 0; +unigi_ext_type_sound_channel * unigi_ext_sound_channel_create(unigi_ext_type_sound_sample * sample); +void unigi_ext_sound_channel_play(unigi_ext_type_sound_channel * channel, uint8_t * buffer, size_t size); +void unigi_ext_sound_handle(uint8_t * buffer, size_t size); +void unigi_ext_sound_init(); #endif diff --git a/structs.h b/structs.h index 94d945f..7e74d90 100644 --- a/structs.h +++ b/structs.h @@ -16,4 +16,20 @@ struct unigi_ext_type_rect { unigi_ext_type_2d_coord y2; }; typedef struct unigi_ext_type_rect unigi_ext_type_rect; + +struct unigi_ext_type_sound_sample { + size_t size; + uint8_t * data; +}; +typedef struct unigi_ext_type_sound_sample unigi_ext_type_sound_sample; + +struct unigi_ext_type_sound_channel { + unigi_ext_type_sound_sample * sound; + float volume; + size_t start; + size_t stop; + size_t progress; + unigi_type_bool loop; +}; +typedef struct unigi_ext_type_sound_channel unigi_ext_type_sound_channel; #endif