Skip to content

Commit

Permalink
cellMic: wait for registration of multiple input devices
Browse files Browse the repository at this point in the history
  • Loading branch information
Megamouse committed Mar 3, 2023
1 parent ea21224 commit 01a2f4a
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 59 deletions.
72 changes: 58 additions & 14 deletions rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Emu/RSX/rsx_utils.h"
#include "Utilities/StrUtil.h"

#include "cellMic.h"
#include "cellAudioIn.h"
#include "cellAudioOut.h"
#include "cellVideoOut.h"
Expand Down Expand Up @@ -34,9 +35,12 @@ void fmt_class_string<CellAudioInError>::format(std::string& out, u64 arg)

struct avconf_manager
{
shared_mutex mutex;
std::vector<CellAudioInDeviceInfo> devices;
CellAudioInDeviceMode inDeviceMode = CELL_AUDIO_IN_SINGLE_DEVICE_MODE; // TODO: use somewhere

void copy_device_info(u32 num, vm::ptr<CellAudioInDeviceInfo> info);
void copy_device_info(u32 num, vm::ptr<CellAudioInDeviceInfo> info) const;
std::optional<CellAudioInDeviceInfo> get_device_info(vm::cptr<char> name) const;

avconf_manager();

Expand All @@ -49,7 +53,8 @@ avconf_manager::avconf_manager()
{
u32 curindex = 0;

auto mic_list = fmt::split(g_cfg.audio.microphone_devices.to_string(), {"@@@"});
const std::vector<std::string> mic_list = fmt::split(g_cfg.audio.microphone_devices.to_string(), {"@@@"});

if (!mic_list.empty())
{
switch (g_cfg.audio.microphone_type)
Expand Down Expand Up @@ -131,20 +136,24 @@ avconf_manager::avconf_manager()
}
}

void avconf_manager::copy_device_info(u32 num, vm::ptr<CellAudioInDeviceInfo> info)
void avconf_manager::copy_device_info(u32 num, vm::ptr<CellAudioInDeviceInfo> info) const
{
memset(info.get_ptr(), 0, sizeof(CellAudioInDeviceInfo));
ensure(num >= devices.size());
*info = devices[num];
}

std::optional<CellAudioInDeviceInfo> avconf_manager::get_device_info(vm::cptr<char> name) const
{
for (const CellAudioInDeviceInfo& device : devices)
{
if (strncmp(device.name, name.get_ptr(), 64) == 0)
{
return device;
}
}

info->portType = devices[num].portType;
info->availableModeCount = devices[num].availableModeCount;
info->state = devices[num].state;
info->deviceId = devices[num].deviceId;
info->type = devices[num].type;
info->availableModes[0].type = devices[num].availableModes[0].type;
info->availableModes[0].channel = devices[num].availableModes[0].channel;
info->availableModes[0].fs = devices[num].availableModes[0].fs;
info->deviceNumber = devices[num].deviceNumber;
strcpy_trunc(info->name, devices[num].name);
return {};
}

error_code cellAudioOutUnregisterDevice(u32 deviceNumber)
Expand Down Expand Up @@ -199,6 +208,7 @@ error_code cellAudioInGetDeviceInfo(u32 deviceNumber, u32 deviceIndex, vm::ptr<C
}

auto& av_manager = g_fxo->get<avconf_manager>();
std::lock_guard lock(av_manager.mutex);

if (deviceNumber >= av_manager.devices.size())
return CELL_AUDIO_OUT_ERROR_DEVICE_NOT_FOUND;
Expand Down Expand Up @@ -273,6 +283,7 @@ error_code cellAudioInGetAvailableDeviceInfo(u32 count, vm::ptr<CellAudioInDevic
}

auto& av_manager = g_fxo->get<avconf_manager>();
std::lock_guard lock(av_manager.mutex);

u32 num_devices_returned = std::min<u32>(count, ::size32(av_manager.devices));

Expand All @@ -281,6 +292,15 @@ error_code cellAudioInGetAvailableDeviceInfo(u32 count, vm::ptr<CellAudioInDevic
av_manager.copy_device_info(index, device_info + index);
}

CellAudioInDeviceInfo disconnected_device{};
disconnected_device.state = CELL_AUDIO_OUT_DEVICE_STATE_UNAVAILABLE;
disconnected_device.deviceNumber = 0xff;

for (u32 index = num_devices_returned; index < count; index++)
{
device_info[index] = disconnected_device;
}

return not_an_error(num_devices_returned);
}

Expand Down Expand Up @@ -355,6 +375,11 @@ error_code cellAudioInSetDeviceMode(u32 deviceMode)
return CELL_AUDIO_IN_ERROR_ILLEGAL_PARAMETER;
}

auto& av_manager = g_fxo->get<avconf_manager>();
std::lock_guard lock(av_manager.mutex);

av_manager.inDeviceMode = static_cast<CellAudioInDeviceMode>(deviceMode);

return CELL_OK;
}

Expand All @@ -368,12 +393,31 @@ error_code cellAudioInRegisterDevice(u64 deviceType, vm::cptr<char> name, vm::pt
return CELL_AUDIO_IN_ERROR_ILLEGAL_PARAMETER;
}

return not_an_error(0); // device number
auto& av_manager = g_fxo->get<avconf_manager>();
const std::lock_guard lock(av_manager.mutex);

std::optional<CellAudioInDeviceInfo> info = av_manager.get_device_info(name);
if (!info || !memchr(info->name, '\0', 64))
{
// TODO
return CELL_AUDIO_IN_ERROR_DEVICE_NOT_FOUND;
}

auto& mic_thr = g_fxo->get<mic_thread>();
const std::lock_guard mic_lock(mic_thr.mutex);
const u32 device_number = mic_thr.register_device(info->name);

return device_number;
}

error_code cellAudioInUnregisterDevice(u32 deviceNumber)
{
cellAvconfExt.todo("cellAudioInUnregisterDevice(deviceNumber=0x%x)", deviceNumber);

auto& mic_thr = g_fxo->get<mic_thread>();
const std::lock_guard lock(mic_thr.mutex);
mic_thr.unregister_device(deviceNumber);

return CELL_OK;
}

Expand Down
Loading

0 comments on commit 01a2f4a

Please sign in to comment.