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

Jose Pablo Carballo jose.carballo at ridgerun.com
Thu Aug 14 13:15:23 PDT 2014


Probably attaching the file is more readable.

Thanks for your help.

On Thu, Aug 14, 2014 at 2:12 PM, Jose Pablo Carballo
<jose.carballo at ridgerun.com> wrote:
> On Thu, Aug 14, 2014 at 12:34 PM, lvqcl <lvqcl.mail at gmail.com> wrote:
>> Jose Pablo Carballo <jose.carballo at ridgerun.com> wrote:
>>
>>> - 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;
>>>
>>
>> I suspect that the expression for total_samples should be not
>>
>> (.....) / 4
>>
>> but
>>
>> (.....) / (channels * bps/8)
>
> Yes, that's correct.
>
> Here is the final diff I used to use the example to convert the 24bps file:
>
> diff --git a/examples/c/encode/file/main.c b/examples/c/encode/file/main.c
> index e3bdea8..b1cf374 100644
> --- a/examples/c/encode/file/main.c
> +++ b/examples/c/encode/file/main.c
> @@ -40,8 +40,10 @@ static void progress_callback(const
> FLAC__StreamEncoder *encoder, FLAC__uint64 b
>
>  #define READSIZE 1024
>
> +#define BPS 24 /* Bits per sample */
> +
>  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*/ * BPS/8
> /*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[])
> @@ -73,14 +75,18 @@ int main(int argc, char *argv[])
>   memcmp(buffer+8, "WAVEfmt \020\000\000\000\001\000\002\000", 16) ||
>   memcmp(buffer+32, "\004\000\020\000data", 8)
>   ) {
> +#if BPS == 16
>   fprintf(stderr, "ERROR: invalid/unsupported WAVE file, only 16bps
> stereo WAVE in canonical form allowed\n");
>   fclose(fin);
>   return 1;
> +#elif BPS == 24
> + /* TODO: check wav header for 24bps */
> +#endif
>   }
>   sample_rate = ((((((unsigned)buffer[27] << 8) | buffer[26]) << 8) |
> buffer[25]) << 8) | buffer[24];
> - channels = 2;
> - bps = 16;
> - total_samples = (((((((unsigned)buffer[43] << 8) | buffer[42]) << 8)
> | buffer[41]) << 8) | buffer[40]) / 4;
> + 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]) / (channels * bps/8);
>
>   /* allocate the encoder */
>   if((encoder = FLAC__stream_encoder_new()) == NULL) {
> @@ -89,7 +95,12 @@ int main(int argc, char *argv[])
>   return 1;
>   }
>
> - ok &= FLAC__stream_encoder_set_verify(encoder, true);
> + if (bps == 16) {
> + /* TODO: Understand why verify doesn't work for 24bps - fails with
> + *   FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA when calling
> + *   FLAC__stream_encoder_process_interleaved().*/
> + ok &= FLAC__stream_encoder_set_verify(encoder, true);
> + }
>   ok &= FLAC__stream_encoder_set_compression_level(encoder, 5);
>   ok &= FLAC__stream_encoder_set_channels(encoder, channels);
>   ok &= FLAC__stream_encoder_set_bits_per_sample(encoder, bps);
> @@ -138,11 +149,23 @@ int main(int argc, char *argv[])
>   /* convert the packed little-endian 16-bit PCM samples from WAVE
> into an interleaved FLAC__int32 buffer for libFLAC */
>   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) {
> + /* 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]);
> + } else if (bps == 24) {
> + pcm[i] = (FLAC__int32)buffer[3*i+2];
> + pcm[i] <<= 8;
> + pcm[i] |= (FLAC__int32)buffer[3*i+1];
> + pcm[i] <<= 8;
> + pcm[i] |= (FLAC__int32)buffer[3*i];
> + }
>   }
>   /* feed samples to encoder */
>   ok = FLAC__stream_encoder_process_interleaved(encoder, pcm, need);
> + if (!ok) {
> + fprintf(stderr, "encoding: FLAC__stream_encoder_process_interleaved FAILED");
> + fprintf(stderr, "   state: %s\n",
> FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder)]);
> + }
>   }
>   left -= need;
>   }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 24bps.patch
Type: text/x-patch
Size: 3552 bytes
Desc: not available
Url : http://lists.xiph.org/pipermail/flac-dev/attachments/20140814/d0b2227b/attachment.bin 


More information about the flac-dev mailing list