void OggWriter::closeResource() { vorbis_analysis_wrote( this->dsp_.get(), 0 ); while( vorbis_analysis_blockout( this->dsp_.get(), this->block_.get() ) == 1 ) { vorbis_analysis( this->block_.get(), NULL ); vorbis_bitrate_addblock( this->block_.get() ); ogg_packet op; while( vorbis_bitrate_flushpacket( this->dsp_.get(), &op ) ) { ogg_stream_packetin( this->muxer_.get(), &op ); } for(;;) { ogg_page og; int ret = ogg_stream_pageout( this->muxer_.get(), &og ); if( ret == 0 ) { break; } std::fwrite( og.header, 1, og.header_len, this->fout_.get() ); std::fwrite( og.body, 1, og.body_len, this->fout_.get() ); } } this->quality_ = -1.f; this->comments_.reset(); this->block_.reset(); this->dsp_.reset(); this->muxer_.reset(); this->encoder_.reset(); this->fout_.reset(); }
static GstBuffer * _create_audio_buffer (void) { GstBuffer *buffer; ogg_packet packet; float **vorbis_buffer; gint i; vorbis_buffer = vorbis_analysis_buffer (&vd, 44100); for (i = 0; i < 44100 * 1; ++i) vorbis_buffer[0][i] = 0.0; vorbis_analysis_wrote (&vd, 44100); vorbis_analysis_blockout (&vd, &vb); vorbis_analysis (&vb, NULL); vorbis_bitrate_addblock (&vb); vorbis_bitrate_flushpacket (&vd, &packet); buffer = gst_buffer_new_and_alloc (packet.bytes); gst_buffer_fill (buffer, 0, packet.packet, packet.bytes); vorbis_comment_clear (&vc); vorbis_block_clear (&vb); vorbis_dsp_clear (&vd); vorbis_info_clear (&vi); return buffer; }
static GstFlowReturn gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc) { GstFlowReturn ret; /* vorbis does some data preanalysis, then divides up blocks for more involved (potentially parallel) processing. Get a single block for encoding now */ while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) { ogg_packet op; GST_LOG_OBJECT (vorbisenc, "analysed to a block"); /* analysis */ vorbis_analysis (&vorbisenc->vb, NULL); vorbis_bitrate_addblock (&vorbisenc->vb); while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) { GST_LOG_OBJECT (vorbisenc, "pushing out a data packet"); ret = gst_vorbis_enc_push_packet (vorbisenc, &op); if (ret != GST_FLOW_OK) return ret; } } return GST_FLOW_OK; }
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; } } } }
void SoundFileWriterOgg::flushBlocks() { // Let the library divide uncompressed data into blocks, and process them vorbis_block block; vorbis_block_init(&m_state, &block); while (vorbis_analysis_blockout(&m_state, &block) == 1) { // Let the automatic bitrate management do its job vorbis_analysis(&block, NULL); vorbis_bitrate_addblock(&block); // Get new packets from the bitrate management engine ogg_packet packet; while (vorbis_bitrate_flushpacket(&m_state, &packet)) { // Write the packet to the ogg stream ogg_stream_packetin(&m_ogg, &packet); // If the stream produced new pages, write them to the output file ogg_page page; while (ogg_stream_flush(&m_ogg, &page) > 0) { m_file.write(reinterpret_cast<const char*>(page.header), page.header_len); m_file.write(reinterpret_cast<const char*>(page.body), page.body_len); } } } // Clear the allocated block vorbis_block_clear(&block); }
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; }
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; } } } }
/*********************************************************************** * Flush *********************************************************************** * **********************************************************************/ static hb_buffer_t * Flush( hb_work_object_t * w ) { hb_work_private_t * pv = w->private_data; hb_buffer_t * buf; int64_t blocksize = 0; if( vorbis_analysis_blockout( &pv->vd, &pv->vb ) == 1 ) { ogg_packet op; vorbis_analysis( &pv->vb, NULL ); vorbis_bitrate_addblock( &pv->vb ); if( vorbis_bitrate_flushpacket( &pv->vd, &op ) ) { buf = hb_buffer_init( sizeof( ogg_packet ) + op.bytes ); memcpy( buf->data, &op, sizeof( ogg_packet ) ); memcpy( buf->data + sizeof( ogg_packet ), op.packet, op.bytes ); blocksize = vorbis_packet_blocksize(&pv->vi, &op); buf->frametype = HB_FRAME_AUDIO; buf->start = (int64_t)(vorbis_granule_time(&pv->vd, op.granulepos) * 90000); buf->stop = (int64_t)(vorbis_granule_time(&pv->vd, (pv->prev_blocksize + blocksize)/4 + op.granulepos) * 90000); /* The stop time isn't accurate for the first ~3 packets, as the actual blocksize depends on the previous _and_ current packets. */ pv->prev_blocksize = blocksize; return buf; } } return NULL; }
/*------------------------------------------------------------------------------ * Send pending Vorbis blocks to the underlying stream *----------------------------------------------------------------------------*/ void VorbisLibEncoder :: vorbisBlocksOut ( void ) throw () { while ( 1 == vorbis_analysis_blockout( &vorbisDspState, &vorbisBlock) ) { ogg_packet oggPacket; ogg_page oggPage; vorbis_analysis( &vorbisBlock, &oggPacket); #ifdef VORBIS_LIB_RC3 vorbis_bitrate_addblock( &vorbisBlock); while ( vorbis_bitrate_flushpacket( &vorbisDspState, &oggPacket) ) { #endif ogg_stream_packetin( &oggStreamState, &oggPacket); while ( ogg_stream_pageout( &oggStreamState, &oggPage) ) { int written; written = sink->write( oggPage.header, oggPage.header_len); written += sink->write( oggPage.body, oggPage.body_len); if ( written < oggPage.header_len + oggPage.body_len ) { // just let go data that could not be written reportEvent( 2, "couldn't write full vorbis data to underlying sink", oggPage.header_len + oggPage.body_len - written); } } #ifdef VORBIS_LIB_RC3 } #endif } }
int fetch_and_process_audio(FILE *audio,ogg_page *audiopage, ogg_stream_state *vo, vorbis_dsp_state *vd, vorbis_block *vb, int audioflag){ ogg_packet op; int i,j; while(audio && !audioflag){ /* process any audio already buffered */ spinnit(); if(ogg_stream_pageout(vo,audiopage)>0) return 1; if(ogg_stream_eos(vo))return 0; { /* read and process more audio */ signed char readbuffer[4096]; int toread=4096/2/audio_ch; int bytesread=fread(readbuffer,1,toread*2*audio_ch,audio); int sampread=bytesread/2/audio_ch; float **vorbis_buffer; int count=0; if(bytesread<=0){ /* end of file. this can be done implicitly, 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{ vorbis_buffer=vorbis_analysis_buffer(vd,sampread); /* uninterleave samples */ for(i=0;i<sampread;i++){ for(j=0;j<audio_ch;j++){ vorbis_buffer[j][i]=((readbuffer[count+1]<<8)| (0x00ff&(int)readbuffer[count]))/32768.f; count+=2; } } vorbis_analysis_wrote(vd,sampread); } while(vorbis_analysis_blockout(vd,vb)==1){ /* analysis, assume we want to use bitrate management */ vorbis_analysis(vb,NULL); vorbis_bitrate_addblock(vb); /* weld packets into the bitstream */ while(vorbis_bitrate_flushpacket(vd,&op)) ogg_stream_packetin(vo,&op); } } } return audioflag; }
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 */
/*! * \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; } } } } }
static int tc_vorbis_outframe(VorbisPrivateData *pd, TCFrameAudio *f) { int has_block = TC_FALSE; ogg_packet op; tc_frame_audio_setup(f); do { has_block = vorbis_analysis_blockout(&pd->vd, &pd->vb); if (has_block == 1) { int has_pkt; /* FIXME: analysis, assume we want to use bitrate management */ vorbis_analysis(&pd->vb, NULL); vorbis_bitrate_addblock(&pd->vb); do { has_pkt = vorbis_bitrate_flushpacket(&pd->vd, &op); if (has_pkt) { tc_frame_audio_add_ogg_packet(pd, f, &op); pd->packets++; } } while (has_pkt); } } while (has_block); pd->frames++; return TC_OK; }
static GstFlowReturn gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc) { GstFlowReturn ret; /* vorbis does some data preanalysis, then divides up blocks for more involved (potentially parallel) processing. Get a single block for encoding now */ while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) { ogg_packet op; GST_LOG_OBJECT (vorbisenc, "analysed to a block"); /* analysis */ vorbis_analysis (&vorbisenc->vb, NULL); vorbis_bitrate_addblock (&vorbisenc->vb); while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) { GstBuffer *buf; if (op.e_o_s) { GstAudioEncoder *enc = GST_AUDIO_ENCODER (vorbisenc); GstClockTime duration; GST_DEBUG_OBJECT (vorbisenc, "Got EOS packet from libvorbis"); GST_AUDIO_ENCODER_STREAM_LOCK (enc); if (!GST_CLOCK_TIME_IS_VALID (enc->output_segment.stop)) { GST_DEBUG_OBJECT (vorbisenc, "Output segment has no end time, setting"); duration = gst_util_uint64_scale (op.granulepos, GST_SECOND, vorbisenc->frequency); enc->output_segment.stop = enc->output_segment.start + duration; GST_DEBUG_OBJECT (enc, "new output segment %" GST_SEGMENT_FORMAT, &enc->output_segment); gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (enc), gst_event_new_segment (&enc->output_segment)); } GST_AUDIO_ENCODER_STREAM_UNLOCK (enc); } GST_LOG_OBJECT (vorbisenc, "pushing out a data packet"); buf = gst_audio_encoder_allocate_output_buffer (GST_AUDIO_ENCODER (vorbisenc), op.bytes); gst_buffer_fill (buf, 0, op.packet, op.bytes); /* tracking granulepos should tell us samples accounted for */ ret = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (vorbisenc), buf, op.granulepos - vorbisenc->samples_out); vorbisenc->samples_out = op.granulepos; if (ret != GST_FLOW_OK) return ret; } } return GST_FLOW_OK; }
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; }
static int oggvorbis_encode_frame(AVCodecContext *avccontext, unsigned char *packets, int buf_size, void *data) { OggVorbisContext *context = avccontext->priv_data ; float **buffer ; ogg_packet op ; signed short *audio = data ; int l, samples = data ? OGGVORBIS_FRAME_SIZE : 0; buffer = vorbis_analysis_buffer(&context->vd, samples) ; if(context->vi.channels == 1) { for(l = 0 ; l < samples ; l++) buffer[0][l]=audio[l]/32768.f; } else { for(l = 0 ; l < samples ; l++){ buffer[0][l]=audio[l*2]/32768.f; buffer[1][l]=audio[l*2+1]/32768.f; } } vorbis_analysis_wrote(&context->vd, samples) ; while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) { vorbis_analysis(&context->vb, NULL); vorbis_bitrate_addblock(&context->vb) ; while(vorbis_bitrate_flushpacket(&context->vd, &op)) { /* i'd love to say the following line is a hack, but sadly it's * not, apparently the end of stream decision is in libogg. */ if(op.bytes==1) continue; memcpy(context->buffer + context->buffer_index, &op, sizeof(ogg_packet)); context->buffer_index += sizeof(ogg_packet); memcpy(context->buffer + context->buffer_index, op.packet, op.bytes); context->buffer_index += op.bytes; // av_log(avccontext, AV_LOG_DEBUG, "e%d / %d\n", context->buffer_index, op.bytes); } } l=0; if(context->buffer_index){ ogg_packet *op2= (ogg_packet*)context->buffer; op2->packet = context->buffer + sizeof(ogg_packet); l= op2->bytes; avccontext->coded_frame->pts= av_rescale_q(op2->granulepos, (AVRational){1, avccontext->sample_rate}, avccontext->time_base); //FIXME we should reorder the user supplied pts and not assume that they are spaced by 1/sample_rate memcpy(packets, op2->packet, l); context->buffer_index -= l + sizeof(ogg_packet); memcpy(context->buffer, context->buffer + l + sizeof(ogg_packet), context->buffer_index); // av_log(avccontext, AV_LOG_DEBUG, "E%d\n", l); } return l; }
int32_t kr_vorbis_encode (krad_vorbis_t *vorbis, kr_codeme_t *codeme, kr_medium_t *medium) { int32_t bo_ret; int32_t ret; int c; float **pcm; ogg_packet op; if (medium != NULL) { if (medium->a.count > 0) { pcm = vorbis_analysis_buffer (&vorbis->vdsp, medium->a.count); for (c = 0; c < vorbis->channels; c++) { memcpy (pcm[c], medium->a.samples[c], medium->a.count * 4); } } else { printk ("KR Vorbis Encoder: Got finish notice"); } ret = vorbis_analysis_wrote (&vorbis->vdsp, medium->a.count); if (ret < 0) { vorbis->error = ret; vorbis->state_str = "Krad Vorbis Encoder: vorbis_analysis_wrote fail"; printke (vorbis->state_str); return -1; } //printk ("KR Vorbis Encoder: wrote %d samples", medium->a.count); } bo_ret = vorbis_analysis_blockout (&vorbis->vdsp, &vorbis->vblock); if (bo_ret < 0) { vorbis->error = bo_ret; vorbis->state_str = "Krad Vorbis Encoder: vorbis_analysis_blockout fail"; printke (vorbis->state_str); return -1; } if (bo_ret == 1) { ret = vorbis_analysis (&vorbis->vblock, &op); if (ret < 0) { vorbis->error = ret; vorbis->state_str = "Krad Vorbis Encoder: vorbis_analysis fail"; printke (vorbis->state_str); return -1; } //printk ("KR Vorbis Encoder: op gpos: %"PRIi64" size %ld", // op.granulepos, op.bytes); codeme->sz = op.bytes; codeme->count = op.granulepos - vorbis->frames; vorbis->frames = op.granulepos; memcpy (codeme->data, op.packet, codeme->sz); //printk ("KR Vorbis Encoder: codeme size: %zu Count: %d", // codeme->sz, codeme->count); } return bo_ret; }
static double encode_vorbis( FILE *f, vorbis_dsp_state *vd, ogg_stream_state *vo, vorbis_block *vb, unsigned int audio_rate, double audiopos, signed char *buf, int n_samples ) { float **vorbis_buffer; const int audio_ch = 2; int i,j; int count = 0; ogg_page og; int got_page = 0; vorbis_buffer = vorbis_analysis_buffer( vd, n_samples ); for( i = 0; i < n_samples; i++ ) { for( j = 0; j < audio_ch; j++ ) { vorbis_buffer[j][i] = ( ( buf[count+1] << 8 ) | ( buf[count] & 0xff ) ) / 32768.0f; count += 2; } } vorbis_analysis_wrote( vd, n_samples ); while( vorbis_analysis_blockout( vd, vb ) == 1 ) { ogg_packet op; vorbis_analysis( vb, NULL ); vorbis_bitrate_addblock( vb ); while( vorbis_bitrate_flushpacket( vd, &op ) ) { ogg_stream_packetin( vo, &op ); } } while( ogg_stream_pageout( vo, &og ) ) { got_page = 1; audiopos = vorbis_granule_time( vd, ogg_page_granulepos( &og ) ); /* printf( "VORBIS: %f\n", audiopos ); */ fwrite( og.header, og.header_len, 1, f ); fwrite( og.body, og.body_len, 1, f ); } if( !got_page ) { double t; t = ( ( 1.0 * n_samples ) / audio_rate ); audiopos += t; } return audiopos; }
static int oggvorbis_encode_frame(AVCodecContext *avccontext, unsigned char *packets, int buf_size, void *data) { OggVorbisContext *context = avccontext->priv_data ; float **buffer ; ogg_packet op ; signed char *audio = data ; int l, samples = data ? OGGVORBIS_FRAME_SIZE : 0; buffer = vorbis_analysis_buffer(&context->vd, samples) ; if(context->vi.channels == 1) { for(l = 0 ; l < samples ; l++) buffer[0][l]=((audio[l*2+1]<<8)|(0x00ff&(int)audio[l*2]))/32768.f; } else { for(l = 0 ; l < samples ; l++){ buffer[0][l]=((audio[l*4+1]<<8)|(0x00ff&(int)audio[l*4]))/32768.f; buffer[1][l]=((audio[l*4+3]<<8)|(0x00ff&(int)audio[l*4+2]))/32768.f; } } vorbis_analysis_wrote(&context->vd, samples) ; while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) { vorbis_analysis(&context->vb, NULL); vorbis_bitrate_addblock(&context->vb) ; while(vorbis_bitrate_flushpacket(&context->vd, &op)) { if(op.bytes==1) //id love to say this is a hack, bad sadly its not, appearently the end of stream decission is in libogg continue; memcpy(context->buffer + context->buffer_index, &op, sizeof(ogg_packet)); context->buffer_index += sizeof(ogg_packet); memcpy(context->buffer + context->buffer_index, op.packet, op.bytes); context->buffer_index += op.bytes; // av_log(avccontext, AV_LOG_DEBUG, "e%d / %d\n", context->buffer_index, op.bytes); } } l=0; if(context->buffer_index){ ogg_packet *op2= (ogg_packet*)context->buffer; op2->packet = context->buffer + sizeof(ogg_packet); l= op2->bytes; avccontext->coded_frame->pts= av_rescale(op2->granulepos, AV_TIME_BASE, avccontext->sample_rate); memcpy(packets, op2->packet, l); context->buffer_index -= l + sizeof(ogg_packet); memcpy(context->buffer, context->buffer + l + sizeof(ogg_packet), context->buffer_index); // av_log(avccontext, AV_LOG_DEBUG, "E%d\n", l); } return l; }
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; }
/* Returns: * 0 No output at this time * >0 Page produced * * Caller should loop over this to ensure that we don't end up with * excessive buffering in libvorbis. */ int encode_dataout(encoder_state *s, ogg_page *og) { ogg_packet op; int result; if(s->in_header) { result = ogg_stream_flush(&s->os, og); if(result==0) { s->in_header = 0; return encode_dataout(s,og); } else return 1; } else { 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, &op)) ogg_stream_packetin(&s->os, &op); } /* FIXME: Make this threshold configurable. * We don't want to buffer too many samples in one page when doing * live encoding - that's fine for non-live encoding, but breaks * badly when doing things live. * So, we flush the stream if we have too many samples buffered */ if(s->samples_in_current_page > s->samplerate * 2) { /*LOG_DEBUG1("Forcing flush: Too many samples in current page (%d)", s->samples_in_current_page); */ result = ogg_stream_flush(&s->os, og); } else result = ogg_stream_pageout(&s->os, og); if(result==0) return 0; else /* Page found! */ { s->samples_in_current_page -= ogg_page_granulepos(og) - s->prevgranulepos; s->prevgranulepos = ogg_page_granulepos(og); return 1; } } }
/* Returns TRUE if an ogg page was output, FALSE if there is nothing * left to do. */ gboolean xmms_ices_encoder_output (encoder_state *s, ogg_page *og) { ogg_packet op; /* As long as we're still in the header, we still have the header * packets to output. Loop over those before going to the actual * vorbis data. */ if (s->in_header) { if (ogg_stream_flush (&s->os, og)) return TRUE; else s->in_header = FALSE; } /* If we're flushing the end of the stream, just output. */ if (s->flushing) { if (ogg_stream_flush (&s->os, og)) return TRUE; else return FALSE; } /* Flush the vorbis analysis stream into ogg packets, and add * those to the ogg packet stream. */ 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, &op)) ogg_stream_packetin (&s->os, &op); } /* For live encoding, we want to stream pages regularly, rather * than burst huge pages. Therefore, we periodically manually * flush the stream. */ if (s->samples_in_current_page > s->rate * 2) { if (!ogg_stream_flush (&s->os, og)) return FALSE; } else { if (!ogg_stream_pageout (&s->os, og)) return FALSE; } /* At this point, we have an ogg page in og. Keep bookkeeping * accurate regarding the number of samples still in the page * buffer, and return. */ s->samples_in_current_page -= (ogg_page_granulepos (og) - s->previous_granulepos); s->previous_granulepos = ogg_page_granulepos (og); return TRUE; }
static void vorbis_encoder_blockout(struct vorbis_encoder *encoder) { while (vorbis_analysis_blockout(&encoder->vd, &encoder->vb) == 1) { ogg_packet packet; vorbis_analysis(&encoder->vb, NULL); vorbis_bitrate_addblock(&encoder->vb); while (vorbis_bitrate_flushpacket(&encoder->vd, &packet)) ogg_stream_packetin(&encoder->os, &packet); } }
void encode_finish(encoder_state *s) { ogg_packet op; vorbis_analysis_wrote(&s->vd, 0); 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, &op)) ogg_stream_packetin(&s->os, &op); } }
void WebMEncoder::encodeAudioInterleaved(const short* samples,int samplesToEncode) { //cout << "AUDIO TIME: " << (lastAudioTime+samplesToEncode-audioSampleRate/2)/double(audioSampleRate) << " VIDEO TIME " << curFrame/30.0 << endl; if( (lastAudioTime+samplesToEncode)>audioSampleRate/2 && (lastAudioTime+samplesToEncode-24000)/double(audioSampleRate) > curFrame/30.0) return; // Skip this frame float **buffer = vorbis_analysis_buffer(&vd,samplesToEncode); const short* curSample = samples; for(int a=0;a<samplesToEncode;a++) { for(int b=0;b<2;b++) { buffer[b][a] = (*curSample)/32768.0f; curSample++; } } vorbis_analysis_wrote(&vd,samplesToEncode); /* 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(true){ ogg_packet opNotMine; if(!vorbis_bitrate_flushpacket(&vd,&opNotMine)) { break; } ogg_packet* op = new ogg_packet(); op->packet = (unsigned char*)malloc(opNotMine.bytes); memcpy(op->packet, opNotMine.packet, opNotMine.bytes); op->bytes = opNotMine.bytes; op->granulepos = opNotMine.granulepos; lastAudioTime = op->granulepos; boost::mutex::scoped_lock scoped_lock(muxerMutex); long long audioTimeNS = ((long long)(double(op->granulepos)*1000000000.0/audioSampleRate)); //printf("GOT AUDIO FRAME: %lld\n", audioTimeNS/1000000); packetsToWrite[audioTimeNS] = op; //cout << "CURRENT AUDIO TIME IN SAMPLES: " << lastAudioTime << " IN SECONDS: " << (double(lastAudioTime)/audioSampleRate) << endl; } } }
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; }
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; }
void TargetFileOggVorbis::processAndWriteVorbisBlocks() { while ( vorbis_analysis_blockout( &mVorbisDspState, &mVorbisBlock ) == 1 ) { vorbis_analysis( &mVorbisBlock, NULL ); vorbis_bitrate_addblock( &mVorbisBlock ); while ( vorbis_bitrate_flushpacket( &mVorbisDspState, &mOggPacket ) == 1 ) { ogg_stream_packetin( &mOggStream, &mOggPacket ); while ( ogg_stream_pageout( &mOggStream, &mOggPage ) != 0 ) { mStream->writeData( mOggPage.header, mOggPage.header_len ); mStream->writeData( mOggPage.body, mOggPage.body_len ); } } } }
void SyncEncodeSoundBuffer(ProgData *pdata,signed char *buff){ float **vorbis_buffer; int count=0,i,j; int sampread=(buff!=NULL)?pdata->periodsize:0; vorbis_buffer=vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp,sampread); if(!pdata->args.use_jack){ for(i=0;i<sampread;i++){ for(j=0;j<pdata->args.channels;j++){ vorbis_buffer[j][i]=((buff[count+1]<<8)| (0x00ff&(int)buff[count]))/ 32768.f; count+=2; } } } else{ for(j=0;j<pdata->args.channels;j++){ for(i=0;i<sampread;i++){ vorbis_buffer[j][i]=((float*)buff)[count]; count++; } } } vorbis_analysis_wrote(&pdata->enc_data->m_vo_dsp,sampread); pthread_mutex_lock(&pdata->libogg_mutex); while(vorbis_analysis_blockout(&pdata->enc_data->m_vo_dsp, &pdata->enc_data->m_vo_block)==1){ vorbis_analysis(&pdata->enc_data->m_vo_block,NULL); vorbis_bitrate_addblock(&pdata->enc_data->m_vo_block); while(vorbis_bitrate_flushpacket(&pdata->enc_data->m_vo_dsp, &pdata->enc_data->m_ogg_pckt2)){ ogg_stream_packetin(&pdata->enc_data->m_ogg_vs, &pdata->enc_data->m_ogg_pckt2); } } pthread_mutex_unlock(&pdata->libogg_mutex); if(!pdata->running)pdata->enc_data->m_ogg_vs.e_o_s=1; pdata->avd-=pdata->periodtime; }
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; }