10 Commits
v1.1 ... v1.2

Author SHA1 Message Date
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
3ef6742c5d Add 'readme.md' 2022-11-24 15:51:49 +01:00
42986dd46a - Reorganització de la capçalera 2022-11-24 15:50:31 +01:00
cc7ef78d59 - [NEW] int JA_SetChannelVolume(const int channel, int volume) 2022-11-24 15:40:02 +01:00
6d8921b160 - Pa que se calle el compilaoooor en Linux 2022-11-09 13:56:32 +01:00
761119acf2 [FIX] JA_DeleteMusic() crashes, wrong free method 2022-10-07 17:44:23 +02:00
edf7484738 [FIX] SDL_AudioDeviceID is an Uint32, not a pointer 2022-10-07 17:33:43 +02:00
cb1154cb20 - JA_Init() now prevents bad multi-init
- [NEW] JA_Quit()
2022-10-07 17:28:20 +02:00
4 changed files with 120 additions and 21 deletions

View File

@@ -31,17 +31,19 @@ JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
int JA_freq {48000};
SDL_AudioFormat JA_format {AUDIO_S16};
Uint8 JA_channels {2};
int JA_volume = 128;
int JA_musicvolume = 128;
int JA_soundvolume = 64;
SDL_AudioDeviceID sdlAudioDevice = 0;
void audioCallback(void * userdata, uint8_t * stream, int len) {
SDL_memset(stream, 0, len);
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) {
const int size = SDL_min(len, current_music->samples*2-current_music->pos);
SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, JA_volume);
SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, JA_musicvolume);
current_music->pos += size/2;
if (size < len) {
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, JA_musicvolume);
current_music->pos = (len-size)/2;
if (current_music->times > 0) current_music->times--;
} else {
@@ -54,11 +56,11 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
if (channels[i].state == JA_CHANNEL_PLAYING) {
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, JA_volume/2);
SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_soundvolume);
channels[i].pos += size;
if (size < len) {
if (channels[i].times != 0) {
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, JA_volume/2);
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, JA_soundvolume);
channels[i].pos = len-size;
if (channels[i].times > 0) channels[i].times--;
} else {
@@ -74,13 +76,19 @@ void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) {
JA_format = format;
JA_channels = channels;
SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL};
SDL_AudioDeviceID sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice);
sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
SDL_PauseAudioDevice(sdlAudioDevice, 0);
}
void JA_Quit() {
SDL_PauseAudioDevice(sdlAudioDevice, 1);
if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice);
sdlAudioDevice = 0;
}
JA_Music JA_LoadMusic(const char* filename) {
int chan, samplerate;
JA_Music music = new JA_Music_t();
// [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");
@@ -88,8 +96,11 @@ JA_Music JA_LoadMusic(const char* filename) {
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
Uint8 *buffer = (Uint8*)malloc(fsize + 1);
fread(buffer, fsize, 1, f);
if (fread(buffer, fsize, 1, f)!=1) return NULL;
fclose(f);
JA_Music music = new JA_Music_t();
music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output);
free(buffer);
// [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert
@@ -97,13 +108,14 @@ JA_Music JA_LoadMusic(const char* filename) {
SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq);
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;
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;
@@ -144,7 +156,7 @@ JA_Music_state JA_GetMusicState() {
void JA_DeleteMusic(JA_Music music) {
if (current_music == music) current_music = NULL;
SDL_free(music->output);
free(music->output);
delete music;
}
@@ -232,7 +244,18 @@ JA_Channel_state JA_GetChannelState(const int channel) {
return channels[channel].state;
}
int JA_SetSoundVolume(int volume) {
JA_soundvolume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
return JA_soundvolume;
}
int JA_SetMusicVolume(int volume) {
JA_musicvolume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
return JA_musicvolume;
}
int JA_SetVolume(int volume) {
JA_volume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
return JA_volume;
}
JA_musicvolume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
JA_soundvolume = JA_musicvolume/2;
return JA_musicvolume;
}

View File

@@ -8,22 +8,26 @@ typedef struct JA_Sound_t *JA_Sound;
typedef struct JA_Music_t *JA_Music;
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels);
void JA_Quit();
JA_Music JA_LoadMusic(const char* filename);
void JA_PlayMusic(JA_Music music, const int loop = -1);
void JA_PauseMusic();
void JA_ResumeMusic();
void JA_StopMusic();
int JA_SetVolume(int volume);
int JA_SetMusicVolume(int volume);
JA_Music_state JA_GetMusicState();
void JA_DeleteMusic(JA_Music music);
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length);
JA_Sound JA_LoadSound(const char* filename);
int JA_PlaySound(JA_Sound sound, const int loop = 0);
void JA_DeleteSound(JA_Sound sound);
int JA_SetSoundVolume(int volume);
void JA_PauseChannel(const int channel);
void JA_ResumeChannel(const int channel);
void JA_StopChannel(const int channel);
JA_Channel_state JA_GetChannelState(const int channel);
void JA_DeleteSound(JA_Sound sound);
int JA_SetVolume(int volume);

View File

@@ -48,6 +48,8 @@ int main(int argc, char **argv) {
case SDL_SCANCODE_DOWN:
volume = JA_SetVolume(volume-16);
break;
default:
break;
}
}

70
readme.md Normal file
View File

@@ -0,0 +1,70 @@
# JailAudio v1.2
JailAudio es una xicoteta api per a reemplaçar lo basic de *SDL_mixer*. Amb ella es poden carregar cançons en format **OGG** o sons en format **WAV**. Per a usar-la nomes tindreu que incloure els arxius `jail_audio.cpp`, `jail_audio.h` i `stb_vorbis.c` al vostre projecte. El seu us es molt senzill i es pot vore un example a l'arxiu `main.cpp`.
## Inicialització
### `void JA_Init(const int freq, const SDL_AudioFormat format, const int channels);`
Inicialitza el subsistema de audio. Es pot especificar la _frequència_, _format_ i _canals_, de la mateixa forma que abans creaveu el `SDL_AudioDevice`.
### `void JA_Quit();`
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
### `JA_Music JA_LoadMusic(const char* filename);`
Carrega un arxiu **OGG** en memoria i el guarda a una variable de tipus `JA_Music`. Es un punter opac, així que nomes val pa usar-lo com a referència a l'hora de fer-lo sonar.
### `void JA_PlayMusic(JA_Music music, const int loop);`
Comença a tocar un **OGG**. Se li pot dir que faça loop (`-1` fa loop, `0` no fa loop (sona 1 vegada), `1` repeteix el so (sona 2 vegades), etc...). Si estava sonant altra musica, pos la para i a prendre per cul.
### `void JA_PauseMusic();`
Pausa la música.
### `void JA_ResumeMusic();`
Continúa la música per on shavia pausat.
### `void JA_StopMusic();`
Pos això...
### `int JA_SetMusicVolume(int volume);`
Canvia el volum de la música. Es un valor entre 0 i 128. Per defecte està a 128.
### `JA_Music_state JA_GetMusicState();`
Torna el estat de la música, que pot ser `JA_MUSIC_INVALID`, `JA_MUSIC_PLAYING`, `JA_MUSIC_PAUSED`o `JA_MUSIC_STOPPED`.
### `void JA_DeleteMusic(JA_Music music);`
Esborra de la memòria una cançò prèviament carregada. Si está sonant pos para de sonar, ningún problema.
## Efectes de só
### `JA_Sound JA_NewSound(Uint8* buffer, Uint32 length);`
Crea un nou só a partir d'un buffer en memòria.
### `JA_Sound JA_LoadSound(const char* filename);`
Carrega un àudio des d'un arxiu **WAV** i el guarda a una variable de tipus `JA_Sound`. Es un punter opac, així que nomes val pa usar-lo com a referència a l'hora de fer-lo sonar.
### `int JA_PlaySound(JA_Sound sound, const int loop);`
Fa sonar un só prèviament carregat. Se li pot dir que faça loop (`-1` fa loop, `0` no fa loop (sona 1 vegada), `1` repeteix el so (sona 2 vegades), etc...). Torna el número del canal en el que està sonant.
### `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.
### `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ó
### `void JA_PauseChannel(const int channel);`
Pausa el só que estiga sonant en el canal especificat. Si s'especifica `-1`, pausa tots els canals que estigueren sonant en eixe moment.
### `void JA_ResumeChannel(const int channel);`
Continua sonant el canal especificat, si es que estava pausat. Si s'especifica `-1`, fa que tots els canals que estigueren pausats es despausen i continuen.
### `void JA_StopChannel(const int channel);`
Para un canal i el deixa lliure. Si s'especifica `-1`, para tots els canals que estigueren sonant en eixe moment.
### `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`.