Initial commit

faad does not work yet
This commit is contained in:
philippe44
2019-05-26 19:29:56 -07:00
parent 21860614e8
commit 66b2f74ebe
11 changed files with 223 additions and 121 deletions

View File

@@ -23,6 +23,18 @@
#include <alac_wrapper.h>
#if BYTES_PER_FRAME == 4
#define ALIGN8(n) (n << 8)
#define ALIGN16(n) (n)
#define ALIGN24(n) (n >> 8)
#define ALIGN32(n) (n >> 16)
#else
#define ALIGN8(n) (n << 24)
#define ALIGN16(n) (n << 16)
#define ALIGN24(n) (n << 8)
#define ALIGN32(n) (n)
#endif
#define BLOCK_SIZE (4096 * BYTES_PER_FRAME)
#define MIN_READ BLOCK_SIZE
#define MIN_SPACE (MIN_READ * 4)
@@ -433,15 +445,15 @@ static decode_state alac_decode(void) {
while (frames > 0) {
size_t f, count;
s32_t *optr;
ISAMPLE_T *optr;
IF_DIRECT(
f = min(frames, _buf_cont_write(outputbuf) / BYTES_PER_FRAME);
optr = (s32_t *)outputbuf->writep;
optr = (ISAMPLE_T *)outputbuf->writep;
);
IF_PROCESS(
f = min(frames, process.max_in_frames - process.in_frames);
optr = (s32_t *)((u8_t *) process.inbuf + process.in_frames * BYTES_PER_FRAME);
optr = (ISAMPLE_T *)((u8_t *) process.inbuf + process.in_frames * BYTES_PER_FRAME);
);
f = min(f, frames);
@@ -449,32 +461,31 @@ static decode_state alac_decode(void) {
if (l->sample_size == 8) {
while (count--) {
*optr++ = (*(u32_t*) iptr) << 24;
*optr++ = (*(u32_t*) (iptr + 1)) << 24;
iptr += 2;
*optr++ = ALIGN8(*iptr++);
*optr++ = ALIGN8(*iptr++);
}
} else if (l->sample_size == 16) {
u16_t *_iptr = (u16_t*) iptr;
while (count--) {
*optr++ = (*(u32_t*) iptr) << 16;
*optr++ = (*(u32_t*) (iptr + 2)) << 16;
iptr += 4;
*optr++ = ALIGN16(*_iptr++);
*optr++ = ALIGN16(*_iptr++);
}
} else if (l->sample_size == 24) {
while (count--) {
*optr++ = (*(u32_t*) iptr) << 8;
*optr++ = (*(u32_t*) (iptr + 3)) << 8;
*optr++ = ALIGN24(*(u32_t*) iptr);
*optr++ = ALIGN24(*(u32_t*) (iptr + 3));
iptr += 6;
}
} else if (l->sample_size == 32) {
u32_t *_iptr = (u32_t*) iptr;
while (count--) {
*optr++ = (*(u32_t*) iptr);
*optr++ = (*(u32_t*) (iptr + 4));
iptr += 8;
*optr++ = ALIGN32(*_iptr++);
*optr++ = ALIGN32(*_iptr++);
}
} else {
LOG_ERROR("unsupported bits per sample: %u", l->sample_size);
}
frames -= f;
IF_DIRECT(

View File

@@ -2,7 +2,7 @@
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
CFLAGS += -DPOSIX -DLINKALL -DLOOPBACK -DDACAUDIO -DTREMOR_ONLY \
CFLAGS += -DPOSIX -DLINKALL -DLOOPBACK -DDACAUDIO -DTREMOR_ONLY -DBYTES_PER_FRAME=4 \
-I$(COMPONENT_PATH)/../components/codecs/inc \
-I$(COMPONENT_PATH)/../components/codecs/inc/mad \
-I$(COMPONENT_PATH)/../components/codecs/inc/faad2 \

View File

@@ -23,6 +23,12 @@
#include <neaacdec.h>
#if BYTES_PER_FRAME == 4
#define ALIGN(n) (n)
#else
#define ALIGN(n) (n << 8)
#endif
#define WRAPBUF_LEN 2048
struct chunk_table {
@@ -315,7 +321,7 @@ static decode_state faad_decode(void) {
size_t bytes_total;
size_t bytes_wrap;
static NeAACDecFrameInfo info;
s32_t *iptr;
ISAMPLE_T *iptr;
bool endstream;
frames_t frames;
@@ -491,29 +497,35 @@ static decode_state faad_decode(void) {
while (frames > 0) {
frames_t f;
frames_t count;
s32_t *optr;
ISAMPLE_T *optr;
IF_DIRECT(
f = _buf_cont_write(outputbuf) / BYTES_PER_FRAME;
optr = (s32_t *)outputbuf->writep;
optr = (ISAMPLE_T *)outputbuf->writep;
);
IF_PROCESS(
f = process.max_in_frames;
optr = (s32_t *)process.inbuf;
optr = (ISAMPLE_T *)process.inbuf;
);
f = min(f, frames);
count = f;
if (info.channels == 2) {
#if BYTES_PER_FRAME == 4
memcpy(optr, iptr, count * BYTES_PER_FRAME);
iptr += count * 2;
optr += count * 2;
#else
while (count--) {
*optr++ = *iptr++ << 8;
*optr++ = *iptr++ << 8;
}
#endif
} else if (info.channels == 1) {
while (count--) {
*optr++ = *iptr << 8;
*optr++ = *iptr++ << 8;
*optr++ = ALIGN(*iptr);
*optr++ = ALIGN(*iptr++);
}
} else {
LOG_WARN("unsupported number of channels");
@@ -563,7 +575,12 @@ static void faad_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) {
conf = NEAAC(a, GetCurrentConfiguration, a->hAac);
#if BYTES_PER_FRAME == 4
conf->outputFormat = FAAD_FMT_16BIT;
#else
conf->outputFormat = FAAD_FMT_24BIT;
#endif
conf->defSampleRate = 44100;
conf->downMatrix = 1;
if (!NEAAC(a, SetConfiguration, a->hAac, conf)) {

View File

@@ -22,6 +22,18 @@
#include <FLAC/stream_decoder.h>
#if BYTES_PER_FRAME == 4
#define ALIGN8(n) (n << 8)
#define ALIGN16(n) (n)
#define ALIGN24(n) (n >> 8)
#define ALIGN32(n) (n >> 16)
#else
#define ALIGN8(n) (n << 24)
#define ALIGN16(n) (n << 16)
#define ALIGN24(n) (n << 8)
#define ALIGN32(n) (n)
#endif
struct flac {
FLAC__StreamDecoder *decoder;
#if !LINKALL
@@ -149,45 +161,45 @@ static FLAC__StreamDecoderWriteStatus write_cb(const FLAC__StreamDecoder *decode
while (frames > 0) {
frames_t f;
frames_t count;
s32_t *optr;
ISAMPLE_T *optr;
IF_DIRECT(
optr = (s32_t *)outputbuf->writep;
optr = (ISAMPLE_T *)outputbuf->writep;
f = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
);
IF_PROCESS(
optr = (s32_t *)process.inbuf;
optr = (ISAMPLE_T *)process.inbuf;
f = process.max_in_frames;
);
f = min(f, frames);
count = f;
if (bits_per_sample == 8) {
while (count--) {
*optr++ = *lptr++ << 24;
*optr++ = *rptr++ << 24;
*optr++ = ALIGN8(*lptr++);
*optr++ = ALIGN8(*rptr++);
}
} else if (bits_per_sample == 16) {
while (count--) {
*optr++ = *lptr++ << 16;
*optr++ = *rptr++ << 16;
*optr++ = ALIGN16(*lptr++);
*optr++ = ALIGN16(*rptr++);
}
} else if (bits_per_sample == 24) {
while (count--) {
*optr++ = *lptr++ << 8;
*optr++ = *rptr++ << 8;
*optr++ = ALIGN24(*lptr++);
*optr++ = ALIGN24(*rptr++);
}
} else if (bits_per_sample == 32) {
while (count--) {
*optr++ = *lptr++;
*optr++ = *rptr++;
*optr++ = ALIGN32(*lptr++);
*optr++ = ALIGN32(*rptr++);
}
} else {
LOG_ERROR("unsupported bits per sample: %u", bits_per_sample);
}
frames -= f;
IF_DIRECT(

View File

@@ -88,15 +88,18 @@ extern struct processstate process;
#endif
// based on libmad minimad.c scale
static inline u32_t scale(mad_fixed_t sample) {
static inline ISAMPLE_T scale(mad_fixed_t sample) {
sample += (1L << (MAD_F_FRACBITS - 24));
if (sample >= MAD_F_ONE)
sample = MAD_F_ONE - 1;
else if (sample < -MAD_F_ONE)
sample = -MAD_F_ONE;
return (s32_t)(sample >> (MAD_F_FRACBITS + 1 - 24)) << 8;
#if BYTES_PER_FRAME == 4
return (ISAMPLE_T)((sample >> (MAD_F_FRACBITS + 1 - 24)) >> 8);
#else
return (ISAMPLE_T)((sample >> (MAD_F_FRACBITS + 1 - 24)) << 8);
#endif
}
// check for id3.2 tag at start of file - http://id3.org/id3v2.4.0-structure, return length
@@ -300,15 +303,15 @@ static decode_state mad_decode(void) {
while (frames > 0) {
size_t f, count;
s32_t *optr;
ISAMPLE_T *optr;
IF_DIRECT(
f = min(frames, _buf_cont_write(outputbuf) / BYTES_PER_FRAME);
optr = (s32_t *)outputbuf->writep;
optr = (ISAMPLE_T *)outputbuf->writep;
);
IF_PROCESS(
f = min(frames, process.max_in_frames - process.in_frames);
optr = (s32_t *)((u8_t *)process.inbuf + process.in_frames * BYTES_PER_FRAME);
optr = (ISAMPLE_T *)((u8_t *)process.inbuf + process.in_frames * BYTES_PER_FRAME);
);
count = f;
@@ -317,7 +320,7 @@ static decode_state mad_decode(void) {
*optr++ = scale(*iptrl++);
*optr++ = scale(*iptrr++);
}
frames -= f;
IF_DIRECT(

View File

@@ -59,7 +59,7 @@ frames_t _output_frames(frames_t avail) {
silence = false;
// start when threshold met
if (output.state == OUTPUT_BUFFER && frames > output.threshold * output.next_sample_rate / 100 && frames > output.start_frames) {
if (output.state == OUTPUT_BUFFER && frames > output.threshold * output.next_sample_rate / 10 && frames > output.start_frames) {
output.state = OUTPUT_RUNNING;
LOG_INFO("start buffer frames: %u", frames);
wake_controller();

View File

@@ -21,6 +21,14 @@
#include "squeezelite.h"
#if BYTES_PER_FRAME == 4
#define SHIFT 16
#define OPTR_T u16_t
#else
#define OPTR_T u32_t
#define SHIFT 0
#endif
extern log_level loglevel;
extern struct buffer *streambuf;
@@ -175,9 +183,9 @@ static void _check_header(void) {
static decode_state pcm_decode(void) {
unsigned bytes, in, out;
frames_t frames, count;
u32_t *optr;
OPTR_T *optr;
u8_t *iptr;
u8_t tmp[16];
u8_t tmp[3*8];
LOCK_S;
@@ -236,10 +244,10 @@ static decode_state pcm_decode(void) {
}
IF_DIRECT(
optr = (u32_t *)outputbuf->writep;
optr = (OPTR_T *)outputbuf->writep;
);
IF_PROCESS(
optr = (u32_t *)process.inbuf;
optr = (OPTR_T *)process.inbuf;
);
iptr = (u8_t *)streambuf->readp;
@@ -261,47 +269,73 @@ static decode_state pcm_decode(void) {
LOG_INFO("reached end of audio");
frames = audio_left / bytes_per_frame;
}
count = frames * channels;
if (channels == 2) {
if (sample_size == 1) {
while (count--) {
*optr++ = *iptr++ << 24;
*optr++ = *iptr++ << (24-SHIFT);
}
} else if (sample_size == 2) {
if (bigendian) {
#if BYTES_PER_FRAME == 4 && !SL_LITTLE_ENDIAN
// while loop below works as is, but memcpy is a win for that 16/16 typical case
memcpy(optr, iptr, count * BYTES_PER_FRAME / 2);
#else
while (count--) {
*optr++ = *(iptr) << 24 | *(iptr+1) << 16;
*optr++ = *(iptr) << (24-SHIFT) | *(iptr+1) << (16-SHIFT);
iptr += 2;
}
#endif
} else {
#if BYTES_PER_FRAME == 4 && SL_LITTLE_ENDIAN
// while loop below works as is, but memcpy is a win for that 16/16 typical case
memcpy(optr, iptr, count * BYTES_PER_FRAME / 2);
#else
while (count--) {
*optr++ = *(iptr) << 16 | *(iptr+1) << 24;
*optr++ = *(iptr) << (16-SHIFT) | *(iptr+1) << (24-SHIFT);
iptr += 2;
}
#endif
}
} else if (sample_size == 3) {
if (bigendian) {
while (count--) {
#if BYTES_PER_FRAME == 4
*optr++ = *(iptr) << 8 | *(iptr+1);
#else
*optr++ = *(iptr) << 24 | *(iptr+1) << 16 | *(iptr+2) << 8;
#endif
iptr += 3;
}
} else {
while (count--) {
#if BYTES_PER_FRAME == 4
*optr++ = *(iptr+1) | *(iptr+2) << 8;
#else
*optr++ = *(iptr) << 8 | *(iptr+1) << 16 | *(iptr+2) << 24;
#endif
iptr += 3;
}
}
} else if (sample_size == 4) {
if (bigendian) {
while (count--) {
#if BYTES_PER_FRAME == 4
*optr++ = *(iptr) << 8 | *(iptr+1);
#else
*optr++ = *(iptr) << 24 | *(iptr+1) << 16 | *(iptr+2) << 8 | *(iptr+3);
#endif
iptr += 4;
}
} else {
while (count--) {
#if BYTES_PER_FRAME == 4
*optr++ = *(iptr+2) | *(iptr+3) << 8;
#else
*optr++ = *(iptr) | *(iptr+1) << 8 | *(iptr+2) << 16 | *(iptr+3) << 24;
#endif
iptr += 4;
}
}
@@ -309,21 +343,21 @@ static decode_state pcm_decode(void) {
} else if (channels == 1) {
if (sample_size == 1) {
while (count--) {
*optr = *iptr++ << 24;
*optr = *iptr++ << (24-SHIFT);
*(optr+1) = *optr;
optr += 2;
}
} else if (sample_size == 2) {
if (bigendian) {
while (count--) {
*optr = *(iptr) << 24 | *(iptr+1) << 16;
*optr = *(iptr) << (24-SHIFT) | *(iptr+1) << (16-SHIFT);
*(optr+1) = *optr;
iptr += 2;
optr += 2;
}
} else {
while (count--) {
*optr = *(iptr) << 16 | *(iptr+1) << 24;
*optr = *(iptr) << (16-SHIFT) | *(iptr+1) << (24-SHIFT);
*(optr+1) = *optr;
iptr += 2;
optr += 2;
@@ -332,14 +366,22 @@ static decode_state pcm_decode(void) {
} else if (sample_size == 3) {
if (bigendian) {
while (count--) {
#if BYTES_PER_FRAME == 4
*optr++ = *(iptr) << 8 | *(iptr+1);
#else
*optr = *(iptr) << 24 | *(iptr+1) << 16 | *(iptr+2) << 8;
#endif
*(optr+1) = *optr;
iptr += 3;
optr += 2;
}
} else {
while (count--) {
#if BYTES_PER_FRAME == 4
*optr++ = *(iptr+1) | *(iptr+2) << 8;
#else
*optr = *(iptr) << 8 | *(iptr+1) << 16 | *(iptr+2) << 24;
#endif
*(optr+1) = *optr;
iptr += 3;
optr += 2;
@@ -348,14 +390,22 @@ static decode_state pcm_decode(void) {
} else if (sample_size == 4) {
if (bigendian) {
while (count--) {
#if BYTES_PER_FRAME == 4
*optr++ = *(iptr) << 8 | *(iptr+1);
#else
*optr++ = *(iptr) << 24 | *(iptr+1) << 16 | *(iptr+2) << 8 | *(iptr+3);
#endif
*(optr+1) = *optr;
iptr += 4;
optr += 2;
}
} else {
while (count--) {
#if BYTES_PER_FRAME == 4
*optr++ = *(iptr+2) | *(iptr+3) << 8;
#else
*optr++ = *(iptr) | *(iptr+1) << 8 | *(iptr+2) << 16 | *(iptr+3) << 24;
#endif
*(optr+1) = *optr;
iptr += 4;
optr += 2;
@@ -365,7 +415,7 @@ static decode_state pcm_decode(void) {
} else {
LOG_ERROR("unsupported channels");
}
LOG_SDEBUG("decoded %u frames", frames);
_buf_inc_readp(streambuf, frames * bytes_per_frame);

View File

@@ -444,7 +444,15 @@ void _wake_create(event_event*);
#define FIXED_ONE 0x10000
#ifndef BYTES_PER_FRAME
#define BYTES_PER_FRAME 8
#endif
#if BYTES_PER_FRAME == 8
#define ISAMPLE_T s32_t
#else
#define ISAMPLE_T s16_t
#endif
#define min(a,b) (((a) < (b)) ? (a) : (b))
@@ -643,7 +651,7 @@ struct outputstate {
unsigned latency;
int pa_hostapi_option;
#endif
int (* write_cb)(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr);
int (* write_cb)(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
unsigned start_frames;
unsigned frames_played;
unsigned frames_played_dmp;// frames played at the point delay is measured

View File

@@ -21,6 +21,12 @@
#include "squeezelite.h"
#if BYTES_PER_FRAME == 4
#define ALIGN(n) (n)
#else
#define ALIGN(n) (n << 16)
#endif
// automatically select between floating point (preferred) and fixed point libraries:
// NOTE: works with Tremor version here: http://svn.xiph.org/trunk/Tremor, not vorbisidec.1.0.2 currently in ubuntu
@@ -207,26 +213,29 @@ static decode_state vorbis_decode(void) {
frames_t count;
s16_t *iptr;
s32_t *optr;
ISAMPLE_T *optr;
frames = n / 2 / channels;
count = frames * channels;
// work backward to unpack samples to 4 bytes per sample
iptr = (s16_t *)write_buf + count;
optr = (s32_t *)write_buf + frames * 2;
optr = (ISAMPLE_T *)write_buf + frames * 2;
if (channels == 2) {
#if BYTES_PER_FRAME == 4
memcpy(optr, iptr, count * BYTES_PER_FRAME / 2);
#else
while (count--) {
*--optr = *--iptr << 16;
}
#endif
} else if (channels == 1) {
while (count--) {
*--optr = *--iptr << 16;
*--optr = *iptr << 16;
*--optr = ALIGN(*--iptr);
*--optr = ALIGN(*iptr);
}
}
IF_DIRECT(
_buf_inc_writep(outputbuf, frames * BYTES_PER_FRAME);
);