You've already forked hackerlibultra
mirror of
https://github.com/HackerN64/hackerlibultra.git
synced 2026-01-21 10:37:53 -08:00
osVoice decomp (#15)
This commit is contained in:
2
Makefile
2
Makefile
@@ -109,6 +109,8 @@ $(BUILD_DIR)/src/mgu/rotate.marker: export VR4300MUL := ON
|
||||
$(BUILD_DIR)/src/os/%.marker: ASFLAGS += -P
|
||||
$(BUILD_DIR)/src/gu/%.marker: ASFLAGS += -P
|
||||
$(BUILD_DIR)/src/libc/%.marker: ASFLAGS += -P
|
||||
$(BUILD_DIR)/src/voice/%.marker: OPTFLAGS += -DLANG_JAPANESE -I$(WORKING_DIR)/src -I$(WORKING_DIR)/src/voice
|
||||
$(BUILD_DIR)/src/voice/%.marker: CC := tools/compile_sjis.py -D__CC=$(WORKING_DIR)/$(CC)
|
||||
|
||||
$(BUILD_DIR)/%.marker: %.c
|
||||
cd $(<D) && $(WORKING_DIR)/$(CC) $(CFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(<F) -o $(WORKING_DIR)/$(@:.marker=.o)
|
||||
|
||||
@@ -115,6 +115,11 @@ typedef struct
|
||||
#define CONT_CMD_WRITE_PAK 3
|
||||
#define CONT_CMD_READ_EEPROM 4
|
||||
#define CONT_CMD_WRITE_EEPROM 5
|
||||
#define CONT_CMD_READ36_VOICE 9
|
||||
#define CONT_CMD_WRITE20_VOICE 10
|
||||
#define CONT_CMD_READ2_VOICE 11
|
||||
#define CONT_CMD_WRITE4_VOICE 12
|
||||
#define CONT_CMD_SWRITE_VOICE 13
|
||||
#define CONT_CMD_CHANNEL_RESET 0xFD
|
||||
#define CONT_CMD_RESET 0xFF
|
||||
|
||||
@@ -125,6 +130,11 @@ typedef struct
|
||||
#define CONT_CMD_WRITE_PAK_TX 35
|
||||
#define CONT_CMD_READ_EEPROM_TX 2
|
||||
#define CONT_CMD_WRITE_EEPROM_TX 10
|
||||
#define CONT_CMD_READ36_VOICE_TX 3
|
||||
#define CONT_CMD_WRITE20_VOICE_TX 23
|
||||
#define CONT_CMD_READ2_VOICE_TX 3
|
||||
#define CONT_CMD_WRITE4_VOICE_TX 7
|
||||
#define CONT_CMD_SWRITE_VOICE_TX 3
|
||||
#define CONT_CMD_RESET_TX 1
|
||||
|
||||
// Bytes received for each joybus command
|
||||
@@ -134,6 +144,11 @@ typedef struct
|
||||
#define CONT_CMD_WRITE_PAK_RX 1
|
||||
#define CONT_CMD_READ_EEPROM_RX 8
|
||||
#define CONT_CMD_WRITE_EEPROM_RX 1
|
||||
#define CONT_CMD_READ36_VOICE_RX 37
|
||||
#define CONT_CMD_WRITE20_VOICE_RX 1
|
||||
#define CONT_CMD_READ2_VOICE_RX 3
|
||||
#define CONT_CMD_WRITE4_VOICE_RX 1
|
||||
#define CONT_CMD_SWRITE_VOICE_RX 1
|
||||
#define CONT_CMD_RESET_RX 3
|
||||
|
||||
#define CONT_CMD_NOP 0xff
|
||||
|
||||
59
src/io/controller_voice.h
Normal file
59
src/io/controller_voice.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef CONTROLLER_VOICE_H
|
||||
#define CONTROLLER_VOICE_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
typedef struct {
|
||||
/* 0x0 */ u8 dummy;
|
||||
/* 0x1 */ u8 txsize;
|
||||
/* 0x2 */ u8 rxsize;
|
||||
/* 0x3 */ u8 cmd;
|
||||
/* 0x4 */ u8 addrh;
|
||||
/* 0x5 */ u8 addrl;
|
||||
/* 0x6 */ u8 data[2];
|
||||
/* 0x8 */ u8 datacrc;
|
||||
} __OSVoiceRead2Format;
|
||||
|
||||
typedef struct {
|
||||
/* 0x0 */ u8 dummy;
|
||||
/* 0x1 */ u8 txsize;
|
||||
/* 0x2 */ u8 rxsize;
|
||||
/* 0x3 */ u8 cmd;
|
||||
/* 0x4 */ u8 addrh;
|
||||
/* 0x5 */ u8 addrl;
|
||||
/* 0x6 */ u8 data[36];
|
||||
/* 0x2A */ u8 datacrc;
|
||||
} __OSVoiceRead36Format;
|
||||
|
||||
typedef struct {
|
||||
/* 0x0 */ u8 dummy;
|
||||
/* 0x1 */ u8 txsize;
|
||||
/* 0x2 */ u8 rxsize;
|
||||
/* 0x3 */ u8 cmd;
|
||||
/* 0x4 */ u8 addrh;
|
||||
/* 0x5 */ u8 addrl;
|
||||
/* 0x6 */ u8 data[4];
|
||||
/* 0xA */ u8 datacrc;
|
||||
} __OSVoiceWrite4Format;
|
||||
|
||||
typedef struct {
|
||||
/* 0x0 */ u8 dummy;
|
||||
/* 0x1 */ u8 txsize;
|
||||
/* 0x2 */ u8 rxsize;
|
||||
/* 0x3 */ u8 cmd;
|
||||
/* 0x4 */ u8 addrh;
|
||||
/* 0x5 */ u8 addrl;
|
||||
/* 0x6 */ u8 data[20];
|
||||
/* 0x1A */ u8 datacrc;
|
||||
} __OSVoiceWrite20Format;
|
||||
|
||||
typedef struct {
|
||||
/* 0x0 */ u8 txsize;
|
||||
/* 0x1 */ u8 rxsize;
|
||||
/* 0x2 */ u8 cmd;
|
||||
/* 0x3 */ u8 data;
|
||||
/* 0x4 */ u8 scrc;
|
||||
/* 0x5 */ u8 datacrc;
|
||||
} __OSVoiceSWriteFormat;
|
||||
|
||||
#endif // CONTROLLER_VOICE_H
|
||||
23
src/voice/voicecheckresult.c
Normal file
23
src/voice/voicecheckresult.c
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
|
||||
s32 __osVoiceCheckResult(OSVoiceHandle* hd, u8* stat) {
|
||||
s32 ret;
|
||||
u8 buf[2];
|
||||
|
||||
if (ret = __osVoiceGetStatus(hd->__mq, hd->__channel, stat), ret == 0) {
|
||||
if (*stat & 1) {
|
||||
ret = CONT_ERR_VOICE_NO_RESPONSE;
|
||||
} else if (ret = __osVoiceContRead2(hd->__mq, hd->__channel, 0, buf), ret == 0) {
|
||||
hd->cmd_status = buf[0] & 7;
|
||||
|
||||
if (buf[0] & 0x40) {
|
||||
ret = CONT_ERR_VOICE_NO_RESPONSE;
|
||||
} else {
|
||||
ret = buf[1] << 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
116
src/voice/voicecheckword.c
Normal file
116
src/voice/voicecheckword.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
|
||||
s32 osVoiceCheckWord(u8* word) {
|
||||
s32 k;
|
||||
s32 ret = 0;
|
||||
u16 sjis;
|
||||
u16 old = 0;
|
||||
|
||||
for (k = 0; word[k] != 0; k += 2) {
|
||||
sjis = (word[k] << 8) + word[k + 1];
|
||||
if (((sjis != 'ー') && (sjis < 'ぁ'))
|
||||
|| ((sjis > 'ん') && (sjis < 'ァ'))
|
||||
|| (sjis == 0x837F) || (sjis > 'ヶ')
|
||||
) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
} else if ((k == 0) && ((sjis == 'ー') || (sjis == 'ん') || (sjis == 'っ')
|
||||
|| (sjis == 'ゎ') || (sjis == 'ン') || (sjis == 'ッ')
|
||||
|| (sjis == 'ヮ') || (sjis == 'ヵ') || (sjis == 'ヶ'))
|
||||
) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
} else if (((sjis == 'ぁ') || (sjis == 'ァ'))
|
||||
&& (old != 'ふ') && (old != 'フ') && (old != 'ヴ')
|
||||
) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
} else if (((sjis == 'ぃ') || (sjis == 'ィ')) && (old != 'う')
|
||||
&& (old != 'て') && (old != 'で') && (old != 'ふ')
|
||||
&& (old != 'ウ') && (old != 'テ') && (old != 'デ')
|
||||
&& (old != 'フ') && (old != 'ヴ')
|
||||
) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
} else if (((sjis == 'ぅ') || (sjis == 'ゥ'))
|
||||
&& (old != 'と') && (old != 'ど')
|
||||
&& (old != 'ふ')
|
||||
&& (old != 'ト') && (old != 'ド')
|
||||
&& (old != 'フ') && (old != 'ヴ')
|
||||
) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
} else if (((sjis == 'ぇ') || (sjis == 'ェ'))
|
||||
&& (old != 'う')
|
||||
&& (old != 'し') && (old != 'じ')
|
||||
&& (old != 'ち') && (old != 'ぢ')
|
||||
&& (old != 'つ') && (old != 'ふ') && (old != 'ウ')
|
||||
&& (old != 'シ') && (old != 'ジ')
|
||||
&& (old != 'チ') && (old != 'ヂ')
|
||||
&& (old != 'ツ') && (old != 'フ') && (old != 'ヴ')
|
||||
) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
} else if (((sjis == 'ぉ') || (sjis == 'ォ'))
|
||||
&& (old != 'う') && (old != 'ふ') && (old != 'ウ') && (old != 'フ') && (old != 'ヴ')
|
||||
) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
} else if (((sjis == 'ゃ') || (sjis == 'ゅ') || (sjis == 'ょ')
|
||||
|| (sjis == 'ャ') || (sjis == 'ュ') || (sjis == 'ョ'))
|
||||
&& (old != 'き') && (old != 'し') && (old != 'ち')
|
||||
&& (old != 'に') && (old != 'ひ') && (old != 'み')
|
||||
&& (old != 'り') && (old != 'ぎ') && (old != 'じ')
|
||||
&& (old != 'ぢ') && (old != 'び') && (old != 'ぴ')
|
||||
&& (old != 'キ') && (old != 'シ') && (old != 'チ')
|
||||
&& (old != 'ニ') && (old != 'ヒ') && (old != 'ミ')
|
||||
&& (old != 'リ') && (old != 'ギ') && (old != 'ジ')
|
||||
&& (old != 'ヂ') && (old != 'ビ') && (old != 'ピ')
|
||||
&& (old != 'ヴ')
|
||||
) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
} else if ((sjis == 'ー')
|
||||
&& ((old == 'ん') || (old == 'っ')
|
||||
|| (old == 'ン') || (old == 'ッ'))
|
||||
) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
} else if (((sjis == 'ん') || (sjis == 'ン'))
|
||||
&& ((old == 'ん') || (old == 'ン'))
|
||||
) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
} else if (((old == 'っ') || (old == 'ッ'))
|
||||
&& ((sjis == 'ー')
|
||||
|| (sjis == 'あ') || (sjis == 'い') || (sjis == 'う') || (sjis == 'え') || (sjis == 'お')
|
||||
|| (sjis == 'な') || (sjis == 'に') || (sjis == 'ぬ') || (sjis == 'ね') || (sjis == 'の')
|
||||
|| (sjis == 'ま') || (sjis == 'み') || (sjis == 'む') || (sjis == 'め') || (sjis == 'も')
|
||||
|| (sjis == 'や') || (sjis == 'ゆ') || (sjis == 'よ')
|
||||
|| (sjis == 'ら') || (sjis == 'り') || (sjis == 'る') || (sjis == 'れ') || (sjis == 'ろ')
|
||||
|| (sjis == 'わ') || (sjis == 'ゐ') || (sjis == 'ゑ') || (sjis == 'を')
|
||||
|| (sjis == 'ん')
|
||||
|| (sjis == 'ぁ') || (sjis == 'ぃ') || (sjis == 'ぅ') || (sjis == 'ぇ') || (sjis == 'ぉ')
|
||||
|| (sjis == 'ゃ') || (sjis == 'ゅ') || (sjis == 'ょ')
|
||||
|| (sjis == 'っ') || (sjis == 'ゎ')
|
||||
|
||||
|| (sjis == 'ア') || (sjis == 'イ') || (sjis == 'ウ') || (sjis == 'エ') || (sjis == 'オ')
|
||||
|| (sjis == 'ナ') || (sjis == 'ニ') || (sjis == 'ヌ') || (sjis == 'ネ') || (sjis == 'ノ')
|
||||
|| (sjis == 'マ') || (sjis == 'ミ') || (sjis == 'ム') || (sjis == 'メ') || (sjis == 'モ')
|
||||
|| (sjis == 'ヤ') || (sjis == 'ユ') || (sjis == 'ヨ')
|
||||
|| (sjis == 'ラ') || (sjis == 'リ') || (sjis == 'ル') || (sjis == 'レ') || (sjis == 'ロ')
|
||||
|| (sjis == 'ワ') || (sjis == 'ヰ') || (sjis == 'ヱ') || (sjis == 'ヲ')
|
||||
|| (sjis == 'ン')
|
||||
|| (sjis == 'ァ') || (sjis == 'ィ') || (sjis == 'ゥ') || (sjis == 'ェ') || (sjis == 'ォ')
|
||||
|| (sjis == 'ャ') || (sjis == 'ュ') || (sjis == 'ョ')
|
||||
|| (sjis == 'ッ') || (sjis == 'ヮ')
|
||||
)
|
||||
) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
old = sjis;
|
||||
}
|
||||
|
||||
if ((sjis == 'っ') || (sjis == 'ッ')) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
28
src/voice/voicecleardictionary.c
Normal file
28
src/voice/voicecleardictionary.c
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
|
||||
s32 osVoiceClearDictionary(OSVoiceHandle* hd, u8 words) {
|
||||
s32 ret;
|
||||
u8 stat;
|
||||
u8 buf[4];
|
||||
|
||||
ERRCK(__osVoiceGetStatus(hd->__mq, hd->__channel, &stat));
|
||||
|
||||
if (stat & 2) {
|
||||
return CONT_ERR_VOICE_NO_RESPONSE;
|
||||
}
|
||||
|
||||
*(u32*)buf = 0x02000000;
|
||||
buf[2] = words;
|
||||
|
||||
ERRCK(__osVoiceContWrite4(hd->__mq, hd->__channel, 0, buf));
|
||||
|
||||
ret = __osVoiceCheckResult(hd, &stat);
|
||||
if (ret & 0xFF00) {
|
||||
ret = CONT_ERR_INVALID;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
75
src/voice/voicecontread2.c
Normal file
75
src/voice/voicecontread2.c
Normal file
@@ -0,0 +1,75 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
#include "voiceinternal.h"
|
||||
#include "io/controller_voice.h"
|
||||
|
||||
#define READ2FORMAT(p) ((__OSVoiceRead2Format*)(ptr))
|
||||
|
||||
s32 __osVoiceContRead2(OSMesgQueue* mq, int channel, u16 address, u8* buffer) {
|
||||
s32 ret;
|
||||
u8 status;
|
||||
int i;
|
||||
u8* ptr;
|
||||
int retry;
|
||||
|
||||
retry = 2;
|
||||
|
||||
__osSiGetAccess();
|
||||
|
||||
do {
|
||||
|
||||
ptr = (u8*)&__osPfsPifRam.ramarray;
|
||||
|
||||
if ((__osContLastCmd != CONT_CMD_READ2_VOICE) || (__osPfsLastChannel != channel)) {
|
||||
__osContLastCmd = CONT_CMD_READ2_VOICE;
|
||||
__osPfsLastChannel = channel;
|
||||
|
||||
for (i = 0; i < channel; i++) {
|
||||
*ptr++ = 0;
|
||||
}
|
||||
|
||||
__osPfsPifRam.pifstatus = CONT_CMD_EXE;
|
||||
|
||||
READ2FORMAT(ptr)->dummy = CONT_CMD_NOP;
|
||||
READ2FORMAT(ptr)->txsize = CONT_CMD_READ2_VOICE_TX;
|
||||
READ2FORMAT(ptr)->rxsize = CONT_CMD_READ2_VOICE_RX;
|
||||
READ2FORMAT(ptr)->cmd = CONT_CMD_READ2_VOICE;
|
||||
READ2FORMAT(ptr)->datacrc = 0xFF;
|
||||
|
||||
ptr[sizeof(__OSVoiceRead2Format)] = CONT_CMD_END;
|
||||
} else {
|
||||
ptr = (u8*)&__osPfsPifRam.ramarray + channel;
|
||||
}
|
||||
|
||||
READ2FORMAT(ptr)->addrh = address >> 3;
|
||||
READ2FORMAT(ptr)->addrl = __osContAddressCrc(address) | (address << 5);
|
||||
|
||||
__osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
__osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = CHNL_ERR(*READ2FORMAT(ptr));
|
||||
|
||||
if (ret == 0) {
|
||||
if (__osVoiceContDataCrc(&READ2FORMAT(ptr)->data, ARRLEN(READ2FORMAT(ptr)->data)) != READ2FORMAT(ptr)->datacrc) {
|
||||
ret = __osVoiceGetStatus(mq, channel, &status);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
ret = CONT_ERR_CONTRFAIL;
|
||||
} else {
|
||||
bcopy(&READ2FORMAT(ptr)->data, buffer, ARRLEN(READ2FORMAT(ptr)->data));
|
||||
}
|
||||
} else {
|
||||
ret = CONT_ERR_NO_CONTROLLER;
|
||||
}
|
||||
|
||||
} while ((ret == CONT_ERR_CONTRFAIL) && (retry-- >= 0));
|
||||
|
||||
__osSiRelAccess();
|
||||
|
||||
return ret;
|
||||
}
|
||||
73
src/voice/voicecontread36.c
Normal file
73
src/voice/voicecontread36.c
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
#include "voiceinternal.h"
|
||||
#include "io/controller_voice.h"
|
||||
|
||||
#define READ36FORMAT(p) ((__OSVoiceRead36Format*)(ptr))
|
||||
|
||||
s32 __osVoiceContRead36(OSMesgQueue* mq, s32 channel, u16 address, u8* buffer) {
|
||||
s32 ret;
|
||||
u8 status;
|
||||
s32 i;
|
||||
u8* ptr;
|
||||
s32 retry = 2;
|
||||
|
||||
__osSiGetAccess();
|
||||
|
||||
do {
|
||||
|
||||
ptr = (u8*)&__osPfsPifRam.ramarray;
|
||||
|
||||
if ((__osContLastCmd != CONT_CMD_READ36_VOICE) || (__osPfsLastChannel != channel)) {
|
||||
__osContLastCmd = CONT_CMD_READ36_VOICE;
|
||||
__osPfsLastChannel = channel;
|
||||
|
||||
for (i = 0; i < channel; i++) {
|
||||
*ptr++ = 0;
|
||||
}
|
||||
|
||||
__osPfsPifRam.pifstatus = CONT_CMD_EXE;
|
||||
|
||||
READ36FORMAT(ptr)->dummy = CONT_CMD_NOP;
|
||||
READ36FORMAT(ptr)->txsize = CONT_CMD_READ36_VOICE_TX;
|
||||
READ36FORMAT(ptr)->rxsize = CONT_CMD_READ36_VOICE_RX;
|
||||
READ36FORMAT(ptr)->cmd = CONT_CMD_READ36_VOICE;
|
||||
READ36FORMAT(ptr)->datacrc = 0xFF;
|
||||
|
||||
ptr[sizeof(__OSVoiceRead36Format)] = CONT_CMD_END;
|
||||
} else {
|
||||
ptr = (u8*)&__osPfsPifRam + channel;
|
||||
}
|
||||
|
||||
READ36FORMAT(ptr)->addrh = address >> 3;
|
||||
READ36FORMAT(ptr)->addrl = __osContAddressCrc(address) | (address << 5);
|
||||
|
||||
__osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
__osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = CHNL_ERR(*READ36FORMAT(ptr));
|
||||
|
||||
if (ret == 0) {
|
||||
if (__osVoiceContDataCrc(&READ36FORMAT(ptr)->data, ARRLEN(READ36FORMAT(ptr)->data)) != READ36FORMAT(ptr)->datacrc) {
|
||||
ret = __osVoiceGetStatus(mq, channel, &status);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
ret = CONT_ERR_CONTRFAIL;
|
||||
} else {
|
||||
bcopy(&READ36FORMAT(ptr)->data, buffer, ARRLEN(READ36FORMAT(ptr)->data));
|
||||
}
|
||||
} else {
|
||||
ret = CONT_ERR_NO_CONTROLLER;
|
||||
}
|
||||
|
||||
} while ((ret == CONT_ERR_CONTRFAIL) && (retry-- >= 0));
|
||||
|
||||
__osSiRelAccess();
|
||||
|
||||
return ret;
|
||||
}
|
||||
22
src/voice/voicecontrolgain.c
Normal file
22
src/voice/voicecontrolgain.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
|
||||
s32 __osVoiceSetADConverter(OSMesgQueue*, int ch, u8 cmd);
|
||||
|
||||
s32 osVoiceControlGain(OSVoiceHandle *hd, s32 analog, s32 digital) {
|
||||
s32 ret;
|
||||
u8 cmd = (u8) (analog == 0 ? 0x18 : 0x98);
|
||||
static u8 digital_table[] = {0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0};
|
||||
|
||||
ERRCK(__osVoiceSetADConverter(hd->__mq,hd->__channel, cmd));
|
||||
|
||||
if ((digital < ARRLEN(digital_table)) && (digital >= 0)) {
|
||||
cmd = digital_table[digital] + 2;
|
||||
} else {
|
||||
return CONT_ERR_INVALID;
|
||||
}
|
||||
|
||||
ERRCK(__osVoiceSetADConverter(hd->__mq,hd->__channel, cmd));
|
||||
return ret;
|
||||
}
|
||||
77
src/voice/voicecontwrite20.c
Normal file
77
src/voice/voicecontwrite20.c
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
#include "voiceinternal.h"
|
||||
#include "io/controller_voice.h"
|
||||
|
||||
#define WRITE20FORMAT(p) ((__OSVoiceWrite20Format*)(ptr))
|
||||
|
||||
s32 __osVoiceContWrite20(OSMesgQueue* mq, int channel, u16 address, u8* buffer) {
|
||||
s32 ret;
|
||||
u8 status;
|
||||
int i;
|
||||
u8* ptr;
|
||||
int retry;
|
||||
u8 crc;
|
||||
|
||||
retry = 2;
|
||||
|
||||
__osSiGetAccess();
|
||||
|
||||
do {
|
||||
|
||||
ptr = (u8*)&__osPfsPifRam;
|
||||
|
||||
if ((__osContLastCmd != CONT_CMD_WRITE20_VOICE) || (__osPfsLastChannel != channel)) {
|
||||
__osContLastCmd = CONT_CMD_WRITE20_VOICE;
|
||||
__osPfsLastChannel = channel;
|
||||
|
||||
for (i = 0; i < channel; i++) {
|
||||
*ptr++ = 0;
|
||||
}
|
||||
|
||||
__osPfsPifRam.pifstatus = CONT_CMD_EXE;
|
||||
|
||||
WRITE20FORMAT(ptr)->dummy = CONT_CMD_NOP;
|
||||
WRITE20FORMAT(ptr)->txsize = CONT_CMD_WRITE20_VOICE_TX;
|
||||
WRITE20FORMAT(ptr)->rxsize = CONT_CMD_WRITE20_VOICE_RX;
|
||||
WRITE20FORMAT(ptr)->cmd = CONT_CMD_WRITE20_VOICE;
|
||||
WRITE20FORMAT(ptr)->datacrc = 0xFF;
|
||||
|
||||
ptr[sizeof(__OSVoiceWrite20Format)] = CONT_CMD_END;
|
||||
} else {
|
||||
ptr = (u8*)&__osPfsPifRam.ramarray + channel;
|
||||
}
|
||||
|
||||
WRITE20FORMAT(ptr)->addrh = address >> 3;
|
||||
WRITE20FORMAT(ptr)->addrl = __osContAddressCrc(address) | (address << 5);
|
||||
|
||||
bcopy(buffer, &WRITE20FORMAT(ptr)->data, 20);
|
||||
|
||||
__osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
crc = __osVoiceContDataCrc(buffer, 20);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
__osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = (WRITE20FORMAT(ptr)->rxsize & 0xC0) >> 4;
|
||||
|
||||
if (ret == 0) {
|
||||
if (crc != WRITE20FORMAT(ptr)->datacrc) {
|
||||
ret = __osVoiceGetStatus(mq, channel, &status);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
ret = CONT_ERR_CONTRFAIL;
|
||||
}
|
||||
} else {
|
||||
ret = CONT_ERR_NO_CONTROLLER;
|
||||
}
|
||||
|
||||
} while ((ret == CONT_ERR_CONTRFAIL) && (retry-- >= 0));
|
||||
|
||||
__osSiRelAccess();
|
||||
|
||||
return ret;
|
||||
}
|
||||
75
src/voice/voicecontwrite4.c
Normal file
75
src/voice/voicecontwrite4.c
Normal file
@@ -0,0 +1,75 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
#include "voiceinternal.h"
|
||||
#include "io/controller_voice.h"
|
||||
|
||||
#define WRITE4FORMAT(p) ((__OSVoiceWrite4Format*)(ptr))
|
||||
|
||||
s32 __osVoiceContWrite4(OSMesgQueue* mq, int channel, u16 address, u8 dst[4]) {
|
||||
s32 ret;
|
||||
u8 status;
|
||||
int i;
|
||||
u8* ptr;
|
||||
s32 retry = 2;
|
||||
u8 crc;
|
||||
|
||||
__osSiGetAccess();
|
||||
|
||||
do {
|
||||
|
||||
ptr = (u8*)&__osPfsPifRam;
|
||||
|
||||
if ((__osContLastCmd != CONT_CMD_WRITE4_VOICE) || (__osPfsLastChannel != channel)) {
|
||||
__osContLastCmd = CONT_CMD_WRITE4_VOICE;
|
||||
__osPfsLastChannel = channel;
|
||||
|
||||
for (i = 0; i < channel; i++) {
|
||||
*ptr++ = 0;
|
||||
}
|
||||
|
||||
__osPfsPifRam.pifstatus = CONT_CMD_EXE;
|
||||
|
||||
WRITE4FORMAT(ptr)->dummy = CONT_CMD_NOP;
|
||||
WRITE4FORMAT(ptr)->txsize = CONT_CMD_WRITE4_VOICE_TX;
|
||||
WRITE4FORMAT(ptr)->rxsize = CONT_CMD_WRITE4_VOICE_RX;
|
||||
WRITE4FORMAT(ptr)->cmd = CONT_CMD_WRITE4_VOICE;
|
||||
WRITE4FORMAT(ptr)->datacrc = 0xFF;
|
||||
|
||||
ptr[sizeof(__OSVoiceWrite4Format)] = CONT_CMD_END;
|
||||
} else {
|
||||
ptr = (u8*)&__osPfsPifRam + channel;
|
||||
}
|
||||
|
||||
WRITE4FORMAT(ptr)->addrh = address >> 3;
|
||||
WRITE4FORMAT(ptr)->addrl = __osContAddressCrc(address) | (address << 5);
|
||||
|
||||
bcopy(dst, &WRITE4FORMAT(ptr)->data, 4);
|
||||
|
||||
__osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
crc = __osVoiceContDataCrc(dst, 4);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
__osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = (WRITE4FORMAT(ptr)->rxsize & 0xC0) >> 4;
|
||||
|
||||
if (ret == 0) {
|
||||
if (crc != WRITE4FORMAT(ptr)->datacrc) {
|
||||
ret = __osVoiceGetStatus(mq, channel, &status);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
ret = CONT_ERR_CONTRFAIL;
|
||||
}
|
||||
} else {
|
||||
ret = CONT_ERR_NO_CONTROLLER;
|
||||
}
|
||||
|
||||
} while ((ret == CONT_ERR_CONTRFAIL) && (retry-- >= 0));
|
||||
|
||||
__osSiRelAccess();
|
||||
|
||||
return ret;
|
||||
}
|
||||
59
src/voice/voicecountsyllables.c
Normal file
59
src/voice/voicecountsyllables.c
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
|
||||
// The VRU can store only 880 semisyllables of words in its dictionary.
|
||||
// Use this function to determine the semisyllable count before adding a word with osVoiceSetWord,
|
||||
// to properly see whether it will fit.
|
||||
|
||||
void osVoiceCountSyllables(u8 *data, u32 *syllable) {
|
||||
s32 k;
|
||||
u16 sjis;
|
||||
u16 old;
|
||||
|
||||
old = 0;
|
||||
*syllable = 1;
|
||||
for (k = 0; data[k] != 0; k += 2) {
|
||||
sjis = data[k + 1] + (data[k] << 8);
|
||||
if ((sjis == 'あ') || (sjis == 'い') || (sjis == 'う') || (sjis == 'え') || (sjis == 'お')
|
||||
|| (sjis == 'ア') || (sjis == 'イ') || (sjis == 'ウ') || (sjis == 'エ') || (sjis == 'オ')
|
||||
) {
|
||||
if (k == 0) {
|
||||
*syllable += 2;
|
||||
} else {
|
||||
*syllable += 1;
|
||||
}
|
||||
} else if ((sjis == 'か') || (sjis == 'き') || (sjis == 'く') || (sjis == 'け') || (sjis == 'こ')
|
||||
|| (sjis == 'た') || (sjis == 'ち') || (sjis == 'つ') || (sjis == 'て') || (sjis == 'と')
|
||||
|| (sjis == 'ぱ') || (sjis == 'ぴ') || (sjis == 'ぷ') || (sjis == 'ぺ') || (sjis == 'ぽ')
|
||||
|| (sjis == 'カ') || (sjis == 'キ') || (sjis == 'ク') || (sjis == 'ケ') || (sjis == 'コ')
|
||||
|| (sjis == 'タ') || (sjis == 'チ') || (sjis == 'ツ') || (sjis == 'テ') || (sjis == 'ト')
|
||||
|| (sjis == 'パ') || (sjis == 'ピ') || (sjis == 'プ') || (sjis == 'ペ') || (sjis == 'ポ')
|
||||
) {
|
||||
if (k == 0) {
|
||||
*syllable += 2;
|
||||
} else if ((old == 'っ') || (old == 'ッ')) {
|
||||
*syllable += 2;
|
||||
} else {
|
||||
*syllable += 3;
|
||||
}
|
||||
} else if ((sjis == 'ぁ') || (sjis == 'ぃ') || (sjis == 'ぅ') || (sjis == 'ぇ') || (sjis == 'ぉ')
|
||||
|| (sjis == 'ゃ') || (sjis == 'ゅ') || (sjis == 'ょ') || (sjis == 'ゎ')
|
||||
|
||||
|| (sjis == 'ァ') || (sjis == 'ィ') || (sjis == 'ゥ') || (sjis == 'ェ') || (sjis == 'ォ')
|
||||
|| (sjis == 'ャ') || (sjis == 'ュ') || (sjis == 'ョ') || (sjis == 'ヮ')
|
||||
|| (sjis == 'ヵ') || (sjis == 'ヶ')
|
||||
) {
|
||||
if ((old == 'あ') || (old == 'い') || (old == 'う') || (old == 'え') || (old == 'お')
|
||||
|| (old == 'ア') || (old == 'イ') || (old == 'ウ') || (old == 'エ') || (old == 'オ')
|
||||
) {
|
||||
*syllable += 1;
|
||||
}
|
||||
} else if ((sjis == 'ん') || (sjis == 'ー') || (sjis == 'っ') || (sjis == 'ン') || (sjis == 'ッ')) {
|
||||
*syllable += 1;
|
||||
} else {
|
||||
*syllable += 2;
|
||||
}
|
||||
old = sjis;
|
||||
}
|
||||
}
|
||||
40
src/voice/voicecrc.c
Normal file
40
src/voice/voicecrc.c
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
|
||||
#define VOICE_CRC_LENGTH 8
|
||||
#define VOICE_CRC_GENERATOR 0x85
|
||||
|
||||
u8 __osVoiceContDataCrc(u8* data, u32 length) {
|
||||
s32 ret = 0;
|
||||
u32 i;
|
||||
u32 j;
|
||||
|
||||
for (j = length; j != 0; j--, data++) {
|
||||
// Loop over each i in the j starting with most significant
|
||||
for (i = (1 << (VOICE_CRC_LENGTH - 1)); i != 0; i >>= 1) {
|
||||
ret <<= 1;
|
||||
if (*data & i) {
|
||||
if (ret & (1 << VOICE_CRC_LENGTH)) {
|
||||
// Same as ret++; ret ^= 0x85 since last i always 0 after the shift
|
||||
ret ^= VOICE_CRC_GENERATOR - 1;
|
||||
} else {
|
||||
ret++;
|
||||
}
|
||||
} else if (ret & (1 << VOICE_CRC_LENGTH)) {
|
||||
ret ^= VOICE_CRC_GENERATOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Act like a j of zeros is appended to data
|
||||
do {
|
||||
ret <<= 1;
|
||||
if (ret & (1 << VOICE_CRC_LENGTH)) {
|
||||
ret ^= VOICE_CRC_GENERATOR;
|
||||
}
|
||||
j++;
|
||||
} while (j < VOICE_CRC_LENGTH);
|
||||
|
||||
// Discarding the excess is done automatically by the return type
|
||||
return ret;
|
||||
}
|
||||
94
src/voice/voicegetreaddata.c
Normal file
94
src/voice/voicegetreaddata.c
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
#include "voiceinternal.h"
|
||||
|
||||
s32 osVoiceGetReadData(OSVoiceHandle* hd, OSVoiceData* micdata) {
|
||||
s32 ret = 0;
|
||||
s32 i;
|
||||
u8 stat;
|
||||
u8 temp[36];
|
||||
static u8 c;
|
||||
|
||||
switch (hd->__mode) {
|
||||
case 1:
|
||||
ret = __osVoiceGetStatus(hd->__mq, hd->__channel, &stat);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
} else if (stat & 1) {
|
||||
return CONT_ERR_NOT_READY;
|
||||
}
|
||||
|
||||
ERRCK(__osVoiceContRead2(hd->__mq, hd->__channel, 0, temp));
|
||||
|
||||
c = temp[0] & 7;
|
||||
hd->cmd_status = c;
|
||||
if ((c != 0) && (c != 7)) {
|
||||
return CONT_ERR_NOT_READY;
|
||||
}
|
||||
case 2:
|
||||
hd->__mode = 2;
|
||||
|
||||
ERRCK(__osVoiceGetStatus(hd->__mq, hd->__channel, &stat))
|
||||
|
||||
if (stat & 2) {
|
||||
return CONT_ERR_VOICE_NO_RESPONSE;
|
||||
}
|
||||
|
||||
*(u32*)temp = 0x600;
|
||||
ERRCK(__osVoiceContWrite4(hd->__mq, hd->__channel, 0, temp));
|
||||
|
||||
case 3:
|
||||
hd->__mode = 3;
|
||||
|
||||
ret = __osVoiceGetStatus(hd->__mq, hd->__channel, &stat);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
} else if (stat & 1) {
|
||||
return CONT_ERR_VOICE_NO_RESPONSE;
|
||||
}
|
||||
|
||||
ERRCK(__osVoiceContRead36(hd->__mq, hd->__channel, 0, temp));
|
||||
|
||||
micdata->warning = temp[4] + (temp[5] << 8);
|
||||
micdata->answer_num = temp[6];
|
||||
micdata->voice_level = temp[8] + (temp[9] << 8);
|
||||
micdata->voice_sn = temp[10] + (temp[11] << 8);
|
||||
micdata->voice_time = temp[12] + (temp[13] << 8);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
micdata->answer[i] = temp[14 + (i << 2)] + (temp[15 + (i << 2)] << 8);
|
||||
micdata->distance[i] = temp[16 + (i << 2)] + (temp[17 + (i << 2)] << 8);
|
||||
}
|
||||
|
||||
if (micdata->answer[0] == 0x7FFF) {
|
||||
micdata->answer_num = 0;
|
||||
}
|
||||
|
||||
hd->cmd_status = temp[34] & 7;
|
||||
if ((c == 0) || (hd->cmd_status == 0)) {
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
hd->__mode = 4;
|
||||
|
||||
ERRCK(__osVoiceGetStatus(hd->__mq, hd->__channel, &stat));
|
||||
|
||||
if (stat & 1) {
|
||||
return CONT_ERR_VOICE_NO_RESPONSE;
|
||||
}
|
||||
|
||||
ERRCK(__osVoiceContRead2(hd->__mq, hd->__channel, 0, temp));
|
||||
|
||||
hd->cmd_status = temp[0] & 7;
|
||||
if (temp[0] & 7) {
|
||||
return CONT_ERR_VOICE_NO_RESPONSE;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
return CONT_ERR_INVALID;
|
||||
}
|
||||
hd->__mode = 0;
|
||||
return ret;
|
||||
}
|
||||
61
src/voice/voicegetstatus.c
Normal file
61
src/voice/voicegetstatus.c
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
#include "voiceinternal.h"
|
||||
|
||||
s32 __osVoiceGetStatus(OSMesgQueue* mq, s32 port, u8* status) {
|
||||
__OSContRequesFormatShort header;
|
||||
s32 ret = 0;
|
||||
s32 i;
|
||||
u8* ptr = (u8*)&__osContPifRam.ramarray;
|
||||
s32 retry = 2;
|
||||
|
||||
__osSiGetAccess();
|
||||
|
||||
do {
|
||||
if (ret != CONT_ERR_CONTRFAIL) {
|
||||
__osContPifRam.pifstatus = CONT_CMD_EXE;
|
||||
|
||||
for (i = 0; i < port; i++, *ptr++ = 0) {
|
||||
;
|
||||
}
|
||||
|
||||
*ptr++ = CONT_CMD_REQUEST_STATUS_TX;
|
||||
*ptr++ = CONT_CMD_REQUEST_STATUS_RX;
|
||||
*ptr = CONT_CMD_REQUEST_STATUS;
|
||||
ptr += 4;
|
||||
*ptr = CONT_CMD_END;
|
||||
|
||||
__osContLastCmd = CONT_CMD_END;
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osContPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
ret = __osSiRawStartDma(OS_READ, &__osContPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ptr = (u8*)&__osContPifRam.ramarray + port;
|
||||
|
||||
header = *((__OSContRequesFormatShort*)ptr);
|
||||
|
||||
ret = CHNL_ERR(header);
|
||||
*status = header.status;
|
||||
|
||||
if (ret == 0) {
|
||||
if (header.typeh == 0 && header.typel == 1) {
|
||||
if (header.status & 4) {
|
||||
ret = CONT_ERR_CONTRFAIL;
|
||||
}
|
||||
} else {
|
||||
ret = CONT_ERR_DEVICE;
|
||||
}
|
||||
} else if (ret & CONT_NO_RESPONSE_ERROR) {
|
||||
ret = CONT_ERR_NO_CONTROLLER;
|
||||
} else {
|
||||
ret = CONT_ERR_CONTRFAIL;
|
||||
}
|
||||
} while ((ret == CONT_ERR_CONTRFAIL) && (retry-- >= 0));
|
||||
|
||||
__osSiRelAccess();
|
||||
|
||||
return ret;
|
||||
}
|
||||
40
src/voice/voiceinit.c
Normal file
40
src/voice/voiceinit.c
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
|
||||
s32 osVoiceInit(OSMesgQueue* mq, OSVoiceHandle* handle, int channel) {
|
||||
s32 ret;
|
||||
s32 i;
|
||||
u8 stat = 0;
|
||||
u8 buf[4];
|
||||
static u8 cmd[] = {0x1E, 0x6E, 0x08, 0x56, 0x03};
|
||||
|
||||
handle->__channel = channel;
|
||||
handle->__mq = mq;
|
||||
handle->__mode = 0;
|
||||
|
||||
ERRCK(__osVoiceGetStatus(mq, channel, &stat));
|
||||
|
||||
if (__osContChannelReset(mq, channel) != 0) {
|
||||
return CONT_ERR_CONTRFAIL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRLEN(cmd); i++) {
|
||||
ERRCK(__osVoiceSetADConverter(mq, channel, cmd[i]));
|
||||
}
|
||||
|
||||
ERRCK(__osVoiceGetStatus(mq, channel, &stat));
|
||||
if (stat & 2) {
|
||||
return CONT_ERR_VOICE_NO_RESPONSE;
|
||||
}
|
||||
|
||||
*(u32*)buf = 0x100;
|
||||
ERRCK(__osVoiceContWrite4(mq, channel, 0, buf));
|
||||
|
||||
ret = __osVoiceCheckResult(handle, &stat);
|
||||
if (ret & 0xFF00) {
|
||||
ret = CONT_ERR_INVALID;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
10
src/voice/voiceinternal.h
Normal file
10
src/voice/voiceinternal.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef VOICE_INTERNAL_H
|
||||
#define VOICE_INTERNAL_H
|
||||
|
||||
// Various prototypes and externs that don't show up in os_voice.h
|
||||
extern s32 __osPfsLastChannel;
|
||||
|
||||
u8 __osVoiceContDataCrc(u8* data, u32 length);
|
||||
s32 __osVoiceCheckResult(OSVoiceHandle* hd, u8* stat);
|
||||
|
||||
#endif
|
||||
47
src/voice/voicemaskdictionary.c
Normal file
47
src/voice/voicemaskdictionary.c
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
#include "voiceinternal.h"
|
||||
|
||||
s32 osVoiceMaskDictionary(OSVoiceHandle* hd, u8* pattern, int size) {
|
||||
s32 ret;
|
||||
s32 i;
|
||||
s32 j;
|
||||
u8 stat;
|
||||
u8 buf[20];
|
||||
|
||||
ERRCK(__osVoiceGetStatus(hd->__mq, hd->__channel, &stat));
|
||||
|
||||
if (stat & 2) {
|
||||
return CONT_ERR_VOICE_NO_RESPONSE;
|
||||
}
|
||||
|
||||
if (size & 1) {
|
||||
j = size + 1;
|
||||
} else {
|
||||
j = size;
|
||||
}
|
||||
|
||||
bzero(&buf, ARRLEN(buf));
|
||||
|
||||
buf[18 - j] = 4;
|
||||
|
||||
for (i = 0; i < j; i += 2) {
|
||||
buf[i + ARRLEN(buf) - j] = pattern[i];
|
||||
buf[i + ARRLEN(buf) - j + 1] = pattern[i + 1];
|
||||
}
|
||||
|
||||
if (size & 1) {
|
||||
buf[ARRLEN(buf) - 1] = 0;
|
||||
}
|
||||
|
||||
ret = __osVoiceContWrite20(hd->__mq, hd->__channel, 0, &buf);
|
||||
if (ret == 0) {
|
||||
ret = __osVoiceCheckResult(hd, &stat);
|
||||
if (ret & 0xFF00) {
|
||||
ret = CONT_ERR_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
70
src/voice/voicesetadconverter.c
Normal file
70
src/voice/voicesetadconverter.c
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
#include "voiceinternal.h"
|
||||
#include "io/controller_voice.h"
|
||||
|
||||
#define SWRITEFORMAT(p) ((__OSVoiceSWriteFormat*)(p))
|
||||
|
||||
s32 __osVoiceSetADConverter(OSMesgQueue* mq, s32 channel, u8 data) {
|
||||
s32 ret;
|
||||
int i;
|
||||
u8* ptr;
|
||||
u8 status;
|
||||
int retry = 2;
|
||||
|
||||
__osSiGetAccess();
|
||||
|
||||
do {
|
||||
|
||||
ptr = (u8*)__osPfsPifRam.ramarray;
|
||||
|
||||
if ((__osContLastCmd != CONT_CMD_SWRITE_VOICE) || (__osPfsLastChannel != channel)) {
|
||||
__osContLastCmd = CONT_CMD_SWRITE_VOICE;
|
||||
__osPfsLastChannel = channel;
|
||||
|
||||
for (i = 0; i < channel; i++) {
|
||||
*ptr++ = 0;
|
||||
}
|
||||
|
||||
__osPfsPifRam.pifstatus = CONT_CMD_EXE;
|
||||
|
||||
SWRITEFORMAT(ptr)->txsize = CONT_CMD_SWRITE_VOICE_TX;
|
||||
SWRITEFORMAT(ptr)->rxsize = CONT_CMD_SWRITE_VOICE_RX;
|
||||
SWRITEFORMAT(ptr)->cmd = CONT_CMD_SWRITE_VOICE;
|
||||
SWRITEFORMAT(ptr)->datacrc = 0;
|
||||
|
||||
ptr[sizeof(__OSVoiceSWriteFormat)] = CONT_CMD_END;
|
||||
} else {
|
||||
ptr = (u8*)&__osPfsPifRam + channel;
|
||||
}
|
||||
|
||||
SWRITEFORMAT(ptr)->data = data;
|
||||
SWRITEFORMAT(ptr)->scrc = __osContAddressCrc(data * 8);
|
||||
|
||||
__osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
__osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = CHNL_ERR(*SWRITEFORMAT(ptr));
|
||||
|
||||
if (ret == 0) {
|
||||
if (SWRITEFORMAT(ptr)->datacrc & 1) {
|
||||
ret = __osVoiceGetStatus(mq, channel, &status);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
ret = CONT_ERR_CONTRFAIL;
|
||||
}
|
||||
} else {
|
||||
ret = CONT_ERR_NO_CONTROLLER;
|
||||
}
|
||||
|
||||
} while ((ret == CONT_ERR_CONTRFAIL) && (retry-- >= 0));
|
||||
|
||||
__osSiRelAccess();
|
||||
|
||||
return ret;
|
||||
}
|
||||
44
src/voice/voicesetword.c
Normal file
44
src/voice/voicesetword.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "PR/os_internal.h"
|
||||
#include "io/controller.h"
|
||||
#include "PR/os_voice.h"
|
||||
|
||||
s32 osVoiceSetWord(OSVoiceHandle *hd, u8 *word) {
|
||||
s32 j;
|
||||
s32 k;
|
||||
s32 ret;
|
||||
u8 stat;
|
||||
u8 buf[40];
|
||||
|
||||
ERRCK(__osVoiceGetStatus(hd->__mq, hd->__channel, &stat));
|
||||
if (stat & 2) {
|
||||
return CONT_ERR_VOICE_NO_RESPONSE;
|
||||
}
|
||||
for (k = 0; word[k] != 0; k += 2) {
|
||||
;
|
||||
}
|
||||
|
||||
bzero(buf, ARRLEN(buf));
|
||||
|
||||
for (j = 0; j < k; j += 2) {
|
||||
buf[ARRLEN(buf) - 1 - k + j] = word[j];
|
||||
buf[ARRLEN(buf) - 1 - k + j - 1] = word[j + 1];
|
||||
}
|
||||
|
||||
buf[ARRLEN(buf) - 1 - j - 5] = 3;
|
||||
|
||||
if (k >= 15) {
|
||||
ERRCK(__osVoiceContWrite20(hd->__mq, hd->__channel, 0, buf));
|
||||
}
|
||||
ERRCK(__osVoiceContWrite20(hd->__mq, hd->__channel, 0, buf + 20));
|
||||
ret = __osVoiceCheckResult(hd, &stat);
|
||||
if (ret != 0) {
|
||||
if (ret & 0x100) {
|
||||
ret = CONT_ERR_VOICE_MEMORY;
|
||||
} else if (ret & 0x200) {
|
||||
ret = CONT_ERR_VOICE_WORD;
|
||||
} else if (ret & 0xFF00) {
|
||||
ret = CONT_ERR_INVALID;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user