mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-12 01:30:49 +01:00
cleanup: float stuff
This commit is contained in:
parent
aec9e9a723
commit
28c6d64693
@ -59,12 +59,25 @@ static void update_position(libvgmstream_priv_t* priv) {
|
||||
pos->current = 0;
|
||||
}
|
||||
|
||||
static int get_sample_size(libvgmstream_sample_t sample_type) {
|
||||
switch(sample_type) {
|
||||
case LIBVGMSTREAM_SAMPLE_PCM24:
|
||||
case LIBVGMSTREAM_SAMPLE_PCM32:
|
||||
case LIBVGMSTREAM_SAMPLE_FLOAT:
|
||||
return 0x04;
|
||||
case LIBVGMSTREAM_SAMPLE_PCM16:
|
||||
default:
|
||||
return 0x02;
|
||||
}
|
||||
}
|
||||
|
||||
static void update_format_info(libvgmstream_priv_t* priv) {
|
||||
libvgmstream_format_t* fmt = &priv->fmt;
|
||||
VGMSTREAM* v = priv->vgmstream;
|
||||
|
||||
fmt->sample_size = 0x02;
|
||||
fmt->sample_type = LIBVGMSTREAM_SAMPLE_PCM16;
|
||||
//fmt->sample_type = LIBVGMSTREAM_SAMPLE_FLOAT;
|
||||
fmt->sample_size = get_sample_size(fmt->sample_type);
|
||||
fmt->sample_rate = v->sample_rate;
|
||||
|
||||
fmt->subsong_index = v->stream_index;
|
||||
|
@ -24,9 +24,13 @@ static bool reset_buf(libvgmstream_priv_t* priv) {
|
||||
priv->buf.input_channels = priv->buf.output_channels;
|
||||
|
||||
priv->buf.sample_size = sizeof(sample_t);
|
||||
//priv->buf.sample_size = sizeof(float);
|
||||
priv->buf.max_samples = INTERNAL_BUF_SAMPLES;
|
||||
priv->buf.max_bytes = priv->buf.max_samples * priv->buf.sample_size * priv->buf.input_channels;
|
||||
priv->buf.data = malloc(priv->buf.max_bytes);
|
||||
|
||||
int max_sample_size = sizeof(sample_t);
|
||||
//int max_sample_size = sizeof(float);
|
||||
int max_bytes = priv->buf.max_samples * max_sample_size * priv->buf.input_channels;
|
||||
priv->buf.data = malloc(max_bytes);
|
||||
if (!priv->buf.data) return false;
|
||||
|
||||
priv->buf.initialized = true;
|
||||
|
@ -25,7 +25,6 @@ typedef struct {
|
||||
/* config */
|
||||
int input_channels;
|
||||
int output_channels;
|
||||
int max_bytes;
|
||||
int max_samples;
|
||||
int sample_size;
|
||||
|
||||
|
@ -86,9 +86,8 @@ void mixer_process(mixer_t* mixer, sbuf_t* sbuf, int32_t current_pos) {
|
||||
mixer->current_subpos = current_pos;
|
||||
}
|
||||
|
||||
// upgrade buf for mixing (somehow using float buf rather than int32 is faster?)
|
||||
// remix to temp buf for mixing (somehow using float buf rather than int32 is faster?)
|
||||
sbuf_copy_to_f32(mixer->mixbuf, sbuf);
|
||||
//sbuf_copy_s16_to_f32(mixer->mixbuf, outbuf, sample_count, mixer->input_channels);
|
||||
|
||||
// apply mixing ops in order. current_channels may increase or decrease per op
|
||||
// - 2ch w/ "1+2,1u" = ch1+ch2, ch1(add and push rest) = 3ch: ch1' ch1+ch2 ch2
|
||||
@ -112,8 +111,9 @@ void mixer_process(mixer_t* mixer, sbuf_t* sbuf, int32_t current_pos) {
|
||||
}
|
||||
}
|
||||
|
||||
// downgrade mix to original output (with new channels)
|
||||
sbuf->channels = mixer->output_channels;
|
||||
// setup + remix to output buf (buf is expected to be big enough to handle config)
|
||||
sbuf->channels = mixer->output_channels; // new channels
|
||||
//if (force_float) sbuf->fmt = SFMT_FLT; // new format
|
||||
//if (force_pcm16) sbuf->fmt = SFMT_PCM16; // new format
|
||||
sbuf_copy_from_f32(sbuf, mixer->mixbuf);
|
||||
//sbuf_copy_f32_to_s16(outbuf, mixer->mixbuf, sbuf->filled, mixer->output_channels);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <math.h>
|
||||
#include "../util.h"
|
||||
#include "sbuf.h"
|
||||
|
||||
@ -20,29 +21,6 @@ void sbuf_init_f32(sbuf_t* sbuf, float* buf, int samples, int channels) {
|
||||
sbuf->fmt = SFMT_F32;
|
||||
}
|
||||
|
||||
//TODO decide if using float 1.0 style or 32767 style (fuzzy PCM when doing that)
|
||||
//TODO: maybe use macro-style templating (but kinda ugly)
|
||||
void sbuf_copy_to_f32(float* dst, sbuf_t* sbuf) {
|
||||
|
||||
switch(sbuf->fmt) {
|
||||
case SFMT_S16: {
|
||||
int16_t* buf = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = (float)buf[s]; // / 32767.0f
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SFMT_F32: {
|
||||
float* buf = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = buf[s];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* when casting float to int, value is simply truncated:
|
||||
* - (int)1.7 = 1, (int)-1.7 = -1
|
||||
@ -52,20 +30,68 @@ void sbuf_copy_to_f32(float* dst, sbuf_t* sbuf) {
|
||||
* - (((int) (f1 + 32768.5)) - 32768)
|
||||
* - etc
|
||||
* but since +-1 isn't really audible we'll just cast, as it's the fastest
|
||||
*
|
||||
* Regular C float-to-int casting ("int i = (int)f") is somewhat slow due to IEEE
|
||||
* float requirements, but C99 adds some faster-but-less-precise casting functions.
|
||||
* MSVC added this in VS2015 (_MSC_VER 1900) but doesn't seem inlined and is very slow.
|
||||
* It's slightly faster (~5%) but causes fuzzy PCM<>float<>PCM conversions.
|
||||
*/
|
||||
static inline int float_to_int(float val) {
|
||||
#if 1
|
||||
return (int)val;
|
||||
#elif defined(_MSC_VER)
|
||||
return (int)val;
|
||||
#else
|
||||
return lrintf(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
//TODO decide if using float 1.0 style or 32767 style (fuzzy PCM when doing that)
|
||||
//TODO: maybe use macro-style templating (but kinda ugly)
|
||||
void sbuf_copy_to_f32(float* dst, sbuf_t* sbuf) {
|
||||
|
||||
switch(sbuf->fmt) {
|
||||
case SFMT_S16: {
|
||||
int16_t* src = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = (float)src[s]; // / 32767.0f
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SFMT_FLT:
|
||||
case SFMT_F32: {
|
||||
float* src = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = src[s];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void sbuf_copy_from_f32(sbuf_t* sbuf, float* src) {
|
||||
switch(sbuf->fmt) {
|
||||
case SFMT_S16: {
|
||||
int16_t* buf = sbuf->buf;
|
||||
int16_t* dst = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
buf[s] = clamp16( src[s]); // * 32767.0f
|
||||
dst[s] = clamp16(float_to_int(src[s]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SFMT_F32: {
|
||||
float* buf = sbuf->buf;
|
||||
float* dst = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
buf[s] = src[s];
|
||||
dst[s] = src[s];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SFMT_FLT: {
|
||||
float* dst = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = src[s] / 32768.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3,26 +3,29 @@
|
||||
|
||||
#include "../streamtypes.h"
|
||||
|
||||
/* interleaved: buffer for all channels = [ch*s] = (ch1 ch2 ch1 ch2 ch1 ch2 ch1 ch2 ...) */
|
||||
/* planar: buffer per channel = [ch][s] = (c1 c1 c1 c1 ...) (c2 c2 c2 c2 ...) */
|
||||
/* All types are interleaved (buffer for all channels = [ch*s] = ch1 ch2 ch1 ch2 ch1 ch2 ...)
|
||||
* rather than planar (buffer per channel = [ch][s] = c1 c1 c1 c1 ... c2 c2 c2 c2 ...) */
|
||||
typedef enum {
|
||||
SFMT_NONE,
|
||||
SFMT_S16,
|
||||
SFMT_S16, /* standard PCM16 */
|
||||
//SFMT_S24,
|
||||
//SFMT_S32,
|
||||
SFMT_F32,
|
||||
SFMT_F32, /* pcm-like float (+-32768), for internal use (simpler pcm > f32 plus some decoders use this) */
|
||||
SFMT_FLT, /* standard float (+-1.0), for external players */
|
||||
} sfmt_t;
|
||||
|
||||
|
||||
/* simple buffer info for internal mixing
|
||||
* meant to held existing sound buffer pointers rather than alloc'ing directly (some ops will swap/move its internals) */
|
||||
typedef struct {
|
||||
void* buf; /* current sample buffer */
|
||||
sfmt_t fmt; /* buffer type */
|
||||
int channels; /* interleaved step or planar buffers */
|
||||
int samples; /* max samples */
|
||||
int filled; /* samples in buffer */
|
||||
//int planar;
|
||||
} sbuf_t;
|
||||
|
||||
|
||||
void sbuf_init_s16(sbuf_t* sbuf, int16_t* buf, int samples, int channels);
|
||||
|
||||
void sbuf_init_f32(sbuf_t* sbuf, float* buf, int samples, int channels);
|
||||
|
Loading…
Reference in New Issue
Block a user