Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4fc5b47dc9 | |||
| 1b7fdbd230 | |||
| f5ee23cea3 | |||
| 774aebf4a4 | |||
| b6b3bf452e | |||
| 1519725d4a | |||
| f0687f9f4d | |||
| cd2f18212b | |||
| c79150b24a | |||
| bf1925bb3a | |||
| 861bb5e7f9 | |||
| debd80f6af | |||
| 3ef6742c5d | |||
| 42986dd46a | |||
| cc7ef78d59 | |||
| 6d8921b160 | |||
| 761119acf2 | |||
| edf7484738 | |||
| cb1154cb20 | |||
| 975fcfd81a | |||
| 52df28a4f0 | |||
| 1ba349f6c3 | |||
| 1623654564 | |||
| 637c5c4677 | |||
| 852710d15d | |||
| f94d9294eb | |||
| a3527dcad3 |
298
jail_audio.cpp
298
jail_audio.cpp
@@ -1,6 +1,8 @@
|
||||
#ifndef JA_USESDLMIXER
|
||||
#include "jail_audio.h"
|
||||
#include "stb_vorbis.c"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define JA_MAX_SIMULTANEOUS_CHANNELS 5
|
||||
|
||||
@@ -9,42 +11,63 @@ struct JA_Sound_t {
|
||||
Uint8* buffer {NULL};
|
||||
};
|
||||
|
||||
enum JA_Channel_state { JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED };
|
||||
|
||||
struct JA_Channel_t {
|
||||
JA_Sound sound;
|
||||
JA_Sound_t *sound;
|
||||
int pos {0};
|
||||
int times {0};
|
||||
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 {
|
||||
int samples {0};
|
||||
Uint32 length {0};
|
||||
int pos {0};
|
||||
int times {0};
|
||||
short* output {NULL};
|
||||
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];
|
||||
|
||||
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;
|
||||
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) {
|
||||
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_memcpy(stream, current_music->output+current_music->pos, size);
|
||||
current_music->pos += size/2;
|
||||
int volume = JA_musicVolume;
|
||||
if (fading) {
|
||||
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 (current_music->times != 0) {
|
||||
SDL_memcpy(stream+size, current_music->output, len-size);
|
||||
current_music->pos = (len-size)/2;
|
||||
SDL_MixAudioFormat(stream+size, (Uint8*)current_music->output, AUDIO_S16, len-size, volume);
|
||||
current_music->pos = len-size;
|
||||
if (current_music->times > 0) current_music->times--;
|
||||
} else {
|
||||
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++) {
|
||||
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, 64);
|
||||
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, 64);
|
||||
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 {
|
||||
@@ -71,37 +94,85 @@ 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_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);
|
||||
if (sdlAudioDevice==0)
|
||||
{
|
||||
SDL_Log("FAILED!\n");
|
||||
SDL_Log("Failed to initialize SDL audio!\n");
|
||||
} else {
|
||||
SDL_Log("OK!\n");
|
||||
}
|
||||
SDL_PauseAudioDevice(sdlAudioDevice, 0);
|
||||
}
|
||||
|
||||
JA_Music JA_LoadMusic(const char* filename) {
|
||||
void JA_Quit() {
|
||||
SDL_PauseAudioDevice(sdlAudioDevice, 1);
|
||||
if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice);
|
||||
sdlAudioDevice = 0;
|
||||
}
|
||||
|
||||
JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length)
|
||||
{
|
||||
int chan, samplerate;
|
||||
JA_Music music = (JA_Music)SDL_malloc(sizeof(JA_Music_t));
|
||||
music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
|
||||
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);
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void JA_PlayMusic(JA_Music music, const int loop) {
|
||||
int chan, samplerate;
|
||||
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.
|
||||
FILE *f = fopen(filename, "rb");
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
Uint8 *buffer = (Uint8*)malloc(fsize + 1);
|
||||
if (fread(buffer, fsize, 1, f)!=1) return NULL;
|
||||
fclose(f);
|
||||
|
||||
JA_Music_t *music = JA_LoadMusic(buffer, fsize);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return music;
|
||||
}
|
||||
|
||||
void JA_PlayMusic(JA_Music_t *music, const int loop)
|
||||
{
|
||||
if (!JA_musicEnabled) return;
|
||||
|
||||
if (current_music != NULL) {
|
||||
current_music->pos = 0;
|
||||
current_music->state = JA_MUSIC_STOPPED;
|
||||
@@ -112,34 +183,111 @@ void JA_PlayMusic(JA_Music music, const int loop) {
|
||||
current_music->times = loop;
|
||||
}
|
||||
|
||||
void JA_PauseMusic() {
|
||||
if (current_music->state == JA_MUSIC_INVALID) return;
|
||||
void JA_PauseMusic()
|
||||
{
|
||||
if (!JA_musicEnabled) return;
|
||||
|
||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
|
||||
current_music->state = JA_MUSIC_PAUSED;
|
||||
}
|
||||
|
||||
void JA_ResumeMusic() {
|
||||
if (current_music->state == JA_MUSIC_INVALID) return;
|
||||
void JA_ResumeMusic()
|
||||
{
|
||||
if (!JA_musicEnabled) return;
|
||||
|
||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
|
||||
current_music->state = JA_MUSIC_PLAYING;
|
||||
}
|
||||
|
||||
void JA_StopMusic() {
|
||||
if (current_music->state == JA_MUSIC_INVALID) return;
|
||||
void JA_StopMusic()
|
||||
{
|
||||
if (!JA_musicEnabled) return;
|
||||
|
||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
|
||||
current_music->pos = 0;
|
||||
current_music->state = JA_MUSIC_STOPPED;
|
||||
}
|
||||
|
||||
bool JA_IsMusicPlaying() {
|
||||
return current_music->state == JA_MUSIC_PLAYING;
|
||||
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;
|
||||
}
|
||||
|
||||
void JA_DeleteMusic(JA_Music music) {
|
||||
JA_Music_state JA_GetMusicState() {
|
||||
if (!JA_musicEnabled) return JA_MUSIC_DISABLED;
|
||||
|
||||
if (current_music == NULL) return JA_MUSIC_INVALID;
|
||||
return current_music->state;
|
||||
}
|
||||
|
||||
void JA_DeleteMusic(JA_Music_t *music) {
|
||||
if (current_music == music) current_music = NULL;
|
||||
free(music->output);
|
||||
free(music);
|
||||
delete music;
|
||||
}
|
||||
|
||||
JA_Sound JA_LoadSound(const char* filename) {
|
||||
JA_Sound sound = new JA_Sound_t();
|
||||
int JA_SetMusicVolume(int volume)
|
||||
{
|
||||
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->length = length;
|
||||
return sound;
|
||||
}
|
||||
|
||||
JA_Sound_t *JA_LoadSound(uint8_t* buffer, uint32_t size) {
|
||||
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_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length);
|
||||
|
||||
@@ -149,14 +297,17 @@ JA_Sound JA_LoadSound(const char* filename) {
|
||||
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
|
||||
SDL_memcpy(cvt.buf, sound->buffer, sound->length);
|
||||
SDL_ConvertAudio(&cvt);
|
||||
free(sound->buffer);
|
||||
SDL_FreeWAV(sound->buffer);
|
||||
sound->buffer = cvt.buf;
|
||||
sound->length = cvt.len_cvt;
|
||||
|
||||
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;
|
||||
while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; }
|
||||
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0;
|
||||
@@ -168,15 +319,32 @@ int JA_PlaySound(JA_Sound sound, const int loop) {
|
||||
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++) {
|
||||
if (channels[i].sound == sound) JA_StopChannel(i);
|
||||
}
|
||||
SDL_FreeWAV(sound->buffer);
|
||||
SDL_free(sound->buffer);
|
||||
delete sound;
|
||||
}
|
||||
|
||||
void JA_PauseChannel(const int channel) {
|
||||
void JA_PauseChannel(const int channel)
|
||||
{
|
||||
if (!JA_soundEnabled) return;
|
||||
|
||||
if (channel == -1) {
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channels[i].state == JA_CHANNEL_PLAYING) channels[i].state = JA_CHANNEL_PAUSED;
|
||||
@@ -186,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) {
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channels[i].state == JA_CHANNEL_PAUSED) channels[i].state = JA_CHANNEL_PLAYING;
|
||||
@@ -196,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) {
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
channels[i].state = JA_CHANNEL_FREE;
|
||||
@@ -210,8 +384,34 @@ void JA_StopChannel(const int channel) {
|
||||
}
|
||||
}
|
||||
|
||||
bool JA_IsChannelPlaying(const int channel) {
|
||||
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return false;
|
||||
return channels[channel].state == JA_CHANNEL_PLAYING;
|
||||
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;
|
||||
return channels[channel].state;
|
||||
}
|
||||
|
||||
int JA_SetSoundVolume(int volume)
|
||||
{
|
||||
JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
|
||||
return JA_soundVolume;
|
||||
}
|
||||
|
||||
void JA_EnableSound(const bool value)
|
||||
{
|
||||
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
|
||||
37
jail_audio.h
37
jail_audio.h
@@ -1,23 +1,40 @@
|
||||
#pragma once
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
typedef struct JA_Sound_t *JA_Sound;
|
||||
typedef struct JA_Music_t *JA_Music;
|
||||
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, JA_MUSIC_DISABLED };
|
||||
|
||||
struct JA_Sound_t;
|
||||
struct JA_Music_t;
|
||||
|
||||
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);
|
||||
JA_Music_t *JA_LoadMusic(const char* filename);
|
||||
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_ResumeMusic();
|
||||
void JA_StopMusic();
|
||||
bool JA_IsMusicPlaying();
|
||||
void JA_DeleteMusic(JA_Music music);
|
||||
void JA_FadeOutMusic(const int milliseconds);
|
||||
JA_Music_state JA_GetMusicState();
|
||||
void JA_DeleteMusic(JA_Music_t *music);
|
||||
int JA_SetMusicVolume(int volume);
|
||||
void JA_SetMusicPosition(float value);
|
||||
float JA_GetMusicPosition();
|
||||
void JA_EnableMusic(const bool value);
|
||||
|
||||
JA_Sound JA_LoadSound(const char* filename);
|
||||
int JA_PlaySound(JA_Sound sound, const int loop = 0);
|
||||
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_ResumeChannel(const int channel);
|
||||
void JA_StopChannel(const int channel);
|
||||
bool JA_IsChannelPlaying(const int channel);
|
||||
void JA_DeleteSound(JA_Sound sound);
|
||||
JA_Channel_state JA_GetChannelState(const int channel);
|
||||
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
166
jail_audio_sdlmixer.cpp
Normal 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
|
||||
27
main.cpp
27
main.cpp
@@ -1,6 +1,7 @@
|
||||
#include "jail_audio.h"
|
||||
#include <stdlib.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stdio.h>
|
||||
|
||||
SDL_Event event;
|
||||
SDL_Window *sdlWindow;
|
||||
@@ -11,12 +12,12 @@ int main(int argc, char **argv) {
|
||||
sdlWindow = SDL_CreateWindow("JailAudio", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 320, 240, SDL_WINDOW_SHOWN);
|
||||
JA_Init(48000, AUDIO_S16, 2);
|
||||
|
||||
JA_Music music = JA_LoadMusic("intro2.ogg");
|
||||
JA_Sound peiv = JA_LoadSound("menu_select.wav");
|
||||
JA_Music_t *music = JA_LoadMusic("intro2.ogg");
|
||||
JA_Sound_t *peiv = JA_LoadSound("menu_select.wav");
|
||||
int channel = -1;
|
||||
|
||||
JA_PlayMusic(music, true);
|
||||
|
||||
JA_PlayMusic(music, -1);
|
||||
int volume = 128;
|
||||
bool should_exit = false;
|
||||
while(!should_exit) {
|
||||
while(SDL_PollEvent(&event)) {
|
||||
@@ -24,7 +25,7 @@ int main(int argc, char **argv) {
|
||||
if (event.type == SDL_KEYDOWN) {
|
||||
switch (event.key.keysym.scancode) {
|
||||
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;
|
||||
case SDL_SCANCODE_2: // Si pulsem la tecla '2' sona el wav 1 vegada
|
||||
JA_PlaySound(peiv);
|
||||
@@ -36,11 +37,25 @@ int main(int argc, char **argv) {
|
||||
channel = JA_PlaySound(peiv, -1);
|
||||
break;
|
||||
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;
|
||||
case SDL_SCANCODE_6: // Si pulsem la tecla '6' stopem definitivament el wav infinit
|
||||
JA_StopChannel(channel);
|
||||
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:
|
||||
volume = JA_SetVolume(volume+16);
|
||||
break;
|
||||
case SDL_SCANCODE_DOWN:
|
||||
volume = JA_SetVolume(volume-16);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
70
readme.md
Normal file
70
readme.md
Normal 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 s’havia 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`.
|
||||
|
||||
117
stb_vorbis.c
117
stb_vorbis.c
@@ -1,4 +1,4 @@
|
||||
// Ogg Vorbis audio decoder - v1.20 - public domain
|
||||
// Ogg Vorbis audio decoder - v1.22 - public domain
|
||||
// http://nothings.org/stb_vorbis/
|
||||
//
|
||||
// Original version written by Sean Barrett in 2007.
|
||||
@@ -29,12 +29,15 @@
|
||||
// Bernhard Wodo Evan Balster github:alxprd
|
||||
// Tom Beaumont Ingo Leitgeb Nicolas Guillemot
|
||||
// Phillip Bennefall Rohit Thiago Goulart
|
||||
// github:manxorist saga musix github:infatum
|
||||
// github:manxorist Saga Musix github:infatum
|
||||
// Timur Gagiev Maxwell Koo Peter Waller
|
||||
// github:audinowho Dougall Johnson David Reid
|
||||
// github:Clownacy Pedro J. Estebanez Remi Verschelde
|
||||
// AnthoFoxo github:morlat Gabriel Ravier
|
||||
//
|
||||
// Partial history:
|
||||
// 1.22 - 2021-07-11 - various small fixes
|
||||
// 1.21 - 2021-07-02 - fix bug for files with no comments
|
||||
// 1.20 - 2020-07-11 - several small fixes
|
||||
// 1.19 - 2020-02-05 - warnings
|
||||
// 1.18 - 2020-02-02 - fix seek bugs; parse header comments; misc warnings etc.
|
||||
@@ -220,6 +223,12 @@ extern int stb_vorbis_decode_frame_pushdata(
|
||||
// channel. In other words, (*output)[0][0] contains the first sample from
|
||||
// the first channel, and (*output)[1][0] contains the first sample from
|
||||
// the second channel.
|
||||
//
|
||||
// *output points into stb_vorbis's internal output buffer storage; these
|
||||
// buffers are owned by stb_vorbis and application code should not free
|
||||
// them or modify their contents. They are transient and will be overwritten
|
||||
// once you ask for more data to get decoded, so be sure to grab any data
|
||||
// you need before then.
|
||||
|
||||
extern void stb_vorbis_flush_pushdata(stb_vorbis *f);
|
||||
// inform stb_vorbis that your next datablock will not be contiguous with
|
||||
@@ -579,7 +588,7 @@ enum STBVorbisError
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__) || defined(__NEWLIB__)
|
||||
#if defined(__linux__) || defined(__linux) || defined(__sun__) || defined(__EMSCRIPTEN__) || defined(__NEWLIB__)
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#else // STB_VORBIS_NO_CRT
|
||||
@@ -646,6 +655,12 @@ typedef signed int int32;
|
||||
|
||||
typedef float codetype;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STBV_NOTUSED(v) (void)(v)
|
||||
#else
|
||||
#define STBV_NOTUSED(v) (void)sizeof(v)
|
||||
#endif
|
||||
|
||||
// @NOTE
|
||||
//
|
||||
// Some arrays below are tagged "//varies", which means it's actually
|
||||
@@ -1046,7 +1061,7 @@ static float float32_unpack(uint32 x)
|
||||
uint32 sign = x & 0x80000000;
|
||||
uint32 exp = (x & 0x7fe00000) >> 21;
|
||||
double res = sign ? -(double)mantissa : (double)mantissa;
|
||||
return (float) ldexp((float)res, exp-788);
|
||||
return (float) ldexp((float)res, (int)exp-788);
|
||||
}
|
||||
|
||||
|
||||
@@ -1077,6 +1092,7 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values)
|
||||
// find the first entry
|
||||
for (k=0; k < n; ++k) if (len[k] < NO_CODE) break;
|
||||
if (k == n) { assert(c->sorted_entries == 0); return TRUE; }
|
||||
assert(len[k] < 32); // no error return required, code reading lens checks this
|
||||
// add to the list
|
||||
add_entry(c, 0, k, m++, len[k], values);
|
||||
// add all available leaves
|
||||
@@ -1090,6 +1106,7 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values)
|
||||
uint32 res;
|
||||
int z = len[i], y;
|
||||
if (z == NO_CODE) continue;
|
||||
assert(z < 32); // no error return required, code reading lens checks this
|
||||
// find lowest available leaf (should always be earliest,
|
||||
// which is what the specification calls for)
|
||||
// note that this property, and the fact we can never have
|
||||
@@ -1099,12 +1116,10 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values)
|
||||
while (z > 0 && !available[z]) --z;
|
||||
if (z == 0) { return FALSE; }
|
||||
res = available[z];
|
||||
assert(z >= 0 && z < 32);
|
||||
available[z] = 0;
|
||||
add_entry(c, bit_reverse(res), i, m++, len[i], values);
|
||||
// propagate availability up the tree
|
||||
if (z != len[i]) {
|
||||
assert(len[i] >= 0 && len[i] < 32);
|
||||
for (y=len[i]; y > z; --y) {
|
||||
assert(available[y] == 0);
|
||||
available[y] = res + (1 << (32-y));
|
||||
@@ -2577,34 +2592,33 @@ static void imdct_step3_inner_s_loop_ld654(int n, float *e, int i_off, float *A,
|
||||
|
||||
while (z > base) {
|
||||
float k00,k11;
|
||||
float l00,l11;
|
||||
|
||||
k00 = z[-0] - z[-8];
|
||||
k11 = z[-1] - z[-9];
|
||||
z[-0] = z[-0] + z[-8];
|
||||
z[-1] = z[-1] + z[-9];
|
||||
z[-8] = k00;
|
||||
z[-9] = k11 ;
|
||||
k00 = z[-0] - z[ -8];
|
||||
k11 = z[-1] - z[ -9];
|
||||
l00 = z[-2] - z[-10];
|
||||
l11 = z[-3] - z[-11];
|
||||
z[ -0] = z[-0] + z[ -8];
|
||||
z[ -1] = z[-1] + z[ -9];
|
||||
z[ -2] = z[-2] + z[-10];
|
||||
z[ -3] = z[-3] + z[-11];
|
||||
z[ -8] = k00;
|
||||
z[ -9] = k11;
|
||||
z[-10] = (l00+l11) * A2;
|
||||
z[-11] = (l11-l00) * A2;
|
||||
|
||||
k00 = z[ -2] - z[-10];
|
||||
k11 = z[ -3] - z[-11];
|
||||
z[ -2] = z[ -2] + z[-10];
|
||||
z[ -3] = z[ -3] + z[-11];
|
||||
z[-10] = (k00+k11) * A2;
|
||||
z[-11] = (k11-k00) * A2;
|
||||
|
||||
k00 = z[-12] - z[ -4]; // reverse to avoid a unary negation
|
||||
k00 = z[ -4] - z[-12];
|
||||
k11 = z[ -5] - z[-13];
|
||||
l00 = z[ -6] - z[-14];
|
||||
l11 = z[ -7] - z[-15];
|
||||
z[ -4] = z[ -4] + z[-12];
|
||||
z[ -5] = z[ -5] + z[-13];
|
||||
z[-12] = k11;
|
||||
z[-13] = k00;
|
||||
|
||||
k00 = z[-14] - z[ -6]; // reverse to avoid a unary negation
|
||||
k11 = z[ -7] - z[-15];
|
||||
z[ -6] = z[ -6] + z[-14];
|
||||
z[ -7] = z[ -7] + z[-15];
|
||||
z[-14] = (k00+k11) * A2;
|
||||
z[-15] = (k00-k11) * A2;
|
||||
z[-12] = k11;
|
||||
z[-13] = -k00;
|
||||
z[-14] = (l11-l00) * A2;
|
||||
z[-15] = (l00+l11) * -A2;
|
||||
|
||||
iter_54(z);
|
||||
iter_54(z-8);
|
||||
@@ -3069,6 +3083,7 @@ static int do_floor(vorb *f, Mapping *map, int i, int n, float *target, YTYPE *f
|
||||
for (q=1; q < g->values; ++q) {
|
||||
j = g->sorted_order[q];
|
||||
#ifndef STB_VORBIS_NO_DEFER_FLOOR
|
||||
STBV_NOTUSED(step2_flag);
|
||||
if (finalY[j] >= 0)
|
||||
#else
|
||||
if (step2_flag[j])
|
||||
@@ -3171,6 +3186,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
|
||||
|
||||
// WINDOWING
|
||||
|
||||
STBV_NOTUSED(left_end);
|
||||
n = f->blocksize[m->blockflag];
|
||||
map = &f->mapping[m->mapping];
|
||||
|
||||
@@ -3368,7 +3384,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
|
||||
// this isn't to spec, but spec would require us to read ahead
|
||||
// and decode the size of all current frames--could be done,
|
||||
// but presumably it's not a commonly used feature
|
||||
f->current_loc = -n2; // start of first frame is positioned for discard
|
||||
f->current_loc = 0u - n2; // start of first frame is positioned for discard (NB this is an intentional unsigned overflow/wrap-around)
|
||||
// we might have to discard samples "from" the next frame too,
|
||||
// if we're lapping a large block then a small at the start?
|
||||
f->discard_samples_deferred = n - right_end;
|
||||
@@ -3642,9 +3658,11 @@ static int start_decoder(vorb *f)
|
||||
f->vendor[len] = (char)'\0';
|
||||
//user comments
|
||||
f->comment_list_length = get32_packet(f);
|
||||
if (f->comment_list_length > 0) {
|
||||
f->comment_list = (char**)setup_malloc(f, sizeof(char*) * (f->comment_list_length));
|
||||
if (f->comment_list == NULL) return error(f, VORBIS_outofmem);
|
||||
f->comment_list = NULL;
|
||||
if (f->comment_list_length > 0)
|
||||
{
|
||||
f->comment_list = (char**) setup_malloc(f, sizeof(char*) * (f->comment_list_length));
|
||||
if (f->comment_list == NULL) return error(f, VORBIS_outofmem);
|
||||
}
|
||||
|
||||
for(i=0; i < f->comment_list_length; ++i) {
|
||||
@@ -3867,8 +3885,7 @@ static int start_decoder(vorb *f)
|
||||
unsigned int div=1;
|
||||
for (k=0; k < c->dimensions; ++k) {
|
||||
int off = (z / div) % c->lookup_values;
|
||||
float val = mults[off];
|
||||
val = mults[off]*c->delta_value + c->minimum_value + last;
|
||||
float val = mults[off]*c->delta_value + c->minimum_value + last;
|
||||
c->multiplicands[j*c->dimensions + k] = val;
|
||||
if (c->sequence_p)
|
||||
last = val;
|
||||
@@ -3951,7 +3968,7 @@ static int start_decoder(vorb *f)
|
||||
if (g->class_masterbooks[j] >= f->codebook_count) return error(f, VORBIS_invalid_setup);
|
||||
}
|
||||
for (k=0; k < 1 << g->class_subclasses[j]; ++k) {
|
||||
g->subclass_books[j][k] = get_bits(f,8)-1;
|
||||
g->subclass_books[j][k] = (int16)get_bits(f,8)-1;
|
||||
if (g->subclass_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup);
|
||||
}
|
||||
}
|
||||
@@ -4509,6 +4526,7 @@ stb_vorbis *stb_vorbis_open_pushdata(
|
||||
*error = VORBIS_need_more_data;
|
||||
else
|
||||
*error = p.error;
|
||||
vorbis_deinit(&p);
|
||||
return NULL;
|
||||
}
|
||||
f = vorbis_alloc(&p);
|
||||
@@ -4566,7 +4584,7 @@ static uint32 vorbis_find_page(stb_vorbis *f, uint32 *end, uint32 *last)
|
||||
header[i] = get8(f);
|
||||
if (f->eof) return 0;
|
||||
if (header[4] != 0) goto invalid;
|
||||
goal = header[22] + (header[23] << 8) + (header[24]<<16) + (header[25]<<24);
|
||||
goal = header[22] + (header[23] << 8) + (header[24]<<16) + ((uint32)header[25]<<24);
|
||||
for (i=22; i < 26; ++i)
|
||||
header[i] = 0;
|
||||
crc = 0;
|
||||
@@ -4970,7 +4988,7 @@ unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f)
|
||||
// set. whoops!
|
||||
break;
|
||||
}
|
||||
previous_safe = last_page_loc+1;
|
||||
//previous_safe = last_page_loc+1; // NOTE: not used after this point, but note for debugging
|
||||
last_page_loc = stb_vorbis_get_file_offset(f);
|
||||
}
|
||||
|
||||
@@ -5081,7 +5099,10 @@ stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const st
|
||||
stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *error, const stb_vorbis_alloc *alloc)
|
||||
{
|
||||
stb_vorbis *f, p;
|
||||
if (data == NULL) return NULL;
|
||||
if (!data) {
|
||||
if (error) *error = VORBIS_unexpected_eof;
|
||||
return NULL;
|
||||
}
|
||||
vorbis_init(&p, alloc);
|
||||
p.stream = (uint8 *) data;
|
||||
p.stream_end = (uint8 *) data + len;
|
||||
@@ -5156,11 +5177,11 @@ static void copy_samples(short *dest, float *src, int len)
|
||||
|
||||
static void compute_samples(int mask, short *output, int num_c, float **data, int d_offset, int len)
|
||||
{
|
||||
#define BUFFER_SIZE 32
|
||||
float buffer[BUFFER_SIZE];
|
||||
int i,j,o,n = BUFFER_SIZE;
|
||||
#define STB_BUFFER_SIZE 32
|
||||
float buffer[STB_BUFFER_SIZE];
|
||||
int i,j,o,n = STB_BUFFER_SIZE;
|
||||
check_endianness();
|
||||
for (o = 0; o < len; o += BUFFER_SIZE) {
|
||||
for (o = 0; o < len; o += STB_BUFFER_SIZE) {
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
if (o + n > len) n = len - o;
|
||||
for (j=0; j < num_c; ++j) {
|
||||
@@ -5177,16 +5198,17 @@ static void compute_samples(int mask, short *output, int num_c, float **data, in
|
||||
output[o+i] = v;
|
||||
}
|
||||
}
|
||||
#undef STB_BUFFER_SIZE
|
||||
}
|
||||
|
||||
static void compute_stereo_samples(short *output, int num_c, float **data, int d_offset, int len)
|
||||
{
|
||||
#define BUFFER_SIZE 32
|
||||
float buffer[BUFFER_SIZE];
|
||||
int i,j,o,n = BUFFER_SIZE >> 1;
|
||||
#define STB_BUFFER_SIZE 32
|
||||
float buffer[STB_BUFFER_SIZE];
|
||||
int i,j,o,n = STB_BUFFER_SIZE >> 1;
|
||||
// o is the offset in the source data
|
||||
check_endianness();
|
||||
for (o = 0; o < len; o += BUFFER_SIZE >> 1) {
|
||||
for (o = 0; o < len; o += STB_BUFFER_SIZE >> 1) {
|
||||
// o2 is the offset in the output data
|
||||
int o2 = o << 1;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
@@ -5216,6 +5238,7 @@ static void compute_stereo_samples(short *output, int num_c, float **data, int d
|
||||
output[o2+i] = v;
|
||||
}
|
||||
}
|
||||
#undef STB_BUFFER_SIZE
|
||||
}
|
||||
|
||||
static void convert_samples_short(int buf_c, short **buffer, int b_offset, int data_c, float **data, int d_offset, int samples)
|
||||
@@ -5288,8 +5311,6 @@ int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short
|
||||
float **outputs;
|
||||
int len = num_shorts / channels;
|
||||
int n=0;
|
||||
int z = f->channels;
|
||||
if (z > channels) z = channels;
|
||||
while (n < len) {
|
||||
int k = f->channel_buffer_end - f->channel_buffer_start;
|
||||
if (n+k >= len) k = len - n;
|
||||
@@ -5308,8 +5329,6 @@ int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, in
|
||||
{
|
||||
float **outputs;
|
||||
int n=0;
|
||||
int z = f->channels;
|
||||
if (z > channels) z = channels;
|
||||
while (n < len) {
|
||||
int k = f->channel_buffer_end - f->channel_buffer_start;
|
||||
if (n+k >= len) k = len - n;
|
||||
|
||||
Reference in New Issue
Block a user