[Vorbis-dev] RE: encode, decode and encode again
Aleksey Surkov
Aleksey_S at abbyy.com
Mon Sep 11 08:17:04 PDT 2006
Hi, Ian!
Thank you for your response. Here is some details...
> Well, without the code we can't say much. Since the problem occurs
with
> large numbers of files I'd suggest there's some kind of memory leak
> somewhere, or some buffer is being filled up and never emptied.
Not exactly so. It works correctly with other files (even with a big
number of files) and fails just for several "bad" files.
>Your problem with round trippping the files may be related or entirely
> separate. Are you sure the .wav files being produced at the
intermediate
> step are valid?
Yes, they are valid. I can play it. More, after converting (changing
frequency) by CDex the files can be compressed again correctly. I just
can't compress it immediately after decompressing, without any
intermediate actions like frequency changing via third-party utility.
> Final aside: this is just a test isn't it? Round tripping audio
through
> the encode/decode is probably a bad idea.
No, unfortunately it`s not a test. It`s a real problem (we've lost the
source files that are compressed into archive... And now the only way to
make some changes in this archive is decompressing-compressing).
And this problem occurs not only with recompressed files.
For example, I have a test wav file (88 kb), the described bug occurs
with it:
http://rapidshare.de/files/32738670/0008.wav.html or I can send it by
email, just write me to Aleksey_S(at)abbyy.com
The Code I use is almost the same as in example below (it's a part that
encodes files):
void COggArchive::addFileToStream(CWAVFile & wavFile)
{
char readBuffer[ReadBufferSize];
int bytesRead;
int channels = pcmDefaultSettings.channels;
int bytesPerSample = wavFile.GetWaveFormat().nBitsPerSample / 8;
int bytesPerChannel = bytesPerSample / channels;
int totalSamples = wavFile.getDataChunkSize() / bytesPerSample;
while( bytesRead = wavFile.ReadData( readBuffer, ReadBufferSize
) ) {
int samplesRead = bytesRead / bytesPerSample;
float **buffer = vorbis_analysis_buffer( &oggState.vd,
samplesRead );
for (int ch = 0; ch < channels; ch++) {
for (int i = 0; i < samplesRead; i++) {
if ( bytesPerChannel == 2 ) {
short ampl;
int sampleChannelOffset = i *
bytesPerSample + ch * 2/*bytesPerChannel*/;
ampl = ( ( 0x00ff &
(short)readBuffer[sampleChannelOffset] ) |
(
readBuffer[sampleChannelOffset + 1] << 8 ) );
buffer[ch][i] = ampl / 32768.f;
} else {
buffer[ch][i] =
readBuffer[i*bytesPerSample + ch/* *bytesPerChannel=1*/] / 255.f;
}
}
}
vorbis_analysis_wrote( &oggState.vd, samplesRead );
EncodeReadSamples();
}
}
void COggArchive::EncodeReadSamples()
{
int eos = 0;
while( vorbis_analysis_blockout( &oggState.vd, &oggState.vb ) ==
1 ) {
/* analysis, assume we want to use bitrate management */
vorbis_analysis( &oggState.vb, 0 );
vorbis_bitrate_addblock( &oggState.vb );
while( vorbis_bitrate_flushpacket( &oggState.vd,
&oggState.op ) ) {
/* weld the packet into the bitstream */
ogg_stream_packetin( &oggState.os, &oggState.op
);
/* write out pages (if any) */
// int eos = 0;
while( !eos ) {
if ( !ogg_stream_pageout( &oggState.os,
&oggState.og ) )
break;
streamBuffer->Write( oggState.og.header,
oggState.og.header_len );
streamBuffer->Write( oggState.og.body,
oggState.og.body_len );
if( ogg_page_eos( &oggState.og ) )
eos = 1;
}
}
}
}
More information about the Vorbis-dev
mailing list