[flac-dev] Encoder example for 24-bit files

Jose Pablo Carballo jose.carballo at ridgerun.com
Wed Aug 13 17:15:45 PDT 2014


Hi,

In the last days I've been taking as reference the example found in
examples/c/encode/file/main.c. With it I've been able to encode a 2ch,
16 bps, 44100 sample rate input WAV file to a FLAC file.

Now I've been trying to modify this example to encode a 2ch, 24 bps,
96000 sample rate WAV file. I have to say I'm a bit lost on how I
should read the input file in this case, and how should I pack the
data to feed the encoder. Any guidance regarding the use of libFLAC,
the understanding of the format, or anything else that you can notice
where I'm complete lost, I'll appreciate your help.

Here's the diff:

Index: main.c
===================================================================
--- main.c (revision 1)
+++ main.c (working copy)
@@ -39,7 +39,7 @@
 #define READSIZE 1024

 static unsigned total_samples = 0; /* can use a 32-bit number due to
WAVE size limitations */
-static FLAC__byte buffer[READSIZE/*samples*/ * 2/*bytes_per_sample*/
* 2/*channels*/]; /* we read the WAVE data into here */
+static FLAC__byte buffer[READSIZE/*samples*/ * 3/*bytes_per_sample*/
* 2/*channels*/]; /* we read the WAVE data into here */
 static FLAC__int32 pcm[READSIZE/*samples*/ * 2/*channels*/];

 int main(int argc, char *argv[])
@@ -71,13 +71,15 @@
  memcmp(buffer+8, "WAVEfmt \020\000\000\000\001\000\002\000", 16) ||
  memcmp(buffer+32, "\004\000\020\000data", 8)
  ) {
+ /* Ignoring for now as I work towards supporting 24bps files.
  fprintf(stderr, "ERROR: invalid/unsupported WAVE file, only 16bps
stereo WAVE in canonical form allowed\n");
  fclose(fin);
  return 1;
+ */
  }
  sample_rate = ((((((unsigned)buffer[27] << 8) | buffer[26]) << 8) |
buffer[25]) << 8) | buffer[24];
- channels = 2;
- bps = 16;
+ channels = ((unsigned)buffer[23] << 8) | buffer[22];
+ bps = ((unsigned)buffer[35] << 8) | buffer[34];
  total_samples = (((((((unsigned)buffer[43] << 8) | buffer[42]) << 8)
| buffer[41]) << 8) | buffer[40]) / 4;

  /* allocate the encoder */
@@ -137,10 +139,17 @@
  size_t i;
  for(i = 0; i < need*channels; i++) {
  /* inefficient but simple and works on big- or little-endian machines */
- pcm[i] = (FLAC__int32)(((FLAC__int16)(FLAC__int8)buffer[2*i+1] << 8)
| (FLAC__int16)buffer[2*i]);
+ if (bps == 16)
+ pcm[i] = (FLAC__int32)(((FLAC__int16)(FLAC__int8)buffer[2*i+1] << 8)
| (FLAC__int16)buffer[2*i]);
+ else if (bps == 24)
+ pcm[i] = (((FLAC__int32)(buffer[2*i+2] << 16))
|((FLAC__int32)(buffer[2*i+1] << 8)) | ((FLAC__int32)(buffer[2*i])));
  }
  /* feed samples to encoder */
  ok = FLAC__stream_encoder_process_interleaved(encoder, pcm, need);
+ if (!ok) {
+ fprintf(stderr, "encoding: process_interleaved %s\n", ok?
"succeeded" : "FAILED");
+ fprintf(stderr, "   state: %s\n",
FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder)]);
+ }
  }
  left -= need;
  }

After running this I get:

encoding: process_interleaved FAILED
   state: FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA
encoding: FAILED
   state: FLAC__STREAM_ENCODER_UNINITIALIZED

Several runs to process_interleaved do succeed before falling in the
FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA state.

Here's the description of my input file:

ffprobe test_music_24_96.wav
avprobe version 0.8.10-4:0.8.10-0ubuntu0.12.04.1, Copyright (c)
2007-2013 the Libav developers
  built on Feb  6 2014 20:56:59 with gcc 4.6.3
[wav @ 0x16719c0] max_analyze_duration reached
Input #0, wav, from 'test_music_24_96.wav':
  Duration: 00:03:07.58, bitrate: 4608 kb/s
    Stream #0.0: Audio: pcm_s24le, 96000 Hz, 2 channels, s32, 4608 kb/s

Thanks!


More information about the flac-dev mailing list