Exemplo n.º 1
0
static PyObject*
DVDA_Title_read(decoders_DVDA_Title *self, PyObject *args)
{
    DVDA_Packet next_packet;
    struct bs_buffer* packet_data = self->packet_data;
    mlp_status mlp_status;

    /*if track has been exhausted, return empty FrameList*/
    if (!self->pcm_frames_remaining) {
        return empty_FrameList(self->audiotools_pcm,
                               self->channel_count,
                               self->bits_per_sample);
    }

    /*otherwise, build FrameList from PCM or MLP packet data*/
    switch (self->frame_codec) {
    case PCM:
        /*if not enough bytes in buffer, read another packet*/
        while (aobpcm_packet_empty(&(self->pcm_decoder), self->frames)) {
            if (read_audio_packet(self->packet_reader,
                                  &next_packet, packet_data)) {
                PyErr_SetString(PyExc_IOError, "I/O reading PCM packet");
                return NULL;
            }

            /*FIXME - ensure packet has same format as PCM*/

            buf_extend(packet_data, self->frames);
        }

        /*FIXME - make this thread friendly*/
        read_aobpcm(&(self->pcm_decoder), self->frames, self->codec_framelist);
        break;
    case MLP:
        /*if not enough bytes in buffer, read another packet*/
        while (mlp_packet_empty(self->mlp_decoder)) {
            if (read_audio_packet(self->packet_reader,
                                  &next_packet, packet_data)) {
                PyErr_SetString(PyExc_IOError, "I/O reading MLP packet");
                return NULL;
            }

            /*FIXME - ensure packet has same format as MLP*/

            buf_extend(packet_data, self->frames);
        }

        /*FIXME - make this thread friendly*/
        if ((mlp_status = read_mlp_frames(self->mlp_decoder,
                                          self->codec_framelist)) != OK) {
            PyErr_SetString(mlp_python_exception(mlp_status),
                            mlp_python_exception_msg(mlp_status));
            return NULL;
        }
    }

    /*account for framelists larger than frames remaining*/
    self->codec_framelist->cross_split(self->codec_framelist,
                                       MIN(self->pcm_frames_remaining,
                                           self->codec_framelist->_[0]->len),
                                       self->output_framelist,
                                       self->codec_framelist);

    /*deduct output FrameList's PCM frames from remaining count*/
    self->pcm_frames_remaining -= self->output_framelist->_[0]->len;

    /*and return output FrameList*/
    return aa_int_to_FrameList(self->audiotools_pcm,
                               self->output_framelist,
                               self->bits_per_sample);
}
Exemplo n.º 2
0
/*the OpusDecoder.read() method*/
static PyObject*
OpusDecoder_read(decoders_OpusDecoder* self, PyObject *args)
{
    static opus_int16 pcm[BUF_SIZE];
    int pcm_frames_read;

    if (self->closed) {
        PyErr_SetString(PyExc_ValueError, "stream is closed");
        return NULL;
    }

    if ((pcm_frames_read = op_read(self->opus_file,
                                   pcm,
                                   BUF_SIZE,
                                   NULL)) >= 0) {
        const int channel_count = op_head(self->opus_file, -1)->channel_count;
        aa_int *channels = self->channels;
        int c;

        channels->reset(channels);

        /*split buffer by channel*/
        for (c = 0; c < channel_count; c++) {
            a_int *channel = channels->append(channels);
            int i;

            channel->resize(channel, pcm_frames_read);
            for (i = 0; i < pcm_frames_read; i++) {
                a_append(channel, pcm[c + (i * channel_count)]);
            }
        }

        /*reorder channels to .wav order if necessary*/
        switch (channel_count) {
        case 1:
        case 2:
        default:
            /*no change*/
            break;
        case 3:
            /*fL fC fR -> fL fR fC*/
            a_int_swap(channels->_[1], channels->_[2]);
            break;
        case 4:
            /*fL fR bL bR -> fL fR bL bR*/
            /*no change*/
            break;
        case 5:
            /*fL fC fR bL bR -> fL fR fC bL bR*/
            a_int_swap(channels->_[1], channels->_[2]);
            break;
        case 6:
            /*fL fC fR bL bR LFE -> fL fR fC bL bR LFE*/
            a_int_swap(channels->_[1], channels->_[2]);

            /*fL fR fC bL bR LFE -> fL fR fC LFE bR bL*/
            a_int_swap(channels->_[3], channels->_[5]);

            /*fL fR fC LFE bR bL -> fL fR fC LFE bL bR*/
            a_int_swap(channels->_[4], channels->_[5]);
            break;
        case 7:
            /*fL fC fR sL sR bC LFE -> fL fR fC sL sR bC LFE*/
            a_int_swap(channels->_[1], channels->_[2]);

            /*fL fR fC sL sR bC LFE -> fL fR fC LFE sR bC sL*/
            a_int_swap(channels->_[3], channels->_[6]);

            /*fL fR fC LFE sR bC sL -> fL fR fC LFE bC sR sL*/
            a_int_swap(channels->_[4], channels->_[5]);

            /*fL fR fC LFE bC sR sL -> fL fR fC LFE bC sL sR*/
            a_int_swap(channels->_[5], channels->_[6]);
            break;
        case 8:
            /*fL fC fR sL sR bL bR LFE -> fL fR fC sL sR bL bR LFE*/
            a_int_swap(channels->_[1], channels->_[2]);

            /*fL fR fC sL sR bL bR LFE -> fL fR fC LFE sR bL bR sL*/
            a_int_swap(channels->_[3], channels->_[6]);

            /*fL fR fC LFE sR bL bR sL -> fL fR fC LFE bL sR bR sL*/
            a_int_swap(channels->_[4], channels->_[5]);

            /*fL fR fC LFE bL sR bR sL -> fL fR fC LFE bL bR sR sL*/
            a_int_swap(channels->_[5], channels->_[6]);

            /*fL fR fC LFE bL bR sR sL -> fL fR fC LFE bL bR sL sR*/
            a_int_swap(channels->_[6], channels->_[7]);
            break;
        }

        /*return new FrameList object*/
        return aa_int_to_FrameList(self->audiotools_pcm,
                                   channels,
                                   16);
    } else {
        /*some sort of read error occurred*/
        PyErr_SetString(PyExc_ValueError, "error reading from file");
        return NULL;
    }
}