twn_audio: settle down on float32 2-channel sampling only, format enums to style used elsewhere
This commit is contained in:
parent
57fe5e8946
commit
a0ea657eb9
@ -16,7 +16,6 @@
|
|||||||
#define KEYBIND_SLOTS_DEFAULT 3
|
#define KEYBIND_SLOTS_DEFAULT 3
|
||||||
|
|
||||||
#define AUDIO_FREQUENCY 48000
|
#define AUDIO_FREQUENCY 48000
|
||||||
#define AUDIO_N_CHANNELS 2
|
|
||||||
|
|
||||||
#define TEXT_FONT_TEXTURE_SIZE_DEFAULT 2048
|
#define TEXT_FONT_TEXTURE_SIZE_DEFAULT 2048
|
||||||
#define TEXT_FONT_OVERSAMPLING_DEFAULT 4
|
#define TEXT_FONT_OVERSAMPLING_DEFAULT 4
|
||||||
|
@ -14,11 +14,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* TODO: default to float sampling format? */
|
static const char *audio_exts[AUDIO_FILE_TYPE_COUNT] = {
|
||||||
|
".ogg", /* AUDIO_FILE_TYPE_OGG */
|
||||||
static const char *audio_exts[audio_file_type_count] = {
|
".xm", /* AUDIO_FILE_TYPE_XM */
|
||||||
".ogg", /* audio_file_type_ogg */
|
|
||||||
".xm", /* audio_file_type_xm */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -68,7 +66,7 @@ void audio_play(const char *path, const char *channel) {
|
|||||||
static AudioFileType infer_audio_file_type(const char *path) {
|
static AudioFileType infer_audio_file_type(const char *path) {
|
||||||
size_t path_len = SDL_strlen(path);
|
size_t path_len = SDL_strlen(path);
|
||||||
|
|
||||||
for (int i = 0; i < audio_file_type_count; ++i) {
|
for (int i = 0; i < AUDIO_FILE_TYPE_COUNT; ++i) {
|
||||||
size_t ext_length = SDL_strlen(audio_exts[i]);
|
size_t ext_length = SDL_strlen(audio_exts[i]);
|
||||||
if (path_len <= ext_length)
|
if (path_len <= ext_length)
|
||||||
continue;
|
continue;
|
||||||
@ -77,7 +75,7 @@ static AudioFileType infer_audio_file_type(const char *path) {
|
|||||||
return (AudioFileType)i;
|
return (AudioFileType)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return audio_file_type_unknown;
|
return AUDIO_FILE_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -85,7 +83,7 @@ static AudioFileType infer_audio_file_type(const char *path) {
|
|||||||
/* or should we expect things to simply fail? */
|
/* or should we expect things to simply fail? */
|
||||||
static union AudioContext init_audio_context(const char *path, AudioFileType type) {
|
static union AudioContext init_audio_context(const char *path, AudioFileType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case audio_file_type_ogg: {
|
case AUDIO_FILE_TYPE_OGG: {
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int64_t len = get_audio_data(path, &data);
|
int64_t len = get_audio_data(path, &data);
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
@ -112,7 +110,7 @@ static union AudioContext init_audio_context(const char *path, AudioFileType typ
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case audio_file_type_xm: {
|
case AUDIO_FILE_TYPE_XM: {
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int64_t len = get_audio_data(path, &data);
|
int64_t len = get_audio_data(path, &data);
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
@ -148,12 +146,12 @@ static union AudioContext init_audio_context(const char *path, AudioFileType typ
|
|||||||
|
|
||||||
static void repeat_audio(AudioChannel *channel) {
|
static void repeat_audio(AudioChannel *channel) {
|
||||||
switch (channel->file_type) {
|
switch (channel->file_type) {
|
||||||
case audio_file_type_ogg: {
|
case AUDIO_FILE_TYPE_OGG: {
|
||||||
stb_vorbis_seek_start(channel->context.vorbis.handle);
|
stb_vorbis_seek_start(channel->context.vorbis.handle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case audio_file_type_xm: {
|
case AUDIO_FILE_TYPE_XM: {
|
||||||
xm_restart(channel->context.xm.handle);
|
xm_restart(channel->context.xm.handle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -209,30 +207,25 @@ PlayAudioArgs audio_get_default_args(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* this assumes int16_t based streams */
|
/* this assumes float based streams */
|
||||||
static void audio_mixin_streams(const AudioChannel *channel,
|
static void audio_mixin_streams(const AudioChannel *channel,
|
||||||
uint8_t *restrict a,
|
uint8_t *restrict a,
|
||||||
uint8_t *restrict b,
|
uint8_t *restrict b,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
int16_t *const sa = (int16_t *)a;
|
float *const sa = (float *)a;
|
||||||
int16_t *const sb = (int16_t *)b;
|
float *const sb = (float *)b;
|
||||||
|
|
||||||
const float left_panning = fminf(fabsf(channel->args.panning - 1.0f), 1.0f);
|
const float left_panning = fminf(fabsf(channel->args.panning - 1.0f), 1.0f);
|
||||||
const float right_panning = fminf(fabsf(channel->args.panning + 1.0f), 1.0f);
|
const float right_panning = fminf(fabsf(channel->args.panning + 1.0f), 1.0f);
|
||||||
|
|
||||||
#if AUDIO_N_CHANNELS == 2
|
|
||||||
|
|
||||||
for (size_t s = 0; s < frames; s += 2) {
|
for (size_t s = 0; s < frames; s += 2) {
|
||||||
/* left channel */
|
/* left channel */
|
||||||
sa[s] += (int16_t)(sb[s] * channel->args.volume * left_panning);
|
sa[s] += (float)(sb[s] * channel->args.volume * left_panning);
|
||||||
|
|
||||||
/* right channel */
|
/* right channel */
|
||||||
sa[s + 1] += (int16_t)(sb[s + 1] * channel->args.volume * right_panning);
|
sa[s + 1] += (float)(sb[s + 1] * channel->args.volume * right_panning);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#error "Unimplemented channel count"
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -242,21 +235,20 @@ static void audio_sample_and_mixin_channel(const AudioChannel *channel,
|
|||||||
int len)
|
int len)
|
||||||
{
|
{
|
||||||
static uint8_t buffer[16384];
|
static uint8_t buffer[16384];
|
||||||
const int int16_buffer_frames = sizeof (buffer) / sizeof (int16_t);
|
|
||||||
const int float_buffer_frames = sizeof (buffer) / sizeof (float);
|
const int float_buffer_frames = sizeof (buffer) / sizeof (float);
|
||||||
const int stream_frames = len / (int)(sizeof (int16_t));
|
const int stream_frames = len / (int)(sizeof (float));
|
||||||
|
|
||||||
switch (channel->file_type) {
|
switch (channel->file_type) {
|
||||||
case audio_file_type_ogg: {
|
case AUDIO_FILE_TYPE_OGG: {
|
||||||
/* feed stream for needed conversions */
|
/* feed stream for needed conversions */
|
||||||
for (int i = 0; i < stream_frames; ) {
|
for (int i = 0; i < stream_frames; ) {
|
||||||
const int n_frames = (stream_frames - i) > int16_buffer_frames ?
|
const int n_frames = (stream_frames - i) > float_buffer_frames ?
|
||||||
int16_buffer_frames : stream_frames - i;
|
float_buffer_frames : stream_frames - i;
|
||||||
|
|
||||||
const int samples_per_channel = stb_vorbis_get_samples_short_interleaved(
|
const int samples_per_channel = stb_vorbis_get_samples_float_interleaved(
|
||||||
channel->context.vorbis.handle,
|
channel->context.vorbis.handle,
|
||||||
channel->context.vorbis.channel_count,
|
channel->context.vorbis.channel_count,
|
||||||
(int16_t *)buffer,
|
(float *)buffer,
|
||||||
n_frames);
|
n_frames);
|
||||||
|
|
||||||
/* handle end of file */
|
/* handle end of file */
|
||||||
@ -272,7 +264,7 @@ static void audio_sample_and_mixin_channel(const AudioChannel *channel,
|
|||||||
|
|
||||||
/* panning and mixing */
|
/* panning and mixing */
|
||||||
audio_mixin_streams(channel,
|
audio_mixin_streams(channel,
|
||||||
&stream[i * sizeof(int16_t)], buffer,
|
&stream[i * sizeof(float)], buffer,
|
||||||
samples_per_channel * 2);
|
samples_per_channel * 2);
|
||||||
|
|
||||||
i += samples_per_channel * 2;
|
i += samples_per_channel * 2;
|
||||||
@ -281,7 +273,7 @@ static void audio_sample_and_mixin_channel(const AudioChannel *channel,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case audio_file_type_xm: {
|
case AUDIO_FILE_TYPE_XM: {
|
||||||
for (int i = 0; i < stream_frames; ) {
|
for (int i = 0; i < stream_frames; ) {
|
||||||
const int n_frames = (stream_frames - i) > float_buffer_frames ?
|
const int n_frames = (stream_frames - i) > float_buffer_frames ?
|
||||||
float_buffer_frames : stream_frames - i;
|
float_buffer_frames : stream_frames - i;
|
||||||
@ -301,13 +293,9 @@ static void audio_sample_and_mixin_channel(const AudioChannel *channel,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert floats to int16_t */
|
|
||||||
for (int p = 0; p < samples_per_channel * 2; ++p)
|
|
||||||
((int16_t *)buffer)[p] = (int16_t)(((float *)buffer)[p] * (float)INT16_MAX);
|
|
||||||
|
|
||||||
/* panning and mixing */
|
/* panning and mixing */
|
||||||
audio_mixin_streams(channel,
|
audio_mixin_streams(channel,
|
||||||
&stream[i * sizeof(int16_t)],
|
&stream[i * sizeof(float)],
|
||||||
buffer,
|
buffer,
|
||||||
samples_per_channel * 2);
|
samples_per_channel * 2);
|
||||||
|
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef enum AudioFileType {
|
typedef enum AudioFileType {
|
||||||
audio_file_type_ogg,
|
AUDIO_FILE_TYPE_OGG,
|
||||||
audio_file_type_xm,
|
AUDIO_FILE_TYPE_XM,
|
||||||
audio_file_type_count,
|
AUDIO_FILE_TYPE_COUNT,
|
||||||
audio_file_type_unknown,
|
AUDIO_FILE_TYPE_UNKNOWN,
|
||||||
} AudioFileType;
|
} AudioFileType;
|
||||||
|
|
||||||
|
|
||||||
|
@ -383,14 +383,16 @@ static bool initialize(void) {
|
|||||||
SDL_zero(request);
|
SDL_zero(request);
|
||||||
|
|
||||||
request.freq = AUDIO_FREQUENCY;
|
request.freq = AUDIO_FREQUENCY;
|
||||||
request.format = AUDIO_S16;
|
request.format = AUDIO_F32;
|
||||||
request.channels = AUDIO_N_CHANNELS;
|
request.channels = 2;
|
||||||
request.callback = audio_callback;
|
request.callback = audio_callback;
|
||||||
/* TODO: check for errors */
|
/* TODO: check for errors */
|
||||||
ctx.audio_device = SDL_OpenAudioDevice(NULL, 0, &request, &got, 0);
|
ctx.audio_device = SDL_OpenAudioDevice(NULL, 0, &request, &got, 0);
|
||||||
ctx.audio_stream_format = got.format;
|
ctx.audio_stream_format = got.format;
|
||||||
ctx.audio_stream_frequency = got.freq;
|
ctx.audio_stream_frequency = got.freq;
|
||||||
ctx.audio_stream_channel_count = got.channels;
|
ctx.audio_stream_channel_count = got.channels;
|
||||||
|
SDL_assert_always(got.format == AUDIO_F32);
|
||||||
|
SDL_assert_always(got.channels == 2);
|
||||||
|
|
||||||
SDL_PauseAudioDevice(ctx.audio_device, 0);
|
SDL_PauseAudioDevice(ctx.audio_device, 0);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user