Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Audio support data for mISDN_dsp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Rewritten by Peter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * This software may be used and distributed according to the terms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * of the GNU General Public License, incorporated herein by reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/mISDNif.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/mISDNdsp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/bitrev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "dsp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) /* ulaw[unsigned char] -> signed 16-bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) s32 dsp_audio_ulaw_to_s32[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) /* alaw[unsigned char] -> signed 16-bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) s32 dsp_audio_alaw_to_s32[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) s32 *dsp_audio_law_to_s32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) EXPORT_SYMBOL(dsp_audio_law_to_s32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /* signed 16-bit -> law */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) u8 dsp_audio_s16_to_law[65536];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) EXPORT_SYMBOL(dsp_audio_s16_to_law);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /* alaw -> ulaw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) u8 dsp_audio_alaw_to_ulaw[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /* ulaw -> alaw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static u8 dsp_audio_ulaw_to_alaw[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) u8 dsp_silence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) /*****************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * generate table for conversion of s16 to alaw/ulaw *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *****************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define AMI_MASK 0x55
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) static inline unsigned char linear2alaw(short int linear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	int seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	int pcm_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	static int seg_end[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	pcm_val = linear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	if (pcm_val >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		/* Sign (7th) bit = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		mask = AMI_MASK | 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		/* Sign bit = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		mask = AMI_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		pcm_val = -pcm_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	/* Convert the scaled magnitude to segment number. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	for (seg = 0; seg < 8; seg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		if (pcm_val <= seg_end[seg])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	/* Combine the sign, segment, and quantization bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	return  ((seg << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		 ((pcm_val >> ((seg)  ?  (seg + 3)  :  4)) & 0x0F)) ^ mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static inline short int alaw2linear(unsigned char alaw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	int seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	alaw ^= AMI_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	i = ((alaw & 0x0F) << 4) + 8 /* rounding error */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	seg = (((int) alaw & 0x70) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (seg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		i = (i + 0x100) << (seg - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	return (short int) ((alaw & 0x80)  ?  i  :  -i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static inline short int ulaw2linear(unsigned char ulaw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	short mu, e, f, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	static short etab[] = {0, 132, 396, 924, 1980, 4092, 8316, 16764};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	mu = 255 - ulaw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	e = (mu & 0x70) / 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	f = mu & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	y = f * (1 << (e + 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	y += etab[e];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	if (mu & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		y = -y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	return y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define BIAS 0x84   /*!< define the add-in bias for 16 bit samples */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static unsigned char linear2ulaw(short sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	static int exp_lut[256] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	int sign, exponent, mantissa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	unsigned char ulawbyte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	/* Get the sample into sign-magnitude. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	sign = (sample >> 8) & 0x80;	  /* set aside the sign */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	if (sign != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		sample = -sample;	      /* get magnitude */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	/* Convert from 16 bit linear to ulaw. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	sample = sample + BIAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	exponent = exp_lut[(sample >> 7) & 0xFF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	mantissa = (sample >> (exponent + 3)) & 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	ulawbyte = ~(sign | (exponent << 4) | mantissa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	return ulawbyte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) void dsp_audio_generate_law_tables(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	for (i = 0; i < 256; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		dsp_audio_alaw_to_s32[i] = alaw2linear(bitrev8((u8)i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	for (i = 0; i < 256; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		dsp_audio_ulaw_to_s32[i] = ulaw2linear(bitrev8((u8)i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	for (i = 0; i < 256; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		dsp_audio_alaw_to_ulaw[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			linear2ulaw(dsp_audio_alaw_to_s32[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		dsp_audio_ulaw_to_alaw[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			linear2alaw(dsp_audio_ulaw_to_s32[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) dsp_audio_generate_s2law_table(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (dsp_options & DSP_OPT_ULAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		/* generating ulaw-table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		for (i = -32768; i < 32768; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			dsp_audio_s16_to_law[i & 0xffff] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 				bitrev8(linear2ulaw(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		/* generating alaw-table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		for (i = -32768; i < 32768; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 			dsp_audio_s16_to_law[i & 0xffff] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 				bitrev8(linear2alaw(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  * the seven bit sample is the number of every second alaw-sample ordered by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * aplitude. 0x00 is negative, 0x7f is positive amplitude.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u8 dsp_audio_seven2law[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) u8 dsp_audio_law2seven[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * generate table for conversion law from/to 7-bit alaw-like sample *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  ********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dsp_audio_generate_seven(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	int i, j, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	u8 spl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	u8 sorted_alaw[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	/* generate alaw table, sorted by the linear value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	for (i = 0; i < 256; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		for (k = 0; k < 256; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			if (dsp_audio_alaw_to_s32[k]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			    < dsp_audio_alaw_to_s32[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		sorted_alaw[j] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	/* generate tabels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	for (i = 0; i < 256; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		/* spl is the source: the law-sample (converted to alaw) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		spl = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		if (dsp_options & DSP_OPT_ULAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			spl = dsp_audio_ulaw_to_alaw[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		/* find the 7-bit-sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		for (j = 0; j < 256; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			if (sorted_alaw[j] == spl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		/* write 7-bit audio value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		dsp_audio_law2seven[i] = j >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	for (i = 0; i < 128; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		spl = sorted_alaw[i << 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		if (dsp_options & DSP_OPT_ULAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			spl = dsp_audio_alaw_to_ulaw[spl];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		dsp_audio_seven2law[i] = spl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* mix 2*law -> law */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) u8 dsp_audio_mix_law[65536];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /******************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  * generate mix table to mix two law samples into one *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  ******************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) dsp_audio_generate_mix_table(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	s32 sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	while (i < 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		while (j < 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			sample = dsp_audio_law_to_s32[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			sample += dsp_audio_law_to_s32[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 				sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 				sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			dsp_audio_mix_law[(i << 8) | j] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 				dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /*************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)  * generate different volume changes *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)  *************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static u8 dsp_audio_reduce8[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static u8 dsp_audio_reduce7[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static u8 dsp_audio_reduce6[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static u8 dsp_audio_reduce5[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static u8 dsp_audio_reduce4[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static u8 dsp_audio_reduce3[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static u8 dsp_audio_reduce2[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static u8 dsp_audio_reduce1[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static u8 dsp_audio_increase1[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static u8 dsp_audio_increase2[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static u8 dsp_audio_increase3[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static u8 dsp_audio_increase4[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static u8 dsp_audio_increase5[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static u8 dsp_audio_increase6[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static u8 dsp_audio_increase7[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static u8 dsp_audio_increase8[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static u8 *dsp_audio_volume_change[16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	dsp_audio_reduce8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	dsp_audio_reduce7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	dsp_audio_reduce6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	dsp_audio_reduce5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	dsp_audio_reduce4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	dsp_audio_reduce3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	dsp_audio_reduce2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	dsp_audio_reduce1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	dsp_audio_increase1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	dsp_audio_increase2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	dsp_audio_increase3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	dsp_audio_increase4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	dsp_audio_increase5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	dsp_audio_increase6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	dsp_audio_increase7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	dsp_audio_increase8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dsp_audio_generate_volume_changes(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	register s32 sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	int num[]   = { 110, 125, 150, 175, 200, 300, 400, 500 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	int denum[] = { 100, 100, 100, 100, 100, 100, 100, 100 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	while (i < 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		dsp_audio_reduce8[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			(dsp_audio_law_to_s32[i] * denum[7] / num[7]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		dsp_audio_reduce7[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			(dsp_audio_law_to_s32[i] * denum[6] / num[6]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		dsp_audio_reduce6[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 			(dsp_audio_law_to_s32[i] * denum[5] / num[5]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		dsp_audio_reduce5[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			(dsp_audio_law_to_s32[i] * denum[4] / num[4]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		dsp_audio_reduce4[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			(dsp_audio_law_to_s32[i] * denum[3] / num[3]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		dsp_audio_reduce3[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 			(dsp_audio_law_to_s32[i] * denum[2] / num[2]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		dsp_audio_reduce2[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 			(dsp_audio_law_to_s32[i] * denum[1] / num[1]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		dsp_audio_reduce1[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 			(dsp_audio_law_to_s32[i] * denum[0] / num[0]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		sample = dsp_audio_law_to_s32[i] * num[0] / denum[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 			sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 			sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		dsp_audio_increase1[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		sample = dsp_audio_law_to_s32[i] * num[1] / denum[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		dsp_audio_increase2[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		sample = dsp_audio_law_to_s32[i] * num[2] / denum[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 			sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		dsp_audio_increase3[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		sample = dsp_audio_law_to_s32[i] * num[3] / denum[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 			sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		dsp_audio_increase4[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		sample = dsp_audio_law_to_s32[i] * num[4] / denum[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 			sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		dsp_audio_increase5[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		sample = dsp_audio_law_to_s32[i] * num[5] / denum[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 			sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		dsp_audio_increase6[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		sample = dsp_audio_law_to_s32[i] * num[6] / denum[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 			sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 			sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		dsp_audio_increase7[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		sample = dsp_audio_law_to_s32[i] * num[7] / denum[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		dsp_audio_increase8[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /**************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)  * change the volume of the given skb *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)  **************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* this is a helper function for changing volume of skb. the range may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)  * -8 to 8, which is a shift to the power of 2. 0 == no volume, 3 == volume*8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dsp_change_volume(struct sk_buff *skb, int volume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	u8 *volume_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	int i, ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	u8 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	if (volume == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	/* get correct conversion table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	if (volume < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		shift = volume + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		if (shift < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		shift = volume + 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		if (shift > 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			shift = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	volume_change = dsp_audio_volume_change[shift];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	ii = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	p = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	/* change volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	while (i < ii) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		*p = volume_change[*p];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }