1 // Copyright (c) 2019- PPSSPP Project.
2 
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0 or later versions.
6 
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 // GNU General Public License 2.0 for more details.
11 
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
14 
15 // Official git repository and contact information can be found at
16 // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17 
18 #include "ppsspp_config.h"
19 #include <algorithm>
20 #include <mutex>
21 
22 #include "Common/Serialize/Serializer.h"
23 #include "Common/Serialize/SerializeFuncs.h"
24 #include "Common/System/System.h"
25 #include "Core/HLE/HLE.h"
26 #include "Core/HLE/FunctionWrappers.h"
27 #include "Core/HLE/sceKernelThread.h"
28 #include "Core/HLE/sceUsbMic.h"
29 #include "Core/CoreTiming.h"
30 #include "Core/MemMapHelpers.h"
31 
32 #if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__)
33 #define HAVE_WIN32_MICROPHONE
34 #endif
35 
36 #ifdef HAVE_WIN32_MICROPHONE
37 #include "Common/CommonWindows.h"
38 #include "Windows/CaptureDevice.h"
39 #endif
40 
41 enum {
42 	SCE_USBMIC_ERROR_INVALID_MAX_SAMPLES = 0x80243806,
43 	SCE_USBMIC_ERROR_INVALID_SAMPLERATE  = 0x8024380A,
44 };
45 
46 int eventMicBlockingResume = -1;
47 
48 static QueueBuf *audioBuf = nullptr;
49 static u32 numNeedSamples;
50 static std::vector<MicWaitInfo> waitingThreads;
51 static bool isNeedInput;
52 static u32 curSampleRate;
53 static u32 curChannels;
54 static u32 readMicDataLength;
55 static u32 curTargetAddr;
56 static int micState; // 0 means stopped, 1 means started, for save state.
57 
__MicBlockingResume(u64 userdata,int cyclesLate)58 static void __MicBlockingResume(u64 userdata, int cyclesLate) {
59 	SceUID threadID = (SceUID)userdata;
60 	u32 error;
61 	int count = 0;
62 	for (auto waitingThread : waitingThreads) {
63 		if (waitingThread.threadID == threadID) {
64 			SceUID waitID = __KernelGetWaitID(threadID, WAITTYPE_MICINPUT, error);
65 			if (waitID == 0)
66 				continue;
67 			if (Microphone::isHaveDevice()) {
68 				if (Microphone::getReadMicDataLength() >= waitingThread.needSize) {
69 					u32 ret = __KernelGetWaitValue(threadID, error);
70 					DEBUG_LOG(HLE, "sceUsbMic: Waking up thread(%d)", (int)waitingThread.threadID);
71 					__KernelResumeThreadFromWait(threadID, ret);
72 					waitingThreads.erase(waitingThreads.begin() + count);
73 				} else {
74 					u64 waitTimeus = (waitingThread.needSize - Microphone::getReadMicDataLength()) * 1000000 / 2 / waitingThread.sampleRate;
75 					CoreTiming::ScheduleEvent(usToCycles(waitTimeus), eventMicBlockingResume, userdata);
76 				}
77 			} else {
78 				for (u32 i = 0; i < waitingThread.needSize; i++) {
79 					if (Memory::IsValidAddress(waitingThread.addr + i)) {
80 						Memory::Write_U8(i & 0xFF, waitingThread.addr + i);
81 					}
82 				}
83 				u32 ret = __KernelGetWaitValue(threadID, error);
84 				DEBUG_LOG(HLE, "sceUsbMic: Waking up thread(%d)", (int)waitingThread.threadID);
85 				__KernelResumeThreadFromWait(threadID, ret);
86 				waitingThreads.erase(waitingThreads.begin() + count);
87 				readMicDataLength += waitingThread.needSize;
88 			}
89 		}
90 		++count;
91 	}
92 }
93 
__UsbMicInit()94 void __UsbMicInit() {
95 	if (audioBuf) {
96 		delete audioBuf;
97 		audioBuf = nullptr;
98 	}
99 	numNeedSamples = 0;
100 	waitingThreads.clear();
101 	isNeedInput = true;
102 	curSampleRate = 44100;
103 	curChannels = 1;
104 	curTargetAddr = 0;
105 	readMicDataLength = 0;
106 	micState = 0;
107 	eventMicBlockingResume = CoreTiming::RegisterEvent("MicBlockingResume", &__MicBlockingResume);
108 }
109 
__UsbMicShutdown()110 void __UsbMicShutdown() {
111 	if (audioBuf) {
112 		delete audioBuf;
113 		audioBuf = nullptr;
114 	}
115 	Microphone::stopMic();
116 }
117 
__UsbMicDoState(PointerWrap & p)118 void __UsbMicDoState(PointerWrap &p) {
119 	auto s = p.Section("sceUsbMic", 0, 3);
120 	if (!s) {
121 		// Still need to restore the event.
122 		eventMicBlockingResume = -1;
123 		CoreTiming::RestoreRegisterEvent(eventMicBlockingResume, "MicBlockingResume", &__MicBlockingResume);
124 		waitingThreads.clear();
125 		return;
126 	}
127 	bool isMicStartedNow = Microphone::isMicStarted();
128 	Do(p, numNeedSamples);
129 	Do(p, waitingThreads);
130 	Do(p, isNeedInput);
131 	Do(p, curSampleRate);
132 	Do(p, curChannels);
133 	Do(p, micState);
134 	if (s > 1) {
135 		Do(p, eventMicBlockingResume);
136 	} else {
137 		eventMicBlockingResume = -1;
138 	}
139 	CoreTiming::RestoreRegisterEvent(eventMicBlockingResume, "MicBlockingResume", &__MicBlockingResume);
140 
141 	if (s > 2) {
142 		Do(p, curTargetAddr);
143 		Do(p, readMicDataLength);
144 	}
145 	if (!audioBuf && numNeedSamples > 0) {
146 		audioBuf = new QueueBuf(numNeedSamples << 1);
147 	}
148 
149 	if (micState == 0) {
150 		if (isMicStartedNow)
151 			Microphone::stopMic();
152 	} else if (micState == 1) {
153 		if (isMicStartedNow) {
154 			// Ok, started.
155 		} else {
156 			Microphone::startMic(new std::vector<u32>({ curSampleRate, curChannels }));
157 		}
158 	}
159 }
160 
QueueBuf(u32 size)161 QueueBuf::QueueBuf(u32 size) : available(0), end(0), capacity(size) {
162 	buf_ = new u8[size];
163 }
164 
~QueueBuf()165 QueueBuf::~QueueBuf() {
166 	delete[] buf_;
167 }
168 
QueueBuf(const QueueBuf & buf)169 QueueBuf::QueueBuf(const QueueBuf &buf) {
170 	buf_ = new u8[buf.capacity];
171 	memcpy(buf_, buf.buf_, buf.capacity);
172 	available = buf.available;
173 	end = buf.end;
174 	capacity = buf.capacity;
175 }
176 
operator =(const QueueBuf & buf)177 QueueBuf& QueueBuf::operator=(const QueueBuf &buf) {
178 	if (capacity < buf.capacity) {
179 		resize(buf.capacity);
180 	}
181 	std::unique_lock<std::mutex> lock(mutex);
182 	memcpy(buf_, buf.buf_, buf.capacity);
183 	available = buf.available;
184 	end = buf.end;
185 	lock.unlock();
186 	return *this;
187 }
188 
push(u8 * buf,u32 size)189 u32 QueueBuf::push(u8 *buf, u32 size) {
190 	u32 addedSize = 0;
191 	if (size > capacity)
192 		resize(size);
193 	// This will overwrite the old data if the size prepare to add more than remaining size.
194 	std::unique_lock<std::mutex> lock(mutex);
195 	while (end + size > capacity) {
196 		memcpy(buf_ + end, buf + addedSize, capacity - end);
197 		addedSize += capacity - end;
198 		size -= capacity - end;
199 		end = 0;
200 	}
201 	memcpy(buf_ + end, buf + addedSize, size);
202 	addedSize += size;
203 	end = (end + size) % capacity;
204 	available = std::min(capacity, available + addedSize);
205 	lock.unlock();
206 	return addedSize;
207 }
208 
pop(u8 * buf,u32 size)209 u32 QueueBuf::pop(u8 *buf, u32 size) {
210 	u32 ret = 0;
211 	if (getAvailableSize() < size)
212 		size = getAvailableSize();
213 	ret = size;
214 
215 	std::unique_lock<std::mutex> lock(mutex);
216 	if (getStartPos() + size <= capacity) {
217 		memcpy(buf, buf_ + getStartPos(), size);
218 	} else {
219 		memcpy(buf, buf_ + getStartPos(), capacity - getStartPos());
220 		memcpy(buf + capacity - getStartPos(), buf_, size - (capacity - getStartPos()));
221 	}
222 	available -= size;
223 	lock.unlock();
224 	return ret;
225 }
226 
resize(u32 newSize)227 void QueueBuf::resize(u32 newSize) {
228 	if (capacity >= newSize) {
229 		return;
230 	}
231 	u32 availableSize = getAvailableSize();
232 	u8 *oldbuf = buf_;
233 
234 	buf_ = new u8[newSize];
235 	pop(buf_, availableSize);
236 	available = availableSize;
237 	end = availableSize;
238 	capacity = newSize;
239 	delete[] oldbuf;
240 }
241 
flush()242 void QueueBuf::flush() {
243 	std::unique_lock<std::mutex> lock(mutex);
244 	available = 0;
245 	end = 0;
246 	lock.unlock();
247 }
248 
getAvailableSize()249 u32 QueueBuf::getAvailableSize() {
250 	return available;
251 }
252 
getRemainingSize()253 u32 QueueBuf::getRemainingSize() {
254 	return capacity - getAvailableSize();
255 }
256 
getStartPos()257 u32 QueueBuf::getStartPos() {
258 	return end >= available ? end - available : capacity - available + end;
259 }
260 
sceUsbMicPollInputEnd()261 static int sceUsbMicPollInputEnd() {
262 	ERROR_LOG(HLE, "UNIMPL sceUsbMicPollInputEnd");
263 	return 0;
264 }
265 
sceUsbMicInputBlocking(u32 maxSamples,u32 sampleRate,u32 bufAddr)266 static int sceUsbMicInputBlocking(u32 maxSamples, u32 sampleRate, u32 bufAddr) {
267 	if (!Memory::IsValidAddress(bufAddr)) {
268 		ERROR_LOG(HLE, "sceUsbMicInputBlocking(%d, %d, %08x): invalid addresses", maxSamples, sampleRate, bufAddr);
269 		return -1;
270 	}
271 
272 	INFO_LOG(HLE, "sceUsbMicInputBlocking: maxSamples: %d, samplerate: %d, bufAddr: %08x", maxSamples, sampleRate, bufAddr);
273 	if (maxSamples <= 0 || (maxSamples & 0x3F) != 0) {
274 		return SCE_USBMIC_ERROR_INVALID_MAX_SAMPLES;
275 	}
276 
277 	if (sampleRate != 44100 && sampleRate != 22050 && sampleRate != 11025) {
278 		return SCE_USBMIC_ERROR_INVALID_SAMPLERATE;
279 	}
280 
281 	return __MicInput(maxSamples, sampleRate, bufAddr, USBMIC);
282 }
283 
sceUsbMicInputInitEx(u32 paramAddr)284 static int sceUsbMicInputInitEx(u32 paramAddr) {
285 	ERROR_LOG(HLE, "UNIMPL sceUsbMicInputInitEx: %08x", paramAddr);
286 	return 0;
287 }
288 
sceUsbMicInput(u32 maxSamples,u32 sampleRate,u32 bufAddr)289 static int sceUsbMicInput(u32 maxSamples, u32 sampleRate, u32 bufAddr) {
290 	if (!Memory::IsValidAddress(bufAddr)) {
291 		ERROR_LOG(HLE, "sceUsbMicInput(%d, %d, %08x): invalid addresses", maxSamples, sampleRate, bufAddr);
292 		return -1;
293 	}
294 
295 	ERROR_LOG(HLE, "UNTEST sceUsbMicInput: maxSamples: %d, samplerate: %d, bufAddr: %08x", maxSamples, sampleRate, bufAddr);
296 	if (maxSamples <= 0 || (maxSamples & 0x3F) != 0) {
297 		return SCE_USBMIC_ERROR_INVALID_MAX_SAMPLES;
298 	}
299 
300 	if (sampleRate != 44100 && sampleRate != 22050 && sampleRate != 11025) {
301 		return SCE_USBMIC_ERROR_INVALID_SAMPLERATE;
302 	}
303 
304 	return __MicInput(maxSamples, sampleRate, bufAddr, USBMIC, false);
305 }
sceUsbMicGetInputLength()306 static int sceUsbMicGetInputLength() {
307 	int ret = Microphone::getReadMicDataLength() / 2;
308 	ERROR_LOG(HLE, "UNTEST sceUsbMicGetInputLength(ret: %d)", ret);
309 	return ret;
310 }
311 
sceUsbMicInputInit(int unknown1,int inputVolume,int unknown2)312 static int sceUsbMicInputInit(int unknown1, int inputVolume, int unknown2) {
313 	ERROR_LOG(HLE, "UNIMPL sceUsbMicInputInit(unknown1: %d, inputVolume: %d, unknown2: %d)", unknown1, inputVolume, unknown2);
314 	return 0;
315 }
316 
sceUsbMicWaitInputEnd()317 static int sceUsbMicWaitInputEnd() {
318 	ERROR_LOG(HLE, "UNIMPL sceUsbMicWaitInputEnd");
319 	return 0;
320 }
321 
startMic(void * param)322 int Microphone::startMic(void *param) {
323 #ifdef HAVE_WIN32_MICROPHONE
324 	if (winMic)
325 		winMic->sendMessage({ CAPTUREDEVIDE_COMMAND::START, param });
326 #elif PPSSPP_PLATFORM(ANDROID)
327 	std::vector<u32> *micParam = static_cast<std::vector<u32>*>(param);
328 	int sampleRate = micParam->at(0);
329 	int channels = micParam->at(1);
330 	INFO_LOG(HLE, "microphone_command : sr = %d", sampleRate);
331 	System_SendMessage("microphone_command", ("startRecording:" + std::to_string(sampleRate)).c_str());
332 #endif
333 	micState = 1;
334 	return 0;
335 }
336 
stopMic()337 int Microphone::stopMic() {
338 #ifdef HAVE_WIN32_MICROPHONE
339 	if (winMic)
340 		winMic->sendMessage({ CAPTUREDEVIDE_COMMAND::STOP, nullptr });
341 #elif PPSSPP_PLATFORM(ANDROID)
342 	System_SendMessage("microphone_command", "stopRecording");
343 #endif
344 	micState = 0;
345 	return 0;
346 }
347 
isHaveDevice()348 bool Microphone::isHaveDevice() {
349 #ifdef HAVE_WIN32_MICROPHONE
350 	return winMic->getDeviceCounts() >= 1;
351 #elif PPSSPP_PLATFORM(ANDROID)
352 	return audioRecording_Available();
353 #endif
354 	return false;
355 }
356 
isMicStarted()357 bool Microphone::isMicStarted() {
358 	return micState == 1;
359 }
360 
361 // Deprecated.
isNeedInput()362 bool Microphone::isNeedInput() {
363 	return ::isNeedInput;
364 }
365 
numNeedSamples()366 u32 Microphone::numNeedSamples() {
367 	return ::numNeedSamples;
368 }
369 
availableAudioBufSize()370 u32 Microphone::availableAudioBufSize() {
371 	return audioBuf->getAvailableSize();
372 }
373 
getReadMicDataLength()374 u32 Microphone::getReadMicDataLength() {
375 	return ::readMicDataLength;
376 }
377 
addAudioData(u8 * buf,u32 size)378 int Microphone::addAudioData(u8 *buf, u32 size) {
379 	if (audioBuf)
380 		audioBuf->push(buf, size);
381 	else
382 		return 0;
383 	if (Memory::IsValidAddress(curTargetAddr)) {
384 		u32 addSize = std::min(audioBuf->getAvailableSize(), numNeedSamples() * 2 - getReadMicDataLength());
385 		u8 *tempbuf8 = new u8[addSize];
386 		getAudioData(tempbuf8, addSize);
387 		Memory::Memcpy(curTargetAddr + readMicDataLength, tempbuf8, addSize);
388 		delete[] tempbuf8;
389 		readMicDataLength += addSize;
390 	}
391 
392 	return size;
393 }
394 
getAudioData(u8 * buf,u32 size)395 u32 Microphone::getAudioData(u8 *buf, u32 size) {
396 	if(audioBuf)
397 		return audioBuf->pop(buf, size);
398 
399 	return 0;
400 }
401 
flushAudioData()402 void Microphone::flushAudioData() {
403 	audioBuf->flush();
404 }
405 
getDeviceList()406 std::vector<std::string> Microphone::getDeviceList() {
407 #ifdef HAVE_WIN32_MICROPHONE
408 	if (winMic) {
409 		return winMic->getDeviceList();
410 	}
411 #endif
412 	return std::vector<std::string>();
413 }
414 
onMicDeviceChange()415 void Microphone::onMicDeviceChange() {
416 	if (Microphone::isMicStarted()) {
417 		Microphone::stopMic();
418 		// Just use the last param.
419 		Microphone::startMic(nullptr);
420 	}
421 }
422 
__MicInput(u32 maxSamples,u32 sampleRate,u32 bufAddr,MICTYPE type,bool block)423 u32 __MicInput(u32 maxSamples, u32 sampleRate, u32 bufAddr, MICTYPE type, bool block) {
424 	curSampleRate = sampleRate;
425 	curChannels = 1;
426 	curTargetAddr = bufAddr;
427 	u32 size = maxSamples << 1;
428 	if (!audioBuf) {
429 		audioBuf = new QueueBuf(size);
430 	} else {
431 		audioBuf->resize(size);
432 	}
433 	if (!audioBuf)
434 		return 0;
435 
436 	numNeedSamples = maxSamples;
437 	readMicDataLength = 0;
438 	if (!Microphone::isMicStarted()) {
439 		std::vector<u32> *param = new std::vector<u32>({ sampleRate, 1 });
440 		Microphone::startMic(param);
441 	}
442 
443 	if (Microphone::availableAudioBufSize() > 0) {
444 		u32 addSize = std::min(Microphone::availableAudioBufSize(), size);
445 		u8 *tempbuf8 = new u8[addSize];
446 		Microphone::getAudioData(tempbuf8, addSize);
447 		Memory::Memcpy(curTargetAddr, tempbuf8, addSize);
448 		delete[] tempbuf8;
449 		readMicDataLength += addSize;
450 	}
451 
452 	if (!block) {
453 		return type == CAMERAMIC ? size : maxSamples;
454 	}
455 
456 	u64 waitTimeus = (size - Microphone::availableAudioBufSize()) * 1000000 / 2 / sampleRate;
457 	CoreTiming::ScheduleEvent(usToCycles(waitTimeus), eventMicBlockingResume, __KernelGetCurThread());
458 	MicWaitInfo waitInfo = { __KernelGetCurThread(), bufAddr, size, sampleRate };
459 	waitingThreads.push_back(waitInfo);
460 	DEBUG_LOG(HLE, "MicInputBlocking: blocking thread(%d)", (int)__KernelGetCurThread());
461 	__KernelWaitCurThread(WAITTYPE_MICINPUT, 1, size, 0, false, "blocking microphone");
462 
463 	return type == CAMERAMIC ? size : maxSamples;
464 }
465 
466 const HLEFunction sceUsbMic[] =
467 {
468 	{0x06128E42, &WrapI_V<sceUsbMicPollInputEnd>,    "sceUsbMicPollInputEnd",         'i', ""    },
469 	{0x2E6DCDCD, &WrapI_UUU<sceUsbMicInputBlocking>, "sceUsbMicInputBlocking",        'i', "xxx" },
470 	{0x45310F07, &WrapI_U<sceUsbMicInputInitEx>,     "sceUsbMicInputInitEx",          'i', "x"   },
471 	{0x5F7F368D, &WrapI_UUU<sceUsbMicInput>,         "sceUsbMicInput",                'i', "xxx" },
472 	{0x63400E20, &WrapI_V<sceUsbMicGetInputLength>,  "sceUsbMicGetInputLength",       'i', ""    },
473 	{0xB8E536EB, &WrapI_III<sceUsbMicInputInit>,     "sceUsbMicInputInit",            'i', "iii" },
474 	{0xF899001C, &WrapI_V<sceUsbMicWaitInputEnd>,    "sceUsbMicWaitInputEnd",         'i', ""    },
475 };
476 
Register_sceUsbMic()477 void Register_sceUsbMic()
478 {
479 	RegisterModule("sceUsbMic", ARRAY_SIZE(sceUsbMic), sceUsbMic);
480 }
481