Example #1
0
static PyObject*
ALACDecoder_read(decoders_ALACDecoder* self, PyObject *args)
{
    pcm_FrameList *framelist;
    status_t status;
    unsigned pcm_frames_read;

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

    if (self->read_pcm_frames >= self->total_pcm_frames) {
        return empty_FrameList(self->audiotools_pcm,
                               self->channels,
                               self->bits_per_sample);
    }

    /*build FrameList based on alac decoding parameters*/
    framelist = new_FrameList(self->audiotools_pcm,
                              self->channels,
                              self->bits_per_sample,
                              self->params.block_size);

    /*decode ALAC frameset to FrameList*/
    if (!setjmp(*br_try(self->bitstream))) {
        status = decode_frameset(self,
                                 &pcm_frames_read,
                                 framelist->samples);
        br_etry(self->bitstream);
    } else {
        br_etry(self->bitstream);
        Py_DECREF((PyObject*)framelist);
        PyErr_SetString(PyExc_IOError, "I/O error reading stream");
        return NULL;
    }

    if (status != OK) {
        Py_DECREF((PyObject*)framelist);
        PyErr_SetString(alac_exception(status), alac_strerror(status));
        return NULL;
    }

    /*constrain FrameList to actual amount of PCM frames read
      which may be less than block size at the end of stream*/
    framelist->frames = pcm_frames_read;
    framelist->samples_length = pcm_frames_read * self->channels;

    /*reorder FrameList to .wav order*/
    reorder_channels(pcm_frames_read,
                     self->channels,
                     framelist->samples);

    self->read_pcm_frames += pcm_frames_read;

    /*return populated FrameList*/
    return (PyObject*)framelist;
}
static PyObject*
MP3Decoder_read(decoders_MP3Decoder* self, PyObject *args)
{
    pcm_FrameList *framelist;
    int *samples;
    static int16_t buffer[BUFFER_SIZE];
    size_t buffer_size;
    size_t i;

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

    /*perform mpg123_read() to output buffer*/
    switch (mpg123_read(self->handle,
                        (unsigned char*)buffer,
                        BUFFER_SIZE,
                        &buffer_size)) {
    case MPG123_DONE:
        /*return empty framelist*/
        return empty_FrameList(self->audiotools_pcm,
                               self->channels,
                               16);
    case MPG123_OK:
        framelist = new_FrameList(self->audiotools_pcm,
                                  self->channels,
                                  BITS_PER_SAMPLE,
                                  (unsigned)(buffer_size / 2 / self->channels));

        samples = framelist->samples;

        for (i = 0; i < (buffer_size / 2); i++) {
            samples[i] = buffer[i];
        }

        return (PyObject*)framelist;
    default:
        /*raise exception*/
        PyErr_SetString(PyExc_ValueError, "error decoding MP3 frame");
        return NULL;
    }
}
Example #3
0
PyObject*
FlacDecoder_read(decoders_FlacDecoder* self, PyObject *args)
{
    uint16_t crc16 = 0;
    int channel;
    struct flac_frame_header frame_header;
    PyObject* framelist;
    PyThreadState *thread_state;
    flac_status error;

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

    self->subframe_data->reset(self->subframe_data);

    /*if all samples have been read, return an empty FrameList*/
    if (self->stream_finalized) {
        return empty_FrameList(self->audiotools_pcm,
                               self->streaminfo.channels,
                               self->streaminfo.bits_per_sample);
    }

    if (self->remaining_samples < 1) {
        self->stream_finalized = 1;

        if (FlacDecoder_verify_okay(self)) {
            return empty_FrameList(self->audiotools_pcm,
                                   self->streaminfo.channels,
                                   self->streaminfo.bits_per_sample);
        } else {
            PyErr_SetString(PyExc_ValueError,
                            "MD5 mismatch at end of stream");
            return NULL;
        }
    }

    thread_state = PyEval_SaveThread();

    if (!setjmp(*br_try(self->bitstream))) {
        /*add callback for CRC16 calculation*/
        br_add_callback(self->bitstream, (bs_callback_f)flac_crc16, &crc16);

        /*read frame header*/
        if ((error = flacdec_read_frame_header(self->bitstream,
                                               &(self->streaminfo),
                                               &frame_header)) != OK) {
            br_pop_callback(self->bitstream, NULL);
            PyEval_RestoreThread(thread_state);
            PyErr_SetString(PyExc_ValueError, FlacDecoder_strerror(error));
            br_etry(self->bitstream);
            return NULL;
        }

        /*read 1 subframe per channel*/
        for (channel = 0; channel < frame_header.channel_count; channel++)
            if ((error =
                 flacdec_read_subframe(
                     self->bitstream,
                     self->qlp_coeffs,
                     self->residuals,
                     (unsigned int)MIN(frame_header.block_size,
                                       self->remaining_samples),
                     flacdec_subframe_bits_per_sample(&frame_header,
                                                      channel),
                     self->subframe_data->append(self->subframe_data))) != OK) {
                br_pop_callback(self->bitstream, NULL);
                PyEval_RestoreThread(thread_state);
                PyErr_SetString(PyExc_ValueError, FlacDecoder_strerror(error));
                br_etry(self->bitstream);
                return NULL;
            }

        /*handle difference channels, if any*/
        flacdec_decorrelate_channels(frame_header.channel_assignment,
                                     self->subframe_data,
                                     self->framelist_data);

        /*check CRC-16*/
        self->bitstream->byte_align(self->bitstream);
        self->bitstream->read(self->bitstream, 16);
        br_pop_callback(self->bitstream, NULL);
        if (crc16 != 0) {
            PyEval_RestoreThread(thread_state);
            PyErr_SetString(PyExc_ValueError, "invalid checksum in frame");
            br_etry(self->bitstream);
            return NULL;
        }

        /*decrement remaining samples*/
        self->remaining_samples -= frame_header.block_size;
    } else {
        /*handle I/O error during read*/
        br_pop_callback(self->bitstream, NULL);
        PyEval_RestoreThread(thread_state);
        PyErr_SetString(PyExc_IOError, "EOF reading frame");
        br_etry(self->bitstream);
        return NULL;
    }

    br_etry(self->bitstream);
    PyEval_RestoreThread(thread_state);

    framelist = array_i_to_FrameList(self->audiotools_pcm,
                                     self->framelist_data,
                                     frame_header.channel_count,
                                     frame_header.bits_per_sample);
    if (framelist != NULL) {
        /*update MD5 sum*/
        if (FlacDecoder_update_md5sum(self, framelist) == OK)
            /*return pcm.FrameList Python object*/
            return framelist;
        else {
            Py_DECREF(framelist);
            return NULL;
        }
    } else {
        return NULL;
    }
}
Example #4
0
static PyObject*
ALACDecoder_read(decoders_ALACDecoder* self, PyObject *args)
{
    unsigned channel_count;
    BitstreamReader* mdat = self->bitstream;
    array_ia* frameset_channels = self->frameset_channels;
    PyThreadState *thread_state;

    /*return an empty framelist if total samples are exhausted*/
    if (self->remaining_frames == 0) {
        return empty_FrameList(self->audiotools_pcm,
                               self->channels,
                               self->bits_per_sample);
    }

    thread_state = PyEval_SaveThread();

    if (!setjmp(*br_try(mdat))) {
        frameset_channels->reset(frameset_channels);

        /*get initial frame's channel count*/
        channel_count = mdat->read(mdat, 3) + 1;
        while (channel_count != 8) {
            /*read a frame from the frameset into "channels"*/
            if (read_frame(self, mdat,
                           frameset_channels, channel_count) != OK) {
                br_etry(mdat);
                PyEval_RestoreThread(thread_state);
                PyErr_SetString(PyExc_ValueError, self->error_message);
                return NULL;
            } else {
                /*ensure all frames have the same sample count*/
                /*FIXME*/

                /*read the channel count of the next frame
                  in the frameset, if any*/
                channel_count = mdat->read(mdat, 3) + 1;
            }
        }

        /*once all the frames in the frameset are read,
          byte-align the output stream*/
        mdat->byte_align(mdat);
        br_etry(mdat);
        PyEval_RestoreThread(thread_state);

        /*decrement the remaining sample count*/
        self->remaining_frames -= MIN(self->remaining_frames,
                                      frameset_channels->_[0]->len);

        /*convert ALAC channel assignment to standard audiotools assignment*/
        alac_order_to_wave_order(frameset_channels);

        /*finally, build and return framelist object from the sample data*/
        return array_ia_to_FrameList(self->audiotools_pcm,
                                     frameset_channels,
                                     self->bits_per_sample);
    } else {
        br_etry(mdat);
        PyEval_RestoreThread(thread_state);
        PyErr_SetString(PyExc_IOError, "EOF during frame reading");
        return NULL;
    }
}
Example #5
0
static PyObject*
OggFlacDecoder_read(decoders_OggFlacDecoder *self, PyObject *args) {
    ogg_status ogg_status;
    flac_status flac_status;
    struct flac_frame_header frame_header;
    int channel;
    PyObject *framelist;
    PyThreadState *thread_state;

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

    self->subframe_data->reset(self->subframe_data);

    /*if all samples have been read, return an empty FrameList*/
    if (self->stream_finalized) {
        return empty_FrameList(self->audiotools_pcm,
                               self->streaminfo.channels,
                               self->streaminfo.bits_per_sample);
    }

    thread_state = PyEval_SaveThread();
    ogg_status = oggreader_next_packet(self->ogg_stream, self->packet);
    PyEval_RestoreThread(thread_state);

    if (ogg_status == OGG_OK) {
        /*decode the next FrameList from the stream*/

        thread_state = PyEval_SaveThread();
        self->crc16 = 0;

        if (!setjmp(*br_try(self->packet))) {
            /*read frame header*/
            if ((flac_status =
                 flacdec_read_frame_header(self->packet,
                                           &(self->streaminfo),
                                           &frame_header)) != OK) {
                PyEval_RestoreThread(thread_state);
                PyErr_SetString(PyExc_ValueError,
                                FlacDecoder_strerror(flac_status));
                br_etry(self->packet);
                return NULL;
            }

            /*read 1 subframe per channel*/
            for (channel = 0; channel < frame_header.channel_count; channel++)
                if ((flac_status = flacdec_read_subframe(
                        self->packet,
                        self->qlp_coeffs,
                        self->residuals,
                        frame_header.block_size,
                        flacdec_subframe_bits_per_sample(&frame_header,
                                                         channel),
                        self->subframe_data->append(self->subframe_data))) !=
                    OK) {
                    PyEval_RestoreThread(thread_state);
                    PyErr_SetString(PyExc_ValueError,
                                    FlacDecoder_strerror(flac_status));
                    br_etry(self->packet);
                    return NULL;
                }

            br_etry(self->packet);

            /*handle difference channels, if any*/
            flacdec_decorrelate_channels(frame_header.channel_assignment,
                                         self->subframe_data,
                                         self->framelist_data);

            /*check CRC-16*/
            self->packet->byte_align(self->packet);
            self->packet->read(self->packet, 16);
            if (self->crc16 != 0) {
                PyEval_RestoreThread(thread_state);
                PyErr_SetString(PyExc_ValueError, "invalid checksum in frame");
                return NULL;
            }

            PyEval_RestoreThread(thread_state);

            framelist = a_int_to_FrameList(self->audiotools_pcm,
                                           self->framelist_data,
                                           frame_header.channel_count,
                                           frame_header.bits_per_sample);

            if (framelist != NULL) {
                /*update MD5 sum*/
                if (OggFlacDecoder_update_md5sum(self, framelist) == 1)
                    /*return pcm.FrameList Python object*/
                    return framelist;
                else {
                    Py_DECREF(framelist);
                    return NULL;
                }
            } else {
                return NULL;
            }
        } else {
            /*read error decoding FLAC frame*/
            PyEval_RestoreThread(thread_state);
            PyErr_SetString(PyExc_IOError, "I/O error decoding FLAC frame");
            br_etry(self->packet);
            return NULL;
        }
    } else if (ogg_status == OGG_STREAM_FINISHED) {
        /*Ogg stream is finished so verify stream's MD5 sum
          then return an empty FrameList if it matches correctly*/

        if (OggFlacDecoder_verify_okay(self)) {
            self->stream_finalized = 1;
            return empty_FrameList(self->audiotools_pcm,
                                   self->streaminfo.channels,
                                   self->streaminfo.bits_per_sample);
        } else {
            PyErr_SetString(PyExc_ValueError,
                            "MD5 mismatch at end of stream");
            return NULL;
        }
    } else {
        /*error reading the next Ogg packet,
          so raise the appropriate exception*/
        PyErr_SetString(ogg_exception(ogg_status), ogg_strerror(ogg_status));
        return NULL;
    }
}
Example #6
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);
}
static PyObject*
VorbisDecoder_read(decoders_VorbisDecoder *self, PyObject *args) {
    int current_bitstream;
    long samples_read;
    float **pcm_channels;

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

    samples_read = ov_read_float(&(self->vorbisfile),
                                 &pcm_channels,
                                 4096,
                                 &current_bitstream);

    if (samples_read >= 0) {
        /*convert floating point samples to integer-based ones*/
        pcm_FrameList *framelist;
        int *samples;
        int c;

        if (samples_read == 0) {
            if (self->vorbisfile.os.e_o_s == 0) {
                /*EOF encountered without EOF being marked in stream*/
                PyErr_SetString(PyExc_IOError,
                                "I/O error reading from Ogg stream");
                return NULL;
            } else {
                return empty_FrameList(self->audiotools_pcm,
                                       self->channel_count,
                                       BITS_PER_SAMPLE);
            }
        }

        framelist = new_FrameList(self->audiotools_pcm,
                                  self->channel_count,
                                  BITS_PER_SAMPLE,
                                  (unsigned)samples_read);

        samples = framelist->samples;

        for (c = 0; c < self->channel_count; c++) {
            int channel[samples_read];

            float_to_int_converter(BITS_PER_SAMPLE)(
                (unsigned)samples_read,
                pcm_channels[c],
                channel);

            put_channel_data(samples,
                             c,
                             self->channel_count,
                             (unsigned)samples_read,
                             channel);
        }

        /*reorder channels to .wav order if necessary*/
        switch (self->channel_count) {
        case 1:
        case 2:
        default:
            /*no change*/
            break;
        case 3:
            /*fL fC fR -> fL fR fC*/
            swap_channel_data(samples, 1, 2,
                              self->channel_count, (unsigned)samples_read);
            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*/
            swap_channel_data(samples, 1, 2,
                              self->channel_count, (unsigned)samples_read);
            break;
        case 6:
            /*fL fC fR bL bR LFE -> fL fR fC bL bR LFE*/
            swap_channel_data(samples, 1, 2,
                              self->channel_count, (unsigned)samples_read);

            /*fL fR fC bL bR LFE -> fL fR fC LFE bR bL*/
            swap_channel_data(samples, 3, 5,
                              self->channel_count, (unsigned)samples_read);

            /*fL fR fC LFE bR bL -> fL fR fC LFE bL bR*/
            swap_channel_data(samples, 4, 5,
                              self->channel_count, (unsigned)samples_read);
            break;
        case 7:
            /*fL fC fR sL sR bC LFE -> fL fR fC sL sR bC LFE*/
            swap_channel_data(samples, 1, 2,
                              self->channel_count, (unsigned)samples_read);

            /*fL fR fC sL sR bC LFE -> fL fR fC LFE sR bC sL*/
            swap_channel_data(samples, 3, 6,
                              self->channel_count, (unsigned)samples_read);

            /*fL fR fC LFE sR bC sL -> fL fR fC LFE bC sR sL*/
            swap_channel_data(samples, 4, 5,
                              self->channel_count, (unsigned)samples_read);

            /*fL fR fC LFE bC sR sL -> fL fR fC LFE bC sL sR*/
            swap_channel_data(samples, 5, 6,
                              self->channel_count, (unsigned)samples_read);
            break;
        case 8:
            /*fL fC fR sL sR bL bR LFE -> fL fR fC sL sR bL bR LFE*/
            swap_channel_data(samples, 1, 2,
                              self->channel_count, (unsigned)samples_read);

            /*fL fR fC sL sR bL bR LFE -> fL fR fC LFE sR bL bR sL*/
            swap_channel_data(samples, 3, 6,
                              self->channel_count, (unsigned)samples_read);

            /*fL fR fC LFE sR bL bR sL -> fL fR fC LFE bL sR bR sL*/
            swap_channel_data(samples, 4, 5,
                              self->channel_count, (unsigned)samples_read);

            /*fL fR fC LFE bL sR bR sL -> fL fR fC LFE bL bR sR sL*/
            swap_channel_data(samples, 5, 6,
                              self->channel_count, (unsigned)samples_read);

            /*fL fR fC LFE bL bR sR sL -> fL fR fC LFE bL bR sL sR*/
            swap_channel_data(samples, 6, 7,
                              self->channel_count, (unsigned)samples_read);
            break;
        }

        return (PyObject*)framelist;
    } else {
        switch (samples_read) {
        case OV_HOLE:
            PyErr_SetString(PyExc_ValueError, "data interruption detected");
            return NULL;
        case OV_EBADLINK:
            PyErr_SetString(PyExc_ValueError, "invalid stream section");
            return NULL;
        case OV_EINVAL:
            PyErr_SetString(PyExc_ValueError, "initial file headers corrupt");
            return NULL;
        default:
            PyErr_SetString(PyExc_ValueError, "unspecified error");
            return NULL;
        }
    }
}