コード例 #1
0
ファイル: ogg.c プロジェクト: meduz/python-audio-tools
ogg_status
oggreader_read_page_header(BitstreamReader *ogg_stream,
                           struct ogg_page_header *header) {
    int i;
    struct bs_callback callback;

    if (!setjmp(*br_try(ogg_stream))) {
        if ((header->magic_number =
             ogg_stream->read(ogg_stream, 32)) != 0x5367674F) {
            br_etry(ogg_stream);
            return OGG_INVALID_MAGIC_NUMBER;
        }

        if ((header->version = ogg_stream->read(ogg_stream, 8)) != 0) {
            br_etry(ogg_stream);
            return OGG_INVALID_STREAM_VERSION;
        }

        header->type = ogg_stream->read(ogg_stream, 8);
        header->granule_position = ogg_stream->read_64(ogg_stream, 64);
        header->bitstream_serial_number = ogg_stream->read(ogg_stream, 32);
        header->page_sequence_number = ogg_stream->read(ogg_stream, 32);

        /*the checksum field is *not* checksummed itself, naturally
          those 4 bytes are treated as 0*/
        br_pop_callback(ogg_stream, &callback);
        header->checksum = ogg_stream->read(ogg_stream, 32);
        br_push_callback(ogg_stream, &callback);
        br_call_callbacks(ogg_stream, 0);
        br_call_callbacks(ogg_stream, 0);
        br_call_callbacks(ogg_stream, 0);
        br_call_callbacks(ogg_stream, 0);

        header->page_segment_count = ogg_stream->read(ogg_stream, 8);
        header->segment_length_total = 0;
        for (i = 0; i < header->page_segment_count; i++) {
            header->page_segment_lengths[i] = ogg_stream->read(ogg_stream, 8);
            header->segment_length_total += header->page_segment_lengths[i];
        }

        br_etry(ogg_stream);
        return OGG_OK;
    } else {
        br_etry(ogg_stream);
        return OGG_PREMATURE_EOF;
    }
}
コード例 #2
0
ファイル: flac.c プロジェクト: meduz/python-audio-tools
flac_status
flacdec_read_frame_header(BitstreamReader *bitstream,
                          struct flac_STREAMINFO *streaminfo,
                          struct flac_frame_header *header)
{
    unsigned block_size_bits;
    unsigned sample_rate_bits;
    uint8_t crc8 = 0;

    br_add_callback(bitstream, (bs_callback_f)flac_crc8, &crc8);

    /*read and verify sync code*/
    if (bitstream->read(bitstream, 14) != 0x3FFE) {
        return ERR_INVALID_SYNC_CODE;
    }

    /*read and verify reserved bit*/
    if (bitstream->read(bitstream, 1) != 0) {
        return ERR_INVALID_RESERVED_BIT;
    }

    header->blocking_strategy = bitstream->read(bitstream, 1);

    block_size_bits = bitstream->read(bitstream, 4);
    sample_rate_bits = bitstream->read(bitstream, 4);
    header->channel_assignment = bitstream->read(bitstream, 4);
    switch (header->channel_assignment) {
    case 0x8:
    case 0x9:
    case 0xA:
        header->channel_count = 2;
        break;
    default:
        header->channel_count = header->channel_assignment + 1;
        break;
    }

    switch (bitstream->read(bitstream, 3)) {
    case 0:
        header->bits_per_sample = streaminfo->bits_per_sample; break;
    case 1:
        header->bits_per_sample = 8; break;
    case 2:
        header->bits_per_sample = 12; break;
    case 4:
        header->bits_per_sample = 16; break;
    case 5:
        header->bits_per_sample = 20; break;
    case 6:
        header->bits_per_sample = 24; break;
    default:
        return ERR_INVALID_BITS_PER_SAMPLE;
    }
    bitstream->read(bitstream, 1); /*padding*/

    header->frame_number = read_utf8(bitstream);

    switch (block_size_bits) {
    case 0x0: header->block_size = streaminfo->maximum_block_size; break;
    case 0x1: header->block_size = 192; break;
    case 0x2: header->block_size = 576; break;
    case 0x3: header->block_size = 1152; break;
    case 0x4: header->block_size = 2304; break;
    case 0x5: header->block_size = 4608; break;
    case 0x6: header->block_size = bitstream->read(bitstream, 8) + 1; break;
    case 0x7: header->block_size = bitstream->read(bitstream, 16) + 1; break;
    case 0x8: header->block_size = 256; break;
    case 0x9: header->block_size = 512; break;
    case 0xA: header->block_size = 1024; break;
    case 0xB: header->block_size = 2048; break;
    case 0xC: header->block_size = 4096; break;
    case 0xD: header->block_size = 8192; break;
    case 0xE: header->block_size = 16384; break;
    case 0xF: header->block_size = 32768; break;
    }

    switch (sample_rate_bits) {
    case 0x0: header->sample_rate = streaminfo->sample_rate; break;
    case 0x1: header->sample_rate = 88200; break;
    case 0x2: header->sample_rate = 176400; break;
    case 0x3: header->sample_rate = 192000; break;
    case 0x4: header->sample_rate = 8000; break;
    case 0x5: header->sample_rate = 16000; break;
    case 0x6: header->sample_rate = 22050; break;
    case 0x7: header->sample_rate = 24000; break;
    case 0x8: header->sample_rate = 32000; break;
    case 0x9: header->sample_rate = 44100; break;
    case 0xA: header->sample_rate = 48000; break;
    case 0xB: header->sample_rate = 96000; break;
    case 0xC: header->sample_rate = bitstream->read(bitstream, 8) * 1000; break;
    case 0xD: header->sample_rate = bitstream->read(bitstream, 16); break;
    case 0xE: header->sample_rate = bitstream->read(bitstream, 16) * 10; break;
    case 0xF:
        return ERR_INVALID_SAMPLE_RATE;
    }

    /*check for valid CRC-8 value*/
    bitstream->read(bitstream, 8);
    br_pop_callback(bitstream, NULL);
    if (crc8 != 0)
        return ERR_INVALID_FRAME_CRC;

    /*Once we've read everything,
      ensure the values are compatible with STREAMINFO.*/

    if (streaminfo->sample_rate != header->sample_rate) {
        return ERR_SAMPLE_RATE_MISMATCH;
    }
    if (streaminfo->channels != header->channel_count) {
        return ERR_CHANNEL_COUNT_MISMATCH;
    }
    if (streaminfo->bits_per_sample != header->bits_per_sample) {
        return ERR_BITS_PER_SAMPLE_MISMATCH;
    }
    if (header->block_size > streaminfo->maximum_block_size) {
        return ERR_MAXIMUM_BLOCK_SIZE_EXCEEDED;
    }

    return OK;
}
コード例 #3
0
ファイル: flac.c プロジェクト: meduz/python-audio-tools
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;
    }
}
コード例 #4
0
static PyObject*
FlacDecoder_offsets(decoders_FlacDecoder* self, PyObject *args)
{
    int channel;
    struct flac_frame_header frame_header;
    flac_status error;
    PyObject* offsets = PyList_New(0);
    PyObject* offset_pair;
    unsigned long long total_offset = 0;
    unsigned samples;
    unsigned long long offset;

    br_add_callback(self->bitstream,
                    (bs_callback_f)increment_offset,
                    &total_offset);

    while (self->remaining_samples > 0) {
        self->subframe_data->reset(self->subframe_data);
        offset = total_offset;

        if (!setjmp(*br_try(self->bitstream))) {
            /*read frame header*/
            if ((error = flacdec_read_frame_header(self->bitstream,
                                                   &(self->streaminfo),
                                                   &frame_header)) != OK) {
                PyErr_SetString(PyExc_ValueError, FlacDecoder_strerror(error));
                goto error;
            }

            samples = frame_header.block_size;

            /*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) {
                    PyErr_SetString(PyExc_ValueError,
                                    FlacDecoder_strerror(error));
                    goto error;
                }

            /*read CRC-16*/
            self->bitstream->byte_align(self->bitstream);
            self->bitstream->read(self->bitstream, 16);

            /*decrement remaining samples*/
            self->remaining_samples -= frame_header.block_size;

            /*add offset pair to our list*/
            offset_pair = Py_BuildValue("(K, I)", offset, samples);
            PyList_Append(offsets, offset_pair);
            Py_DECREF(offset_pair);
        } else {
            /*handle I/O error during read*/
            PyErr_SetString(PyExc_IOError, "EOF reading frame");
            goto error;
        }

        br_etry(self->bitstream);
    }

    self->stream_finalized = 1;
    br_pop_callback(self->bitstream, NULL);

    return offsets;
error:
    Py_XDECREF(offsets);
    br_etry(self->bitstream);
    br_pop_callback(self->bitstream, NULL);

    return NULL;
}