return output >> scalebits;
}
+unsigned FLAC__plugin_common__pack_pcm_signed_big_endian(FLAC__byte *data, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, unsigned source_bps, unsigned target_bps)
+{
+ static dither_state dither[FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS];
+ FLAC__byte * const start = data;
+ FLAC__int32 sample;
+ const FLAC__int32 *input_;
+ unsigned samples, channel;
+ const unsigned bytes_per_sample = target_bps / 8;
+ unsigned inc = bytes_per_sample * channels;
+
+ FLAC__ASSERT(channels > 0 && channels <= FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS);
+ FLAC__ASSERT(source_bps < 32);
+ FLAC__ASSERT(target_bps <= 24);
+ FLAC__ASSERT(target_bps <= source_bps);
+ FLAC__ASSERT((source_bps & 7) == 0);
+ FLAC__ASSERT((target_bps & 7) == 0);
+
+ if(source_bps != target_bps) {
+ const FLAC__int32 MIN = -(1L << (source_bps - 1));
+ const FLAC__int32 MAX = ~MIN; /*(1L << (source_bps-1)) - 1 */
+
+ for(channel = 0; channel < channels; channel++) {
+
+ samples = wide_samples;
+ data = start + bytes_per_sample * channel;
+ input_ = input[channel];
+
+ while(samples--) {
+ sample = linear_dither(source_bps, target_bps, *input_++, &dither[channel], MIN, MAX);
+
+ switch(target_bps) {
+ case 8:
+ data[0] = sample ^ 0x80;
+ break;
+ case 16:
+ data[0] = (FLAC__byte)(sample >> 8);
+ data[1] = (FLAC__byte)sample;
+ break;
+ case 24:
+ data[0] = (FLAC__byte)(sample >> 16);
+ data[1] = (FLAC__byte)(sample >> 8);
+ data[2] = (FLAC__byte)sample;
+ break;
+ }
+
+ data += inc;
+ }
+ }
+ }
+ else {
+ for(channel = 0; channel < channels; channel++) {
+ samples = wide_samples;
+ data = start + bytes_per_sample * channel;
+ input_ = input[channel];
+
+ while(samples--) {
+ sample = *input_++;
+
+ switch(target_bps) {
+ case 8:
+ data[0] = sample ^ 0x80;
+ break;
+ case 16:
+ data[0] = (FLAC__byte)(sample >> 8);
+ data[1] = (FLAC__byte)sample;
+ break;
+ case 24:
+ data[0] = (FLAC__byte)(sample >> 16);
+ data[1] = (FLAC__byte)(sample >> 8);
+ data[2] = (FLAC__byte)sample;
+ break;
+ }
+
+ data += inc;
+ }
+ }
+ }
+
+ return data - start;
+}
+
unsigned FLAC__plugin_common__pack_pcm_signed_little_endian(FLAC__byte *data, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, unsigned source_bps, unsigned target_bps)
{
static dither_state dither[FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS];
#include "defs.h" /* buy FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS for the caller */
#include "FLAC/ordinals.h"
+unsigned FLAC__plugin_common__pack_pcm_signed_big_endian(FLAC__byte *data, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, unsigned source_bps, unsigned target_bps);
unsigned FLAC__plugin_common__pack_pcm_signed_little_endian(FLAC__byte *data, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, unsigned source_bps, unsigned target_bps);
#endif
#endif
-int FLAC__plugin_common__apply_gain(FLAC__byte *data_out, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, const unsigned source_bps, const unsigned target_bps, const float scale, const FLAC__bool hard_limit, FLAC__bool do_dithering, DitherContext *dither_context)
+int FLAC__plugin_common__apply_gain(FLAC__byte *data_out, FLAC__bool little_endian_data_out, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, const unsigned source_bps, const unsigned target_bps, const float scale, const FLAC__bool hard_limit, FLAC__bool do_dithering, DitherContext *dither_context)
{
static const FLAC__int32 conv_factors_[33] = {
-1, /* 0 bits-per-sample (not supported) */
else if(val64 < hard_clip_factor)
val32 = (FLAC__int32)hard_clip_factor;
- switch(target_bps) {
- case 8:
- data_out[0] = val32 ^ 0x80;
- break;
- case 24:
- data_out[2] = (FLAC__byte)(val32 >> 16);
- /* fall through */
- case 16:
- data_out[1] = (FLAC__byte)(val32 >> 8);
- data_out[0] = (FLAC__byte)val32;
+ if (little_endian_data_out) {
+ switch(target_bps) {
+ case 8:
+ data_out[0] = val32 ^ 0x80;
+ break;
+ case 24:
+ data_out[2] = (FLAC__byte)(val32 >> 16);
+ /* fall through */
+ case 16:
+ data_out[1] = (FLAC__byte)(val32 >> 8);
+ data_out[0] = (FLAC__byte)val32;
+ break;
+ }
+ }
+ else {
+ switch(target_bps) {
+ case 8:
+ data_out[0] = val32 ^ 0x80;
+ break;
+ case 16:
+ data_out[0] = (FLAC__byte)(val32 >> 8);
+ data_out[1] = (FLAC__byte)val32;
+ break;
+ case 24:
+ data_out[0] = (FLAC__byte)(val32 >> 16);
+ data_out[1] = (FLAC__byte)(val32 >> 8);
+ data_out[2] = (FLAC__byte)val32;
+ break;
+ }
}
}
}
void FLAC__plugin_common__init_dither_context(DitherContext *dither, int bits, int shapingtype);
/* scale = (float) pow(10., (double)replaygain * 0.05); */
-int FLAC__plugin_common__apply_gain(FLAC__byte *data_out, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, const unsigned source_bps, const unsigned target_bps, const float scale, const FLAC__bool hard_limit, FLAC__bool do_dithering, DitherContext *dither_context);
+int FLAC__plugin_common__apply_gain(FLAC__byte *data_out, FLAC__bool little_endian_data_out, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, const unsigned source_bps, const unsigned target_bps, const float scale, const FLAC__bool hard_limit, FLAC__bool do_dithering, DitherContext *dither_context);
#endif
if(cfg.replaygain.enable && file_info_.has_replaygain) {
bytes = (int)FLAC__plugin_common__apply_gain(
sample_buffer_,
+ true, /* little_endian_data_out */
reservoir_,
n,
channels,
static file_info_struct file_info_;
static pthread_t decode_thread_;
static FLAC__bool audio_error_ = false;
+static FLAC__bool is_big_endian_host_;
#define BITRATE_HIST_SEGMENT_MSEC 500
/* 500ms * 50 = 25s should be enough */
void FLAC_XMMS__init()
{
ConfigFile *cfg;
+ FLAC__uint32 test = 1;
+
+ is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
flac_cfg.title.tag_override = FALSE;
g_free(flac_cfg.title.tag_format);
file_info_.sample_format_bytes_per_sample = 1;
}
else if(flac_cfg.output.resolution.replaygain.bps_out == 16) {
- file_info_.sample_format = FMT_S16_LE;
+ file_info_.sample_format = (is_big_endian_host_) ? FMT_S16_BE : FMT_S16_LE;
file_info_.sample_format_bytes_per_sample = 2;
}
else {
file_info_.sample_format_bytes_per_sample = 1;
}
else if(file_info_.bits_per_sample == 16 || (file_info_.bits_per_sample == 24 && flac_cfg.output.resolution.normal.dither_24_to_16)) {
- file_info_.sample_format = FMT_S16_LE;
+ file_info_.sample_format = (is_big_endian_host_) ? FMT_S16_BE : FMT_S16_LE;
file_info_.sample_format_bytes_per_sample = 2;
}
else {
if(file_info_.has_replaygain && flac_cfg.output.replaygain.enable) {
FLAC__plugin_common__apply_gain(
sample_buffer_start,
+ !is_big_endian_host_,
buffer,
wide_samples,
channels,
&file_info_.dither_context
);
}
+ else if(is_big_endian_host_) {
+ FLAC__plugin_common__pack_pcm_signed_big_endian(
+ sample_buffer_start,
+ buffer,
+ wide_samples,
+ channels,
+ bits_per_sample,
+ file_info->sample_format_bytes_per_sample * 8
+ );
+ }
else {
FLAC__plugin_common__pack_pcm_signed_little_endian(
sample_buffer_start,