112 | .PP
113 | .br
114 | This is free software; see the source for copying conditions. There is NO
115 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
116 |
--------------------------------------------------------------------------------
/doc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | sndfile-tools
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
sndfile-tools
16 |
17 |
18 | Sndfile-tools is a small collection of programs that use libsndfile and other
19 | libraries to do useful things.
20 | The collection currently includes the following programs:
21 |
22 |
23 |
29 |
30 |
31 | The sndfile-tools package is released under the terms of the
32 |
33 | GNU General Public License
34 | (version 2 or version 3).
35 |
36 |
37 |
38 | The latest version is 1.5 and it can be downloaded here:
39 |
40 | sndfile-tools-1.5.tar.bz2
41 | (
42 | GPG signature).
43 |
44 |
45 |
46 |
47 | It should be trivial to compile on Linux and relatively easy to compile on
48 | other Unices (including Mac OSX).
49 | Its probably possible to compile it on windows, but why would anyone bother?
50 |
51 |
52 |
53 |
54 |
55 |
56 | sndfile-generate-chirp
57 |
58 |
59 | Create a sound file containing a swept sine wave (ie a chirp).
60 |
61 |
62 |
63 | sndfile-generate-chirp [options] <sample rate> <length in seconds> <sound file>
64 |
65 | Options include:
66 |
67 | -from <start> Sweep start frequency in Hz (default 200Hz).
68 | -to <end> Sweep end frequency in Hz (default fs/2).
69 | -amp <value> Amplitude of generated sine (default 1.0).
70 | <sweep type> One of (default -log):
71 | -log logarithmic sweep
72 | -quad quadratic sweep
73 | -linear linear sweep
74 |
75 | The output file will contain floating point samples in the range [-1.0, 1.0].
76 | The output file type is determined by the file name extension which should be one
77 | of 'wav', 'aifc', 'aif', 'aiff', 'au', 'caf' and 'w64'.
78 |
79 |
80 |
81 |
82 |
83 | sndfile-jackplay
84 |
85 |
86 | Play a sound file via the JACK Audio Connect Kit daemon.
87 |
88 |
89 |
90 | sndfile-jackplay <filename>
91 |
92 |
93 |
94 |
95 |
96 |
97 | sndfile-spectrogram
98 |
99 |
100 | Generate a spectrogram as a PNG file from a given sound file.
101 |
102 |
103 |
104 |
105 | sndfile-spectrogram <sound file> <img width> <img height> <png name>
106 |
107 |
108 |
109 |
110 | This program (in conjunction with sndfile-generate-chirp) is particularly useful
111 | for evaluating the quality of sample rate converters.
112 | For instance, a chirp can be generated at 96kHz, passed through the converter
113 | and a spectrogram generated for the converter output file. For example:
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 | sndfile-mix-to-mono
126 |
127 |
128 |
129 | Convert a multi-channel input file to a mono output file, by mixing all input
130 | channels into one.
131 |
132 |
133 |
134 |
135 | sndfile-mix-to-mono <input file> <output file>
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.12)
2 |
3 | project(sndfile-tools
4 | VERSION 1.5
5 | DESCRIPTION "Collection of programs for operating on sound files"
6 | HOMEPAGE_URL "http://libsndfile.github.io/libsamplerate/"
7 | LANGUAGES C
8 | )
9 |
10 | include(CheckIncludeFile)
11 | include(CheckLibraryExists)
12 | include(CMakeDependentOption)
13 | include(CPack)
14 | include(GNUInstallDirs)
15 | include(FeatureSummary)
16 | include(CTest)
17 |
18 | find_library(HAVE_LIBM m)
19 | if(HAVE_LIBM)
20 | check_library_exists(m floor "" HAVE_FLOOR_IN_LIBM)
21 | if(HAVE_FLOOR_IN_LIBM)
22 | list(APPEND CMAKE_REQUIRED_LIBRARIES m)
23 | endif()
24 | endif()
25 |
26 | check_include_file(sys/wait.h HAVE_SYS_WAIT_H)
27 |
28 | find_package(PkgConfig)
29 |
30 | pkg_check_modules(SNDFILE REQUIRED IMPORTED_TARGET sndfile>=1.0.19)
31 | pkg_check_modules(SAMPLERATE REQUIRED IMPORTED_TARGET samplerate>=0.1.5)
32 | pkg_check_modules(FFTW3 REQUIRED IMPORTED_TARGET fftw3>=0.15.0)
33 | pkg_check_modules(CAIRO REQUIRED IMPORTED_TARGET cairo>=1.4.0)
34 | pkg_check_modules(JACK IMPORTED_TARGET jack>=0.100)
35 | if(JACK_FOUND)
36 | find_package(Threads)
37 | endif()
38 |
39 | configure_file(config.h.cmake config.h)
40 | add_compile_definitions(HAVE_CONFIG_H)
41 | include_directories(${PROJECT_BINARY_DIR})
42 |
43 | cmake_dependent_option(ENABLE_JACK "Enable libjack" ON "ENABLE_JACK" OFF)
44 |
45 | add_executable(sndfile-generate-chirp
46 | src/generate-chirp.c
47 | src/common.c
48 | src/common.h
49 | )
50 | target_link_libraries(sndfile-generate-chirp PRIVATE PkgConfig::SNDFILE)
51 |
52 | add_executable(sndfile-spectrogram
53 | src/spectrogram.c
54 | src/window.c
55 | src/common.c
56 | src/window.h
57 | src/common.h
58 | src/spectrum.c
59 | src/spectrum.h
60 | )
61 | target_link_libraries(sndfile-spectrogram
62 | PRIVATE
63 | PkgConfig::SNDFILE
64 | PkgConfig::FFTW3
65 | PkgConfig::CAIRO
66 | )
67 |
68 | add_executable(sndfile-mix-to-mono
69 | src/mix-to-mono.c
70 | src/common.h
71 | src/common.c
72 | )
73 | target_link_libraries(sndfile-mix-to-mono PRIVATE PkgConfig::SNDFILE)
74 |
75 | add_executable(sndfile-waveform
76 | src/waveform.c
77 | src/common.c
78 | src/common.h
79 | )
80 | target_link_libraries(sndfile-waveform
81 | PRIVATE
82 | PkgConfig::SNDFILE
83 | PkgConfig::CAIRO
84 | )
85 |
86 | add_executable(sndfile-resample
87 | src/resample.c
88 | src/common.c
89 | src/common.h
90 | )
91 | target_link_libraries(sndfile-resample
92 | PRIVATE
93 | PkgConfig::SNDFILE
94 | PkgConfig::SAMPLERATE
95 | )
96 |
97 | if(ENABLE_JACK)
98 | add_executable(sndfile-jackplay src/jackplay.c)
99 | target_link_libraries(sndfile-jackplay
100 | PRIVATE
101 | PkgConfig::SNDFILE
102 | PkgConfig::JACK
103 | )
104 | if(Threads_FOUND)
105 | target_link_libraries(sndfile-jackplay PRIVATE Threads::Threads)
106 | endif()
107 | endif()
108 |
109 | set(SNDFILE_TOOLS_TARGETS
110 | sndfile-generate-chirp
111 | sndfile-spectrogram
112 | sndfile-mix-to-mono
113 | sndfile-waveform
114 | sndfile-resample
115 | )
116 | if(ENABLE_JACK)
117 | list(APPEND SNDFILE_TOOLS_TARGETS sndfile-jackplay)
118 | endif()
119 |
120 | install(TARGETS ${SNDFILE_TOOLS_TARGETS}
121 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
122 | )
123 |
124 | set(SNDFILE_TOOLS_MANS
125 | man/sndfile-generate-chirp.1
126 | man/sndfile-mix-to-mono.1
127 | man/sndfile-resample.1
128 | man/sndfile-spectrogram.1
129 | man/sndfile-waveform.1
130 | )
131 | if(ENABLE_JACK)
132 | list(APPEND SNDFILE_TOOLS_MANS man/sndfile-jackplay.1)
133 | endif()
134 |
135 | install(FILES ${SNDFILE_TOOLS_MANS} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
136 |
137 | add_feature_info(ENABLE_JACK ENABLE_JACK "build sndfile-jackplay (requires libjack library).")
138 |
139 | feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
140 |
141 | if(BUILD_TESTING)
142 | add_executable(kaiser_window_test tests/kaiser_window_test.c src/window.h src/window.c)
143 | target_include_directories(kaiser_window_test PRIVATE ${PROJECT_SOURCE_DIR})
144 | add_test(COMMAND kaiser_window_test NAME kaiser_window_test)
145 |
146 | if(HAVE_SYS_WAIT_H)
147 | add_executable(common_tests tests/common_tests.c src/common.c src/common.h)
148 | target_include_directories(common_tests PRIVATE ${PROJECT_SOURCE_DIR})
149 | add_test(COMMAND common_tests NAME common_tests)
150 | endif()
151 | endif()
152 |
--------------------------------------------------------------------------------
/src/window.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (C) 2007-2015 Erik de Castro Lopo
3 | **
4 | ** This program is free software: you can redistribute it and/or modify
5 | ** it under the terms of the GNU General Public License as published by
6 | ** the Free Software Foundation, either version 2 or version 3 of the
7 | ** License.
8 | **
9 | ** This program is distributed in the hope that it will be useful,
10 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | ** GNU General Public License for more details.
13 | **
14 | ** You should have received a copy of the GNU General Public License
15 | ** along with this program. If not, see .
16 | */
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include "window.h"
24 |
25 | #define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof (x [0])))
26 |
27 |
28 | static double besseli0 (double x) ;
29 | static double factorial (int k) ;
30 |
31 | void
32 | calc_kaiser_window (double * data, int datalen, double beta)
33 | {
34 | /*
35 | ** besseli0 (beta * sqrt (1- (2*x/N).^2))
36 | ** w (x) = --------------------------------------, -N/2 <= x <= N/2
37 | ** besseli0 (beta)
38 | */
39 |
40 | double two_n_on_N, denom ;
41 | int k ;
42 |
43 | denom = besseli0 (beta) ;
44 |
45 | if (! isfinite (denom))
46 | { printf ("besseli0 (%f) : %f\nExiting\n", beta, denom) ;
47 | exit (1) ;
48 | } ;
49 |
50 | for (k = 0 ; k < datalen ; k++)
51 | { double n = k + 0.5 - 0.5 * datalen ;
52 | two_n_on_N = (2.0 * n) / datalen ;
53 | data [k] = besseli0 (beta * sqrt (1.0 - two_n_on_N * two_n_on_N)) / denom ;
54 | } ;
55 |
56 | return ;
57 | } /* calc_kaiser_window */
58 |
59 | void
60 | calc_nuttall_window (double * data, int datalen)
61 | {
62 | const double a [4] = { 0.355768, 0.487396, 0.144232, 0.012604 } ;
63 | int k ;
64 |
65 | /*
66 | ** Nuttall window function from :
67 | **
68 | ** http://en.wikipedia.org/wiki/Window_function
69 | */
70 |
71 | for (k = 0 ; k < datalen ; k++)
72 | { double scale ;
73 |
74 | scale = M_PI * k / (datalen - 1) ;
75 |
76 | data [k] = a [0] - a [1] * cos (2.0 * scale) + a [2] * cos (4.0 * scale) - a [3] * cos (6.0 * scale) ;
77 | } ;
78 |
79 | return ;
80 | } /* calc_nuttall_window */
81 |
82 | void
83 | calc_hann_window (double * data, int datalen)
84 | {
85 | int k ;
86 |
87 | /*
88 | ** Hann window function from :
89 | **
90 | ** http://en.wikipedia.org/wiki/Window_function
91 | */
92 |
93 | for (k = 0 ; k < datalen ; k++)
94 | data [k] = 0.5 * (1.0 - cos (2.0 * M_PI * k / (datalen - 1))) ;
95 |
96 | return ;
97 | } /* calc_hann_window */
98 |
99 | /*==============================================================================
100 | */
101 |
102 | static double
103 | besseli0 (double x)
104 | { int k ;
105 | double result = 0.0 ;
106 |
107 | for (k = 1 ; k < 25 ; k++)
108 | { double temp ;
109 |
110 | temp = pow (0.5 * x, k) / factorial (k) ;
111 | result += temp * temp ;
112 | } ;
113 |
114 | return 1.0 + result ;
115 | } /* besseli0 */
116 |
117 | static double
118 | factorial (int val)
119 | { static double memory [64] = { 1.0 } ;
120 | static int have_entry = 0 ;
121 |
122 | int k ;
123 |
124 | if (val < 0)
125 | { printf ("Oops : val < 0.\n") ;
126 | exit (1) ;
127 | } ;
128 |
129 | if (val > ARRAY_LEN (memory))
130 | { printf ("Oops : val > ARRAY_LEN (memory).\n") ;
131 | exit (1) ;
132 | } ;
133 |
134 | if (val < have_entry)
135 | return memory [val] ;
136 |
137 | for (k = have_entry + 1 ; k <= val ; k++)
138 | memory [k] = k * memory [k - 1] ;
139 |
140 | have_entry = val ;
141 |
142 | return memory [val] ;
143 | } /* factorial */
144 |
145 | /*==============================================================================
146 | */
147 |
148 | static void init_test (void) __attribute__ ((constructor)) ;
149 |
150 | static void
151 | init_test (void)
152 | {
153 | /* puts (__func__) ;*/
154 |
155 | assert (factorial (0) == 1.0) ;
156 | assert (factorial (2) == 2.0) ;
157 | assert (factorial (0) == 1.0) ;
158 | assert (factorial (5) == 120.0) ;
159 | assert (factorial (8) == 40320.0) ;
160 |
161 | assert (fabs (besseli0 (0.0) - 1.0) < 1e-8) ;
162 | assert (fabs (besseli0 (0.5) - 1.06348337074132) < 1e-8) ;
163 | assert (fabs (besseli0 (1.0) - 1.26606587775201) < 1e-14) ;
164 | assert (fabs (besseli0 (2.0) - 2.27958530233607) < 1e-14) ;
165 | assert (fabs (besseli0 (3.5) - 7.37820343222548) < 1e-14) ;
166 |
167 | } /* init_test */
168 |
169 |
--------------------------------------------------------------------------------
/autogen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Run this to set up the build system: configure, makefiles, etc.
3 | # (based on the version in enlightenment's cvs)
4 |
5 | package="sndfile-tools"
6 |
7 | olddir=`pwd`
8 | srcdir=`dirname $0`
9 | test -z "$srcdir" && srcdir=.
10 |
11 | cd "$srcdir"
12 | DIE=0
13 |
14 | echo -n "checking for autoconf... "
15 | result="yes"
16 | (autoconf --version) < /dev/null > /dev/null 2>&1 || {
17 | echo
18 | echo "You must have autoconf installed to compile $package."
19 | echo "Download the appropriate package for your distribution,"
20 | echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
21 | result="no"
22 | DIE=1
23 | }
24 | echo $result
25 |
26 | VERSIONGREP="sed -e s/.*[^0-9\.]\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/"
27 | VERSIONMKMAJ="sed -e s/\([0-9][0-9]*\)[^0-9].*/\\1/"
28 | VERSIONMKMIN="sed -e s/.*[0-9][0-9]*\.//"
29 |
30 | # do we need automake?
31 | if test -r Makefile.am; then
32 | AM_OPTIONS=`fgrep AUTOMAKE_OPTIONS Makefile.am`
33 | AM_NEEDED=`echo $AM_OPTIONS | $VERSIONGREP`
34 | if test x"$AM_NEEDED" = "x$AM_OPTIONS"; then
35 | AM_NEEDED=""
36 | fi
37 | if test -z $AM_NEEDED; then
38 | echo -n "checking for automake... "
39 | AUTOMAKE=automake
40 | ACLOCAL=aclocal
41 | if ($AUTOMAKE --version < /dev/null > /dev/null 2>&1); then
42 | echo "yes"
43 | else
44 | echo "no"
45 | AUTOMAKE=
46 | fi
47 | else
48 | echo -n "checking for automake $AM_NEEDED or later... "
49 | majneeded=`echo $AM_NEEDED | $VERSIONMKMAJ`
50 | minneeded=`echo $AM_NEEDED | $VERSIONMKMIN`
51 | for am in automake-$AM_NEEDED automake$AM_NEEDED \
52 | automake automake-1.7 automake-1.8 automake-1.9 automake-1.10; do
53 | ($am --version < /dev/null > /dev/null 2>&1) || continue
54 | ver=`$am --version < /dev/null | head -n 1 | $VERSIONGREP`
55 | maj=`echo $ver | $VERSIONMKMAJ`
56 | min=`echo $ver | $VERSIONMKMIN`
57 | if test $maj -eq $majneeded -a $min -ge $minneeded; then
58 | AUTOMAKE=$am
59 | echo $AUTOMAKE
60 | break
61 | fi
62 | done
63 | test -z $AUTOMAKE && echo "no"
64 | echo -n "checking for aclocal $AM_NEEDED or later... "
65 | for ac in aclocal-$AM_NEEDED aclocal$AM_NEEDED \
66 | aclocal aclocal-1.7 aclocal-1.8 aclocal-1.9 aclocal-1.10; do
67 | ($ac --version < /dev/null > /dev/null 2>&1) || continue
68 | ver=`$ac --version < /dev/null | head -n 1 | $VERSIONGREP`
69 | maj=`echo $ver | $VERSIONMKMAJ`
70 | min=`echo $ver | $VERSIONMKMIN`
71 | if test $maj -eq $majneeded -a $min -ge $minneeded; then
72 | ACLOCAL=$ac
73 | echo $ACLOCAL
74 | break
75 | fi
76 | done
77 | test -z $ACLOCAL && echo "no"
78 | fi
79 | test -z $AUTOMAKE || test -z $ACLOCAL && {
80 | echo
81 | echo "You must have automake installed to compile $package."
82 | echo "Download the appropriate package for your distribution,"
83 | echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
84 | exit 1
85 | }
86 | fi
87 |
88 | echo -n "checking for libtool... "
89 | for LIBTOOLIZE in libtoolize glibtoolize nope; do
90 | ($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 && break
91 | done
92 | if test x$LIBTOOLIZE = xnope; then
93 | echo "nope."
94 | LIBTOOLIZE=libtoolize
95 | else
96 | echo $LIBTOOLIZE
97 | fi
98 | ($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 || {
99 | echo
100 | echo "You must have libtool installed to compile $package."
101 | echo "Download the appropriate package for your system,"
102 | echo "or get the source from one of the GNU ftp sites"
103 | echo "listed in http://www.gnu.org/order/ftp.html"
104 | DIE=1
105 | }
106 |
107 | echo -n "checking for pkg-config ... "
108 | result="yes"
109 | (pkg-config --version) < /dev/null > /dev/null 2>&1 || {
110 | echo
111 | echo "You must have pkg-config installed to compile $package."
112 | echo "Download the appropriate package for your distribution."
113 | result="no"
114 | DIE=1
115 | }
116 | echo $result
117 |
118 | if test "$DIE" -eq 1; then
119 | exit 1
120 | fi
121 |
122 | if test ! -d build-aux ; then
123 | echo "Creating 'build-aux' directory."
124 | mkdir build-aux
125 | fi
126 |
127 | echo "Generating configuration files for $package, please wait ... "
128 |
129 | echo " $ACLOCAL $ACLOCAL_FLAGS"
130 | $ACLOCAL $ACLOCAL_FLAGS || exit 1
131 | echo " $LIBTOOLIZE --automake --force"
132 | $LIBTOOLIZE --automake --force || exit 1
133 |
134 | echo " autoheader"
135 | autoheader || exit 1
136 | echo " $AUTOMAKE --add-missing $AUTOMAKE_FLAGS"
137 | $AUTOMAKE --copy --add-missing $AUTOMAKE_FLAGS || exit 1
138 | echo " autoconf"
139 | autoconf || exit 1
140 |
141 | if test -d .git; then
142 | fprecommit=.git/hooks/pre-commit
143 | if test ! -f $fprecommit ; then
144 | echo "Installing git pre-commit hook for this project."
145 | cat > $fprecommit << 'foobar'
146 | #!/bin/sh
147 | exec Scripts/git-pre-commit-hook
148 | foobar
149 | chmod u+x $fprecommit
150 | echo
151 | fi
152 | fi
153 |
--------------------------------------------------------------------------------
/ChangeLog:
--------------------------------------------------------------------------------
1 | 2012-09-06 Erik de Castro Lopo
2 |
3 | * src/resample.c
4 | Fix valgrind warning.
5 |
6 | * Makefile.am tests/valgrind-test.sh
7 | Add a valgrind test for some of the executables.
8 |
9 | 2012-09-04 Erik de Castro Lopo
10 |
11 | * configure.ac
12 | Remove un-needed AC_LANG_SOURCE statement. Thanks to Robin Gareus.
13 |
14 | 2012-07-24 Erik de Castro Lopo
15 |
16 | * src/common.c
17 | Fix minor bug in sfx_mix_mono_read_double(). Patch from Martin Guy. Thanks.
18 |
19 | 2012-02-25 Erik de Castro Lopo
20 |
21 | * M4/extra_pkg.m4
22 | Update PKG_CHECK_MOD_VERSION macro to add an AC_TRY_LINK step. This fix
23 | allows the configure process to catch attempts to link incompatible
24 | libraries. For example, linking 32 bit version of eg libFLAC to a 64 bit
25 | version of sndfile-tools will now fail at the configure stage.
26 |
27 | 2011-01-14 Robin Gareus
28 |
29 | * src/waveform.c
30 | added sndfile-waveform, a waveform image generator
31 |
32 | 2011-01-13 Erik de Castro Lopo
33 |
34 | * src/jackplay.c
35 | Improve reporting of loop count.
36 |
37 | 2011-01-12 Erik de Castro Lopo
38 |
39 | * src/*.[ch]
40 | Update copyright years.
41 |
42 | * src/jackplay.c
43 | Add ability to play a file in a loop.
44 |
45 | * man/sndfile-jackplay.1
46 | Update with new options.
47 |
48 | 2011-01-11 Erik de Castro Lopo
49 |
50 | * configure.ac
51 | Add AM_SILENT_RULES and other tweaks.
52 |
53 | * src/common.c
54 | Fix bug in sfx_mix_mono_read_double() where a bunch of crap got appended to
55 | the end of the mixed down file. Thanks to Tom Szilagyi for the bug report.
56 | Remove cruft.
57 |
58 | 2010-04-07 Erik de Castro Lopo
59 |
60 | * src/jackplay.c
61 | Use jack_client_open() instead of deprecated jack_client_new().
62 |
63 | * man/sndfile-spectrogram.1
64 | Fix two typos reported by Igor Murzov.
65 |
66 | 2010-02-22 Erik de Castro Lopo
67 |
68 | * configure.ac
69 | Detect presence of libsamplerate.
70 |
71 | * src/resample.c Makefile.am
72 | Add file originally from the libsamplerate source distribution and hook
73 | into build.
74 |
75 | 2009-12-21 Erik de Castro Lopo
76 |
77 | * src/*c
78 | Remove 'sndfile-' parts of file names.
79 |
80 | * src/jackplay.c
81 | Reorder JACK initialisation calls to remove click at start of playback.
82 |
83 | 2009-12-14 Erik de Castro Lopo
84 |
85 | * configure.ac
86 | Don't test for a fortran compiler.
87 |
88 | * man/sndfile-generate-chirp.1 man/sndfile-mix-to-mono.1
89 | man/sndfile-spectrogram.1
90 | New man pages.
91 |
92 | * Makefile.am
93 | Hook new man pages into build.
94 |
95 | * NEWS doc/index.html
96 | Update for 1.03 release.
97 |
98 | 2009-12-07 Erik de Castro Lopo
99 |
100 | * M4/*.m4 configure.ac
101 | Rename custom M4 macros to MN_*.
102 |
103 | * man/sndfile-jackplay.1 Makefile.am
104 | Add man page for sndfile-jackplay.
105 |
106 | * doc/index.html
107 | Add sndfile-jackplay.
108 |
109 | 2009-12-04 Erik de Castro Lopo
110 |
111 | * src/sndfile-merge.c
112 | Remove this (moved to libsndfile source distribution).
113 |
114 | * src/sndfile-jackplay.c
115 | Add file originally from the libsndfile source distribution.
116 |
117 | * M4/extra_pkg.m4 configure.ac
118 | Add M4 macro for using in configure.ac to find the JACK library.
119 |
120 | * Makefile.am
121 | Fix build after previous changes.
122 |
123 | 2009-11-28 Erik de Castro Lopo
124 |
125 | * src/sndfile-spectrogram.c
126 | Improve the way the spectrogram is interpolated.
127 |
128 | 2009-11-26 Erik de Castro Lopo
129 |
130 | * src/sndfile-spectrogram.c
131 | Initialize colour to black so it writes black instead of random values from
132 | the stack.
133 | Add a --dyn-range=XXX command line option to set spectrogram dynamic range.
134 | Add --no-border command line option to disable rendering of border, scales,
135 | heat map and title.
136 |
137 | * src/sndfile-merge.c
138 | New program contributed by Jonatan Liljedahl that takes two mono files and
139 | merges them into a stereo file.
140 |
141 | 2009-03-02 Erik de Castro Lopo
142 |
143 | * src/window.c
144 | Add bounds check before array access.
145 |
146 | 2007-10-21 Erik de Castro Lopo
147 |
148 | * src/sndfile-spectrogram.c
149 | Calculate longer FFTs and then interpolate to the image height.
150 |
151 | * src/kaiser_window_test.c
152 | Test a longer window length.
153 |
154 | * doc/*
155 | Add rudimentary documentation.
156 |
157 | * configure.ac src/common.c
158 | Detect presence of sf_get_info() and SFC_GET_CURRENT_SF_INFO.
159 |
--------------------------------------------------------------------------------
/configure.ac:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2002-2021 Erik de Castro Lopo
2 |
3 | dnl Require autoconf version >= 2.69)
4 | AC_PREREQ([2.69])
5 |
6 | AC_INIT([sndfile-tools],[1.5],[sndfile@mega-nerd.com],
7 | [sndfile-tools],[https://github.com/libsndfile/sndfile-tools/])
8 |
9 | dnl Check whether we want to set defaults for CFLAGS, CPPFLAGS and LDFLAGS
10 | AC_MSG_CHECKING([whether configure should try to set CFLAGS/CPPFLAGS/LDFLAGS])
11 | AS_IF([test "x${CFLAGS+set}" = "xset" || test "x${CPPFLAGS+set}" = "xset" || test "x${LDFLAGS+set}" = "xset"], [
12 | enable_flags_setting=no
13 | : ${CFLAGS=""}
14 | ], [
15 | enable_flags_setting=yes
16 | dnl Set to empty flags so AC_PROG_CC does not add -g -O2
17 | CFLAGS=""
18 | ])
19 | AC_MSG_RESULT([${enable_flags_setting}])
20 |
21 | dnl Put config stuff in 'build-aux'.
22 | AC_CONFIG_AUX_DIR([build-aux])
23 |
24 | AC_CONFIG_SRCDIR([src/spectrogram.c])
25 | AC_CANONICAL_HOST
26 |
27 | AC_CONFIG_MACRO_DIR([m4])
28 | AC_CONFIG_HEADERS([src/config.h])
29 |
30 | AM_INIT_AUTOMAKE([1.14 foreign dist-bzip2 no-dist-gzip subdir-objects])
31 | AM_SILENT_RULES([yes])
32 |
33 | dnl ====================================================================================
34 |
35 | AC_PROG_CC
36 | AC_PROG_CC_C99
37 |
38 | AS_IF([test "x$ac_cv_prog_cc_c99" = "xno"], [
39 | AC_MSG_ERROR([sndfile-tools requires a C99 capable compiler!])
40 | ])
41 |
42 | AC_LANG([C])
43 | AX_COMPILER_VENDOR
44 | AX_COMPILER_VERSION
45 |
46 | dnl ====================================================================================
47 | dnl Finished checking, handle options.
48 |
49 | AC_ARG_ENABLE([werror],
50 | [AS_HELP_STRING([--enable-werror], [enable -Werror in all Makefiles])])
51 |
52 | AC_ARG_ENABLE([jack],
53 | [AS_HELP_STRING([--disable-jack], [disable use of JACK (default=autodetect)])], [], [enable_jack=auto])
54 |
55 | dnl ====================================================================================
56 | dnl Check for functions.
57 |
58 | AC_SEARCH_LIBS([floor], [m], [], [
59 | AC_MSG_ERROR([unable to find the floor() function!])
60 | ])
61 | AC_CHECK_FUNCS([floor ceil fmod lrint lrintf])
62 |
63 | dnl ====================================================================================
64 | dnl Check for libsndfile.
65 |
66 | PKG_CHECK_MODULES([SNDFILE], [sndfile >= 1.0.19], [
67 | AC_DEFINE([HAVE_SNDFILE], [1], [Set to 1 if you have libsndfile])
68 | ], [
69 | AC_MSG_ERROR([libsndfile could not be found!])
70 | ])
71 |
72 | dnl ====================================================================================
73 | dnl Check for libsamplerate.
74 |
75 | PKG_CHECK_MODULES([SAMPLERATE], [samplerate >= 0.1.5], [
76 | AC_DEFINE([HAVE_SAMPLERATE], [1], [Set to 1 if you have libsamplerate])
77 | ], [
78 | AC_MSG_ERROR([libsamplerate could not be found!])
79 | ])
80 |
81 | dnl ====================================================================================
82 | dnl Check for libfftw3 which is required for src/sndfile-spectrogram.c).
83 |
84 | PKG_CHECK_MODULES([FFTW3], [fftw3 >= 0.15.0], [
85 | AC_DEFINE([HAVE_FFTW3], [1], [Set to 1 if you have FFTW])
86 | ], [
87 | AC_MSG_ERROR([FFTW could not be found!])
88 | ])
89 |
90 | dnl ====================================================================================
91 | dnl Check for libcairo which is required for src/sndfile-spectrogram.c.
92 |
93 | PKG_CHECK_MODULES([CAIRO], [cairo >= 1.4.0], [
94 | AC_DEFINE([HAVE_CAIRO], [1], [Set to 1 if you have Cairo])
95 | ], [
96 | AC_MSG_ERROR([Cairo could not be found!])
97 | ])
98 |
99 | dnl ====================================================================================
100 | dnl Check for JACK which is required for src/sndfile-jackplay.c.
101 |
102 | AS_IF([test "x$enable_jack" != "xno"], [
103 | PKG_CHECK_MODULES([JACK], [jack >= 0.100], [
104 | AC_DEFINE([HAVE_JACK], [1], [Set to 1 if you have JACK])
105 | enable_jack="yes"
106 |
107 | AX_PTHREAD
108 | JACK_CFLAGS="${JACK_CFLAGS} ${PTHREAD_CFLAGS}"
109 | JACK_LIBS="${JACK_LIBS} ${PTHREAD_LIBS}"
110 | ], [
111 | AS_IF([test "x$enable_jack" = "xyes"], [
112 | dnl explicitly passed --enable-jack, hence error out loud and clearly
113 | AC_MSG_ERROR([You explicitly requested JACK support, but JACK could not be found!])
114 | ], [
115 | dnl did not explicitly pass --enable-jack, relying on default automagic on
116 | enable_jack="no (auto)"
117 | ])
118 | ])
119 | ])
120 | AM_CONDITIONAL([HAVE_JACK], [test "x$enable_jack" = "xyes"])
121 |
122 | dnl ====================================================================================
123 | dnl Compiler stuff.
124 |
125 | AS_IF([test "x$enable_flags_setting" = "xyes"], [
126 | AX_APPEND_COMPILE_FLAGS([-O2 -pipe], [CFLAGS])
127 |
128 | AS_CASE([${host_os}],
129 | [darwin*], [
130 | ldflags_test="-Wl,-dead_strip_dylibs"],
131 | [linux*], [
132 | ldflags_test="-Wl,-O1 -Wl,--as-needed -Wl,--no-undefined -Wl,--gc-sections"]
133 | )
134 | AX_APPEND_LINK_FLAGS([${ldflags_test}], [LDFLAGS])
135 | ])
136 |
137 | AS_IF([test "x$enable_werror" = "xyes"], [
138 | AX_APPEND_COMPILE_FLAGS([-Werror], [CFLAGS])
139 | ])
140 |
141 | AX_APPEND_COMPILE_FLAGS([-Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -Waggregate-return -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wpointer-arith], [CFLAGS])
142 |
143 | dnl ====================================================================================
144 | dnl Now use the information from the checking stage.
145 |
146 | AC_CONFIG_FILES([Makefile])
147 | AC_OUTPUT
148 |
149 | dnl ====================================================================================
150 |
151 | AX_RECURSIVE_EVAL([$bindir], [full_absolute_bindir])
152 | AC_MSG_RESULT([
153 | -=-=-=-=-=-=-=-=-=-= Configuration Complete =-=-=-=-=-=-=-=-=-=-=-
154 |
155 | Configuration summary :
156 |
157 | sndfile-tools version : ............... ${VERSION}
158 |
159 | Host CPU : ............................ ${host_cpu}
160 | Host Vendor : ......................... ${host_vendor}
161 | Host OS : ............................. ${host_os}
162 |
163 | CFLAGS : .............................. ${CFLAGS}
164 | CPPFLAGS : ............................ ${CPPFLAGS}
165 | LDFLAGS : ............................. ${LDFLAGS}
166 |
167 | Tools :
168 |
169 | C Compiler Vendor is : ................ ${ax_cv_c_compiler_vendor} (${ax_cv_c_compiler_version})
170 |
171 | Extra tools required for testing and examples :
172 |
173 | Found libjack ......................... ${enable_jack}
174 |
175 | Installation directories :
176 |
177 | Program directory : ................... ${full_absolute_bindir}
178 |
179 | ])
180 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | Original author:
2 |
3 | The main author of libsndfile is Erik de Castro Lopo .
4 |
5 | Current maintainers:
6 |
7 | After the release of version 1.04, @erikd transferred the project to
8 | [the libsndfile team](https://github.com/libsndfile) consisting of:
9 |
10 | * Erik de Castro Lopo aka @erikd
11 | * David Seifert aka @SoapGentoo
12 | * Arthur Taylor aka @arthurt
13 | * @evpobr
14 |
15 | Current release manager is David Seifert:
16 |
17 | -----BEGIN PGP PUBLIC KEY BLOCK-----
18 | Version: GnuPG v2
19 |
20 | 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
125 | =K3x+
126 | -----END PGP PUBLIC KEY BLOCK-----
127 |
128 | Previous release manager:
129 |
130 | Versions before 1.5 - Erik de Castro Lopo.
131 |
132 | The public GPG key:
133 |
134 | -----BEGIN PGP SIGNATURE-----
135 |
136 | iQIzBAABCAAdFiEEapGlzyLCTJmjXgE/z9z5H7JCrO0FAljgv0wACgkQz9z5H7JC
137 | rO2RhxAAnIuHquhkhaY8CVsIOGImMxEF8RKDyFoioV9RnckNzBb592EYxU9hS0MM
138 | cT6xPZU0bJa8CvmCxEABMlkk60JP4VmmOtWxD8EEyktbHGyao80mDR82yVKYv78L
139 | zTRzz/JoTncgwWz/QataMbkAfy3KpxkwDW87az0kzkqGuSm3Jg3medt+t/iBe0Wm
140 | jcxIexxEZCmIhty6VyaVEkGWax0zdJHe7aD9FK2C/R3DU5Byp4e9pcp/a8v74G1n
141 | dgD4S3YlqvJGuU9S6QD4PzsoWD1X8f6pHzxpRP/OkqHAe11sSRo6sSYYCjsYi9Ca
142 | IJSlVC1nMx9OUxxAA8ZqtnztOo7GZcJ5NAL5X3GNV6YfQ7Bqxvtr6QG26F06MB6i
143 | p08UC7NC0bxFsD3f07wY22QnbnM052rniTn5sqQZv+GVls6t1b3u1iHzEjAjlgvi
144 | eOjVVt/A8iaOzMbKC/3+SZ9/GYqbSAQOCIoWAXmhV9IaMQyQeLCIC1YD5NMGBXal
145 | HPfSHV0hSUDbKjAYXFigJRzFU125bXTgg+v13Kd0KklIEjoaZYZLAYs0BupXdjBf
146 | jSPv8pwUaXJkv9/bGH0Ot1fvwDqPDOlGFINQbGAWdxwsdhiYBeXMFeFNTEfiqEMz
147 | BhhMxKa+Mfd9fkrX4NNigGW5QgRBS+FHNLf6ZfiXSnBGjjxMcbI=
148 | =UUA0
149 | -----END PGP SIGNATURE-----
150 |
--------------------------------------------------------------------------------
/Scripts/cstyle.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python -tt
2 | #
3 | # Copyright (C) 2005-2012 Erik de Castro Lopo
4 | #
5 | # Released under the 2 clause BSD license.
6 |
7 | """
8 | This program checks C code for compliance to coding standards used in
9 | libsndfile and other projects I run.
10 | """
11 |
12 | import re
13 | import sys
14 |
15 |
16 | class Preprocessor:
17 | """
18 | Preprocess lines of C code to make it easier for the CStyleChecker class to
19 | test for correctness. Preprocessing works on a single line at a time but
20 | maintains state between consecutive lines so it can preprocessess multi-line
21 | comments.
22 | Preprocessing involves:
23 | - Strip C++ style comments from a line.
24 | - Strip C comments from a series of lines. When a C comment starts and
25 | ends on the same line it will be replaced with 'comment'.
26 | - Replace arbitrary C strings with the zero length string.
27 | - Replace '#define f(x)' with '#define f (c)' (The C #define requires that
28 | there be no space between defined macro name and the open paren of the
29 | argument list).
30 | Used by the CStyleChecker class.
31 | """
32 | def __init__ (self):
33 | self.comment_nest = 0
34 | self.leading_space_re = re.compile ('^(\t+| )')
35 | self.trailing_space_re = re.compile ('(\t+| )$')
36 | self.define_hack_re = re.compile ("(#\s*define\s+[a-zA-Z0-9_]+)\(")
37 |
38 | def comment_nesting (self):
39 | """
40 | Return the currect comment nesting. At the start and end of the file,
41 | this value should be zero. Inside C comments it should be 1 or
42 | (possibly) more.
43 | """
44 | return self.comment_nest
45 |
46 | def __call__ (self, line):
47 | """
48 | Strip the provided line of C and C++ comments. Stripping of multi-line
49 | C comments works as expected.
50 | """
51 |
52 | line = self.define_hack_re.sub (r'\1 (', line)
53 |
54 | line = self.process_strings (line)
55 |
56 | # Strip C++ style comments.
57 | if self.comment_nest == 0:
58 | line = re.sub ("( |\t*)//.*", '', line)
59 |
60 | # Strip C style comments.
61 | open_comment = line.find ('/*')
62 | close_comment = line.find ('*/')
63 |
64 | if self.comment_nest > 0 and close_comment < 0:
65 | # Inside a comment block that does not close on this line.
66 | return ""
67 |
68 | if open_comment >= 0 and close_comment < 0:
69 | # A comment begins on this line but doesn't close on this line.
70 | self.comment_nest += 1
71 | return self.trailing_space_re.sub ('', line [:open_comment])
72 |
73 | if open_comment < 0 and close_comment >= 0:
74 | # Currently open comment ends on this line.
75 | self.comment_nest -= 1
76 | return self.trailing_space_re.sub ('', line [close_comment + 2:])
77 |
78 | if open_comment >= 0 and close_comment > 0 and self.comment_nest == 0:
79 | # Comment begins and ends on this line. Replace it with 'comment'
80 | # so we don't need to check whitespace before and after the comment
81 | # we're removing.
82 | newline = line [:open_comment] + "comment" + line [close_comment + 2:]
83 | return self.__call__ (newline)
84 |
85 | return line
86 |
87 | def process_strings (self, line):
88 | """
89 | Given a line of C code, return a string where all literal C strings have
90 | been replaced with the empty string literal "".
91 | """
92 | for k in range (0, len (line)):
93 | if line [k] == '"':
94 | start = k
95 | for k in range (start + 1, len (line)):
96 | if line [k] == '"' and line [k - 1] != '\\':
97 | return line [:start + 1] + '"' + self.process_strings (line [k + 1:])
98 | return line
99 |
100 |
101 | class CStyleChecker:
102 | """
103 | A class for checking the whitespace and layout of a C code.
104 | """
105 | def __init__ (self, debug):
106 | self.debug = debug
107 | self.filename = None
108 | self.error_count = 0
109 | self.line_num = 1
110 | self.orig_line = ''
111 | self.trailing_newline_re = re.compile ('[\r\n]+$')
112 | self.indent_re = re.compile ("^\s*")
113 | self.last_line_indent = ""
114 | self.last_line_indent_curly = False
115 | self.re_checks = \
116 | [ ( re.compile (" "), "multiple space instead of tab" )
117 | , ( re.compile ("\t "), "space after tab" )
118 | , ( re.compile ("[^ ];"), "missing space before semi-colon" )
119 | , ( re.compile ("{[^\s]"), "missing space after open brace" )
120 | , ( re.compile ("[^\s]}"), "missing space before close brace" )
121 | , ( re.compile ("[ \t]+$"), "contains trailing whitespace" )
122 |
123 | , ( re.compile (",[^\s\n]"), "missing space after comma" )
124 | , ( re.compile (";[a-zA-Z0-9]"), "missing space after semi-colon" )
125 | , ( re.compile ("=[^\s\"'=]"), "missing space after assignment" )
126 |
127 | # Open and close parenthesis.
128 | , ( re.compile ("[^\s\(\[\*&']\("), "missing space before open parenthesis" )
129 | , ( re.compile ("\)(-[^>]|[^,'\s\n\)\]-])"), "missing space after close parenthesis" )
130 | , ( re.compile ("\s(do|for|if|when)\s.*{$"), "trailing open parenthesis at end of line" )
131 | , ( re.compile ("\( [^;]"), "space after open parenthesis" )
132 | , ( re.compile ("[^;] \)"), "space before close parenthesis" )
133 |
134 | # Open and close square brace.
135 | , ( re.compile ("[^\s\(\]]\["), "missing space before open square brace" )
136 | , ( re.compile ("\][^,\)\]\[\s\.-]"), "missing space after close square brace" )
137 | , ( re.compile ("\[ "), "space after open square brace" )
138 | , ( re.compile (" \]"), "space before close square brace" )
139 |
140 | # Space around operators.
141 | , ( re.compile ("[^\s][\*/%+-][=][^\s]"), "missing space around opassign" )
142 | , ( re.compile ("[^\s][<>!=^/][=]{1,2}[^\s]"), "missing space around comparison" )
143 |
144 | # Parens around single argument to return.
145 | , ( re.compile ("\s+return\s+\([a-zA-Z0-9_]+\)\s+;"), "parens around return value" )
146 | ]
147 |
148 | def get_error_count (self):
149 | """
150 | Return the current error count for this CStyleChecker object.
151 | """
152 | return self.error_count
153 |
154 | def check_files (self, files):
155 | """
156 | Run the style checker on all the specified files.
157 | """
158 | for filename in files:
159 | self.check_file (filename)
160 |
161 | def check_file (self, filename):
162 | """
163 | Run the style checker on the specified file.
164 | """
165 | self.filename = filename
166 | try:
167 | cfile = open (filename, "r")
168 | except IOError as e:
169 | return
170 |
171 | self.line_num = 1
172 |
173 | preprocess = Preprocessor ()
174 | while 1:
175 | line = cfile.readline ()
176 | if not line:
177 | break
178 |
179 | line = self.trailing_newline_re.sub ('', line)
180 | self.orig_line = line
181 |
182 | self.line_checks (preprocess (line))
183 |
184 | self.line_num += 1
185 |
186 | cfile.close ()
187 | self.filename = None
188 |
189 | # Check for errors finding comments.
190 | if preprocess.comment_nesting () != 0:
191 | print ("Weird, comments nested incorrectly.")
192 | sys.exit (1)
193 |
194 | return
195 |
196 | def line_checks (self, line):
197 | """
198 | Run the style checker on provided line of text, but within the context
199 | of how the line fits within the file.
200 | """
201 |
202 | indent = len (self.indent_re.search (line).group ())
203 | if re.search ("^\s+}", line):
204 | if not self.last_line_indent_curly and indent != self.last_line_indent:
205 | None # self.error ("bad indent on close curly brace")
206 | self.last_line_indent_curly = True
207 | else:
208 | self.last_line_indent_curly = False
209 |
210 | # Now all the regex checks.
211 | for (check_re, msg) in self.re_checks:
212 | if check_re.search (line):
213 | self.error (msg)
214 |
215 | if re.search ("[a-zA-Z0-9][<>!=^/&\|]{1,2}[a-zA-Z0-9]", line):
216 | if not re.search (".*#include.*[a-zA-Z0-9]/[a-zA-Z]", line):
217 | self.error ("missing space around operator")
218 |
219 | self.last_line_indent = indent
220 | return
221 |
222 | def error (self, msg):
223 | """
224 | Print an error message and increment the error count.
225 | """
226 | print ("%s (%d) : %s" % (self.filename, self.line_num, msg))
227 | if self.debug:
228 | print ("'" + self.orig_line + "'")
229 | self.error_count += 1
230 |
231 | #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
232 |
233 | if len (sys.argv) < 1:
234 | print ("Usage : yada yada")
235 | sys.exit (1)
236 |
237 | # Create a new CStyleChecker object
238 | if sys.argv [1] == '-d' or sys.argv [1] == '--debug':
239 | cstyle = CStyleChecker (True)
240 | cstyle.check_files (sys.argv [2:])
241 | else:
242 | cstyle = CStyleChecker (False)
243 | cstyle.check_files (sys.argv [1:])
244 |
245 |
246 | if cstyle.get_error_count ():
247 | sys.exit (1)
248 |
249 | sys.exit (0)
250 |
--------------------------------------------------------------------------------
/src/generate-chirp.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (C) 2007-2015 Erik de Castro Lopo
3 | **
4 | ** This program is free software: you can redistribute it and/or modify
5 | ** it under the terms of the GNU General Public License as published by
6 | ** the Free Software Foundation, either version 2 or version 3 of the
7 | ** License.
8 | **
9 | ** This program is distributed in the hope that it will be useful,
10 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | ** GNU General Public License for more details.
13 | **
14 | ** You should have received a copy of the GNU General Public License
15 | ** along with this program. If not, see .
16 | */
17 |
18 | /* Generate a sound file containing a chirp */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 |
25 | #include "common.h"
26 |
27 | #include
28 |
29 | typedef double (*freq_func_t) (double w0, double w1, double total_length) ;
30 |
31 | typedef struct
32 | { double amplitude ;
33 | int samplerate, format ;
34 | double start_freq, end_freq, seconds ;
35 | freq_func_t sweep_func ;
36 | } PARAMS ;
37 |
38 | static void usage_exit (const char * argv0) ;
39 | static void check_int_range (const char * name, int value, int lower, int upper) ;
40 | static void check_double_range (const char * name, double value, double lower, double upper) ;
41 | static freq_func_t parse_sweep_type (const char * name) ;
42 | static int guess_major_format (const char * filename) ;
43 | static void generate_file (const char * filename, const PARAMS * params) ;
44 |
45 |
46 | int
47 | main (int argc, char * argv [])
48 | {
49 | PARAMS params = { 1.0, -1, -1, 0, 0, 0, NULL } ;
50 | const char * filename ;
51 | int k ;
52 |
53 | if (argc < 4)
54 | usage_exit (argv [0]) ;
55 |
56 | for (k = 1 ; k < argc - 3 ; k++)
57 | { if (strcmp (argv [k], "-from") == 0)
58 | { k++ ;
59 | params.start_freq = parse_double_or_die (argv [k], "from frequency") ;
60 | continue ;
61 | } ;
62 | if (strcmp (argv [k], "-to") == 0)
63 | { k++ ;
64 | params.end_freq = parse_double_or_die (argv [k], "to frequency") ;
65 | continue ;
66 | } ;
67 | if (strcmp (argv [k], "-amp") == 0)
68 | { k++ ;
69 | params.amplitude = strtod (argv [k], NULL) ;
70 | continue ;
71 | } ;
72 |
73 | if (argv [k][0] == '-')
74 | { params.sweep_func = parse_sweep_type (argv [k]) ;
75 | continue ;
76 | } ;
77 |
78 | printf ("\nUnknown option '%s'.\n\n", argv [k]) ;
79 | exit (1) ;
80 | } ;
81 |
82 | params.samplerate = parse_int_or_die (argv [argc - 3], "sample rate") ;
83 | params.seconds = parse_double_or_die (argv [argc - 2], "seconds") ;
84 | filename = argv [argc - 1] ;
85 |
86 | check_int_range ("sample rate", params.samplerate, 1000, 200 * 1000) ;
87 | check_double_range ("seconds", params.seconds, 0.1, 100.0) ;
88 |
89 | if (params.sweep_func == NULL)
90 | params.sweep_func = parse_sweep_type ("-log") ;
91 | if (params.start_freq <= 0.0)
92 | params.start_freq = 100.0 ;
93 | if (params.end_freq <= 0.0)
94 | params.end_freq = params.samplerate / 2.0 - 100.0 ;
95 |
96 | if (params.end_freq <= params.start_freq)
97 | { printf ("\nError : end frequency %g < start frequency %g.\n\n", params.end_freq, params.start_freq) ;
98 | exit (1) ;
99 | } ;
100 |
101 | params.format = guess_major_format (filename) | SF_FORMAT_FLOAT ;
102 |
103 | generate_file (filename, ¶ms) ;
104 |
105 | return 0 ;
106 | } /* main */
107 |
108 | /*==============================================================================
109 | */
110 |
111 | static void
112 | usage_exit (const char * argv0)
113 | {
114 | const char * progname ;
115 |
116 | progname = strrchr (argv0, '/') ;
117 | progname = (progname == NULL) ? argv0 : progname + 1 ;
118 |
119 | puts ("\nCreate a sound file containing a swept sine wave (ie a chirp).") ;
120 |
121 | printf ("\nUsage :\n\n %s [options] \n\n", progname) ;
122 |
123 | puts (
124 | " Options include:\n\n"
125 | " -from Sweep start frequency in Hz (default 200Hz).\n"
126 | " -to Sweep end frequency in Hz (default fs/2).\n"
127 | " -amp Amplitude of generated sine (default 1.0).\n"
128 | " One of (default -log):\n"
129 | " -log logarithmic sweep\n"
130 | " -quad quadratic sweep\n"
131 | " -linear linear sweep\n"
132 | "\n"
133 | " The parameter can be a decimal like 1.5.\n"
134 | ) ;
135 |
136 | puts (
137 | " The output file will contain floating point samples in the range [-1.0, 1.0].\n"
138 | " The output file type is determined by the file name extension which should be one\n"
139 | " of 'wav', 'aifc', 'aif', 'aiff', 'au', 'caf' and 'w64'.\n"
140 | ) ;
141 |
142 | exit (0) ;
143 | } /* usage_exit */
144 |
145 | static void
146 | check_int_range (const char * name, int value, int lower, int upper)
147 | {
148 | if (value < lower || value > upper)
149 | { printf ("Error : '%s' parameter must be in range [%d, %d]\n", name, lower, upper) ;
150 | exit (1) ;
151 | } ;
152 | } /* check_int_range */
153 |
154 | static void
155 | check_double_range (const char * name, double value, double lower, double upper)
156 | {
157 | if (value < lower || value > upper)
158 | { printf ("Error : '%s' parameter must be in range [%.1f, %.1f]\n", name, lower, upper) ;
159 | exit (1) ;
160 | } ;
161 | } /* check_double_range */
162 |
163 | static void
164 | write_chirp (SNDFILE * file, int samplerate, double seconds, double amp, double w0, double w1, freq_func_t sweep_func)
165 | {
166 | double instantaneous_w, current_phase ;
167 | float * data ;
168 | int total_samples, k ;
169 |
170 | total_samples = lrint (seconds * samplerate) ;
171 |
172 | data = malloc (total_samples * sizeof (data [0])) ;
173 | if (data == NULL)
174 | { printf ("\nError : malloc failed : %s\n", strerror (errno)) ;
175 | exit (1) ;
176 | } ;
177 |
178 | current_phase = 0.0 ;
179 | instantaneous_w = w0 ;
180 |
181 | printf ("Start frequency : %8.1f Hz (%f rad/sec)\n", instantaneous_w * samplerate / (2.0 * M_PI), instantaneous_w) ;
182 |
183 | for (k = 0 ; k < total_samples ; k++)
184 | { data [k] = amp * sin (current_phase) ;
185 |
186 | instantaneous_w = sweep_func (w0, w1, (1.0 * k) / total_samples) ;
187 | current_phase = fmod (current_phase + instantaneous_w, 2.0 * M_PI) ;
188 |
189 | } ;
190 |
191 | sf_write_float (file, data, total_samples) ;
192 |
193 | printf ("End frequency : %8.1f Hz (%f rad/sec)\n", instantaneous_w * samplerate / (2.0 * M_PI), instantaneous_w) ;
194 |
195 | free (data) ;
196 | } /* write_chirp */
197 |
198 | static void
199 | generate_file (const char * filename, const PARAMS * params)
200 | {
201 | char buffer [1024] ;
202 | SNDFILE * file ;
203 | SF_INFO info = { } ;
204 | double w0, w1 ;
205 |
206 | info.format = params->format ;
207 | info.samplerate = params->samplerate ;
208 | info.channels = 1 ;
209 |
210 | file = sf_open (filename, SFM_WRITE, &info) ;
211 | if (file == NULL)
212 | { printf ("\nError : Not able to create file named '%s' : %s/\n", filename, sf_strerror (NULL)) ;
213 | exit (1) ;
214 | } ;
215 |
216 | sf_set_string (file, SF_STR_TITLE, "Logarithmic chirp signal") ;
217 |
218 | snprintf (buffer, sizeof (buffer), "start_freq : %g Hz end_freq : %g Hz amplitude : %g", params->start_freq, params->end_freq, params->amplitude) ;
219 | sf_set_string (file, SF_STR_COMMENT, buffer) ;
220 |
221 | sf_set_string (file, SF_STR_SOFTWARE, "sndfile-generate-chirp") ;
222 | sf_set_string (file, SF_STR_COPYRIGHT, "No copyright.") ;
223 |
224 | w0 = 2.0 * M_PI * params->start_freq / params->samplerate ;
225 | w1 = 2.0 * M_PI * params->end_freq / params->samplerate ;
226 |
227 | write_chirp (file, params->samplerate, params->seconds, params->amplitude, w0, w1, params->sweep_func) ;
228 |
229 | sf_close (file) ;
230 | } /* generate_file */
231 |
232 | static double
233 | log_freq_func (double w0, double w1, double indx)
234 | { return pow (10.0, log10 (w0) + (log10 (w1) - log10 (w0)) * indx) ;
235 | } /* log_freq_func */
236 |
237 | static double
238 | quad_freq_func (double w0, double w1, double indx)
239 | { return w0 + (w1 - w0) * indx * indx ;
240 | } /* log_freq_func */
241 |
242 | static double
243 | linear_freq_func (double w0, double w1, double indx)
244 | { return w0 + (w1 - w0) * indx ;
245 | } /* linear_freq_func */
246 |
247 | static freq_func_t
248 | parse_sweep_type (const char * name)
249 | {
250 | if (strcmp (name, "-log") == 0)
251 | return log_freq_func ;
252 | if (strcmp (name, "-quad") == 0)
253 | return quad_freq_func ;
254 | if (strcmp (name, "-linear") == 0)
255 | return linear_freq_func ;
256 |
257 | printf ("\nError : Bad sweep type. Should be one of '-log', '-quad' and '-linear'.\n\n") ;
258 | exit (1) ;
259 | return NULL ;
260 | } /* parse_sweep_type */
261 |
262 | static int
263 | guess_major_format (const char * filename)
264 | {
265 | const char * ext ;
266 |
267 | ext = strrchr (filename, '.') ;
268 | if (ext == NULL)
269 | { printf ("\nError : cannot figure out file type from file name '%s'.\n\n", filename) ;
270 | exit (1) ;
271 | } ;
272 |
273 | if (strcasecmp (ext, ".wav") == 0)
274 | return SF_FORMAT_WAV ;
275 | if (strcasecmp (ext, ".aif") == 0 || strcasecmp (ext, ".aiff") == 0 || strcasecmp (ext, ".aifc") == 0)
276 | return SF_FORMAT_AIFF ;
277 | if (strcasecmp (ext, ".au") == 0)
278 | return SF_FORMAT_AU ;
279 | if (strcasecmp (ext, ".caf") == 0)
280 | return SF_FORMAT_CAF ;
281 | if (strcasecmp (ext, ".w64") == 0)
282 | return SF_FORMAT_W64 ;
283 |
284 | printf ("\nError : Can only generate files with extensions 'wav', 'aifc', 'aiff', 'aif', 'au', 'w64' and 'caf'.\n\n") ;
285 | exit (1) ;
286 | return 0 ;
287 | } /* guess_major_format */
288 |
289 |
--------------------------------------------------------------------------------
/INSTALL:
--------------------------------------------------------------------------------
1 | Installation Instructions
2 | *************************
3 |
4 | Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
5 | Software Foundation, Inc.
6 |
7 | This file is free documentation; the Free Software Foundation gives
8 | unlimited permission to copy, distribute and modify it.
9 |
10 | Basic Installation
11 | ==================
12 |
13 | These are generic installation instructions.
14 |
15 | The `configure' shell script attempts to guess correct values for
16 | various system-dependent variables used during compilation. It uses
17 | those values to create a `Makefile' in each directory of the package.
18 | It may also create one or more `.h' files containing system-dependent
19 | definitions. Finally, it creates a shell script `config.status' that
20 | you can run in the future to recreate the current configuration, and a
21 | file `config.log' containing compiler output (useful mainly for
22 | debugging `configure').
23 |
24 | It can also use an optional file (typically called `config.cache'
25 | and enabled with `--cache-file=config.cache' or simply `-C') that saves
26 | the results of its tests to speed up reconfiguring. (Caching is
27 | disabled by default to prevent problems with accidental use of stale
28 | cache files.)
29 |
30 | If you need to do unusual things to compile the package, please try
31 | to figure out how `configure' could check whether to do them, and mail
32 | diffs or instructions to the address given in the `README' so they can
33 | be considered for the next release. If you are using the cache, and at
34 | some point `config.cache' contains results you don't want to keep, you
35 | may remove or edit it.
36 |
37 | The file `configure.ac' (or `configure.in') is used to create
38 | `configure' by a program called `autoconf'. You only need
39 | `configure.ac' if you want to change it or regenerate `configure' using
40 | a newer version of `autoconf'.
41 |
42 | The simplest way to compile this package is:
43 |
44 | 1. `cd' to the directory containing the package's source code and type
45 | `./configure' to configure the package for your system. If you're
46 | using `csh' on an old version of System V, you might need to type
47 | `sh ./configure' instead to prevent `csh' from trying to execute
48 | `configure' itself.
49 |
50 | Running `configure' takes awhile. While running, it prints some
51 | messages telling which features it is checking for.
52 |
53 | 2. Type `make' to compile the package.
54 |
55 | 3. Optionally, type `make check' to run any self-tests that come with
56 | the package.
57 |
58 | 4. Type `make install' to install the programs and any data files and
59 | documentation.
60 |
61 | 5. You can remove the program binaries and object files from the
62 | source code directory by typing `make clean'. To also remove the
63 | files that `configure' created (so you can compile the package for
64 | a different kind of computer), type `make distclean'. There is
65 | also a `make maintainer-clean' target, but that is intended mainly
66 | for the package's developers. If you use it, you may have to get
67 | all sorts of other programs in order to regenerate files that came
68 | with the distribution.
69 |
70 | Compilers and Options
71 | =====================
72 |
73 | Some systems require unusual options for compilation or linking that the
74 | `configure' script does not know about. Run `./configure --help' for
75 | details on some of the pertinent environment variables.
76 |
77 | You can give `configure' initial values for configuration parameters
78 | by setting variables in the command line or in the environment. Here
79 | is an example:
80 |
81 | ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
82 |
83 | *Note Defining Variables::, for more details.
84 |
85 | Compiling For Multiple Architectures
86 | ====================================
87 |
88 | You can compile the package for more than one kind of computer at the
89 | same time, by placing the object files for each architecture in their
90 | own directory. To do this, you must use a version of `make' that
91 | supports the `VPATH' variable, such as GNU `make'. `cd' to the
92 | directory where you want the object files and executables to go and run
93 | the `configure' script. `configure' automatically checks for the
94 | source code in the directory that `configure' is in and in `..'.
95 |
96 | If you have to use a `make' that does not support the `VPATH'
97 | variable, you have to compile the package for one architecture at a
98 | time in the source code directory. After you have installed the
99 | package for one architecture, use `make distclean' before reconfiguring
100 | for another architecture.
101 |
102 | Installation Names
103 | ==================
104 |
105 | By default, `make install' installs the package's commands under
106 | `/usr/local/bin', include files under `/usr/local/include', etc. You
107 | can specify an installation prefix other than `/usr/local' by giving
108 | `configure' the option `--prefix=PREFIX'.
109 |
110 | You can specify separate installation prefixes for
111 | architecture-specific files and architecture-independent files. If you
112 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses
113 | PREFIX as the prefix for installing programs and libraries.
114 | Documentation and other data files still use the regular prefix.
115 |
116 | In addition, if you use an unusual directory layout you can give
117 | options like `--bindir=DIR' to specify different values for particular
118 | kinds of files. Run `configure --help' for a list of the directories
119 | you can set and what kinds of files go in them.
120 |
121 | If the package supports it, you can cause programs to be installed
122 | with an extra prefix or suffix on their names by giving `configure' the
123 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
124 |
125 | Optional Features
126 | =================
127 |
128 | Some packages pay attention to `--enable-FEATURE' options to
129 | `configure', where FEATURE indicates an optional part of the package.
130 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE
131 | is something like `gnu-as' or `x' (for the X Window System). The
132 | `README' should mention any `--enable-' and `--with-' options that the
133 | package recognizes.
134 |
135 | For packages that use the X Window System, `configure' can usually
136 | find the X include and library files automatically, but if it doesn't,
137 | you can use the `configure' options `--x-includes=DIR' and
138 | `--x-libraries=DIR' to specify their locations.
139 |
140 | Specifying the System Type
141 | ==========================
142 |
143 | There may be some features `configure' cannot figure out automatically,
144 | but needs to determine by the type of machine the package will run on.
145 | Usually, assuming the package is built to be run on the _same_
146 | architectures, `configure' can figure that out, but if it prints a
147 | message saying it cannot guess the machine type, give it the
148 | `--build=TYPE' option. TYPE can either be a short name for the system
149 | type, such as `sun4', or a canonical name which has the form:
150 |
151 | CPU-COMPANY-SYSTEM
152 |
153 | where SYSTEM can have one of these forms:
154 |
155 | OS KERNEL-OS
156 |
157 | See the file `config.sub' for the possible values of each field. If
158 | `config.sub' isn't included in this package, then this package doesn't
159 | need to know the machine type.
160 |
161 | If you are _building_ compiler tools for cross-compiling, you should
162 | use the option `--target=TYPE' to select the type of system they will
163 | produce code for.
164 |
165 | If you want to _use_ a cross compiler, that generates code for a
166 | platform different from the build platform, you should specify the
167 | "host" platform (i.e., that on which the generated programs will
168 | eventually be run) with `--host=TYPE'.
169 |
170 | Sharing Defaults
171 | ================
172 |
173 | If you want to set default values for `configure' scripts to share, you
174 | can create a site shell script called `config.site' that gives default
175 | values for variables like `CC', `cache_file', and `prefix'.
176 | `configure' looks for `PREFIX/share/config.site' if it exists, then
177 | `PREFIX/etc/config.site' if it exists. Or, you can set the
178 | `CONFIG_SITE' environment variable to the location of the site script.
179 | A warning: not all `configure' scripts look for a site script.
180 |
181 | Defining Variables
182 | ==================
183 |
184 | Variables not defined in a site shell script can be set in the
185 | environment passed to `configure'. However, some packages may run
186 | configure again during the build, and the customized values of these
187 | variables may be lost. In order to avoid this problem, you should set
188 | them in the `configure' command line, using `VAR=value'. For example:
189 |
190 | ./configure CC=/usr/local2/bin/gcc
191 |
192 | causes the specified `gcc' to be used as the C compiler (unless it is
193 | overridden in the site shell script). Here is a another example:
194 |
195 | /bin/bash ./configure CONFIG_SHELL=/bin/bash
196 |
197 | Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
198 | configuration-related scripts to be executed by `/bin/bash'.
199 |
200 | `configure' Invocation
201 | ======================
202 |
203 | `configure' recognizes the following options to control how it operates.
204 |
205 | `--help'
206 | `-h'
207 | Print a summary of the options to `configure', and exit.
208 |
209 | `--version'
210 | `-V'
211 | Print the version of Autoconf used to generate the `configure'
212 | script, and exit.
213 |
214 | `--cache-file=FILE'
215 | Enable the cache: use and save the results of the tests in FILE,
216 | traditionally `config.cache'. FILE defaults to `/dev/null' to
217 | disable caching.
218 |
219 | `--config-cache'
220 | `-C'
221 | Alias for `--cache-file=config.cache'.
222 |
223 | `--quiet'
224 | `--silent'
225 | `-q'
226 | Do not print messages saying which checks are being made. To
227 | suppress all normal output, redirect it to `/dev/null' (any error
228 | messages will still be shown).
229 |
230 | `--srcdir=DIR'
231 | Look for the package's source code in directory DIR. Usually
232 | `configure' can determine that directory automatically.
233 |
234 | `configure' also accepts some other, not widely useful, options. Run
235 | `configure --help' for more details.
236 |
237 |
--------------------------------------------------------------------------------
/src/resample.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2002-2020, Erik de Castro Lopo
3 | ** All rights reserved.
4 | **
5 | ** This code is released under 2-clause BSD license. Please see the
6 | ** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING
7 | */
8 |
9 | #include "config.h"
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #include "common.h"
18 |
19 | #include
20 | #include
21 |
22 | #define DEFAULT_CONVERTER SRC_SINC_MEDIUM_QUALITY
23 |
24 | #define BUFFER_LEN 4096 /*-(1<<16)-*/
25 |
26 | static void usage_exit (const char *progname) ;
27 | static sf_count_t sample_rate_convert (SNDFILE *infile, SNDFILE *outfile, int converter, double src_ratio, int channels, double * gain, int normalize, sf_count_t nframes) ;
28 | static double apply_gain (float * data, long frames, int channels, double max, double gain) ;
29 |
30 | int
31 | main (int argc, char *argv [])
32 | { SNDFILE *infile, *outfile = NULL ;
33 | SF_INFO sfinfo = { } ;
34 | sf_count_t nframes ;
35 |
36 | int normalize = 1 ;
37 | sf_count_t count ;
38 | double src_ratio = -1.0, gain = 1.0 ;
39 | int new_sample_rate = -1, k, converter, max_speed = SF_FALSE, raw_bits ;
40 | char raw_type ;
41 |
42 | if (argc == 2 && strcmp (argv [1], "--version") == 0)
43 | { char buffer [64], *cptr ;
44 |
45 | if ((cptr = strrchr (argv [0], '/')) != NULL)
46 | argv [0] = cptr + 1 ;
47 | if ((cptr = strrchr (argv [0], '\\')) != NULL)
48 | argv [0] = cptr + 1 ;
49 |
50 | sf_command (NULL, SFC_GET_LIB_VERSION, buffer, sizeof (buffer)) ;
51 |
52 | printf ("%s (%s,%s)\n", argv [0], src_get_version (), buffer) ;
53 | exit (0) ;
54 | } ;
55 |
56 | if (argc < 5 || argc > 10)
57 | usage_exit (argv [0]) ;
58 |
59 | /* Set default converter. */
60 | converter = DEFAULT_CONVERTER ;
61 |
62 | for (k = 1 ; k < argc - 2 ; k++)
63 | { if (strcmp (argv [k], "--max-speed") == 0)
64 | max_speed = SF_TRUE ;
65 | else if (strcmp (argv [k], "--no-normalize") == 0)
66 | normalize = 0 ;
67 | else if (strcmp (argv [k], "-to") == 0)
68 | { k ++ ;
69 | new_sample_rate = parse_int_or_die (argv [k], "sample rate") ;
70 | }
71 | else if (strcmp (argv [k], "-by") == 0)
72 | { k ++ ;
73 | src_ratio = atof (argv [k]) ;
74 | }
75 | else if (strcmp (argv [k], "-c") == 0)
76 | { k ++ ;
77 | converter = parse_int_or_die (argv [k], "converter") ;
78 | }
79 | else if (strcmp (argv [k], "-r") == 0)
80 | { k ++ ;
81 | if (sscanf (argv [k], "%d,%d,%c,%d", &sfinfo.samplerate, &sfinfo.channels, &raw_type, &raw_bits) != 4)
82 | { printf ("Error : unable to decode raw audio parameters.\n") ;
83 | usage_exit (argv [0]) ;
84 | }
85 | sfinfo.format = SF_FORMAT_RAW ;
86 | if (raw_type == 'i' && (raw_bits == 8 || raw_bits == 16 || raw_bits == 24 || raw_bits == 32))
87 | { switch (raw_bits)
88 | { case 8:
89 | sfinfo.format |= SF_FORMAT_PCM_S8 ;
90 | break ;
91 |
92 | case 16:
93 | sfinfo.format |= SF_FORMAT_PCM_16 ;
94 | break ;
95 |
96 | case 24:
97 | sfinfo.format |= SF_FORMAT_PCM_24 ;
98 | break ;
99 |
100 | case 32:
101 | sfinfo.format |= SF_FORMAT_PCM_32 ;
102 | break ;
103 |
104 | default:
105 | printf ("Error : PCM bits per sample should be 8, 16, 24 or 32.\n") ;
106 | usage_exit (argv [0]) ;
107 | }
108 | }
109 | else if (raw_type == 'f' && (raw_bits == 32 || raw_bits == 64))
110 | { switch (raw_bits)
111 | { case 32:
112 | sfinfo.format |= SF_FORMAT_FLOAT ;
113 | break ;
114 |
115 | case 64:
116 | sfinfo.format |= SF_FORMAT_DOUBLE ;
117 | break ;
118 |
119 | default:
120 | printf ("Error : Floating point bits per sample should be 32 or 64.\n") ;
121 | usage_exit (argv [0]) ;
122 | }
123 | }
124 | else
125 | { printf ("Error : invalid raw audio parameters.\n") ;
126 | usage_exit (argv [0]) ;
127 | }
128 | }
129 | else
130 | usage_exit (argv [0]) ;
131 | } ;
132 |
133 | if (new_sample_rate <= 0 && src_ratio <= 0.0)
134 | usage_exit (argv [0]) ;
135 |
136 | if (src_get_name (converter) == NULL)
137 | { printf ("Error : bad converter number.\n") ;
138 | usage_exit (argv [0]) ;
139 | } ;
140 |
141 | if (strcmp (argv [argc - 2], argv [argc - 1]) == 0)
142 | { printf ("Error : input and output file names are the same.\n") ;
143 | exit (1) ;
144 | } ;
145 |
146 | if ((infile = sf_open (argv [argc - 2], SFM_READ, &sfinfo)) == NULL)
147 | { printf ("Error : Not able to open input file '%s'\n", argv [argc - 2]) ;
148 | exit (1) ;
149 | } ;
150 |
151 | printf ("Input File : %s\n", argv [argc - 2]) ;
152 | printf ("Sample Rate : %d\n", sfinfo.samplerate) ;
153 | printf ("Input Frames : %ld\n\n", (long) sfinfo.frames) ;
154 |
155 | nframes = sfinfo.frames ;
156 |
157 | if (new_sample_rate > 0)
158 | { src_ratio = (1.0 * new_sample_rate) / sfinfo.samplerate ;
159 | sfinfo.samplerate = new_sample_rate ;
160 | }
161 | else if (src_is_valid_ratio (src_ratio))
162 | sfinfo.samplerate = (int) floor (sfinfo.samplerate * src_ratio) ;
163 | else
164 | { printf ("Not able to determine new sample rate. Exiting.\n") ;
165 | sf_close (infile) ;
166 | exit (1) ;
167 | } ;
168 |
169 | if (fabs (src_ratio - 1.0) < 1e-20)
170 | { printf ("Target samplerate and input samplerate are the same. Exiting.\n") ;
171 | sf_close (infile) ;
172 | exit (0) ;
173 | } ;
174 |
175 | printf ("SRC Ratio : %f\n", src_ratio) ;
176 | printf ("Converter : %s\n\n", src_get_name (converter)) ;
177 |
178 | if (src_is_valid_ratio (src_ratio) == 0)
179 | { printf ("Error : Sample rate change out of valid range.\n") ;
180 | sf_close (infile) ;
181 | exit (1) ;
182 | } ;
183 |
184 | /* Delete the output file length to zero if already exists. */
185 | remove (argv [argc - 1]) ;
186 |
187 | printf ("Output File : %s\n", argv [argc - 1]) ;
188 | printf ("Sample Rate : %d\n", sfinfo.samplerate) ;
189 |
190 | do
191 | { sf_close (outfile) ;
192 |
193 | if ((outfile = sf_open (argv [argc - 1], SFM_WRITE, &sfinfo)) == NULL)
194 | { printf ("Error : Not able to open output file '%s'\n", argv [argc - 1]) ;
195 | sf_close (infile) ;
196 | exit (1) ;
197 | } ;
198 |
199 | if (max_speed)
200 | { /* This is mainly for the comparison program tests/src-evaluate.c */
201 | sf_command (outfile, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_FALSE) ;
202 | }
203 | else
204 | { /* Update the file header after every write. */
205 | sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
206 | } ;
207 |
208 | sf_command (outfile, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
209 |
210 | count = sample_rate_convert (infile, outfile, converter, src_ratio, sfinfo.channels, &gain, normalize, nframes) ;
211 | }
212 | while (count < 0) ;
213 |
214 | printf ("Output Frames : %ld\n\n", (long) count) ;
215 |
216 | sf_close (infile) ;
217 | sf_close (outfile) ;
218 |
219 | return 0 ;
220 | } /* main */
221 |
222 | /*==============================================================================
223 | */
224 |
225 | static sf_count_t
226 | sample_rate_convert (SNDFILE *infile, SNDFILE *outfile, int converter, double src_ratio, int channels, double * gain, int normalize, sf_count_t nframes)
227 | { static float input [BUFFER_LEN] ;
228 | static float output [BUFFER_LEN] ;
229 |
230 | SRC_STATE *src_state ;
231 | SRC_DATA src_data ;
232 | int error ;
233 | double max = 0.0 ;
234 | sf_count_t output_count = 0 ;
235 |
236 | char anim [4] = "-\\|/" ;
237 | short p_anim = 0 ;
238 |
239 | sf_seek (infile, 0, SEEK_SET) ;
240 | sf_seek (outfile, 0, SEEK_SET) ;
241 |
242 | /* Initialize the sample rate converter. */
243 | if ((src_state = src_new (converter, channels, &error)) == NULL)
244 | { printf ("\n\nError : src_new() failed : %s.\n\n", src_strerror (error)) ;
245 | exit (1) ;
246 | } ;
247 |
248 | src_data.end_of_input = 0 ; /* Set this later. */
249 |
250 | /* Start with zero to force load in while loop. */
251 | src_data.input_frames = 0 ;
252 | src_data.data_in = input ;
253 |
254 | src_data.src_ratio = src_ratio ;
255 |
256 | src_data.data_out = output ;
257 | src_data.output_frames = BUFFER_LEN /channels ;
258 |
259 | while (1)
260 | {
261 | /* If the input buffer is empty, refill it. */
262 | if (src_data.input_frames == 0)
263 | { src_data.input_frames = sf_readf_float (infile, input, BUFFER_LEN / channels) ;
264 | src_data.data_in = input ;
265 |
266 | /* The last read will not be a full buffer, so snd_of_input. */
267 | if (src_data.input_frames < BUFFER_LEN / channels)
268 | src_data.end_of_input = SF_TRUE ;
269 | } ;
270 |
271 | if ((error = src_process (src_state, &src_data)))
272 | { printf ("\nError : %s\n", src_strerror (error)) ;
273 | exit (1) ;
274 | } ;
275 |
276 | /* Terminate if done. */
277 | if (src_data.end_of_input && src_data.output_frames_gen == 0)
278 | break ;
279 |
280 | max = apply_gain (src_data.data_out, src_data.output_frames_gen, channels, max, *gain) ;
281 |
282 | /* Write output. */
283 | sf_writef_float (outfile, output, src_data.output_frames_gen) ;
284 | output_count += src_data.output_frames_gen ;
285 |
286 | src_data.data_in += src_data.input_frames_used * channels ;
287 | src_data.input_frames -= src_data.input_frames_used ;
288 | nframes -= src_data.input_frames_used ;
289 | printf (" %c remaining : %19lld\r", anim [p_anim], (long long int) nframes) ;
290 | p_anim = (p_anim + 1) % 4 ;
291 | } ;
292 | printf ("\n") ;
293 |
294 | src_delete (src_state) ;
295 |
296 | if (normalize && max > 1.0)
297 | { *gain = 1.0 / max ;
298 | printf ("\nOutput has clipped. Restarting conversion to prevent clipping.\n\n") ;
299 | return -1 ;
300 | } ;
301 |
302 | return output_count ;
303 | } /* sample_rate_convert */
304 |
305 | static double
306 | apply_gain (float * data, long frames, int channels, double max, double gain)
307 | {
308 | long k ;
309 |
310 | for (k = 0 ; k < frames * channels ; k++)
311 | { data [k] *= gain ;
312 |
313 | if (fabs (data [k]) > max)
314 | max = fabs (data [k]) ;
315 | } ;
316 |
317 | return max ;
318 | } /* apply_gain */
319 |
320 | static void
321 | usage_exit (const char *progname)
322 | { char lsf_ver [128] ;
323 | const char *cptr ;
324 | int k ;
325 |
326 | if ((cptr = strrchr (progname, '/')) != NULL)
327 | progname = cptr + 1 ;
328 |
329 | if ((cptr = strrchr (progname, '\\')) != NULL)
330 | progname = cptr + 1 ;
331 |
332 |
333 | sf_command (NULL, SFC_GET_LIB_VERSION, lsf_ver, sizeof (lsf_ver)) ;
334 |
335 | printf ("\n"
336 | " A Sample Rate Converter using libsndfile for file I/O and Secret \n"
337 | " Rabbit Code (aka libsamplerate) for performing the conversion.\n"
338 | " It works on any file format supported by libsndfile with any \n"
339 | " number of channels (limited only by host memory).\n"
340 | "\n"
341 | " %s\n"
342 | " %s\n"
343 | "\n"
344 | " Usage : \n"
345 | " %s -to [-c ]