mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Add experimental echo cancellation to qTox
It compiles with modified OpenAL (unchanged logic otherwise), but effectiveness needs testing (like uTox)
This commit is contained in:
parent
1c3bcd000c
commit
15917d1a01
|
@ -333,3 +333,23 @@ bool Audio::tryCaptureSamples(uint8_t* buf, int framesize)
|
|||
alcCaptureSamples(Audio::alInDev, buf, framesize);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
#include "audiofilterer.h"
|
||||
#include <AL/alext.h>
|
||||
|
||||
void Audio::getEchoesToFilter(AudioFilterer* filterer, int framesize)
|
||||
{
|
||||
#ifdef ALC_LOOPBACK_CAPTURE_SAMPLES
|
||||
ALint samples;
|
||||
alcGetIntegerv(Audio::alOutDev, ALC_LOOPBACK_CAPTURE_SAMPLES, sizeof(samples), &samples);
|
||||
if (samples >= framesize)
|
||||
{
|
||||
int16_t buf[framesize];
|
||||
alcCaptureSamplesLoopback(Audio::alOutDev, buf, framesize);
|
||||
filterer->passAudioOutput(buf, framesize);
|
||||
filterer->setEchoDelayMs(5); // This 5ms is configurable I believe
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,7 @@ class QTimer;
|
|||
class QThread;
|
||||
class QMutex;
|
||||
struct Tox;
|
||||
class AudioFilterer;
|
||||
|
||||
class Audio : QObject
|
||||
{
|
||||
|
@ -64,6 +65,11 @@ public:
|
|||
static void playGroupAudioQueued(Tox*, int group, int peer, const int16_t* data,
|
||||
unsigned samples, uint8_t channels, unsigned sample_rate, void*);
|
||||
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
static void getEchoesToFilter(AudioFilterer* filter, int framesize);
|
||||
// is a null op #ifndef ALC_LOOPBACK_CAPTURE_SAMPLES
|
||||
#endif
|
||||
|
||||
public slots:
|
||||
/// Must be called from the audio thread, plays a group call's received audio
|
||||
void playGroupAudio(int group, int peer, const int16_t* data,
|
||||
|
|
|
@ -35,15 +35,28 @@ void AudioFilterer::closeFilter()
|
|||
filter = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void AudioFilterer::filterAudio(int16_t* data, int framesize)
|
||||
bool AudioFilterer::filterAudio(int16_t* data, int framesize)
|
||||
{
|
||||
if (!filter)
|
||||
return;
|
||||
|
||||
filter_audio(filter, (int16_t*) data, framesize);
|
||||
return filter && 0 == filter_audio(filter, (int16_t*) data, framesize);
|
||||
}
|
||||
|
||||
/* Enable/disable filters. 1 to enable, 0 to disable. */
|
||||
bool AudioFilterer::enableDisableFilters(int echo, int noise, int gain)
|
||||
{
|
||||
return filter && 0 == enable_disable_filters(filter, echo, noise, gain);
|
||||
}
|
||||
|
||||
/* Give the audio output from your software to this function so it knows what echo to cancel from the frame */
|
||||
bool AudioFilterer::passAudioOutput(const int16_t *data, int samples)
|
||||
{
|
||||
return filter && 0 == pass_audio_output(filter, data, samples);
|
||||
}
|
||||
|
||||
/* Tell the echo canceller how much time in ms it takes for audio to be played and recorded back after. */
|
||||
bool AudioFilterer::setEchoDelayMs(int16_t msInSndCardBuf)
|
||||
{
|
||||
return filter && 0 == set_echo_delay_ms(filter, msInSndCardBuf);
|
||||
}
|
||||
|
||||
AudioFilterer::~AudioFilterer()
|
||||
{
|
||||
|
|
|
@ -28,11 +28,20 @@ class AudioFilterer
|
|||
public:
|
||||
explicit AudioFilterer() = default;
|
||||
~AudioFilterer();
|
||||
|
||||
void startFilter(unsigned int fs);
|
||||
void filterAudio(int16_t* data, int framesize);
|
||||
void closeFilter();
|
||||
|
||||
/* Enable/disable filters. 1 to enable, 0 to disable. */
|
||||
bool enableDisableFilters(int echo, int noise, int gain);
|
||||
|
||||
bool filterAudio(int16_t* data, int samples);
|
||||
|
||||
/* Give the audio output from your software to this function so it knows what echo to cancel from the frame */
|
||||
bool passAudioOutput(const int16_t *data, int samples);
|
||||
|
||||
/* Tell the echo canceller how much time in ms it takes for audio to be played and recorded back after. */
|
||||
bool setEchoDelayMs(int16_t msInSndCardBuf);
|
||||
|
||||
private:
|
||||
struct Filter_Audio* filter{nullptr};
|
||||
};
|
||||
|
|
|
@ -258,7 +258,12 @@ void Core::sendCallAudio(int callId, ToxAv* toxav)
|
|||
{
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
if (filterer[callId])
|
||||
{
|
||||
// is a null op #ifndef ALC_LOOPBACK_CAPTURE_SAMPLES
|
||||
Audio::getEchoesToFilter(filterer[callId], framesize);
|
||||
|
||||
filterer[callId]->filterAudio((int16_t*) buf, framesize);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t dest[bufsize];
|
||||
|
|
Loading…
Reference in New Issue
Block a user