Fixed alaw/ulaw conversion library

This commit is contained in:
Andreas Eversberg 2024-01-14 13:12:14 +01:00
parent 48242a6b53
commit 22e1f73080
2 changed files with 52 additions and 46 deletions

View File

@ -9,11 +9,13 @@
** **
\*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "g711.h"
/* ulaw -> signed 16-bit */
static int16_t _ulaw_flipped_to_linear[256] =
static int16_t g711_ulaw_to_linear[256] =
{
0x8284, 0x8684, 0x8a84, 0x8e84, 0x9284, 0x9684, 0x9a84, 0x9e84,
0xa284, 0xa684, 0xaa84, 0xae84, 0xb284, 0xb684, 0xba84, 0xbe84,
@ -50,7 +52,7 @@ static int16_t _ulaw_flipped_to_linear[256] =
};
/* alaw -> signed 16-bit */
static int16_t _alaw_flipped_to_linear[256] =
int16_t g711_alaw_flipped_to_linear[256] =
{
0x13fc, 0xec04, 0x0144, 0xfebc, 0x517c, 0xae84, 0x051c, 0xfae4,
0x0a3c, 0xf5c4, 0x0048, 0xffb8, 0x287c, 0xd784, 0x028c, 0xfd74,
@ -87,17 +89,25 @@ static int16_t _alaw_flipped_to_linear[256] =
};
/* Xlaw -> signed 16-bit */
static int16_t _alaw_to_linear[256];
static int16_t _ulaw_to_linear[256];
static int16_t g711_alaw_to_linear[256];
int16_t g711_ulaw_flipped_to_linear[256];
/* signed 16-bit -> Xlaw */
static uint8_t _linear_to_alaw_flipped[65536];
static uint8_t _linear_to_ulaw_flipped[65536];
static uint8_t _linear_to_alaw[65536];
static uint8_t _linear_to_ulaw[65536];
uint8_t g711_linear_to_alaw_flipped[65536];
uint8_t g711_linear_to_ulaw_flipped[65536];
static uint8_t g711_linear_to_alaw[65536];
static uint8_t g711_linear_to_ulaw[65536];
/* transcode */
static uint8_t g711_alaw_to_ulaw[256];
static uint8_t g711_ulaw_to_alaw[256];
static uint8_t g711_alaw_flipped_to_ulaw[256];
static uint8_t g711_ulaw_flipped_to_alaw[256];
static uint8_t g711_alaw_to_ulaw_flipped[256];
static uint8_t g711_ulaw_to_alaw_flipped[256];
/* table is used to generate linear_to_alaw */
static int16_t _alaw_relations[] =
static int16_t g711_alaw_relations[] =
{
0x8684, 0x55, 0x8a84, 0xd5, 0x8e84, 0x15, 0x9284, 0x95,
0x9684, 0x75, 0x9a84, 0xf5, 0x9e84, 0x35, 0xa284, 0xb5,
@ -165,20 +175,9 @@ static int16_t _alaw_relations[] =
0x6d7c, 0x94, 0x717c, 0x14, 0x757c, 0xd4, 0x797c, 0x54
};
uint8_t _flip[256];
/* Xlaw -> signed 16-bit */
int16_t *g711_ulaw_flipped_to_linear = _ulaw_flipped_to_linear;
int16_t *g711_alaw_flipped_to_linear = _alaw_flipped_to_linear;
int16_t *g711_alaw_to_linear = _alaw_to_linear;
int16_t *g711_ulaw_to_linear = _ulaw_to_linear;
/* signed 16-bit -> Xlaw */
uint8_t *g711_linear_to_alaw_flipped = _linear_to_alaw_flipped;
uint8_t *g711_linear_to_ulaw_flipped = _linear_to_ulaw_flipped;
uint8_t *g711_linear_to_alaw = _linear_to_ulaw;
uint8_t *g711_linear_to_ulaw = _linear_to_ulaw;
uint8_t g711_flip[256];
static int g711_initialized = 0;
/* generate tables
*/
@ -188,7 +187,7 @@ void g711_init(void)
/* flip tables */
for (i = 0; i < 256; i++) {
_flip[i]
g711_flip[i]
= ((i & 1) << 7)
+ ((i & 2) << 5)
+ ((i & 4) << 3)
@ -197,38 +196,50 @@ void g711_init(void)
+ ((i & 32) >> 3)
+ ((i & 64) >> 5)
+ ((i & 128) >> 7);
_alaw_to_linear[i] = _alaw_flipped_to_linear[_flip[i]];
_ulaw_to_linear[i] = _ulaw_flipped_to_linear[_flip[i]];
g711_alaw_to_linear[i] = g711_alaw_flipped_to_linear[g711_flip[i]];
g711_ulaw_flipped_to_linear[i] = g711_ulaw_to_linear[g711_flip[i]];
}
/* linear to alaw tables */
i = j = 0;
while(i < 65536) {
if (i - 32768 > _alaw_relations[j << 1])
if (i - 32768 > g711_alaw_relations[j << 1])
j++;
if (j > 255)
j = 255;
_linear_to_alaw_flipped[(i - 32768) & 0xffff] = _alaw_relations[(j << 1) | 1];
_linear_to_alaw[(i - 32768) & 0xffff] = _flip[_alaw_relations[(j << 1) | 1]];
g711_linear_to_alaw_flipped[(i - 32768) & 0xffff] = g711_alaw_relations[(j << 1) | 1];
g711_linear_to_alaw[(i - 32768) & 0xffff] = g711_flip[g711_alaw_relations[(j << 1) | 1]];
i++;
}
/* linear to ulaw tables */
i = j = 0;
while(i < 32768) {
if (i - 32768 > _ulaw_flipped_to_linear[j])
if (i - 32768 > g711_ulaw_to_linear[j])
j++;
_linear_to_ulaw_flipped[(i - 32768) & 0xffff] = j;
_linear_to_ulaw[(i - 32768) & 0xffff] = _flip[j];
g711_linear_to_ulaw[(i - 32768) & 0xffff] = j;
g711_linear_to_ulaw_flipped[(i - 32768) & 0xffff] = g711_flip[j];
i++;
}
j = 255;
while(i < 65536) {
if (i - 32768 > _alaw_flipped_to_linear[j])
if (i - 32768 > g711_ulaw_to_linear[j])
j--;
_linear_to_ulaw_flipped[(i - 32768) & 0xffff] = j;
_linear_to_ulaw[(i - 32768) & 0xffff] = _flip[j];
g711_linear_to_ulaw[(i - 32768) & 0xffff] = j;
g711_linear_to_ulaw_flipped[(i - 32768) & 0xffff] = g711_flip[j];
i++;
}
/* transcode */
for (i = 0; i < 256; i++) {
g711_alaw_to_ulaw[i] = g711_linear_to_ulaw[(uint16_t)g711_alaw_to_linear[i]];
g711_ulaw_to_alaw[i] = g711_linear_to_alaw[(uint16_t)g711_ulaw_to_linear[i]];
g711_alaw_flipped_to_ulaw[i] = g711_linear_to_ulaw[(uint16_t)g711_alaw_to_linear[g711_flip[i]]];
g711_ulaw_flipped_to_alaw[i] = g711_linear_to_alaw[(uint16_t)g711_ulaw_to_linear[g711_flip[i]]];
g711_alaw_to_ulaw_flipped[i] = g711_flip[g711_linear_to_ulaw[(uint16_t)g711_alaw_to_linear[i]]];
g711_ulaw_to_alaw_flipped[i] = g711_flip[g711_linear_to_alaw[(uint16_t)g711_ulaw_to_linear[i]]];
}
g711_initialized = 1;
}

View File

@ -1,13 +1,8 @@
#pragma once
extern int16_t g711_alaw_flipped_to_linear[256];
extern int16_t g711_ulaw_flipped_to_linear[256];
extern uint8_t g711_linear_to_alaw_flipped[65536];
extern uint8_t g711_linear_to_ulaw_flipped[65536];
void g711_init(void);
/* Xlaw -> signed 16-bit */
extern int16_t *g711_ulaw_flipped_to_linear;
extern int16_t *g711_alaw_flipped_to_linear;
extern int16_t *g711_alaw_to_linear;
extern int16_t *g711_ulaw_to_linear;
/* signed 16-bit -> Xlaw */
extern uint8_t *g711_linear_to_alaw_flipped;
extern uint8_t *g711_linear_to_ulaw_flipped;
extern uint8_t *g711_linear_to_alaw;
extern uint8_t *g711_linear_to_ulaw;