Example #1
0
ogg_status
oggreader_next_packet(OggReader *reader, BitstreamReader *packet) {
    ogg_status result;
    uint8_t segment_length;

    br_substream_reset(packet);
    do {
        result = oggreader_next_segment(reader, packet, &segment_length);
    } while ((result == OGG_OK) && (segment_length == 255));

    return result;
}
Example #2
0
int
flacdec_read_metadata(BitstreamReader *bitstream,
                      struct flac_STREAMINFO *streaminfo,
                      a_obj *seektable,
                      int *channel_mask)
{
    BitstreamReader *comment = br_substream_new(BS_LITTLE_ENDIAN);

    enum {
        fL =  0x1,
        fR =  0x2,
        fC =  0x4,
        LFE = 0x8,
        bL =  0x10,
        bR =  0x20,
        bC =  0x100,
        sL =  0x200,
        sR =  0x400
    };

    if (!setjmp(*br_try(bitstream))) {
        unsigned last_block;

        if (bitstream->read(bitstream, 32) != 0x664C6143u) {
#ifndef STANDALONE
            PyErr_SetString(PyExc_ValueError, "not a FLAC file");
#endif
            br_etry(bitstream);
            comment->close(comment);
            return 1;
        }

        do {
            last_block = bitstream->read(bitstream, 1);
            const unsigned block_type = bitstream->read(bitstream, 7);
            const unsigned block_length = bitstream->read(bitstream, 24);

            switch (block_type) {
            case 0:   /*STREAMINFO*/
                streaminfo->minimum_block_size =
                    bitstream->read(bitstream, 16);
                streaminfo->maximum_block_size =
                    bitstream->read(bitstream, 16);
                streaminfo->minimum_frame_size =
                    bitstream->read(bitstream, 24);
                streaminfo->maximum_frame_size =
                    bitstream->read(bitstream, 24);
                streaminfo->sample_rate =
                    bitstream->read(bitstream, 20);
                streaminfo->channels =
                    bitstream->read(bitstream, 3) + 1;
                streaminfo->bits_per_sample =
                    bitstream->read(bitstream, 5) + 1;
                streaminfo->total_samples =
                    bitstream->read_64(bitstream, 36);

                bitstream->read_bytes(bitstream, streaminfo->md5sum, 16);

                /*default channel mask based on channel count*/
                switch (streaminfo->channels) {
                case 1:
                    *channel_mask = fC;
                    break;
                case 2:
                    *channel_mask = fL | fR;
                    break;
                case 3:
                    *channel_mask = fL | fR | fC;
                    break;
                case 4:
                    *channel_mask = fL | fR | bL | bR;
                    break;
                case 5:
                    *channel_mask = fL | fR | fC | bL | bR;
                    break;
                case 6:
                    *channel_mask = fL | fR | fC | LFE | bL | bR;
                    break;
                case 7:
                    *channel_mask = fL | fR | fC | LFE | bC | sL | sR;
                    break;
                case 8:
                    *channel_mask = fL | fR | fC | LFE | bL | bR | sL | sR;
                    break;
                default:
                    /*shouldn't be able to happen*/
                    *channel_mask = 0;
                    break;
                }
                break;
            case 3: /*SEEKTABLE*/
                {
                    unsigned seekpoints = block_length / 18;
                    seektable->reset_for(seektable, seekpoints);

                    for (; seekpoints > 0; seekpoints--) {
                        struct flac_SEEKPOINT seekpoint;
                        seekpoint.sample_number =
                            bitstream->read_64(bitstream, 64);
                        seekpoint.byte_offset =
                            bitstream->read_64(bitstream, 64);
                        seekpoint.samples =
                            bitstream->read(bitstream, 16);
                        seektable->append(seektable, &seekpoint);
                    }
                }
                break;
            case 4: /*VORBIS_COMMENT*/
                {
                    /*Vorbis comment's channel mask - if any -
                      overrides default one from channel count */

                    br_substream_reset(comment);
                    bitstream->substream_append(bitstream,
                                                comment,
                                                block_length);

                    flacdec_read_vorbis_comment(comment,
                                                streaminfo->channels,
                                                channel_mask);
                }
                break;
            default:  /*all other blocks*/
                bitstream->skip(bitstream, block_length * 8);
                break;
            }
        } while (!last_block);

        br_etry(bitstream);
        comment->close(comment);
        return 0;
    } else {
#ifndef STANDALONE
        PyErr_SetString(PyExc_IOError, "EOF while reading metadata");
#endif
        br_etry(bitstream);
        comment->close(comment);
        return 1;
    }
}