какой кодек выбрать для VoIP

Oleg_B
Уже с Приветом
Posts: 5406
Joined: 16 Apr 1999 09:01
Location: MA

Post by Oleg_B »

uniqueman wrote:Я получаю сигнал, кодированный через G 711 (как говорят это стандарт для Т1), конвертирую его в чистый, линейный PCM. Затем конвертирую обратно в тот же G 711 который был, в u-law PCM. В результате качество искажается очень сильно.. почему? ведь по идее я сделал два действия , которые противополжны друг другу... взял число два, умножил на два (перевел в linear PCM), потом опять разделил на два (перевел обратно в G 711).. и у меня не получилось исходной двойки :pain1:


Ошибка в реализации алгоритма, других вариантов не вижу.
И... не нужно никаких формул, таблички из 256 16-битных чисел хватит.
Oleg_B
Уже с Приветом
Posts: 5406
Joined: 16 Apr 1999 09:01
Location: MA

Post by Oleg_B »

uniqueman wrote:От кого и от чего зависит каким кодеком сжимается линейный PCM для передачи по Т1?


Как вы подключены к Т1? Девайс, его интерфейс (PRI, BRI, ISDN, Raw?) Умных слов немножко насыпьте, может и поймём чего...
User avatar
Sanek
Уже с Приветом
Posts: 6991
Joined: 04 Sep 2002 04:06

Post by Sanek »

Сори, давно не заходил в эти края, а тут такая дискуссия...

Шуметь конверсия может только из за неправильной перекодировки. В случае с мю это, как тут уже правильно подметили, это просто табличный lookup.

Что же касается T1, то не зависимо от того, как он подключен к диалоджику, по нему будет ехать мю или А и ничего другого. Насколько я помню, (писал для D240E-SC 6 лет назад) подавать ему нужно уже готовый мю или А.
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Post by uniqueman »

Ошибка в реализации алгоритма, других вариантов не вижу.
И... не нужно никаких формул, таблички из 256 16-битных чисел хватит.


звиняйте за неграмотность, а что за табличка и где ее взять?
- Чай, кофе не предлагаю...
- Спасибо, мы уже пиво выпили
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Post by uniqueman »

Oleg_B wrote:
uniqueman wrote:От кого и от чего зависит каким кодеком сжимается линейный PCM для передачи по Т1?


Как вы подключены к Т1? Девайс, его интерфейс (PRI, BRI, ISDN, Raw?) Умных слов немножко насыпьте, может и поймём чего...


С нашей стороны начинается Dialogic card (ну собственно это на самом деле конец пути, но начнем с обратного), куда собственно и приходит голос. До этого стоит огромный rack от NewBridge компании, где в стойках стоят T1 карты, потом опять же по Т1 путь идет прямо до провайдера ну и там уже не знаю..

Каких умных слов насыпать тоже не знаю. :pain1:
- Чай, кофе не предлагаю...
- Спасибо, мы уже пиво выпили
Oleg_B
Уже с Приветом
Posts: 5406
Joined: 16 Apr 1999 09:01
Location: MA

Post by Oleg_B »

uniqueman wrote:звиняйте за неграмотность, а что за табличка и где ее взять?


WORD table[256];

for(int n=0; n<256; n++) {
table[n] = mu_law_to_linear(BYTE(n)); // may use ACM G.711 codec here...
}
Oleg_B
Уже с Приветом
Posts: 5406
Joined: 16 Apr 1999 09:01
Location: MA

Post by Oleg_B »

[quote="uniqueman"]С нашей стороны начинается Dialogic card (ну собственно это на самом деле конец пути, но начнем с обратного), куда собственно и приходит голос. До этого стоит огромный rack от NewBridge компании, где в стойках стоят T1 карты, потом опять же по Т1 путь идет прямо до провайдера ну и там уже не знаю..
quote]

Ну вот и читайте документацию этого диалоджика, смотрите его установки. Скорее всего, мю-ло идёт.
Меня смущает этот огромный рак... Я не знаю, что такое Нью-бридж и зачем он... Что в него приходит? Т-3?
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Post by uniqueman »

Oleg_B,

я честно говоря не понял что Вы мне написали. Я испольлзую вот такие функуции для перевода..

Из u-law в линейный

void mulaw_decode(const char* mulaw, USHORT sz)

{
int i;
for(i=0; i<sz; i++)
{
int t;

/* Complement to obtain normal u-law value. */
char val = ~mulaw[i];

t = ((val & 0x0f) << 3) + 0x84;
t <<= (val & 0x70) >> 4;

LinearPCM[i] = (val & 0x80) ? (0x84 - t) : (t - 0x84);
}
}

обратно

void mulaw_encode(char mulaw[], short linear[], USHORT sz)

{
int i;
for(i=0; i<sz; i++)
{
int mask;
int seg;
unsigned char uval;

if (linear[i] < 0)
{
linear[i] = 0x84 - linear[i];
mask = 0x7f;
}
else
{
linear[i] += 0x84;
mask = 0xff;
}

if (linear[i] > 0x7fff)
linear[i] = 0x7fff;

/* Convert the scaled magnitude to segment number. */
seg = val_seg(linear[i]);

/*
* Combine the sign, segment, quantization bits;
* and complement the code word.
*/
uval = (seg << 4) | ((linear[i] >> (seg + 3)) & 0x0f);

mulaw[i] = uval ^ mask;
}
}

и вот такая комбинация выдает неправильные данные.. шума очень много получается
- Чай, кофе не предлагаю...
- Спасибо, мы уже пиво выпили
Oleg_B
Уже с Приветом
Posts: 5406
Joined: 16 Apr 1999 09:01
Location: MA

Post by Oleg_B »

ну так проверьте эти функции,
для всех чисел от 0 до 255: раскодировать в линейный и закодировать обратно. должно получиться то же число. если нет - то претензии к тому, кто это писал...
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Post by uniqueman »

Ну вот и читайте документацию этого диалоджика, смотрите его установки. Скорее всего, мю-ло идёт.


да, именно это и идет

Меня смущает этот огромный рак... Я не знаю, что такое Нью-бридж и зачем он... Что в него приходит? Т-3?


это какой то менеджер, в него сейчас входит кабель, в котором 8 Т1 линий. У нас в этом раке стоят восемь Т1 карточек.
- Чай, кофе не предлагаю...
- Спасибо, мы уже пиво выпили
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Post by uniqueman »

Oleg_B wrote:ну так проверьте эти функции,
для всех чисел от 0 до 255: раскодировать в линейный и закодировать обратно. должно получиться то же число. если нет - то претензии к тому, кто это писал...


так вот я об этом и говорю. ЧИсла разные получаются.
- Чай, кофе не предлагаю...
- Спасибо, мы уже пиво выпили
Oleg_B
Уже с Приветом
Posts: 5406
Joined: 16 Apr 1999 09:01
Location: MA

Post by Oleg_B »

значит ошибка в программе :umnik1:
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Post by uniqueman »

Oleg_B wrote:значит ошибка в программе :umnik1:


ошибка в этих функциях где то, Вы имеете в виду?
- Чай, кофе не предлагаю...
- Спасибо, мы уже пиво выпили
Oleg_B
Уже с Приветом
Posts: 5406
Joined: 16 Apr 1999 09:01
Location: MA

Post by Oleg_B »

очевидно
User avatar
Sanek
Уже с Приветом
Posts: 6991
Joined: 04 Sep 2002 04:06

Post by Sanek »

Code: Select all

1 /*
  2  * mulaw.h --
  3  *
  4  *      Mulaw table declarations
  5  *
  6  * Copyright (c) 1991-2002 The Regents of the University of California.
  7  * All rights reserved.
  8  *
  9  * Redistribution and use in source and binary forms, with or without
 10  * modification, are permitted provided that the following conditions are met:
 11  *
 12  * A. Redistributions of source code must retain the above copyright notice,
 13  *    this list of conditions and the following disclaimer.
 14  * B. Redistributions in binary form must reproduce the above copyright notice,
 15  *    this list of conditions and the following disclaimer in the documentation
 16  *    and/or other materials provided with the distribution.
 17  * C. Neither the names of the copyright holders nor the names of its
 18  *    contributors may be used to endorse or promote products derived from this
 19  *    software without specific prior written permission.
 20  *
 21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
 22  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 23  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
 25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 31  * POSSIBILITY OF SUCH DAMAGE.
 32  *
 33  * @(#) $Header: /usr/mash/src/repository/mash/mash-1/codec/audio/mulaw.h,v 1.5 2002/02/03 03:11:42 lim Exp $
 34  */
 35
 36 extern short mulawtolin[256];
 37 extern u_char lintomulaw[65536];
 38 extern u_char mulawsum[256*256];
 39


Code: Select all

  1 /*
  2  * mktab.c --
  3  *
  4  *      Tables for mulaw
  5  *
 32  */
 33
 34 #ifndef lint
 35 static char rcsid[] =
 36     "@(#) $Header: /usr/mash/src/repository/mash/mash-1/codec/audio/mktab.c,v 1.6 2002/02/03 03:11:42 lim Exp $";
 37 #endif
 38
 39 #include <stdio.h>
 40 #include <math.h>
 41 #include <sys/types.h>
 42 #include "mulaw.h"
 43
 44 #define BIAS 0x84
 45 #define CLIP 32635
 46
 47 u_char
 48 st_linear_to_ulaw(register int linear)
 49 {
 50         static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
 51                                    4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
 52                                    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
 53                                    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
 54                                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
 55                                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
 56                                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
 57                                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
 58                                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
 59                                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
 60                                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
 61                                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
 62                                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
 63                                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
 64                                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
 65                                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
 66         register int sign, exponent, mantissa;
 67         register u_char ulawbyte;
 68
 69         /* Get the value into sign-magnitude. */
 70         sign = (linear >> 8) & 0x80;
 71         if (sign != 0) {
 72                 /* sign extend the value, just in case */
 73                 linear |= 0xffff0000;
 74                 linear = -linear;
 75         }
 76         if (linear > CLIP)
 77                 linear = CLIP;
 78
 79         /* Convert from 16 bit linear to ulaw. */
 80         linear += BIAS;
 81         exponent = exp_lut[(linear >> 7) & 0xFF];
 82         mantissa = (linear >> (exponent + 3)) & 0x0F;
 83         ulawbyte = ~(sign | (exponent << 4) | mantissa);
 84         return ulawbyte;
 85 }
 86
 87 int
 88 st_ulaw_to_linear(ulawbyte)
 89         u_char ulawbyte;
 90 {
 91         static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
 92         int sign, exponent, mantissa, sample;
 93
 94         ulawbyte = ~ulawbyte;
 95         sign = (ulawbyte & 0x80);
 96         exponent = (ulawbyte >> 4) & 0x07;
 97         mantissa = ulawbyte & 0x0F;
 98         sample = exp_lut[exponent] + (mantissa << (exponent + 3)) +
 99                  (1 << (exponent + 2));
100         if (sign != 0)
101                 sample = -sample;
102         /*
103          * ulaw maps zero to full-scale negative.  This is a very poor
104          * choice given that most i/o failure modes stick zero in the
105          * buffer.  So, to save our ears, we map ulaw zero to linear zero.
106          */
107         return (ulawbyte == 0xff? 0 : sample);
108 }
109
110 tab_tolin(f)
111         register FILE *f;
112 {
113         register int i, j;
114
115         fprintf(f, "const short mulawtolin[256] = {\n");
116         for (i = 0; i < 256; ) {
117                 putc('\t', f);
118                 for (j = i + 8; i < j; ++i)
119                         fprintf(f, "%d, ", st_ulaw_to_linear(i));
120                 putc('\n', f);
121         }
122         fprintf(f, "};\n");
123 }
124
125 tab_tomu(f)
126         register FILE *f;
127 {
128         register int i, j;
129
130         fprintf(f, "const unsigned char lintomulaw[65536] = {\n");
131         for (i = 0; i < 65536; ) {
132                 putc('\t', f);
133                 for (j = i + 8; i < j; ++i)
134                         fprintf(f, "%d, ", st_linear_to_ulaw(i));
135                 putc('\n', f);
136         }
137         fprintf(f, "};\n");
138 }
139
140 /*
141  * build a linear to mulaw lookup table extended by 1
142  * bit to handle clipping in the table lookup rather
143  * than testing each sample.
144  */
145 tab_tomuX(f)
146         register FILE *f;
147 {
148         register int i, j;
149
150         fprintf(f, "const unsigned char lintomulawX[65536*2] = {\n");
151         /* positive half */
152         for (i = 0; i < 32768; ) {
153                 putc('\t', f);
154                 for (j = i + 8; i < j; ++i)
155                         fprintf(f, "%d, ", st_linear_to_ulaw(i));
156                 putc('\n', f);
157         }
158         /* positive overflow (clipped) */
159         for (i = 32768; i < 65536; ) {
160                 putc('\t', f);
161                 for (j = i + 8; i < j; ++i)
162                         fprintf(f, "%d, ", 0x80);
163                 putc('\n', f);
164         }
165         /* negative overflow (clipped) */
166         for (i = 65536; i < 98304; ) {
167                 putc('\t', f);
168                 for (j = i + 8; i < j; ++i)
169                         fprintf(f, "%d, ", 0x01);
170                 putc('\n', f);
171         }
172         /* negative half */
173         for (i = 98304; i < 131072; ) {
174                 putc('\t', f);
175                 for (j = i + 8; i < j; ++i)
176                         fprintf(f, "%d, ", st_linear_to_ulaw(i));
177                 putc('\n', f);
178         }
179         fprintf(f, "};\n");
180 }
181
182 void
183 prtone(f, u)
184         register FILE *f;
185         register int u;
186 {
187         if (u < -CLIP)
188                 u = -CLIP;
189         else if (u > CLIP)
190                 u = CLIP;
191         fprintf(f, "%d, ", st_linear_to_ulaw(u));
192 }
193
194 tab_sum(f)
195         register FILE *f;
196 {
197         register int i, j, k, u;
198
199         fprintf(f, "const unsigned char mulawsum[256*256] = {\n");
200         for (i = 0; i < 256; ++i) {
201                 fprintf(f, "/* %d */\n", i);
202                 u = st_ulaw_to_linear(i);
203                 for (j = 0; j < 256; ) {
204                         putc('\t', f);
205                         for (k = j + 8; j < k; ++j)
206                                 prtone(f, u + st_ulaw_to_linear(j));
207                         putc('\n', f);
208                 }
209         }
210         fprintf(f, "};\n");
211 }
212
213 void
214 prt8(f, u, us)
215         register FILE *f;
216         register int u;
217         register int* us;
218 {
219         register int k;
220
221         putc('\t', f);
222         for (k = 0; k < 8; ++k)
223                 prtone(f, u + us[k]);
224         putc('\n', f);
225 }
226
227 int
228 prtup64(f, u, uj)
229         register FILE *f;
230         register int u, uj;
231 {
232         register int k;
233         int us[64], uabs, uk;
234
235         /*
236          * compute the 64 values that would precede uj in a mulaw
237          * table (assuming a gain of 17/16 which is roughly right
238          * for large uj).  Do them in reverse order since mulaw
239          * values are complemented.
240          */
241         uabs = (uj>=0? uj : -uj) << 4;
242         for (k = 64; --k >= 0; ) {
243                 uk = uabs >> 4;
244                 us[k] = uj>=0? uk : -uk;
245                 uabs += uk;
246         }
247         for (k = 0; k < 64; k += 8)
248                 prt8(f, u, us + k);
249 }
250
251 int
252 prtlow64(f, u, uj)
253         register FILE *f;
254         register int u, uj;
255 {
256         register int k;
257         int us[64], uabs, uk;
258
259         /*
260          * compute the 64 values that would follow uj in a mulaw
261          * table.
262          */
263         uabs = 1 << 4;
264         for (k = 48; --k >= 0; ) {
265                 uk = uabs >> 4;
266                 us[k] = uj>=0? uk : -uk;
267                 uabs += uk;
268         }
269         for (k = 64; --k >= 48; ) {
270                 us[k] = 0;
271         }
272         for (k = 0; k < 64; k += 8)
273                 prt8(f, u, us + k);
274 }
275
276 tab_mugain(f)
277         register FILE *f;
278 {
279         register int i, j, k;
280 #define M 16.
281         double g = 1.;
282         double gi = pow(M, (double)1. / 32.);
283
284         fprintf(f, "const unsigned char mugaintab[64*256] = {\n");
285         for (i = 0; i < 64; ++i) {
286                 fprintf(f, "/* step %d (gain %g) */\n", i - 32, g / M);
287
288                 for (j = 0; j < 256; ) {
289                         putc('\t', f);
290                         for (k = j + 8; j < k; ++j) {
291                                 double v = g / M * (double)st_ulaw_to_linear(j);
292                                 prtone(f, (int)v);
293                         }
294                         putc('\n', f);
295                 }
296                 g *= gi;
297         }
298         fprintf(f, "};\n");
299 #undef M
300 }
301
302 /*
303  * Output a table that maps mulaw samples to power levels, where
304  * the power level is given by p = log_2(x^2) (i.e., not really db).
305  * p is expressed in 32-bit fixed point, with 19 bits of fraction.
306  * Since ulaw samples range over 16 bits (linear), we need 32 bits
307  * to represent log_2(x^2).  To compute the power in a frame, we add
308  * 160 of these samples, so we need to be able to represent 32 * 160 = 0x1400,
309  * with the encoding.  Thus, we need 13 bits for the integer part,
310  * which gives 19 bits of fraction.  This encoding will allow the
311  * frame size to go to 256.  Note that all the values are positive
312  * since the smallest linear value is 4 (except for 0, which we will
313  * just encode as 0).
314  */
315 #ifdef notdef
316 tab_mudb(f)
317         register FILE *f;
318 {
319         register int i, j;
320         double log2 = log((double)2);
321
322         fprintf(f, "const unsigned long mulawtodb[256] = {\n");
323         for (i = 0; i < 256; ) {
324                 putc('\t', f);
325                 for (j = i + 4; i < j; ++i) {
326                         u_long s;
327                         double d = (double)st_ulaw_to_linear(i);
328                         if (d != 0) {
329                                 d = d * d;
330                                 d = log(d) / log2;
331                                 d *= (double)(1 << MUDB_FRACBITS);
332                         }
333                         fprintf(f, "0x%lx, ", (u_long)irint(d));
334                 }
335                 putc('\n', f);
336         }
337         fprintf(f, "};\n");
338 }
339
340 tab_x(f)
341         register FILE *f;
342 {
343         register int i;
344
345         for (i = 0; i <= CLIP; ++i) {
346                 int u = st_linear_to_ulaw(i);
347                 printf("%d\n", ~u & 0x7f);
348         }
349 }
350
351 tab_xx(f)
352         register FILE *f;
353 {
354         register int i;
355
356         for (i = 0; i <= CLIP; ++i) {
357                 int u = st_linear_to_ulaw(i);
358                 printf("%d\n", st_ulaw_to_linear(u));
359         }
360 }
361 #endif
362
363 main(int argc, char* argv[])
364 {
365         if (argc != 2)
366                 exit(1);
367         if (strcmp(argv[1], "-mulaw") == 0) {
368                 tab_tolin(stdout);
369                 tab_tomu(stdout);
370         } else if (strcmp(argv[1], "-sum") == 0)
371                 tab_sum(stdout);
372         else if (strcmp(argv[1], "-scale") == 0)
373                 tab_mugain(stdout);
374         else if (strcmp(argv[1], "-muX") == 0)
375                 tab_tomuX(stdout);
376 #ifdef notdef
377         else if (strcmp(argv[1], "-db") == 0)
378                 tab_mudb(stdout);
379         else if (strcmp(argv[1], "-x") == 0)
380                 tab_x(stdout);
381         else if (strcmp(argv[1], "-xx") == 0)
382                 tab_xx(stdout);
383 #endif
384         else
385                 exit(1);
386         exit(0);
387 }
388

Return to “Вопросы и новости IT”