Процесс записи инициируется путем обнаружения активности микрофона на уровне операционной системы, в результате чего создаются два отдельных необработанных файла. файлы — по одному для каждого аудиоканала.
Один канал захватывает входной сигнал микрофона, а другой записывает выходной сигнал динамиков, образуя двухканальную запись.
После остановки записи эти два файла объединяются в один стереофайл, причем один канал предназначен для локального пользователя на компьютере, а другой — для входящего звука с удаленного динамика.
В настоящее время , приложение работает эффективно, но ему не хватает функций предварительной обработки звука и эхоподавления.
Этот недостаток приводит к тому, что микрофон улавливает звук из динамиков и добавляет его в канал микрофона.
Эта проблема не затрагивает канал динамиков. Очевидно, что эта проблема не возникает при использовании наушников, поскольку в этом случае микрофон ничего не слышит из динамиков.
В отличие от нашего приложения, стандартные коммуникационные платформы, такие как Microsoft Teams, Zoom, Skype, В Viber и WhatsApp для Windows используются механизмы, которые не позволяют микрофону захватывать звук, выводимый из динамиков, что позволяет избежать петли обратной связи, когда удаленные участники могут услышать эхо своих голосов.
Мне нужна ваша помощь. внедрить эту функцию в наше существующее приложение, которое позволяет микрофону изолировать и устранять шум и звук из динамиков, гарантируя, что он записывает только звук локального пользователя во время конференц-связи.
Я прикрепляю код для записи с микрофона.
Мне нужно добавить профессиональную обработку, где мы можем эхоподавлять в коде ниже:
// ЗАДАЧА: применить алгоритм эхоподавления к pData< /strong>
Код: Выделить всё
bool AudioCapture::CaptureMicrophoneAudio(const wchar_t* outputFilePath)
{
// Activate audio client
IAudioClient* pAudioClient = nullptr;
HRESULT hr = pDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&pAudioClient);
if (FAILED(hr)) {
logger->Log("Error activating audio client: ");
pDevice->Release();
//CoUninitialize();
return false;
}
// Get mix format
WAVEFORMATEX* pWaveFormat = nullptr;
hr = pAudioClient->GetMixFormat(&pWaveFormat);
if (FAILED(hr)) {
logger->Log("Error getting mix format: ");
pAudioClient->Release();
pDevice->Release();
//CoUninitialize();
return false;
}
logger->Log("WAVEFORMATEX: nChannels - " + std::to_string(pWaveFormat->nChannels));
logger->Log("WAVEFORMATEX: nSamplesPerSec - " + std::to_string(pWaveFormat->nSamplesPerSec));
logger->Log("WAVEFORMATEX: wBitsPerSample - " + std::to_string(pWaveFormat->wBitsPerSample));
logger->Log("WAVEFORMATEX: wFormatTag - " + std::to_string(pWaveFormat->wFormatTag));
logger->Log("WAVEFORMATEX: cbSize - " + std::to_string(pWaveFormat->cbSize));
logger->Log("WAVEFORMATEX: nAvgBytesPerSec - " + std::to_string(pWaveFormat->nAvgBytesPerSec));
logger->Log("WAVEFORMATEX: nBlockAlign - " + std::to_string(pWaveFormat->nBlockAlign));
nMicChannels = pWaveFormat->nChannels;
nMicSamplesPerSec = pWaveFormat->nSamplesPerSec;
wMicBitsPerSample = pWaveFormat->wBitsPerSample;
nMicAvgBytesPerSec = pWaveFormat->nAvgBytesPerSec;
// Initialize audio client with the mix format
hr = pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, 0, 0, 0, pWaveFormat, NULL);
if (FAILED(hr)) {
logger->Log("Error initializing audio client: ");
CoTaskMemFree(pWaveFormat);
pAudioClient->Release();
pDevice->Release();
//CoUninitialize();
return false;
}
// Get capture client
IAudioCaptureClient* pCaptureClient = nullptr;
hr = pAudioClient->GetService(__uuidof(IAudioCaptureClient), (void**)&pCaptureClient);
if (FAILED(hr)) {
logger->Log("Error getting capture client: ");
CoTaskMemFree(pWaveFormat);
pAudioClient->Release();
pDevice->Release();
// CoUninitialize();
return false;
}
// Open binary file for writing
std::string tempFilePath = Utils::GetTempFilename("Audio_mic_capture", "raw");
logger->Log(tempFilePath);
std::ofstream outFile(tempFilePath, std::ios::binary);
if (!outFile.is_open()) {
logger->Log("Error opening binary file for writing");
CoTaskMemFree(pWaveFormat);
pCaptureClient->Release();
pAudioClient->Release();
pDevice->Release();
// CoUninitialize();
return false;
}
// Start capturing
hr = pAudioClient->Start();
if (FAILED(hr))
{
logger->Log("Error starting audio client: ");
CoTaskMemFree(pWaveFormat);
pCaptureClient->Release();
pAudioClient->Release();
pDevice->Release();
// CoUninitialize();
return false;
}
// Main loop for capturing and writing to file
while (!exitFlag)
{
// Capture audio data
// Read audio data from pCaptureClient
BYTE* pData;
UINT32 numFramesAvailable;
DWORD flags;
hr = pCaptureClient->GetBuffer(&pData, &numFramesAvailable, &flags, NULL, NULL);
if (FAILED(hr))
{
logger->Log("Error getting audio buffer: ");
break;
}
//
// TODO: Apply echo cancellation algorithm to pData
//
// Write audio data to file
int count = numFramesAvailable * pWaveFormat->nBlockAlign;
outFile.write(reinterpret_cast(pData), count);
// Release the buffer
hr = pCaptureClient->ReleaseBuffer(numFramesAvailable);
if (FAILED(hr))
{
logger->Log("Error releasing audio buffer: ");
break;
}
}
logger->Log("Capturing Completed");
// Close binary file
outFile.close();
// Stop capturing
pAudioClient->Stop();
// Clean up resources
CoTaskMemFree(pWaveFormat);
pCaptureClient->Release();
pAudioClient->Release();
pDevice->Release();
// CoUninitialize();
// convert to mp3 and delete temp file
std::string tempFilePathMp3 = Utils::GetTempFilename("Audio_capture_mic", "mp3");
tempMicFilePathWMp3 = std::wstring(tempFilePathMp3.begin(), tempFilePathMp3.end());
std::wstring tempFilePathW(tempFilePath.begin(), tempFilePath.end());
if (!convertToMp3(tempFilePathW, tempMicFilePathWMp3, nMicChannels, nMicSamplesPerSec, wMicBitsPerSample, nMicAvgBytesPerSec))
{
logger->Log("Failed to convert to MP3");
}
else
{
logger->Log("Saved to MP3 data");
}
// Remove temp file
std::remove(tempFilePath.c_str());
return true;
}

Ждем вашего опыта для получения рекомендаций.
Подробнее здесь: https://stackoverflow.com/questions/781 ... -windows-c