Skip to content

Commit

Permalink
Merge squeezelite git resample branch.
Browse files Browse the repository at this point in the history
  • Loading branch information
ralph-irving committed Jun 27, 2013
1 parent e264992 commit ce95728
Show file tree
Hide file tree
Showing 16 changed files with 1,024 additions and 130 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Cross compile support - create a Makefile which defines these three variables and then includes this Makefile...
CFLAGS ?= -Wall -fPIC -O2 $(OPTS)
LDFLAGS ?= -lasound -lpthread -ldl -lrt
LDFLAGS ?= -lasound -lpthread -lm -ldl -lrt
EXECUTABLE ?= squeezelite

SOURCES = main.c slimproto.c utils.c output.c buffer.c stream.c decode.c flac.c pcm.c mad.c vorbis.c faad.c mpg.c
SOURCES = main.c slimproto.c utils.c output.c buffer.c stream.c decode.c process.c resample.c flac.c pcm.c mad.c vorbis.c faad.c mpg.c
DEPS = squeezelite.h

OBJECTS = $(SOURCES:.c=.o)
Expand Down
3 changes: 3 additions & 0 deletions Makefile.resample
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
OPTS = -DRESAMPLE

include Makefile
65 changes: 62 additions & 3 deletions decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ extern struct buffer *streambuf;
extern struct buffer *outputbuf;
extern struct streamstate stream;
extern struct outputstate output;
extern struct processstate process;

struct decodestate decode;
struct codec *codecs[MAX_CODECS];
static struct codec *codec;
struct codec *codec;
static bool running = true;

#define LOCK_S mutex_lock(streambuf->mutex)
Expand All @@ -41,10 +42,20 @@ static bool running = true;
#define LOCK_D mutex_lock(decode.mutex);
#define UNLOCK_D mutex_unlock(decode.mutex);

#if PROCESS
#define IF_DIRECT(x) if (decode.direct) { x }
#define IF_PROCESS(x) if (!decode.direct) { x }
#define MAY_PROCESS(x) { x }
#else
#define IF_DIRECT(x) { x }
#define IF_PROCESS(x)
#define MAY_PROCESS(x)
#endif

static void *decode_thread() {

while (running) {
size_t bytes, space;
size_t bytes, space, min_space;
bool toend;
bool ran = false;

Expand All @@ -61,11 +72,28 @@ static void *decode_thread() {
if (decode.state == DECODE_RUNNING && codec) {

LOG_SDEBUG("streambuf bytes: %u outputbuf space: %u", bytes, space);

IF_DIRECT(
min_space = codec->min_space;
);
IF_PROCESS(
min_space = process.max_out_frames * BYTES_PER_FRAME;
);

if (space > codec->min_space && (bytes > codec->min_read_bytes || toend)) {
if (space > min_space && (bytes > codec->min_read_bytes || toend)) {

decode.state = codec->decode();

IF_PROCESS(
if (process.in_frames) {
process_samples();
}

if (decode.state == DECODE_COMPLETE) {
process_drain();
}
);

if (decode.state != DECODE_RUNNING) {

LOG_INFO("decode %s", decode.state == DECODE_COMPLETE ? "complete" : "error");
Expand Down Expand Up @@ -130,6 +158,11 @@ void decode_init(log_level level, const char *opt) {

decode.new_stream = true;
decode.state = DECODE_STOPPED;

MAY_PROCESS(
decode.direct = true;
decode.process = false;
);
}

void decode_close(void) {
Expand All @@ -147,6 +180,27 @@ void decode_close(void) {
mutex_destroy(decode.mutex);
}

void decode_flush(void) {
LOG_INFO("decode flush");
LOCK_D;
decode.state = DECODE_STOPPED;
IF_PROCESS(
process_flush();
);
UNLOCK_D;
}

unsigned decode_newstream(unsigned sample_rate, unsigned max_sample_rate) {

MAY_PROCESS(
if (decode.process) {
return process_newstream(&decode.direct, sample_rate, max_sample_rate);
}
);

return sample_rate;
}

void codec_open(u8_t format, u8_t sample_size, u8_t sample_rate, u8_t channels, u8_t endianness) {
int i;

Expand All @@ -157,6 +211,10 @@ void codec_open(u8_t format, u8_t sample_size, u8_t sample_rate, u8_t channels,
decode.new_stream = true;
decode.state = DECODE_STOPPED;

MAY_PROCESS(
decode.direct = true; // potentially changed within codec when processing enabled
);

// find the required codec
for (i = 0; i < MAX_CODECS; ++i) {

Expand All @@ -180,3 +238,4 @@ void codec_open(u8_t format, u8_t sample_size, u8_t sample_rate, u8_t channels,

LOG_ERROR("codec not found");
}

42 changes: 34 additions & 8 deletions faad.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,23 @@ extern struct buffer *outputbuf;
extern struct streamstate stream;
extern struct outputstate output;
extern struct decodestate decode;
extern struct processstate process;

#define LOCK_S mutex_lock(streambuf->mutex)
#define UNLOCK_S mutex_unlock(streambuf->mutex)
#define LOCK_O mutex_lock(outputbuf->mutex)
#define UNLOCK_O mutex_unlock(outputbuf->mutex)
#if PROCESS
#define LOCK_O_direct if (decode.direct) mutex_lock(outputbuf->mutex)
#define UNLOCK_O_direct if (decode.direct) mutex_unlock(outputbuf->mutex)
#define IF_DIRECT(x) if (decode.direct) { x }
#define IF_PROCESS(x) if (!decode.direct) { x }
#else
#define LOCK_O_direct mutex_lock(outputbuf->mutex)
#define UNLOCK_O_direct mutex_unlock(outputbuf->mutex)
#define IF_DIRECT(x) { x }
#define IF_PROCESS(x)
#endif

// minimal code for mp4 file parsing to extract audio config and find media data

Expand Down Expand Up @@ -334,7 +346,7 @@ static decode_state faad_decode(void) {

LOCK_O;
LOG_INFO("setting track_start");
output.next_sample_rate = samplerate;
output.next_sample_rate = decode_newstream(samplerate, output.max_sample_rate);
output.track_start = outputbuf->writep;
if (output.fade_mode) _checkfade(true);
decode.new_stream = false;
Expand Down Expand Up @@ -417,8 +429,6 @@ static decode_state faad_decode(void) {
return DECODE_RUNNING;
}

LOCK_O;

frames = info.samples / info.channels;

if (a->skip) {
Expand All @@ -445,16 +455,25 @@ static decode_state faad_decode(void) {

LOG_SDEBUG("write %u frames", frames);

LOCK_O_direct;

while (frames > 0) {
frames_t f = _buf_cont_write(outputbuf) / BYTES_PER_FRAME;
frames_t f;
frames_t count;
s32_t *optr;

IF_DIRECT(
f = _buf_cont_write(outputbuf) / BYTES_PER_FRAME;
optr = (s32_t *)outputbuf->writep;
);
IF_PROCESS(
f = process.max_in_frames;
optr = (s32_t *)process.inbuf;
);

f = min(f, frames);
count = f;

optr = (s32_t *)outputbuf->writep;

if (info.channels == 2) {
while (count--) {
*optr++ = *iptr++ << 8;
Expand All @@ -470,10 +489,17 @@ static decode_state faad_decode(void) {
}

frames -= f;
_buf_inc_writep(outputbuf, f * BYTES_PER_FRAME);

IF_DIRECT(
_buf_inc_writep(outputbuf, f * BYTES_PER_FRAME);
);
IF_PROCESS(
process.in_frames = f;
if (frames) LOG_ERROR("unhandled case");
);
}

UNLOCK_O;
UNLOCK_O_direct;

return DECODE_RUNNING;
}
Expand Down
57 changes: 48 additions & 9 deletions flac.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,23 @@ extern struct buffer *outputbuf;
extern struct streamstate stream;
extern struct outputstate output;
extern struct decodestate decode;
extern struct processstate process;

#define LOCK_S mutex_lock(streambuf->mutex)
#define UNLOCK_S mutex_unlock(streambuf->mutex)
#define LOCK_O mutex_lock(outputbuf->mutex)
#define UNLOCK_O mutex_unlock(outputbuf->mutex)
#if PROCESS
#define LOCK_O_direct if (decode.direct) mutex_lock(outputbuf->mutex)
#define UNLOCK_O_direct if (decode.direct) mutex_unlock(outputbuf->mutex)
#define IF_DIRECT(x) if (decode.direct) { x }
#define IF_PROCESS(x) if (!decode.direct) { x }
#else
#define LOCK_O_direct mutex_lock(outputbuf->mutex)
#define UNLOCK_O_direct mutex_unlock(outputbuf->mutex)
#define IF_DIRECT(x) { x }
#define IF_PROCESS(x)
#endif

static FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *want, void *client_data) {
size_t bytes;
Expand Down Expand Up @@ -89,27 +101,42 @@ static FLAC__StreamDecoderWriteStatus write_cb(const FLAC__StreamDecoder *decode
FLAC__int32 *lptr = (FLAC__int32 *)buffer[0];
FLAC__int32 *rptr = (FLAC__int32 *)buffer[channels > 1 ? 1 : 0];

LOCK_O;

if (decode.new_stream) {
LOCK_O;
LOG_INFO("setting track_start");
output.next_sample_rate = frame->header.sample_rate;
output.next_sample_rate = decode_newstream(frame->header.sample_rate, output.max_sample_rate);
output.track_start = outputbuf->writep;
if (output.fade_mode) _checkfade(true);
decode.new_stream = false;
UNLOCK_O;
}

LOCK_O_direct;

while (frames > 0) {
frames_t f = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
frames_t f;
frames_t count;
u32_t *optr;
s32_t *optr;

IF_DIRECT(
optr = (s32_t *)outputbuf->writep;
f = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
);
IF_PROCESS(
optr = (s32_t *)process.inbuf;
f = process.max_in_frames;
);

f = min(f, frames);

count = f;
optr = (u32_t *)outputbuf->writep;

if (bits_per_sample == 16) {
if (bits_per_sample == 8) {
while (count--) {
*optr++ = *lptr++ << 24;
*optr++ = *rptr++ << 24;
}
} else if (bits_per_sample == 16) {
while (count--) {
*optr++ = *lptr++ << 16;
*optr++ = *rptr++ << 16;
Expand All @@ -119,15 +146,27 @@ static FLAC__StreamDecoderWriteStatus write_cb(const FLAC__StreamDecoder *decode
*optr++ = *lptr++ << 8;
*optr++ = *rptr++ << 8;
}
} else if (bits_per_sample == 32) {
while (count--) {
*optr++ = *lptr++;
*optr++ = *rptr++;
}
} else {
LOG_ERROR("unsupported bits per sample: %u", bits_per_sample);
}

frames -= f;
_buf_inc_writep(outputbuf, f * BYTES_PER_FRAME);

IF_DIRECT(
_buf_inc_writep(outputbuf, f * BYTES_PER_FRAME);
);
IF_PROCESS(
process.in_frames = f;
if (frames) LOG_ERROR("unhandled case");
);
}

UNLOCK_O;
UNLOCK_O_direct;

return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
Expand Down
Loading

0 comments on commit ce95728

Please sign in to comment.