Add Music fluctuations project and Chinese plan docs
This commit is contained in:
82
MVS/Music fluctuations/source/audio3d/Reberation.cpp
Normal file
82
MVS/Music fluctuations/source/audio3d/Reberation.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include"Reberation.h"
|
||||
#include<assert.h>
|
||||
|
||||
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<float>(quiet_period) / static_cast<float>(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<float>& p_input, std::vector<float>* p_output_left, std::vector<float>* 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<float>(rand()) / static_cast<float>(RAND_MAX);
|
||||
}
|
||||
|
||||
const std::vector<float>& Reberation::GetImpulseResponseLeft() const {
|
||||
return m_impulse_response_left;
|
||||
}
|
||||
|
||||
const std::vector<float>& Reberation::GetImpulseResponseRight() const {
|
||||
return m_impulse_response_right;
|
||||
}
|
||||
Reference in New Issue
Block a user