WAVs can loop, and OGG and WAV loops can be finite

This commit is contained in:
2021-02-04 14:37:57 +01:00
parent ac5421a340
commit 55c9a0ddba
3 changed files with 31 additions and 22 deletions

View File

@@ -12,6 +12,7 @@ struct JA_Sound_t {
struct JA_Sound_Playing_t { struct JA_Sound_Playing_t {
Uint32 length {0}; Uint32 length {0};
int pos {0}; int pos {0};
int times {0};
Uint8 *buffer {NULL}; Uint8 *buffer {NULL};
JA_Sound_Playing_t* prev {NULL}; JA_Sound_Playing_t* prev {NULL};
JA_Sound_Playing_t* next {NULL}; JA_Sound_Playing_t* next {NULL};
@@ -24,7 +25,7 @@ struct JA_Music_t {
int pos {0}; int pos {0};
short *output {NULL}; short *output {NULL};
JA_Music_state state {JA_MUSIC_INVALID}; JA_Music_state state {JA_MUSIC_INVALID};
bool loop {false}; int times {0};
}; };
JA_Music current_music{NULL}; JA_Music current_music{NULL};
@@ -44,9 +45,10 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
SDL_memcpy(stream, current_music->output+current_music->pos, size); SDL_memcpy(stream, current_music->output+current_music->pos, size);
current_music->pos += size/2; current_music->pos += size/2;
if (size < len) { if (size < len) {
if (current_music->loop) { if (current_music->times != 0) {
SDL_memcpy(stream+size, current_music->output, len-size); SDL_memcpy(stream+size, current_music->output, len-size);
current_music->pos = (len-size)/2; current_music->pos = (len-size)/2;
if (current_music->times > 0) current_music->times--;
} else { } else {
current_music->pos = 0; current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED; current_music->state = JA_MUSIC_STOPPED;
@@ -60,20 +62,26 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
SDL_MixAudioFormat(stream, sound->buffer+sound->pos, AUDIO_S16, size, 64); SDL_MixAudioFormat(stream, sound->buffer+sound->pos, AUDIO_S16, size, 64);
sound->pos += size; sound->pos += size;
if (size < len) { if (size < len) {
if (sound == last_sound) last_sound = sound->prev; if (sound->times != 0) {
if (sound == first_sound) first_sound = sound->next; SDL_MixAudioFormat(stream+size, sound->buffer, AUDIO_S16, len-size, 64);
if (sound->prev != NULL) sound->prev->next = sound->next; sound->pos = len-size;
if (sound->next != NULL) sound->next->prev = sound->prev; if (sound->times > 0) sound->times--;
if (free_sounds_list == NULL) {
free_sounds_list = sound;
sound = sound->next;
free_sounds_list->prev = free_sounds_list->next = NULL;
} else { } else {
free_sounds_list->prev = sound; if (sound == last_sound) last_sound = sound->prev;
sound = sound->next; if (sound == first_sound) first_sound = sound->next;
free_sounds_list->prev->next = free_sounds_list; if (sound->prev != NULL) sound->prev->next = sound->next;
free_sounds_list = free_sounds_list->prev; if (sound->next != NULL) sound->next->prev = sound->prev;
free_sounds_list->prev = NULL; if (free_sounds_list == NULL) {
free_sounds_list = sound;
sound = sound->next;
free_sounds_list->prev = free_sounds_list->next = NULL;
} else {
free_sounds_list->prev = sound;
sound = sound->next;
free_sounds_list->prev->next = free_sounds_list;
free_sounds_list = free_sounds_list->prev;
free_sounds_list->prev = NULL;
}
} }
} else { } else {
sound = sound->next; sound = sound->next;
@@ -114,7 +122,7 @@ JA_Music JA_LoadMusic(const char* filename) {
return music; return music;
} }
void JA_PlayMusic(JA_Music music, const bool loop) { void JA_PlayMusic(JA_Music music, const int loop) {
int chan, samplerate; int chan, samplerate;
if (current_music != NULL) { if (current_music != NULL) {
current_music->pos = 0; current_music->pos = 0;
@@ -123,7 +131,7 @@ void JA_PlayMusic(JA_Music music, const bool loop) {
current_music = music; current_music = music;
current_music->pos = 0; current_music->pos = 0;
current_music->state = JA_MUSIC_PLAYING; current_music->state = JA_MUSIC_PLAYING;
current_music->loop = loop; current_music->times = loop;
} }
void JA_PauseMusic() { void JA_PauseMusic() {
@@ -170,7 +178,7 @@ JA_Sound JA_LoadSound(const char* filename) {
return sound; return sound;
} }
void JA_PlaySound(JA_Sound sound) { void JA_PlaySound(JA_Sound sound, const int loop) {
if (free_sounds_list == NULL) { if (free_sounds_list == NULL) {
first_sound->prev = last_sound; first_sound->prev = last_sound;
last_sound->next = first_sound; last_sound->next = first_sound;
@@ -188,6 +196,7 @@ void JA_PlaySound(JA_Sound sound) {
} }
last_sound->buffer = sound->buffer; last_sound->buffer = sound->buffer;
last_sound->length = sound->length; last_sound->length = sound->length;
last_sound->times = loop;
last_sound->pos = 0; last_sound->pos = 0;
} }

View File

@@ -7,7 +7,7 @@ typedef struct JA_Music_t *JA_Music;
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels); void JA_Init(const int freq, const SDL_AudioFormat format, const int channels);
JA_Music JA_LoadMusic(const char* filename); JA_Music JA_LoadMusic(const char* filename);
void JA_PlayMusic(JA_Music music, const bool loop = true); void JA_PlayMusic(JA_Music music, const int loop = -1);
void JA_PauseMusic(); void JA_PauseMusic();
void JA_ResumeMusic(); void JA_ResumeMusic();
void JA_StopMusic(); void JA_StopMusic();
@@ -15,5 +15,5 @@ bool JA_IsMusicPlaying();
void JA_DeleteMusic(JA_Music music); void JA_DeleteMusic(JA_Music music);
JA_Sound JA_LoadSound(const char* filename); JA_Sound JA_LoadSound(const char* filename);
void JA_PlaySound(JA_Sound sound); void JA_PlaySound(JA_Sound sound, const int loop = 0);
void JA_DeleteSound(JA_Sound sound); void JA_DeleteSound(JA_Sound sound);

View File

@@ -15,13 +15,13 @@ int main(int argc, char **argv) {
JA_Sound peiv = JA_LoadSound("menu_select.wav"); JA_Sound peiv = JA_LoadSound("menu_select.wav");
JA_PlayMusic(music, true); JA_PlayMusic(music, true);
bool should_exit = false; bool should_exit = false;
while(!should_exit) { while(!should_exit) {
while(SDL_PollEvent(&event)) { while(SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) { should_exit = true; break; } if (event.type == SDL_QUIT) { should_exit = true; break; }
if (event.type == SDL_KEYDOWN) { if (event.type == SDL_KEYDOWN) {
JA_PlaySound(peiv); JA_PlaySound(peiv, 2);
if (JA_IsMusicPlaying()) if (JA_IsMusicPlaying())
JA_PauseMusic(); JA_PauseMusic();
else else