rpcsx/rpcs3/Emu/Cell/Modules/cellAudio.h

165 lines
4 KiB
C
Raw Normal View History

#pragma once
2016-03-21 20:43:03 +01:00
#include "Utilities/Thread.h"
2018-02-09 15:49:37 +01:00
// Error codes
2017-09-20 12:01:57 +02:00
enum CellAudioError : u32
{
2014-04-04 15:25:38 +02:00
CELL_AUDIO_ERROR_ALREADY_INIT = 0x80310701,
CELL_AUDIO_ERROR_AUDIOSYSTEM = 0x80310702,
CELL_AUDIO_ERROR_NOT_INIT = 0x80310703,
CELL_AUDIO_ERROR_PARAM = 0x80310704,
CELL_AUDIO_ERROR_PORT_FULL = 0x80310705,
CELL_AUDIO_ERROR_PORT_ALREADY_RUN = 0x80310706,
CELL_AUDIO_ERROR_PORT_NOT_OPEN = 0x80310707,
CELL_AUDIO_ERROR_PORT_NOT_RUN = 0x80310708,
CELL_AUDIO_ERROR_TRANS_EVENT = 0x80310709,
CELL_AUDIO_ERROR_PORT_OPEN = 0x8031070a,
CELL_AUDIO_ERROR_SHAREDMEMORY = 0x8031070b,
CELL_AUDIO_ERROR_MUTEX = 0x8031070c,
CELL_AUDIO_ERROR_EVENT_QUEUE = 0x8031070d,
CELL_AUDIO_ERROR_AUDIOSYSTEM_NOT_FOUND = 0x8031070e,
CELL_AUDIO_ERROR_TAG_NOT_FOUND = 0x8031070f,
};
// constants
enum
{
2014-04-04 15:25:38 +02:00
CELL_AUDIO_BLOCK_16 = 16,
CELL_AUDIO_BLOCK_8 = 8,
CELL_AUDIO_BLOCK_SAMPLES = 256,
CELL_AUDIO_CREATEEVENTFLAG_SPU = 0x00000001,
CELL_AUDIO_EVENT_HEADPHONE = 1,
2018-02-09 15:49:37 +01:00
CELL_AUDIO_EVENT_MIX = 0,
2014-04-04 15:25:38 +02:00
CELL_AUDIO_EVENTFLAG_BEFOREMIX = 0x80000000,
CELL_AUDIO_EVENTFLAG_DECIMATE_2 = 0x08000000,
CELL_AUDIO_EVENTFLAG_DECIMATE_4 = 0x10000000,
CELL_AUDIO_EVENTFLAG_HEADPHONE = 0x20000000,
CELL_AUDIO_EVENTFLAG_NOMIX = 0x40000000,
CELL_AUDIO_MAX_PORT = 4,
CELL_AUDIO_MAX_PORT_2 = 8,
2018-02-09 15:49:37 +01:00
CELL_AUDIO_MISC_ACCVOL_ALLDEVICE = 0x0000ffffUL,
2014-04-04 15:25:38 +02:00
CELL_AUDIO_PERSONAL_DEVICE_PRIMARY = 0x8000,
CELL_AUDIO_PORT_2CH = 2,
CELL_AUDIO_PORT_8CH = 8,
CELL_AUDIO_PORTATTR_BGM = 0x0000000000000010ULL,
CELL_AUDIO_PORTATTR_INITLEVEL = 0x0000000000001000ULL,
CELL_AUDIO_PORTATTR_OUT_NO_ROUTE = 0x0000000000100000ULL,
CELL_AUDIO_PORTATTR_OUT_PERSONAL_0 = 0x0000000001000000ULL,
CELL_AUDIO_PORTATTR_OUT_PERSONAL_1 = 0x0000000002000000ULL,
CELL_AUDIO_PORTATTR_OUT_PERSONAL_2 = 0x0000000004000000ULL,
CELL_AUDIO_PORTATTR_OUT_PERSONAL_3 = 0x0000000008000000ULL,
2018-02-09 15:49:37 +01:00
CELL_AUDIO_PORTATTR_OUT_SECONDARY = 0x0000000000000001ULL,
2014-04-04 15:25:38 +02:00
CELL_AUDIO_STATUS_CLOSE = 0x1010,
CELL_AUDIO_STATUS_READY = 1,
CELL_AUDIO_STATUS_RUN = 2,
};
//libaudio datatypes
struct CellAudioPortParam
2018-02-09 15:49:37 +01:00
{
be_t<u64> nChannel;
be_t<u64> nBlock;
be_t<u64> attr;
be_t<float> level;
2018-02-09 15:49:37 +01:00
};
struct CellAudioPortConfig
2018-02-09 15:49:37 +01:00
{
2016-03-21 20:43:03 +01:00
vm::bptr<u64> readIndexAddr;
be_t<u32> status;
be_t<u64> nChannel;
be_t<u64> nBlock;
be_t<u32> portSize;
be_t<u32> portAddr;
};
2015-01-16 15:36:53 +01:00
enum : u32
{
BUFFER_NUM = 32,
BUFFER_SIZE = 256,
AUDIO_PORT_COUNT = 8,
AUDIO_PORT_OFFSET = 256 * 1024,
AUDIO_SAMPLES = CELL_AUDIO_BLOCK_SAMPLES,
2015-01-16 15:36:53 +01:00
};
2016-03-21 20:43:03 +01:00
extern u64 get_system_time();
2015-01-16 15:36:53 +01:00
2016-03-21 20:43:03 +01:00
enum class audio_port_state : u32
2015-01-16 15:36:53 +01:00
{
2016-03-21 20:43:03 +01:00
closed,
opened,
started,
2015-01-16 15:36:53 +01:00
};
2016-03-21 20:43:03 +01:00
struct audio_port
{
2016-03-21 20:43:03 +01:00
atomic_t<audio_port_state> state{ audio_port_state::closed };
2015-01-16 15:36:53 +01:00
2016-03-21 20:43:03 +01:00
u32 number;
vm::ptr<char> addr{};
vm::ptr<u64> index{};
2015-11-26 09:06:29 +01:00
u32 channel;
u32 block;
u64 attr;
u64 tag;
u64 counter; // copy of global counter
u32 size;
2015-04-12 03:36:25 +02:00
2016-03-21 20:43:03 +01:00
struct alignas(8) level_set_t
2015-04-12 03:36:25 +02:00
{
float value;
float inc;
};
2018-02-09 15:49:37 +01:00
float level;
2015-07-08 17:01:59 +02:00
atomic_t<level_set_t> level_set;
};
class audio_config final : public old_thread
{
2016-03-21 20:43:03 +01:00
void on_task() override;
std::string get_name() const override { return "Audio Thread"; }
2017-03-11 00:14:48 +01:00
vm::ptr<char> m_buffer = vm::null;
vm::ptr<u64> m_indexes = vm::null;
2015-11-26 09:06:29 +01:00
2016-03-21 20:43:03 +01:00
u64 m_counter{};
public:
2017-03-11 00:14:48 +01:00
void on_init(const std::shared_ptr<void>&) override;
2016-03-21 20:43:03 +01:00
const u64 start_time = get_system_time();
std::array<audio_port, AUDIO_PORT_COUNT> ports;
2015-01-16 15:36:53 +01:00
std::vector<u64> keys;
2017-02-05 14:35:10 +01:00
semaphore<> mutex;
2017-03-11 00:14:48 +01:00
audio_config() = default;
~audio_config()
2017-01-28 00:42:31 +01:00
{
2017-03-11 00:14:48 +01:00
vm::dealloc_verbose_nothrow(m_buffer.addr());
vm::dealloc_verbose_nothrow(m_indexes.addr());
2017-01-28 00:42:31 +01:00
}
2016-03-21 20:43:03 +01:00
audio_port* open_port()
{
for (u32 i = 0; i < AUDIO_PORT_COUNT; i++)
{
2016-03-21 20:43:03 +01:00
if (ports[i].state.compare_and_swap_test(audio_port_state::closed, audio_port_state::opened))
{
2016-03-21 20:43:03 +01:00
return &ports[i];
}
}
2016-03-21 20:43:03 +01:00
return nullptr;
}
};