{"id":15654424,"url":"https://github.com/djeedai/libfar","last_synced_at":"2025-04-30T23:39:41.213Z","repository":{"id":77370494,"uuid":"216282965","full_name":"djeedai/libfar","owner":"djeedai","description":"C/C++ fast audio resampling library","archived":false,"fork":false,"pushed_at":"2019-11-03T16:14:18.000Z","size":99,"stargazers_count":42,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-25T12:15:35.533Z","etag":null,"topics":["audio","audio-processing","c","cpp","resample","resampling"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/djeedai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-19T23:30:41.000Z","updated_at":"2025-01-15T06:14:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"835092d0-86e5-4389-8cce-fe7a19a74432","html_url":"https://github.com/djeedai/libfar","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djeedai%2Flibfar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djeedai%2Flibfar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djeedai%2Flibfar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djeedai%2Flibfar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/djeedai","download_url":"https://codeload.github.com/djeedai/libfar/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242728393,"owners_count":20175934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio","audio-processing","c","cpp","resample","resampling"],"created_at":"2024-10-03T12:51:40.735Z","updated_at":"2025-03-09T17:30:40.105Z","avatar_url":"https://github.com/djeedai.png","language":"C","readme":"# libfar\n\nFast audio resampling library for C and C++.\n\nThis library focuses on speed at the expense of audio quality, for scenarios where correct audio processing is not needed. For that it takes many shortcuts to reduce processing and latency.\n\nIf you are looking for a high quality resampling library for offline audio processing, or where audio quality is more important than performance, this project is not suited. Look at a resampler like [the Opus Silk resampler](https://github.com/xiph/opus/blob/master/silk/resampler.c) instead.\n\n## Usage\n\n**C**\n\n```c\n#include \"libfar.h\"\n\n// Upsample float stereo audio from 22050 Hz to 44100 Hz.\nbyte32* upsample(const byte32* buffer, size_t size)\n{\n  const size_t size_out = size * 2;\n  const size_t aligned_size_out = (size_out + 31) \u0026 ~(size_t)31;\n  char32* buf_out = far_malloc_align32(aligned_size_out);\n  const int num_channels = 2; // stereo\n  far_upsample2f32(buffer, size, 22050, num_channels, buf_out, size_out);\n  return buf_out;\n}\n```\n\n**C++**\n\n```cpp\n#include \"libfar.h\"\n\n// Convert int16 48kHz audio from mono to stereo.\nshort512* mono_to_stereo(const short512* buffer, size_t size)\n{\n  const size_t size_out = size * 2;\n  const size_t aligned_size_out = (size_out + 63) \u0026 ~(size_t)63;\n  short512* buf_out = libfar::malloc_align(aligned_size_out, 64);\n  libfar::adapt_ch1x2s16(buffer, size, 48000, buf_out, size_out);\n  return buf_out;\n}\n```\n\n## Coding conventions\n\n### Symbols scoping\n\nInternally functions names are wrapped into the `FAR_FN` macro to allow inserting an optional prefix for C usage (defined by `FAR_FN_PREFIX`).\n\n**C**\n\nFunctions are prefixed with `FAR_FN_PREFIX`, which defaults to `far_` but can be redefined by the user:\n\n```cpp\nfar_upsample2f32(...);\n```\n\n**C++**\n\nFunctions are enclosed inside the `libfar` namespace:\n\n```cpp\nlibfar::upsample2f32(...);\n```\n\nThe `FAR_FN_PREFIX` preprocessor definition is ignored.\n\n### Audio sample types\n\n`libfar` supports 3 different audio sample types:\n\n| Sample type | Kind | Size | Range | Description |\n|---|---|---|---|---|\n| `uint8` | Integer | 1 byte | [0:255] | Low-resolution 8-bit format, generally only used to achieve retro 8-bit effects. Avoid this format for anything else, as its resolution is too low and produces distorsions. |\n| `int16` | Integer | 2 bytes | [-32768:32767] | Most common audio sample format for playback and storage. |\n| `float` | Floating-point | 4 bytes | [-1.0:1.0] | Used by some game engines (Unity3D) or as intermediate type for audio pipelines while applying effects to retain a high precision and avoid distorsion. |\n\n### Boolean type\n\n**C**\n\nIn C, there is no built-in boolean type. As a fallback, `libfar` defines a `far_bool` type backed by an `int32_t` type and equal to `0` for `false` and `-1` (bit pattern 0xFFFFFFFF) for `true`.\n\n```c\ntypedef int32_t far_bool;\n#define far_true ((far_bool)-1)\n#define far_false ((far_bool)0)\n```\n\n**C++**\n\nIn C++ for convenience `far_bool` is an alias of the built-in boolean type `bool`. Developers are encouraged to use `bool` directly.\n\n```cpp\nusing far_bool = bool;\nconstexpr bool far_true = true;\nconstexpr bool far_false = false;\n```\n\n### Buffer alignment\n\nBuffers are over-aligned compared to standard C/C++ rules to improve performance with SIMD. Special types aliases are defined for those buffers to make the alignment requirement explicit via the type name. There is currently no compile-time check, and it is still possible to pass the wrong type, so developers should be careful.\n\n| Sample type | Alignment | Aligned type alias |\n|---|---|---|\n| Unspecified* | 4 bytes | `byte4` |\n| Unspecified* | 8 bytes | `byte8` |\n| Unspecified* | 16 bytes | `byte16` |\n| Unspecified* | 32 bytes | `byte32` |\n| `int16` | 2 bytes | `int16` |\n| `int16` | 16 bytes | `short128` |\n| `int16` | 32 bytes | `short256` |\n| `int16` | 32 bytes | `short512` |\n| `float` | 4 bytes | `float` |\n| `float` | 16 bytes | `float128` |\n| `float` | 32 bytes | `float256` |\n| `float` | 32 bytes | `float512` |\n\n**Unspecified sample types indicate only an alignment, without specifying an actual type. This is useful for functions which can operate on any sample type, but still require an aligned buffer.*\n\nTypically the following SIMD implementations requires some specific alignment:\n\n- **SSE, SSE2, ..., SSE4.2** : 16 bytes (128 bits)\n- **AVX, AVX2** : 32 bytes  (256 bits)\n- **AVX512** : 64 bytes (512 bits)\n\nTypes of a given alignment can safely be cast to a lower alignment. Therefore most generic dispatching functions take some 64-byte aligned buffers to not lose any generality.\n\n**C++**\n\n```cpp\n// Generic dispatcher function func1().\nbyte16* ptr16 = ...\nlibfar::func1((const byte4*)ptr16, ...); // OK; cast to lower alignment.\n\n// Specific SSE implementation of func1()\nbyte16* ptr16 = ...\nlibfar::func1_sse(ptr16, ...); // OK; SSE explicitly requires 16-byte alignment.\n```\n\n### Memory allocators\n\nDefault allocators are based on the standard library's `aligned_alloc()`. Custom allocators can be defined by defining the `FAR_CUSTOM_ALLOCATORS` preprocessor symbol to avoid defining the built-in allocators, and defining them manually instead.\n\n_Note_: If defining the allocators generically for both C and C++, remember to use the `FAR_FN()` macro. Otherwise you can use directly the prefix (default: `far_`) for C or the namespace (`libfar`) for C++.\n\n```c\nchar* FAR_FN(malloc_align)(size_t size, size_t align) {\n  // ...\n}\n\nvoid FAR_FN(free_align)(void* ptr) {\n  // ...\n}\n\nbyte32* FAR_FN(malloc_align32)(size_t size) {\n  // ...\n}\n\nvoid FAR_FN(free_align32)(byte32* ptr) {\n  // ...\n}\n```\n\n**C++**\n\nOn C++ only, some templated versions are provided for convenience, which deduct the alignment from the sample type alias.\n\n```cpp\nshort512* buffer = libfar::malloc_align\u003cshort512\u003e(size); // 64-byte aligned\nfloat128* buffer = libfar::malloc_align\u003cfloat128\u003e(size); // 16-byte aligned\n```\n\n## Feature reference\n\n### Resampling\n\nChange the sample rate by an integral factor.\n\n| Name | Sample type | Description |\n|---|---|---|\n| `upsample2f32` | `float` | Upsample 1:2 |\n| `upsample3f32` | `float` | Upsample 1:3 |\n| `downsample2f32` | `float` | Downsample 2:1 |\n| `downsample3f32` | `float` | Downsample 3:1 |\n\n**C**\n\n```c\nsize_t size_out = 3 * size_in;\nfloat512* buf_out =(float512*)far_malloc_align64(size_out);\nfar_upsample3f32(buf_in, size_in, 48000, 2, buf_out, size_out);\n```\n\n**C++**\n\n```cpp\nsize_t size_out = size_in / 2;\nfloat512* buf_out = libfar::malloc_align\u003cfloat512\u003e(size_out);\nlibfar::downsample2f32(buf_in, size_in, 44100, 1, buf_out, size_out);\n```\n\n### Channel adapting\n\nChange the number of audio channels.\n\n| Name | Sample type | Input | Output |\n|---|---|---|---|\n| `adapt_ch1x2s16` | `int16` | Mono (1) | Stereo (2) |\n| `adapt_ch1x2f32` | `float` | Mono (1) | Stereo (2) |\n| `adapt_ch2x1s16` | `int16` | Stereo (2) | Mono (1) |\n| `adapt_ch2x1f32` | `float` | Stereo (2) | Mono (1) |\n\n### Memory\n\nUtilities for allocating and deallocating aligned memory buffers.\n\n| Name | Description |\n|---|---|\n| `malloc_align(size, align)` | Allocate a block of memory with the given size and alignment. |\n| `free_align(ptr)` | Free a block of memory allocated with `malloc_align`. |\n| `malloc_align16(size)` | Allocate a 16-byte aligned block of memory with the given size. Default implementation is a shorthand for `malloc_align(size, 16)`. Custom implementations can optimize the allocation based on the compile-time size. |\n| `free_align16(ptr)` | Free a block of memory allocated with `malloc_align16`. |\n| `malloc_align32(size)` | Allocate a 32-byte aligned block of memory with the given size. Default implementation is a shorthand for `malloc_align(size, 32)`. Custom implementations can optimize the allocation based on the compile-time size. |\n| `free_align32(ptr)` | Free a block of memory allocated with `malloc_align32`. |\n| `malloc_align64(size)` | Allocate a 64-byte aligned block of memory with the given size. Default implementation is a shorthand for `malloc_align(size, 64)`. Custom implementations can optimize the allocation based on the compile-time size. |\n| `free_align64(ptr)` | Free a block of memory allocated with `malloc_align64`. |\n\n**C++**\n\nIn C++, an extra templated helper is available which deduces the alignment from the type alias, which redirects to the corresponding `malloc_alignN()` variant, where `N` is the deduced alignment.\n\n```cpp\ntemplate \u003ctypename T\u003e\nT* malloc_align(size_t size);\n```\n\nThe template is only instantiated for the `intX` and `floatX` type aliases.\n\n| Template instantiation | Returned buffer alignment | Implementation |\n|---|---|---|\n| `malloc_align\u003cfloat128\u003e(size)` | 16 bytes | `malloc_align16()` |\n| `malloc_align\u003cfloat256\u003e(size)` | 32 bytes | `malloc_align32()` |\n| `malloc_align\u003cfloat512\u003e(size)` | 64 bytes | `malloc_align64()` |\n| `malloc_align\u003cshort128\u003e(size)` | 16 bytes | `malloc_align16()` |\n| `malloc_align\u003cshort256\u003e(size)` | 32 bytes | `malloc_align32()` |\n| `malloc_align\u003cshort512\u003e(size)` | 64 bytes | `malloc_align64()` |\n\n### CPUID\n\nUtilities to detect CPU features at runtime and dynamically select the fastest implementation of each library function available on the current host CPU. This is generally used internally only.\n\n| Name | Description |\n|---|---|\n| `void cpuid_init()` | Query and cache the hardware feature support for the host machine. Called once automatically before any of the other functions below; the result is cached after that. |\n| `far_bool has_sse()` | Return `far_true` if SSE is available on the host machine. |\n| `far_bool has_sse2()` | Return `far_true` if SSE2 is available on the host machine. |\n| `far_bool has_sse3()` | Return `far_true` if SSE3 is available on the host machine. |\n| `far_bool has_ssse3()` | Return `far_true` if SSSE3 is available on the host machine. |\n| `far_bool has_sse41()` | Return `far_true` if SSE4.1 is available on the host machine. |\n| `far_bool has_sse42()` | Return `far_true` if SSE4.2 is available on the host machine. |\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjeedai%2Flibfar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdjeedai%2Flibfar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjeedai%2Flibfar/lists"}