diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2023-12-06 21:30:14 +0100 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2023-12-06 21:30:14 +0100 |
commit | 93a9691246574b6d51ddbbdb5be3dceb89ff24e9 (patch) | |
tree | 3f6611ae8d22b496644fa6b863d2a9597b5d4e8b | |
parent | cf80678d0c2472092be2da141247f61de292aafb (diff) | |
download | libfshift-93a9691246574b6d51ddbbdb5be3dceb89ff24e9.tar.gz |
Just simple tool to show the library usage.
-rw-r--r-- | LICENSE | 25 | ||||
-rw-r--r-- | app/unisono/CMakeLists.txt | 28 | ||||
-rw-r--r-- | app/unisono/main.c | 112 |
3 files changed, 165 insertions, 0 deletions
@@ -0,0 +1,25 @@ +BSD 2-Clause License + +Copyright (c) 2023, Daniil Cherednik +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/app/unisono/CMakeLists.txt b/app/unisono/CMakeLists.txt new file mode 100644 index 0000000..8a44354 --- /dev/null +++ b/app/unisono/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.12) + +project(unisono) +set (CMAKE_C_STANDARD 99) +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -fsanitize=address -fno-omit-frame-pointer") + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(LIBSNDFILE_PKGCONF sndfile) +endif(PKG_CONFIG_FOUND) + +find_path(LIBSNDFILE_INCLUDE_DIR + NAMES sndfile.h + PATHS ${LIBSNDFILE_PKGCONF_INCLUDE_DIRS} +) + +find_library(LIBSNDFILE_LIBRARY + NAMES sndfile libsndfile-1 + PATHS ${LIBSNDFILE_PKGCONF_LIBRARY_DIRS} +) + +message(STATUS "sndfile include dirs path: ${LIBSNDFILE_INCLUDE_DIR}") +message(STATUS "sndfile libs path: ${LIBSNDFILE_LIBRARY}") + +add_executable(unisono "main.c") +include_directories(${LIBSNDFILE_INCLUDE_DIRS}) +target_link_libraries(unisono PRIVATE ${LIBSNDFILE_LIBRARY}) + diff --git a/app/unisono/main.c b/app/unisono/main.c new file mode 100644 index 0000000..4940962 --- /dev/null +++ b/app/unisono/main.c @@ -0,0 +1,112 @@ +#include <getopt.h> +#include <stdlib.h> +#include <string.h> + +#include <sndfile.h> + +static void print_usage(const char* name) +{ + fprintf(stdout, "usage: %s\n", name); +} + +#define BUFFER_LEN 16384 + +static float in_data[BUFFER_LEN]; +static float out_data[BUFFER_LEN]; + +/////////////////////////////////////////////////////////////////////////////// + +void downmix(float* in, int len) +{ + int i, j; + // Downmix stereo to mono + for (i = 0, j = 0; i < len; i+=2, j++) { + in[j] = (in[i] + in[i + 1]) / 2.0; + } +} + +void process(float *in, float *out, const SF_INFO *info, int len) +{ + int i; + // Call processing here + for (int i = 0; i < len / 2; i++) { + out[i * 2] = in[i]; + out[i * 2 + 1] = -in[i]; + } +} + +int main(int argc, char** argv) +{ + const char* my_name = argv[0]; + const char* in_file_nm = NULL; + const char* out_file_nm = NULL; + float shift = 0.0; + int ch; + + SF_INFO sf_info; + SNDFILE *in_file, *out_file; + int read_channels; + int read_block_sz = BUFFER_LEN; + int read_count; + + while ((ch = getopt(argc, argv, "f:i:")) != -1) { + switch (ch) { + case 'i': + in_file_nm = optarg; + break; + case 'f': + shift = atof(optarg); + break; + default: + print_usage(my_name); + return 1; + } + } + + if (optind == argc) { + print_usage(my_name); + return 1; + } + out_file_nm = argv[optind]; + fprintf(stderr, "input: %s -> %s, shift: %f hz\n", in_file_nm, out_file_nm, shift); + + memset(&sf_info, 0, sizeof(sf_info)); + + if (!(in_file = sf_open(in_file_nm, SFM_READ, &sf_info))) { + printf ("Unable to open input file %s.\n", in_file_nm); + puts (sf_strerror (NULL)); + return 1; + } + + if (sf_info.channels > 2) + { + printf ("Expected stereo or mono input file") ; + sf_close (in_file); + return 1; + } + + read_channels = sf_info.channels; + sf_info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; + sf_info.channels = 2; + + if (!(out_file = sf_open(out_file_nm, SFM_WRITE, &sf_info))) { + printf ("Unable to open output file %s.\n", out_file_nm); + puts (sf_strerror (NULL)) ; + + sf_close(in_file); + return 1 ; + } + + + while ((read_count = (int)sf_readf_float(in_file, in_data, BUFFER_LEN / 2))) { + if (read_channels == 2) + downmix(in_data, BUFFER_LEN); + process(in_data, out_data, &sf_info, BUFFER_LEN); + sf_writef_float(out_file, out_data, read_count); + } + + sf_close(in_file) ; + sf_close(out_file) ; + + return 0; +} |