FLAC Audio Libraries App

FLAC

by Xiph.org

Lossless Audio Codec
Helps with: Audio Libraries
Similar to: LAME MP3 Encoder App MAD App Musepack SV8 App Opus 1.1 App More...
Source Type: Open
License Types:
BSD
Supported OS:
Languages: C CPP

What is it all about?

FLAC is a lossless coding format which is dedicated for audio files. It perfectly preserves the data quality and provides significant performances. It's supported by a variety of audio devices.

Key Features

* Supported by many players * Supported by many hardware architecture * Easy to integrate in embedded systems * Also provide many tools (under GPL license)


Resources

Resource Type

Link

Wikipedia https://en.wikipedia.org/wiki/FLAC

Pricing

Yearly
Monthly
Lifetime
Free
Freemium
Trial With Card
Trial No Card
By Quote

Description

Completely Free

Product Analysis

Multimedia

FLAC (Free Lossless Audio Codec)

FLAC (Free Lossless Audio Codec)

By Alvie Amar | 7/10/2016 | Product Analysis |Beginners

FLAC (Free Lossless Audio Codec) is an audio format that can reduce audio files upto 50 to 60 percent of their original size and decompresses them without any loss in quality. FLAC became an alternative to other lossless audio formats in 2001 when it first appeared.

 

FLAC is supported by default in Android and freely supported and available on most common operating system like Windows, UNIX (Linux, Solaris, OS X, and IRIX), OS/2 and Amiga.

 

FLAC is know for the following features:

  • Lossless (No loss of information and quality during the encoding of audio data)
  • Widespread hardware support compared to other lossless formats - from portable players, to home stereo equipment, and car stereos as well
  • Portable to many systems
  • Streaming support
  • Extremely fast decoding
  • Supports high resolution streams and multi-channel
  • Suitable for archiving
  • Convenient for CD archiving
  • Open-source and freely licensed

 

The good thing about using FLAC is that it retains the information of the audio file which can lead to a significant boost in quality. FLAC has several independent implementations and a well documented API. It was considered to be the fastest and most supported audio codec with an open source reference implementation.

What is FLAC good for?

FLAC’s storage requirements and bandwidth reduction without compromising the audio's quality is its main advantage compared to other lossless compression methods. FLAC also supports fast sample-accurate seeking which is useful for playback and makes FLAC files suitable when being used in editing applications. For those who wish for their audio collections to be preserved, FLAC is also know as archive format just like other lossless audio formats. If the original data of an audio file is lost or damaged a FLAC copy of an audio track guarantees that the data of the original copy can be recovered anytime.

 

FLAC examples and code snippets

Flac is an audio library which can be integrated into any audio application. FLAC has C and C++ APIs. The interface to libFLAC is the FLAC C API. It is a set of structures of FLAC components streams, encoding and decoding function streams and manipulating FLAC metadata in files. While the FLAC C++ API is a set of classes that encapsulates the functions and structures in libFLAC.

 

In order to better understand the FLAC API, one should browse through the modules in the FLAC API documentation that can be found in https://xiph.org/flac/api/

 

For now, I will show you one example of a FLAC function. This example uses libFLAC++ to encode a .wav file to a FLAC. It only supports 16-bit stereo files in canonical WAVE format.

#if HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "FLAC++/metadata.h"
#include "FLAC++/encoder.h"

class OurEncoder: public FLAC::Encoder::File {
public:
OurEncoder(): FLAC::Encoder::File() { }
protected:
virtual void progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate);
};

#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__int32 pcm[READSIZE/*samples*/ * 2/*channels*/];
static FLAC__int32 *pcm_[2] = { pcm, pcm+READSIZE };

int main(int argc, char *argv[])
{
bool ok = true;
OurEncoder encoder;
FLAC__StreamEncoderInitStatus init_status;
FLAC__StreamMetadata *metadata[2];
FLAC__StreamMetadata_VorbisComment_Entry entry;
FILE *fin;
unsigned sample_rate = 0;
unsigned channels = 0;
unsigned bps = 0;

if(argc != 3) {
fprintf(stderr, "usage: %s infile.wav outfile.flac\n", argv[0]);
return 1;
}

if((fin = fopen(argv[1], "rb")) == NULL) {
fprintf(stderr, "ERROR: opening %s for output\n", argv[1]);
return 1;
}

/* read wav header and validate it */
if(
fread(buffer, 1, 44, fin) != 44 ||
memcmp(buffer, "RIFF", 4) ||
memcmp(buffer+8, "WAVEfmt \020\000\000\000\001\000\002\000", 16) ||
memcmp(buffer+32, "\004\000\020\000data", 8)
) {
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;
total_samples = (((((((unsigned)buffer[43] << 8) | buffer[42]) << 8) | buffer[41]) << 8) | buffer[40]) / 4;
  
/* check the encoder */
if(!encoder) {
fprintf(stderr, "ERROR: allocating encoder\n");
fclose(fin);
return 1;
}

ok &= encoder.set_verify(true);
ok &= encoder.set_compression_level(5);
ok &= encoder.set_channels(channels);
ok &= encoder.set_bits_per_sample(bps);
ok &= encoder.set_sample_rate(sample_rate);
ok &= encoder.set_total_samples_estimate(total_samples);

/* now add some metadata; we'll add some tags and a padding block */
if(ok) {
if(
(metadata[0] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)) == NULL ||
(metadata[1] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)) == NULL ||
/* there are many tag (vorbiscomment) functions but these are convenient for this particular use: */
!FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "ARTIST", "Some Artist") ||
!FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, /*copy=*/false) || /* copy=false: let metadata object take control of entry's allocated string */
!FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "YEAR", "1984") ||
!FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, /*copy=*/false)
) {
fprintf(stderr, "ERROR: out of memory or tag error\n");
ok = false;
}

metadata[1]->length = 1234; /* set the padding length */

ok = encoder.set_metadata(metadata, 2);
}

/* initialize encoder */
if(ok) {
init_status = encoder.init(argv[2]);
if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
fprintf(stderr, "ERROR: initializing encoder: %s\n", FLAC__StreamEncoderInitStatusString[init_status]);
ok = false;
}
}

/* read blocks of samples from WAVE file and feed to encoder */
if(ok) {
size_t left = (size_t)total_samples;
while(ok && left) {
size_t need = (left>READSIZE? (size_t)READSIZE : (size_t)left);
if(fread(buffer, channels*(bps/8), need, fin) != need) {
fprintf(stderr, "ERROR: reading from WAVE file\n");
ok = false;
}
else {
/* 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]);
}
/* feed samples to encoder */
ok = encoder.process_interleaved(pcm, need);
}
left -= need;
}
}

ok &= encoder.finish();

fprintf(stderr, "encoding: %s\n", ok? "succeeded" : "FAILED");
fprintf(stderr, "   state: %s\n", encoder.get_state().resolved_as_cstring(encoder));

/* now that encoding is finished, the metadata can be freed */
FLAC__metadata_object_delete(metadata[0]);
FLAC__metadata_object_delete(metadata[1]);

fclose(fin);

return 0;
}

void OurEncoder::progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate)
{
#ifdef _MSC_VER
fprintf(stderr, "wrote %I64u bytes, %I64u/%u samples, %u/%u frames\n", bytes_written, samples_written, total_samples, frames_written, total_frames_estimate);
#else
fprintf(stderr, "wrote %llu bytes, %llu/%u samples, %u/%u frames\n", bytes_written, samples_written, total_samples, frames_written, total_frames_estimate);
#endif
}

 

The decoders, encoders and metadata interface are completely independent of each other. So if you only require the stream encoder in your application and no decoder and metadata interface, you can remove the stream decoder and metadata interface in the library thus reducing its size.

 

Conclusion

FLAC was specifically designed for efficient compression and packing of audio data. FLAC offers several advantages over its competitors throughout the years e.g. MP3’s.  Although MP3’s are very convenient and supported by most of the devices, MP3 is still a lossy format, meaning some of the sound quality is lost during the conversion process. FLAC, on the other hand, is a lossless codec that doesn’t lose any quality of the original sound during conversion.  If the quality of sound is your highest priority, then converting CD’s to a lossless codec like FLAC is worth considering.

 

By Alvie Amar | 7/10/2016 | Product Analysis

{{CommentsModel.TotalCount}} Comments

Your Comment

{{CommentsModel.Message}}

Top DiscoverSDK Experts

User photo
20
Hadi Chami
Software Developer Manager
Multimedia | Hardware and RT and 52 more
View Profile
User photo
20
Mohamed Amine Mounzih
Mobile and Web Application Developer
Multimedia | Audio Libraries and 41 more
View Profile
User photo
20
ahmedxp kh
Ahmedxp PC ENG
Multimedia | Hardware and RT and 123 more
View Profile
User photo
20
Redentor Del Rosario
Cyber Security
Multimedia | Hardware and RT and 122 more
View Profile
Show All

Interested in becoming a DiscoverSDK Expert? Learn more

X

Compare Products

Select up to three two products to compare by clicking on the compare icon () of each product.

{{compareToolModel.Error}}

Now comparing:

{{product.ProductName | createSubstring:25}} X
Compare Now