使用C语言扩展Python(三)

简介:
上一篇中我们已经了解如何在Python程序和C模块之间进行值的相互传递,现在我们来进入实作阶段,看看如何将一个C语言开发的开源mp3编解码库LAME包装为一个Python下可以使用的扩展模块。
首先去http://lame.sourceforge.net/download.php下载LAME的源代码,然后切换到root用户编译源代码,
./configure
make
make install
安装完成后你可以在/usr/local/include/lame目录下找到lame.h头文件,我们在后面的demo程序中会include它的,下面就是一个非常简单的lame示例程序lame_test.c:

复制代码
代码
#include <stdio.h>
#include <stdlib.h>
#include <lame.h>

#define INBUFSIZE 4096
#define MP3BUFSIZE (int) (1.25 * INBUFSIZE) + 7200

int encode(char* inPath, char* outPath) {
    int status = 0;
    lame_global_flags* gfp;
    int ret_code;
    FILE* infp;
    FILE* outfp;
    short* input_buffer;
    int input_samples;
    char* mp3_buffer;
    int mp3_bytes;
    
    gfp = lame_init();
    if (gfp == NULL) {
        printf("lame_init failed\n");
        status = -1;
        goto exit;
    }
    
    ret_code = lame_init_params(gfp);
    if (ret_code < 0) {
        printf("lame_init_params returned %d\n",ret_code);
        status = -1;
        goto close_lame;
    }

    infp = fopen(inPath, "rb");
    outfp = fopen(outPath, "wb");
    
    input_buffer = (short*)malloc(INBUFSIZE*2);
    mp3_buffer = (char*)malloc(MP3BUFSIZE);
    
    do{
        input_samples = fread(input_buffer, 2, INBUFSIZE, infp);
        mp3_bytes = lame_encode_buffer_interleaved(gfp, input_buffer,input_samples/2, mp3_buffer, MP3BUFSIZE);
        if (mp3_bytes < 0) {
            printf("lame_encode_buffer_interleaved returned %d\n", mp3_bytes);
            status = -1;
            goto free_buffers;
        } else if(mp3_bytes > 0) {
            fwrite(mp3_buffer, 1, mp3_bytes, outfp);
        }
    }while (input_samples == INBUFSIZE);
    
    mp3_bytes = lame_encode_flush(gfp, mp3_buffer, sizeof(mp3_buffer));
    if (mp3_bytes > 0) {
        printf("writing %d mp3 bytes\n", mp3_bytes);
        fwrite(mp3_buffer, 1, mp3_bytes, outfp);
    }
free_buffers:
    free(mp3_buffer);
    free(input_buffer);
    
    fclose(outfp);
    fclose(infp);
close_lame:
    lame_close(gfp);
exit:
    return status;
}

int main(int argc, char** argv) {
    if (argc < 3) {
        printf("usage: lame_test rawinfile mp3outfile\n");
    }
    encode(argv[1], argv[2]);
    return 0;
}
复制代码
编译步骤:

gcc -I /usr/local/include/lame lame_test.c -lmp3lame -o lame_test
试验准备:

首先需要一个test.wav文件,先安装sox来将wav文件转为raw格式的数据:

    sudo apt-get install sox
    sox test.wav -t raw test.raw
 

然后执行lame_test来对其进行mp3编码:

./lame_test ./test.raw ./test.mp3 
好了,现在我们要在这个c程序的基础上将其包装为一个Python扩展模块。下面的pylame.c就是简单地调用lame_test.c中定义的encode方法,然后通过它对外部的python程序提高mp3编码的服务

复制代码
代码
#include <Python.h>
#include <lame.h>

int encode(char* ,char*);

static PyObject * pylame_encode(PyObject* self, PyObject* args) {
    int status;
    char* inPath;
    char* outPath;
    if (!PyArg_ParseTuple(args, "ss", &inPath, &outPath)) {        
        return NULL;
    }
    status = encode(inPath, outPath);
    return Py_BuildValue("i", status);
}

static PyMethodDef pylame_methods[] = {
    {"encode", pylame_encode, METH_VARARGS, NULL},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC initpylame() {
    Py_InitModule3("pylame", pylame_methods, "an simple lame module.");
}
复制代码
模块编译步骤:

gcc -shared -I /usr/include/python2.6 -I /usr/local/include/lame/ pylame.c lame_test.c -lmp3lame -o pylame.so
ok,现在lame扩展模块已经封装好了,可以到python程序中进行调用了。在pylame.so所在目录下新建一个python文件lame1.py代码如下:

import pylame

if __name__ == '__main__':
    inPath = './test.raw'
    outPath = './test.mp3'
    pylame.encode(inPath, outPath)
编译执行: 

python ./lame1.py
你会发现生成了一个test.mp3,打开听听看是否是你想要的歌曲呢,呵呵。。。 


本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2010/05/22/1741667.html,如需转载请自行联系原作者
目录
相关文章
|
3月前
|
Unix 编译器 Shell
[oeasy]python0033_先有操作系统还是先有编程语言_c语言是怎么来的
本文回顾了计算机语言与操作系统的起源,探讨了早期 Unix 操作系统及其与 C 语言的相互促进发展。Unix 最初用汇编语言编写,运行在 PDP-7 上,后来 Thompson 和 Ritchie 开发了 C 语言及编译器,使 Unix 重写并成功编译。1974 年 Ritchie 发表论文,Unix 开始被学术界关注,并逐渐普及。伯克利分校也在此过程中发挥了重要作用,推动了 Unix 和 C 语言的广泛传播。
71 9
[oeasy]python0033_先有操作系统还是先有编程语言_c语言是怎么来的
|
15天前
|
Unix 编译器 C语言
[oeasy]python052_[系统开发语言为什么默认是c语言
本文介绍了C语言为何成为系统开发的首选语言,从其诞生背景、发展历史及特点进行阐述。C语言源于贝尔实验室,与Unix操作系统相互促进,因其简洁、高效、跨平台等特性,逐渐成为主流。文章还提及了C语言的学习资料及其对编程文化的影响。
24 5
|
1月前
|
缓存 监控 测试技术
Python中的装饰器:功能扩展与代码复用的利器###
本文深入探讨了Python中装饰器的概念、实现机制及其在实际开发中的应用价值。通过生动的实例和详尽的解释,文章展示了装饰器如何增强函数功能、提升代码可读性和维护性,并鼓励读者在项目中灵活运用这一强大的语言特性。 ###
|
3月前
|
Python
Python--turtle库科赫雪花的扩展
使用Python的turtle库创建科赫雪花,并加入随机阶数、尺寸、位置和颜色的功能,每次运行生成不同图像。
Python--turtle库科赫雪花的扩展
|
2月前
|
机器学习/深度学习 缓存 PyTorch
pytorch学习一(扩展篇):miniconda下载、安装、配置环境变量。miniconda创建多版本python环境。整理常用命令(亲测ok)
这篇文章是关于如何下载、安装和配置Miniconda,以及如何使用Miniconda创建和管理Python环境的详细指南。
550 0
pytorch学习一(扩展篇):miniconda下载、安装、配置环境变量。miniconda创建多版本python环境。整理常用命令(亲测ok)
|
2月前
|
机器学习/深度学习 物联网 数据处理
C语言用于物联网更合适还是python
选择 C 语言还是 Python 作为物联网(IoT)开发的语言取决于多个因素,包括项目的性质、资源限制、性能需求以及开发团队的技能水平。C 语言性能优越,适合资源受限的嵌入式设备,能直接访问硬件,广泛应用于底层开发,但开发复杂且容易出错。Python 则以其简单的语法和丰富的库支持快速开发和原型制作,适合跨平台应用和数据处理,但性能较低,资源占用较大。根据项目需求,性能和资源要求高时选择 C 语言,需快速开发和易于维护时选择 Python。
|
2月前
|
Python
Python扩展TimedRotatingFileHandler
【10月更文挑战第7天】 python log执行扩展压缩功能
63 0
|
2月前
|
编译器 C语言
初识C语言:扩展世界观,选择语句之行
初识C语言:扩展世界观,选择语句之行
|
3月前
|
存储 缓存 API
比较一下 Python、C、C 扩展、Cython 之间的差异
比较一下 Python、C、C 扩展、Cython 之间的差异
54 0
|
3月前
|
SQL 关系型数据库 C语言
PostgreSQL SQL扩展 ---- C语言函数(三)
可以用C(或者与C兼容,比如C++)语言编写用户自定义函数(User-defined functions)。这些函数被编译到动态可加载目标文件(也称为共享库)中并被守护进程加载到服务中。“C语言函数”与“内部函数”的区别就在于动态加载这个特性,二者的实际编码约定本质上是相同的(因此,标准的内部函数库为用户自定义C语言函数提供了丰富的示例代码)