Skip to content

Commit

Permalink
Add support for changing the capture device.
Browse files Browse the repository at this point in the history
  • Loading branch information
Hoikas committed Sep 15, 2019
1 parent 2a97681 commit 0bce02c
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 11 deletions.
5 changes: 5 additions & 0 deletions Sources/Plasma/FeatureLib/pfConsole/pfConsoleCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3325,6 +3325,11 @@ PF_CONSOLE_CMD( Audio, SetDeviceName, "string deviceName", "Meant for plClient i
plgAudioSys::SetPlaybackDevice(ST::string::from_utf8(params[0]));
}

PF_CONSOLE_CMD(Audio, SetCaptureDeviceName, "string deviceName", "Sets the audio capture device name")
{
plgAudioSys::SetCaptureDevice(ST::string::from_utf8(params[0]));
}

PF_CONSOLE_CMD( Audio, // groupName
ShowIcons, // fxnName
"bool b", // paramList
Expand Down
17 changes: 17 additions & 0 deletions Sources/Plasma/FeatureLib/pfPython/pyAudioControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,3 +367,20 @@ std::vector<ST::string> pyAudioControl::GetPlaybackDevices() const
return plgAudioSys::Sys()->GetPlaybackDevices();
return std::vector<ST::string>();
}

void pyAudioControl::SetCaptureDevice(const ST::string& device)
{
plgAudioSys::SetCaptureDevice(device);
}

ST::string pyAudioControl::GetCaptureDevice() const
{
return plgAudioSys::GetCaptureDevice();
}

std::vector<ST::string> pyAudioControl::GetCaptureDevices() const
{
if (plgAudioSys::Sys())
return plgAudioSys::Sys()->GetCaptureDevices();
return std::vector<ST::string>();
}
5 changes: 5 additions & 0 deletions Sources/Plasma/FeatureLib/pfPython/pyAudioControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ class pyAudioControl
uint8_t GetPriorityCutoff() const;
void SetPriorityCutoff(uint8_t cut);

void SetCaptureDevice(const ST::string& device);
ST::string GetCaptureDevice() const;

std::vector<ST::string> GetCaptureDevices() const;

};

#endif // _pyAudioControl_h_
29 changes: 29 additions & 0 deletions Sources/Plasma/FeatureLib/pfPython/pyAudioControlGlue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,32 @@ PYTHON_METHOD_DEFINITION_NOARGS(ptAudioControl, getPlaybackDevices)
return tup;
}

PYTHON_METHOD_DEFINITION(ptAudioControl, setCaptureDevice, args)
{
char* devicename = nullptr;
int devicenamelen = 0;
if (!PyArg_ParseTuple(args, "et#", "utf8", &devicename, &devicenamelen)) {
PyErr_SetString(PyExc_TypeError, "setCaptureDevice expects a string");
PYTHON_RETURN_ERROR;
}
self->fThis->SetCaptureDevice(ST::string::from_utf8(devicename, devicenamelen));
PYTHON_RETURN_NONE;
}

PYTHON_METHOD_DEFINITION_NOARGS(ptAudioControl, getCaptureDevice)
{
return PyUnicode_FromSTString(self->fThis->GetCaptureDevice());
}

PYTHON_METHOD_DEFINITION_NOARGS(ptAudioControl, getCaptureDevices)
{
std::vector<ST::string> devices = self->fThis->GetCaptureDevices();
PyObject* tup = PyTuple_New(devices.size());
for (size_t i = 0; i < devices.size(); ++i)
PyTuple_SET_ITEM(tup, i, PyUnicode_FromSTString(devices[i]));
return tup;
}

PYTHON_START_METHODS_TABLE(ptAudioControl)
PYTHON_METHOD(ptAudioControl, setSoundFXVolume, "Params: volume\nSets the SoundFX volume (0.0 to 1.0) for the game.\n"
"This only sets the volume for this game session."),
Expand Down Expand Up @@ -429,6 +455,9 @@ PYTHON_START_METHODS_TABLE(ptAudioControl)
PYTHON_METHOD_NOARGS(ptAudioControl, getPriorityCutoff, "Returns current sound priority"),
PYTHON_METHOD(ptAudioControl, setPriorityCutoff, "Params: priority\nSets the sound priority"),
PYTHON_METHOD(ptAudioControl, enableVoiceChat, "Params: state\nEnables or disables voice chat."),
PYTHON_METHOD(ptAudioControl, setCaptureDevice, "Sets the name for the capture device being used by the audio system"),
PYTHON_METHOD_NOARGS(ptAudioControl, getCaptureDevice, "Gets the name for the capture device being used by the audio system."),
PYTHON_METHOD_NOARGS(ptAudioControl, getCaptureDevices, "Gets the name of all available audio capture devices."),

PYTHON_END_METHODS_TABLE;

Expand Down
75 changes: 64 additions & 11 deletions Sources/Plasma/PubUtilLib/plAudio/plAudioSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,27 @@ ST::string plAudioSystem::GetDefaultPlaybackDevice() const
}
}

std::vector<ST::string> plAudioSystem::GetCaptureDevices() const
{
std::vector<ST::string> retval;
retval.push_back(s_defaultDeviceMagic);

const ALchar* devices = alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER);
const ALchar* ptr = devices;
while (*ptr) {
ST::string deviceName = ST::string::from_utf8(ptr);
retval.push_back(deviceName);
ptr += deviceName.size() + sizeof(ALchar);
}

return retval;
}

ST::string plAudioSystem::GetDefaultCaptureDevice() const
{
return ST::string::from_utf8(alcGetString(nullptr, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
}

//// Init ////////////////////////////////////////////////////////////////////
bool plAudioSystem::Init()
{
Expand Down Expand Up @@ -878,16 +899,38 @@ bool plAudioSystem::MsgReceive(plMessage* msg)
return hsKeyedObject::MsgReceive(msg);
}

bool plAudioSystem::BeginCapture()
bool plAudioSystem::OpenCaptureDevice()
{
if (fCaptureDevice) {
if (!EndCapture())
return false;
const ST::string& deviceName = plgAudioSys::fCaptureDeviceName;
bool defaultDeviceRequested = (deviceName.empty() || deviceName == s_defaultDeviceMagic);
if (defaultDeviceRequested)
plgAudioSys::fCaptureDeviceName = s_defaultDeviceMagic;
ALCsizei bufferSize = fCaptureFrequency * sizeof(int16_t) * BUFFER_LEN_SECONDS;

if (!defaultDeviceRequested) {
fCaptureDevice = alcCaptureOpenDevice(deviceName.c_str(), fCaptureFrequency, AL_FORMAT_MONO16, bufferSize);
if (!fCaptureDevice) {
plStatusLog::AddLineS("audio.log", plStatusLog::kRed, "ASYS: ERROR! Failed to open capture device '%s'.", deviceName.c_str());
}
}

ALCsizei bufferSize = fCaptureFrequency * sizeof(int16_t) * BUFFER_LEN_SECONDS;
fCaptureDevice = alcCaptureOpenDevice(nullptr, fCaptureFrequency, AL_FORMAT_MONO16, bufferSize);
if (fCaptureDevice) {
if (!fCaptureDevice) {
plgAudioSys::fCaptureDeviceName = s_defaultDeviceMagic;
fCaptureDevice = alcCaptureOpenDevice(nullptr, fCaptureFrequency, AL_FORMAT_MONO16, bufferSize);
if (!fCaptureDevice) {
plStatusLog::AddLineS("audio.log", plStatusLog::kRed, "ASYS: ERROR! Failed to open default capture device.");
}
}

return fCaptureDevice != nullptr;
}

bool plAudioSystem::BeginCapture()
{
if (IsCapturing())
return true;

if (OpenCaptureDevice()) {
alcCaptureStart(fCaptureDevice);
return true;
} else {
Expand All @@ -897,7 +940,7 @@ bool plAudioSystem::BeginCapture()

bool plAudioSystem::CaptureSamples(uint32_t samples, int16_t* data) const
{
if (!fCaptureDevice)
if (!IsCapturing())
return false;

alcCaptureSamples(fCaptureDevice, data, samples);
Expand All @@ -918,7 +961,7 @@ bool plAudioSystem::SetCaptureSampleRate(uint32_t sampleRate)
{
if (fCaptureFrequency != sampleRate) {
fCaptureFrequency = sampleRate;
if (fCaptureDevice) {
if (IsCapturing()) {
if (!EndCapture())
return false;
return BeginCapture();
Expand All @@ -929,7 +972,7 @@ bool plAudioSystem::SetCaptureSampleRate(uint32_t sampleRate)

bool plAudioSystem::EndCapture()
{
if (!fCaptureDevice)
if (!IsCapturing())
return false;

alcCaptureStop(fCaptureDevice);
Expand Down Expand Up @@ -963,7 +1006,8 @@ uint8_t plgAudioSys::fPriorityCutoff = 9; // We cut off sounds
bool plgAudioSys::fEnableExtendedLogs = false;
float plgAudioSys::fGlobalFadeVolume = 1.f;
bool plgAudioSys::fLogStreamingUpdates = false;
ST::string plgAudioSys::fPlaybackDeviceName;
ST::string plgAudioSys::fPlaybackDeviceName = s_defaultDeviceMagic;
ST::string plgAudioSys::fCaptureDeviceName = s_defaultDeviceMagic;
bool plgAudioSys::fRestarting = false;
bool plgAudioSys::fMutedStateChange = false;

Expand Down Expand Up @@ -1124,3 +1168,12 @@ void plgAudioSys::SetListenerOrientation(const hsVector3& view, const hsVector3&
if (fSys)
fSys->SetListenerOrientation(view, up);
}

void plgAudioSys::SetCaptureDevice(const ST::string& name)
{
fCaptureDeviceName = name;
if (fSys && fSys->IsCapturing()) {
if (fSys->EndCapture())
fSys->BeginCapture();
}
}
13 changes: 13 additions & 0 deletions Sources/Plasma/PubUtilLib/plAudio/plAudioSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ class plAudioSystem : public hsKeyedObject
*/
ST::string GetDefaultPlaybackDevice() const;

/** Gets a vector of all available audio capture devices. */
std::vector<ST::string> GetCaptureDevices() const;

/** Gets the name of the default audio capture device. */
ST::string GetDefaultCaptureDevice() const;

/** Does the current playback device support EAX? */
bool IsEAXSupported() const { return fEAXSupported; }

Expand All @@ -120,6 +126,7 @@ class plAudioSystem : public hsKeyedObject
bool BeginCapture();
bool CaptureSamples(uint32_t samples, int16_t* data) const;
uint32_t GetCaptureSampleCount() const;
bool IsCapturing() const { return fCaptureDevice != nullptr; }
bool SetCaptureSampleRate(uint32_t sampleRate);
bool EndCapture();

Expand Down Expand Up @@ -156,6 +163,8 @@ class plAudioSystem : public hsKeyedObject
bool fEAXSupported;
double fLastUpdateTimeMs;

bool OpenCaptureDevice();

void RegisterSoftSound(const plKey& soundKey);
void UnregisterSoftSound(const plKey& soundKey);
void IUpdateSoftSounds(const hsPoint3& newPosition);
Expand Down Expand Up @@ -237,6 +246,9 @@ class plgAudioSys
Restart();
}

static ST::string GetCaptureDevice() { return fCaptureDeviceName; }
static void SetCaptureDevice(const ST::string& name);

static bool IsRestarting() { return fRestarting; }

private:
Expand All @@ -258,6 +270,7 @@ class plgAudioSys
static float f2D3DBias;
static bool fLogStreamingUpdates;
static ST::string fPlaybackDeviceName;
static ST::string fCaptureDeviceName;
static bool fRestarting;
static bool fMutedStateChange;

Expand Down

0 comments on commit 0bce02c

Please sign in to comment.