Files
XCEngine/MVS/Music fluctuations/source/audio/AudioSource.cpp

373 lines
8.9 KiB
C++
Raw Normal View History

#include"AudioSource.h"
AudioSource::AudioSource():
m_filter(64),
m_reberation(AUDIO_BUFFER_SIZE / 2, 44100, 0.5f),
m_hrtf_filter_L(128),
m_hrtf_filter_R(128)
{
HRTFInitialize();
return;
//---------------------------------------------------------<2D><>ɾ
std::vector<float> lowPassKernel(64, 0.0f);
float cutoffFrequency = 1000.0f; // <20><>ֹƵ<D6B9><C6B5>Ϊ1000 Hz
float nyquistFrequency = 0.5f * 44100.0f; // NyquistƵ<74><C6B5>
int numTaps = 64; // <20>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (int i = 0; i < numTaps; ++i) {
float frequency = i * nyquistFrequency / numTaps;
if (frequency <= cutoffFrequency) {
lowPassKernel[i] = 1.0f; // <20><>ͨ<EFBFBD>˲<EFBFBD><CBB2><EFBFBD>
}
}
m_filter.SetTimeDomainKernel(lowPassKernel);
}
AudioSource::~AudioSource()
{
m_historyEnergys.clear();
}
void AudioSource::HRTFInitialize()
{
/*hrtf-filter*/
m_hrtf.SetDirection(0, 0);
std::vector<float> hrtfData;
m_hrtf.GetLeftEarTimeHRTF(hrtfData);
for (int i = 0; i < 128; i++)
{
hrtfData[i] /= (float)32767;
}
m_hrtf_filter_L.SetTimeDomainKernel(hrtfData);
hrtfData.clear();
m_hrtf.GetRightEarTimeHRTF(hrtfData);
for (int i = 0; i < 128; i++)
{
hrtfData[i] /= (float)32767;
}
m_hrtf_filter_R.SetTimeDomainKernel(hrtfData);
/*fade-window*/
m_fade_window.resize(m_bufferSize / 2.);
double phase_step = PI / 2. / (m_bufferSize / 2. - 1);
for (int i = 0; i < m_bufferSize / 2.; i++)
{
m_fade_window[i] = sin(i * phase_step);
m_fade_window[i] *= m_fade_window[i];
}
}
void AudioSource::Play()
{
if (!m_isLoaded) { return; }
m_isActive = true;
m_lastingTime = 0;
}
void AudioSource::Load(AudioClip* p_clip)
{
m_isLoaded = false;
//TODO:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ļ<EFBFBD><C4BC>ĺ<EFBFBD>׺<EFBFBD><D7BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>filereader<65><72><EFBFBD><EFBFBD>
m_wavReader = new WavFileReader();
if (!m_wavReader->OpenFile(std::string(p_clip->GetName()))) { return; }
m_isLoaded = true;
m_audioClip = p_clip;
m_energyRate = m_wavReader->GetSampleRate() / (float)1024;
}
void AudioSource::Update(double p_deltaTime)
{
if (!m_isActive || !m_audioClip) { return; }
m_lastingTime += p_deltaTime;
/*energy-detect*/
if (m_isEnergyDetecting)
{
int index = m_lastingTime * m_energyRate;
/*this-energy*/
m_thisEnergy = 0;
for (int i = 0; i < m_wavReader->GetChannels() * 1024; i++)
{
m_thisEnergy += pow(m_wavReader->GetSampleValue(m_wavReader->GetChannels() * 1024 * index + i), 2);
}
/*averge-energy*/
for (int j = m_avergeOldIndex + 1; j < index; j++)
{
long long historyEnergy = 0;
for (int i = 0; i < m_wavReader->GetChannels() * 1024; i++)
{
historyEnergy += pow(m_wavReader->GetSampleValue(m_wavReader->GetChannels() * 1024 * j + i), 2);
}
/*calaulate-averge*/
if (m_avergeOldIndex < (int)m_energyRate - 1)
{
m_avergeEnergy *= m_avergeOldIndex;
m_avergeEnergy += historyEnergy;
m_avergeOldIndex += 1;
m_avergeEnergy /= m_avergeOldIndex;
m_historyEnergys.push_front(historyEnergy);
}
else
{
m_avergeEnergy *= (int)m_energyRate;
m_avergeEnergy += historyEnergy;
m_historyEnergys.push_front(historyEnergy);
m_avergeEnergy -= m_historyEnergys.back();
m_avergeEnergy /= (int)m_energyRate;
m_avergeOldIndex += 1;
m_historyEnergys.pop_back();
}
}
m_thisEnergyScale = m_avergeEnergy == 0 ? 0 : m_thisEnergy / (float)m_avergeEnergy;
m_thisEnergyScale = m_thisEnergyScale < m_maxEnergyScale ? m_thisEnergyScale : m_maxEnergyScale;
}
}
float AudioSource::GetEnergy()
{
return m_thisEnergyScale;
}
void AudioSource::StartEnergyDetect()
{
m_isEnergyDetecting = true;
}
void AudioSource::CloseEnergyDetect()
{
m_isEnergyDetecting = false;
}
short* AudioSource::GetBufferData()
{
return m_buffer;
}
void AudioSource::PrepareBufferData()
{
/*dry-audio*/
float sample = 0;
std::vector<float> samples;
for (int i = 0; i < m_bufferSize; i++)
{
m_sampleIndex++;
std::vector<float> data;
if (m_sampleIndex >= m_wavReader->GetSampleNum())
{
sample += 0;
m_isActive = false;
continue;
}
sample += m_wavReader->GetSampleValue(m_sampleIndex);
if (i % 2 == 1)
{
samples.push_back(sample / 2.);
sample = 0;
}
}
//####/*hrtf*/####
/*caculate hrtf result*/
std::vector<float> hrtfLeft(m_bufferSize / 2, 0);
std::vector<float> hrtfRight(m_bufferSize / 2, 0);
for (int i = 0; i < AUDIO_BUFFER_SIZE / 2 / 128; i++)
{
std::vector<float> subSamples(128);
std::vector<float> subHrtfLeft(128);
std::vector<float> subHrtfRight(128);
std::copy(samples.begin() + i * 128, samples.begin() + (i + 1) * 128, subSamples.begin());
m_hrtf_filter_L.AddSignalBlock(subSamples);
m_hrtf_filter_L.GetResult(&subHrtfLeft);
std::copy(subHrtfLeft.begin(), subHrtfLeft.end(), hrtfLeft.begin() + 128 * i);
m_hrtf_filter_R.AddSignalBlock(subSamples);
m_hrtf_filter_R.GetResult(&subHrtfRight);
std::copy(subHrtfRight.begin(), subHrtfRight.end(), hrtfRight.begin() + 128 * i);
}
/*direction-changed*/
if (m_hrtf.SetDirection(m_elevation, m_azimuth))
{
/*change-kernel*/
std::vector<float> hrtfData;
m_hrtf.GetLeftEarTimeHRTF(hrtfData);
for (int i = 0; i < 128; i++)
{
hrtfData[i] /= (float)32767;
}
m_hrtf_filter_L.SetTimeDomainKernel(hrtfData);
hrtfData.clear();
m_hrtf.GetRightEarTimeHRTF(hrtfData);
for (int i = 0; i < 128; i++)
{
hrtfData[i] /= (float)32767;
}
m_hrtf_filter_R.SetTimeDomainKernel(hrtfData);
/*caculate new hrtf result*/
std::vector<float> newHrtfLeft(m_bufferSize / 2, 0);
std::vector<float> newHrtfRight(m_bufferSize / 2, 0);
for (int i = 0; i < AUDIO_BUFFER_SIZE / 2 / 128; i++)
{
std::vector<float> subSamples(128);
std::vector<float> subHrtfLeft(128);
std::vector<float> subHrtfRight(128);
std::copy(samples.begin() + i * 128, samples.begin() + (i + 1) * 128, subSamples.begin());
m_hrtf_filter_L.AddSignalBlock(subSamples);
m_hrtf_filter_L.GetResult(&subHrtfLeft);
std::copy(subHrtfLeft.begin(), subHrtfLeft.end(), newHrtfLeft.begin() + 128 * i);
m_hrtf_filter_R.AddSignalBlock(subSamples);
m_hrtf_filter_R.GetResult(&subHrtfRight);
std::copy(subHrtfRight.begin(), subHrtfRight.end(), newHrtfRight.begin() + 128 * i);
}
/*apply fade window*/
ApplyFadeWindow(hrtfLeft, newHrtfLeft, &hrtfLeft);
ApplyFadeWindow(hrtfRight, newHrtfRight, &hrtfRight);
}
for (int i = 0; i < m_bufferSize; i++)
{
if (i % 2 == 0)
{
m_buffer[i] = hrtfLeft[i / 2];
}
else
{
m_buffer[i] = hrtfRight[i / 2];
}
}
}
void AudioSource::ApplyFadeWindow(const std::vector<float>& p_block_last, const std::vector<float>& p_block_next, std::vector<float>* p_fade_result)
{
for (int i = 0; i < m_bufferSize / 2.; i++)
{
(*p_fade_result)[i] = p_block_last[i] * m_fade_window[m_bufferSize / 2. - 1 - i] + p_block_next[i] * m_fade_window[i];
}
}
void AudioSource::SetDirection(int p_elevation, int p_azimuth)
{
if (p_elevation > 90) { p_elevation = 90; }
if (p_elevation < -90) { p_elevation = -90; }
m_azimuth = p_azimuth;
m_elevation = p_elevation;
}
/*
float sample = 0;
std::vector<float> samples;
for (int i = 0; i < m_bufferSize; i++)
{
m_sampleIndex++;
std::vector<float> data;
if (m_sampleIndex >= m_wavReader->GetSampleNum())
{
sample += 0;
m_isActive = false;
continue;
}
sample += m_wavReader->GetSampleValue(m_sampleIndex);
if (i % 2 == 1)
{
samples.push_back(sample / 2.);
sample = 0;
}
}
std::vector<float> reberationLeft(m_bufferSize / 2, 0);
std::vector<float> reberationRight(m_bufferSize / 2, 0);
m_reberation.AddReberation(samples, &reberationLeft, &reberationRight);
for (int i = 0; i < m_bufferSize; i++)
{
if (i % 2 == 0)
{
m_buffer[i] = reberationLeft[i / 2];
}
else
{
m_buffer[i] = reberationRight[i / 2];
}
}
*/
/*
float sample = 0;
std::vector<float> samples;
for (int i = 0; i < m_bufferSize; i++)
{
m_sampleIndex++;
std::vector<float> data;
if (m_sampleIndex >= m_wavReader->GetSampleNum())
{
sample += 0;
m_isActive = false;
continue;
}
sample += m_wavReader->GetSampleValue(m_sampleIndex);
if (i % 2 == 1)
{
samples.push_back(sample / 2.);
sample = 0;
}
}
std::vector<float> hrtfLeft(m_bufferSize / 2, 0);
std::vector<float> hrtfRight(m_bufferSize / 2, 0);
for (int i = 0; i < AUDIO_BUFFER_SIZE / 2 / 128; i++)
{
std::vector<float> subSamples(128);
std::vector<float> subHrtfLeft(128);
std::vector<float> subHrtfRight(128);
std::copy(samples.begin() + i * 128, samples.begin() + (i + 1) * 128, subSamples.begin());
m_hrtf_filter_L.AddSignalBlock(subSamples);
m_hrtf_filter_L.GetResult(&subHrtfLeft);
std::copy(subHrtfLeft.begin(), subHrtfLeft.end(), hrtfLeft.begin() + 128 * i);
m_hrtf_filter_R.AddSignalBlock(subSamples);
m_hrtf_filter_R.GetResult(&subHrtfRight);
std::copy(subHrtfRight.begin(), subHrtfRight.end(), hrtfRight.begin() + 128 * i);
}
for (int i = 0; i < m_bufferSize; i++)
{
if (i % 2 == 0)
{
m_buffer[i] = hrtfLeft[i / 2];
}
else
{
m_buffer[i] = hrtfRight[i / 2];
}
}
*/
/*
for (int i = 0; i < m_bufferSize; i++)
{
if (i % 2 == 0)
{
m_buffer[i] = samples[i / 2];
}
else
{
m_buffer[i] = samples[i / 2];
}
}
*/