int main(int argc, char *argv[]) { /*perform simple round-trip using page reader and writer*/ BitstreamReader *reader = br_open(stdin, BS_LITTLE_ENDIAN); BitstreamWriter *writer = bw_open(stdout, BS_LITTLE_ENDIAN); struct ogg_page page; do { ogg_status result; if ((result = read_ogg_page(reader, &page)) == OGG_OK) { write_ogg_page(writer, &page); } else { fprintf(stderr, "*** Error: %s", ogg_strerror(result)); goto error; } } while (!page.header.stream_end); reader->close(reader); writer->close(writer); return 0; error: reader->close(reader); writer->close(writer); return 1; }
int main(int argc, char *argv[]) { FILE *f = fopen(argv[1], "rb"); OggReader *reader = oggreader_open(f); BitstreamReader *packet = bs_substream_new(BS_LITTLE_ENDIAN); ogg_status result; do { result = oggreader_next_packet(reader, packet); if (result < 0) { fprintf(stderr, "Error : %s\n", ogg_error(result)); } else if (result == OGG_OK) { printf("packet size %u\n", packet->input.substream->buffer_size); } } while (result == OGG_OK); packet->close(packet); oggreader_close(reader); fclose(f); return 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; } }
int main(int argc, char* argv[]) { FILE* ogg_file; OggReader* ogg_stream = NULL; BitstreamReader* packet = NULL; struct flac_STREAMINFO streaminfo; uint16_t header_packets; a_int* residuals = NULL; a_int* qlp_coeffs = NULL; aa_int* subframe_data = NULL; a_int* framelist_data = NULL; ogg_status result; uint16_t crc16 = 0; FrameList_int_to_char_converter converter; unsigned pcm_size; unsigned output_data_size = 1; uint8_t* output_data = NULL; audiotools__MD5Context md5; unsigned char stream_md5sum[16]; const static unsigned char blank_md5sum[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; if (argc < 2) { fprintf(stderr, "*** Usage: %s <file.oga>\n", argv[0]); return 1; } /*open input file for reading*/ if ((ogg_file = fopen(argv[1], "rb")) == NULL) { fprintf(stderr, "*** %s: %s\n", argv[1], strerror(errno)); return 1; } else { /*open bitstream and setup temporary arrays/buffers*/ ogg_stream = oggreader_open(ogg_file); packet = br_substream_new(BS_BIG_ENDIAN); subframe_data = aa_int_new(); residuals = a_int_new(); qlp_coeffs = a_int_new(); framelist_data = a_int_new(); output_data = malloc(output_data_size); } /*the first packet should be the FLAC's STREAMINFO*/ if ((result = oggreader_next_packet(ogg_stream, packet)) == OGG_OK) { if (!oggflac_read_streaminfo(packet, &streaminfo, &header_packets)) { goto error; } else { converter = FrameList_get_int_to_char_converter( streaminfo.bits_per_sample, 0, 1); } } else { fprintf(stderr, "*** Error: %s\n", ogg_strerror(result)); goto error; } /*skip subsequent header packets*/ for (; header_packets > 0; header_packets--) { if ((result = oggreader_next_packet(ogg_stream, packet)) != OGG_OK) { fprintf(stderr, "*** Error: %s\n", ogg_strerror(result)); goto error; } } /*initialize the output MD5 sum*/ audiotools__MD5Init(&md5); /*add callback for CRC16 calculation*/ br_add_callback(packet, (bs_callback_f)flac_crc16, &crc16); /*decode the next FrameList from the stream*/ result = oggreader_next_packet(ogg_stream, packet); while (result != OGG_STREAM_FINISHED) { if (result == OGG_OK) { flac_status flac_status; struct flac_frame_header frame_header; unsigned channel; subframe_data->reset(subframe_data); if (!setjmp(*br_try(packet))) { /*read frame header*/ if ((flac_status = flacdec_read_frame_header(packet, &streaminfo, &frame_header)) != OK) { fprintf(stderr, "*** Error: %s\n", FlacDecoder_strerror(flac_status)); br_etry(packet); goto error; } /*read 1 subframe per channel*/ for (channel = 0; channel < frame_header.channel_count; channel++) if ((flac_status = flacdec_read_subframe( packet, qlp_coeffs, residuals, frame_header.block_size, flacdec_subframe_bits_per_sample(&frame_header, channel), subframe_data->append(subframe_data))) != OK) { fprintf(stderr, "*** Error: %s\n", FlacDecoder_strerror(flac_status)); br_etry(packet); goto error; } br_etry(packet); } else { br_etry(packet); fprintf(stderr, "*** I/O Error reading FLAC frame\n"); goto error; } /*handle difference channels, if any*/ flacdec_decorrelate_channels(frame_header.channel_assignment, subframe_data, framelist_data); /*check CRC-16*/ packet->byte_align(packet); packet->read(packet, 16); if (crc16 != 0) { fprintf(stderr, "*** Error: invalid checksum in frame\n"); goto error; } /*turn FrameList into string of output*/ pcm_size = (streaminfo.bits_per_sample / 8) * framelist_data->len; if (pcm_size > output_data_size) { output_data_size = pcm_size; output_data = realloc(output_data, output_data_size); } FrameList_samples_to_char(output_data, framelist_data->_, converter, framelist_data->len, streaminfo.bits_per_sample); /*update MD5 sum*/ audiotools__MD5Update(&md5, output_data, pcm_size); /*output string to stdout*/ fwrite(output_data, sizeof(unsigned char), pcm_size, stdout); result = oggreader_next_packet(ogg_stream, packet); } else { /*some error reading Ogg stream*/ fprintf(stderr, "*** Error: %s\n", ogg_strerror(result)); goto error; } } /*Ogg stream is finished so verify stream's MD5 sum*/ audiotools__MD5Final(stream_md5sum, &md5); if (!((memcmp(streaminfo.md5sum, blank_md5sum, 16) == 0) || (memcmp(stream_md5sum, streaminfo.md5sum, 16) == 0))) { fprintf(stderr, "*** MD5 mismatch at end of stream\n"); goto error; } /*close streams, temporary buffers*/ oggreader_close(ogg_stream); packet->close(packet); subframe_data->del(subframe_data); residuals->del(residuals); qlp_coeffs->del(qlp_coeffs); framelist_data->del(framelist_data); free(output_data); return 0; error: oggreader_close(ogg_stream); packet->close(packet); subframe_data->del(subframe_data); residuals->del(residuals); qlp_coeffs->del(qlp_coeffs); framelist_data->del(framelist_data); free(output_data); return 1; }
static PyObject* DVDA_Title_next_track(decoders_DVDA_Title *self, PyObject *args) { unsigned PTS_ticks; DVDA_Packet next_packet; struct bs_buffer* packet_data = self->packet_data; unsigned i; if (!PyArg_ParseTuple(args, "I", &PTS_ticks)) return NULL; /*ensure previous track has been exhausted, if any*/ if (self->pcm_frames_remaining) { PyErr_SetString(PyExc_ValueError, "current track has not been exhausted"); return NULL; } /*read the next packet*/ if (read_audio_packet(self->packet_reader, &next_packet, packet_data)) { PyErr_SetString(PyExc_IOError, "I/O error reading initialization packet"); return NULL; } #else int DVDA_Title_next_track(decoders_DVDA_Title *self, unsigned PTS_ticks) { DVDA_Packet next_packet; struct bs_buffer* packet_data = self->packet_data; unsigned i; if (self->pcm_frames_remaining) { fprintf(stderr, "current track has not been exhausted\n"); return 0; } if (read_audio_packet(self->packet_reader, &next_packet, packet_data)) { fprintf(stderr, "I/O error reading initialization packet\n"); return 0; } #endif if (next_packet.codec_ID == PCM_CODEC_ID) { /*if the packet is PCM, initialize Title's stream attributes (bits-per-sample, sample rate, channel assignment/mask) with values taken from the first packet*/ /*PCM stores stream attributes in the second padding block*/ self->bits_per_sample = dvda_bits_per_sample(next_packet.PCM.group_1_bps); self->sample_rate = dvda_sample_rate(next_packet.PCM.group_1_rate); self->channel_assignment = next_packet.PCM.channel_assignment; self->channel_count = dvda_channel_count(next_packet.PCM.channel_assignment); self->channel_mask = dvda_channel_mask(next_packet.PCM.channel_assignment); self->frame_codec = PCM; init_aobpcm_decoder(&(self->pcm_decoder), self->bits_per_sample, self->channel_count); buf_extend(packet_data, self->frames); } else if (next_packet.codec_ID == MLP_CODEC_ID) { /*if the packet is MLP, check if the first frame starts with a major sync*/ enum {PACKET_DATA}; BitstreamReader* r = br_open_buffer(packet_data, BS_BIG_ENDIAN); r->mark(r, PACKET_DATA); if (!setjmp(*br_try(r))) { unsigned sync_words; unsigned stream_type; r->parse(r, "32p 24u 8u", &sync_words, &stream_type); if ((sync_words == 0xF8726F) && (stream_type == 0xBB)) { /*if so, discard any unconsumed packet data and initialize Title's stream attributes with values taken from the major sync*/ unsigned group_1_bps; unsigned group_2_bps; unsigned group_1_rate; unsigned group_2_rate; r->parse(r, "4u 4u 4u 4u 11p 5u 48p", &group_1_bps, &group_2_bps, &group_1_rate, &group_2_rate, &(self->channel_assignment)); self->bits_per_sample = dvda_bits_per_sample(group_1_bps); self->sample_rate = dvda_sample_rate(group_1_rate); self->channel_count = dvda_channel_count(self->channel_assignment); self->channel_mask = dvda_channel_mask(self->channel_assignment); self->frame_codec = MLP; self->mlp_decoder->major_sync_read = 0; r->rewind(r, PACKET_DATA); r->unmark(r, PACKET_DATA); br_etry(r); r->close(r); buf_reset(self->frames); buf_extend(packet_data, self->frames); } else { /*if not, append packet data to any unconsumed data and leave Title's stream attributes as they were*/ r->rewind(r, PACKET_DATA); r->unmark(r, PACKET_DATA); br_etry(r); r->close(r); buf_extend(packet_data, self->frames); } } else { /*if I/O error reading major sync, append packet data to any unconsumed data and leave Title's stream attributes as they were*/ r->rewind(r, PACKET_DATA); r->unmark(r, PACKET_DATA); br_etry(r); r->close(r); buf_extend(packet_data, self->frames); } } else { #ifndef STANDALONE PyErr_SetString(PyExc_ValueError, "unknown codec ID"); return NULL; #else return 0; #endif } /*convert PTS ticks to PCM frames based on sample rate*/ self->pcm_frames_remaining = (unsigned)round((double)PTS_ticks * (double)self->sample_rate / (double)PTS_PER_SECOND); /*initalize codec's framelist with the proper number of channels*/ if (self->codec_framelist->len != self->channel_count) { self->codec_framelist->reset(self->codec_framelist); for (i = 0; i < self->channel_count; i++) self->codec_framelist->append(self->codec_framelist); } #ifndef STANDALONE Py_INCREF(Py_None); return Py_None; #else return 1; #endif }