rpcsx/rpcs3/Emu/Cell/Modules/cellMic.cpp

527 lines
12 KiB
C++
Raw Normal View History

2014-07-12 09:46:14 +02:00
#include "stdafx.h"
2014-10-18 20:22:52 +02:00
#include "Emu/System.h"
2016-03-21 20:43:03 +01:00
#include "Emu/Cell/PPUModule.h"
2014-10-18 20:22:52 +02:00
#include "cellMic.h"
2018-03-14 21:27:56 +01:00
#include <Emu/IdManager.h>
#include <Emu/Cell/lv2/sys_event.h>
#include <thread>
2014-10-18 20:22:52 +02:00
LOG_CHANNEL(cellMic);
2014-10-18 20:22:52 +02:00
2018-03-14 21:27:56 +01:00
void mic_thread::on_init(const std::shared_ptr<void>& _this)
{
named_thread::on_init(_this);
}
void mic_thread::on_task()
{
while (micInited && !Emu.IsStopped())
{
if (Emu.IsPaused())
{
std::this_thread::sleep_for(1ms); // hack from cellAudio
continue;
}
if (!micOpened || !micStarted)
continue;
// If event queue is not set, then we can't send any events
if (eventQueueKey == 0)
continue;
std::this_thread::sleep_for(1s);
// Make sure the mic thread wasn't stopped while we were sleeping
if (!micInited)
break;
auto micQueue = lv2_event_queue::find(eventQueueKey);
micQueue->send(0, CELL_MIC_DATA, 0, 0);
}
}
/// Initialization/Shutdown Functions
2015-07-09 17:30:37 +02:00
s32 cellMicInit()
{
2018-03-14 21:27:56 +01:00
cellMic.trace("cellMicInit()");
const auto micThread = fxm::make<mic_thread>();
micInited = true;
if (!micThread)
return CELL_MIC_ERROR_ALREADY_INIT;
2014-10-18 20:22:52 +02:00
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicEnd()
{
2018-03-14 21:27:56 +01:00
cellMic.trace("cellMicEnd()");
micInited = false;
const auto micThread = fxm::withdraw<mic_thread>();
2018-03-14 21:27:56 +01:00
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
2014-10-18 20:22:52 +02:00
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
/// Open/Close Microphone Functions
s32 cellMicOpen(u32 deviceNumber, u32 sampleRate)
{
2018-03-14 21:27:56 +01:00
cellMic.todo("cellMicOpen(deviceNumber=%um sampleRate=%u)", deviceNumber, sampleRate);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
if (micThread->micOpened)
return CELL_MIC_ERROR_ALREADY_OPEN;
micThread->DspFrequency = sampleRate;
micThread->micOpened = true;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicOpenRaw(u32 deviceNumber, u32 sampleRate, u32 maxChannels)
{
2018-03-14 21:27:56 +01:00
cellMic.todo("cellMicOpenRaw(deviceNumber=%d, sampleRate=%d, maxChannels=%d)", deviceNumber, sampleRate, maxChannels);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
if (micThread->micOpened)
return CELL_MIC_ERROR_ALREADY_OPEN;
micThread->rawFrequency = sampleRate;
micThread->micOpened = true;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicOpenEx(u32 deviceNumber, u32 rawSampleRate, u32 rawChannel, u32 DSPSampleRate, u32 bufferSizeMS, u8 signalType)
{
2018-03-14 21:27:56 +01:00
cellMic.todo("cellMicOpenEx(deviceNumber=%d, rawSampleRate=%d, rawChannel=%d, DSPSampleRate=%d, bufferSizeMS=%d, signalType=0x%x)", deviceNumber, rawSampleRate, rawChannel, DSPSampleRate,
bufferSizeMS, signalType);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
if (micThread->micOpened)
return CELL_MIC_ERROR_ALREADY_OPEN;
micThread->rawFrequency = rawSampleRate;
micThread->DspFrequency = DSPSampleRate;
micThread->micOpened = true;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
u8 cellMicIsOpen(u32 deviceNumber)
{
2018-03-14 21:27:56 +01:00
cellMic.warning("cellMicIsOpen(deviceNumber=%d)", deviceNumber);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return false;
return micThread->micOpened;
}
2018-03-14 21:27:56 +01:00
s32 cellMicIsAttached(u32 deviceNumber)
{
2018-03-14 21:27:56 +01:00
cellMic.warning("cellMicIsAttached(deviceNumber=%d)", deviceNumber);
return 1;
}
2018-03-14 21:27:56 +01:00
s32 cellMicClose(u32 deviceNumber)
{
2018-03-14 21:27:56 +01:00
cellMic.warning("cellMicClose(deviceNumber=%d)", deviceNumber);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
micThread->micOpened = false;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
/// Starting/Stopping Microphone Functions
s32 cellMicStart(u32 deviceNumber)
{
2018-03-14 21:27:56 +01:00
cellMic.warning("cellMicStart(deviceNumber=%d)", deviceNumber);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
if (!micThread->micOpened)
return CELL_MIC_ERROR_NOT_OPEN;
micThread->micStarted = true;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicStartEx(u32 deviceNumber, u32 flags)
{
2018-03-14 21:27:56 +01:00
cellMic.todo("cellMicStartEx(deviceNumber=%d, flags=%d)", deviceNumber, flags);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
if (!micThread->micOpened)
return CELL_MIC_ERROR_NOT_OPEN;
micThread->micStarted = true;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicStop(u32 deviceNumber)
{
2018-03-14 21:27:56 +01:00
cellMic.todo("cellMicStop(deviceNumber=%d)", deviceNumber);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
if (!micThread->micOpened)
return CELL_MIC_ERROR_NOT_OPEN;
micThread->micStarted = false;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
/// Microphone Attributes/States Functions
s32 cellMicGetDeviceAttr(u32 deviceNumber, vm::ptr<void> deviceAttributes, vm::ptr<u32> arg1, vm::ptr<u32> arg2)
{
2018-03-14 21:27:56 +01:00
cellMic.todo("cellMicGetDeviceAttr(deviceNumber=%d, deviceAttribute=*0x%x, arg1=*0x%x, arg2=*0x%x)", deviceNumber, deviceAttributes, arg1, arg2);
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicSetDeviceAttr()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicGetSignalAttr()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicSetSignalAttr()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicGetSignalState(u32 deviceNumber, CellMicSignalState signalState, vm::ptr<void> value)
{
2018-03-14 21:27:56 +01:00
cellMic.todo("cellMicGetSignalState(deviceNumber=%d, signalSate=%d, value=0x%x)", deviceNumber, (int)signalState, value);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
be_t<u32>* ival = (be_t<u32>*)value.get_ptr();
be_t<f32>* fval = (be_t<f32>*)value.get_ptr();
switch (signalState)
{
case CELL_MIC_SIGSTATE_LOCTALK:
*ival = 9; // Someone is probably talking
break;
case CELL_MIC_SIGSTATE_FARTALK:
// TODO
break;
case CELL_MIC_SIGSTATE_NSR:
// TODO
break;
case CELL_MIC_SIGSTATE_AGC:
// TODO
break;
case CELL_MIC_SIGSTATE_MICENG:
*fval = 40.0f; // 40 decibels
break;
case CELL_MIC_SIGSTATE_SPKENG:
// TODO
break;
}
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicGetFormatRaw(u32 deviceNumber, vm::ptr<CellMicInputFormat> format)
{
2018-03-14 21:27:56 +01:00
cellMic.warning("cellMicGetFormatRaw(deviceNumber=%d, format=0x%x)", deviceNumber, format);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
format->channelNum = 4;
format->subframeSize = 2;
format->bitResolution = micThread->bitResolution;
format->dataType = 1;
format->sampleRate = micThread->rawFrequency;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicGetFormatAux(u32 deviceNumber, vm::ptr<CellMicInputFormat> format)
{
2018-03-14 21:27:56 +01:00
cellMic.warning("cellMicGetFormatAux(deviceNumber=%d, format=0x%x)", deviceNumber, format);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
format->channelNum = 4;
format->subframeSize = 2;
format->bitResolution = micThread->bitResolution;
format->dataType = 1;
format->sampleRate = micThread->AuxFrequency;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicGetFormatDsp(u32 deviceNumber, vm::ptr<CellMicInputFormat> format)
{
2018-03-14 21:27:56 +01:00
cellMic.warning("cellMicGetFormatDsp(deviceNumber=%d, format=0x%x)", deviceNumber, format);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
format->channelNum = 4;
format->subframeSize = 2;
format->bitResolution = micThread->bitResolution;
format->dataType = 1;
format->sampleRate = micThread->DspFrequency;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
/// Event Queue Functions
s32 cellMicSetNotifyEventQueue(u64 key)
{
2018-03-14 21:27:56 +01:00
cellMic.warning("cellMicSetNotifyEventQueue(key=0x%llx)", key);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
// default mic queue size = 4
auto micQueue = lv2_event_queue::find(key);
micQueue->send(0, CELL_MIC_ATTACH, 0, 0);
micThread->eventQueueKey = key;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicSetNotifyEventQueue2(u64 key, u64 source)
{
2018-03-14 21:27:56 +01:00
// TODO: Actually do things with the source variable
cellMic.todo("cellMicSetNotifyEventQueue2(key=0x%llx, source=0x%llx", key, source);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
// default mic queue size = 4
auto micQueue = lv2_event_queue::find(key);
micQueue->send(0, CELL_MIC_ATTACH, 0, 0);
micThread->eventQueueKey = key;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicRemoveNotifyEventQueue(u64 key)
{
2018-03-14 21:27:56 +01:00
cellMic.warning("cellMicRemoveNotifyEventQueue(key=0x%llx)", key);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
micThread->eventQueueKey = 0;
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
/// Reading Functions
s32 cellMicRead(u32 deviceNumber, vm::ptr<void> data, u32 maxBytes)
{
2018-03-14 21:27:56 +01:00
cellMic.warning("cellMicRead(deviceNumber=%d, data=0x%x, maxBytes=0x%x)", deviceNumber, data, maxBytes);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
const s32 size = std::min<s32>(maxBytes, bufferSize);
return size;
}
2018-03-14 21:27:56 +01:00
s32 cellMicReadRaw(u32 deviceNumber, vm::ptr<void> data, int maxBytes)
{
2018-03-14 21:27:56 +01:00
cellMic.warning("cellMicReadRaw(deviceNumber=%d, data=0x%x, maxBytes=%d)", deviceNumber, data, maxBytes);
const auto micThread = fxm::get<mic_thread>();
if (!micThread)
return CELL_MIC_ERROR_NOT_INIT;
const s32 size = std::min<s32>(maxBytes, bufferSize);
return size;
}
2018-03-14 21:27:56 +01:00
s32 cellMicReadAux()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicReadDsp()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
/// Unimplemented Functions
s32 cellMicReset()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicGetDeviceGUID()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
s32 cellMicGetType()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicGetStatus()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicStopEx()
{
fmt::throw_exception("Unexpected function" HERE);
}
2015-07-09 17:30:37 +02:00
s32 cellMicSysShareClose()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicGetFormat()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicSetMultiMicNotifyEventQueue()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicGetFormatEx()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicSysShareStop()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicSysShareOpen()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicCommand()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicSysShareStart()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicSysShareInit()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicSysShareEnd()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2015-07-09 17:30:37 +02:00
s32 cellMicGetDeviceIdentifier()
{
UNIMPLEMENTED_FUNC(cellMic);
return CELL_OK;
}
2018-03-14 21:27:56 +01:00
DECLARE(ppu_module_manager::cellMic)
("cellMic", []() {
REG_FUNC(cellMic, cellMicInit);
REG_FUNC(cellMic, cellMicEnd);
REG_FUNC(cellMic, cellMicOpen);
REG_FUNC(cellMic, cellMicClose);
REG_FUNC(cellMic, cellMicGetDeviceGUID);
REG_FUNC(cellMic, cellMicGetType);
REG_FUNC(cellMic, cellMicIsAttached);
REG_FUNC(cellMic, cellMicIsOpen);
REG_FUNC(cellMic, cellMicGetDeviceAttr);
REG_FUNC(cellMic, cellMicSetDeviceAttr);
REG_FUNC(cellMic, cellMicGetSignalAttr);
REG_FUNC(cellMic, cellMicSetSignalAttr);
REG_FUNC(cellMic, cellMicGetSignalState);
REG_FUNC(cellMic, cellMicStart);
REG_FUNC(cellMic, cellMicRead);
REG_FUNC(cellMic, cellMicStop);
REG_FUNC(cellMic, cellMicReset);
REG_FUNC(cellMic, cellMicSetNotifyEventQueue);
REG_FUNC(cellMic, cellMicSetNotifyEventQueue2);
REG_FUNC(cellMic, cellMicRemoveNotifyEventQueue);
REG_FUNC(cellMic, cellMicOpenEx);
REG_FUNC(cellMic, cellMicStartEx);
REG_FUNC(cellMic, cellMicGetFormatRaw);
REG_FUNC(cellMic, cellMicGetFormatAux);
REG_FUNC(cellMic, cellMicGetFormatDsp);
REG_FUNC(cellMic, cellMicOpenRaw);
REG_FUNC(cellMic, cellMicReadRaw);
REG_FUNC(cellMic, cellMicReadAux);
REG_FUNC(cellMic, cellMicReadDsp);
REG_FUNC(cellMic, cellMicGetStatus);
2015-08-01 03:46:42 +02:00
REG_FUNC(cellMic, cellMicStopEx); // this function shouldn't exist
REG_FUNC(cellMic, cellMicSysShareClose);
REG_FUNC(cellMic, cellMicGetFormat);
REG_FUNC(cellMic, cellMicSetMultiMicNotifyEventQueue);
REG_FUNC(cellMic, cellMicGetFormatEx);
REG_FUNC(cellMic, cellMicSysShareStop);
REG_FUNC(cellMic, cellMicSysShareOpen);
REG_FUNC(cellMic, cellMicCommand);
REG_FUNC(cellMic, cellMicSysShareStart);
REG_FUNC(cellMic, cellMicSysShareInit);
REG_FUNC(cellMic, cellMicSysShareEnd);
REG_FUNC(cellMic, cellMicGetDeviceIdentifier);
});