public void seek_helper(long offst, VorbisFileInstance instance) { //callbacks.seek_func(datasource, offst, SEEK_SET); fseek(datasource, offst, SEEK_SET); this.offset = offst; instance.oy.reset(); }
int open_seekable() { VorbisFileInstance instance = makeInstance(); Info initial_i = new Info(); Comment initial_c = new Comment(); int serialno; long end; int ret; int dataoffset; Page og = new Page(); // is this even vorbis...? int[] foo = new int[1]; ret = fetch_headers(initial_i, initial_c, foo, null, instance); serialno = foo[0]; dataoffset = (int)offset; //!! instance.os.clear(); if (ret == -1) { return(-1); } // we can seek, so set out learning all about this file skable = true; //(callbacks.seek_func)(datasource, 0, SEEK_END); fseek(datasource, 0, SEEK_END); //offset=end=(callbacks.tell_func)(datasource); offset = ftell(datasource); end = offset; // We get the offset for the last page of the physical bitstream. // Most OggVorbis files will contain a single logical bitstream end = get_prev_page(og, instance); // moer than one logical bitstream? if (og.serialno() != serialno) { // Chained bitstream. Bisect-search each logical bitstream // section. Do so based on serial number only if (bisect_forward_serialno(0, 0, end + 1, serialno, 0, instance) < 0) { clear(); return(OV_EREAD); } } else { // Only one logical bitstream if (bisect_forward_serialno(0, end, end + 1, serialno, 0, instance) < 0) { clear(); return(OV_EREAD); } } prefetch_all_headers(initial_i, initial_c, dataoffset, instance); //return(raw_seek(0)); return(0); }
public int get_next_page(Page page, long boundary, VorbisFileInstance instance) { if (boundary > 0) { boundary += offset; } while (true) { int more; if (boundary > 0 && offset >= boundary) { return(OV_FALSE); } more = instance.oy.pageseek(page); if (more < 0) { offset -= more; } else { if (more == 0) { if (boundary == 0) { return(OV_FALSE); } // if(get_data()<=0)return -1; int ret = get_data(instance); if (ret == 0) { return(OV_EOF); } if (ret < 0) { return(OV_EREAD); } } else { int ret = (int)offset; //!!! offset += more; return(ret); } } } }
private int get_prev_page(Page page, VorbisFileInstance instance) { long begin = offset; //!!! int ret; int offst = -1; while (offst == -1) { begin -= CHUNKSIZE; if (begin < 0) { begin = 0; } seek_helper(begin, instance); while (offset < begin + CHUNKSIZE) { ret = get_next_page(page, begin + CHUNKSIZE - offset, instance); if (ret == OV_EREAD) { return(OV_EREAD); } if (ret < 0) { break; } else { offst = ret; } } } seek_helper(offst, instance); //!!! ret = get_next_page(page, CHUNKSIZE, instance); if (ret < 0) { //System.err.println("Missed page fencepost at end of logical bitstream Exiting"); //System.exit(1); return(OV_EFAULT); } return(offst); }
public int get_data(VorbisFileInstance instance) { int index = instance.oy.buffer(CHUNKSIZE); byte[] buffer = instance.oy.data; // int bytes=callbacks.read_func(buffer, index, 1, CHUNKSIZE, datasource); int bytes = 0; try { bytes = datasource.Read(buffer, index, CHUNKSIZE); } catch (Exception e) { Console.Error.WriteLine(e.Message); return(OV_EREAD); } instance.oy.wrote(bytes); if (bytes == -1) { bytes = 0; } return(bytes); }
public VorbisFileInstance makeInstance() { VorbisFileInstance instance = new VorbisFileInstance(this); return(instance); }
// last step of the OggVorbis_File initialization; get all the // vorbis_info structs and PCM positions. Only called by the seekable // initialization (local stream storage is hacked slightly; pay // attention to how that's done) public void prefetch_all_headers(Info first_i, Comment first_c, int dataoffset, VorbisFileInstance instance) { Page og = new Page(); int ret; vi = new Info[links]; vc = new Comment[links]; dataoffsets = new long[links]; pcmlengths = new long[links]; serialnos = new int[links]; for (int i = 0; i < links; i++) { if (first_i != null && first_c != null && i == 0) { // we already grabbed the initial header earlier. This just // saves the waste of grabbing it again // !!!!!!!!!!!!! vi[i] = first_i; //memcpy(vf->vi+i,first_i,sizeof(vorbis_info)); vc[i] = first_c; //memcpy(vf->vc+i,first_c,sizeof(vorbis_comment)); dataoffsets[i] = dataoffset; } else { // seek to the location of the initial header seek_helper(offsets[i], instance); //!!! if (fetch_headers(vi[i], vc[i], null, null, instance) == -1) { Console.Error.WriteLine("Error opening logical bitstream #" + (i + 1) + "\n"); dataoffsets[i] = -1; } else { dataoffsets[i] = offset; instance.os.clear(); } } // get the serial number and PCM length of this link. To do this, // get the last page of the stream long end = offsets[i + 1]; //!!! seek_helper(end, instance); while (true) { ret = get_prev_page(og, instance); if (ret == -1) { // this should not be possible Console.Error.WriteLine("Could not find last page of logical " + "bitstream #" + (i) + "\n"); vi[i].clear(); vc[i].clear(); break; } if (og.granulepos() != -1) { serialnos[i] = og.serialno(); pcmlengths[i] = og.granulepos(); break; } } } }
// uses the local ogg_stream storage in vf; this is important for // non-streaming input sources public int fetch_headers(Info vi, Comment vc, int[] serialno, Page og_ptr, VorbisFileInstance instance) { //System.err.println("fetch_headers"); Page og = new Page(); Packet op = new Packet(); int ret; if (og_ptr == null) { ret = get_next_page(og, CHUNKSIZE, instance); if (ret == OV_EREAD) { return(OV_EREAD); } if (ret < 0) { return(OV_ENOTVORBIS); } og_ptr = og; } if (serialno != null) { serialno[0] = og_ptr.serialno(); } instance.os.init(og_ptr.serialno()); // extract the initial header from the first page and verify that the // Ogg bitstream is in fact Vorbis data vi.init(); vc.init(); int i = 0; while (i < 3) { instance.os.pagein(og_ptr); while (i < 3) { int result = instance.os.packetout(op); if (result == 0) { break; } if (result == -1) { Console.Error.WriteLine("Corrupt header in logical bitstream."); //goto bail_header; vi.clear(); vc.clear(); instance.os.clear(); return(-1); } if (vi.synthesis_headerin(vc, op) != 0) { Console.Error.WriteLine("Illegal header in logical bitstream."); //goto bail_header; vi.clear(); vc.clear(); instance.os.clear(); return(-1); } i++; } if (i < 3) { if (get_next_page(og_ptr, 1, instance) < 0) { Console.Error.WriteLine("Missing header in logical bitstream."); //goto bail_header; vi.clear(); vc.clear(); instance.os.clear(); return(-1); } } } return(0); }
public int bisect_forward_serialno(long begin, long searched, long end, int currentno, int m, VorbisFileInstance instance) { long endsearched = end; long next = end; Page page = new Page(); int ret; while (searched < endsearched) { long bisect; if (endsearched - searched < CHUNKSIZE) { bisect = searched; } else { bisect = (searched + endsearched) / 2; } seek_helper(bisect, instance); ret = get_next_page(page, -1, instance); if (ret == OV_EREAD) { return(OV_EREAD); } if (ret < 0 || page.serialno() != currentno) { endsearched = bisect; if (ret >= 0) { next = ret; } } else { searched = ret + page.header_len + page.body_len; } } seek_helper(next, instance); ret = get_next_page(page, -1, instance); if (ret == OV_EREAD) { return(OV_EREAD); } if (searched >= end || ret == -1) { links = m + 1; offsets = new long[m + 2]; offsets[m + 1] = searched; } else { ret = bisect_forward_serialno(next, offset, end, page.serialno(), m + 1, instance); if (ret == OV_EREAD) { return(OV_EREAD); } } offsets[m] = begin; return(0); }