mirror of https://github.com/qTox/qTox.git
8 changed files with 196 additions and 131 deletions
@ -0,0 +1,112 @@ |
|||||||
|
#include "audio.h" |
||||||
|
#include "src/core.h" |
||||||
|
|
||||||
|
#include <QDebug> |
||||||
|
|
||||||
|
std::atomic<int> Audio::userCount{0}; |
||||||
|
ALCdevice* Audio::alInDev{nullptr}; |
||||||
|
ALCdevice* Audio::alOutDev{nullptr}; |
||||||
|
ALCcontext* Audio::alContext{0}; |
||||||
|
ALuint Audio::alMainSource{0}; |
||||||
|
|
||||||
|
void Audio::suscribeInput() |
||||||
|
{ |
||||||
|
if (userCount++) |
||||||
|
if (alInDev) |
||||||
|
alcCaptureStart(alInDev); |
||||||
|
} |
||||||
|
|
||||||
|
void Audio::unsuscribeInput() |
||||||
|
{ |
||||||
|
if (--userCount) |
||||||
|
if (alInDev) |
||||||
|
alcCaptureStop(alInDev); |
||||||
|
} |
||||||
|
|
||||||
|
void Audio::openInput(const QString& inDevDescr) |
||||||
|
{ |
||||||
|
auto* tmp = alInDev; |
||||||
|
alInDev = nullptr; |
||||||
|
alcCaptureCloseDevice(tmp); |
||||||
|
int stereoFlag = av_DefaultSettings.audio_channels==1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; |
||||||
|
if (inDevDescr.isEmpty()) |
||||||
|
alInDev = alcCaptureOpenDevice(nullptr,av_DefaultSettings.audio_sample_rate, stereoFlag, |
||||||
|
(av_DefaultSettings.audio_frame_duration * av_DefaultSettings.audio_sample_rate * 4) |
||||||
|
/ 1000 * av_DefaultSettings.audio_channels); |
||||||
|
else |
||||||
|
alInDev = alcCaptureOpenDevice(inDevDescr.toStdString().c_str(),av_DefaultSettings.audio_sample_rate, stereoFlag, |
||||||
|
(av_DefaultSettings.audio_frame_duration * av_DefaultSettings.audio_sample_rate * 4) |
||||||
|
/ 1000 * av_DefaultSettings.audio_channels); |
||||||
|
if (!alInDev) |
||||||
|
qWarning() << "Audio: Cannot open input audio device"; |
||||||
|
else |
||||||
|
qDebug() << "Audio: Opening audio input "<<inDevDescr; |
||||||
|
|
||||||
|
Core::getInstance()->resetCallSources(); // Force to regen each group call's sources
|
||||||
|
|
||||||
|
// Restart the capture if necessary
|
||||||
|
if (userCount.load() != 0) |
||||||
|
alcCaptureStart(alInDev); |
||||||
|
} |
||||||
|
|
||||||
|
void Audio::openOutput(const QString& outDevDescr) |
||||||
|
{ |
||||||
|
auto* tmp = alOutDev; |
||||||
|
alOutDev = nullptr; |
||||||
|
alcCloseDevice(tmp); |
||||||
|
if (outDevDescr.isEmpty()) |
||||||
|
alOutDev = alcOpenDevice(nullptr); |
||||||
|
else |
||||||
|
alOutDev = alcOpenDevice(outDevDescr.toStdString().c_str()); |
||||||
|
if (!alOutDev) |
||||||
|
{ |
||||||
|
qWarning() << "Audio: Cannot open output audio device"; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
alcDestroyContext(alContext); |
||||||
|
alContext=alcCreateContext(alOutDev,nullptr); |
||||||
|
if (!alcMakeContextCurrent(alContext)) |
||||||
|
{ |
||||||
|
qWarning() << "Audio: Cannot create output audio context"; |
||||||
|
alcCloseDevice(alOutDev); |
||||||
|
} |
||||||
|
else |
||||||
|
alGenSources(1, &alMainSource); |
||||||
|
|
||||||
|
|
||||||
|
qDebug() << "Audio: Opening audio output "<<outDevDescr; |
||||||
|
} |
||||||
|
|
||||||
|
Core::getInstance()->resetCallSources(); // Force to regen each group call's sources
|
||||||
|
} |
||||||
|
|
||||||
|
void Audio::closeInput() |
||||||
|
{ |
||||||
|
if (alInDev) |
||||||
|
alcCaptureCloseDevice(alInDev); |
||||||
|
|
||||||
|
userCount = 0; |
||||||
|
} |
||||||
|
|
||||||
|
void Audio::closeOutput() |
||||||
|
{ |
||||||
|
if (alContext) |
||||||
|
{ |
||||||
|
alcMakeContextCurrent(nullptr); |
||||||
|
alcDestroyContext(alContext); |
||||||
|
} |
||||||
|
|
||||||
|
if (alOutDev) |
||||||
|
alcCloseDevice(alOutDev); |
||||||
|
} |
||||||
|
|
||||||
|
void Audio::playMono16Sound(const QByteArray& data) |
||||||
|
{ |
||||||
|
ALuint buffer; |
||||||
|
alGenBuffers(1, &buffer); |
||||||
|
alBufferData(buffer, AL_FORMAT_MONO16, data.data(), data.size(), 44100); |
||||||
|
alSourcei(alMainSource, AL_BUFFER, buffer); |
||||||
|
alSourcePlay(alMainSource); |
||||||
|
alDeleteBuffers(1, &buffer); |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
#ifndef AUDIO_H |
||||||
|
#define AUDIO_H |
||||||
|
|
||||||
|
#include <atomic> |
||||||
|
|
||||||
|
#if defined(__APPLE__) && defined(__MACH__) |
||||||
|
#include <OpenAL/al.h> |
||||||
|
#include <OpenAL/alc.h> |
||||||
|
#else |
||||||
|
#include <AL/al.h> |
||||||
|
#include <AL/alc.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
class QString; |
||||||
|
class QByteArray; |
||||||
|
|
||||||
|
class Audio |
||||||
|
{ |
||||||
|
public: |
||||||
|
static void suscribeInput(); ///< Call when you need to capture sound from the open input device.
|
||||||
|
static void unsuscribeInput(); ///< Call once you don't need to capture on the open input device anymore.
|
||||||
|
|
||||||
|
static void openInput(const QString& inDevDescr); ///< Open an input device, use before suscribing
|
||||||
|
static void openOutput(const QString& outDevDescr); ///< Open an output device
|
||||||
|
|
||||||
|
static void closeInput(); ///< Close an input device, please don't use unless everyone's unsuscribed
|
||||||
|
static void closeOutput(); ///< Close an output device
|
||||||
|
|
||||||
|
static void playMono16Sound(const QByteArray& data); ///< Play a 44100Hz mono 16bit PCM sound
|
||||||
|
|
||||||
|
public: |
||||||
|
static ALCdevice* alOutDev, *alInDev; |
||||||
|
static ALCcontext* alContext; |
||||||
|
static ALuint alMainSource; |
||||||
|
|
||||||
|
private: |
||||||
|
Audio(); |
||||||
|
|
||||||
|
private: |
||||||
|
static std::atomic<int> userCount; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif // AUDIO_H
|
Loading…
Reference in new issue