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); } }
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; }
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; } } }
/*! * \brief Close a OGG/Vorbis filestream. * \param fs A OGG/Vorbis filestream. */ static void ogg_vorbis_close(struct ast_filestream *fs) { struct ogg_vorbis_desc *s = (struct ogg_vorbis_desc *) fs->_private; if (s->writing) { /* Tell the Vorbis encoder that the stream is finished * and write out the rest of the data */ vorbis_analysis_wrote(&s->vd, 0); write_stream(s, fs->f); } else { /* clear OggVorbis_File handle */ ov_clear(&s->ov_f); } }
static av_cold int oggvorbis_encode_close(AVCodecContext *avccontext) { OggVorbisContext *context = avccontext->priv_data ; /* ogg_packet op ; */ vorbis_analysis_wrote(&context->vd, 0) ; /* notify vorbisenc this is EOF */ vorbis_block_clear(&context->vb); vorbis_dsp_clear(&context->vd); vorbis_info_clear(&context->vi); av_freep(&avccontext->coded_frame); av_freep(&avccontext->extradata); return 0 ; }
void EncoderVorbis::encodeBuffer(const CSAMPLE *samples, const int size) { float **buffer = vorbis_analysis_buffer(&m_vdsp, size); // Deinterleave samples. We use normalized floats in the engine [-1.0, 1.0] // and libvorbis expects samples in the range [-1.0, 1.0] so no conversion // is required. for (int i = 0; i < size/2; ++i) { buffer[0][i] = samples[i*2]; buffer[1][i] = samples[i*2+1]; } /** encodes audio **/ vorbis_analysis_wrote(&m_vdsp, size/2); /** writes the OGG page and sends it to file or stream **/ writePage(); }
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; }
/* Encode the given data into Ogg Vorbis. */ void xmms_ices_encoder_input (encoder_state *s, xmms_samplefloat_t *buf, int bytes) { float **buffer; int i,j; int channels = s->vi.channels; int samples = bytes / (sizeof (xmms_samplefloat_t)*channels); buffer = vorbis_analysis_buffer (&s->vd, samples); for (i = 0; i < samples; i++) for (j = 0; j < channels; j++) buffer[j][i] = buf[i*channels + j]; vorbis_analysis_wrote (&s->vd, samples); s->samples_in_current_page += samples; }
void encode_data_float(encoder_state *s, float **pcm, int samples) { float **buf; int i; buf = vorbis_analysis_buffer(&s->vd, samples); for(i=0; i < s->vi.channels; i++) { memcpy(buf[i], pcm[i], samples*sizeof(float)); } vorbis_analysis_wrote(&s->vd, samples); s->samples_in_current_page += samples; }
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; }
void OggVorbisEncoder::close() { if (mClosed) return; // Mark end of data and flush any remaining data in the buffers vorbis_analysis_wrote(&mVorbisState, 0); writeBlocks(); flush(); ogg_stream_clear(&mOggState); vorbis_block_clear(&mVorbisBlock); vorbis_dsp_clear(&mVorbisState); vorbis_info_clear(&mVorbisInfo); mClosed = true; }
void SoundFileWriterOgg::close() { if (m_file.is_open()) { // Submit an empty packet to mark the end of stream vorbis_analysis_wrote(&m_state, 0); flushBlocks(); // Close the file m_file.close(); } // Clear all the ogg/vorbis structures ogg_stream_clear(&m_ogg); vorbis_dsp_clear(&m_state); vorbis_info_clear(&m_vorbis); }
int FileVorbis::close_file() { if(fd) { if(wr) { vorbis_analysis_wrote(&vd, 0); FLUSH_VORBIS ogg_stream_clear(&os); vorbis_block_clear(&vb); vorbis_dsp_clear(&vd); vorbis_comment_clear(&vc); vorbis_info_clear(&vi); fclose(fd); } if(rd) { // This also closes the file handle. ov_clear(&vf); } fd = 0; } if(pcm_history) { for(int i = 0; i < asset->channels; i++) delete [] pcm_history[i]; delete [] pcm_history; } if(pcm_history_float) { for(int i = 0; i < asset->channels; i++) delete [] pcm_history_float[i]; delete [] pcm_history_float; } reset_parameters(); FileBase::close_file(); return 0; }
void TargetFileOggVorbis::performWrite( const Buffer *buffer, size_t numFrames, size_t frameOffset ) { // process incoming buffer in chunks of maximum mVorbisBufferSize, this prevents memory allocation errors auto currFrame = frameOffset; auto lastFrame = frameOffset + numFrames; while ( currFrame != lastFrame ) { auto numFramesChunk = std::min( mVorbisBufferSize, lastFrame - currFrame ); float ** bufferOgg = vorbis_analysis_buffer( &mVorbisDspState, (int)numFramesChunk ); for ( size_t c = 0; c < getNumChannels(); ++c ) { std::memcpy( bufferOgg[ c ], buffer->getChannel( c ) + currFrame, numFramesChunk * sizeof( float ) ); } vorbis_analysis_wrote( &mVorbisDspState, (int)numFramesChunk ); processAndWriteVorbisBlocks(); currFrame += numFramesChunk; } }
static GstFlowReturn gst_vorbis_enc_clear (GstVorbisEnc * vorbisenc) { GstFlowReturn ret = GST_FLOW_OK; if (vorbisenc->setup) { vorbis_analysis_wrote (&vorbisenc->vd, 0); ret = gst_vorbis_enc_output_buffers (vorbisenc); /* marked EOS to encoder, recreate if needed */ vorbisenc->setup = FALSE; } /* clean up and exit. vorbis_info_clear() must be called last */ vorbis_block_clear (&vorbisenc->vb); vorbis_dsp_clear (&vorbisenc->vd); vorbis_info_clear (&vorbisenc->vi); return ret; }
int FileVorbis::write_samples(double **buffer, int64_t len) { if(!fd) return 0; float **vorbis_buffer = vorbis_analysis_buffer(&vd, len); for(int i = 0; i < asset->channels; i++) { float *output = vorbis_buffer[i]; double *input = buffer[i]; for(int j = 0; j < len; j++) { output[j] = input[j]; } } vorbis_analysis_wrote(&vd, len); FLUSH_VORBIS return 0; }
void ogg_encoder_end_handler(guac_audio_stream* audio) { /* Get state */ ogg_encoder_state* state = (ogg_encoder_state*) audio->data; /* Write end-of-stream */ vorbis_analysis_wrote(&(state->vorbis_state), 0); ogg_encoder_write_blocks(audio); /* Clean up encoder */ ogg_stream_clear(&(state->ogg_state)); vorbis_block_clear(&(state->vorbis_block)); vorbis_dsp_clear(&(state->vorbis_state)); vorbis_comment_clear(&(state->comment)); vorbis_info_clear(&(state->info)); /* Free stream state */ free(audio->data); }
static bool vorbis_encoder_pre_tag(struct encoder *_encoder, G_GNUC_UNUSED GError **error) { struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder; vorbis_analysis_wrote(&encoder->vd, 0); vorbis_encoder_blockout(encoder); /* reinitialize vorbis_dsp_state and vorbis_block to reset the end-of-stream marker */ vorbis_block_clear(&encoder->vb); vorbis_dsp_clear(&encoder->vd); vorbis_analysis_init(&encoder->vd, &encoder->vi); vorbis_block_init(&encoder->vd, &encoder->vb); ogg_stream_reset(&encoder->os); encoder->flush = true; return true; }
static int output_data(char *readbuffer, int32 bytes) { int i, j, ch = ((dpm.encoding & PE_MONO) ? 1 : 2); double **buffer; int16 *samples = (int16 *)readbuffer; int nsamples = bytes / (2 * ch); ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */ ogg_packet op; /* one raw packet of data for decode */ /* data to encode */ /* expose the buffer to submit data */ buffer = vorbis_analysis_buffer(&vd, nsamples); /* uninterleave samples */ for(j = 0; j < ch; j++) for(i = 0; i < nsamples; i++) buffer[j][i] = samples[i*ch+j] * (1.0/32768.0); /* tell the library how much we actually submitted */ vorbis_analysis_wrote(&vd, nsamples); /* 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(ogg_stream_pageout(&os, &og) != 0) { write(dpm.fd, og.header, og.header_len); write(dpm.fd, og.body, og.body_len); } } return 0; }
static int icecast_internal_disconnect(t_channel *c, t_channel_outputstream *os, t_icecast *icecast, char *error, int errsize) { (void)c; (void)error; (void)errsize; (void)os; if (!icecast->connected) return MSERV_SUCCESS; vorbis_analysis_wrote(&icecast->vd, 0); vorbis_block_clear(&icecast->vb); vorbis_dsp_clear(&icecast->vd); vorbis_info_clear(&icecast->vi); shout_close(icecast->shout); icecast->connected = 0; return MSERV_SUCCESS; }
/*! * \brief Close a OGG/Vorbis filestream. * \param fs A OGG/Vorbis filestream. */ static void ogg_vorbis_close(struct ast_filestream *fs) { struct vorbis_desc *s = (struct vorbis_desc *)fs->_private; if (s->writing) { /* Tell the Vorbis encoder that the stream is finished * and write out the rest of the data */ vorbis_analysis_wrote(&s->vd, 0); write_stream(s, fs->f); } ogg_stream_clear(&s->os); vorbis_block_clear(&s->vb); vorbis_dsp_clear(&s->vd); vorbis_comment_clear(&s->vc); vorbis_info_clear(&s->vi); if (s->writing) { ogg_sync_clear(&s->oy); } }
/* * Encode length bytes of audio from the packet into Ogg stream */ PRBool MediaRecorder::EncodeAudio(PRInt16 *a_frames, int len) { int i, j, n; float **a_buffer; /* Uninterleave samples */ n = len / aState->backend->GetFrameSize(); a_buffer = vorbis_analysis_buffer(&aState->vd, n); for (i = 0; i < n; i++){ for (j = 0; j < (int)params->chan; j++) { a_buffer[j][i] = (float)((float)a_frames[i+j] / 32768.f); } } /* Tell libvorbis to do its thing */ vorbis_analysis_wrote(&aState->vd, n); WriteAudio(); return PR_TRUE; }
static bool vorbis_encoder_write(struct encoder *_encoder, const void *data, size_t length, G_GNUC_UNUSED GError **error) { struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder; unsigned num_frames; num_frames = length / audio_format_frame_size(&encoder->audio_format); /* this is for only 16-bit audio */ pcm16_to_vorbis_buffer(vorbis_analysis_buffer(&encoder->vd, num_frames), (const int16_t *)data, num_frames, encoder->audio_format.channels); vorbis_analysis_wrote(&encoder->vd, num_frames); vorbis_encoder_blockout(encoder); return true; }
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; }
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; }
/*! * \brief Write audio data from a frame to an OGG/Vorbis filestream. * \param fs An OGG/Vorbis filestream. * \param f A frame containing audio to be written to the filestream. * \return -1 if there was an error, 0 on success. */ static int ogg_vorbis_write(struct ast_filestream *fs, struct ast_frame *f) { int i; float **buffer; short *data; struct ogg_vorbis_desc *s = (struct ogg_vorbis_desc *) fs->_private; if (!s->writing) { ast_log(LOG_ERROR, "This stream is not set up for writing!\n"); return -1; } if (f->frametype != AST_FRAME_VOICE) { ast_log(LOG_WARNING, "Asked to write non-voice frame!\n"); return -1; } if (f->subclass.format.id != AST_FORMAT_SLINEAR) { ast_log(LOG_WARNING, "Asked to write non-SLINEAR frame (%s)!\n", ast_getformatname(&f->subclass.format)); return -1; } if (!f->datalen) return -1; data = (short *) f->data.ptr; buffer = vorbis_analysis_buffer(&s->vd, f->samples); for (i = 0; i < f->samples; i++) buffer[0][i] = (double)data[i] / 32768.0; vorbis_analysis_wrote(&s->vd, f->samples); write_stream(s, fs->f); s->writing_pcm_pos += f->samples; return 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 */
static void process_frames(void *self) { VORBIS_STREAM *stream; size_t frames; ogg_packet header, header_comm, header_code; float **vorbuf; size_t i, j; stream = (VORBIS_STREAM *)self; frames = stream->header.bookmark; if (stream->header.init == 0) { stream->header.init = 1; vorbis_analysis_headerout(&(stream->vd), &(stream->vc), &header, &header_comm, &header_code); ogg_stream_packetin(&(stream->os), &header); ogg_stream_packetin(&(stream->os), &header_comm); ogg_stream_packetin(&(stream->os), &header_code); while (ogg_stream_flush(&(stream->os), &(stream->og))) vorbis_send(stream); } vorbuf = vorbis_analysis_buffer(&(stream->vd), frames); for (i = 0; i < QMX_CHANNELS; i++) { for (j = 0; j < frames; j++) { vorbuf[i][j] = (float)(distch[i][j]); } } vorbis_analysis_wrote(&(stream->vd), frames); while (vorbis_analysis_blockout(&(stream->vd), &(stream->vb)) == 1) { vorbis_analysis(&(stream->vb), NULL); //&(stream->op)); vorbis_bitrate_addblock(&(stream->vb)); while (vorbis_bitrate_flushpacket(&(stream->vd), &(stream->op))) { ogg_stream_packetin(&(stream->os), &(stream->op)); } } while (ogg_stream_pageout(&(stream->os), &(stream->og))) vorbis_send(stream); stream->header.bookmark = 0; return; }
static void vorbis_write_real (void * data, gint length) { int samples = length / sizeof (float); int channel, result; float * end = (float *) data + samples; float * * buffer = vorbis_analysis_buffer (& vd, samples / input.channels); float * from, * to; for (channel = 0; channel < input.channels; channel ++) { to = buffer[channel]; for (from = (float *) data + channel; from < end; from += input.channels) * to ++ = * from; } vorbis_analysis_wrote (& vd, samples / input.channels); while(vorbis_analysis_blockout(&vd, &vb) == 1) { vorbis_analysis(&vb, &op); vorbis_bitrate_addblock(&vb); while (vorbis_bitrate_flushpacket(&vd, &op)) { ogg_stream_packetin(&os, &op); while ((result = ogg_stream_pageout(&os, &og))) { if (result == 0) break; write_output(og.header, og.header_len); write_output(og.body, og.body_len); } } } }