I've been hunting bugs for the past three days and I've kind of given up. I've plowed through all the samples in the OpenAL SDK and the Vorbis examples, but to no avail, so I hope someone can help me.
The problem: I record audio using OpenAL, and for debug reasons i output it to C:/out.wav which i can then play with any audio player of choice and it plays back whatever i recorded.
The exact same buffer i get from openAL is what I input into libvorbisenc
(I request a buffer with vorbis_analysis_buffer and run alcCaptureSamples on it, after which i let vorbis do it's thing.)
The point being : Why is vorbis returning silence to my output file and how do i get valid compressed audio in my file "C:/out.ogg" ?
Don't worry about some missing or extra parentheses , they were lost in the copy+paste and removal of comments
the code runs, but it's output just isn't valid.
Relevant defines etc:
//due to strange formatting constraints of this site the's are omitted
define CHANNELS 1
define HERTZ 22050
define BITSPERSAMPLE 16
define BYTESPERSAMPLE 2
define SAMPLES 4410
define SAMPLESIZE 2
define ALIGN (CHANNELS*BITSPERSAMPLE/8)
define BUFFERSIZE (SAMPLES*SAMPLESIZE)
typedef struct
{
char szRIFF[4];
long lRIFFSize;
char szWave[4];
char szFmt[4];
long lFmtSize;
WAVEFORMATEX wfex;
char szData[4];
long lDataSize;
} WAVEHEADER;
class vorbispacker{
public:
vorbispacker();
~vorbispacker();
void consume();
muxer * mux;
// the needed ogg_stream_state is found at this->mux->state;
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 */
};
vorbis setup
void vorbispacker::setup(){
this->mux = new muxer;
vorbis_info_init(&this->vi);
int ret = vorbis_encode_init_vbr(&this->vi,CHANNELS,HERTZ,0.7);
vorbis_comment_init(&this->vc);
vorbis_comment_add_tag(&this->vc,"ENCODER","Test");
ret =vorbis_analysis_init(&this->vd,&this->vi);
ret= vorbis_block_init(&this->vd,&this->vb);
iSize=0;
iDataSize=0;
//TEST//
out = fopen("C:/out.wav","wb");
// Prepare a WAVE file header for the captured data
sprintf(swaveheader.szRIFF, "RIFF");
swaveheader.lRIFFSize = 0;
sprintf(swaveheader.szWave, "WAVE");
sprintf(swaveheader.szFmt, "fmt ");
swaveheader.lFmtSize = sizeof(WAVEFORMATEX);
swaveheader.wfex.nChannels = CHANNELS;
swaveheader.wfex.wBitsPerSample = BITSPERSAMPLE;
swaveheader.wfex.wFormatTag = WAVE_FORMAT_PCM;
swaveheader.wfex.nSamplesPerSec = HERTZ;
swaveheader.wfex.nBlockAlign = swaveheader.wfex.nChannels * swaveheader.wfex.wBitsPerSample / 8;
swaveheader.wfex.nAvgBytesPerSec = swaveheader.wfex.nSamplesPerSec * swaveheader.wfex.nBlockAlign;
swaveheader.wfex.cbSize = 0;
sprintf(swaveheader.szData, "data");
swaveheader.lDataSize = 0;
fwrite(&swaveheader, sizeof(WAVEHEADER), 1, out);
srand(time(NULL));
ret = ogg_stream_init(&this->mux->state,rand());
this->eos=0;
ogg_packet header;
ogg_packet header_comm;
ogg_packet header_code;
vorbis_analysis_headerout(&this->vd,&this->vc,&header,&header_comm,&header_code);
ret = ogg_stream_packetin(&this->mux->state,&header);
ret =ogg_stream_packetin(&this->mux->state,&header_comm);
ret =ogg_stream_packetin(&this->mux->state,&header_code);
while(1){
int res = ogg_stream_flush(&this->mux->state,&this->og);
if(!res)break;
this->mux->write(this->og);
}
// this code works great, the headers are correct , and are output to out.ogg
};
The problematic code:
* // set up buffer*
float ** vorbisbuffer = vorbis_analysis_buffer(&this->vd,SAMPLES);
*// retrieve audio samples ( MONO 16 bit)*
alcCaptureSamples(mic->pdevice,vorbisbuffer[0],SAMPLES);
//this goes to debug .wav file -> the exact same buffer that goes into vorbis
fwrite(vorbisbuffer[0], BUFFERSIZE, 1, out);
iDataSize +=BUFFERSIZE;
int eos =0;
/* tell the library how much we actually submitted */
//SAMPLES is what is inserted into openAL , hence what we put in vorbis
vorbis_analysis_wrote(&vd,SAMPLES);
while(vorbis_analysis_blockout(&this->vd,&this->vb)==1){
/* analysis, assume we want to use bitrate management */
vorbis_analysis(&this->vb,NULL);
vorbis_bitrate_addblock(&this->vb);
while(vorbis_bitrate_flushpacket(&this->vd,&this->op)){
/* weld the packet into the bitstream */
ogg_stream_packetin(&this->mux->state,&op);
/* write out pages (if any) */
while(!eos){
//if result > 0 there are more packets available
int result=ogg_stream_pageout(&this->mux->state,&this->og);
if(result==0)break;
//write ogg page to stream
// since that function outputs the ogg headers OK, i suppose there's no error there.
this->mux->write(this->og);
/* 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;
}
}
}
It's a lot to digest, but I really hope someone can help me.
Thanks in advance.