PcmDither: convert struct to a class
This commit is contained in:
@@ -38,7 +38,6 @@ PcmConvert::PcmConvert()
|
|||||||
|
|
||||||
pcm_dsd_init(&dsd);
|
pcm_dsd_init(&dsd);
|
||||||
pcm_resample_init(&resample);
|
pcm_resample_init(&resample);
|
||||||
pcm_dither_24_init(&dither);
|
|
||||||
|
|
||||||
pcm_buffer_init(&format_buffer);
|
pcm_buffer_init(&format_buffer);
|
||||||
pcm_buffer_init(&channels_buffer);
|
pcm_buffer_init(&channels_buffer);
|
||||||
@@ -71,7 +70,7 @@ PcmConvert::Convert16(const audio_format *src_format,
|
|||||||
|
|
||||||
assert(dest_format->format == SAMPLE_FORMAT_S16);
|
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),
|
sample_format(src_format->format),
|
||||||
src_buffer, src_size,
|
src_buffer, src_size,
|
||||||
&len);
|
&len);
|
||||||
|
@@ -42,7 +42,7 @@ class PcmConvert {
|
|||||||
|
|
||||||
struct pcm_resample_state resample;
|
struct pcm_resample_state resample;
|
||||||
|
|
||||||
struct pcm_dither dither;
|
PcmDither dither;
|
||||||
|
|
||||||
/** the buffer for converting the sample format */
|
/** the buffer for converting the sample format */
|
||||||
struct pcm_buffer format_buffer;
|
struct pcm_buffer format_buffer;
|
||||||
|
@@ -21,11 +21,9 @@
|
|||||||
#include "PcmDither.hxx"
|
#include "PcmDither.hxx"
|
||||||
#include "PcmPrng.hxx"
|
#include "PcmPrng.hxx"
|
||||||
|
|
||||||
static int16_t
|
inline int16_t
|
||||||
pcm_dither_sample_24_to_16(int32_t sample, struct pcm_dither *dither)
|
PcmDither::Dither24To16(int_fast32_t sample)
|
||||||
{
|
{
|
||||||
int32_t output, rnd;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
from_bits = 24,
|
from_bits = 24,
|
||||||
to_bits = 16,
|
to_bits = 16,
|
||||||
@@ -37,18 +35,18 @@ pcm_dither_sample_24_to_16(int32_t sample, struct pcm_dither *dither)
|
|||||||
MAX = ONE - 1
|
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];
|
error[2] = error[1];
|
||||||
dither->error[1] = dither->error[0] / 2;
|
error[1] = error[0] / 2;
|
||||||
|
|
||||||
/* round */
|
/* round */
|
||||||
output = sample + round;
|
int_fast32_t output = sample + round;
|
||||||
|
|
||||||
rnd = pcm_prng(dither->random);
|
int_fast32_t rnd = pcm_prng(random);
|
||||||
output += (rnd & mask) - (dither->random & mask);
|
output += (rnd & mask) - (random & mask);
|
||||||
|
|
||||||
dither->random = rnd;
|
random = rnd;
|
||||||
|
|
||||||
/* clip */
|
/* clip */
|
||||||
if (output > MAX) {
|
if (output > MAX) {
|
||||||
@@ -65,29 +63,29 @@ pcm_dither_sample_24_to_16(int32_t sample, struct pcm_dither *dither)
|
|||||||
|
|
||||||
output &= ~mask;
|
output &= ~mask;
|
||||||
|
|
||||||
dither->error[0] = sample - output;
|
error[0] = sample - output;
|
||||||
|
|
||||||
return (int16_t)(output >> scale_bits);
|
return (int16_t)(output >> scale_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pcm_dither_24_to_16(struct pcm_dither *dither,
|
PcmDither::Dither24To16(int16_t *dest, const int32_t *src,
|
||||||
int16_t *dest, const int32_t *src, const int32_t *src_end)
|
const int32_t *src_end)
|
||||||
{
|
{
|
||||||
while (src < src_end)
|
while (src < src_end)
|
||||||
*dest++ = pcm_dither_sample_24_to_16(*src++, dither);
|
*dest++ = Dither24To16(*src++);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int16_t
|
inline int16_t
|
||||||
pcm_dither_sample_32_to_16(int32_t sample, struct pcm_dither *dither)
|
PcmDither::Dither32To16(int_fast32_t sample)
|
||||||
{
|
{
|
||||||
return pcm_dither_sample_24_to_16(sample >> 8, dither);
|
return Dither24To16(sample >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pcm_dither_32_to_16(struct pcm_dither *dither,
|
PcmDither::Dither32To16(int16_t *dest, const int32_t *src,
|
||||||
int16_t *dest, const int32_t *src, const int32_t *src_end)
|
const int32_t *src_end)
|
||||||
{
|
{
|
||||||
while (src < src_end)
|
while (src < src_end)
|
||||||
*dest++ = pcm_dither_sample_32_to_16(*src++, dither);
|
*dest++ = Dither32To16(*src++);
|
||||||
}
|
}
|
||||||
|
@@ -22,24 +22,23 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct pcm_dither {
|
class PcmDither {
|
||||||
int32_t error[3];
|
int32_t error[3];
|
||||||
int32_t random;
|
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
|
#endif
|
||||||
|
@@ -33,17 +33,17 @@ pcm_convert_8_to_16(int16_t *out, const int8_t *in, const int8_t *in_end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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)
|
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
|
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)
|
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
|
static void
|
||||||
@@ -70,7 +70,7 @@ pcm_allocate_8_to_16(struct pcm_buffer *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int16_t *
|
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,
|
const int32_t *src, size_t src_size,
|
||||||
size_t *dest_size_r)
|
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 *
|
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,
|
const int32_t *src, size_t src_size,
|
||||||
size_t *dest_size_r)
|
size_t *dest_size_r)
|
||||||
{
|
{
|
||||||
@@ -112,7 +112,7 @@ pcm_allocate_float_to_16(struct pcm_buffer *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int16_t *
|
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,
|
enum sample_format src_format, const void *src,
|
||||||
size_t src_size, size_t *dest_size_r)
|
size_t src_size, size_t *dest_size_r)
|
||||||
{
|
{
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct pcm_buffer;
|
struct pcm_buffer;
|
||||||
struct pcm_dither;
|
class PcmDither;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts PCM samples to 16 bit. If the source format is 24 bit,
|
* Converts PCM samples to 16 bit. If the source format is 24 bit,
|
||||||
@@ -41,7 +41,7 @@ struct pcm_dither;
|
|||||||
* @return the destination buffer
|
* @return the destination buffer
|
||||||
*/
|
*/
|
||||||
const int16_t *
|
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,
|
enum sample_format src_format, const void *src,
|
||||||
size_t src_size, size_t *dest_size_r);
|
size_t src_size, size_t *dest_size_r);
|
||||||
|
|
||||||
|
@@ -37,9 +37,7 @@ random24()
|
|||||||
void
|
void
|
||||||
test_pcm_dither_24()
|
test_pcm_dither_24()
|
||||||
{
|
{
|
||||||
struct pcm_dither dither;
|
PcmDither dither;
|
||||||
|
|
||||||
pcm_dither_24_init(&dither);
|
|
||||||
|
|
||||||
enum { N = 256 };
|
enum { N = 256 };
|
||||||
int32_t src[N];
|
int32_t src[N];
|
||||||
@@ -48,7 +46,7 @@ test_pcm_dither_24()
|
|||||||
|
|
||||||
int16_t dest[N];
|
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) {
|
for (unsigned i = 0; i < N; ++i) {
|
||||||
g_assert_cmpint(dest[i], >=, (src[i] >> 8) - 8);
|
g_assert_cmpint(dest[i], >=, (src[i] >> 8) - 8);
|
||||||
@@ -59,9 +57,7 @@ test_pcm_dither_24()
|
|||||||
void
|
void
|
||||||
test_pcm_dither_32()
|
test_pcm_dither_32()
|
||||||
{
|
{
|
||||||
struct pcm_dither dither;
|
PcmDither dither;
|
||||||
|
|
||||||
pcm_dither_24_init(&dither);
|
|
||||||
|
|
||||||
enum { N = 256 };
|
enum { N = 256 };
|
||||||
int32_t src[N];
|
int32_t src[N];
|
||||||
@@ -70,7 +66,7 @@ test_pcm_dither_32()
|
|||||||
|
|
||||||
int16_t dest[N];
|
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) {
|
for (unsigned i = 0; i < N; ++i) {
|
||||||
g_assert_cmpint(dest[i], >=, (src[i] >> 16) - 8);
|
g_assert_cmpint(dest[i], >=, (src[i] >> 16) - 8);
|
||||||
|
Reference in New Issue
Block a user