PcmDither: convert struct to a class

This commit is contained in:
Max Kellermann 2013-01-31 22:43:28 +01:00
parent 1b175025fe
commit f2491c88c8
7 changed files with 49 additions and 57 deletions

View File

@ -38,7 +38,6 @@ PcmConvert::PcmConvert()
pcm_dsd_init(&dsd);
pcm_resample_init(&resample);
pcm_dither_24_init(&dither);
pcm_buffer_init(&format_buffer);
pcm_buffer_init(&channels_buffer);
@ -71,7 +70,7 @@ PcmConvert::Convert16(const audio_format *src_format,
assert(dest_format->format == SAMPLE_FORMAT_S16);
buf = pcm_convert_to_16(&format_buffer, &dither,
buf = pcm_convert_to_16(&format_buffer, dither,
sample_format(src_format->format),
src_buffer, src_size,
&len);

View File

@ -42,7 +42,7 @@ class PcmConvert {
struct pcm_resample_state resample;
struct pcm_dither dither;
PcmDither dither;
/** the buffer for converting the sample format */
struct pcm_buffer format_buffer;

View File

@ -21,11 +21,9 @@
#include "PcmDither.hxx"
#include "PcmPrng.hxx"
static int16_t
pcm_dither_sample_24_to_16(int32_t sample, struct pcm_dither *dither)
inline int16_t
PcmDither::Dither24To16(int_fast32_t sample)
{
int32_t output, rnd;
enum {
from_bits = 24,
to_bits = 16,
@ -37,18 +35,18 @@ pcm_dither_sample_24_to_16(int32_t sample, struct pcm_dither *dither)
MAX = ONE - 1
};
sample += dither->error[0] - dither->error[1] + dither->error[2];
sample += error[0] - error[1] + error[2];
dither->error[2] = dither->error[1];
dither->error[1] = dither->error[0] / 2;
error[2] = error[1];
error[1] = error[0] / 2;
/* round */
output = sample + round;
int_fast32_t output = sample + round;
rnd = pcm_prng(dither->random);
output += (rnd & mask) - (dither->random & mask);
int_fast32_t rnd = pcm_prng(random);
output += (rnd & mask) - (random & mask);
dither->random = rnd;
random = rnd;
/* clip */
if (output > MAX) {
@ -65,29 +63,29 @@ pcm_dither_sample_24_to_16(int32_t sample, struct pcm_dither *dither)
output &= ~mask;
dither->error[0] = sample - output;
error[0] = sample - output;
return (int16_t)(output >> scale_bits);
}
void
pcm_dither_24_to_16(struct pcm_dither *dither,
int16_t *dest, const int32_t *src, const int32_t *src_end)
PcmDither::Dither24To16(int16_t *dest, const int32_t *src,
const int32_t *src_end)
{
while (src < src_end)
*dest++ = pcm_dither_sample_24_to_16(*src++, dither);
*dest++ = Dither24To16(*src++);
}
static int16_t
pcm_dither_sample_32_to_16(int32_t sample, struct pcm_dither *dither)
inline int16_t
PcmDither::Dither32To16(int_fast32_t sample)
{
return pcm_dither_sample_24_to_16(sample >> 8, dither);
return Dither24To16(sample >> 8);
}
void
pcm_dither_32_to_16(struct pcm_dither *dither,
int16_t *dest, const int32_t *src, const int32_t *src_end)
PcmDither::Dither32To16(int16_t *dest, const int32_t *src,
const int32_t *src_end)
{
while (src < src_end)
*dest++ = pcm_dither_sample_32_to_16(*src++, dither);
*dest++ = Dither32To16(*src++);
}

View File

@ -22,24 +22,23 @@
#include <stdint.h>
struct pcm_dither {
class PcmDither {
int32_t error[3];
int32_t random;
public:
constexpr PcmDither()
:error{0, 0, 0}, random(0) {}
void Dither24To16(int16_t *dest, const int32_t *src,
const int32_t *src_end);
void Dither32To16(int16_t *dest, const int32_t *src,
const int32_t *src_end);
private:
int16_t Dither24To16(int_fast32_t sample);
int16_t Dither32To16(int_fast32_t sample);
};
static inline void
pcm_dither_24_init(struct pcm_dither *dither)
{
dither->error[0] = dither->error[1] = dither->error[2] = 0;
dither->random = 0;
}
void
pcm_dither_24_to_16(struct pcm_dither *dither,
int16_t *dest, const int32_t *src, const int32_t *src_end);
void
pcm_dither_32_to_16(struct pcm_dither *dither,
int16_t *dest, const int32_t *src, const int32_t *src_end);
#endif

View File

@ -33,17 +33,17 @@ pcm_convert_8_to_16(int16_t *out, const int8_t *in, const int8_t *in_end)
}
static void
pcm_convert_24_to_16(struct pcm_dither *dither,
pcm_convert_24_to_16(PcmDither &dither,
int16_t *out, const int32_t *in, const int32_t *in_end)
{
pcm_dither_24_to_16(dither, out, in, in_end);
dither.Dither24To16(out, in, in_end);
}
static void
pcm_convert_32_to_16(struct pcm_dither *dither,
pcm_convert_32_to_16(PcmDither &dither,
int16_t *out, const int32_t *in, const int32_t *in_end)
{
pcm_dither_32_to_16(dither, out, in, in_end);
dither.Dither32To16(out, in, in_end);
}
static void
@ -70,7 +70,7 @@ pcm_allocate_8_to_16(struct pcm_buffer *buffer,
}
static int16_t *
pcm_allocate_24p32_to_16(struct pcm_buffer *buffer, struct pcm_dither *dither,
pcm_allocate_24p32_to_16(struct pcm_buffer *buffer, PcmDither &dither,
const int32_t *src, size_t src_size,
size_t *dest_size_r)
{
@ -84,7 +84,7 @@ pcm_allocate_24p32_to_16(struct pcm_buffer *buffer, struct pcm_dither *dither,
}
static int16_t *
pcm_allocate_32_to_16(struct pcm_buffer *buffer, struct pcm_dither *dither,
pcm_allocate_32_to_16(struct pcm_buffer *buffer, PcmDither &dither,
const int32_t *src, size_t src_size,
size_t *dest_size_r)
{
@ -112,7 +112,7 @@ pcm_allocate_float_to_16(struct pcm_buffer *buffer,
}
const int16_t *
pcm_convert_to_16(struct pcm_buffer *buffer, struct pcm_dither *dither,
pcm_convert_to_16(struct pcm_buffer *buffer, PcmDither &dither,
enum sample_format src_format, const void *src,
size_t src_size, size_t *dest_size_r)
{

View File

@ -26,7 +26,7 @@
#include <stddef.h>
struct pcm_buffer;
struct pcm_dither;
class PcmDither;
/**
* Converts PCM samples to 16 bit. If the source format is 24 bit,
@ -41,7 +41,7 @@ struct pcm_dither;
* @return the destination buffer
*/
const int16_t *
pcm_convert_to_16(struct pcm_buffer *buffer, struct pcm_dither *dither,
pcm_convert_to_16(struct pcm_buffer *buffer, PcmDither &dither,
enum sample_format src_format, const void *src,
size_t src_size, size_t *dest_size_r);

View File

@ -37,9 +37,7 @@ random24()
void
test_pcm_dither_24()
{
struct pcm_dither dither;
pcm_dither_24_init(&dither);
PcmDither dither;
enum { N = 256 };
int32_t src[N];
@ -48,7 +46,7 @@ test_pcm_dither_24()
int16_t dest[N];
pcm_dither_24_to_16(&dither, dest, src, src + N);
dither.Dither24To16(dest, src, src + N);
for (unsigned i = 0; i < N; ++i) {
g_assert_cmpint(dest[i], >=, (src[i] >> 8) - 8);
@ -59,9 +57,7 @@ test_pcm_dither_24()
void
test_pcm_dither_32()
{
struct pcm_dither dither;
pcm_dither_24_init(&dither);
PcmDither dither;
enum { N = 256 };
int32_t src[N];
@ -70,7 +66,7 @@ test_pcm_dither_32()
int16_t dest[N];
pcm_dither_32_to_16(&dither, dest, src, src + N);
dither.Dither32To16(dest, src, src + N);
for (unsigned i = 0; i < N; ++i) {
g_assert_cmpint(dest[i], >=, (src[i] >> 16) - 8);