Пример #1
0
	void PrepareFFTChunk(audio_chunk const & source, audio_chunk & out, double centerOffset) {
		const t_size channels = source.get_channel_count();
		const t_uint32 sampleRate = source.get_sample_rate();
		FB2K_DYNAMIC_ASSERT( sampleRate > 0 );
		out.set_channels(channels, source.get_channel_config());
		out.set_sample_rate(sampleRate);
		const t_size inSize = source.get_sample_count();
		const t_size fftSize = MatchFFTSize(inSize);
		out.set_sample_count(fftSize);
		out.set_data_size(fftSize * channels);
		if (fftSize >= inSize) { //rare case with *REALLY* small input
			pfc::memcpy_t( out.get_data(), source.get_data(), inSize * channels );
			pfc::memset_null_t( out.get_data() + inSize * channels, (fftSize - inSize) * channels );
		} else { //inSize > fftSize, we're using a subset of source chunk for the job, pick a subset around centerOffset.
			const double baseOffset = pfc::max_t<double>(0, centerOffset - 0.5 * (double)fftSize / (double)sampleRate);
			const t_size baseSample = pfc::min_t<t_size>( (t_size) audio_math::time_to_samples(baseOffset, sampleRate), inSize - fftSize);
			pfc::memcpy_t( out.get_data(), source.get_data() + baseSample * channels, fftSize * channels);
		}
	}
Пример #2
0
void output_impl::process_samples(const audio_chunk & p_chunk) {
	pfc::dynamic_assert(m_incoming_ptr == m_incoming.get_size());
	t_samplespec spec;
	spec.fromchunk(p_chunk);
	if (!spec.is_valid()) pfc::throw_exception_with_message< exception_io_data >("Invalid audio stream specifications");
	m_incoming_spec = spec;
	t_size length = p_chunk.get_used_size();
	m_incoming.set_data_fromptr(p_chunk.get_data(),length);
	m_incoming_ptr = 0;
}
Пример #3
0
 bool decode_run(audio_chunk &chunk, abort_callback &abort)
 {
     if (m_current_packet >= m_demuxer->num_packets() + 1)
         return false;
     int64_t pull_packet = m_current_packet;
     if (m_current_packet == m_demuxer->num_packets()) {
         /*
          * If the end padding is shorter than the decoder delay,
          * we already have fed all packets to the decoder but still
          * we have to feed extra packet to pull the final delayed result.
          * Due to overlap+add, samples might not be fully reconstructed
          * anyway...
          */
         if (decoder_delay() <= m_demuxer->end_padding())
             return false;
         else
             pull_packet = m_current_packet - 1;
     }
     auto asbd = m_demuxer->format().asbd;
     uint32_t fpp  = asbd.mFramesPerPacket;
     uint32_t npackets = m_demuxer->read_packets(pull_packet,
                                                 m_packets_per_chunk,
                                                 &m_chunk_buffer, abort);
     if (npackets == 0)
         return false;
     m_current_packet += npackets;
     int64_t trim = std::max(m_current_packet * fpp - m_demuxer->duration()
                             - m_demuxer->start_offset() - decoder_delay(),
                             static_cast<int64_t>(0));
     if (trim >= fpp * npackets)
         return false;
     m_decoder->decode(m_chunk_buffer.data(), m_chunk_buffer.size(),
                       chunk, abort);
     t_size nframes = chunk.get_sample_count();
     unsigned nchannels = chunk.get_channels();
     if (trim > 0) {
         nframes = fpp * npackets - trim;
         chunk.set_sample_count(nframes);
     }
     if (m_start_skip) {
         if (m_start_skip >= nframes) {
             m_start_skip -= nframes;
             return decode_run(chunk, abort);
         }
         uint32_t rest = nframes - m_start_skip;
         uint32_t bpf  = nchannels * sizeof(audio_sample);
         audio_sample *bp = chunk.get_data();
         std::memmove(bp, bp + m_start_skip * nchannels, rest * bpf);
         chunk.set_sample_count(rest);
         m_start_skip = 0;
     }
     update_dynamic_vbr_info(m_current_packet - npackets, m_current_packet);
     return true;
 }