PCM转PCMA(pcm_alaw,G711.A率)转换表 && PCM转PCMU(pcm_ulaw,G711.U率)转换表

PCM转PCMA(pcm_alaw,G711.A率)转换表 && PCM转PCMU(pcm_ulaw,G711.U率)转换表

ffmpeg源码生成转码表

最近要做一个功能,int16_t的PCM数据转为uint8的PCMA数据,
网上的不太可信,找ffmpeg库,发现ffmpeg库使用的是查表发实现的,
而且还有现成的生成表数据的源代码,可信度非常高

/*
 * Generate a header file for hardcoded PCM tables
 *
 * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <stdlib.h>
#define CONFIG_HARDCODED_TABLES 0
#include "pcm_tablegen.h"
#include "tableprint.h"

int main(void)
{
    pcm_alaw_tableinit();
    pcm_ulaw_tableinit();
    pcm_vidc_tableinit();

    write_fileheader();

    WRITE_ARRAY("static const", uint8_t, linear_to_alaw);
    WRITE_ARRAY("static const", uint8_t, linear_to_ulaw);
    WRITE_ARRAY("static const", uint8_t, linear_to_vidc);

    return 0;
}

编译上有些小问题,没太关注,直接使用了注释大法,
没有用的统统干掉,编译通过,执行生成转换映射表。
不用再去研究转换公式,直接对照着表查询结果即可。
拿走不谢

使用方式

可参照ffmpeg源代码pcm.c使用

    case AV_CODEC_ID_PCM_ALAW:
        for (; n > 0; n--) {
            v      = *samples++;
            *dst++ = linear_to_alaw[(v + 32768) >> 2];
        }
        break;
    case AV_CODEC_ID_PCM_MULAW:
        for (; n > 0; n--) {
            v      = *samples++;
            *dst++ = linear_to_ulaw[(v + 32768) >> 2];
        }
        break;

PCM有符号,加上32768变成正数除以4查表即可。

生成源码

表数据太大,CSDN不让保存,放到我个人服务器上了(大神手下留情不要攻击)。
http://118.126.97.61:8084/src_libs/ffmpeg_pcm_table/

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来示数据库,使用类的实例中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 达式语言: SQLAlchemy 提供了一个丰富的 SQL 达式语言,允许开发者以 Python 达式的方式编写复杂的 SQL 查询。 达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来示数据库,使用类的实例中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 达式语言: SQLAlchemy 提供了一个丰富的 SQL 达式语言,允许开发者以 Python 达式的方式编写复杂的 SQL 查询。 达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
在Java中,可以使用查法来实现PCMAlaw、μlaw之间的格式转换。具体实现步骤如下: 1. 创建一个用于存储PCM数据与Alaw、μlaw数据转换的查数组。 2. 对于PCM数据:将其按照一定的规则进行分段,并分别计算每一段的平均值。 3. 对于Alaw、μlaw数据:根据它们的特定编码规则,计算出对应的PCM值。 4. 将PCM值通过查转换Alaw、μlaw数据。 下面是一个简单的示例代码: ```java public class PcmAlawConverter { private static final int BIAS = 0x84; private static final int MAX = 32635; private static final int[] PCM_TO_ALAW = new int[65536]; private static final int[] PCM_TO_ULAW = new int[65536]; static { for (int i = 0; i < 65536; i++) { PCM_TO_ALAW[i] = encodeAlaw(i); PCM_TO_ULAW[i] = encodeUlaw(i); } } public static byte[] pcmToAlaw(byte[] pcmData) { byte[] alawData = new byte[pcmData.length]; for (int i = 0; i < pcmData.length; i += 2) { short pcm = (short) ((pcmData[i + 1] << 8) | pcmData[i]); int index = pcm + 32768; alawData[i] = (byte) PCM_TO_ALAW[index]; } return alawData; } public static byte[] pcmToUlaw(byte[] pcmData) { byte[] ulawData = new byte[pcmData.length]; for (int i = 0; i < pcmData.length; i += 2) { short pcm = (short) ((pcmData[i + 1] << 8) | pcmData[i]); int index = pcm + 32768; ulawData[i] = (byte) PCM_TO_ULAW[index]; } return ulawData; } private static int encodeAlaw(int pcm) { pcm = pcm >> 3; if (pcm < 0) { pcm = -pcm - 1; pcm ^= 0x7f; } else { pcm ^= 0x55; } int encoded = pcm & 0xff; encoded |= BIAS; return encoded; } private static int encodeUlaw(int pcm) { pcm = pcm >> 2; if (pcm < 0) { pcm = -pcm; pcm |= 0x80; } int exponent = (int) (Math.log(pcm) / Math.log(2)); int mantissa = pcm >> (exponent + 3); int encoded = ~(exponent << 4 | mantissa) & 0xff; return encoded; } } ``` 在这个例子中,我们首先创建了两个查数组`PCM_TO_ALAW`和`PCM_TO_ULAW`,用于存储PCM数据与Alaw、μlaw数据转换的结果。 然后,我们实现了两个方法`pcmToAlaw`和`pcmToUlaw`,用于将PCM数据转换Alaw、μlaw数据。在这两个方法中,我们首先将PCM数据解码成一个short类型的值,然后将其转换成一个在查数组中的索引值,并使用该索引值在查数组中查找对应的Alaw、μlaw数据。 最后,我们实现了两个私有方法`encodeAlaw`和`encodeUlaw`,用于将PCM数据编码成Alaw、μlaw数据。在这两个方法中,我们按照Alaw、μlaw的编码规则,计算出对应的Alaw、μlaw值。 需要注意的是,在Alaw、μlaw数据与PCM数据的转换过程中,需要考虑到字节序的问题,这里我们假设PCM数据是以小端模式存储的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值