Event fix, cellAudio fix

This commit is contained in:
Nekotekina 2014-02-21 00:47:22 +04:00
parent 08b4748aae
commit 81147506f0
5 changed files with 319 additions and 292 deletions

View file

@ -58,4 +58,20 @@ bool EventManager::UnregisterKey(u64 key)
return true;
}
return false;
}
bool EventManager::SendEvent(u64 key, u64 source, u64 d1, u64 d2, u64 d3)
{
if (!key) return false;
SMutexLocker lock(m_lock);
auto f = key_map.find(key);
if (f == key_map.end())
{
return false;
}
EventQueue* eq = f->second;
eq->events.push(source, d1, d2, d3);
return true;
}

View file

@ -83,7 +83,6 @@ enum
CELL_ADEC_ERROR_M4AAC_STEREO_MIXDOWN_ELEMENT_IS_NOT_SUPPORTED
= 0x8061243c,
/* SBR */
CELL_ADEC_ERROR_M4AAC_SBR_CH_OVERFLOW = 0x80612480,
CELL_ADEC_ERROR_M4AAC_SBR_NOSYNCH = 0x80612481,
CELL_ADEC_ERROR_M4AAC_SBR_ILLEGAL_PROGRAM = 0x80612482,
@ -108,82 +107,71 @@ enum
CELL_ADEC_ERROR_AT3_OFFSET = 0x80612100,
CELL_ADEC_ERROR_AT3_OK = 0x80612100,
/* Adapter level error */
CELL_ADEC_ERROR_AT3_BUSY = 0x80612164,
CELL_ADEC_ERROR_AT3_EMPTY = 0x80612165,
/* Core level error */
CELL_ADEC_ERROR_AT3_ERROR = 0x80612180,
CELL_ADEC_ERROR_ATX_OFFSET = 0x80612200,
CELL_ADEC_ERROR_ATX_NONE = 0x80612200, /* no errors */
CELL_ADEC_ERROR_ATX_NONE = 0x80612200,
CELL_ADEC_ERROR_ATX_OK = 0x80612200,
/*----- Adapter level error -----*/
CELL_ADEC_ERROR_ATX_BUSY = 0x80612264,
CELL_ADEC_ERROR_ATX_EMPTY = 0x80612265,
CELL_ADEC_ERROR_ATX_ATSHDR = 0x80612266,
/*----- Core level error -----*/
/* non fatal errors */
CELL_ADEC_ERROR_ATX_NON_FATAL = 0x80612281, /* undefined error */
CELL_ADEC_ERROR_ATX_NOT_IMPLE = 0x80612282, /* not implemented */
CELL_ADEC_ERROR_ATX_PACK_CE_OVERFLOW = 0x80612283, /* pack_channel_block_at5() in pack_at5.c */
CELL_ADEC_ERROR_ATX_ILLEGAL_NPROCQUS = 0x80612284, /* unpack_sheader() in pack_at5_sheader.c */
/* fatal errors(block level) */
CELL_ADEC_ERROR_ATX_FATAL = 0x8061228c, /* undefined error */
CELL_ADEC_ERROR_ATX_ENC_OVERFLOW = 0x8061228d, /* at5enc_proc() in at5enc.c */
CELL_ADEC_ERROR_ATX_PACK_CE_UNDERFLOW = 0x8061228e, /* pack_channel_block_at5() in pack_at5.c */
/* to check syntax */
CELL_ADEC_ERROR_ATX_SYNTAX_IDCT = 0x8061228f, /* unpack_idct() in pack_at5_codetbl.c */
CELL_ADEC_ERROR_ATX_SYNTAX_GAINADJ = 0x80612290, /* unpack_gainadj() in pack_at5_gainadj.c */
CELL_ADEC_ERROR_ATX_SYNTAX_IDSF = 0x80612291, /* unpack_idsf() in pack_at5_sfactor.c */
CELL_ADEC_ERROR_ATX_SYNTAX_SPECTRA = 0x80612292, /* unpack_spectra() in pack_at5_spectra.c */
CELL_ADEC_ERROR_ATX_SYNTAX_IDWL = 0x80612293, /* unpack_idwl() in pack_at5_idwl.c */
CELL_ADEC_ERROR_ATX_SYNTAX_GHWAVE = 0x80612294, /* unpack_ghwave() in pack_at5_ghwave.c */
CELL_ADEC_ERROR_ATX_SYNTAX_SHEADER = 0x80612295, /* unpack_sheader() in pack_at5_sheader.c */
CELL_ADEC_ERROR_ATX_SYNTAX_IDWL_A = 0x80612296, /* idwl[][]{0-7} range error */
CELL_ADEC_ERROR_ATX_SYNTAX_IDWL_B = 0x80612297, /* idwl restriction error (wlc_encqu<=divqu<nprocqus,ich=0) */
CELL_ADEC_ERROR_ATX_SYNTAX_IDWL_C = 0x80612298, /* idwl restriction error (0<=wlc_divqu<=wlc_encqu,ich=0) */
CELL_ADEC_ERROR_ATX_SYNTAX_IDWL_D = 0x80612299, /* idwl restriction error (wlc_encqu<divqu<=nprocqus,ich=1) */
CELL_ADEC_ERROR_ATX_SYNTAX_IDWL_E = 0x8061229a, /* idwl restriction error (wlc_encqu<=nprocqus) */
CELL_ADEC_ERROR_ATX_SYNTAX_IDSF_A = 0x8061229b, /* idsf[][]{0-63} range error */
CELL_ADEC_ERROR_ATX_SYNTAX_IDSF_B = 0x8061229c, /* sfc_nbitlen{0-6} range error */
CELL_ADEC_ERROR_ATX_SYNTAX_IDSF_C = 0x8061229d, /* idsf restriction error (0<=sfc_divqu<=nrealqus) */
CELL_ADEC_ERROR_ATX_SYNTAX_IDSF_D = 0x8061229e, /* idsf restriction error (0<=sfc_sg_divqu<=nrealqus) */
CELL_ADEC_ERROR_ATX_SYNTAX_IDCT_A = 0x8061229f, /* idct restriction error (0<=ctc_divqu<=nrealqus) */
CELL_ADEC_ERROR_ATX_SYNTAX_GC_NGC = 0x806122a0, /* ngc[][]{0-7} range error */
CELL_ADEC_ERROR_ATX_SYNTAX_GC_IDLEV_A = 0x806122a1, /* idlev[][][]{0-15} range error */
CELL_ADEC_ERROR_ATX_SYNTAX_GC_IDLOC_A = 0x806122a2, /* idloc[][][]{0-31} range error */
CELL_ADEC_ERROR_ATX_SYNTAX_GC_IDLEV_B = 0x806122a3, /* gain_control_data restriction error (idlev[][][]) */
CELL_ADEC_ERROR_ATX_SYNTAX_GC_IDLOC_B = 0x806122a4, /* gain_control_data restriction error (idloc[][][]) */
CELL_ADEC_ERROR_ATX_SYNTAX_SN_NWVS = 0x806122a5, /* sinusoid_data restriction error */
/* fatal errors(handle level) */
CELL_ADEC_ERROR_ATX_FATAL_HANDLE = 0x806122aa, /* undefined error at handle level */
/* parameter assertion error */
CELL_ADEC_ERROR_ATX_ASSERT_SAMPLING_FREQ = 0x806122ab, /* sampling freqeuency assertion error */
CELL_ADEC_ERROR_ATX_ASSERT_CH_CONFIG_INDEX = 0x806122ac, /* channel_config_index assertion error */
CELL_ADEC_ERROR_ATX_ASSERT_NBYTES = 0x806122ad, /* a number of bytes(nbytes) assertion error */
CELL_ADEC_ERROR_ATX_ASSERT_BLOCK_NUM = 0x806122ae, /* a number of blocks(block_num) assertion error */
CELL_ADEC_ERROR_ATX_ASSERT_BLOCK_ID = 0x806122af, /* block_id assertion error */
CELL_ADEC_ERROR_ATX_ASSERT_CHANNELS = 0x806122b0, /* a number of channels per block assertion error */
CELL_ADEC_ERROR_ATX_UNINIT_BLOCK_SPECIFIED = 0x806122b1, /* uninitialized block specified */
CELL_ADEC_ERROR_ATX_POSCFG_PRESENT = 0x806122b2, /* "position_config_data" presents(currently fatal error) */
CELL_ADEC_ERROR_ATX_BUFFER_OVERFLOW = 0x806122b3, /* buffer overflow */
CELL_ADEC_ERROR_ATX_ILL_BLK_TYPE_ID = 0x806122b4, /* illegal "block_type_id" detected */
CELL_ADEC_ERROR_ATX_UNPACK_CHANNEL_BLK_FAILED = 0x806122b5, /* unpack_channel_block() failed */
CELL_ADEC_ERROR_ATX_ILL_BLK_ID_USED_1 = 0x806122b6, /* illegal "block_id" used (more audio_channel_block) */
CELL_ADEC_ERROR_ATX_ILL_BLK_ID_USED_2 = 0x806122b7, /* illegal "block_id" used (less audio_channel_block) */
/* error in parameter assertion */
CELL_ADEC_ERROR_ATX_ILLEGAL_ENC_SETTING = 0x806122b8, /* illegal encoder setting(init_atrac5_encode()) */
CELL_ADEC_ERROR_ATX_ILLEGAL_DEC_SETTING = 0x806122b9, /* illegal decoder setting(init_atrac5_decode()) */
CELL_ADEC_ERROR_ATX_ASSERT_NSAMPLES = 0x806122ba, /* a number of input PCM samples assertion error */
/* (for atx_encode() and atx_encode_alt()) */
/* ATS */
CELL_ADEC_ERROR_ATX_ILL_SYNCWORD = 0x806122bb, /* illegal syncword used */
CELL_ADEC_ERROR_ATX_ILL_SAMPLING_FREQ = 0x806122bc, /* illegal sampling_frequeny_index @ config_data() */
CELL_ADEC_ERROR_ATX_ILL_CH_CONFIG_INDEX = 0x806122bd, /* illegal channel_config_index @ config_data() */
CELL_ADEC_ERROR_ATX_RAW_DATA_FRAME_SIZE_OVER = 0x806122be, /* size of raw_data_frame > frame_length */
CELL_ADEC_ERROR_ATX_SYNTAX_ENHANCE_LENGTH_OVER = 0x806122bf, /* enhance_length {0,2046} range error */
CELL_ADEC_ERROR_ATX_SPU_INTERNAL_FAIL = 0x806122c8, /* spu-processing failed */
CELL_ADEC_ERROR_ATX_NON_FATAL = 0x80612281,
CELL_ADEC_ERROR_ATX_NOT_IMPLE = 0x80612282,
CELL_ADEC_ERROR_ATX_PACK_CE_OVERFLOW = 0x80612283,
CELL_ADEC_ERROR_ATX_ILLEGAL_NPROCQUS = 0x80612284,
CELL_ADEC_ERROR_ATX_FATAL = 0x8061228c,
CELL_ADEC_ERROR_ATX_ENC_OVERFLOW = 0x8061228d,
CELL_ADEC_ERROR_ATX_PACK_CE_UNDERFLOW = 0x8061228e,
CELL_ADEC_ERROR_ATX_SYNTAX_IDCT = 0x8061228f,
CELL_ADEC_ERROR_ATX_SYNTAX_GAINADJ = 0x80612290,
CELL_ADEC_ERROR_ATX_SYNTAX_IDSF = 0x80612291,
CELL_ADEC_ERROR_ATX_SYNTAX_SPECTRA = 0x80612292,
CELL_ADEC_ERROR_ATX_SYNTAX_IDWL = 0x80612293,
CELL_ADEC_ERROR_ATX_SYNTAX_GHWAVE = 0x80612294,
CELL_ADEC_ERROR_ATX_SYNTAX_SHEADER = 0x80612295,
CELL_ADEC_ERROR_ATX_SYNTAX_IDWL_A = 0x80612296,
CELL_ADEC_ERROR_ATX_SYNTAX_IDWL_B = 0x80612297,
CELL_ADEC_ERROR_ATX_SYNTAX_IDWL_C = 0x80612298,
CELL_ADEC_ERROR_ATX_SYNTAX_IDWL_D = 0x80612299,
CELL_ADEC_ERROR_ATX_SYNTAX_IDWL_E = 0x8061229a,
CELL_ADEC_ERROR_ATX_SYNTAX_IDSF_A = 0x8061229b,
CELL_ADEC_ERROR_ATX_SYNTAX_IDSF_B = 0x8061229c,
CELL_ADEC_ERROR_ATX_SYNTAX_IDSF_C = 0x8061229d,
CELL_ADEC_ERROR_ATX_SYNTAX_IDSF_D = 0x8061229e,
CELL_ADEC_ERROR_ATX_SYNTAX_IDCT_A = 0x8061229f,
CELL_ADEC_ERROR_ATX_SYNTAX_GC_NGC = 0x806122a0,
CELL_ADEC_ERROR_ATX_SYNTAX_GC_IDLEV_A = 0x806122a1,
CELL_ADEC_ERROR_ATX_SYNTAX_GC_IDLOC_A = 0x806122a2,
CELL_ADEC_ERROR_ATX_SYNTAX_GC_IDLEV_B = 0x806122a3,
CELL_ADEC_ERROR_ATX_SYNTAX_GC_IDLOC_B = 0x806122a4,
CELL_ADEC_ERROR_ATX_SYNTAX_SN_NWVS = 0x806122a5,
CELL_ADEC_ERROR_ATX_FATAL_HANDLE = 0x806122aa,
CELL_ADEC_ERROR_ATX_ASSERT_SAMPLING_FREQ = 0x806122ab,
CELL_ADEC_ERROR_ATX_ASSERT_CH_CONFIG_INDEX = 0x806122ac,
CELL_ADEC_ERROR_ATX_ASSERT_NBYTES = 0x806122ad,
CELL_ADEC_ERROR_ATX_ASSERT_BLOCK_NUM = 0x806122ae,
CELL_ADEC_ERROR_ATX_ASSERT_BLOCK_ID = 0x806122af,
CELL_ADEC_ERROR_ATX_ASSERT_CHANNELS = 0x806122b0,
CELL_ADEC_ERROR_ATX_UNINIT_BLOCK_SPECIFIED = 0x806122b1,
CELL_ADEC_ERROR_ATX_POSCFG_PRESENT = 0x806122b2,
CELL_ADEC_ERROR_ATX_BUFFER_OVERFLOW = 0x806122b3,
CELL_ADEC_ERROR_ATX_ILL_BLK_TYPE_ID = 0x806122b4,
CELL_ADEC_ERROR_ATX_UNPACK_CHANNEL_BLK_FAILED = 0x806122b5,
CELL_ADEC_ERROR_ATX_ILL_BLK_ID_USED_1 = 0x806122b6,
CELL_ADEC_ERROR_ATX_ILL_BLK_ID_USED_2 = 0x806122b7,
CELL_ADEC_ERROR_ATX_ILLEGAL_ENC_SETTING = 0x806122b8,
CELL_ADEC_ERROR_ATX_ILLEGAL_DEC_SETTING = 0x806122b9,
CELL_ADEC_ERROR_ATX_ASSERT_NSAMPLES = 0x806122ba,
CELL_ADEC_ERROR_ATX_ILL_SYNCWORD = 0x806122bb,
CELL_ADEC_ERROR_ATX_ILL_SAMPLING_FREQ = 0x806122bc,
CELL_ADEC_ERROR_ATX_ILL_CH_CONFIG_INDEX = 0x806122bd,
CELL_ADEC_ERROR_ATX_RAW_DATA_FRAME_SIZE_OVER = 0x806122be,
CELL_ADEC_ERROR_ATX_SYNTAX_ENHANCE_LENGTH_OVER = 0x806122bf,
CELL_ADEC_ERROR_ATX_SPU_INTERNAL_FAIL = 0x806122c8,
CELL_ADEC_ERROR_LPCM_FATAL = 0x80612001,
@ -194,14 +182,9 @@ enum
CELL_ADEC_ERROR_MP3_OFFSET = 0x80612700U,
CELL_ADEC_ERROR_MP3_OK = 0x80612700,
/* Adapter level error */
CELL_ADEC_ERROR_MP3_BUSY = 0x80612764,
CELL_ADEC_ERROR_MP3_EMPTY = 0x80612765,
/* Core level error */
CELL_ADEC_ERROR_MP3_ERROR = 0x80612781,
CELL_ADEC_ERROR_MP3_LOST_SYNC = 0x80612782,
CELL_ADEC_ERROR_MP3_NOT_L3 = 0x80612783,
@ -224,27 +207,24 @@ enum
CELL_ADEC_ERROR_M2BC_FATAL = 0x80612b01,
CELL_ADEC_ERROR_M2BC_SEQ = 0x80612b02, /* Not Used */
CELL_ADEC_ERROR_M2BC_SEQ = 0x80612b02,
CELL_ADEC_ERROR_M2BC_ARG = 0x80612b03,
CELL_ADEC_ERROR_M2BC_BUSY = 0x80612b04,
CELL_ADEC_ERROR_M2BC_EMPTY = 0x80612b05,
/* Common header contents error */
CELL_ADEC_ERROR_M2BC_SYNCF = 0x80612b11,
CELL_ADEC_ERROR_M2BC_LAYER = 0x80612b12,
CELL_ADEC_ERROR_M2BC_BITRATE = 0x80612b13,
CELL_ADEC_ERROR_M2BC_SAMPLEFREQ = 0x80612b14,
CELL_ADEC_ERROR_M2BC_VERSION = 0x80612b15,
CELL_ADEC_ERROR_M2BC_MODE_EXT = 0x80612b16, /* Not Used */
CELL_ADEC_ERROR_M2BC_UNSUPPORT = 0x80612b17, /* <MS-2323>*/
CELL_ADEC_ERROR_M2BC_MODE_EXT = 0x80612b16,
CELL_ADEC_ERROR_M2BC_UNSUPPORT = 0x80612b17,
/* Extension file header contents error */
CELL_ADEC_ERROR_M2BC_OPENBS_EX = 0x80612b21,
CELL_ADEC_ERROR_M2BC_SYNCF_EX = 0x80612b22,
CELL_ADEC_ERROR_M2BC_CRCGET_EX = 0x80612b23,
CELL_ADEC_ERROR_M2BC_CRC_EX = 0x80612b24,
/* Data sampling & CRC error (proper to MPEG I part) */
CELL_ADEC_ERROR_M2BC_CRCGET = 0x80612b31,
CELL_ADEC_ERROR_M2BC_CRC = 0x80612b32,
CELL_ADEC_ERROR_M2BC_BITALLOC = 0x80612b33,
@ -252,7 +232,6 @@ enum
CELL_ADEC_ERROR_M2BC_SAMPLE = 0x80612b35,
CELL_ADEC_ERROR_M2BC_OPENBS = 0x80612b36,
/* Data sampling & CRC error (MPEG II muliti codec part) */
CELL_ADEC_ERROR_M2BC_MC_CRCGET = 0x80612b41,
CELL_ADEC_ERROR_M2BC_MC_CRC = 0x80612b42,
CELL_ADEC_ERROR_M2BC_MC_BITALLOC = 0x80612b43,
@ -261,14 +240,12 @@ enum
CELL_ADEC_ERROR_M2BC_MC_HEADER = 0x80612b46,
CELL_ADEC_ERROR_M2BC_MC_STATUS = 0x80612b47,
/* Data sampling & CRC error (MPEG II extention muliti codec part) */
CELL_ADEC_ERROR_M2BC_AG_CCRCGET = 0x80612b51,
CELL_ADEC_ERROR_M2BC_AG_CRC = 0x80612b52,
CELL_ADEC_ERROR_M2BC_AG_BITALLOC = 0x80612b53,
CELL_ADEC_ERROR_M2BC_AG_SCALE = 0x80612b54,
CELL_ADEC_ERROR_M2BC_AG_SAMPLE = 0x80612b55,
CELL_ADEC_ERROR_M2BC_AG_STATUS = 0x80612b57,
};
// Audio Codec Type

View file

@ -135,66 +135,41 @@ struct CellAudioPortConfig
struct AudioPortConfig
{
bool m_is_audio_port_opened;
bool m_is_audio_port_started;
bool m_is_audio_port_stopped;
CellAudioPortParam m_param;
const u32 m_buffer; // 64 KB or 128 KB with 8x16 config
const u32 m_index;
AudioPortConfig();
void finalize();
};
struct AudioConfig //custom structure
{
Array<AudioPortConfig*> m_ports;
enum
{
AUDIO_PORT_COUNT = 8,
};
AudioPortConfig m_ports[AUDIO_PORT_COUNT];
u32 m_buffer; // 1 MB memory for audio ports
u32 m_indexes; // current block indexes and other info
bool m_is_audio_initialized;
bool m_is_audio_finalized;
u32 m_port_in_use;
u64 event_key;
AudioConfig()
: m_is_audio_initialized(false)
, m_is_audio_finalized(false)
, m_port_in_use(0)
, event_key(0)
{
m_ports.SetCount(8);
for (u32 i = 0; i < m_ports.GetCount(); i++)
m_ports[i] = nullptr;
memset(&m_ports, 0, sizeof(AudioPortConfig) * AUDIO_PORT_COUNT);
}
void Clear()
{
for (u32 i = 0; i < m_ports.GetCount(); i++)
{
if (m_ports[i])
{
delete m_ports[i];
m_ports[i] = nullptr;
}
}
memset(&m_ports, 0, sizeof(AudioPortConfig) * AUDIO_PORT_COUNT);
m_port_in_use = 0;
}
} m_config;
AudioPortConfig::AudioPortConfig()
: m_is_audio_port_started(false)
, m_buffer(Memory.Alloc(1024 * 128, 1024)) // max 128K size
, m_index(Memory.Alloc(16, 16)) // allocation for u64 value "read index"
{
m_config.m_port_in_use++;
mem64_t index(m_index);
index = 0;
}
void AudioPortConfig::finalize()
{
m_config.m_port_in_use--;
Memory.Free(m_buffer);
Memory.Free(m_index);
}
//libmixer datatypes
typedef void * CellAANHandle;
@ -307,160 +282,41 @@ int cellAudioInit()
}
m_config.m_is_audio_initialized = true;
return CELL_OK;
}
int cellAudioQuit()
{
cellAudio.Warning("cellAudioQuit()");
// alloc memory
m_config.m_buffer = Memory.Alloc(128 * 1024 * m_config.AUDIO_PORT_COUNT, 1024);
memset(Memory + m_config.m_buffer, 0, 128 * 1024 * m_config.AUDIO_PORT_COUNT);
m_config.m_indexes = Memory.Alloc(sizeof(u64) * m_config.AUDIO_PORT_COUNT, 16);
memset(Memory + m_config.m_indexes, 0, sizeof(u64) * m_config.AUDIO_PORT_COUNT);
if (!m_config.m_is_audio_initialized)
{
return CELL_AUDIO_ERROR_NOT_INIT;
}
m_config.m_is_audio_initialized = false;
return CELL_OK;
}
int cellAudioPortOpen(mem_ptr_t<CellAudioPortParam> audioParam, mem32_t portNum)
{
cellAudio.Warning("cellAudioPortOpen(audioParam_addr=0x%x, portNum_addr=0x%x)", audioParam.GetAddr(), portNum.GetAddr());
if(!audioParam.IsGood() || !portNum.IsGood())
{
return CELL_AUDIO_ERROR_PARAM;
}
if (m_config.m_port_in_use >= m_config.m_ports.GetCount())
{
return CELL_AUDIO_ERROR_PORT_FULL;
}
for (u32 i = 0; i < m_config.m_ports.GetCount(); i++)
{
if (m_config.m_ports[i] == nullptr)
thread t("Audio", []()
{
CellAudioPortParam& ref = (m_config.m_ports[i] = new AudioPortConfig)->m_param;
ref.nChannel = audioParam->nChannel;
ref.nBlock = audioParam->nBlock;
ref.attr = audioParam->attr;
ref.level = audioParam->level;
WAVHeader header(2); // WAV file header (stereo)
portNum = i;
cellAudio.Warning("*** audio port opened(nChannel=%lld, nBlock=0x%llx, attr=0x%llx, level=%f): port = %d",
(u64)ref.nChannel, (u64)ref.nBlock, (u64)ref.attr, (float)ref.level, portNum.GetValue());
//TODO: implementation of ring buffer
return CELL_OK;
}
}
return CELL_AUDIO_ERROR_PORT_FULL;
}
int cellAudioGetPortConfig(u32 portNum, mem_ptr_t<CellAudioPortConfig> portConfig)
{
cellAudio.Warning("cellAudioGetPortConfig(portNum=0x%x, portConfig_addr=0x%x)", portNum, portConfig.GetAddr());
if (!portConfig.IsGood() || portNum >= m_config.m_ports.GetCount())
{
return CELL_AUDIO_ERROR_PARAM;
}
if (!m_config.m_ports[portNum])
{
portConfig->status = CELL_AUDIO_STATUS_CLOSE;
}
else if (m_config.m_ports[portNum]->m_is_audio_port_started)
{
portConfig->status = CELL_AUDIO_STATUS_RUN;
}
else
{
CellAudioPortParam& ref = m_config.m_ports[portNum]->m_param;
portConfig->status = CELL_AUDIO_STATUS_READY;
portConfig->nChannel = ref.nChannel;
portConfig->nBlock = ref.nBlock;
portConfig->portSize = ref.nChannel * ref.nBlock * 256 * sizeof(float);
portConfig->portAddr = m_config.m_ports[portNum]->m_buffer; // 0x20020000
portConfig->readIndexAddr = m_config.m_ports[portNum]->m_index; // 0x20010010 on ps3
ConLog.Write("*** nChannel=%d, nBlock=%d, portSize=0x%x, portAddr=0x%x, readIndexAddr=0x%x",
(u32)portConfig->nChannel, (u32)portConfig->nBlock, (u32)portConfig->portSize, (u32)portConfig->portAddr, (u32)portConfig->readIndexAddr);
// portAddr - readIndexAddr == 0xFFF0 on ps3
}
return CELL_OK;
}
int cellAudioPortStart(u32 portNum)
{
cellAudio.Warning("cellAudioPortStart(portNum=0x%x)", portNum);
if (portNum >= m_config.m_ports.GetCount())
{
return CELL_AUDIO_ERROR_PARAM;
}
if (!m_config.m_ports[portNum])
{
return CELL_AUDIO_ERROR_PORT_OPEN;
}
if (m_config.m_ports[portNum]->m_is_audio_port_started)
{
return CELL_AUDIO_ERROR_PORT_ALREADY_RUN;
}
m_config.m_ports[portNum]->m_is_audio_port_started = true;
m_config.m_ports[portNum]->m_is_audio_port_stopped = false;
std::string t_name = "AudioPort0";
t_name[9] += portNum;
thread t(t_name, [portNum]()
{
AudioPortConfig& port = *m_config.m_ports[portNum];
mem64_t index(port.m_index); // index storage
if (port.m_param.nChannel > 8)
{
ConLog.Error("Port aborted: invalid channel count (%d)", port.m_param.nChannel);
port.m_is_audio_port_stopped = true;
return;
}
WAVHeader header(port.m_param.nChannel); // WAV file header
wxString output_name = "audioport0.wav";
output_name[9] = '0' + portNum;
wxString output_name = "audio.wav";
wxFile output(output_name, wxFile::write); // create output file
if (!output.IsOpened())
{
ConLog.Error("Port aborted: cannot create %s", output_name.wx_str());
port.m_is_audio_port_stopped = true;
ConLog.Error("Audio aborted: cannot create %s", output_name.wx_str());
return;
}
ConLog.Write("Port started");
ConLog.Write("Audio started");
u64 start_time = get_system_time();
u64 counter = 0;
output.Write(&header, sizeof(header)); // write file header
const u32 block_size = port.m_param.nChannel * 256 * sizeof(float);
float buffer[2*256]; // buffer for 2 channels
float buffer2[8*256]; // buffer for 8 channels (max count)
float buffer[32*256]; // buffer for max channel count (8)
while (port.m_is_audio_port_started)
while (m_config.m_is_audio_initialized)
{
if (Emu.IsStopped())
{
ConLog.Warning("Port aborted");
ConLog.Warning("Audio aborted");
goto abort;
}
@ -480,59 +336,219 @@ int cellAudioPortStart(u32 portNum)
continue;
}
u32 position = index.GetValue(); // get old value
memcpy(buffer, Memory + port.m_buffer + position * block_size, block_size);
memset(Memory + port.m_buffer + position * block_size, 0, block_size);
bool first_mix = true;
index = (position + 1) % port.m_param.nBlock; // write new value
// TODO: send aftermix event (normal audio event)
for (u32 i = 0; i < block_size; i++)
// MIX:
for (u32 i = 0; i < m_config.AUDIO_PORT_COUNT; i++)
{
// reverse byte order (TODO: use port.m_param.level)
buffer[i] = re(buffer[i]);
}
if (!m_config.m_ports[i].m_is_audio_port_started) continue;
if (output.Write(&buffer, block_size) != (size_t)block_size) // write file data
AudioPortConfig& port = m_config.m_ports[i];
mem64_t index(m_config.m_indexes + i * sizeof(u64));
const u32 block_size = port.m_param.nChannel * 256;
u32 position = index.GetValue(); // get old value
u32 buf_addr = m_config.m_buffer + (i * 128 * 1024) + (position * block_size * sizeof(float));
memcpy(buffer2, Memory + buf_addr, block_size * sizeof(float));
memset(Memory + buf_addr, 0, block_size * sizeof(float));
index = (position + 1) % port.m_param.nBlock; // write new value
if (first_mix)
{
for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++)
{
// reverse byte order (TODO: use port.m_param.level)
buffer[i] = re(buffer2[i]);
}
first_mix = false;
}
else
{
for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++)
{
float value = re(buffer2[i]);
buffer[i] = (buffer[i] + value) * 0.5; // TODO: valid mixing
}
}
}
// send aftermix event (normal audio event)
// TODO: check event source
Emu.GetEventManager().SendEvent(m_config.event_key, 0x10103000e010e07, 0, 0, 0);
if (output.Write(&buffer, sizeof(buffer)) != sizeof(buffer)) // write file data
{
ConLog.Error("Port aborted: cannot write %s", output_name.wx_str());
goto abort;
}
header.Size += block_size; // update file header
header.RIFF.Size += block_size;
header.Size += sizeof(buffer); // update file header
header.RIFF.Size += sizeof(buffer);
}
ConLog.Write("Port finished");
ConLog.Write("Audio finished");
abort:
output.Seek(0);
output.Write(&header, sizeof(header)); // write fixed file header
output.Close();
port.m_is_audio_port_stopped = true;
m_config.m_is_audio_finalized = true;
});
t.detach();
return CELL_OK;
}
int cellAudioQuit()
{
cellAudio.Warning("cellAudioQuit()");
if (!m_config.m_is_audio_initialized)
{
return CELL_AUDIO_ERROR_NOT_INIT;
}
m_config.m_is_audio_initialized = false;
while (!m_config.m_is_audio_finalized)
{
Sleep(1);
if (Emu.IsStopped())
{
ConLog.Warning("cellAudioQuit() aborted");
break;
}
}
Memory.Free(m_config.m_buffer);
Memory.Free(m_config.m_indexes);
return CELL_OK;
}
int cellAudioPortOpen(mem_ptr_t<CellAudioPortParam> audioParam, mem32_t portNum)
{
cellAudio.Warning("cellAudioPortOpen(audioParam_addr=0x%x, portNum_addr=0x%x)", audioParam.GetAddr(), portNum.GetAddr());
if(!audioParam.IsGood() || !portNum.IsGood())
{
return CELL_AUDIO_ERROR_PARAM;
}
if (audioParam->nChannel > 8 || audioParam->nBlock > 16)
{
return CELL_AUDIO_ERROR_PARAM;
}
if (m_config.m_port_in_use >= m_config.AUDIO_PORT_COUNT)
{
return CELL_AUDIO_ERROR_PORT_FULL;
}
for (u32 i = 0; i < m_config.AUDIO_PORT_COUNT; i++)
{
if (!m_config.m_ports[i].m_is_audio_port_opened)
{
CellAudioPortParam& param = m_config.m_ports[i].m_param;
param.nChannel = audioParam->nChannel;
param.nBlock = audioParam->nBlock;
param.attr = audioParam->attr;
param.level = audioParam->level;
portNum = i;
cellAudio.Warning("*** audio port opened(nChannel=%lld, nBlock=0x%llx, attr=0x%llx, level=%f): port = %d",
(u64)param.nChannel, (u64)param.nBlock, (u64)param.attr, (float)param.level, i);
m_config.m_port_in_use++;
m_config.m_ports[i].m_is_audio_port_opened = true;
m_config.m_ports[i].m_is_audio_port_started = false;
return CELL_OK;
}
}
return CELL_AUDIO_ERROR_PORT_FULL;
}
int cellAudioGetPortConfig(u32 portNum, mem_ptr_t<CellAudioPortConfig> portConfig)
{
cellAudio.Warning("cellAudioGetPortConfig(portNum=0x%x, portConfig_addr=0x%x)", portNum, portConfig.GetAddr());
if (!portConfig.IsGood() || portNum >= m_config.AUDIO_PORT_COUNT)
{
return CELL_AUDIO_ERROR_PARAM;
}
if (!m_config.m_ports[portNum].m_is_audio_port_opened)
{
portConfig->status = CELL_AUDIO_STATUS_CLOSE;
}
else if (m_config.m_ports[portNum].m_is_audio_port_started)
{
portConfig->status = CELL_AUDIO_STATUS_RUN;
}
else
{
portConfig->status = CELL_AUDIO_STATUS_READY;
}
CellAudioPortParam& ref = m_config.m_ports[portNum].m_param;
portConfig->nChannel = ref.nChannel;
portConfig->nBlock = ref.nBlock;
portConfig->portSize = ref.nChannel * ref.nBlock * 256 * sizeof(float);
portConfig->portAddr = m_config.m_buffer + (128 * 1024 * portNum); // 0x20020000
portConfig->readIndexAddr = m_config.m_indexes + (sizeof(u64) * portNum); // 0x20010010 on ps3
ConLog.Write("*** nChannel=%d, nBlock=%d, portSize=0x%x, portAddr=0x%x, readIndexAddr=0x%x",
(u32)portConfig->nChannel, (u32)portConfig->nBlock, (u32)portConfig->portSize, (u32)portConfig->portAddr, (u32)portConfig->readIndexAddr);
// portAddr - readIndexAddr == 0xFFF0 on ps3
return CELL_OK;
}
int cellAudioPortStart(u32 portNum)
{
cellAudio.Warning("cellAudioPortStart(portNum=0x%x)", portNum);
if (portNum >= m_config.AUDIO_PORT_COUNT)
{
return CELL_AUDIO_ERROR_PARAM;
}
if (!m_config.m_ports[portNum].m_is_audio_port_opened)
{
return CELL_AUDIO_ERROR_PORT_OPEN;
}
if (m_config.m_ports[portNum].m_is_audio_port_started)
{
return CELL_AUDIO_ERROR_PORT_ALREADY_RUN;
}
m_config.m_ports[portNum].m_is_audio_port_started = true;
return CELL_OK;
}
int cellAudioPortClose(u32 portNum)
{
cellAudio.Warning("cellAudioPortClose(portNum=0x%x)", portNum);
if (portNum >= m_config.m_ports.GetCount())
if (portNum >= m_config.AUDIO_PORT_COUNT)
{
return CELL_AUDIO_ERROR_PARAM;
}
if (!m_config.m_ports[portNum])
if (!m_config.m_ports[portNum].m_is_audio_port_opened)
{
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
}
m_config.m_ports[portNum]->finalize();
safe_delete(m_config.m_ports[portNum]);
m_config.m_ports[portNum].m_is_audio_port_started = false;
m_config.m_port_in_use--;
return CELL_OK;
}
@ -540,31 +556,22 @@ int cellAudioPortStop(u32 portNum)
{
cellAudio.Warning("cellAudioPortStop(portNum=0x%x)",portNum);
if (portNum >= m_config.m_ports.GetCount())
if (portNum >= m_config.AUDIO_PORT_COUNT)
{
return CELL_AUDIO_ERROR_PARAM;
}
if (!m_config.m_ports[portNum])
if (!m_config.m_ports[portNum].m_is_audio_port_opened)
{
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
}
if (!m_config.m_ports[portNum]->m_is_audio_port_started)
if (!m_config.m_ports[portNum].m_is_audio_port_started)
{
return CELL_AUDIO_ERROR_PORT_NOT_RUN;
}
m_config.m_ports[portNum]->m_is_audio_port_started = false;
while (!m_config.m_ports[portNum]->m_is_audio_port_stopped)
{
Sleep(1);
if (Emu.IsStopped())
{
ConLog.Warning("cellAudioPortStop(%d) aborted", portNum);
break;
}
}
m_config.m_ports[portNum].m_is_audio_port_started = false;
return CELL_OK;
}
@ -589,8 +596,24 @@ int cellAudioSetPortLevel(u32 portNum, float level)
// Utility Functions
int cellAudioCreateNotifyEventQueue(mem32_t id, mem64_t key)
{
cellAudio.Error("cellAudioCreateNotifyEventQueue(id_addr=0x%x, key_addr=0x%x)", id.GetAddr(), key.GetAddr());
key = 0x123456789ABCDEF0;
cellAudio.Warning("cellAudioCreateNotifyEventQueue(id_addr=0x%x, key_addr=0x%x)", id.GetAddr(), key.GetAddr());
if (Emu.GetEventManager().CheckKey(0x80004d494f323221))
{
return CELL_AUDIO_ERROR_EVENT_QUEUE;
}
EventQueue* eq = new EventQueue(SYS_SYNC_FIFO, SYS_PPU_QUEUE, 0x80004d494f323221, 0x80004d494f323221, 32);
if (!Emu.GetEventManager().RegisterKey(eq, 0x80004d494f323221))
{
delete eq;
return CELL_AUDIO_ERROR_EVENT_QUEUE;
}
id = cellAudio.GetNewId(eq);
key = 0x80004d494f323221;
return CELL_OK;
}
@ -609,11 +632,10 @@ int cellAudioSetNotifyEventQueue(u64 key)
EventQueue* eq;
if (!Emu.GetEventManager().GetEventQueue(key, eq))
{
//return CELL_AUDIO_ERROR_PARAM;
return CELL_OK;
return CELL_AUDIO_ERROR_PARAM;
}
// eq->events.push(0, 0, 0, 0);
// TODO: connect port
return CELL_OK;
}
@ -626,7 +648,18 @@ int cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
int cellAudioRemoveNotifyEventQueue(u64 key)
{
cellAudio.Error("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key);
cellAudio.Warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key);
EventQueue* eq;
if (!Emu.GetEventManager().GetEventQueue(key, eq))
{
return CELL_AUDIO_ERROR_PARAM;
}
m_config.event_key = 0;
// TODO: disconnect port
return CELL_OK;
}

View file

@ -199,7 +199,7 @@ int sys_event_queue_receive(u32 equeue_id, mem_ptr_t<sys_event_data> event, u64
}
case SMR_SIGNAL:
{
eq->events.pop(*(sys_event_data*)(Memory + event));
eq->events.pop(*event);
eq->owner.unlock(tid);
return CELL_OK;
}

View file

@ -220,4 +220,5 @@ public:
bool RegisterKey(EventQueue* data, u64 key);
bool GetEventQueue(u64 key, EventQueue*& data);
bool UnregisterKey(u64 key);
bool SendEvent(u64 key, u64 source, u64 d1, u64 d2, u64 d3);
};