summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorSepalani <sepalani@hotmail.fr>2024-05-14 01:52:52 +0400
committerSepalani <sepalani@hotmail.fr>2025-05-07 20:33:22 +0400
commit407218a8b4efdfe294f7c3bdc7fed229c57fcf8e (patch)
tree5bf369b294f62fe106cd71e35cc98baeaf6f408a /Source
parentdbc09bfb0d75f939fd29e68d621cb56fff07ba6e (diff)
IOS/USB: Report Wii Speak packet size properly
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/IOS/USB/Emulated/Microphone.cpp12
-rw-r--r--Source/Core/Core/IOS/USB/Emulated/Microphone.h2
-rw-r--r--Source/Core/Core/IOS/USB/Emulated/WiiSpeak.cpp33
3 files changed, 23 insertions, 24 deletions
diff --git a/Source/Core/Core/IOS/USB/Emulated/Microphone.cpp b/Source/Core/Core/IOS/USB/Emulated/Microphone.cpp
index 6e2f40072c..592f2e9977 100644
--- a/Source/Core/Core/IOS/USB/Emulated/Microphone.cpp
+++ b/Source/Core/Core/IOS/USB/Emulated/Microphone.cpp
@@ -235,7 +235,7 @@ long Microphone::DataCallback(const s16* input_buffer, long nframes)
}
#endif
-void Microphone::ReadIntoBuffer(u8* dst, u32 size)
+u16 Microphone::ReadIntoBuffer(u8* ptr, u32 size)
{
static constexpr u32 SINGLE_READ_SIZE = BUFF_SIZE_SAMPLES * sizeof(SampleType);
@@ -245,22 +245,20 @@ void Microphone::ReadIntoBuffer(u8* dst, u32 size)
std::lock_guard lock(m_ring_lock);
- for (u8* end = dst + size; dst < end; dst += SINGLE_READ_SIZE, size -= SINGLE_READ_SIZE)
+ u8* begin = ptr;
+ for (u8* end = begin + size; ptr < end; ptr += SINGLE_READ_SIZE, size -= SINGLE_READ_SIZE)
{
if (size < SINGLE_READ_SIZE || m_samples_avail < BUFF_SIZE_SAMPLES)
break;
SampleType* last_buffer = &m_stream_buffer[m_stream_rpos];
- std::memcpy(dst, last_buffer, SINGLE_READ_SIZE);
+ std::memcpy(ptr, last_buffer, SINGLE_READ_SIZE);
m_samples_avail -= BUFF_SIZE_SAMPLES;
m_stream_rpos += BUFF_SIZE_SAMPLES;
m_stream_rpos %= STREAM_SIZE;
}
- if (size != 0)
- {
- std::memset(dst, 0, size);
- }
+ return static_cast<u16>(ptr - begin);
}
bool Microphone::HasData(u32 sample_count = BUFF_SIZE_SAMPLES) const
diff --git a/Source/Core/Core/IOS/USB/Emulated/Microphone.h b/Source/Core/Core/IOS/USB/Emulated/Microphone.h
index 227d9926b4..d4c383ccb5 100644
--- a/Source/Core/Core/IOS/USB/Emulated/Microphone.h
+++ b/Source/Core/Core/IOS/USB/Emulated/Microphone.h
@@ -28,7 +28,7 @@ public:
~Microphone();
bool HasData(u32 sample_count) const;
- void ReadIntoBuffer(u8* dst, u32 size);
+ u16 ReadIntoBuffer(u8* ptr, u32 size);
private:
#ifdef HAVE_CUBEB
diff --git a/Source/Core/Core/IOS/USB/Emulated/WiiSpeak.cpp b/Source/Core/Core/IOS/USB/Emulated/WiiSpeak.cpp
index 712292f240..70b9095dd1 100644
--- a/Source/Core/Core/IOS/USB/Emulated/WiiSpeak.cpp
+++ b/Source/Core/Core/IOS/USB/Emulated/WiiSpeak.cpp
@@ -3,6 +3,8 @@
#include "Core/IOS/USB/Emulated/WiiSpeak.h"
+#include <algorithm>
+
#include "Core/Config/MainSettings.h"
#include "Core/HW/Memmap.h"
#include "Core/System.h"
@@ -177,10 +179,18 @@ int WiiSpeak::SubmitTransfer(std::unique_ptr<IsoMessage> cmd)
switch (cmd->endpoint)
{
case ENDPOINT_AUDIO_IN:
+ {
// Transfer: Wii Speak -> Wii
+ u16 size = 0;
if (m_microphone && m_microphone->HasData(cmd->length / sizeof(s16)))
- m_microphone->ReadIntoBuffer(packets, cmd->length);
+ size = m_microphone->ReadIntoBuffer(packets, cmd->length);
+ for (std::size_t i = 0; i < cmd->num_packets; i++)
+ {
+ cmd->SetPacketReturnValue(i, std::min(size, cmd->packet_sizes[i]));
+ size = (size > cmd->packet_sizes[i]) ? (size - cmd->packet_sizes[i]) : 0;
+ }
break;
+ }
case ENDPOINT_AUDIO_OUT:
// Transfer: Wii -> Wii Speak
break;
@@ -203,22 +213,13 @@ int WiiSpeak::SubmitTransfer(std::unique_ptr<IsoMessage> cmd)
// (i.e. 128 samples in 16-bit mono) per frame transfer. The Microphone class is using cubeb
// configured with a sample rate of 8000.
//
- // Based on these numbers, here are some theoretical speeds:
- // - fastest transfer speed would be 8000 samples in 63 ms (i.e. 8000 * 1/128 = 62.5)
- // * using a timing of 1 ms per frame of 128 samples
- // * here cubeb sample rate is the bottleneck
- // - slowest transfer speed would be 8000 samples in 1000 ms (i.e. 128 * 1000/8000 = 16)
- // * using a timing of 16 ms per frame of 128 samples
- // * matching cubeb sampling rate
- //
- // A decent timing would be 16ms. However, it seems that the Wii Speak Channel record feature is
- // broken if the timing is less than 32ms and that the record playback is broken when around 34ms
- // and above. Monster Hunter 3 doesn't seem affected by this timing issue.
+ // Based on USB sniffing using Wireshark + Dolphin USB passthrough:
+ // - 125 frames are received per second (i.e. timing 8 ms per frame)
+ // - however, the cmd->length=0x80 which doesn't match the HLE emulation
+ // - each frame having 8 packets of 0x10 bytes
//
- // TODO: Investigate and ensure that's the proper way to fix it.
- // Maybe it's related to the Wii DSP and its stereo/mono mode?
- // If so, what would be the impact of using DSP LLE/HLE in mono/stereo?
- const u32 transfer_timing = 32000;
+ // Let's sample at a reasonable speed.
+ const u32 transfer_timing = 2000;
cmd->ScheduleTransferCompletion(IPC_SUCCESS, transfer_timing);
return IPC_SUCCESS;
}