PCM的WAV格式如何转为ALAW

hyzkui 2009-03-18 03:05:09
请问一下:

PCM的WAV格式如何转为ALAW
...全文
777 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
hellochenhang 2009-03-20
  • 打赏
  • 举报
回复
这个代码只能实现每个sample的转换,存成.wav文件还需要加入文件头信息,具体的你可以查看微软的文档,里面有专门描述wav格式的。如果你只是想做一下变换,而不必要搞懂如何变换,你可以直接用cool edit
hyzkui 2009-03-18
  • 打赏
  • 举报
回复
请问一下,我需要转的是一个pcm的文件(1.wav),要转换生成另一个(alaw)1.wav文件,该怎么处理?
hyzkui 2009-03-18
  • 打赏
  • 举报
回复
你这个代码能实现吗?
hellochenhang 2009-03-18
  • 打赏
  • 举报
回复
为什么我贴的代码不能语法高亮???
hellochenhang 2009-03-18
  • 打赏
  • 举报
回复


/*
* g711.c
*
* u-law, A-law and linear PCM conversions.
*/
#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
#define QUANT_MASK (0xf) /* Quantization field mask. */
#define NSEGS (8) /* Number of A-law segments. */
#define SEG_SHIFT (4) /* Left shift for segment number. */
#define SEG_MASK (0x70) /* Segment field mask. */

// wmay - changed from short to int16_t
static uint16_t seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
// wmay - removed tables _u2a _a2u

// wmay - change
static uint8_t
search(
uint16_t val,
uint16_t *table,
uint8_t size)
{
uint8_t i;

for (i = 0; i < size; i++)
{
if (val <= *table++)
return (i);
}
return (size);
}

/*
* linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
*
* linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
*
* Linear Input Code Compressed Code
* ------------------------ ---------------
* 0000000wxyza 000wxyz
* 0000001wxyza 001wxyz
* 000001wxyzab 010wxyz
* 00001wxyzabc 011wxyz
* 0001wxyzabcd 100wxyz
* 001wxyzabcde 101wxyz
* 01wxyzabcdef 110wxyz
* 1wxyzabcdefg 111wxyz
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
// wmay - changed definitions of variable
static uint8_t
linear2alaw(
int16_t pcm_val) /* 2's complement (16-bit range) */
{
uint8_t mask;
uint8_t seg;
uint8_t aval;

if (pcm_val >= 0)
{
mask = 0xD5; /* sign (7th) bit = 1 */
}
else
{
mask = 0x55; /* sign bit = 0 */
pcm_val = ~pcm_val; // wmay -pcm_val - 8;
}

/* Convert the scaled magnitude to segment number. */
seg = search((uint16_t)pcm_val, seg_end, 8);

/* Combine the sign, segment, and quantization bits. */

if (seg >= 8) /* out of range, return maximum value. */
return (0x7F ^ mask);
else
{
aval = seg << SEG_SHIFT;
if (seg < 2)
aval |= (pcm_val >> 4) & QUANT_MASK;
else
aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
return (aval ^ mask);
}
}


// wmay - removed alaw2linear

#define BIAS (0x84) /* Bias for linear code. */

/*
* linear2ulaw() - Convert a linear PCM value to u-law
*
* In order to simplify the encoding process, the original linear magnitude
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
* (33 - 8191). The result can be seen in the following encoding table:
*
* Biased Linear Input Code Compressed Code
* ------------------------ ---------------
* 00000001wxyza 000wxyz
* 0000001wxyzab 001wxyz
* 000001wxyzabc 010wxyz
* 00001wxyzabcd 011wxyz
* 0001wxyzabcde 100wxyz
* 001wxyzabcdef 101wxyz
* 01wxyzabcdefg 110wxyz
* 1wxyzabcdefgh 111wxyz
*
* Each biased linear code has a leading 1 which identifies the segment
* number. The value of the segment number is equal to 7 minus the number
* of leading 0's. The quantization interval is directly available as the
* four bits wxyz. * The trailing bits (a - h) are ignored.
*
* Ordinarily the complement of the resulting code word is used for
* transmission, and so the code word is complemented before it is returned.
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
static uint8_t
linear2ulaw(
int16_t pcm_val) /* 2's complement (16-bit range) */
{
uint8_t mask;
uint8_t seg;
uint8_t uval;

/* if someone has passed in a bum short (e.g. they manipulated an
* int rather than a short, so the value looks positive, not
* negative) fix that */
#if 0
if(pcm_val & 0x8000)
{
pcm_val = - (~pcm_val & 0x7fff) - 1;
}
#endif

/* Get the sign and the magnitude of the value. */
if (pcm_val < 0)
{
pcm_val = BIAS - pcm_val;
mask = 0x7F;
}
else
{
pcm_val += BIAS;
mask = 0xFF;
}

/* Convert the scaled magnitude to segment number. */
seg = search(pcm_val, seg_end, 8);

/*
* Combine the sign, segment, quantization bits;
* and complement the code word.
*/
if (seg >= 8) /* out of range, return maximum value. */
return (0x7F ^ mask);
else
{
uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
return (uval ^ mask);
}

}

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧