Exemplo n.º 1
0
		// add the incoming page to the stream state; we decompose the page
		// into packet segments here as well.

		public int pagein(Page og)
		{
			byte[] header_base=og.header_base;
			int header=og.header;
			byte[] body_base=og.body_base;
			int body=og.body;
			int bodysize=og.body_len;
			int segptr=0;

			int version=og.version();
			int continued=og.continued();
			int bos=og.bos();
			int eos=og.eos();
			long granulepos=og.granulepos();
			int _serialno=og.serialno();
			int _pageno=og.pageno();
			int segments=header_base[header+26]&0xff;

			// clean up 'returned data'
		{
			int lr=lacing_returned;
			int br=body_returned;

			// body data

			//System.out.println("br="+br+", body_fill="+body_fill);

			if(br!=0)
			{
				body_fill-=br;
				if(body_fill!=0)
				{
					Array.Copy(body_data, br, body_data, 0, body_fill);
				}
				body_returned=0;
			}

			//System.out.println("?? br="+br+", body_fill="+body_fill+" body_returned="+body_returned);

			if(lr!=0)
			{
				// segment table
				if((lacing_fill-lr)!=0)
				{
					Array.Copy(lacing_vals, lr, lacing_vals, 0, lacing_fill-lr);
					Array.Copy(granule_vals, lr, granule_vals, 0, lacing_fill-lr);
				}
				lacing_fill-=lr;
				lacing_packet-=lr;
				lacing_returned=0;
			}
		}

			// check the serial number
			if(_serialno!=serialno)return(-1);
			if(version>0)return(-1);

			lacing_expand(segments+1);

			// are we in sequence?
			if(_pageno!=pageno)
			{
				int i;

				// unroll previous partial packet (if any)
				for(i=lacing_packet;i<lacing_fill;i++)
				{
					body_fill-=lacing_vals[i]&0xff;
					//System.out.println("??");
				}
				lacing_fill=lacing_packet;

				// make a note of dropped data in segment table
				if(pageno!=-1)
				{
					lacing_vals[lacing_fill++]=0x400;
					lacing_packet++;
				}

				// are we a 'continued packet' page?  If so, we'll need to skip
				// some segments
				if(continued!=0)
				{
					bos=0;
					for(;segptr<segments;segptr++)
					{
						int val=(header_base[header+27+segptr]&0xff);
						body+=val;
						bodysize-=val;
						if(val<255)
						{
							segptr++;
							break;
						}
					}
				}
			}

			//System.out.println("bodysize="+bodysize);

			if(bodysize!=0)
			{
				body_expand(bodysize);
				Array.Copy(body_base, body, body_data, body_fill, bodysize);
				body_fill+=bodysize;
			}

			//System.out.println("bodyfill="+body_fill);

		{
			int saved=-1;
			while(segptr<segments)
			{
				int val=(header_base[header+27+segptr]&0xff);
				lacing_vals[lacing_fill]=val;
				granule_vals[lacing_fill]=-1;
      
				if(bos!=0)
				{
					lacing_vals[lacing_fill]|=0x100;
					bos=0;
				}
      
				if(val<255)saved=lacing_fill;
      
				lacing_fill++;
				segptr++;
      
				if(val<255)lacing_packet=lacing_fill;
			}
  
			/* set the granulepos on the last pcmval of the last full packet */
			if(saved!=-1)
			{
				granule_vals[saved]=granulepos;
			}
		}

			if(eos!=0)
			{
				e_o_s=1;
				if(lacing_fill>0)
					lacing_vals[lacing_fill-1]|=0x200;
			}

			pageno=_pageno+1;
			return(0);
		}
Exemplo n.º 2
0
        // add the incoming page to the stream state; we decompose the page
        // into packet segments here as well.

        public int pagein(Page og)
        {
            byte[] header_base = og.header_base;
            int    header      = og.header;

            byte[] body_base = og.body_base;
            int    body      = og.body;
            int    bodysize  = og.body_len;
            int    segptr    = 0;

            int  version    = og.version();
            int  continued  = og.continued();
            int  bos        = og.bos();
            int  eos        = og.eos();
            long granulepos = og.granulepos();
            int  _serialno  = og.serialno();
            int  _pageno    = og.pageno();
            int  segments   = header_base[header + 26] & 0xff;

            // clean up 'returned data'
            {
                int lr = lacing_returned;
                int br = body_returned;

                // body data

                //System.out.println("br="+br+", body_fill="+body_fill);

                if (br != 0)
                {
                    body_fill -= br;
                    if (body_fill != 0)
                    {
                        Array.Copy(body_data, br, body_data, 0, body_fill);
                    }
                    body_returned = 0;
                }

                //System.out.println("?? br="+br+", body_fill="+body_fill+" body_returned="+body_returned);

                if (lr != 0)
                {
                    // segment table
                    if ((lacing_fill - lr) != 0)
                    {
                        Array.Copy(lacing_vals, lr, lacing_vals, 0, lacing_fill - lr);
                        Array.Copy(granule_vals, lr, granule_vals, 0, lacing_fill - lr);
                    }
                    lacing_fill    -= lr;
                    lacing_packet  -= lr;
                    lacing_returned = 0;
                }
            }

            // check the serial number
            if (_serialno != serialno)
            {
                return(-1);
            }
            if (version > 0)
            {
                return(-1);
            }

            lacing_expand(segments + 1);

            // are we in sequence?
            if (_pageno != pageno)
            {
                int i;

                // unroll previous partial packet (if any)
                for (i = lacing_packet; i < lacing_fill; i++)
                {
                    body_fill -= lacing_vals[i] & 0xff;
                    //System.out.println("??");
                }
                lacing_fill = lacing_packet;

                // make a note of dropped data in segment table
                if (pageno != -1)
                {
                    lacing_vals[lacing_fill++] = 0x400;
                    lacing_packet++;
                }

                // are we a 'continued packet' page?  If so, we'll need to skip
                // some segments
                if (continued != 0)
                {
                    bos = 0;
                    for (; segptr < segments; segptr++)
                    {
                        int val = (header_base[header + 27 + segptr] & 0xff);
                        body     += val;
                        bodysize -= val;
                        if (val < 255)
                        {
                            segptr++;
                            break;
                        }
                    }
                }
            }

            //System.out.println("bodysize="+bodysize);

            if (bodysize != 0)
            {
                body_expand(bodysize);
                Array.Copy(body_base, body, body_data, body_fill, bodysize);
                body_fill += bodysize;
            }

            //System.out.println("bodyfill="+body_fill);

            {
                int saved = -1;
                while (segptr < segments)
                {
                    int val = (header_base[header + 27 + segptr] & 0xff);
                    lacing_vals[lacing_fill]  = val;
                    granule_vals[lacing_fill] = -1;

                    if (bos != 0)
                    {
                        lacing_vals[lacing_fill] |= 0x100;
                        bos = 0;
                    }

                    if (val < 255)
                    {
                        saved = lacing_fill;
                    }

                    lacing_fill++;
                    segptr++;

                    if (val < 255)
                    {
                        lacing_packet = lacing_fill;
                    }
                }

                /* set the granulepos on the last pcmval of the last full packet */
                if (saved != -1)
                {
                    granule_vals[saved] = granulepos;
                }
            }

            if (eos != 0)
            {
                e_o_s = 1;
                if (lacing_fill > 0)
                {
                    lacing_vals[lacing_fill - 1] |= 0x200;
                }
            }

            pageno = _pageno + 1;
            return(0);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Enumerates PCM chunks
        /// </summary>
        /// <returns>Enumerator</returns>
        public IEnumerator <PCMChunk> GetEnumerator()
        {
            int bytesRead = 0;

            while (eos == 0)
            {
                while (eos == 0)
                {
                    int result = oy.pageout(og);
                    if (result == 0)
                    {
                        break;
                    }                           // need more data
                    if (result == -1)
                    {
                        // missing or corrupt data at this page position
                        throw new Exception("Corrupt or missing data in bitstream...");
                    }
                    else
                    {
                        os.pagein(og); // can safely ignore errors at this point
                        while (true)
                        {
                            result = os.packetout(op);

                            if (result == 0)
                            {
                                break;
                            }                           // need more data
                            if (result == -1)
                            {
                                // missing or corrupt data at this page position
                                // no reason to complain; already complained above
                            }
                            else
                            {
                                // we have a packet. Decode it
                                int samples;

                                if (vb.synthesis(op) == 0)
                                {
                                    // test for success!
                                    vd.synthesis_blockin(vb);
                                }

                                // **pcm is a multichannel float vector. In stereo, for
                                // example, pcm[0] is left, and pcm[1] is right. samples is
                                // the size of each channel. Convert the float values
                                // (-1.<=range<=1.) to whatever PCM format and write it out
                                while ((samples = vd.synthesis_pcmout(_pcm, _index)) > 0)
                                {
                                    float[][] pcm       = _pcm[0];
                                    int       bout      = (samples < convsize ? samples : convsize);
                                    int       chunkSize = 2 * vi.channels * bout;
                                    pcm_offset += samples;

                                    if (bytesRead + chunkSize > convbuffer.Length)
                                    {
                                        PCMChunk chunk = new PCMChunk {
                                            Bytes = convbuffer, Channels = vi.channels, Length = bytesRead, Rate = vi.rate
                                        };
                                        bytesRead = 0;
                                        yield return(chunk);
                                    }

                                    ConvertChunk(bout, bytesRead, pcm);

                                    bytesRead += chunkSize;
                                    vd.synthesis_read(bout); // tell libvorbis how many samples we actually consumed
                                }
                            }
                        }
                        if (og.eos() != 0)
                        {
                            eos = 1;
                        }
                    }
                }
                if (eos == 0)
                {
                    ReadNextPage();
                }
            }

            if (bytesRead != 0)
            {
                PCMChunk chunk = new PCMChunk {
                    Bytes = convbuffer, Channels = vi.channels, Length = bytesRead, Rate = vi.rate
                };
                yield return(chunk);
            }
            else
            {
                yield break;
            }
        }