Example #1
0
    void encode_silent_samples(int n_samples)
        {
        float **buffer;
        int i;

        /* generate a silent buffer */
        buffer = vorbis_analysis_buffer(&vd, n_samples);
        for (i = 0; i < vi.channels; i++)
            memset(buffer[i], 0, n_samples * sizeof (float));
        vorbis_analysis_wrote(&vd, n_samples);

        /* encode it */
        while (vorbis_analysis_blockout(&vd, &vb) == 1)
            {
            vorbis_analysis(&vb, NULL);
            vorbis_bitrate_addblock(&vb);
            while (vorbis_bitrate_flushpacket(&vd, &op))
                {
                ogg_stream_packetin(&os, &op);
                while (ogg_stream_pageout(&os, &og))
                    {
                    write_out(&og);
                    if (ogg_page_eos(&og))
                        break;
                    }
                }
            }
        }
Example #2
0
static int
ogg_close (SF_PRIVATE *psf)
{
	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
	VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;

	if (odata == NULL || vdata == NULL)
		return 0 ;

	/*	Clean up this logical bitstream ; before exit we shuld see if we're
	**	followed by another [chained]. */

	if (psf->file.mode == SFM_WRITE)
	{
		if (psf->write_current <= 0)
			ogg_write_header (psf, 0) ;

		vorbis_analysis_wrote (&vdata->vd, 0) ;
		while (vorbis_analysis_blockout (&vdata->vd, &vdata->vb) == 1)
		{

		/* analysis, assume we want to use bitrate management */
			vorbis_analysis (&vdata->vb, NULL) ;
			vorbis_bitrate_addblock (&vdata->vb) ;

			while (vorbis_bitrate_flushpacket (&vdata->vd, &odata->op))
			{	/* weld the packet into the bitstream */
				ogg_stream_packetin (&odata->os, &odata->op) ;

				/* write out pages (if any) */
				while (!odata->eos)
				{	int result = ogg_stream_pageout (&odata->os, &odata->og) ;
					if (result == 0) break ;
					psf_fwrite (odata->og.header, 1, odata->og.header_len, psf) ;
					psf_fwrite (odata->og.body, 1, odata->og.body_len, psf) ;

		/* this could be set above, but for illustrative purposes, I do
		   it here (to show that vorbis does know where the stream ends) */

					if (ogg_page_eos (&odata->og)) odata->eos = 1 ;
				}
			}
		}
	}

	/* ogg_page and ogg_packet structs always point to storage in
	   libvorbis.  They are never freed or manipulated directly */

	vorbis_block_clear (&vdata->vb) ;
	vorbis_dsp_clear (&vdata->vd) ;
	vorbis_comment_clear (&vdata->vc) ;
	vorbis_info_clear (&vdata->vi) ;	 /* must be called last */
	/* should look here to reopen if chained */

	/* OK, clean up the framer */
	ogg_sync_clear (&odata->oy) ;
	ogg_stream_clear (&odata->os) ;

	return 0 ;
} /* ogg_close */
Example #3
0
/*!
 * \brief Write out any pending encoded data.
 * \param s An OGG/Vorbis filestream.
 * \param f The file to write to.
 */
static void write_stream(struct vorbis_desc *s, FILE *f)
{
	while (vorbis_analysis_blockout(&s->vd, &s->vb) == 1) {
		vorbis_analysis(&s->vb, NULL);
		vorbis_bitrate_addblock(&s->vb);

		while (vorbis_bitrate_flushpacket(&s->vd, &s->op)) {
			ogg_stream_packetin(&s->os, &s->op);
			while (!s->eos) {
				if (ogg_stream_pageout(&s->os, &s->og) == 0) {
					break;
				}
				if (!fwrite(s->og.header, 1, s->og.header_len, f)) {
				ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
				}
				if (!fwrite(s->og.body, 1, s->og.body_len, f)) {
					ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
				}
				if (ogg_page_eos(&s->og)) {
					s->eos = 1;
				}
			}
		}
	}
}
bool VorbisWriter::write(QByteArray &left, QByteArray &right, long samples, bool flush) {
	const long maxChunkSize = 4096;

	const qint16 *leftData = (const qint16 *)left.constData();
	const qint16 *rightData = stereo ? (const qint16 *)right.constData() : NULL;

	long todoSamples = samples;
	int eos = 0;

	while (!eos) {
		long chunkSize = todoSamples > maxChunkSize ? maxChunkSize : todoSamples;
		todoSamples -= chunkSize;

		if (chunkSize == 0) {
			if (!flush)
				break;
			hasFlushed = true;
			vorbis_analysis_wrote(&pd->vd, 0);
		} else {
			float **buffer = vorbis_analysis_buffer(&pd->vd, chunkSize);

			for (long i = 0; i < chunkSize; i++)
				buffer[0][i] = (float)leftData[i] / 32768.0f;
			leftData += chunkSize;

			if (stereo) {
				for (long i = 0; i < chunkSize; i++)
					buffer[1][i] = (float)rightData[i] / 32768.0f;
				rightData += chunkSize;
			}

			vorbis_analysis_wrote(&pd->vd, chunkSize);
		}

		while (vorbis_analysis_blockout(&pd->vd, &pd->vb) == 1) {
			vorbis_analysis(&pd->vb, NULL);
			vorbis_bitrate_addblock(&pd->vb);

			while (vorbis_bitrate_flushpacket(&pd->vd, &pd->op)) {
				ogg_stream_packetin(&pd->os, &pd->op);

				while (!eos && ogg_stream_pageout(&pd->os, &pd->og) != 0) {
					file.write((const char *)pd->og.header, pd->og.header_len);
					file.write((const char *)pd->og.body, pd->og.body_len);

					if (ogg_page_eos(&pd->og))
						eos = 1;
				}
			}
		}
	}

	samplesWritten += samples;

	left.remove(0, samples * 2);
	if (stereo)
		right.remove(0, samples * 2);

	return true;
}
Example #5
0
void
MediaRecorder::WriteAudio()
{
    int ret;
    nsresult rv;
    PRUint32 wr;

    while (vorbis_analysis_blockout(&aState->vd, &aState->vb) == 1) {
        vorbis_analysis(&aState->vb, NULL);
        vorbis_bitrate_addblock(&aState->vb);
        while (vorbis_bitrate_flushpacket(
                &aState->vd, &aState->op)) {
            ogg_stream_packetin(&aState->os, &aState->op);

            for (;;) {
                ret = ogg_stream_pageout(&aState->os, &aState->og);
                if (ret == 0)
                    break;

                rv = WriteData(aState->og.header, aState->og.header_len, &wr);
                rv = WriteData(aState->og.body, aState->og.body_len, &wr);

                if (ogg_page_eos(&aState->og))
                    break;
            }
        }
    }
}
Example #6
0
int  lame_encode_ogg_frame (
	lame_global_flags*  gfp,
	const sample_t*     inbuf_l, 
	const sample_t*     inbuf_r,
	unsigned char*      mp3buf, 
	size_t              mp3buf_size )
{
    lame_internal_flags *gfc = gfp->internal_flags;
    int  i;
    int  eos   = 0;
    int  bytes = 0;
  
    /* expose the buffer to submit data */
    double **buffer = vorbis_analysis_buffer(&vd2,gfp->framesize);
  
    /* change level of input by -90 dB (no de-interleaving!) */
    for ( i = 0; i < gfp->framesize; i++ )
        buffer [0] [i] = (1/32768.) * inbuf_l [i];
    if ( gfc->channels_out == 2 )
        for ( i = 0; i < gfp->framesize; i++ )
            buffer [1] [i] = (1/32768.) * inbuf_r [i];
  
  /* tell the library how much we actually submitted */
  vorbis_analysis_wrote(&vd2,i);

  /* vorbis does some data preanalysis, then divvies up blocks for
     more involved (potentially parallel) processing.  Get a single
     block for encoding now */
  while(vorbis_analysis_blockout(&vd2,&vb2)==1){
    int result;
    /* analysis */
    vorbis_analysis(&vb2,&op2);
    
    /* weld the packet into the bitstream */
    ogg_stream_packetin(&os2,&op2);
    
    /* write out pages (if any) */
    do {
      result=ogg_stream_pageout(&os2,&og2);
      if (result==0) break;
	
      /* check if mp3buffer is big enough for the output */
      bytes += og2.header_len + og2.body_len;
      /*
      DEBUGF("\n\n*********\ndecoded bytes=%i  %i \n",bytes,mp3buf_size);
      */
      if (bytes > mp3buf_size && mp3buf_size>0)
	return -6;
      
      memcpy(mp3buf,og2.header,og2.header_len);
      memcpy(mp3buf+og2.header_len,og2.body,og2.body_len);
      mp3buf += og2.header_len + og2.body_len;
      
      if(ogg_page_eos(&og2))eos=1;
    } while (1);
  }
  (gfp -> frameNum)++;
  return bytes;
}
Example #7
0
static PyObject * py_ogg_ogg_page_eos(PyObject *self, PyObject *args) {
  int size;
  int c_out;
  ogg_page * og;
  PyArg_ParseTuple(args, "s#", &og, &size);
  c_out = ogg_page_eos(og);
  return Py_BuildValue("i", c_out);
};
Example #8
0
static ChainState *
validate_ogg_page (ogg_page * page)
{
  gulong serialno;
  gint64 granule;
  ChainState *state;

  serialno = ogg_page_serialno (page);
  granule = ogg_page_granulepos (page);
  state = g_hash_table_lookup (eos_chain_states, GINT_TO_POINTER (serialno));

  fail_if (ogg_page_packets (page) == 0 && granule != -1,
      "Must have granulepos -1 when page has no packets, has %" G_GINT64_FORMAT,
      granule);

  if (ogg_page_bos (page)) {
    fail_unless (state == NULL, "Extraneous BOS flag on chain %u", serialno);

    state = g_new0 (ChainState, 1);
    g_hash_table_insert (eos_chain_states, GINT_TO_POINTER (serialno), state);
    state->serialno = serialno;
    state->last_granule = granule;
    state->codec = get_page_codec (page);

    /* check for things like BOS ordering, etc */
    switch (state->codec) {
      case CODEC_THEORA:
        /* check we have no vorbis/speex chains yet */
        g_hash_table_foreach (eos_chain_states, (GHFunc) fail_if_audio, NULL);
        break;
      case CODEC_VORBIS:
      case CODEC_SPEEX:
        /* no checks (yet) */
        break;
      case CODEC_UNKNOWN:
      default:
        break;
    }
  } else if (ogg_page_eos (page)) {
    fail_unless (state != NULL, "Missing BOS flag on chain %u", serialno);
    state->eos = TRUE;
  } else {
    fail_unless (state != NULL, "Missing BOS flag on chain %u", serialno);
    fail_unless (!state->eos, "Data after EOS flag on chain %u", serialno);
  }

  if (granule != -1) {
    fail_unless (granule >= state->last_granule,
        "Granulepos out-of-order for chain %u: old=%" G_GINT64_FORMAT ", new="
        G_GINT64_FORMAT, serialno, state->last_granule, granule);
    state->last_granule = granule;
  }

  return state;
}
tbool CVorbisEncoder::Finalize_Descendant()
{
	if (miOutputSamplesTotal > 0) {
		// Actually done any processing?
		
		// Tell the library we're at end of stream so that it can handle
		// the last frame and mark end of stream in the output properly
		vorbis_analysis_wrote(&vd,0);
		
		while(vorbis_analysis_blockout(&vd,&vb)==1){
			
			/* analysis, assume we want to use bitrate management */
			vorbis_analysis(&vb,NULL);
			vorbis_bitrate_addblock(&vb);
			
			while(vorbis_bitrate_flushpacket(&vd,&op)){
				
				/* weld the packet into the bitstream */
				ogg_stream_packetin(&os,&op);
				
				/* write out pages (if any) */
				tbool bEOS = false;
				while(!bEOS){
					int result=ogg_stream_pageout(&os,&og);
					if(result==0)break;
					//fwrite(og.header,1,og.header_len,stdout);
					//fwrite(og.body,1,og.body_len,stdout);
					WriteOutput((char*)og.header, og.header_len);
					WriteOutput((char*)og.body, og.body_len);
					
					/* this could be set above, but for illustrative purposes, I do
						it here (to show that vorbis does know where the stream ends) */
					
					if(ogg_page_eos(&og))bEOS=1;
				}
			}
		}

		/* clean up and exit.  vorbis_info_clear() must be called last */
		ogg_stream_clear(&os);
		vorbis_block_clear(&vb);
		vorbis_dsp_clear(&vd);
		vorbis_comment_clear(&vc);
		vorbis_info_clear(&vi);
		
		/* ogg_page and ogg_packet structs always point to storage in
			libvorbis.  They're never freed or manipulated directly */
	}

	tfloat fSecs = ((tfloat)miOutputSamplesTotal) / miOutputSampleFreq;
	tfloat fKbps = muiBytesTotalOutput * 8.0f / (fSecs * 1000);
	std::cout << "Done (wrote " << muiBytesTotalOutput << " bytes, " << fSecs << " secs, avg rate " << fKbps << " kbps)\n\n";
	
	return true;
}
Example #10
0
static void close_output(void)
{
  int eos = 0;
  ogg_page   og; /* one Ogg bitstream page.  Vorbis packets are inside */
  ogg_packet op; /* one raw packet of data for decode */

  if(dpm.fd < 0)
    return;

  /* end of file.  this can be done implicitly in the mainline,
     but it's easier to see here in non-clever fashion.
     Tell the library we're at end of stream so that it can handle
     the last frame and mark end of stream in the output properly */
  vorbis_analysis_wrote(&vd, 0);

  /* vorbis does some data preanalysis, then divvies up blocks for
     more involved (potentially parallel) processing.  Get a single
     block for encoding now */
  while(vorbis_analysis_blockout(&vd, &vb) == 1) {

    /* analysis */
    vorbis_analysis(&vb, &op);
      
    /* weld the packet into the bitstream */
    ogg_stream_packetin(&os, &op);

    /* write out pages (if any) */
    while(!eos){
      int result = ogg_stream_pageout(&os,&og);
      if(result == 0)
	break;
      write(dpm.fd, og.header, og.header_len);
      write(dpm.fd, og.body, og.body_len);

      /* this could be set above, but for illustrative purposes, I do
	 it here (to show that vorbis does know where the stream ends) */

      if(ogg_page_eos(&og))
	eos = 1;
    }
  }

  /* clean up and exit.  vorbis_info_clear() must be called last */

  ogg_stream_clear(&os);
  vorbis_block_clear(&vb);
  vorbis_dsp_clear(&vd);
  close(dpm.fd);
  dpm.fd = -1;
}
Example #11
0
/*!
 * \brief Create a new OGG/Vorbis filestream and set it up for writing.
 * \param s File pointer that points to on-disk storage.
 * \param comment Comment that should be embedded in the OGG/Vorbis file.
 * \return A new filestream.
 */
static int ogg_vorbis_rewrite(struct ast_filestream *s,
						 const char *comment)
{
	ogg_packet header;
	ogg_packet header_comm;
	ogg_packet header_code;
	struct ogg_vorbis_desc *tmp = (struct ogg_vorbis_desc *) s->_private;

	tmp->writing = 1;
	tmp->writing_pcm_pos = 0;

	vorbis_info_init(&tmp->vi);

	if (vorbis_encode_init_vbr(&tmp->vi, 1, DEFAULT_SAMPLE_RATE, 0.4)) {
		ast_log(LOG_ERROR, "Unable to initialize Vorbis encoder!\n");
		return -1;
	}

	vorbis_comment_init(&tmp->vc);
	vorbis_comment_add_tag(&tmp->vc, "ENCODER", "Asterisk PBX");
	if (comment)
		vorbis_comment_add_tag(&tmp->vc, "COMMENT", (char *) comment);

	vorbis_analysis_init(&tmp->vd, &tmp->vi);
	vorbis_block_init(&tmp->vd, &tmp->vb);

	ogg_stream_init(&tmp->os, ast_random());

	vorbis_analysis_headerout(&tmp->vd, &tmp->vc, &header, &header_comm,
				  &header_code);
	ogg_stream_packetin(&tmp->os, &header);
	ogg_stream_packetin(&tmp->os, &header_comm);
	ogg_stream_packetin(&tmp->os, &header_code);

	while (!tmp->eos) {
		if (ogg_stream_flush(&tmp->os, &tmp->og) == 0)
			break;
		if (!fwrite(tmp->og.header, 1, tmp->og.header_len, s->f)) {
			ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
		}
		if (!fwrite(tmp->og.body, 1, tmp->og.body_len, s->f)) {
			ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
		}
		if (ogg_page_eos(&tmp->og))
			tmp->eos = 1;
	}

	return 0;
}
Example #12
0
int lame_encode_ogg_finish(lame_global_flags *gfp,
			  char *mp3buf, int mp3buf_size)
{
  int eos=0,bytes=0;

  vorbis_analysis_wrote(&vd2,0);

  while(vorbis_analysis_blockout(&vd2,&vb2)==1){
    
    /* analysis */
    vorbis_analysis(&vb2,&op2);

      /* weld the packet into the bitstream */
      ogg_stream_packetin(&os2,&op2);

      /* write out pages (if any) */
      while(!eos){
	int result=ogg_stream_pageout(&os2,&og2);
	if(result==0)break;


	/* check if mp3buffer is big enough for the output */
	bytes += og2.header_len + og2.body_len;
	if (bytes > mp3buf_size && mp3buf_size>0)
	  return -5;
	
	memcpy(mp3buf,og2.header,og2.header_len);
	memcpy(mp3buf+og2.header_len,og2.body,og2.body_len);

	/* this could be set above, but for illustrative purposes, I do
	   it here (to show that vorbis does know where the stream ends) */
	if(ogg_page_eos(&og2))eos=1;

      }
    }


  /* clean up and exit.  vorbis_info_clear() must be called last */
  ogg_stream_clear(&os2);
  vorbis_block_clear(&vb2);
  vorbis_dsp_clear(&vd2);

  
  /* ogg_page and ogg_packet structs always point to storage in
     libvorbis.  They're never freed or manipulated directly */
  return bytes;

}
bool ShoutVSTEncoderOGG::Process( float **inputs, long sampleFrames )
{
  if (!bInitialized) return false;

  float **buffer=vorbis_analysis_buffer(&vd,sampleFrames);

  /* uninterleave samples */
  for(int i=0;i<sampleFrames;i++){
    buffer[0][i] = inputs[0][i];
    buffer[1][i] = inputs[1][i];
  }

  /* tell the library how much we actually submitted */
  vorbis_analysis_wrote(&vd,sampleFrames);

  /* vorbis does some data preanalysis, then divvies up blocks for
  more involved (potentially parallel) processing.  Get a single
  block for encoding now */
  int eos = 0;

  while(vorbis_analysis_blockout(&vd,&vb)==1){

    /* analysis, assume we want to use bitrate management */
    vorbis_analysis(&vb,NULL);
    vorbis_bitrate_addblock(&vb);

    while(vorbis_bitrate_flushpacket(&vd,&op)){

      /* weld the packet into the bitstream */
      ogg_stream_packetin(&os,&op);

      /* write out pages (if any) */
      while(!eos){
        int result=ogg_stream_pageout(&os,&og);
        if(result==0)break;
        if (!SendOGGPageToICE(&og)) return false;

        /* this could be set above, but for illustrative purposes, I do
        it here (to show that vorbis does know where the stream ends) */

        if(ogg_page_eos(&og))eos=1;
      }
    }
  } 

  return true;
}
	bool VideoClip_Theora::_readData()
	{
		int audioEos = 0;
		int serno = 0;
		float audioTime = 0;
		float time = this->timer->getTime();
		if (this->restarted)
		{
			time = 0.0f;
		}
		char* buffer = NULL;
		int bytesRead = 0;
		ogg_int64_t granule = 0;
		do
		{
			buffer = ogg_sync_buffer(&this->info.OggSyncState, BUFFER_SIZE);
			bytesRead = this->stream->read(buffer, BUFFER_SIZE);
			ogg_sync_wrote(&this->info.OggSyncState, bytesRead);
			if (bytesRead == 0)
			{
				if (!this->autoRestart)
				{
					this->endOfFile = true;
					log(this->name + " finished playing");
				}
				return false;
			}
			// when we fill the stream with enough pages, it'll start spitting out packets
			// which contain key frames, delta frames or audio data
			while (ogg_sync_pageout(&this->info.OggSyncState, &this->info.OggPage) > 0)
			{
				serno = ogg_page_serialno(&this->info.OggPage);
				if (serno == this->info.TheoraStreamState.serialno)
				{
					ogg_stream_pagein(&this->info.TheoraStreamState, &this->info.OggPage);
				}
				if (this->audioInterface != NULL && serno == this->info.VorbisStreamState.serialno)
				{
					granule = ogg_page_granulepos(&this->info.OggPage);
					audioTime = (float)vorbis_granule_time(&this->info.VorbisDSPState, granule);
					audioEos = ogg_page_eos(&this->info.OggPage);
					ogg_stream_pagein(&this->info.VorbisStreamState, &this->info.OggPage);
				}
			}
		} while (this->audioInterface != NULL && audioEos == 0 && audioTime < time + 1.0f);
		return true;
	}
Example #15
0
void EncoderVorbis::writePage() {

    /*
     * Vorbis streams begin with three headers; the initial header (with
     * most of the codec setup parameters) which is mandated by the Ogg
     * bitstream spec.  The second header holds any comment fields.  The
     * third header holds the bitstream codebook.  We merely need to
     * make the headers, then pass them to libvorbis one at a time;
     * libvorbis handles the additional Ogg bitstream constraints
         */


    //Write header only once after stream has been initalized
    int result;
    if (m_header_write) {
        while (true) {
            result = ogg_stream_flush(&m_oggs, &m_oggpage);
            if (result == 0)
                break;
            m_pCallback->write(m_oggpage.header, m_oggpage.body, m_oggpage.header_len, m_oggpage.body_len);
        }
        m_header_write = false;
    }

    while (vorbis_analysis_blockout(&m_vdsp, &m_vblock) == 1) {
        vorbis_analysis(&m_vblock, 0);
        vorbis_bitrate_addblock(&m_vblock);
        while (vorbis_bitrate_flushpacket(&m_vdsp, &m_oggpacket)) {
            // weld packet into bitstream
            ogg_stream_packetin(&m_oggs, &m_oggpacket);
            // write out pages
            bool eos = false;
            while (!eos) {
                int result = ogg_stream_pageout(&m_oggs, &m_oggpage);
                if (result == 0)
                    break;
                m_pCallback->write(m_oggpage.header, m_oggpage.body,
                                   m_oggpage.header_len, m_oggpage.body_len);
                if (ogg_page_eos(&m_oggpage))
                    eos = true;
            }
        }
    }
}
Example #16
0
void ogg_encoder_write_blocks(guac_audio_stream* audio) {

    /* Get state */
    ogg_encoder_state* state = (ogg_encoder_state*) audio->data;

    while (vorbis_analysis_blockout(&(state->vorbis_state),
                &(state->vorbis_block)) == 1) {

        /* Analyze */
        vorbis_analysis(&(state->vorbis_block), NULL);
        vorbis_bitrate_addblock(&(state->vorbis_block));

        /* Flush Ogg pages */
        while (vorbis_bitrate_flushpacket(&(state->vorbis_state),
                    &(state->ogg_packet))) {

            /* Weld packet into bitstream */
            ogg_stream_packetin(&(state->ogg_state), &(state->ogg_packet));

            /* Write out pages */
            while (ogg_stream_pageout(&(state->ogg_state),
                        &(state->ogg_page)) != 0) {

                /* Write packet header */
                guac_audio_stream_write_encoded(audio,
                        state->ogg_page.header,
                        state->ogg_page.header_len);

                /* Write packet body */
                guac_audio_stream_write_encoded(audio,
                        state->ogg_page.body,
                        state->ogg_page.body_len);

                if (ogg_page_eos(&(state->ogg_page)))
                    break;

            }

        }

    }

}
/*!
 * \brief Write out any pending encoded data.
 * \param s An OGG/Vorbis filestream.
 * \param f The file to write to.
 */
static void write_stream(struct vorbis_desc *s, FILE *f)
{
	while (vorbis_analysis_blockout(&s->vd, &s->vb) == 1) {
		vorbis_analysis(&s->vb, NULL);
		vorbis_bitrate_addblock(&s->vb);

		while (vorbis_bitrate_flushpacket(&s->vd, &s->op)) {
			ogg_stream_packetin(&s->os, &s->op);
			while (!s->eos) {
				if (ogg_stream_pageout(&s->os, &s->og) == 0) {
					break;
				}
				fwrite(s->og.header, 1, s->og.header_len, f);
				fwrite(s->og.body, 1, s->og.body_len, f);
				if (ogg_page_eos(&s->og)) {
					s->eos = 1;
				}
			}
		}
	}
}
Example #18
0
int oggWrite(EncInfo* encInfo,int close) {
    int total = 0;
#ifdef DEBUG
fprintf(file,"oggwrite\n");
#endif
    /* vorbis does some data preanalysis, then divvies up blocks for
       more involved (potentially parallel) processing.  Get a single
       block for encoding now */

    while(vorbis_analysis_blockout(&encInfo->vd,&encInfo->vb)==1){
      /* analysis */
      vorbis_analysis(&encInfo->vb,NULL);
      vorbis_bitrate_addblock(&encInfo->vb);
      
      while(vorbis_bitrate_flushpacket(&encInfo->vd,&encInfo->op)){
      /* weld the packet into the bitstream */
      ogg_stream_packetin(&encInfo->os,&encInfo->op);

      /* write out pages (if any) */
      while(!ogg_page_eos(&encInfo->og)){
          int result;
#ifdef DEBUG
fprintf(file,"Write a page\n");
#endif
          result=ogg_stream_pageout(&encInfo->os,&encInfo->og);
          if(result==0)break;
          result = mmioWrite(encInfo->hmmioSS, encInfo->og.header,encInfo->og.header_len);
          total += result;
          if (result!=encInfo->og.header_len) return -1;
          result = mmioWrite(encInfo->hmmioSS, encInfo->og.body,encInfo->og.body_len);
          total += result;
          if (result!=encInfo->og.body_len) return -1;
      }
    }
    }
#ifdef DEBUG
fprintf(file,"Wrote %d\n",total);
#endif
    return total;
}
Example #19
0
static int vorbis_write(SWORD *pbuf, size_t nr)
{
    float **buffer;
    size_t i;
    size_t amount = (stereo) ? nr / 2 : nr;
    int result;
    int eos = 0;

    buffer = vorbis_analysis_buffer(&vd, (int)amount);
    for (i = 0; i < amount; i++) {
        if (stereo == 1) {
            buffer[0][i]= pbuf[i * 2] / 32768.f;
            buffer[1][i]= pbuf[(i * 2) + 1] / 32768.f;
        } else {
            buffer[0][i]= pbuf[i] / 32768.f;
        }
    }

    vorbis_analysis_wrote(&vd, (int)i);

    while (vorbis_analysis_blockout(&vd, &vb) == 1) {
        vorbis_analysis(&vb, NULL);
        vorbis_bitrate_addblock(&vb);
        while (vorbis_bitrate_flushpacket(&vd, &op)) {
            ogg_stream_packetin(&os, &op);
            while(!eos) {
                result = ogg_stream_pageout(&os, &og);
                if (!result) {
                    break;
                }
                fwrite(og.header, 1, (size_t)(og.header_len), vorbis_fd);
                fwrite(og.body, 1, (size_t)(og.body_len), vorbis_fd);
                if (ogg_page_eos(&og)) {
                    eos = 1;
                }
            }
        }
    }
    return 0;
}
Example #20
0
static void
ogg_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames)
{
	vorbis_analysis_wrote (&vdata->vd, in_frames) ;

	/*
	**	Vorbis does some data preanalysis, then divvies up blocks for
	**	more involved (potentially parallel) processing. Get a single
	**	block for encoding now.
	*/
	while (vorbis_analysis_blockout (&vdata->vd, &vdata->vb) == 1)
	{
		/* analysis, assume we want to use bitrate management */
		vorbis_analysis (&vdata->vb, NULL) ;
		vorbis_bitrate_addblock (&vdata->vb) ;

		while (vorbis_bitrate_flushpacket (&vdata->vd, &odata->op))
		{
			/* weld the packet into the bitstream */
			ogg_stream_packetin (&odata->os, &odata->op) ;

			/* write out pages (if any) */
			while (!odata->eos)
			{	int result = ogg_stream_pageout (&odata->os, &odata->og) ;
				if (result == 0)
					break ;
				psf_fwrite (odata->og.header, 1, odata->og.header_len, psf) ;
				psf_fwrite (odata->og.body, 1, odata->og.body_len, psf) ;

				/*	This could be set above, but for illustrative purposes, I do
				**	it here (to show that vorbis does know where the stream ends) */
				if (ogg_page_eos (&odata->og))
					odata->eos = 1 ;
				} ;
			} ;
		} ;

	vdata->loc += in_frames ;
} /* ogg_write_data */
bool Finish(void *ctx)
{
  ogg_context *context = (ogg_context *)ctx;
  if (!context || !context->callbacks.write)
    return false;

  int eos = 0;
  // tell vorbis we are encoding the end of the stream
  vorbis_analysis_wrote(&context->vorbisDspState, 0);
  while (vorbis_analysis_blockout(&context->vorbisDspState, &context->vorbisBlock) == 1)
  {
    /* analysis, assume we want to use bitrate management */
    vorbis_analysis(&context->vorbisBlock, NULL);
    vorbis_bitrate_addblock(&context->vorbisBlock);

    ogg_packet packet;
    ogg_page   page;
    while (vorbis_bitrate_flushpacket(&context->vorbisDspState, &packet))
    {
      /* weld the packet into the bitstream */
      ogg_stream_packetin(&context->oggStreamState, &packet);

      /* write out pages (if any) */
      while (!eos)
      {
        int result = ogg_stream_pageout(&context->oggStreamState, &page);
        if (result == 0)
          break;
        context->callbacks.write(context->callbacks.opaque, page.header, page.header_len);
        context->callbacks.write(context->callbacks.opaque, page.body, page.body_len);

        /* this could be set above, but for illustrative purposes, I do
        it here (to show that vorbis does know where the stream ends) */
        if (ogg_page_eos(&page)) eos = 1;
      }
    }
  }
  return true;
}
Example #22
0
int main(){
  ogg_stream_state os; /* take physical pages, weld into a logical
			  stream of packets */
  ogg_page         og; /* one Ogg bitstream page.  Vorbis packets are inside */
  ogg_packet       op; /* one raw packet of data for decode */
  
  vorbis_info      vi; /* struct that stores all the static vorbis bitstream
			  settings */
  vorbis_comment   vc; /* struct that stores all the user comments */

  vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
  vorbis_block     vb; /* local working space for packet->PCM decode */

  int eos=0,ret;
  int i, founddata;

#if defined(macintosh) && defined(__MWERKS__)
  int argc = 0;
  char **argv = NULL;
  argc = ccommand(&argv); /* get a "command line" from the Mac user */
                          /* this also lets the user set stdin and stdout */
#endif

  /* we cheat on the WAV header; we just bypass 44 bytes and never
     verify that it matches 16bit/stereo/44.1kHz.  This is just an
     example, after all. */

#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
  /* if we were reading/writing a file, it would also need to in
     binary mode, eg, fopen("file.wav","wb"); */
  /* Beware the evil ifdef. We avoid these where we can, but this one we 
     cannot. Don't add any more, you'll probably go to hell if you do. */
  _setmode( _fileno( stdin ), _O_BINARY );
  _setmode( _fileno( stdout ), _O_BINARY );
#endif


  /* we cheat on the WAV header; we just bypass the header and never
     verify that it matches 16bit/stereo/44.1kHz.  This is just an
     example, after all. */

  readbuffer[0] = '\0';
  for (i=0, founddata=0; i<30 && ! feof(stdin) && ! ferror(stdin); i++)
  {
    fread(readbuffer,1,2,stdin);

    if ( ! strncmp((char*)readbuffer, "da", 2) )
    {
      founddata = 1;
      fread(readbuffer,1,6,stdin);
      break;
    }
  }

  /********** Encode setup ************/

  vorbis_info_init(&vi);

  /* choose an encoding mode.  A few possibilities commented out, one
     actually used: */

  /*********************************************************************
   Encoding using a VBR quality mode.  The usable range is -.1
   (lowest quality, smallest file) to 1. (highest quality, largest file).
   Example quality mode .4: 44kHz stereo coupled, roughly 128kbps VBR 
  
   ret = vorbis_encode_init_vbr(&vi,2,44100,.4);

   ---------------------------------------------------------------------

   Encoding using an average bitrate mode (ABR).
   example: 44kHz stereo coupled, average 128kbps VBR 
  
   ret = vorbis_encode_init(&vi,2,44100,-1,128000,-1);

   ---------------------------------------------------------------------

   Encode using a quality mode, but select that quality mode by asking for
   an approximate bitrate.  This is not ABR, it is true VBR, but selected
   using the bitrate interface, and then turning bitrate management off:

   ret = ( vorbis_encode_setup_managed(&vi,2,44100,-1,128000,-1) ||
           vorbis_encode_ctl(&vi,OV_ECTL_RATEMANAGE2_SET,NULL) ||
           vorbis_encode_setup_init(&vi));

   *********************************************************************/

  ret=vorbis_encode_init_vbr(&vi,2,44100,0.1);

  /* do not continue if setup failed; this can happen if we ask for a
     mode that libVorbis does not support (eg, too low a bitrate, etc,
     will return 'OV_EIMPL') */

  if(ret)exit(1);

  /* add a comment */
  vorbis_comment_init(&vc);
  vorbis_comment_add_tag(&vc,"ENCODER","encoder_example.c");

  /* set up the analysis state and auxiliary encoding storage */
  vorbis_analysis_init(&vd,&vi);
  vorbis_block_init(&vd,&vb);
  
  /* set up our packet->stream encoder */
  /* pick a random serial number; that way we can more likely build
     chained streams just by concatenation */
  srand(time(NULL));
  ogg_stream_init(&os,rand());

  /* Vorbis streams begin with three headers; the initial header (with
     most of the codec setup parameters) which is mandated by the Ogg
     bitstream spec.  The second header holds any comment fields.  The
     third header holds the bitstream codebook.  We merely need to
     make the headers, then pass them to libvorbis one at a time;
     libvorbis handles the additional Ogg bitstream constraints */

  {
    ogg_packet header;
    ogg_packet header_comm;
    ogg_packet header_code;

    vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
    ogg_stream_packetin(&os,&header); /* automatically placed in its own
					 page */
    ogg_stream_packetin(&os,&header_comm);
    ogg_stream_packetin(&os,&header_code);

	/* This ensures the actual
	 * audio data will start on a new page, as per spec
	 */
	while(!eos){
		int result=ogg_stream_flush(&os,&og);
		if(result==0)break;
		fwrite(og.header,1,og.header_len,stdout);
		fwrite(og.body,1,og.body_len,stdout);
	}

  }
  
  while(!eos){
    long i;
    long bytes=fread(readbuffer,1,READ*4,stdin); /* stereo hardwired here */

    if(bytes==0){
      /* end of file.  this can be done implicitly in the mainline,
         but it's easier to see here in non-clever fashion.
         Tell the library we're at end of stream so that it can handle
         the last frame and mark end of stream in the output properly */
      vorbis_analysis_wrote(&vd,0);

    }else{
      /* data to encode */

      /* expose the buffer to submit data */
      float **buffer=vorbis_analysis_buffer(&vd,READ);
      
      /* uninterleave samples */
      for(i=0;i<bytes/4;i++){
	buffer[0][i]=((readbuffer[i*4+1]<<8)|
		      (0x00ff&(int)readbuffer[i*4]))/32768.f;
	buffer[1][i]=((readbuffer[i*4+3]<<8)|
		      (0x00ff&(int)readbuffer[i*4+2]))/32768.f;
      }
    
      /* tell the library how much we actually submitted */
      vorbis_analysis_wrote(&vd,i);
    }

    /* vorbis does some data preanalysis, then divvies up blocks for
       more involved (potentially parallel) processing.  Get a single
       block for encoding now */
    while(vorbis_analysis_blockout(&vd,&vb)==1){

      /* analysis, assume we want to use bitrate management */
      vorbis_analysis(&vb,NULL);
      vorbis_bitrate_addblock(&vb);

      while(vorbis_bitrate_flushpacket(&vd,&op)){
	
	/* weld the packet into the bitstream */
	ogg_stream_packetin(&os,&op);
	
	/* write out pages (if any) */
	while(!eos){
	  int result=ogg_stream_pageout(&os,&og);
	  if(result==0)break;
	  fwrite(og.header,1,og.header_len,stdout);
	  fwrite(og.body,1,og.body_len,stdout);
	  
	  /* this could be set above, but for illustrative purposes, I do
	     it here (to show that vorbis does know where the stream ends) */
	  
	  if(ogg_page_eos(&og))eos=1;
	}
      }
    }
  }

  /* clean up and exit.  vorbis_info_clear() must be called last */
  
  ogg_stream_clear(&os);
  vorbis_block_clear(&vb);
  vorbis_dsp_clear(&vd);
  vorbis_comment_clear(&vc);
  vorbis_info_clear(&vi);
  
  /* ogg_page and ogg_packet structs always point to storage in
     libvorbis.  They're never freed or manipulated directly */
  
  fprintf(stderr,"Done.\n");
  return(0);
}
Example #23
0
 int main(){
  ogg_sync_state   oy; /* sync and verify incoming physical bitstream */
  ogg_stream_state os; /* take physical pages, weld into a logical
                          stream of packets */
  ogg_page         og; /* one Ogg bitstream page. Vorbis packets are inside */
  ogg_packet       op; /* one raw packet of data for decode */

  vorbis_info      vi; /* struct that stores all the static vorbis bitstream
                          settings */
  vorbis_comment   vc; /* struct that stores all the bitstream user comments */
  vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
  vorbis_block     vb; /* local working space for packet->PCM decode */

  char *buffer;
  int  bytes;

  FILE *instream;
  FILE *outstream;
  char *inname = "01.ogg";
  char *outname = "esmith2000-09-28d1t15.raw";

//#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
//  /* Beware the evil ifdef. We avoid these where we can, but this one we
//     cannot. Don't add any more, you'll probably go to hell if you do. */
//  //_setmode( _fileno( stdin ), _O_BINARY );
//  //_setmode( _fileno( stdout ), _O_BINARY );
//#endif

#if defined(macintosh) && defined(__MWERKS__)
  {
    int argc;
    char **argv;
    argc=ccommand(&argv); /* get a "command line" from the Mac user */
                     /* this also lets the user set stdin and stdout */
  }
#endif

  /********** Decode setup ************/

  //opening the file
  
  
  if( fopen_s( &instream, inname, "rb" ) != 0 )
  {
	  fprintf(stderr,"Can not open file %s\n", inname);
      exit(1);
  };
  
  if( fopen_s( &outstream, outname, "wb" ) != 0 )
  {
	  fprintf(stderr,"Can not open file %s\n", outname);
      exit(1);
  }


  ogg_sync_init(&oy); /* Now we can read pages */
  
  while(1){ /* we repeat if the bitstream is chained */
    int eos=0;
    int i;

    /* grab some data at the head of the stream. We want the first page
       (which is guaranteed to be small and only contain the Vorbis
       stream initial header) We need the first page to get the stream
       serialno. */

    /* submit a 4k block to libvorbis' Ogg layer */
    buffer=ogg_sync_buffer(&oy,4096);
    //bytes=fread(buffer,1,4096,stdin);
	bytes=fread(buffer,1,4096,instream);
    ogg_sync_wrote(&oy,bytes);
    
    /* Get the first page. */
    if(ogg_sync_pageout(&oy,&og)!=1){
      /* have we simply run out of data?  If so, we're done. */
      if(bytes<4096)break;
      
      /* error case.  Must not be Vorbis data */
      fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n");
      exit(1);
    }
  
    /* Get the serial number and set up the rest of decode. */
    /* serialno first; use it to set up a logical stream */
    ogg_stream_init(&os,ogg_page_serialno(&og));
    
    /* extract the initial header from the first page and verify that the
       Ogg bitstream is in fact Vorbis data */
    
    /* I handle the initial header first instead of just having the code
       read all three Vorbis headers at once because reading the initial
       header is an easy way to identify a Vorbis bitstream and it's
       useful to see that functionality seperated out. */
    
    vorbis_info_init(&vi);
    vorbis_comment_init(&vc);
    if(ogg_stream_pagein(&os,&og)<0){ 
      /* error; stream version mismatch perhaps */
      fprintf(stderr,"Error reading first page of Ogg bitstream data.\n");
      exit(1);
    }
    
    if(ogg_stream_packetout(&os,&op)!=1){ 
      /* no page? must not be vorbis */
      fprintf(stderr,"Error reading initial header packet.\n");
      exit(1);
    }
    
    if(vorbis_synthesis_headerin(&vi,&vc,&op)<0){ 
      /* error case; not a vorbis header */
      fprintf(stderr,"This Ogg bitstream does not contain Vorbis "
              "audio data.\n");
      exit(1);
    }
    
    /* At this point, we're sure we're Vorbis. We've set up the logical
       (Ogg) bitstream decoder. Get the comment and codebook headers and
       set up the Vorbis decoder */
    
    /* The next two packets in order are the comment and codebook headers.
       They're likely large and may span multiple pages. Thus we read
       and submit data until we get our two packets, watching that no
       pages are missing. If a page is missing, error out; losing a
       header page is the only place where missing data is fatal. */
    
    i=0;
    while(i<2){
      while(i<2){
        int result=ogg_sync_pageout(&oy,&og);
        if(result==0)break; /* Need more data */
        /* Don't complain about missing or corrupt data yet. We'll
           catch it at the packet output phase */
        if(result==1){
          ogg_stream_pagein(&os,&og); /* we can ignore any errors here
                                         as they'll also become apparent
                                         at packetout */
          while(i<2){
            result=ogg_stream_packetout(&os,&op);
            if(result==0)break;
            if(result<0){
              /* Uh oh; data at some point was corrupted or missing!
                 We can't tolerate that in a header.  Die. */
              fprintf(stderr,"Corrupt secondary header.  Exiting.\n");
              exit(1);
            }
            result=vorbis_synthesis_headerin(&vi,&vc,&op);
            if(result<0){
              fprintf(stderr,"Corrupt secondary header.  Exiting.\n");
              exit(1);
            }
            i++;
          }
        }
      }
      /* no harm in not checking before adding more */
      buffer=ogg_sync_buffer(&oy,4096);
      //bytes=fread(buffer,1,4096,stdin);
	  bytes=fread(buffer,1,4096,instream);
      if(bytes==0 && i<2){
        fprintf(stderr,"End of file before finding all Vorbis headers!\n");
        exit(1);
      }
      ogg_sync_wrote(&oy,bytes);
    }
    
    /* Throw the comments plus a few lines about the bitstream we're
       decoding */
    {
      char **ptr=vc.user_comments;
      while(*ptr){
        fprintf(stderr,"%s\n",*ptr);
        ++ptr;
      }
      fprintf(stderr,"\nBitstream is %d channel, %ldHz\n",vi.channels,vi.rate);
      fprintf(stderr,"Encoded by: %s\n\n",vc.vendor);
    }
    
    convsize=4096/vi.channels;

    /* OK, got and parsed all three headers. Initialize the Vorbis
       packet->PCM decoder. */
    if(vorbis_synthesis_init(&vd,&vi)==0){ /* central decode state */
      vorbis_block_init(&vd,&vb);          /* local state for most of the decode
                                              so multiple block decodes can
                                              proceed in parallel. We could init
                                              multiple vorbis_block structures
                                              for vd here */
      
      /* The rest is just a straight decode loop until end of stream */
      while(!eos){
        while(!eos){
          int result=ogg_sync_pageout(&oy,&og);
          if(result==0)break; /* need more data */
          if(result<0){ /* missing or corrupt data at this page position */
            fprintf(stderr,"Corrupt or missing data in bitstream; "
                    "continuing...\n");
          }else{
            ogg_stream_pagein(&os,&og); /* can safely ignore errors at
                                           this point */
            while(1){
              result=ogg_stream_packetout(&os,&op);
              
              if(result==0)break; /* need more data */
              if(result<0){ /* missing or corrupt data at this page position */
                /* no reason to complain; already complained above */
              }else{
                /* we have a packet.  Decode it */
                float **pcm;
                int samples;
                
                if(vorbis_synthesis(&vb,&op)==0) /* test for success! */
                  vorbis_synthesis_blockin(&vd,&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=vorbis_synthesis_pcmout(&vd,&pcm))>0){
                  int j;
                  int clipflag=0;
                  int bout=(samples<convsize?samples:convsize);
                  
                  /* convert floats to 16 bit signed ints (host order) and
                     interleave */
                  for(i=0;i<vi.channels;i++){
                    ogg_int16_t *ptr=convbuffer+i;
                    float  *mono=pcm[i];
                    for(j=0;j<bout;j++){
#if 1
                      int val=floor(mono[j]*32767.f+.5f);
#else /* optional dither */
                      int val=mono[j]*32767.f+drand48()-0.5f;
#endif
                      /* might as well guard against clipping */
                      if(val>32767){
                        val=32767;
                        clipflag=1;
                      }
                      if(val<-32768){
                        val=-32768;
                        clipflag=1;
                      }
                      *ptr=val;
                      ptr+=vi.channels;
                    }
                  }
                  
                  if(clipflag)
                    fprintf(stderr,"Clipping in frame %ld\n",(long)(vd.sequence));
                  
                  
                  //fwrite(convbuffer,2*vi.channels,bout,stdout);
				  fwrite(convbuffer,2*vi.channels,bout,outstream);
                  
                  vorbis_synthesis_read(&vd,bout); /* tell libvorbis how
                                                      many samples we
                                                      actually consumed */
                }            
              }
            }
            if(ogg_page_eos(&og))eos=1;
          }
        }
        if(!eos){
          buffer=ogg_sync_buffer(&oy,4096);
          //bytes=fread(buffer,1,4096,stdin);
		  bytes=fread(buffer,1,4096,instream);
          ogg_sync_wrote(&oy,bytes);
          if(bytes==0)eos=1;
        }
      }
      
      /* ogg_page and ogg_packet structs always point to storage in
         libvorbis.  They're never freed or manipulated directly */
      
      vorbis_block_clear(&vb);
      vorbis_dsp_clear(&vd);
    }else{
      fprintf(stderr,"Error: Corrupt header during playback initialization.\n");
    }

    /* clean up this logical bitstream; before exit we see if we're
       followed by another [chained] */
    
    ogg_stream_clear(&os);
    vorbis_comment_clear(&vc);
    vorbis_info_clear(&vi);  /* must be called last */
  }

  /* OK, clean up the framer */
  ogg_sync_clear(&oy);
  
  fprintf(stderr,"Done.\n");
  return(0);
}
Example #24
0
static stream_processor *
find_stream_processor (stream_set *set, ogg_page *page)
{	uint32_t serial = ogg_page_serialno (page) ;
	int i, invalid = 0 ;

	stream_processor *stream ;

	for (i = 0 ; i < set->used ; i++)
	{	if (serial == set->streams [i].serial)
		{	/* We have a match! */
			stream = & (set->streams [i]) ;

			set->in_headers = 0 ;
			/* if we have detected EOS, then this can't occur here. */
			if (stream->end)
			{	stream->isillegal = 1 ;
				return stream ;
			}

			stream->isnew = 0 ;
			stream->end = ogg_page_eos (page) ;
			stream->serial = serial ;
			return stream ;
		} ;
	} ;

	/* If there are streams open, and we've reached the end of the
	** headers, then we can't be starting a new stream.
	** XXX: might this sometimes catch ok streams if EOS flag is missing,
	** but the stream is otherwise ok?
	*/
	if (streams_open (set) && !set->in_headers)
		invalid = 1 ;

	set->in_headers = 1 ;

	if (set->allocated < set->used)
		stream = &set->streams [set->used] ;
	else
	{	set->allocated += 5 ;
		set->streams = realloc (set->streams, sizeof (stream_processor) * set->allocated) ;
		stream = &set->streams [set->used] ;
	} ;

	set->used++ ;

	stream->isnew = 1 ;
	stream->isillegal = invalid ;

	{	int res ;
		ogg_packet packet ;

		/* We end up processing the header page twice, but that's ok. */
		ogg_stream_init (&stream->ostream, serial) ;
		ogg_stream_pagein (&stream->ostream, page) ;
		res = ogg_stream_packetout (&stream->ostream, &packet) ;
		if (res <= 0)
			return NULL ;
		else if (packet.bytes >= 7 && memcmp (packet.packet, "\x01vorbis", 7) == 0)
		{	stream->lastgranulepos = 0 ;
			vorbis_comment_init (&stream->vcomment) ;
			vorbis_info_init (&stream->vinfo) ;
		} ;

		res = ogg_stream_packetout (&stream->ostream, &packet) ;

		/* re-init, ready for processing */
		ogg_stream_clear (&stream->ostream) ;
		ogg_stream_init (&stream->ostream, serial) ;
	}

	stream->end = ogg_page_eos (page) ;
	stream->serial = serial ;

	return stream ;
} /* find_stream_processor */
Example #25
0
static sf_count_t
vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn)
{	VORBIS_PRIVATE *vdata = psf->codec_data ;
	OGG_PRIVATE *odata = psf->container_data ;
	int len, samples, i = 0 ;
	float **pcm ;

	len = lens / psf->sf.channels ;

	while ((samples = vorbis_synthesis_pcmout (&vdata->vdsp, &pcm)) > 0)
	{	if (samples > len) samples = len ;
		i += transfn (psf, samples, ptr, i, psf->sf.channels, pcm) ;
		len -= samples ;
		/* tell libvorbis how many samples we actually consumed */
		vorbis_synthesis_read (&vdata->vdsp, samples) ;
		vdata->loc += samples ;
		if (len == 0)
			return i ; /* Is this necessary */
	}
	goto start0 ;		/* Jump into the nasty nest */
	while (len > 0 && !odata->eos)
	{	while (len > 0 && !odata->eos)
		{	int result = ogg_sync_pageout (&odata->osync, &odata->opage) ;
			if (result == 0) break ; /* need more data */
			if (result < 0)
			{	/* missing or corrupt data at this page position */
				psf_log_printf (psf, "Corrupt or missing data in bitstream ; continuing...\n") ;
			}
			else
			{	/* can safely ignore errors at this point */
				ogg_stream_pagein (&odata->ostream, &odata->opage) ;
start0:
				while (1)
				{	result = ogg_stream_packetout (&odata->ostream, &odata->opacket) ;
					if (result == 0)
						break ; /* need more data */
					if (result < 0)
					{	/* missing or corrupt data at this page position */
						/* no reason to complain ; already complained above */
					}
					else
					{	/* we have a packet.	Decode it */
						if (vorbis_synthesis (&vdata->vblock, &odata->opacket) == 0) /* test for success! */
							vorbis_synthesis_blockin (&vdata->vdsp, &vdata->vblock) ;
						/*
						** 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 = vorbis_synthesis_pcmout (&vdata->vdsp, &pcm)) > 0)
						{	if (samples > len) samples = len ;
							i += transfn (psf, samples, ptr, i, psf->sf.channels, pcm) ;
							len -= samples ;
							/* tell libvorbis how many samples we actually consumed */
							vorbis_synthesis_read (&vdata->vdsp, samples) ;
							vdata->loc += samples ;
							if (len == 0)
								return i ; /* Is this necessary */
						} ;
					}
				}
				if (ogg_page_eos (&odata->opage)) odata->eos = 1 ;
			}
		}
		if (!odata->eos)
		{	char *buffer ;
			int bytes ;
			buffer = ogg_sync_buffer (&odata->osync, 4096) ;
			bytes = psf_fread (buffer, 1, 4096, psf) ;
			ogg_sync_wrote (&odata->osync, bytes) ;
			if (bytes == 0) odata->eos = 1 ;
		}
	}
	return i ;
} /* vorbis_read_sample */
Example #26
0
int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
  unsigned char *header=og->header;
  unsigned char *body=og->body;
  long           bodysize=og->body_len;
  int            segptr=0;

  int version=ogg_page_version(og);
  int continued=ogg_page_continued(og);
  int bos=ogg_page_bos(og);
  int eos=ogg_page_eos(og);
  ogg_int64_t granulepos=ogg_page_granulepos(og);
  int serialno=ogg_page_serialno(og);
  long pageno=ogg_page_pageno(og);
  int segments=header[26];
  
  /* clean up 'returned data' */
  {
    long lr=os->lacing_returned;
    long br=os->body_returned;

    /* body data */
    if(br){
      os->body_fill-=br;
      if(os->body_fill)
	memmove(os->body_data,os->body_data+br,os->body_fill);
      os->body_returned=0;
    }

    if(lr){
      /* segment table */
      if(os->lacing_fill-lr){
	memmove(os->lacing_vals,os->lacing_vals+lr,
		(os->lacing_fill-lr)*sizeof(*os->lacing_vals));
	memmove(os->granule_vals,os->granule_vals+lr,
		(os->lacing_fill-lr)*sizeof(*os->granule_vals));
      }
      os->lacing_fill-=lr;
      os->lacing_packet-=lr;
      os->lacing_returned=0;
    }
  }

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

  _os_lacing_expand(os,segments+1);

  /* are we in sequence? */
  if(pageno!=os->pageno){
    int i;

    /* unroll previous partial packet (if any) */
    for(i=os->lacing_packet;i<os->lacing_fill;i++)
      os->body_fill-=os->lacing_vals[i]&0xff;
    os->lacing_fill=os->lacing_packet;

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

    /* are we a 'continued packet' page?  If so, we'll need to skip
       some segments */
    if(continued){
      bos=0;
      for(;segptr<segments;segptr++){
	int val=header[27+segptr];
	body+=val;
	bodysize-=val;
	if(val<255){
	  segptr++;
	  break;
	}
      }
    }
  }
  
  if(bodysize){
    _os_body_expand(os,bodysize);
    memcpy(os->body_data+os->body_fill,body,bodysize);
    os->body_fill+=bodysize;
  }

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

  }

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

  os->pageno=pageno+1;

  return(0);
}
int oe_encode ( oe_enc_opt* opt )
{
	ogg_stream_state os;
	ogg_page 		 og;
	ogg_packet 		 op;

	vorbis_dsp_state vd;
	vorbis_block     vb;
	vorbis_info      vi;

	long	samplesdone   = 0;
    int		eos;
	long	bytes_written = 0;
	long	packetsdone   = 0;
	int		ret           = 0;
	
	vorbis_info_init ( &vi );

	if ( opt->quality >= 0.0f )
	{
		if ( vorbis_encode_init_vbr ( &vi, opt->channels, opt->rate, opt->quality ) )
		{
			vorbis_info_clear ( &vi );
			return 1;
		}
	}
	else
	{
		if ( vorbis_encode_init ( 
									&vi,
									opt->channels,
									opt->rate,
									opt->max_bitrate > 0 ? opt->max_bitrate * 1000 : -1,
									opt->bitrate * 1000, 
									opt->min_bitrate > 0 ? opt->min_bitrate * 1000 : -1
								) )
		{
			vorbis_info_clear ( &vi );
			return 1;
		}
	}

	vorbis_analysis_init ( &vd, &vi );
	vorbis_block_init    ( &vd, &vb );

	ogg_stream_init ( &os, opt->serialno );

	ogg_packet header_main;
	ogg_packet header_comments;
	ogg_packet header_codebooks;
	int result;

	vorbis_analysis_headerout ( &vd,opt->comments, &header_main, &header_comments, &header_codebooks );

	ogg_stream_packetin ( &os, &header_main );
	ogg_stream_packetin ( &os, &header_comments );
	ogg_stream_packetin ( &os, &header_codebooks );

	while ( ( result = ogg_stream_flush ( &os, &og ) ) )
	{
		if ( !result )
			break;
		
		ret = oe_write_page ( &og, opt->out );

		if ( ret != og.header_len + og.body_len )
		{
			ret = 1;
			goto cleanup;
		}
		else
			bytes_written += ret;
	}
	
	eos = 0;

	while ( !eos )
	{
		float** buffer       = vorbis_analysis_buffer ( &vd, READSIZE );
		long    samples_read = opt->read_samples ( opt->readdata, buffer, READSIZE );

		if ( samples_read == 0 )
			vorbis_analysis_wrote ( &vd, 0 );
		else
		{
			samplesdone += samples_read;

			vorbis_analysis_wrote ( &vd, samples_read );
		}

		while ( vorbis_analysis_blockout ( &vd, &vb ) == 1 )
		{
			vorbis_analysis         ( &vb, NULL );
			vorbis_bitrate_addblock ( &vb );

			while ( vorbis_bitrate_flushpacket ( &vd, &op ) )
			{
				ogg_stream_packetin ( &os,&op );
				packetsdone++;

				while ( !eos )
				{
					int result = ogg_stream_pageout ( &os, &og );

					if ( !result )
						break;

					ret = oe_write_page ( &og, opt->out );

					if ( ret != og.header_len + og.body_len )
					{
						ret = 1;
						goto cleanup;
					}
					else
						bytes_written += ret; 
	
					if ( ogg_page_eos ( &og ) )
						eos = 1;
				}
			}
		}
	}

	ret = 0;

cleanup:

	ogg_stream_clear ( &os );

	vorbis_block_clear ( &vb );
	vorbis_dsp_clear   ( &vd );
	vorbis_info_clear  ( &vi );

	return ret;
}
Example #28
0
/*
  For lame_decode_fromfile:  return code
  -1     error, or eof
  0     ok, but need more data before outputing any samples
  n     number of samples output.  
*/
int lame_decode_ogg_fromfile( lame_global_flags*  gfp,
                              FILE*               fd,
                              short int           pcm_l[],
                              short int           pcm_r[],
                              mp3data_struct*     mp3data )
{
  lame_internal_flags *gfc = gfp->internal_flags;
  int samples,result,i,j,eof=0,eos=0,bout=0;
  double **pcm;

  while(1){

    /* 
    **pcm is a multichannel double 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 */
    /* unpack the buffer, if it has at least 1024 samples */
    convsize=1024;
    samples=vorbis_synthesis_pcmout(&vd,&pcm);
    if (samples >= convsize || eos || eof) {
      /* read 1024 samples, or if eos, read what ever is in buffer */
      int clipflag=0;
      bout=(samples<convsize?samples:convsize);
      
      /* convert doubles to 16 bit signed ints (host order) and
	 interleave */
      for(i=0;i<vi.channels;i++){
	double  *mono=pcm[i];
	for(j=0;j<bout;j++){
	  int val=mono[j]*32767.;
	  /* might as well guard against clipping */
	  if(val>32767){
	    val=32767;
	    clipflag=1;
	  }
	  if(val<-32768){
	    val=-32768;
	    clipflag=1;
	  }
	  if (i==0) pcm_l[j]=val;
	  if (i==1) pcm_r[j]=val;
	}
      }
      
      /*
      if(clipflag)
	MSGF( gfc, "Clipping in frame %ld\n", vd.sequence );
      */
      
      /* tell libvorbis how many samples we actually consumed */
      vorbis_synthesis_read(&vd,bout); 
      
      break;
    }    

    result=ogg_sync_pageout(&oy,&og);
      
    if(result==0) {
      /* need more data */
    }else if (result==-1){ /* missing or corrupt data at this page position */
      ERRORF( gfc, "Corrupt or missing data in bitstream; "
	      "continuing...\n");
    }else{
      /* decode this page */
      ogg_stream_pagein(&os,&og); /* can safely ignore errors at
				       this point */
      do {
	result=ogg_stream_packetout(&os,&op);
	if(result==0) {
	  /* need more data */
	} else 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 */
	  vorbis_synthesis(&vb,&op);
	  vorbis_synthesis_blockin(&vd,&vb);
	}
      } while (result!=0);
    }

    /* is this the last page? */    
    if(ogg_page_eos(&og))eos=1;
    
    if(!eos){
      char *buffer;
      int bytes;
      buffer=ogg_sync_buffer(&oy,4096);
      bytes=fread(buffer,1,4096,fd);
      ogg_sync_wrote(&oy,bytes);
      if(bytes==0)eof=1;
    }
  }

  mp3data->stereo = vi.channels;
  mp3data->samplerate = vi.rate;
  mp3data->bitrate = 0; //ov_bitrate_instant(&vf);
  /*  mp3data->nsamp=MAX_U_32_NUM;*/

  
  if (bout==0) {
    /* clean up this logical bitstream; before exit we see if we're
       followed by another [chained] */
    ogg_stream_clear(&os);
    
    /* ogg_page and ogg_packet structs always point to storage in
       libvorbis.  They're never freed or manipulated directly */
    
    vorbis_block_clear(&vb);
    vorbis_dsp_clear(&vd);
    vorbis_info_clear(&vi);  /* must be called last */
    
    /* OK, clean up the framer */
    ogg_sync_clear(&oy);
    return -1;
  }
  return bout;
}
Example #29
0
/**
**  Load vorbis.
**
**  @param name   File name.
**  @param flags  Load flags.
**
**  @return       Returns the loaded sample.
*/
CSample *LoadVorbis(const std::string &name, int flags)
{
	CSample *sample;
	OggData *data;
	CFile *f;
	vorbis_info *info;

	f = new CFile;
	if (f->open(name.c_str(), CL_OPEN_READ) == -1) {
		fprintf(stderr, "Can't open file `%s'\n", name.c_str());
		delete f;
		return NULL;
	}

	if (flags & PlayAudioStream) {
		sample = new CSampleVorbisStream;
		data = &((CSampleVorbisStream *)sample)->Data;
	} else {
		sample = new CSampleVorbis;
		data = &((CSampleVorbis *)sample)->Data;
	}
	memset(data, 0, sizeof(*data));

	if (OggInit(f, data) || !data->audio) {
		delete sample;
		f->close();
		delete f;
		return NULL;
	}

	info = &data->vinfo;

	sample->Channels = info->channels;
	sample->SampleSize = 16;
	sample->Frequency = info->rate;

	sample->Len = 0;
	sample->Pos = 0;
	data->File = f;

	if (flags & PlayAudioStream) {
		sample->Buffer = new unsigned char[SOUND_BUFFER_SIZE];
	} else {
		unsigned char *buf;
		int pos;
		int ret;
		int total;
		ogg_page pg;
		ogg_sync_state sync;
		int i;

		// find total size
		pos = f->tell();
		ogg_sync_init(&sync);
		for (i = 0; ; ++i) {
			f->seek(-1 * i * 4096, SEEK_END);
			buf = (unsigned char *)ogg_sync_buffer(&sync, 4096);
			f->read(buf, 8192);
			ogg_sync_wrote(&sync, 8192);
			if (ogg_sync_pageout(&sync, &pg) == 1 && ogg_page_eos(&pg)) {
				total = (int)(ogg_page_granulepos(&pg) * 2 * sample->Channels);
				break;
			}
		}
		f->seek(pos, SEEK_SET);

		sample->Buffer = new unsigned char[total];
		pos = 0;

		while ((ret = VorbisStreamRead(sample, &((CSampleVorbis *)sample)->Data,
				sample->Buffer + pos, 8192))) {
			pos += ret;
		}

		sample->Len = total;
		sample->Pos = 0;

		f->close();
		delete f;
		OggFree(data);
	}

	return sample;
}
S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname)
{
#define READ_BUFFER 1024
	unsigned char readbuffer[READ_BUFFER*4+44];   /* out of the data segment, not the stack */	/*Flawfinder: ignore*/

	ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */
	ogg_page         og; /* one Ogg bitstream page.  Vorbis packets are inside */
	ogg_packet       op; /* one raw packet of data for decode */
	
	vorbis_info      vi; /* struct that stores all the static vorbis bitstream settings */
	vorbis_comment   vc; /* struct that stores all the user comments */
	
	vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
	vorbis_block     vb; /* local working space for packet->PCM decode */
	
	int eos=0;
	int result;

	U16 num_channels = 0;
	U32 sample_rate = 0;
	U32 bits_per_sample = 0;

	S32 format_error = 0;
	std::string error_msg;
	if ((format_error = check_for_invalid_wav_formats(in_fname, error_msg)))
	{
		llwarns << error_msg << ": " << in_fname << llendl;
		return(format_error);
	}

#if 1
	unsigned char wav_header[44];	/*Flawfinder: ignore*/

	S32 data_left = 0;

	LLAPRFile infile ;
	infile.open(in_fname,LL_APR_RB);
	if (!infile.getFileHandle())
	{
		llwarns << "Couldn't open temporary ogg file for writing: " << in_fname
			<< llendl;
		return(LLVORBISENC_SOURCE_OPEN_ERR);
	}

	LLAPRFile outfile ;
	outfile.open(out_fname,LL_APR_WPB);
	if (!outfile.getFileHandle())
	{
		llwarns << "Couldn't open upload sound file for reading: " << in_fname
			<< llendl;
		return(LLVORBISENC_DEST_OPEN_ERR);
	}
	
	 // parse the chunks
	 U32 chunk_length = 0;
	 U32 file_pos = 12;  // start at the first chunk (usually fmt but not always)
	 
	 while (infile.eof() != APR_EOF)
	 {
		 infile.seek(APR_SET,file_pos);
		 infile.read(wav_header, 44);
		 
		 chunk_length = ((U32) wav_header[7] << 24) 
			 + ((U32) wav_header[6] << 16) 
			 + ((U32) wav_header[5] << 8) 
			 + wav_header[4];
		 
//		 llinfos << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << llendl;
		 
		 if (!(strncmp((char *)&(wav_header[0]),"fmt ",4)))
		 {
			 num_channels = ((U16) wav_header[11] << 8) + wav_header[10];
			 sample_rate = ((U32) wav_header[15] << 24) 
				 + ((U32) wav_header[14] << 16) 
				 + ((U32) wav_header[13] << 8) 
				 + wav_header[12];
			 bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22];
		 }
	 	 else if (!(strncmp((char *)&(wav_header[0]),"data",4)))
		 {
			 infile.seek(APR_SET,file_pos+8);
			 // leave the file pointer at the beginning of the data chunk data
			 data_left = chunk_length;			
			 break;
		 }
		 file_pos += (chunk_length + 8);
		 chunk_length = 0;
	 } 
	 

	 /********** Encode setup ************/
	 
	 /* choose an encoding mode */
	 /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
	 vorbis_info_init(&vi);

	 // always encode to mono

	 // SL-52913 & SL-53779 determined this quality level to be our 'good
	 // enough' general-purpose quality level with a nice low bitrate.
	 // Equivalent to oggenc -q0.5
	 F32 quality = 0.05f;
//	 quality = (bitrate==128000 ? 0.4f : 0.1);

//	 if (vorbis_encode_init(&vi, /* num_channels */ 1 ,sample_rate, -1, bitrate, -1))
	 if (vorbis_encode_init_vbr(&vi, /* num_channels */ 1 ,sample_rate, quality))
//	 if (vorbis_encode_setup_managed(&vi,1,sample_rate,-1,bitrate,-1) ||
//		vorbis_encode_ctl(&vi,OV_ECTL_RATEMANAGE_AVG,NULL) ||
//		vorbis_encode_setup_init(&vi))
	{
		llwarns << "unable to initialize vorbis codec at quality " << quality << llendl;
		//		llwarns << "unable to initialize vorbis codec at bitrate " << bitrate << llendl;
		return(LLVORBISENC_DEST_OPEN_ERR);
	}
	 
	 /* add a comment */
	 vorbis_comment_init(&vc);
//	 vorbis_comment_add(&vc,"Linden");
	 
	 /* set up the analysis state and auxiliary encoding storage */
	 vorbis_analysis_init(&vd,&vi);
	 vorbis_block_init(&vd,&vb);
	 
	 /* set up our packet->stream encoder */
	 /* pick a random serial number; that way we can more likely build
		chained streams just by concatenation */
	 ogg_stream_init(&os, ll_rand());
	 
	 /* Vorbis streams begin with three headers; the initial header (with
		most of the codec setup parameters) which is mandated by the Ogg
		bitstream spec.  The second header holds any comment fields.  The
		third header holds the bitstream codebook.  We merely need to
		make the headers, then pass them to libvorbis one at a time;
		libvorbis handles the additional Ogg bitstream constraints */
	 
	 {
		 ogg_packet header;
		 ogg_packet header_comm;
		 ogg_packet header_code;
		 
		 vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
		 ogg_stream_packetin(&os,&header); /* automatically placed in its own
											  page */
		 ogg_stream_packetin(&os,&header_comm);
		 ogg_stream_packetin(&os,&header_code);
		 
		 /* We don't have to write out here, but doing so makes streaming 
		  * much easier, so we do, flushing ALL pages. This ensures the actual
		  * audio data will start on a new page
		  */
		 while(!eos){
			 int result=ogg_stream_flush(&os,&og);
			 if(result==0)break;
			 outfile.write(og.header, og.header_len);
			 outfile.write(og.body, og.body_len);
		 }
		 
	 }
	 
	 
	 while(!eos)
	 {
		 long bytes_per_sample = bits_per_sample/8;

		 long bytes=(long)infile.read(readbuffer,llclamp((S32)(READ_BUFFER*num_channels*bytes_per_sample),0,data_left)); /* stereo hardwired here */
		 
		 if (bytes==0)
		 {
			 /* end of file.  this can be done implicitly in the mainline,
				but it's easier to see here in non-clever fashion.
				Tell the library we're at end of stream so that it can handle
				the last frame and mark end of stream in the output properly */

			 vorbis_analysis_wrote(&vd,0);
//			 eos = 1;
			 
		 }
		 else
		 {
			 long i;
			 long samples;
			 int temp;

			 data_left -= bytes;
             /* data to encode */
			 
			 /* expose the buffer to submit data */
			 float **buffer=vorbis_analysis_buffer(&vd,READ_BUFFER);
			
			 i = 0;
			 samples = bytes / (num_channels * bytes_per_sample);

			 if (num_channels == 2)
			 {
				 if (bytes_per_sample == 2)
				 {
					 /* uninterleave samples */
					 for(i=0; i<samples ;i++)
					 {
					 	 temp =  ((signed char *)readbuffer)[i*4+1];	/*Flawfinder: ignore*/
						 temp += ((signed char *)readbuffer)[i*4+3];	/*Flawfinder: ignore*/
						 temp <<= 8;
						 temp += readbuffer[i*4];
						 temp += readbuffer[i*4+2];

						 buffer[0][i] = ((float)temp) / 65536.f;
					 }
				 }
				 else // presume it's 1 byte per which is unsigned (F#@%ing wav "standard")
				 {
					 /* uninterleave samples */
					 for(i=0; i<samples ;i++)
					 {
					 	 temp  = readbuffer[i*2+0];
						 temp += readbuffer[i*2+1];
						 temp -= 256;
						 buffer[0][i] = ((float)temp) / 256.f;
					 }
				 } 
			 }
			 else if (num_channels == 1)
			 {
				 if (bytes_per_sample == 2)
				 {
					 for(i=0; i < samples ;i++)
					 {
					 	 temp = ((signed char*)readbuffer)[i*2+1];
						 temp <<= 8;
						 temp += readbuffer[i*2];
						 buffer[0][i] = ((float)temp) / 32768.f;
					 }
				 }
				 else // presume it's 1 byte per which is unsigned (F#@%ing wav "standard")
				 {
					 for(i=0; i < samples ;i++)
					 {
						 temp = readbuffer[i];
						 temp -= 128;
						 buffer[0][i] = ((float)temp) / 128.f;
					 }
				 }
			 }
				
			 /* tell the library how much we actually submitted */
			 vorbis_analysis_wrote(&vd,i);
		 }
			 
		 /* vorbis does some data preanalysis, then divvies up blocks for
			more involved (potentially parallel) processing.  Get a single
			block for encoding now */
		 while(vorbis_analysis_blockout(&vd,&vb)==1)
		 {
			 
			 /* analysis */
			/* Do the main analysis, creating a packet */
			vorbis_analysis(&vb, NULL);
			vorbis_bitrate_addblock(&vb);

			while(vorbis_bitrate_flushpacket(&vd, &op)) 
			{
			 
			 /* weld the packet into the bitstream */
			 ogg_stream_packetin(&os,&op);
			 
			 /* write out pages (if any) */
			 while(!eos)
			 {
				 result = ogg_stream_pageout(&os,&og);

				 if(result==0)
				 	break;

				 outfile.write(og.header, og.header_len);
				 outfile.write(og.body, og.body_len);
				 
				 /* this could be set above, but for illustrative purposes, I do
					it here (to show that vorbis does know where the stream ends) */
				 
				 if(ogg_page_eos(&og))
				 	eos=1;
				 
			 }
			}
		 }
	 }
	 
	 
	 
	 /* clean up and exit.  vorbis_info_clear() must be called last */
	 
	 ogg_stream_clear(&os);
	 vorbis_block_clear(&vb);
	 vorbis_dsp_clear(&vd);
	 vorbis_comment_clear(&vc);
	 vorbis_info_clear(&vi);
	 
	 /* ogg_page and ogg_packet structs always point to storage in
		libvorbis.  They're never freed or manipulated directly */
	 
//	 fprintf(stderr,"Vorbis encoding: Done.\n");
	 llinfos << "Vorbis encoding: Done." << llendl;
	 
#endif
	 return(LLVORBISENC_NOERR);
	 
}