#include"Reberation.h" #include Reberation::Reberation(int p_block_size, int p_sampling_rate, float p_reberation_time) : m_block_size(p_block_size), m_reberation_output_read_pos(0) { RenderImpulseResponse(p_block_size, p_sampling_rate, p_reberation_time); m_left_reberation_filter = new FFTFilter(m_block_size); m_left_reberation_filter->SetTimeDomainKernel(GetImpulseResponseLeft()); m_right_reberation_filter = new FFTFilter(m_block_size); m_right_reberation_filter->SetTimeDomainKernel(GetImpulseResponseRight()); m_reberation_input.reserve(m_block_size); m_reberation_output_left.resize(m_block_size, 0.0f); m_reberation_output_right.resize(m_block_size, 0.0f); } Reberation::~Reberation() { } void Reberation::RenderImpulseResponse(int p_block_size, int p_sampling_rate, float p_reberation_time) { m_impulse_response_left.resize(p_block_size, 0.0f); m_impulse_response_right.resize(p_block_size, 0.0f); int quiet_period = p_block_size; // filter_delay = block_size m_quiet_period_sec = static_cast(quiet_period) / static_cast(p_sampling_rate); const float exp_decay = -13.8155; srand(0); for (int i = 0; i < p_block_size; ++i) { float envelope = exp(exp_decay * (i + quiet_period) / p_sampling_rate / p_reberation_time); assert(envelope >= 0 && envelope <= 1.0); m_impulse_response_left[i] = FloatRand() * envelope; m_impulse_response_right[i] = FloatRand() * envelope; } } float Reberation::GetQuietPeriod() const { return m_quiet_period_sec; } void Reberation::AddReberation(const std::vector& p_input, std::vector* p_output_left, std::vector* p_output_right) { assert(p_output_left && p_output_right); assert(p_output_left->size() == p_output_right->size()); assert(p_input.size() == p_output_right->size()); for (int i = 0; i < p_input.size(); ++i) { (*p_output_left)[i] += m_reberation_output_left[m_reberation_output_read_pos]; (*p_output_right)[i] += m_reberation_output_right[m_reberation_output_read_pos]; ++m_reberation_output_read_pos; } m_reberation_input.insert(m_reberation_input.end(), p_input.begin(), p_input.end()); if (m_reberation_output_read_pos == m_block_size) { m_left_reberation_filter->AddSignalBlock(m_reberation_input); m_right_reberation_filter->AddSignalBlock(m_reberation_input); m_reberation_input.clear(); m_left_reberation_filter->GetResult(&m_reberation_output_left); m_right_reberation_filter->GetResult(&m_reberation_output_right); m_reberation_output_read_pos = 0; } assert(m_reberation_output_read_pos < m_block_size); } float Reberation::FloatRand() { return static_cast(rand()) / static_cast(RAND_MAX); } const std::vector& Reberation::GetImpulseResponseLeft() const { return m_impulse_response_left; } const std::vector& Reberation::GetImpulseResponseRight() const { return m_impulse_response_right; }