⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slutil.c

📁 The combined demo is dedicated for S1C33L05, so DMT33L05 should be used to load and run the demo. F
💻 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 + -