#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; //---------------------------------------------------------待删 std::vector lowPassKernel(64, 0.0f); float cutoffFrequency = 1000.0f; // 截止频率为1000 Hz float nyquistFrequency = 0.5f * 44100.0f; // Nyquist频率 int numTaps = 64; // 滤波器长度 for (int i = 0; i < numTaps; ++i) { float frequency = i * nyquistFrequency / numTaps; if (frequency <= cutoffFrequency) { lowPassKernel[i] = 1.0f; // 低通滤波器 } } m_filter.SetTimeDomainKernel(lowPassKernel); } AudioSource::~AudioSource() { m_historyEnergys.clear(); } void AudioSource::HRTFInitialize() { /*hrtf-filter*/ m_hrtf.SetDirection(0, 0); std::vector 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:检查音频文件的后缀名,用相应的filereader打开 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 samples; for (int i = 0; i < m_bufferSize; i++) { m_sampleIndex++; std::vector 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 hrtfLeft(m_bufferSize / 2, 0); std::vector hrtfRight(m_bufferSize / 2, 0); for (int i = 0; i < AUDIO_BUFFER_SIZE / 2 / 128; i++) { std::vector subSamples(128); std::vector subHrtfLeft(128); std::vector 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 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 newHrtfLeft(m_bufferSize / 2, 0); std::vector newHrtfRight(m_bufferSize / 2, 0); for (int i = 0; i < AUDIO_BUFFER_SIZE / 2 / 128; i++) { std::vector subSamples(128); std::vector subHrtfLeft(128); std::vector 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& p_block_last, const std::vector& p_block_next, std::vector* 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 samples; for (int i = 0; i < m_bufferSize; i++) { m_sampleIndex++; std::vector 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 reberationLeft(m_bufferSize / 2, 0); std::vector 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 samples; for (int i = 0; i < m_bufferSize; i++) { m_sampleIndex++; std::vector 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 hrtfLeft(m_bufferSize / 2, 0); std::vector hrtfRight(m_bufferSize / 2, 0); for (int i = 0; i < AUDIO_BUFFER_SIZE / 2 / 128; i++) { std::vector subSamples(128); std::vector subHrtfLeft(128); std::vector 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]; } } */