mirror of https://github.com/PCSX2/pcsx2.git
USB: Audio support for EyeToy
This commit is contained in:
parent
d6507a945b
commit
c2ea8c4eab
|
@ -6,6 +6,8 @@
|
||||||
#include "usb-eyetoy-webcam.h"
|
#include "usb-eyetoy-webcam.h"
|
||||||
#include "ov519.h"
|
#include "ov519.h"
|
||||||
#include "USB/qemu-usb/desc.h"
|
#include "USB/qemu-usb/desc.h"
|
||||||
|
#include "USB/usb-mic/audio.h"
|
||||||
|
#include "USB/usb-mic/usb-mic.h"
|
||||||
#include "USB/USB.h"
|
#include "USB/USB.h"
|
||||||
#include "StateWrapper.h"
|
#include "StateWrapper.h"
|
||||||
|
|
||||||
|
@ -23,7 +25,7 @@ namespace usb_eyetoy
|
||||||
u32 subtype;
|
u32 subtype;
|
||||||
|
|
||||||
std::unique_ptr<VideoDevice> videodev;
|
std::unique_ptr<VideoDevice> videodev;
|
||||||
// struct freeze {
|
USBDevice* mic;
|
||||||
uint8_t regs[0xFF]; //OV519
|
uint8_t regs[0xFF]; //OV519
|
||||||
uint8_t i2c_regs[0xFF]; //OV764x
|
uint8_t i2c_regs[0xFF]; //OV764x
|
||||||
|
|
||||||
|
@ -32,7 +34,6 @@ namespace usb_eyetoy
|
||||||
std::unique_ptr<unsigned char[]> mpeg_frame_data;
|
std::unique_ptr<unsigned char[]> mpeg_frame_data;
|
||||||
unsigned int mpeg_frame_size;
|
unsigned int mpeg_frame_size;
|
||||||
unsigned int mpeg_frame_offset;
|
unsigned int mpeg_frame_offset;
|
||||||
// } f;
|
|
||||||
} EYETOYState;
|
} EYETOYState;
|
||||||
|
|
||||||
static const USBDescStrings desc_strings = {
|
static const USBDescStrings desc_strings = {
|
||||||
|
@ -103,8 +104,11 @@ namespace usb_eyetoy
|
||||||
|
|
||||||
static void eyetoy_handle_reset(USBDevice* dev)
|
static void eyetoy_handle_reset(USBDevice* dev)
|
||||||
{
|
{
|
||||||
reset_controller(USB_CONTAINER_OF(dev, EYETOYState, dev));
|
EYETOYState* s = USB_CONTAINER_OF(dev, EYETOYState, dev);
|
||||||
reset_sensor(USB_CONTAINER_OF(dev, EYETOYState, dev));
|
reset_controller(s);
|
||||||
|
reset_sensor(s);
|
||||||
|
if (s->mic)
|
||||||
|
s->mic->klass.handle_reset(s->mic);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void webcam_handle_control_eyetoy(USBDevice* dev, USBPacket* p, int request, int value, int index, int length, uint8_t* data)
|
static void webcam_handle_control_eyetoy(USBDevice* dev, USBPacket* p, int request, int value, int index, int length, uint8_t* data)
|
||||||
|
@ -328,10 +332,8 @@ namespace usb_eyetoy
|
||||||
}
|
}
|
||||||
else if (devep == 2)
|
else if (devep == 2)
|
||||||
{
|
{
|
||||||
// get audio
|
if (s->mic)
|
||||||
//Console.Warning("get audio %d\n", len);
|
s->mic->klass.handle_data(s->mic, p);
|
||||||
memset(data, 0, std::min(p->buffer_size, max_ep_size));
|
|
||||||
usb_packet_copy(p, data, std::min(p->buffer_size, max_ep_size));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case USB_TOKEN_OUT:
|
case USB_TOKEN_OUT:
|
||||||
|
@ -408,11 +410,18 @@ namespace usb_eyetoy
|
||||||
{
|
{
|
||||||
EYETOYState* s = USB_CONTAINER_OF(dev, EYETOYState, dev);
|
EYETOYState* s = USB_CONTAINER_OF(dev, EYETOYState, dev);
|
||||||
close_camera(s);
|
close_camera(s);
|
||||||
|
if (s->mic)
|
||||||
|
s->mic->klass.unrealize(s->mic);
|
||||||
delete s;
|
delete s;
|
||||||
}
|
}
|
||||||
|
|
||||||
USBDevice* EyeToyWebCamDevice::CreateDevice(SettingsInterface& si, u32 port, u32 subtype) const
|
USBDevice* EyeToyWebCamDevice::CreateDevice(SettingsInterface& si, u32 port, u32 subtype) const
|
||||||
{
|
{
|
||||||
|
const usb_mic::MicrophoneDevice* mic_proxy =
|
||||||
|
static_cast<usb_mic::MicrophoneDevice*>(RegisterDevice::instance().Device(DEVTYPE_MICROPHONE));
|
||||||
|
if (!mic_proxy)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
std::unique_ptr<VideoDevice> videodev(VideoDevice::CreateInstance());
|
std::unique_ptr<VideoDevice> videodev(VideoDevice::CreateInstance());
|
||||||
if (!videodev)
|
if (!videodev)
|
||||||
{
|
{
|
||||||
|
@ -435,6 +444,8 @@ namespace usb_eyetoy
|
||||||
goto fail;
|
goto fail;
|
||||||
s->dev.klass.handle_control = webcam_handle_control_eyetoy;
|
s->dev.klass.handle_control = webcam_handle_control_eyetoy;
|
||||||
s->dev.klass.handle_data = webcam_handle_data_eyetoy;
|
s->dev.klass.handle_data = webcam_handle_data_eyetoy;
|
||||||
|
|
||||||
|
s->mic = mic_proxy->CreateDevice(si, port, 0, false, 16000, TypeName());
|
||||||
}
|
}
|
||||||
else if (subtype == TYPE_OV511P)
|
else if (subtype == TYPE_OV511P)
|
||||||
{
|
{
|
||||||
|
@ -503,17 +514,42 @@ namespace usb_eyetoy
|
||||||
std::span<const char*> EyeToyWebCamDevice::SubTypes() const
|
std::span<const char*> EyeToyWebCamDevice::SubTypes() const
|
||||||
{
|
{
|
||||||
static const char* subtypes[] = {
|
static const char* subtypes[] = {
|
||||||
TRANSLATE_NOOP("USB", "Sony EyeToy"), TRANSLATE_NOOP("USB", "Konami Capture Eye")};
|
TRANSLATE_NOOP("USB", "Sony EyeToy"),
|
||||||
|
TRANSLATE_NOOP("USB", "Konami Capture Eye")
|
||||||
|
};
|
||||||
return subtypes;
|
return subtypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::span<const SettingInfo> EyeToyWebCamDevice::Settings(u32 subtype) const
|
std::span<const SettingInfo> EyeToyWebCamDevice::Settings(u32 subtype) const
|
||||||
{
|
{
|
||||||
static constexpr const SettingInfo info[] = {
|
switch (subtype)
|
||||||
{SettingInfo::Type::StringList, "device_name", TRANSLATE_NOOP("USB", "Device Name"),
|
{
|
||||||
TRANSLATE_NOOP("USB", "Selects the device to capture images from."), "", nullptr, nullptr, nullptr,
|
case TYPE_EYETOY:
|
||||||
nullptr, nullptr, &VideoDevice::GetDeviceList},
|
{
|
||||||
};
|
static constexpr const SettingInfo info[] = {
|
||||||
return info;
|
{SettingInfo::Type::StringList, "device_name", TRANSLATE_NOOP("USB", "Video Device"),
|
||||||
|
TRANSLATE_NOOP("USB", "Selects the device to capture images from."), "", nullptr, nullptr, nullptr,
|
||||||
|
nullptr, nullptr, &VideoDevice::GetDeviceList},
|
||||||
|
{SettingInfo::Type::StringList, "input_device_name", TRANSLATE_NOOP("USB", "Audio Device"),
|
||||||
|
TRANSLATE_NOOP("USB", "Selects the device to read audio from."), "", nullptr, nullptr, nullptr, nullptr,
|
||||||
|
nullptr, &AudioDevice::GetInputDeviceList},
|
||||||
|
{SettingInfo::Type::Integer, "input_latency", TRANSLATE_NOOP("USB", "Audio Latency"),
|
||||||
|
TRANSLATE_NOOP("USB", "Specifies the latency to the host input device."),
|
||||||
|
AudioDevice::DEFAULT_LATENCY_STR, "1", "1000", "1", TRANSLATE_NOOP("USB", "%dms"), nullptr, nullptr, 1.0f},
|
||||||
|
};
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
case TYPE_OV511P:
|
||||||
|
{
|
||||||
|
static constexpr const SettingInfo info[] = {
|
||||||
|
{SettingInfo::Type::StringList, "device_name", TRANSLATE_NOOP("USB", "Video Device"),
|
||||||
|
TRANSLATE_NOOP("USB", "Selects the device to capture images from."), "", nullptr, nullptr, nullptr,
|
||||||
|
nullptr, nullptr, &VideoDevice::GetDeviceList},
|
||||||
|
};
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // namespace usb_eyetoy
|
} // namespace usb_eyetoy
|
||||||
|
|
|
@ -55,13 +55,13 @@ namespace usb_mic
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A USB audio device supports an arbitrary number of alternate
|
* A USB audio device supports an arbitrary number of alternate
|
||||||
* interface settings for each interface. Each corresponds to a block
|
* interface settings for each interface. Each corresponds to a block
|
||||||
* diagram of parameterized blocks. This can thus refer to things like
|
* diagram of parameterized blocks. This can thus refer to things like
|
||||||
* number of channels, data rates, or in fact completely different
|
* number of channels, data rates, or in fact completely different
|
||||||
* block diagrams. Alternative setting 0 is always the null block diagram,
|
* block diagrams. Alternative setting 0 is always the null block diagram,
|
||||||
* which is used by a disabled device.
|
* which is used by a disabled device.
|
||||||
*/
|
*/
|
||||||
enum usb_audio_altset : int8_t
|
enum usb_audio_altset : int8_t
|
||||||
{
|
{
|
||||||
ALTSET_OFF = 0x00, /* No endpoint */
|
ALTSET_OFF = 0x00, /* No endpoint */
|
||||||
|
@ -200,7 +200,7 @@ namespace usb_mic
|
||||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||||
0x00, /* iInterface */
|
0x00, /* iInterface */
|
||||||
|
|
||||||
/* Interface 1, Alternate Setting 1, Audio Streaming - Operational */
|
/* Interface 1, Alternate Setting 1, Audio Streaming - 1 channel */
|
||||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||||
0x01, /* bInterfaceNumber */
|
0x01, /* bInterfaceNumber */
|
||||||
|
@ -252,7 +252,7 @@ namespace usb_mic
|
||||||
0x00, /* bLockDelayUnits */
|
0x00, /* bLockDelayUnits */
|
||||||
WBVAL(0x0000), /* wLockDelay */
|
WBVAL(0x0000), /* wLockDelay */
|
||||||
|
|
||||||
/* Interface 1, Alternate Setting 2, Audio Streaming - ? */
|
/* Interface 1, Alternate Setting 2, Audio Streaming - 2 channels */
|
||||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||||
0x01, /* bInterfaceNumber */
|
0x01, /* bInterfaceNumber */
|
||||||
|
@ -402,7 +402,7 @@ namespace usb_mic
|
||||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||||
0x00, /* iInterface */
|
0x00, /* iInterface */
|
||||||
|
|
||||||
/* Interface 1, Alternate Setting 1, Audio Streaming - Operational */
|
/* Interface 1, Alternate Setting 1, Audio Streaming - 1 channel */
|
||||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||||
0x01, /* bInterfaceNumber */
|
0x01, /* bInterfaceNumber */
|
||||||
|
@ -454,7 +454,7 @@ namespace usb_mic
|
||||||
0x00, /* bLockDelayUnits */
|
0x00, /* bLockDelayUnits */
|
||||||
WBVAL(0x0000), /* wLockDelay */
|
WBVAL(0x0000), /* wLockDelay */
|
||||||
|
|
||||||
/* Interface 1, Alternate Setting 2, Audio Streaming - ? */
|
/* Interface 1, Alternate Setting 2, Audio Streaming - 2 channels */
|
||||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||||
0x01, /* bInterfaceNumber */
|
0x01, /* bInterfaceNumber */
|
||||||
|
@ -627,7 +627,7 @@ namespace usb_mic
|
||||||
Console.Warning("singstar: ep control cs %x, cn %X, %X %X data:", cs, cn, attrib, ep);
|
Console.Warning("singstar: ep control cs %x, cn %X, %X %X data:", cs, cn, attrib, ep);
|
||||||
/*for(int i=0; i<length; i++)
|
/*for(int i=0; i<length; i++)
|
||||||
Console.Warning("%02X ", data[i]);
|
Console.Warning("%02X ", data[i]);
|
||||||
Console.Warning("\n");*/
|
Console.Warning("\n");*/
|
||||||
|
|
||||||
switch (aid)
|
switch (aid)
|
||||||
{
|
{
|
||||||
|
@ -692,8 +692,8 @@ namespace usb_mic
|
||||||
switch (request)
|
switch (request)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Audio device specific request
|
* Audio device specific request
|
||||||
*/
|
*/
|
||||||
case ClassInterfaceRequest | AUDIO_REQUEST_GET_CUR:
|
case ClassInterfaceRequest | AUDIO_REQUEST_GET_CUR:
|
||||||
case ClassInterfaceRequest | AUDIO_REQUEST_GET_MIN:
|
case ClassInterfaceRequest | AUDIO_REQUEST_GET_MIN:
|
||||||
case ClassInterfaceRequest | AUDIO_REQUEST_GET_MAX:
|
case ClassInterfaceRequest | AUDIO_REQUEST_GET_MAX:
|
||||||
|
@ -749,24 +749,21 @@ namespace usb_mic
|
||||||
{
|
{
|
||||||
SINGSTARMICState* s = USB_CONTAINER_OF(dev, SINGSTARMICState, dev);
|
SINGSTARMICState* s = USB_CONTAINER_OF(dev, SINGSTARMICState, dev);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint8_t devep = p->ep->nr;
|
|
||||||
|
|
||||||
switch (p->pid)
|
switch (p->pid)
|
||||||
{
|
{
|
||||||
case USB_TOKEN_IN:
|
case USB_TOKEN_IN:
|
||||||
//Console.Warning("token in ep: %d len: %zd\n", devep, p->iov.size);
|
//Console.Warning("token in ep: %d len: %zd\n", devep, p->iov.size);
|
||||||
if (devep == 1)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
int outChns = s->f.intf == 1 ? 1 : 2;
|
int outChns = s->f.intf == 2 ? 2 : 1;
|
||||||
uint32_t frames, out_frames[2] = {0}, chn;
|
uint32_t frames, out_frames[2] = {0}, chn;
|
||||||
int16_t *src1, *src2;
|
int16_t *src1, *src2;
|
||||||
int16_t* dst = (int16_t*)p->buffer_ptr;
|
int16_t* dst = (int16_t*)p->buffer_ptr;
|
||||||
size_t len = p->buffer_size;
|
size_t len = p->buffer_size;
|
||||||
|
|
||||||
// send only 1ms (bInterval) of samples
|
// send only 1ms (bInterval) of samples
|
||||||
if (s->f.srate[0] == 48000 || s->f.srate[0] == 8000)
|
if (s->f.srate[0] == 48000 || s->f.srate[0] == 8000 || s->f.srate[0] == 16000)
|
||||||
len = std::min<u32>(p->buffer_size, outChns * sizeof(int16_t) * s->f.srate[0] / 1000);
|
len = std::min<u32>(p->buffer_size, outChns * sizeof(int16_t) * s->f.srate[0] / 1000);
|
||||||
|
|
||||||
//Divide 'len' bytes between 2 channels of 16 bits
|
//Divide 'len' bytes between 2 channels of 16 bits
|
||||||
|
@ -912,10 +909,10 @@ namespace usb_mic
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
static const bool dual_mic = subtype == MIC_SINGSTAR;
|
static const bool dual_mic = subtype == MIC_SINGSTAR;
|
||||||
return CreateDevice(si, port, subtype, dual_mic, MicrophoneDevice::TypeName());
|
return CreateDevice(si, port, subtype, dual_mic, 48000, MicrophoneDevice::TypeName());
|
||||||
}
|
}
|
||||||
|
|
||||||
USBDevice* MicrophoneDevice::CreateDevice(SettingsInterface& si, u32 port, u32 subtype, bool dual_mic, const char* devtype) const
|
USBDevice* MicrophoneDevice::CreateDevice(SettingsInterface& si, u32 port, u32 subtype, bool dual_mic, const int samplerate, const char* devtype) const
|
||||||
{
|
{
|
||||||
if (subtype >= MIC_COUNT)
|
if (subtype >= MIC_COUNT)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -985,6 +982,7 @@ namespace usb_mic
|
||||||
Host::OSD_ERROR_DURATION);
|
Host::OSD_ERROR_DURATION);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
s->audsrc[i]->SetResampling(samplerate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1020,8 +1018,8 @@ namespace usb_mic
|
||||||
// set defaults
|
// set defaults
|
||||||
s->f.vol[0] = 240; /* 0 dB */
|
s->f.vol[0] = 240; /* 0 dB */
|
||||||
s->f.vol[1] = 240; /* 0 dB */
|
s->f.vol[1] = 240; /* 0 dB */
|
||||||
s->f.srate[0] = 48000;
|
s->f.srate[0] = samplerate;
|
||||||
s->f.srate[1] = 48000;
|
s->f.srate[1] = samplerate;
|
||||||
|
|
||||||
usb_desc_init(&s->dev);
|
usb_desc_init(&s->dev);
|
||||||
usb_ep_init(&s->dev);
|
usb_ep_init(&s->dev);
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace usb_mic
|
||||||
class MicrophoneDevice : public DeviceProxy
|
class MicrophoneDevice : public DeviceProxy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
USBDevice* CreateDevice(SettingsInterface& si, u32 port, u32 subtype, bool dual_mic, const char* devtype) const;
|
USBDevice* CreateDevice(SettingsInterface& si, u32 port, u32 subtype, bool dual_mic, const int samplerate, const char* devtype) const;
|
||||||
USBDevice* CreateDevice(SettingsInterface& si, u32 port, u32 subtype) const override;
|
USBDevice* CreateDevice(SettingsInterface& si, u32 port, u32 subtype) const override;
|
||||||
const char* Name() const override;
|
const char* Name() const override;
|
||||||
const char* TypeName() const override;
|
const char* TypeName() const override;
|
||||||
|
|
|
@ -393,7 +393,7 @@ namespace usb_pad
|
||||||
if (!mic_proxy)
|
if (!mic_proxy)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
USBDevice* mic = mic_proxy->CreateDevice(si, port, 0, false, TypeName());
|
USBDevice* mic = mic_proxy->CreateDevice(si, port, 0, false, 48000, TypeName());
|
||||||
if (!mic)
|
if (!mic)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue