/* used to track pcm position without actually performing decode. Useful for sequential 'fast forward' */ static public int vorbis_synthesis_trackonly(ref vorbis_block vb, ref Ogg.ogg_packet op) { vorbis_dsp_state vd = vb.vd; private_state b = vd.backend_state as private_state; vorbis_info vi = vd.vi; codec_setup_info ci = vi.codec_setup as codec_setup_info; Ogg.oggpack_buffer opb = vb.opb; int mode; /* first things first. Make sure decode is ready */ _vorbis_block_ripcord(ref vb); Ogg.oggpack_readinit(ref opb, op.packet, op.bytes); /* Check the packet type */ if (Ogg.oggpack_read(ref opb, 1) != 0) { /* Oops. This is not an audio data packet */ return(OV_ENOTAUDIO); } /* read our mode and pre/post windowsize */ mode = Ogg.oggpack_read(ref opb, b.modebits); if (mode == -1) { return(OV_EBADPACKET); } vb.mode = mode; vb.W = ci.mode_param[mode].blockflag; if (vb.W > 0) { vb.lW = Ogg.oggpack_read(ref opb, 1); vb.nW = Ogg.oggpack_read(ref opb, 1); if (vb.nW == -1) { return(OV_EBADPACKET); } } else { vb.lW = 0; vb.nW = 0; } /* more setup */ vb.granulepos = op.granulepos; vb.sequence = op.packetno; vb.eofflag = op.e_o_s; /* no pcm */ vb.pcmend = 0; vb.pcm = null; return(0); }
/* Is this packet a vorbis ID header? */ static public int vorbis_synthesis_idheader(ref Ogg.ogg_packet op) { Ogg.oggpack_buffer opb = new Ogg.oggpack_buffer(); char[] buffer = new char[6]; if (op == null) { return(0); } Ogg.oggpack_readinit(ref opb, op.packet, op.bytes); if (op.b_o_s == 0) { return(0); /* Not the initial packet */ } if (Ogg.oggpack_read(ref opb, 8) != 1) { return(0); /* Not an ID header */ } _v_readstring(ref opb, ref buffer, 6); if ( buffer[0] != 'v' || buffer[1] != 'o' || buffer[2] != 'r' || buffer[3] != 'b' || buffer[4] != 'i' || buffer[5] != 's' ) { return(0); /* not vorbis */ } return(1); }
static public int vorbis_packet_blocksize(ref vorbis_info vi, ref Ogg.ogg_packet op) { codec_setup_info ci = vi.codec_setup as codec_setup_info; Ogg.oggpack_buffer opb = new Ogg.oggpack_buffer(); int mode; Ogg.oggpack_readinit(ref opb, op.packet, op.bytes); /* Check the packet type */ if (Ogg.oggpack_read(ref opb, 1) != 0) { /* Oops. This is not an audio data packet */ return(OV_ENOTAUDIO); } { int modebits = 0; int v = ci.modes; while (v > 1) { modebits++; v >>= 1; } /* read our mode and pre/post windowsize */ mode = Ogg.oggpack_read(ref opb, modebits); } if (mode == -1) { return(OV_EBADPACKET); } return(ci.blocksizes[ci.mode_param[mode].blockflag]); }
static public int vorbis_synthesis(ref vorbis_block vb, ref Ogg.ogg_packet op) { vorbis_dsp_state vd = (vb != null) ? vb.vd : null; private_state b = (vd != null) ? (vd.backend_state as private_state) : null; vorbis_info vi = (vd != null) ? vd.vi : null; codec_setup_info ci = (vi != null) ? (vi.codec_setup as codec_setup_info) : null; Ogg.oggpack_buffer opb = (vb != null) ? vb.opb : null; int type, mode, i; if (vd == null || b == null || vi == null || ci == null || opb == null) { return(OV_EBADHEADER); } /* first things first. Make sure decode is ready */ _vorbis_block_ripcord(ref vb); Ogg.oggpack_readinit(ref opb, op.packet, op.bytes); /* Check the packet type */ if (Ogg.oggpack_read(ref opb, 1) != 0) { /* Oops. This is not an audio data packet */ return(OV_ENOTAUDIO); } /* read our mode and pre/post windowsize */ mode = Ogg.oggpack_read(ref opb, b.modebits); if (mode == -1) { return(OV_EBADPACKET); } vb.mode = mode; if (ci.mode_param[mode] == null) { return(OV_EBADPACKET); } vb.W = ci.mode_param[mode].blockflag; if (vb.W > 0) { /* this doesn't get mapped through mode selection as it's used only for window selection */ vb.lW = Ogg.oggpack_read(ref opb, 1); vb.nW = Ogg.oggpack_read(ref opb, 1); if (vb.nW == -1) { return(OV_EBADPACKET); } } else { vb.lW = 0; vb.nW = 0; } /* more setup */ vb.granulepos = op.granulepos; vb.sequence = op.packetno; vb.eofflag = op.e_o_s; /* alloc pcm passback storage */ vb.pcmend = ci.blocksizes[vb.W]; vb.pcm = (float **)_vorbis_block_alloc(ref vb, sizeof(float *) * vi.channels); for (i = 0; i < vi.channels; i++) { vb.pcm[i] = (float *)_vorbis_block_alloc(ref vb, sizeof(float) * vb.pcmend); } /* unpack_header enforces range checking */ type = ci.map_type[ci.mode_param[mode].mapping]; return(_mapping_P[type].inverse(ref vb, ci.map_param[ci.mode_param[mode].mapping])); }
/* The Vorbis header is in three packets; the initial small packet in the first page that identifies basic parameters, a second packet * with bitstream comments and a third packet that holds the codebook. */ static public int vorbis_synthesis_headerin(ref vorbis_info vi, ref vorbis_comment vc, ref Ogg.ogg_packet op) { Ogg.oggpack_buffer opb = new Ogg.oggpack_buffer(); Ogg.oggpack_readinit(ref opb, op.packet, op.bytes); /* Which of the three types of header is this? */ /* Also verify header-ness, vorbis */ { char[] buffer = new char[6]; int packtype = Ogg.oggpack_read(ref opb, 8); _v_readstring(ref opb, ref buffer, 6); if ( buffer[0] != 'v' || buffer[1] != 'o' || buffer[2] != 'r' || buffer[3] != 'b' || buffer[4] != 'i' || buffer[5] != 's' ) { /* not a vorbis header */ return(OV_ENOTVORBIS); } switch (packtype) { case 0x01: /* least significant *bit* is read first */ { if (op.b_o_s == 0) { /* Not the initial packet */ return(OV_EBADHEADER); } if (vi.rate != 0) { /* previously initialized info header */ return(OV_EBADHEADER); } } return(_vorbis_unpack_info(ref vi, ref opb)); case 0x03: /* least significant *bit* is read first */ { if (vi.rate == 0) { /* um... we didn't get the initial header */ return(OV_EBADHEADER); } } return(_vorbis_unpack_comment(ref vc, ref opb)); case 0x05: /* least significant *bit* is read first */ { if (vi.rate == 0 || vc.vendor == null) { /* um... we didn;t get the initial header or comments yet */ return(OV_EBADHEADER); } } return(_vorbis_unpack_books(ref vi, ref opb)); default: { /* Not a valid vorbis header type */ return(OV_EBADHEADER); } } } }
static void ClipTest(uint[] b, int vals, int bits, uint[] comp, int compsize) { int bytes; byte *buffer; Ogg.oggpack_reset(ref o); for (int i = 0; i < vals; i++) { Ogg.oggpack_write(ref o, b[i], bits > 0 ? bits : iLog(b[i])); } buffer = Ogg.oggpack_get_buffer(ref o); bytes = Ogg.oggpack_bytes(ref o); if (bytes != compsize) { throw new Exception("wrong number of bytes!"); } for (int i = 0; i < bytes; i++) { if (buffer[i] != comp[i]) { for (int j = 0; j < bytes; j++) { Console.WriteLine(buffer[j] + " , " + comp[j]); } throw new Exception("wrote incorrect value!"); } } Ogg.oggpack_readinit(ref r, buffer, bytes); for (int i = 0; i < vals; i++) { int tbit = bits > 0 ? bits : iLog(b[i]); if (Ogg.oggpack_look(ref r, tbit) == -1) { throw new Exception("out of data!"); } if (Ogg.oggpack_look(ref r, tbit) != (b[i] & mask[tbit])) { throw new Exception("looked at incorrect value!"); } if (tbit == 1) { if (Ogg.oggpack_look1(ref r) != (b[i] & mask[tbit])) { throw new Exception("looked at single bit incorrect value!"); } } if (tbit == 1) { if (Ogg.oggpack_read1(ref r) != (b[i] & mask[tbit])) { throw new Exception("read incorrect single bit value!"); } } else if (Ogg.oggpack_read(ref r, tbit) != (b[i] & mask[tbit])) { throw new Exception("read incorrect value!"); } } if (Ogg.oggpack_bytes(ref r) != bytes) { throw new Exception("leftover bytes after read!"); } }
static public void Test() { byte *buffer; int bytes = 0; /* Test read/write together */ /* Later we test against pregenerated bitstreams */ Ogg.oggpack_writeinit(ref o); Console.Write("Small preclipped packing (LSb): "); ClipTest(testBuffer1, testSize1, 0, one, oneSize); Console.WriteLine("ok."); Console.Write("Null bit call (LSb): "); ClipTest(testBuffer3, testSize3, 0, two, twoSize); Console.WriteLine("ok."); Console.Write("Large preclipped packing (LSb): "); ClipTest(testBuffer2, testSize2, 0, three, threeSize); Console.WriteLine("ok."); Console.Write("32 bit precliiped packing (LSb): "); { Ogg.oggpack_reset(ref o); for (int i = 0; i < testSize2; i++) { Ogg.oggpack_write(ref o, large[i], 32); } buffer = Ogg.oggpack_get_buffer(ref o); bytes = Ogg.oggpack_bytes(ref o); Ogg.oggpack_readinit(ref r, buffer, bytes); for (int i = 0; i < testSize2; i++) { if (Ogg.oggpack_look(ref r, 32) == -1) { throw new Exception("out of data. failed!"); } if (Ogg.oggpack_look(ref r, 32) != large[i]) { throw new Exception("read incorrect value! " + Ogg.oggpack_look(ref r, 32) + " != " + large[1]); } Ogg.oggpack_adv(ref r, 32); } if (Ogg.oggpack_bytes(ref r) != bytes) { throw new Exception("leftover bytes after read!"); } Console.WriteLine("ok."); } Console.Write("Small unclipped packing (LSb): "); ClipTest(testBuffer1, testSize1, 7, four, fourSize); Console.WriteLine("ok."); Console.Write("Large unclipped packing (LSb): "); ClipTest(testBuffer2, testSize2, 17, five, fiveSize); Console.WriteLine("ok."); Console.Write("Single bit unclipped packing (LSb): "); ClipTest(testBuffer3, testSize3, 1, six, sixSize); Console.WriteLine("ok."); Console.Write("Testing read past end (LSb): "); { byte *temp = (byte *)Ogg._ogg_malloc(8); try { for (int i = 0; i < 8; i++) { temp[i] = 0; } Ogg.oggpack_readinit(ref r, temp, 8); for (int i = 0; i < 64; i++) { if (Ogg.oggpack_read(ref r, 1) != 0) { throw new Exception("failed; got -1 prematurely."); } } if (Ogg.oggpack_look(ref r, 1) != -1 || Ogg.oggpack_read(ref r, 1) != -1) { throw new Exception("failed; read past end without -1"); } for (int i = 0; i < 8; i++) { temp[i] = 0; } Ogg.oggpack_readinit(ref r, temp, 8); if (Ogg.oggpack_read(ref r, 30) != 0 || Ogg.oggpack_read(ref r, 16) != 0) { throw new Exception("failed 2; got -1 prematurely."); } if (Ogg.oggpack_look(ref r, 18) != 0 || Ogg.oggpack_look(ref r, 18) != 0) { throw new Exception("failed 3; got -1 prematurely."); } if (Ogg.oggpack_look(ref r, 19) != -1 || Ogg.oggpack_look(ref r, 19) != -1) { throw new Exception("failed 3; got -1 prematurely."); } if (Ogg.oggpack_look(ref r, 32) != -1 || Ogg.oggpack_look(ref r, 32) != -1) { throw new Exception("failed 3; got -1 prematurely."); } Ogg.oggpack_writeclear(ref o); Console.WriteLine("ok."); } finally { Ogg._ogg_free(temp); } } /********** lazy, cut-n-paste retest with MSb packing ***********/ /* Test read/write together */ /* Later we test against pregenerated bitstreams */ Ogg.oggpackB_writeinit(ref o); Console.Write("Small preclipped packing (MSb): "); ClipTestB(testBuffer1, testSize1, 0, oneB, oneSize); Console.WriteLine("ok."); Console.Write("Null bit call (LSb): "); ClipTestB(testBuffer3, testSize3, 0, twoB, twoSize); Console.WriteLine("ok."); Console.Write("Large preclipped packing (LSb): "); ClipTestB(testBuffer2, testSize2, 0, threeB, threeSize); Console.WriteLine("ok."); Console.Write("32 bit precliiped packing (LSb): "); { Ogg.oggpackB_reset(ref o); for (int i = 0; i < testSize2; i++) { Ogg.oggpackB_write(ref o, large[i], 32); } buffer = Ogg.oggpackB_get_buffer(ref o); bytes = Ogg.oggpackB_bytes(ref o); Ogg.oggpackB_readinit(ref r, buffer, bytes); for (int i = 0; i < testSize2; i++) { if (Ogg.oggpackB_look(ref r, 32) == -1) { throw new Exception("out of data. failed!"); } if (Ogg.oggpackB_look(ref r, 32) != large[i]) { throw new Exception("read incorrect value! " + Ogg.oggpackB_look(ref r, 32) + " != " + large[1]); } Ogg.oggpackB_adv(ref r, 32); } if (Ogg.oggpackB_bytes(ref r) != bytes) { throw new Exception("leftover bytes after read!"); } Console.WriteLine("ok."); } Console.Write("Small unclipped packing (LSb): "); ClipTestB(testBuffer1, testSize1, 7, fourB, fourSize); Console.WriteLine("ok."); Console.Write("Large unclipped packing (LSb): "); ClipTestB(testBuffer2, testSize2, 17, fiveB, fiveSize); Console.WriteLine("ok."); Console.Write("Single bit unclipped packing (LSb): "); ClipTestB(testBuffer3, testSize3, 1, sixB, sixSize); Console.WriteLine("ok."); Console.Write("Testing read past end (LSb): "); { byte *temp = (byte *)Ogg._ogg_malloc(8); try { for (int i = 0; i < 8; i++) { temp[i] = 0; } Ogg.oggpackB_readinit(ref r, temp, 8); for (int i = 0; i < 64; i++) { if (Ogg.oggpackB_read(ref r, 1) != 0) { throw new Exception("failed; got -1 prematurely."); } } if (Ogg.oggpackB_look(ref r, 1) != -1 || Ogg.oggpackB_read(ref r, 1) != -1) { throw new Exception("failed; read past end without -1"); } for (int i = 0; i < 8; i++) { temp[i] = 0; } Ogg.oggpackB_readinit(ref r, temp, 8); if (Ogg.oggpackB_read(ref r, 30) != 0 || Ogg.oggpackB_read(ref r, 16) != 0) { throw new Exception("failed 2; got -1 prematurely."); } if (Ogg.oggpackB_look(ref r, 18) != 0 || Ogg.oggpackB_look(ref r, 18) != 0) { throw new Exception("failed 3; got -1 prematurely."); } if (Ogg.oggpackB_look(ref r, 19) != -1 || Ogg.oggpackB_look(ref r, 19) != -1) { throw new Exception("failed 3; got -1 prematurely."); } if (Ogg.oggpackB_look(ref r, 32) != -1 || Ogg.oggpackB_look(ref r, 32) != -1) { throw new Exception("failed 3; got -1 prematurely."); } Ogg.oggpackB_writeclear(ref o); Console.WriteLine("ok."); } finally { Ogg._ogg_free(temp); } } }