📄 slutil.c
字号:
/*
* slutil.c : speak and listen data translate function.
*
* Ver 0.10 1998/12/17 H.Matsuoka start
* Ver 0.20 1999/ 1/ 7 H.Matsuoka Add shift_offset[] function
* Ver 0.21 1999/ 1/11 H.Matsuoka Add setSpeakVolume
* Ver 0.22 1999/ 2/19 H.Matsuoka Modify slLis2Pcm assembler
* Ver 0.30 1999/ 8/24 H.Matsuoka PCM15
* Ver 0.31 1999/11/17 H.Matsuoka for PCM15 mono
* Ver 0.40 2000/ 2/14 H.Matsuoka for PCM15 stereo
* Ver 0.40 2000/ 2/23 M.Igarashi bug fix for stereo
* Ver 0.41 2003/12/03 CH.Yoon port to gnu33
*
*/
#include "slutil.h"
short SPK_VOLUME0;
short SPK_PREDATA;
short SPK_PREDATA2;
/*
* set speak volume
*/
void setSpeakVolume(short spkv)
{
SPK_VOLUME0 = spkv;
}
#ifdef PWM_ADJUST
// PWM adjust for 3.9Kohm with 18bit precision
static const unsigned char ucAdj18 [] = {
0x4, // 0
0x8, // 1
0xc, // 2
0x10, // 3
0x14, // 4
0x17, // 5
0x1b, // 6
0x1f, // 7
0x22, // 8
0x26, // 9
0x29, // a
0x2d, // b
0x30, // c
0x33, // d
0x36, // e
0x39, // f
0x3c, // 10
0x3f, // 11
0x42, // 12
0x45, // 13
0x48, // 14
0x4b, // 15
0x4d, // 16
0x50, // 17
0x52, // 18
0x55, // 19
0x57, // 1a
0x5a, // 1b
0x5c, // 1c
0x5e, // 1d
0x60, // 1e
0x62, // 1f
0x64, // 20
0x66, // 21
0x68, // 22
0x6a, // 23
0x6c, // 24
0x6d, // 25
0x6f, // 26
0x71, // 27
0x72, // 28
0x74, // 29
0x75, // 2a
0x76, // 2b
0x77, // 2c
0x79, // 2d
0x7a, // 2e
0x7b, // 2f
0x7c, // 30
0x7d, // 31
0x7e, // 32
0x7e, // 33
0x7f, // 34
0x80, // 35
0x80, // 36
0x81, // 37
0x81, // 38
0x82, // 39
0x82, // 3a
0x83, // 3b
0x83, // 3c
0x83, // 3d
0x83, // 3e
0x83, // 3f
0x83, // 40
0x83, // 41
0x83, // 42
0x83, // 43
0x82, // 44
0x82, // 45
0x82, // 46
0x81, // 47
0x80, // 48
0x80, // 49
0x7f, // 4a
0x7e, // 4b
0x7e, // 4c
0x7d, // 4d
0x7c, // 4e
0x7b, // 4f
0x7a, // 50
0x79, // 51
0x78, // 52
0x76, // 53
0x75, // 54
0x74, // 55
0x72, // 56
0x71, // 57
0x6f, // 58
0x6d, // 59
0x6c, // 5a
0x6a, // 5b
0x68, // 5c
0x66, // 5d
0x64, // 5e
0x62, // 5f
0x60, // 60
0x5e, // 61
0x5c, // 62
0x5a, // 63
0x57, // 64
0x55, // 65
0x52, // 66
0x50, // 67
0x4d, // 68
0x4b, // 69
0x48, // 6a
0x45, // 6b
0x42, // 6c
0x3f, // 6d
0x3c, // 6e
0x39, // 6f
0x36, // 70
0x33, // 71
0x30, // 72
0x2d, // 73
0x29, // 74
0x26, // 75
0x22, // 76
0x1f, // 77
0x1b, // 78
0x17, // 79
0x14, // 7a
0x10, // 7b
0xc, // 7c
0x8, // 7d
0x4, // 7e
0x0, // 7f
};
#endif
/*
* slPcm2Spk()
* short* Src source data (mono PCM 16bit)
* short* Dst destination data
* int Length source data length(sample count)
* Slparam* slParam offset, clipping data
*/
void slPcm2Spk(short* Src, short* Dst, int Length, Slparam* slParam)
{
#ifdef PWM_ADJUST
asm(" pushn %r1");
#endif
asm(" ld.uh %r11,[%r9]+"); // offset = slParam->offset
asm(" add %r9,2"); // skip slParam->shift
asm(" ld.uh %r10,[%r9]"); // limit = slParam->limit
asm(" xld.uh %r13,[SPK_VOLUME0]");
asm(" xld.uh %r4,[SPK_PREDATA]");
#ifdef PWM_ADJUST
asm(" ext ucAdj18@h"); // %r0 = adjust table address
asm(" ext ucAdj18@m");
asm(" ld.w %r0,ucAdj18@l");
#endif
asm("SluChangeLoop:");
asm(" ld.h %r5,[%r6]+"); // Data = *Src++;
asm(" mlt.w %r5,%r13"); // Data *= volume;
asm(" ld.w %r5,%alr");
asm(" sra %r5,8"); // Data >>= 8;
asm(" add %r5,%r11"); // Data += offset;
#ifdef PWM_ADJUST
asm(" ld.w %r1,%r5"); // pwmadj = ucAdj18[(Data+0x20)>>8];
asm(" add %r1,0x20");
asm(" srl %r1,8");
asm(" add %r1,%r0");
asm(" ld.ub %r1,[%r1]");
asm(" mlt.w %r1,%r13"); // pwmadj = (pwmadj * volume)>>11;
asm(" ld.w %r1,%alr");
asm(" xsra %r1,10"); // 17/Nov/99 15bit to 16bit
asm(" add %r5,%r1"); // Data += pwmadj;
#endif
asm(" xjrge SpkL1"); // if(Data < 0)
asm(" ld.w %r5,0x0"); // Data = 0;
asm("SpkL1: ");
asm(" cmp %r5,%r10"); // if(Data > limit)
asm(" xjrle SpkL2");
asm(" ld.w %r5,%r10"); // Data = limit;
asm("SpkL2: ");
asm(" add %r4,%r5"); // pre data + current data;
asm(" srl %r4,1"); // /2
asm(" ld.h [%r7]+,%r4");
asm(" ld.h [%r7]+,%r5");
asm(" sub %r8,0x01");
asm(" jrgt SluChangeLoop");
asm(" xld.h [SPK_PREDATA],%r5"); // save current data for predata
#ifdef PWM_ADJUST
asm(" popn %r1");
#endif
}
/*
* slPcm2SpkLR()
* short* Src source data (stereo PCM 16bit)
* short* Dst destination data
* int Length source data length(sample count)
* Slparam* slParam offset, clipping data
*/
void slPcm2SpkLR(short* Src, short* Dst, int Length, Slparam* slParam)
{
#ifdef PWM_ADJUST
asm(" pushn %r1");
#endif
asm(" ld.uh %r11,[%r9]+"); // offset = slParam->offset
asm(" add %r9,0x02");
asm(" ld.uh %r10,[%r9]"); // limit = slParam->limit bug
asm(" xld.uh %r13,[SPK_VOLUME0]");
asm(" xld.uh %r4,[SPK_PREDATA]");
asm(" xld.uh %r12,[SPK_PREDATA2]");
#ifdef PWM_ADJUST
asm(" ext ucAdj18@h"); // %r0 = adjust table address
asm(" ext ucAdj18@m");
asm(" ld.w %r0,ucAdj18@l");
#endif
asm("SluChangeLoop2:");
// L data calc
asm(" ld.h %r9,[%r6]+"); // Data = *Src++;
asm(" mlt.w %r9,%r13"); // Data *= volume;
asm(" ld.w %r9,%alr");
asm(" sra %r9,8"); // Data >>= 8 ;
asm(" add %r9,%r11"); // Data += offset;
#ifdef PWM_ADJUST
asm(" ld.w %r1,%r9"); // pwmadj = ucAdj18[(Data+0x20)>>8];
asm(" add %r1,0x20");
asm(" srl %r1,8");
asm(" add %r1,%r0");
asm(" ld.ub %r1,[%r1]");
asm(" mlt.w %r1,%r13"); // pwmadj = (pwmadj * volume)>>10;
asm(" ld.w %r1,%alr");
asm(" sra %r1,10");
asm(" add %r9,%r1"); // Data += pwmadj;
#endif
asm(" xjrge SpkLL1"); // if(Data < 0)
asm(" ld.w %r9,0x0"); // Data = 0;
asm("SpkLL1: ");
asm(" cmp %r9,%r10"); // if(Data > limit)
asm(" xjrle SpkLL2");
asm(" ld.w %r9,%r10"); // Data = limit;
asm("SpkLL2: ");
asm(" add %r4,%r9"); // pre data + current data;
asm(" srl %r4,1"); // /2
asm(" ld.h [%r7]+,%r4");
// R data calc
asm(" ld.h %r5,[%r6]+"); // Data = *Src++;
asm(" mlt.w %r5,%r13"); // Data *= volume;
asm(" ld.w %r5,%alr");
asm(" sra %r5,8"); // Data >>= 8;
asm(" add %r5,%r11"); // Data += offset;
#ifdef PWM_ADJUST
asm(" add %r5,%r1"); // Data += pwmadj;
#endif
asm(" xjrge SpkRL1"); // if(Data < 0)
asm(" ld.w %r5,0x0"); // Data = 0;
asm("SpkRL1: ");
asm(" cmp %r5,%r10"); // if(Data > limit)
asm(" xjrle SpkRL2");
asm(" ld.w %r5,%r10"); // Data = limit;
asm("SpkRL2: ");
asm(" add %r12,%r5"); // pre data + current data;
asm(" srl %r12,1"); // /2
asm(" ld.h [%r7]+,%r12");
asm(" ld.h [%r7]+,%r9");
asm(" ld.h [%r7]+,%r5");
asm(" sub %r8,0x01");
asm(" jrgt SluChangeLoop2");
asm(" xld.h [SPK_PREDATA],%r9"); // save current data for predata bug fix M.Igarashi
asm(" xld.h [SPK_PREDATA2],%r5"); // save current data for predata bug fix M.Igarashi
#ifdef PWM_ADJUST
asm(" popn %r1");
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -