I'm using flac-1.2.1 and visual studio 2010 on windows xp sp3<br>and I want to compress raw CDDA with the stream encoder to a file.<br><br>But I just can't get the flac encoder to work,<br>the encoder always returns an error<br>
enc.get_state() == "FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA"<br>get_verify_decoder_state() == "FLAC__STREAM_DECODER_READ_FRAME"<br><br><br><br>this is the code I have now<br><br>/*****************************************************************************/<br>
FLAC__StreamEncoderInitStatus init_status;<br> TMyFlacEncoder enc;<br> bool ok = true;<br><br> unsigned int sample_size = 4; //2 * (16 / 8); 2 channels * (16 bits / 8) bytes<br>
unsigned int samples_per_sector = disc.getBytesPerSector(trackNum) / sample_size / 2 /*channels*/;<br> unsigned int total_samples = trackLength * samples_per_sector;<br><br><br> // compress<br> ok &= enc.set_verify(true);<br>
ok &= enc.set_channels ( 2); // 2 channels<br> ok &= enc.set_bits_per_sample( 16); // 16 bits<br> ok &= enc.set_sample_rate (44100); // 44.100 Hz<br> ok &= enc.set_compression_level((FCompressionStrength > 8) ? 8 : FCompressionStrength);<br>
ok &= enc.set_total_samples_estimate(total_samples);<br> <br> enc.setOutFile(&file);<br><br><br> /* initialize encoder */<br> init_status = enc.init();<br> if( (!ok) || (init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK)) {<br>
return false;<br> }<br><br> <br><br> /* read sectors from disc and feed to encoder */<br> for (unsigned int i = 0; i < trackLength; ++i) {<br><br> disc.seekTrack(i, trackNum, false);<br><br> ok = enc.process_interleaved((FLAC__int32*)disc.getBuffer(), samples_per_sector);<br>
<br> FProgressCur++;<br><br> if (!ok || !progressCallback()) {<br> cout << "Flac error: " << enc.get_state().as_cstring() << endl;<br> cout << "Flac verify state: " << enc.get_verify_decoder_state().as_cstring() << endl;<br>
return false;<br> }<br><br> }<br><br> ok &= enc.finish(); <br>/*****************************************************************************/<br><br>disc.seekTrack, seeks the disc in LBA mode<br>
disc.getBuffer, returns the buffer pointer to the cd sectors of the last seek, this is 2352 bytes in length for CDDA<br><br><br><br>and the encoder child class from FLAC::Encoder::Stream<br><br>/*****************************************************************************/<br>
class TMyFlacEncoder: public FLAC::Encoder::Stream {<br> protected:<br> TMyFileAccess *FFile; // the file we are writing to<br> long long FFlacOffset;<br><br><br> virtual FLAC__StreamEncoderReadStatus read_callback (FLAC__byte buffer[], size_t *bytes)<br>
{<br> if(*bytes > 0) {<br> *bytes = FFile->Read(buffer, sizeof(FLAC__byte), *bytes);<br> if(FFile->Error())<br> return FLAC__STREAM_ENCODER_READ_STATUS_ABORT;<br>
else if(*bytes == 0)<br> return FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM;<br> else<br> return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE;<br> }<br>
else<br> return FLAC__STREAM_ENCODER_READ_STATUS_ABORT;<br> }<br><br><br> virtual FLAC__StreamEncoderWriteStatus write_callback (const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame)<br>
{<br><br> if ( FFile->Write((unsigned char*)buffer, 1, bytes) != bytes ) {<br> return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;<br> }<br><br> return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;<br>
}<br><br> virtual FLAC__StreamEncoderSeekStatus seek_callback (FLAC__uint64 absolute_byte_offset)<br> {<br> if (FFile->Seek(absolute_byte_offset + FFlacOffset, SEEK_SET) < 0 ) {<br> return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;<br>
}<br><br> return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;<br> }<br><br> virtual FLAC__StreamEncoderTellStatus tell_callback (FLAC__uint64 *absolute_byte_offset)<br> {<br> long long pos = FFile->Tell() - FFlacOffset;<br>
*absolute_byte_offset = (FLAC__uint64)pos;<br><br> if( pos < 0 ) {<br> return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR;<br> }<br><br> return FLAC__STREAM_ENCODER_TELL_STATUS_OK;<br>
}<br><br><br> public:<br> TMyFlacEncoder(): FLAC::Encoder::Stream() {<br> <br> FFile = NULL;<br><br> }<br><br> // you need to call this before starting the compression<br>
void setOutFile(TMyFileAccess *file)<br> {<br> FFile = file;<br> FFlacOffset = file->Tell();<br> }<br><br><br>}; <br>/*****************************************************************************/<br>