12 Commits

Author SHA1 Message Date
4fc5b47dc9 - [FIX] Si no feia falta conversió de format, la música no apuntava correctament la duració al carregar 2024-12-30 19:52:28 +01:00
1b7fdbd230 - [FIX] La musica duraba la meitat per contar samples en compte de bytes 2024-12-29 08:06:58 +01:00
f5ee23cea3 - [NEW] JA_PlaySoundOnChannel(JA_Sound_t *sound, const int channel, const int loop = 0); 2024-12-28 10:59:25 +01:00
774aebf4a4 - [NEW] JA_FadeOutMusic(const int milliseconds); 2024-12-23 13:34:36 +01:00
b6b3bf452e - [FIX] La música duraba el doble, i ho completaba amb roido 2024-11-27 13:33:07 +01:00
1519725d4a - [NEW] JA_SetMusicPosition() i JA_GetMusicPosition(), per a obtindre o especificar la posició de la música en segons (decimals). 2024-11-26 14:37:23 +01:00
f0687f9f4d - [NEW] JA_LoadMusic() i JA_LoadSound() ara també accepten un buffer de uint8_t* i un tamany, a l'hora de carregar.
- [FIX] JA_PlaySound() de vegades no tornava res
2024-10-06 15:06:11 +02:00
cd2f18212b - [NEW] JA_SetMusicVolume(int volume)
- [NEW] JA_EnableMusic(const bool value)
- [NEW]  JA_SetSoundVolume(int volume)
- [NEW] JA_EnableSound(const bool value)
2024-05-31 18:25:11 +02:00
c79150b24a - Types changed, SDL_Mixer version included 2022-12-01 19:42:20 +01:00
bf1925bb3a Update 'readme.md' 2022-11-24 16:12:43 +01:00
861bb5e7f9 Merge branch 'master' of https://gitea.sustancia.synology.me/JailDoctor/JailAudio 2022-11-24 16:10:36 +01:00
debd80f6af - Removed volume per channel
- [NEW] JA_SetSoundVolume sets volume for all sound effects
- [NEW] JA_SetMusicVolume sets volume for the music
- JA_SetVolume works as always: sets volume for both, with sounds volume halved.
2022-11-24 16:10:33 +01:00
5 changed files with 417 additions and 72 deletions

View File

@@ -1,3 +1,4 @@
#ifndef JA_USESDLMIXER
#include "jail_audio.h" #include "jail_audio.h"
#include "stb_vorbis.c" #include "stb_vorbis.c"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
@@ -11,40 +12,62 @@ struct JA_Sound_t {
}; };
struct JA_Channel_t { struct JA_Channel_t {
JA_Sound sound; JA_Sound_t *sound;
int pos {0}; int pos {0};
int times {0}; int times {0};
int volume {64};
JA_Channel_state state { JA_CHANNEL_FREE }; JA_Channel_state state { JA_CHANNEL_FREE };
}; };
struct JA_Music_t { struct JA_Music_t {
int samples {0}; int samples {0};
Uint32 length {0};
int pos {0}; int pos {0};
int times {0}; int times {0};
short* output {NULL}; short* output {NULL};
JA_Music_state state {JA_MUSIC_INVALID}; JA_Music_state state {JA_MUSIC_INVALID};
}; };
JA_Music current_music{NULL}; JA_Music_t *current_music{NULL};
JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS]; 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; int JA_musicVolume = 128;
int JA_soundVolume = 64;
bool JA_musicEnabled = true;
bool JA_soundEnabled = true;
SDL_AudioDeviceID sdlAudioDevice = 0; SDL_AudioDeviceID sdlAudioDevice = 0;
bool fading = false;
int fade_start_time;
int fade_duration;
int fade_initial_volume;
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); int volume = JA_musicVolume;
SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, JA_volume); if (fading) {
current_music->pos += size/2; int time = SDL_GetTicks();
if (time > (fade_start_time+fade_duration)) {
fading = false;
current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED;
volume = 0;
} else {
const int time_passed = time - fade_start_time;
const float percent = (float)time_passed / (float)fade_duration;
volume = JA_musicVolume * (1.0 - percent);
}
}
const int size = SDL_min(len, current_music->length - current_music->pos);
SDL_MixAudioFormat(stream, (Uint8*)(current_music->output)+current_music->pos, AUDIO_S16, size, volume);
current_music->pos += size;
if (size < len) { if (size < len) {
if (current_music->times != 0) { if (current_music->times != 0) {
SDL_MixAudioFormat(stream+size, (Uint8*)current_music->output, AUDIO_S16, len-size, JA_volume); SDL_MixAudioFormat(stream+size, (Uint8*)current_music->output, AUDIO_S16, len-size, volume);
current_music->pos = (len-size)/2; current_music->pos = len-size;
if (current_music->times > 0) current_music->times--; if (current_music->times > 0) current_music->times--;
} else { } else {
current_music->pos = 0; current_music->pos = 0;
@@ -56,11 +79,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, channels[i].volume); SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_soundVolume);
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, channels[i].volume); SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, JA_soundVolume);
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 {
@@ -71,13 +94,26 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
} }
} }
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)
{
#ifdef DEBUG
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG);
#endif
SDL_Log("Iniciant JailAudio...");
JA_freq = freq; JA_freq = freq;
JA_format = format; JA_format = format;
JA_channels = channels; JA_channels = channels;
SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL}; SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL};
if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice); if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice);
sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0); sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
if (sdlAudioDevice==0)
{
SDL_Log("FAILED!\n");
SDL_Log("Failed to initialize SDL audio!\n");
} else {
SDL_Log("OK!\n");
}
SDL_PauseAudioDevice(sdlAudioDevice, 0); SDL_PauseAudioDevice(sdlAudioDevice, 0);
} }
@@ -87,9 +123,36 @@ void JA_Quit() {
sdlAudioDevice = 0; sdlAudioDevice = 0;
} }
JA_Music JA_LoadMusic(const char* filename) { JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length)
{
int chan, samplerate; int chan, samplerate;
JA_Music_t *music = new JA_Music_t();
music->samples = stb_vorbis_decode_memory(buffer, length, &chan, &samplerate, &music->output);
// [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert
// music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq);
SDL_Log("Music length: %f\n", float(music->samples)/float(JA_freq));
if (cvt.needed) {
cvt.len = music->samples * chan * 2;
music->length = cvt.len;
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
SDL_memcpy(cvt.buf, music->output, cvt.len);
SDL_ConvertAudio(&cvt);
free(music->output);
music->output = (short*)cvt.buf;
}
music->length = music->samples * chan * 2;
music->pos = 0;
music->state = JA_MUSIC_STOPPED;
return music;
}
JA_Music_t *JA_LoadMusic(const char* filename)
{
// [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid. // [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid.
FILE *f = fopen(filename, "rb"); FILE *f = fopen(filename, "rb");
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
@@ -99,30 +162,17 @@ JA_Music JA_LoadMusic(const char* filename) {
if (fread(buffer, fsize, 1, f)!=1) return NULL; if (fread(buffer, fsize, 1, f)!=1) return NULL;
fclose(f); fclose(f);
JA_Music music = new JA_Music_t(); JA_Music_t *music = JA_LoadMusic(buffer, fsize);
music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output);
free(buffer); free(buffer);
// [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert
// music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq);
if (cvt.needed) {
cvt.len = music->samples * chan * 2;
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
SDL_memcpy(cvt.buf, music->output, cvt.len);
SDL_ConvertAudio(&cvt);
free(music->output);
music->output = (short*)cvt.buf;
}
music->pos = 0;
music->state = JA_MUSIC_STOPPED;
return music; return music;
} }
void JA_PlayMusic(JA_Music music, const int loop) { void JA_PlayMusic(JA_Music_t *music, const int loop)
{
if (!JA_musicEnabled) return;
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;
@@ -133,42 +183,111 @@ void JA_PlayMusic(JA_Music music, const int loop) {
current_music->times = loop; current_music->times = loop;
} }
void JA_PauseMusic() { void JA_PauseMusic()
{
if (!JA_musicEnabled) return;
if (current_music == NULL || 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 (!JA_musicEnabled) return;
if (current_music == NULL || 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 (!JA_musicEnabled) return;
if (current_music == NULL || 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;
} }
void JA_FadeOutMusic(const int milliseconds)
{
if (!JA_musicEnabled) return;
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
fading = true;
fade_start_time = SDL_GetTicks();
fade_duration = milliseconds;
fade_initial_volume = JA_musicVolume;
}
JA_Music_state JA_GetMusicState() { JA_Music_state JA_GetMusicState() {
if (!JA_musicEnabled) return JA_MUSIC_DISABLED;
if (current_music == NULL) return JA_MUSIC_INVALID; if (current_music == NULL) return JA_MUSIC_INVALID;
return current_music->state; return current_music->state;
} }
void JA_DeleteMusic(JA_Music music) { void JA_DeleteMusic(JA_Music_t *music) {
if (current_music == music) current_music = NULL; if (current_music == music) current_music = NULL;
free(music->output); free(music->output);
delete music; delete music;
} }
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length) { int JA_SetMusicVolume(int volume)
JA_Sound sound = new JA_Sound_t(); {
JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
return JA_musicVolume;
}
void JA_SetMusicPosition(float value)
{
if (!current_music) return;
current_music->pos = value * JA_freq;
}
float JA_GetMusicPosition()
{
if (!current_music) return 0;
return float(current_music->pos)/float(JA_freq);
}
void JA_EnableMusic(const bool value)
{
if (!value && current_music != NULL && current_music->state==JA_MUSIC_PLAYING) JA_StopMusic();
JA_musicEnabled = value;
}
JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length) {
JA_Sound_t *sound = new JA_Sound_t();
sound->buffer = buffer; sound->buffer = buffer;
sound->length = length; sound->length = length;
return sound; return sound;
} }
JA_Sound JA_LoadSound(const char* filename) { JA_Sound_t *JA_LoadSound(uint8_t* buffer, uint32_t size) {
JA_Sound sound = new JA_Sound_t(); JA_Sound_t *sound = new JA_Sound_t();
SDL_AudioSpec wavSpec;
SDL_LoadWAV_RW(SDL_RWFromMem(buffer, size),1, &wavSpec, &sound->buffer, &sound->length);
SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq);
cvt.len = sound->length;
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
SDL_memcpy(cvt.buf, sound->buffer, sound->length);
SDL_ConvertAudio(&cvt);
SDL_FreeWAV(sound->buffer);
sound->buffer = cvt.buf;
sound->length = cvt.len_cvt;
return sound;
}
JA_Sound_t *JA_LoadSound(const char* filename) {
JA_Sound_t *sound = new JA_Sound_t();
SDL_AudioSpec wavSpec; SDL_AudioSpec wavSpec;
SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length); SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length);
@@ -185,7 +304,10 @@ JA_Sound JA_LoadSound(const char* filename) {
return sound; return sound;
} }
int JA_PlaySound(JA_Sound sound, const int loop) { int JA_PlaySound(JA_Sound_t *sound, const int loop)
{
if (!JA_soundEnabled) return -1;
int channel = 0; int channel = 0;
while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; } while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; }
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0; if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0;
@@ -197,7 +319,21 @@ int JA_PlaySound(JA_Sound sound, const int loop) {
return channel; return channel;
} }
void JA_DeleteSound(JA_Sound sound) { int JA_PlaySoundOnChannel(JA_Sound_t *sound, const int channel, const int loop)
{
if (!JA_soundEnabled) return -1;
if (channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return -1;
channels[channel].sound = sound;
channels[channel].times = loop;
channels[channel].pos = 0;
channels[channel].state = JA_CHANNEL_PLAYING;
return channel;
}
void JA_DeleteSound(JA_Sound_t *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);
} }
@@ -205,7 +341,10 @@ void JA_DeleteSound(JA_Sound sound) {
delete sound; delete sound;
} }
void JA_PauseChannel(const int channel) { void JA_PauseChannel(const int channel)
{
if (!JA_soundEnabled) return;
if (channel == -1) { if (channel == -1) {
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) channels[i].state = JA_CHANNEL_PAUSED; if (channels[i].state == JA_CHANNEL_PLAYING) channels[i].state = JA_CHANNEL_PAUSED;
@@ -215,7 +354,10 @@ void JA_PauseChannel(const int channel) {
} }
} }
void JA_ResumeChannel(const int channel) { void JA_ResumeChannel(const int channel)
{
if (!JA_soundEnabled) return;
if (channel == -1) { if (channel == -1) {
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_PAUSED) channels[i].state = JA_CHANNEL_PLAYING; if (channels[i].state == JA_CHANNEL_PAUSED) channels[i].state = JA_CHANNEL_PLAYING;
@@ -225,7 +367,10 @@ void JA_ResumeChannel(const int channel) {
} }
} }
void JA_StopChannel(const int channel) { void JA_StopChannel(const int channel)
{
if (!JA_soundEnabled) return;
if (channel == -1) { if (channel == -1) {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
channels[i].state = JA_CHANNEL_FREE; channels[i].state = JA_CHANNEL_FREE;
@@ -239,18 +384,34 @@ void JA_StopChannel(const int channel) {
} }
} }
JA_Channel_state JA_GetChannelState(const int channel) { JA_Channel_state JA_GetChannelState(const int channel)
{
if (!JA_soundEnabled) return JA_SOUND_DISABLED;
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID; if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
return channels[channel].state; return channels[channel].state;
} }
int JA_SetChannelVolume(const int channel, int volume) { int JA_SetSoundVolume(int volume)
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID; {
channels[channel].volume = volume > 128 ? 128 : volume < 0 ? 0 : volume; JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
return channels[channel].volume; return JA_soundVolume;
} }
int JA_SetVolume(int volume) { void JA_EnableSound(const bool value)
JA_volume = volume > 128 ? 128 : volume < 0 ? 0 : volume; {
return JA_volume; for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
{
if (channels[i].state == JA_CHANNEL_PLAYING) JA_StopChannel(i);
}
JA_soundEnabled = value;
} }
int JA_SetVolume(int volume)
{
JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
JA_soundVolume = JA_musicVolume/2;
return JA_musicVolume;
}
#endif

View File

@@ -1,32 +1,40 @@
#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_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED, JA_SOUND_DISABLED };
enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED }; enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED, JA_MUSIC_DISABLED };
typedef struct JA_Sound_t *JA_Sound; struct JA_Sound_t;
typedef struct JA_Music_t *JA_Music; struct JA_Music_t;
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);
void JA_Quit(); void JA_Quit();
JA_Music JA_LoadMusic(const char* filename); JA_Music_t *JA_LoadMusic(const char* filename);
void JA_PlayMusic(JA_Music music, const int loop = -1); JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length);
void JA_PlayMusic(JA_Music_t *music, const int loop = -1);
void JA_PauseMusic(); void JA_PauseMusic();
void JA_ResumeMusic(); void JA_ResumeMusic();
void JA_StopMusic(); void JA_StopMusic();
int JA_SetVolume(int volume); void JA_FadeOutMusic(const int milliseconds);
JA_Music_state JA_GetMusicState(); JA_Music_state JA_GetMusicState();
void JA_DeleteMusic(JA_Music music); void JA_DeleteMusic(JA_Music_t *music);
int JA_SetMusicVolume(int volume);
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length); void JA_SetMusicPosition(float value);
JA_Sound JA_LoadSound(const char* filename); float JA_GetMusicPosition();
int JA_PlaySound(JA_Sound sound, const int loop = 0); void JA_EnableMusic(const bool value);
void JA_DeleteSound(JA_Sound sound);
JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length);
JA_Sound_t *JA_LoadSound(Uint8* buffer, Uint32 length);
JA_Sound_t *JA_LoadSound(const char* filename);
int JA_PlaySound(JA_Sound_t *sound, const int loop = 0);
int JA_PlaySoundOnChannel(JA_Sound_t *sound, const int channel, 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);
JA_Channel_state JA_GetChannelState(const int channel); JA_Channel_state JA_GetChannelState(const int channel);
int JA_SetChannelVolume(const int channel, int volume); void JA_DeleteSound(JA_Sound_t *sound);
int JA_SetSoundVolume(int volume);
void JA_EnableSound(const bool value);
int JA_SetVolume(int volume);

166
jail_audio_sdlmixer.cpp Normal file
View File

@@ -0,0 +1,166 @@
#ifdef JA_USESDLMIXER
#include "jail_audio.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
#include <stdio.h>
struct JA_Sound_t {}; // Dummy structs
struct JA_Music_t {};
int JA_freq {48000};
SDL_AudioFormat JA_format {AUDIO_S16};
Uint8 JA_channels {2};
int JA_musicVolume = 128;
int JA_soundVolume = 64;
bool JA_musicEnabled = true;
bool JA_soundEnabled = true;
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) {
JA_freq = freq;
JA_format = format;
JA_channels = channels;
Mix_OpenAudio(JA_freq, JA_format, JA_channels, 1024);
}
void JA_Quit() {
Mix_CloseAudio();
}
JA_Music_t *JA_LoadMusic(const char* filename) {
return (JA_Music_t*)Mix_LoadMUS(filename);
}
void JA_PlayMusic(JA_Music_t *music, const int loop)
{
if (!JA_musicEnabled) return;
Mix_PlayMusic((Mix_Music*)music, loop);
Mix_VolumeMusic(JA_musicVolume);
}
void JA_PauseMusic()
{
if (!JA_musicEnabled) return;
Mix_PauseMusic();
}
void JA_ResumeMusic()
{
if (!JA_musicEnabled) return;
Mix_ResumeMusic();
}
void JA_StopMusic()
{
if (!JA_musicEnabled) return;
Mix_HaltMusic();
}
JA_Music_state JA_GetMusicState()
{
if (!JA_musicEnabled) return JA_MUSIC_DISABLED;
if (Mix_PausedMusic()) {
return JA_MUSIC_PAUSED;
} else if (Mix_PlayingMusic()) {
return JA_MUSIC_PLAYING;
} else {
return JA_MUSIC_STOPPED;
}
}
void JA_DeleteMusic(JA_Music_t *music)
{
Mix_FreeMusic((Mix_Music*)music);
}
int JA_SetMusicVolume(int volume)
{
JA_musicVolume = volume;
Mix_VolumeMusic(JA_musicVolume);
return JA_musicVolume;
}
void JA_EnableMusic(const bool value)
{
if (Mix_PlayingMusic()) Mix_HaltMusic();
JA_musicEnabled = value;
}
JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length)
{
return NULL;
}
JA_Sound_t *JA_LoadSound(const char* filename) {
JA_Sound_t *sound = (JA_Sound_t*)Mix_LoadWAV(filename);
return sound;
}
int JA_PlaySound(JA_Sound_t *sound, const int loop) {
if (!JA_soundEnabled) return -1;
const int channel = Mix_PlayChannel(-1, (Mix_Chunk*)sound, loop);
Mix_Volume(-1, JA_soundVolume);
return channel;
}
void JA_DeleteSound(JA_Sound_t *sound)
{
Mix_FreeChunk((Mix_Chunk*)sound);
}
void JA_PauseChannel(const int channel)
{
if (!JA_soundEnabled) return;
Mix_Pause(channel);
}
void JA_ResumeChannel(const int channel)
{
if (!JA_soundEnabled) return;
Mix_Resume(channel);
}
void JA_StopChannel(const int channel)
{
if (!JA_soundEnabled) return;
Mix_HaltChannel(channel);
}
JA_Channel_state JA_GetChannelState(const int channel)
{
if (!JA_soundEnabled) return JA_SOUND_DISABLED;
if (Mix_Paused(channel)) {
return JA_CHANNEL_PAUSED;
} else if (Mix_Playing(channel)) {
return JA_CHANNEL_PLAYING;
} else {
return JA_CHANNEL_FREE;
}
}
int JA_SetSoundVolume(int volume)
{
JA_musicVolume = volume;
Mix_Volume(-1, JA_musicVolume);
return JA_musicVolume;
}
void JA_EnableSound(const bool value)
{
Mix_HaltChannel(-1);
JA_soundEnabled = value;
}
int JA_SetVolume(int volume)
{
JA_SetSoundVolume(volume);
return JA_SetMusicVolume(volume);
}
#endif

View File

@@ -12,11 +12,11 @@ int main(int argc, char **argv) {
sdlWindow = SDL_CreateWindow("JailAudio", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 320, 240, SDL_WINDOW_SHOWN); sdlWindow = SDL_CreateWindow("JailAudio", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 320, 240, SDL_WINDOW_SHOWN);
JA_Init(48000, AUDIO_S16, 2); JA_Init(48000, AUDIO_S16, 2);
JA_Music music = JA_LoadMusic("intro2.ogg"); JA_Music_t *music = JA_LoadMusic("intro2.ogg");
JA_Sound peiv = JA_LoadSound("menu_select.wav"); JA_Sound_t *peiv = JA_LoadSound("menu_select.wav");
int channel = -1; int channel = -1;
JA_PlayMusic(music, true); JA_PlayMusic(music, -1);
int volume = 128; int volume = 128;
bool should_exit = false; bool should_exit = false;
while(!should_exit) { while(!should_exit) {
@@ -42,6 +42,12 @@ int main(int argc, char **argv) {
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_7:
JA_PlayMusic(music, 0);
break;
case SDL_SCANCODE_0: // Si pulsem la tecla '1' pausem o despausem la música
JA_FadeOutMusic(1000);
break;
case SDL_SCANCODE_UP: case SDL_SCANCODE_UP:
volume = JA_SetVolume(volume+16); volume = JA_SetVolume(volume+16);
break; break;

View File

@@ -8,6 +8,9 @@ Inicialitza el subsistema de audio. Es pot especificar la _frequència_, _format
### `void JA_Quit();` ### `void JA_Quit();`
Tanquem la paraeta. Tanquem la paraeta.
### `int JA_SetVolume(int volume);`
Canvia el volum general. Es un valor entre 0 i 128. Per defecte està a 128. La música al 100%, el só al 50%.
## Música ## Música
### `JA_Music JA_LoadMusic(const char* filename);` ### `JA_Music JA_LoadMusic(const char* filename);`
@@ -25,7 +28,7 @@ Continúa la música per on shavia pausat.
### `void JA_StopMusic();` ### `void JA_StopMusic();`
Pos això... Pos això...
### `int JA_SetVolume(int volume);` ### `int JA_SetMusicVolume(int volume);`
Canvia el volum de la música. Es un valor entre 0 i 128. Per defecte està a 128. Canvia el volum de la música. Es un valor entre 0 i 128. Per defecte està a 128.
### `JA_Music_state JA_GetMusicState();` ### `JA_Music_state JA_GetMusicState();`
@@ -48,6 +51,9 @@ Fa sonar un só prèviament carregat. Se li pot dir que faça loop (`-1` fa loop
### `void JA_DeleteSound(JA_Sound sound);` ### `void JA_DeleteSound(JA_Sound sound);`
Esborra de la memòria un só prèviament carregat. Si el só estava sonant en eixe moment, pos el para, ningún problema. Esborra de la memòria un só prèviament carregat. Si el só estava sonant en eixe moment, pos el para, ningún problema.
### `int JA_SetSoundVolume(int volume);`
Especifica el volum dels efecte de só. Es un valor entre 0 i 128. Per defecte està a 64.
## Canals de só ## Canals de só
### `void JA_PauseChannel(const int channel);` ### `void JA_PauseChannel(const int channel);`
@@ -62,5 +68,3 @@ Para un canal i el deixa lliure. Si s'especifica `-1`, para tots els canals que
### `JA_Channel_state JA_GetChannelState(const int channel);` ### `JA_Channel_state JA_GetChannelState(const int channel);`
Torna el estat del canal especificat, que pot ser `JA_CHANNEL_INVALID`, `JA_CHANNEL_FREE`,`JA_CHANNEL_PLAYING` o `JA_CHANNEL_PAUSED`. Torna el estat del canal especificat, que pot ser `JA_CHANNEL_INVALID`, `JA_CHANNEL_FREE`,`JA_CHANNEL_PLAYING` o `JA_CHANNEL_PAUSED`.
### `int JA_SetChannelVolume(const int channel, int volume);`
Especifica el volum de un canal. Es un valor entre 0 i 128. Per defecte està a 64.