mirror of https://github.com/qTox/qTox.git
8 changed files with 196 additions and 131 deletions
@ -0,0 +1,112 @@
@@ -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 @@
@@ -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