static int read_packet (OGGZ * oggz, oggz_packet * zp, long serialno, void * user_data) { ogg_packet * op = &zp->op; static int iter = 0; static long b_o_s = 1; static long e_o_s = 0; #ifdef DEBUG printf ("%08" PRI_OGGZ_OFF_T "x: serialno %010lu, " "granulepos %" PRId64 ", packetno %" PRId64, oggz_tell (oggz), serialno, op->granulepos, op->packetno); if (op->b_o_s) { printf (" *** bos"); } if (op->e_o_s) { printf (" *** eos"); } printf ("\n"); #endif if (op->bytes != 1) FAIL ("Packet too long"); if (op->packet[0] != 'a' + iter) FAIL ("Packet contains incorrect data"); if ((op->b_o_s == 0) != (b_o_s == 0)) FAIL ("Packet has incorrect b_o_s"); if ((op->e_o_s == 0) != (e_o_s == 0)) FAIL ("Packet has incorrect e_o_s"); if (op->granulepos != -1 && op->granulepos != iter) FAIL ("Packet has incorrect granulepos"); if (op->packetno != iter) FAIL ("Packet has incorrect packetno"); iter++; b_o_s = 0; if (iter == 10) { e_o_s = 1; } else if (iter == 11) { iter = 0; b_o_s = 1; e_o_s = 0; } return 0; }
int main (int argc, char ** argv) { FILE * f; OGGZ * oggz; long n; ogg_int64_t units; if (argc < 2) { printf ("usage: %s filename\n", argv[0]); } if ((f = fopen ((char *)argv[1], "rb")) == NULL) { printf ("unable to open file %s\n", argv[1]); exit (1); } if ((oggz = oggz_new (OGGZ_READ | OGGZ_AUTO)) == NULL) { printf ("unable to create oggz\n"); exit (1); } oggz_io_set_read (oggz, my_io_read, f); oggz_io_set_seek (oggz, my_io_seek, f); oggz_io_set_tell (oggz, my_io_tell, f); oggz_set_read_callback (oggz, -1, read_packet, NULL); while ((n = oggz_read (oggz, 1024)) > 0); units = oggz_tell_units (oggz); printf ("Total length: %" PRId64 " ms\n", units); oggz_seek_units (oggz, units/2, SEEK_SET); printf ("seeked to byte offset %" PRId64 "\n", oggz_tell (oggz)); while ((n = oggz_read (oggz, 1024)) > 0); oggz_close (oggz); exit (0); }
int speex_dec_open(decoder_t * dec, char * filename) { speex_pdata_t * pd = (speex_pdata_t *)dec->pdata; file_decoder_t * fdec = dec->fdec; int enh = 1; char ogg_sig[4]; long length_in_bytes = 0; long length_in_samples = 0; if ((pd->speex_file = fopen(filename, "rb")) == NULL) { fprintf(stderr, "speex_decoder_open: fopen() failed\n"); return DECODER_OPEN_FERROR; } if (fread(ogg_sig, 1, 4, pd->speex_file) != 4) { fprintf(stderr, "couldn't read OGG signature from %s\n", filename); return DECODER_OPEN_FERROR; } if ((ogg_sig[0] != 'O') || (ogg_sig[1] != 'g') || (ogg_sig[2] != 'g') || (ogg_sig[3] != 'S')) { /* not an OGG stream */ fclose(pd->speex_file); return DECODER_OPEN_BADLIB; } if ((pd->oggz = oggz_open(filename, OGGZ_READ | OGGZ_AUTO)) == NULL) { printf("nonexistent or unaccessible file %s\n", filename); return DECODER_OPEN_FERROR; } oggz_set_read_callback(pd->oggz, -1, read_ogg_packet, dec); pd->packetno = 0; pd->exploring = 1; pd->error = 0; while (pd->packetno < 2) { /* process Speex header and comments */ oggz_read(pd->oggz, 1024); } if (pd->error != 0) { printf("Error opening Speex\n"); oggz_close(pd->oggz); return DECODER_OPEN_BADLIB; } /* parse ogg packets till eof to get the last granulepos */ while (oggz_read(pd->oggz, 1024) > 0) ; length_in_bytes = oggz_tell(pd->oggz); oggz_close(pd->oggz); speex_bits_destroy(&(pd->bits)); speex_decoder_destroy(pd->decoder); if ((pd->channels != 1) && (pd->channels != 2)) { printf("Sorry, Ogg Speex with %d channels is unsupported\n", pd->channels); return DECODER_OPEN_FERROR; } pd->packetno = 0; pd->exploring = 0; pd->error = 0; pd->oggz = oggz_open(filename, OGGZ_READ | OGGZ_AUTO); oggz_set_read_callback(pd->oggz, -1, read_ogg_packet, dec); speex_bits_init(&(pd->bits)); pd->decoder = speex_decoder_init(pd->mode); speex_decoder_ctl(pd->decoder, SPEEX_SET_ENH, &enh); pd->is_eos = 0; pd->rb = rb_create(pd->channels * sample_size * RB_SPEEX_SIZE); fdec->fileinfo.channels = pd->channels; fdec->fileinfo.sample_rate = pd->sample_rate; length_in_samples = pd->granulepos + pd->nframes - 1; fdec->fileinfo.total_samples = length_in_samples; fdec->fileinfo.bps = 8 * length_in_bytes / (length_in_samples / pd->sample_rate); fdec->file_lib = SPEEX_LIB; strcpy(dec->format_str, "Ogg Speex"); return DECODER_OPEN_SUCCESS; }