python c example2:pylame2

#include <Python.h>
#include <lame.h>

//pyton object variables
typedef struct{
    PyObject_HEAD
    FILE *outfp;
    lame_global_flags *gfp;
} pylame2_EncoderObject;


static PyObject *Encoder_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
    pylame2_EncoderObject *self = (pylame2_EncoderObject *)type->tp_alloc(type, 0);
    self->outfp = NULL;
    self->gfp = NULL;
    return (PyObject *)self;
}

static void Encoder_dealloc(pylame2_EncoderObject *self)
{
    if(self->gfp)
    {
        lame_close(self->gfp);
    }
    if(self->outfp)
    {
        fclose(self->outfp);
    }
    self->ob_type->tp_free(self);
}

static int Encoder_init(pylame2_EncoderObject * self, PyObject *args, PyObject *kw)
{
    char *outpath;
    if(!PyArg_ParseTuple(args, "s", &outpath))
    {
        return -1;
    }
    if(self->outfp || self->gfp)
    {
        PyErr_SetString(PyExc_Exception, "__init__ already called");
        return -1;
    }
    self->outfp = fopen(outpath, "wb");
    self->gfp = lame_init();
    lame_init_params(self->gfp);
    return 0;
}

static PyObject *Encoder_encode(pylame2_EncoderObject *self, PyObject *args)
{
    char *in_buffer;
    int in_length;
    int mp3_length;
    char *mp3_buffer;
    int mp3_bytes;
    if(!(self->outfp && self->gtp))
    {
        PyErr_SetString(PyExc_Exception, "encoder not open");
        return NULL;
    }
    if(!PyArg_ParseTuple(args, "s#", &in_buffer, &in_length))
    {
        return NULL;
    }
    in_length /=2;
    mp3_length = (int)(1.25 * in_length) + 7200;
    mp3_buffer = (char*)malloc(mp3_length);
    if(in_length > 0)
    {
        mp3_bytes = lame_encode_buffer_interleaved(
            self->gtp,
            (short *)in_buffer,
            in_length / 2,
            mp3_buffer,
            mp3_length
        );
        if(mpe3_bytes > 0)
        {
            fwrite(mp3_buffer, 1, mp3_bytes, self->outfp);
        }
    }
    free(mp3_buffer);
    Py_RETURN_NONE;
}
static PyObject *Encoder_close(pylame2_EncoderObject * self)
{
    int mp3_length;
    char * mp3_buffer;
    int mpe3_bytes;
    if(!(self->outfp && self->gfp))
    {
        PyErr_SetString(PyExc_Exception, "encoder not open");
        return NULL;
    }
    mp3_length = 7200;
    mp3_buffer = (char*)malloc(mp3_length);
    mp3_bytes = lame_encode_flush(self->gfp, mp3_buffer, sizeof(mp3_buffer));
    if(mp3_bytes > 0)
    {
        fwrite(mp3_buffer, 1, mp3_bytes, self->outfp);
    }
    free(mp3_buffer);
    lame_close(self->gfp);
    self->gfp = NULL;
    fclose(self->outfp);
    self->outfp = NULL;
    Py_RETURN_NONE;
}
static PyMethodDef Encoder_methods[] ={
    {"encode", (PyCFunction)Encoder_encode, METH_VARARGS, "Encodes and writes data to the output file."},
    {"close", (PyCFunction)Encoder_close, METH_NOARGS, "Closes the output file."},
    {NULL, NULL, 0, NULL}
};
static PyTypeObject pylame2_EncoderType = {
    PyObject_HEAD_INIT(NULL)
    0,                                  /* ob_size */
    "pylame2.Encoder",                  /* tp_name */
    sizeof(pylame2_EncoderObject),      /* tp_basicsize */
    0,                                  /* tp_itemsize */
    (destructor)Encoder_dealloc,        /* tp_dealloc */
    0,                                  /* tp_print */
    0,                                  /* tp_getattr */
    0,                                  /* tp_setattr */
    0,                                  /* tp_compare */
    0,                                  /* tp_repr */
    0,                                  /* tp_as_number */
    0,                                  /* tp_as_sequence */
    0,                                  /* tp_as_mapping */
    0,                                  /* tp_hash */
    0,                                  /* tp_call */
    0,                                  /* tp_str */
    0,                                  /* tp_getattro */
    0,                                  /* tp_setattro */
    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
    "My first encoder object.",         /* tp_doc */
    0,                                  /* tp_traverse */
    0,                                  /* tp_clear */
    0,                                  /* tp_richcompare */
    0,                                  /* tp_weaklistoffset */
    0,                                  /* tp_iter */
    0,                                  /* tp_iternext */
    Encoder_methods,                    /* tp_methods */
    0,                                  /* tp_members */
    0,                                  /* tp_getset */
    0,                                  /* tp_base */
    0,                                  /* tp_dict */
    0,                                  /* tp_descr_get */
    0,                                  /* tp_descr_set */
    0,                                  /* tp_dictoffset */
    (initproc)Encoder_init,             /* tp_init */
    0,                                  /* tp_alloc */
    Encoder_new,                        /* tp_new */
    0,                                  /* tp_free */
};

static PyMethodDef pylame2_methods[] = {
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC initpylame2(){
    PyObject *m;
    if(PyType_Ready(&pylame2_EncoderType) < 0)
    {
        return;
    }
    m = Py_InitModule3("pylame2", pylame2_methods, "My Second LAME module.");
    Py_INCREF(&pylame2_EncoderType);
    PyModule_AddObject(m, "Encoder", (PyObject *)&pylame2_EncoderType);
};

/*
    gcc -shared -I/usr/include/pytyon3.1 -I/usr/include/lame pylame2.c -lmp3lame -o pylame2.so
*/
/*python code
    import pylame2

    INBUFSIZE = 4096

    encoder = pylame2.Encoder('test.mp3')
    input = file('test.raw', 'rb')
    data = input.read(INBUFSIZE)

    while data != '':
        encoder.encode(data)
        data = input.read(INBUFSIZE)

    input.close()
    encoder.close()
*/

 use the python object's methods in c code

#include <Python.h>
#include <lame.h>

//pyton object variables
typedef struct{
    PyObject_HEAD
    //FILE *outfp;
    PyObject *outfp;
    lame_global_flags *gfp;
} pylame2_EncoderObject;


static PyObject *Encoder_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
    pylame2_EncoderObject *self = (pylame2_EncoderObject *)type->tp_alloc(type, 0);
    self->outfp = NULL;
    self->gfp = NULL;
    return (PyObject *)self;
}

static void Encoder_dealloc(pylame2_EncoderObject *self)
{
    if(self->gfp)
    {
        lame_close(self->gfp);
    }
    /*
    if(self->outfp)
    {
        fclose(self->outfp);
    }*/
    Py_XDECREF(self->outfp);
    self->ob_type->tp_free(self);
}

static int Encoder_init(pylame2_EncoderObject * self, PyObject *args, PyObject *kw)
{
    //char *outpath;
    PyObject *outfp;
    if(!PyArg_ParseTuple(args, "O", &outfp))
    {
        return -1;
    }
    if(self->outfp || self->gfp)
    {
        PyErr_SetString(PyExc_Exception, "__init__ already called");
        return -1;
    }
    //self->outfp = fopen(outpath, "wb");
    self->outfp = outfp;
    Py_INCREF(self->outfp);
    self->gfp = lame_init();
    lame_init_params(self->gfp);
    return 0;
}

static PyObject *Encoder_encode(pylame2_EncoderObject *self, PyObject *args)
{
    char *in_buffer;
    int in_length;
    int mp3_length;
    char *mp3_buffer;
    int mp3_bytes;
    if(!(self->outfp && self->gtp))
    {
        PyErr_SetString(PyExc_Exception, "encoder not open");
        return NULL;
    }

    if(!PyArg_ParseTuple(args, "s#", &in_buffer, &in_length))
    {
        return NULL;
    }
    in_length /=2;
    mp3_length = (int)(1.25 * in_length) + 7200;
    mp3_buffer = (char*)malloc(mp3_length);

    if(in_length > 0)
    {
        mp3_bytes = lame_encode_buffer_interleaved(
            self->gtp,
            (short *)in_buffer,
            in_length / 2,
            mp3_buffer,
            mp3_length
        );
        if(mpe3_bytes > 0)
        {
            //fwrite(mp3_buffer, 1, mp3_bytes, self->outfp);
            PyObject * write_result = PyObject_CallMethod(self->outfp, "write", "(s#)", mp3_buffer, mp3_bytes);
            if(!write_result)
            {
                free(mp3_buffer);
                return NULL;
            }
            Py_DECREF(write_result);
        }
    }
   // free(mp3_buffer);
   // Py_RETURN_NONE;
}
static PyObject *Encoder_close(pylame2_EncoderObject * self)
{
    int mp3_length;
    char * mp3_buffer;
    int mpe3_bytes;
    if(!(self->outfp && self->gfp))
    {
        PyErr_SetString(PyExc_Exception, "encoder not open");
        return NULL;
    }
    mp3_length = 7200;
    mp3_buffer = (char*)malloc(mp3_length);
    mp3_bytes = lame_encode_flush(self->gfp, mp3_buffer, sizeof(mp3_buffer));
    if(mp3_bytes > 0)
    {
        fwrite(mp3_buffer, 1, mp3_bytes, self->outfp);
    }
    free(mp3_buffer);
    lame_close(self->gfp);
    self->gfp = NULL;
    fclose(self->outfp);
    self->outfp = NULL;
    Py_RETURN_NONE;
}
static PyMethodDef Encoder_methods[] ={
    {"encode", (PyCFunction)Encoder_encode, METH_VARARGS, "Encodes and writes data to the output file."},
    {"close", (PyCFunction)Encoder_close, METH_NOARGS, "Closes the output file."},
    {NULL, NULL, 0, NULL}
};
static PyTypeObject pylame2_EncoderType = {
    PyObject_HEAD_INIT(NULL)
    0,                                  /* ob_size */
    "pylame2.Encoder",                  /* tp_name */
    sizeof(pylame2_EncoderObject),      /* tp_basicsize */
    0,                                  /* tp_itemsize */
    (destructor)Encoder_dealloc,        /* tp_dealloc */
    0,                                  /* tp_print */
    0,                                  /* tp_getattr */
    0,                                  /* tp_setattr */
    0,                                  /* tp_compare */
    0,                                  /* tp_repr */
    0,                                  /* tp_as_number */
    0,                                  /* tp_as_sequence */
    0,                                  /* tp_as_mapping */
    0,                                  /* tp_hash */
    0,                                  /* tp_call */
    0,                                  /* tp_str */
    0,                                  /* tp_getattro */
    0,                                  /* tp_setattro */
    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
    "My first encoder object.",         /* tp_doc */
    0,                                  /* tp_traverse */
    0,                                  /* tp_clear */
    0,                                  /* tp_richcompare */
    0,                                  /* tp_weaklistoffset */
    0,                                  /* tp_iter */
    0,                                  /* tp_iternext */
    Encoder_methods,                    /* tp_methods */
    0,                                  /* tp_members */
    0,                                  /* tp_getset */
    0,                                  /* tp_base */
    0,                                  /* tp_dict */
    0,                                  /* tp_descr_get */
    0,                                  /* tp_descr_set */
    0,                                  /* tp_dictoffset */
    (initproc)Encoder_init,             /* tp_init */
    0,                                  /* tp_alloc */
    Encoder_new,                        /* tp_new */
    0,                                  /* tp_free */
};

static PyMethodDef pylame2_methods[] = {
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC initpylame2(){
    PyObject *m;
    if(PyType_Ready(&pylame2_EncoderType) < 0)
    {
        return;
    }
    m = Py_InitModule3("pylame2", pylame2_methods, "My Second LAME module.");
    Py_INCREF(&pylame2_EncoderType);
    PyModule_AddObject(m, "Encoder", (PyObject *)&pylame2_EncoderType);
};

/*
    gcc -shared -I/usr/include/pytyon3.1 -I/usr/include/lame pylame2.c -lmp3lame -o pylame2.so
*/
/*python code
    import pylame2

    INBUFSIZE = 4096

    class MyFile(file):
        def __init__(self, path, mode):
            file.__init__(self, path, mode)
            self.n = 0

        def write(self, s):
            file.write(self, s)
            self.n += 1

    output = MyFile('test3.mp3', 'wb')
    encoder = pylame2.Encoder(output)
    input = file('test.raw', 'rb')

    data = input.read(INBUFSIZE)
    while data !='':
        encoder.encode(data)
        data = input.read(INBUFSIE)

    input.close()
    encoder.close()
    output.close()

    print("output.write was called %d times" % output.n)
*/

 

posted @ 2018-04-01 12:57  在左手  阅读(232)  评论(0编辑  收藏  举报