6 Commits

3 changed files with 47 additions and 27 deletions

View File

@@ -9,8 +9,6 @@ struct JA_Sound_t {
Uint8* buffer {NULL}; Uint8* buffer {NULL};
}; };
enum JA_Channel_state { JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED };
struct JA_Channel_t { struct JA_Channel_t {
JA_Sound sound; JA_Sound sound;
int pos {0}; int pos {0};
@@ -18,8 +16,6 @@ struct JA_Channel_t {
JA_Channel_state state { JA_CHANNEL_FREE }; JA_Channel_state state { JA_CHANNEL_FREE };
}; };
enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED };
struct JA_Music_t { struct JA_Music_t {
int samples {0}; int samples {0};
int pos {0}; int pos {0};
@@ -34,16 +30,17 @@ JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
int JA_freq {48000}; int JA_freq {48000};
SDL_AudioFormat JA_format {AUDIO_S16}; SDL_AudioFormat JA_format {AUDIO_S16};
Uint8 JA_channels {2}; Uint8 JA_channels {2};
int JA_volume = 128;
void audioCallback(void * userdata, uint8_t * stream, int len) { void audioCallback(void * userdata, uint8_t * stream, int len) {
SDL_memset(stream, 0, len); SDL_memset(stream, 0, len);
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) { if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) {
const int size = SDL_min(len, current_music->samples*2-current_music->pos); const int size = SDL_min(len, current_music->samples*2-current_music->pos);
SDL_memcpy(stream, current_music->output+current_music->pos, size); SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, JA_volume);
current_music->pos += size/2; current_music->pos += size/2;
if (size < len) { if (size < len) {
if (current_music->times != 0) { if (current_music->times != 0) {
SDL_memcpy(stream+size, current_music->output, len-size); SDL_MixAudioFormat(stream+size, (Uint8*)current_music->output, AUDIO_S16, len-size, JA_volume);
current_music->pos = (len-size)/2; current_music->pos = (len-size)/2;
if (current_music->times > 0) current_music->times--; if (current_music->times > 0) current_music->times--;
} else { } else {
@@ -56,11 +53,11 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
if (channels[i].state == JA_CHANNEL_PLAYING) { if (channels[i].state == JA_CHANNEL_PLAYING) {
const int size = SDL_min(len, channels[i].sound->length - channels[i].pos); const int size = SDL_min(len, channels[i].sound->length - channels[i].pos);
SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, 64); SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_volume/2);
channels[i].pos += size; channels[i].pos += size;
if (size < len) { if (size < len) {
if (channels[i].times != 0) { if (channels[i].times != 0) {
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, 64); SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, JA_volume/2);
channels[i].pos = len-size; channels[i].pos = len-size;
if (channels[i].times > 0) channels[i].times--; if (channels[i].times > 0) channels[i].times--;
} else { } else {
@@ -82,7 +79,7 @@ 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) {
int chan, samplerate; int chan, samplerate;
JA_Music music = (JA_Music)SDL_malloc(sizeof(JA_Music_t)); JA_Music music = new JA_Music_t();
music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output); music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
SDL_AudioCVT cvt; SDL_AudioCVT cvt;
@@ -101,7 +98,6 @@ JA_Music JA_LoadMusic(const char* filename) {
} }
void JA_PlayMusic(JA_Music music, const int loop) { void JA_PlayMusic(JA_Music music, const int loop) {
int chan, samplerate;
if (current_music != NULL) { if (current_music != NULL) {
current_music->pos = 0; current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED; current_music->state = JA_MUSIC_STOPPED;
@@ -113,29 +109,37 @@ void JA_PlayMusic(JA_Music music, const int loop) {
} }
void JA_PauseMusic() { void JA_PauseMusic() {
if (current_music->state == JA_MUSIC_INVALID) return; if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
current_music->state = JA_MUSIC_PAUSED; current_music->state = JA_MUSIC_PAUSED;
} }
void JA_ResumeMusic() { void JA_ResumeMusic() {
if (current_music->state == JA_MUSIC_INVALID) return; if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
current_music->state = JA_MUSIC_PLAYING; current_music->state = JA_MUSIC_PLAYING;
} }
void JA_StopMusic() { void JA_StopMusic() {
if (current_music->state == JA_MUSIC_INVALID) return; if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
current_music->pos = 0; current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED; current_music->state = JA_MUSIC_STOPPED;
} }
bool JA_IsMusicPlaying() { JA_Music_state JA_GetMusicState() {
return current_music->state == JA_MUSIC_PLAYING; if (current_music == NULL) return JA_MUSIC_INVALID;
return current_music->state;
} }
void JA_DeleteMusic(JA_Music music) { void JA_DeleteMusic(JA_Music music) {
if (current_music == music) current_music = NULL; if (current_music == music) current_music = NULL;
free(music->output); SDL_free(music->output);
free(music); delete music;
}
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length) {
JA_Sound sound = new JA_Sound_t();
sound->buffer = buffer;
sound->length = length;
return sound;
} }
JA_Sound JA_LoadSound(const char* filename) { JA_Sound JA_LoadSound(const char* filename) {
@@ -149,7 +153,7 @@ JA_Sound JA_LoadSound(const char* filename) {
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult); cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
SDL_memcpy(cvt.buf, sound->buffer, sound->length); SDL_memcpy(cvt.buf, sound->buffer, sound->length);
SDL_ConvertAudio(&cvt); SDL_ConvertAudio(&cvt);
free(sound->buffer); SDL_FreeWAV(sound->buffer);
sound->buffer = cvt.buf; sound->buffer = cvt.buf;
sound->length = cvt.len_cvt; sound->length = cvt.len_cvt;
@@ -172,7 +176,7 @@ void JA_DeleteSound(JA_Sound sound) {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
if (channels[i].sound == sound) JA_StopChannel(i); if (channels[i].sound == sound) JA_StopChannel(i);
} }
SDL_FreeWAV(sound->buffer); SDL_free(sound->buffer);
delete sound; delete sound;
} }
@@ -210,8 +214,12 @@ void JA_StopChannel(const int channel) {
} }
} }
bool JA_IsChannelPlaying(const int channel) { JA_Channel_state JA_GetChannelState(const int channel) {
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return false; if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
return channels[channel].state == JA_CHANNEL_PLAYING; return channels[channel].state;
} }
int JA_SetVolume(int volume) {
JA_volume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
return JA_volume;
}

View File

@@ -1,6 +1,9 @@
#pragma once #pragma once
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED };
enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED };
typedef struct JA_Sound_t *JA_Sound; typedef struct JA_Sound_t *JA_Sound;
typedef struct JA_Music_t *JA_Music; typedef struct JA_Music_t *JA_Music;
@@ -11,13 +14,16 @@ 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();
bool JA_IsMusicPlaying(); JA_Music_state JA_GetMusicState();
void JA_DeleteMusic(JA_Music music); void JA_DeleteMusic(JA_Music music);
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length);
JA_Sound JA_LoadSound(const char* filename); JA_Sound JA_LoadSound(const char* filename);
int JA_PlaySound(JA_Sound sound, const int loop = 0); int JA_PlaySound(JA_Sound sound, const int loop = 0);
void JA_PauseChannel(const int channel); void JA_PauseChannel(const int channel);
void JA_ResumeChannel(const int channel); void JA_ResumeChannel(const int channel);
void JA_StopChannel(const int channel); void JA_StopChannel(const int channel);
bool JA_IsChannelPlaying(const int channel); JA_Channel_state JA_GetChannelState(const int channel);
void JA_DeleteSound(JA_Sound sound); void JA_DeleteSound(JA_Sound sound);
int JA_SetVolume(int volume);

View File

@@ -16,7 +16,7 @@ int main(int argc, char **argv) {
int channel = -1; int channel = -1;
JA_PlayMusic(music, true); JA_PlayMusic(music, true);
int volume = 128;
bool should_exit = false; bool should_exit = false;
while(!should_exit) { while(!should_exit) {
while(SDL_PollEvent(&event)) { while(SDL_PollEvent(&event)) {
@@ -24,7 +24,7 @@ int main(int argc, char **argv) {
if (event.type == SDL_KEYDOWN) { if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.scancode) { switch (event.key.keysym.scancode) {
case SDL_SCANCODE_1: // Si pulsem la tecla '1' pausem o despausem la música case SDL_SCANCODE_1: // Si pulsem la tecla '1' pausem o despausem la música
if (JA_IsMusicPlaying()) { JA_PauseMusic(); } else { JA_ResumeMusic(); } if (JA_GetMusicState() == JA_MUSIC_PLAYING) { JA_PauseMusic(); } else { JA_ResumeMusic(); }
break; break;
case SDL_SCANCODE_2: // Si pulsem la tecla '2' sona el wav 1 vegada case SDL_SCANCODE_2: // Si pulsem la tecla '2' sona el wav 1 vegada
JA_PlaySound(peiv); JA_PlaySound(peiv);
@@ -36,11 +36,17 @@ int main(int argc, char **argv) {
channel = JA_PlaySound(peiv, -1); channel = JA_PlaySound(peiv, -1);
break; break;
case SDL_SCANCODE_5: // Si pulsem la tecla '5' pausem o despausem el wav que sonaba infinitament case SDL_SCANCODE_5: // Si pulsem la tecla '5' pausem o despausem el wav que sonaba infinitament
if (JA_IsChannelPlaying(channel)) { JA_PauseChannel(channel); } else { JA_ResumeChannel(channel); } if (JA_GetChannelState(channel) == JA_CHANNEL_PLAYING) { JA_PauseChannel(channel); } else { JA_ResumeChannel(channel); }
break; break;
case SDL_SCANCODE_6: // Si pulsem la tecla '6' stopem definitivament el wav infinit case SDL_SCANCODE_6: // Si pulsem la tecla '6' stopem definitivament el wav infinit
JA_StopChannel(channel); JA_StopChannel(channel);
break; break;
case SDL_SCANCODE_UP:
volume = JA_SetVolume(volume+16);
break;
case SDL_SCANCODE_DOWN:
volume = JA_SetVolume(volume-16);
break;
} }
} }