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

📄 g711m.h

📁 arm ads1.2 with crack.rar
💻 H
字号:
;/*
; * G.711 assembler macros
; * Copyright (C) ARM Limited 1998-1999. All rights reserved.
; */

;===========================================================================
;
; CCITT A-law (and u-law) to linear (and back) converter macros.
;
; Optimised ARM macros used for ADPCM as defined by G.721, G723, G726.
;
; These macros are based on the C language implementation of G723 from
; Sun Microsystems.
;
; First release	: 22/02/1996
;
; Added support of A-law <-> u-law conversion
; Date   		: 31/03/1998
;
;===========================================================================

	INCLUDE regchekm.h

	IMPORT	G711_a2u_lookup
	IMPORT	G711_u2a_lookup

;====G711_alaw2linear===================================================
;
; Purpose : Converts an 8-bit A-law value (inverted, unsigned char) to a signed
;           16-bit PCM value
;
; Parameters: $in  = register holding A-law value (unsigned char)
;             $out = register used to hold output PCM conversion (int)
;                    (this may be the same as $in).
;             $t1  = temporary register.
;             $t2  = temporary register.
;
; Performance:
;             ARM7M = 12 cycles worst case (11S 0N 1I).
; Code Size:
;             11 Instructions (44 bytes).
;
;-----------------------------------------------------------------------
;

  MACRO
$label  G711_alaw2linear_macro $in, $out, $t1, $t2

  DISTINCT $in, $t1, $t2
  DISTINCT $out, $t1, $t2

$label
  EOR      $t2,  $in, #0x55    ; Decode transmitted byte.
  AND      $out, $t2, #0x0F    ; Strip out lower data (t).
  MOV      $out, $out, LSL #4
  MOV      $t1,  $t2, LSR #4   ; Strip out segment number,
  AND      $t1,  $t1, #7       ; and remove sign bit

  SUBS     $t1,  $t1, #1       ; Calculate (seg-1).
  ADDLT    $out, $out, #0x0008 ; If seg=0 then t+=0x008
  ADDGE    $out, $out, #0x0108 ; If seg>0 then t+=0x108
  MOVGT    $out, $out, LSL $t1 ; If seg>1 then t=t << (seg-1)

  TST      $t2,  #0x80         ; Was the sign bit set ?
  RSBEQ    $out, $out, #0      ; If not then t=-t

  MEND


;====G711_linear2alaw===================================================
;
; Purpose : Converts a signed 16-bit linear PCM value to an 8-bit A-law value.
;
; Parameters: $in  = register holding input linear PCM value.
;             $out = register used to hold output 8-bit A-law conversion.
;                    (this may be the same as $in, OR the same as $msk,
;                     but must not be the same as $t1,$t2).
;             $t1  = temporary register.
;             $t2  = temporary register.
;             $msk = temporary register (may be the same as $out).
;
; Performance:
;             ARM7M = 27 cycles worst case (26S 0N 1I).
; Code Size:
;             26 Instructions (104 bytes).
;
;-----------------------------------------------------------------------
;

   MACRO
$label  G711_linear2alaw_macro $in, $out, $t1, $t2, $msk

   DISTINCT $in, $t1, $t2, $msk
   DISTINCT $out, $t1, $t2

$label
  RSBS     $t1,  $in, #0     ; if (pcm_val >=0)
  MOVLE    $msk, #0xD5       ;      mask = 0xD5 : sign (7th bit) = 1
  MOVGT    $msk, #0x55       ; else mask = 0x55 : sign (7th bit) = 0
  SUBGT    $in,  $t1, #8     ;      pcm_val = -pcm_val - 8

; Convert the input signal into logarithmic form (segment number).
  MOV      $t1,  #0
  MOVS     $t2,  $in, LSR #4 ; Store (pcm_val >> 4) for later.
  BLE      %FT00

  CMP      $in,  #0x00001000
  MOVGE    $in,  $in, LSR #4
  ADDGE    $t1,  $t1, #4

  CMP      $in,  #0x00000400
  MOVGE    $in,  $in, LSR #2
  ADDGE    $t1,  $t1, #2

  CMP      $in,  #0x00000100
  MOVGE    $in,  $in, LSR #1
  ADDGE    $t1,  $t1, #1

  CMP      $in,  #0x00000100
  ADDGE    $t1,  $t1, #1

00 ; Skip

; Time to combine the sign, segment, and quantisation bits.
  CMP      $t1,  #8           ; if (seg>=8)
  MOVGE    $in,  #0x7F        ;   return (0x7F ^ mask)
                                    ; else
  MOVLT    $in,  $t1, LSL #4  ;   aval = seg << SEG_SHIFT
  SUBS     $t1,  $t1, #1      ;   if (seg>=2)
  MOVGT    $t2,  $t2, LSR $t1 ;      pcm_val = pcm_val >> (seg-1)

  AND      $t2,  $t2, #0x0F   ; pcm_val = pcm_val & QUANT_MASK
  ORR      $in,  $in, $t2     ; aval |= pcm_val

  EOR      $out, $in, $msk     ; return aval ^ mask

  MEND

;====G711_linear2ulaw===================================================
;
; Purpose : Converts a signed 16-bit linear PCM value to an 8-bit u-law value.
;
; Parameters: $in  = register holding input linear PCM value.
;             $out = register used to hold output 8-bit u-law conversion.
;                    (this may be the same as $in, OR the same as $msk,
;                     but must not be the same as $t1,$t2).
;             $msk = temporary register (may be the same as $out).
;             $t1  = temporary register.
;             $t2  = temporary register.
;
; Performance:
;             ARM7M = 26 cycles worst case (25S 0N 1I).
; Code Size:
;             25 instructions (100 bytes).
;
;-----------------------------------------------------------------------
;
; $in - linear input sample (2's complement, 16-bit range).

  MACRO
$label  G711_linear2ulaw_macro $in, $out, $msk, $t1, $t2

  DISTINCT $in, $t1, $t2, $msk
  DISTINCT $out, $t1, $t2

 ; Get the sign and the magnitude of the input value.
  CMP     $in, #0               ; if (pcm_val < 0) {
  RSBLT   $in, $in, #0x84       ;     pcm_val = BIAS - pcm_val;
  MOVLT   $msk, #0x7F            ;     mask = 0x7F;
                                      ;	} else {
  ADDGE   $in, $in, #0x84       ;     pcm_val += BIAS;
  MOVGE   $msk, #0xFF           ;     mask = 0xFF; }


 ; Convert the input signal into logarithmic form (segment number).
  MOV      $t1, #0
  MOVS     $t2, $in, LSR #3     ; Store (pcm_val >> 3) for later.
  BLE      %FT00

  CMP      $in, #0x00001000
  MOVGE    $in, $in, LSR #4
  ADDGE    $t1, $t1, #4

  CMP      $in, #0x00000400
  MOVGE    $in, $in, LSR #2
  ADDGE    $t1, $t1, #2

  CMP      $in, #0x00000100
  MOVGE    $in, $in, LSR #1
  ADDGE    $t1, $t1, #1

  CMP      $in, #0x00000100
  ADDGE    $t1, $t1, #1

00

 ; Interleave the sign, segment, and quantization bits
 ; and complement the output word.
  CMP      $t1, #8              ; If out of range then return maximum value.
  MOVGE    $in, #0x7F           ;      output = 0x7F

  MOVLT    $in, $t2, ASR $t1    ; else output = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
  ANDLT    $in, $in, #0x0F
  ORRLT    $in, $in, $t1, LSL #4

  EOR      $out, $in, $msk   ; return (output ^ mask);

  MEND

;-----------------------------------------------------------------------
;
; G711_ulaw2linear() - Converts an 8-bit u-law value to a 16-bit linear PCM.
;
; Based on the G711 C code from Sun Microsystems - refer to this for functionality.
;
; First, a biased linear code is derived from the code word. An unbiased
; output can then be obtained by subtracting 33 from the biased code.
;
; Note 1: this function expects to be passed the complement of the
;         original code word. This is in keeping with ISDN conventions.
;
; Note 2: this function could be implemented more quickly with a
;         lookup table, but this would add approx 512 bytes of extra
;         storage space for the table.
;
; Parameters:
;    $in  - register containing the input 8-bit u-law value.
;    $out - register to return the 16-bit linear value in (may be the same as $in).
;    $seg - temporary register (used for the segment number).
;
; Performance:
;              ARM7M = 9 cycles all cases (8S 0N 1I)
; Code Size:
;              8 Instructions (24 bytes).
;

 MACRO
 G711_ulaw2linear_macro $in, $out, $seg

 DISTINCT $in, $seg
 DISTINCT $out, $seg

 MVNS    $seg, $in,  LSL #25  ; Complement to obtain the standard u-law input value, also
                              ; test to see if input was positive (the sign bit gets NOTted and
                              ; shifted into the carry flag, where we shall keep it until needed).
 MOV     $seg, $seg, LSR #29  ; whilst extracting the segment number from the input word, ie does:
                              ;    in=~in;
                              ;    seg=(in & 0x70) >> 4;
                              ;    if (in & sign_bit) {flags=CS} else {flags=CC}

 MVN     $out, $in,  LSL #3   ; Complement again! This time to get the quantisation bits.
 AND     $out, $out, #0x078   ;    out = (in & 0xF) << 3

 ADD     $out, $out, #0x84    ;    out = out + BIAS
 MOV     $out, $out, LSL $seg ;    out = out << segment

 SUBCS   $out, $out, #0x84    ;	   return ((in & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
 RSBCC   $out, $out, #0x84

 MEND
 
;-----------------------------------------------------------------------
;
; G711_alaw2ulaw() - Converts an 8-bit A-law value to an 8-bit u-law value.
;
; Based on the G711 C code from Sun Microsystems - refer to this for functionality.
;
; Parameters:
;   $alaw     - register containing the input 8-bit A-law value
;	$alaw     - register to return the 8-bit u-law value
;			    may be the same register as $alaw
;	$tmp      - temporary register
;	$table 	  - register containing pointer to address of lookup table
;               if register does not contain address for lookup table,
;               do not pass anything for $hastable
;				table address given by G711_a2u_lookup in file uatables.s
;	$hastable - parameter which should only be given if $table contains a valid
;				address for the lookup table that is required
;				the value given can be anything and is not required to
;				to be register
;				if $table is not valid, do not pass anything for this parameter
;
; Register differentation:
;	$alaw, $tmp, $table must be distinct registers
;	$ulaw, $tmp  must be distinct registers
;	$ulaw may equal $table
;	$ulaw may equal $alaw
;
;-----------------------------------------------------------------------
;
	MACRO
	G711_alaw2ulaw_macro $alaw, $ulaw, $tmp, $table, $hastable
 
	DISTINCT $alaw, $tmp, $table
	DISTINCT $ulaw, $tmp
	
	IF	"$hastable" = ""
 					B	a2u_skip_table
G711_a2u_lookup_ptr	DCD	G711_a2u_lookup
a2u_skip_table		LDR	$table, G711_a2u_lookup_ptr
	ENDIF
	
	AND	$tmp, $alaw, #0x7F		; ensure value between 0..127 (remove sign)
	EOR	$tmp, $tmp, #0x55		; remove even bit inversion, in accordance with
								; Note 2 of G.711 Table 1a
	LDRB	$tmp, [$table, $tmp]	; lookup value in table
	EOR	$tmp, $tmp, #0x7F		; exclusive or with 127 to get actual value
	AND	$ulaw, $alaw, #0x80		; put sign bit from original input into output
	ORR	$ulaw, $ulaw, $tmp		; put new value (less sign) into output
	
	MEND

;-----------------------------------------------------------------------
;
; G711_ulaw2alaw() - Converts an 8-bit u-law value to an 8-bit A-law value.
;
; Based on the G711 C code from Sun Microsystems - refer to this for functionality.
;
; Parameters:
;   $ulaw     - register containing the input 8-bit u-law value
;	$alaw     - register to return the 8-bit A-law value
;			    may be the same register as $ulaw
;	$tmp      - temporary register
;	$table 	  - register containing pointer to address of lookup table
;               if register does not contain address for lookup table,
;               do not pass anything for $hastable
;				table address given by G711_u2a_lookup in file uatables.s
;	$hastable - parameter which should only be given if $table contains a valid
;				address for the lookup table that is required
;				the value given can be anything and is not required to
;				to be register
;				if $table is not valid, do not pass anything for this parameter
;
; Register differentation:
;	$ulaw, $tmp, $table must be distinct registers
;	$alaw, $tmp  must be distinct registers
;	$alaw may equal $table
;	$alaw may equal $ulaw
;
;-----------------------------------------------------------------------
;
	MACRO
	G711_ulaw2alaw_macro $ulaw, $alaw, $tmp, $table, $hastable
 
	DISTINCT $ulaw, $tmp, $table
	DISTINCT $alaw, $tmp
	
 	IF	"$hastable" = ""
 					B	u2a_skip_table
G711_u2a_lookup_ptr	DCD	G711_u2a_lookup
u2a_skip_table		LDR	$table, G711_u2a_lookup_ptr
	ENDIF
	
	AND	$tmp, $ulaw, #0x7F		; ensure value between 0..127 (remove sign)
	EOR	$tmp, $tmp, #0x7F		; exclusive or with 127 to get value to lookup
	LDRB	$tmp, [$table, $tmp]	; lookup value in table
	SUB	$tmp, $tmp, #1			; subtract one from value looked up
								; to bring value in range 0..127
	EOR	$tmp, $tmp, #0x55		; add even bit inversion, in accordance with
								; Note 2 of G.711 Table 1a
	AND	$alaw, $ulaw, #0x80		; put sign bit from original input into output
	ORR	$alaw, $alaw, $tmp		; put new value (less sign) into output
	
	MEND

;-----------------------------------------------------------------------

	END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -