mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 19:45:20 +00: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)
|
||||
{
|
||||
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)
|
||||
|
@ -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
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
cellMic.error("Make sure microphone use is authorized under \"Microphone privacy settings\" in windows configuration");
|
||||
#endif
|
||||
return CELL_MICIN_ERROR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
input_devices.push_back(device);
|
||||
internal_bufs.emplace_back();
|
||||
internal_bufs[0].resize(inbuf_size, 0);
|
||||
devices[0].device = device;
|
||||
devices[0].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
|
||||
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)
|
||||
{
|
||||
// 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
|
||||
{
|
||||
input_devices.push_back(device);
|
||||
internal_bufs.emplace_back();
|
||||
internal_bufs[1].resize(inbuf_size, 0);
|
||||
devices[1].device = device;
|
||||
devices[1].buf.resize(inbuf_size, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -455,16 +455,16 @@ error_code microphone_device::close_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();
|
||||
internal_bufs.clear();
|
||||
micdevice.device = nullptr;
|
||||
micdevice.buf.clear();
|
||||
}
|
||||
|
||||
mic_opened = false;
|
||||
|
||||
|
@ -473,12 +473,12 @@ error_code microphone_device::close_microphone()
|
|||
|
||||
error_code microphone_device::start_microphone()
|
||||
{
|
||||
for (ALCdevice* micdevice : input_devices)
|
||||
for (const mic_device& micdevice : devices)
|
||||
{
|
||||
alcCaptureStart(micdevice);
|
||||
if (ALCenum err = alcGetError(micdevice); err != ALC_NO_ERROR)
|
||||
alcCaptureStart(micdevice.device);
|
||||
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();
|
||||
return CELL_MICIN_ERROR_FATAL;
|
||||
}
|
||||
|
@ -491,12 +491,12 @@ error_code microphone_device::start_microphone()
|
|||
|
||||
error_code microphone_device::stop_microphone()
|
||||
{
|
||||
for (ALCdevice* micdevice : input_devices)
|
||||
for (const mic_device& micdevice : devices)
|
||||
{
|
||||
alcCaptureStop(micdevice);
|
||||
if (ALCenum err = alcGetError(micdevice); err != ALC_NO_ERROR)
|
||||
alcCaptureStop(micdevice.device);
|
||||
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();
|
||||
|
||||
if (signal_types & CELLMIC_SIGTYPE_RAW)
|
||||
{
|
||||
get_raw(num_samples);
|
||||
}
|
||||
|
||||
if (signal_types & CELLMIC_SIGTYPE_DSP)
|
||||
{
|
||||
get_dsp(num_samples);
|
||||
}
|
||||
|
||||
// TODO: aux?
|
||||
}
|
||||
}
|
||||
|
@ -533,21 +539,26 @@ u32 microphone_device::capture_audio()
|
|||
|
||||
u32 num_samples = inbuf_size / sample_size;
|
||||
|
||||
for (ALCdevice* micdevice : input_devices)
|
||||
for (const mic_device& micdevice : devices)
|
||||
{
|
||||
ALCint samples_in = 0;
|
||||
alcGetIntegerv(micdevice, ALC_CAPTURE_SAMPLES, 1, &samples_in);
|
||||
if (ALCenum err = alcGetError(micdevice); err != ALC_NO_ERROR)
|
||||
alcGetIntegerv(micdevice.device, ALC_CAPTURE_SAMPLES, 1, &samples_in);
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
@ -555,115 +566,116 @@ u32 microphone_device::capture_audio()
|
|||
|
||||
// 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();
|
||||
|
||||
switch (device_type)
|
||||
{
|
||||
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
|
||||
memcpy(tmp_ptr, internal_bufs[0].data(), num_samples * (bit_resolution / 8) * num_channels);
|
||||
std::memcpy(tmp_ptr, device.buf.data(), bufsize);
|
||||
break;
|
||||
}
|
||||
case microphone_handler::standard:
|
||||
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
|
||||
for (u32 index = 0; index < num_samples; index++)
|
||||
{
|
||||
const u32 sample_pos = index * sample_size;
|
||||
|
||||
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);
|
||||
const u32 curindex = sample_pos + indchan * channel_size;
|
||||
microphone_device::variable_byteswap(buf.data() + curindex, tmp_ptr + curindex, channel_size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case microphone_handler::singstar:
|
||||
{
|
||||
ensure(sample_size == 4);
|
||||
|
||||
// Mixing the 2 mics as if channels
|
||||
if (input_devices.size() == 2)
|
||||
// Each device buffer contains 16 bit mono samples
|
||||
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)
|
||||
{
|
||||
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];
|
||||
const u32 src_index = index / 2;
|
||||
|
||||
tmp_ptr[index] = buf_0[src_index];
|
||||
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
|
||||
{
|
||||
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];
|
||||
const u32 src_index = index / 2;
|
||||
|
||||
tmp_ptr[index] = buf_0[src_index];
|
||||
tmp_ptr[index + 1] = buf_0[src_index + 1];
|
||||
tmp_ptr[index + 2] = 0;
|
||||
tmp_ptr[index + 3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
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)
|
||||
{
|
||||
u8* tmp_ptr = temp_buf.data();
|
||||
|
||||
switch (device_type)
|
||||
if (num_samples == 0)
|
||||
{
|
||||
case microphone_handler::real_singstar:
|
||||
// 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;
|
||||
case microphone_handler::null:
|
||||
default: ensure(false); break;
|
||||
return;
|
||||
}
|
||||
|
||||
rbuf_dsp.write_bytes(tmp_ptr, num_samples * sample_size);
|
||||
};
|
||||
get_data(num_samples);
|
||||
|
||||
rbuf_dsp.write_bytes(temp_buf.data(), num_samples * sample_size);
|
||||
}
|
||||
|
||||
/// Initialization/Shutdown Functions
|
||||
|
||||
|
|
|
@ -197,12 +197,12 @@ public:
|
|||
|
||||
u32 read_bytes(u8* buf, const u32 size)
|
||||
{
|
||||
ensure(buf);
|
||||
|
||||
const u32 to_read = size > m_used ? m_used : size;
|
||||
if (!to_read)
|
||||
return 0;
|
||||
|
||||
ensure(buf);
|
||||
|
||||
u8* data = m_container.data();
|
||||
const u32 new_tail = m_tail + to_read;
|
||||
|
||||
|
@ -226,6 +226,11 @@ public:
|
|||
|
||||
void write_bytes(const u8* buf, const u32 size)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ensure(size <= Size);
|
||||
|
||||
const u32 over_size = m_used + size;
|
||||
|
@ -280,7 +285,7 @@ public:
|
|||
error_code start_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();
|
||||
bool has_data() const;
|
||||
|
@ -320,18 +325,24 @@ private:
|
|||
|
||||
u32 capture_audio();
|
||||
|
||||
void get_data(const u32 num_samples);
|
||||
void get_raw(const u32 num_samples);
|
||||
void get_dsp(const u32 num_samples);
|
||||
|
||||
microphone_handler device_type = microphone_handler::null;
|
||||
std::vector<std::string> device_name;
|
||||
|
||||
bool mic_registered = false;
|
||||
bool mic_opened = false;
|
||||
bool mic_started = false;
|
||||
|
||||
std::vector<ALCdevice*> input_devices;
|
||||
std::vector<std::vector<u8>> internal_bufs;
|
||||
struct mic_device
|
||||
{
|
||||
std::string name;
|
||||
ALCdevice* device = nullptr;
|
||||
std::vector<u8> buf;
|
||||
};
|
||||
|
||||
std::vector<mic_device> devices;
|
||||
std::vector<u8> temp_buf;
|
||||
|
||||
// Sampling information provided at opening of mic
|
||||
|
|
Loading…
Add table
Reference in a new issue