// (virtual)
int PcmDecoder::decode(
    int dst_count,
    int16_t* dst_data)
{
    if (dst_count <= 0)
        return 0;

    if (dst_data == NULL)
        return 0;

    if (offset_ >= dst_count_)
        return 0;

    int actual_count = 0;
    const uint8_t* src_samples = static_cast<const uint8_t*>(get_raw_data());

    int64_t offset = offset_;

    int cached_index = -1;
    int16_t cached_sample = 0;

    for (int i = 0; i < dst_count && offset < dst_count_; ++i) {
        int src_index = static_cast<int>((offset * dst_ratio_) >> 16);

        if (src_index != cached_index) {
            cached_index = src_index;
            cached_sample = pcm8_to_pcm16(src_samples[src_index]);
        }

        dst_data[i] = cached_sample;

        ++offset;
        ++actual_count;
    }

    offset = offset_;

    for (int i = 0; i < actual_count; ++i) {
        if (!(i == 0 && offset == 0)) {
            int16_t prev_sample;

            if (i > 0)
                prev_sample = dst_data[i - 1];
            else
                prev_sample = last_sample_;

            dst_data[i] = static_cast<int16_t>(
                (alpha_ * dst_data[i]) +
                (one_minus_alpha_ * prev_sample));
        }

        ++offset;
    }

    offset_ = offset;
    last_sample_ = dst_data[actual_count - 1];

    return actual_count;
}
示例#2
0
int PcmDecoder::decode(
	const int dst_count,
	std::int16_t* const dst_data)
{
	if (dst_count <= 0)
	{
		return 0;
	}

	if (!dst_data)
	{
		return 0;
	}

	if (offset_ >= dst_count_)
	{
		return 0;
	}

	auto actual_count = 0;

	const auto src_samples = static_cast<const std::uint8_t*>(get_raw_data());

	auto offset = offset_;

	auto cached_index = -1;
	auto cached_sample = std::int16_t{};

	for (int i = 0; i < dst_count && offset < dst_count_; ++i)
	{
		const auto src_index = static_cast<int>((offset * dst_ratio_) >> 16);

		if (src_index != cached_index)
		{
			cached_index = src_index;
			cached_sample = pcm8_to_pcm16(src_samples[src_index]);
		}

		dst_data[i] = cached_sample;

		++offset;
		++actual_count;
	}

	offset = offset_;

	for (int i = 0; i < actual_count; ++i)
	{
		if (!(i == 0 && offset == 0))
		{
			auto prev_sample = std::int16_t{};

			if (i > 0)
			{
				prev_sample = dst_data[i - 1];
			}
			else
			{
				prev_sample = last_sample_;
			}

			dst_data[i] = static_cast<std::int16_t>((alpha_ * dst_data[i]) + (one_minus_alpha_ * prev_sample));
		}

		++offset;
	}

	offset_ = offset;
	last_sample_ = dst_data[actual_count - 1];

	return actual_count;
}