From b719c4389f12da025938e4e4be695c16b3658ee0 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Thu, 29 Dec 2016 17:05:09 +0000 Subject: [PATCH] improved the sound implementation (still has too much latency, although mainly due to other parts of the menu) --- inc/hashtable.h | 20 +++++ inc/sound.h | 5 ++ res/filesystem/bgm21.it | Bin 0 -> 19103 bytes src/hashtable.c | 159 ++++++++++++++++++++++++++++++++++++++++ src/menu.c | 66 ++++------------- src/sound.c | 108 +++++++++++++++++++++++++++ 6 files changed, 308 insertions(+), 50 deletions(-) create mode 100644 inc/hashtable.h create mode 100644 inc/sound.h create mode 100644 res/filesystem/bgm21.it create mode 100644 src/hashtable.c create mode 100644 src/sound.c diff --git a/inc/hashtable.h b/inc/hashtable.h new file mode 100644 index 0000000..c31518c --- /dev/null +++ b/inc/hashtable.h @@ -0,0 +1,20 @@ +typedef struct hashtable hashtable; +void hashtable_destroy(hashtable *t); +typedef struct hashtable_entry hashtable_entry; +hashtable_entry *hashtable_body_allocate(unsigned int capacity); +hashtable *hashtable_create(); +void hashtable_remove(hashtable *t,char *key); +void hashtable_resize(hashtable *t,unsigned int capacity); +void hashtable_set(hashtable *t,char *key,void *value); +void *hashtable_get(hashtable *t,char *key); +unsigned int hashtable_find_slot(hashtable *t,char *key); +unsigned long hashtable_hash(char *str); +struct hashtable { + unsigned int size; + unsigned int capacity; + hashtable_entry* body; +}; +struct hashtable_entry { + char* key; + void* value; +}; \ No newline at end of file diff --git a/inc/sound.h b/inc/sound.h new file mode 100644 index 0000000..4edf08b --- /dev/null +++ b/inc/sound.h @@ -0,0 +1,5 @@ +void sndInit(void); +void sndPlayBGM(char* filename); +void sndStopAll(void); +void sndPlaySFX(char* filename); +void sndUpdate(void); \ No newline at end of file diff --git a/res/filesystem/bgm21.it b/res/filesystem/bgm21.it new file mode 100644 index 0000000000000000000000000000000000000000..b6ed8463125754d57382a8a742739ffcde9f764e GIT binary patch literal 19103 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 AhX4Qo literal 0 HcmV?d00001 diff --git a/src/hashtable.c b/src/hashtable.c new file mode 100644 index 0000000..d0c6697 --- /dev/null +++ b/src/hashtable.c @@ -0,0 +1,159 @@ +/** + * Hashtable implementation + * (c) 2011 @marekweb + * + * Uses dynamic addressing with linear probing. + */ + +#include +#include +#include +#include +#include "hashtable.h" + +/* + * Interface section used for `makeheaders`. + */ +#if INTERFACE +struct hashtable_entry { + char* key; + void* value; +}; + +struct hashtable { + unsigned int size; + unsigned int capacity; + hashtable_entry* body; +}; +#endif + +#define HASHTABLE_INITIAL_CAPACITY 2 + +/** + * Compute the hash value for the given string. + * Implements the djb k=33 hash function. + */ +unsigned long hashtable_hash(char* str) +{ + unsigned long hash = 5381; + int c; + while ((c = *str++)) + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + return hash; +} + +/** + * Find an available slot for the given key, using linear probing. + */ +unsigned int hashtable_find_slot(hashtable* t, char* key) +{ + int index = hashtable_hash(key) % t->capacity; + while (t->body[index].key != NULL && strcmp(t->body[index].key, key) != 0) { + index = (index + 1) % t->capacity; + } + return index; +} + +/** + * Return the item associated with the given key, or NULL if not found. + */ +void* hashtable_get(hashtable* t, char* key) +{ + int index = hashtable_find_slot(t, key); + if (t->body[index].key != NULL) { + return t->body[index].value; + } else { + return NULL; + } +} + +/** + * Assign a value to the given key in the table. + */ +void hashtable_set(hashtable* t, char* key, void* value) +{ + int index = hashtable_find_slot(t, key); + if (t->body[index].key != NULL) { + /* Entry exists; update it. */ + t->body[index].value = value; + } else { + t->size++; + /* Create a new entry */ + if ((float)t->size / t->capacity > 0.8) { + /* Resize the hash table */ + hashtable_resize(t, t->capacity * 2); + index = hashtable_find_slot(t, key); + } + t->body[index].key = key; + t->body[index].value = value; + } +} + +/** + * Remove a key from the table + */ +void hashtable_remove(hashtable* t, char* key) +{ + int index = hashtable_find_slot(t, key); + if (t->body[index].key != NULL) { + t->body[index].key = NULL; + t->body[index].value = NULL; + t->size--; + } +} + +/** + * Create a new, empty hashtable + */ +hashtable* hashtable_create() +{ + hashtable* new_ht = malloc(sizeof(hashtable)); + new_ht->size = 0; + new_ht->capacity = HASHTABLE_INITIAL_CAPACITY; + new_ht->body = hashtable_body_allocate(new_ht->capacity); + return new_ht; +} + +#if 0 +/** + * Adds all items from another table. + */ +hashtable* hashtable_merge(hashtable* ht, hashtable* other) +{ +} +#endif + +/** + * Allocate a new memory block with the given capacity. + */ +hashtable_entry* hashtable_body_allocate(unsigned int capacity) +{ + return (hashtable_entry*)calloc(capacity, sizeof(hashtable_entry)); +} + +/** + * Resize the allocated memory. + * Warning: clears the table of all entries. + */ +void hashtable_resize(hashtable* t, unsigned int capacity) +{ + assert(capacity >= t->size); + unsigned int old_capacity = t->capacity; + hashtable_entry* old_body = t->body; + t->body = hashtable_body_allocate(capacity); + t->capacity = capacity; + for (int i = 0; i < old_capacity; i++) { + if (old_body[i].key != NULL) { + hashtable_set(t, old_body[i].key, old_body[i].value); + } + } +} + +/** + * Destroy the table and deallocate it from memory. This does not deallocate the contained items. + */ +void hashtable_destroy(hashtable* t) +{ + free(t->body); + free(t); +} diff --git a/src/menu.c b/src/menu.c index cfdd3e9..41786cb 100644 --- a/src/menu.c +++ b/src/menu.c @@ -36,7 +36,7 @@ #include "menu.h" //sound -#include +#include "sound.h" #include "mp3.h" //debug @@ -2567,48 +2567,18 @@ void playSound(int snd) { //no thread support in libdragon yet, sounds pause the menu for a time :/ - //maybe global - int v1; - - static SAMPLE *add_sfx = NULL; if (snd == 1) - add_sfx = Sample_Load("rom://ed64_mono.wav"); + sndPlaySFX("rom://ed64_mono.wav"); if (snd == 2) - add_sfx = Sample_Load("rom://bamboo.wav"); + sndPlaySFX("rom://bamboo.wav"); if (snd == 3) - add_sfx = Sample_Load("rom://warning.wav"); + sndPlaySFX("rom://warning.wav"); if (snd == 4) - add_sfx = Sample_Load("rom://done.wav"); + sndPlaySFX("rom://done.wav"); - MikMod_SetNumVoices(-1, 2); - - if (!add_sfx) - { - MikMod_Exit(); - } - else - { - MikMod_EnableOutput(); - - audio_write_silence(); - audio_write_silence(); - - v1 = Sample_Play(add_sfx, 0, 0); - Voice_SetVolume(v1, 100); - - //maybe put update function into a int/vblank callback - for (int s = 0; s < 50; s++) - { - MikMod_Update(); - sleep(10); - } - - MikMod_DisableOutput(); - Sample_Free(add_sfx); - } } //draws the next char at the text input screen @@ -3355,21 +3325,11 @@ int main(void) if (sound_on) { - audio_init(44100, 2); //load soundsystem + audio_init(44100, 2); + sndInit(); + timer_init(); - - MikMod_RegisterAllDrivers(); - MikMod_RegisterAllLoaders(); - - md_mode = 0; - md_mode |= DMODE_16BITS; - md_mode |= DMODE_SOFT_MUSIC; - md_mode |= DMODE_SOFT_SNDFX; - - md_mixfreq = audio_get_frequency(); - - MikMod_Init(""); } if (!fast_boot) @@ -3378,6 +3338,9 @@ int main(void) playSound(1); sleep(2000); //splash screen duration + + //todo: if bgm is enabled, we should start it... + //sndPlayBGM("rom://bgm21.it"); } border_color_1 = translate_color(border_color_1_s); @@ -3434,6 +3397,8 @@ int main(void) //system main-loop with controller inputs-scan while (1) { + sndUpdate(); + if (playing == 1) playing = update_mp3(buf_ptr, buf_size); @@ -4329,8 +4294,9 @@ int main(void) drawBoxNumber(disp, 2); display_show(disp); - printText("ALT64: v0.1.8.6.1.1", 9, 8, disp); - printText(" ", 9, -1, disp); + printText("Altra64: v0.1.8.6.1.2", 9, 8, disp); + sprintf(firmware_str, "ED64 firmware: v%03x", evd_getFirmVersion()); + printText(firmware_str , 9, -1, disp); printText("by Saturnu", 9, -1, disp); printText("& JonesAlmighty", 9, -1, disp); printText(" ", 9, -1, disp); diff --git a/src/sound.c b/src/sound.c new file mode 100644 index 0000000..7589cc8 --- /dev/null +++ b/src/sound.c @@ -0,0 +1,108 @@ +#include +#include //needed for audio_get_frequency() +#include "hashtable.h" + +MODULE *moduleBGM = NULL; + +/* sound effects */ +hashtable* samples = NULL; + +/* voices */ +SBYTE voiceSFX; + +void sndInit(void) +{ + samples = hashtable_create(); + + /* register all the drivers */ + MikMod_RegisterAllDrivers(); + MikMod_RegisterAllLoaders(); + + /* initialize the library */ + md_mode = 0; + md_mode |= DMODE_16BITS; + md_mode |= DMODE_SOFT_MUSIC; + md_mode |= DMODE_SOFT_SNDFX; + md_mode |= DMODE_INTERP; + + md_mixfreq = audio_get_frequency(); + + MikMod_Init(""); + + /* reserve 2 voices for sound effects */ + MikMod_SetNumVoices(-1, 2); + + /* get ready to play */ + MikMod_EnableOutput(); + + +} + +void sndPlayBGM(char* filename) +{ + if (Player_Active()) + { + Player_Stop(); + } + Player_Free(moduleBGM); + moduleBGM = NULL; + + moduleBGM = Player_Load(filename, 64, 0); + + if (moduleBGM) + { + Player_Start(moduleBGM); + Player_SetVolume(20); + } +} + +void sndStopAll(void) +{ + Voice_Stop(voiceSFX); + Player_Stop(); + MikMod_DisableOutput(); + + int index = 0; + while (index < samples->capacity) { + Sample_Free(samples->body[index].value); + index = index + 1; + } + + hashtable_destroy(samples); + + Player_Free(moduleBGM); + moduleBGM = NULL; + + samples = hashtable_create(); + //MikMod_Exit(); //I dont think we should ever exit as that would mean reinitialising?! +} + +void sndPlaySFX(char* filename) +{ + if (!Voice_Stopped(voiceSFX)) + { + Voice_Stop(voiceSFX); + } + + + if (hashtable_get(samples, filename) == NULL) + { + hashtable_set(samples, filename, Sample_Load(filename)); + } + + //audio_write_silence(); + Voice_SetVolume(voiceSFX, 200); + voiceSFX = Sample_Play(hashtable_get(samples, filename), 0, 0); + + MikMod_Update(); //force an update so that the voice is registered as playing! + +} + +void sndUpdate(void) +{ + if (!Voice_Stopped(voiceSFX) || Player_Active()) + { + MikMod_Update(); + + } +}