mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 21:41:26 +12:00
cellMic: remove duplicate code and add size checks
This commit is contained in:
parent
f09d22a00d
commit
667db0f2de
2 changed files with 126 additions and 103 deletions
|
@ -260,7 +260,9 @@ microphone_device::microphone_device(microphone_handler type)
|
||||||
|
|
||||||
void microphone_device::add_device(const std::string& name)
|
void microphone_device::add_device(const std::string& name)
|
||||||
{
|
{
|
||||||
device_name.push_back(name);
|
devices.push_back(mic_device{
|
||||||
|
.name = name
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code microphone_device::open_microphone(const u8 type, const u32 dsp_r, const u32 raw_r, const u8 channels)
|
error_code microphone_device::open_microphone(const u8 type, const u32 dsp_r, const u32 raw_r, const u8 channels)
|
||||||
|
@ -406,39 +408,37 @@ error_code microphone_device::open_microphone(const u8 type, const u32 dsp_r, co
|
||||||
|
|
||||||
aux_samplingrate = dsp_samplingrate = raw_samplingrate; // Same rate for now
|
aux_samplingrate = dsp_samplingrate = raw_samplingrate; // Same rate for now
|
||||||
|
|
||||||
ensure(!device_name.empty());
|
ensure(!devices.empty());
|
||||||
|
|
||||||
ALCdevice* device = alcCaptureOpenDevice(device_name[0].c_str(), raw_samplingrate, num_al_channels, inbuf_size);
|
ALCdevice* device = alcCaptureOpenDevice(devices[0].name.c_str(), raw_samplingrate, num_al_channels, inbuf_size);
|
||||||
|
|
||||||
if (ALCenum err = alcGetError(device); err != ALC_NO_ERROR || !device)
|
if (ALCenum err = alcGetError(device); err != ALC_NO_ERROR || !device)
|
||||||
{
|
{
|
||||||
cellMic.error("Error opening capture device %s (error=0x%x, device=*0x%x)", device_name[0], err, device);
|
cellMic.error("Error opening capture device %s (error=0x%x, device=*0x%x)", devices[0].name, err, device);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
cellMic.error("Make sure microphone use is authorized under \"Microphone privacy settings\" in windows configuration");
|
cellMic.error("Make sure microphone use is authorized under \"Microphone privacy settings\" in windows configuration");
|
||||||
#endif
|
#endif
|
||||||
return CELL_MICIN_ERROR_DEVICE_NOT_SUPPORT;
|
return CELL_MICIN_ERROR_DEVICE_NOT_SUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
input_devices.push_back(device);
|
devices[0].device = device;
|
||||||
internal_bufs.emplace_back();
|
devices[0].buf.resize(inbuf_size, 0);
|
||||||
internal_bufs[0].resize(inbuf_size, 0);
|
|
||||||
temp_buf.resize(inbuf_size, 0);
|
temp_buf.resize(inbuf_size, 0);
|
||||||
|
|
||||||
if (device_type == microphone_handler::singstar && device_name.size() >= 2)
|
if (device_type == microphone_handler::singstar && devices.size() >= 2)
|
||||||
{
|
{
|
||||||
// Open a 2nd microphone into the same device
|
// Open a 2nd microphone into the same device
|
||||||
device = alcCaptureOpenDevice(device_name[1].c_str(), raw_samplingrate, AL_FORMAT_MONO16, inbuf_size);
|
device = alcCaptureOpenDevice(devices[1].name.c_str(), raw_samplingrate, AL_FORMAT_MONO16, inbuf_size);
|
||||||
|
|
||||||
if (ALCenum err = alcGetError(device); err != ALC_NO_ERROR || !device)
|
if (ALCenum err = alcGetError(device); err != ALC_NO_ERROR || !device)
|
||||||
{
|
{
|
||||||
// Ignore it and move on
|
// Ignore it and move on
|
||||||
cellMic.error("Error opening 2nd SingStar capture device %s (error=0x%x, device=*0x%x)", device_name[1], err, device);
|
cellMic.error("Error opening 2nd SingStar capture device %s (error=0x%x, device=*0x%x)", devices[1].name, err, device);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
input_devices.push_back(device);
|
devices[1].device = device;
|
||||||
internal_bufs.emplace_back();
|
devices[1].buf.resize(inbuf_size, 0);
|
||||||
internal_bufs[1].resize(inbuf_size, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,16 +455,16 @@ error_code microphone_device::close_microphone()
|
||||||
stop_microphone();
|
stop_microphone();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& micdevice : input_devices)
|
for (mic_device& micdevice : devices)
|
||||||
{
|
{
|
||||||
if (alcCaptureCloseDevice(micdevice) != ALC_TRUE)
|
if (alcCaptureCloseDevice(micdevice.device) != ALC_TRUE)
|
||||||
{
|
{
|
||||||
cellMic.error("Error closing capture device");
|
cellMic.error("Error closing capture device %s", micdevice.name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input_devices.clear();
|
micdevice.device = nullptr;
|
||||||
internal_bufs.clear();
|
micdevice.buf.clear();
|
||||||
|
}
|
||||||
|
|
||||||
mic_opened = false;
|
mic_opened = false;
|
||||||
|
|
||||||
|
@ -473,12 +473,12 @@ error_code microphone_device::close_microphone()
|
||||||
|
|
||||||
error_code microphone_device::start_microphone()
|
error_code microphone_device::start_microphone()
|
||||||
{
|
{
|
||||||
for (ALCdevice* micdevice : input_devices)
|
for (const mic_device& micdevice : devices)
|
||||||
{
|
{
|
||||||
alcCaptureStart(micdevice);
|
alcCaptureStart(micdevice.device);
|
||||||
if (ALCenum err = alcGetError(micdevice); err != ALC_NO_ERROR)
|
if (ALCenum err = alcGetError(micdevice.device); err != ALC_NO_ERROR)
|
||||||
{
|
{
|
||||||
cellMic.error("Error starting capture (error=0x%x)", err);
|
cellMic.error("Error starting capture of device %s (error=0x%x)", micdevice.name, err);
|
||||||
stop_microphone();
|
stop_microphone();
|
||||||
return CELL_MICIN_ERROR_FATAL;
|
return CELL_MICIN_ERROR_FATAL;
|
||||||
}
|
}
|
||||||
|
@ -491,12 +491,12 @@ error_code microphone_device::start_microphone()
|
||||||
|
|
||||||
error_code microphone_device::stop_microphone()
|
error_code microphone_device::stop_microphone()
|
||||||
{
|
{
|
||||||
for (ALCdevice* micdevice : input_devices)
|
for (const mic_device& micdevice : devices)
|
||||||
{
|
{
|
||||||
alcCaptureStop(micdevice);
|
alcCaptureStop(micdevice.device);
|
||||||
if (ALCenum err = alcGetError(micdevice); err != ALC_NO_ERROR)
|
if (ALCenum err = alcGetError(micdevice.device); err != ALC_NO_ERROR)
|
||||||
{
|
{
|
||||||
cellMic.error("Error stopping capture (error=0x%x)", err);
|
cellMic.error("Error stopping capture of device %s (error=0x%x)", micdevice.name, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,9 +515,15 @@ void microphone_device::update_audio()
|
||||||
const u32 num_samples = capture_audio();
|
const u32 num_samples = capture_audio();
|
||||||
|
|
||||||
if (signal_types & CELLMIC_SIGTYPE_RAW)
|
if (signal_types & CELLMIC_SIGTYPE_RAW)
|
||||||
|
{
|
||||||
get_raw(num_samples);
|
get_raw(num_samples);
|
||||||
|
}
|
||||||
|
|
||||||
if (signal_types & CELLMIC_SIGTYPE_DSP)
|
if (signal_types & CELLMIC_SIGTYPE_DSP)
|
||||||
|
{
|
||||||
get_dsp(num_samples);
|
get_dsp(num_samples);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: aux?
|
// TODO: aux?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,21 +539,26 @@ u32 microphone_device::capture_audio()
|
||||||
|
|
||||||
u32 num_samples = inbuf_size / sample_size;
|
u32 num_samples = inbuf_size / sample_size;
|
||||||
|
|
||||||
for (ALCdevice* micdevice : input_devices)
|
for (const mic_device& micdevice : devices)
|
||||||
{
|
{
|
||||||
ALCint samples_in = 0;
|
ALCint samples_in = 0;
|
||||||
alcGetIntegerv(micdevice, ALC_CAPTURE_SAMPLES, 1, &samples_in);
|
alcGetIntegerv(micdevice.device, ALC_CAPTURE_SAMPLES, 1, &samples_in);
|
||||||
if (ALCenum err = alcGetError(micdevice); err != ALC_NO_ERROR)
|
if (ALCenum err = alcGetError(micdevice.device); err != ALC_NO_ERROR)
|
||||||
{
|
{
|
||||||
cellMic.error("Error getting number of captured samples (error=0x%x)", err);
|
cellMic.error("Error getting number of captured samples of device %s (error=0x%x)", micdevice.name, err);
|
||||||
return CELL_MICIN_ERROR_FATAL;
|
return CELL_MICIN_ERROR_FATAL;
|
||||||
}
|
}
|
||||||
num_samples = std::min<u32>(num_samples, samples_in);
|
num_samples = std::min<u32>(num_samples, samples_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 index = 0; index < input_devices.size(); index++)
|
for (mic_device& micdevice : devices)
|
||||||
{
|
{
|
||||||
alcCaptureSamples(input_devices[index], internal_bufs[index].data(), num_samples);
|
alcCaptureSamples(micdevice.device, micdevice.buf.data(), num_samples);
|
||||||
|
|
||||||
|
if (ALCenum err = alcGetError(micdevice.device); err != ALC_NO_ERROR)
|
||||||
|
{
|
||||||
|
cellMic.error("Error capturing samples of device %s (error=0x%x)", micdevice.name, err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return num_samples;
|
return num_samples;
|
||||||
|
@ -555,115 +566,116 @@ u32 microphone_device::capture_audio()
|
||||||
|
|
||||||
// Private functions
|
// Private functions
|
||||||
|
|
||||||
void microphone_device::get_raw(const u32 num_samples)
|
void microphone_device::get_data(const u32 num_samples)
|
||||||
{
|
{
|
||||||
|
ensure(num_samples > 0);
|
||||||
|
|
||||||
u8* tmp_ptr = temp_buf.data();
|
u8* tmp_ptr = temp_buf.data();
|
||||||
|
|
||||||
switch (device_type)
|
switch (device_type)
|
||||||
{
|
{
|
||||||
case microphone_handler::real_singstar:
|
case microphone_handler::real_singstar:
|
||||||
|
{
|
||||||
|
const usz bufsize = num_samples * sample_size;
|
||||||
|
const mic_device& device = ::at32(devices, 0);
|
||||||
|
ensure(bufsize <= device.buf.size());
|
||||||
|
ensure(bufsize <= temp_buf.size());
|
||||||
|
|
||||||
// Straight copy from device
|
// Straight copy from device
|
||||||
memcpy(tmp_ptr, internal_bufs[0].data(), num_samples * (bit_resolution / 8) * num_channels);
|
std::memcpy(tmp_ptr, device.buf.data(), bufsize);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case microphone_handler::standard:
|
case microphone_handler::standard:
|
||||||
case microphone_handler::rocksmith:
|
case microphone_handler::rocksmith:
|
||||||
|
{
|
||||||
|
const u8 channel_size = bit_resolution / 8;
|
||||||
|
const usz bufsize = num_samples * sample_size;
|
||||||
|
const std::vector<u8>& buf = ::at32(devices, 0).buf;
|
||||||
|
ensure(bufsize <= buf.size());
|
||||||
|
ensure(bufsize <= temp_buf.size());
|
||||||
|
|
||||||
// BE Translation
|
// BE Translation
|
||||||
for (u32 index = 0; index < num_samples; index++)
|
for (u32 index = 0; index < num_samples; index++)
|
||||||
{
|
{
|
||||||
|
const u32 sample_pos = index * sample_size;
|
||||||
|
|
||||||
for (u32 indchan = 0; indchan < num_channels; indchan++)
|
for (u32 indchan = 0; indchan < num_channels; indchan++)
|
||||||
{
|
{
|
||||||
const u32 curindex = (index * sample_size) + indchan * (bit_resolution / 8);
|
const u32 curindex = sample_pos + indchan * channel_size;
|
||||||
microphone_device::variable_byteswap(internal_bufs[0].data() + curindex, tmp_ptr + curindex, bit_resolution / 8);
|
microphone_device::variable_byteswap(buf.data() + curindex, tmp_ptr + curindex, channel_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case microphone_handler::singstar:
|
case microphone_handler::singstar:
|
||||||
|
{
|
||||||
ensure(sample_size == 4);
|
ensure(sample_size == 4);
|
||||||
|
|
||||||
// Mixing the 2 mics as if channels
|
// Each device buffer contains 16 bit mono samples
|
||||||
if (input_devices.size() == 2)
|
const usz bufsize = num_samples * sizeof(u16);
|
||||||
|
const std::vector<u8>& buf_0 = ::at32(devices, 0).buf;
|
||||||
|
ensure(bufsize <= buf_0.size());
|
||||||
|
|
||||||
|
// Mixing the 2 mics into the 2 destination channels
|
||||||
|
if (devices.size() == 2)
|
||||||
{
|
{
|
||||||
|
const std::vector<u8>& buf_1 = ::at32(devices, 1).buf;
|
||||||
|
ensure(bufsize <= buf_1.size());
|
||||||
|
|
||||||
for (u32 index = 0; index < (num_samples * 4); index += 4)
|
for (u32 index = 0; index < (num_samples * 4); index += 4)
|
||||||
{
|
{
|
||||||
tmp_ptr[index] = internal_bufs[0][(index / 2)];
|
const u32 src_index = index / 2;
|
||||||
tmp_ptr[index + 1] = internal_bufs[0][(index / 2) + 1];
|
|
||||||
tmp_ptr[index + 2] = internal_bufs[1][(index / 2)];
|
tmp_ptr[index] = buf_0[src_index];
|
||||||
tmp_ptr[index + 3] = internal_bufs[1][(index / 2) + 1];
|
tmp_ptr[index + 1] = buf_0[src_index + 1];
|
||||||
|
tmp_ptr[index + 2] = buf_1[src_index];
|
||||||
|
tmp_ptr[index + 3] = buf_1[src_index + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (u32 index = 0; index < (num_samples * 4); index += 4)
|
for (u32 index = 0; index < (num_samples * 4); index += 4)
|
||||||
{
|
{
|
||||||
tmp_ptr[index] = internal_bufs[0][(index / 2)];
|
const u32 src_index = index / 2;
|
||||||
tmp_ptr[index + 1] = internal_bufs[0][(index / 2) + 1];
|
|
||||||
|
tmp_ptr[index] = buf_0[src_index];
|
||||||
|
tmp_ptr[index + 1] = buf_0[src_index + 1];
|
||||||
tmp_ptr[index + 2] = 0;
|
tmp_ptr[index + 2] = 0;
|
||||||
tmp_ptr[index + 3] = 0;
|
tmp_ptr[index + 3] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case microphone_handler::null:
|
case microphone_handler::null:
|
||||||
default: ensure(false); break;
|
ensure(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void microphone_device::get_raw(const u32 num_samples)
|
||||||
|
{
|
||||||
|
if (num_samples == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rbuf_raw.write_bytes(tmp_ptr, num_samples * sample_size);
|
get_data(num_samples);
|
||||||
};
|
|
||||||
|
rbuf_raw.write_bytes(temp_buf.data(), num_samples * sample_size);
|
||||||
|
}
|
||||||
|
|
||||||
void microphone_device::get_dsp(const u32 num_samples)
|
void microphone_device::get_dsp(const u32 num_samples)
|
||||||
{
|
{
|
||||||
u8* tmp_ptr = temp_buf.data();
|
if (num_samples == 0)
|
||||||
|
|
||||||
switch (device_type)
|
|
||||||
{
|
{
|
||||||
case microphone_handler::real_singstar:
|
return;
|
||||||
// Straight copy from device
|
|
||||||
memcpy(tmp_ptr, internal_bufs[0].data(), num_samples * (bit_resolution / 8) * num_channels);
|
|
||||||
break;
|
|
||||||
case microphone_handler::standard:
|
|
||||||
case microphone_handler::rocksmith:
|
|
||||||
// BE Translation
|
|
||||||
for (u32 index = 0; index < num_samples; index++)
|
|
||||||
{
|
|
||||||
for (u32 indchan = 0; indchan < num_channels; indchan++)
|
|
||||||
{
|
|
||||||
const u32 curindex = (index * sample_size) + indchan * (bit_resolution / 8);
|
|
||||||
microphone_device::variable_byteswap(internal_bufs[0].data() + curindex, tmp_ptr + curindex, bit_resolution / 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case microphone_handler::singstar:
|
|
||||||
ensure(sample_size == 4);
|
|
||||||
|
|
||||||
// Mixing the 2 mics as if channels
|
|
||||||
if (input_devices.size() == 2)
|
|
||||||
{
|
|
||||||
for (u32 index = 0; index < (num_samples * 4); index += 4)
|
|
||||||
{
|
|
||||||
tmp_ptr[index] = internal_bufs[0][(index / 2)];
|
|
||||||
tmp_ptr[index + 1] = internal_bufs[0][(index / 2) + 1];
|
|
||||||
tmp_ptr[index + 2] = internal_bufs[1][(index / 2)];
|
|
||||||
tmp_ptr[index + 3] = internal_bufs[1][(index / 2) + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (u32 index = 0; index < (num_samples * 4); index += 4)
|
|
||||||
{
|
|
||||||
tmp_ptr[index] = internal_bufs[0][(index / 2)];
|
|
||||||
tmp_ptr[index + 1] = internal_bufs[0][(index / 2) + 1];
|
|
||||||
tmp_ptr[index + 2] = 0;
|
|
||||||
tmp_ptr[index + 3] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
get_data(num_samples);
|
||||||
case microphone_handler::null:
|
|
||||||
default: ensure(false); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
rbuf_dsp.write_bytes(tmp_ptr, num_samples * sample_size);
|
rbuf_dsp.write_bytes(temp_buf.data(), num_samples * sample_size);
|
||||||
};
|
}
|
||||||
|
|
||||||
/// Initialization/Shutdown Functions
|
/// Initialization/Shutdown Functions
|
||||||
|
|
||||||
|
|
|
@ -197,12 +197,12 @@ public:
|
||||||
|
|
||||||
u32 read_bytes(u8* buf, const u32 size)
|
u32 read_bytes(u8* buf, const u32 size)
|
||||||
{
|
{
|
||||||
ensure(buf);
|
|
||||||
|
|
||||||
const u32 to_read = size > m_used ? m_used : size;
|
const u32 to_read = size > m_used ? m_used : size;
|
||||||
if (!to_read)
|
if (!to_read)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
ensure(buf);
|
||||||
|
|
||||||
u8* data = m_container.data();
|
u8* data = m_container.data();
|
||||||
const u32 new_tail = m_tail + to_read;
|
const u32 new_tail = m_tail + to_read;
|
||||||
|
|
||||||
|
@ -226,6 +226,11 @@ public:
|
||||||
|
|
||||||
void write_bytes(const u8* buf, const u32 size)
|
void write_bytes(const u8* buf, const u32 size)
|
||||||
{
|
{
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ensure(size <= Size);
|
ensure(size <= Size);
|
||||||
|
|
||||||
const u32 over_size = m_used + size;
|
const u32 over_size = m_used + size;
|
||||||
|
@ -280,7 +285,7 @@ public:
|
||||||
error_code start_microphone();
|
error_code start_microphone();
|
||||||
error_code stop_microphone();
|
error_code stop_microphone();
|
||||||
|
|
||||||
std::string get_device_name() const { return device_name.empty() ? "" : device_name.front(); }
|
std::string get_device_name() const { return devices.empty() ? "" : devices.front().name; }
|
||||||
|
|
||||||
void update_audio();
|
void update_audio();
|
||||||
bool has_data() const;
|
bool has_data() const;
|
||||||
|
@ -320,18 +325,24 @@ private:
|
||||||
|
|
||||||
u32 capture_audio();
|
u32 capture_audio();
|
||||||
|
|
||||||
|
void get_data(const u32 num_samples);
|
||||||
void get_raw(const u32 num_samples);
|
void get_raw(const u32 num_samples);
|
||||||
void get_dsp(const u32 num_samples);
|
void get_dsp(const u32 num_samples);
|
||||||
|
|
||||||
microphone_handler device_type = microphone_handler::null;
|
microphone_handler device_type = microphone_handler::null;
|
||||||
std::vector<std::string> device_name;
|
|
||||||
|
|
||||||
bool mic_registered = false;
|
bool mic_registered = false;
|
||||||
bool mic_opened = false;
|
bool mic_opened = false;
|
||||||
bool mic_started = false;
|
bool mic_started = false;
|
||||||
|
|
||||||
std::vector<ALCdevice*> input_devices;
|
struct mic_device
|
||||||
std::vector<std::vector<u8>> internal_bufs;
|
{
|
||||||
|
std::string name;
|
||||||
|
ALCdevice* device = nullptr;
|
||||||
|
std::vector<u8> buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<mic_device> devices;
|
||||||
std::vector<u8> temp_buf;
|
std::vector<u8> temp_buf;
|
||||||
|
|
||||||
// Sampling information provided at opening of mic
|
// Sampling information provided at opening of mic
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue