Skip to content

Commit

Permalink
[Android] Audio record using OpenSL
Browse files Browse the repository at this point in the history
  • Loading branch information
Florin9doi committed Sep 7, 2019
1 parent 7f0d652 commit d6e47a2
Show file tree
Hide file tree
Showing 18 changed files with 379 additions and 30 deletions.
7 changes: 6 additions & 1 deletion Core/HLE/sceKernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,14 @@
#include "scePsmf.h"
#include "sceImpose.h"
#include "sceUsb.h"
#include "sceUsbCam.h"
#include "sceUsbGps.h"
#include "sceUsbMic.h"
#include "scePspNpDrm_user.h"
#include "sceVaudio.h"
#include "sceHeap.h"
#include "sceDmac.h"
#include "sceMp4.h"
#include "sceUsbCam.h"

#include "../Util/PPGeDraw.h"

Expand Down Expand Up @@ -145,6 +146,7 @@ void __KernelInit()
__VideoPmpInit();
__UsbGpsInit();
__UsbCamInit();
__UsbMicInit();

SaveState::Init(); // Must be after IO, as it may create a directory
Reporting::Init();
Expand All @@ -169,6 +171,7 @@ void __KernelShutdown()
kernelObjects.Clear();

__UsbCamShutdown();
__UsbMicShutdown();

__AudioCodecShutdown();
__VideoPmpShutdown();
Expand Down Expand Up @@ -276,6 +279,8 @@ void __KernelDoState(PointerWrap &p)
__VideoPmpDoState(p);
__AACDoState(p);
__UsbGpsDoState(p);
__UsbCamDoState(p);
__UsbMicDoState(p);

// IMPORTANT! Add new sections last!
}
Expand Down
2 changes: 1 addition & 1 deletion Core/HLE/sceUsb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ static int sceUsbGetState() {
| (usbConnected ? USB_STATUS_CONNECTED : USB_STATUS_DISCONNECTED)
| (usbActivated ? USB_STATUS_ACTIVATED : USB_STATUS_DEACTIVATED);
}
INFO_LOG(HLE, "sceUsbGetState: 0x%x", state);
VERBOSE_LOG(HLE, "sceUsbGetState: 0x%x", state);
return state;
}

Expand Down
64 changes: 50 additions & 14 deletions Core/HLE/sceUsbCam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@
#include "Core/HLE/HLE.h"
#include "Core/HLE/FunctionWrappers.h"
#include "Core/HLE/sceUsbCam.h"
#include "Core/HLE/sceUsbMic.h"
#include "Core/MemMapHelpers.h"

PspUsbCamSetupMicParam micParam;
PspUsbCamSetupVideoParam videoParam;

bool cameraEnabled = false;
unsigned int videoBufferLength = 0;
unsigned int nextVideoFrame = 0;
uint8_t *videoBuffer;
Expand All @@ -41,6 +43,14 @@ void __UsbCamInit() {
videoBuffer = new uint8_t[VIDEO_BUFFER_SIZE];
}

void __UsbCamDoState(PointerWrap &p) {
auto s = p.Section("sceUsbCam", 0, 1);
if (!s)
return;

p.Do(cameraEnabled);
}

void __UsbCamShutdown() {
delete[] videoBuffer;
videoBuffer = nullptr;
Expand All @@ -50,32 +60,57 @@ void __UsbCamShutdown() {
// module has been initialized.

static int sceUsbCamSetupMic(u32 paramAddr, u32 workareaAddr, int wasize) {
INFO_LOG(HLE, "UNIMPL sceUsbCamSetupMic");
if (Memory::IsValidRange(paramAddr, sizeof(micParam))) {
Memory::ReadStruct(paramAddr, &micParam);
}
INFO_LOG(HLE, "UNIMPL sceUsbCamSetupMic: freq=%d", micParam.frequency);
return 0;
}

static int sceUsbCamStartMic() {
INFO_LOG(HLE, "UNIMPL sceUsbCamStartMic");
__UsbMicStart(micParam.frequency, false);
return 0;
}

static int sceUsbCamStopMic() {
INFO_LOG(HLE, "UNIMPL sceUsbCamStopMic");
__UsbMicStop();
return 0;
}

static int sceUsbCamReadMicBlocking(u32 bufAddr, u32 size) {
INFO_LOG(HLE, "UNIMPL sceUsbCamReadMicBlocking: size: %d", size);
for (unsigned int i = 0; i < size; i++) {
if (Memory::IsValidAddress(bufAddr + i)) {
Memory::Write_U8(i & 0xFF, bufAddr + i);
}
std::lock_guard<std::mutex> lock(__UsbMicContext()->dataBufferMutex);
u32 transferSize = std::min(__UsbMicContext()->dataBufferLength, size);
if (Memory::IsValidRange(bufAddr, size)) {
Memory::Memcpy(bufAddr, __UsbMicContext()->dataBuffer, transferSize);
}
hleEatMicro(1000000 / micParam.frequency * (size / 2));
return size;
INFO_LOG(HLE, "UNIMPL sceUsbCamReadMicBlocking: size=%d, ret=%d", size, transferSize);
return transferSize;
}

static int sceUsbCamReadMic(u32 bufAddr, u32 size) {
std::lock_guard<std::mutex> lock( __UsbMicContext()->dataBufferMutex);
u32 transferSize = std::min( __UsbMicContext()->dataBufferLength, size);
if (Memory::IsValidRange(bufAddr, size)) {
Memory::Memcpy(bufAddr, __UsbMicContext()->dataBuffer + __UsbMicContext()->bufferPos, transferSize);
__UsbMicContext()->bufferPos += transferSize;
}
__UsbMicContext()->nextDataLen = transferSize;
INFO_LOG(HLE, "UNIMPL sceUsbCamReadMic: size=%d, pos=0x%x, ret=%d", size, __UsbMicContext()->bufferPos, transferSize);
return transferSize;
}

static int sceUsbCamPollReadMicEnd() {
std::lock_guard<std::mutex> lock( __UsbMicContext()->dataBufferMutex);
INFO_LOG(HLE, "UNIMPL sceUsbCamPollReadMicEnd: ret=%d", __UsbMicContext()->nextDataLen);
return __UsbMicContext()->nextDataLen;
}

static int sceUsbCamGetMicDataLength() {
std::lock_guard<std::mutex> lock( __UsbMicContext()->dataBufferMutex);
INFO_LOG(HLE, "UNIMPL sceUsbCamGetMicDataLength: ret=%d", __UsbMicContext()->nextDataLen);
return __UsbMicContext()->nextDataLen;
}

static int sceUsbCamSetupVideo(u32 paramAddr, u32 workareaAddr, int wasize) {
Expand All @@ -98,12 +133,14 @@ static int sceUsbCamSetupVideo(u32 paramAddr, u32 workareaAddr, int wasize) {
static int sceUsbCamStartVideo() {
INFO_LOG(HLE, "UNIMPL sceUsbCamStartVideo");
System_SendMessage("camera_command", "startVideo");
cameraEnabled = true;
return 0;
}

static int sceUsbCamStopVideo() {
INFO_LOG(HLE, "UNIMPL sceUsbCamStopVideo");
System_SendMessage("camera_command", "stopVideo");
cameraEnabled = false;
return 0;
}

Expand All @@ -114,12 +151,11 @@ static int sceUsbCamAutoImageReverseSW(int rev) {

static int sceUsbCamReadVideoFrameBlocking(u32 bufAddr, u32 size) {
std::lock_guard<std::mutex> lock(videoBufferMutex);

u32 transferSize = std::min(videoBufferLength, size);
if (Memory::IsValidRange(bufAddr, size)) {
Memory::Memcpy(bufAddr, videoBuffer, transferSize);
}
return videoBufferLength;
return transferSize;
}

static int sceUsbCamReadVideoFrame(u32 bufAddr, u32 size) {
Expand All @@ -128,7 +164,7 @@ static int sceUsbCamReadVideoFrame(u32 bufAddr, u32 size) {
if (Memory::IsValidRange(bufAddr, size)) {
Memory::Memcpy(bufAddr, videoBuffer, transferSize);
}
nextVideoFrame = videoBufferLength;
nextVideoFrame = transferSize;
return 0;
}

Expand All @@ -144,10 +180,10 @@ const HLEFunction sceUsbCam[] =
{ 0X82A64030, &WrapI_V<sceUsbCamStartMic>, "sceUsbCamStartMic", 'i', "" },
{ 0X5145868A, &WrapI_V<sceUsbCamStopMic>, "sceUsbCamStopMic", 'i', "" },
{ 0X36636925, &WrapI_UU<sceUsbCamReadMicBlocking>, "sceUsbCamReadMicBlocking", 'i', "xx" },
{ 0X3DC0088E, nullptr, "sceUsbCamReadMic", '?', "" },
{ 0X3DC0088E, &WrapI_UU<sceUsbCamReadMic>, "sceUsbCamReadMic", 'i', "xx" },
{ 0XB048A67D, nullptr, "sceUsbCamWaitReadMicEnd", '?', "" },
{ 0XF8847F60, nullptr, "sceUsbCamPollReadMicEnd", '?', "" },
{ 0X5778B452, nullptr, "sceUsbCamGetMicDataLength", '?', "" },
{ 0XF8847F60, &WrapI_V<sceUsbCamPollReadMicEnd>, "sceUsbCamPollReadMicEnd", 'i', "" },
{ 0X5778B452, &WrapI_V<sceUsbCamGetMicDataLength>, "sceUsbCamGetMicDataLength", 'i', "" },
{ 0X08AEE98A, nullptr, "sceUsbCamSetMicGain", '?', "" },

{ 0X17F7B2FB, &WrapI_UUI<sceUsbCamSetupVideo>, "sceUsbCamSetupVideo", 'i', "xxi" },
Expand Down
1 change: 1 addition & 0 deletions Core/HLE/sceUsbCam.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
void Register_sceUsbCam();

void __UsbCamInit();
void __UsbCamDoState(PointerWrap &p);
void __UsbCamShutdown();

namespace Camera {
Expand Down
4 changes: 3 additions & 1 deletion Core/HLE/sceUsbGps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,16 @@ const HLEFunction sceUsbGps[] =
{0X268F95CA, nullptr, "sceUsbGpsSetInitDataLocation", '?', "" },
{0X31F95CDE, nullptr, "sceUsbGpsGetPowerSaveMode", '?', "" },
{0X54D26AA4, nullptr, "sceUsbGpsGetInitDataLocation", '?', "" },
{0X5881C826, nullptr, "sceUsbGpsGetStaticNavMode", '?', "" },
{0X63D1F89D, nullptr, "sceUsbGpsResetInitialPosition", '?', "" },
{0X69E4AAA8, nullptr, "sceUsbGpsSaveInitData", '?', "" },
{0X6EED4811, &WrapI_V<sceUsbGpsClose>, "sceUsbGpsClose", 'i', "" },
{0X7C16AC3A, &WrapI_U<sceUsbGpsGetState>, "sceUsbGpsGetState", 'i', "x"},
{0X7C16AC3A, &WrapI_U<sceUsbGpsGetState>, "sceUsbGpsGetState", 'i', "x" },
{0X934EC2B2, &WrapI_UU<sceUsbGpsGetData>, "sceUsbGpsGetData", 'i', "xx" },
{0X9D8F99E8, nullptr, "sceUsbGpsSetPowerSaveMode", '?', "" },
{0X9F267D34, &WrapI_V<sceUsbGpsOpen>, "sceUsbGpsOpen", 'i', "" },
{0XA259CD67, nullptr, "sceUsbGpsReset", '?', "" },
{0XA8ED0BC2, nullptr, "sceUsbGpsSetStaticNavMode", '?', "" },
};

void Register_sceUsbGps()
Expand Down
6 changes: 3 additions & 3 deletions Core/HLE/sceUsbGps.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ typedef struct {
float garbage3;
float speed;
float bearing;
} GpsData;
} GpsData;

typedef struct {
unsigned char id;
Expand All @@ -63,6 +63,6 @@ namespace GPS {
void init();
void setGpsTime(time_t *time);
void setGpsData(float latitude, float longitude, float altitude, float speed, float bearing, long long time);
GpsData *getGpsData();
SatData *getSatData();
GpsData* getGpsData();
SatData* getSatData();
}
97 changes: 89 additions & 8 deletions Core/HLE/sceUsbMic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.

#include <algorithm>
#include <mutex>

#include "base/NativeApp.h"
Expand All @@ -24,15 +25,57 @@
#include "Core/HLE/sceUsbMic.h"
#include "Core/MemMapHelpers.h"


enum {
BUFFER_SIZE = 4 * 1000,
};

UsbMicContext usbMicContext;

void __UsbMicInit() {
__UsbMicContext()->dataBuffer = new uint8_t[BUFFER_SIZE];

// dummy data
for (int i = 0; i < BUFFER_SIZE; i++) {
__UsbMicContext()->dataBuffer[i] = i & 0xFF;
}
__UsbMicContext()->dataBufferLength = BUFFER_SIZE;
}

void __UsbMicDoState(PointerWrap &p) {
auto s = p.Section("sceUsbMic", 0, 1);
if (!s)
return;

p.Do(__UsbMicContext()->microphoneEnabled);
p.Do(__UsbMicContext()->sampleRate);
ERROR_LOG(HLE, "__UsbUsbMicDoState: mode=%d, enabled=%d, sr=%d", p.mode,
__UsbMicContext()->microphoneEnabled, __UsbMicContext()->sampleRate);

if (__UsbMicContext()->microphoneEnabled) {
__UsbMicStart(__UsbMicContext()->sampleRate, true);
}
}

void __UsbMicShutdown() {
delete[] __UsbMicContext()->dataBuffer;
__UsbMicContext()->dataBuffer = nullptr;
}

static int sceUsbMicInputBlocking(u32 size, u32 samplerate, u32 bufAddr) {
INFO_LOG(HLE, "UNIMPL sceUsbMicInputBlocking: size: %d, samplerate: %d", size, samplerate);
for (unsigned int i = 0; i < size; i++) {
if (Memory::IsValidAddress(bufAddr + i)) {
Memory::Write_U8(i & 0xFF, bufAddr + i);
}
__UsbMicStart(samplerate, false);
VERBOSE_LOG(HLE, "UNIMPL sceUsbMicInputBlocking: size: %d, samplerate: %d", size, samplerate);
std::lock_guard<std::mutex> lock(__UsbMicContext()->dataBufferMutex);
u32 transferSize = std::min(__UsbMicContext()->dataBufferLength, size);
if (Memory::IsValidRange(bufAddr, size)) {
Memory::Memcpy(bufAddr, __UsbMicContext()->dataBuffer, transferSize);
}
hleEatMicro(1000000 / samplerate * (size / 2));
return size;
return transferSize;
}

static int sceUsbMicInputInit(u32 unk1, u32 volume, u32 unk2) {
ERROR_LOG(HLE, "UNIMPL sceUsbMicInputInit: %d, 0x%x, %d", unk1, volume, unk2);
return 0;
}

const HLEFunction sceUsbMic[] =
Expand All @@ -42,11 +85,49 @@ const HLEFunction sceUsbMic[] =
{0x45310F07, nullptr, "sceUsbMicInputInitEx", '?', "" },
{0x5F7F368D, nullptr, "sceUsbMicInput", '?', "" },
{0x63400E20, nullptr, "sceUsbMicGetInputLength", '?', "" },
{0xB8E536EB, nullptr, "sceUsbMicInputInit", '?', "" },
{0xB8E536EB, &WrapI_UUU<sceUsbMicInputInit>, "sceUsbMicInputInit", 'i', "xxx" },
{0xF899001C, nullptr, "sceUsbMicWaitInputEnd", '?', "" },
};

void Register_sceUsbMic()
{
RegisterModule("sceUsbMic", ARRAY_SIZE(sceUsbMic), sceUsbMic);
}

UsbMicContext* __UsbMicContext() {
return &usbMicContext;
}

void __UsbMicStart(int sampleRate, bool ignore) {
INFO_LOG(HLE, "__UsbMicStart: sr=%d, ignore=%d", sampleRate, ignore);
if (__UsbMicContext()->sampleRate != sampleRate || ignore) {
if (__UsbMicContext()->microphoneEnabled) {
System_SendMessage("microphone_command", "stopRecording");
}
__UsbMicContext()->sampleRate = sampleRate;
System_SendMessage("microphone_command", ("startRecording:" + std::to_string(sampleRate)).c_str());
__UsbMicContext()->microphoneEnabled = true;
}
}

void __UsbMicStop() {
System_SendMessage("microphone_command", "stopRecording");
__UsbMicContext()->microphoneEnabled = false;
__UsbMicContext()->sampleRate = 0;
}

void __UsbMicPushData(long long length, unsigned char* data) {
ERROR_LOG(HLE, "__UsbMicPushData: length %lld", length);
std::lock_guard<std::mutex> lock(__UsbMicContext()->dataBufferMutex);
memset(__UsbMicContext()->dataBuffer, 0, BUFFER_SIZE);
if (length > BUFFER_SIZE) {
__UsbMicContext()->dataBufferLength = 0;
__UsbMicContext()->bufferPos = 0;
ERROR_LOG(HLE, "pushMicrophoneData: length error: %lld > %d", length, BUFFER_SIZE);
} else {
__UsbMicContext()->dataBufferLength = length;
__UsbMicContext()->bufferPos = 0;
memcpy(__UsbMicContext()->dataBuffer, data, length);
}
}

22 changes: 22 additions & 0 deletions Core/HLE/sceUsbMic.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,26 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.

#pragma once

void Register_sceUsbMic();

void __UsbMicInit();
void __UsbMicDoState(PointerWrap &p);
void __UsbMicShutdown();

typedef struct {
bool microphoneEnabled = false;
int sampleRate = 0;

std::mutex dataBufferMutex;
unsigned int dataBufferLength = 0;
uint8_t *dataBuffer;

unsigned int nextDataLen = 0;
unsigned int bufferPos = 0;
} UsbMicContext;

UsbMicContext* __UsbMicContext();
void __UsbMicStart(int sampleRate, bool ignore);
void __UsbMicStop();
void __UsbMicPushData(long long length, unsigned char *data);
Loading

0 comments on commit d6e47a2

Please sign in to comment.