Add Music fluctuations project and Chinese plan docs

This commit is contained in:
2026-03-21 15:55:54 +08:00
parent 629455df07
commit a172d75e36
462 changed files with 382904 additions and 0 deletions

View 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;
}