Beispiel #1
0
/* This should be called with a unique decoder instance as the seeking
 * it does triggers an FAAD bug which results in distorted audio due to
 * retained state being corrupted.  (One suspects NeAACDecPostSeekReset()
 * should resolve the problem but experimentation suggests not and no
 * documentation exists describing its use.) */
static int aac_count_time (struct aac_data *data)
{
	NeAACDecFrameInfo frame_info;
	int samples = 0, bytes = 0, frames = 0;
	off_t file_size;
	int16_t *sample_buf;

	file_size = io_file_size (data->stream);
	if (file_size == -1)
		return -1;

	if (io_seek(data->stream, file_size / 2, SEEK_SET) == -1)
		return -1;
	buffer_flush (data);

	/* Guess track length by decoding the middle 50 frames which have
	 * more than 25% of samples having absolute values greater than 16. */
	while (frames < 50) {
		if (buffer_fill_frame (data) <= 0)
			break;

		sample_buf = NeAACDecDecode (data->decoder, &frame_info,
		                             buffer_data (data), buffer_length (data));

		if (frame_info.error == 0 && frame_info.samples > 0) {
			unsigned int ix, zeroes = 0;

			for (ix = 0; ix < frame_info.samples; ix += 1) {
				if (RANGE(-16, sample_buf[ix], 16))
					zeroes += 1;
			}

			if (zeroes * 4 < frame_info.samples) {
				samples += frame_info.samples;
				bytes += frame_info.bytesconsumed;
				frames += 1;
			}
		}

		if (frame_info.bytesconsumed == 0)
			break;

		buffer_consume (data, frame_info.bytesconsumed);
	}

	if (frames == 0)
		return -1;

	samples /= frames;
	samples /= data->channels;
	bytes /= frames;

	return ((file_size / bytes) * samples) / data->sample_rate;
}
Beispiel #2
0
static int aac_count_time (struct aac_data *data)
{
	NeAACDecFrameInfo frame_info;
	int samples = 0, bytes = 0, frames = 0;
	off_t file_size;
	char *sample_buf;
	long saved_pos;

	file_size = io_file_size (data->stream);
	if (file_size == -1)
		return -1;

	saved_pos = io_tell (data->stream);

	/* guess track length by decoding the first 10 frames */
	while (frames < 10) {
		if (buffer_fill_frame(data) <= 0)
			break;

		sample_buf = NeAACDecDecode(data->decoder, &frame_info,
			buffer_data(data), buffer_length(data));
		if (frame_info.error == 0 && frame_info.samples > 0) {
			samples += frame_info.samples;
			bytes += frame_info.bytesconsumed;
			frames++;
		}
		if (frame_info.bytesconsumed == 0)
			break;

		buffer_consume (data, frame_info.bytesconsumed);
	}

	if (io_seek(data->stream, saved_pos, SEEK_SET) == (off_t)-1) {
		logit ("Can't seek after couting time");
		return -1;
	}

	if (frames == 0)
		return -1;

	samples /= frames;
	samples /= data->channels;
	bytes /= frames;

	return ((file_size / bytes) * samples) / data->sample_rate;
}
Beispiel #3
0
static void *aac_open_internal (struct io_stream *stream, const char *fname)
{
	struct aac_data *data;
	NeAACDecConfigurationPtr neaac_cfg;
	unsigned char channels;
	unsigned long sample_rate;
	int n;

	/* init private struct */
	data = xcalloc (1, sizeof *data);
	data->decoder = NeAACDecOpen();

	/* set decoder config */
	neaac_cfg = NeAACDecGetCurrentConfiguration(data->decoder);
	neaac_cfg->outputFormat = FAAD_FMT_16BIT;	/* force 16 bit audio */
	neaac_cfg->downMatrix = 1;			/* 5.1 -> stereo */
	neaac_cfg->dontUpSampleImplicitSBR = 0;		/* upsample, please! */
	NeAACDecSetConfiguration(data->decoder, neaac_cfg);

	if (stream)
		data->stream = stream;
	else {
		data->stream = io_open (fname, 1);
		if (!io_ok(data->stream)) {
			decoder_error (&data->error, ERROR_FATAL, 0,
					"Can't open AAC file: %s", io_strerror(data->stream));
			return data;
		}
	}

	/* find a frame */
	if (buffer_fill_frame(data) <= 0) {
		decoder_error (&data->error, ERROR_FATAL, 0,
				"Not a valid (or unsupported) AAC file");
		return data;
	}

	/* in case of a bug, make sure there is at least some data
	 * in the buffer for NeAACDecInit() to work with.
	 */
	if (buffer_fill_min(data, 256) <= 0) {
		decoder_error (&data->error, ERROR_FATAL, 0,
				"AAC file/stream too short");
		return data;
	}

	/* init decoder, returns the length of the header (if any) */
	channels = (unsigned char)data->channels;
	sample_rate = data->sample_rate;
	n = NeAACDecInit (data->decoder, buffer_data(data), buffer_length(data),
		&sample_rate, &channels);
	data->channels = channels;
	data->sample_rate = (int)sample_rate;
	if (n < 0) {
		decoder_error (&data->error, ERROR_FATAL, 0,
				"libfaad can't open this stream");
		return data;
	}

	logit ("sample rate %dHz, channels %d", data->sample_rate, data->channels);
	if (!data->sample_rate || !data->channels) {
		decoder_error (&data->error, ERROR_FATAL, 0,
				"Invalid AAC sound parameters");
		return data;
	}

	/* skip the header */
	logit ("skipping header (%d bytes)", n);
	buffer_consume (data, n);

	/*NeAACDecInitDRM(data->decoder, data->sample_rate, data->channels);*/

	data->ok = 1;
	return data;
}