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; }
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; } }