A single-file FLAC encoding library. Does not use any C library functions, does not allocate memory directly (it leaves that up to you to figure out). Compatible with C89.
Use case: you want to generate FLAC audio without requiring an external library, and simplicity is your main concern, not compression or speed.
tflac currently supports the following subframe encodings:
CONSTANTFIXEDVERBATIM
It's roughly equivalent to compressing with FLAC's "-0" switch.
In one C file define TFLAC_IMPLEMENTATION before including tflac.h.
#define TFLAC_IMPLEMENTATION
#include "tflac.h"There's a few compile-time options you can set:
- Define
TFLAC_32BIT_ONLYand tflac will not use 64-bit types at all, and instead emulate 64-bit types with a pair of 32-bit ints. - Define
TFLAC_DISABLE_SSE2to disable SSE2 detection. - Define
TFLAC_DISABLE_SSSE3to disable SSSE3 detection. - Define
TFLAC_DISABLE_SSE4_1to disable SSE4.1 detection. - Define
TFLAC_PUBLICif you need to customize function decorators for public API functions. - Define
TFLAC_PRIVATEif you need to customize function decorators for private API functions.
For example, if you're building a DLL on Windows and want to export
the public API functions you could define TFLAC_PUBLIC as
__declspec(dllexport) like so:
#define TFLAC_IMPLEMENTATION
#define TFLAC_PUBLIC __declspec(dllexport)
#include "tflac.h"Call tflac_detect_cpu() before doing anything, like as early in your
program as possible, before you create any threads etc.
This will attempt to check your CPU type, and set some internal global variables. For example, if your CPU supports SSE2, the library will swap the default fixed-order calculators for a set that use SSE2.
You'll have to create a tflac struct. The whole struct definition is
provided so you can allocate it on the stack, or call tflac_size()
to get the structure size at runtime. Initialize it with tflac_init().
You then need to set 4 parameters. You can either set the tflac struct fields
yourself, or use setter functions (tflac_set_blocksize(),
tflac_set_samplerate(), etc).
- audio block size
- channels
- bit depth
- sample rate
You then need to acquire a memory chunk, to be used by tflac internally for storing residuals. You can get this needed memory size with a C macro, or with a function. The only required parameter is your audio block size.
Once you've set your parameters and acquired memory, call tflac_validate()
with the memory you've allocated for tflac's internals. It will make sure
your parameters are sane, that the memory chunk is large enough, and
proceed to set up all of its internal pointers to the memory chunk.
Note: the library will not free this memory for you since the library didn't allocate it.
You'll need to write out the fLaC stream marker and a STREAMINFO block.
The library has a function for generating a STREAMINFO block, since
that's a required metadata block. Other blocks are pretty straightforward
to create, I don't plan to include that functionality.
You'll need a buffer for storing encoded frames. You can find the maximum required buffer size with a C macro, or with a function. The parameters are your audio block size, channels, and bit depth.
You can have your audio in interleaved or planar format, and as either
tflac_s16 or tflac_s32. The encode functions are:
tflac_encode_s16i:tflac_s16samples in a 1-dimensional array (tflac_s16*), interleaved.tflac_encode_s16p:tflac_s16samples in a multi-dimensional array (tflac_s16**).tflac_encode_s32i:tflac_int32samples in a 1-dimensional array (tflac_int32*), interleaved.tflac_encode_s32p:tflac_int32samples in a multi-dimensional array (tflac_int32**).
tflac_s16 is a typedef for int16_t, and tflac_s32 is a typedef for int32_t
in most cases.
#define TFLAC_IMPLEMENTATION
#include "tflac.h"
#define BLOCKSIZE 1152
#define CHANNELS 2
#define BITDEPTH 16
#define SAMPLERATE 44100
int main(int argc, const char *argv[]) {
/* get the size we need to alloc for tflac internal memory */
tflac_u32 memory_size = tflac_size_memory(BLOCKSIZE);
/* get a chunk for tflac internal memory */
void* memory = malloc(memory_size);
/* get the size we need to alloc for the output buffer */
tflac_u32 buffer_size = tflac_size_frame(BLOCKSIZE, CHANNELS, BITDEPTH);
/* get a hunk for our buffer */
void* buffer = malloc(buffer_size);
/* this will be used to know how much of the buffer to write
after calls to encode */
tflac_u32 buffer_used = 0;
tflac t;
tflac_init(&t);
/* set some parameters */
t.blocksize = BLOCKSIZE;
t.samplerate = SAMPLERATE;
t.bitdepth = BITDEPTH;
t.channels = CHANNELS;
/* validate our parameters and tell tflac what memory to use */
tflac_validate(&t, memory, memory_size);
/* open a file and write out the stream marker */
FILE* output = fopen("some-file.flac","wb");
fwrite("fLaC", 1, 4, output);
/* encode the STREAMINFO block and write it out */
tflac_encode_streaminfo(&t, 1, buffer, buffer_size, &buffer_used);
fwrite(buffer, 1, buffer_used, output);
/* loop until you run out of audio */
while(have_audio()) {
/* hand-waving over this part, here we're using a 2d array of audio samples
and assuming it's always BLOCKSIZE samples */
tflac_s32** samples = get_some_audio_somehow();
/* encode your audio samples into a FLAC frame */
tflac_encode_s32p(&t, BLOCKSIZE, samples, buffer, buffer_size, &buffer_used);
/* and write it out */
fwrite(buffer, 1, buffer_used, output);
}
free(buffer);
free(ptr);
}BSD Zero Clause (see the LICENSE file).