Exemplo n.º 1
0
/*---------------------------------------------------------------------------*/
static void *decode_thread(struct thread_ctx_s *ctx) {
	while (ctx->decode_running) {
		size_t bytes, space, min_space;
		bool toend;
		bool ran = false;

		LOCK_S;
		bytes = _buf_used(ctx->streambuf);
		toend = (ctx->stream.state <= DISCONNECT);
		UNLOCK_S;
		LOCK_O;
		space = _buf_space(ctx->outputbuf);
		UNLOCK_O;

		LOCK_D;

		if (ctx->decode.state == DECODE_RUNNING && ctx->codec) {

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

			IF_DIRECT(
				min_space = ctx->codec->min_space;
			);
			IF_PROCESS(
				min_space = ctx->process.max_out_frames * BYTES_PER_FRAME;
			);
Exemplo n.º 2
0
static FLAC__StreamDecoderWriteStatus write_cb(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame,
											   const FLAC__int32 *const buffer[], void *client_data) {

	size_t frames = frame->header.blocksize;
	unsigned bits_per_sample = frame->header.bits_per_sample;
	unsigned channels = frame->header.channels;

	FLAC__int32 *lptr = (FLAC__int32 *)buffer[0];
	FLAC__int32 *rptr = (FLAC__int32 *)buffer[channels > 1 ? 1 : 0];
	
	if (decode.new_stream) {
		LOCK_O;
		LOG_INFO("setting track_start");
		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;
		frames_t count;
		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;
		);
Exemplo n.º 3
0
static decode_state mpg_decode(void) {
    size_t bytes, space, size;
    int ret;
    u8_t *write_buf;

    LOCK_S;
    LOCK_O_direct;
    bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));

    IF_DIRECT(
        space = min(_buf_space(outputbuf), _buf_cont_write(outputbuf));
        write_buf = outputbuf->writep;
    );
Exemplo n.º 4
0
static decode_state vorbis_decode(void) {
	static int channels;
	bool end;
	frames_t frames;
	int bytes, s, n;
	u8_t *write_buf;

	LOCK_S;
	LOCK_O_direct;
	end = (stream.state <= DISCONNECT);

	IF_DIRECT(
		frames = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
	);
Exemplo n.º 5
0
static FLAC__StreamDecoderWriteStatus write_cb(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame,
											   const FLAC__int32 *const buffer[], void *client_data) {

	size_t frames = frame->header.blocksize;
	unsigned bits_per_sample = frame->header.bits_per_sample;
	unsigned channels = frame->header.channels;

	FLAC__int32 *lptr = (FLAC__int32 *)buffer[0];
	FLAC__int32 *rptr = (FLAC__int32 *)buffer[channels > 1 ? 1 : 0];
	
	if (decode.new_stream) {
		LOCK_O;
		LOG_INFO("setting track_start");
		output.track_start = outputbuf->writep;
		decode.new_stream = false;

#if DSD
		if (output.has_dop && bits_per_sample == 24 && is_flac_dop((u32_t *)lptr, (u32_t *)rptr, frames)) {
			LOG_INFO("file contains DOP");
			output.next_dop = true;
			output.next_sample_rate = frame->header.sample_rate;
			output.fade = FADE_INACTIVE;
		} else {
			output.next_sample_rate = decode_newstream(frame->header.sample_rate, output.supported_rates);
			output.next_dop = false;
			if (output.fade_mode) _checkfade(true);
		}
#else
		output.next_sample_rate = decode_newstream(frame->header.sample_rate, output.supported_rates);
		if (output.fade_mode) _checkfade(true);
#endif

		UNLOCK_O;
	}

	LOCK_O_direct;

	while (frames > 0) {
		frames_t f;
		frames_t count;
		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;
		);
Exemplo n.º 6
0
static void *decode_thread() {

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

		LOCK_S;
		bytes = _buf_used(streambuf);
		toend = (stream.state <= DISCONNECT);
		UNLOCK_S;
		LOCK_O;
		space = _buf_space(outputbuf);
		UNLOCK_O;

		LOCK_D;

		if (decode.state == DECODE_RUNNING && codec) {
		
			LOG_SDEBUG("streambuf bytes: %u outputbuf space: %u", bytes, space);
			
			if (space > codec->min_space && (bytes > codec->min_read_bytes || toend)) {
				
				decode.state = codec->decode();

				if (decode.state != DECODE_RUNNING) {

					LOG_INFO("decode %s", decode.state == DECODE_COMPLETE ? "complete" : "error");

					LOCK_O;
					if (output.fade_mode) _checkfade(false);
					UNLOCK_O;

					wake_controller();
				}

				ran = true;
			}
		}
		
		UNLOCK_D;

		if (!ran) {
			usleep(100000);
		}
	}

	return 0;
}
Exemplo n.º 7
0
static decode_state mpg_decode(void) {
	size_t bytes, space, size;
	int ret;

	LOCK_S;
	LOCK_O;
	bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
	space = min(_buf_space(outputbuf), _buf_cont_write(outputbuf));
	bytes = min(bytes, READ_SIZE);
	space = min(space, WRITE_SIZE);

	if (stream.state <= DISCONNECT && bytes == 0) {
		UNLOCK_O;
		UNLOCK_S;
		return DECODE_COMPLETE;
	}

	if (m->use16bit) {
		space = (space / BYTES_PER_FRAME) * 4;
	}

	ret = m->mpg123_decode(m->h, streambuf->readp, bytes, outputbuf->writep, space, &size);

	if (ret == MPG123_NEW_FORMAT) {

		if (decode.new_stream) {
			long rate;
			int channels, enc;
			
			m->mpg123_getformat(m->h, &rate, &channels, &enc);
			
			LOG_INFO("setting track_start");
			output.next_sample_rate = rate;
			output.track_start = outputbuf->writep;
			if (output.fade_mode) _checkfade(true);
			decode.new_stream = false;

		} else {
			LOG_WARN("format change mid stream - not supported");
		}
	}

	// expand 16bit output to 32bit samples
	if (m->use16bit) {
		s16_t *iptr;
		s32_t *optr;
		size_t count = size / 2;
		size = count * 4;
		iptr = (s16_t *)outputbuf->writep + count;
		optr = (s32_t *)outputbuf->writep + count;
		while (count--) {
			*--optr = *--iptr << 16;
		}
	}

	_buf_inc_readp(streambuf, bytes);
	_buf_inc_writep(outputbuf, size);

	UNLOCK_O;
	UNLOCK_S;

	LOG_SDEBUG("write %u frames", size / BYTES_PER_FRAME);

	if (ret == MPG123_DONE) {
		LOG_INFO("stream complete");
		return DECODE_COMPLETE;
	}

	if (ret == MPG123_ERR) {
		LOG_WARN("Error");
		return DECODE_COMPLETE;
	}

	// OK and NEED_MORE keep running
	return DECODE_RUNNING;
}