diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..6afa6198 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +# Binary test data files - prevent CRLF corruption +src/unsup/test_data/cftest1.dat binary + +# Shell scripts must use LF +*.sh text eol=lf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db054c2f..d016c134 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: push: branches: [dev, main, STL_2026_itu_submission] pull_request: - branches: [dev, main] + branches: [dev, main, STL_2026_itu_submission] jobs: build-and-test: @@ -58,7 +58,7 @@ jobs: run: | # Exclude build directory from Windows Defender to avoid scan delays powershell -Command "Add-MpPreference -ExclusionPath '${{ github.workspace }}'" - cmake . + cmake . -DCMAKE_C_FLAGS="/we4700" - name: Build (Unix) if: runner.os != 'Windows' diff --git a/.gitignore b/.gitignore index 9a028291..ebc849df 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ *.tmp [Bb]in/ -# Generated test files +# Generated test output files *05g10.* *.[am]16 *.[am]24 @@ -47,8 +47,6 @@ src/is54/test_data/voice.bec src/is54/test_data/voice.hbs !src/is54/test_data/voice.log src/is54/test_data/voice.rek -src/sv56/test_data/voice.prc -src/sv56/test_data/voice.rms src/unsup/test_data/astrip.blk src/unsup/test_data/undo.txt src/utl/test_data/voice.rnp @@ -97,3 +95,8 @@ bld/ .vs/ *vcxproj* *.sln* +.vscode/ +/build +*.double +stderr.txt +stdout.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index cbd02f45..c6f06c16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ -cmake_minimum_required(VERSION 3.1) -project(STL2023 VERSION 2023) -add_definitions( -DVERSION_STL="${CMAKE_PROJECT_NAME}" ) +cmake_minimum_required(VERSION 3.10...3.31) +project(STL2026 VERSION 2026) + +add_definitions( -DVERSION_STL="${CMAKE_PROJECT_NAME}" -DCMAKE_POLICY_VERSION_MINIMUM=3.5 ) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) @@ -24,6 +25,7 @@ add_subdirectory(src/eid) add_subdirectory(src/esdru) add_subdirectory(src/fir) add_subdirectory(src/freqresp) +add_subdirectory(src/gain_chk) add_subdirectory(src/g711) add_subdirectory(src/g711iplc) add_subdirectory(src/g722) diff --git a/README.md b/README.md index 006b0732..70e0f127 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ README for the _ITU-T Software Tool Library_ (STL) === -The STL provides software for speech- and audio-related speech processing, including narrowband (telephony), wideband ans super-wideband applications. +The STL provides software for speech- and audio-related speech processing, including narrowband (telephony), wideband and super-wideband applications. This includes codecs, noise generators, filter, etc. The STL is standardized by ITU-T in [Recommendation ITU-T G.191 "Software tools for speech and audio coding standardization"](http://itu.int/ITU-T/G.191). @@ -18,6 +18,8 @@ To build the STL tools, you need: Not so recent C compilers might also work (not tested). +## Linux / macOS + ```shell #Download source code git clone https://github.com/openitu/STL @@ -26,16 +28,40 @@ git clone https://github.com/openitu/STL cd STL #Generate platform dependent build scripts using CMake -#For using a specific generator see CMake parameter "-G" cmake . -##Build STL tools +#Build STL tools cmake --build . -##Run tests (optional) +#Run tests (optional) ctest ``` +## Windows + +Prerequisites: +* Visual Studio with the **"Desktop development with C++"** workload installed +* CMake (included with Visual Studio, or install separately) + +```powershell +#Download source code +git clone https://github.com/openitu/STL + +#Enter directory +cd STL + +#Generate Visual Studio project files (adjust version as needed) +cmake -G "Visual Studio 18 2026" . + +#Build STL tools +cmake --build . --config Release + +#Run tests (optional) +ctest -C Release +``` + +> **Note:** On Windows, you must specify a configuration (`Release` or `Debug`) for both the build and test steps. + # Licenses The STL, and all of its derivations, is subject to the "ITU-T General Public License", which is a modified version of the GPL1. Please read the file `LICENSE.md` for the terms and conditions. @@ -57,13 +83,12 @@ The primary audience using, maintaining and extending the STL is primarily const We distinguish between (1) the STL code development in the open source environment, and (2) the maintenance and update of Recommendation ITU-T G.191 in the standardization environment. ## Open source environment (GitHub): -* It follows the best practices for open source code development +* It follows the best practices for open source code development. * Participation is open and encouraged to anyone interested in the development of the STL, independent of ITU membership. -* The open source environment will have three branches of the STL: - 1. Master branch — the latest ITU-T approved version of the STL (starting with STL2009); - 2. Development branch — to advance the STL code and add new features; and - 3. Submission branch — to submit new stable code to SG12. -* Proposals submitted to the development branch document motivation and intended merits. +* The repository uses a single long-lived branch: + * **`main`** — the latest version of the STL, updated upon ITU-T approval. + * **Feature/fix branches** — short-lived branches for new tools or changes, merged via pull requests. +* Approved versions are marked with git tags (e.g., `STL2024`, `STL2026`). * Any tools in the library should satisfy the principles outlined in clauses 2.3 and 2.4 of the G.191: ITU-T Software Tool Library 2009 User's manual, in particular with respect to testing of portability and compliance. * New tools: * should not overlap in functionality provided by other tools already in the library, unless there is community consensus on the benefits of such approach; @@ -73,11 +98,10 @@ We distinguish between (1) the STL code development in the open source environme * Changes to existing tools: * should provide sufficient evidence that the changes do not break existing code (in particular, backward compatibility), unless there is community consensus that this is the best approach; * should respect the license of the tool. - * The development branch is used for discussion and consensus building on a stable version, for inclusion in the submission branch. ## Standardization environment ([ITU-T Study Group 12](https://itu.int/go/tsg12)): * Participation is limited to those who can participate in the standardization work in ITU-T SG12. * The Editor of ITU-T G.191 monitors the change process in the open source environment. -* Upon availability of sufficient stable material in the submission branch, the Editor of ITU-T G.191 submits a TD to Q2/12 summarizing the proposed changes and related discussion, and provides a snapshot of the submission branch as basis for a revised version of ITU-T G.191. +* Upon availability of sufficient stable material, the Editor of ITU-T G.191 opens a pull request against `main`, submits a TD to Q2/12 summarizing the proposed changes, and provides the PR as basis for a revised version of ITU-T G.191. * The TD is considered by Q2/12, and action is taken following the alternative approval procedure (AAP) for ITU-T Recommendations. -* The Editor of ITU-T G.191 provides feedback on the actions taken to the developers in the open source environment, and, upon approval of a revised version of G.191, updates the master branch of the open source environment. +* The Editor of ITU-T G.191 provides feedback on the actions taken to the developers in the open source environment, and, upon approval of a revised version of G.191, merges the PR into `main` and tags the release. diff --git a/cmake/CompareTextFiles.cmake b/cmake/CompareTextFiles.cmake new file mode 100644 index 00000000..562ca046 --- /dev/null +++ b/cmake/CompareTextFiles.cmake @@ -0,0 +1,25 @@ +# cmake/CompareTextFiles.cmake +# Compare two text files, ignoring line-ending differences (CRLF vs LF). +# +# Usage (from a -P script): +# include(/path/to/CompareTextFiles.cmake) +# compare_text_files(GOT EXPECTED [LABEL ]) + +function(compare_text_files) + cmake_parse_arguments(_CTF "" "GOT;EXPECTED;LABEL" "" ${ARGN}) + + file(READ "${_CTF_GOT}" _got) + string(REPLACE "\r\n" "\n" _got "${_got}") + + file(READ "${_CTF_EXPECTED}" _want) + string(REPLACE "\r\n" "\n" _want "${_want}") + + if(NOT _got STREQUAL _want) + message(FATAL_ERROR "Text file mismatch: ${_CTF_LABEL}\n--- got ---\n${_got}\n--- expected ---\n${_want}") + endif() +endfunction() + +# Auto-invoke when called via cmake -P with -D variables +if(DEFINED GOT AND DEFINED EXPECTED) + compare_text_files(GOT "${GOT}" EXPECTED "${EXPECTED}" LABEL "${LABEL}") +endif() diff --git a/doc/g191.md b/doc/g191.md index 58cab3b7..67e27295 100644 --- a/doc/g191.md +++ b/doc/g191.md @@ -12,27 +12,27 @@ Please refer to the official Recommendation ITU-T G.191 for the complete text: [ Recommendation ITU-T G.191 provides source code for speech and audio processing modules for narrowband, wideband and super-wideband telephony applications. The set includes codecs, filters, noise generators. -This edition introduces changes to Annex A, which describes the ITU-T Software Tools (STL) containing a high-quality, portable C code library for speech processing applications. This release of the STL, also known as STL2024, incorporates: +This edition introduces changes to Annex A, which describes the ITU-T Software Tools (STL) containing a high-quality, portable C code library for speech processing applications. This release of the STL, also known as STL2026, incorporates: -* BS1770demo improvements: +* WAV file I/O support with multi-bit-depth (16/24/32-bit) processing for all tools - - a new RMS option disabling the gating function for background noise measurement, +* Extensions to the speech voltmeter (sv56) for arbitrary bit-depth processing - - the handling of the edge case where all gating blacks are below -70 LKFS, +* A delay-and-error profile to frame-erasure pattern conversion tool (dlyerr\_2\_errpat) for jitter buffer emulation (3GPP S4-121077) - - improved reporting with scaling factor being reported in the linear and log domains. +* An EID for 3GPP AMR bitstreams (eid-amr) -* WMC Tool updates: +* A pseudo-random selection tool (random) for EVS processing scripts (3GPP S4-121078) - - New command line parameter to allow control on the number of frames per second (default still 50) +* SHQ2/SHQ3 half-band and HP50 high-pass FIR filters - - Export information on all memory allocations occurring during runtime - - - Example script for graphical analysis and profiling of dymanic memory allocation +* P.863/P.863.2 resampling FIR filters for rate-change factors 2, 3, 4 and 6 (as published in ETSI TR 103 138) - - Bugs fixes and code improvements +* A per-band gain verification tool (gain\_chk) for codec and speech-processing validation -Recommendation ITU-T G.191 includes an electronic attachment containing STL2024 and manual. +* Cross-platform portability fixes with expanded CTest regression coverage + +Recommendation ITU-T G.191 includes an electronic attachment containing STL2026 and manual. ## Keywords diff --git a/doc/g191_Annex_A.md b/doc/g191_Annex_A.md index 68ea05c1..a31f70d2 100644 --- a/doc/g191_Annex_A.md +++ b/doc/g191_Annex_A.md @@ -40,6 +40,10 @@ The following programs are examples of the use of the modules: | `stereoop.c` | on the use of stereo file operations. | | `esdru.c` | on the use of energy-based spatial distortion reference unit [ITU-T P.811]. | | `wmc_tool.cpp` | on the use of WMC tool for speech and audio codecs complexity and memory measurement. | +| `dlyerr_2_errpat.c` | on the use of the delay/error profile to frame-erasure pattern conversion tool for jitter buffer emulation. | +| `eid-amr.c` | on the use of the EID for 3GPP AMR codec frame erasure simulation using G.192 error patterns. | +| `random.c` | on the use of the pseudo-random selection tool for deterministic item selection or range drawing. | +| `gain_chk.c` | on the use of the per-band gain verification tool for codec and speech-processing validation. | || @@ -85,6 +89,20 @@ The functions included are as follows: | `LP12_48kHz_init` | initialize a low-pass filter with a cut-off frequency of 12 kHz at (48-kHz sampling). | | `LP14_48kHz_init` | initialize a low-pass filter with a cut-off frequency of 14 kHz at 48-kHz sampling). | | `LP20_48kHz_init` | initialize a low-pass filter with a cut-off frequency of 20 kHz (48-kHz sampling). | +| `shq_up_1_to_2_init` | initialize 1:2 SHQ half-band up-sampling filter. | +| `shq_up_1_to_3_init` | initialize 1:3 SHQ up-sampling filter. | +| `shq_down_2_to_1_init` | initialize 2:1 SHQ half-band down-sampling filter. | +| `shq_down_3_to_1_init` | initialize 3:1 SHQ down-sampling filter. | +| `hp50_32khz_init` | initialize 50-Hz high-pass filter (32-kHz sampling). | +| `hp50_48khz_init` | initialize 50-Hz high-pass filter (48-kHz sampling). | +| `p863_up_1_to_2_init` | initialize P.863/P.863.2 resampling 1:2 up-sampling filter (256 taps). | +| `p863_down_2_to_1_init` | initialize P.863/P.863.2 resampling 2:1 down-sampling filter (256 taps). | +| `p863_up_1_to_3_init` | initialize P.863/P.863.2 resampling 1:3 up-sampling filter (384 taps). | +| `p863_down_3_to_1_init` | initialize P.863/P.863.2 resampling 3:1 down-sampling filter (384 taps). | +| `p863_up_1_to_4_init` | initialize P.863/P.863.2 resampling 1:4 up-sampling filter (512 taps). | +| `p863_down_4_to_1_init` | initialize P.863/P.863.2 resampling 4:1 down-sampling filter (512 taps). | +| `p863_up_1_to_6_init` | initialize P.863/P.863.2 resampling 1:6 up-sampling filter (768 taps). | +| `p863_down_6_to_1_init` | initialize P.863/P.863.2 resampling 6:1 down-sampling filter (768 taps). | | `hq_kernel` | FIR filtering function. | | `hq_reset` | clear state variables. | | `hq_free` | deallocate FIR-filter memory. | @@ -460,14 +478,14 @@ Variable definitions: | `W_mult0_16_16(var1, var2)` | Multiplies 16-bit var1 by 16-bit var2, sign extends to 64 bits and returns the 64 bit result. | | `W_mac0_16_16(W_acc, var1, var2)` | Multiplies 16-bit var1 by 16-bit var2, sign extends to 64 bits; adds this 64 bit value to the 64 bit W_acc without saturation control, and returns a 64 bit result. | | `W_msu0_16_16(W_acc, var1, var2)` | Multiplies 16-bit var1 by 16-bit var2, sign extends to 64 bits; subtracts this 64 bit value from the 64 bit W_acc without saturation control, and returns a 64 bit result. | -| `W_mult_16_16(W_acc, var1, var2)` | Multiplies a signed 16-bit var1 by signed 16-bit var2, shifts the product left by 1 and sign extends to 64-bits without saturation control and returns a 64 bit result.
The operation is performed in fractional mode.
For example, if var1 is in 1Q15 format and var2 is in 1Q15 format, then the result is produced in 33Q31 format. | +| `W_mult_16_16(var1, var2)` | Multiplies a signed 16-bit var1 by signed 16-bit var2, shifts the product left by 1 and sign extends to 64-bits without saturation control and returns a 64 bit result.
The operation is performed in fractional mode.
For example, if var1 is in 1Q15 format and var2 is in 1Q15 format, then the result is produced in 33Q31 format. | | `W_mac_16_16(W_acc, var1, var2)` | Multiplies a signed 16-bit var1 by signed 16-bit var2, shifts the result left by 1 and sign extends to 64-bits;
add this 64 bit value to the 64 bit W_acc without saturation control, and returns a 64 bit result.
The operation is performed in fractional mode.
For example, if var1 is in 1Q15 format and var2 is in 1Q15 format, then the product is in 33Q31 format which is then added to W_acc (in 33Q31 format) to provide a final result in 33Q31 format. | | `W_msu_16_16(W_acc, var1, var2)` | Multiplies a signed 16-bit var1 by signed 16-bit var2, shifts the result left by 1 and sign extends to 64-bit;
subtracts this 64 bit value from the 64 bit W_acc without saturation control, and returns a 64 bit result.
The operation is performed in fractional mode.
For example, if var1 is in 1Q15 format and var2 is in 1Q15 format, then the product is in 33Q31 format which is then subtracted from W_acc (in 33Q31 format) to provide a final result in 33Q31 format. | | `W_deposit32_l(L_var1)` | Deposits the 32 bit L_var1 into the 32 LS bits of the 64-bit output. The 32 MS bits of the output are sign extended. | | `W_deposit32_h(L_var1)` | Deposits the 32-bit L_var1 into the 32 MS bits of the 64-bit output. The 32 LS bits of the output are zeroed. | -| `W_sat_l(W_v1)` | Saturates the 64-bit variable W_v1 to 32-bit value and returns the lower 32 bits.
For example, a 64-bit wide accumulator is helpful in accumulating 16*16 multiplies without checking for saturation. However, at the end of the multiply-and-accumulate loop, we need to return only the 32-bit value after checking for saturation.
If W_v1 is in 33Q31 format, then the result returned will be saturated to 1Q31 format. | -| `W_sat_m(W_v1)` | Arithmetically shifts right the 64-bit variable W_v1 by 16 bits; saturates the 64-bit value to 32-bit value and returns the lower 32 bits.
For example, a 64-bit wide accumulator is helpful in accumulating 32\*16 multiplies without checking for saturation. A 32\*16 multiply gives a 48-bit product; at the end of the multiply-and-accumulate loop, the result is in the lower 48 bits of the 64-bit accumulator. Now an arithmetic right shift by 16 bits will drop the LSB 16 bits. Now we should check for saturation and return the lower 32 bits.
If W_var is in 17Q47 format, then the result returned will be saturated to 1Q31 format. | -| `W_shl_sat_l(W_1, var1)` | Arithmetically shifts left the 64-bit W_v1 by v1 positions with lower 32-bit saturation and returns the 32 LSB of 64-bit result.
If v1 is negative, the result is shifted to right by (-var1) positions and sign extended. After shift operation, returns the 32 MSB of 64-bit result. | +| `W_sat_l(W_var1)` | Saturates the 64-bit variable W_var1 to 32-bit value and returns the lower 32 bits.
For example, a 64-bit wide accumulator is helpful in accumulating 16*16 multiplies without checking for saturation. However, at the end of the multiply-and-accumulate loop, we need to return only the 32-bit value after checking for saturation.
If W_var1 is in 33Q31 format, then the result returned will be saturated to 1Q31 format. | +| `W_sat_m(W_var1)` | Arithmetically shifts right the 64-bit variable W_var1 by 16 bits; saturates the 64-bit value to 32-bit value and returns the lower 32 bits.
For example, a 64-bit wide accumulator is helpful in accumulating 32\*16 multiplies without checking for saturation. A 32\*16 multiply gives a 48-bit product; at the end of the multiply-and-accumulate loop, the result is in the lower 48 bits of the 64-bit accumulator. Now an arithmetic right shift by 16 bits will drop the LSB 16 bits. Now we should check for saturation and return the lower 32 bits.
If W_var1 is in 17Q47 format, then the result returned will be saturated to 1Q31 format. | +| `W_shl_sat_l(W_var1, L_var2)` | Arithmetically shifts left the 64-bit W_var1 by L_var2 positions with lower 32-bit saturation and returns the 32 LSB of 64-bit result.
If L_var2 is negative, the result is shifted to right by (-L_var2) positions and sign extended. After shift operation, returns the 32 LSB of 64-bit result. | | `W_extract_l(W_var1)` | Returns the 32 LSB of a 64-bit variable W_var1. | | `W_extract_h(W_var1)` | Returns the 32 MSB of a 64-bit variable W_var1. | | `W_round48_L(W_var1)` | Rounds the lower 16 bits of the 64-bit input number W_var1 into the most significant 32 bits with saturation. Shifts the resulting bits right by 16 and returns the 32-bit number:
if W_var1 is in 17Q47 format, then the result returned will be rounded and saturated to 1Q31 format. | @@ -501,7 +519,7 @@ Variable definitions: |---------------------|-----------------------------------------------------------| | `Mpy_32_16_1(L_var1, var2)` | Multiplies the signed 32-bit variable L_var1 with signed 16-bit variable var2. Shifts the product left by 1 with 48-bit saturation control; returns the 32 MSB of the 48-bit result after truncation of lower 16 bits.
The operation is performed in fractional mode.
For example, if L_var1 is in 1Q31 format and var2 is in 1Q15 format, then the product is produced in 17Q47 format which is then saturated, truncated and returned in 1Q31 format.
The following code snippet describes the operations performed:
`W_var1 = W_mult_32_16(L_var1, var2 );`
`L_var_out = W_sat_m(W_var1 );` | | `Mpy_32_16_r(L_var1, var2)` | Multiplies the signed 32-bit variable L_var1 with signed 16-bit variable var2. Shifts the product left by 1 with 48-bit saturation control; returns the 32 MSB of the 48-bit result after rounding of the lower 16 bits
The operation is performed in fractional mode.
For example, if L_var1 is in 1Q31 format and var2 is in 1Q15 format, then the product is produced in 17Q47 format which is then rounded, saturated, and returned in 1Q31 format.
The following code snippet describes the operations performed:
`W_var1 = W_mult_32_16(L_var1, var2 );`
`L_var_out = W_round48_L(W_var1);` | -| `Mpy_32_32(L_var1, L_var2)` | Multiplies the signed 32-bit variable L_var1 with signed 32-bit variable L_var2. Shifts the product left by 1 with 64-bit saturation control; Returns the 32 MSB of the 64-bit result after truncating of the lower 32 bits.
The operation is performed in fractional mode.
For example, if L_var1 is in 1Q31 format and var2 is in 1Q31 format, then the product is produced in 1Q63 format which is then truncated, saturated, and returned in 1Q31 format.
The following code snippet describes the operations performed:
`W_var1 = (( Word64) L_var1 * L_var2);`
`L_var_out = W_extract_h(W_shl(W_var1, 1));` | +| `Mpy_32_32(L_var1, L_var2)` | Multiplies the signed 32-bit variable L_var1 with signed 32-bit variable L_var2. Shifts the product left by 1 with 64-bit saturation control; Returns the 32 MSB of the 64-bit result after truncating of the lower 32 bits.
The operation is performed in fractional mode.
For example, if L_var1 is in 1Q31 format and L_var2 is in 1Q31 format, then the product is produced in 1Q63 format which is then truncated, saturated, and returned in 1Q31 format.
The following code snippet describes the operations performed:
`W_var1 = (( Word64) L_var1 * L_var2);`
`L_var_out = W_extract_h(W_shl(W_var1, 1));` | | `Mpy_32_32_r(L_var1, L_var2)` | Multiplies the signed 32-bit variable L_var1 with signed 32-bit variable L_var2. Adds rounding offset to lower 31 bits of the product. Shifts the result left by 1 with 64-bit saturation control; returns the 32 MSB of the 64-bit result with saturation control.
The operation is performed in fractional mode.
For example, if L_var1 is in 1Q31 format and L_var2 is in 1Q31 format, then the result is produced in 1Q63 format which is then rounded, saturated, and returned in 1Q31 format.
The following code snippet describes the operations performed:
`W_var1 = (( Word64)L_var1 * L_var2);`
`W_var1 = W_var1 + 0x40000000LL;`
`W_var1 = W_shl( W_var1, 1 );`
`L_var_out = W_extract_h(W_var1 );` | | `Madd_32_16(L_var3, L_var1, var2)` | Multiplies the signed 32-bit variable L_var1 with signed 16-bit variable var2. Shifts the product left by 1 with 48-bit saturation control; adds the 32-bit MSB of the 48-bit result with 32-bit L_var3 with 32-bit saturation control.
The operation is performed in fractional mode.
For example, if L_var1 is in 1Q31 format and var2 is in 1Q15 format, then the product is produced in 17Q47 format which is then saturated, truncated to 1Q31 format and added to L_var3 in 1Q31 format.
The following code snippet describes the operations performed:
`L_var_out = Mpy_32_16_1(L_var1, var2);`
`L_var_out = L_add(L_var3, L_var_out);` | | `Madd_32_16_r(L_var3, L_var1, var2)` | Multiplies the signed 32-bit variable L_var1 with signed 16-bit variable var2. Shifts the product left by 1 with 48-bit saturation control; gets the 32-bit MSB from 48-bit result after rounding of the lower 16 bits and adds this with 32-bit L_var3 with 32-bit saturation control.
The operation is performed in fractional mode.
For example, if L_var1 is in 1Q31 format and var2 is in 1Q15 format, then the product is produced in 17Q47 format which is then saturated, rounded to 1Q31 format and added to L_var3 in 1Q31 format.
The following code snippet describes the operations performed:
`L_var_out = Mpy_32_16_r(L_var1, var2);`
`L_var_out = L_add(L_var3, L_var_out);` | @@ -527,8 +545,8 @@ Variable definitions: ||| |---------------------|-----------------------------------------------------------| -| `CL_shr(CL_var1, var2)` | Arithmetically shifts right the real and imaginary parts of the 32-bit complex number CL_var1 by var2 positions.
If var2 is negative, real and imaginary parts of CL_var1 are shifted to the most significant bits by (-var2) positions with 32-bit saturation control.
If var2 is positive, real and imaginary parts of CL_var1 are shifted to the least significant bits by ( var2 ) positions with sign extension.
The following code snippet describes the operations performed on the real and the imaginary parts of a complex number:
`CL_result.re = L_shr(CL_var1.re, L_shift_val);`
`CL_result.im = L_shr(CL_var1.im, L_shift_val);` | -| `CL_shl(CL_var1, var2)` | Arithmetically shifts left the real and imaginary parts of the 32-bit complex number CL_var1 by L_shift_val positions.
If var2 is negative, real and imaginary parts of CL_var1 are shifted to the least significant bits by ( -var2 ) positions with sign extension.
If var2 is positive, real and imaginary parts of CL_var1 are shifted to the most significant bits by (var2) positions with 32-bit saturation control.
The following code snippet describes the operations performed on the real and the imaginary parts of a complex number:
`CL_result.re = L_shl(CL_var1.re, L_shift_val);`
`CL_result.im = L_shl(CL_var1.im, L_shift_val);` | +| `CL_shr(CL_var1, L_var2)` | Arithmetically shifts right the real and imaginary parts of the 32-bit complex number CL_var1 by L_var2 positions.
If L_var2 is negative, real and imaginary parts of CL_var1 are shifted to the most significant bits by (-L_var2) positions with 32-bit saturation control.
If L_var2 is positive, real and imaginary parts of CL_var1 are shifted to the least significant bits by (L_var2) positions with sign extension.
The following code snippet describes the operations performed on the real and the imaginary parts of a complex number:
`CL_result.re = L_shr(CL_var1.re, L_var2);`
`CL_result.im = L_shr(CL_var1.im, L_var2);` | +| `CL_shl(CL_var1, L_var2)` | Arithmetically shifts left the real and imaginary parts of the 32-bit complex number CL_var1 by L_var2 positions.
If L_var2 is negative, real and imaginary parts of CL_var1 are shifted to the least significant bits by ( -L_var2 ) positions with sign extension.
If L_var2 is positive, real and imaginary parts of CL_var1 are shifted to the most significant bits by (L_var2) positions with 32-bit saturation control.
The following code snippet describes the operations performed on the real and the imaginary parts of a complex number:
`CL_result.re = L_shl(CL_var1.re, L_var2);`
`CL_result.im = L_shl(CL_var1.im, L_var2);` | | `CL_add(CL_var1, CL_var2)` | Adds the two 32-bit complex numbers CL_var1 and CL_var2 with 32-bit saturation control.
Real part of the 32-bit complex number CL_var1 is added to real part of the 32-bit complex number CL_var2 with 32-bit saturation control. The result forms the real part of the result variable.
Imaginary part of the 32-bit complex number CL_var1 is added to Imaginary part of the 32-bit complex number CL_var2 with 32-bit saturation control. The result forms the imaginary part of the result variable.
Following code snippet describe the operations performed on the real and the imaginary parts of a complex number:
`CL_result.re = L_add(CL_var1.re, CL_var2.re);`
`CL_result.im = L_add(CL_var1.im, CL_var2.im);` | | `CL_sub(CL_var1, CL_var2)` | Subtracts the two 32-bit complex numbers CL_var1 and CL_var2 with 32-bit saturation control.
Real part of the 32-bit complex number CL_var2 is subtracted from real part of the 32-bit complex number CL_var1 with 32-bit saturation control. The result forms the real part of the result variable.
Imaginary part of the 32-bit complex number CL_var2 is subtracted from imaginary part of the 32-bit complex number CL_var1 with 32-bit saturation control. The result forms the imaginary part of the result variable.
The following code snippet describes the operations performed on the real and the imaginary parts of a complex number:
`CL_result.re = L_sub(CL_var1.re, CL_var2.re);`
`CL_result.im = L_sub(CL_var1.im, CL_var2.im);` | | `CL_scale(CL_var, var1)` | Multiplies the real and imaginary parts of a 32-bit complex number CL_var by a 16-bit var1. The resulting 48-bit product for each part is rounded, saturated and 32-bit MSB of 48-bit result are returned.
The following code snippet describes the operations performed on real & imaginary part of a complex number:
`CL_result.re = Mpy_32_16_r(CL_var.re, var1);`
`CL_result.im = Mpy_32_16_r(CL_var.im, var1);` | @@ -710,4 +728,51 @@ The main program for WMC Tool. Depends on: `wmc_auto_c.txt` Auto-generated C source file for inclusion in projects. ------------------------------------------------------------------------------------------ +## u) Delay/error profile to frame-erasure pattern conversion + +Name: `dlyerr_2_errpat.c` + +Converts a delay-and-error profile (one entry per packet with network delay in ms and a loss flag) into a frame-erasure error pattern suitable for use with the `eid-xor` tool. Supports fixed-delay and bounded-loss-rate jitter buffer emulation modes. Output formats include G.192 word, G.192 byte, and text. + +## v) EID for 3GPP AMR codec + +Name: `eid-amr.c` + +Applies G.192 frame erasure patterns to 3GPP AMR bitstreams. The standard `eid-xor` tool cannot be used directly with AMR because the AMR bitstream follows the ETSI/3GPP format rather than ITU-T G.192. Lost frames are signalled with frame type NO\_DATA and all data bits are forced to zero. + +## w) Pseudo-random selection tool + +Name: `random.c` + +Provides deterministic pseudo-random selection of items from a list or drawing of integers from a numeric range. Uses the EID linear congruential generator for cross-platform reproducibility. Supports configurable seed, dummy pre-runs, and multi-item selection. + +## x) WAV file I/O module + +Name: `wav_io.c` + +Associated header file: `wav_io.h` + +Shared library providing transparent WAV and raw PCM file I/O for all audio-processing tools. Supports 8/16/24/32-bit integer PCM and 32-bit IEEE float WAV files. When a file has a `.wav` extension, the header is parsed automatically; raw PCM files continue to work as before. + +The functions included are as follows. + +||| +|---------------------|-----------------------------------------------------------| +| `audio_open_read` | open a file for reading; auto-detects WAV or raw PCM format. | +| `audio_open_write` | open a file for writing in WAV or raw PCM format. | +| `audio_read` | read samples from an open audio file. | +| `audio_write` | write samples to an open audio file. | +| `audio_close` | close an audio file and finalize the WAV header if applicable. | +| `audio_is_wav` | query whether an open file is WAV format. | +| `audio_get_sample_rate` | return the sample rate of a WAV file. | +| `audio_get_channels` | return the number of channels. | +| `audio_seek` | seek to a sample offset within the file. | +| `audio_get_data_size` | return the total data size in bytes. | + +## y) Per-band gain verification tool + +Name: `gain_chk.c` + +Compares a reference and processed 16-bit PCM (or WAV) stream by computing per-band gain differences across up to 25 frequency bands. Reports per-frame gain amplification for active and inactive frames. Intended for verifying that codecs and processing tools do not introduce excessive gain in any frequency band. + -=Pagebreak=- diff --git a/doc/manual/Makefile b/doc/manual/Makefile index 5b907ea4..b9a48712 100644 --- a/doc/manual/Makefile +++ b/doc/manual/Makefile @@ -1,7 +1,7 @@ BIBTEX = bibtex PDFLATEX = pdflatex -PARTS = STLmanual.tex intro.tex g711.tex g711iplc.tex g726.tex g727.tex g728.tex g722.tex rpe.tex rate.tex eid.tex mnru.tex sv56.tex reverb.tex truncate.tex freqresp.tex stereoop.tex esdru.tex bs1770demo.tex basop.tex utl.tex wmc_tool.tex +PARTS = STLmanual.tex intro.tex g711.tex g711iplc.tex g726.tex g727.tex g728.tex g722.tex rpe.tex rate.tex eid.tex mnru.tex sv56.tex reverb.tex truncate.tex freqresp.tex stereoop.tex esdru.tex bs1770demo.tex gain_chk.tex basop.tex utl.tex wmc_tool.tex STLmanual.pdf : $(PARTS) bibliography.bib $(PDFLATEX) $(PARTS) diff --git a/doc/manual/STLmanual.tex b/doc/manual/STLmanual.tex index a9cc935a..ac628910 100644 --- a/doc/manual/STLmanual.tex +++ b/doc/manual/STLmanual.tex @@ -18,7 +18,7 @@ \addtolength{\itemsep}{-20pt} % Define headers -\def\ugst_title{ ITU-T Software Tool Library, release 2024} +\def\ugst_title{ ITU-T Software Tool Library, release 2026} \def\us{$\mu$s} \markboth{ \hspace{1cm} \hfill \ugst_title }% { Version: \today \hfill \hspace{1cm} } @@ -61,7 +61,7 @@ \pagenumbering{roman} %============================================================================== -\title{ITU-T Software Tool Library 2024 User's Manual} +\title{ITU-T Software Tool Library 2026 User's Manual} \author{ITU-T Users' Group on Software Tools} %------------------------------------------------------------------------------ @@ -71,7 +71,7 @@ \ruley{100mm} - Copyright \copyright~ 2005, 2006, 2009, 2019, 2022, 2023 and 2024 by the International + Copyright \copyright~ 2005, 2006, 2009, 2019, 2022, 2023, 2024 and 2026 by the International Telecommunication Union (ITU) \ruley{15mm} @@ -182,6 +182,11 @@ %============================================================================= \include{freqresp} +%============================================================================= +% chapter gain_chk: Gain amplification verification tool +%============================================================================= +\include{gain_chk} + %============================================================================= % chapter stereoop: Stereo processing tool %============================================================================= diff --git a/doc/manual/basop.tex b/doc/manual/basop.tex index 8ec24454..fac729dc 100644 --- a/doc/manual/basop.tex +++ b/doc/manual/basop.tex @@ -1008,27 +1008,27 @@ \subsection{Variable definitions} \subsection{Operators with complexity weight of 1} %........................................................ -\NewOperator{CL\_shr(CL\_var1, var2)} +\NewOperator{CL\_shr(CL\_var1, L\_var2)} -Arithmetically shifts right the real and imaginary parts of the 32-bit complex number CL\_var1 by var2 positions.\\ -If var2 is negative, real and imaginary parts of CL\_var1 are shifted to the most significant bits by (-var2) positions with 32-bit saturation control.\\ -If var2 is positive, real and imaginary parts of CL\_var1 are shifted to the least significant bits by (var2) positions with sign extension.\\ +Arithmetically shifts right the real and imaginary parts of the 32-bit complex number CL\_var1 by L\_var2 positions.\\ +If L\_var2 is negative, real and imaginary parts of CL\_var1 are shifted to the most significant bits by (-L\_var2) positions with 32-bit saturation control.\\ +If L\_var2 is positive, real and imaginary parts of CL\_var1 are shifted to the least significant bits by (L\_var2) positions with sign extension.\\ The following code snippet describes the operations performed on real \& imaginary part of a complex number: -{\tt \rulex{5mm}CL\_result.re = L\_shr(CL\_var1.re, L\_shift\_val);\\ -\rulex{5mm}CL\_result.im = L\_shr(CL\_var1.im, L\_shift\_val);\\ +{\tt \rulex{5mm}CL\_result.re = L\_shr(CL\_var1.re, L\_var2);\\ +\rulex{5mm}CL\_result.im = L\_shr(CL\_var1.im, L\_var2);\\ } %........................................................ -\NewOperator{CL\_shl(CL\_var1, var2)} +\NewOperator{CL\_shl(CL\_var1, L\_var2)} -Arithmetically shifts left the real and imaginary parts of the 32-bit complex number CL\_var1 by L\_shift\_val positions.\\ -If var2 is negative, real and imaginary parts of CL\_var1 are shifted to the least significant bits by ( -var2 ) positions with sign extension.\\ -If var2 is positive, real and imaginary parts of CL\_var1 are shifted to the most significant bits by (var2) positions with 32-bit saturation control.\\ +Arithmetically shifts left the real and imaginary parts of the 32-bit complex number CL\_var1 by L\_var2 positions.\\ +If L\_var2 is negative, real and imaginary parts of CL\_var1 are shifted to the least significant bits by ( -L\_var2 ) positions with sign extension.\\ +If L\_var2 is positive, real and imaginary parts of CL\_var1 are shifted to the most significant bits by (L\_var2) positions with 32-bit saturation control.\\ The following code snippet describes the operations performed on real \& imaginary part of a complex number: -{\tt \rulex{5mm} CL\_result.re = L\_shl(CL\_var1.re, L\_shift\_val);\\ -\rulex{5mm} CL\_result.im = L\_shl(CL\_var1.im, L\_shift\_val); +{\tt \rulex{5mm} CL\_result.re = L\_shl(CL\_var1.re, L\_var2);\\ +\rulex{5mm} CL\_result.im = L\_shl(CL\_var1.im, L\_var2); } %........................................................ @@ -1503,7 +1503,7 @@ \subsection{Operators with complexity weight of 1} Multiplies 16-bit var1 by 16-bit var2, sign extends to 64 bits; subtracts this 64 bit value from the 64 bit W\_acc without saturation control, and returns a 64 bit result. %........................................................ -\NewOperator{W\_mult\_16\_16(W\_acc, var1, var2)} +\NewOperator{W\_mult\_16\_16(var1, var2)} \textbf{ This operator is SIMD and VLIW friendly} @@ -1542,29 +1542,29 @@ \subsection{Operators with complexity weight of 1} Deposits the 32-bit L\_var1 into the 32 MS bits of the 64-bit output. The 32 LS bits of the output are zeroed. %........................................................ -\NewOperator{W\_sat\_l(W\_v1)} +\NewOperator{W\_sat\_l(W\_var1)} -Saturates the 64-bit variable W\_v1 to 32-bit value and returns the lower 32 bits.\\ +Saturates the 64-bit variable W\_var1 to 32-bit value and returns the lower 32 bits.\\ For example, a 64-bit wide accumulator is helpful in accumulating 16*16 multiplies without checking for saturation. However, at the end of the multiply-and-accumulate loop, we need to return only the 32-bit value after checking for saturation.\\ -If W\_v1 is in 33Q31 format, then the result returned will be saturated to 1Q31 format. +If W\_var1 is in 33Q31 format, then the result returned will be saturated to 1Q31 format. %........................................................ -\NewOperator{W\_sat\_m(W\_v1)} +\NewOperator{W\_sat\_m(W\_var1)} -Arithmetically shifts right the 64-bit variable W\_v1 by 16 bits; saturates the 64-bit value to 32-bit value and returns the lower 32 bits.\\ +Arithmetically shifts right the 64-bit variable W\_var1 by 16 bits; saturates the 64-bit value to 32-bit value and returns the lower 32 bits.\\ For example, a 64-bit wide accumulator is helpful in accumulating 32\*16 multiplies without checking for saturation. A 32\*16 multiply gives a 48-bit product; at the end of the multiply-and-accumulate loop, the result is in the lower 48 bits of the 64-bit accumulator. Now an arithmetic right shift by 16 bits will drop the LSB 16 bits. Now we should check for saturation and return the lower 32 bits.\\ -If W\_var is in 17Q47 format, then the result returned will be saturated to 1Q31 format. +If W\_var1 is in 17Q47 format, then the result returned will be saturated to 1Q31 format. %........................................................ -\NewOperator{W\_shl\_sat\_l(W\_1, var1)} +\NewOperator{W\_shl\_sat\_l(W\_var1, L\_var2)} -Arithmetically shifts left the 64-bit W\_v1 by v1 positions with lower 32-bit saturation and returns the 32 LSB of 64-bit result.\\ -If v1 is negative, the result is shifted to right by (-var1) positions and sign extended. -After shift operation, returns the 32 MSB of 64-bit result. +Arithmetically shifts left the 64-bit W\_var1 by L\_var2 positions with lower 32-bit saturation and returns the 32 LSB of 64-bit result.\\ +If L\_var2 is negative, the result is shifted to right by (-L\_var2) positions and sign extended. +After shift operation, returns the 32 LSB of 64-bit result. %........................................................ \NewOperator{W\_extract\_l(W\_var1)} @@ -1611,7 +1611,7 @@ \subsection{Operators with complexity weight of 1} %........................................................ \NewOperator{W\_neg(W\_var1)} -Negates a 64-bit variables W\_var1 with 64-bit saturation control. +Negates the 64-bit variable W\_var1 with 64-bit saturation control. Set overflow flag. Returns 64-bit result. %........................................................ @@ -1713,7 +1713,7 @@ \subsection{Operators} Returns the 32 MSB of the 64-bit result after truncating of the lower 32 bits. The operation is performed in fractional mode. -For example, if L\_var1 is in 1Q31 format and var2 is in 1Q31 format, then the product is produced in 1Q63 format which is then truncated, saturated, and returned in 1Q31 format. +For example, if L\_var1 is in 1Q31 format and L\_var2 is in 1Q31 format, then the product is produced in 1Q63 format which is then truncated, saturated, and returned in 1Q31 format. The following code snippet describes the operations performed: diff --git a/doc/manual/eid.tex b/doc/manual/eid.tex index 8769dbe8..009a6cbd 100644 --- a/doc/manual/eid.tex +++ b/doc/manual/eid.tex @@ -7,6 +7,7 @@ % Apr.96 - Peter Kroon % Feb.2000 - Convergence towards STL2000 % Oct.2009 - EID-EV Jonas Svedberg, Yusuke Hiwasaki +% May.2026 - EID-AMR Balazs Kövesi, Stéphane Ragot %============================================================================= %============================================================================= @@ -1341,3 +1342,190 @@ \subsubsection{EID-EV G.192 Output frame examples } \label{fig:G192outputFrameLayer034ErrorIndividual} \end{center} \end{figure} + +%-------------------------------------- +\section {Delay/error profile to erasure pattern (dlyerr\_2\_errpat)} \label{DLYERR} + + +\subsection{Description} + +The {\tt dlyerr\_2\_errpat} tool converts a delay-and-error profile into a +frame-erasure error pattern suitable for use with {\tt eid-xor}. This enables +simulation of jitter buffer management (JBM) behavior: packets that arrive +too late for playout are treated as lost, in addition to packets lost in +the network. + +The input profile contains one integer per line representing either: +\begin{itemize} +\item A network delay in milliseconds (0--1999), or +\item The value $-1$, indicating the packet was lost in the network. +\end{itemize} + +Two JBM emulation modes are supported: +\begin{itemize} +\item {\bf Constant-delay mode} ({\tt -d}): a fixed JBM delay in milliseconds. + Any packet with delay exceeding this threshold is marked as lost. +\item {\bf Bounded-loss-rate mode} ({\tt -l}): the tool automatically selects + the minimum JBM delay such that the combined late-loss rate stays + below the specified percentage. +\end{itemize} + +\subsection{Algorithm} + +Processing is performed in two passes over the input profile: + +\begin{enumerate} +\item {\bf Histogram pass}: reads the profile and builds a delay histogram + (counts per millisecond bin). In bounded-loss-rate mode, this histogram + is used to determine the JBM delay threshold by accumulating from the + highest delay downward until the target late-loss rate is exceeded. + +\item {\bf Output pass}: re-reads the profile and classifies each packet: + \begin{itemize} + \item delay $= -1$ (network loss) $\rightarrow$ frame erased + \item delay $>$ JBM threshold $\rightarrow$ frame erased (late loss) + \item otherwise $\rightarrow$ frame received (good) + \end{itemize} +\end{enumerate} + +If the profile is shorter than the requested output length ({\tt -L}), the +file is rewound and reused from the beginning. + +When {\tt -f~2} is specified, each packet decision produces two consecutive +frame-erasure flags in the output (for codecs sending two frames per packet). + +\subsection{Usage} + +{\tt\small +\begin{verbatim} +dlyerr_2_errpat [options] + + -i delay/error profile (required) + -o error pattern output (required) + -d constant-JBM-delay mode + -l bounded-loss-rate mode + -L output length (default: 7500) + -s skip initial frames in profile + -f <1|2> frames per packet (default: 1) + -w word-oriented G.192 output + -b byte-oriented G.192 output + -c text with LF (one entry per line) +\end{verbatim} +} + +Exactly one of {\tt -d} or {\tt -l} must be supplied. + +\subsection{Output formats} + +\begin{itemize} +\item {\bf Default text}: concatenated ASCII {\tt 0} (good) / {\tt 1} (erased) +\item {\bf Text with LF} ({\tt -c}): one digit per line +\item {\bf Byte G.192} ({\tt -b}): binary bytes 0x21 (good) / 0x20 (erased) +\item {\bf Word G.192} ({\tt -w}): binary 16-bit words 0x6B21 / 0x6B20 +\end{itemize} + +\subsection{Example} + +Apply MTSI delay/error profile with a fixed 200\,ms JBM delay, word-oriented +G.192 output, random offset into the profile: + +{\tt\small +\begin{verbatim} +dlyerr_2_errpat -d 200 -f 1 -w -s 1234 \ + -i dly_err_profile_1.dat -o ep1.g192 +eid-xor -fer -ep g192 bitstream.g192 ep1.g192 output.g192 +\end{verbatim} +} + +Bounded loss rate of 1\%, two frames per packet: + +{\tt\small +\begin{verbatim} +dlyerr_2_errpat -l 1 -f 2 -w -i dly_err_profile_5.dat -o ep5.g192 +\end{verbatim} +} + +\subsection{Origin} + +Provided by Fraunhofer IIS via 3GPP Tdoc S4-121077 (TSGS4\#70, Chicago, +13--17 Aug 2012), in support of the EVS reference codec processing plan. + +%-------------------------------------- +\section {Adaptation for 3GPP AMR codec (EID-AMR)} \label{EID-AMR2} +%-------------------------------------- + +\subsection{Description} + +The {\tt eid-xor} tool operates on bitstreams conforming to the ITU-T G.192 +serial bitstream format. However, the 3GPP AMR narrowband codec uses a +different serial bitstream format, defined in Clause~6.3 of 3GPP TS~26.073. +In this format, each frame is a fixed-size block of 250 16-bit words +({\tt SERIAL\_FRAMESIZE} = 1 + 244 + 5), where: +\begin{itemize} +\item Word 0: frame type indicator (e.g.\ 0x00--0x07 for AMR modes, 0x03 = NO\_DATA) +\item Words 1--244: serial speech bits ({\tt MAX\_SERIAL} = 244) +\item Words 245--249: auxiliary/padding +\end{itemize} + +Since this format is not compliant with ITU-T G.192, a dedicated tool +called {\tt eid-amr} is provided to apply frame erasure patterns to AMR +bitstreams. + +\subsection{Algorithm} + +The {\tt eid-amr} tool reads an AMR bitstream and a G.192 frame erasure +pattern file. For each AMR frame, one erasure flag is consumed from the +error pattern: +\begin{itemize} +\item If the flag is {\tt G192\_SYNC} (0x6B21, good frame): the AMR frame + is written to the output unchanged. +\item If the flag is {\tt G192\_FER} (0x6B20, erased frame): the frame type + is set to NO\_DATA (0x03), all 244 serial data bits are forced to zero, + and the modified frame is written to the output. +\end{itemize} + +If the error pattern file is shorter than the AMR bitstream, the error +pattern is rewound and reused from the beginning (same behavior as +{\tt eid-xor}). + +Note that {\tt eid-amr} handles only frame erasures; bit errors are not +supported. + + +\subsection{Usage} + +{\tt\small +\begin{verbatim} +eid-amr +\end{verbatim} +} + +Where: +\begin{itemize} +\item {\tt AMR\_bitstream\_in}: input AMR serial bitstream (ETSI/3GPP format) +\item {\tt G.192\_FER\_pattern}: G.192 word-oriented frame erasure pattern + (as generated by {\tt gen-patt} with {\tt -g192 -fer}) +\item {\tt AMR\_bitstream\_out}: output AMR bitstream with erasures applied +\end{itemize} + +Statistics are reported to {\tt stderr} upon completion: number of processed +frames, distorted frames, frame erasure rate, and number of error pattern +wraps. + +\subsection{Example} + +Generate a 3\% burst frame erasure pattern and apply it to an AMR bitstream +encoded at 4.75~kbit/s: + +{\tt\small +\begin{verbatim} +gen-patt -g192 ep.g192 f 500 1 state.ser 0.03 +eid-amr input_475.amr ep.g192 output_475_fer.amr +\end{verbatim} +} + +\subsection{Origin} + +This tool is derived from the EID-3G tool (Nobuhiko Naka, NTT DOCOMO) and +was originally submitted to 3GPP in Tdoc S4-120998 (TSGS4\#70, Chicago, +13--17 Aug 2012). Authors: Balazs K\"ovesi, St\'ephane Ragot (Orange SA). diff --git a/doc/manual/gain_chk.tex b/doc/manual/gain_chk.tex new file mode 100644 index 00000000..aa44a00c --- /dev/null +++ b/doc/manual/gain_chk.tex @@ -0,0 +1,228 @@ +%============================================================================= +% THIS IS chapter{Gain amplification verification tool} +% +% May 2026 - created for STL integration +%============================================================================= +\chapter{Gain amplification verification tool} +\label{ch:gain_chk} +%============================================================================= + +\section{Introduction} +\label{sec:gain_chk-intro} + +The \texttt{gain\_chk} tool compares a reference signal and a processed +signal and reports short-time gain differences per frequency band. The +tool is intended for objective verification of spectral gain behavior in +speech and audio processing chains. + +Both inputs are raw 16-bit PCM files. The processing is frame-based with +20 ms frames and supports sampling frequencies 8, 16, 32 and 48 kHz. +Optionally, a VAD file can be provided to separate statistics for active +and inactive frames. + +\section{Description of the algorithm} +\label{sec:gain_chk-algorithm} + +\subsection{Frame and spectrum analysis} + +Let $x_1[n]$ be the reference frame and $x_2[n]$ be the processed frame, +with frame length $L=\frac{F_s}{50}$ samples (20 ms). Each frame is +windowed with a Hamming window +\begin{equation} +w[n] = 0.54 - 0.46\cos\left(\frac{2\pi n}{L-1}\right), \quad n=0,\ldots,L-1. +\end{equation} + +The tool computes the real FFT of each windowed frame after zero-padding +to the next power-of-two length. For each frequency bin $k$, the spectral +energy is +\begin{equation} +P_i[k] = \Re\{X_i[k]\}^2 + \Im\{X_i[k]\}^2, \quad i \in \{1,2\}. +\end{equation} + +\subsection{Band energy accumulation} + +The analysis bands are defined by upper frequency limits in the +\texttt{bands[]} table. Values in $(0,1]$ are interpreted as normalized +fractions of Nyquist ($F_s/2$). For each band $b$, the tool accumulates +average bin energy: +\begin{equation} +E_i^{(b)} = \frac{1}{N_b}\sum_{k \in \mathcal{B}_b} P_i[k], +\end{equation} +where $\mathcal{B}_b$ is the set of bins inside the band and $N_b$ its +number of bins. + +For each frame class (all/active/inactive), band energies are accumulated +across frames: +\begin{equation} +\bar{E}_i^{(b)} = \sum_{\mbox{\scriptsize frames}} E_i^{(b)}. +\end{equation} + +\subsection{Reported gain measures} + +For each band, the gain ratio is +\begin{equation} +R^{(b)} = \frac{\bar{E}_2^{(b)} + E_{\min}}{\bar{E}_1^{(b)} + E_{\min}}, +\end{equation} +where $E_{\min}$ is a small offset used for numerical robustness. + +The reported outputs are: +\begin{equation} +G_{\mathrm{dB}}^{(b)} = 10\log_{10}\left(R^{(b)}\right), +\end{equation} +\begin{equation} +G_{\%}^{(b)} = \left(R^{(b)} - 1\right)\cdot 100. +\end{equation} + +The same ratio is also computed on the total energy over all bands. + +\subsection{VAD-conditioned processing} + +When a VAD file is present (\texttt{-v}), one 16-bit flag is read per +frame. Frames with non-zero VAD are treated as active. Frames with zero +VAD are treated as inactive. + +For inactive frames, a low-energy gate is applied on the reference frame: +if mean time-domain energy is below a fixed threshold, that frame is not +included in spectral statistics. This avoids unstable ratios in near-silent +segments. + +\subsection{Threshold check mode} + +When threshold options are enabled, two checks are available: +\begin{itemize} +\item \texttt{-a}: maximum allowed positive gain (amplification) in dB for active frames; +\item \texttt{-s}: maximum allowed attenuation in dB for inactive frames (requires VAD). +\end{itemize} + +The tool returns a numeric code intended for automation scripts: +\begin{itemize} +\item 1: active fail and inactive fail; +\item 2: active pass and inactive fail; +\item 3: active fail and inactive pass; +\item 4: active pass and inactive pass. +\end{itemize} + +\section{Implementation} +\label{sec:gain_chk-impl} + +\subsection{Data and file format} + +The tool expects 16-bit PCM input files in native host byte order, +consistent with other STL command-line tools. + +Mandatory input/output arguments: +\begin{itemize} +\item \texttt{-i} reference PCM file; +\item \texttt{-o} processed PCM file; +\item \texttt{-t} output text file; +\item \texttt{-r} sampling frequency in Hz. +\end{itemize} + +Optional arguments: +\begin{itemize} +\item \texttt{-v} VAD file (one 16-bit flag per frame); +\item \texttt{-a} active-frame amplification threshold (dB); +\item \texttt{-s} inactive-frame attenuation threshold (dB). +\end{itemize} + +\subsection{Output file format} + +The results text file (\texttt{-t}) is opened in append mode. For each +invocation, the tool writes: + +\begin{enumerate} +\item The command line used. +\item A header line indicating the frame class (\texttt{For all Frames}, + \texttt{For Active Frames}, or \texttt{For Inactive Frames}). +\item One line per frequency band: +\begin{verbatim} +Ener Ratio (Out/In) for critical band ( Hz - Hz) = dB ( %) +\end{verbatim} +\item A full-spectrum summary line covering band $0$--$F_s/2$. +\item A separator line of dashes. +\end{enumerate} + +\noindent When a VAD file is provided, the above block is repeated +separately for active and inactive frame classes. + +\subsection{Command line syntax} + +{\tt {\small +\begin{tabular}{llll} +gain\_chk & -i ref.pcm & -o proc.pcm & -t results.txt \\ + & -r Fs & [-v vad.bin] & [-a A\_dB] [-s S\_dB] \\ +\end{tabular} +}} + +\subsection{Processing flow} + +Pseudo code: +{\tt\small +\begin{verbatim} +Read and validate command line +Initialize frame length, bands, and Hamming window +for each complete 20 ms frame in both input files: + read reference and processed PCM frame + read VAD flag if provided (else active by default) + optionally skip low-energy inactive frame + apply Hamming window and zero padding + compute FFT of both frames + for each frequency band: + accumulate average spectral energy in reference/processed +After loop: + print per-band and total gain in dB and percent + optionally evaluate thresholds and return status code +\end{verbatim} +} + +\section{Tests and portability} +\label{sec:gain_chk-tests} + +The STL CMake integration defines regression tests for \texttt{gain\_chk} +using bundled PCM material. Tests run at 48 kHz and compare expected tool +output against reference files. + +The implementation is ANSI C style and uses standard C library calls plus +math functions (\texttt{log}, \texttt{log10}, \texttt{cos}). It is portable +across common Unix-like and Windows toolchains supported by STL. + +\section{Example code} +\label{sec:gain_chk-example} + +The demonstration program is \texttt{gain\_chk.c}. It implements command +line parsing, frame-based spectral analysis, optional VAD-conditioned +statistics, report generation, and threshold-based return codes. + +A typical invocation comparing a reference and processed file at 48~kHz: + +{\tt {\small +\begin{verbatim} +$ gain_chk -i ref.pcm -o processed.pcm -t results.txt -r 48000 +\end{verbatim} +}} + +\noindent Sample output written to \texttt{results.txt}: + +{\tt {\small +\begin{verbatim} +For all Frames +Ener Ratio (Out/In) for critical band 0 ( 0 Hz - 4000 Hz) = -1.49 dB ( -29.02%) +Ener Ratio (Out/In) for critical band 1 ( 4000 Hz - 8000 Hz) = -6.58 dB ( -78.00%) +Ener Ratio (Out/In) for critical band 2 ( 8000 Hz - 16000 Hz) = -35.58 dB ( -99.97%) +Ener Ratio (Out/In) for critical band 3 (16000 Hz - 20000 Hz) = -16.10 dB ( -97.55%) +Ener Ratio (Out/In) for the Full Spectrum( 0 Hz - 20000 Hz) = -1.55 dB ( -30.02%) +\end{verbatim} +}} + +\noindent With threshold checking enabled for scripted pass/fail: + +{\tt {\small +\begin{verbatim} +$ gain_chk -i ref.pcm -o processed.pcm -t results.txt -r 48000 \ + -v vad.bin -a 3.0 -s 6.0 +$ echo $? +4 +\end{verbatim} +}} + +\noindent Exit code~4 indicates both active and inactive thresholds passed. diff --git a/doc/manual/graphics/hp50_32khz.pdf b/doc/manual/graphics/hp50_32khz.pdf new file mode 100644 index 00000000..25861658 Binary files /dev/null and b/doc/manual/graphics/hp50_32khz.pdf differ diff --git a/doc/manual/graphics/hp50_48khz.pdf b/doc/manual/graphics/hp50_48khz.pdf new file mode 100644 index 00000000..53fd034d Binary files /dev/null and b/doc/manual/graphics/hp50_48khz.pdf differ diff --git a/doc/manual/graphics/shq2_down.pdf b/doc/manual/graphics/shq2_down.pdf new file mode 100644 index 00000000..82dd2932 Binary files /dev/null and b/doc/manual/graphics/shq2_down.pdf differ diff --git a/doc/manual/graphics/shq2_up.pdf b/doc/manual/graphics/shq2_up.pdf new file mode 100644 index 00000000..9edb29ca Binary files /dev/null and b/doc/manual/graphics/shq2_up.pdf differ diff --git a/doc/manual/graphics/shq3_down.pdf b/doc/manual/graphics/shq3_down.pdf new file mode 100644 index 00000000..afa93104 Binary files /dev/null and b/doc/manual/graphics/shq3_down.pdf differ diff --git a/doc/manual/graphics/shq3_up.pdf b/doc/manual/graphics/shq3_up.pdf new file mode 100644 index 00000000..0f91b740 Binary files /dev/null and b/doc/manual/graphics/shq3_up.pdf differ diff --git a/doc/manual/intro.tex b/doc/manual/intro.tex index 07eadbe2..ea4e0868 100644 --- a/doc/manual/intro.tex +++ b/doc/manual/intro.tex @@ -31,6 +31,8 @@ \chapter{Introduction} In 2024, the revision of the STL offers additional features and bug fixes to the BS.1770 demo and WMC tool. +In 2026, the proposed revision of the STL adds: WAV file I/O support with multi-bit-depth (16/24/32-bit) processing for all tools; extensions to the speech voltmeter (sv56) for arbitrary bit-depth processing; a delay-and-error profile to frame-erasure pattern conversion tool (dlyerr\_2\_errpat) for jitter buffer emulation (3GPP S4-121077); an EID for 3GPP AMR bitstreams (eid-amr); a pseudo-random selection tool (random) for EVS processing scripts (3GPP S4-121078); SHQ2/SHQ3 half-band and HP50 high-pass FIR filters; and cross-platform portability fixes with expanded CTest regression coverage. + Since STL2019, the build toolchain uses CMake to generate platform-dependent and tool-dependent build scripts as well as to execute regression tests for each module in the STL. Modules have been tested on Windows, MacOS and several Linux flavors. @@ -195,6 +197,8 @@ \section{Acknowledgements} For the STL2024, the improvements to BS.1770 demo and WMC Tool were kindly provided by Mr Erik Norvell from Ericsson and Mr Vladimir Malenovsky from VoiceAge Corporation respectively. +For the STL2026, the dlyerr\_2\_errpat tool (delay/error profile to frame-erasure pattern converter) and the random tool were kindly contributed by Mr Stefan Doehla from Fraunhofer IIS via 3GPP SA4. The SHQ2/SHQ3 and HP50 FIR filters and the eid-amr tool (EID for 3GPP AMR bitstreams) were contributed by Mr St\'{e}phane Ragot. Mr Markus Multrus from Fraunhofer IIS contributed bug fixes to the basic operators documentation. The sv56 updates were provided by Mr Jan Reimes from HEAD acoustics. The WAV I/O support, integration of contributions, and maintenance of the GitHub repository were performed by Mr Ludovic Malfait (BT Group). + Above all, special thank goes to ITU-T SG16 Counselor Mr~Sim\~ao Ferraz de Campos Neto, the ``father'' of the STL. %============================================================================= @@ -236,6 +240,7 @@ \chapter{Tutorial} \item[STL2022] ITU-T Software Tools Library, release 2022. \item[STL2023] ITU-T Software Tools Library, release 2023. \item[STL2024] ITU-T Software Tools Library, release 2024. +\item[STL2026] ITU-T Software Tools Library, release 2026. \item[UGST] Users' Group on Software Tools, of ITU-T Study Group 16. \end{Descr} diff --git a/doc/manual/rate.tex b/doc/manual/rate.tex index e3fcf05c..584710c3 100644 --- a/doc/manual/rate.tex +++ b/doc/manual/rate.tex @@ -488,15 +488,17 @@ \section{Implementation} %-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- \subsection{FIR module} -The frequency responses of the implemented high-quality low-pass +The frequency responses of the implemented high-quality (HQ) low-pass filters are shown in figures \ref{hq-frq-1-2} and \ref{hq-frq-1-3} -(for rate-change factors 2 and 3, respectively), while the telephone +(denoted HQ2 and HQ3 in the command line, for rate-change factors 2 and 3, respectively), while the telephone bandwidth bandpass filter is given in figure \ref{hq-bandpass} (only a rate-change factor of 2 is available). The impulse responses of these filters are given in figures \ref{ir-hq-up}, \ref{ir-hq-down}, and \ref{ir-bandpass}, respectively for the up-sampling filters (factors 2 and 3), for the down-sampling filters (factors 2 and 3), -and for the bandpass filter. +and for the bandpass filter. + +Additional filters (SHQ2 and SHQ3 for super-high-quality for rate-change factors 2 and 3, respectively) with more taps (729 coefficients) and smaller transition band (stopband attenuation $-80$\,dB) are also provided; their frequency responses are given in figures \ref{shq2} and \ref{shq3}. These filters are intended for applications requiring higher spectral selectivity than the standard HQ filters, such as wideband and super-wideband codec characterization in 3GPP. The transmit-side IRS filter has been implemented for the ``regular'' and modified flavors. The regular transmit-side P.48 IRS filter @@ -546,6 +548,10 @@ \subsection{FIR module} the same routines are called, while for IRS, band-limiting or MUSHRA anchors, there is no rate-change routine from 16 to 32 kHz. +High-pass filters with 50 Hz cutoff frequency (3\,dB point) for the 32 and 48 kHz sampling rates (HP50\_32K with 1119 coefficients and HP50\_48K with 1679 coefficients) are also provided. Their frequency response is given in figure \ref{hp50}. + +Resampling filters as used in ITU-T Rec.\ P.863 (POLQA) and ITU-T Rec.\ P.863.2 (PAMD), also published in ETSI TR~103~138, are provided for rate-change factors 2, 3, 4 and~6 (with 256, 384, 512 and 768 taps, respectively). These filters use a normalized cutoff frequency of~0.475 and are intended for standardized resampling of speech signals between sampling rates of 8, 16 and~48~kHz. + Since the digital filters have memory, state variables are needed. In this version of the STL, a type {\tt SCD\_FIR} is defined, containing the past sample memory, as well as filter coefficients and other control @@ -583,7 +589,7 @@ \subsection{FIR module} (b) High-quality filter for down-sampling. \end{center} - \caption{\SF High-quality filter responses for a + \caption{\SF Super-high-quality filter responses for a factor of 2 and sampling rates of 8000 and 16000 Hz.\label{hq-frq-1-2}} @@ -603,13 +609,54 @@ \subsection{FIR module} (b) High-quality filter for down-sampling. \end{center} - \caption{\SF High-quality filter responses for a + \caption{\SF Super-high-quality filter responses for a factor of 3 and sampling rates of 8000 and 24000 Hz.\label{hq-frq-1-3}} \end{figure} %------------- End of FIR filters response: frq for factor 3 ---------------- +%----------- Begin of FIR filters response : frq for factor 2 --------------- +\begin{figure}[hbtp] + \begin{center} + %Both boxes' dimension: 15.24cm x 8.89cm + \includegraphics[scale=0.8]{shq2_up.pdf} + \\ + (a) Super-high-quality filter for up-sampling. + + \includegraphics[scale=0.8]{shq2_down.pdf} + \\ + (b) Super-high-quality filter for down-sampling. + + \end{center} + \caption{\SF Super-high-quality filter responses for a + factor of 2 and sampling rates of 8000 and + 16000 Hz.\label{shq2}} + +\end{figure} +%------------- End of FIR filters response: frq for factor 2 ---------------- + +%----------- Begin of FIR filters response: frq for factor 3 --------------- +\begin{figure}[hbtp] + \begin{center} + %Both boxes' dimension: 15.24cm x 8.89cm + \includegraphics[scale=0.8]{shq3_up.pdf} + \\ + (a) High-quality filter for up-sampling. + + \includegraphics[scale=0.8]{shq3_down.pdf} + \\ + (b) High-quality filter for down-sampling. + + \end{center} + \caption{\SF Super-high-quality filter responses for a + factor of 3 and sampling rates of 8000 and + 24000 Hz.\label{shq3}} + +\end{figure} +%------------- End of FIR filters response: frq for factor 3 ---------------- + + %----------- Begin of FIR filters response: frq for bandpass filter -------- \begin{figure}[hbtp] @@ -1142,6 +1189,26 @@ \subsection{FIR module} } \end{figure} %----- End of FIR filters response: impulse response for LP20 ----- + + +%----------- Begin of FIR filters response : frq for factor 2 --------------- +\begin{figure}[hbtp] + \begin{center} + %Both boxes' dimension: 15.24cm x 8.89cm + \includegraphics{hp50_32khz} + \\ + (a) 50Hz high-pass filter operating at 32 kHz. + + \includegraphics{hp50_48khz} + \\ + (b) 50Hz high-pass filter operating at 48 kHz. + + \end{center} + \caption{\SF 50Hz high-pass filter responses (32000 and 48000 Hz).\label{hp50}} + +\end{figure} +%------------- End of FIR filters response: frq for factor 2 ---------------- + \flushfloats @@ -1180,6 +1247,14 @@ \subsection{FIR module} SCD\_FIR *LP12\_48kHz\_init (void);\\ SCD\_FIR *LP14\_48kHz\_init (void);\\ SCD\_FIR *L20\_48kHz\_init (void);\\ +SCD\_FIR *p863\_up\_1\_to\_2\_init (void);\\ +SCD\_FIR *p863\_down\_2\_to\_1\_init (void);\\ +SCD\_FIR *p863\_up\_1\_to\_3\_init (void);\\ +SCD\_FIR *p863\_down\_3\_to\_1\_init (void);\\ +SCD\_FIR *p863\_up\_1\_to\_4\_init (void);\\ +SCD\_FIR *p863\_down\_4\_to\_1\_init (void);\\ +SCD\_FIR *p863\_up\_1\_to\_6\_init (void);\\ +SCD\_FIR *p863\_down\_6\_to\_1\_init (void);\\ } @@ -1398,6 +1473,46 @@ \subsection{FIR module} point for this filter is located at approximately 20000 Hz. Code is in file {\tt fir-LP.c}. +{\tt p863\_up\_1\_to\_2\_init} is the initialization routine for the +P.863/P.863.2 resampling FIR up-sampling filter by a factor of~2 +(256~taps, normalized cutoff frequency 0.475). Code is in file {\tt +fir-resamp.c}. + +{\tt p863\_down\_2\_to\_1\_init} is the initialization routine for the +P.863/P.863.2 resampling FIR down-sampling filter by a factor of~2 +(256~taps, normalized cutoff frequency 0.475). Code is in file {\tt +fir-resamp.c}. + +{\tt p863\_up\_1\_to\_3\_init} is the initialization routine for the +P.863/P.863.2 resampling FIR up-sampling filter by a factor of~3 +(384~taps, normalized cutoff frequency 0.475). Code is in file {\tt +fir-resamp.c}. + +{\tt p863\_down\_3\_to\_1\_init} is the initialization routine for the +P.863/P.863.2 resampling FIR down-sampling filter by a factor of~3 +(384~taps, normalized cutoff frequency 0.475). Code is in file {\tt +fir-resamp.c}. + +{\tt p863\_up\_1\_to\_4\_init} is the initialization routine for the +P.863/P.863.2 resampling FIR up-sampling filter by a factor of~4 +(512~taps, normalized cutoff frequency 0.475). Code is in file {\tt +fir-resamp.c}. + +{\tt p863\_down\_4\_to\_1\_init} is the initialization routine for the +P.863/P.863.2 resampling FIR down-sampling filter by a factor of~4 +(512~taps, normalized cutoff frequency 0.475). Code is in file {\tt +fir-resamp.c}. + +{\tt p863\_up\_1\_to\_6\_init} is the initialization routine for the +P.863/P.863.2 resampling FIR up-sampling filter by a factor of~6 +(768~taps, normalized cutoff frequency 0.475). Code is in file {\tt +fir-resamp.c}. + +{\tt p863\_down\_6\_to\_1\_init} is the initialization routine for the +P.863/P.863.2 resampling FIR down-sampling filter by a factor of~6 +(768~taps, normalized cutoff frequency 0.475). Code is in file {\tt +fir-resamp.c}. + \rulex{1mm} diff --git a/doc/manual/sv56.tex b/doc/manual/sv56.tex index b17938c6..24905375 100644 --- a/doc/manual/sv56.tex +++ b/doc/manual/sv56.tex @@ -220,13 +220,15 @@ \section{Implementation} needed in this approach. These state variables have been arranged as fields of a structure whose name is {\tt SVP56\_state}. The fields of the structure are\footnote{\SF All the fields are \double, except the -\float\ $f$ and the {\tt unsigned long} {\em a[]}, {\em hang[]}, and -{\em n}.}: +\float\ $f$, the {\tt int} {\em thres\_no} and {\em bitno}, and the +{\tt unsigned long} {\em a[]}, {\em hang[]}, and {\em n}.}: \begin{quote} \normalsize {\em f} \hfill \parbox{100mm}{\SF Sampling frequency, in Hz }\\ - {\em a[15]} \hfill \parbox{100mm}{\SF Activity count }\\ - {\em c[15]} \hfill \parbox{100mm}{\SF Threshold level }\\ - {\em hang[15]} \hfill \parbox{100mm}{\SF Hangover count }\\ + {\em a[]} \hfill \parbox{100mm}{\SF Activity count (size: {\em thres\_no}) }\\ + {\em c[]} \hfill \parbox{100mm}{\SF Threshold level (size: {\em thres\_no}) }\\ + {\em hang[]} \hfill \parbox{100mm}{\SF Hangover count (size: {\em thres\_no}) }\\ + {\em thres\_no} \hfill \parbox{100mm}{\SF Number of thresholds in use ($= bitno - 1$) }\\ + {\em bitno} \hfill \parbox{100mm}{\SF Bit depth of input signal (1--32, default 16) }\\ {\em n} \hfill \parbox{100mm}{\SF Number of samples read since last reset }\\ {\em s} \hfill \parbox{100mm}{\SF Sum of all samples since last @@ -270,7 +272,7 @@ \subsection{{\tt init\_speech\_voltmeter}} \#include "sv-p56.h"\\ void init\_speech\_voltmeter \pbox{110mm}{ - (SVP56\_state {\em *state}, double {\em f}); + (SVP56\_state {\em *state}, double {\em f}, int {\em bitno}); } } @@ -280,13 +282,21 @@ \subsection{{\tt init\_speech\_voltmeter}} {\tt init\_speech\_voltmeter} performs the initialization of the speech voltmeter state variables in the structure pointed by {\em -state} to the appropriate initial values. The only value required from -the user is the sampling rate $f$ (in Hz) of the signal that the speech -voltmeter is supposed to measure. Note that when measuring new +state} to the appropriate initial values. The user must specify the +sampling rate $f$ (in Hz) and the bit depth {\em bitno} of the signal +that the speech voltmeter is supposed to measure. The bit depth +determines the number of thresholds used ($B-1$) and must be in the +range 1 to 32. Note that when measuring new speech material, the state variable shall be re-initialized, otherwise accumulation of previous measurements will happen and wrong measurements will be reported. +The header file {\tt sv-p56.h} defines two constants that control the +maximum bit depth supported: +\begin{quote} \normalsize + {\tt SVP56\_MAX\_NO\_BITS} \hfill \parbox{100mm}{\SF Maximum bit depth supported (default: 32). }\\ + {\tt SVP56\_MAX\_THRESHOLDS} \hfill \parbox{100mm}{\SF Maximum number of thresholds ($=$ SVP56\_MAX\_NO\_BITS $-$ 1). } +\end{quote} {\bf Variables: } @@ -298,6 +308,12 @@ \subsection{{\tt init\_speech\_voltmeter}} Is the sampling rate (in Hz) of the signal to be measured in the next calls of {\tt speech\_voltmeter}. If zero or negative, the sampling rate is initialized to 16000 Hz. + +\item[\pbox{20mm}{\em bitno}] %\rulex{1mm}\\ + Is the bit depth (resolution) of the input signal, in the + range 1 to 32. This determines the number of threshold levels + used by the algorithm ($B-1$ thresholds). For standard + telephony, use 16. \end{Descr} {\bf Return value: } @@ -435,25 +451,30 @@ \section{Portability and compliance} input file, which is saved in an aoutput file. Levels are reported in dBov. -In general, input files are in integer representation, 16-bit words, -2's complement (i.e., {\tt short} data). In UGST convention, this -data must be left-adjusted, {\em rather} than right-adjusted. Since -the speech voltmeter uses {\tt float} input data, it is necessary to -convert from {\tt short} (in the mentioned format) to {\tt float}; -this is carried out by the function {\tt sh2fl()}. In addition, the -option to `normalize' the input data to the range -1..+1 is selected. +The example programs support variable bit-width input files from 8 to +32 bits per sample (controlled by the {\em bitno} parameter). Supported +storage widths are 8-bit (1 byte/sample), 16-bit (2 bytes/sample), +24-bit (3 bytes/sample), and 32-bit (4 bytes/sample). For bit depths +between 12 and 15, samples are stored in 2 bytes with the least +significant bits masked to zero. Files use native byte order. + +Since the speech voltmeter uses {\tt float} input data normalized to +the range --1.0..+1.0, the helper functions in {\tt sv56-util.h} handle +the conversion between raw integer samples and normalized floats: +{\tt sv56\_raw2fl()} reads raw bytes and normalizes by dividing by +$2^{bitno-1}$, and {\tt sv56\_fl2raw()} performs the inverse operation +with truncation and hard-clipping. After the equalization factor is found, results are reported on the screen, which varies according to the program used and some of the -command-line options. +command-line options. While program {\tt actlevel.c} stops at this point, program {\tt sv56demo.c} proceeds calling the function {\tt scale()} to carry out the (amplitude) equalization using single (rather than double) float precision. After equalization, the samples are converted back to -integer (short, right-justified) with the routine {\tt fl2sh()} using -truncation, no zero-padding of the least significant bits, -left-justification of data, and hard-clipping of data above the -overload point. After that, data is saved to the user-specified file . +raw integer format with {\tt sv56\_fl2raw()} using +truncation and hard-clipping of data above the +overload point. After that, data is saved to the user-specified file. %-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- @@ -471,7 +492,7 @@ \section{Portability and compliance} #include #include "ugstdemo.h" /* ... UGST demonstration program defs ... */ #include "sv-p56.h" /* ... SV-P56 prototypes & defs ... */ -#include "ugst-utl.h" /* ... UGST utilities ... */ +#include "sv56-util.h" /* ... SV56 I/O utilities ... */ #define BLK_LEN 256 void main(argc, argv) @@ -482,7 +503,8 @@ \section{Portability and compliance} char FileIn[180]; /* input file name */ FILE *Fi; /* input file pointers */ long N=BLK_LEN, l; - short bitno, buffer[BLK_LEN]; + int bitno, bps; + unsigned char raw_buf[BLK_LEN * 4]; float Buf[BLK_LEN]; double ActiveLeveldB, sf, satur; @@ -493,20 +515,21 @@ \section{Portability and compliance} FIND_PAR_D(2, "_Sampling Frequency: .. ", sf, 16000); FIND_PAR_L(3, "_A/D resolution: ...... ", bitno, 16); - /* Calculate overload point in the non-normalized range */ + /* Calculate bytes per sample and overload point */ + bps = sv56_bytes_per_sample(bitno); satur = pow ((double)2.0, (double)(bitno - 1)); /* Reset- variables for speech level measurements */ - init_speech_voltmeter(&state, sf); + init_speech_voltmeter(&state, sf, bitno); /* Opening input file */ Fi = fopen(FileIn, RB); /* Read samples ... */ - while ((l = fread(buffer, N, sizeof(short), Fi)) > 0) + while ((l = fread(raw_buf, bps, N, Fi)) > 0) { - /* ... Convert samples to float, normalizing to +1..-1 */ - sh2fl((long) l, buffer, Buf, (long) state.bitno, 1); + /* ... Convert raw samples to float, normalizing to +1..-1 */ + sv56_raw2fl((long) l, raw_buf, Buf, bitno); /* ... Get the active level */ ActiveLeveldB = speech_voltmeter(Buf, (long) l, &state); @@ -524,7 +547,7 @@ \section{Portability and compliance} printf("\n Maximum negative value: .. %7.0f [PCM]", SVP56_get_neg_max(state) * satur); printf("\n Long-term energy (rms): .. %7.3f [dBov]", - SVP56_get_rms_dB(state); + SVP56_get_rms_dB(state)); printf("\n Active speech level: ..... %7.3f [dBov]", ActiveLeveldB); printf("\n Activity factor: ......... %7.3f [%%]", SVP56_get_activity(state)); diff --git a/doc/manual/unsup.tex b/doc/manual/unsup.tex index b71d4c45..bb6d6b7c 100644 --- a/doc/manual/unsup.tex +++ b/doc/manual/unsup.tex @@ -68,6 +68,11 @@ \section{Source code} scaling factors (linear or dB), and adding a DC level. For Unix/MSDOS. +\item[random.c:] + randomization tool for selecting items from a list or + drawing numbers from a range. Reuses the EID linear + congruential generator from eid.c. For Unix/MSDOS. + \item[sb.c:] swap bytes for word-oriented files. For VMS/Unix/MSDOS. @@ -119,3 +124,178 @@ \section{Test files} \end{verbatim}} \end{Descr} + + +%---------------------------------------------------------------------- +\section{The {\tt random} tool} +\label{sec:random} +%---------------------------------------------------------------------- + +%---------------------------------------------------------------------- +\subsection{Introduction} +%---------------------------------------------------------------------- + +The {\tt random} tool provides deterministic pseudo-random selection +capabilities for use in speech and audio codec evaluation scripts. It +was originally developed for the EVS (Enhanced Voice Services) codec +processing scripts as specified in 3GPP S4-121078. + +The tool supports two modes of operation: +\begin{itemize} +\item {\bf Subset selection:} randomly select one or more items from a + provided list, sampling without replacement. +\item {\bf Range mode:} draw random integers from a specified numeric + range. +\end{itemize} + +Deterministic behavior is achieved through a seed-based linear +congruential sequence (LCS) generator, ensuring reproducible results +across platforms when the same seed is used. + +%---------------------------------------------------------------------- +\subsection{Description of the algorithm} +%---------------------------------------------------------------------- + +The pseudo-random number generator is inherited from the EID tool +({\tt eid.c}) in the STL. It implements a linear congruential +generator as described by Knuth~\cite{Knuth}: + +\[ + \mathrm{seed}_{n+1} = (69069 \times \mathrm{seed}_n + 1) \bmod 2^{32} +\] + +The generator returns a uniformly distributed value in $[0, 1)$ by +scaling: +\[ + r = 2^{-32} \times \mathrm{seed} +\] + +The {\tt unsigned int} type (32 bits on all modern platforms) is used +to ensure identical behavior on Windows, Linux, and macOS. + +\subsubsection{Subset mode} + +In subset mode, the tool selects {\em n} items from a list of {\em N} +items without replacement. For each selection: +\begin{enumerate} +\item A random index $k = \lfloor N \cdot r \rfloor$ is computed. +\item The item at position $k$ is output. +\item The item is removed from the list (remaining items shift down). +\item $N$ is decremented for the next draw. +\end{enumerate} + +\subsubsection{Range mode} + +In range mode, the tool draws {\em n} random integers from the +inclusive range $[\mathrm{start}, \mathrm{stop}]$. Each value is computed +as: +\[ + v = \mathrm{start} + \lfloor (\mathrm{stop} - \mathrm{start} + 1) \cdot r \rfloor +\] + +Note that in range mode, values are drawn independently (with +replacement). + +\subsubsection{Dummy pre-runs} + +An optional number of dummy pre-runs can be specified. These advance +the RNG state before selection begins, effectively providing a +secondary diversification mechanism beyond the seed value. + +%---------------------------------------------------------------------- +\subsection{Implementation} +%---------------------------------------------------------------------- + +The tool is implemented as a single source file {\tt random.c} in the +{\tt src/unsup/} directory. + +\subsubsection{Usage} + +{\tt +\begin{verbatim} +random [OPTIONS] [ITEM_LIST] +\end{verbatim} +} + +\subsubsection{Options} + +\begin{Descr}{40mm} +\item[\tt -s SEED] + Seed for the random number generator. Any value between 0 and + $2^{32}-1$. Default: 3141592653. + +\item[\tt -d PRERUNS] + Number of dummy pre-runs to advance the RNG state before + selection begins. Default: 0. + +\item[\tt -r START STOP] + Range mode: draw random integers from the inclusive range + $[\mathrm{START}, \mathrm{STOP}]$. When this option is specified, + no item list is expected. + +\item[\tt -n NUM\_ITEMS] + Number of items to select (subset mode) or numbers to draw + (range mode). Default: 1. + +\item[\tt -v] + Verbose output: shows the internal state of the item list + after each selection (subset mode only). + +\item[\tt -h] + Print usage information and exit. +\end{Descr} + +\subsubsection{Examples} + +\paragraph{Select one item from a list:} +{\tt +\begin{verbatim} +$ random -s 42 alpha bravo charlie delta echo +alpha +\end{verbatim} +} + +\paragraph{Select 3 items from a list with 3 dummy pre-runs:} +{\tt +\begin{verbatim} +$ random -s 42 -d 3 -n 3 alpha bravo charlie delta echo +bravo delta charlie +\end{verbatim} +} + +\paragraph{Draw 5 random integers from a range:} +{\tt +\begin{verbatim} +$ random -s 12345 -r 10 20 -n 5 +12 19 12 14 14 +\end{verbatim} +} + +\subsubsection{Limitations} + +\begin{itemize} +\item Maximum of 1000 items in subset mode. +\item The seed is parsed with {\tt atoi()}, limiting practical input to + signed integer range on some platforms. For full 32-bit range, + numeric overflow wraps as expected for unsigned arithmetic. +\end{itemize} + +%---------------------------------------------------------------------- +\subsection{Tests and portability} +%---------------------------------------------------------------------- + +Three CTest test cases validate the tool: + +\begin{enumerate} +\item {\bf random1:} Range mode with seed 12345, range $[10, 20]$, 5 + draws. Expected output: ``12 19 12 14 14''. +\item {\bf random2:} Subset mode with seed 42, selecting 1 item from 5. + Expected output starts with ``alpha''. +\item {\bf random3:} Subset mode with seed 42, 3 dummy pre-runs, + selecting 3 items from 5. Expected output: ``bravo delta charlie''. +\end{enumerate} + +Tests use {\tt PASS\_REGULAR\_EXPRESSION} to verify stdout matches +expected values, ensuring cross-platform reproducibility of the RNG +sequence. + diff --git a/doc/manual/utl.tex b/doc/manual/utl.tex index b8ec63d9..68ed8e29 100644 --- a/doc/manual/utl.tex +++ b/doc/manual/utl.tex @@ -534,6 +534,160 @@ \subsection{{\tt parallelize\_*\_justified}} parallel sample buffer. +%-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. +\section{WAV file I/O} \label{Utl-wav-io} + +The {\tt wav\_io} module provides transparent reading and writing of WAV +files alongside the traditional raw (headerless) PCM format used throughout +the STL. All tools that process audio PCM signals use this module to +auto-detect the input format and to select the output format based on the +output filename extension. + +\subsection{Design} + +\begin{itemize} +\item {\bf Input auto-detection:} When opening a file for reading, the first + four bytes are checked for the RIFF magic number ({\tt 0x52494646}). If + found, the file is parsed as a WAV file; otherwise it is treated as raw + PCM (legacy behavior). +\item {\bf Output format:} Determined solely by the output filename extension. + If the filename ends in {\tt .wav} (case-insensitive), a WAV file with a + canonical 44-byte header is written. Any other extension produces raw PCM + output, preserving full backward compatibility. +\item {\bf Supported formats:} 8-bit unsigned PCM, 16-bit signed PCM, 24-bit + signed PCM, 32-bit signed PCM, and 32-bit IEEE~754 float (format tags~1 + and~3). +\item {\bf Parameter validation:} The caller specifies expected sample rate, + channel count, and bit depth. If any expected value is non-zero and does not + match the WAV header, the file is rejected with an error. +\item {\bf Multi-channel:} When a multi-channel WAV file is opened by a mono + tool, channel~1 is extracted and a warning is printed to {\tt stderr}. +\end{itemize} + +\subsection{{\tt audio\_open\_read}} + +Opens a file for reading with automatic format detection. + +{\small +\begin{verbatim} +AUDIO_FILE *audio_open_read( + const char *filename, /* File to open */ + long expected_rate, /* Expected sample rate (0 = don't check) */ + int expected_channels, /* Expected channels (0 = don't check) */ + int expected_bits /* Expected bits/sample (0 = don't check) */ +); +\end{verbatim} +} + +Returns a pointer to an {\tt AUDIO\_FILE} structure, or {\tt NULL} on error. +For raw files, the file pointer is positioned at byte~0. For WAV files, it is +positioned at the start of the PCM data chunk. + +\subsection{{\tt audio\_open\_write}} + +Opens a file for writing. The format is determined by the filename extension. + +{\small +\begin{verbatim} +AUDIO_FILE *audio_open_write( + const char *filename, /* File to create */ + long sample_rate, /* Sample rate for WAV header */ + int channels, /* Channel count for WAV header */ + int bits_per_sample /* Bits per sample (8, 16, 24, or 32) */ +); +\end{verbatim} +} + +For WAV output, a 44-byte placeholder header is written on open and updated +with the correct data size on close. + +\subsection{{\tt audio\_read} and {\tt audio\_write}} + +Read and write samples in the native bit depth of the file: + +{\small +\begin{verbatim} +long audio_read(AUDIO_FILE *af, void *buffer, long nsamples); +long audio_write(AUDIO_FILE *af, void *buffer, long nsamples); +\end{verbatim} +} + +The buffer type must match the file's bit depth: + +\begin{center} +\begin{tabular}{lll} +\hline +{\bf Bit depth} & {\bf Buffer type} & {\bf Bytes/sample} \\ +\hline +8-bit PCM & {\tt unsigned char *} & 1 \\ +16-bit PCM & {\tt short *} & 2 \\ +24-bit PCM & {\tt long *} (sign-extended) & 3 on disk, 4 in memory \\ +32-bit PCM & {\tt long *} & 4 \\ +32-bit float & {\tt float *} & 4 \\ +\hline +\end{tabular} +\end{center} + +For multi-channel WAV input, {\tt audio\_read} de-interleaves and returns only +channel~1. Both functions return the number of samples actually read or +written. + +\subsection{{\tt audio\_close}} + +Closes the file. For WAV output, seeks back to the header and writes the +final data size and file size fields. + +{\small +\begin{verbatim} +void audio_close(AUDIO_FILE *af); +\end{verbatim} +} + +\subsection{Accessor functions} + +{\small +\begin{verbatim} +int audio_is_wav(AUDIO_FILE *af); /* 1 if WAV, 0 if raw */ +long audio_get_sample_rate(AUDIO_FILE *af); /* From WAV header, 0 if raw */ +int audio_get_channels(AUDIO_FILE *af); /* From WAV header, 0 if raw */ +\end{verbatim} +} + +\subsection{Usage example} + +The following fragment shows a 16-bit tool reading and writing WAV or raw: + +{\small +\begin{verbatim} +#include "wav_io.h" + +AUDIO_FILE *in, *out; +short buf[256]; +long n; + +in = audio_open_read("input.wav", 8000, 1, 16); +out = audio_open_write("output.wav", 8000, 1, 16); + +while ((n = audio_read(in, buf, 256)) > 0) { + /* process buf[] */ + audio_write(out, buf, n); +} + +audio_close(out); +audio_close(in); +\end{verbatim} +} + +A 24-bit tool would use {\tt long} buffers and pass 24 for {\tt expected\_bits}: + +{\small +\begin{verbatim} +AUDIO_FILE *in = audio_open_read("hires.wav", 48000, 1, 24); +long buf[256]; +audio_read(in, buf, 256); /* 24-bit values sign-extended into long */ +\end{verbatim} +} + %-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. \section{Portability and compliance} \label{Utl-port} diff --git a/doc/md_to_docx.sh b/doc/md_to_docx.sh old mode 100644 new mode 100755 diff --git a/src/basop/test_framework/CMakeLists.txt b/src/basop/test_framework/CMakeLists.txt index 61cf933a..07121290 100644 --- a/src/basop/test_framework/CMakeLists.txt +++ b/src/basop/test_framework/CMakeLists.txt @@ -14,18 +14,20 @@ file(MAKE_DIRECTORY ./test_data ) add_test( NAME basop_sanity_test WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test_data COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/basop_test Test_type=0 ) add_test( NAME basop_precision_vectors WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test_data COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/basop_test Test_type=1 ) -# List all reference files and compare each of them +# List all reference files and compare each of them (CRLF-tolerant) file(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/test/test_ref/*.csv") foreach(file ${files}) # Extract basename get_filename_component( basename ${file} NAME ) - # Perform diff - add_test( basop_precision_test_${basename} - ${CMAKE_COMMAND} -E compare_files - ${CMAKE_CURRENT_SOURCE_DIR}/test/test_ref/${basename} - ${CMAKE_CURRENT_SOURCE_DIR}/test_data/${basename} + # Perform diff (line-ending tolerant) + add_test( NAME basop_precision_test_${basename} + COMMAND ${CMAKE_COMMAND} + -DGOT=${CMAKE_CURRENT_SOURCE_DIR}/test_data/${basename} + -DEXPECTED=${CMAKE_CURRENT_SOURCE_DIR}/test/test_ref/${basename} + -DLABEL=basop_${basename} + -P ${CMAKE_CURRENT_SOURCE_DIR}/compare_basop_csv.cmake ) endforeach() diff --git a/src/basop/test_framework/compare_basop_csv.cmake b/src/basop/test_framework/compare_basop_csv.cmake new file mode 100644 index 00000000..8b38550c --- /dev/null +++ b/src/basop/test_framework/compare_basop_csv.cmake @@ -0,0 +1,4 @@ +# Compare a basop test output CSV against its reference, tolerating CRLF. +# Invoked via: cmake -DGOT=... -DEXPECTED=... -DLABEL=... -P compare_basop_csv.cmake +include(${CMAKE_CURRENT_LIST_DIR}/../../../cmake/CompareTextFiles.cmake) +compare_text_files(GOT "${GOT}" EXPECTED "${EXPECTED}" LABEL "${LABEL}") diff --git a/src/basop/test_framework/test/test_precision.c b/src/basop/test_framework/test/test_precision.c index 9f8f298d..d3bae3e6 100755 --- a/src/basop/test_framework/test/test_precision.c +++ b/src/basop/test_framework/test/test_precision.c @@ -450,14 +450,14 @@ void print_test_out(int test_index, FILE * fp, int index, int f_type1, char *fnm case DATA_TYPE_FLOAT_L: { float * outf_d = (float *)((char *)out_dut + (sizeof(float)*index)); - unsigned long * res = (unsigned long *)outf_d; + unsigned int * res = (unsigned int *)outf_d; fprintf(fp, "%X,\n", *res); } break; case DATA_TYPE_LONG: { int * outf_d = (int *)((char *)out_dut + (sizeof(int)*index)); - unsigned long * res = (unsigned long *)outf_d; + unsigned int * res = (unsigned int *)outf_d; fprintf(fp, "%X,\n", *res); } break; @@ -471,7 +471,7 @@ void print_test_out(int test_index, FILE * fp, int index, int f_type1, char *fnm { f_cmplx * outf_d = (f_cmplx *)((char *)out_dut + (sizeof(f_cmplx)*index)); float res = (sqrt(outf_d->re*outf_d->re + outf_d->im*outf_d->im)); - unsigned long *res1 = (unsigned long *)&res; + unsigned int *res1 = (unsigned int *)&res; fprintf(fp, "%X,\n", *res1); } break; @@ -479,7 +479,7 @@ void print_test_out(int test_index, FILE * fp, int index, int f_type1, char *fnm { f_cmplx * outf_d = (f_cmplx *)((char *)out_dut + (sizeof(f_cmplx)*index)); float res = sqrt((outf_d->re*outf_d->re + outf_d->im*outf_d->im)); - unsigned long *res1 = (unsigned long *)&res; + unsigned int *res1 = (unsigned int *)&res; fprintf(fp, "%X,\n", *res1); } break; diff --git a/src/bs1770demo/CMakeLists.txt b/src/bs1770demo/CMakeLists.txt index daba5f89..619dbd5a 100644 --- a/src/bs1770demo/CMakeLists.txt +++ b/src/bs1770demo/CMakeLists.txt @@ -1,4 +1,6 @@ -add_executable(bs1770demo bs1770demo.c) +include_directories(../utl) + +add_executable(bs1770demo bs1770demo.c ../utl/wav_io.c) target_link_libraries(bs1770demo ${M_LIBRARY}) diff --git a/src/bs1770demo/bs1770demo.c b/src/bs1770demo/bs1770demo.c index 84ec2f77..4bf03cb7 100644 --- a/src/bs1770demo/bs1770demo.c +++ b/src/bs1770demo/bs1770demo.c @@ -10,6 +10,7 @@ #include #include #include +#include "wav_io.h" #define BLOCK_SIZE 19200 /* 400 ms in 48000 Hz sample rate */ #define STEP_SIZE 4800 /* 100 ms in 48000 Hz sample rate (75% overlap of 400 ms gating blocks) */ @@ -387,8 +388,8 @@ long parse_conf( /* o: 0:success, -1:fail */ int main(int argc, char **argv ) { - FILE* f_input; - FILE* f_output; + AUDIO_FILE* f_input; + AUDIO_FILE* f_output; char *input_filename; char *output_filename; double *input; @@ -477,7 +478,7 @@ int main(int argc, char **argv ) } input_filename = argv[i++]; - if( (f_input = fopen( input_filename, "rb" )) == NULL ) + if( (f_input = audio_open_read (input_filename, 48000, 0, 16)) == NULL ) { fprintf( stderr, "*** Could not open input file %s, exiting..\n\n", input_filename ); usage(); @@ -489,7 +490,7 @@ int main(int argc, char **argv ) else { output_filename = argv[i]; - if( (f_output = fopen( output_filename, "wb" )) == NULL ) + if( (f_output = audio_open_write( output_filename, audio_get_sample_rate (f_input), 1, 16 )) == NULL ) { fprintf( stderr, "*** Could not open output file %s, exiting..\n\n", output_filename ); usage(); @@ -541,9 +542,8 @@ int main(int argc, char **argv ) fprintf( stdout, "nchan: %ld\n", nchan ); /* Find length of input file */ - fseek( f_input, 0L, SEEK_END ); - length_total = ftell( f_input ) / (2*nchan); /* 2 bytes per sample (16 bits), nchan channels */ - if( (ftell( f_input ) % (2 * nchan)) != 0 ) + length_total = audio_get_data_size( f_input ) / (2*nchan); /* 2 bytes per sample (16 bits), nchan channels */ + if( (audio_get_data_size( f_input ) % (2 * nchan)) != 0 ) { fprintf( stderr, "*** Number of samples not divisible into number of channels, exiting..\n" ); exit( -1 ); @@ -553,7 +553,7 @@ int main(int argc, char **argv ) fprintf( stderr, "*** Input file must be longer than 400 ms to use bs1770demo, exiting..\n" ); exit( -1 ); } - rewind( f_input ); + audio_seek( f_input, 0L ); n_gating_blocks = 4 * (length_total - BLOCK_SIZE) / (BLOCK_SIZE); /* Allocate input buffers */ @@ -572,7 +572,7 @@ int main(int argc, char **argv ) for( n = 0, j = -3; j < n_gating_blocks; n++, j++ ) { /* Read next sub-block */ - fread( input_short, sizeof( short ), STEP_SIZE * nchan, f_input ); + fread( input_short, sizeof( short ), STEP_SIZE * nchan, f_input->fp ); deinterleave_short2double( input_short, input, STEP_SIZE * nchan, nchan ); @@ -610,16 +610,16 @@ int main(int argc, char **argv ) fac = find_scaling_factor( gating_block_energy, n_gating_blocks, lev_target, rms_flag, &lev_input, &lev_obtained ); /* Apply scaling */ - rewind( f_input ); + audio_seek( f_input, 0L ); length_total = 0; clip = 0; - while( (length = (long)fread( input_short, sizeof( short ), STEP_SIZE * nchan, f_input ) ) ) + while( (length = (long)fread( input_short, sizeof( short ), STEP_SIZE * nchan, f_input->fp ) ) ) { deinterleave_short2double( input_short, input, STEP_SIZE * nchan, nchan ); scale(input, fac, input, STEP_SIZE * nchan ); clip += interleave_double2short( input, input_short, STEP_SIZE * nchan, nchan ); length_total += length / nchan; - fwrite( input_short, sizeof( short ), length, f_output ); + fwrite( input_short, sizeof( short ), length, f_output->fp ); } fprintf( stdout, "Input level: %.6f\n", lev_input ); @@ -633,7 +633,7 @@ int main(int argc, char **argv ) fprintf( stderr, "*** Warning: %ld samples clipped\n", clip ); } - fclose( f_output ); + audio_close( f_output ); } else { @@ -666,7 +666,7 @@ int main(int argc, char **argv ) } /* Close files */ - fclose( f_input ); + audio_close( f_input ); /* Deallocate memory */ free( input ); diff --git a/src/eid/CMakeLists.txt b/src/eid/CMakeLists.txt index a83eb223..f86dd01d 100644 --- a/src/eid/CMakeLists.txt +++ b/src/eid/CMakeLists.txt @@ -103,3 +103,45 @@ add_test(eid-xor ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/eid-xor -fer -bs bit -ep g192 add_test(eid-xor ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/eid-xor -fer -bs bit -ep byte test_data/zero.src test_data/epf05g10.byt test_data/z_f05g10.bby) add_test(eid-xor ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/eid-xor -fer -bs bit -ep bit test_data/zero.src test_data/epf05g10.bit test_data/z_f05g10.bbi) + +#--- dlyerr_2_errpat: delay/error profile to frame-erasure pattern (from 3GPP S4-121077) +add_executable(dlyerr_2_errpat dlyerr_2_errpat.c softbit.c) +target_link_libraries(dlyerr_2_errpat ${M_LIBRARY}) + +# default text format, constant delay +add_test(dlyerr_2_errpat1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/dlyerr_2_errpat + -i test_data/profile.dat -o test_data/t1_text.proc -L 30 -d 40) +add_test(dlyerr_2_errpat1-verify ${CMAKE_COMMAND} -E compare_files --ignore-eol + test_data/t1_text.ref test_data/t1_text.proc) + +# LF text format +add_test(dlyerr_2_errpat2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/dlyerr_2_errpat + -i test_data/profile.dat -o test_data/t2_lf.proc -L 30 -d 40 -c) +add_test(dlyerr_2_errpat2-verify ${CMAKE_COMMAND} -E compare_files --ignore-eol + test_data/t2_lf.ref test_data/t2_lf.proc) + +# word G.192 format with frame aggregation +add_test(dlyerr_2_errpat3 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/dlyerr_2_errpat + -i test_data/profile.dat -o test_data/t3_word.proc -L 30 -d 40 -w -f 2) +add_test(dlyerr_2_errpat3-verify ${CMAKE_COMMAND} -E compare_files + test_data/t3_word.ref test_data/t3_word.proc) + +# late-loss-rate driven threshold +add_test(dlyerr_2_errpat4 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/dlyerr_2_errpat + -i test_data/profile.dat -o test_data/t4_lateloss.proc -L 30 -l 5.0) +add_test(dlyerr_2_errpat4-verify ${CMAKE_COMMAND} -E compare_files --ignore-eol + test_data/t4_lateloss.ref test_data/t4_lateloss.proc) + +#--- eid-amr: EID for 3GPP AMR codec (from 3GPP S4-120998) +add_executable(eid-amr eid-amr.c softbit.c) +target_link_libraries(eid-amr ${M_LIBRARY}) + +add_test(eid-amr1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/eid-amr + test_data/bst475.amr test_data/bf03.g192 test_data/bst475_bf03.tst) +add_test(eid-amr1-verify ${CMAKE_COMMAND} -E compare_files + test_data/bst475_bf03.amr test_data/bst475_bf03.tst) + +add_test(eid-amr2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/eid-amr + test_data/bst122.amr test_data/bf06.g192 test_data/bst122_bf06.tst) +add_test(eid-amr2-verify ${CMAKE_COMMAND} -E compare_files + test_data/bst122_bf06.amr test_data/bst122_bf06.tst) diff --git a/src/eid/README.md b/src/eid/README.md index 6918115c..7cf55033 100644 --- a/src/eid/README.md +++ b/src/eid/README.md @@ -20,6 +20,8 @@ The "Error Insertion Device" (EID) module is built of the following files: eid-int.c: .... Interpolates error patterns from a master EP eid-xor.c: .... Disturbs bits or erases frames based on error patterns + eid-amr.c: .... EID for 3GPP AMR codec (frame erasures via G.192 patterns) + dlyerr_2_errpat.c: Delay/error profile to frame-erasure pattern converter ep-stats.c: ... Assesses and prints statistics about an error pattern file gen-patt.c: ... Generates error pattern files softbit.c: .... Library with softbit file I/O and format check @@ -263,5 +265,68 @@ little-endian computers (PC/VAX/Alpha) are: Has not been implemented yet. +<<<<<<< HEAD + +## dlyerr_2_errpat: Delay/error profile to frame-erasure pattern + +Converts a delay-and-error profile (one integer per line: network delay in ms, +or -1 for network loss) into a frame-erasure error pattern for use with +`eid-xor`. Supports two jitter buffer management emulation modes. + +Usage: + + dlyerr_2_errpat [options] + + -i delay/error profile (required) + -o error pattern output (required) + -d constant-JBM-delay mode (milliseconds) + -l bounded-loss-rate mode (percent) + -L output length in frames (default: 7500) + -s skip offset frames into the profile + -f <1|2> frames per packet (default: 1) + -w word-oriented G.192 output + -b byte-oriented G.192 output + -c text mode with LF (one entry per line) + +Exactly one of `-d` or `-l` must be supplied. + +Input format: one integer per line. Values 0--1999 represent network delay in +milliseconds; -1 indicates network loss (packet never arrived). If the input +file is shorter than `-L` frames, it wraps around. + +Output: `0` = good frame, `1` = lost frame (text mode); or G.192 binary +equivalent with `-w` or `-b` flags. + +Example (fixed JBM delay of 200ms, word G.192 output): + + dlyerr_2_errpat -d 200 -f 1 -w -s 100 -i profile.dat -o ep.g192 + eid-xor -fer -ep g192 bitstream.g192 ep.g192 output.g192 + +Originally provided by Fraunhofer IIS via 3GPP Tdoc S4-121077 +(TSGS4#70, Chicago, 13--17 Aug 2012), in support of the EVS codec +processing plan. + +## EID-AMR: Error Insertion Device for 3GPP AMR codec + +The `eid-amr` tool provides frame erasure simulation for 3GPP AMR bitstreams +using G.192 error patterns. The `eid-xor` tool is not directly applicable to +AMR because the AMR bitstream follows the ETSI/3GPP format (TS 26.073 §6.3), +which is not compliant with ITU-T G.192. + +Derived from the EID-3G tool (Nobuhiko Naka, NTT DOCOMO). Differences: +- No position parameter (consistent with `eid-xor` usage). +- Only frame erasures (no bit errors). +- All data bits in an erased frame are forced to zero. +- Lost frames signalled with frame type NO\_DATA (0x03). +- Statistics reported to stderr. + +Usage: + + eid-amr + +Originally submitted to 3GPP in Tdoc S4-120998 (Aug. 2012). +Authors: Balazs Kovesi, Stephane Ragot (Orange SA). + + Good luck! -- diff --git a/src/eid/bs-stats.c b/src/eid/bs-stats.c index be380291..7de91771 100644 --- a/src/eid/bs-stats.c +++ b/src/eid/bs-stats.c @@ -213,7 +213,7 @@ int main (int argc, char *argv[]) { /* Command line parameters */ char bs_format = g192; /* Generic Speech bitstream format */ char ibs_file[MAX_STRLEN]; /* Input bitstream file */ - char out_file[MAX_STRLEN]; /* Output ASCII file */ + char out_file[MAX_STRLEN] = "-"; /* Output ASCII file */ char log = 1; /* Flag for en/dis-abling output file */ long fr_len = 0; /* Frame length in bits */ long bs_len; /* BS frame length, with headers */ diff --git a/src/eid/dlyerr_2_errpat.c b/src/eid/dlyerr_2_errpat.c new file mode 100644 index 00000000..e139e36e --- /dev/null +++ b/src/eid/dlyerr_2_errpat.c @@ -0,0 +1,253 @@ +/*---------------------------------------------------------------------------* + * Delay-and-error profile to FER pattern conversion tool, V1.2 * + * ------------------------------------------ * + * (C) 2012 Fraunhofer IIS. * + * * + * =============================================================== * + * COPYRIGHT NOTE: This source code, and all of its derivations, * + * is subject to the "ITU-T General Public License". Please have * + * it read in the distribution disk, or in the ITU-T Recommendation * + * G.191 on "SOFTWARE TOOLS FOR SPEECH AND AUDIO CODING STANDARDS". * + * See LICENSE.md in the top-level directory for terms. * + * =============================================================== * + * * + * Fraunhofer IIS makes no representation nor warranty in regard to * + * the accuracy, completeness or sufficiency of The Software, nor * + * shall Fraunhofer IIS be held liable for any damages whatsoever * + * relating to use of said Software. * + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include "ugstdemo.h" +#include "softbit.h" + +static void usage() { + fprintf(stdout, "\nConvert a delay and error profile to an error pattern\n"); + fprintf(stdout, "\nValid commandline switches:\n"); + fprintf(stdout, "-i \n"); + fprintf(stdout, "-o \n"); + fprintf(stdout, "-L \n"); + fprintf(stdout, "-s \n"); + fprintf(stdout, "-f [1;2]\n"); + fprintf(stdout, "-l \n"); + fprintf(stdout, "-b use byte-oriented G.192 format (0x21 okay, 0x20 lost)\n"); + fprintf(stdout, "-w use word-oriented G.192 format (0x6b21 okay, 0x6b20 lost)\n"); + fprintf(stdout, "-c use LF for text format to have one entry per line - was default in V1.0\n"); + fprintf(stdout, "-d \n"); + fprintf(stdout, " either -l or -d parameter must be supplied (not both!) and a valid inputfile\n"); +} + +/* Write one frame erasure flag to output */ +static void write_flag(short flag, int useG192, int useG192WordOriented, int useLF, FILE *outfile) { + if (useG192) { + if (useG192WordOriented) + save_g192(&flag, 1, outfile); + else + save_byte(&flag, 1, outfile); + } else { + /* Text mode: 0 = good, 1 = erased */ + if (useLF) + fprintf(outfile, "%c\n", flag == G192_FER ? '1' : '0'); + else + fprintf(outfile, "%c", flag == G192_FER ? '1' : '0'); + } +} + +int main(int argc, char **argv) { + int i; + char *infilename = NULL; + char *outfilename = NULL; + float late_loss_rate = 0.0f; + unsigned int constant_delay_ms = 0; + int shift = 0; + int length = 7500; + unsigned int framesPerPacket = 1; /* no aggregation by default */ + int useG192 = 0; + int useG192WordOriented = 0; + int useLF = 0; + int retval = 0; + + char line[64] = {0}; + unsigned int delayCount[2001] = {0}; /* [-1;1999] ms */ + unsigned int line_cnt = 0; + + FILE *infile = NULL; + FILE *outfile = NULL; + + while (argc > 1 && argv[1][0] == '-') { + if (strcmp(argv[1], "-i") == 0) { + if (argc < 3) { usage(); return -1; } + infilename = argv[2]; + argc -= 2; argv += 2; + } else if (strcmp(argv[1], "-o") == 0) { + if (argc < 3) { usage(); return -1; } + outfilename = argv[2]; + argc -= 2; argv += 2; + } else if (strcmp(argv[1], "-l") == 0) { + if (argc < 3) { usage(); return -1; } + late_loss_rate = (float)atof(argv[2]); + argc -= 2; argv += 2; + } else if (strcmp(argv[1], "-d") == 0) { + if (argc < 3) { usage(); return -1; } + constant_delay_ms = atoi(argv[2]); + argc -= 2; argv += 2; + } else if (strcmp(argv[1], "-s") == 0) { + if (argc < 3) { usage(); return -1; } + shift = atoi(argv[2]); + argc -= 2; argv += 2; + } else if (strcmp(argv[1], "-L") == 0) { + if (argc < 3) { usage(); return -1; } + length = atoi(argv[2]); + argc -= 2; argv += 2; + } else if (strcmp(argv[1], "-f") == 0) { + if (argc < 3) { usage(); return -1; } + framesPerPacket = atoi(argv[2]); + argc -= 2; argv += 2; + } else if (strcmp(argv[1], "-b") == 0) { + useG192 = 1; + argc--; argv++; + } else if (strcmp(argv[1], "-w") == 0) { + useG192 = 1; + useG192WordOriented = 1; + argc--; argv++; + } else if (strcmp(argv[1], "-c") == 0) { + useLF = 1; + argc--; argv++; + } else if (strcmp(argv[1], "-?") == 0 || strcmp(argv[1], "-help") == 0 || strcmp(argv[1], "--help") == 0) { + usage(); + return 0; + } else { + fprintf(stderr, "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]); + usage(); + return -1; + } + } + + if ((infilename == NULL) || ((late_loss_rate == 0) && (constant_delay_ms == 0)) || + framesPerPacket == 0U || framesPerPacket > 2U) { + usage(); + return -1; + } + + infile = fopen(infilename, "r"); + if (!infile) { + fprintf(stderr, "unable to open %s\n", infilename); + return -2; + } + + if (outfilename) { + outfile = fopen(outfilename, useG192 ? WB : "w"); + if (!outfile) { + fprintf(stderr, "unable to open %s\n", outfilename); + retval = -2; + goto cleanup; + } + } + + /* read offset to Nirvana */ + for (i = 0; i < shift; i++) { + if (!fgets(line, 63, infile)) { + fprintf(stderr, "shift out of range\n"); + retval = -3; + goto cleanup; + } + } + + /* create delay histogram */ + for (i = 0; i < length; i++) { + int delay_ms; + if (!fgets(line, 63, infile)) { + rewind(infile); + if (!fgets(line, 63, infile)) { + fprintf(stderr, "unable to rewind and read file\n"); + retval = -4; + goto cleanup; + } + } + line_cnt++; + delay_ms = atoi(line); + if ((delay_ms < -1) || (delay_ms > 1999)) { + fprintf(stderr, "value in line %u out of range - aborting\n", line_cnt); + retval = -5; + goto cleanup; + } + if (delay_ms == -1) + delayCount[2000]++; + else + delayCount[delay_ms]++; + } + + if (late_loss_rate) { + unsigned int late_loss_cnt = 0; + for (i = 1999; i >= 0; i--) { + float current_late_loss_rate; + late_loss_cnt += delayCount[i]; + current_late_loss_rate = ((float)late_loss_cnt * 100.0f) / (float)line_cnt; + if (current_late_loss_rate > late_loss_rate) { + constant_delay_ms = i; + fprintf(stdout, "selected %ims to stay below %f late loss\n", i, late_loss_rate); + break; + } + } + } + + /**** emulate constant delay JBM with given delay ****/ + fseek(infile, 0, SEEK_SET); + + /* read offset to nirvana, again */ + for (i = 0; i < shift; i++) { + if (!fgets(line, 63, infile)) { + fprintf(stderr, "shift out of range\n"); + retval = -3; + goto cleanup; + } + } + + if (constant_delay_ms) { + unsigned int late_loss_cnt = 0; + unsigned int network_loss_cnt = 0; + unsigned int iFramePerPacket; + for (i = 0; i < length; i++) { + int delay_ms; + short flag; + if (!fgets(line, 63, infile)) { + rewind(infile); + if (!fgets(line, 63, infile)) { + fprintf(stderr, "unable to rewind and read file\n"); + retval = -4; + goto cleanup; + } + } + delay_ms = atoi(line); + + if (delay_ms == -1) { + network_loss_cnt++; + flag = G192_FER; + } else if ((unsigned int)delay_ms > constant_delay_ms) { + late_loss_cnt++; + flag = G192_FER; + } else { + flag = G192_SYNC; + } + + if (outfile) { + for (iFramePerPacket = 0; iFramePerPacket != framesPerPacket; ++iFramePerPacket) + write_flag(flag, useG192, useG192WordOriented, useLF, outfile); + } + } + + fprintf(stdout, "#processed delay and error values: %u\n", line_cnt); + fprintf(stdout, "network loss rate: %.3f%%\n", ((float)network_loss_cnt * 100.0f) / (float)line_cnt); + fprintf(stdout, "late loss rate: %.3f%%\n", ((float)late_loss_cnt * 100.0f) / (float)line_cnt); + fprintf(stdout, "distorted frames: %u\n", framesPerPacket * (network_loss_cnt + late_loss_cnt)); + } + +cleanup: + fclose(infile); + if (outfile) + fclose(outfile); + + return retval; +} diff --git a/src/eid/eid-amr.c b/src/eid/eid-amr.c new file mode 100644 index 00000000..6b9d3094 --- /dev/null +++ b/src/eid/eid-amr.c @@ -0,0 +1,107 @@ +/* + eid-amr.c + + EID for AMR using G.192 error pattern of frame erasures. + This tool is based on the eid-3g tool written by Nobuhiko Naka, NTT DOCOMO + (see: http://www.3gpp.org/ftp/tsg_sa/WG4_CODEC/AMR-NB_3G-Characterization/EID_Error_Patterns/) + + Modifications: + - using G.192 error pattern for frame erasures + - only frame erasures (no bit errors) + - no position parameter to skip frames (usage similar to ITU-T STL eid-xor tool) + - all data bits in a lost frame are forced to a value of 0 + - statistics reported to stderr at the end of processing + - uses softbit.c read_g192() for error pattern reading + + NOTES: + A lost frame in DTX on/off is signalled with a frame type code 0x03, + independently from the TX or RX frame type. + + Contact: + Balazs Kovesi, Stephane Ragot + ORANGE SA + firstname.lastname@orange.com + + =============================================================== + COPYRIGHT NOTE: This source code, and all of its derivations, + is subject to the "ITU-T General Public License". Please have + it read in the distribution disk, or in the ITU-T Recommendation + G.191 on "SOFTWARE TOOLS FOR SPEECH AND AUDIO CODING STANDARDS". + See LICENSE.md in the top-level directory for terms. + =============================================================== +*/ + +#include +#include +#include +#include "ugstdemo.h" +#include "softbit.h" + +#define MAX_SERIAL 244 +#define SERIAL_FRAMESIZE (1 + MAX_SERIAL + 5) + +int main(int argc, char *argv[]) { + short spch[SERIAL_FRAMESIZE]; + short epat; + + FILE *fsp, *fep, *fwe; + + long frame, fercnt, wrapcnt; + int i; + + if (argc != 4) { + fprintf(stderr, "eid-amr: EID for 3GPP AMR codec using G.192 frame erasure patterns\n\n"); + fprintf(stderr, "Usage: eid-amr \n"); + exit(1); + } + + if ((fsp = fopen(argv[1], RB)) == NULL) { perror(argv[1]); exit(1); } + if ((fep = fopen(argv[2], RB)) == NULL) { perror(argv[2]); exit(1); } + if ((fwe = fopen(argv[3], WB)) == NULL) { perror(argv[3]); exit(1); } + + frame = 0; + fercnt = 0; + wrapcnt = 0; + + while (fread(spch, sizeof(short), SERIAL_FRAMESIZE, fsp) == SERIAL_FRAMESIZE) { + /* Read one erasure flag from G.192 error pattern */ + if (read_g192(&epat, 1, fep) != 1) { + fseek(fep, 0L, SEEK_SET); + fprintf(stderr, "Warning: Error pattern file shorter than speech file\n--> wrap error pattern file\n"); + wrapcnt++; + if (read_g192(&epat, 1, fep) != 1) { + fprintf(stderr, "Error: Error pattern file read failure\n"); + exit(1); + } + } + + if (epat == G192_FER) { + spch[0] = 0x03; /* NO_DATA frame type */ + fercnt++; + for (i = 0; i < MAX_SERIAL; i++) { + spch[i + 1] = 0; /* erase bits in bad frame (force value of 0) */ + } + } else if (epat != G192_SYNC) { + fprintf(stderr, "Error: invalid pattern value 0x%04X at frame %ld\n", (unsigned short)epat, frame); + exit(1); + } + + fwrite(spch, sizeof(short), SERIAL_FRAMESIZE, fwe); + frame++; + } + + fclose(fsp); + fclose(fep); + fclose(fwe); + + fprintf(stderr, "_Input bit stream file ..................: %s\n", argv[1]); + fprintf(stderr, "_Error pattern file .....................: %s\n", argv[2]); + fprintf(stderr, "_Output bit stream file .................: %s\n", argv[3]); + fprintf(stderr, "# Error pattern files wrapped ...........: %ld times\n", wrapcnt); + fprintf(stderr, "# Processed frames ..................... : %ld\n", frame); + fprintf(stderr, "# Distorted frames ..................... : %ld\n", fercnt); + if (frame > 0) + fprintf(stderr, "# Frame erasure rate ....................: %f %%\n", (100.0 * fercnt) / frame); + + return 0; +} diff --git a/src/eid/softbit.h b/src/eid/softbit.h index 02b396d8..4cf067d3 100644 --- a/src/eid/softbit.h +++ b/src/eid/softbit.h @@ -16,7 +16,7 @@ /* ......... Smart prototypes .......... */ #ifndef ARGS -#if (defined(__STDC__) || defined(VMS) || defined(__DECC) || defined(MSDOS) || defined(__MSDOS__)) +#if (defined(__STDC__) || defined(VMS) || defined(__DECC) || defined(MSDOS) || defined(__MSDOS__) || defined(_MSC_VER)) #define ARGS(x) x #else #define ARGS(x) () diff --git a/src/eid/test_data/bf03.g192 b/src/eid/test_data/bf03.g192 new file mode 100644 index 00000000..d2449ec4 --- /dev/null +++ b/src/eid/test_data/bf03.g192 @@ -0,0 +1 @@ +!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k \ No newline at end of file diff --git a/src/eid/test_data/bf06.g192 b/src/eid/test_data/bf06.g192 new file mode 100644 index 00000000..999e8ecf --- /dev/null +++ b/src/eid/test_data/bf06.g192 @@ -0,0 +1 @@ +!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k k!k!k!k!k!k!k!k!k k!k!k!k!k k k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k!k \ No newline at end of file diff --git a/src/eid/test_data/bst122.amr b/src/eid/test_data/bst122.amr new file mode 100644 index 00000000..43eb1645 Binary files /dev/null and b/src/eid/test_data/bst122.amr differ diff --git a/src/eid/test_data/bst122_bf06.amr b/src/eid/test_data/bst122_bf06.amr new file mode 100644 index 00000000..11097c7f Binary files /dev/null and b/src/eid/test_data/bst122_bf06.amr differ diff --git a/src/eid/test_data/bst475.amr b/src/eid/test_data/bst475.amr new file mode 100644 index 00000000..7cc7b95e Binary files /dev/null and b/src/eid/test_data/bst475.amr differ diff --git a/src/eid/test_data/bst475_bf03.amr b/src/eid/test_data/bst475_bf03.amr new file mode 100644 index 00000000..4c6e4c70 Binary files /dev/null and b/src/eid/test_data/bst475_bf03.amr differ diff --git a/src/eid/test_data/profile.dat b/src/eid/test_data/profile.dat new file mode 100644 index 00000000..22030ae8 --- /dev/null +++ b/src/eid/test_data/profile.dat @@ -0,0 +1,30 @@ +10 +20 +5 +0 +30 +-1 +10 +40 +20 +5 +80 +10 +-1 +30 +20 +10 +5 +0 +60 +20 +10 +30 +-1 +40 +10 +50 +5 +20 +10 +10 diff --git a/src/eid/test_data/t1_text.ref b/src/eid/test_data/t1_text.ref new file mode 100644 index 00000000..58e58f24 --- /dev/null +++ b/src/eid/test_data/t1_text.ref @@ -0,0 +1 @@ +000001000010100000100010010000 \ No newline at end of file diff --git a/src/eid/test_data/t2_lf.ref b/src/eid/test_data/t2_lf.ref new file mode 100644 index 00000000..24460fff --- /dev/null +++ b/src/eid/test_data/t2_lf.ref @@ -0,0 +1,30 @@ +0 +0 +0 +0 +0 +1 +0 +0 +0 +0 +1 +0 +1 +0 +0 +0 +0 +0 +1 +0 +0 +0 +1 +0 +0 +1 +0 +0 +0 +0 diff --git a/src/eid/test_data/t3_word.ref b/src/eid/test_data/t3_word.ref new file mode 100644 index 00000000..31848379 --- /dev/null +++ b/src/eid/test_data/t3_word.ref @@ -0,0 +1 @@ +!k!k!k!k!k!k!k!k!k!k k k!k!k!k!k!k!k!k!k k k!k!k k k!k!k!k!k!k!k!k!k!k!k k k!k!k!k!k!k!k k k!k!k!k!k k k!k!k!k!k!k!k!k!k \ No newline at end of file diff --git a/src/eid/test_data/t4_lateloss.ref b/src/eid/test_data/t4_lateloss.ref new file mode 100644 index 00000000..c49265e8 --- /dev/null +++ b/src/eid/test_data/t4_lateloss.ref @@ -0,0 +1 @@ +000001000010100000000010000000 \ No newline at end of file diff --git a/src/esdru/CMakeLists.txt b/src/esdru/CMakeLists.txt index da2dddcc..bcd73cd0 100644 --- a/src/esdru/CMakeLists.txt +++ b/src/esdru/CMakeLists.txt @@ -1,12 +1,12 @@ include_directories(../utl) -add_executable(esdru esdru.c ../utl/ugst-utl.c) +add_executable(esdru esdru.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(esdru ${M_LIBRARY}) #TEST: ESDRU add_test(esdru1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/esdru -e_out test_data/es_el.test.double 0.2 test_data/stereo_test.pcm test_data/stereo_test.0.2.test_dummy.pcm) -add_test(esdru1-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q -reltol 1e-6 test_data/es_el.test.double test_data/es_el.double) +add_test(esdru1-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q -double -reltol 1e-6 test_data/es_el.test.double test_data/es_el.double) add_test(esdru2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/esdru -e_in test_data/es_el.double 0.2 test_data/stereo_test.pcm test_data/stereo_test.0.2.test.pcm) add_test(esdru2-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 2 test_data/stereo_test.0.2.test.pcm test_data/stereo_test.0.2.pcm) add_test(esdru3 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/esdru 1.0 test_data/stereo_test.pcm test_data/stereo_test.1.0.test.pcm) diff --git a/src/esdru/esdru.c b/src/esdru/esdru.c index da62b7f0..6faa4e2c 100644 --- a/src/esdru/esdru.c +++ b/src/esdru/esdru.c @@ -9,6 +9,7 @@ #include #include #include "ugst-utl.h" /* for ran16_32c */ +#include "wav_io.h" #define LOCAL_PI 3.14159265358979323846 @@ -271,8 +272,8 @@ void apply_spatial_dist( int main(int argc, char **argv ) { - FILE* f_input; - FILE* f_output; + AUDIO_FILE* f_input; + AUDIO_FILE* f_output; FILE* f_energy; char *input_filename; char *output_filename; @@ -286,6 +287,7 @@ int main(int argc, char **argv ) long step; long length; long fs; + int fs_given = 0; long clip; long i; short energy_input; @@ -315,6 +317,7 @@ int main(int argc, char **argv ) fprintf(stderr, "Invalid sampling frequency %s, exiting..\n", argv[i + 1] ); usage(); } + fs_given = 1; i += 2; } else if( strcmp( argv[i], "-e_step" ) == 0 ) @@ -398,12 +401,14 @@ int main(int argc, char **argv ) } input_filename = argv[i++]; output_filename = argv[i]; - if( (f_input = fopen( input_filename, "rb" )) == NULL ) + if( (f_input = audio_open_read (input_filename, fs_given ? fs : 0, 0, 16)) == NULL ) { fprintf( stderr, "Could not open input file %s, exiting..\n\n", input_filename ); usage(); } - if( (f_output = fopen( output_filename, "wb" )) == NULL ) + if (audio_get_sample_rate (f_input) > 0) + fs = audio_get_sample_rate (f_input); + if( (f_output = audio_open_write( output_filename, fs, 1, 16 )) == NULL ) { fprintf( stderr, "Could not open output file %s, exiting..\n\n", output_filename ); usage(); @@ -421,13 +426,12 @@ int main(int argc, char **argv ) fseed = (float) intseed; /* Load input file */ - fseek( f_input, 0L, SEEK_END ); - length = ftell( f_input ) / 4; /* 2 bytes per sample, 2 channels */ - rewind( f_input ); + length = audio_get_data_size( f_input ) / 4; /* 2 bytes per sample, 2 channels */ + audio_seek( f_input, 0L ); input = malloc(sizeof(double) * length * 2); input_short = malloc( sizeof( short ) * length * 2 ); m = malloc( sizeof( double ) * length ); - fread( input_short, sizeof(short), length * 2, f_input); + fread( input_short, sizeof(short), length * 2, f_input->fp); convert_short2double( input_short, input, length * 2); step = (long) (1.5 * fs / 50.0); @@ -437,7 +441,7 @@ int main(int argc, char **argv ) clip = convert_double2short(input, input_short, length * 2); - fwrite( input_short, sizeof( short ), length * 2, f_output ); + fwrite( input_short, sizeof( short ), length * 2, f_output->fp ); fprintf( stdout, "--> Done processing %ld samples\n", length ); if (clip > 0) @@ -449,8 +453,8 @@ int main(int argc, char **argv ) { fclose( f_energy ); } - fclose( f_input ); - fclose( f_output ); + audio_close( f_input ); + audio_close( f_output ); free( input ); free( input_short ); free( m ); diff --git a/src/fir/CMakeLists.txt b/src/fir/CMakeLists.txt index b064f32e..dfc767d0 100644 --- a/src/fir/CMakeLists.txt +++ b/src/fir/CMakeLists.txt @@ -2,13 +2,13 @@ include_directories(../iir) include_directories(../utl) -add_executable(filter filter.c fir-dsm.c fir-flat.c fir-irs.c fir-lib.c fir-pso.c fir-tia.c fir-hirs.c fir-wb.c fir-msin.c fir-LP.c ../iir/iir-lib.c ../iir/iir-g712.c ../iir/iir-dir.c ../iir/iir-flat.c ../utl/ugst-utl.c) +add_executable(filter filter.c fir-dsm.c fir-flat.c fir-irs.c fir-lib.c fir-pso.c fir-tia.c fir-hirs.c fir-wb.c fir-msin.c fir-LP.c fir-resamp.c ../iir/iir-lib.c ../iir/iir-g712.c ../iir/iir-dir.c ../iir/iir-flat.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(filter ${M_LIBRARY}) -add_executable(flt fltresp.c fir-dsm.c fir-flat.c fir-irs.c fir-lib.c fir-pso.c fir-tia.c fir-hirs.c fir-wb.c fir-msin.c fir-LP.c ../iir/iir-lib.c ../iir/iir-g712.c ../iir/iir-dir.c ../iir/iir-flat.c) +add_executable(flt fltresp.c fir-dsm.c fir-flat.c fir-irs.c fir-lib.c fir-pso.c fir-tia.c fir-hirs.c fir-wb.c fir-msin.c fir-LP.c fir-resamp.c ../iir/iir-lib.c ../iir/iir-g712.c ../iir/iir-dir.c ../iir/iir-flat.c) target_link_libraries(flt ${M_LIBRARY}) -add_executable(firdemo firdemo.c fir-dsm.c fir-flat.c fir-irs.c fir-lib.c fir-pso.c fir-tia.c fir-hirs.c fir-wb.c fir-msin.c fir-LP.c ../iir/iir-lib.c ../iir/iir-g712.c ../iir/iir-dir.c ../iir/iir-flat.c ../utl/ugst-utl.c) +add_executable(firdemo firdemo.c fir-dsm.c fir-flat.c fir-irs.c fir-lib.c fir-pso.c fir-tia.c fir-hirs.c fir-wb.c fir-msin.c fir-LP.c fir-resamp.c ../iir/iir-lib.c ../iir/iir-g712.c ../iir/iir-dir.c ../iir/iir-flat.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(firdemo ${M_LIBRARY}) #Test: FIR @@ -146,10 +146,10 @@ add_test(filter20 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q PCM1 test_data/tes add_test(filter20-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/pcm1.flt test_data/testpcm1.ref) add_test(filter21 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -up iflat test_data/test.src test_data/test-cas.flt) -add_test(filter21-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q test_data/test-cas.flt test_data/test-cas.ref) +add_test(filter21-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/test-cas.flt test_data/test-cas.ref) add_test(filter22 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -async iflat test_data/test.src test_data/test-asy.flt) -add_test(filter22-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q test_data/test-asy.flt test_data/test-asy.ref) +add_test(filter22-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/test-asy.flt test_data/test-asy.ref) add_test(filter23 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -async -delay 37 iflat test_data/test.src test_data/tst-asyd.flt) add_test(filter23-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -delay 37 test_data/tst-asyd.flt test_data/test-asy.flt) @@ -158,10 +158,79 @@ add_test(filter24 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -async -delay -37 add_test(filter24-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -delay -37 test_data/tst-asys.flt test_data/test-asy.flt) add_test(filter25 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -down iflat test_data/test.src test_data/test-sac.flt) -add_test(filter25-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q test_data/test-sac.flt test_data/test-sac.ref) +add_test(filter25-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/test-sac.flt test_data/test-sac.ref) add_test(filter26 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q p341 test_data/test.src test_data/testp341.flt) -add_test(filter26-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q test_data/testp341.flt test_data/testp341.ref) +add_test(filter26-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/testp341.flt test_data/testp341.ref) add_test(filter27 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q 5kbp test_data/test.src test_data/test5kbp.flt) -add_test(filter27-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q test_data/test5kbp.flt test_data/test5kbp.ref) +add_test(filter27-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/test5kbp.flt test_data/test5kbp.ref) + +add_test(filter28 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -up SHQ2 test_data/test.src test_data/test-shq2.flt) +add_test(filter28-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/test-shq2.flt test_data/tst-shq2.ref) + +add_test(filter29 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q SHQ3 test_data/test.src test_data/test-shq3.flt) +add_test(filter29-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/test-shq3.flt test_data/tst-shq3.ref) + +add_test(filter30 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q HP50_32KHZ test_data/test.src test_data/test-hp50-32khz.flt) +add_test(filter30-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/test-hp50-32khz.flt test_data/test-hp50-32khz.ref) + +add_test(filter31 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q HP50_48KHZ test_data/test.src test_data/test-hp50-48khz.flt) +add_test(filter31-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/test-hp50-48khz.flt test_data/test-hp50-48khz.ref) + +#Test: P863 resampling filters (raw PCM) +add_test(filter-p863-48to16 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -down P863_3 test_data/p863_48k_in.raw test_data/p863_48k_to_16k.tst) +add_test(filter-p863-48to16-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_48k_to_16k.tst test_data/p863_48k_to_16k.raw) + +add_test(filter-p863-48to8 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -down P863_6 test_data/p863_48k_in.raw test_data/p863_48k_to_8k.tst) +add_test(filter-p863-48to8-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_48k_to_8k.tst test_data/p863_48k_to_8k.raw) + +add_test(filter-p863-8to16 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -up P863_2 test_data/p863_8k_in.raw test_data/p863_8k_to_16k.tst) +add_test(filter-p863-8to16-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_8k_to_16k.tst test_data/p863_8k_to_16k.raw) + +add_test(filter-p863-8to48 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -up P863_6 test_data/p863_8k_in.raw test_data/p863_8k_to_48k.tst) +add_test(filter-p863-8to48-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_8k_to_48k.tst test_data/p863_8k_to_48k.raw) + +#Test: P863 resampling filters (WAV) +add_test(filter-p863-48to16-wav ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -down P863_3 test_data/p863_48k_in.wav test_data/p863_48k_to_16k_tst.wav) +add_test(filter-p863-48to16-wav-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_48k_to_16k_tst.wav test_data/p863_48k_to_16k.wav) + +add_test(filter-p863-48to8-wav ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -down P863_6 test_data/p863_48k_in.wav test_data/p863_48k_to_8k_tst.wav) +add_test(filter-p863-48to8-wav-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_48k_to_8k_tst.wav test_data/p863_48k_to_8k.wav) + +add_test(filter-p863-8to16-wav ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -up P863_2 test_data/p863_8k_in.wav test_data/p863_8k_to_16k_tst.wav) +add_test(filter-p863-8to16-wav-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_8k_to_16k_tst.wav test_data/p863_8k_to_16k.wav) + +add_test(filter-p863-8to48-wav ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/filter -q -up P863_6 test_data/p863_8k_in.wav test_data/p863_8k_to_48k_tst.wav) +add_test(filter-p863-8to48-wav-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_8k_to_48k_tst.wav test_data/p863_8k_to_48k.wav) + +set_tests_properties( + filter-p863-48to16 filter-p863-48to16-verify + filter-p863-48to8 filter-p863-48to8-verify + filter-p863-8to16 filter-p863-8to16-verify + filter-p863-8to48 filter-p863-8to48-verify + filter-p863-48to16-wav filter-p863-48to16-wav-verify + filter-p863-48to8-wav filter-p863-48to8-wav-verify + filter-p863-8to16-wav filter-p863-8to16-wav-verify + filter-p863-8to48-wav filter-p863-8to48-wav-verify + PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +#Test: P863 cross-validation (raw output vs WAV reference, WAV output vs raw reference) +add_test(filter-p863-48to16-cross-raw2wav ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_48k_to_16k.tst test_data/p863_48k_to_16k.wav) +add_test(filter-p863-48to16-cross-wav2raw ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_48k_to_16k_tst.wav test_data/p863_48k_to_16k.raw) + +add_test(filter-p863-48to8-cross-raw2wav ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_48k_to_8k.tst test_data/p863_48k_to_8k.wav) +add_test(filter-p863-48to8-cross-wav2raw ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_48k_to_8k_tst.wav test_data/p863_48k_to_8k.raw) + +add_test(filter-p863-8to16-cross-raw2wav ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_8k_to_16k.tst test_data/p863_8k_to_16k.wav) +add_test(filter-p863-8to16-cross-wav2raw ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_8k_to_16k_tst.wav test_data/p863_8k_to_16k.raw) + +add_test(filter-p863-8to48-cross-raw2wav ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_8k_to_48k.tst test_data/p863_8k_to_48k.wav) +add_test(filter-p863-8to48-cross-wav2raw ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/p863_8k_to_48k_tst.wav test_data/p863_8k_to_48k.raw) + +set_tests_properties( + filter-p863-48to16-cross-raw2wav filter-p863-48to16-cross-wav2raw + filter-p863-48to8-cross-raw2wav filter-p863-48to8-cross-wav2raw + filter-p863-8to16-cross-raw2wav filter-p863-8to16-cross-wav2raw + filter-p863-8to48-cross-raw2wav filter-p863-8to48-cross-wav2raw + PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/fir/README.md b/src/fir/README.md index ee57a574..f4089018 100644 --- a/src/fir/README.md +++ b/src/fir/README.md @@ -28,6 +28,9 @@ The ITU-T/UGST FIR Standard HQ and IRS Up/Downsampling and Filtering Module fir-pso.c: ..... sub-unit of the FIR module with the psophometric weighting init.functions fir-LP.c: ...... sub-unit of the FIR module with lowpass filters (anchors) + fir-wb.c: ...... sub-unit with wideband filters: SHQ2/SHQ3 (super-high-quality + low-pass, 729 coefs, -80dB) and HP50_32KHZ/HP50_48KHZ + (50 Hz high-pass for 32/48 kHz sampling rates) firflt.c: ...... dummy program that calls all the sub-units. Equivalent to the old HQFLT.C file. diff --git a/src/fir/filter.c b/src/fir/filter.c index 6708d091..54a0439b 100644 --- a/src/fir/filter.c +++ b/src/fir/filter.c @@ -33,10 +33,10 @@ Options: -mod .......... uses the modified IRS characteristic instead of the "regular" one. - -down ......... filtering is downsample (for HQ2, HQ3, FLAT, IFLAT, and PCM) - -up ........... filtering is upsample (for HQ2, HQ3, FLAT, IFLAT, and PCM) - -async ........ asynchronization operation (disables -down) \n")) - -delay d ...... number of samples to delay the input signal for + -down ......... filtering is downsample (for HQ2, HQ3, SHQ2, SHQ3, FLAT, IFLAT, and PCM) + -up ........... filtering is upsample (for HQ2, HQ3, SHQ2, SHQ3, FLAT, IFLAT, and PCM) + -async ........ asynchronization operation (disables -down) \n")) + -delay d ...... number of samples to delay the input signal for asynchronous tandeming simulation. For d>0, null samples are inserted in the begining of the file, d<0 causes samples to be dropped. Default is d=0. @@ -44,39 +44,41 @@ Valid filter specifications: Flt_type Description - IRS8 (regular) IRS weighting with factor 1:1 at 8kHz - IRS16 (regular or modified) IRS weighting with factor 1:1 at 16kHz - IRS48 (modified) IRS weighting with factor 1:1 at 48kHz - HIRS16 Half-tilt IRS weighting for data sampled at 16kHz, factor 1:1 - TIRS IRS weighting with TIA coefficients, sf=8kHz, factor 1:1 - DSM Delta-SM filtering characteristic, 1:1 - PSO Psophometric wheighting filter, 1:1 - HQ2 FIR (High quality) low-pass with factor 1:2 (up) or 2:1 (down) - HQ3 FIR (High quality) low-pass with factor 1:3 (up) or 3:1 (down) - FLAT Linear-phase pass-band with factor 1:2 (up) or 2:1 (down) - FLAT1 Linear-phase pass-band with factor 1:1 (no rate change) - PCM Standard IIR PCM quality factor 1:2 (up) or 2:1 (down) - PCM1 Standard PCM quality with factor 1:1 at 16 kHz - GSM1 GSM Mobile station input response w/ factor 1:1 at 16 kHz - P341 Send-part weighting of ITU-T Rec.P.341 (Wideband telephones) - DC Direct-form DC-removal IIR filter (factor 1:1) - IFLAT Flat IIR low-pass with factor 1:3 (up) or 3:1 (down) using a - cascade structure - 5KBP 50-5000 Hz Flat bandpass FIR filter for fs=16kHz, 1:1 - 100_5KBP 100-5000 Hz Flat bandpass FIR filter for fs=16kHz, 1:1 - 14KBP 50-14000 Hz Flat bandpass FIR filter for fs=32kHz, 1:1 - 20KBP 20-20000 Hz Flat bandpass FIR filter for fs=48kHz, 1:1 (non-linear phase in HP-design) - LP1p5 low-pass filter with cut-off frequency 1.5kHz for fs=48kHz, 1:1 - LP35 low-pass filter with cut-off frequency 3.5kHz for fs=48kHz, 1:1 - LP7 low-pass filter with cut-off frequency 7kHz for fs=48kHz, 1:1 - LP10 low-pass filter with cut-off frequency 10kHz for fs=48kHz, 1:1 - // FILTER_12k48k_HW - LP12 low-pass filter with cut-off frequency 12kHz for fs=48kHz, 1:1 - // FILTER_12k48k_HW - LP14 low-pass filter with cut-off frequency 14kHz for fs=48kHz, 1:1 - LP20 low-pass filter with cut-off frequency 20kHz for fs=48kHz, 1:1 - RXIRS8 Receive-side Modified IRS weighting with factor 1:1 at 8kHz - RXIRS16 Receive-side Modified IRS weighting with factor 1:1 at 16kHz + IRS8 (regular) IRS weighting with factor 1:1 at 8kHz + IRS16 (regular or modified) IRS weighting with factor 1:1 at 16kHz + IRS48 (modified) IRS weighting with factor 1:1 at 48kHz + HIRS16 Half-tilt IRS weighting for data sampled at 16kHz, factor 1:1 + TIRS IRS weighting with TIA coefficients, sf=8kHz, factor 1:1 + DSM Delta-SM filtering characteristic, 1:1 + PSO Psophometric wheighting filter, 1:1 + HQ2 FIR (High quality) low-pass with factor 1:2 (up) or 2:1 (down) + HQ3 FIR (High quality) low-pass with factor 1:3 (up) or 3:1 (down) + SHQ2 FIR (Super High quality) low-pass with factor 1:2 (up) or 2:1 (down) (729 coefs) + SHQ3 FIR (Super High quality) low-pass with factor 1:3 (up) or 3:1 (down) (729 coefs) + FLAT Linear-phase pass-band with factor 1:2 (up) or 2:1 (down) + FLAT1 Linear-phase pass-band with factor 1:1 (no rate change) + PCM Standard IIR PCM quality factor 1:2 (up) or 2:1 (down) + PCM1 Standard PCM quality with factor 1:1 at 16 kHz + GSM1 GSM Mobile station input response w/ factor 1:1 at 16 kHz + P341 Send-part weighting of ITU-T Rec.P.341 (Wideband telephones) + DC Direct-form DC-removal IIR filter (factor 1:1) + IFLAT Flat IIR low-pass with factor 1:3 (up) or 3:1 (down) using a + cascade structure + 5KBP 50-5000 Hz Flat bandpass FIR filter for fs=16kHz, 1:1 + 100_5KBP 100-5000 Hz Flat bandpass FIR filter for fs=16kHz, 1:1 + 14KBP 50-14000 Hz Flat bandpass FIR filter for fs=32kHz, 1:1 + 20KBP 20-20000 Hz Flat bandpass FIR filter for fs=48kHz, 1:1 (non-linear phase in HP-design) + LP1p5 low-pass filter with cut-off frequency 1.5kHz for fs=48kHz, 1:1 + LP35 low-pass filter with cut-off frequency 3.5kHz for fs=48kHz, 1:1 + LP7 low-pass filter with cut-off frequency 7kHz for fs=48kHz, 1:1 + LP10 low-pass filter with cut-off frequency 10kHz for fs=48kHz, 1:1 + LP12 low-pass filter with cut-off frequency 12kHz for fs=48kHz, 1:1 + LP14 low-pass filter with cut-off frequency 14kHz for fs=48kHz, 1:1 + LP20 low-pass filter with cut-off frequency 20kHz for fs=48kHz, 1:1 + RXIRS8 Receive-side Modified IRS weighting with factor 1:1 at 8kHz + RXIRS16 Receive-side Modified IRS weighting with factor 1:1 at 16kHz + HP50_32KHZ 50 Hz highpass FIR filter w/ factor 1:1 at sf=32kHz, 1119 coefs + HP50_48KHZ 50 Hz highpass FIR filter w/ factor 1:1 at sf=48kHz, 1679 coefs Testing: @@ -152,6 +154,7 @@ 02.Feb.2010 v3.5 - Modified maximum string length for filenames to avoid buffer overruns (y.hiwasaki) + 05.April.2012 v3.6 - Added filters: HP50_32KHZ, HP50_48KHZ, SHQ2 and SHQ3 (b.kovesi France Telecom) =========================================================================== */ @@ -171,6 +174,7 @@ #include "iirflt.h" #include "firflt.h" #include "ugst-utl.h" +#include "wav_io.h" /* LOCAL DEFINITIONS */ #ifndef max @@ -195,6 +199,7 @@ int valid_filter (char *F_type, char modified_IRS) { || strncmp (F_type, "dsm", 3) == 0 || strncmp (F_type, "DSM", 3) == 0 || strncmp (F_type, "pso", 3) == 0 || strncmp (F_type, "PSO", 3) == 0 || strncmp (F_type, "hq", 2) == 0 || strncmp (F_type, "HQ", 2) == 0 + || strncmp (F_type, "shq", 3) == 0 || strncmp (F_type, "SHQ", 3) == 0 || strncmp (F_type, "flat", 4) == 0 || strncmp (F_type, "FLAT", 4) == 0 || strncmp (F_type, "gsm1", 4) == 0 || strncmp (F_type, "GSM1", 4) == 0 || strncmp (F_type, "msin", 4) == 0 || strncmp (F_type, "MSIN", 4) == 0 @@ -204,7 +209,11 @@ int valid_filter (char *F_type, char modified_IRS) { // FILTER_12k48k_HW || strncmp (F_type, "LP12", 4) == 0 || strncmp (F_type, "lp12", 4) == 0 // FILTER_12k48k_HW - || strncmp (F_type, "LP14", 4) == 0 || strncmp (F_type, "lp14", 4) == 0 || strncmp (F_type, "LP20", 4) == 0 || strncmp (F_type, "lp20", 4) == 0) + || strncmp (F_type, "LP14", 4) == 0 || strncmp (F_type, "lp14", 4) == 0 || strncmp (F_type, "LP20", 4) == 0 || strncmp (F_type, "lp20", 4) == 0 || strncmp (F_type, "hp50_32khz", 10) == 0 || strncmp (F_type, "HP50_32KHZ", 10) == 0 || strncmp (F_type, "hp50_48khz", 10) == 0 || strncmp (F_type, "HP50_48KHZ", 10) == 0 + || strncmp (F_type, "p863_2", 6) == 0 || strncmp (F_type, "P863_2", 6) == 0 + || strncmp (F_type, "p863_3", 6) == 0 || strncmp (F_type, "P863_3", 6) == 0 + || strncmp (F_type, "p863_4", 6) == 0 || strncmp (F_type, "P863_4", 6) == 0 + || strncmp (F_type, "p863_6", 6) == 0 || strncmp (F_type, "P863_6", 6) == 0) valid = 1; /* No MOD-IRS filter at 8 kHz */ @@ -258,37 +267,45 @@ void display_usage () { printf ("\n"); printf (" Valid filter specifications:\n"); printf (" Flt_type Description\n"); - printf (" IRS8 (regular) IRS weighting with factor 1:1 at 8kHz\n"); - printf (" IRS16 (regular or modified) IRS weighting with factor 1:1 at 16kHz\n"); - printf (" IRS48 (modified) IRS weighting with factor 1:1 at 48kHz\n"); - printf (" RXIRS8 Receive-side Modified IRS weighting with factor 1:1 at 8kHz\n"); - printf (" RXIRS16 Receive-side Modified IRS weighting with factor 1:1 at 16kHz\n"); - printf (" HIRS16 Half-tilt IRS weighting, sf=16kHz, factor 1:1.\n"); - printf (" TIRS IRS weighting w/ TIA coefficients, sf=8kHz, factor 1:1.\n"); - printf (" DSM Delta-SM filtering characteristic, 1:1\n"); - printf (" PSO Psophometric wheighting filter, 1:1\n"); - printf (" HQ2 FIR (High quality) low-pass for factor 1:2 (up) or 2:1(down)\n"); - printf (" HQ3 FIR (High quality) low-pass for factor 1:3 (up) or 3:1(down)\n"); - printf (" FLAT Linear-phase passband w/ factor 1:2 (up) or 2:1 (down)\n"); - printf (" FLAT1 Linear-phase pass-band FIR w/ factor 1:1 (no rate change)\n"); - printf (" PCM Standard IIR PCM quality factor 1:2 (up) or 2:1 (down)\n"); - printf (" PCM1 Standard PCM quality with factor 1:1 at 16 kHz\n"); - printf (" GSM1 GSM Mobile station input FIR w/ factor 1:1 at 16 kHz\n"); - printf (" MSIN Same as GSM1\n"); - printf (" P341 P.341 send-mask FIR with factor 1:1 at 16 kHz\n"); - printf (" DC Direct-form DC-removal IIR filter (factor 1:1)\n"); - printf (" IFLAT Cascade-form IIR flat low-pass with factor 1:3 (up) or 3:1 (down)\n"); - printf (" 5KBP 50-5k Hz Flat bandpass FIR filter w/ factor 1:1 at sf=16kHz\n"); - printf (" 100_5KBP 100-5k Hz Flat bandpass FIR filter w/ factor 1:1 at sf=16kHz\n"); - printf (" 14KBP 50-14k Hz Flat bandpass FIR filter w/ factor 1:1 at sf=32kHz\n"); - printf (" 20KBP 20-20k Hz Flat bandpass FIR filter w/ factor 1:1 at sf=48kHz\n"); - printf (" LP1p5 1.5kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); - printf (" LP35 3.5kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); - printf (" LP7 7kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); - printf (" LP10 10kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); - printf (" LP12 12kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); - printf (" LP14 14kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); - printf (" LP20 20kHz low-pass filter for fs=48kHz, w/ factor 1:1\n\n"); + printf (" IRS8 (regular) IRS weighting with factor 1:1 at 8kHz\n"); + printf (" IRS16 (regular or modified) IRS weighting with factor 1:1 at 16kHz\n"); + printf (" IRS48 (modified) IRS weighting with factor 1:1 at 48kHz\n"); + printf (" RXIRS8 Receive-side Modified IRS weighting with factor 1:1 at 8kHz\n"); + printf (" RXIRS16 Receive-side Modified IRS weighting with factor 1:1 at 16kHz\n"); + printf (" HIRS16 Half-tilt IRS weighting, sf=16kHz, factor 1:1.\n"); + printf (" TIRS IRS weighting w/ TIA coefficients, sf=8kHz, factor 1:1.\n"); + printf (" DSM Delta-SM filtering characteristic, 1:1\n"); + printf (" PSO Psophometric wheighting filter, 1:1\n"); + printf (" HQ2 FIR (High quality) low-pass for factor 1:2 (up) or 2:1(down)\n"); + printf (" HQ3 FIR (High quality) low-pass for factor 1:3 (up) or 3:1(down)\n"); + printf (" FLAT Linear-phase passband w/ factor 1:2 (up) or 2:1 (down)\n"); + printf (" FLAT1 Linear-phase pass-band FIR w/ factor 1:1 (no rate change)\n"); + printf (" PCM Standard IIR PCM quality factor 1:2 (up) or 2:1 (down)\n"); + printf (" PCM1 Standard PCM quality with factor 1:1 at 16 kHz\n"); + printf (" GSM1 GSM Mobile station input FIR w/ factor 1:1 at 16 kHz\n"); + printf (" MSIN Same as GSM1\n"); + printf (" P341 P.341 send-mask FIR with factor 1:1 at 16 kHz\n"); + printf (" DC Direct-form DC-removal IIR filter (factor 1:1)\n"); + printf (" IFLAT Cascade-form IIR flat low-pass with factor 1:3 (up) or 3:1 (down)\n"); + printf (" 5KBP 50-5k Hz Flat bandpass FIR filter w/ factor 1:1 at sf=16kHz\n"); + printf (" 100_5KBP 100-5k Hz Flat bandpass FIR filter w/ factor 1:1 at sf=16kHz\n"); + printf (" 14KBP 50-14k Hz Flat bandpass FIR filter w/ factor 1:1 at sf=32kHz\n"); + printf (" 20KBP 20-20k Hz Flat bandpass FIR filter w/ factor 1:1 at sf=48kHz\n"); + printf (" LP1p5 1.5kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); + printf (" LP35 3.5kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); + printf (" LP7 7kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); + printf (" LP10 10kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); + printf (" LP12 12kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); + printf (" LP14 14kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); + printf (" LP20 20kHz low-pass filter for fs=48kHz, w/ factor 1:1\n"); + printf (" HP50_32KHZ 50 Hz highpass FIR filter w/ factor 1:1 at sf=32kHz, 1119 coefs\n"); + printf (" HP50_48KHZ 50 Hz highpass FIR filter w/ factor 1:1 at sf=48kHz, 1679 coefs\n"); + printf (" SHQ2 FIR (Super High quality : 729 coefs, -80dB) low-pass for factor 1:2 (up) or 2:1(down)\n"); + printf (" SHQ3 FIR (Super High quality : 729 coefs, -80dB) low-pass for factor 1:3 (up) or 3:1(down)\n"); + printf (" P863_2 P.863/P.863.2 resampling filter for factor 1:2 (up) or 2:1 (down)\n"); + printf (" P863_3 P.863/P.863.2 resampling filter for factor 1:3 (up) or 3:1 (down)\n"); + printf (" P863_4 P.863/P.863.2 resampling filter for factor 1:4 (up) or 4:1 (down)\n"); + printf (" P863_6 P.863/P.863.2 resampling filter for factor 1:6 (up) or 6:1 (down)\n\n"); /* Quit program */ exit (-128); @@ -318,6 +335,7 @@ int main (int argc, char *argv[]) { char modified_IRS = 0, quiet = 0; long inp_size, out_size, factor, smpno; double fs = 8000; + int fs_given = 0; char kernel_type = 0; static char funny[9] = "|/-\\|/-\\"; @@ -327,7 +345,7 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN]; - FILE *Fi, *Fo; + AUDIO_FILE *Fi, *Fo; long start_byte; #ifdef VMS char mrs[15]; @@ -351,6 +369,7 @@ int main (int argc, char *argv[]) { } else if (strcmp (argv[1], "-fs") == 0) { /* Change sampling frequency */ fs = atof (argv[2]); + fs_given = 1; /* Move arg{c,v} over the option to the next argument */ argc -= 2; @@ -437,14 +456,7 @@ int main (int argc, char *argv[]) { start_byte += skip * sizeof (short); #endif - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); - } + /* N2 will be computed after opening file if processing the whole file */ inp_size = N; /* samples */ @@ -570,6 +582,20 @@ int main (int argc, char *argv[]) { : hq_down_3_to_1_init (); } +#if 1 // not yet implemented +/* + * Filter type: SHQ2 - Super High quality 2:1 or 1:2 factor: + * SHQ3 - Super High quality 3:1 or 3:1 factor + */ + else if (strncmp (F_type, "shq", 3) == 0 || strncmp (F_type, "SHQ", 3) == 0) { + if (upsample) /* It is up-sampling! */ + fir_state = F_type[3] == '2' ? shq_up_1_to_2_init () + : shq_up_1_to_3_init (); + else /* It is down-sampling! */ + fir_state = F_type[3] == '2' ? shq_down_2_to_1_init () + : shq_down_3_to_1_init (); + } +#endif /* * Filter type: P.341 send mask: factor 1:1 */ @@ -652,14 +678,57 @@ int main (int argc, char *argv[]) { fir_state = LP20_48kHz_init (); } -/* - * Filter type: PCM - Standard PCM quality 2:1 or 1:2 factor: - * . fs == 8000 -> upsample: 1:2 - * . fs == 16000 -> downsample: 2:1 - * PCM1 - Standard PCM quality with 1:1 factor - * . fs == 8000 -> unimplemented - * . fs == 16000 -> OK, 1:1 at 16 kHz - */ + + /* + * Filter type: 50 Hz highpass filter (fs=32kHz): factor 1:1 + */ + else if (strncmp (F_type, "hp50_32khz", 10) == 0 || strncmp (F_type, "HP50_32KHZ", 10) == 0) { + fir_state = hp50_32khz_init (); + } + + /* + * Filter type: 50 Hz highpass filter (fs=48kHz): factor 1:1 + */ + else if (strncmp (F_type, "hp50_48khz", 10) == 0 || strncmp (F_type, "HP50_48KHZ", 10) == 0) { + fir_state = hp50_48khz_init (); + } + + /* + * Filter type: P863 - P.863/P.863.2 resampling filters + * P863_2: factor 1:2 (up) or 2:1 (down) + * P863_3: factor 1:3 (up) or 3:1 (down) + * P863_4: factor 1:4 (up) or 4:1 (down) + * P863_6: factor 1:6 (up) or 6:1 (down) + */ + else if (strncmp (F_type, "p863_", 5) == 0 || strncmp (F_type, "P863_", 5) == 0) { + int f = atoi (&F_type[5]); + if (upsample) { + switch (f) { + case 2: fir_state = p863_up_1_to_2_init (); break; + case 3: fir_state = p863_up_1_to_3_init (); break; + case 4: fir_state = p863_up_1_to_4_init (); break; + case 6: fir_state = p863_up_1_to_6_init (); break; + default: error_terminate ("P863: factor must be 2, 3, 4, or 6\n", 15); + } + } else { + switch (f) { + case 2: fir_state = p863_down_2_to_1_init (); break; + case 3: fir_state = p863_down_3_to_1_init (); break; + case 4: fir_state = p863_down_4_to_1_init (); break; + case 6: fir_state = p863_down_6_to_1_init (); break; + default: error_terminate ("P863: factor must be 2, 3, 4, or 6\n", 15); + } + } + } + + /* + * Filter type: PCM - Standard PCM quality 2:1 or 1:2 factor: + * . fs == 8000 -> upsample: 1:2 + * . fs == 16000 -> downsample: 2:1 + * PCM1 - Standard PCM quality with 1:1 factor + * . fs == 8000 -> unimplemented + * . fs == 16000 -> OK, 1:1 at 16 kHz + */ else if (strncmp (F_type, "pcm", 3) == 0 || strncmp (F_type, "PCM", 3) == 0) { if (strncmp (F_type, "pcm1", 4) == 0 || strncmp (F_type, "PCM1", 4) == 0) { parallel_iir_state = stdpcm_16khz_init (); @@ -759,15 +828,21 @@ int main (int argc, char *argv[]) { #endif /* Opening input file; abort if there's any problem */ - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, fs_given ? (long) fs : 0, 0, 16)) == NULL) KILL (FileIn, 2); + if (audio_get_sample_rate (Fi) > 0) + fs = (double) audio_get_sample_rate (Fi); + + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = ceil ((audio_get_data_size (Fi) - start_byte) / (double) (N * sizeof (short))); /* Creates output file */ - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, (long) fs, 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0)) + if (audio_seek (Fi, start_byte)) KILL (FileIn, 4); @@ -775,7 +850,7 @@ int main (int argc, char *argv[]) { /* One-time delay of output signal, if appropriate */ if (async && delay > 0) - if ((smpno = fwrite (zero, sizeof (short), delay, Fo)) == 0 && ferror (Fo)) + if ((smpno = audio_write (Fo, zero, delay)) == 0) KILL (FileOut, 6); /* Process regular frames */ @@ -788,7 +863,7 @@ int main (int argc, char *argv[]) { memset (OutBuff, '\0', out_size * sizeof (float)); /* Read a block of samples */ - if ((smpno = fread (TmpBuff, sizeof (short), N, Fi)) == 0) + if ((smpno = audio_read (Fi, TmpBuff, N)) == 0) KILL (FileIn, 5); /* ... and convert short to float, normalizing */ @@ -830,12 +905,12 @@ int main (int argc, char *argv[]) { skip -= smpno; continue; } else if (skip > 0) { - if ((smpno = fwrite (&TmpBuff[skip], sizeof (short), (smpno - skip), Fo)) == 0 && ferror (Fo)) + if ((smpno = audio_write (Fo, &TmpBuff[skip], (smpno - skip))) == 0) KILL (FileOut, 6); total += smpno; skip = 0; } else { - if ((smpno = fwrite (TmpBuff, sizeof (short), smpno, Fo)) == 0 && ferror (Fo)) + if ((smpno = audio_write (Fo, TmpBuff, smpno)) == 0) KILL (FileOut, 6); total += smpno; } @@ -846,8 +921,8 @@ int main (int argc, char *argv[]) { fprintf (stderr, "\n"); /* Close open files */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); /* Release some memory */ free (TmpBuff); diff --git a/src/fir/fir-flat.c b/src/fir/fir-flat.c index 8dfdea82..b279c342 100644 --- a/src/fir/fir-flat.c +++ b/src/fir/fir-flat.c @@ -39,6 +39,10 @@ ORIGINAL BY: = hq_down_3_to_1_init() : initialize down-sampling filter 3:1 = hq_up_1_to_2_init() : initialize up-sampling filter 1:2 = hq_up_1_to_3_init() : initialize up-sampling filter 1:3 + = shq_down_2_to_1_init() : initialize down-sampling filter 2:1 + = shq_down_3_to_1_init() : initialize down-sampling filter 3:1 + = shq_up_1_to_2_init() : initialize up-sampling filter 1:2 + = shq_up_1_to_3_init() : initialize up-sampling filter 1:3 = linear_phase_pb_2_to_1_init() = linear_phase_pb_1_to_2_init() = linear_phase_pb_1_to_1_init() @@ -62,6 +66,7 @@ ORIGINAL BY: ** THIS FILE WAS SPLIT FROM THE ORIGINAL .C FILE ** 16.May.97 v2.2 Added function for HQ flat bandpass keeping the sampling rate (1:1 factor) + 05.April.2012 v2.3 - Added filters: SHQ2 and SHQ3 (France Telecom) ============================================================================= */ @@ -83,6 +88,8 @@ ORIGINAL BY: void fill_lp_2_to_1 ARGS ((float *h0[], long *lenh0)); void fill_lp_3_to_1 ARGS ((float **h0, long *lenh0)); +void fill_slp_2_to_1 ARGS ((float *h0[], long *lenh0)); +void fill_slp_3_to_1 ARGS ((float **h0, long *lenh0)); void fill_flat_band_pass ARGS ((float **h0, long *lenh0)); @@ -715,4 +722,663 @@ SCD_FIR *linear_phase_pb_1_to_1_init () { /* ................ End of linear_phase_pb_1_to_1_init() ................ */ +/*****************************************************************************/ +/*****************************************************************************/ + +/* + ============================================================================ + + SCD_FIR *shq_down_2_to_1_init (void); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Description: + ~~~~~~~~~~~~ + + Initialization routine for super high quality FIR downsampling filter + by factor of 2. + + Parameters: none. + ~~~~~~~~~~~ + + Return value: + ~~~~~~~~~~~~~ + Returns a pointer to struct SCD_FIR; + + Author: + ~~~~~~~ + + History: + ~~~~~~~~ + 05.April.2012 v1.0 - Added filters: SHQ2 and SHQ3 (France Telecom) + + ============================================================================ +*/ +SCD_FIR *shq_down_2_to_1_init () { + float *h0; /* pointer to array with FIR coeff. */ + long lenh0; /* number of FIR coefficients */ + + + /* allocate array for FIR coeff. and fill with coefficients */ + fill_slp_2_to_1 (&h0, &lenh0); + + return fir_initialization ( /* Returns: pointer to SCD_FIR-struct */ + lenh0, /* In: number of FIR-coefficients */ + h0, /* In: pointer to array with FIR-cof. */ + 1.0, /* In: gain factor for FIR-coeffic. */ + 2l, /* In: Down-sampling factor */ + 'D' /* In: switch to down-sampling kernel */ + ); +} + +/* ..................... End of shq_down_2_to_1_init() ..................... */ + + + +/* + ============================================================================ + + SCD_FIR *shq_up_1_to_2_init (void); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Description: + ~~~~~~~~~~~~ + + Initialization routine for super high quality upsampling FIR filter + by factor of 2. + + Parameters: none. + ~~~~~~~~~~~ + + Return value: + ~~~~~~~~~~~~~ + Returns a pointer to struct SCD_FIR; + + Author: + ~~~~~~~ + + History: + ~~~~~~~~ + 05.April.2012 v1.0 - Added filters: SHQ2 and SHQ3 (France Telecom) + + ============================================================================ +*/ +SCD_FIR *shq_up_1_to_2_init () { + float *h0; /* pointer to array with FIR coeff. */ + long lenh0; /* number of FIR coefficients */ + + + /* allocate array for FIR coeff. and fill with coefficients */ + fill_slp_2_to_1 (&h0, &lenh0); + + return fir_initialization ( /* Returns: pointer to SCD_FIR-struct */ + lenh0, /* In: number of FIR-coefficients */ + h0, /* In: pointer to array with FIR-cof. */ + 2.0, /* In: gain factor for FIR-coeffic. */ + 2l, /* In: Up-sampling factor */ + 'U' /* In: Switch to upsampling procedure */ + ); +} + +/* ..................... End of shq_up_1_to_2_init() ..................... */ + + + +/* + ============================================================================ + + SCD_FIR *shq_down_3_to_1_init (void); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Description: + ~~~~~~~~~~~~ + + Initialization routine for super high quality FIR downsampling filter + by factor of 3. + + Parameters: none. + ~~~~~~~~~~~ + + Return value: + ~~~~~~~~~~~~~ + Returns a pointer to struct SCD_FIR; + + Author: + ~~~~~~~ + + History: + ~~~~~~~~ + 05.April.2012 v1.0 - Added filters: SHQ2 and SHQ3 (France Telecom) + + ============================================================================ +*/ +SCD_FIR *shq_down_3_to_1_init () { + float *h0; /* pointer to array with FIR coeff. */ + long lenh0; /* number of FIR coefficients */ + + + /* allocate array for FIR coeff. and fill with coefficients */ + fill_slp_3_to_1 (&h0, &lenh0); + + return fir_initialization ( /* Returns: pointer to SCD_FIR-struct */ + lenh0, /* In: number of FIR-coefficients */ + h0, /* In: pointer to array with FIR-cof. */ + 1.0, /* In: gain factor for FIR-coeffic. */ + 3l, /* In: Down-sampling factor */ + 'D' /* In: switch to down-sampling proc. */ + ); +} + +/* .................... End of shq_down_3_to_1_init() ..................... */ + + + +/* + ============================================================================ + + SCD_FIR *shq_up_1_to_3_init (void); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Description: + ~~~~~~~~~~~~ + + Initialization routine for super high quality FIR upsampling filter + by factor of 3. + + Parameters: none. + ~~~~~~~~~~~ + + Return value: + ~~~~~~~~~~~~~ + Returns a pointer to struct SCD_FIR; + + Author: + ~~~~~~~ + + History: + ~~~~~~~~ + 05.April.2012 v1.0 - Added filters: SHQ2 and SHQ3 (France Telecom) + + ============================================================================ +*/ +SCD_FIR *shq_up_1_to_3_init () { + float *h0; /* pointer to array with FIR coeff. */ + long lenh0; /* number of FIR coefficients */ + + + /* allocate array for FIR coeff. and fill with coefficients */ + fill_slp_3_to_1 (&h0, &lenh0); + + return fir_initialization ( /* Returns: pointer to SCD_FIR-struct */ + lenh0, /* In: number of FIR-coefficients */ + h0, /* In: pointer to array with FIR-cof. */ + 3.0, /* In: gain factor for FIR-coeffic. */ + 3l, /* In: Up-sampling factor */ + 'U' /* In: switch to upsampling procedure */ + ); +} + +/* ...................... End of shq_up_1_to_3_init() ...................... */ + + +/* + ============================================================================ + + void fill_slp_2_to_1 (float **h0, long *lenh0); + ~~~~~~~~~~~~~~~~~~~ + + Description: + ~~~~~~~~~~~~ + + Initialize pointer to array with of FIR coefficients of a low + pass filter for up/down sampling filter with factor 2:1 or 1:2 + and float representation. + v1.0 filtdemo firpm 16000,3935,4000,0.3, 80, 728 + v1.1 filtdemo firpm 16000,3935,4000,0.3, 100, 872 + h2 = filtdemo('getfilt') + for i = 1:length(h2) fprintf('(float)%20.12e, ', h2(i)); + if rem(i,5) == 0 fprintf('\n'); end end + + Parameters: + ~~~~~~~~~~~ + h0: (Out) pointer to array with FIR coefficients + lenh0: (Out) pointer to number of coefficients + + + Return value: + ~~~~~~~~~~~~~ + None. + + Author: + ~~~~~~~ + + History: + ~~~~~~~~ + 08.DEC.2011 v1.0 Release of 1st version + 15.FEB.2012 v1.1 Release of 2nd version with more stopband attenuation + + ============================================================================ +*/ +#define lensh02 873 + +void fill_slp_2_to_1 (h0, lenh0) + float *h0[]; + long *lenh0; +{ + static float sh02[lensh02] = { + (float) 3.796696928466e-006, (float) - 1.916895913880e-004, (float) - 9.559790653313e-004, (float) - 2.309090436241e-003, (float) - 3.355260288418e-003, + (float) - 2.821616068751e-003, (float) - 6.494578851510e-004, (float) 1.368071261832e-003, (float) 1.370278722621e-003, (float) - 2.336521287917e-004, + (float) - 1.185316896754e-003, (float) - 3.557893702940e-004, (float) 8.234667012568e-004, (float) 6.081914903075e-004, (float) - 4.869084931865e-004, + (float) - 6.784989588347e-004, (float) 2.211378711751e-004, (float) 6.567967063227e-004, (float) - 2.508428842065e-005, (float) - 5.918859501058e-004, + (float) - 1.133457948942e-004, (float) 5.103528659400e-004, (float) 2.077730139398e-004, (float) - 4.257030079639e-004, (float) - 2.693320767774e-004, + (float) 3.450469073084e-004, (float) 3.071631118731e-004, (float) - 2.713518058883e-004, (float) - 3.278882894771e-004, (float) 2.057925864008e-004, + (float) 3.366006455231e-004, (float) - 1.482361183421e-004, (float) - 3.367394950886e-004, (float) 9.845446547453e-005, (float) 3.312977192436e-004, + (float) - 5.533287789728e-005, (float) - 3.217977487285e-004, (float) 1.843967368528e-005, (float) 3.099640470313e-004, (float) 1.328843895284e-005, + (float) - 2.965903264243e-004, (float) - 4.040411770010e-005, (float) 2.826060999738e-004, (float) 6.386636089117e-005, (float) - 2.682059180462e-004, + (float) - 8.400473971490e-005, (float) 2.539623487208e-004, (float) 1.015795101283e-004, (float) - 2.398340044811e-004, (float) - 1.167662237676e-004, + (float) 2.262277295494e-004, (float) 1.302389953023e-004, (float) - 2.128963846610e-004, (float) - 1.420059883336e-004, (float) 2.001325818624e-004, + (float) 1.525152442899e-004, (float) - 1.878370907468e-004, (float) - 1.619282978772e-004, (float) 1.760669168660e-004, (float) 1.705747652949e-004, + (float) - 1.645342831667e-004, (float) - 1.782437567680e-004, (float) 1.536329356026e-004, (float) 1.854489350961e-004, (float) - 1.431090602159e-004, + (float) - 1.923098357663e-004, (float) 1.327632434198e-004, (float) 1.988019142637e-004, (float) - 1.224823030873e-004, (float) - 2.047505646951e-004, + (float) 1.125436526441e-004, (float) 2.105136263884e-004, (float) - 1.026783876418e-004, (float) - 2.159988725649e-004, (float) 9.291206030779e-005, + (float) 2.212630220095e-004, (float) - 8.322092258564e-005, (float) - 2.263811595801e-004, (float) 7.350850871907e-005, (float) 2.313695981464e-004, + (float) - 6.362969041322e-005, (float) - 2.360269018314e-004, (float) 5.380295174011e-005, (float) 2.405543319009e-004, (float) - 4.394022835345e-005, + (float) - 2.450580921435e-004, (float) 3.380378919976e-005, (float) 2.493326534241e-004, (float) - 2.346096839263e-005, (float) - 2.533379001119e-004, + (float) 1.298908745154e-005, (float) 2.571630808553e-004, (float) - 2.297001211178e-006, (float) - 2.607451266109e-004, (float) - 8.605011575155e-006, + (float) 2.640373512578e-004, (float) 1.959506007225e-005, (float) - 2.672713250910e-004, (float) - 3.098103063675e-005, (float) 2.701901534524e-004, + (float) 4.267470287693e-005, (float) - 2.727139254030e-004, (float) - 5.452878257789e-005, (float) 2.749705769146e-004, (float) 6.658908505887e-005, + (float) - 2.770661665078e-004, (float) - 7.913713870114e-005, (float) 2.786327455942e-004, (float) 9.185585608604e-005, (float) - 2.798865730517e-004, + (float) - 1.049053516406e-004, (float) 2.807049278836e-004, (float) 1.182425329275e-004, (float) - 2.810498626639e-004, (float) - 1.318263284371e-004, + (float) 2.808967923003e-004, (float) 1.455506215115e-004, (float) - 2.804597862803e-004, (float) - 1.597707317081e-004, (float) 2.793085842202e-004, + (float) 1.741553960777e-004, (float) - 2.775743726755e-004, (float) - 1.887189126391e-004, (float) 2.752088365441e-004, (float) 2.033292028967e-004, + (float) - 2.723750410219e-004, (float) - 2.181185345008e-004, (float) 2.690195363322e-004, (float) 2.331377491223e-004, (float) - 2.650434716994e-004, + (float) - 2.483814212302e-004, (float) 2.602688344952e-004, (float) 2.635383838792e-004, (float) - 2.550401641814e-004, (float) - 2.789293863887e-004, + (float) 2.491244096402e-004, (float) 2.945239709175e-004, (float) - 2.422677063636e-004, (float) - 3.097933373634e-004, (float) 2.353216838587e-004, + (float) 3.261618119620e-004, (float) - 2.259436476779e-004, (float) - 3.401042900591e-004, (float) 2.190501787592e-004, (float) 3.582196439592e-004, + (float) - 2.060273208877e-004, (float) - 3.696711810736e-004, (float) 1.999494168871e-004, (float) 3.895781288432e-004, (float) - 1.842093035737e-004, + (float) - 4.009205689012e-004, (float) 1.747765776478e-004, (float) 4.170995964833e-004, (float) - 1.621552954359e-004, (float) - 4.335350916263e-004, + (float) 1.456088038973e-004, (float) 4.447247309663e-004, (float) - 1.338587279643e-004, (float) - 4.603990618508e-004, (float) 1.185710423385e-004, + (float) 4.756987576397e-004, (float) - 1.000048491894e-004, (float) - 4.866041612047e-004, (float) 8.476411455038e-005, (float) 4.998780903868e-004, + (float) - 6.827228464703e-005, (float) - 5.146667747733e-004, (float) 4.753115459198e-005, (float) 5.255987039514e-004, (float) - 2.779134779343e-005, + (float) - 5.355054669473e-004, (float) 9.674319498129e-006, (float) 5.478734582255e-004, (float) 1.129727308307e-005, (float) - 5.595560306151e-004, + (float) - 3.493017868056e-005, (float) 5.677956913097e-004, (float) 5.713859403233e-005, (float) - 5.757813638276e-004, (float) - 7.867758251969e-005, + (float) 5.852799390936e-004, (float) 1.025052366029e-004, (float) - 5.941431998669e-004, (float) - 1.287437605610e-004, (float) 6.000426995209e-004, + (float) 1.543883746225e-004, (float) - 6.047947232235e-004, (float) - 1.791348851279e-004, (float) 6.103250533849e-004, (float) 2.050193734239e-004, + (float) - 6.160453602904e-004, (float) - 2.334612077119e-004, (float) 6.194421365491e-004, (float) 2.625902273169e-004, (float) - 6.205808968069e-004, + (float) - 2.909797933304e-004, (float) 6.209921559119e-004, (float) 3.189781263679e-004, (float) - 6.218075972611e-004, (float) - 3.484125142872e-004, + (float) 6.217754987501e-004, (float) 3.794107287795e-004, (float) - 6.197373802874e-004, (float) - 4.110126983210e-004, (float) 6.154740944566e-004, + (float) 4.419629007982e-004, (float) - 6.102659557898e-004, (float) - 4.726777081461e-004, (float) 6.046314459814e-004, (float) 5.039254713546e-004, + (float) - 5.984097187292e-004, (float) - 5.364779620831e-004, (float) 5.904522258905e-004, (float) 5.697973331218e-004, (float) - 5.802595330793e-004, + (float) - 6.029679388270e-004, (float) 5.681353065596e-004, (float) 6.352880253925e-004, (float) - 5.552572270111e-004, (float) - 6.675564463085e-004, + (float) 5.416686835400e-004, (float) 7.004526959840e-004, (float) - 5.267382801903e-004, (float) - 7.340039635307e-004, (float) 5.098171451209e-004, + (float) 7.676007675934e-004, (float) - 4.909399565337e-004, (float) - 8.009185568264e-004, (float) 4.701439201458e-004, (float) 8.334617833183e-004, + (float) - 4.480343741175e-004, (float) - 8.653751202061e-004, (float) 4.250690490151e-004, (float) 8.973420149762e-004, (float) - 4.009277182108e-004, + (float) - 9.297436930304e-004, (float) 3.747939959452e-004, (float) 9.620204713426e-004, (float) - 3.465711833398e-004, (float) - 9.937591861314e-004, + (float) 3.163873335071e-004, (float) 1.024733751383e-003, (float) - 2.843503685027e-004, (float) - 1.054638636894e-003, (float) 2.509109323082e-004, + (float) 1.083612570606e-003, (float) - 2.163900938188e-004, (float) - 1.112203502198e-003, (float) 1.803999502271e-004, (float) 1.140444841288e-003, + (float) - 1.425881460745e-004, (float) - 1.168069638194e-003, (float) 1.029125055130e-004, (float) 1.195016515742e-003, (float) - 6.105502150698e-005, + (float) - 1.220730499698e-003, (float) 1.722309885781e-005, (float) 1.244802222599e-003, (float) 2.793170702027e-005, (float) - 1.267597215030e-003, + (float) - 7.433354174569e-005, (float) 1.289443015758e-003, (float) 1.223071384268e-004, (float) - 1.310173684327e-003, (float) - 1.717961954652e-004, + (float) 1.329974954064e-003, (float) 2.232129919651e-004, (float) - 1.348538305787e-003, (float) - 2.767754823491e-004, (float) 1.365216750693e-003, + (float) 3.319638947909e-004, (float) - 1.380095678916e-003, (float) - 3.886579246534e-004, (float) 1.393229786168e-003, (float) 4.469245863820e-004, + (float) - 1.404378077863e-003, (float) - 5.064357635350e-004, (float) 1.413756425541e-003, (float) 5.672145160932e-004, (float) - 1.421549050340e-003, + (float) - 6.296742832444e-004, (float) 1.427153322508e-003, (float) 6.930389693885e-004, (float) - 1.431723738610e-003, (float) - 7.590842956586e-004, + (float) 1.433006680474e-003, (float) 8.254983244591e-004, (float) - 1.433298843968e-003, (float) - 8.949540559698e-004, (float) 1.429349304332e-003, + (float) 9.640000205246e-004, (float) - 1.424329953401e-003, (float) - 1.035464848937e-003, (float) 1.415601499601e-003, (float) 1.106948972842e-003, + (float) - 1.405087088396e-003, (float) - 1.179673831986e-003, (float) 1.392478926372e-003, (float) 1.254375291373e-003, (float) - 1.376198638858e-003, + (float) - 1.329115340603e-003, (float) 1.358185632312e-003, (float) 1.405674275449e-003, (float) - 1.337154931483e-003, (float) - 1.483771621272e-003, + (float) 1.312269387543e-003, (float) 1.561900282048e-003, (float) - 1.285301279727e-003, (float) - 1.642079777660e-003, (float) 1.254114183544e-003, + (float) 1.722681043912e-003, (float) - 1.219211242008e-003, (float) - 1.803063205736e-003, (float) 1.181949655991e-003, (float) 1.884828365040e-003, + (float) - 1.140994785147e-003, (float) - 1.967442657059e-003, (float) 1.095925463900e-003, (float) 2.049903843463e-003, (float) - 1.047877974227e-003, + (float) - 2.133252204410e-003, (float) 9.962070742267e-004, (float) 2.217664374578e-003, (float) - 9.399028586473e-004, (float) - 2.301879563126e-003, + (float) 8.799533412324e-004, (float) 2.386557312794e-003, (float) - 8.160716710263e-004, (float) - 2.472094691981e-003, (float) 7.471803656806e-004, + (float) 2.557416285858e-003, (float) - 6.736494366209e-004, (float) - 2.642112224434e-003, (float) 5.963947377435e-004, (float) 2.727379304929e-003, + (float) - 5.143438896094e-004, (float) - 2.812899297523e-003, (float) 4.268830572252e-004, (float) 2.897715073078e-003, (float) - 3.346488919796e-004, + (float) - 2.981956373303e-003, (float) 2.380521797797e-004, (float) 3.066623414599e-003, (float) - 1.359382829811e-004, (float) - 3.151255446637e-003, + (float) 2.782985135369e-005, (float) 3.235110828048e-003, (float) 8.584892395569e-005, (float) - 3.318355500563e-003, (float) - 2.049786891772e-004, + (float) 3.401760376538e-003, (float) 3.307328425452e-004, (float) - 3.484791457407e-003, (float) - 4.636621183957e-004, (float) 3.566606134171e-003, + (float) 6.034051597652e-004, (float) - 3.647201821596e-003, (float) - 7.497497805930e-004, (float) 3.727291920777e-003, (float) 9.036595637004e-004, + (float) - 3.806649107069e-003, (float) - 1.065867612984e-003, (float) 3.884567294966e-003, (float) 1.236277315086e-003, (float) - 3.961005564525e-003, + (float) - 1.414791150723e-003, (float) 4.036756667297e-003, (float) 1.602515835838e-003, (float) - 4.111869542510e-003, (float) - 1.800743383460e-003, + (float) 4.185540927469e-003, (float) 2.009872291898e-003, (float) - 4.257408085939e-003, (float) - 2.230058942337e-003, (float) 4.327941872004e-003, + (float) 2.462366047089e-003, (float) - 4.397272684020e-003, (float) - 2.708200770755e-003, (float) 4.464960149734e-003, (float) 2.968539548004e-003, + (float) - 4.530883832943e-003, (float) - 3.244542924923e-003, (float) 4.595095710114e-003, (float) 3.537784469302e-003, (float) - 4.657460095921e-003, + (float) - 3.849899735547e-003, (float) 4.718000809430e-003, (float) 4.182843960043e-003, (float) - 4.776999990045e-003, (float) - 4.539528511166e-003, + (float) 4.833943437272e-003, (float) 4.922646164542e-003, (float) - 4.888454593861e-003, (float) - 5.334885946192e-003, (float) 4.941143760176e-003, + (float) 5.780469043985e-003, (float) - 4.992461365274e-003, (float) - 6.265199509171e-003, (float) 5.041554413526e-003, (float) 6.794738285542e-003, + (float) - 5.088173036641e-003, (float) - 7.376044395058e-003, (float) 5.132524592209e-003, (float) 8.018375971792e-003, (float) - 5.174387044018e-003, + (float) - 8.733007006427e-003, (float) 5.213750365616e-003, (float) 9.534285432471e-003, (float) - 5.251195927114e-003, (float) - 1.044195072235e-002, + (float) 5.286143606555e-003, (float) 1.148100562390e-002, (float) - 5.318182436083e-003, (float) - 1.268466390300e-002, (float) 5.347878808814e-003, + (float) 1.410004942171e-002, (float) - 5.375128932984e-003, (float) - 1.579376157069e-002, (float) 5.399698942850e-003, (float) 1.786325203520e-002, + (float) - 5.422169472156e-003, (float) - 2.045920855579e-002, (float) 5.442242611442e-003, (float) 2.382438645728e-002, (float) - 5.459104973796e-003, + (float) - 2.837649392789e-002, (float) 5.474214913211e-003, (float) 3.490845950781e-002, (float) - 5.486081437467e-003, (float) - 4.511486713033e-002, + (float) 5.495807726126e-003, (float) 6.340609543466e-002, (float) - 5.502587343827e-003, (float) - 1.059496325621e-001, (float) 5.506719537453e-003, + (float) 3.182586432339e-001, (float) 4.944918979528e-001, (float) 3.182586432339e-001, (float) 5.506719537453e-003, (float) - 1.059496325621e-001, + (float) - 5.502587343827e-003, (float) 6.340609543466e-002, (float) 5.495807726126e-003, (float) - 4.511486713033e-002, (float) - 5.486081437467e-003, + (float) 3.490845950781e-002, (float) 5.474214913211e-003, (float) - 2.837649392789e-002, (float) - 5.459104973796e-003, (float) 2.382438645728e-002, + (float) 5.442242611442e-003, (float) - 2.045920855579e-002, (float) - 5.422169472156e-003, (float) 1.786325203520e-002, (float) 5.399698942850e-003, + (float) - 1.579376157069e-002, (float) - 5.375128932984e-003, (float) 1.410004942171e-002, (float) 5.347878808814e-003, (float) - 1.268466390300e-002, + (float) - 5.318182436083e-003, (float) 1.148100562390e-002, (float) 5.286143606555e-003, (float) - 1.044195072235e-002, (float) - 5.251195927114e-003, + (float) 9.534285432471e-003, (float) 5.213750365616e-003, (float) - 8.733007006427e-003, (float) - 5.174387044018e-003, (float) 8.018375971792e-003, + (float) 5.132524592209e-003, (float) - 7.376044395058e-003, (float) - 5.088173036641e-003, (float) 6.794738285542e-003, (float) 5.041554413526e-003, + (float) - 6.265199509171e-003, (float) - 4.992461365274e-003, (float) 5.780469043985e-003, (float) 4.941143760176e-003, (float) - 5.334885946192e-003, + (float) - 4.888454593861e-003, (float) 4.922646164542e-003, (float) 4.833943437272e-003, (float) - 4.539528511166e-003, (float) - 4.776999990045e-003, + (float) 4.182843960043e-003, (float) 4.718000809430e-003, (float) - 3.849899735547e-003, (float) - 4.657460095921e-003, (float) 3.537784469302e-003, + (float) 4.595095710114e-003, (float) - 3.244542924923e-003, (float) - 4.530883832943e-003, (float) 2.968539548004e-003, (float) 4.464960149734e-003, + (float) - 2.708200770755e-003, (float) - 4.397272684020e-003, (float) 2.462366047089e-003, (float) 4.327941872004e-003, (float) - 2.230058942337e-003, + (float) - 4.257408085939e-003, (float) 2.009872291898e-003, (float) 4.185540927469e-003, (float) - 1.800743383460e-003, (float) - 4.111869542510e-003, + (float) 1.602515835838e-003, (float) 4.036756667297e-003, (float) - 1.414791150723e-003, (float) - 3.961005564525e-003, (float) 1.236277315086e-003, + (float) 3.884567294966e-003, (float) - 1.065867612984e-003, (float) - 3.806649107069e-003, (float) 9.036595637004e-004, (float) 3.727291920777e-003, + (float) - 7.497497805930e-004, (float) - 3.647201821596e-003, (float) 6.034051597652e-004, (float) 3.566606134171e-003, (float) - 4.636621183957e-004, + (float) - 3.484791457407e-003, (float) 3.307328425452e-004, (float) 3.401760376538e-003, (float) - 2.049786891772e-004, (float) - 3.318355500563e-003, + (float) 8.584892395569e-005, (float) 3.235110828048e-003, (float) 2.782985135369e-005, (float) - 3.151255446637e-003, (float) - 1.359382829811e-004, + (float) 3.066623414599e-003, (float) 2.380521797797e-004, (float) - 2.981956373303e-003, (float) - 3.346488919796e-004, (float) 2.897715073078e-003, + (float) 4.268830572252e-004, (float) - 2.812899297523e-003, (float) - 5.143438896094e-004, (float) 2.727379304929e-003, (float) 5.963947377435e-004, + (float) - 2.642112224434e-003, (float) - 6.736494366209e-004, (float) 2.557416285858e-003, (float) 7.471803656806e-004, (float) - 2.472094691981e-003, + (float) - 8.160716710263e-004, (float) 2.386557312794e-003, (float) 8.799533412324e-004, (float) - 2.301879563126e-003, (float) - 9.399028586473e-004, + (float) 2.217664374578e-003, (float) 9.962070742267e-004, (float) - 2.133252204410e-003, (float) - 1.047877974227e-003, (float) 2.049903843463e-003, + (float) 1.095925463900e-003, (float) - 1.967442657059e-003, (float) - 1.140994785147e-003, (float) 1.884828365040e-003, (float) 1.181949655991e-003, + (float) - 1.803063205736e-003, (float) - 1.219211242008e-003, (float) 1.722681043912e-003, (float) 1.254114183544e-003, (float) - 1.642079777660e-003, + (float) - 1.285301279727e-003, (float) 1.561900282048e-003, (float) 1.312269387543e-003, (float) - 1.483771621272e-003, (float) - 1.337154931483e-003, + (float) 1.405674275449e-003, (float) 1.358185632312e-003, (float) - 1.329115340603e-003, (float) - 1.376198638858e-003, (float) 1.254375291373e-003, + (float) 1.392478926372e-003, (float) - 1.179673831986e-003, (float) - 1.405087088396e-003, (float) 1.106948972842e-003, (float) 1.415601499601e-003, + (float) - 1.035464848937e-003, (float) - 1.424329953401e-003, (float) 9.640000205246e-004, (float) 1.429349304332e-003, (float) - 8.949540559698e-004, + (float) - 1.433298843968e-003, (float) 8.254983244591e-004, (float) 1.433006680474e-003, (float) - 7.590842956586e-004, (float) - 1.431723738610e-003, + (float) 6.930389693885e-004, (float) 1.427153322508e-003, (float) - 6.296742832444e-004, (float) - 1.421549050340e-003, (float) 5.672145160932e-004, + (float) 1.413756425541e-003, (float) - 5.064357635350e-004, (float) - 1.404378077863e-003, (float) 4.469245863820e-004, (float) 1.393229786168e-003, + (float) - 3.886579246534e-004, (float) - 1.380095678916e-003, (float) 3.319638947909e-004, (float) 1.365216750693e-003, (float) - 2.767754823491e-004, + (float) - 1.348538305787e-003, (float) 2.232129919651e-004, (float) 1.329974954064e-003, (float) - 1.717961954652e-004, (float) - 1.310173684327e-003, + (float) 1.223071384268e-004, (float) 1.289443015758e-003, (float) - 7.433354174569e-005, (float) - 1.267597215030e-003, (float) 2.793170702027e-005, + (float) 1.244802222599e-003, (float) 1.722309885781e-005, (float) - 1.220730499698e-003, (float) - 6.105502150698e-005, (float) 1.195016515742e-003, + (float) 1.029125055130e-004, (float) - 1.168069638194e-003, (float) - 1.425881460745e-004, (float) 1.140444841288e-003, (float) 1.803999502271e-004, + (float) - 1.112203502198e-003, (float) - 2.163900938188e-004, (float) 1.083612570606e-003, (float) 2.509109323082e-004, (float) - 1.054638636894e-003, + (float) - 2.843503685027e-004, (float) 1.024733751383e-003, (float) 3.163873335071e-004, (float) - 9.937591861314e-004, (float) - 3.465711833398e-004, + (float) 9.620204713426e-004, (float) 3.747939959452e-004, (float) - 9.297436930304e-004, (float) - 4.009277182108e-004, (float) 8.973420149762e-004, + (float) 4.250690490151e-004, (float) - 8.653751202061e-004, (float) - 4.480343741175e-004, (float) 8.334617833183e-004, (float) 4.701439201458e-004, + (float) - 8.009185568264e-004, (float) - 4.909399565337e-004, (float) 7.676007675934e-004, (float) 5.098171451209e-004, (float) - 7.340039635307e-004, + (float) - 5.267382801903e-004, (float) 7.004526959840e-004, (float) 5.416686835400e-004, (float) - 6.675564463085e-004, (float) - 5.552572270111e-004, + (float) 6.352880253925e-004, (float) 5.681353065596e-004, (float) - 6.029679388270e-004, (float) - 5.802595330793e-004, (float) 5.697973331218e-004, + (float) 5.904522258905e-004, (float) - 5.364779620831e-004, (float) - 5.984097187292e-004, (float) 5.039254713546e-004, (float) 6.046314459814e-004, + (float) - 4.726777081461e-004, (float) - 6.102659557898e-004, (float) 4.419629007982e-004, (float) 6.154740944566e-004, (float) - 4.110126983210e-004, + (float) - 6.197373802874e-004, (float) 3.794107287795e-004, (float) 6.217754987501e-004, (float) - 3.484125142872e-004, (float) - 6.218075972611e-004, + (float) 3.189781263679e-004, (float) 6.209921559119e-004, (float) - 2.909797933304e-004, (float) - 6.205808968069e-004, (float) 2.625902273169e-004, + (float) 6.194421365491e-004, (float) - 2.334612077119e-004, (float) - 6.160453602904e-004, (float) 2.050193734239e-004, (float) 6.103250533849e-004, + (float) - 1.791348851279e-004, (float) - 6.047947232235e-004, (float) 1.543883746225e-004, (float) 6.000426995209e-004, (float) - 1.287437605610e-004, + (float) - 5.941431998669e-004, (float) 1.025052366029e-004, (float) 5.852799390936e-004, (float) - 7.867758251969e-005, (float) - 5.757813638276e-004, + (float) 5.713859403233e-005, (float) 5.677956913097e-004, (float) - 3.493017868056e-005, (float) - 5.595560306151e-004, (float) 1.129727308307e-005, + (float) 5.478734582255e-004, (float) 9.674319498129e-006, (float) - 5.355054669473e-004, (float) - 2.779134779343e-005, (float) 5.255987039514e-004, + (float) 4.753115459198e-005, (float) - 5.146667747733e-004, (float) - 6.827228464703e-005, (float) 4.998780903868e-004, (float) 8.476411455038e-005, + (float) - 4.866041612047e-004, (float) - 1.000048491894e-004, (float) 4.756987576397e-004, (float) 1.185710423385e-004, (float) - 4.603990618508e-004, + (float) - 1.338587279643e-004, (float) 4.447247309663e-004, (float) 1.456088038973e-004, (float) - 4.335350916263e-004, (float) - 1.621552954359e-004, + (float) 4.170995964833e-004, (float) 1.747765776478e-004, (float) - 4.009205689012e-004, (float) - 1.842093035737e-004, (float) 3.895781288432e-004, + (float) 1.999494168871e-004, (float) - 3.696711810736e-004, (float) - 2.060273208877e-004, (float) 3.582196439592e-004, (float) 2.190501787592e-004, + (float) - 3.401042900591e-004, (float) - 2.259436476779e-004, (float) 3.261618119620e-004, (float) 2.353216838587e-004, (float) - 3.097933373634e-004, + (float) - 2.422677063636e-004, (float) 2.945239709175e-004, (float) 2.491244096402e-004, (float) - 2.789293863887e-004, (float) - 2.550401641814e-004, + (float) 2.635383838792e-004, (float) 2.602688344952e-004, (float) - 2.483814212302e-004, (float) - 2.650434716994e-004, (float) 2.331377491223e-004, + (float) 2.690195363322e-004, (float) - 2.181185345008e-004, (float) - 2.723750410219e-004, (float) 2.033292028967e-004, (float) 2.752088365441e-004, + (float) - 1.887189126391e-004, (float) - 2.775743726755e-004, (float) 1.741553960777e-004, (float) 2.793085842202e-004, (float) - 1.597707317081e-004, + (float) - 2.804597862803e-004, (float) 1.455506215115e-004, (float) 2.808967923003e-004, (float) - 1.318263284371e-004, (float) - 2.810498626639e-004, + (float) 1.182425329275e-004, (float) 2.807049278836e-004, (float) - 1.049053516406e-004, (float) - 2.798865730517e-004, (float) 9.185585608604e-005, + (float) 2.786327455942e-004, (float) - 7.913713870114e-005, (float) - 2.770661665078e-004, (float) 6.658908505887e-005, (float) 2.749705769146e-004, + (float) - 5.452878257789e-005, (float) - 2.727139254030e-004, (float) 4.267470287693e-005, (float) 2.701901534524e-004, (float) - 3.098103063675e-005, + (float) - 2.672713250910e-004, (float) 1.959506007225e-005, (float) 2.640373512578e-004, (float) - 8.605011575155e-006, (float) - 2.607451266109e-004, + (float) - 2.297001211178e-006, (float) 2.571630808553e-004, (float) 1.298908745154e-005, (float) - 2.533379001119e-004, (float) - 2.346096839263e-005, + (float) 2.493326534241e-004, (float) 3.380378919976e-005, (float) - 2.450580921435e-004, (float) - 4.394022835345e-005, (float) 2.405543319009e-004, + (float) 5.380295174011e-005, (float) - 2.360269018314e-004, (float) - 6.362969041322e-005, (float) 2.313695981464e-004, (float) 7.350850871907e-005, + (float) - 2.263811595801e-004, (float) - 8.322092258564e-005, (float) 2.212630220095e-004, (float) 9.291206030779e-005, (float) - 2.159988725649e-004, + (float) - 1.026783876418e-004, (float) 2.105136263884e-004, (float) 1.125436526441e-004, (float) - 2.047505646951e-004, (float) - 1.224823030873e-004, + (float) 1.988019142637e-004, (float) 1.327632434198e-004, (float) - 1.923098357663e-004, (float) - 1.431090602159e-004, (float) 1.854489350961e-004, + (float) 1.536329356026e-004, (float) - 1.782437567680e-004, (float) - 1.645342831667e-004, (float) 1.705747652949e-004, (float) 1.760669168660e-004, + (float) - 1.619282978772e-004, (float) - 1.878370907468e-004, (float) 1.525152442899e-004, (float) 2.001325818624e-004, (float) - 1.420059883336e-004, + (float) - 2.128963846610e-004, (float) 1.302389953023e-004, (float) 2.262277295494e-004, (float) - 1.167662237676e-004, (float) - 2.398340044811e-004, + (float) 1.015795101283e-004, (float) 2.539623487208e-004, (float) - 8.400473971490e-005, (float) - 2.682059180462e-004, (float) 6.386636089117e-005, + (float) 2.826060999738e-004, (float) - 4.040411770010e-005, (float) - 2.965903264243e-004, (float) 1.328843895284e-005, (float) 3.099640470313e-004, + (float) 1.843967368528e-005, (float) - 3.217977487285e-004, (float) - 5.533287789728e-005, (float) 3.312977192436e-004, (float) 9.845446547453e-005, + (float) - 3.367394950886e-004, (float) - 1.482361183421e-004, (float) 3.366006455231e-004, (float) 2.057925864008e-004, (float) - 3.278882894771e-004, + (float) - 2.713518058883e-004, (float) 3.071631118731e-004, (float) 3.450469073084e-004, (float) - 2.693320767774e-004, (float) - 4.257030079639e-004, + (float) 2.077730139398e-004, (float) 5.103528659400e-004, (float) - 1.133457948942e-004, (float) - 5.918859501058e-004, (float) - 2.508428842065e-005, + (float) 6.567967063227e-004, (float) 2.211378711751e-004, (float) - 6.784989588347e-004, (float) - 4.869084931865e-004, (float) 6.081914903075e-004, + (float) 8.234667012568e-004, (float) - 3.557893702940e-004, (float) - 1.185316896754e-003, (float) - 2.336521287917e-004, (float) 1.370278722621e-003, + (float) 1.368071261832e-003, (float) - 6.494578851510e-004, (float) - 2.821616068751e-003, (float) - 3.355260288418e-003, (float) - 2.309090436241e-003, + (float) - 9.559790653313e-004, (float) - 1.916895913880e-004, (float) 3.796696928466e-006 + }; + + *lenh0 = lensh02; /* store 'number of coefficients' */ + *h0 = sh02; /* store pointer to h02[]-array */ +} + +#undef lensh02 +/* ....................... End of fill_slp_2_to_1() ....................... */ + + + +/* + ============================================================================ + + void fill_slp_3_to_1 (float **h0, long *lenh0); + ~~~~~~~~~~~~~~~~~~~ + + Description: + ~~~~~~~~~~~~ + + Initialize pointer to array with FIR coefficients for up/down + sampling low-pass filter with factor 3:1 or 1:3 and 24 bit + representation. + v1.0 filtdemo firpm 16000,2602,2667,0.3, 80, 728 + v1.1 filtdemo firpm 16000,2602,2667,0.3, 100, 872 + h3 = filtdemo('getfilt') + for i = 1:length(h3) fprintf('(float)%20.12e, ', h3(i)); + if rem(i,5) == 0 fprintf('\n'); end end + + Parameters: + ~~~~~~~~~~~ + h0: (Out) pointer to array with FIR coefficients + lenh0: (Out) pointer to number of coefficients + + + Return value: + ~~~~~~~~~~~~~ + None. + + Author: + ~~~~~~~ + + History: + ~~~~~~~~ + 05.April.2012 v1.0 - Added filters: SHQ2 and SHQ3 (France Telecom) + + ============================================================================ +*/ +#define lensh03 873 + +void fill_slp_3_to_1 (h0, lenh0) + float **h0; + long *lenh0; +{ + static float sh03[lensh03] = { + (float) - 5.702667454304e-005, (float) - 2.290248756652e-004, (float) - 5.695388694927e-004, (float) - 1.047262848994e-003, (float) - 1.506278259322e-003, + (float) - 1.697084386485e-003, (float) - 1.398843870300e-003, (float) - 5.776254455710e-004, (float) 5.267279465880e-004, (float) 1.474227829087e-003, + (float) 1.850941005949e-003, (float) 1.521886181517e-003, (float) 7.374635156026e-004, (float) - 2.831586756965e-006, (float) - 2.610758773407e-004, + (float) 5.790488592536e-005, (float) 6.558699193392e-004, (float) 1.065027553853e-003, (float) 9.887411557505e-004, (float) 5.083645939775e-004, + (float) 2.342940220659e-006, (float) - 1.567062494057e-004, (float) 1.110403908595e-004, (float) 5.457214173255e-004, (float) 7.717764862227e-004, + (float) 6.055726812478e-004, (float) 1.949515317766e-004, (float) - 1.184196188439e-004, (float) - 9.160203082544e-005, (float) 2.209374944482e-004, + (float) 5.265018221270e-004, (float) 5.531560214976e-004, (float) 2.815751711742e-004, (float) - 4.853153913830e-005, (float) - 1.563367357580e-004, + (float) 3.366074541317e-005, (float) 3.328093694602e-004, (float) 4.636714131641e-004, (float) 3.086568259652e-004, (float) 9.521084805123e-006, + (float) - 1.672524549008e-004, (float) - 7.321835254365e-005, (float) 1.915905388598e-004, (float) 3.756857462901e-004, (float) 3.081437126124e-004, + (float) 5.226907920748e-005, (float) - 1.575946050063e-004, (float) - 1.344789464591e-004, (float) 9.034674803378e-005, (float) 3.003518594011e-004, + (float) 2.971198893452e-004, (float) 8.384203623239e-005, (float) - 1.407963804041e-004, (float) - 1.703890216943e-004, (float) 1.652684652722e-005, + (float) 2.386510548738e-004, (float) 2.839782736591e-004, (float) 1.090673723768e-004, (float) - 1.216308514221e-004, (float) - 1.923295141096e-004, + (float) - 3.985072213105e-005, (float) 1.875991204246e-004, (float) 2.717660216481e-004, (float) 1.314707046626e-004, (float) - 1.008243557814e-004, + (float) - 2.054434756406e-004, (float) - 8.467292384865e-005, (float) 1.442573681930e-004, (float) 2.610066066766e-004, (float) 1.524510476976e-004, + (float) - 7.902847673495e-005, (float) - 2.130526218114e-004, (float) - 1.219890713673e-004, (float) 1.063399253112e-004, (float) 2.519859951800e-004, + (float) 1.734491436341e-004, (float) - 5.587231315091e-005, (float) - 2.169349988011e-004, (float) - 1.549061289756e-004, (float) 7.120763788262e-005, + (float) 2.437177281471e-004, (float) 1.948555676425e-004, (float) - 3.086033846812e-005, (float) - 2.175745882557e-004, (float) - 1.849236252476e-004, + (float) 3.722566423543e-005, (float) 2.353340603942e-004, (float) 2.167081052392e-004, (float) - 3.703170533307e-006, (float) - 2.152202989036e-004, + (float) - 2.130638454690e-004, (float) 3.078805881752e-006, (float) 2.259877675272e-004, (float) 2.390210432952e-004, (float) 2.617581267358e-005, + (float) - 2.094639911149e-004, (float) - 2.396408397869e-004, (float) - 3.220609123686e-005, (float) 2.146367670825e-004, (float) 2.613020076192e-004, + (float) 5.899602321765e-005, (float) - 1.997806524280e-004, (float) - 2.644528721997e-004, (float) - 6.908347167316e-005, (float) 2.003994342832e-004, + (float) 2.828118853525e-004, (float) 9.456005724760e-005, (float) - 1.859305896169e-004, (float) - 2.873053305036e-004, (float) - 1.078135783906e-004, + (float) 1.825933898221e-004, (float) 3.028816854225e-004, (float) 1.326435299606e-004, (float) - 1.676779512332e-004, (float) - 3.079331791370e-004, + (float) - 1.485750250569e-004, (float) 1.605453339105e-004, (float) 3.207874253071e-004, (float) 1.729981027969e-004, (float) - 1.446923844597e-004, + (float) - 3.258518962902e-004, (float) - 1.912839973272e-004, (float) 1.337849210997e-004, (float) 3.359204137548e-004, (float) 2.154852410306e-004, + (float) - 1.164355791130e-004, (float) - 3.402946219591e-004, (float) - 2.356749110871e-004, (float) 1.017519030470e-004, (float) 3.473219066124e-004, + (float) 2.595861094810e-004, (float) - 8.247985162440e-005, (float) - 3.501778624332e-004, (float) - 2.808530765872e-004, (float) 6.448731739501e-005, + (float) 3.542546122559e-004, (float) 3.044839629528e-004, (float) - 4.306342775237e-005, (float) - 3.551282513302e-004, (float) - 3.263921987448e-004, + (float) 2.192426783394e-005, (float) 3.561971331453e-004, (float) 3.497859191992e-004, (float) 2.055980934252e-006, (float) - 3.544148970394e-004, + (float) - 3.717977628683e-004, (float) - 2.629987685449e-005, (float) 3.520514596533e-004, (float) 3.944857642507e-004, (float) 5.277571215679e-005, + (float) - 3.471915002737e-004, (float) - 4.160648347652e-004, (float) - 7.993813455368e-005, (float) 3.411114019359e-004, (float) 4.376339448427e-004, + (float) 1.088493550823e-004, (float) - 3.327174320834e-004, (float) - 4.581277303213e-004, (float) - 1.385955596429e-004, (float) 3.227066885945e-004, + (float) 4.780809063323e-004, (float) 1.696775520342e-004, (float) - 3.105144597273e-004, (float) - 4.968659484029e-004, (float) - 2.014702976084e-004, + (float) 2.967304590010e-004, (float) 5.150937489368e-004, (float) 2.347087797104e-004, (float) - 2.804528555952e-004, (float) - 5.317678587328e-004, + (float) - 2.684301130237e-004, (float) 2.625408226728e-004, (float) 5.476982715351e-004, (float) 3.035278106007e-004, (float) - 2.419332992486e-004, + (float) - 5.617064251919e-004, (float) - 3.388485533212e-004, (float) 2.196467033878e-004, (float) 5.746786785084e-004, (float) 3.752457273392e-004, + (float) - 1.947946881500e-004, (float) - 5.857581310721e-004, (float) - 4.120508580248e-004, (float) 1.677356672876e-004, (float) 5.950203471973e-004, + (float) 4.492196431000e-004, (float) - 1.384637472272e-004, (float) - 6.023600081843e-004, (float) - 4.866311063082e-004, (float) 1.070101277961e-004, + (float) 6.077115455789e-004, (float) 5.242229671950e-004, (float) - 7.332517897366e-005, (float) - 6.108956903682e-004, (float) - 5.617572406918e-004, + (float) 3.765710388723e-005, (float) 6.122535665132e-004, (float) 5.998690210736e-004, (float) 1.103337252265e-006, (float) - 6.101918060802e-004, + (float) - 6.366652752751e-004, (float) - 4.101866700778e-005, (float) 6.065187804431e-004, (float) 6.737711020146e-004, (float) 8.349599417419e-005, + (float) - 6.001874205543e-004, (float) - 7.107611600986e-004, (float) - 1.289670732718e-004, (float) 5.898895822538e-004, (float) 7.457161842468e-004, + (float) 1.753449481877e-004, (float) - 5.774443295022e-004, (float) - 7.798678193657e-004, (float) - 2.230334725061e-004, (float) 5.635271134980e-004, + (float) 8.152306244447e-004, (float) 2.755046534225e-004, (float) - 5.434273506344e-004, (float) - 8.464802274973e-004, (float) - 3.277092661666e-004, + (float) 5.210307991128e-004, (float) 8.756596447340e-004, (float) 3.794273420016e-004, (float) - 4.990318212014e-004, (float) - 9.079503131393e-004, + (float) - 4.380386208554e-004, (float) 4.685715007029e-004, (float) 9.341398358924e-004, (float) 4.952457363886e-004, (float) - 4.360095410718e-004, + (float) - 9.581583004572e-004, (float) - 5.526178358650e-004, (float) 4.017025817632e-004, (float) 9.817267986707e-004, (float) 6.126724675261e-004, + (float) - 3.629093431450e-004, (float) - 1.002439646862e-003, (float) - 6.737587650718e-004, (float) 3.204253623397e-004, (float) 1.020517658997e-003, + (float) 7.360180736312e-004, (float) - 2.737981347557e-004, (float) - 1.035166912472e-003, (float) - 7.986608366722e-004, (float) 2.233015838909e-004, + (float) 1.045721090576e-003, (float) 8.598542706791e-004, (float) - 1.720078687206e-004, (float) - 1.056474335818e-003, (float) - 9.249608577418e-004, + (float) 1.139016227189e-004, (float) 1.061470672775e-003, (float) 9.889032323226e-004, (float) - 5.260312145850e-005, (float) - 1.062802973797e-003, + (float) - 1.052661166844e-003, (float) - 1.234469409022e-005, (float) 1.060136819634e-003, (float) 1.115982607845e-003, (float) 8.099003769379e-005, + (float) - 1.052868934904e-003, (float) - 1.177547710041e-003, (float) - 1.512053491539e-004, (float) 1.044016157338e-003, (float) 1.241286624384e-003, + (float) 2.276412600050e-004, (float) - 1.028714494774e-003, (float) - 1.302806041666e-003, (float) - 3.068949503392e-004, (float) 1.009322937005e-003, + (float) 1.363843344369e-003, (float) 3.906609064444e-004, (float) - 9.838656513075e-004, (float) - 1.422262246448e-003, (float) - 4.770635768666e-004, + (float) 9.535551337159e-004, (float) 1.478448816939e-003, (float) 5.657155736003e-004, (float) - 9.194440566142e-004, (float) - 1.534039735215e-003, + (float) - 6.587006775073e-004, (float) 8.793107473467e-004, (float) 1.587111750398e-003, (float) 7.547147875959e-004, (float) - 8.338828124821e-004, + (float) - 1.638222602213e-003, (float) - 8.546083977396e-004, (float) 7.818895385424e-004, (float) 1.686035622285e-003, (float) 9.575865466165e-004, + (float) - 7.231383262379e-004, (float) - 1.729347857177e-003, (float) - 1.061753152135e-003, (float) 6.598691919979e-004, (float) 1.770597985361e-003, + (float) 1.169781516343e-003, (float) - 5.891500710358e-004, (float) - 1.806699639550e-003, (float) - 1.278568313904e-003, (float) 5.141179931545e-004, + (float) 1.841027853974e-003, (float) 1.391905141504e-003, (float) - 4.306947853300e-004, (float) - 1.869713791607e-003, (float) - 1.506708961470e-003, + (float) 3.409327833389e-004, (float) 1.894038136926e-003, (float) 1.624014474020e-003, (float) - 2.437048054541e-004, (float) - 1.912908177017e-003, + (float) - 1.743223810231e-003, (float) 1.387216181787e-004, (float) 1.925117887436e-003, (float) 1.862486593022e-003, (float) - 2.821070804092e-005, + (float) - 1.933229951667e-003, (float) - 1.984800448536e-003, (float) - 9.123378372710e-005, (float) 1.933710705029e-003, (float) 2.106846839834e-003, + (float) 2.165780283200e-004, (float) - 1.929629718754e-003, (float) - 2.232160937187e-003, (float) - 3.519049528335e-004, (float) 1.916818837101e-003, + (float) 2.357203940722e-003, (float) 4.947204738569e-004, (float) - 1.896926099071e-003, (float) - 2.483378267598e-003, (float) - 6.466372123975e-004, + (float) 1.868195138012e-003, (float) 2.609246811353e-003, (float) 8.069238284096e-004, (float) - 1.830682441595e-003, (float) - 2.734527768949e-003, + (float) - 9.751897771009e-004, (float) 1.785017781192e-003, (float) 2.860388753350e-003, (float) 1.153172877730e-003, (float) - 1.729312203396e-003, + (float) - 2.985339528727e-003, (float) - 1.339916394519e-003, (float) 1.664473634983e-003, (float) 3.110932565488e-003, (float) 1.537838751758e-003, + (float) - 1.587754627653e-003, (float) - 3.234954638367e-003, (float) - 1.745673580609e-003, (float) 1.499886644666e-003, (float) 3.358421754204e-003, + (float) 1.965130821805e-003, (float) - 1.398872765578e-003, (float) - 3.479845703961e-003, (float) - 2.195572687404e-003, (float) 1.285003495634e-003, + (float) 3.600016865417e-003, (float) 2.438562967617e-003, (float) - 1.156618036116e-003, (float) - 3.718180542243e-003, (float) - 2.694534774140e-003, + (float) 1.012925180360e-003, (float) 3.834373750933e-003, (float) 2.964679101911e-003, (float) - 8.525485951972e-004, (float) - 3.948403524289e-003, + (float) - 3.250343132486e-003, (float) 6.737384489508e-004, (float) 4.059688224041e-003, (float) 3.552470544664e-003, (float) - 4.754275550708e-004, + (float) - 4.168928142770e-003, (float) - 3.873956808281e-003, (float) 2.542076569209e-004, (float) 4.274495623229e-003, (float) 4.215541860516e-003, + (float) - 8.876791492217e-006, (float) - 4.377372661019e-003, (float) - 4.581049335760e-003, (float) - 2.649760888835e-004, (float) 4.475649547624e-003, + (float) 4.971772999526e-003, (float) 5.691152906036e-004, (float) - 4.570711772495e-003, (float) - 5.392866001693e-003, (float) - 9.088730314323e-004, + (float) 4.661637388475e-003, (float) 5.848570522367e-003, (float) 1.289087294300e-003, (float) - 4.748854210334e-003, (float) - 6.345622677870e-003, + (float) - 1.717082156368e-003, (float) 4.831896281817e-003, (float) 6.891804999608e-003, (float) 2.201630775936e-003, (float) - 4.910578903278e-003, + (float) - 7.497415910832e-003, (float) - 2.754230074063e-003, (float) 4.984610468332e-003, (float) 8.175812718542e-003, (float) 3.389552293110e-003, + (float) - 5.054700764131e-003, (float) - 8.946696508829e-003, (float) - 4.129951171808e-003, (float) 5.118515051062e-003, (float) 9.833011394039e-003, + (float) 5.001471509665e-003, (float) - 5.178437003297e-003, (float) - 1.087335325218e-002, (float) - 6.047856746429e-003, (float) 5.230953032476e-003, + (float) 1.211655268747e-002, (float) 7.325438345332e-003, (float) - 5.280041797037e-003, (float) - 1.364671806495e-002, (float) - 8.931122228028e-003, + (float) 5.322573977944e-003, (float) 1.558985548986e-002, (float) 1.101542440923e-002, (float) - 5.359868891871e-003, (float) - 1.816627590250e-002, + (float) - 1.384581531568e-002, (float) 5.391484192615e-003, (float) 2.178322539469e-002, (float) 1.793508230734e-002, (float) - 5.418411065727e-003, + (float) - 2.729479625998e-002, (float) - 2.441474613854e-002, (float) 5.438809365830e-003, (float) 3.683129238215e-002, (float) 3.635025705283e-002, + (float) - 5.453919890093e-003, (float) - 5.764317282647e-002, (float) - 6.601087176309e-002, (float) 5.463088425909e-003, (float) 1.404772330964e-001, + (float) 2.728880604165e-001, (float) 3.278675322959e-001, (float) 2.728880604165e-001, (float) 1.404772330964e-001, (float) 5.463088425909e-003, + (float) - 6.601087176309e-002, (float) - 5.764317282647e-002, (float) - 5.453919890093e-003, (float) 3.635025705283e-002, (float) 3.683129238215e-002, + (float) 5.438809365830e-003, (float) - 2.441474613854e-002, (float) - 2.729479625998e-002, (float) - 5.418411065727e-003, (float) 1.793508230734e-002, + (float) 2.178322539469e-002, (float) 5.391484192615e-003, (float) - 1.384581531568e-002, (float) - 1.816627590250e-002, (float) - 5.359868891871e-003, + (float) 1.101542440923e-002, (float) 1.558985548986e-002, (float) 5.322573977944e-003, (float) - 8.931122228028e-003, (float) - 1.364671806495e-002, + (float) - 5.280041797037e-003, (float) 7.325438345332e-003, (float) 1.211655268747e-002, (float) 5.230953032476e-003, (float) - 6.047856746429e-003, + (float) - 1.087335325218e-002, (float) - 5.178437003297e-003, (float) 5.001471509665e-003, (float) 9.833011394039e-003, (float) 5.118515051062e-003, + (float) - 4.129951171808e-003, (float) - 8.946696508829e-003, (float) - 5.054700764131e-003, (float) 3.389552293110e-003, (float) 8.175812718542e-003, + (float) 4.984610468332e-003, (float) - 2.754230074063e-003, (float) - 7.497415910832e-003, (float) - 4.910578903278e-003, (float) 2.201630775936e-003, + (float) 6.891804999608e-003, (float) 4.831896281817e-003, (float) - 1.717082156368e-003, (float) - 6.345622677870e-003, (float) - 4.748854210334e-003, + (float) 1.289087294300e-003, (float) 5.848570522367e-003, (float) 4.661637388475e-003, (float) - 9.088730314323e-004, (float) - 5.392866001693e-003, + (float) - 4.570711772495e-003, (float) 5.691152906036e-004, (float) 4.971772999526e-003, (float) 4.475649547624e-003, (float) - 2.649760888835e-004, + (float) - 4.581049335760e-003, (float) - 4.377372661019e-003, (float) - 8.876791492217e-006, (float) 4.215541860516e-003, (float) 4.274495623229e-003, + (float) 2.542076569209e-004, (float) - 3.873956808281e-003, (float) - 4.168928142770e-003, (float) - 4.754275550708e-004, (float) 3.552470544664e-003, + (float) 4.059688224041e-003, (float) 6.737384489508e-004, (float) - 3.250343132486e-003, (float) - 3.948403524289e-003, (float) - 8.525485951972e-004, + (float) 2.964679101911e-003, (float) 3.834373750933e-003, (float) 1.012925180360e-003, (float) - 2.694534774140e-003, (float) - 3.718180542243e-003, + (float) - 1.156618036116e-003, (float) 2.438562967617e-003, (float) 3.600016865417e-003, (float) 1.285003495634e-003, (float) - 2.195572687404e-003, + (float) - 3.479845703961e-003, (float) - 1.398872765578e-003, (float) 1.965130821805e-003, (float) 3.358421754204e-003, (float) 1.499886644666e-003, + (float) - 1.745673580609e-003, (float) - 3.234954638367e-003, (float) - 1.587754627653e-003, (float) 1.537838751758e-003, (float) 3.110932565488e-003, + (float) 1.664473634983e-003, (float) - 1.339916394519e-003, (float) - 2.985339528727e-003, (float) - 1.729312203396e-003, (float) 1.153172877730e-003, + (float) 2.860388753350e-003, (float) 1.785017781192e-003, (float) - 9.751897771009e-004, (float) - 2.734527768949e-003, (float) - 1.830682441595e-003, + (float) 8.069238284096e-004, (float) 2.609246811353e-003, (float) 1.868195138012e-003, (float) - 6.466372123975e-004, (float) - 2.483378267598e-003, + (float) - 1.896926099071e-003, (float) 4.947204738569e-004, (float) 2.357203940722e-003, (float) 1.916818837101e-003, (float) - 3.519049528335e-004, + (float) - 2.232160937187e-003, (float) - 1.929629718754e-003, (float) 2.165780283200e-004, (float) 2.106846839834e-003, (float) 1.933710705029e-003, + (float) - 9.123378372710e-005, (float) - 1.984800448536e-003, (float) - 1.933229951667e-003, (float) - 2.821070804092e-005, (float) 1.862486593022e-003, + (float) 1.925117887436e-003, (float) 1.387216181787e-004, (float) - 1.743223810231e-003, (float) - 1.912908177017e-003, (float) - 2.437048054541e-004, + (float) 1.624014474020e-003, (float) 1.894038136926e-003, (float) 3.409327833389e-004, (float) - 1.506708961470e-003, (float) - 1.869713791607e-003, + (float) - 4.306947853300e-004, (float) 1.391905141504e-003, (float) 1.841027853974e-003, (float) 5.141179931545e-004, (float) - 1.278568313904e-003, + (float) - 1.806699639550e-003, (float) - 5.891500710358e-004, (float) 1.169781516343e-003, (float) 1.770597985361e-003, (float) 6.598691919979e-004, + (float) - 1.061753152135e-003, (float) - 1.729347857177e-003, (float) - 7.231383262379e-004, (float) 9.575865466165e-004, (float) 1.686035622285e-003, + (float) 7.818895385424e-004, (float) - 8.546083977396e-004, (float) - 1.638222602213e-003, (float) - 8.338828124821e-004, (float) 7.547147875959e-004, + (float) 1.587111750398e-003, (float) 8.793107473467e-004, (float) - 6.587006775073e-004, (float) - 1.534039735215e-003, (float) - 9.194440566142e-004, + (float) 5.657155736003e-004, (float) 1.478448816939e-003, (float) 9.535551337159e-004, (float) - 4.770635768666e-004, (float) - 1.422262246448e-003, + (float) - 9.838656513075e-004, (float) 3.906609064444e-004, (float) 1.363843344369e-003, (float) 1.009322937005e-003, (float) - 3.068949503392e-004, + (float) - 1.302806041666e-003, (float) - 1.028714494774e-003, (float) 2.276412600050e-004, (float) 1.241286624384e-003, (float) 1.044016157338e-003, + (float) - 1.512053491539e-004, (float) - 1.177547710041e-003, (float) - 1.052868934904e-003, (float) 8.099003769379e-005, (float) 1.115982607845e-003, + (float) 1.060136819634e-003, (float) - 1.234469409022e-005, (float) - 1.052661166844e-003, (float) - 1.062802973797e-003, (float) - 5.260312145850e-005, + (float) 9.889032323226e-004, (float) 1.061470672775e-003, (float) 1.139016227189e-004, (float) - 9.249608577418e-004, (float) - 1.056474335818e-003, + (float) - 1.720078687206e-004, (float) 8.598542706791e-004, (float) 1.045721090576e-003, (float) 2.233015838909e-004, (float) - 7.986608366722e-004, + (float) - 1.035166912472e-003, (float) - 2.737981347557e-004, (float) 7.360180736312e-004, (float) 1.020517658997e-003, (float) 3.204253623397e-004, + (float) - 6.737587650718e-004, (float) - 1.002439646862e-003, (float) - 3.629093431450e-004, (float) 6.126724675261e-004, (float) 9.817267986707e-004, + (float) 4.017025817632e-004, (float) - 5.526178358650e-004, (float) - 9.581583004572e-004, (float) - 4.360095410718e-004, (float) 4.952457363886e-004, + (float) 9.341398358924e-004, (float) 4.685715007029e-004, (float) - 4.380386208554e-004, (float) - 9.079503131393e-004, (float) - 4.990318212014e-004, + (float) 3.794273420016e-004, (float) 8.756596447340e-004, (float) 5.210307991128e-004, (float) - 3.277092661666e-004, (float) - 8.464802274973e-004, + (float) - 5.434273506344e-004, (float) 2.755046534225e-004, (float) 8.152306244447e-004, (float) 5.635271134980e-004, (float) - 2.230334725061e-004, + (float) - 7.798678193657e-004, (float) - 5.774443295022e-004, (float) 1.753449481877e-004, (float) 7.457161842468e-004, (float) 5.898895822538e-004, + (float) - 1.289670732718e-004, (float) - 7.107611600986e-004, (float) - 6.001874205543e-004, (float) 8.349599417419e-005, (float) 6.737711020146e-004, + (float) 6.065187804431e-004, (float) - 4.101866700778e-005, (float) - 6.366652752751e-004, (float) - 6.101918060802e-004, (float) 1.103337252265e-006, + (float) 5.998690210736e-004, (float) 6.122535665132e-004, (float) 3.765710388723e-005, (float) - 5.617572406918e-004, (float) - 6.108956903682e-004, + (float) - 7.332517897366e-005, (float) 5.242229671950e-004, (float) 6.077115455789e-004, (float) 1.070101277961e-004, (float) - 4.866311063082e-004, + (float) - 6.023600081843e-004, (float) - 1.384637472272e-004, (float) 4.492196431000e-004, (float) 5.950203471973e-004, (float) 1.677356672876e-004, + (float) - 4.120508580248e-004, (float) - 5.857581310721e-004, (float) - 1.947946881500e-004, (float) 3.752457273392e-004, (float) 5.746786785084e-004, + (float) 2.196467033878e-004, (float) - 3.388485533212e-004, (float) - 5.617064251919e-004, (float) - 2.419332992486e-004, (float) 3.035278106007e-004, + (float) 5.476982715351e-004, (float) 2.625408226728e-004, (float) - 2.684301130237e-004, (float) - 5.317678587328e-004, (float) - 2.804528555952e-004, + (float) 2.347087797104e-004, (float) 5.150937489368e-004, (float) 2.967304590010e-004, (float) - 2.014702976084e-004, (float) - 4.968659484029e-004, + (float) - 3.105144597273e-004, (float) 1.696775520342e-004, (float) 4.780809063323e-004, (float) 3.227066885945e-004, (float) - 1.385955596429e-004, + (float) - 4.581277303213e-004, (float) - 3.327174320834e-004, (float) 1.088493550823e-004, (float) 4.376339448427e-004, (float) 3.411114019359e-004, + (float) - 7.993813455368e-005, (float) - 4.160648347652e-004, (float) - 3.471915002737e-004, (float) 5.277571215679e-005, (float) 3.944857642507e-004, + (float) 3.520514596533e-004, (float) - 2.629987685449e-005, (float) - 3.717977628683e-004, (float) - 3.544148970394e-004, (float) 2.055980934252e-006, + (float) 3.497859191992e-004, (float) 3.561971331453e-004, (float) 2.192426783394e-005, (float) - 3.263921987448e-004, (float) - 3.551282513302e-004, + (float) - 4.306342775237e-005, (float) 3.044839629528e-004, (float) 3.542546122559e-004, (float) 6.448731739501e-005, (float) - 2.808530765872e-004, + (float) - 3.501778624332e-004, (float) - 8.247985162440e-005, (float) 2.595861094810e-004, (float) 3.473219066124e-004, (float) 1.017519030470e-004, + (float) - 2.356749110871e-004, (float) - 3.402946219591e-004, (float) - 1.164355791130e-004, (float) 2.154852410306e-004, (float) 3.359204137548e-004, + (float) 1.337849210997e-004, (float) - 1.912839973272e-004, (float) - 3.258518962902e-004, (float) - 1.446923844597e-004, (float) 1.729981027969e-004, + (float) 3.207874253071e-004, (float) 1.605453339105e-004, (float) - 1.485750250569e-004, (float) - 3.079331791370e-004, (float) - 1.676779512332e-004, + (float) 1.326435299606e-004, (float) 3.028816854225e-004, (float) 1.825933898221e-004, (float) - 1.078135783906e-004, (float) - 2.873053305036e-004, + (float) - 1.859305896169e-004, (float) 9.456005724760e-005, (float) 2.828118853525e-004, (float) 2.003994342832e-004, (float) - 6.908347167316e-005, + (float) - 2.644528721997e-004, (float) - 1.997806524280e-004, (float) 5.899602321765e-005, (float) 2.613020076192e-004, (float) 2.146367670825e-004, + (float) - 3.220609123686e-005, (float) - 2.396408397869e-004, (float) - 2.094639911149e-004, (float) 2.617581267358e-005, (float) 2.390210432952e-004, + (float) 2.259877675272e-004, (float) 3.078805881752e-006, (float) - 2.130638454690e-004, (float) - 2.152202989036e-004, (float) - 3.703170533307e-006, + (float) 2.167081052392e-004, (float) 2.353340603942e-004, (float) 3.722566423543e-005, (float) - 1.849236252476e-004, (float) - 2.175745882557e-004, + (float) - 3.086033846812e-005, (float) 1.948555676425e-004, (float) 2.437177281471e-004, (float) 7.120763788262e-005, (float) - 1.549061289756e-004, + (float) - 2.169349988011e-004, (float) - 5.587231315091e-005, (float) 1.734491436341e-004, (float) 2.519859951800e-004, (float) 1.063399253112e-004, + (float) - 1.219890713673e-004, (float) - 2.130526218114e-004, (float) - 7.902847673495e-005, (float) 1.524510476976e-004, (float) 2.610066066766e-004, + (float) 1.442573681930e-004, (float) - 8.467292384865e-005, (float) - 2.054434756406e-004, (float) - 1.008243557814e-004, (float) 1.314707046626e-004, + (float) 2.717660216481e-004, (float) 1.875991204246e-004, (float) - 3.985072213105e-005, (float) - 1.923295141096e-004, (float) - 1.216308514221e-004, + (float) 1.090673723768e-004, (float) 2.839782736591e-004, (float) 2.386510548738e-004, (float) 1.652684652722e-005, (float) - 1.703890216943e-004, + (float) - 1.407963804041e-004, (float) 8.384203623239e-005, (float) 2.971198893452e-004, (float) 3.003518594011e-004, (float) 9.034674803378e-005, + (float) - 1.344789464591e-004, (float) - 1.575946050063e-004, (float) 5.226907920748e-005, (float) 3.081437126124e-004, (float) 3.756857462901e-004, + (float) 1.915905388598e-004, (float) - 7.321835254365e-005, (float) - 1.672524549008e-004, (float) 9.521084805123e-006, (float) 3.086568259652e-004, + (float) 4.636714131641e-004, (float) 3.328093694602e-004, (float) 3.366074541317e-005, (float) - 1.563367357580e-004, (float) - 4.853153913830e-005, + (float) 2.815751711742e-004, (float) 5.531560214976e-004, (float) 5.265018221270e-004, (float) 2.209374944482e-004, (float) - 9.160203082544e-005, + (float) - 1.184196188439e-004, (float) 1.949515317766e-004, (float) 6.055726812478e-004, (float) 7.717764862227e-004, (float) 5.457214173255e-004, + (float) 1.110403908595e-004, (float) - 1.567062494057e-004, (float) 2.342940220659e-006, (float) 5.083645939775e-004, (float) 9.887411557505e-004, + (float) 1.065027553853e-003, (float) 6.558699193392e-004, (float) 5.790488592536e-005, (float) - 2.610758773407e-004, (float) - 2.831586756965e-006, + (float) 7.374635156026e-004, (float) 1.521886181517e-003, (float) 1.850941005949e-003, (float) 1.474227829087e-003, (float) 5.267279465880e-004, + (float) - 5.776254455710e-004, (float) - 1.398843870300e-003, (float) - 1.697084386485e-003, (float) - 1.506278259322e-003, (float) - 1.047262848994e-003, + (float) - 5.695388694927e-004, (float) - 2.290248756652e-004, (float) - 5.702667454304e-005 + }; + + *lenh0 = lensh03; /* store 'number of coefficients' */ + *h0 = sh03; /* store pointer to h02[]-array */ +} + +#undef lensh03 +/* ........................ End of fill_lp_3_to_1() ........................ */ + + + /* ************************* END OF FIR-FLAT.C ************************** */ diff --git a/src/fir/fir-resamp.c b/src/fir/fir-resamp.c new file mode 100644 index 00000000..381275ea --- /dev/null +++ b/src/fir/fir-resamp.c @@ -0,0 +1,374 @@ +/* 11.Jun.2026 + ============================================================================= + MODULE: FIRFLT, HIGH QUALITY FIR UP/DOWN-SAMPLING FILTER + Sub-unit: P.863/P.863.2 resampling filter coefficients + + DESCRIPTION: + Resampling (up- and down-sampling) filter coefficients as used + internally in ITU-T Rec. P.863 (POLQA) and ITU-T Rec. P.863.2 + (PAMD), also published in ETSI TR 103 138. + + Parameters: + Up-/Down-sampling factor : 2, 3, 4, 6 + Normalized cutoff frequency : 0.475 + Taps length : 256, 384, 512, 768 + + FUNCTIONS: + = p863_up_1_to_2_init() : upsample by 2 + = p863_down_2_to_1_init() : downsample by 2 + = p863_up_1_to_3_init() : upsample by 3 + = p863_down_3_to_1_init() : downsample by 3 + = p863_up_1_to_4_init() : upsample by 4 + = p863_down_4_to_1_init() : downsample by 4 + = p863_up_1_to_6_init() : upsample by 6 + = p863_down_6_to_1_init() : downsample by 6 + + HISTORY: + 11.Jun.2026 v1.0 Initial version with P.863/P.863.2 coefficients + ============================================================================= +*/ + +#include +#include "firflt.h" + +/* Prototype for fir_initialization (local to FIR module) */ +extern SCD_FIR *fir_initialization(long lenh0, float h0[], double gain, + long idwnup, int hswitch); + +/* ===== Factor 2 coefficients (256 taps) ===== */ +#define P863_LEN2 256 +static float p863_coeff_2[P863_LEN2] = { + 0, 0, -6.5763719827429698e-010f, -1.774023861733666e-009f, 1.2414749056730942e-008f, 1.9906123506125452e-008f, -5.9510076264774008e-008f, -9.6687532645616197e-008f, 1.66884257199444e-007f, 3.1237237262031871e-007f, -3.3983941493666253e-007f, + -7.8779955361649331e-007f, 5.3948551236313662e-007f, 1.6771858427505528e-006f, -6.5717878611679203e-007f, -3.1498182198772881e-006f, 4.9176438991917664e-007f, 5.3605197242465177e-006f, 2.6627472229717859e-007f, -8.4100490156544121e-006f, + -2.0397385098007832e-006f, 1.2297920626484224e-005f, 5.3551467039425532e-006f, -1.6871391475782036e-005f, -1.0815998060702207e-005f, 2.1775438559660563e-005f, 1.9057372869734062e-005f, -2.6409347486383157e-005f, -3.0681905607647534e-005f, + 2.9895950025429203e-005f, 4.6178861973460251e-005f, -3.1069520438032896e-005f, -6.5829851372446374e-005f, 2.8487821667709268e-005f, 8.9606465148413245e-005f, -2.0472772075678042e-005f, -0.00011706671809786473f, 5.1827046362012261e-006f, + 0.0001472584530757325f, 1.9282727971246898e-005f, -0.00017863872344900064f, -5.4746194835846432e-005f, 0.00020901849289291851f, 0.0001027885187579864f, -0.00023554171126832167f, -0.00016456285423100214f, 0.00025470689810904595f, + 0.00024059577819139221f, -0.00026243778983911883f, -0.00033058600417171713f, 0.00025420742334478951f, 0.00043321314468742269f, -0.00022521731907383636f, -0.00054597008359065545f, 0.00017063031310737982f, 0.00066503295722125297f, + -8.5852225867947491e-005f, -0.00078518239225245973f, -3.314587132453256e-005f, 0.00089978846282958065f, 0.0001894763205778044f, -0.0010008698109676916f, -0.00038496894666652844f, 0.0010792345735753637f, 0.00061980740254703639f, + -0.0011247072787871168f, -0.00089218632521024968f, 0.0011264418632411625f, 0.0011980086053723093f, -0.0010733166126649849f, -0.0015306418300333473f, 0.00095440236729098216f, 0.0018807516238043274f, -0.00075949101257426059f, + -0.0022362271693290958f, 0.00047966735940588935f, 0.0025822106579300812f, -0.00010790427373140747f, -0.0029012378877155813f, -0.00036034139785756989f, 0.0031734918095996751f, 0.00092655569989163675f, -0.0033771646737769767f, + -0.0015886405747488589f, 0.0034889177121195229f, 0.0023404544854695236f, -0.0034844201489225525f, -0.0031714384762093445f, 0.0033389418457091574f, 0.0040663397971393506f, -0.0030279660137300175f, -0.0050050371670088464f, + 0.0025277799060584578f, 0.0059624608057177722f, -0.0018159915800828521f, -0.0069085856029574037f, 0.00087190838226179287f, 0.0078084554717001839f, 0.00032330475586840607f, -0.0086221678375741368f, -0.0017867964974218652f, + 0.0093047031940857849f, 0.0035346851016972076f, -0.0098054137618684718f, -0.0055834365845588117f, 0.010066863561789697f, 0.0079523551931751733f, -0.010022489589275232f, -0.010667874162915635f, 0.0095921202839666011f, 0.013770944722886543f, + -0.0086734861247152375f, -0.017330147658877984f, 0.007125840656877094f, 0.021466256724857198f, -0.0047368917723037965f, -0.02640196067996621f, 0.0011508918522695137f, 0.032573558475288276f, 0.0043058942083083699f, -0.04092002623534835f, + -0.013123047317319701f, 0.053800644355014922f, 0.029432522332983702f, -0.07905510753323601f, -0.070603281955663899f, 0.16653563152580322f, 0.43210517492693151f, 0.43210517492693151f, 0.16653563152580322f, -0.070603281955663899f, + -0.07905510753323601f, 0.029432522332983702f, 0.053800644355014922f, -0.013123047317319701f, -0.04092002623534835f, 0.0043058942083083699f, 0.032573558475288276f, 0.0011508918522695137f, -0.02640196067996621f, -0.0047368917723037965f, + 0.021466256724857198f, 0.007125840656877094f, -0.017330147658877984f, -0.0086734861247152375f, 0.013770944722886543f, 0.0095921202839666011f, -0.010667874162915635f, -0.010022489589275232f, 0.0079523551931751733f, 0.010066863561789697f, + -0.0055834365845588117f, -0.0098054137618684718f, 0.0035346851016972076f, 0.0093047031940857849f, -0.0017867964974218652f, -0.0086221678375741368f, 0.00032330475586840607f, 0.0078084554717001839f, 0.00087190838226179287f, -0.0069085856029574037f, + -0.0018159915800828521f, 0.0059624608057177722f, 0.0025277799060584578f, -0.0050050371670088464f, -0.0030279660137300175f, 0.0040663397971393506f, 0.0033389418457091574f, -0.0031714384762093445f, -0.0034844201489225525f, 0.0023404544854695236f, + 0.0034889177121195229f, -0.0015886405747488589f, -0.0033771646737769767f, 0.00092655569989163675f, 0.0031734918095996751f, -0.00036034139785756989f, -0.0029012378877155813f, -0.00010790427373140747f, 0.0025822106579300812f, 0.00047966735940588935f, + -0.0022362271693290958f, -0.00075949101257426059f, 0.0018807516238043274f, 0.00095440236729098216f, -0.0015306418300333473f, -0.0010733166126649849f, 0.0011980086053723093f, 0.0011264418632411625f, -0.00089218632521024968f, -0.0011247072787871168f, + 0.00061980740254703639f, 0.0010792345735753637f, -0.00038496894666652844f, -0.0010008698109676916f, 0.0001894763205778044f, 0.00089978846282958065f, -3.314587132453256e-005f, -0.00078518239225245973f, -8.5852225867947491e-005f, + 0.00066503295722125297f, 0.00017063031310737982f, -0.00054597008359065545f, -0.00022521731907383636f, 0.00043321314468742269f, 0.00025420742334478951f, -0.00033058600417171713f, -0.00026243778983911883f, 0.00024059577819139221f, + 0.00025470689810904595f, -0.00016456285423100214f, -0.00023554171126832167f, 0.0001027885187579864f, 0.00020901849289291851f, -5.4746194835846432e-005f, -0.00017863872344900064f, 1.9282727971246898e-005f, 0.0001472584530757325f, + 5.1827046362012261e-006f, -0.00011706671809786473f, -2.0472772075678042e-005f, 8.9606465148413245e-005f, 2.8487821667709268e-005f, -6.5829851372446374e-005f, -3.1069520438032896e-005f, 4.6178861973460251e-005f, 2.9895950025429203e-005f, + -3.0681905607647534e-005f, -2.6409347486383157e-005f, 1.9057372869734062e-005f, 2.1775438559660563e-005f, -1.0815998060702207e-005f, -1.6871391475782036e-005f, 5.3551467039425532e-006f, 1.2297920626484224e-005f, -2.0397385098007832e-006f, + -8.4100490156544121e-006f, 2.6627472229717859e-007f, 5.3605197242465177e-006f, 4.9176438991917664e-007f, -3.1498182198772881e-006f, -6.5717878611679203e-007f, 1.6771858427505528e-006f, 5.3948551236313662e-007f, -7.8779955361649331e-007f, + -3.3983941493666253e-007f, 3.1237237262031871e-007f, 1.66884257199444e-007f, -9.6687532645616197e-008f, -5.9510076264774008e-008f, 1.9906123506125452e-008f, 1.2414749056730942e-008f, -1.774023861733666e-009f, -6.5763719827429698e-010f, 0, 0 +}; + +/* ===== Factor 3 coefficients (384 taps) ===== */ +#define P863_LEN3 384 +static float p863_coeff_3[P863_LEN3] = { + 0, 0, 2.3880746115417979e-012f, -4.5343415972185956e-010f, -1.7028923693853441e-009f, -8.4389218922391723e-010f, 7.0886322089252491e-009f, 1.7823442117517211e-008f, 1.0539111015548094e-008f, -3.1035329229307842e-008f, -7.8008721342201113e-008f, + -5.5013179015273081e-008f, 7.8373038971897041e-008f, 2.2677624162079388e-007f, 1.8723729611363639e-007f, -1.3597919980774955e-007f, -5.1525109043066013e-007f, -4.9214912582622773e-007f, 1.5611474641711949e-007f, 9.8689786030031712e-007f, + 1.0855171108011384e-006f, -4.209163776439778e-008f, -1.6581521032698434e-006f, -2.1053975439152689e-006f, -3.6241406240010495e-007f, 2.4956190227089128e-006f, 3.6955100599155535e-006f, 1.2778541529707893e-006f, -3.3921881683773868e-006f, + -5.9806767317411985e-006f, -2.9848210124607548e-006f, 4.1449463649568185e-006f, 9.0353737700341518e-006f, 5.8098117598301362e-006f, -4.4380986479937058e-006f, -1.2847364087664612e-005f, -1.0099718886239792e-005f, 3.8341822726575751e-006f, + 1.7279238895754075e-005f, 1.6184956417715211e-005f, -1.7766515950069911e-006f, -2.2031421375875686e-005f, -2.4332197474561585e-005f, -2.3935893830332066e-006f, 2.6610704187670043e-005f, 3.4688827539044313e-005f, 9.4059149174868379e-006f, + -3.0308643847167159e-005f, -4.7222326692234452e-005f, -2.0011211342978361e-005f, 3.21940723469157e-005f, 6.165879748525753e-005f, 3.4917099927271079e-005f, -3.1123582207292488e-005f, -7.7425667680991548e-005f, -5.4708999269250088e-005f, + 2.577308987781682e-005f, 9.3604140221858044e-005f, 7.9760289617795927e-005f, -1.4692502254423751e-005f, -0.00010889717026579475f, -0.00011013620268662548f, -3.6158556879223616e-006f, 0.0001216185724870181f, 0.00014549727178608354f, + 3.0595982474299318e-005f, -0.00012970827460345757f, -0.00018500914128594408f, -6.7516766125712941e-005f, 0.00013077773401920316f, 0.00022726616314751351f, 0.00011533479050810643f, -0.00012218814922106667f, -0.0002702364280887844f, + -0.00017454748366115282f, 0.00010116237881355587f, 0.00031123563710566926f, 0.00024504420572403208f, -6.4929506879834371e-005f, -0.0003469364881548334f, -0.00032596406894792673f, 1.0898863908295805e-005f, 0.00037341903410889127f, + 0.00041557007503908419f, 6.3141854669029868e-005f, -0.00038626579342104116f, -0.00051114946203511689f, -0.00015881180649481054f, 0.00038070332659446656f, 0.00060894991394983033f, 0.00027691484340688086f, -0.00035178962058860294f, + -0.00070416047005391713f, -0.00041722076140240455f, 0.0002946440659191659f, 0.00079094457776394305f, 0.00057826177316502804f, -0.00020471420364945214f, -0.00086253079886660299f, -0.00075715647434190857f, 7.8070911470995362e-005f, + 0.00091136427280373545f, 0.00094947338778067448f, 8.8278554519033553e-005f, -0.0009293192651450272f, -0.0011491452952806316f, -0.00029607208887276254f, 0.00090797011524895829f, 0.0013484439951688934f, 0.00054548255243221946f, + -0.000838914799088754f, -0.001538022883205785f, -0.0008348301978265524f, 0.00071414231291492831f, 0.0017070319061425984f, 0.0011603318483905376f, -0.00052643234200925183f, -0.0018433060757642621f, -0.0015158999272543692f, 0.0002697733894813892f, + 0.0019336249762676805f, 0.0018930024652897349f, 6.021611870556079e-005f, -0.0019640366858605209f, -0.0022805922944297693f, -0.00046588009586367909f, 0.0019202354051257818f, 0.0026651097342190338f, 0.00094714667042056667f, -0.0017879779679787202f, + -0.0030305581721061983f, -0.0015011947191469351f, 0.0015535203986233206f, 0.0033586459453791243f, 0.0021221776374211261f, -0.0012040517954721853f, -0.0036289806756199228f, -0.0028010130124567607f, 0.00072809898190702991f, 0.003819293305134377f, + 0.003525241226079005f, -0.00011587128589573347f, -0.0039056577872044335f, -0.0042789481851768178f, -0.0006404901001903022f, 0.0038626572576360109f, 0.0050427365221956564f, 0.0015468006178818786f, -0.0036634258809922441f, -0.0057937141549434489f, + -0.0026069121453312217f, 0.0032794623708833487f, 0.0065054460370959485f, 0.0038230566948668477f, -0.002680056749194326f, -0.0071477783712048451f, -0.0051965616268714477f, 0.0018310771148689472f, 0.0076863825761675714f, 0.0067291104816989663f, + -0.00069268873089433464f, -0.0080817538371880607f, -0.0084248543076559067f, -0.00078476133674093313f, 0.0082871806988380516f, 0.010293946989183475f, 0.0026681594256980651f, -0.0082447475286898889f, -0.012358661120613597f, -0.0050553447712100314f, + 0.0078774100284280009f, 0.01466459885817459f, 0.0081018116965398818f, -0.0070726742803038133f, -0.017302973136825221f, -0.012076765102941719f, 0.0056465299509595125f, 0.020459849179604396f, 0.017493985702572986f, -0.0032545471025644682f, + -0.024541438327006275f, -0.025466852745084697f, -0.00086649040778759723f, 0.030563214485593314f, 0.038914791575798587f, 0.0088735876642893445f, -0.041810097260969986f, -0.068593882874520951f, -0.030308278060979799f, 0.077444747987009496f, + 0.21148838226467084f, 0.30375847843681869f, 0.30375847843681869f, 0.21148838226467084f, 0.077444747987009496f, -0.030308278060979799f, -0.068593882874520951f, -0.041810097260969986f, 0.0088735876642893445f, 0.038914791575798587f, 0.030563214485593314f, + -0.00086649040778759723f, -0.025466852745084697f, -0.024541438327006275f, -0.0032545471025644682f, 0.017493985702572986f, 0.020459849179604396f, 0.0056465299509595125f, -0.012076765102941719f, -0.017302973136825221f, -0.0070726742803038133f, + 0.0081018116965398818f, 0.01466459885817459f, 0.0078774100284280009f, -0.0050553447712100314f, -0.012358661120613597f, -0.0082447475286898889f, 0.0026681594256980651f, 0.010293946989183475f, 0.0082871806988380516f, -0.00078476133674093313f, + -0.0084248543076559067f, -0.0080817538371880607f, -0.00069268873089433464f, 0.0067291104816989663f, 0.0076863825761675714f, 0.0018310771148689472f, -0.0051965616268714477f, -0.0071477783712048451f, -0.002680056749194326f, 0.0038230566948668477f, + 0.0065054460370959485f, 0.0032794623708833487f, -0.0026069121453312217f, -0.0057937141549434489f, -0.0036634258809922441f, 0.0015468006178818786f, 0.0050427365221956564f, 0.0038626572576360109f, -0.0006404901001903022f, -0.0042789481851768178f, + -0.0039056577872044335f, -0.00011587128589573347f, 0.003525241226079005f, 0.003819293305134377f, 0.00072809898190702991f, -0.0028010130124567607f, -0.0036289806756199228f, -0.0012040517954721853f, 0.0021221776374211261f, 0.0033586459453791243f, + 0.0015535203986233206f, -0.0015011947191469351f, -0.0030305581721061983f, -0.0017879779679787202f, 0.00094714667042056667f, 0.0026651097342190338f, 0.0019202354051257818f, -0.00046588009586367909f, -0.0022805922944297693f, -0.0019640366858605209f, + 6.021611870556079e-005f, 0.0018930024652897349f, 0.0019336249762676805f, 0.0002697733894813892f, -0.0015158999272543692f, -0.0018433060757642621f, -0.00052643234200925183f, 0.0011603318483905376f, 0.0017070319061425984f, 0.00071414231291492831f, + -0.0008348301978265524f, -0.001538022883205785f, -0.000838914799088754f, 0.00054548255243221946f, 0.0013484439951688934f, 0.00090797011524895829f, -0.00029607208887276254f, -0.0011491452952806316f, -0.0009293192651450272f, 8.8278554519033553e-005f, + 0.00094947338778067448f, 0.00091136427280373545f, 7.8070911470995362e-005f, -0.00075715647434190857f, -0.00086253079886660299f, -0.00020471420364945214f, 0.00057826177316502804f, 0.00079094457776394305f, 0.0002946440659191659f, -0.00041722076140240455f, + -0.00070416047005391713f, -0.00035178962058860294f, 0.00027691484340688086f, 0.00060894991394983033f, 0.00038070332659446656f, -0.00015881180649481054f, -0.00051114946203511689f, -0.00038626579342104116f, 6.3141854669029868e-005f, 0.00041557007503908419f, + 0.00037341903410889127f, 1.0898863908295805e-005f, -0.00032596406894792673f, -0.0003469364881548334f, -6.4929506879834371e-005f, 0.00024504420572403208f, 0.00031123563710566926f, 0.00010116237881355587f, -0.00017454748366115282f, -0.0002702364280887844f, + -0.00012218814922106667f, 0.00011533479050810643f, 0.00022726616314751351f, 0.00013077773401920316f, -6.7516766125712941e-005f, -0.00018500914128594408f, -0.00012970827460345757f, 3.0595982474299318e-005f, 0.00014549727178608354f, 0.0001216185724870181f, + -3.6158556879223616e-006f, -0.00011013620268662548f, -0.00010889717026579475f, -1.4692502254423751e-005f, 7.9760289617795927e-005f, 9.3604140221858044e-005f, 2.577308987781682e-005f, -5.4708999269250088e-005f, -7.7425667680991548e-005f, + -3.1123582207292488e-005f, 3.4917099927271079e-005f, 6.165879748525753e-005f, 3.21940723469157e-005f, -2.0011211342978361e-005f, -4.7222326692234452e-005f, -3.0308643847167159e-005f, 9.4059149174868379e-006f, 3.4688827539044313e-005f, + 2.6610704187670043e-005f, -2.3935893830332066e-006f, -2.4332197474561585e-005f, -2.2031421375875686e-005f, -1.7766515950069911e-006f, 1.6184956417715211e-005f, 1.7279238895754075e-005f, 3.8341822726575751e-006f, -1.0099718886239792e-005f, + -1.2847364087664612e-005f, -4.4380986479937058e-006f, 5.8098117598301362e-006f, 9.0353737700341518e-006f, 4.1449463649568185e-006f, -2.9848210124607548e-006f, -5.9806767317411985e-006f, -3.3921881683773868e-006f, 1.2778541529707893e-006f, + 3.6955100599155535e-006f, 2.4956190227089128e-006f, -3.6241406240010495e-007f, -2.1053975439152689e-006f, -1.6581521032698434e-006f, -4.209163776439778e-008f, 1.0855171108011384e-006f, 9.8689786030031712e-007f, 1.5611474641711949e-007f, + -4.9214912582622773e-007f, -5.1525109043066013e-007f, -1.3597919980774955e-007f, 1.8723729611363639e-007f, 2.2677624162079388e-007f, 7.8373038971897041e-008f, -5.5013179015273081e-008f, -7.8008721342201113e-008f, -3.1035329229307842e-008f, + 1.0539111015548094e-008f, 1.7823442117517211e-008f, 7.0886322089252491e-009f, -8.4389218922391723e-010f, -1.7028923693853441e-009f, -4.5343415972185956e-010f, 2.3880746115417979e-012f, 0, 0 +}; + +/* ===== Factor 4 coefficients (512 taps) ===== */ +#define P863_LEN4 512 +static float p863_coeff_4[P863_LEN4] = { + 0, 0, 1.2991300775641274e-11f, -1.2707556082002351e-11f, -3.2425901472574716e-10f, -1.0883363753489433e-09f, + -1.6539754909023193e-09f, -2.5306638148159503e-10f, 4.6922554722760015e-09f, 1.181771621965007e-08f, 1.5006931505612116e-08f, 5.770009765206447e-09f, + -1.937574551353074e-08f, -5.073369972287947e-08f, -6.443556206772023e-08f, -3.453737571377001e-08f, 4.488632426885434e-08f, 1.4175441950830963e-07f, + 1.901946665452237e-07f, 1.2521543110183777e-07f, -6.538595165044632e-08f, -3.0529784057633844e-07f, -4.4552027731676405e-07f, -3.419858179219399e-07f, + 3.775063272818829e-08f, 5.459760401694811e-07f, 8.887036832570474e-07f, 7.751393559828222e-07f, 1.1791740049431614e-07f, -8.380879650482852e-07f, + -1.5702031530906168e-06f, -1.536205786841987e-06f, -5.244425154336332e-07f, 1.1106014047140515e-06f, 2.515457403823864e-06f, 2.7469049544104547e-06f, + 1.3485949945425106e-06f, -1.2336559964009238e-06f, -3.7046772503896565e-06f, -4.521787460774139e-06f, -2.795452258395797e-06f, 1.0088026964542039e-06f, + 5.0514538092647904e-06f, 6.945104903087823e-06f, 5.095029947777826e-06f, -1.6519189909568147e-07f, -6.382481009302464e-06f, -1.0043156185704507e-05f, + -8.480720169307173e-06f, -1.6362846427710696e-06f, 7.420999243396657e-06f, 1.3754041839375716e-05f, 1.3159805012876274e-05f, 4.789306214851627e-06f, + -7.776686097809898e-06f, -1.7897365097928146e-05f, -1.9277118540992935e-05f, -9.717904559020066e-06f, 6.944620927430452e-06f, 2.2146890621458765e-05f, + 2.6873753571239316e-05f, 1.684150057211881e-05f, -4.315618376925129e-06f, -2.600945884195945e-05f, -3.584348881895493e-05f, -2.6529876447755036e-05f, + -8.00336532524567e-07f, 2.8813515148244846e-05f, 4.589028379000438e-05f, 3.9049724838544477e-05f, 9.136593962241157e-06f, -2.9710420736075288e-05f, + -5.649069233367912e-05f, -5.4505381568332704e-05f, -2.1418279849748793e-05f, 2.7691253875670086e-05f, 6.686532712235799e-05f, 7.277724759053949e-05f, + 3.8297745251674225e-05f, -2.162109209299681e-05f, -7.596352378011714e-05f, -9.346216896366033e-05f, -6.02792416569394e-05f, 1.0291811123820618e-05f, + 8.2465076906938e-05f, 0.00011582060395798645f, 8.763617483509935e-05f, 7.506712831829961e-06f, -8.480234032458162e-05f, -0.00013873570570011262f, + -0.0001203253394264482f, -3.289839707489907e-05f, 8.120510932793255e-05f, 0.000160689441369783f, 0.000157903422423803f, 6.681849334041871e-05f, + -6.976956239785217e-05f, -0.000179760525719859f, -0.00019945171250628253f, -0.00010990096150128463f, 4.855118200575707e-05f, 0.00019364825783285604f, + 0.00024351529998844964f, 0.00016236099411512037f, -1.568006473916238e-05f, -0.00019972532707688388f, -0.0002880630492939974f, -0.00022387905263177607f, + -3.050454944990755e-05f, 0.0001951213306372152f, 0.00033047424095655645f, 0.0002934935478389351f, 9.130525941729616e-05f, -0.00017683717551561084f, + -0.00036755700317456555f, -0.00036950972708088466f, -0.00016750917047607462f, 0.00014188879655118605f, 0.00039560249725767465f, 0.0004494323637618531f, + 0.00025922965136282954f, -8.74767989470366e-05f, -0.0004104773243279228f, -0.0005299294454091315f, -0.0003657555091429631f, 1.1176830869681065e-05f, + 0.00040775484320920816f, 0.0006068332131794505f, 0.00048541645050176384f, 8.885618261553143e-05f, -0.00038288411373427265f, -0.000675183631629642f, + -0.000615473789364383f, -0.0002136782494124946f, 0.00033139310592028765f, 0.0007293177025262143f, 0.0007520449616691922f, 0.00036335036355604033f, + -0.00024912075740064326f, -0.0007630060456518995f, -0.0008900695005976765f, -0.0005367464602286234f, 0.00013247054126936693f, 0.0007696359416062905f, + 0.0010233227184114771f, 0.0007313854778651061f, 2.1323451182260114e-05f, -0.0007424376750825578f, -0.0011444814700838244f, -0.0009432973099801437f, + -0.00021392818189837774f, 0.0006747486560177692f, 0.0012452441007728369f, 0.0011669314035000333f, 0.00044565213691552356f, -0.000560307564366402f, + -0.0013165040882592428f, -0.001395115120816527f, -0.0007152058199719592f, 0.000393568800315759f, 0.0013485740849686467f, 0.0016190667406393176f, + 0.0010194929859247677f, -0.00017002596254656562f, -0.0013314541552569158f, -0.0018284651554870807f, -0.001353442067829303f, -0.0001134679462787328f, + 0.0012551351073552717f, 0.0020115749654969514f, 0.0017098851670412384f, 0.0004583962528190966f, -0.0011099250414032592f, -0.002155421794178071f, + -0.0020794890014819126f, -0.0008643025438124062f, 0.0008867846569099381f, 0.0022460082525491186f, 0.002450738247717242f, 0.0013285537607450467f, + -0.0005776545226723317f, -0.0022685559702115064f, -0.0028099666043646396f, -0.001846151122471303f, 0.0001757553758812236f, 0.002207753271784653f, + 0.0031414243452301755f, 0.002409594058094278f, 0.0003241595638860537f, -0.0020479809296349767f, -0.0034273625532641925f, -0.0030087974002319393f, + -0.0009256236421035292f, 0.0017734790441972653f, 0.0036481025697628205f, 0.003631055222906989f, 0.0016303738513069896f, -0.001368404750316566f, + -0.003782042471204629f, -0.004261035002383981f, -0.002438398070725006f, 0.0008167098558569123f, 0.003805526844837627f, 0.0048807714861798645f, + 0.003348154464813144f, -0.00010173346597469165f, -0.0036924645319536932f, -0.005469607326241074f, -0.004357023710626261f, -0.0007946550658895f, + 0.0034135069393125004f, 0.006003990156095559f, 0.005462090893488422f, 0.0018936377807628284f, -0.002934467144054682f, -0.006456968557164035f, + -0.006661425881706465f, -0.0032222434382727294f, 0.0022134023306814203f, 0.006797099388371624f, 0.00795617958267588f, 0.004818285057820308f, + -0.0011952485864216802f, -0.006986208624140421f, -0.009354136308602956f, -0.0067393293208882765f, -0.0001982873562654969f, 0.0069748394581529245f, + 0.010876113057789582f, 0.00907985855652922f, 0.0020887325681544387f, -0.006692721990455363f, -0.012568502698548978f, -0.012006696703631388f, + -0.004683547311032964f, 0.00602746820070927f, 0.014530689614650228f, 0.015840190875226187f, 0.008377697012721275f, -0.004771553503959317f, + -0.01698411980367491f, -0.021269320646164838f, -0.014036005642908779f, 0.002466651529467916f, 0.020484382547902292f, 0.03005764845083724f, + 0.02398882053926445f, 0.002192590255406906f, -0.026810202530847604f, -0.0483541984557258f, -0.04737186896080941f, -0.01513607751069205f, + 0.045944787176249516f, 0.12178387323751173f, 0.1909000411869741f, 0.23202473878914937f, 0.23202473878914937f, 0.1909000411869741f, + 0.12178387323751173f, 0.045944787176249516f, -0.01513607751069205f, -0.04737186896080941f, -0.0483541984557258f, -0.026810202530847604f, + 0.002192590255406906f, 0.02398882053926445f, 0.03005764845083724f, 0.020484382547902292f, 0.002466651529467916f, -0.014036005642908779f, + -0.021269320646164838f, -0.01698411980367491f, -0.004771553503959317f, 0.008377697012721275f, 0.015840190875226187f, 0.014530689614650228f, + 0.00602746820070927f, -0.004683547311032964f, -0.012006696703631388f, -0.012568502698548978f, -0.006692721990455363f, 0.0020887325681544387f, + 0.00907985855652922f, 0.010876113057789582f, 0.0069748394581529245f, -0.0001982873562654969f, -0.0067393293208882765f, -0.009354136308602956f, + -0.006986208624140421f, -0.0011952485864216802f, 0.004818285057820308f, 0.00795617958267588f, 0.006797099388371624f, 0.0022134023306814203f, + -0.0032222434382727294f, -0.006661425881706465f, -0.006456968557164035f, -0.002934467144054682f, 0.0018936377807628284f, 0.005462090893488422f, + 0.006003990156095559f, 0.0034135069393125004f, -0.0007946550658895f, -0.004357023710626261f, -0.005469607326241074f, -0.0036924645319536932f, + -0.00010173346597469165f, 0.003348154464813144f, 0.0048807714861798645f, 0.003805526844837627f, 0.0008167098558569123f, -0.002438398070725006f, + -0.004261035002383981f, -0.003782042471204629f, -0.001368404750316566f, 0.0016303738513069896f, 0.003631055222906989f, 0.0036481025697628205f, + 0.0017734790441972653f, -0.0009256236421035292f, -0.0030087974002319393f, -0.0034273625532641925f, -0.0020479809296349767f, 0.0003241595638860537f, + 0.002409594058094278f, 0.0031414243452301755f, 0.002207753271784653f, 0.0001757553758812236f, -0.001846151122471303f, -0.0028099666043646396f, + -0.0022685559702115064f, -0.0005776545226723317f, 0.0013285537607450467f, 0.002450738247717242f, 0.0022460082525491186f, 0.0008867846569099381f, + -0.0008643025438124062f, -0.0020794890014819126f, -0.002155421794178071f, -0.0011099250414032592f, 0.0004583962528190966f, 0.0017098851670412384f, + 0.0020115749654969514f, 0.0012551351073552717f, -0.0001134679462787328f, -0.001353442067829303f, -0.0018284651554870807f, -0.0013314541552569158f, + -0.00017002596254656562f, 0.0010194929859247677f, 0.0016190667406393176f, 0.0013485740849686467f, 0.000393568800315759f, -0.0007152058199719592f, + -0.001395115120816527f, -0.0013165040882592428f, -0.000560307564366402f, 0.00044565213691552356f, 0.0011669314035000333f, 0.0012452441007728369f, + 0.0006747486560177692f, -0.00021392818189837774f, -0.0009432973099801437f, -0.0011444814700838244f, -0.0007424376750825578f, 2.1323451182260114e-05f, + 0.0007313854778651061f, 0.0010233227184114771f, 0.0007696359416062905f, 0.00013247054126936693f, -0.0005367464602286234f, -0.0008900695005976765f, + -0.0007630060456518995f, -0.00024912075740064326f, 0.00036335036355604033f, 0.0007520449616691922f, 0.0007293177025262143f, 0.00033139310592028765f, + -0.0002136782494124946f, -0.000615473789364383f, -0.000675183631629642f, -0.00038288411373427265f, 8.885618261553143e-05f, 0.00048541645050176384f, + 0.0006068332131794505f, 0.00040775484320920816f, 1.1176830869681065e-05f, -0.0003657555091429631f, -0.0005299294454091315f, -0.0004104773243279228f, + -8.74767989470366e-05f, 0.00025922965136282954f, 0.0004494323637618531f, 0.00039560249725767465f, 0.00014188879655118605f, -0.00016750917047607462f, + -0.00036950972708088466f, -0.00036755700317456555f, -0.00017683717551561084f, 9.130525941729616e-05f, 0.0002934935478389351f, 0.00033047424095655645f, + 0.0001951213306372152f, -3.050454944990755e-05f, -0.00022387905263177607f, -0.0002880630492939974f, -0.00019972532707688388f, -1.568006473916238e-05f, + 0.00016236099411512037f, 0.00024351529998844964f, 0.00019364825783285604f, 4.855118200575707e-05f, -0.00010990096150128463f, -0.00019945171250628253f, + -0.000179760525719859f, -6.976956239785217e-05f, 6.681849334041871e-05f, 0.000157903422423803f, 0.000160689441369783f, 8.120510932793255e-05f, + -3.289839707489907e-05f, -0.0001203253394264482f, -0.00013873570570011262f, -8.480234032458162e-05f, 7.506712831829961e-06f, 8.763617483509935e-05f, + 0.00011582060395798645f, 8.2465076906938e-05f, 1.0291811123820618e-05f, -6.02792416569394e-05f, -9.346216896366033e-05f, -7.596352378011714e-05f, + -2.162109209299681e-05f, 3.8297745251674225e-05f, 7.277724759053949e-05f, 6.686532712235799e-05f, 2.7691253875670086e-05f, -2.1418279849748793e-05f, + -5.4505381568332704e-05f, -5.649069233367912e-05f, -2.9710420736075288e-05f, 9.136593962241157e-06f, 3.9049724838544477e-05f, 4.589028379000438e-05f, + 2.8813515148244846e-05f, -8.00336532524567e-07f, -2.6529876447755036e-05f, -3.584348881895493e-05f, -2.600945884195945e-05f, -4.315618376925129e-06f, + 1.684150057211881e-05f, 2.6873753571239316e-05f, 2.2146890621458765e-05f, 6.944620927430452e-06f, -9.717904559020066e-06f, -1.9277118540992935e-05f, + -1.7897365097928146e-05f, -7.776686097809898e-06f, 4.789306214851627e-06f, 1.3159805012876274e-05f, 1.3754041839375716e-05f, 7.420999243396657e-06f, + -1.6362846427710696e-06f, -8.480720169307173e-06f, -1.0043156185704507e-05f, -6.382481009302464e-06f, -1.6519189909568147e-07f, 5.095029947777826e-06f, + 6.945104903087823e-06f, 5.0514538092647904e-06f, 1.0088026964542039e-06f, -2.795452258395797e-06f, -4.521787460774139e-06f, -3.7046772503896565e-06f, + -1.2336559964009238e-06f, 1.3485949945425106e-06f, 2.7469049544104547e-06f, 2.515457403823864e-06f, 1.1106014047140515e-06f, -5.244425154336332e-07f, + -1.536205786841987e-06f, -1.5702031530906168e-06f, -8.380879650482852e-07f, 1.1791740049431614e-07f, 7.751393559828222e-07f, 8.887036832570474e-07f, + 5.459760401694811e-07f, 3.775063272818829e-08f, -3.419858179219399e-07f, -4.4552027731676405e-07f, -3.0529784057633844e-07f, -6.538595165044632e-08f, + 1.2521543110183777e-07f, 1.901946665452237e-07f, 1.4175441950830963e-07f, 4.488632426885434e-08f, -3.453737571377001e-08f, -6.443556206772023e-08f, + -5.073369972287947e-08f, -1.937574551353074e-08f, 5.770009765206447e-09f, 1.5006931505612116e-08f, 1.181771621965007e-08f, 4.6922554722760015e-09f, + -2.5306638148159503e-10f, -1.6539754909023193e-09f, -1.0883363753489433e-09f, -3.2425901472574716e-10f, -1.2707556082002351e-11f, 1.2991300775641274e-11f, + 0, 0 +}; + +/* ===== Factor 6 coefficients (768 taps) ===== */ +#define P863_LEN6 768 +static float p863_coeff_6[P863_LEN6] = { + 0, 0, 2.691239924154828e-12f, 1.1828539027346112e-11f, 1.537678992124691e-11f, -3.1335654479869494e-11f, + -1.9709071280477305e-10f, -5.248064118418001e-10f, -9.51381731279286e-10f, -1.2410008763135097e-09f, -9.930951082636695e-10f, 2.28107470502183e-10f, + 2.645711238283505e-09f, 5.9789349448002054e-09f, 9.246128218035411e-09f, 1.0817071302193613e-08f, 8.81636638720527e-09f, 1.8556810104194671e-09f, + -1.0089665711571232e-08f, -2.4984867921475803e-08f, -3.859576051529636e-08f, -4.518884483648565e-08f, -3.911531647701826e-08f, -1.6985910384779763e-08f, + 2.0187158038407728e-08f, 6.56984160679439e-08f, 1.0746842146236057e-07f, 1.3038003060051805e-07f, 1.2043301999843577e-07f, 6.98165233472851e-08f, + -1.8575955256728605e-08f, -1.2887790166769242e-07f, -2.3360609465673318e-07f, -2.9916558380919976e-07f, -2.9478799977106246e-07f, -2.0288946624290177e-07f, + -2.7891854588389937e-08f, 1.9964925679003818e-07f, 4.25999961202196e-07f, 5.849848067357207e-07f, 6.149318849908952e-07f, 4.780008570940273e-07f, + 1.7654259185517028e-07f, -2.390462883978719e-07f, -6.750429872594422e-07f, -1.0127802760012628e-06f, -1.1379118280829263e-06f, -9.740376083153232e-07f, + -5.116868845731189e-07f, 1.765979842996413e-07f, 9.419097945454788e-07f, 1.5873541986613687e-06f, 1.9149301373470155e-06f, 1.7806663582809258e-06f, + 1.143733350219884e-06f, 9.467860877910933e-08f, -1.1484798394999376e-06f, -2.2802225651653813e-06f, -2.9779202914242935e-06f, -2.9876264959214665e-06f, + -2.203734205629703e-06f, -7.195568958705088e-07f, 1.169289632945126e-06f, 3.016287801367824e-06f, 4.323696092525644e-06f, 4.66981747470593e-06f, + 3.832827875404265e-06f, 1.8769928536209681e-06f, -8.270502826770229e-07f, -3.661909388482541e-06f, -5.896943190857115e-06f, -6.868846754126758e-06f, + -6.1664774806085404e-06f, -3.770766054468487e-06f, -1.0681717109783684e-07f, 4.016100018535679e-06f, 7.573673021989436e-06f, 9.572182772489344e-06f, + 9.313903839206387e-06f, 6.613913881503402e-06f, 1.9054003350526885e-06f, -3.806589553951066e-06f, -9.147013859009695e-06f, -1.2691498798386898e-05f, + -1.3333643382732469e-05f, -1.0607006582875768e-05f, -4.8724000492981274e-06f, 2.692366003430763e-06f, 1.0317342373158007e-05f, 1.6042159651260656e-05f, + 1.820668633540655e-05f, 1.5910878336996937e-05f, 9.320735053412442e-06f, -2.740174359813823e-07f, -1.0688739061583608e-05f, -1.932605805253585e-05f, + -2.3809127279542265e-05f, -2.2615023926355254e-05f, -1.5543839717163266e-05f, -3.8872324521640265e-06f, 9.773568468952705e-06f, 2.212011999721824e-05f, + 2.988664778393458e-05f, 3.070344982909068e-05f, 2.3780490067865e-05f, 1.024146219566499e-05f, -7.006637231184095e-06f, -2.3872746018477846e-05f, + -3.603341117882283e-05f, -4.002028816797243e-05f, -3.417465815777557e-05f, -1.9213291464732e-05f, 1.7698780085840604e-06f, 2.3910224388238513e-05f, + 4.167805084205758e-05f, 5.0237898294931096e-05f, 4.6732536591469296e-05f, 3.115747283293287e-05f, 6.572134618200237e-06f, -2.145474134416278e-05f, + -4.607935202681541e-05f, -6.083045378499977e-05f, -6.127944612408436e-05f, -4.63086316244695e-05f, -1.8626278197123308e-05f, 1.5655032748882834e-05f, + 4.833395043391465e-05f, 7.105610879688223e-05f, 7.741979300458653e-05f, 6.472766236692141e-05f, 3.491584157791999e-05f, -5.6299938557223714e-06f, + -4.739789768353654e-05f, -7.995073288441698e-05f, -9.450353669455348e-05f, -8.624792240002861e-05f, -5.581843466722564e-05f, -9.475276647106836e-06f, + 4.212328682528971e-05f, 8.633588458239913e-05f, 0.0001116027274787376f, 0.00011042486406119114f, 8.149972830032109e-05f, 3.0422431031760574e-05f, + -3.131031531861043e-05f, -8.884316159376149e-05f, -0.00012750155200331027f, -0.00013649307135328725f, -0.00011184660662576022f, -5.780418307922092e-05f, + 1.3774226033203211e-05f, 8.595633313966191e-05f, 0.00014070296987162006f, 0.0001633347777040411f, 0.00014640387262396037f, 9.196321623926072e-05f, + 1.157444307940535e-05f, -7.607175578778393e-05f, -0.00014945443689276262f, -0.00018946381166227083f, -0.00018431901261959646f, -0.0001329097142102547f, + -4.563889644759457e-05f, 5.757653860596238e-05f, 0.00015179440591692495f, 0.0002130285335328205f, 0.0002242996579722704f, 0.00018024216434545852f, + 8.903798250712117e-05f, -2.89428088362726e-05f, -0.00014562030460083452f, -0.00023183668917914544f, -0.00026458825304284705f, -0.00023307650021536254f, + -0.00014200540887034094f, -1.116470369424232e-05f, 0.00012877755492326877f, 0.00024340423431723786f, 0.00030295803344061305f, 0.00028998881291818565f, + 0.00020429142207811283f, 6.377162994954104e-05f, -9.916797784749802e-05f, -0.0002450291060281673f, -0.00033673373853927404f, -0.0003489767404299755f, + -0.0002750725778339314f, -0.00012947230718511564f, 5.4874683724266626e-05f, 0.00023388968509776965f, 0.00036283954499724997f, 0.0004074442241842563f, + 0.00035287542885270373f, 0.00020830912486435524f, 5.700643354394805e-06f, -0.00020716636324439341f, -0.0003778755478488185f, -0.0004622136024407257f, + -0.00043551985080457316f, -0.0002996590281028708f, -8.369322660349729e-05f, 0.00016218327373728096f, 0.00037822278267612763f, 0.0005095680085994171f, + 0.0005200872932458632f, 0.0004021335775498866f, 0.00017962947202432243f, -9.656593983252403e-05f, -0.00036017534034318133f, -0.0005453257947001756f, + -0.0006029184799152024f, -0.0005134988701415268f, -0.0002932866713238596f, 8.409423734104047e-06f, 0.00032009664994853484f, 0.000564947257716049f, + 0.0006796440073147703f, 0.0006306211703786999f, 0.00042356504465827625f, 0.00010354940020593262f, -0.00025459557921401604f, -0.00056367237533275f, + -0.000745249935902165f, -0.0007494432795037147f, -0.0005683789433809046f, -0.00023976249450019229f, 0.00016071671200037333f, 0.0005366866370135178f, + 0.000794178884862575f, 0.00086499549032453f, 0.0007245735362801915f, 0.0003997115889927176f, -3.613809815664295e-05f, -0.0004793104720456748f, + -0.0008204653938672434f, -0.0009714434650863762f, -0.0008878723835859144f, -0.0005817666488097535f, -0.00012063098325035138f, 0.000387206320324671f, + 0.0008179024786880318f, 0.0010621735733697998f, 0.0010528599573031263f, 0.000783068568853146f, 0.0003100600703417042f, -0.0002565961558720999f, + -0.0007802344633793596f, -0.0011299141868816099f, -0.001213001401090671f, -0.0009994417150751657f, -0.0005314230983962694f, 8.448134650865583e-05f, + 0.0007013694018032594f, 0.0011668892017168851f, 0.001360699649507721f, 0.0012253403293674297f, 0.0007826466076227966f, 0.00013114380113039367f, + -0.000575602781164748f, -0.0011649976932383162f, -0.0014873874506915337f, -0.0014538306405106657f, -0.0010601864459545338f, -0.0003910935278882586f, + 0.0003978427911930665f, 0.0011160111306802627f, 0.001583648840995474f, 0.0016766077219011598f, 0.001358936932918977f, 0.0006948153834432945f, + -0.000163826281401473f, -0.00101177697301324f, -0.0016393611363987892f, -0.0018840426030750455f, -0.0016721737676909565f, -0.0010402454244288109f, + -0.00012968638587027814f, 0.0008444146452898538f, 0.0016438443679279932f, 0.002065250674652296f, 0.001991528323569564f, 0.001423699236028589f, + 0.0004847501066751298f, -0.0006064866379520778f, -0.001585999954687689f, -0.002208166640388556f, -0.0023069860593334167f, -0.0018398015723057382f, + -0.0009021206418670336f, 0.00029112333986494875f, 0.001454413618303933f, 0.002299603441905315f, 0.002606895019486452f, 0.0022814537885444343f, + 0.001381201221652482f, 0.0001079256271408814f, -0.0012373878562206998f, -0.0023252613565889484f, -0.0028779607130344355f, -0.0027398331837579586f, + -0.0019200660782804076f, -0.0005963499224796556f, 0.0009228543792967101f, 0.002269636290554184f, 0.003105189005540589f, 0.0032044110974639535f, + 0.0025155804434977406f, 0.001179498550313731f, -0.0004980923359440308f, -0.002115748235827439f, -0.0032717150482324516f, -0.0036629655414078164f, + -0.0031636439376678694f, -0.0018628405052291059f, -5.086484742755164e-05f, 0.0018445621699828237f, 0.003358415711090973f, 0.004101546070654008f, + 0.0038595992992198572f, 0.0026527959791814225f, 0.0007403304559674372f, -0.0014338841732215583f, -0.003343128797128057f, -0.004504316650754686f, + -0.004598879085877497f, -0.003558167390675537f, -0.001590923732936595f, 0.0008563413932258106f, 0.003199157832490015f, 0.004853141153493943f, + 0.005378027138078235f, 0.004592602844898446f, 0.002631054152962605f, -7.569452202221049e-05f, -0.002892440783972528f, -0.005126649521643357f, + -0.006196371644937026f, -0.005778966765403332f, -0.0039032909617394158f, -0.0009600656227028338f, 0.0023760888885792867f, 0.005298237762153511f, + 0.007058952275705875f, 0.007157527451734127f, 0.005476622337773767f, 0.002332302051157702f, -0.001579362286885288f, -0.0053317509190652645f, + -0.007982128411187294f, -0.008802530499726536f, -0.007471906569662577f, -0.004180563208241132f, 0.0003836987462893026f, 0.005171649597199791f, + 0.009005633268375423f, 0.010859429623592322f, 0.010120560500457598f, 0.006770733239430279f, 0.0014354647775230676f, -0.004718218214971998f, + -0.010222552117649898f, -0.013641241144069397f, -0.013921285427190419f, -0.010682921414477523f, -0.0043746457509470545f, 0.0037539092491463157f, + 0.011870220996013016f, 0.01793441831433124f, 0.020160315305735612f, 0.01746572362712614f, 0.009811159292865194f, -0.0016567662826508281f, + -0.014704561453844802f, -0.026352219834002717f, -0.033402104849064786f, -0.033060950449359014f, -0.02353466296554083f, -0.0044745524666263475f, + 0.022822436309568785f, 0.055512077227906076f, 0.08959523242306079f, 0.12054160595214061f, 0.1440351159573109f, 0.15670473689431666f, + 0.15670473689431666f, 0.1440351159573109f, 0.12054160595214061f, 0.08959523242306079f, 0.055512077227906076f, 0.022822436309568785f, + -0.0044745524666263475f, -0.02353466296554083f, -0.033060950449359014f, -0.033402104849064786f, -0.026352219834002717f, -0.014704561453844802f, + -0.0016567662826508281f, 0.009811159292865194f, 0.01746572362712614f, 0.020160315305735612f, 0.01793441831433124f, 0.011870220996013016f, + 0.0037539092491463157f, -0.0043746457509470545f, -0.010682921414477523f, -0.013921285427190419f, -0.013641241144069397f, -0.010222552117649898f, + -0.004718218214971998f, 0.0014354647775230676f, 0.006770733239430279f, 0.010120560500457598f, 0.010859429623592322f, 0.009005633268375423f, + 0.005171649597199791f, 0.0003836987462893026f, -0.004180563208241132f, -0.007471906569662577f, -0.008802530499726536f, -0.007982128411187294f, + -0.0053317509190652645f, -0.001579362286885288f, 0.002332302051157702f, 0.005476622337773767f, 0.007157527451734127f, 0.007058952275705875f, + 0.005298237762153511f, 0.0023760888885792867f, -0.0009600656227028338f, -0.0039032909617394158f, -0.005778966765403332f, -0.006196371644937026f, + -0.005126649521643357f, -0.002892440783972528f, -7.569452202221049e-05f, 0.002631054152962605f, 0.004592602844898446f, 0.005378027138078235f, + 0.004853141153493943f, 0.003199157832490015f, 0.0008563413932258106f, -0.001590923732936595f, -0.003558167390675537f, -0.004598879085877497f, + -0.004504316650754686f, -0.003343128797128057f, -0.0014338841732215583f, 0.0007403304559674372f, 0.0026527959791814225f, 0.0038595992992198572f, + 0.004101546070654008f, 0.003358415711090973f, 0.0018445621699828237f, -5.086484742755164e-05f, -0.0018628405052291059f, -0.0031636439376678694f, + -0.0036629655414078164f, -0.0032717150482324516f, -0.002115748235827439f, -0.0004980923359440308f, 0.001179498550313731f, 0.0025155804434977406f, + 0.0032044110974639535f, 0.003105189005540589f, 0.002269636290554184f, 0.0009228543792967101f, -0.0005963499224796556f, -0.0019200660782804076f, + -0.0027398331837579586f, -0.0028779607130344355f, -0.0023252613565889484f, -0.0012373878562206998f, 0.0001079256271408814f, 0.001381201221652482f, + 0.0022814537885444343f, 0.002606895019486452f, 0.002299603441905315f, 0.001454413618303933f, 0.00029112333986494875f, -0.0009021206418670336f, + -0.0018398015723057382f, -0.0023069860593334167f, -0.002208166640388556f, -0.001585999954687689f, -0.0006064866379520778f, 0.0004847501066751298f, + 0.001423699236028589f, 0.001991528323569564f, 0.002065250674652296f, 0.0016438443679279932f, 0.0008444146452898538f, -0.00012968638587027814f, + -0.0010402454244288109f, -0.0016721737676909565f, -0.0018840426030750455f, -0.0016393611363987892f, -0.00101177697301324f, -0.000163826281401473f, + 0.0006948153834432945f, 0.001358936932918977f, 0.0016766077219011598f, 0.001583648840995474f, 0.0011160111306802627f, 0.0003978427911930665f, + -0.0003910935278882586f, -0.0010601864459545338f, -0.0014538306405106657f, -0.0014873874506915337f, -0.0011649976932383162f, -0.000575602781164748f, + 0.00013114380113039367f, 0.0007826466076227966f, 0.0012253403293674297f, 0.001360699649507721f, 0.0011668892017168851f, 0.0007013694018032594f, + 8.448134650865583e-05f, -0.0005314230983962694f, -0.0009994417150751657f, -0.001213001401090671f, -0.0011299141868816099f, -0.0007802344633793596f, + -0.0002565961558720999f, 0.0003100600703417042f, 0.000783068568853146f, 0.0010528599573031263f, 0.0010621735733697998f, 0.0008179024786880318f, + 0.000387206320324671f, -0.00012063098325035138f, -0.0005817666488097535f, -0.0008878723835859144f, -0.0009714434650863762f, -0.0008204653938672434f, + -0.0004793104720456748f, -3.613809815664295e-05f, 0.0003997115889927176f, 0.0007245735362801915f, 0.00086499549032453f, 0.000794178884862575f, + 0.0005366866370135178f, 0.00016071671200037333f, -0.00023976249450019229f, -0.0005683789433809046f, -0.0007494432795037147f, -0.000745249935902165f, + -0.00056367237533275f, -0.00025459557921401604f, 0.00010354940020593262f, 0.00042356504465827625f, 0.0006306211703786999f, 0.0006796440073147703f, + 0.000564947257716049f, 0.00032009664994853484f, 8.409423734104047e-06f, -0.0002932866713238596f, -0.0005134988701415268f, -0.0006029184799152024f, + -0.0005453257947001756f, -0.00036017534034318133f, -9.656593983252403e-05f, 0.00017962947202432243f, 0.0004021335775498866f, 0.0005200872932458632f, + 0.0005095680085994171f, 0.00037822278267612763f, 0.00016218327373728096f, -8.369322660349729e-05f, -0.0002996590281028708f, -0.00043551985080457316f, + -0.0004622136024407257f, -0.0003778755478488185f, -0.00020716636324439341f, 5.700643354394805e-06f, 0.00020830912486435524f, 0.00035287542885270373f, + 0.0004074442241842563f, 0.00036283954499724997f, 0.00023388968509776965f, 5.4874683724266626e-05f, -0.00012947230718511564f, -0.0002750725778339314f, + -0.0003489767404299755f, -0.00033673373853927404f, -0.0002450291060281673f, -9.916797784749802e-05f, 6.377162994954104e-05f, 0.00020429142207811283f, + 0.00028998881291818565f, 0.00030295803344061305f, 0.00024340423431723786f, 0.00012877755492326877f, -1.116470369424232e-05f, -0.00014200540887034094f, + -0.00023307650021536254f, -0.00026458825304284705f, -0.00023183668917914544f, -0.00014562030460083452f, -2.89428088362726e-05f, 8.903798250712117e-05f, + 0.00018024216434545852f, 0.0002242996579722704f, 0.0002130285335328205f, 0.00015179440591692495f, 5.757653860596238e-05f, -4.563889644759457e-05f, + -0.0001329097142102547f, -0.00018431901261959646f, -0.00018946381166227083f, -0.00014945443689276262f, -7.607175578778393e-05f, 1.157444307940535e-05f, + 9.196321623926072e-05f, 0.00014640387262396037f, 0.0001633347777040411f, 0.00014070296987162006f, 8.595633313966191e-05f, 1.3774226033203211e-05f, + -5.780418307922092e-05f, -0.00011184660662576022f, -0.00013649307135328725f, -0.00012750155200331027f, -8.884316159376149e-05f, -3.131031531861043e-05f, + 3.0422431031760574e-05f, 8.149972830032109e-05f, 0.00011042486406119114f, 0.0001116027274787376f, 8.633588458239913e-05f, 4.212328682528971e-05f, + -9.475276647106836e-06f, -5.581843466722564e-05f, -8.624792240002861e-05f, -9.450353669455348e-05f, -7.995073288441698e-05f, -4.739789768353654e-05f, + -5.6299938557223714e-06f, 3.491584157791999e-05f, 6.472766236692141e-05f, 7.741979300458653e-05f, 7.105610879688223e-05f, 4.833395043391465e-05f, + 1.5655032748882834e-05f, -1.8626278197123308e-05f, -4.63086316244695e-05f, -6.127944612408436e-05f, -6.083045378499977e-05f, -4.607935202681541e-05f, + -2.145474134416278e-05f, 6.572134618200237e-06f, 3.115747283293287e-05f, 4.6732536591469296e-05f, 5.0237898294931096e-05f, 4.167805084205758e-05f, + 2.3910224388238513e-05f, 1.7698780085840604e-06f, -1.9213291464732e-05f, -3.417465815777557e-05f, -4.002028816797243e-05f, -3.603341117882283e-05f, + -2.3872746018477846e-05f, -7.006637231184095e-06f, 1.024146219566499e-05f, 2.3780490067865e-05f, 3.070344982909068e-05f, 2.988664778393458e-05f, + 2.212011999721824e-05f, 9.773568468952705e-06f, -3.8872324521640265e-06f, -1.5543839717163266e-05f, -2.2615023926355254e-05f, -2.3809127279542265e-05f, + -1.932605805253585e-05f, -1.0688739061583608e-05f, -2.740174359813823e-07f, 9.320735053412442e-06f, 1.5910878336996937e-05f, 1.820668633540655e-05f, + 1.6042159651260656e-05f, 1.0317342373158007e-05f, 2.692366003430763e-06f, -4.8724000492981274e-06f, -1.0607006582875768e-05f, -1.3333643382732469e-05f, + -1.2691498798386898e-05f, -9.147013859009695e-06f, -3.806589553951066e-06f, 1.9054003350526885e-06f, 6.613913881503402e-06f, 9.313903839206387e-06f, + 9.572182772489344e-06f, 7.573673021989436e-06f, 4.016100018535679e-06f, -1.0681717109783684e-07f, -3.770766054468487e-06f, -6.1664774806085404e-06f, + -6.868846754126758e-06f, -5.896943190857115e-06f, -3.661909388482541e-06f, -8.270502826770229e-07f, 1.8769928536209681e-06f, 3.832827875404265e-06f, + 4.66981747470593e-06f, 4.323696092525644e-06f, 3.016287801367824e-06f, 1.169289632945126e-06f, -7.195568958705088e-07f, -2.203734205629703e-06f, + -2.9876264959214665e-06f, -2.9779202914242935e-06f, -2.2802225651653813e-06f, -1.1484798394999376e-06f, 9.467860877910933e-08f, 1.143733350219884e-06f, + 1.7806663582809258e-06f, 1.9149301373470155e-06f, 1.5873541986613687e-06f, 9.419097945454788e-07f, 1.765979842996413e-07f, -5.116868845731189e-07f, + -9.740376083153232e-07f, -1.1379118280829263e-06f, -1.0127802760012628e-06f, -6.750429872594422e-07f, -2.390462883978719e-07f, 1.7654259185517028e-07f, + 4.780008570940273e-07f, 6.149318849908952e-07f, 5.849848067357207e-07f, 4.25999961202196e-07f, 1.9964925679003818e-07f, -2.7891854588389937e-08f, + -2.0288946624290177e-07f, -2.9478799977106246e-07f, -2.9916558380919976e-07f, -2.3360609465673318e-07f, -1.2887790166769242e-07f, -1.8575955256728605e-08f, + 6.98165233472851e-08f, 1.2043301999843577e-07f, 1.3038003060051805e-07f, 1.0746842146236057e-07f, 6.56984160679439e-08f, 2.0187158038407728e-08f, + -1.6985910384779763e-08f, -3.911531647701826e-08f, -4.518884483648565e-08f, -3.859576051529636e-08f, -2.4984867921475803e-08f, -1.0089665711571232e-08f, + 1.8556810104194671e-09f, 8.81636638720527e-09f, 1.0817071302193613e-08f, 9.246128218035411e-09f, 5.9789349448002054e-09f, 2.645711238283505e-09f, + 2.28107470502183e-10f, -9.930951082636695e-10f, -1.2410008763135097e-09f, -9.51381731279286e-10f, -5.248064118418001e-10f, -1.9709071280477305e-10f, + -3.1335654479869494e-11f, 1.537678992124691e-11f, 1.1828539027346112e-11f, 2.691239924154828e-12f, 0, 0 +}; + + + + +/* ===== Init functions ===== */ + +SCD_FIR *p863_up_1_to_2_init(void) { + return fir_initialization(P863_LEN2, p863_coeff_2, 2.0, 2L, 'U'); +} + +SCD_FIR *p863_down_2_to_1_init(void) { + return fir_initialization(P863_LEN2, p863_coeff_2, 1.0, 2L, 'D'); +} + +SCD_FIR *p863_up_1_to_3_init(void) { + return fir_initialization(P863_LEN3, p863_coeff_3, 3.0, 3L, 'U'); +} + +SCD_FIR *p863_down_3_to_1_init(void) { + return fir_initialization(P863_LEN3, p863_coeff_3, 1.0, 3L, 'D'); +} + +SCD_FIR *p863_up_1_to_4_init(void) { + return fir_initialization(P863_LEN4, p863_coeff_4, 4.0, 4L, 'U'); +} + +SCD_FIR *p863_down_4_to_1_init(void) { + return fir_initialization(P863_LEN4, p863_coeff_4, 1.0, 4L, 'D'); +} + +SCD_FIR *p863_up_1_to_6_init(void) { + return fir_initialization(P863_LEN6, p863_coeff_6, 6.0, 6L, 'U'); +} + +SCD_FIR *p863_down_6_to_1_init(void) { + return fir_initialization(P863_LEN6, p863_coeff_6, 1.0, 6L, 'D'); +} diff --git a/src/fir/fir-wb.c b/src/fir/fir-wb.c index 15bf4727..5b633b3b 100644 --- a/src/fir/fir-wb.c +++ b/src/fir/fir-wb.c @@ -77,6 +77,8 @@ ORIGINAL BY: Cyril Guillaume & Stephane Ragot 11.May.2007 v2.3 Added 20-20000 Hz bandpass filter Ingemar Johansson & Jonas Svedberg, Ericsson + 05.April.2012 v2.3 - Added filters: HP50_32KHZ, HP50_48KHZ (France Telecom) + ============================================================================= */ @@ -1828,3 +1830,737 @@ SCD_FIR *bp20k_48khz_init () { /* .................... End of bp20k_48khz_init() .................... */ /* ************************** END OF FIR-WB.C *************************** */ + + + +/* + ============================================================================ + + void fill_hp50_32khz (float **h0, long *lenh0); + ~~~~~~~~~~~~~~~~~~~~~ + + Description: + ~~~~~~~~~~~~ + Fill filter coefficients for 50 Hz (3dB point) highpass filtering for samples at 32 kHz. + firpm(1118,[0 3/16000 66/16000 1],[0 0 1 1 ],[40 1]) + Same lengt, HP response and passband oscillation (+-0.15dB) as the 14KBP filter + + Parameters: + ~~~~~~~~~~~ + h0: (Out) pointer to array with FIR coefficients + lenh0: (Out) pointer to number of coefficients + + Return value: + ~~~~~~~~~~~~~ + None. + + History: + ~~~~~~~~ + 05.April.2012 v1.0 - Added filters: HP50_32KHZ, HP50_48KHZ (France Telecom) + + ============================================================================ +*/ +#undef HP50_32K_LEN +#define HP50_32K_LEN 1119 +void fill_hp50_32khz (float **h0, long *lenh0) { + static float hp50_32khz_coeff[HP50_32K_LEN] = { + (F) 9.2342753e-003, (F) 1.5551665e-004, (F) 1.5663328e-004, (F) 1.5798547e-004, (F) 1.5903747e-004, + (F) 1.6033147e-004, (F) 1.6129533e-004, (F) 1.6253497e-004, (F) 1.6343643e-004, (F) 1.6461419e-004, + (F) 1.6544194e-004, (F) 1.6657230e-004, (F) 1.6734333e-004, (F) 1.6843147e-004, (F) 1.6914017e-004, + (F) 1.7020317e-004, (F) 1.7087787e-004, (F) 1.7195115e-004, (F) 1.7260586e-004, (F) 1.7371570e-004, + (F) 1.7438288e-004, (F) 1.7560111e-004, (F) 1.7633494e-004, (F) 1.7773870e-004, (F) 1.7859148e-004, + (F) 1.8031784e-004, (F) 1.8138467e-004, (F) 1.8364291e-004, (F) 1.8500691e-004, (F) 1.8826921e-004, + (F) 1.9002553e-004, (F) 1.9648117e-004, (F) 1.7591939e-004, (F) 1.8640971e-004, (F) 1.8950640e-004, + (F) 1.8933708e-004, (F) 1.9094255e-004, (F) 1.9111524e-004, (F) 1.9238679e-004, (F) 1.9267245e-004, + (F) 1.9374881e-004, (F) 1.9407034e-004, (F) 1.9502938e-004, (F) 1.9535326e-004, (F) 1.9621245e-004, + (F) 1.9652536e-004, (F) 1.9732846e-004, (F) 1.9764305e-004, (F) 1.9840997e-004, (F) 1.9872274e-004, + (F) 1.9948456e-004, (F) 1.9982454e-004, (F) 2.0062041e-004, (F) 2.0098888e-004, (F) 2.0182655e-004, + (F) 2.0221283e-004, (F) 2.0309827e-004, (F) 2.0343574e-004, (F) 2.0429009e-004, (F) 2.0439317e-004, + (F) 2.0505697e-004, (F) 2.0443830e-004, (F) 2.0447446e-004, (F) 2.0117747e-004, (F) 2.0668075e-004, + (F) 2.0606828e-004, (F) 2.0522994e-004, (F) 2.0580818e-004, (F) 2.0551705e-004, (F) 2.0583582e-004, + (F) 2.0559447e-004, (F) 2.0575204e-004, (F) 2.0551182e-004, (F) 2.0556260e-004, (F) 2.0528478e-004, + (F) 2.0524898e-004, (F) 2.0494755e-004, (F) 2.0486118e-004, (F) 2.0453189e-004, (F) 2.0439794e-004, + (F) 2.0404606e-004, (F) 2.0389248e-004, (F) 2.0352446e-004, (F) 2.0334171e-004, (F) 2.0292316e-004, + (F) 2.0268931e-004, (F) 2.0218689e-004, (F) 2.0186213e-004, (F) 2.0119510e-004, (F) 2.0072227e-004, + (F) 1.9983291e-004, (F) 1.9922601e-004, (F) 1.9811086e-004, (F) 1.9764812e-004, (F) 1.9670052e-004, + (F) 1.9821206e-004, (F) 1.9574339e-004, (F) 1.9460314e-004, (F) 1.9434052e-004, (F) 1.9312581e-004, + (F) 1.9244888e-004, (F) 1.9126723e-004, (F) 1.9044159e-004, (F) 1.8925727e-004, (F) 1.8831959e-004, + (F) 1.8709650e-004, (F) 1.8608695e-004, (F) 1.8483886e-004, (F) 1.8376430e-004, (F) 1.8246886e-004, + (F) 1.8133430e-004, (F) 1.8000008e-004, (F) 1.7881024e-004, (F) 1.7740887e-004, (F) 1.7613174e-004, + (F) 1.7463511e-004, (F) 1.7326225e-004, (F) 1.7165185e-004, (F) 1.7016635e-004, (F) 1.6842980e-004, + (F) 1.6686975e-004, (F) 1.6506208e-004, (F) 1.6351953e-004, (F) 1.6172121e-004, (F) 1.6035465e-004, + (F) 1.5856474e-004, (F) 1.5725670e-004, (F) 1.5400320e-004, (F) 1.5251907e-004, (F) 1.5099189e-004, + (F) 1.4860587e-004, (F) 1.4676216e-004, (F) 1.4449103e-004, (F) 1.4250292e-004, (F) 1.4021375e-004, + (F) 1.3809993e-004, (F) 1.3577053e-004, (F) 1.3357737e-004, (F) 1.3119183e-004, (F) 1.2890182e-004, + (F) 1.2644454e-004, (F) 1.2407353e-004, (F) 1.2154154e-004, (F) 1.1906901e-004, (F) 1.1642978e-004, + (F) 1.1384795e-004, (F) 1.1110845e-004, (F) 1.0843159e-004, (F) 1.0559403e-004, (F) 1.0283674e-004, + (F) 9.9931180e-005, (F) 9.7143301e-005, (F) 9.4193407e-005, (F) 9.1380999e-005, (F) 8.8349417e-005, + (F) 8.5454155e-005, (F) 8.2145791e-005, (F) 7.8972973e-005, (F) 7.5176800e-005, (F) 7.2644410e-005, + (F) 6.9400379e-005, (F) 6.5655639e-005, (F) 6.2520637e-005, (F) 5.8926380e-005, (F) 5.5592602e-005, + (F) 5.1960346e-005, (F) 4.8492626e-005, (F) 4.4819152e-005, (F) 4.1246975e-005, (F) 3.7486700e-005, + (F) 3.3802916e-005, (F) 2.9964364e-005, (F) 2.6183621e-005, (F) 2.2246019e-005, (F) 1.8349478e-005, + (F) 1.4312671e-005, (F) 1.0327219e-005, (F) 6.2116278e-006, (F) 2.1468476e-006, (F) - 2.0462664e-006, + (F) - 6.1754788e-006, (F) - 1.0433728e-005, (F) - 1.4631174e-005, (F) - 1.8994868e-005, (F) - 2.3307139e-005, + (F) - 2.7830625e-005, (F) - 3.2298035e-005, (F) - 3.7020060e-005, (F) - 4.1543856e-005, (F) - 4.6245143e-005, + (F) - 5.0403230e-005, (F) - 5.5414477e-005, (F) - 6.0403894e-005, (F) - 6.4897114e-005, (F) - 6.9912852e-005, + (F) - 7.4678495e-005, (F) - 7.9718290e-005, (F) - 8.4612320e-005, (F) - 8.9698178e-005, (F) - 9.4721351e-005, + (F) - 9.9898650e-005, (F) - 1.0502188e-004, (F) - 1.1027447e-004, (F) - 1.1550253e-004, (F) - 1.2085379e-004, + (F) - 1.2617687e-004, (F) - 1.3159904e-004, (F) - 1.3699375e-004, (F) - 1.4249159e-004, (F) - 1.4796949e-004, + (F) - 1.5355011e-004, (F) - 1.5911076e-004, (F) - 1.6479026e-004, (F) - 1.7046432e-004, (F) - 1.7627586e-004, + (F) - 1.8206851e-004, (F) - 1.8799894e-004, (F) - 1.9387145e-004, (F) - 1.9986051e-004, (F) - 2.0570182e-004, + (F) - 2.1170656e-004, (F) - 2.1762031e-004, (F) - 2.2408600e-004, (F) - 2.3020843e-004, (F) - 2.3612941e-004, + (F) - 2.4259571e-004, (F) - 2.4875579e-004, (F) - 2.5518652e-004, (F) - 2.6147595e-004, (F) - 2.6796135e-004, + (F) - 2.7438622e-004, (F) - 2.8093774e-004, (F) - 2.8744468e-004, (F) - 2.9407149e-004, (F) - 3.0067960e-004, + (F) - 3.0738263e-004, (F) - 3.1405879e-004, (F) - 3.2082305e-004, (F) - 3.2758021e-004, (F) - 3.3443304e-004, + (F) - 3.4128144e-004, (F) - 3.4822305e-004, (F) - 3.5516575e-004, (F) - 3.6221220e-004, (F) - 3.6925666e-004, + (F) - 3.7639420e-004, (F) - 3.8350434e-004, (F) - 3.9070041e-004, (F) - 3.9784824e-004, (F) - 4.0508935e-004, + (F) - 4.1228858e-004, (F) - 4.1967673e-004, (F) - 4.2705956e-004, (F) - 4.3464576e-004, (F) - 4.4189166e-004, + (F) - 4.4925726e-004, (F) - 4.5702829e-004, (F) - 4.6443246e-004, (F) - 4.7212529e-004, (F) - 4.7968369e-004, + (F) - 4.8742511e-004, (F) - 4.9509526e-004, (F) - 5.0286502e-004, (F) - 5.1061081e-004, (F) - 5.1845390e-004, + (F) - 5.2627883e-004, (F) - 5.3417018e-004, (F) - 5.4205412e-004, (F) - 5.5001749e-004, (F) - 5.5799069e-004, + (F) - 5.6603542e-004, (F) - 5.7408320e-004, (F) - 5.8219998e-004, (F) - 5.9032342e-004, (F) - 5.9851277e-004, + (F) - 6.0669333e-004, (F) - 6.1492812e-004, (F) - 6.2314811e-004, (F) - 6.3143448e-004, (F) - 6.3971196e-004, + (F) - 6.4808079e-004, (F) - 6.5645951e-004, (F) - 6.6495597e-004, (F) - 6.7340132e-004, (F) - 6.8188705e-004, + (F) - 6.9023175e-004, (F) - 6.9882694e-004, (F) - 7.0758003e-004, (F) - 7.1597837e-004, (F) - 7.2471488e-004, + (F) - 7.3329577e-004, (F) - 7.4204112e-004, (F) - 7.5069691e-004, (F) - 7.5944753e-004, (F) - 7.6818552e-004, + (F) - 7.7699171e-004, (F) - 7.8577593e-004, (F) - 7.9461592e-004, (F) - 8.0346439e-004, (F) - 8.1237496e-004, + (F) - 8.2128725e-004, (F) - 8.3024166e-004, (F) - 8.3919545e-004, (F) - 8.4819452e-004, (F) - 8.5719302e-004, + (F) - 8.6622788e-004, (F) - 8.7525413e-004, (F) - 8.8432225e-004, (F) - 8.9339327e-004, (F) - 9.0252009e-004, + (F) - 9.1165217e-004, (F) - 9.2084585e-004, (F) - 9.3003378e-004, (F) - 9.3925877e-004, (F) - 9.4842600e-004, + (F) - 9.5763434e-004, (F) - 9.6685278e-004, (F) - 9.7624213e-004, (F) - 9.8558142e-004, (F) - 9.9469419e-004, + (F) - 1.0041623e-003, (F) - 1.0134207e-003, (F) - 1.0228270e-003, (F) - 1.0321370e-003, (F) - 1.0415421e-003, + (F) - 1.0509287e-003, (F) - 1.0603454e-003, (F) - 1.0697472e-003, (F) - 1.0791931e-003, (F) - 1.0886461e-003, + (F) - 1.0981218e-003, (F) - 1.1075850e-003, (F) - 1.1170647e-003, (F) - 1.1265441e-003, (F) - 1.1360444e-003, + (F) - 1.1455390e-003, (F) - 1.1550493e-003, (F) - 1.1645586e-003, (F) - 1.1740960e-003, (F) - 1.1836376e-003, + (F) - 1.1932042e-003, (F) - 1.2027641e-003, (F) - 1.2123405e-003, (F) - 1.2218939e-003, (F) - 1.2314513e-003, + (F) - 1.2409915e-003, (F) - 1.2505846e-003, (F) - 1.2602023e-003, (F) - 1.2698414e-003, (F) - 1.2793765e-003, + (F) - 1.2888500e-003, (F) - 1.2986084e-003, (F) - 1.3080936e-003, (F) - 1.3177360e-003, (F) - 1.3272775e-003, + (F) - 1.3369056e-003, (F) - 1.3464878e-003, (F) - 1.3560717e-003, (F) - 1.3656533e-003, (F) - 1.3752525e-003, + (F) - 1.3848374e-003, (F) - 1.3944071e-003, (F) - 1.4039627e-003, (F) - 1.4135209e-003, (F) - 1.4230765e-003, + (F) - 1.4326278e-003, (F) - 1.4421680e-003, (F) - 1.4517067e-003, (F) - 1.4612428e-003, (F) - 1.4707800e-003, + (F) - 1.4803050e-003, (F) - 1.4898201e-003, (F) - 1.4993153e-003, (F) - 1.5087988e-003, (F) - 1.5182618e-003, + (F) - 1.5277224e-003, (F) - 1.5371854e-003, (F) - 1.5466604e-003, (F) - 1.5561103e-003, (F) - 1.5655040e-003, + (F) - 1.5748552e-003, (F) - 1.5842315e-003, (F) - 1.5937465e-003, (F) - 1.6029720e-003, (F) - 1.6123861e-003, + (F) - 1.6216776e-003, (F) - 1.6310319e-003, (F) - 1.6403094e-003, (F) - 1.6495786e-003, (F) - 1.6588508e-003, + (F) - 1.6680951e-003, (F) - 1.6773067e-003, (F) - 1.6864862e-003, (F) - 1.6956610e-003, (F) - 1.7048193e-003, + (F) - 1.7139612e-003, (F) - 1.7230717e-003, (F) - 1.7321649e-003, (F) - 1.7412365e-003, (F) - 1.7502915e-003, + (F) - 1.7593161e-003, (F) - 1.7683126e-003, (F) - 1.7772766e-003, (F) - 1.7862164e-003, (F) - 1.7951289e-003, + (F) - 1.8040225e-003, (F) - 1.8128956e-003, (F) - 1.8217521e-003, (F) - 1.8305658e-003, (F) - 1.8393318e-003, + (F) - 1.8480455e-003, (F) - 1.8567739e-003, (F) - 1.8654993e-003, (F) - 1.8742251e-003, (F) - 1.8827205e-003, + (F) - 1.8914187e-003, (F) - 1.8999453e-003, (F) - 1.9085111e-003, (F) - 1.9169830e-003, (F) - 1.9254474e-003, + (F) - 1.9339013e-003, (F) - 1.9422783e-003, (F) - 1.9506295e-003, (F) - 1.9589431e-003, (F) - 1.9672506e-003, + (F) - 1.9755049e-003, (F) - 1.9837264e-003, (F) - 1.9918954e-003, (F) - 2.0000433e-003, (F) - 2.0081449e-003, + (F) - 2.0162141e-003, (F) - 2.0242280e-003, (F) - 2.0322084e-003, (F) - 2.0401417e-003, (F) - 2.0480469e-003, + (F) - 2.0559056e-003, (F) - 2.0637353e-003, (F) - 2.0715137e-003, (F) - 2.0792531e-003, (F) - 2.0869231e-003, + (F) - 2.0945604e-003, (F) - 2.1021565e-003, (F) - 2.1097586e-003, (F) - 2.1172812e-003, (F) - 2.1247500e-003, + (F) - 2.1320815e-003, (F) - 2.1395760e-003, (F) - 2.1468415e-003, (F) - 2.1541473e-003, (F) - 2.1613533e-003, + (F) - 2.1685494e-003, (F) - 2.1757036e-003, (F) - 2.1827534e-003, (F) - 2.1898035e-003, (F) - 2.1967961e-003, + (F) - 2.2037585e-003, (F) - 2.2106328e-003, (F) - 2.2174712e-003, (F) - 2.2242476e-003, (F) - 2.2309941e-003, + (F) - 2.2376696e-003, (F) - 2.2443002e-003, (F) - 2.2508627e-003, (F) - 2.2573883e-003, (F) - 2.2638523e-003, + (F) - 2.2702762e-003, (F) - 2.2766333e-003, (F) - 2.2829462e-003, (F) - 2.2891862e-003, (F) - 2.2953787e-003, + (F) - 2.3015001e-003, (F) - 2.3075962e-003, (F) - 2.3136302e-003, (F) - 2.3196255e-003, (F) - 2.3255025e-003, + (F) - 2.3313432e-003, (F) - 2.3371056e-003, (F) - 2.3429385e-003, (F) - 2.3485211e-003, (F) - 2.3541678e-003, + (F) - 2.3597041e-003, (F) - 2.3652138e-003, (F) - 2.3706526e-003, (F) - 2.3759854e-003, (F) - 2.3813401e-003, + (F) - 2.3865859e-003, (F) - 2.3917824e-003, (F) - 2.3968782e-003, (F) - 2.4019512e-003, (F) - 2.4069457e-003, + (F) - 2.4118957e-003, (F) - 2.4167526e-003, (F) - 2.4215631e-003, (F) - 2.4262966e-003, (F) - 2.4309880e-003, + (F) - 2.4355990e-003, (F) - 2.4401590e-003, (F) - 2.4446355e-003, (F) - 2.4490606e-003, (F) - 2.4534014e-003, + (F) - 2.4576959e-003, (F) - 2.4619128e-003, (F) - 2.4660912e-003, (F) - 2.4701730e-003, (F) - 2.4741950e-003, + (F) - 2.4781081e-003, (F) - 2.4820112e-003, (F) - 2.4858283e-003, (F) - 2.4896281e-003, (F) - 2.4932110e-003, + (F) - 2.4968799e-003, (F) - 2.5004058e-003, (F) - 2.5038901e-003, (F) - 2.5072888e-003, (F) - 2.5105972e-003, + (F) - 2.5139194e-003, (F) - 2.5170758e-003, (F) - 2.5201976e-003, (F) - 2.5232275e-003, (F) - 2.5262357e-003, + (F) - 2.5291376e-003, (F) - 2.5319814e-003, (F) - 2.5347278e-003, (F) - 2.5374318e-003, (F) - 2.5400513e-003, + (F) - 2.5426174e-003, (F) - 2.5450901e-003, (F) - 2.5475049e-003, (F) - 2.5498302e-003, (F) - 2.5521002e-003, + (F) - 2.5542824e-003, (F) - 2.5564137e-003, (F) - 2.5584559e-003, (F) - 2.5604403e-003, (F) - 2.5623171e-003, + (F) - 2.5641411e-003, (F) - 2.5658766e-003, (F) - 2.5675914e-003, (F) - 2.5691867e-003, (F) - 2.5707272e-003, + (F) - 2.5721182e-003, (F) - 2.5735785e-003, (F) - 2.5748584e-003, (F) - 2.5760978e-003, (F) - 2.5772547e-003, + (F) - 2.5783297e-003, (F) - 2.5793907e-003, (F) - 2.5802554e-003, (F) - 2.5811389e-003, (F) - 2.5819204e-003, + (F) - 2.5826616e-003, (F) - 2.5832717e-003, (F) - 2.5838350e-003, (F) - 2.5843078e-003, (F) - 2.5847406e-003, + (F) - 2.5850741e-003, (F) - 2.5853470e-003, (F) - 2.5855214e-003, (F) - 2.5856405e-003, (F) 9.9741433e-001, + (F) - 2.5856405e-003, (F) - 2.5855214e-003, (F) - 2.5853470e-003, (F) - 2.5850741e-003, (F) - 2.5847406e-003, + (F) - 2.5843078e-003, (F) - 2.5838350e-003, (F) - 2.5832717e-003, (F) - 2.5826616e-003, (F) - 2.5819204e-003, + (F) - 2.5811389e-003, (F) - 2.5802554e-003, (F) - 2.5793907e-003, (F) - 2.5783297e-003, (F) - 2.5772547e-003, + (F) - 2.5760978e-003, (F) - 2.5748584e-003, (F) - 2.5735785e-003, (F) - 2.5721182e-003, (F) - 2.5707272e-003, + (F) - 2.5691867e-003, (F) - 2.5675914e-003, (F) - 2.5658766e-003, (F) - 2.5641411e-003, (F) - 2.5623171e-003, + (F) - 2.5604403e-003, (F) - 2.5584559e-003, (F) - 2.5564137e-003, (F) - 2.5542824e-003, (F) - 2.5521002e-003, + (F) - 2.5498302e-003, (F) - 2.5475049e-003, (F) - 2.5450901e-003, (F) - 2.5426174e-003, (F) - 2.5400513e-003, + (F) - 2.5374318e-003, (F) - 2.5347278e-003, (F) - 2.5319814e-003, (F) - 2.5291376e-003, (F) - 2.5262357e-003, + (F) - 2.5232275e-003, (F) - 2.5201976e-003, (F) - 2.5170758e-003, (F) - 2.5139194e-003, (F) - 2.5105972e-003, + (F) - 2.5072888e-003, (F) - 2.5038901e-003, (F) - 2.5004058e-003, (F) - 2.4968799e-003, (F) - 2.4932110e-003, + (F) - 2.4896281e-003, (F) - 2.4858283e-003, (F) - 2.4820112e-003, (F) - 2.4781081e-003, (F) - 2.4741950e-003, + (F) - 2.4701730e-003, (F) - 2.4660912e-003, (F) - 2.4619128e-003, (F) - 2.4576959e-003, (F) - 2.4534014e-003, + (F) - 2.4490606e-003, (F) - 2.4446355e-003, (F) - 2.4401590e-003, (F) - 2.4355990e-003, (F) - 2.4309880e-003, + (F) - 2.4262966e-003, (F) - 2.4215631e-003, (F) - 2.4167526e-003, (F) - 2.4118957e-003, (F) - 2.4069457e-003, + (F) - 2.4019512e-003, (F) - 2.3968782e-003, (F) - 2.3917824e-003, (F) - 2.3865859e-003, (F) - 2.3813401e-003, + (F) - 2.3759854e-003, (F) - 2.3706526e-003, (F) - 2.3652138e-003, (F) - 2.3597041e-003, (F) - 2.3541678e-003, + (F) - 2.3485211e-003, (F) - 2.3429385e-003, (F) - 2.3371056e-003, (F) - 2.3313432e-003, (F) - 2.3255025e-003, + (F) - 2.3196255e-003, (F) - 2.3136302e-003, (F) - 2.3075962e-003, (F) - 2.3015001e-003, (F) - 2.2953787e-003, + (F) - 2.2891862e-003, (F) - 2.2829462e-003, (F) - 2.2766333e-003, (F) - 2.2702762e-003, (F) - 2.2638523e-003, + (F) - 2.2573883e-003, (F) - 2.2508627e-003, (F) - 2.2443002e-003, (F) - 2.2376696e-003, (F) - 2.2309941e-003, + (F) - 2.2242476e-003, (F) - 2.2174712e-003, (F) - 2.2106328e-003, (F) - 2.2037585e-003, (F) - 2.1967961e-003, + (F) - 2.1898035e-003, (F) - 2.1827534e-003, (F) - 2.1757036e-003, (F) - 2.1685494e-003, (F) - 2.1613533e-003, + (F) - 2.1541473e-003, (F) - 2.1468415e-003, (F) - 2.1395760e-003, (F) - 2.1320815e-003, (F) - 2.1247500e-003, + (F) - 2.1172812e-003, (F) - 2.1097586e-003, (F) - 2.1021565e-003, (F) - 2.0945604e-003, (F) - 2.0869231e-003, + (F) - 2.0792531e-003, (F) - 2.0715137e-003, (F) - 2.0637353e-003, (F) - 2.0559056e-003, (F) - 2.0480469e-003, + (F) - 2.0401417e-003, (F) - 2.0322084e-003, (F) - 2.0242280e-003, (F) - 2.0162141e-003, (F) - 2.0081449e-003, + (F) - 2.0000433e-003, (F) - 1.9918954e-003, (F) - 1.9837264e-003, (F) - 1.9755049e-003, (F) - 1.9672506e-003, + (F) - 1.9589431e-003, (F) - 1.9506295e-003, (F) - 1.9422783e-003, (F) - 1.9339013e-003, (F) - 1.9254474e-003, + (F) - 1.9169830e-003, (F) - 1.9085111e-003, (F) - 1.8999453e-003, (F) - 1.8914187e-003, (F) - 1.8827205e-003, + (F) - 1.8742251e-003, (F) - 1.8654993e-003, (F) - 1.8567739e-003, (F) - 1.8480455e-003, (F) - 1.8393318e-003, + (F) - 1.8305658e-003, (F) - 1.8217521e-003, (F) - 1.8128956e-003, (F) - 1.8040225e-003, (F) - 1.7951289e-003, + (F) - 1.7862164e-003, (F) - 1.7772766e-003, (F) - 1.7683126e-003, (F) - 1.7593161e-003, (F) - 1.7502915e-003, + (F) - 1.7412365e-003, (F) - 1.7321649e-003, (F) - 1.7230717e-003, (F) - 1.7139612e-003, (F) - 1.7048193e-003, + (F) - 1.6956610e-003, (F) - 1.6864862e-003, (F) - 1.6773067e-003, (F) - 1.6680951e-003, (F) - 1.6588508e-003, + (F) - 1.6495786e-003, (F) - 1.6403094e-003, (F) - 1.6310319e-003, (F) - 1.6216776e-003, (F) - 1.6123861e-003, + (F) - 1.6029720e-003, (F) - 1.5937465e-003, (F) - 1.5842315e-003, (F) - 1.5748552e-003, (F) - 1.5655040e-003, + (F) - 1.5561103e-003, (F) - 1.5466604e-003, (F) - 1.5371854e-003, (F) - 1.5277224e-003, (F) - 1.5182618e-003, + (F) - 1.5087988e-003, (F) - 1.4993153e-003, (F) - 1.4898201e-003, (F) - 1.4803050e-003, (F) - 1.4707800e-003, + (F) - 1.4612428e-003, (F) - 1.4517067e-003, (F) - 1.4421680e-003, (F) - 1.4326278e-003, (F) - 1.4230765e-003, + (F) - 1.4135209e-003, (F) - 1.4039627e-003, (F) - 1.3944071e-003, (F) - 1.3848374e-003, (F) - 1.3752525e-003, + (F) - 1.3656533e-003, (F) - 1.3560717e-003, (F) - 1.3464878e-003, (F) - 1.3369056e-003, (F) - 1.3272775e-003, + (F) - 1.3177360e-003, (F) - 1.3080936e-003, (F) - 1.2986084e-003, (F) - 1.2888500e-003, (F) - 1.2793765e-003, + (F) - 1.2698414e-003, (F) - 1.2602023e-003, (F) - 1.2505846e-003, (F) - 1.2409915e-003, (F) - 1.2314513e-003, + (F) - 1.2218939e-003, (F) - 1.2123405e-003, (F) - 1.2027641e-003, (F) - 1.1932042e-003, (F) - 1.1836376e-003, + (F) - 1.1740960e-003, (F) - 1.1645586e-003, (F) - 1.1550493e-003, (F) - 1.1455390e-003, (F) - 1.1360444e-003, + (F) - 1.1265441e-003, (F) - 1.1170647e-003, (F) - 1.1075850e-003, (F) - 1.0981218e-003, (F) - 1.0886461e-003, + (F) - 1.0791931e-003, (F) - 1.0697472e-003, (F) - 1.0603454e-003, (F) - 1.0509287e-003, (F) - 1.0415421e-003, + (F) - 1.0321370e-003, (F) - 1.0228270e-003, (F) - 1.0134207e-003, (F) - 1.0041623e-003, (F) - 9.9469419e-004, + (F) - 9.8558142e-004, (F) - 9.7624213e-004, (F) - 9.6685278e-004, (F) - 9.5763434e-004, (F) - 9.4842600e-004, + (F) - 9.3925877e-004, (F) - 9.3003378e-004, (F) - 9.2084585e-004, (F) - 9.1165217e-004, (F) - 9.0252009e-004, + (F) - 8.9339327e-004, (F) - 8.8432225e-004, (F) - 8.7525413e-004, (F) - 8.6622788e-004, (F) - 8.5719302e-004, + (F) - 8.4819452e-004, (F) - 8.3919545e-004, (F) - 8.3024166e-004, (F) - 8.2128725e-004, (F) - 8.1237496e-004, + (F) - 8.0346439e-004, (F) - 7.9461592e-004, (F) - 7.8577593e-004, (F) - 7.7699171e-004, (F) - 7.6818552e-004, + (F) - 7.5944753e-004, (F) - 7.5069691e-004, (F) - 7.4204112e-004, (F) - 7.3329577e-004, (F) - 7.2471488e-004, + (F) - 7.1597837e-004, (F) - 7.0758003e-004, (F) - 6.9882694e-004, (F) - 6.9023175e-004, (F) - 6.8188705e-004, + (F) - 6.7340132e-004, (F) - 6.6495597e-004, (F) - 6.5645951e-004, (F) - 6.4808079e-004, (F) - 6.3971196e-004, + (F) - 6.3143448e-004, (F) - 6.2314811e-004, (F) - 6.1492812e-004, (F) - 6.0669333e-004, (F) - 5.9851277e-004, + (F) - 5.9032342e-004, (F) - 5.8219998e-004, (F) - 5.7408320e-004, (F) - 5.6603542e-004, (F) - 5.5799069e-004, + (F) - 5.5001749e-004, (F) - 5.4205412e-004, (F) - 5.3417018e-004, (F) - 5.2627883e-004, (F) - 5.1845390e-004, + (F) - 5.1061081e-004, (F) - 5.0286502e-004, (F) - 4.9509526e-004, (F) - 4.8742511e-004, (F) - 4.7968369e-004, + (F) - 4.7212529e-004, (F) - 4.6443246e-004, (F) - 4.5702829e-004, (F) - 4.4925726e-004, (F) - 4.4189166e-004, + (F) - 4.3464576e-004, (F) - 4.2705956e-004, (F) - 4.1967673e-004, (F) - 4.1228858e-004, (F) - 4.0508935e-004, + (F) - 3.9784824e-004, (F) - 3.9070041e-004, (F) - 3.8350434e-004, (F) - 3.7639420e-004, (F) - 3.6925666e-004, + (F) - 3.6221220e-004, (F) - 3.5516575e-004, (F) - 3.4822305e-004, (F) - 3.4128144e-004, (F) - 3.3443304e-004, + (F) - 3.2758021e-004, (F) - 3.2082305e-004, (F) - 3.1405879e-004, (F) - 3.0738263e-004, (F) - 3.0067960e-004, + (F) - 2.9407149e-004, (F) - 2.8744468e-004, (F) - 2.8093774e-004, (F) - 2.7438622e-004, (F) - 2.6796135e-004, + (F) - 2.6147595e-004, (F) - 2.5518652e-004, (F) - 2.4875579e-004, (F) - 2.4259571e-004, (F) - 2.3612941e-004, + (F) - 2.3020843e-004, (F) - 2.2408600e-004, (F) - 2.1762031e-004, (F) - 2.1170656e-004, (F) - 2.0570182e-004, + (F) - 1.9986051e-004, (F) - 1.9387145e-004, (F) - 1.8799894e-004, (F) - 1.8206851e-004, (F) - 1.7627586e-004, + (F) - 1.7046432e-004, (F) - 1.6479026e-004, (F) - 1.5911076e-004, (F) - 1.5355011e-004, (F) - 1.4796949e-004, + (F) - 1.4249159e-004, (F) - 1.3699375e-004, (F) - 1.3159904e-004, (F) - 1.2617687e-004, (F) - 1.2085379e-004, + (F) - 1.1550253e-004, (F) - 1.1027447e-004, (F) - 1.0502188e-004, (F) - 9.9898650e-005, (F) - 9.4721351e-005, + (F) - 8.9698178e-005, (F) - 8.4612320e-005, (F) - 7.9718290e-005, (F) - 7.4678495e-005, (F) - 6.9912852e-005, + (F) - 6.4897114e-005, (F) - 6.0403894e-005, (F) - 5.5414477e-005, (F) - 5.0403230e-005, (F) - 4.6245143e-005, + (F) - 4.1543856e-005, (F) - 3.7020060e-005, (F) - 3.2298035e-005, (F) - 2.7830625e-005, (F) - 2.3307139e-005, + (F) - 1.8994868e-005, (F) - 1.4631174e-005, (F) - 1.0433728e-005, (F) - 6.1754788e-006, (F) - 2.0462664e-006, + (F) 2.1468476e-006, (F) 6.2116278e-006, (F) 1.0327219e-005, (F) 1.4312671e-005, (F) 1.8349478e-005, + (F) 2.2246019e-005, (F) 2.6183621e-005, (F) 2.9964364e-005, (F) 3.3802916e-005, (F) 3.7486700e-005, + (F) 4.1246975e-005, (F) 4.4819152e-005, (F) 4.8492626e-005, (F) 5.1960346e-005, (F) 5.5592602e-005, + (F) 5.8926380e-005, (F) 6.2520637e-005, (F) 6.5655639e-005, (F) 6.9400379e-005, (F) 7.2644410e-005, + (F) 7.5176800e-005, (F) 7.8972973e-005, (F) 8.2145791e-005, (F) 8.5454155e-005, (F) 8.8349417e-005, + (F) 9.1380999e-005, (F) 9.4193407e-005, (F) 9.7143301e-005, (F) 9.9931180e-005, (F) 1.0283674e-004, + (F) 1.0559403e-004, (F) 1.0843159e-004, (F) 1.1110845e-004, (F) 1.1384795e-004, (F) 1.1642978e-004, + (F) 1.1906901e-004, (F) 1.2154154e-004, (F) 1.2407353e-004, (F) 1.2644454e-004, (F) 1.2890182e-004, + (F) 1.3119183e-004, (F) 1.3357737e-004, (F) 1.3577053e-004, (F) 1.3809993e-004, (F) 1.4021375e-004, + (F) 1.4250292e-004, (F) 1.4449103e-004, (F) 1.4676216e-004, (F) 1.4860587e-004, (F) 1.5099189e-004, + (F) 1.5251907e-004, (F) 1.5400320e-004, (F) 1.5725670e-004, (F) 1.5856474e-004, (F) 1.6035465e-004, + (F) 1.6172121e-004, (F) 1.6351953e-004, (F) 1.6506208e-004, (F) 1.6686975e-004, (F) 1.6842980e-004, + (F) 1.7016635e-004, (F) 1.7165185e-004, (F) 1.7326225e-004, (F) 1.7463511e-004, (F) 1.7613174e-004, + (F) 1.7740887e-004, (F) 1.7881024e-004, (F) 1.8000008e-004, (F) 1.8133430e-004, (F) 1.8246886e-004, + (F) 1.8376430e-004, (F) 1.8483886e-004, (F) 1.8608695e-004, (F) 1.8709650e-004, (F) 1.8831959e-004, + (F) 1.8925727e-004, (F) 1.9044159e-004, (F) 1.9126723e-004, (F) 1.9244888e-004, (F) 1.9312581e-004, + (F) 1.9434052e-004, (F) 1.9460314e-004, (F) 1.9574339e-004, (F) 1.9821206e-004, (F) 1.9670052e-004, + (F) 1.9764812e-004, (F) 1.9811086e-004, (F) 1.9922601e-004, (F) 1.9983291e-004, (F) 2.0072227e-004, + (F) 2.0119510e-004, (F) 2.0186213e-004, (F) 2.0218689e-004, (F) 2.0268931e-004, (F) 2.0292316e-004, + (F) 2.0334171e-004, (F) 2.0352446e-004, (F) 2.0389248e-004, (F) 2.0404606e-004, (F) 2.0439794e-004, + (F) 2.0453189e-004, (F) 2.0486118e-004, (F) 2.0494755e-004, (F) 2.0524898e-004, (F) 2.0528478e-004, + (F) 2.0556260e-004, (F) 2.0551182e-004, (F) 2.0575204e-004, (F) 2.0559447e-004, (F) 2.0583582e-004, + (F) 2.0551705e-004, (F) 2.0580818e-004, (F) 2.0522994e-004, (F) 2.0606828e-004, (F) 2.0668075e-004, + (F) 2.0117747e-004, (F) 2.0447446e-004, (F) 2.0443830e-004, (F) 2.0505697e-004, (F) 2.0439317e-004, + (F) 2.0429009e-004, (F) 2.0343574e-004, (F) 2.0309827e-004, (F) 2.0221283e-004, (F) 2.0182655e-004, + (F) 2.0098888e-004, (F) 2.0062041e-004, (F) 1.9982454e-004, (F) 1.9948456e-004, (F) 1.9872274e-004, + (F) 1.9840997e-004, (F) 1.9764305e-004, (F) 1.9732846e-004, (F) 1.9652536e-004, (F) 1.9621245e-004, + (F) 1.9535326e-004, (F) 1.9502938e-004, (F) 1.9407034e-004, (F) 1.9374881e-004, (F) 1.9267245e-004, + (F) 1.9238679e-004, (F) 1.9111524e-004, (F) 1.9094255e-004, (F) 1.8933708e-004, (F) 1.8950640e-004, + (F) 1.8640971e-004, (F) 1.7591939e-004, (F) 1.9648117e-004, (F) 1.9002553e-004, (F) 1.8826921e-004, + (F) 1.8500691e-004, (F) 1.8364291e-004, (F) 1.8138467e-004, (F) 1.8031784e-004, (F) 1.7859148e-004, + (F) 1.7773870e-004, (F) 1.7633494e-004, (F) 1.7560111e-004, (F) 1.7438288e-004, (F) 1.7371570e-004, + (F) 1.7260586e-004, (F) 1.7195115e-004, (F) 1.7087787e-004, (F) 1.7020317e-004, (F) 1.6914017e-004, + (F) 1.6843147e-004, (F) 1.6734333e-004, (F) 1.6657230e-004, (F) 1.6544194e-004, (F) 1.6461419e-004, + (F) 1.6343643e-004, (F) 1.6253497e-004, (F) 1.6129533e-004, (F) 1.6033147e-004, (F) 1.5903747e-004, + (F) 1.5798547e-004, (F) 1.5663328e-004, (F) 1.5551665e-004, (F) 9.2342753e-003 + }; + *lenh0 = HP50_32K_LEN; /* store 'number of coefficients' */ + *h0 = hp50_32khz_coeff; /* store pointer to []-array */ +} + +#undef HP50_32K_LEN +/* ...................... End of fill_bp14k_32khz() ..................... */ + + +/* + ============================================================================ + + SCD_FIR hp50_32khz_init (void); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Description: + ~~~~~~~~~~~~ + + Initialization routine for a band-pass filter which limits the + bandwidth of the input signal from 50 Hz to 14000 Hz (3 dB points). + No rate change is implemented. + + Parameters: none. + ~~~~~~~~~~~ + + Return value: + ~~~~~~~~~~~~~ + Returns a pointer to struct SCD_FIR; + + History: + ~~~~~~~~ + 05.April.2012 v1.0 - Added filters: HP50_32KHZ, HP50_48KHZ (France Telecom) + + ============================================================================ +*/ +SCD_FIR *hp50_32khz_init () { + float *h0; /* pointer to array with FIR coeff. */ + long lenh0; /* number of FIR coefficients */ + + + /* allocate array for FIR coeff. and fill with coefficients */ + fill_hp50_32khz (&h0, &lenh0); + + return fir_initialization ( /* Returns: pointer to SCD_FIR-struct */ + lenh0, /* In: number of FIR-coefficients */ + h0, /* In: pointer to array with FIR-cof. */ + 1.0, /* In: gain factor for FIR-coeffic. */ + 1l, /* In: Down-sampling factor */ + 'D' /* In: switch to down-sampling proc. */ + ); /* (works here as simple FIR-fil. */ +} + +/* .................... End of hp50_32khz_init() .................... */ + + + +/* + ============================================================================ + + void fill_hp50_48khz (float **h0, long *lenh0); + ~~~~~~~~~~~~~~~~~~~~~ + + Description: + ~~~~~~~~~~~~ + Fill filter coefficients for 50 Hz (3dB point) highpass filtering for samples at 48 kHz. + firpm(1678,[0 2.5/24000 66/24000 1],[0.000 0.00 1 1 ],[60 1]); + Same lengt, HP response and passband oscillation (+-0.15dB) as the 14KBP filter or HP50@32kHz + + Parameters: + ~~~~~~~~~~~ + h0: (Out) pointer to array with FIR coefficients + lenh0: (Out) pointer to number of coefficients + + Return value: + ~~~~~~~~~~~~~ + None. + + History: + ~~~~~~~~ + 05.April.2012 v1.0 - Added filters: HP50_32KHZ, HP50_48KHZ (France Telecom) + + ============================================================================ +*/ +#undef HP50_48K_LEN +#define HP50_48K_LEN 1679 +void fill_hp50_48khz (float **h0, long *lenh0) { + static float hp50_48khz_coeff[HP50_48K_LEN] = { + (F) 9.2170161e-003, (F) 1.0282141e-004, (F) 1.0323477e-004, (F) 1.0392614e-004, (F) 1.0431790e-004, + (F) 1.0499377e-004, (F) 1.0536773e-004, (F) 1.0603588e-004, (F) 1.0638882e-004, (F) 1.0705021e-004, + (F) 1.0739106e-004, (F) 1.0805611e-004, (F) 1.0837965e-004, (F) 1.0905795e-004, (F) 1.0938090e-004, + (F) 1.1007974e-004, (F) 1.1040957e-004, (F) 1.1115190e-004, (F) 1.1149459e-004, (F) 1.1229782e-004, + (F) 1.1266869e-004, (F) 1.1356565e-004, (F) 1.1396913e-004, (F) 1.1501372e-004, (F) 1.1546739e-004, + (F) 1.1671837e-004, (F) 1.1723162e-004, (F) 1.1881924e-004, (F) 1.1938009e-004, (F) 1.2160186e-004, + (F) 1.2211069e-004, (F) 1.2681189e-004, (F) 1.0603987e-004, (F) 1.1739216e-004, (F) 1.2019571e-004, + (F) 1.1960227e-004, (F) 1.2084617e-004, (F) 1.2064739e-004, (F) 1.2156945e-004, (F) 1.2152965e-004, + (F) 1.2231705e-004, (F) 1.2236911e-004, (F) 1.2308341e-004, (F) 1.2319054e-004, (F) 1.2387359e-004, + (F) 1.2402521e-004, (F) 1.2468629e-004, (F) 1.2487613e-004, (F) 1.2553014e-004, (F) 1.2574208e-004, + (F) 1.2639667e-004, (F) 1.2662486e-004, (F) 1.2727834e-004, (F) 1.2749849e-004, (F) 1.2815380e-004, + (F) 1.2832364e-004, (F) 1.2895095e-004, (F) 1.2901611e-004, (F) 1.2957883e-004, (F) 1.2941200e-004, + (F) 1.2984364e-004, (F) 1.2918213e-004, (F) 1.2939196e-004, (F) 1.2692712e-004, (F) 1.3285917e-004, + (F) 1.3188746e-004, (F) 1.3108290e-004, (F) 1.3185337e-004, (F) 1.3174954e-004, (F) 1.3230559e-004, + (F) 1.3234605e-004, (F) 1.3281968e-004, (F) 1.3292077e-004, (F) 1.3334594e-004, (F) 1.3347954e-004, + (F) 1.3388084e-004, (F) 1.3402423e-004, (F) 1.3439884e-004, (F) 1.3454719e-004, (F) 1.3489334e-004, + (F) 1.3502831e-004, (F) 1.3534817e-004, (F) 1.3545658e-004, (F) 1.3573672e-004, (F) 1.3580183e-004, + (F) 1.3604220e-004, (F) 1.3603623e-004, (F) 1.3623973e-004, (F) 1.3616781e-004, (F) 1.3635135e-004, + (F) 1.3622245e-004, (F) 1.3647364e-004, (F) 1.3635685e-004, (F) 1.3690649e-004, (F) 1.3696791e-004, + (F) 1.3896829e-004, (F) 1.3697478e-004, (F) 1.3692105e-004, (F) 1.3768980e-004, (F) 1.3743527e-004, + (F) 1.3778116e-004, (F) 1.3765261e-004, (F) 1.3789559e-004, (F) 1.3780411e-004, (F) 1.3798877e-004, + (F) 1.3791032e-004, (F) 1.3805069e-004, (F) 1.3795926e-004, (F) 1.3806087e-004, (F) 1.3795585e-004, + (F) 1.3801376e-004, (F) 1.3788717e-004, (F) 1.3790990e-004, (F) 1.3775349e-004, (F) 1.3774242e-004, + (F) 1.3756412e-004, (F) 1.3753506e-004, (F) 1.3733693e-004, (F) 1.3732519e-004, (F) 1.3713014e-004, + (F) 1.3715429e-004, (F) 1.3698332e-004, (F) 1.3708216e-004, (F) 1.3691530e-004, (F) 1.3707353e-004, + (F) 1.3676131e-004, (F) 1.3683967e-004, (F) 1.3537370e-004, (F) 1.3597876e-004, (F) 1.3620588e-004, + (F) 1.3557968e-004, (F) 1.3560751e-004, (F) 1.3522156e-004, (F) 1.3513030e-004, (F) 1.3477709e-004, + (F) 1.3462320e-004, (F) 1.3427186e-004, (F) 1.3406692e-004, (F) 1.3370193e-004, (F) 1.3346421e-004, + (F) 1.3308486e-004, (F) 1.3281213e-004, (F) 1.3242329e-004, (F) 1.3212756e-004, (F) 1.3172649e-004, + (F) 1.3142101e-004, (F) 1.3102020e-004, (F) 1.3071229e-004, (F) 1.3031017e-004, (F) 1.3001517e-004, + (F) 1.2959499e-004, (F) 1.2929298e-004, (F) 1.2883966e-004, (F) 1.2850208e-004, (F) 1.2795178e-004, + (F) 1.2754364e-004, (F) 1.2684799e-004, (F) 1.2641365e-004, (F) 1.2561428e-004, (F) 1.2595624e-004, + (F) 1.2528676e-004, (F) 1.2434765e-004, (F) 1.2412368e-004, (F) 1.2341104e-004, (F) 1.2298547e-004, + (F) 1.2231406e-004, (F) 1.2182429e-004, (F) 1.2115661e-004, (F) 1.2062332e-004, (F) 1.1995423e-004, + (F) 1.1939587e-004, (F) 1.1871658e-004, (F) 1.1813439e-004, (F) 1.1745353e-004, (F) 1.1685124e-004, + (F) 1.1616264e-004, (F) 1.1554840e-004, (F) 1.1484676e-004, (F) 1.1420856e-004, (F) 1.1348183e-004, + (F) 1.1281518e-004, (F) 1.1203418e-004, (F) 1.1133137e-004, (F) 1.1049916e-004, (F) 1.0975257e-004, + (F) 1.0887415e-004, (F) 1.0813498e-004, (F) 1.0726099e-004, (F) 1.0661111e-004, (F) 1.0578194e-004, + (F) 1.0529542e-004, (F) 1.0396291e-004, (F) 1.0299308e-004, (F) 1.0247409e-004, (F) 1.0137922e-004, + (F) 1.0060085e-004, (F) 9.9604074e-005, (F) 9.8760420e-005, (F) 9.7773259e-005, (F) 9.6892188e-005, + (F) 9.5905360e-005, (F) 9.4993975e-005, (F) 9.3992439e-005, (F) 9.3056320e-005, (F) 9.2042727e-005, + (F) 9.1073535e-005, (F) 9.0039349e-005, (F) 8.9038684e-005, (F) 8.7969516e-005, (F) 8.6929477e-005, + (F) 8.5825876e-005, (F) 8.4750138e-005, (F) 8.3606584e-005, (F) 8.2519454e-005, (F) 8.1353458e-005, + (F) 8.0258949e-005, (F) 7.9094451e-005, (F) 7.8017131e-005, (F) 7.6835554e-005, (F) 7.5741110e-005, + (F) 7.4464448e-005, (F) 7.3269051e-005, (F) 7.1728435e-005, (F) 7.0709936e-005, (F) 6.9687722e-005, + (F) 6.8148646e-005, (F) 6.7027725e-005, (F) 6.5663462e-005, (F) 6.4441171e-005, (F) 6.3085250e-005, + (F) 6.1818800e-005, (F) 6.0452242e-005, (F) 5.9143854e-005, (F) 5.7756282e-005, (F) 5.6415612e-005, + (F) 5.5001511e-005, (F) 5.3618819e-005, (F) 5.2178565e-005, (F) 5.0758389e-005, (F) 4.9285680e-005, + (F) 4.7838012e-005, (F) 4.6344615e-005, (F) 4.4875639e-005, (F) 4.3364404e-005, (F) 4.1892374e-005, + (F) 4.0354202e-005, (F) 3.8864361e-005, (F) 3.7301364e-005, (F) 3.5770376e-005, (F) 3.4140016e-005, + (F) 3.2553422e-005, (F) 3.0858734e-005, (F) 2.9262279e-005, (F) 2.7585354e-005, (F) 2.6196851e-005, + (F) 2.4508556e-005, (F) 2.2595147e-005, (F) 2.1125524e-005, (F) 1.9336697e-005, (F) 1.7687295e-005, + (F) 1.5919286e-005, (F) 1.4217836e-005, (F) 1.2432060e-005, (F) 1.0686745e-005, (F) 8.8806737e-006, + (F) 7.1001852e-006, (F) 5.2646709e-006, (F) 3.4494433e-006, (F) 1.5949437e-006, (F) - 2.5040016e-007, + (F) - 2.1249647e-006, (F) - 3.9880938e-006, (F) - 5.8828077e-006, (F) - 7.7707834e-006, (F) - 9.6904874e-006, + (F) - 1.1604256e-005, (F) - 1.3572472e-005, (F) - 1.5517481e-005, (F) - 1.7525599e-005, (F) - 1.9516113e-005, + (F) - 2.1556262e-005, (F) - 2.3549789e-005, (F) - 2.5587191e-005, (F) - 2.7557313e-005, (F) - 2.9593067e-005, + (F) - 3.1583770e-005, (F) - 3.3828247e-005, (F) - 3.6003270e-005, (F) - 3.7882528e-005, (F) - 4.0157616e-005, + (F) - 4.2238257e-005, (F) - 4.4435158e-005, (F) - 4.6576406e-005, (F) - 4.8788370e-005, (F) - 5.0966866e-005, + (F) - 5.3195433e-005, (F) - 5.5407648e-005, (F) - 5.7659653e-005, (F) - 5.9896191e-005, (F) - 6.2164814e-005, + (F) - 6.4430870e-005, (F) - 6.6719855e-005, (F) - 6.9012344e-005, (F) - 7.1334393e-005, (F) - 7.3660509e-005, + (F) - 7.6014789e-005, (F) - 7.8374135e-005, (F) - 8.0767477e-005, (F) - 8.3140519e-005, (F) - 8.5558944e-005, + (F) - 8.7951462e-005, (F) - 9.0371180e-005, (F) - 9.2768583e-005, (F) - 9.5215819e-005, (F) - 9.7654715e-005, + (F) - 1.0017071e-004, (F) - 1.0268888e-004, (F) - 1.0528563e-004, (F) - 1.0773097e-004, (F) - 1.1012977e-004, + (F) - 1.1287369e-004, (F) - 1.1534129e-004, (F) - 1.1795237e-004, (F) - 1.2051726e-004, (F) - 1.2313545e-004, + (F) - 1.2573245e-004, (F) - 1.2836778e-004, (F) - 1.3099695e-004, (F) - 1.3365159e-004, (F) - 1.3630467e-004, + (F) - 1.3898420e-004, (F) - 1.4167133e-004, (F) - 1.4437565e-004, (F) - 1.4709544e-004, (F) - 1.4983227e-004, + (F) - 1.5257694e-004, (F) - 1.5533702e-004, (F) - 1.5810382e-004, (F) - 1.6088469e-004, (F) - 1.6365806e-004, + (F) - 1.6646857e-004, (F) - 1.6926417e-004, (F) - 1.7209519e-004, (F) - 1.7493698e-004, (F) - 1.7782269e-004, + (F) - 1.8070933e-004, (F) - 1.8362809e-004, (F) - 1.8652433e-004, (F) - 1.8942093e-004, (F) - 1.9226519e-004, + (F) - 1.9520475e-004, (F) - 1.9831231e-004, (F) - 2.0112323e-004, (F) - 2.0414964e-004, (F) - 2.0711506e-004, + (F) - 2.1012138e-004, (F) - 2.1311883e-004, (F) - 2.1614560e-004, (F) - 2.1917324e-004, (F) - 2.2221937e-004, + (F) - 2.2527550e-004, (F) - 2.2835091e-004, (F) - 2.3143610e-004, (F) - 2.3453175e-004, (F) - 2.3764368e-004, + (F) - 2.4076019e-004, (F) - 2.4388735e-004, (F) - 2.4702508e-004, (F) - 2.5017411e-004, (F) - 2.5333543e-004, + (F) - 2.5650720e-004, (F) - 2.5971239e-004, (F) - 2.6291070e-004, (F) - 2.6614678e-004, (F) - 2.6938916e-004, + (F) - 2.7264437e-004, (F) - 2.7588913e-004, (F) - 2.7914295e-004, (F) - 2.8238998e-004, (F) - 2.8565591e-004, + (F) - 2.8895192e-004, (F) - 2.9231668e-004, (F) - 2.9568523e-004, (F) - 2.9885971e-004, (F) - 3.0230245e-004, + (F) - 3.0562944e-004, (F) - 3.0899705e-004, (F) - 3.1236984e-004, (F) - 3.1575932e-004, (F) - 3.1915720e-004, + (F) - 3.2256619e-004, (F) - 3.2599148e-004, (F) - 3.2942304e-004, (F) - 3.3286616e-004, (F) - 3.3631386e-004, + (F) - 3.3977978e-004, (F) - 3.4324533e-004, (F) - 3.4673121e-004, (F) - 3.5022620e-004, (F) - 3.5373782e-004, + (F) - 3.5726001e-004, (F) - 3.6079784e-004, (F) - 3.6435228e-004, (F) - 3.6789813e-004, (F) - 3.7147125e-004, + (F) - 3.7503555e-004, (F) - 3.7860142e-004, (F) - 3.8217419e-004, (F) - 3.8576582e-004, (F) - 3.8937618e-004, + (F) - 3.9300877e-004, (F) - 3.9666663e-004, (F) - 4.0031807e-004, (F) - 4.0393867e-004, (F) - 4.0751295e-004, + (F) - 4.1131485e-004, (F) - 4.1493297e-004, (F) - 4.1862574e-004, (F) - 4.2232986e-004, (F) - 4.2603467e-004, + (F) - 4.2975534e-004, (F) - 4.3347834e-004, (F) - 4.3721957e-004, (F) - 4.4095707e-004, (F) - 4.4471248e-004, + (F) - 4.4847023e-004, (F) - 4.5224882e-004, (F) - 4.5602551e-004, (F) - 4.5982681e-004, (F) - 4.6362882e-004, + (F) - 4.6744464e-004, (F) - 4.7126296e-004, (F) - 4.7509149e-004, (F) - 4.7892223e-004, (F) - 4.8274958e-004, + (F) - 4.8660067e-004, (F) - 4.9044254e-004, (F) - 4.9429973e-004, (F) - 4.9818084e-004, (F) - 5.0207382e-004, + (F) - 5.0597844e-004, (F) - 5.0988090e-004, (F) - 5.1378900e-004, (F) - 5.1767455e-004, (F) - 5.2157784e-004, + (F) - 5.2550534e-004, (F) - 5.2954292e-004, (F) - 5.3338602e-004, (F) - 5.3736583e-004, (F) - 5.4133594e-004, + (F) - 5.4529167e-004, (F) - 5.4927299e-004, (F) - 5.5324706e-004, (F) - 5.5724157e-004, (F) - 5.6122794e-004, + (F) - 5.6523832e-004, (F) - 5.6924539e-004, (F) - 5.7327066e-004, (F) - 5.7728920e-004, (F) - 5.8132765e-004, + (F) - 5.8535649e-004, (F) - 5.8939695e-004, (F) - 5.9343652e-004, (F) - 5.9748510e-004, (F) - 6.0153590e-004, + (F) - 6.0559430e-004, (F) - 6.0967412e-004, (F) - 6.1374540e-004, (F) - 6.1783904e-004, (F) - 6.2194403e-004, + (F) - 6.2603808e-004, (F) - 6.3013543e-004, (F) - 6.3422627e-004, (F) - 6.3833154e-004, (F) - 6.4243332e-004, + (F) - 6.4657635e-004, (F) - 6.5072148e-004, (F) - 6.5488235e-004, (F) - 6.5892065e-004, (F) - 6.6313078e-004, + (F) - 6.6727626e-004, (F) - 6.7140842e-004, (F) - 6.7557927e-004, (F) - 6.7972979e-004, (F) - 6.8390501e-004, + (F) - 6.8806653e-004, (F) - 6.9225262e-004, (F) - 6.9642391e-004, (F) - 7.0061078e-004, (F) - 7.0478617e-004, + (F) - 7.0897873e-004, (F) - 7.1315848e-004, (F) - 7.1735508e-004, (F) - 7.2155033e-004, (F) - 7.2575613e-004, + (F) - 7.2996431e-004, (F) - 7.3418147e-004, (F) - 7.3840652e-004, (F) - 7.4261917e-004, (F) - 7.4684907e-004, + (F) - 7.5107177e-004, (F) - 7.5527988e-004, (F) - 7.5950621e-004, (F) - 7.6373284e-004, (F) - 7.6797990e-004, + (F) - 7.7222020e-004, (F) - 7.7648381e-004, (F) - 7.8071490e-004, (F) - 7.8494955e-004, (F) - 7.8914860e-004, + (F) - 7.9348415e-004, (F) - 7.9769844e-004, (F) - 8.0193496e-004, (F) - 8.0621272e-004, (F) - 8.1045333e-004, + (F) - 8.1472245e-004, (F) - 8.1897072e-004, (F) - 8.2323951e-004, (F) - 8.2748711e-004, (F) - 8.3175195e-004, + (F) - 8.3600580e-004, (F) - 8.4027518e-004, (F) - 8.4453368e-004, (F) - 8.4880893e-004, (F) - 8.5307776e-004, + (F) - 8.5735118e-004, (F) - 8.6162249e-004, (F) - 8.6589382e-004, (F) - 8.7016289e-004, (F) - 8.7442056e-004, + (F) - 8.7869469e-004, (F) - 8.8295395e-004, (F) - 8.8721488e-004, (F) - 8.9150003e-004, (F) - 8.9577366e-004, + (F) - 9.0005378e-004, (F) - 9.0431520e-004, (F) - 9.0858594e-004, (F) - 9.1282776e-004, (F) - 9.1709567e-004, + (F) - 9.2135966e-004, (F) - 9.2568012e-004, (F) - 9.2987591e-004, (F) - 9.3414524e-004, (F) - 9.3843171e-004, + (F) - 9.4266414e-004, (F) - 9.4693507e-004, (F) - 9.5117535e-004, (F) - 9.5543687e-004, (F) - 9.5967515e-004, + (F) - 9.6393468e-004, (F) - 9.6817845e-004, (F) - 9.7243400e-004, (F) - 9.7667465e-004, (F) - 9.8092565e-004, + (F) - 9.8516064e-004, (F) - 9.8939684e-004, (F) - 9.9362682e-004, (F) - 9.9785357e-004, (F) - 1.0020771e-003, + (F) - 1.0062964e-003, (F) - 1.0105278e-003, (F) - 1.0147410e-003, (F) - 1.0189627e-003, (F) - 1.0231919e-003, + (F) - 1.0273888e-003, (F) - 1.0315914e-003, (F) - 1.0357772e-003, (F) - 1.0399770e-003, (F) - 1.0441581e-003, + (F) - 1.0483674e-003, (F) - 1.0525531e-003, (F) - 1.0567446e-003, (F) - 1.0608604e-003, (F) - 1.0650738e-003, + (F) - 1.0692510e-003, (F) - 1.0733797e-003, (F) - 1.0775588e-003, (F) - 1.0816965e-003, (F) - 1.0858563e-003, + (F) - 1.0899914e-003, (F) - 1.0941426e-003, (F) - 1.0982701e-003, (F) - 1.1024024e-003, (F) - 1.1065175e-003, + (F) - 1.1106354e-003, (F) - 1.1147366e-003, (F) - 1.1188392e-003, (F) - 1.1229363e-003, (F) - 1.1270269e-003, + (F) - 1.1311162e-003, (F) - 1.1351978e-003, (F) - 1.1392810e-003, (F) - 1.1433394e-003, (F) - 1.1474060e-003, + (F) - 1.1514586e-003, (F) - 1.1554824e-003, (F) - 1.1595257e-003, (F) - 1.1635549e-003, (F) - 1.1675920e-003, + (F) - 1.1716069e-003, (F) - 1.1756321e-003, (F) - 1.1796207e-003, (F) - 1.1836123e-003, (F) - 1.1875792e-003, + (F) - 1.1916120e-003, (F) - 1.1955664e-003, (F) - 1.1995059e-003, (F) - 1.2034982e-003, (F) - 1.2074293e-003, + (F) - 1.2113866e-003, (F) - 1.2153109e-003, (F) - 1.2192453e-003, (F) - 1.2231497e-003, (F) - 1.2270598e-003, + (F) - 1.2309518e-003, (F) - 1.2348445e-003, (F) - 1.2387214e-003, (F) - 1.2425990e-003, (F) - 1.2464649e-003, + (F) - 1.2503198e-003, (F) - 1.2541682e-003, (F) - 1.2580017e-003, (F) - 1.2618275e-003, (F) - 1.2656312e-003, + (F) - 1.2694420e-003, (F) - 1.2732312e-003, (F) - 1.2770072e-003, (F) - 1.2808060e-003, (F) - 1.2845712e-003, + (F) - 1.2883348e-003, (F) - 1.2920713e-003, (F) - 1.2958126e-003, (F) - 1.2995222e-003, (F) - 1.3032464e-003, + (F) - 1.3069539e-003, (F) - 1.3106774e-003, (F) - 1.3143214e-003, (F) - 1.3179943e-003, (F) - 1.3216911e-003, + (F) - 1.3253120e-003, (F) - 1.3289667e-003, (F) - 1.3325813e-003, (F) - 1.3362028e-003, (F) - 1.3397971e-003, + (F) - 1.3433966e-003, (F) - 1.3469767e-003, (F) - 1.3505509e-003, (F) - 1.3541091e-003, (F) - 1.3576589e-003, + (F) - 1.3611918e-003, (F) - 1.3647088e-003, (F) - 1.3682185e-003, (F) - 1.3717083e-003, (F) - 1.3751927e-003, + (F) - 1.3786586e-003, (F) - 1.3821294e-003, (F) - 1.3855717e-003, (F) - 1.3890107e-003, (F) - 1.3924517e-003, + (F) - 1.3958431e-003, (F) - 1.3992389e-003, (F) - 1.4026138e-003, (F) - 1.4059908e-003, (F) - 1.4093413e-003, + (F) - 1.4126989e-003, (F) - 1.4160271e-003, (F) - 1.4193442e-003, (F) - 1.4226165e-003, (F) - 1.4259289e-003, + (F) - 1.4292197e-003, (F) - 1.4324405e-003, (F) - 1.4357099e-003, (F) - 1.4389270e-003, (F) - 1.4421539e-003, + (F) - 1.4453523e-003, (F) - 1.4485514e-003, (F) - 1.4517231e-003, (F) - 1.4548847e-003, (F) - 1.4580274e-003, + (F) - 1.4611567e-003, (F) - 1.4642681e-003, (F) - 1.4673659e-003, (F) - 1.4704549e-003, (F) - 1.4735233e-003, + (F) - 1.4765858e-003, (F) - 1.4796281e-003, (F) - 1.4826638e-003, (F) - 1.4856674e-003, (F) - 1.4886671e-003, + (F) - 1.4916506e-003, (F) - 1.4945890e-003, (F) - 1.4975504e-003, (F) - 1.5004827e-003, (F) - 1.5034084e-003, + (F) - 1.5063028e-003, (F) - 1.5091954e-003, (F) - 1.5120520e-003, (F) - 1.5149014e-003, (F) - 1.5177300e-003, + (F) - 1.5205758e-003, (F) - 1.5233678e-003, (F) - 1.5261251e-003, (F) - 1.5289303e-003, (F) - 1.5316663e-003, + (F) - 1.5344141e-003, (F) - 1.5371295e-003, (F) - 1.5398364e-003, (F) - 1.5425153e-003, (F) - 1.5451826e-003, + (F) - 1.5478334e-003, (F) - 1.5504665e-003, (F) - 1.5530859e-003, (F) - 1.5556881e-003, (F) - 1.5582783e-003, + (F) - 1.5608417e-003, (F) - 1.5633971e-003, (F) - 1.5659237e-003, (F) - 1.5684387e-003, (F) - 1.5709227e-003, + (F) - 1.5734049e-003, (F) - 1.5758605e-003, (F) - 1.5782894e-003, (F) - 1.5807395e-003, (F) - 1.5831377e-003, + (F) - 1.5855244e-003, (F) - 1.5878847e-003, (F) - 1.5902389e-003, (F) - 1.5925621e-003, (F) - 1.5948806e-003, + (F) - 1.5971795e-003, (F) - 1.5994648e-003, (F) - 1.6017023e-003, (F) - 1.6039374e-003, (F) - 1.6061948e-003, + (F) - 1.6083671e-003, (F) - 1.6105632e-003, (F) - 1.6127188e-003, (F) - 1.6148653e-003, (F) - 1.6169867e-003, + (F) - 1.6190977e-003, (F) - 1.6211891e-003, (F) - 1.6232595e-003, (F) - 1.6253137e-003, (F) - 1.6273450e-003, + (F) - 1.6293578e-003, (F) - 1.6313431e-003, (F) - 1.6333175e-003, (F) - 1.6352621e-003, (F) - 1.6371955e-003, + (F) - 1.6391040e-003, (F) - 1.6410056e-003, (F) - 1.6428767e-003, (F) - 1.6447288e-003, (F) - 1.6465844e-003, + (F) - 1.6483719e-003, (F) - 1.6501672e-003, (F) - 1.6519389e-003, (F) - 1.6536996e-003, (F) - 1.6554282e-003, + (F) - 1.6571491e-003, (F) - 1.6588414e-003, (F) - 1.6605117e-003, (F) - 1.6621541e-003, (F) - 1.6638005e-003, + (F) - 1.6654288e-003, (F) - 1.6669834e-003, (F) - 1.6685753e-003, (F) - 1.6701176e-003, (F) - 1.6716515e-003, + (F) - 1.6731631e-003, (F) - 1.6746564e-003, (F) - 1.6761265e-003, (F) - 1.6775701e-003, (F) - 1.6789983e-003, + (F) - 1.6803975e-003, (F) - 1.6817812e-003, (F) - 1.6831383e-003, (F) - 1.6844858e-003, (F) - 1.6858018e-003, + (F) - 1.6871089e-003, (F) - 1.6883875e-003, (F) - 1.6896522e-003, (F) - 1.6908826e-003, (F) - 1.6920984e-003, + (F) - 1.6932997e-003, (F) - 1.6944435e-003, (F) - 1.6956151e-003, (F) - 1.6967487e-003, (F) - 1.6978597e-003, + (F) - 1.6989426e-003, (F) - 1.7000133e-003, (F) - 1.7010552e-003, (F) - 1.7020763e-003, (F) - 1.7030812e-003, + (F) - 1.7040712e-003, (F) - 1.7050255e-003, (F) - 1.7059364e-003, (F) - 1.7068863e-003, (F) - 1.7077671e-003, + (F) - 1.7086455e-003, (F) - 1.7094964e-003, (F) - 1.7103232e-003, (F) - 1.7111262e-003, (F) - 1.7119057e-003, + (F) - 1.7126703e-003, (F) - 1.7134064e-003, (F) - 1.7141292e-003, (F) - 1.7148261e-003, (F) - 1.7155080e-003, + (F) - 1.7161579e-003, (F) - 1.7167949e-003, (F) - 1.7174006e-003, (F) - 1.7179873e-003, (F) - 1.7185461e-003, + (F) - 1.7190909e-003, (F) - 1.7196156e-003, (F) - 1.7200987e-003, (F) - 1.7206103e-003, (F) - 1.7210535e-003, + (F) - 1.7214820e-003, (F) - 1.7218914e-003, (F) - 1.7222858e-003, (F) - 1.7226498e-003, (F) - 1.7229951e-003, + (F) - 1.7233213e-003, (F) - 1.7236201e-003, (F) - 1.7238898e-003, (F) - 1.7241422e-003, (F) - 1.7244071e-003, + (F) - 1.7245924e-003, (F) - 1.7247871e-003, (F) - 1.7249510e-003, (F) - 1.7250894e-003, (F) - 1.7252121e-003, + (F) - 1.7253110e-003, (F) - 1.7253955e-003, (F) - 1.7254479e-003, (F) - 1.7254883e-003, (F) 9.9827450e-001, + (F) - 1.7254883e-003, (F) - 1.7254479e-003, (F) - 1.7253955e-003, (F) - 1.7253110e-003, (F) - 1.7252121e-003, + (F) - 1.7250894e-003, (F) - 1.7249510e-003, (F) - 1.7247871e-003, (F) - 1.7245924e-003, (F) - 1.7244071e-003, + (F) - 1.7241422e-003, (F) - 1.7238898e-003, (F) - 1.7236201e-003, (F) - 1.7233213e-003, (F) - 1.7229951e-003, + (F) - 1.7226498e-003, (F) - 1.7222858e-003, (F) - 1.7218914e-003, (F) - 1.7214820e-003, (F) - 1.7210535e-003, + (F) - 1.7206103e-003, (F) - 1.7200987e-003, (F) - 1.7196156e-003, (F) - 1.7190909e-003, (F) - 1.7185461e-003, + (F) - 1.7179873e-003, (F) - 1.7174006e-003, (F) - 1.7167949e-003, (F) - 1.7161579e-003, (F) - 1.7155080e-003, + (F) - 1.7148261e-003, (F) - 1.7141292e-003, (F) - 1.7134064e-003, (F) - 1.7126703e-003, (F) - 1.7119057e-003, + (F) - 1.7111262e-003, (F) - 1.7103232e-003, (F) - 1.7094964e-003, (F) - 1.7086455e-003, (F) - 1.7077671e-003, + (F) - 1.7068863e-003, (F) - 1.7059364e-003, (F) - 1.7050255e-003, (F) - 1.7040712e-003, (F) - 1.7030812e-003, + (F) - 1.7020763e-003, (F) - 1.7010552e-003, (F) - 1.7000133e-003, (F) - 1.6989426e-003, (F) - 1.6978597e-003, + (F) - 1.6967487e-003, (F) - 1.6956151e-003, (F) - 1.6944435e-003, (F) - 1.6932997e-003, (F) - 1.6920984e-003, + (F) - 1.6908826e-003, (F) - 1.6896522e-003, (F) - 1.6883875e-003, (F) - 1.6871089e-003, (F) - 1.6858018e-003, + (F) - 1.6844858e-003, (F) - 1.6831383e-003, (F) - 1.6817812e-003, (F) - 1.6803975e-003, (F) - 1.6789983e-003, + (F) - 1.6775701e-003, (F) - 1.6761265e-003, (F) - 1.6746564e-003, (F) - 1.6731631e-003, (F) - 1.6716515e-003, + (F) - 1.6701176e-003, (F) - 1.6685753e-003, (F) - 1.6669834e-003, (F) - 1.6654288e-003, (F) - 1.6638005e-003, + (F) - 1.6621541e-003, (F) - 1.6605117e-003, (F) - 1.6588414e-003, (F) - 1.6571491e-003, (F) - 1.6554282e-003, + (F) - 1.6536996e-003, (F) - 1.6519389e-003, (F) - 1.6501672e-003, (F) - 1.6483719e-003, (F) - 1.6465844e-003, + (F) - 1.6447288e-003, (F) - 1.6428767e-003, (F) - 1.6410056e-003, (F) - 1.6391040e-003, (F) - 1.6371955e-003, + (F) - 1.6352621e-003, (F) - 1.6333175e-003, (F) - 1.6313431e-003, (F) - 1.6293578e-003, (F) - 1.6273450e-003, + (F) - 1.6253137e-003, (F) - 1.6232595e-003, (F) - 1.6211891e-003, (F) - 1.6190977e-003, (F) - 1.6169867e-003, + (F) - 1.6148653e-003, (F) - 1.6127188e-003, (F) - 1.6105632e-003, (F) - 1.6083671e-003, (F) - 1.6061948e-003, + (F) - 1.6039374e-003, (F) - 1.6017023e-003, (F) - 1.5994648e-003, (F) - 1.5971795e-003, (F) - 1.5948806e-003, + (F) - 1.5925621e-003, (F) - 1.5902389e-003, (F) - 1.5878847e-003, (F) - 1.5855244e-003, (F) - 1.5831377e-003, + (F) - 1.5807395e-003, (F) - 1.5782894e-003, (F) - 1.5758605e-003, (F) - 1.5734049e-003, (F) - 1.5709227e-003, + (F) - 1.5684387e-003, (F) - 1.5659237e-003, (F) - 1.5633971e-003, (F) - 1.5608417e-003, (F) - 1.5582783e-003, + (F) - 1.5556881e-003, (F) - 1.5530859e-003, (F) - 1.5504665e-003, (F) - 1.5478334e-003, (F) - 1.5451826e-003, + (F) - 1.5425153e-003, (F) - 1.5398364e-003, (F) - 1.5371295e-003, (F) - 1.5344141e-003, (F) - 1.5316663e-003, + (F) - 1.5289303e-003, (F) - 1.5261251e-003, (F) - 1.5233678e-003, (F) - 1.5205758e-003, (F) - 1.5177300e-003, + (F) - 1.5149014e-003, (F) - 1.5120520e-003, (F) - 1.5091954e-003, (F) - 1.5063028e-003, (F) - 1.5034084e-003, + (F) - 1.5004827e-003, (F) - 1.4975504e-003, (F) - 1.4945890e-003, (F) - 1.4916506e-003, (F) - 1.4886671e-003, + (F) - 1.4856674e-003, (F) - 1.4826638e-003, (F) - 1.4796281e-003, (F) - 1.4765858e-003, (F) - 1.4735233e-003, + (F) - 1.4704549e-003, (F) - 1.4673659e-003, (F) - 1.4642681e-003, (F) - 1.4611567e-003, (F) - 1.4580274e-003, + (F) - 1.4548847e-003, (F) - 1.4517231e-003, (F) - 1.4485514e-003, (F) - 1.4453523e-003, (F) - 1.4421539e-003, + (F) - 1.4389270e-003, (F) - 1.4357099e-003, (F) - 1.4324405e-003, (F) - 1.4292197e-003, (F) - 1.4259289e-003, + (F) - 1.4226165e-003, (F) - 1.4193442e-003, (F) - 1.4160271e-003, (F) - 1.4126989e-003, (F) - 1.4093413e-003, + (F) - 1.4059908e-003, (F) - 1.4026138e-003, (F) - 1.3992389e-003, (F) - 1.3958431e-003, (F) - 1.3924517e-003, + (F) - 1.3890107e-003, (F) - 1.3855717e-003, (F) - 1.3821294e-003, (F) - 1.3786586e-003, (F) - 1.3751927e-003, + (F) - 1.3717083e-003, (F) - 1.3682185e-003, (F) - 1.3647088e-003, (F) - 1.3611918e-003, (F) - 1.3576589e-003, + (F) - 1.3541091e-003, (F) - 1.3505509e-003, (F) - 1.3469767e-003, (F) - 1.3433966e-003, (F) - 1.3397971e-003, + (F) - 1.3362028e-003, (F) - 1.3325813e-003, (F) - 1.3289667e-003, (F) - 1.3253120e-003, (F) - 1.3216911e-003, + (F) - 1.3179943e-003, (F) - 1.3143214e-003, (F) - 1.3106774e-003, (F) - 1.3069539e-003, (F) - 1.3032464e-003, + (F) - 1.2995222e-003, (F) - 1.2958126e-003, (F) - 1.2920713e-003, (F) - 1.2883348e-003, (F) - 1.2845712e-003, + (F) - 1.2808060e-003, (F) - 1.2770072e-003, (F) - 1.2732312e-003, (F) - 1.2694420e-003, (F) - 1.2656312e-003, + (F) - 1.2618275e-003, (F) - 1.2580017e-003, (F) - 1.2541682e-003, (F) - 1.2503198e-003, (F) - 1.2464649e-003, + (F) - 1.2425990e-003, (F) - 1.2387214e-003, (F) - 1.2348445e-003, (F) - 1.2309518e-003, (F) - 1.2270598e-003, + (F) - 1.2231497e-003, (F) - 1.2192453e-003, (F) - 1.2153109e-003, (F) - 1.2113866e-003, (F) - 1.2074293e-003, + (F) - 1.2034982e-003, (F) - 1.1995059e-003, (F) - 1.1955664e-003, (F) - 1.1916120e-003, (F) - 1.1875792e-003, + (F) - 1.1836123e-003, (F) - 1.1796207e-003, (F) - 1.1756321e-003, (F) - 1.1716069e-003, (F) - 1.1675920e-003, + (F) - 1.1635549e-003, (F) - 1.1595257e-003, (F) - 1.1554824e-003, (F) - 1.1514586e-003, (F) - 1.1474060e-003, + (F) - 1.1433394e-003, (F) - 1.1392810e-003, (F) - 1.1351978e-003, (F) - 1.1311162e-003, (F) - 1.1270269e-003, + (F) - 1.1229363e-003, (F) - 1.1188392e-003, (F) - 1.1147366e-003, (F) - 1.1106354e-003, (F) - 1.1065175e-003, + (F) - 1.1024024e-003, (F) - 1.0982701e-003, (F) - 1.0941426e-003, (F) - 1.0899914e-003, (F) - 1.0858563e-003, + (F) - 1.0816965e-003, (F) - 1.0775588e-003, (F) - 1.0733797e-003, (F) - 1.0692510e-003, (F) - 1.0650738e-003, + (F) - 1.0608604e-003, (F) - 1.0567446e-003, (F) - 1.0525531e-003, (F) - 1.0483674e-003, (F) - 1.0441581e-003, + (F) - 1.0399770e-003, (F) - 1.0357772e-003, (F) - 1.0315914e-003, (F) - 1.0273888e-003, (F) - 1.0231919e-003, + (F) - 1.0189627e-003, (F) - 1.0147410e-003, (F) - 1.0105278e-003, (F) - 1.0062964e-003, (F) - 1.0020771e-003, + (F) - 9.9785357e-004, (F) - 9.9362682e-004, (F) - 9.8939684e-004, (F) - 9.8516064e-004, (F) - 9.8092565e-004, + (F) - 9.7667465e-004, (F) - 9.7243400e-004, (F) - 9.6817845e-004, (F) - 9.6393468e-004, (F) - 9.5967515e-004, + (F) - 9.5543687e-004, (F) - 9.5117535e-004, (F) - 9.4693507e-004, (F) - 9.4266414e-004, (F) - 9.3843171e-004, + (F) - 9.3414524e-004, (F) - 9.2987591e-004, (F) - 9.2568012e-004, (F) - 9.2135966e-004, (F) - 9.1709567e-004, + (F) - 9.1282776e-004, (F) - 9.0858594e-004, (F) - 9.0431520e-004, (F) - 9.0005378e-004, (F) - 8.9577366e-004, + (F) - 8.9150003e-004, (F) - 8.8721488e-004, (F) - 8.8295395e-004, (F) - 8.7869469e-004, (F) - 8.7442056e-004, + (F) - 8.7016289e-004, (F) - 8.6589382e-004, (F) - 8.6162249e-004, (F) - 8.5735118e-004, (F) - 8.5307776e-004, + (F) - 8.4880893e-004, (F) - 8.4453368e-004, (F) - 8.4027518e-004, (F) - 8.3600580e-004, (F) - 8.3175195e-004, + (F) - 8.2748711e-004, (F) - 8.2323951e-004, (F) - 8.1897072e-004, (F) - 8.1472245e-004, (F) - 8.1045333e-004, + (F) - 8.0621272e-004, (F) - 8.0193496e-004, (F) - 7.9769844e-004, (F) - 7.9348415e-004, (F) - 7.8914860e-004, + (F) - 7.8494955e-004, (F) - 7.8071490e-004, (F) - 7.7648381e-004, (F) - 7.7222020e-004, (F) - 7.6797990e-004, + (F) - 7.6373284e-004, (F) - 7.5950621e-004, (F) - 7.5527988e-004, (F) - 7.5107177e-004, (F) - 7.4684907e-004, + (F) - 7.4261917e-004, (F) - 7.3840652e-004, (F) - 7.3418147e-004, (F) - 7.2996431e-004, (F) - 7.2575613e-004, + (F) - 7.2155033e-004, (F) - 7.1735508e-004, (F) - 7.1315848e-004, (F) - 7.0897873e-004, (F) - 7.0478617e-004, + (F) - 7.0061078e-004, (F) - 6.9642391e-004, (F) - 6.9225262e-004, (F) - 6.8806653e-004, (F) - 6.8390501e-004, + (F) - 6.7972979e-004, (F) - 6.7557927e-004, (F) - 6.7140842e-004, (F) - 6.6727626e-004, (F) - 6.6313078e-004, + (F) - 6.5892065e-004, (F) - 6.5488235e-004, (F) - 6.5072148e-004, (F) - 6.4657635e-004, (F) - 6.4243332e-004, + (F) - 6.3833154e-004, (F) - 6.3422627e-004, (F) - 6.3013543e-004, (F) - 6.2603808e-004, (F) - 6.2194403e-004, + (F) - 6.1783904e-004, (F) - 6.1374540e-004, (F) - 6.0967412e-004, (F) - 6.0559430e-004, (F) - 6.0153590e-004, + (F) - 5.9748510e-004, (F) - 5.9343652e-004, (F) - 5.8939695e-004, (F) - 5.8535649e-004, (F) - 5.8132765e-004, + (F) - 5.7728920e-004, (F) - 5.7327066e-004, (F) - 5.6924539e-004, (F) - 5.6523832e-004, (F) - 5.6122794e-004, + (F) - 5.5724157e-004, (F) - 5.5324706e-004, (F) - 5.4927299e-004, (F) - 5.4529167e-004, (F) - 5.4133594e-004, + (F) - 5.3736583e-004, (F) - 5.3338602e-004, (F) - 5.2954292e-004, (F) - 5.2550534e-004, (F) - 5.2157784e-004, + (F) - 5.1767455e-004, (F) - 5.1378900e-004, (F) - 5.0988090e-004, (F) - 5.0597844e-004, (F) - 5.0207382e-004, + (F) - 4.9818084e-004, (F) - 4.9429973e-004, (F) - 4.9044254e-004, (F) - 4.8660067e-004, (F) - 4.8274958e-004, + (F) - 4.7892223e-004, (F) - 4.7509149e-004, (F) - 4.7126296e-004, (F) - 4.6744464e-004, (F) - 4.6362882e-004, + (F) - 4.5982681e-004, (F) - 4.5602551e-004, (F) - 4.5224882e-004, (F) - 4.4847023e-004, (F) - 4.4471248e-004, + (F) - 4.4095707e-004, (F) - 4.3721957e-004, (F) - 4.3347834e-004, (F) - 4.2975534e-004, (F) - 4.2603467e-004, + (F) - 4.2232986e-004, (F) - 4.1862574e-004, (F) - 4.1493297e-004, (F) - 4.1131485e-004, (F) - 4.0751295e-004, + (F) - 4.0393867e-004, (F) - 4.0031807e-004, (F) - 3.9666663e-004, (F) - 3.9300877e-004, (F) - 3.8937618e-004, + (F) - 3.8576582e-004, (F) - 3.8217419e-004, (F) - 3.7860142e-004, (F) - 3.7503555e-004, (F) - 3.7147125e-004, + (F) - 3.6789813e-004, (F) - 3.6435228e-004, (F) - 3.6079784e-004, (F) - 3.5726001e-004, (F) - 3.5373782e-004, + (F) - 3.5022620e-004, (F) - 3.4673121e-004, (F) - 3.4324533e-004, (F) - 3.3977978e-004, (F) - 3.3631386e-004, + (F) - 3.3286616e-004, (F) - 3.2942304e-004, (F) - 3.2599148e-004, (F) - 3.2256619e-004, (F) - 3.1915720e-004, + (F) - 3.1575932e-004, (F) - 3.1236984e-004, (F) - 3.0899705e-004, (F) - 3.0562944e-004, (F) - 3.0230245e-004, + (F) - 2.9885971e-004, (F) - 2.9568523e-004, (F) - 2.9231668e-004, (F) - 2.8895192e-004, (F) - 2.8565591e-004, + (F) - 2.8238998e-004, (F) - 2.7914295e-004, (F) - 2.7588913e-004, (F) - 2.7264437e-004, (F) - 2.6938916e-004, + (F) - 2.6614678e-004, (F) - 2.6291070e-004, (F) - 2.5971239e-004, (F) - 2.5650720e-004, (F) - 2.5333543e-004, + (F) - 2.5017411e-004, (F) - 2.4702508e-004, (F) - 2.4388735e-004, (F) - 2.4076019e-004, (F) - 2.3764368e-004, + (F) - 2.3453175e-004, (F) - 2.3143610e-004, (F) - 2.2835091e-004, (F) - 2.2527550e-004, (F) - 2.2221937e-004, + (F) - 2.1917324e-004, (F) - 2.1614560e-004, (F) - 2.1311883e-004, (F) - 2.1012138e-004, (F) - 2.0711506e-004, + (F) - 2.0414964e-004, (F) - 2.0112323e-004, (F) - 1.9831231e-004, (F) - 1.9520475e-004, (F) - 1.9226519e-004, + (F) - 1.8942093e-004, (F) - 1.8652433e-004, (F) - 1.8362809e-004, (F) - 1.8070933e-004, (F) - 1.7782269e-004, + (F) - 1.7493698e-004, (F) - 1.7209519e-004, (F) - 1.6926417e-004, (F) - 1.6646857e-004, (F) - 1.6365806e-004, + (F) - 1.6088469e-004, (F) - 1.5810382e-004, (F) - 1.5533702e-004, (F) - 1.5257694e-004, (F) - 1.4983227e-004, + (F) - 1.4709544e-004, (F) - 1.4437565e-004, (F) - 1.4167133e-004, (F) - 1.3898420e-004, (F) - 1.3630467e-004, + (F) - 1.3365159e-004, (F) - 1.3099695e-004, (F) - 1.2836778e-004, (F) - 1.2573245e-004, (F) - 1.2313545e-004, + (F) - 1.2051726e-004, (F) - 1.1795237e-004, (F) - 1.1534129e-004, (F) - 1.1287369e-004, (F) - 1.1012977e-004, + (F) - 1.0773097e-004, (F) - 1.0528563e-004, (F) - 1.0268888e-004, (F) - 1.0017071e-004, (F) - 9.7654715e-005, + (F) - 9.5215819e-005, (F) - 9.2768583e-005, (F) - 9.0371180e-005, (F) - 8.7951462e-005, (F) - 8.5558944e-005, + (F) - 8.3140519e-005, (F) - 8.0767477e-005, (F) - 7.8374135e-005, (F) - 7.6014789e-005, (F) - 7.3660509e-005, + (F) - 7.1334393e-005, (F) - 6.9012344e-005, (F) - 6.6719855e-005, (F) - 6.4430870e-005, (F) - 6.2164814e-005, + (F) - 5.9896191e-005, (F) - 5.7659653e-005, (F) - 5.5407648e-005, (F) - 5.3195433e-005, (F) - 5.0966866e-005, + (F) - 4.8788370e-005, (F) - 4.6576406e-005, (F) - 4.4435158e-005, (F) - 4.2238257e-005, (F) - 4.0157616e-005, + (F) - 3.7882528e-005, (F) - 3.6003270e-005, (F) - 3.3828247e-005, (F) - 3.1583770e-005, (F) - 2.9593067e-005, + (F) - 2.7557313e-005, (F) - 2.5587191e-005, (F) - 2.3549789e-005, (F) - 2.1556262e-005, (F) - 1.9516113e-005, + (F) - 1.7525599e-005, (F) - 1.5517481e-005, (F) - 1.3572472e-005, (F) - 1.1604256e-005, (F) - 9.6904874e-006, + (F) - 7.7707834e-006, (F) - 5.8828077e-006, (F) - 3.9880938e-006, (F) - 2.1249647e-006, (F) - 2.5040016e-007, + (F) 1.5949437e-006, (F) 3.4494433e-006, (F) 5.2646709e-006, (F) 7.1001852e-006, (F) 8.8806737e-006, + (F) 1.0686745e-005, (F) 1.2432060e-005, (F) 1.4217836e-005, (F) 1.5919286e-005, (F) 1.7687295e-005, + (F) 1.9336697e-005, (F) 2.1125524e-005, (F) 2.2595147e-005, (F) 2.4508556e-005, (F) 2.6196851e-005, + (F) 2.7585354e-005, (F) 2.9262279e-005, (F) 3.0858734e-005, (F) 3.2553422e-005, (F) 3.4140016e-005, + (F) 3.5770376e-005, (F) 3.7301364e-005, (F) 3.8864361e-005, (F) 4.0354202e-005, (F) 4.1892374e-005, + (F) 4.3364404e-005, (F) 4.4875639e-005, (F) 4.6344615e-005, (F) 4.7838012e-005, (F) 4.9285680e-005, + (F) 5.0758389e-005, (F) 5.2178565e-005, (F) 5.3618819e-005, (F) 5.5001511e-005, (F) 5.6415612e-005, + (F) 5.7756282e-005, (F) 5.9143854e-005, (F) 6.0452242e-005, (F) 6.1818800e-005, (F) 6.3085250e-005, + (F) 6.4441171e-005, (F) 6.5663462e-005, (F) 6.7027725e-005, (F) 6.8148646e-005, (F) 6.9687722e-005, + (F) 7.0709936e-005, (F) 7.1728435e-005, (F) 7.3269051e-005, (F) 7.4464448e-005, (F) 7.5741110e-005, + (F) 7.6835554e-005, (F) 7.8017131e-005, (F) 7.9094451e-005, (F) 8.0258949e-005, (F) 8.1353458e-005, + (F) 8.2519454e-005, (F) 8.3606584e-005, (F) 8.4750138e-005, (F) 8.5825876e-005, (F) 8.6929477e-005, + (F) 8.7969516e-005, (F) 8.9038684e-005, (F) 9.0039349e-005, (F) 9.1073535e-005, (F) 9.2042727e-005, + (F) 9.3056320e-005, (F) 9.3992439e-005, (F) 9.4993975e-005, (F) 9.5905360e-005, (F) 9.6892188e-005, + (F) 9.7773259e-005, (F) 9.8760420e-005, (F) 9.9604074e-005, (F) 1.0060085e-004, (F) 1.0137922e-004, + (F) 1.0247409e-004, (F) 1.0299308e-004, (F) 1.0396291e-004, (F) 1.0529542e-004, (F) 1.0578194e-004, + (F) 1.0661111e-004, (F) 1.0726099e-004, (F) 1.0813498e-004, (F) 1.0887415e-004, (F) 1.0975257e-004, + (F) 1.1049916e-004, (F) 1.1133137e-004, (F) 1.1203418e-004, (F) 1.1281518e-004, (F) 1.1348183e-004, + (F) 1.1420856e-004, (F) 1.1484676e-004, (F) 1.1554840e-004, (F) 1.1616264e-004, (F) 1.1685124e-004, + (F) 1.1745353e-004, (F) 1.1813439e-004, (F) 1.1871658e-004, (F) 1.1939587e-004, (F) 1.1995423e-004, + (F) 1.2062332e-004, (F) 1.2115661e-004, (F) 1.2182429e-004, (F) 1.2231406e-004, (F) 1.2298547e-004, + (F) 1.2341104e-004, (F) 1.2412368e-004, (F) 1.2434765e-004, (F) 1.2528676e-004, (F) 1.2595624e-004, + (F) 1.2561428e-004, (F) 1.2641365e-004, (F) 1.2684799e-004, (F) 1.2754364e-004, (F) 1.2795178e-004, + (F) 1.2850208e-004, (F) 1.2883966e-004, (F) 1.2929298e-004, (F) 1.2959499e-004, (F) 1.3001517e-004, + (F) 1.3031017e-004, (F) 1.3071229e-004, (F) 1.3102020e-004, (F) 1.3142101e-004, (F) 1.3172649e-004, + (F) 1.3212756e-004, (F) 1.3242329e-004, (F) 1.3281213e-004, (F) 1.3308486e-004, (F) 1.3346421e-004, + (F) 1.3370193e-004, (F) 1.3406692e-004, (F) 1.3427186e-004, (F) 1.3462320e-004, (F) 1.3477709e-004, + (F) 1.3513030e-004, (F) 1.3522156e-004, (F) 1.3560751e-004, (F) 1.3557968e-004, (F) 1.3620588e-004, + (F) 1.3597876e-004, (F) 1.3537370e-004, (F) 1.3683967e-004, (F) 1.3676131e-004, (F) 1.3707353e-004, + (F) 1.3691530e-004, (F) 1.3708216e-004, (F) 1.3698332e-004, (F) 1.3715429e-004, (F) 1.3713014e-004, + (F) 1.3732519e-004, (F) 1.3733693e-004, (F) 1.3753506e-004, (F) 1.3756412e-004, (F) 1.3774242e-004, + (F) 1.3775349e-004, (F) 1.3790990e-004, (F) 1.3788717e-004, (F) 1.3801376e-004, (F) 1.3795585e-004, + (F) 1.3806087e-004, (F) 1.3795926e-004, (F) 1.3805069e-004, (F) 1.3791032e-004, (F) 1.3798877e-004, + (F) 1.3780411e-004, (F) 1.3789559e-004, (F) 1.3765261e-004, (F) 1.3778116e-004, (F) 1.3743527e-004, + (F) 1.3768980e-004, (F) 1.3692105e-004, (F) 1.3697478e-004, (F) 1.3896829e-004, (F) 1.3696791e-004, + (F) 1.3690649e-004, (F) 1.3635685e-004, (F) 1.3647364e-004, (F) 1.3622245e-004, (F) 1.3635135e-004, + (F) 1.3616781e-004, (F) 1.3623973e-004, (F) 1.3603623e-004, (F) 1.3604220e-004, (F) 1.3580183e-004, + (F) 1.3573672e-004, (F) 1.3545658e-004, (F) 1.3534817e-004, (F) 1.3502831e-004, (F) 1.3489334e-004, + (F) 1.3454719e-004, (F) 1.3439884e-004, (F) 1.3402423e-004, (F) 1.3388084e-004, (F) 1.3347954e-004, + (F) 1.3334594e-004, (F) 1.3292077e-004, (F) 1.3281968e-004, (F) 1.3234605e-004, (F) 1.3230559e-004, + (F) 1.3174954e-004, (F) 1.3185337e-004, (F) 1.3108290e-004, (F) 1.3188746e-004, (F) 1.3285917e-004, + (F) 1.2692712e-004, (F) 1.2939196e-004, (F) 1.2918213e-004, (F) 1.2984364e-004, (F) 1.2941200e-004, + (F) 1.2957883e-004, (F) 1.2901611e-004, (F) 1.2895095e-004, (F) 1.2832364e-004, (F) 1.2815380e-004, + (F) 1.2749849e-004, (F) 1.2727834e-004, (F) 1.2662486e-004, (F) 1.2639667e-004, (F) 1.2574208e-004, + (F) 1.2553014e-004, (F) 1.2487613e-004, (F) 1.2468629e-004, (F) 1.2402521e-004, (F) 1.2387359e-004, + (F) 1.2319054e-004, (F) 1.2308341e-004, (F) 1.2236911e-004, (F) 1.2231705e-004, (F) 1.2152965e-004, + (F) 1.2156945e-004, (F) 1.2064739e-004, (F) 1.2084617e-004, (F) 1.1960227e-004, (F) 1.2019571e-004, + (F) 1.1739216e-004, (F) 1.0603987e-004, (F) 1.2681189e-004, (F) 1.2211069e-004, (F) 1.2160186e-004, + (F) 1.1938009e-004, (F) 1.1881924e-004, (F) 1.1723162e-004, (F) 1.1671837e-004, (F) 1.1546739e-004, + (F) 1.1501372e-004, (F) 1.1396913e-004, (F) 1.1356565e-004, (F) 1.1266869e-004, (F) 1.1229782e-004, + (F) 1.1149459e-004, (F) 1.1115190e-004, (F) 1.1040957e-004, (F) 1.1007974e-004, (F) 1.0938090e-004, + (F) 1.0905795e-004, (F) 1.0837965e-004, (F) 1.0805611e-004, (F) 1.0739106e-004, (F) 1.0705021e-004, + (F) 1.0638882e-004, (F) 1.0603588e-004, (F) 1.0536773e-004, (F) 1.0499377e-004, (F) 1.0431790e-004, + (F) 1.0392614e-004, (F) 1.0323477e-004, (F) 1.0282141e-004, (F) 9.2170161e-003 + }; + *lenh0 = HP50_48K_LEN; /* store 'number of coefficients' */ + *h0 = hp50_48khz_coeff; /* store pointer to []-array */ +} + +#undef HP50_48K_LEN +/* ...................... End of fill_bp14k_32khz() ..................... */ + + +/* + ============================================================================ + + SCD_FIR hp50_32khz_init (void); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Description: + ~~~~~~~~~~~~ + + Initialization routine for a band-pass filter which limits the + bandwidth of the input signal from 50 Hz to 14000 Hz (3 dB points). + No rate change is implemented. + + Parameters: none. + ~~~~~~~~~~~ + + Return value: + ~~~~~~~~~~~~~ + Returns a pointer to struct SCD_FIR; + + History: + ~~~~~~~~ + 05.April.2012 v1.0 - Added filters: HP50_32KHZ, HP50_48KHZ (France Telecom) + + ============================================================================ +*/ +SCD_FIR *hp50_48khz_init () { + float *h0; /* pointer to array with FIR coeff. */ + long lenh0; /* number of FIR coefficients */ + + + /* allocate array for FIR coeff. and fill with coefficients */ + fill_hp50_48khz (&h0, &lenh0); + + return fir_initialization ( /* Returns: pointer to SCD_FIR-struct */ + lenh0, /* In: number of FIR-coefficients */ + h0, /* In: pointer to array with FIR-cof. */ + 1.0, /* In: gain factor for FIR-coeffic. */ + 1l, /* In: Down-sampling factor */ + 'D' /* In: switch to down-sampling proc. */ + ); /* (works here as simple FIR-fil. */ +} + +/* .................... End of hp50_32khz_init() .................... */ diff --git a/src/fir/firdemo.c b/src/fir/firdemo.c index af6e4303..3cc98806 100644 --- a/src/fir/firdemo.c +++ b/src/fir/firdemo.c @@ -207,6 +207,7 @@ #include "ugstdemo.h" /* private defines for user interface */ #include "ugst-utl.h" /* conversion from float -> short */ #include "firflt.h" /* definitions for high quality filter */ +#include "wav_io.h" /* WAV file I/O support */ /* Specific Includes */ @@ -332,8 +333,7 @@ int main (int argc, char *argv[]) { /* ......... File related variables ......... */ char inpfil[MAX_STRLEN], outfil[MAX_STRLEN]; - FILE *inpfilptr, *outfilptr; - int inp, out; + AUDIO_FILE *inpfilptr, *outfilptr; #if defined(VMS) char mrs[15]; #endif @@ -416,14 +416,12 @@ int main (int argc, char *argv[]) { #endif GET_PAR_S (1, "_BIN-File to be filtered: ................ ", inpfil); - if ((inpfilptr = fopen (inpfil, RB)) == NULL) + if ((inpfilptr = audio_open_read (inpfil, 0, 0, 16)) == NULL) error_terminate ("Error opening input file\n", 1); - inp = fileno (inpfilptr); GET_PAR_S (2, "_BIN-Output File: ........................ ", outfil); - if ((outfilptr = fopen (outfil, WB)) == NULL) + if ((outfilptr = audio_open_write (outfil, audio_get_sample_rate (inpfilptr), 1, 16)) == NULL) error_terminate ("Error opening output file\n", 1); - out = fileno (outfilptr); GET_PAR_L (3, "_IRS Filter (0, 8, 16, 48): ........ ", irs); if ((irs != 0) && (irs != 8) && (irs != 16) && (irs != 48)) @@ -432,19 +430,19 @@ int main (int argc, char *argv[]) { GET_PAR_L (4, "_Delta-SM filtering (0:skip, 1:apply): ... ", delta_sm); GET_PAR_L (5, "_First Up-Sampling (0, 2, -2, 3): ..... ", up_1); - if ((up_1 != 0) && (up_1 != 2) && (up_1 != -2) && (up_1 != 3)) + if ((up_1 != 0) && (up_1 != 2) && (up_1 != -2) && (up_1 != 3) && (up_1 != 4) && (up_1 != 6)) error_terminate ("wrong upsampling factor\n", 1); GET_PAR_L (6, "_Second Up-Sampling (0, 2, -2, 3): .... ", up_2); - if ((up_2 != 0) && (up_2 != 2) && (up_2 != -2) && (up_2 != 3)) + if ((up_2 != 0) && (up_2 != 2) && (up_2 != -2) && (up_2 != 3) && (up_2 != 4) && (up_2 != 6)) error_terminate ("wrong upsampling factor\n", 1); GET_PAR_L (7, "_First Down-Sampling (0, 2, -2, 3): .... ", down_1); - if ((down_1 != 0) && (down_1 != 2) && (down_1 != -2) && (down_1 != 3)) + if ((down_1 != 0) && (down_1 != 2) && (down_1 != -2) && (down_1 != 3) && (down_1 != 4) && (down_1 != 6)) error_terminate ("wrong downsampling factor\n", 1); GET_PAR_L (8, "_Second Down-Sampling (0, 2, -2, 3): .... ", down_2); - if ((down_2 != 0) && (down_2 != 2) && (down_2 != -2) && (down_2 != 3)) + if ((down_2 != 0) && (down_2 != 2) && (down_2 != -2) && (down_2 != 3) && (down_2 != 4) && (down_2 != 6)) error_terminate ("wrong downsampling factor\n", 1); FIND_PAR_L (9, "_Segment Length for Filtering: ........... ", lseg, lseg); @@ -457,13 +455,13 @@ int main (int argc, char *argv[]) { /* * ... Allocate memory ... */ - sh_buff = (short *) calloc (9l * lseg, sizeof (short)); + sh_buff = (short *) calloc (36l * lseg, sizeof (short)); fl_buff = (float *) calloc (lseg, sizeof (float)); irs_buff = (float *) calloc (lseg, sizeof (float)); - up1_buff = (float *) calloc (3l * lseg, sizeof (float)); - up2_buff = (float *) calloc (9l * lseg, sizeof (float)); - down1_buff = (float *) calloc (9l * lseg, sizeof (float)); - down2_buff = (float *) calloc (9l * lseg, sizeof (float)); + up1_buff = (float *) calloc (6l * lseg, sizeof (float)); + up2_buff = (float *) calloc (36l * lseg, sizeof (float)); + down1_buff = (float *) calloc (36l * lseg, sizeof (float)); + down2_buff = (float *) calloc (36l * lseg, sizeof (float)); if (!(sh_buff && fl_buff && irs_buff && up1_buff && up2_buff && down1_buff && down2_buff)) error_terminate ("Error allocating memory for sample buffers\n", 3); @@ -538,6 +536,12 @@ int main (int argc, char *argv[]) { /* get pointer to a struct which contains filter coefficients and cleared state variables for a upsampling factor of 3 */ if ((up1_ptr = hq_up_1_to_3_init ()) == 0) error_terminate ("hq_up_1_to_3 initialization failure!\n", 1); + } else if (up_1 == 4) { + if ((up1_ptr = p863_up_1_to_4_init ()) == 0) + error_terminate ("p863_up_1_to_4 initialization failure!\n", 1); + } else if (up_1 == 6) { + if ((up1_ptr = p863_up_1_to_6_init ()) == 0) + error_terminate ("p863_up_1_to_6 initialization failure!\n", 1); } else up1_ptr = NULL; @@ -555,6 +559,12 @@ int main (int argc, char *argv[]) { /* get pointer to a struct which contains filter coefficients and cleared state variables for a upsampling factor of 3 */ if ((up2_ptr = hq_up_1_to_3_init ()) == 0) error_terminate ("hq_up_1_to_3 initialization failure!\n", 1); + } else if (up_2 == 4) { + if ((up2_ptr = p863_up_1_to_4_init ()) == 0) + error_terminate ("p863_up_1_to_4 initialization failure!\n", 1); + } else if (up_2 == 6) { + if ((up2_ptr = p863_up_1_to_6_init ()) == 0) + error_terminate ("p863_up_1_to_6 initialization failure!\n", 1); } else up2_ptr = NULL; @@ -572,6 +582,12 @@ int main (int argc, char *argv[]) { /* get pointer to a struct which contains filter coefficients and cleared state variables for a downsampling factor of 3 */ if ((down1_ptr = hq_down_3_to_1_init ()) == 0) error_terminate ("hq_down_3_to_1 initialization failure!\n", 1); + } else if (down_1 == 4) { + if ((down1_ptr = p863_down_4_to_1_init ()) == 0) + error_terminate ("p863_down_4_to_1 initialization failure!\n", 1); + } else if (down_1 == 6) { + if ((down1_ptr = p863_down_6_to_1_init ()) == 0) + error_terminate ("p863_down_6_to_1 initialization failure!\n", 1); } else down1_ptr = NULL; @@ -589,6 +605,12 @@ int main (int argc, char *argv[]) { /* get pointer to a struct which contains filter coefficients and cleared state variables for a downsampling factor of 3 */ if ((down2_ptr = hq_down_3_to_1_init ()) == 0) error_terminate ("hq_down_3_to_1 initialization failure!\n", 1); + } else if (down_2 == 4) { + if ((down2_ptr = p863_down_4_to_1_init ()) == 0) + error_terminate ("p863_down_4_to_1 initialization failure!\n", 1); + } else if (down_2 == 6) { + if ((down2_ptr = p863_down_6_to_1_init ()) == 0) + error_terminate ("p863_down_6_to_1 initialization failure!\n", 1); } else down2_ptr = NULL; @@ -613,7 +635,7 @@ int main (int argc, char *argv[]) { lsegx = lseg; while (lsegx == lseg) { /* Read data from file in a short array ... */ - lsegx = fread (sh_buff, sizeof (short), lseg, inpfilptr); + lsegx = audio_read (inpfilptr, sh_buff, lseg); /* ... and convert short to float, normalizing */ sh2fl_16bit (lsegx, sh_buff, fl_buff, 1); @@ -744,7 +766,7 @@ int main (int argc, char *argv[]) { /* * ......... WRITE SAMPLES TO OUTPUT FILE ......... */ - nsam += fwrite (sh_buff, sizeof (short), lsegdown2, outfilptr); + nsam += audio_write (outfilptr, sh_buff, lsegdown2); } @@ -790,8 +812,8 @@ int main (int argc, char *argv[]) { free (sh_buff); /* Close files */ - fclose (outfilptr); - fclose (inpfilptr); + audio_close (outfilptr); + audio_close (inpfilptr); #ifndef VMS return (0); diff --git a/src/fir/firflt.h b/src/fir/firflt.h index 93752bfb..50495a2e 100644 --- a/src/fir/firflt.h +++ b/src/fir/firflt.h @@ -87,6 +87,20 @@ SCD_FIR *LP20_48kHz_init ARGS ((void)); // FILTER_12k48k_HW SCD_FIR *LP12_48kHz_init ARGS ((void)); // FILTER_12k48k_HW +SCD_FIR *shq_up_1_to_2_init ARGS ((void)); +SCD_FIR *shq_up_1_to_3_init ARGS ((void)); +SCD_FIR *shq_down_2_to_1_init ARGS ((void)); +SCD_FIR *shq_down_3_to_1_init ARGS ((void)); +SCD_FIR *hp50_32khz_init ARGS ((void)); +SCD_FIR *hp50_48khz_init ARGS ((void)); +SCD_FIR *p863_up_1_to_2_init ARGS ((void)); +SCD_FIR *p863_down_2_to_1_init ARGS ((void)); +SCD_FIR *p863_up_1_to_3_init ARGS ((void)); +SCD_FIR *p863_down_3_to_1_init ARGS ((void)); +SCD_FIR *p863_up_1_to_4_init ARGS ((void)); +SCD_FIR *p863_down_4_to_1_init ARGS ((void)); +SCD_FIR *p863_up_1_to_6_init ARGS ((void)); +SCD_FIR *p863_down_6_to_1_init ARGS ((void)); void hq_free ARGS ((SCD_FIR * fir_ptr)); void hq_reset ARGS ((SCD_FIR * fir_ptr)); diff --git a/src/fir/test_data/p863_48k_in.raw b/src/fir/test_data/p863_48k_in.raw new file mode 100644 index 00000000..9b2c4910 Binary files /dev/null and b/src/fir/test_data/p863_48k_in.raw differ diff --git a/src/fir/test_data/p863_48k_in.wav b/src/fir/test_data/p863_48k_in.wav new file mode 100644 index 00000000..a9f3113d Binary files /dev/null and b/src/fir/test_data/p863_48k_in.wav differ diff --git a/src/fir/test_data/p863_48k_to_16k.raw b/src/fir/test_data/p863_48k_to_16k.raw new file mode 100644 index 00000000..506474f7 Binary files /dev/null and b/src/fir/test_data/p863_48k_to_16k.raw differ diff --git a/src/fir/test_data/p863_48k_to_16k.wav b/src/fir/test_data/p863_48k_to_16k.wav new file mode 100644 index 00000000..e43b5e8c Binary files /dev/null and b/src/fir/test_data/p863_48k_to_16k.wav differ diff --git a/src/fir/test_data/p863_48k_to_8k.raw b/src/fir/test_data/p863_48k_to_8k.raw new file mode 100644 index 00000000..68496c13 Binary files /dev/null and b/src/fir/test_data/p863_48k_to_8k.raw differ diff --git a/src/fir/test_data/p863_48k_to_8k.wav b/src/fir/test_data/p863_48k_to_8k.wav new file mode 100644 index 00000000..ec297549 Binary files /dev/null and b/src/fir/test_data/p863_48k_to_8k.wav differ diff --git a/src/fir/test_data/p863_8k_in.raw b/src/fir/test_data/p863_8k_in.raw new file mode 100644 index 00000000..3959540e Binary files /dev/null and b/src/fir/test_data/p863_8k_in.raw differ diff --git a/src/fir/test_data/p863_8k_in.wav b/src/fir/test_data/p863_8k_in.wav new file mode 100644 index 00000000..83f28ee0 Binary files /dev/null and b/src/fir/test_data/p863_8k_in.wav differ diff --git a/src/fir/test_data/p863_8k_to_16k.raw b/src/fir/test_data/p863_8k_to_16k.raw new file mode 100644 index 00000000..96897ebc Binary files /dev/null and b/src/fir/test_data/p863_8k_to_16k.raw differ diff --git a/src/fir/test_data/p863_8k_to_16k.wav b/src/fir/test_data/p863_8k_to_16k.wav new file mode 100644 index 00000000..9b71e02b Binary files /dev/null and b/src/fir/test_data/p863_8k_to_16k.wav differ diff --git a/src/fir/test_data/p863_8k_to_48k.raw b/src/fir/test_data/p863_8k_to_48k.raw new file mode 100644 index 00000000..7e485c11 Binary files /dev/null and b/src/fir/test_data/p863_8k_to_48k.raw differ diff --git a/src/fir/test_data/p863_8k_to_48k.wav b/src/fir/test_data/p863_8k_to_48k.wav new file mode 100644 index 00000000..e13a80f1 Binary files /dev/null and b/src/fir/test_data/p863_8k_to_48k.wav differ diff --git a/src/fir/test_data/test-hp50-32khz.ref b/src/fir/test_data/test-hp50-32khz.ref new file mode 100644 index 00000000..7332c523 Binary files /dev/null and b/src/fir/test_data/test-hp50-32khz.ref differ diff --git a/src/fir/test_data/test-hp50-48khz.ref b/src/fir/test_data/test-hp50-48khz.ref new file mode 100644 index 00000000..e9f78d91 Binary files /dev/null and b/src/fir/test_data/test-hp50-48khz.ref differ diff --git a/src/fir/test_data/tst-shq2.ref b/src/fir/test_data/tst-shq2.ref new file mode 100644 index 00000000..a78451c9 Binary files /dev/null and b/src/fir/test_data/tst-shq2.ref differ diff --git a/src/fir/test_data/tst-shq3.ref b/src/fir/test_data/tst-shq3.ref new file mode 100644 index 00000000..eea0bfda Binary files /dev/null and b/src/fir/test_data/tst-shq3.ref differ diff --git a/src/freqresp/CMakeLists.txt b/src/freqresp/CMakeLists.txt index b4ad7bcf..418ffb7f 100644 --- a/src/freqresp/CMakeLists.txt +++ b/src/freqresp/CMakeLists.txt @@ -1,11 +1,17 @@ include_directories(../utl) -add_executable(freqresp freqresp.c bmp_utils.c export.c fft.c) +add_executable(freqresp freqresp.c bmp_utils.c export.c fft.c ../utl/wav_io.c) target_link_libraries(freqresp ${M_LIBRARY}) add_test(freqresp ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/freqresp -bmp test_data/bmpOut.tst test_data/input.src test_data/input.src test_data/asciiOut.tst) add_test(freqresp-verify1 ${CMAKE_COMMAND} -E compare_files test_data/bmpOut.ref test_data/bmpOut.tst) -add_test(freqresp-verify2 ${CMAKE_COMMAND} -E compare_files test_data/asciiOut.ref test_data/asciiOut.tst) +add_test(NAME freqresp-verify2 + COMMAND ${CMAKE_COMMAND} + -DGOT=${CMAKE_CURRENT_SOURCE_DIR}/test_data/asciiOut.tst + -DEXPECTED=${CMAKE_CURRENT_SOURCE_DIR}/test_data/asciiOut.ref + -DLABEL=freqresp_asciiOut + -P ${CMAKE_CURRENT_SOURCE_DIR}/compare_freqresp_text.cmake +) diff --git a/src/freqresp/compare_freqresp_text.cmake b/src/freqresp/compare_freqresp_text.cmake new file mode 100644 index 00000000..55213f7b --- /dev/null +++ b/src/freqresp/compare_freqresp_text.cmake @@ -0,0 +1,4 @@ +# Compare freqresp text output against reference, tolerating CRLF. +# Invoked via: cmake -DGOT=... -DEXPECTED=... -DLABEL=... -P compare_freqresp_text.cmake +include(${CMAKE_CURRENT_LIST_DIR}/../../cmake/CompareTextFiles.cmake) +compare_text_files(GOT "${GOT}" EXPECTED "${EXPECTED}" LABEL "${LABEL}") diff --git a/src/freqresp/freqresp.c b/src/freqresp/freqresp.c index 60e46cbd..6b294f3b 100644 --- a/src/freqresp/freqresp.c +++ b/src/freqresp/freqresp.c @@ -49,6 +49,7 @@ #include "fft.h" #include "export.h" #include "bmp_utils.h" +#include "wav_io.h" /* UGST modules */ #include "ugstdemo.h" @@ -114,7 +115,7 @@ int main (int argc, char *argv[]) { float avg2PowSp[NFFT_MAX / 2]; /* Average Power spectrum vector for the second input file */ /* file variables */ - FILE *fp; /* file pointer */ + AUDIO_FILE *fp; /* file pointer */ char in1FileName[MAX_STRLEN]; /* name of the first input file (input of the codec) */ char in2FileName[MAX_STRLEN]; /* name of the second input file (output of the codec) */ char asciiFileName[MAX_STRLEN]; /* name of the output ASCII file */ @@ -124,6 +125,7 @@ int main (int argc, char *argv[]) { /* algorithm variables */ int nfft = 2048; long fs = 16000; /* sampling frequency */ + int fs_given = 0; int little_endian; /* flag =1 if little-endian, else =0 */ int i, j; int nbread; @@ -153,6 +155,7 @@ int main (int argc, char *argv[]) { if (strcmp (argv[1], "-fs") == 0) { /* Set the sampling frequency parameter */ fs = atol (argv[2]); + fs_given = 1; /* Move arg{c,v} over the option to the next argument */ argc -= 2; @@ -279,14 +282,16 @@ int main (int argc, char *argv[]) { /* ..... First File ..... */ /* open first input file */ - fp = fopen (in1FileName, "rb"); + fp = audio_open_read (in1FileName, fs_given ? fs : 0, 0, 16); if (fp == NULL) { fprintf (stderr, "Error: Can't open input file %s", in1FileName); exit (-1); } + if (audio_get_sample_rate (fp) > 0) + fs = audio_get_sample_rate (fp); /* loop over first input file */ - while ((nbread = fread (frame_sh, sizeof (short), nfft, fp)) == nfft) { + while ((nbread = audio_read (fp, frame_sh, nfft)) == nfft) { /* increment the number of processed frames */ nbFrame++; @@ -313,16 +318,16 @@ int main (int argc, char *argv[]) { } /* For overlapping, reposition the file pointer nb_samples_ov samples before its current position */ - fseek (fp, -nb_samples_ov * 2, SEEK_CUR); + fseek (fp->fp, -nb_samples_ov * 2, SEEK_CUR); } /* close input file */ - fclose (fp); + audio_close (fp); /* ..... Second File ..... */ /* open second input file */ - fp = fopen (in2FileName, "rb"); + fp = audio_open_read (in2FileName, fs_given ? fs : 0, 0, 16); if (fp == NULL) { fprintf (stderr, "Error: Can't open input file %s", in2FileName); exit (-1); @@ -330,7 +335,7 @@ int main (int argc, char *argv[]) { nbFrame = 0; /* loop over first input file */ - while ((nbread = fread (frame_sh, sizeof (short), nfft, fp)) == nfft) { + while ((nbread = audio_read (fp, frame_sh, nfft)) == nfft) { /* increment the number of processed frames */ nbFrame++; @@ -356,10 +361,10 @@ int main (int argc, char *argv[]) { } /* For overlapping, reposition the file pointer nb_samples_ov samples before its current position */ - fseek (fp, -nb_samples_ov * 2, SEEK_CUR); + fseek (fp->fp, -nb_samples_ov * 2, SEEK_CUR); } /* close input file */ - fclose (fp); + audio_close (fp); /* .... Save Average Power Spectrum .... */ diff --git a/src/g711/CMakeLists.txt b/src/g711/CMakeLists.txt index ebb229eb..c9d53d2b 100644 --- a/src/g711/CMakeLists.txt +++ b/src/g711/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(../utl) -add_executable(g711demo g711demo.c g711.c) +add_executable(g711demo g711demo.c g711.c ../utl/wav_io.c) target_link_libraries(g711demo ${M_LIBRARY}) add_executable(shiftbit shiftbit.c) diff --git a/src/g711/g711demo.c b/src/g711/g711demo.c index f61731d4..471574ea 100644 --- a/src/g711/g711demo.c +++ b/src/g711/g711demo.c @@ -166,6 +166,7 @@ /* G711 module functions */ #include "g711.h" +#include "wav_io.h" /* @@ -231,8 +232,7 @@ int main (int argc, char *argv[]) { short *log_buff; /* compressed data */ short *lon_buff; /* quantized output samples */ char inpfil[MAX_STRLEN], outfil[MAX_STRLEN]; - FILE *Fi, *Fo; - int inp, out; + AUDIO_FILE *Fi, *Fo; char law[MAX_STRLEN], lilo[MAX_STRLEN]; short inp_type, out_type; char revert_even_bits = 1; @@ -327,28 +327,24 @@ int main (int argc, char *argv[]) { #endif /* Open input file */ - if ((Fi = fopen (inpfil, RB)) == NULL) + if ((Fi = audio_open_read (inpfil, 8000, 0, 16)) == NULL) KILL (inpfil, 2); - inp = fileno (Fi); /* Open (create) output file */ - if ((Fo = fopen (outfil, WB)) == NULL) + if ((Fo = audio_open_write (outfil, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (outfil, 3); - out = fileno (Fo); /* Define starting byte in file */ start_byte = (N1 * N + skip) * sizeof (short); /* ... and move file's pointer to 1st desired block */ - if (fseek (Fi, (N1 * N + skip) * sizeof (short), 0) < 0l) + if (audio_seek (Fi, (N1 * N + skip) * sizeof (short)) < 0) KILL (inpfil, 4); /* Check whether is to process til end-of-file */ if (N2 == 0) { - struct stat st; /* ... hey, need to skip the delayed samples! ... */ - stat (inpfil, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); + N2 = ceil ((audio_get_data_size (Fi) - start_byte) / (double) (N * sizeof (short))); } @@ -365,38 +361,38 @@ int main (int argc, char *argv[]) { /* Input: LINEAR | Output: LOG */ if (inp_type == IS_LIN && out_type == IS_LOG) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { - if ((smpno = fread (lin_buff, sizeof (short), N, Fi)) < 0) + if ((smpno = audio_read (Fi, lin_buff, N)) < 0) KILL (inpfil, 5); alaw_compress (smpno, lin_buff, log_buff); if (!revert_even_bits) for (i = 0; i < smpno; i++) log_buff[i] ^= 0x0055; - if ((smpno = fwrite (log_buff, sizeof (short), smpno, Fo)) < 0) + if ((smpno = audio_write (Fo, log_buff, smpno)) < 0) KILL (outfil, 6); } /* Input: LINEAR | Output: LINEAR */ else if (inp_type == IS_LIN && out_type == IS_LIN) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { - if ((smpno = fread (lin_buff, sizeof (short), N, Fi)) < 0) + if ((smpno = audio_read (Fi, lin_buff, N)) < 0) KILL (inpfil, 5); alaw_compress (smpno, lin_buff, log_buff); alaw_expand (smpno, log_buff, lon_buff); - if ((smpno = fwrite (lon_buff, sizeof (short), smpno, Fo)) < 0) + if ((smpno = audio_write (Fo, lon_buff, smpno)) < 0) KILL (outfil, 6); } /* Input: LOG | Output: LINEAR */ else if (inp_type == IS_LOG) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { - if ((smpno = fread (log_buff, sizeof (short), N, Fi)) < 0) + if ((smpno = audio_read (Fi, log_buff, N)) < 0) KILL (inpfil, 5); if (!revert_even_bits) for (i = 0; i < smpno; i++) log_buff[i] ^= 0x0055; alaw_expand (smpno, log_buff, lon_buff); - if ((smpno = fwrite (lon_buff, sizeof (short), smpno, Fo)) < 0) + if ((smpno = audio_write (Fo, lon_buff, smpno)) < 0) KILL (outfil, 6); } break; @@ -407,26 +403,26 @@ int main (int argc, char *argv[]) { /* Input: LINEAR | Output: LOG */ if (inp_type == IS_LIN && out_type == IS_LOG) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { - smpno = fread (lin_buff, sizeof (short), N, Fi); + smpno = audio_read (Fi, lin_buff, N); ulaw_compress (smpno, lin_buff, log_buff); - smpno = fwrite (log_buff, sizeof (short), smpno, Fo); + smpno = audio_write (Fo, log_buff, smpno); } /* Input: LINEAR | Output: LINEAR */ else if (inp_type == IS_LIN && out_type == IS_LIN) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { - smpno = fread (lin_buff, sizeof (short), N, Fi); + smpno = audio_read (Fi, lin_buff, N); ulaw_compress (smpno, lin_buff, log_buff); ulaw_expand (smpno, log_buff, lon_buff); - smpno = fwrite (lon_buff, sizeof (short), smpno, Fo); + smpno = audio_write (Fo, lon_buff, smpno); } /* Input: LOG | Output: LINEAR */ else if (inp_type == IS_LOG) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { - smpno = fread (log_buff, sizeof (short), N, Fi); + smpno = audio_read (Fi, log_buff, N); ulaw_expand (smpno, log_buff, lon_buff); - smpno = fwrite (lon_buff, sizeof (short), smpno, Fo); + smpno = audio_write (Fo, lon_buff, smpno); } break; } @@ -437,8 +433,8 @@ int main (int argc, char *argv[]) { t2 = clock (); printf ("Speed: %f sec CPU-time for %ld processed samples\n", (t2 - t1) / (double) CLOCKS_PER_SEC, tot_smpno); - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); #ifndef VMS return (0); #endif diff --git a/src/g711/shiftbit.c b/src/g711/shiftbit.c index 92cb0d20..f10bbc98 100644 --- a/src/g711/shiftbit.c +++ b/src/g711/shiftbit.c @@ -97,7 +97,7 @@ int main (int argc, char *argv[]) { fprintf (stderr, "%s: Reading, ", inp); for (k = 0; k < l; k += 256) - if (fread (&buf[k],1, 512, fi) < 0) + if (fread (&buf[k],1, 512, Fi) < 0) KILL (inp, 5); fprintf (stderr, "shifting, "); diff --git a/src/g711iplc/CMakeLists.txt b/src/g711iplc/CMakeLists.txt index c8ed50fd..7f516418 100644 --- a/src/g711iplc/CMakeLists.txt +++ b/src/g711iplc/CMakeLists.txt @@ -1,7 +1,7 @@ include_directories(../eid) include_directories(../utl) -add_executable(g711iplc g711iplc.c plcferio.c g711iplc.c lowcfe.c ../eid/softbit.c) +add_executable(g711iplc g711iplc.c plcferio.c g711iplc.c lowcfe.c ../eid/softbit.c ../utl/wav_io.c) target_compile_definitions(g711iplc PUBLIC USEDOUBLES=1) target_link_libraries(g711iplc ${M_LIBRARY}) @@ -9,13 +9,13 @@ add_executable(asc2g192 asc2g192.c) target_link_libraries(asc2g192 ${M_LIBRARY}) add_test(g711iplc1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/g711iplc -stats test_data/fe10.g192 test_data/f2.le test_data/f2_10_c.raw) -add_test(g711iplc1-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/f2_10.raw test_data/f2_10_c.raw) +add_test(g711iplc1-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q -abstol 1 test_data/f2_10.raw test_data/f2_10_c.raw) add_test(g711iplc2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/g711iplc -noplc -stats test_data/fe10.g192 test_data/f2.le test_data/f2_10m_c.raw) add_test(g711iplc2-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/f2_10m.raw test_data/f2_10m_c.raw) add_test(g711iplc3 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/g711iplc -stats test_data/fe10_2.g192 test_data/f2.le test_data/f2_10_2_c.raw) -add_test(g711iplc3-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/f2_10_2.raw test_data/f2_10_2_c.raw) +add_test(g711iplc3-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q -abstol 1 test_data/f2_10_2.raw test_data/f2_10_2_c.raw) add_test(g711iplc4 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/g711iplc -noplc -stats test_data/fe10_2.g192 test_data/f2.le test_data/f2_10_2m_c.raw) add_test(g711iplc4-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/f2_10_2m.raw test_data/f2_10_2m_c.raw) diff --git a/src/g711iplc/g711iplc.c b/src/g711iplc/g711iplc.c index 30410b81..ba41adcf 100644 --- a/src/g711iplc/g711iplc.c +++ b/src/g711iplc/g711iplc.c @@ -47,6 +47,7 @@ #include #include "plcferio.h" #include "lowcfe.h" +#include "wav_io.h" char usage[] = "\ G711IPLC Version 1.0 of 24/May/2005\n\ @@ -72,8 +73,8 @@ int main (int argc, char *argv[]) { int nframes; /* processed frame count */ int nerased; /* erased frame count */ char *arg; - FILE *fi; /* input file */ - FILE *fo; /* output file */ + AUDIO_FILE *fi; /* input file */ + AUDIO_FILE *fo; /* output file */ LowcFE_c lc; /* PLC simulation data */ readplcmask mask; /* error pattern file reader */ short in[FRAMESZ]; /* i/o buffer */ @@ -98,17 +99,17 @@ int main (int argc, char *argv[]) { exit (EXIT_FAILURE); } readplcmask_open (&mask, argv[0]); /* PLC pattern file */ - if ((fi = fopen (argv[1], "rb")) == NULL) { /* input file */ + if ((fi = audio_open_read (argv[1], 8000, 0, 16)) == NULL) { /* input file */ fprintf (stderr, "Can't open input file: %s", argv[1]); exit (EXIT_FAILURE); } - if ((fo = fopen (argv[2], "wb")) == NULL) { /* output file */ + if ((fo = audio_open_write (argv[2], audio_get_sample_rate (fi), 1, 16)) == NULL) { /* output file */ fprintf (stderr, "Can't open output file: %s", argv[2]); exit (EXIT_FAILURE); } nframes = nerased = 0; g711plc_construct (&lc); - while (fread (in, sizeof (short), FRAMESZ, fi) == FRAMESZ) { + while (audio_read (fi, in, FRAMESZ) == FRAMESZ) { nframes++; if (readplcmask_erased (&mask)) { nerased++; /* frame is erased */ @@ -127,9 +128,9 @@ int main (int argc, char *argv[]) { * file is time-aligned with the input file. */ if (nframes == 1) - fwrite (&in[POVERLAPMAX], sizeof (short), FRAMESZ - POVERLAPMAX, fo); + audio_write (fo, &in[POVERLAPMAX], FRAMESZ - POVERLAPMAX); else - fwrite (in, sizeof (short), FRAMESZ, fo); + audio_write (fo, in, FRAMESZ); } /* * the following code outputs the delayed speech in the history buffer @@ -140,13 +141,13 @@ int main (int argc, char *argv[]) { for (i = 0; i < FRAMESZ; i++) in[i] = 0; g711plc_addtohistory (&lc, in); - fwrite (in, sizeof (short), POVERLAPMAX, fo); + audio_write (fo, in, POVERLAPMAX); } if (dostats && nframes) printf ("%d of %d frames concealed = %.2f%%\n", nerased, nframes, (double) nerased / nframes * 100.); /* cleanup */ - fclose (fo); - fclose (fi); + audio_close (fo); + audio_close (fi); readplcmask_close (&mask); return 0; } diff --git a/src/g722/CMakeLists.txt b/src/g722/CMakeLists.txt index 70e691ca..e89cc163 100644 --- a/src/g722/CMakeLists.txt +++ b/src/g722/CMakeLists.txt @@ -2,13 +2,13 @@ include_directories(../basop) include_directories(../eid) include_directories(../utl) -add_executable(g722demo g722demo.c funcg722.c g722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c) +add_executable(g722demo g722demo.c funcg722.c g722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c ../utl/wav_io.c) target_link_libraries(g722demo ${M_LIBRARY}) -add_executable(encg722 encg722.c funcg722.c g722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c) +add_executable(encg722 encg722.c funcg722.c g722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c ../utl/wav_io.c) target_link_libraries(encg722 ${M_LIBRARY}) -add_executable(decg722 decg722.c funcg722.c g722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c) +add_executable(decg722 decg722.c funcg722.c g722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c ../utl/wav_io.c) target_link_libraries(decg722 ${M_LIBRARY}) add_executable(tstcg722 tstcg722.c funcg722.c funcg722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c) diff --git a/src/g722/decg722.c b/src/g722/decg722.c index e2d10077..518269ec 100644 --- a/src/g722/decg722.c +++ b/src/g722/decg722.c @@ -85,6 +85,7 @@ FRANCE #include "g722.h" #include "ugstdemo.h" #include "g722_com.h" +#include "wav_io.h" #include "stl.h" @@ -221,7 +222,8 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[MAX_STR], FileOut[MAX_STR]; - FILE *F_cod, *F_out; + FILE *F_cod; + AUDIO_FILE *F_out; long iter = 0; short N = DEF_FR_SIZE, N2 = 0, smpno = 0; long i = 0; @@ -354,7 +356,7 @@ int main (int argc, char *argv[]) { KILL (FileIn, -2); } /* Open output file */ - if ((F_out = fopen (FileOut, WB)) == NULL) { + if ((F_out = audio_open_write (FileOut, 16000, 1, 16)) == NULL) { KILL (FileOut, -2); } @@ -556,7 +558,7 @@ int main (int argc, char *argv[]) { /* Update sample counter */ iter += smpno; /* Save a frame of decoded speech samples */ - if ((short) fwrite ((char *) outcode, sizeof (Word16), N, F_out) != N) { + if ((short) audio_write (F_out, outcode, N) != N) { KILL (FileOut, -4); } if (debug) { @@ -595,7 +597,7 @@ int main (int argc, char *argv[]) { iter += smpno; /* Save decoded samples */ - if ((short) fwrite ((char *) outcode, sizeof (Word16), N, F_out) != N) { + if ((short) audio_write (F_out, outcode, N) != N) { KILL (FileOut, -4); } if (debug) { @@ -609,7 +611,7 @@ int main (int argc, char *argv[]) { } /* Close input and output files */ - fclose (F_out); + audio_close (F_out); fclose (F_cod); /* Exit with success for non-vms systems */ diff --git a/src/g722/encg722.c b/src/g722/encg722.c index 44d7f2de..9580320e 100644 --- a/src/g722/encg722.c +++ b/src/g722/encg722.c @@ -84,6 +84,7 @@ FRANCE #include "g722.h" #include "ugstdemo.h" #include "g722_com.h" +#include "wav_io.h" #include "stl.h" @@ -131,7 +132,8 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[MAX_STR], FileOut[MAX_STR]; - FILE *F_inp, *F_cod; + AUDIO_FILE *F_inp; + FILE *F_cod; long iter = 0; long frames = 1; /* number of processed frames */ @@ -240,7 +242,7 @@ int main (int argc, char *argv[]) { } /* Open input file */ - if ((F_inp = fopen (FileIn, RB)) == NULL) { + if ((F_inp = audio_open_read (FileIn, 16000, 0, 16)) == NULL) { fprintf (stderr, "Could not open %s\n", FileIn); KILL (FileIn, -2); } @@ -262,7 +264,7 @@ int main (int argc, char *argv[]) { #endif /* Read one frame of samples from input file and process */ - while ((fread ((char *) incode, sizeof (short), N, F_inp)) == (size_t) N) { + while ((audio_read (F_inp, incode, N)) == (size_t) N) { #ifdef WMOPS setCounter (spe1Id); fwc (); @@ -370,7 +372,7 @@ int main (int argc, char *argv[]) { #endif /* Close input and output files */ - fclose (F_inp); + audio_close (F_inp); fclose (F_cod); /* Exit with success for non-vms systems */ diff --git a/src/g722/g722demo.c b/src/g722/g722demo.c index 678ab82a..ad1f7c4a 100644 --- a/src/g722/g722demo.c +++ b/src/g722/g722demo.c @@ -81,6 +81,7 @@ /* G.722- and UGST-specific prototypes */ #include "g722.h" #include "ugstdemo.h" +#include "wav_io.h" /* Local definitions */ #define DFT_BLK 1024 @@ -161,7 +162,7 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[80], FileOut[80]; - FILE *inp, *out; + AUDIO_FILE *inp, *out; int read1; long iter = 0; long N = DFT_BLK, N1 = 1, N2 = 0, smpno = 0; @@ -252,11 +253,8 @@ int main (int argc, char *argv[]) { /* Check if is to process the whole file */ if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = (long) ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); + /* N2 will be computed after opening file */ + N2 = 0; } /* Protect mode, if misgiven */ @@ -264,11 +262,15 @@ int main (int argc, char *argv[]) { error_terminate ("Bad mode specified; aborting\n", 2); /* Open input file */ - if ((inp = fopen (FileIn, RB)) == NULL) + if ((inp = audio_open_read (FileIn, 16000, 0, 16)) == NULL) KILL (FileIn, -2); + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = (long) ceil ((audio_get_data_size (inp) - start_byte) / (double) (N * sizeof (short))); + /* Open output file */ - if ((out = fopen (FileOut, WB)) == NULL) + if ((out = audio_open_write (FileOut, audio_get_sample_rate (inp), 1, 16)) == NULL) KILL (FileOut, -2); #ifndef STATIC_ALLOCATION @@ -327,7 +329,7 @@ int main (int argc, char *argv[]) { N /= 2; /* *** Read samples from input file and decode *** NOTE: Number of output samples: - if encoder + decoder, #inp samples = #out samples - if encoder only, #out samples = half of # of input samples - if decoder only, #out samples = double the # of input bitstream samples *** */ - while ((read1 = fread (incode, sizeof (short), N, inp)) != 0) { + while ((read1 = audio_read (inp, incode, N)) != 0) { /* print progress flag */ if (!quiet) fprintf (stderr, "%c\r", funny[(iter / read1) % 8]); @@ -360,7 +362,7 @@ int main (int argc, char *argv[]) { iter += smpno; /* Save bitstream or decoded samples */ - if (fwrite (out_buf, sizeof (Word16), read1, out) != (size_t) read1) + if (audio_write (out, out_buf, read1) != (size_t) read1) KILL (FileOut, -4); } @@ -382,8 +384,8 @@ int main (int argc, char *argv[]) { #endif /* Close input and output files */ - fclose (out); - fclose (inp); + audio_close (out); + audio_close (inp); /* Exit with success for non-vms systems */ #ifndef VMS diff --git a/src/g726/CMakeLists.txt b/src/g726/CMakeLists.txt index fe3cf65c..cb7885d8 100644 --- a/src/g726/CMakeLists.txt +++ b/src/g726/CMakeLists.txt @@ -3,10 +3,10 @@ include_directories(../eid) include_directories(../g711) include_directories(../utl) -add_executable(vbr-g726 vbr-g726.c g726.c ../g711/g711.c) +add_executable(vbr-g726 vbr-g726.c g726.c ../g711/g711.c ../utl/wav_io.c) target_link_libraries(vbr-g726 ${M_LIBRARY}) -add_executable(g726demo g726demo.c g726.c) +add_executable(g726demo g726demo.c g726.c ../utl/wav_io.c) target_link_libraries(g726demo ${M_LIBRARY}) #Verification: g726demo @@ -72,13 +72,13 @@ target_link_libraries(g726demo ${M_LIBRARY}) #Verification: vbr-g726 add_test(g726-vbr1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vbr-g726 -q -law A -rate 16-24-32-40-32-24 test_data/voice.src test_data/voicvbra.tst) -add_test(g726-vbr1-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/voicvbra.tst test_data/voicevbr.arf) +add_test(g726-vbr1-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/voicvbra.tst test_data/voicevbr.arf) add_test(g726-vbr2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vbr-g726 -q -law l -rate 16-24-32-40-32-24 test_data/voice.src test_data/voicvbrl.tst) add_test(g726-vbr2-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/voicvbrl.tst test_data/voicevbr.lrf) add_test(g726-vbr3 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vbr-g726 -q -law u -rate 16-24-32-40-32-24 test_data/voice.src test_data/voicvbru.tst) -add_test(g726-vbr3-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/voicvbru.tst test_data/voicevbr.urf) +add_test(g726-vbr3-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/voicvbru.tst test_data/voicevbr.urf) add_test(g726-vbr5 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vbr-g726 -q -law a -enc -rate 16 test_data/nrm.a test_data/nrm.a16 16 1 1024) add_test(g726-vbr5-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/rn16fa.i test_data/nrm.a16 256 1 64) diff --git a/src/g726/g726demo.c b/src/g726/g726demo.c index cdf1dd3f..1fe7a960 100644 --- a/src/g726/g726demo.c +++ b/src/g726/g726demo.c @@ -120,6 +120,7 @@ /* ..... G.726 module as include functions ..... */ #include "g726.h" +#include "wav_io.h" /* ------------------------------------------------------------------------- @@ -212,8 +213,7 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN], law[4], lilo[8]; - FILE *Fi, *Fo; - int inp, out; + AUDIO_FILE *Fi, *Fo; long start_byte; #ifdef VMS char mrs[15]; @@ -266,14 +266,7 @@ int main (int argc, char *argv[]) { /* Find starting byte in file */ start_byte = sizeof (short) * (long) (--N1) * (long) N; - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); - } + /* N2 will be computed after opening file if processing the whole file */ /* Classification of the conversion desired */ inp_type = toupper ((int) lilo[1]) == 'O' ? IS_LOG : IS_ADPCM; @@ -318,20 +311,22 @@ int main (int argc, char *argv[]) { */ /* Opening input file; abort if there's any problem */ - if ((Fi = fopen (FileIn, "rb")) == NULL) + if ((Fi = audio_open_read (FileIn, 8000, 0, 16)) == NULL) KILL (FileIn, 2); - inp = fileno (Fi); + + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = ceil ((audio_get_data_size (Fi) - start_byte) / (double) (N * sizeof (short))); /* Creates output file */ #ifdef VMS sprintf (mrs, "mrs=%d", 512); #endif - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); - out = fileno (Fo); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* @@ -344,7 +339,7 @@ int main (int argc, char *argv[]) { fprintf (stderr, "%c\r", funny[cur_blk % 8]); /* Read a block of samples */ - if ((smpno = fread (inp_buf, sizeof (short), N, Fi)) < 0) + if ((smpno = audio_read (Fi, inp_buf, N)) < 0) KILL (FileIn, 5); /* Check if reset is needed */ @@ -361,7 +356,7 @@ int main (int argc, char *argv[]) { } /* Write ADPCM output word */ - if ((smpno = fwrite (out_buf, sizeof (short), smpno, Fo)) < 0) + if ((smpno = audio_write (Fo, out_buf, smpno)) < 0) KILL (FileOut, 6); } @@ -370,8 +365,8 @@ int main (int argc, char *argv[]) { */ /* Close input and output files */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); /* Exit with success for non-vms systems */ #ifndef VMS diff --git a/src/g726/vbr-g726.c b/src/g726/vbr-g726.c index c0983029..adcc3512 100644 --- a/src/g726/vbr-g726.c +++ b/src/g726/vbr-g726.c @@ -139,6 +139,7 @@ /* ..... G.726 module as include functions ..... */ #include "g726.h" #include "g711.h" +#include "wav_io.h" /* ------------------------------------------------------------------------- @@ -302,8 +303,7 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN]; - FILE *Fi, *Fo; - int inp, out; + AUDIO_FILE *Fi, *Fo; long start_byte; #ifdef VMS char mrs[15]; @@ -411,14 +411,7 @@ int main (int argc, char *argv[]) { /* Find starting byte in file */ start_byte = sizeof (short) * (long) (--N1) * (long) N; - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); - } + /* N2 will be computed after opening file if processing the whole file */ /* Define correct data I/O types */ if (encode && decode) { @@ -451,20 +444,22 @@ int main (int argc, char *argv[]) { */ /* Opening input file; abort if there's any problem */ - if ((Fi = fopen (FileIn, "rb")) == NULL) + if ((Fi = audio_open_read (FileIn, 8000, 0, 16)) == NULL) KILL (FileIn, 2); - inp = fileno (Fi); + + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = ceil ((audio_get_data_size (Fi) - start_byte) / (double) (N * sizeof (short))); /* Creates output file */ #ifdef VMS sprintf (mrs, "mrs=%d", 512); #endif - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); - out = fileno (Fo); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* @@ -486,7 +481,7 @@ int main (int argc, char *argv[]) { #endif /* Read a block of samples */ - if ((smpno = fread (inp_buf, sizeof (short), N, Fi)) < 0) + if ((smpno = audio_read (Fi, inp_buf, N)) < 0) KILL (FileIn, 5); /* Compress linear input samples */ @@ -521,7 +516,7 @@ int main (int argc, char *argv[]) { } /* Write ADPCM output word */ - if ((smpno = fwrite (out_buf, sizeof (short), smpno, Fo)) < 0) + if ((smpno = audio_write (Fo, out_buf, smpno)) < 0) KILL (FileOut, 6); } @@ -536,8 +531,8 @@ int main (int argc, char *argv[]) { free (rate); /* Close input and output files */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); /* Exit with success for non-vms systems */ #ifndef VMS diff --git a/src/g727/CMakeLists.txt b/src/g727/CMakeLists.txt index 39e5f5a1..34198750 100644 --- a/src/g727/CMakeLists.txt +++ b/src/g727/CMakeLists.txt @@ -6,7 +6,7 @@ include_directories(../utl) add_executable(discard discard.c) target_link_libraries(discard ${M_LIBRARY}) -add_executable(g727demo g727demo.c g727.c ../g711/g711.c) +add_executable(g727demo g727demo.c g727.c ../g711/g711.c ../utl/wav_io.c) target_link_libraries(g727demo ${M_LIBRARY}) add_test(g727-1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/g727demo -q -core 4 -enh 0 -enc -law A test_data/speech.a-s test_data/speech44.iad) diff --git a/src/g727/g727demo.c b/src/g727/g727demo.c index b237bdaa..a7d1947e 100644 --- a/src/g727/g727demo.c +++ b/src/g727/g727demo.c @@ -103,6 +103,7 @@ /* ..... G.727 module as include functions ..... */ #include "g727.h" #include "../g711/g711.h" +#include "wav_io.h" /* Global variables */ @@ -200,8 +201,7 @@ int main (int argc, char **argv) { /* File variables */ char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN]; - FILE *Fi, *Fo; - int inp, out; + AUDIO_FILE *Fi, *Fo; long start_byte; #ifdef VMS char mrs[15]; @@ -360,14 +360,7 @@ int main (int argc, char **argv) { /* Find starting byte in file */ start_byte = sizeof (short) * (long) (--N1) * (long) N; - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = (st.st_size - start_byte) / (N * sizeof (short)); - } + /* N2 will be computed after opening file if processing the whole file */ /* Convert law letter to number */ @@ -422,20 +415,22 @@ int main (int argc, char **argv) { */ /* Opening input file; abort if there's any problem */ - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, 8000, 0, 16)) == NULL) KILL (FileIn, 2); - inp = fileno (Fi); + + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = audio_get_data_size (Fi) / (N * sizeof (short)); /* Creates output file */ #ifdef VMS sprintf (mrs, "mrs=%d", 512); #endif - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); - out = fileno (Fo); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* @@ -457,7 +452,7 @@ int main (int argc, char **argv) { #endif /* Read a block of samples */ - if ((smpno = fread (inp_buf, sizeof (short), N, Fi)) < 0) + if ((smpno = audio_read (Fi, inp_buf, N)) < 0) KILL (FileIn, 5); /* Compress linear input samples */ @@ -489,7 +484,7 @@ int main (int argc, char **argv) { } /* Write ADPCM output word */ - if ((smpno = fwrite (out_buf, sizeof (short), smpno, Fo)) < 0) + if ((smpno = audio_write (Fo, out_buf, smpno)) < 0) KILL (FileOut, 6); } @@ -499,8 +494,8 @@ int main (int argc, char **argv) { */ /* Close input and output files */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); /* Exit with success for non-vms systems */ #ifndef VMS diff --git a/src/g728/g728fixed/g728fpdec.c b/src/g728/g728fixed/g728fpdec.c index 31f2fd5d..caa9497b 100644 --- a/src/g728/g728fixed/g728fpdec.c +++ b/src/g728/g728fixed/g728fpdec.c @@ -111,6 +111,7 @@ void g728fp_decinit (G728FpDecData * d) { d->ferased = 0; d->fecount = 0; d->ofecount = 0; + d->ogaindb = 0; d->tap = 0; g728fp_zerof (d->etpast, KPMAX); d->feframesz = 4; /* 10. msec */ @@ -137,7 +138,7 @@ void g728fp_decode (Short * speech, /* output speech */ Float *aptr; /* For attenuating a or atmp */ Float gptmp[LPCLG]; Gain gain; - Float gaindb; + Float gaindb = 0; Statelpc et; Float multfac; Float rc; diff --git a/src/gain_chk/CMakeLists.txt b/src/gain_chk/CMakeLists.txt new file mode 100644 index 00000000..2ef59d80 --- /dev/null +++ b/src/gain_chk/CMakeLists.txt @@ -0,0 +1,20 @@ +include_directories(../utl) + +add_executable(gain_chk gain_chk.c ../utl/wav_io.c) +target_link_libraries(gain_chk ${M_LIBRARY}) + +set(_gain_chk_testdir "${CMAKE_CURRENT_BINARY_DIR}/gain_chk_ctest_scratch") +file(MAKE_DIRECTORY "${_gain_chk_testdir}") + +# Reference PCM: input48c.pcm; processed: syn.{a,b,c,d}.pcm; stderr vs gain_chk_stderr_*.ref +foreach(_case self a b c d) + add_test( + NAME gain_chk_${_case} + COMMAND ${CMAKE_COMMAND} + -DGAIN_CHK=$ + -DPCM_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test_data + -DWORKDIR=${_gain_chk_testdir} + -DCASE=${_case} + -P ${CMAKE_CURRENT_SOURCE_DIR}/test_data/gain_chk_ctest.cmake + ) +endforeach() diff --git a/src/gain_chk/Gain_Chk_Release_Notes.txt b/src/gain_chk/Gain_Chk_Release_Notes.txt new file mode 100644 index 00000000..58e73855 --- /dev/null +++ b/src/gain_chk/Gain_Chk_Release_Notes.txt @@ -0,0 +1,70 @@ +/*---------------------------------------------------------------------------* + * Gain Amplification Verification tool * + * ------------------------------------ * + * * + * Version: 3.0 * + * Revision Date: October 17, 2012 * + *---------------------------------------------------------------------------*/ + + +Changes from V2.0 to V3.0 +========================= + +1) #define OUTPUT_VALUES + This activates the output of values to the screen, printed without headers. + They are printed as is (either 4 or 8 values if VAD file is used). + +2) #define THRESHOLD_CHECK + This introduces the two new switches "-a XX" "-s YY". + The switch -a specifies active signal max amplification XX in dB. + The switch -i specifies incatve (silence) signal max attenuation YY + in dB. The results from the gain gain calculation are compared against + the specified thresholds XX and YY. + + When defined, the tool returns one of the follwoing codes: + 0: Error During Processing + 1: Active Signal Amp above Threshold, Inactive Signal Att below Threshold (Both Fail) + 2: Inactive Signal Att below Threshold (Inactive Sig Fail, Active Sig Pass) + 3: Active Signal Amp above Threshold (Inactive Sig Pass, Active Sig Fail) + 4: Active Signal Amp below Threshold, Inactive Signal Att above Threshold (Both Pass) + + +Both changes simplifies a handling of results inside the gain check script. + + +Changes from V1.0 to V2.0 +========================= + +1) Better Protection of 'Division by' 0 and 'Log of 0'. + Now all this checking is done in the 'print_bands()' function. + +2) Bands can now be Specified as a Fraction of Fs/2. + +3) Energy Calculations and Printout are Seperated when using the VAD Flag File. + In the previous version, frames with VAD=0 were skipped. + In this version, the energy ratio (in % and dB) of all Bands Specified will be + calculated for Active and Inactive Frames. The results will be printed for each. + +4) Printout of the Bands Energy is now in the 'print_bands()' function. + +5) Better Checking of the Frequency Bands Validity. + The previous version had a bug that caused it to crash + with some combinations of Freq Bands. + +6) Removed the 'E_MIN' addition in the energy calculation + (for Both the Original and Processed Files). + This addition was not necessary; the check for Energy < E_MIN is now done + only once now in the 'print_bands()' function. + +7) An energy threshold has been added. + When the VAD file is used and a frame is Inactive (VAD=0) + The energy of the original is calculted to see if it is meaningful + to include the frame in the frequency energy calculation. + The threshold is set that if the energy is lower than the + energy of a sine wave of 2 in amplitude, the frame is skipped. + The amplitude of 2 means that the sine wave varies between -2 to +2 + if quantized by a 16 bits short. + +8) Total Energy (Full Spectrum) will be printed for both Active and Inactive frames. + The corresponds to the Band 0-Fs/2. + \ No newline at end of file diff --git a/src/gain_chk/README.md b/src/gain_chk/README.md new file mode 100644 index 00000000..b9ed1901 --- /dev/null +++ b/src/gain_chk/README.md @@ -0,0 +1,143 @@ +# gain_chk — gain amplification verification + +## Copyright + +This software is protected by copyright law and by international treaties. The source code, and all of its derivations, is provided by VoiceAge Corporation under the "ITU-T Software Tools' General Public License". Please, read the license file or refer to ITU-T Recommendation G.191 on "SOFTWARE TOOLS FOR SPEECH AND AUDIO CODING STANDARDS". Any use of this software is permitted provided that this notice is not removed and that neither the authors nor VoiceAge Corporation are deemed to have made any representations as to the suitability of this software for any purpose nor are held responsible for any defects of this software. THERE IS NO WARRANTY FOR THIS SOFTWARE. + +(C) 2026 copyright VoiceAge Corporation. All Rights Reserved. + +## Description + +`gain_chk` compares reference and processed 16-bit PCM streams in 20 ms frames, +performs short-time spectral analysis, and reports per-band energy ratios (dB +and percent). Optional VAD flags split statistics into active and inactive +frames. Optional threshold checks (`-a`, `-s`) return a numeric exit status for +scripting. + +## Files + +``` +gain_chk.c ........................ main program +test_data/ ........................ regression PCM and CMake driver for CTest +Gain_Chk_Release_Notes.txt ....... revision notes (VoiceAge V3.0 history) +``` + +## Build + +`gain_chk` is not built on its own: it is a target of the **top-level STL** CMake +project (see the repository root `README.md` for toolchain prerequisites). + +From the **STL repository root** (the directory that contains the top-level +`CMakeLists.txt`): + +1. **Configure** the build (example: out-of-tree build directory `build`): + + ```shell + cmake -S . -B build + ``` + + You can use another build path or generator (for example `cmake -G Ninja -S . -B build`). + +2. **Build only** the `gain_chk` executable: + + ```shell + cmake --build build --target gain_chk + ``` + +3. The binary is written to **`build/bin/gain_chk`** (the project sets + `CMAKE_RUNTIME_OUTPUT_DIRECTORY` to `${CMAKE_BINARY_DIR}/bin`). + +To build **all** STL targets, omit `--target gain_chk` and run +`cmake --build build` (or your chosen build directory). + +## Tests (CTest) + +CMake registers **five** tests in `src/gain_chk/CMakeLists.txt`: + +| CTest name | Reference (`-i`) | Processed (`-o`) | Golden stderr | +|-----------------|--------------------|--------------------|---------------------------------------| +| `gain_chk_self` | `input48c.pcm` | `input48c.pcm` | `test_data/gain_chk_stderr_self.ref` | +| `gain_chk_a` | `input48c.pcm` | `syn.a.pcm` | `test_data/gain_chk_stderr_a.ref` | +| `gain_chk_b` | `input48c.pcm` | `syn.b.pcm` | `test_data/gain_chk_stderr_b.ref` | +| `gain_chk_c` | `input48c.pcm` | `syn.c.pcm` | `test_data/gain_chk_stderr_c.ref` | +| `gain_chk_d` | `input48c.pcm` | `syn.d.pcm` | `test_data/gain_chk_stderr_d.ref` | + +Each test runs `gain_chk` at **48 kHz** (`-r 48000`), captures **stderr** to a scratch +file under the build tree, and compares it **byte-for-byte** to the matching `*.ref` +in `src/gain_chk/test_data/` (two-decimal band summary line plus the expected +end-of-file warning when the PCM length is an exact multiple of the frame size). + +### Running the tests + +All commands below assume your **current working directory is the STL repository +root** (the folder that contains the top-level `CMakeLists.txt`). The examples use +an out-of-tree build directory named **`build`**; use the same name everywhere, or +replace it with your own path. + +**Full chain in one line** (configure, build `gain_chk`, run only the five +`gain_chk_*` tests): + +```shell +cmake -S . -B build && cmake --build build --target gain_chk && ctest --test-dir build -R '^gain_chk_' --output-on-failure +``` + +**If the build tree is already configured**, rebuild the tool and run the same tests: + +```shell +cmake --build build --target gain_chk && ctest --test-dir build -R '^gain_chk_' --output-on-failure +``` + +**Same steps split** (equivalent to the one-liner): + +1. `cmake -S . -B build` +2. `cmake --build build --target gain_chk` +3. `ctest --test-dir build -R '^gain_chk_' --output-on-failure` + +**If you prefer to run `ctest` from inside the build directory**: + +```shell +cd build +ctest -R '^gain_chk_' --output-on-failure +``` + +**Verbose** output (shows the exact `cmake -P …/gain_chk_ctest.cmake` command line +for each test): + +```shell +ctest --test-dir build -R '^gain_chk_' -V +``` + +`CTestTestfile.cmake` (and related CTest files) under **`build/`** are **generated +by CMake** from `add_test`; they are not edited by hand (same idea as +`src/truncate/`). + +### Updating the golden `*.ref` files + +If you change `gain_chk`, the floating-point path, or the PCM files under +`test_data/`, the stderr text may change. In that case, regenerate the corresponding +`gain_chk_stderr_*.ref` (for example by running `gain_chk` once per case, redirecting +stderr to a file, and replacing the ref) and commit the updated refs after you have +verified the new output is correct. + +## Usage (summary) + +``` +gain_chk -i original_f -o processed_f -t results_f -r Fs [-v VAD_f] [-a val] [-s val] +``` + +- `-i` reference binary (16-bit samples, frame length implied by `Fs`) +- `-o` processed binary (same layout as reference) +- `-t` results text file (append mode) +- `-r` sampling frequency in Hz: 8000, 16000, 32000, or 48000 +- `-v` optional VAD file (one 16-bit flag per frame) +- `-a` optional active-frame maximum amplification threshold (dB), requires build with `THRESHOLD_CHECK` +- `-s` optional inactive-frame maximum attenuation threshold (dB); requires `-v` + +Frequency bands analysed are configured in the `bands[]` table in `gain_chk.c` +(terminate the list with `0.0f`; values in (0,1] are interpreted as fractions of +`Fs/2`). + +## Formatting + +C sources in this tree follow `FORMATTING.md` at the repository root (GNU +`indent` options; spaces instead of tab characters). diff --git a/src/gain_chk/gain_chk.c b/src/gain_chk/gain_chk.c new file mode 100644 index 00000000..404c96bf --- /dev/null +++ b/src/gain_chk/gain_chk.c @@ -0,0 +1,862 @@ +/* + * (C) 2026 copyright VoiceAge Corporation. All Rights Reserved. + * + * This software is protected by copyright law and by international treaties. The source code, and all of its derivations, + * is provided by VoiceAge Corporation under the "ITU-T Software Tools' General Public License". Please, read the license file + * or refer to ITU-T Recommendation G.191 on "SOFTWARE TOOLS FOR SPEECH AND AUDIO CODING STANDARDS". + * + * Any use of this software is permitted provided that this notice is not removed and that neither the authors nor + * VoiceAge Corporation are deemed to have made any representations as to the suitability of this software + * for any purpose nor are held responsible for any defects of this software. THERE IS NO WARRANTY FOR THIS SOFTWARE. + * + * gain_chk: gain amplification verification tool (V3.0). Revision history: Gain_Chk_Release_Notes.txt in this folder. + * Authors: Guy Richard, Tommy Vaillancourt (Tommy.Vaillancourt@USherbrooke.ca) + */ + +#include +#include +#include +#include + +#include "wav_io.h" + +#define PI2 6.2831853f +#define NB_BANDS 25 +#define L_MAX 1024 +#define N_FRM_TYPE 2 /* Active / Inactive */ +#define E_MIN 0.03f /* To Avoid Division by 0 */ +#define RATIO_MIN 0.00001f /* to Avoid Log of 0 */ + + +/* define end frequencies of frequency bands to be analysed (Terminate list with a 0) */ +/* Using Value 'N' such as 0.0 < N <= 1.0 Specifies the Freq Band as N * (Fs/2) */ +static float bands[NB_BANDS] = { + /* // critical bands + 100, 200, 300, 400, 510, 630, 770, 920, 1080, 1270, 1480, 1720, 2000, + 2320, 2700, 3150, 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500 + */ + 4000, 8000, 16000, 20000, 0.0f +}; + +#define THRESHOLD_CHECK +#define OUTPUT_VALUES + +static void usage( void ) +{ + printf( " Usage: gain_chk -i original_f -o processed_f -t results_f [-r Fs] [-v VAD_f]\n\n" ); + printf( " -i original_f - reference audio file (raw PCM or WAV)\n" ); + printf( " -o processed_f - evaluated audio file (raw PCM or WAV)\n" ); + printf( " -t results_f - results text file\n" ); + printf( " -r Fs - sampling frequency [8000, 16000, 32000, 48000] in Hz\n" ); + printf( " (optional for WAV input; read from header)\n" ); + printf( " -v VAD_f - VAD Flag binary file (One 16 Bits Flag per Frame), optional\n" ); +#ifdef THRESHOLD_CHECK + printf( " -a val - Active Signal Amplification Threshold (in dB)\n" ); + printf( " -s val - Inactive Signal Attenuation Threshold (in dB)\n" ); +#endif + + exit(0); +} + + +/*---------------------------------------------------------------------* + * + * FUNCTION NAME fft_rel + * Computes the split-radix FFT in place for the real-valued + * signal x of length n. The algorithm has been ported from + * the Fortran code of [1]. + * + * References + * [1] H.V. Sorensen, D.L. Jones, M.T. Heideman, C.S. Burrus, + * "Real-valued fast Fourier transform algorithm," IEEE + * Trans. on Signal Processing, Vol.35, No.6, pp 849-863, + * 1987. + * + * INPUT + * x[0:n-1] Input sequence. + * n Number of samples in the sequence (need to be power of 2). + * m m = log2(n). + * + * OUTPUT + * x[0:n-1] Transform coeffients in the order re[0], re[1], + * ..., re[n/2], im[n/2-1], ..., im[1]. + *---------------------------------------------------------------------*/ + +static void fft_rel( float x[], short n, short m ) +{ + short i, j, k, n1, n2, n4; + short i1, i2, i3, i4; + float xt, e, a, cc, ss, t1, t2; + + /* Digit reverse counter */ + j=0; + for ( i=0; i>1; + } + j +=k; + } + + /* Length two butterflies */ + for ( i=0; i gain) + { + /* Yes (Fail) */ + return 0; + } + i++; + } + } + + /* All Passed */ + return 1; +} +#endif + +#ifdef OUTPUT_VALUES +/*---------------------------------------------------------------------------* + * print_bands_val_stderr * + * ~~~~~~~~~~~~~ * + * Output the Results to 'stderr'. * + *--------------------------------------------------------------------------*/ + +static void print_bands_val( float *ener1, float *ener2, FILE *file) +{ + int i; + float ratio; + #define FMT "% 8.2f " + + i=0; + while ( bands[i] != 0.0f ) + { + ratio = (ener2[i] + E_MIN) / (ener1[i] + E_MIN); + if (ratio < RATIO_MIN) ratio = RATIO_MIN; + fprintf( file, FMT, 10.0*log10(ratio) ); + i++; + } + + /* 3 Because we want do Always Print 3 Bands (NB, WB, SWB) */ + while (i++ < 3) + { + fprintf( file, " =NA() " ); + } + + /* Print "full Band" Energy Ratio */ + /* The Full Spectrum Energy is in the Last Value of the Array */ + ratio = (ener2[NB_BANDS+1] + E_MIN) / (ener1[NB_BANDS+1] + E_MIN); + if (ratio < RATIO_MIN) ratio = RATIO_MIN; + fprintf( file, FMT, 10.0*log10(ratio) ); +} +#endif + +/*---------------------------------------------------------------------------* + * main function * + * ~~~~~~~~~~~~~ * + * Gain Amplification Verification. * + *--------------------------------------------------------------------------*/ + +int main( int argc, char *argv[] ) +{ + + long frame; + long frames_analysed; + short i,j, L_FFT, LOG2_L_FFT, L_FRAME, cnt, VAD_Flag; +#ifdef THRESHOLD_CHECK + float Active_Amp_Thres=99999.0f, Inactive_Att_Thres=99999.0f; + int Active_Pass=1, Inactive_Pass=1; +#endif + short Skip_Ener_Calc; + short data1[L_MAX], data2[L_MAX]; + float original_buf[L_MAX], processed_buf[L_MAX]; + float fft_buf_orig[L_MAX], fft_buf_proc[L_MAX], win[L_MAX]; + float Fs, f_bin, freq, tmp, band_ener1, band_ener2; + float band_ener_tot1[N_FRM_TYPE][NB_BANDS+2], band_ener_tot2[N_FRM_TYPE][NB_BANDS+2]; + float *ptR1, *ptI1, *ptR2, *ptI2; + + AUDIO_FILE *file1, *file2; + FILE *file3, *file4; + char *fname1 = NULL, *fname2 = NULL; + + printf("===================================================================\n"); + printf("Gain Amplification Verification tool, V3.0\n"); + printf("------------------------------------------\n"); + printf("===================================================================\n"); + + if( argc < 5 ) + { + fprintf( stderr, "Error: too few command-line arguments (got %d; need at least -i, -o, -t, -r and their values).\n", + argc - 1 ); + usage(); + } + + else + { + i = 1; + Fs = -1.0f; + file1 = NULL; + file2 = NULL; + file3 = NULL; + file4 = NULL; + + /* Process input arguments */ + /* ~~~~~~~~~~~~~~~~~~~~~~~ */ + + while( i < argc ) + { + if(argv[i][0] == '-') + { + switch(argv[i][1]) + { + case 'i': i++; if ( i >= argc || *argv[i] == '\0' ) + { + fprintf( stderr, "Error: -i requires a reference PCM file path (argument missing or empty).\n" ); + usage(); + } + + fname1 = argv[i]; + printf( "\nReference file: %s\n", argv[i] ); + + i++; + + break; + + case 'o': i++; if ( i >= argc || *argv[i] == '\0' ) + { + fprintf( stderr, "Error: -o requires an evaluated PCM file path (argument missing or empty).\n" ); + usage(); + } + + fname2 = argv[i]; + printf("Evaluated file: %s\n", argv[i]); + + i++; + + break; + + case 't': i++; if ( i >= argc || *argv[i] == '\0' ) + { + fprintf( stderr, "Error: -t requires a results text file path (argument missing or empty).\n" ); + usage(); + } + + if ( (file4 = fopen( argv[i], "at" )) == NULL) + { + fprintf( stderr, "Error: cannot open results text file (-t): %s\n", argv[i] ); + exit( 1 ); + } + printf( "Results text file: %s\n ", argv[i]); + + i++; + + break; + + case 'r': if ( ++i >= argc ) + { + fprintf( stderr, "Error: -r requires a sampling frequency in Hz (argument missing).\n" ); + usage(); + } + + Fs = (float)atof( argv[i] ); + printf( "Sampling frequency = %5.0f Hz\n\n", Fs ); + + i++; + break; + + /* Optional input argument */ + case 'v': i++; if ( i >= argc || *argv[i] == '\0' ) + { + fprintf( stderr, "Error: -v requires a VAD flags file path (argument missing or empty).\n" ); + usage(); + } + + if ( (file3 = fopen( argv[i], "rb" )) == NULL) + { + fprintf( stderr, "Error: cannot open VAD input file (-v): %s\n", argv[i] ); + exit( 1 ); + } + printf( "VAD File: %s\n\n", argv[i] ); + + i++; + break; +#ifdef THRESHOLD_CHECK + case 'a': if ( ++i >= argc ) + { + fprintf( stderr, "Error: -a requires the active-frame max amplification threshold in dB (argument missing).\n" ); + usage(); + } + + Active_Amp_Thres = (float)atof( argv[i] ); + if (Active_Amp_Thres <= 0.0f) + { + fprintf( stderr, "Error: -a value must be strictly positive (got %g).\n", (double)Active_Amp_Thres ); + exit(0); + } + printf( "Active Signal Max Amplification Threshold = %5.3f dB\n\n", Active_Amp_Thres ); + + i++; + break; + + case 's': if ( ++i >= argc ) + { + fprintf( stderr, "Error: -s requires the inactive-frame max attenuation threshold in dB (argument missing).\n" ); + usage(); + } + + Inactive_Att_Thres = (float)atof( argv[i] ); + if (Inactive_Att_Thres <= 0.0f) + { + fprintf( stderr, "Error: -s value must be strictly positive (got %g).\n", (double)Inactive_Att_Thres ); + exit(0); + } + printf( "Inactive Signal Max Attenuation Threshold = %5.3f dB\n\n", Inactive_Att_Thres ); + + i++; + break; +#endif + + default: + + if ( argv[i][0] == '-' && argv[i][1] == '\0' ) + { + fprintf( stderr, "Error: lone '-' is not a valid option.\n" ); + } + else if ( argv[i][0] == '-' && argv[i][2] != '\0' ) + { + fprintf( stderr, "Error: multi-character option '%s' is not supported (use single-letter flags like -i, -o).\n", + argv[i] ); + } + else + { + fprintf( stderr, "Error: unknown option flag '-%c' in '%s'.\n", + (int)(unsigned char)argv[i][1], argv[i] ); + } + usage(); + break; + } + } + else + { + fprintf( stderr, "Error: unexpected argument '%s' (all parameters must use -flag value form).\n", argv[i] ); + usage(); + } + } + } + + if ( fname1 == NULL || fname2 == NULL || file4 == NULL ) + { + if ( fname1 == NULL ) + { + fputs( "Error: missing required option -i .\n", stderr ); + } + if ( fname2 == NULL ) + { + fputs( "Error: missing required option -o .\n", stderr ); + } + if ( file4 == NULL ) + { + fputs( "Error: missing required option -t .\n", stderr ); + } + usage(); + } +#ifdef THRESHOLD_CHECK + if ( file3 == NULL && Inactive_Att_Thres != 99999.0f) + { + fputs( "Error: -s (inactive attenuation threshold) requires a VAD file with -v .\n", stderr ); + exit(0); + } + +#endif + /* Open audio files */ + if ( (file1 = audio_open_read( fname1, 0, 0, 16 )) == NULL) + { + fprintf( stderr, "Error: cannot open reference input file (-i): %s\n", fname1 ); + exit( 1 ); + } + if ( (file2 = audio_open_read( fname2, 0, 0, 16 )) == NULL) + { + fprintf( stderr, "Error: cannot open evaluated input file (-o): %s\n", fname2 ); + exit( 1 ); + } + + /* Resolve sampling frequency: use WAV header if -r not provided */ + if ( Fs < 0.0f && audio_is_wav( file1 ) ) + { + Fs = (float)audio_get_sample_rate( file1 ); + printf( "Sampling frequency = %5.0f Hz (from WAV header)\n\n", Fs ); + } + if ( Fs!=8000 && Fs!=16000 && Fs!=32000 && Fs!=48000 ) + { + if ( Fs < 0.0f ) + { + fputs( "Error: missing required option -r (sampling frequency in Hz).\n", stderr ); + } + else + { + fprintf( stderr, "Error: invalid sampling frequency %.0f Hz for -r (allowed: 8000, 16000, 32000, 48000).\n", + (double)Fs ); + } + usage(); + } + /* Validate WAV sample rates against resolved Fs */ + if ( audio_is_wav( file1 ) && audio_get_sample_rate( file1 ) != (long)Fs ) + { + fprintf( stderr, "Error: WAV sample rate (%ld Hz) in reference file does not match -r %.0f Hz.\n", + audio_get_sample_rate( file1 ), (double)Fs ); + exit( 1 ); + } + if ( audio_is_wav( file2 ) && audio_get_sample_rate( file2 ) != (long)Fs ) + { + fprintf( stderr, "Error: WAV sample rate (%ld Hz) in evaluated file does not match -r %.0f Hz.\n", + audio_get_sample_rate( file2 ), (double)Fs ); + exit( 1 ); + } + + L_FRAME = (short)(Fs / 50 + 0.5f); /* number of samples in frame of 20 ms */ + + /* Frequency bands management */ + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + for ( j = 0; j < N_FRM_TYPE; j++ ) + { + for ( i = 0; i < NB_BANDS+2; i++ ) + { + band_ener_tot1[j][i] = 0.0f; + band_ener_tot2[j][i] = 0.0f; + } + } + + /* Check Bands (and convert) */ + for ( i=0; i 0 ) + { + /* Check Frequency Bands Ordering */ + if (bands[i] <= bands[i-1]) + { + fprintf( stderr, "Error: bad order of frequency bands (%6.1f Hz, %6.1f Hz); aborting.\n", + (double)bands[i-1], (double)bands[i] ); + exit( 1 ); + } + } + /* Limit Frequency to Fs/2 */ + if ( bands[i] > Fs/2.0f ) + { + bands[i] = Fs/2.0f; + if ( i > 0 ) + { + if (bands[i] == bands[i-1]) + { + bands[i] = 0.0f; + break; + } + } + } + } + + if ( i == 0 ) + { + fprintf( stderr, "Error: no frequency bands defined in bands[]; aborting.\n" ); + exit( 1 ); + } + if ( i == NB_BANDS ) + { + fprintf( stderr, "Error: frequency band list must end with 0.0f; aborting.\n" ); + exit( 1 ); + } + + if ( 2.0 * Fs / L_FRAME > bands[0] ) + { + fprintf( stderr, "Error: insufficient frequency resolution for the configured bands (Fs=%.0f Hz); aborting.\n", + (double)Fs ); + exit( 1 ); + } + + /* Initializations */ + for ( i = 0; i < L_MAX; i++ ) + { + original_buf[i] = 0.0f; + processed_buf[i] = 0.0f; + fft_buf_orig[i] = 0.0f; + fft_buf_proc[i] = 0.0f; + } + + /* prepare hamming window for frequency analysis */ + tmp = (float)(PI2/(L_FRAME-1)); + for ( i=0; i< L_FRAME; i++ ) + { + win[i] = 0.54f - 0.46f * (float)cos( tmp * i ); + } + + /* set fft length after zero padding */ + LOG2_L_FFT = (short)( log( L_FRAME - 0.5 ) / log( 2.0 ) ) + 1; + L_FFT = 1<fp ) ) + { + fputs( "Error: read error on reference file (-i).\n", stderr ); + } + if ( ferror( file2->fp ) ) + { + fputs( "Error: read error on evaluated file (-o).\n", stderr ); + } + if ( !ferror( file1->fp ) && !ferror( file2->fp ) ) + { + if ( nread1 == 0 && nread2 == 0 ) + { + fputs( "Error: both input files are empty or shorter than one frame.\n", stderr ); + } + else if ( nread1 < (long)L_FRAME && nread2 < (long)L_FRAME ) + { + fprintf( stderr, "Error: both files are shorter than one frame (read %ld and %ld samples, need %d).\n", + nread1, nread2, (int)L_FRAME ); + } + else if ( nread1 < (long)L_FRAME ) + { + fprintf( stderr, "Error: reference file (-i) is shorter than one frame or ended first (read %ld samples, need %d).\n", + nread1, (int)L_FRAME ); + } + else + { + fprintf( stderr, "Error: evaluated file (-o) is shorter than one frame or ended first (read %ld samples, need %d).\n", + nread2, (int)L_FRAME ); + } + } + + exit( 1 ); + } + + if ( frames_analysed == 0 ) + { + fprintf( stderr, "Error: read %ld complete frame(s), but none were analysed in the spectrum\n" + " (e.g. all VAD=0 frames skipped as low-energy inactive). No usable results.\n", + frame ); + exit( 1 ); + } + + if ( nread1 != (long)L_FRAME || nread2 != (long)L_FRAME ) + { + fprintf( stderr, "Warning: stopped after %ld complete frame(s): inputs do not both extend by another full frame\n" + " (last fread: %ld samples from -i, %ld from -o; need %d per frame).\n", + frame, nread1, nread2, (int)L_FRAME ); + } + } + + printf( "\n Done.\n\n" ); + + + /* save the results */ + /* ~~~~~~~~~~~~~~~~ */ + + for ( i=0; i short */ #include "iirflt.h" /* G.712 IIR filtering functions */ +#include "wav_io.h" /* * ......... Definitions for this test program ......... @@ -195,7 +196,7 @@ int main (int argc, char *argv[]) { /* ......... File related variables ......... */ char inpfil[MAX_STRLEN], outfil[MAX_STRLEN]; - FILE *inpfilptr, *outfilptr; + AUDIO_FILE *inpfilptr, *outfilptr; #if defined(VMS) static char mrs[15] = "mrs="; #endif @@ -255,11 +256,11 @@ int main (int argc, char *argv[]) { #endif GET_PAR_S (1, "_BIN-File to be processed: ............... ", inpfil); - if ((inpfilptr = fopen (inpfil, RB)) == NULL) + if ((inpfilptr = audio_open_read (inpfil, 0, 0, 16)) == NULL) error_terminate ("\n Error opening input file", 1); GET_PAR_S (2, "_BIN-Output File: ........................ ", outfil); - if ((outfilptr = fopen (outfil, WB)) == NULL) + if ((outfilptr = audio_open_write (outfil, audio_get_sample_rate (inpfilptr), 1, 16)) == NULL) error_terminate ("\n Error opening output file", 1); FIND_PAR_L (3, "_Segment Length for Filtering: ........... ", lseg, lseg); @@ -288,7 +289,7 @@ int main (int argc, char *argv[]) { lsegx = lseg; while (lsegx == lseg) { /* Read input buffer */ - lsegx = fread (sh_buff, sizeof (short), lseg, inpfilptr); + lsegx = audio_read (inpfilptr, sh_buff, lseg); /* convert short data to float in normalized range */ sh2fl_16bit (lsegx, sh_buff, fl_buff, 1); @@ -309,7 +310,7 @@ int main (int argc, char *argv[]) { /* Skip samples if requested */ if (lseg1 > skip) { /* Write samples to output file */ - nsam += fwrite (&sh_buff[skip], sizeof (short), (lseg1 - skip), outfilptr); + nsam += audio_write (outfilptr, &sh_buff[skip], (lseg1 - skip)); } else skip -= lseg1; } @@ -335,8 +336,8 @@ int main (int argc, char *argv[]) { cascade_iir_free (typ1_ptr); /* Close files */ - fclose (outfilptr); - fclose (inpfilptr); + audio_close (outfilptr); + audio_close (inpfilptr); #ifndef VMS return 0; diff --git a/src/iir/cirsdemo.c b/src/iir/cirsdemo.c index e6497411..76c0f40b 100644 --- a/src/iir/cirsdemo.c +++ b/src/iir/cirsdemo.c @@ -107,6 +107,7 @@ #include "ugstdemo.h" /* private defines for user interface */ #include "ugst-utl.h" /* conversion from float -> short */ #include "iirflt.h" /* IRS IIR filtering functions */ +#include "wav_io.h" /* * ......... Definitions for this test program ......... @@ -196,7 +197,7 @@ int main (int argc, char *argv[]) { /* ......... File related variables ......... */ char inpfil[MAX_STRLEN], outfil[MAX_STRLEN]; - FILE *inpfilptr, *outfilptr; + AUDIO_FILE *inpfilptr, *outfilptr; #if defined(VMS) static char mrs[15] = "mrs="; #endif @@ -256,11 +257,11 @@ int main (int argc, char *argv[]) { #endif GET_PAR_S (1, "_BIN-File to be processed: ............... ", inpfil); - if ((inpfilptr = fopen (inpfil, RB)) == NULL) + if ((inpfilptr = audio_open_read (inpfil, 0, 0, 16)) == NULL) error_terminate ("\n Error opening input file", 1); GET_PAR_S (2, "_BIN-Output File: ........................ ", outfil); - if ((outfilptr = fopen (outfil, WB)) == NULL) + if ((outfilptr = audio_open_write (outfil, audio_get_sample_rate (inpfilptr), 1, 16)) == NULL) error_terminate ("\n Error opening output file", 1); FIND_PAR_L (3, "_Segment Length for Filtering: ........... ", lseg, lseg); @@ -289,7 +290,7 @@ int main (int argc, char *argv[]) { lsegx = lseg; while (lsegx == lseg) { /* Read input buffer */ - lsegx = fread (sh_buff, sizeof (short), lseg, inpfilptr); + lsegx = audio_read (inpfilptr, sh_buff, lseg); /* convert short data to float in normalized range */ sh2fl_16bit (lsegx, sh_buff, fl_buff, 1); @@ -310,7 +311,7 @@ int main (int argc, char *argv[]) { /* Skip samples if requested */ if (lseg1 > skip) { /* Write samples to output file */ - nsam += fwrite (&sh_buff[skip], sizeof (short), (lseg1 - skip), outfilptr); + nsam += audio_write (outfilptr, &sh_buff[skip], (lseg1 - skip)); skip = 0; } else skip -= lseg1; @@ -337,8 +338,8 @@ int main (int argc, char *argv[]) { cascade_iir_free (typ1_ptr); /* Close files */ - fclose (outfilptr); - fclose (inpfilptr); + audio_close (outfilptr); + audio_close (inpfilptr); #ifndef VMS return 0; diff --git a/src/iir/pcmdemo.c b/src/iir/pcmdemo.c index 1bef0696..1aa51439 100644 --- a/src/iir/pcmdemo.c +++ b/src/iir/pcmdemo.c @@ -137,6 +137,7 @@ #include "ugstdemo.h" /* private defines for user interface */ #include "ugst-utl.h" /* conversion from float -> short */ #include "iirflt.h" /* Standard PCM filtering functions */ +#include "wav_io.h" /* * ......... Definitions for this test program ......... @@ -243,7 +244,7 @@ int main (int argc, char *argv[]) { /* ......... File related variables ......... */ char inpfil[MAX_STRLEN], outfil[MAX_STRLEN]; - FILE *inpfilptr, *outfilptr; + AUDIO_FILE *inpfilptr, *outfilptr; #if defined(VMS) static char mrs[15] = "mrs=512"; #endif @@ -304,11 +305,11 @@ int main (int argc, char *argv[]) { /* ......... GETTING PARAMETERS ......... */ GET_PAR_S (1, "_BIN-File to be processed: ............... ", inpfil); - if ((inpfilptr = fopen (inpfil, RB)) == NULL) + if ((inpfilptr = audio_open_read (inpfil, 0, 0, 16)) == NULL) error_terminate ("\n Error opening input file", 1); GET_PAR_S (2, "_BIN-Output File: ........................ ", outfil); - if ((outfilptr = fopen (outfil, WB)) == NULL) + if ((outfilptr = audio_open_write (outfil, audio_get_sample_rate (inpfilptr), 1, 16)) == NULL) error_terminate ("\n Error opening output file", 1); GET_PAR_S (3, "_type of filter 1: ....................... ", typ1); @@ -402,7 +403,7 @@ int main (int argc, char *argv[]) { lsegx = lseg; while (lsegx == lseg) { /* Read input buffer */ - lsegx = fread (sh_buff, sizeof (short), lseg, inpfilptr); + lsegx = audio_read (inpfilptr, sh_buff, lseg); /* convert short data to float in normalized range */ sh2fl_16bit (lsegx, sh_buff, fl_buff, 1); @@ -487,7 +488,7 @@ int main (int argc, char *argv[]) { /* Skip samples if requested */ if (lseg1 > skip) { /* Write samples to output file */ - nsam += fwrite (&sh_buff[skip], sizeof (short), (lseg3 - skip), outfilptr); + nsam += audio_write (outfilptr, &sh_buff[skip], (lseg3 - skip)); skip = 0; } else skip -= lseg1; @@ -530,8 +531,8 @@ int main (int argc, char *argv[]) { #endif /* Close files */ - fclose (outfilptr); - fclose (inpfilptr); + audio_close (outfilptr); + audio_close (inpfilptr); #ifndef VMS return 0; diff --git a/src/is54/CMakeLists.txt b/src/is54/CMakeLists.txt index ecf060ba..dee5bef0 100644 --- a/src/is54/CMakeLists.txt +++ b/src/is54/CMakeLists.txt @@ -20,3 +20,5 @@ add_test(uvselp-decode4 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uvselp -q -dec -pf -bi add_test(uvselp-both1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uvselp -q -nolog test_data/voice.src test_data/voice.rek) add_test(uvselp-both2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uvselp -q -nolog -pf test_data/voice.src test_data/voice-pf.rek) + + diff --git a/src/is54/g_quant.c b/src/is54/g_quant.c index d98bc399..5d3f6225 100644 --- a/src/is54/g_quant.c +++ b/src/is54/g_quant.c @@ -36,22 +36,21 @@ Motorola Inc. #include "vparams.h" /*#include "stdlib.h"*/ /* function declarations*/ -static FTYPE corr (); -/*FTYPE *vec1Ptr, FTYPE *vec2Ptr*/ +static FTYPE corr (FTYPE *vec1Ptr, FTYPE *vec2Ptr); int G_QUANT (int lag, FTYPE rs00, FTYPE rs11, FTYPE rs22) { - FTYPE Rpc0; /* correlation between the weighted speech and the */ + FTYPE Rpc0 = 0.0; /* correlation between the weighted speech and the */ /* weighted pitch excitation vector */ FTYPE Rpc1; /* correlation between the weighted speech and the */ /* weighted 1st codebook excitation vector */ FTYPE Rpc2; /* correlation between the weighted speech and the */ /* weighted 2nd codebook excitation vector */ - FTYPE Rcc00; /* Rcc(mn) -- correlation between excitation vector */ + FTYPE Rcc00 = 0.0; /* Rcc(mn) -- correlation between excitation vector */ /* m and n, where vector 0 is the pitch excitation, */ /* vector 1 is the 1st codebook excitation, and */ /* vector 2 is the 2nd codebook excitation */ - FTYPE Rcc01; /* */ - FTYPE Rcc02; /* */ + FTYPE Rcc01 = 0.0; /* */ + FTYPE Rcc02 = 0.0; /* */ FTYPE Rcc11; /* */ FTYPE Rcc12; /* */ FTYPE Rcc22; /* */ @@ -64,7 +63,7 @@ int G_QUANT (int lag, FTYPE rs00, FTYPE rs11, FTYPE rs22) { FTYPE maxVal; /* the current best (maximum) error value */ int code; /* the best GSP0 centroid, returned to T_SUB() */ - FTYPE *savePtr, *tmpPtr, *tmpPtr2, *endPtr, *endPtr2; + FTYPE *savePtr = NULL, *tmpPtr, *tmpPtr2, *endPtr, *endPtr2; errCoefs = (FTYPE *) malloc (GSP0_TERMS * sizeof (FTYPE)); diff --git a/src/is54/init.c b/src/is54/init.c index d96f72a2..06f6dcf0 100644 --- a/src/is54/init.c +++ b/src/is54/init.c @@ -88,13 +88,13 @@ void initTables () { FILE *fptmp; char *line; - line = (char *) malloc (MAXLINE * sizeof (char)); + line = (char *) calloc (MAXLINE, sizeof (char)); /* allocate input speech buffer, interpolated coef buffer, and residual */ /* energy estimate buffer */ - inBuf = (FTYPE *) malloc (INBUFSIZ * sizeof (FTYPE)); - I_CBUFF = (FTYPE *) malloc ((NP * 3 * N_SUB) * sizeof (FTYPE)); - RS_BUFF = (FTYPE *) malloc ((2 * N_SUB) * sizeof (FTYPE)); + inBuf = (FTYPE *) calloc (INBUFSIZ, sizeof (FTYPE)); + I_CBUFF = (FTYPE *) calloc (NP * 3 * N_SUB, sizeof (FTYPE)); + RS_BUFF = (FTYPE *) calloc (2 * N_SUB, sizeof (FTYPE)); /* initialize codes to zero (in case 1st denominator in FLAT is zero) */ codeBuf = (int *) calloc (numCodes, sizeof (int)); @@ -109,29 +109,29 @@ void initTables () { /* (1<<(K_BITS_8+1))-1 + (1<<(K_BITS_9+1))-1 + */ /* (1<<(K_BITS_10+1))-1; */ numDecisionVals = 445; - *r0kAddr = (FTYPE *) malloc (numDecisionVals * sizeof (FTYPE)); - sst = (FTYPE *) malloc ((NP + 1) * sizeof (FTYPE)); + *r0kAddr = (FTYPE *) calloc (numDecisionVals, sizeof (FTYPE)); + sst = (FTYPE *) calloc ((NP + 1), sizeof (FTYPE)); /* T_SUB() and R_SUB() allocations */ - T_STATE = (FTYPE *) malloc (NP * sizeof (FTYPE)); - T_VEC = (FTYPE *) malloc (S_LEN * sizeof (FTYPE)); - P = (FTYPE *) malloc (S_LEN * sizeof (FTYPE)); - P_VEC = (FTYPE *) malloc (S_LEN * sizeof (FTYPE)); - W_P_VEC = (FTYPE *) malloc (S_LEN * sizeof (FTYPE)); - BASIS = (FTYPE *) malloc (S_LEN * C_BITS * sizeof (FTYPE)); - BASIS_A = (FTYPE *) malloc (S_LEN * C_BITS_A * sizeof (FTYPE)); - W_BASIS = (FTYPE *) malloc (S_LEN * C_BITS * sizeof (FTYPE)); - BITS = (FTYPE *) malloc (C_BITS * sizeof (FTYPE)); - X_VEC = (FTYPE *) malloc (S_LEN * sizeof (FTYPE)); - W_X_VEC = (FTYPE *) malloc (S_LEN * sizeof (FTYPE)); - X_A_VEC = (FTYPE *) malloc (S_LEN * sizeof (FTYPE)); - W_X_A_VEC = (FTYPE *) malloc (S_LEN * sizeof (FTYPE)); + T_STATE = (FTYPE *) calloc (NP, sizeof (FTYPE)); + T_VEC = (FTYPE *) calloc (S_LEN, sizeof (FTYPE)); + P = (FTYPE *) calloc (S_LEN, sizeof (FTYPE)); + P_VEC = (FTYPE *) calloc (S_LEN, sizeof (FTYPE)); + W_P_VEC = (FTYPE *) calloc (S_LEN, sizeof (FTYPE)); + BASIS = (FTYPE *) calloc (S_LEN * C_BITS, sizeof (FTYPE)); + BASIS_A = (FTYPE *) calloc (S_LEN * C_BITS_A, sizeof (FTYPE)); + W_BASIS = (FTYPE *) calloc (S_LEN * C_BITS, sizeof (FTYPE)); + BITS = (FTYPE *) calloc (C_BITS, sizeof (FTYPE)); + X_VEC = (FTYPE *) calloc (S_LEN, sizeof (FTYPE)); + W_X_VEC = (FTYPE *) calloc (S_LEN, sizeof (FTYPE)); + X_A_VEC = (FTYPE *) calloc (S_LEN, sizeof (FTYPE)); + W_X_A_VEC = (FTYPE *) calloc (S_LEN, sizeof (FTYPE)); T_P_STATE = (FTYPE *) calloc (LMAX, sizeof (FTYPE)); xmtExPtr = T_P_STATE + LMAX - S_LEN; - TABLE = (int *) malloc (((1 << C_BITS) - 2) * sizeof (int)); - GSP0_TABLE = (FTYPE *) malloc (GSP0_TERMS * GSP0_NUM * sizeof (FTYPE)); + TABLE = (int *) calloc (((1 << C_BITS) - 2), sizeof (int)); + GSP0_TABLE = (FTYPE *) calloc (GSP0_TERMS * GSP0_NUM, sizeof (FTYPE)); R_P_STATE = (FTYPE *) calloc (LMAX, sizeof (FTYPE)); - outBuf = (FTYPE *) malloc (S_LEN * sizeof (FTYPE)); + outBuf = (FTYPE *) calloc (S_LEN, sizeof (FTYPE)); /* fill r0 quantization table */ temp = sqrt ((double) S_LEN); /* sqrt (S_LEN * max amplitude squared) */ @@ -229,7 +229,7 @@ void initTables () { #include "gray.i" /* gray-code table */ /* store SST bandwidth widening factors for A_SST() */ - P_SST = (FTYPE *) malloc ((NP + 1) * sizeof (FTYPE)); + P_SST = (FTYPE *) calloc ((NP + 1), sizeof (FTYPE)); nb = log (0.5) / (2.0 * log (cos ((4.0 * atan (1.0) * POST_BEQ_N) / (2.0 * SRATE)))); temp = 1.0; diff --git a/src/is54/interp.c b/src/is54/interp.c index da9d2f29..cb891490 100644 --- a/src/is54/interp.c +++ b/src/is54/interp.c @@ -32,8 +32,7 @@ Motorola Inc. #include #include "vparams.h" -int ATORC (); /* from paramConv.c */ - /* FTYPE *a, FTYPE *k */ +int ATORC (FTYPE *a, FTYPE *k); /* from paramConv.c */ void I_MOV (struct coefSet defSet, int numSets, FTYPE rq0); FTYPE RES_ENG (FTYPE rq0, FTYPE * k); @@ -120,9 +119,7 @@ void I_MOV (struct coefSet defSet, int numSets, FTYPE rq0) { /* RES_ENG calculates a residual energy estimate*/ -FTYPE RES_ENG (rq0, k) - FTYPE rq0; - FTYPE *k; +FTYPE RES_ENG (FTYPE rq0, FTYPE *k) { FTYPE *endPtr /* , tmp = 1.0 */ , ftmp; double tmp = 1.0; diff --git a/src/is54/lag.c b/src/is54/lag.c index 155880c7..e924f782 100644 --- a/src/is54/lag.c +++ b/src/is54/lag.c @@ -36,8 +36,7 @@ Motorola Inc. #include "vparams.h" /*#include "stdlib.h"*/ /* function declarations*/ -static void i_resp (); -/*FTYPE *htPtr*/ +static void i_resp (FTYPE *htPtr); int LAG_SEARCH () { @@ -51,7 +50,7 @@ int LAG_SEARCH () { FTYPE Cl; /* Holds the cross correlation between bl and P, the */ /* weighted speech, for lag l */ FTYPE Gl; /* Holds the energy in bl */ - FTYPE E; /* Holds the partial energy of bl for lags greater */ + FTYPE E = 0.0; /* Holds the partial energy of bl for lags greater */ /* than S_LEN */ FTYPE ClBest = 0.0; /* Holds the value of Cl for the current best */ /* Cl**2 / Gl */ diff --git a/src/is54/makec.c b/src/is54/makec.c index d5dfa882..2a6cf1e4 100644 --- a/src/is54/makec.c +++ b/src/is54/makec.c @@ -37,8 +37,7 @@ Motorola Inc. #include "vparams.h" /*#include "stdlib.h"*/ /* from paramConv.c */ -int ATORC (); -/*FTYPE *a, FTYPE *k*/ +int ATORC (FTYPE *a, FTYPE *k); void widen (FTYPE lambda, char side) { FTYPE term; /* holds lambda**i term (widening factor for Ai) */ @@ -66,15 +65,11 @@ void widen (FTYPE lambda, char side) { /* coefficients*/ /* function declarations */ -void ATOCOR (); -/*FTYPE *k, FTYPE *ac*/ -void LEVINSON (); -/*FTYPE *ac, FTYPE *a*/ +void ATOCOR (FTYPE *k, FTYPE *ac); +void LEVINSON (FTYPE *ac, FTYPE *a); /* function definition*/ -void A_SST (wCoefPtr, ssCoefPtr) - FTYPE *wCoefPtr; - FTYPE *ssCoefPtr; +void A_SST (FTYPE *wCoefPtr, FTYPE *ssCoefPtr) { FTYPE *tmpKs; /* points to temporary reflection coef buffer */ FTYPE *tmpAcs; /* points to temp autocorrelation buffer */ diff --git a/src/is54/r_sub.h b/src/is54/r_sub.h index 02b5a0f5..769e230a 100644 --- a/src/is54/r_sub.h +++ b/src/is54/r_sub.h @@ -40,31 +40,24 @@ extern FTYPE RS00, RS11, RS22; /* Function declarations ... */ /* from filters.c*/ -void I_DIR (); -/*FTYPE *inPtr, FTYPE *oPtr, FTYPE *stPtr, FTYPE *coefPtr, int len*/ -void DIR (); -/*FTYPE *inPtr, FTYPE *oPtr, FTYPE *stPtr, FTYPE *coefPtr, int len*/ +void I_DIR (FTYPE *inPtr, FTYPE *oPtr, FTYPE *stPtr, FTYPE *coefPtr, int len); +void DIR (FTYPE *inPtr, FTYPE *oPtr, FTYPE *stPtr, FTYPE *coefPtr, int len); /* from p_ex.c*/ -void P_EX (); -/*FTYPE *oPtr, FTYPE *psPtr, int lag*/ +void P_EX (FTYPE *oPtr, FTYPE *psPtr, int lag); /* from b_con.c*/ -void B_CON (); -/*int codeWord, int numBits, FTYPE *bitArray*/ +void B_CON (int codeWord, int numBits, FTYPE *bitArray); /* from v_con.c*/ -void V_CON (); -/*FTYPE *basisPtr, FTYPE *bitArray, int numBasis, FTYPE *oPtr*/ +void V_CON (FTYPE *basisPtr, FTYPE *bitArray, int numBasis, FTYPE *oPtr); /* from rs_rr.c*/ -FTYPE RS_RR (); -/*FTYPE *vecPtr, FTYPE rs*/ +FTYPE RS_RR (FTYPE *vecPtr, FTYPE rs); /* from excite.c*/ -FTYPE EXCITE (); -/*int gsp0, int lag, FTYPE rs00, FTYPE rs11, FTYPE rs22, +FTYPE EXCITE (int gsp0, int lag, FTYPE rs00, FTYPE rs11, FTYPE rs22, FTYPE *pVecPtr, FTYPE *x1VecPtr, FTYPE *x2VecPtr, - FTYPE *oPtr*/ + FTYPE *oPtr); /* ......................... End of file r_sub.h ........................... */ diff --git a/src/is54/t_sub.h b/src/is54/t_sub.h index 1440b285..2d5a5259 100644 --- a/src/is54/t_sub.h +++ b/src/is54/t_sub.h @@ -38,53 +38,40 @@ extern FTYPE RS00, RS11, RS22; /*-------------------------------------------------------------------------*/ /* Function declarations ... */ /* ... from filters.c*/ -void I_DIR (); -/*FTYPE *inPtr, FTYPE *oPtr, FTYPE *stPtr, FTYPE *coefPtr, int len*/ -void DIR (); -/*FTYPE *inPtr, FTYPE *oPtr, FTYPE *stPtr, FTYPE *coefPtr, int len*/ -void ZI_DIR (); -/*FTYPE *oPtr, FTYPE *stPtr, FTYPE *coefPtr, int len*/ +void I_DIR (FTYPE *inPtr, FTYPE *oPtr, FTYPE *stPtr, FTYPE *coefPtr, int len); +void DIR (FTYPE *inPtr, FTYPE *oPtr, FTYPE *stPtr, FTYPE *coefPtr, int len); +void ZI_DIR (FTYPE *oPtr, FTYPE *stPtr, FTYPE *coefPtr, int len); /* ... from lag_search.c*/ -int LAG_SEARCH (); -/*void*/ +int LAG_SEARCH (void); /* ... from p_ex.c*/ -void P_EX (); -/*FTYPE *oPtr, FTYPE *psPtr, int lag*/ +void P_EX (FTYPE *oPtr, FTYPE *psPtr, int lag); /* ... from decorr.c*/ -void DECORR (); -/*FTYPE *vecPtr, FTYPE *basisPtr, int numBasis*/ +void DECORR (FTYPE *vecPtr, FTYPE *basisPtr, int numBasis); /* ... from v_srch.c*/ -int V_SRCH (); -/*FTYPE *wiPtr, FTYPE *wBasisPtr, int numBasis*/ +int V_SRCH (FTYPE *wiPtr, FTYPE *wBasisPtr, int numBasis); /* ... from b_con.c*/ -void B_CON (); -/*int codeWord, int numBits, FTYPE *bitArray*/ +void B_CON (int codeWord, int numBits, FTYPE *bitArray); /* ... from v_con.c*/ -void V_CON (); -/*FTYPE *basisPtr, FTYPE *bitArray, int numBasis, FTYPE *oPtr*/ +void V_CON (FTYPE *basisPtr, FTYPE *bitArray, int numBasis, FTYPE *oPtr); /* ... from rs_rr.c*/ -FTYPE RS_RR (); -/*FTYPE *vecPtr, FTYPE rs*/ +FTYPE RS_RR (FTYPE *vecPtr, FTYPE rs); /* ... from g_quant.c*/ -int G_QUANT (); -/*int lag, FTYPE rs00, FTYPE rs11, FTYPE rs22*/ +int G_QUANT (int lag, FTYPE rs00, FTYPE rs11, FTYPE rs22); /* ... from excite.c*/ -FTYPE EXCITE (); -/*int gsp0, int lag, FTYPE rs00, FTYPE rs11, FTYPE rs22, +FTYPE EXCITE (int gsp0, int lag, FTYPE rs00, FTYPE rs11, FTYPE rs22, FTYPE *pVecPtr, FTYPE *x1VecPtr, FTYPE *x2VecPtr, - FTYPE *oPtr*/ + FTYPE *oPtr); /* ... from weightedSnr.c*/ -void runningSnr (); -/*FTYPE *speech, FTYPE *syn, FTYPE *wSpeech, FTYPE *wsyn*/ +void runningSnr (FTYPE *speech, FTYPE *syn, FTYPE *wSpeech, FTYPE *wsyn); /* ......................... End of file t_sub.h ........................... */ diff --git a/src/is54/vselp.c b/src/is54/vselp.c index 2201dcfa..3ab2b97c 100644 --- a/src/is54/vselp.c +++ b/src/is54/vselp.c @@ -187,7 +187,7 @@ int main (int argc, char *argv[]) { FTYPE *tmpPtr, *tmpPtr2, *endPtr, f1; int i, numRead; short *shPtr; - long (*get_codes) (), (*put_codes) (); + long (*get_codes) (FILE *, int *), (*put_codes) (FILE *, int *); long bs_read = 0, bs_saved = 0; char use_user_resp_file = 0; /* Don't use user's response file */ char InpFile[MAX_STRLEN], OutFile[MAX_STRLEN], LogFile[MAX_STRLEN], PackedFile[MAX_STRLEN]; diff --git a/src/is54/vselp.h b/src/is54/vselp.h index 8dbac1ec..c7a81a47 100644 --- a/src/is54/vselp.h +++ b/src/is54/vselp.h @@ -39,73 +39,55 @@ Motorola Inc. /*-------------------------------------------------------------------------*/ /* Function declarations ... */ /* ... from getParams.c */ -void getParams (); -/*FILE *fpget */ +void getParams (FILE *fpget); /* ... from calcParams.c */ -void calcParams (); +void calcParams (void); /* ... from initTables.c */ -void initTables (); +void initTables (void); /* ... from filt4.c */ -void FILT4 (); -/*FTYPE *inPtr, int len */ +void FILT4 (FTYPE *inPtr, int len); /* ... from flatv.c */ -void FLATV (); -FTYPE lookup (); -/*int i */ +void FLATV (void); +FTYPE lookup (int i); /* ... from paramConv.c */ -int ATORC (); -/*FTYPE *a, FTYPE *k */ -int RCTOA (); -/*FTYPE *k, FTYPE *a */ +int ATORC (FTYPE *a, FTYPE *k); +int RCTOA (FTYPE *k, FTYPE *a); /* ... from interpolate.c */ -int INTERPOLATE (); -/*struct coefSet defCoefs, - int numSets, - struct coefSet oCoefs, - int i, - FTYPE rq0 */ +int INTERPOLATE (struct coefSet defCoefs, int numSets, + struct coefSet oCoefs, int i, FTYPE rq0); -void I_MOV (); -/*struct coefSet defSet, - int numSets, - FTYPE rq0 */ +void I_MOV (struct coefSet defSet, int numSets, FTYPE rq0); -FTYPE RES_ENG (); -/*FTYPE rq0, FTYPE *k */ +FTYPE RES_ENG (FTYPE rq0, FTYPE *k); /* ... from t_sub.c */ -void T_SUB (); -/*int sfIndex */ +void T_SUB (int sfIndex); /* ... from putCodesEtc.c */ -long putCodesHex (); -long putCodesBin (); -/*int *paramP */ -long getCodesHex (); -long getCodesBin (); -/*int *codePtr */ -void putCodesLog (); +long putCodesHex (FILE *fpstream, int *paramP); +long putCodesBin (FILE *fpstream, int *paramP); +long getCodesHex (FILE *fpcode, int *codePtr); +long getCodesBin (FILE *fpcode, int *codePtr); +void putCodesLog (void); /* ... from makeCoefs.c */ -void widen (); -/*FTYPE lambda, char side */ -void A_SST (); -/*FTYPE *wCoefPtr, FTYPE *ssCoefPtr */ +void widen (FTYPE lambda, char side); +void A_SST (FTYPE *wCoefPtr, FTYPE *ssCoefPtr); /* ... from r_sub.c */ -void R_SUB (); +void R_SUB (void); /* ... from weightedSnr.c */ -void printSnr (); +void printSnr (FILE *fplog); /* ... from freeSpace.c */ -void freeSpace (); +void freeSpace (void); /* external definitions */ #include "edef.i" diff --git a/src/mnru/CMakeLists.txt b/src/mnru/CMakeLists.txt index 51d6bf86..23b587de 100644 --- a/src/mnru/CMakeLists.txt +++ b/src/mnru/CMakeLists.txt @@ -1,12 +1,12 @@ include_directories(../utl) -add_executable(mnrudemo mnrudemo.c mnru.c ../utl/ugst-utl.c filtering_routines.c) +add_executable(mnrudemo mnrudemo.c mnru.c ../utl/ugst-utl.c filtering_routines.c ../utl/wav_io.c) target_link_libraries(mnrudemo ${M_LIBRARY}) add_executable(p50fbmnru p50fbmnru.c mnru.c ../utl/ugst-utl.c filtering_routines.c ) target_link_libraries(p50fbmnru ${M_LIBRARY}) -add_executable(snr calc-snr.c) +add_executable(snr calc-snr.c ../utl/wav_io.c) target_link_libraries(snr ${M_LIBRARY}) #TEST: MNRU @@ -88,7 +88,7 @@ add_test(p50fbmnru_Q0_clipping_clamp ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/p50fbmnru add_test(p50fbmnru_Q0_clipping_clamp-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/P501_D_AM_fm_FB_48k_Q0_clamp.ref test_data/P501_D_AM_fm_FB_48k_Q0_clamp.pcm) add_test(p50fbmnru_Q0_clipping_overflow ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/p50fbmnru test_data/P501_D_AM_fm_FB_48k.pcm test_data/P501_D_AM_fm_FB_48k_Q0_overflow.pcm 0 M --overflow) -add_test(p50fbmnru_Q0_clipping_overflow-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/P501_D_AM_fm_FB_48k_Q0_overflow.ref test_data/P501_D_AM_fm_FB_48k_Q0_overflow.pcm) +add_test(p50fbmnru_Q0_clipping_overflow-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/signal-diff -q -equiv 1 test_data/P501_D_AM_fm_FB_48k_Q0_overflow.ref test_data/P501_D_AM_fm_FB_48k_Q0_overflow.pcm) #TEST: Compute SNR for MNRU files #TODO: no automatic verification data available diff --git a/src/mnru/calc-snr.c b/src/mnru/calc-snr.c index 62c37150..6e0944f3 100644 --- a/src/mnru/calc-snr.c +++ b/src/mnru/calc-snr.c @@ -51,6 +51,7 @@ #include #include #include +#include "wav_io.h" #if defined(VMS) #include @@ -136,7 +137,8 @@ int main (int argc, char *argv[]) { char out_is_file = NO, oper; int i, k, l, K; char File1[MAX_STRLEN], File2[MAX_STRLEN]; - FILE *F1, *F2, *Fo = stdout; + AUDIO_FILE *F1, *F2; + FILE *Fo = stdout; #ifdef VMS char mrs[15] = "mrs="; #endif @@ -224,24 +226,23 @@ int main (int argc, char *argv[]) { out_is_file = YES; } - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - stat (File1, &st); - N2 = st.st_size / (N * sizeof (short)); - } + /* N2 will be computed after opening files */ /* Open input files */ - if ((F1 = fopen (File1, RB)) == NULL) + if ((F1 = audio_open_read (File1, 0, 0, 16)) == NULL) KILL (File1, 2); - if ((F2 = fopen (File2, RB)) == NULL) + if ((F2 = audio_open_read (File2, 0, 0, 16)) == NULL) KILL (File2, 3); + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = audio_get_data_size (F1) / (N * sizeof (short)); + /* Positions file to the starting of block N1 */ N1--; /* for the 1st block is not 1 but 0! */ - if (fseek (F1, N1 * N * sizeof (short), 0) != 0l) + if (audio_seek (F1, N1 * N * sizeof (short)) != 0l) KILL (File1, 5); - if (fseek (F2, N1 * N * sizeof (short), 0) != 0l) + if (audio_seek (F2, N1 * N * sizeof (short)) != 0l) KILL (File2, 6); /* Allocate memory for SNR vector */ @@ -266,7 +267,7 @@ int main (int argc, char *argv[]) { /* Down to work */ for (i = 0; i < N2; i++) { - if ((l = fread (a, sizeof (short), N, F1)) > 0 && (k = fread (b, sizeof (short), N, F2)) > 0) { + if ((l = audio_read (F1, a, N)) > 0 && (k = audio_read (F2, b, N)) > 0) { oper = i == 0 ? SNR_RESET : (i == N2 - 1 ? SNR_STOP : SNR_MEASURE); total_snr_dB = get_SNR (oper, a, b, N, N2, &state); } else { @@ -315,8 +316,8 @@ int main (int argc, char *argv[]) { } /* Closing... */ - fclose (F1); - fclose (F2); + audio_close (F1); + audio_close (F2); if (out_is_file) fclose (Fo); #ifndef VMS diff --git a/src/mnru/mnru.c b/src/mnru/mnru.c index bdb3c3b3..40b6580b 100644 --- a/src/mnru/mnru.c +++ b/src/mnru/mnru.c @@ -723,7 +723,7 @@ double *P50_MNRU_process(char operation, MNRU_state *s, double* input, double* o return (NULL); /* Seed for random number generation (NO LONGER USED) */ - s->seed = NULL; + s->seed = 0; /* Gain for signal path */ if (mode == MOD_NOISE) diff --git a/src/mnru/mnrudemo.c b/src/mnru/mnrudemo.c index a05f28a5..9f112a14 100644 --- a/src/mnru/mnrudemo.c +++ b/src/mnru/mnrudemo.c @@ -75,6 +75,7 @@ /* ... Include of utilities ... */ #include "ugst-utl.h" +#include "wav_io.h" /* @@ -138,8 +139,7 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[80], FileOut[80]; - FILE *Fi, *Fo; - int fhi, fho; + AUDIO_FILE *Fi, *Fo; #ifdef VMS char mrs[15]; #endif @@ -261,14 +261,7 @@ int main (int argc, char *argv[]) { /* Find starting byte in file */ start_byte = sizeof (short) * (long) (--N1) * (long) N; - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = (st.st_size - start_byte) / (N * sizeof (short)); - } + /* N2 will be computed after opening file if processing the whole file */ /* Allocate memory for data vectors */ if ((inp = (float *) calloc (N, sizeof (float))) == NULL) @@ -280,17 +273,19 @@ int main (int argc, char *argv[]) { #ifdef VMS sprintf (mrs, "mrs=%d", 2 * N); #endif - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); - fhi = fileno (Fi); + + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = audio_get_data_size (Fi) / (N * sizeof (short)); /* Creates output file */ - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); - fho = fileno (Fo); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* INSERTION OF MODULATED NOISE ACCORDING TO P.810 */ @@ -305,7 +300,7 @@ int main (int argc, char *argv[]) { /* Read samples ... */ for (cur_frame = 0; cur_frame < N2; cur_frame++) { /* Read samples ... */ - if ((l = fread (Buf, sizeof (short), N, Fi)) < 0) + if ((l = audio_read (Fi, Buf, N)) < 0) KILL (FileIn, 5); /* Information on processing phase */ @@ -330,7 +325,7 @@ int main (int argc, char *argv[]) { over += fl2sh_16bit ((long) l, out, Buf, 1); /* Save data to file */ - if ((l = fwrite (Buf, sizeof (short), l, Fo)) <= 0) + if ((l = audio_write (Fo, Buf, l)) <= 0) KILL (FileOut, 4); } @@ -341,8 +336,8 @@ int main (int argc, char *argv[]) { fprintf (stderr, "\nOverflow samples: %ld", over); fprintf (stderr, "\nClipped noise samples: %ld", state.clip); fprintf (stderr, "\n"); - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); #ifndef VMS return (0); #endif diff --git a/src/mnru/p50fbmnru.c b/src/mnru/p50fbmnru.c index e21cd6fb..e850a0c4 100644 --- a/src/mnru/p50fbmnru.c +++ b/src/mnru/p50fbmnru.c @@ -14,8 +14,12 @@ #define random_MNRU new_random_MNRU /* Defines minimum and maximum value for a short int. */ +#ifndef SHRT_MIN #define SHRT_MIN -32768 +#endif +#ifndef SHRT_MAX #define SHRT_MAX +32767 +#endif void show_use(void) { @@ -45,7 +49,7 @@ int main(int argc, char *argv[]) { MNRU_state state; FILE *In, *Out; - char dcFilterMode ; + char dcFilterMode = 0; short B_Len, BuffLen; long lFileLen = 0; int i, B_Max; diff --git a/src/mnru/snr.c b/src/mnru/snr.c index c90beb9c..0f975a37 100644 --- a/src/mnru/snr.c +++ b/src/mnru/snr.c @@ -54,6 +54,7 @@ float get_SNR (int mode, short *a, short *b, long N, long N2, SNR_state * s) { s->tot_smpno = 0; s->total_err = 0; s->total_sqr = 0; + s->total_snr_dB = 0; } diff --git a/src/reverb/CMakeLists.txt b/src/reverb/CMakeLists.txt index 04e36d63..d6beb2d0 100644 --- a/src/reverb/CMakeLists.txt +++ b/src/reverb/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(../utl) -add_executable(reverb reverb.c reverb-lib.c) +add_executable(reverb reverb.c reverb-lib.c ../utl/wav_io.c) target_link_libraries(reverb ${M_LIBRARY}) #NOTE: Test depends on endianess! diff --git a/src/reverb/reverb.c b/src/reverb/reverb.c index 0c000ebc..bdee0fa1 100644 --- a/src/reverb/reverb.c +++ b/src/reverb/reverb.c @@ -39,6 +39,7 @@ /* UGST modules */ #include "ugstdemo.h" +#include "wav_io.h" #include "reverb-lib.h" @@ -68,8 +69,8 @@ static void display_usage () { int main (int argc, char *argv[]) { /* File variables */ - FILE *ptr_fileIn; - FILE *ptr_fileOut; + AUDIO_FILE *ptr_fileIn; + AUDIO_FILE *ptr_fileOut; FILE *ptr_fileIR; char FileIn[MAX_STRLEN]; char FileIR[MAX_STRLEN]; @@ -149,14 +150,14 @@ int main (int argc, char *argv[]) { fclose (ptr_fileIR); /* open the input file */ - ptr_fileIn = fopen (FileIn, "rb"); + ptr_fileIn = audio_open_read (FileIn, 0, 0, 16); if (ptr_fileIn == NULL) { fprintf (stderr, "\nUnable to open Input file\n"); exit (-1); } /* open the output file */ - ptr_fileOut = fopen (FileOut, "wb"); + ptr_fileOut = audio_open_write (FileOut, audio_get_sample_rate (ptr_fileIn), 1, 16); if (ptr_fileOut == NULL) { fprintf (stderr, "\nUnable to open Output file\n"); exit (-1); @@ -178,15 +179,15 @@ int main (int argc, char *argv[]) { /* .......FILTERING OPERATION ........ */ /* Filter the sound File */ - while (!feof (ptr_fileIn)) { - count = (long) fread (buffIn + N - 1, sizeof (short), N, ptr_fileIn); /* read a block of the input file */ + while (!feof (ptr_fileIn->fp)) { + count = (long) fread (buffIn + N - 1, sizeof (short), N, ptr_fileIn->fp); /* read a block of the input file */ local_sat_pos = conv (IR, buffIn, buffRvb, alignFact, N, count); /* convolves a block of the input file with the impulse response */ if (local_sat_pos >= 0) { fprintf (stderr, "\nWarning warning!! Saturation(s) in output file. In sample %ld\n", local_sat_pos + global_count); } global_count += count; - fwrite (buffRvb, sizeof (short), count, ptr_fileOut); /* output the processed block */ + fwrite (buffRvb, sizeof (short), count, ptr_fileOut->fp); /* output the processed block */ shift (buffIn, N); /* shift a part of the input buffer (to keep the N-1 last samples of the input file for the next processing) */ } @@ -201,8 +202,8 @@ int main (int argc, char *argv[]) { free (buffRvb); free (IR); /* close the opened files */ - fclose (ptr_fileIn); - fclose (ptr_fileOut); + audio_close (ptr_fileIn); + audio_close (ptr_fileOut); return (0); diff --git a/src/rpeltp/CMakeLists.txt b/src/rpeltp/CMakeLists.txt index 6ffd124b..0cd0c48e 100644 --- a/src/rpeltp/CMakeLists.txt +++ b/src/rpeltp/CMakeLists.txt @@ -1,7 +1,7 @@ include_directories(../g711) include_directories(../utl) -add_executable(rpedemo rpedemo.c add.c code.c debug.c decode.c long_ter.c lpc.c preproce.c rpe.c gsm_dest.c gsm_deco.c gsm_enco.c gsm_expl.c gsm_impl.c gsm_crea.c gsm_prin.c gsm_opti.c rpeltp.c short_te.c table.c ../g711/g711.c) +add_executable(rpedemo rpedemo.c add.c code.c debug.c decode.c long_ter.c lpc.c preproce.c rpe.c gsm_dest.c gsm_deco.c gsm_enco.c gsm_expl.c gsm_impl.c gsm_crea.c gsm_prin.c gsm_opti.c rpeltp.c short_te.c table.c ../g711/g711.c ../utl/wav_io.c) target_link_libraries(rpedemo ${M_LIBRARY}) add_executable(test-add add_test.c) diff --git a/src/rpeltp/rpedemo.c b/src/rpeltp/rpedemo.c index 562943b3..5632a00f 100644 --- a/src/rpeltp/rpedemo.c +++ b/src/rpeltp/rpedemo.c @@ -120,6 +120,7 @@ #include "private.h" #include "gsm.h" #include "rpeltp.h" +#include "wav_io.h" /* ..... G.711 module definitions ..... */ #include "g711.h" @@ -205,7 +206,7 @@ int main (argc, argv) /* File variables */ char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN]; - FILE *Fi, *Fo; + AUDIO_FILE *Fi, *Fo; long start_byte; char format, run_encoder, run_decoder; #ifdef VMS @@ -279,18 +280,7 @@ int main (argc, argv) /* Find staring byte in file; all are 16-bit word-aligned =>short data type */ start_byte = sizeof (short) * (long) (--N1) * (long) N; - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - /* convert to block count, depending on whether the input file is a uncoded or coded file */ - if (run_encoder) - N2 = (st.st_size - start_byte) / (N * sizeof (short)); - else - N2 = (st.st_size - start_byte) / (RPE_FRAME_SIZE * sizeof (short)); - } + /* N2 will be computed after opening file if processing the whole file */ /* Choose A/u law */ if (format == A_LAW) { @@ -325,14 +315,23 @@ int main (argc, argv) #endif /* Opening input/output files; abort if there's any problem */ - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, 8000, 0, 16)) == NULL) KILL (FileIn, 2); - if ((Fo = fopen (FileOut, WB)) == NULL) + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) { + long data_size = audio_get_data_size (Fi); + if (run_encoder) + N2 = (data_size - start_byte) / (N * sizeof (short)); + else + N2 = (data_size - start_byte) / (RPE_FRAME_SIZE * sizeof (short)); + } + + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* ......... CREATE AND INIT GSM OBJECT (STATE VARIABLE) ......... */ @@ -354,14 +353,14 @@ int main (argc, argv) memset (inp_buf, (int) 0, N); /* Read a block of uncoded samples */ - if ((smpno = fread (inp_buf, sizeof (short), (long) N, Fi)) <= 0) + if ((smpno = audio_read (Fi, inp_buf, (long) N)) <= 0) break; } else { /* Reset frame vector */ memset (rpe_frame, (int) 0, (long) RPE_FRAME_SIZE); /* Read a unpacked frame */ - if ((smpno = fread (rpe_frame, sizeof (short), (long) RPE_FRAME_SIZE, Fi)) <= 0) + if ((smpno = audio_read (Fi, rpe_frame, (long) RPE_FRAME_SIZE)) <= 0) break; } @@ -388,7 +387,7 @@ int main (argc, argv) } /* Save samples to file */ - if (!(smpno = fwrite (out_buf, sizeof (short), (long) smpno, Fo))) + if (!(smpno = audio_write (Fo, out_buf, (long) smpno))) break; } /* ENCODER-ONLY OPERATION */ @@ -401,7 +400,7 @@ int main (argc, argv) /* Run only the encoder, unpack frame and save rpe-ltp frame */ rpeltp_encode (rpe_enc_state, inp_buf, rpe_frame); - if (!(smpno = fwrite (rpe_frame, sizeof (short), RPE_FRAME_SIZE, Fo))) + if (!(smpno = audio_write (Fo, rpe_frame, RPE_FRAME_SIZE))) break; } /* DECODER-ONLY OPERATION */ @@ -416,23 +415,23 @@ int main (argc, argv) } /* Save the decoded samples */ - if (!(smpno = fwrite (out_buf, sizeof (short), (long) N, Fo))) + if (!(smpno = audio_write (Fo, out_buf, (long) N))) break; } count += smpno; } /* Check for errors */ - if (ferror (Fi)) + if (ferror (Fi->fp)) KILL (FileIn, 6); - else if (ferror (Fo)) + else if (ferror (Fo->fp)) KILL (FileOut, 7); /* ......... FINALIZATIONS ......... */ /* Close input and output files and state */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); rpeltp_delete (rpe_enc_state); rpeltp_delete (rpe_dec_state); diff --git a/src/stereoop/CMakeLists.txt b/src/stereoop/CMakeLists.txt index 6f2e55fa..f7f83808 100644 --- a/src/stereoop/CMakeLists.txt +++ b/src/stereoop/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(../utl) -add_executable(stereoop stereoop.c) +add_executable(stereoop stereoop.c ../utl/wav_io.c) target_link_libraries(stereoop ${M_LIBRARY}) add_test(stereoop1-interleave ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/stereoop -q -interleave test_data/sample.L.32k.1ch.smp test_data/sample.R.32k.1ch.smp test_data/sample.LR.32k.2ch.smp ) diff --git a/src/stereoop/stereoop.c b/src/stereoop/stereoop.c index 932c3e71..0a683958 100644 --- a/src/stereoop/stereoop.c +++ b/src/stereoop/stereoop.c @@ -25,6 +25,7 @@ v1.03 Feb 2, 2010: #include #include #include /* memset, strcmp */ +#include "wav_io.h" /* ..... Definitions used by the program ..... */ #define VERSION "stereoop.c 1.03 Feb 2, 2010" @@ -98,8 +99,8 @@ short n_infiles[N_MODES] = { 2, 1, 1, 1, 1, 1 }; short n_outfiles[N_MODES] = { 1, 2, 1, 1, 1, 1 }; int main (int argc, char *argv[]) { - FILE *Fif[MAX_IFILES]; /* Pointer to input files */ - FILE *Fof[MAX_OFILES]; /* Pointer to output files */ + AUDIO_FILE *Fif[MAX_IFILES]; /* Pointer to input files */ + AUDIO_FILE *Fof[MAX_OFILES]; /* Pointer to output files */ char ifname[MAX_IFILES][MAX_STRLEN]; /* Input file names */ char ofname[MAX_OFILES][MAX_STRLEN]; /* Output file names */ char tmp_str[MAX_STR]; @@ -180,13 +181,13 @@ int main (int argc, char *argv[]) { /* Open files */ for (i = 0; i < n_infiles[mode]; i++) { - if ((Fif[i] = fopen (ifname[i], RB)) == NULL) { + if ((Fif[i] = audio_open_read (ifname[i], 0, 0, 16)) == NULL) { sprintf (tmp_str, "Could not open input file %d,(%s)\n", i + 1, ifname[i]); error_terminate (tmp_str, 1); } } for (i = 0; i < n_outfiles[mode]; i++) { - if ((Fof[i] = fopen (ofname[i], WB)) == NULL) { + if ((Fof[i] = audio_open_write (ofname[i], audio_get_sample_rate (Fif[0]), 1, 16)) == NULL) { sprintf (tmp_str, "Could not create output file %d,(%s)\n", i + 1, ofname[i]); error_terminate (tmp_str, 1); } @@ -195,11 +196,11 @@ int main (int argc, char *argv[]) { /* start of actual operation */ memset (tmp_short, 0, sizeof (short) * 2); if (mode == INTER) { /* read two mono file samples */ - while ((n_in = fread (tmp_short, sizeof (short), 1, Fif[0])) == 1) { - if ((n_in = fread (&tmp_short[1], sizeof (short), 1, Fif[1])) != 1) { + while ((n_in = audio_read (Fif[0], tmp_short, 1)) == 1) { + if ((n_in = audio_read (Fif[1], &tmp_short[1], 1)) != 1) { error_terminate ("Error, 1ch input file 2(right), shorter than 1ch input file 1(Left)\n", 1); } - if ((n_out = fwrite (tmp_short, sizeof (short), 2, Fof[0])) != 2) { + if ((n_out = audio_write (Fof[0], tmp_short, 2)) != 2) { error_terminate ("Error, could not write to 2ch output stereo file \n", 1); } cnt_samples++; @@ -207,18 +208,18 @@ int main (int argc, char *argv[]) { } /* while (1ch,1ch)->2ch */ /* check if samples are still available in right channel */ - if ((n_in = fread (&tmp_short[1], sizeof (short), 1, Fif[1])) != 0) { + if ((n_in = audio_read (Fif[1], &tmp_short[1], 1)) != 0) { error_terminate ("Error, 1ch input file 1(Left), shorter than 1ch input file 2(right)!\n", 1); } } else { /* reading of 2ch stereo file input samples */ - while ((n_in = fread (tmp_short, sizeof (short), 2, Fif[0])) == 2) { + while ((n_in = audio_read (Fif[0], tmp_short, 2)) == 2) { if (mode == SPLIT) { - if ((n_out = fwrite (tmp_short, sizeof (short), 1, Fof[0])) != 1) { + if ((n_out = audio_write (Fof[0], tmp_short, 1)) != 1) { error_terminate ("Error, could not write to 1ch output file 1 (Left)\n", 1); } - if ((n_out = fwrite (&tmp_short[1], sizeof (short), 1, Fof[1])) != 1) { + if ((n_out = audio_write (Fof[1], &tmp_short[1], 1)) != 1) { error_terminate ("Error, could not write to 1ch output file 2 (Right)\n", 1); } } else { /* all 2ch to 1ch options */ @@ -253,7 +254,7 @@ int main (int argc, char *argv[]) { error_terminate ("Error, illegal mode option\n", 1); break; } - if ((n_out = fwrite (tmp_short_1ch, sizeof (short), 1, Fof[0])) != 1) { + if ((n_out = audio_write (Fof[0], tmp_short_1ch, 1)) != 1) { error_terminate ("Error, could not write to 1ch output file 1\n", 1); } } @@ -273,10 +274,10 @@ int main (int argc, char *argv[]) { fprintf (stdout, "(Total %ld samples processed)\n\n", cnt_samples); } for (i = 0; i < n_infiles[mode]; i++) { - fclose (Fif[i]); + audio_close (Fif[i]); } for (i = 0; i < n_outfiles[mode]; i++) { - fclose (Fof[i]); + audio_close (Fof[i]); } return 0; } diff --git a/src/sv56/.gitignore b/src/sv56/.gitignore new file mode 100644 index 00000000..a4b86269 --- /dev/null +++ b/src/sv56/.gitignore @@ -0,0 +1,3 @@ +**/*.out +test_data/voice.prc +test_data/voice.rms \ No newline at end of file diff --git a/src/sv56/CMakeLists.txt b/src/sv56/CMakeLists.txt index 099a7861..dac870a9 100644 --- a/src/sv56/CMakeLists.txt +++ b/src/sv56/CMakeLists.txt @@ -1,17 +1,146 @@ include_directories(../g711) include_directories(../utl) -add_executable(sv56demo sv56demo.c sv-p56.c ../utl/ugst-utl.c) +add_executable(sv56demo sv56demo.c sv-p56.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(sv56demo ${M_LIBRARY}) -add_executable(actlev actlevel.c sv-p56.c ../utl/ugst-utl.c) +add_executable(actlev actlevel.c sv-p56.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(actlev ${M_LIBRARY}) add_test(sv56demo1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q test_data/voice.src test_data/voice.prc 256 1 0 -30) -add_test(sv56demo1-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/voice.nrm test_data/voice.prc) +set_tests_properties(sv56demo1 PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo1-verify ${CMAKE_COMMAND} -E compare_files test_data/voice.nrm test_data/voice.prc) +set_tests_properties(sv56demo1-verify PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) add_test(sv56demo2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q -rms test_data/voice.src test_data/voice.rms 256 1 0 -30) -add_test(sv56demo2-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/voice.ltl test_data/voice.rms) +set_tests_properties(sv56demo2 PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo2-verify ${CMAKE_COMMAND} -E compare_files test_data/voice.ltl test_data/voice.rms) +set_tests_properties(sv56demo2-verify PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) add_test(sv56demo3 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/actlev -q test_data/voice.src test_data/voice.nrm test_data/voice.prc test_data/voice.ltl test_data/voice.rms) +set_tests_properties(sv56demo3 PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +# 12-bit backward compatibility test +add_test(sv56demo4 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q -log test_data/voice_12bit.log test_data/voice.src test_data/voice_12bit.prc 256 1 0 -30 16000 12) +set_tests_properties(sv56demo4 PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) +add_test(sv56demo4-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q test_data/voice_12bit.nrm test_data/voice_12bit.prc) +set_tests_properties(sv56demo4-verify PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS sv56demo4) +add_test(sv56demo4-log-verify ${CMAKE_COMMAND} + -DGOT=${CMAKE_CURRENT_SOURCE_DIR}/test_data/voice_12bit.log + -DEXPECTED=${CMAKE_CURRENT_SOURCE_DIR}/test_data/voice_12bit.log.ref + -DLABEL=sv56demo4-log + -P ${CMAKE_SOURCE_DIR}/cmake/CompareTextFiles.cmake) +set_tests_properties(sv56demo4-log-verify PROPERTIES DEPENDS sv56demo4) + +# WAV integration tests +add_test(sv56demo-wav-24bit-normal ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q test_data/speech_normal_24bit.wav test_data/speech_normal_24bit.out) +set_tests_properties(sv56demo-wav-24bit-normal PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-24bit-normal-verify ${CMAKE_COMMAND} -E compare_files test_data/speech_normal_24bit.ref test_data/speech_normal_24bit.out) +set_tests_properties(sv56demo-wav-24bit-normal-verify PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-32bit ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q test_data/speech_normal_32bit.wav test_data/speech_normal_32bit.out) +set_tests_properties(sv56demo-wav-32bit PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-32bit-verify ${CMAKE_COMMAND} -E compare_files test_data/speech_normal_32bit.ref test_data/speech_normal_32bit.out) +set_tests_properties(sv56demo-wav-32bit-verify PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-24bit ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q test_data/speech_quiet_24bit.wav test_data/speech_quiet_24bit.out) +set_tests_properties(sv56demo-wav-24bit PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-24bit-verify ${CMAKE_COMMAND} -E compare_files test_data/speech_quiet_24bit.ref test_data/speech_quiet_24bit.out) +set_tests_properties(sv56demo-wav-24bit-verify PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-float ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q test_data/speech_quiet_32bit_float.wav test_data/speech_quiet_32bit_float.out) +set_tests_properties(sv56demo-wav-float PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-float-verify ${CMAKE_COMMAND} -E compare_files test_data/speech_quiet_32bit_float.ref test_data/speech_quiet_32bit_float.out) +set_tests_properties(sv56demo-wav-float-verify PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-vquiet-32bit ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q test_data/speech_vquiet_32bit.wav test_data/speech_vquiet_32bit.out) +set_tests_properties(sv56demo-wav-vquiet-32bit PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-vquiet-32bit-verify ${CMAKE_COMMAND} -E compare_files test_data/speech_vquiet_32bit.ref test_data/speech_vquiet_32bit.out) +set_tests_properties(sv56demo-wav-vquiet-32bit-verify PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-vquiet-16bit-adc ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q -bits 16 test_data/speech_vquiet_32bit.wav test_data/speech_vquiet_32bit_16bit.out) +set_tests_properties(sv56demo-wav-vquiet-16bit-adc PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-vquiet-16bit-adc-verify ${CMAKE_COMMAND} -E compare_files test_data/speech_vquiet_32bit_16bit.ref test_data/speech_vquiet_32bit_16bit.out) +set_tests_properties(sv56demo-wav-vquiet-16bit-adc-verify PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +# WAV text output (statistics) verification tests +add_test(sv56demo-wav-24bit-normal-log ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q -log test_data/speech_normal_24bit.log test_data/speech_normal_24bit.wav test_data/speech_normal_24bit.out) +set_tests_properties(sv56demo-wav-24bit-normal-log PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-24bit-normal-log-verify ${CMAKE_COMMAND} + -DGOT=${CMAKE_CURRENT_SOURCE_DIR}/test_data/speech_normal_24bit.log + -DEXPECTED=${CMAKE_CURRENT_SOURCE_DIR}/test_data/speech_normal_24bit.log.ref + -DLABEL=sv56demo-wav-24bit-normal-log + -P ${CMAKE_SOURCE_DIR}/cmake/CompareTextFiles.cmake) + +add_test(sv56demo-wav-32bit-log ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q -log test_data/speech_normal_32bit.log test_data/speech_normal_32bit.wav test_data/speech_normal_32bit.out) +set_tests_properties(sv56demo-wav-32bit-log PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-32bit-log-verify ${CMAKE_COMMAND} + -DGOT=${CMAKE_CURRENT_SOURCE_DIR}/test_data/speech_normal_32bit.log + -DEXPECTED=${CMAKE_CURRENT_SOURCE_DIR}/test_data/speech_normal_32bit.log.ref + -DLABEL=sv56demo-wav-32bit-log + -P ${CMAKE_SOURCE_DIR}/cmake/CompareTextFiles.cmake) + +add_test(sv56demo-wav-vquiet-32bit-log ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q -log test_data/speech_vquiet_32bit.log test_data/speech_vquiet_32bit.wav test_data/speech_vquiet_32bit.out) +set_tests_properties(sv56demo-wav-vquiet-32bit-log PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-vquiet-32bit-log-verify ${CMAKE_COMMAND} + -DGOT=${CMAKE_CURRENT_SOURCE_DIR}/test_data/speech_vquiet_32bit.log + -DEXPECTED=${CMAKE_CURRENT_SOURCE_DIR}/test_data/speech_vquiet_32bit.log.ref + -DLABEL=sv56demo-wav-vquiet-32bit-log + -P ${CMAKE_SOURCE_DIR}/cmake/CompareTextFiles.cmake) + +add_test(sv56demo-wav-vquiet-16bit-adc-log ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q -log test_data/speech_vquiet_32bit_16bit.log -bits 16 test_data/speech_vquiet_32bit.wav test_data/speech_vquiet_32bit_16bit.out) +set_tests_properties(sv56demo-wav-vquiet-16bit-adc-log PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(sv56demo-wav-vquiet-16bit-adc-log-verify ${CMAKE_COMMAND} + -DGOT=${CMAKE_CURRENT_SOURCE_DIR}/test_data/speech_vquiet_32bit_16bit.log + -DEXPECTED=${CMAKE_CURRENT_SOURCE_DIR}/test_data/speech_vquiet_32bit_16bit.log.ref + -DLABEL=sv56demo-wav-vquiet-16bit-adc-log + -P ${CMAKE_SOURCE_DIR}/cmake/CompareTextFiles.cmake) + +# actlev WAV integration tests +add_test(actlev-wav-24bit ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/actlev -q -log test_data/actlev_normal_24bit.log test_data/speech_normal_24bit.wav) +set_tests_properties(actlev-wav-24bit PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(actlev-wav-24bit-verify ${CMAKE_COMMAND} + -DGOT=${CMAKE_CURRENT_SOURCE_DIR}/test_data/actlev_normal_24bit.log + -DEXPECTED=${CMAKE_CURRENT_SOURCE_DIR}/test_data/actlev_normal_24bit.log.ref + -DLABEL=actlev-wav-24bit + -P ${CMAKE_SOURCE_DIR}/cmake/CompareTextFiles.cmake) + +add_test(actlev-wav-vquiet-32bit ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/actlev -q -log test_data/actlev_vquiet_32bit.log test_data/speech_vquiet_32bit.wav) +set_tests_properties(actlev-wav-vquiet-32bit PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(actlev-wav-vquiet-32bit-verify ${CMAKE_COMMAND} + -DGOT=${CMAKE_CURRENT_SOURCE_DIR}/test_data/actlev_vquiet_32bit.log + -DEXPECTED=${CMAKE_CURRENT_SOURCE_DIR}/test_data/actlev_vquiet_32bit.log.ref + -DLABEL=actlev-wav-vquiet-32bit + -P ${CMAKE_SOURCE_DIR}/cmake/CompareTextFiles.cmake) + +add_test(actlev-wav-vquiet-16bit-adc ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/actlev -q -bits 16 -log test_data/actlev_vquiet_32bit_16bit.log test_data/speech_vquiet_32bit.wav) +set_tests_properties(actlev-wav-vquiet-16bit-adc PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_test(actlev-wav-vquiet-16bit-adc-verify ${CMAKE_COMMAND} + -DGOT=${CMAKE_CURRENT_SOURCE_DIR}/test_data/actlev_vquiet_32bit_16bit.log + -DEXPECTED=${CMAKE_CURRENT_SOURCE_DIR}/test_data/actlev_vquiet_32bit_16bit.log.ref + -DLABEL=actlev-wav-vquiet-16bit-adc + -P ${CMAKE_SOURCE_DIR}/cmake/CompareTextFiles.cmake) + +add_test(actlev-wav-multi ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/actlev -q -log test_data/actlev_multi.log test_data/speech_normal_24bit.wav test_data/speech_vquiet_32bit.wav) +set_tests_properties(actlev-wav-multi PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) +add_test(actlev-wav-multi-verify ${CMAKE_COMMAND} + -DGOT=${CMAKE_CURRENT_SOURCE_DIR}/test_data/actlev_multi.log + -DEXPECTED=${CMAKE_CURRENT_SOURCE_DIR}/test_data/actlev_multi.log.ref + -DLABEL=actlev-wav-multi + -P ${CMAKE_SOURCE_DIR}/cmake/CompareTextFiles.cmake) diff --git a/src/sv56/README.md b/src/sv56/README.md index 0cf60760..30dd6898 100644 --- a/src/sv56/README.md +++ b/src/sv56/README.md @@ -6,72 +6,73 @@ CODING STANDARDS". ============================================================= -The UGST P.56 speech voltmeter module, version 3.1 (21/Aug/95), needs the -following files: +# UGST P.56 Speech Voltmeter -# C program code -``` -sv-p56.c ........ the speech voltmeter (SV) module itself; needs the - prototypes in sv-p56.h -sv-p56.h ........ prototypes and definitions needed by the SV module. -``` +Measures and equalizes active speech levels according to ITU-T Recommendation +P.56. Includes `sv56demo` (measure + equalize) and `actlev` (measure only). -# Additional modules needed (see directory ../utl): -``` -ugst-utl.c ...... UGST utilities' module: conversion between float and short - data formats functions/macros and gain/loss function. -ugst-utl.h ...... prototypes and definitions needed by the UGST utilities' - module. -ugstdemo.h ...... prototypes and definitions needed by UGST demo programs. -``` +# WAV file support -# Demo -``` -sv56demo.c ...... Demonstration program for the SV module; needs the files - sv-p56.c, ugst-utl.c, ugst-utl.h, and ugstdemo.h in the - current directory. -actlevel.c ...... Demo program that only measures the level/min/max/etc for - all the files given in the command line. In MSDOS, needs - wildargs.obj when using Borland compilers, in order to - be able to automatically process commands like - actlev *.src - This is not a concern in Unix because wildcard expansion - is included in the shell. Wildcard expansion is *not* - implemented in VMS (sorry). Please mind that the -q option - gives a more compact listing of the file statistics. -``` +`sv56demo` transparently supports WAV files (8/16/24/32-bit PCM and 32-bit +IEEE float). The format is auto-detected from the RIFF header; raw PCM files +continue to work as before (assumed 16-bit, native byte order). + +When a WAV file is detected: +- Bit depth and sample rate are read from the header +- The `-bits` flag overrides the A/D resolution used by the P.56 algorithm + (must be ≤ file bit depth), simulating a lower-resolution ADC/DAC +- Output format matches the input (WAV output if filename ends in `.wav`) + +## Benefits of higher bit depths + +The P.56 speech voltmeter's ability to detect and measure speech depends on +the signal being above the quantization noise floor. Higher bit depths +provide more dynamic range: + +| Bit depth | Dynamic range | Noise floor | +|-----------|--------------|-------------| +| 16-bit | ~96 dB | -96 dBov | +| 24-bit | ~144 dB | -144 dBov | +| 32-bit | ~192 dB | -192 dBov | + +### Test results: very quiet speech (-91 dBov) + +| Resolution | Active level | Activity | Result | +|------------|-------------|----------|--------| +| 32-bit | -91.029 dBov | 90.2% | Speech correctly detected and measured | +| 16-bit ADC | — | 0% | **Signal below noise floor — undetectable** | + +With 32-bit resolution, the speech voltmeter correctly measures a signal at +-91 dBov with 90% activity. With a 16-bit ADC simulation (`-bits 16`), the +same signal falls below the quantization threshold and the algorithm reports +zero activity — it cannot distinguish speech from silence. + +For signals at normal levels (-26 dBov), all bit depths produce identical +measurements, confirming full backward compatibility. -# Makefiles +# Source files -Makefiles have been provided for automatic build-up of the executable program -and to process a test file. ``` -makefile.djc: ... make file for MSDOS port of gcc -makefile.tcc .... DOS make file, for tcc -makefile.unx .... make file for Unix machines. Set up for gcc, may be tailored +sv-p56.c ........ P.56 speech voltmeter module +sv-p56.h ........ prototypes and definitions for the SV module +sv56demo.c ...... demo program: measure active level and equalize +actlevel.c ...... demo program: measure level/min/max for multiple files ``` -# Test file +# Dependencies (from ../utl) -The file `voice.src`, also used for testing the IS54 VSELP, is needed -for testing the sv-p56 demo programs. A reference, normalized file, -is available in the ZIP-compatible archive sv56-tst.zip. [pk]unzip is -necessary to extract the reference processed file. The contents of this -archive file is, as reported by unzip: ``` - Length Method Size Ratio Date Time CRC-32 Name - ------ ------ ---- ----- ---- ---- ------ ---- - 105472 Deflate 79982 24% 01-12-95 10:23 66211f99 voice.nrm - 105472 Deflate 80086 24% 08-21-95 12:25 8d3c67bf voice.ltl - ------ ------ --- ------- - 210944 160068 24% 2 +ugst-utl.c ...... float/short conversion and gain/loss functions +ugst-utl.h ...... prototypes for UGST utilities +ugstdemo.h ...... macros for UGST demo programs +wav_io.c ........ WAV file I/O (auto-detect, read, write) +wav_io.h ........ WAV I/O prototypes ``` -NOTE! This file is in the big-endian (high-byte first) format. Therefore, - before using under MSDOS or VAX/VMS, the files need to be byte-swapped. - See unsupported program sb in the ../unsup directory. If testing is - done using the provided makefiles, they will attempt to carry out - the necessary byte-swapping for voice.nrm. For this, a version of - the utility awk (gawk is preferred) must be available in the path. +# Test data --- -- +The `test_data/` directory contains: +- `voice.src` — raw 16-bit PCM test signal +- `voice.nrm`, `voice.ltl` — reference outputs for regression tests +- `speech_*.wav` — WAV test files at various bit depths and levels +- `*.ref`, `*.log.ref` — reference outputs for binary and text comparison diff --git a/src/sv56/actlevel.c b/src/sv56/actlevel.c index 0fc01e5d..86dac198 100644 --- a/src/sv56/actlevel.c +++ b/src/sv56/actlevel.c @@ -155,6 +155,7 @@ /* ... Include of utilities ... */ #include "ugst-utl.h" +#include "wav_io.h" /* ... Local definitions ... */ #define DEF_BLK_LEN 256 /* samples per block */ @@ -423,16 +424,19 @@ int main (int argc, char *argv[]) { /* File-related variables */ char FileIn[150]; - FILE *Fi; /* input file pointer */ + AUDIO_FILE *Fi; /* input file pointer */ FILE *out = stdout; /* where to print the statistical results */ #ifdef VMS char mrs[15]; #endif /* Other variables */ - short buffer[4096]; + short short_buf[4096]; + long long_buf[4096]; float Buf[4096]; - long start_byte, bitno = 16; + long start_byte, bitno = 16, k; + char user_set_bitno = 0; + int file_bitno, is_float; double sf = 16000; /* Hz */ double ActiveLeveldB, level = 0, gain = 0; static char funny[] = "|/-\\|/-\\", funny_size = sizeof (funny), quiet = 0; @@ -470,8 +474,9 @@ int main (int argc, char *argv[]) { argv++; argc--; } else if (strcmp (argv[1], "-bits") == 0) { - /* Change default sampling frequency */ + /* Change default A/D resolution */ bitno = atoi (argv[2]); + user_set_bitno = 1; /* Update argc/argv to next valid option/argument */ argv += 2; @@ -543,9 +548,6 @@ int main (int argc, char *argv[]) { start_byte *= N * sizeof (short); N2_ori = N2; - /* Overflow (saturation) point */ - Overflow = pow ((double) 2.0, (double) (bitno - 1)); - /* REPEAT FOR ALL FILES IN THE COMMAND LINE */ while (argc > 1) { @@ -554,30 +556,44 @@ int main (int argc, char *argv[]) { argv++; argc--; - /* Reset variables for speech level measurements */ - init_speech_voltmeter (&state, sf); - /* ......... FILE PREPARATION ......... */ /* Opening input file; abort if there's any problem */ -#ifdef VMS - sprintf (mrs, "mrs=%d", 2 * N); -#endif - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, 0, 0, 0)) == NULL) KILL (FileIn, 2); + /* If WAV, derive file bit depth and sample rate from header */ + if (audio_is_wav (Fi)) { + file_bitno = Fi->bits_per_sample; + if (audio_get_sample_rate (Fi) > 0) + sf = (double) audio_get_sample_rate (Fi); + if (!user_set_bitno) + bitno = file_bitno; + } else { + file_bitno = 16; + } + is_float = (audio_is_wav (Fi) && Fi->audio_format == 3); + if (is_float && !user_set_bitno) + bitno = 32; + + /* Overflow (saturation) point */ + Overflow = is_float ? 1.0 : pow ((double) 2.0, (double) (file_bitno - 1)); + + /* Reset variables for speech level measurements */ + init_speech_voltmeter (&state, sf, (int)bitno); + /* Reinitialize number of blocks as specified initially */ N2 = N2_ori; /* Check if is to process the whole file */ if (N2 == 0) { - struct stat st; - stat (FileIn, &st); - N2 = ceil (st.st_size / (double) (N * sizeof (short))); + int bps = file_bitno / 8; + long data_size = audio_get_data_size (Fi); + N2 = ceil ((data_size - start_byte) / (double) (N * bps)); } /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0) KILL (FileIn, 4); @@ -587,19 +603,27 @@ int main (int argc, char *argv[]) { if (!quiet) fprintf (stderr, " Processing \r"); for (i = 0; i < N2; i++) { - if ((l = fread (buffer, sizeof (short), N, Fi)) > 0) { - /* ... Convert samples to float */ - sh2fl ((long) l, buffer, Buf, bitno, 1); - - /* ... Get the active level */ - ActiveLeveldB = speech_voltmeter (Buf, (long) l, &state); - - /* Print progress flag */ - if (!quiet) - fprintf (stderr, "%c\r", funny[i % funny_size]); + if (is_float) { + if ((l = audio_read (Fi, Buf, N)) <= 0) + KILL (FileIn, 5); + } else if (file_bitno <= 16) { + if ((l = audio_read (Fi, short_buf, N)) <= 0) + KILL (FileIn, 5); + for (k = 0; k < l; k++) + Buf[k] = (float) ((double) short_buf[k] / Overflow); } else { - KILL (FileIn, 5); + if ((l = audio_read (Fi, long_buf, N)) <= 0) + KILL (FileIn, 5); + for (k = 0; k < l; k++) + Buf[k] = (float) ((double) long_buf[k] / Overflow); } + + /* ... Get the active level */ + ActiveLeveldB = speech_voltmeter (Buf, (long) l, &state); + + /* Print progress flag */ + if (!quiet) + fprintf (stderr, "%c\r", funny[i % funny_size]); } if (!quiet) fprintf (stderr, "\n"); @@ -681,7 +705,7 @@ int main (int argc, char *argv[]) { #endif /* LOCAL_PRINT */ /* Close current file */ - fclose (Fi); + audio_close (Fi); } /* FINALIZATIONS */ diff --git a/src/sv56/sv-p56.c b/src/sv56/sv-p56.c index 8c0bc420..a09fe7c3 100644 --- a/src/sv56/sv-p56.c +++ b/src/sv56/sv-p56.c @@ -223,21 +223,23 @@ double bin_interp (double upcount, double lwcount, double upthr, double lwthr, d #define M 15.9 /* in [dB] */ #define THRES_NO 15 /* number of thresholds in the speech voltmeter */ -void init_speech_voltmeter (SVP56_state * state, double sampl_freq) { +void init_speech_voltmeter (SVP56_state * state, double sampl_freq, int bitno) { double x; long I, j; /* First initializations */ state->f = sampl_freq; + state->bitno = bitno; + state->thres_no = bitno - 1; I = floor (H * state->f + 0.5); - /* Inicialization of threshold vector */ - for (x = 0.5, j = 1; j <= THRES_NO; j++, x /= 2.0) - state->c[THRES_NO - j] = x; + /* Inicialization of threshold vector: geometric progression from 0.5 down to 2^-(bitno-1) */ + for (x = 0.5, j = 1; j <= state->thres_no; j++, x /= 2.0) + state->c[state->thres_no - j] = x; /* Inicialization of activity and hangover count vectors */ - for (j = 0; j < THRES_NO; j++) { + for (j = 0; j < state->thres_no; j++) { state->a[j] = 0; state->hang[j] = I; } @@ -247,8 +249,8 @@ void init_speech_voltmeter (SVP56_state * state, double sampl_freq) { /* Inicialization of other quantities referring to state variables */ state->max = 0; - state->maxP = -32768.; - state->maxN = 32767.; + state->maxP = -pow(2.0, (double)(bitno - 1)); + state->maxN = pow(2.0, (double)(bitno - 1)) - 1.0; /* Defining the 0 dB reference level in terms of normalized values */ state->refdB = 0 /* dBov */ ; @@ -350,7 +352,7 @@ double speech_voltmeter (float *buffer, long smpno, SVP56_state * state) { int I, j; long k; double g, x, AdB, CdB, AmdB, CmdB, ActiveSpeechLevel; - double LongTermLevel, Delta[15]; + double LongTermLevel, Delta[SVP56_MAX_THRESHOLDS]; /* Some initializations */ @@ -380,7 +382,7 @@ double speech_voltmeter (float *buffer, long smpno, SVP56_state * state) { state->q = g * (state->q) + (1 - g) * (state->p); /* Applies threshold to the envelope q */ - for (j = 0; j < THRES_NO; j++) { + for (j = 0; j < state->thres_no; j++) { if ((state->q) >= state->c[j]) { state->a[j]++; state->hang[j] = 0; @@ -412,7 +414,7 @@ double speech_voltmeter (float *buffer, long smpno, SVP56_state * state) { return (ActiveSpeechLevel); /* Proceed serially for steps 2 and up -- this is the most common case */ - for (j = 1; j < THRES_NO; j++) { + for (j = 1; j < state->thres_no; j++) { if (state->a[j] != 0) { AdB = 10 * log10 (((state->sq) / state->a[j]) + MIN_LOG_OFFSET); CdB = 20 * log10 (((double) state->c[j]) + MIN_LOG_OFFSET); diff --git a/src/sv56/sv-p56.h b/src/sv56/sv-p56.h index c21116f9..5eb9e600 100644 --- a/src/sv56/sv-p56.h +++ b/src/sv56/sv-p56.h @@ -11,7 +11,7 @@ COPYRIGHT NOTE: This source code, and all of its derivations, is subject to the "ITU-T General Public License". Please have it read in the distribution disk, or in the ITU-T - Recommendation G.191 on "SOFTWARE TOOLS FOR SPEECH AND AUDIO + Recommendation G.191 on "SOFTWARE TOOLS FOR SPEECH AND AUDIO CODING STANDARDS". ============================================================= @@ -19,15 +19,15 @@ 28.Feb.92 v1.0 First version 18.May.92 v1.1 Prototype of new init_speech_voltmeter; removal of `init` parameter in speech_voltmeter; - macros for accessing SVP56_state statistics. + macros for accessing SVP56_state statistics. - 01.Sep.95 v2.2 Updated version number to match sv-p56.c and added + 01.Sep.95 v2.2 Updated version number to match sv-p56.c and added smart prototypes ============================================================================ */ #ifndef SPEECH_VOLTMETER_defined -#define SPEECH_VOLTMETER_defined 220 +#define SPEECH_VOLTMETER_defined 230 /* DEFINITION FOR SMART PROTOTYPES */ #ifndef ARGS @@ -38,12 +38,26 @@ #endif #endif +/* + * Maximum bit depth supported by the speech voltmeter. + * Increase this constant if higher bit depths are needed. + */ +#define SVP56_MAX_NO_BITS 32 + +/* + * Maximum number of thresholds supported by the speech voltmeter. + * Derived from SVP56_MAX_NO_BITS: thres_no = bitno - 1. + */ +#define SVP56_MAX_THRESHOLDS (SVP56_MAX_NO_BITS - 1) + /* State for speech voltmeter function */ typedef struct { float f; /* sampling frequency, in Hz */ - unsigned long a[15]; /* activity count */ - double c[15]; /* threshold level; 15 is the no.of thres. */ - unsigned long hang[15]; /* hangover count */ + unsigned long a[SVP56_MAX_THRESHOLDS]; /* activity count per threshold */ + double c[SVP56_MAX_THRESHOLDS]; /* threshold level */ + unsigned long hang[SVP56_MAX_THRESHOLDS]; /* hangover count */ + int thres_no; /* actual number of thresholds in use (bitno-1) */ + int bitno; /* bit depth of input signal (default 16) */ unsigned long n; /* number of samples read since last reset */ double s; /* sum of all samples since last reset */ double sq; /* squared sum of samples since last reset */ @@ -59,7 +73,7 @@ typedef struct { /* Speech voltmeter prototypes */ double bin_interp ARGS ((double upcount, double lwcount, double upthr, double lwthr, double Margin, double tol)); -void init_speech_voltmeter ARGS ((SVP56_state * state, double sampl_freq)); +void init_speech_voltmeter ARGS ((SVP56_state * state, double sampl_freq, int bitno)); double speech_voltmeter ARGS ((float *buffer, long smpno, SVP56_state * state)); diff --git a/src/sv56/sv56demo.c b/src/sv56/sv56demo.c index 89fb4cc5..a2387698 100644 --- a/src/sv56/sv56demo.c +++ b/src/sv56/sv56demo.c @@ -185,6 +185,7 @@ /* ... Include of utilities ... */ #include "ugst-utl.h" +#include "wav_io.h" /* Local definitions */ #define MIN_LOG_OFFSET 1.0e-20 /* To avoid sigularity with log(0.0) */ @@ -424,7 +425,7 @@ int main (int argc, char *argv[]) { /* Parameters for operation */ double Overflow; /* Max.positive value for AD_resolution bits */ - long N = 256, N1 = 1, N2 = 0, i, l; + long N = 256, N1 = 1, N2 = 0, i, l, k; double NdB = -26; /* dBov */ /* Intermediate storage variables for speech voltmeter */ @@ -432,7 +433,7 @@ int main (int argc, char *argv[]) { /* File-related variables */ char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN]; - FILE *Fi, *Fo; /* input/output file pointers */ + AUDIO_FILE *Fi, *Fo; /* input/output file pointers */ FILE *out = stdout; /* where to print the statistical results */ #ifdef VMS char mrs[15]; @@ -440,13 +441,16 @@ int main (int argc, char *argv[]) { /* Other variables */ char quiet = 0, use_active_level = 1, long_summary = 1; - short buffer[4096]; + short short_buf[4096]; /* for 8/16-bit reads */ + long long_buf[4096]; /* for 24/32-bit reads */ + int write_buf32[4096]; /* for 32-bit writes (4 bytes each) */ float Buf[4096]; long NrSat = 0, start_byte, bitno = 16; + char user_set_bitno = 0, is_float = 0; + int bps, file_bitno; double sf = 16000, factor; double ActiveLeveldB, DesiredSpeechLeveldB; static char funny[5] = { '/', '-', '\\', '|', '-' }; - static unsigned mask[5] = { 0xFFFF, 0xFFFE, 0xFFFB, 0xFFF8, 0xFFF0 }; /* ......... GET PARAMETERS ......... */ @@ -471,8 +475,9 @@ int main (int argc, char *argv[]) { argv += 2; argc -= 2; } else if (strcmp (argv[1], "-bits") == 0) { - /* Change default sampling frequency */ + /* Change default A/D resolution */ bitno = atol (argv[2]); + user_set_bitno = 1; /* Update argc/argv to next valid option/argument */ argv += 2; @@ -557,44 +562,65 @@ int main (int argc, char *argv[]) { FIND_PAR_D (7, "_Sampling Frequency: ................... ", sf, sf); FIND_PAR_L (8, "_A/D resolution: ....................... ", bitno, bitno); + /* Validate bitno */ + if (bitno < 1 || bitno > 32) { + fprintf (stderr, "Error: bitno must be between 1 and 32\n"); + exit (1); + } + +/* + * ......... FILE PREPARATION ......... + */ + + /* Opening input file; auto-detects WAV vs raw */ + if ((Fi = audio_open_read (FileIn, 0, 0, 0)) == NULL) + KILL (FileIn, 2); + + /* If WAV, derive file bit depth and sample rate from header */ + if (audio_is_wav (Fi)) { + file_bitno = Fi->bits_per_sample; + if (audio_get_sample_rate (Fi) > 0) + sf = (double) audio_get_sample_rate (Fi); + if (!user_set_bitno) + bitno = file_bitno; + else if (bitno > file_bitno) { + fprintf (stderr, "Error: requested resolution (%ld bits) exceeds file bit depth (%d)\n", bitno, file_bitno); + exit (1); + } + } else { + file_bitno = 16; /* raw PCM is always 16-bit */ + } + + /* Check if input is IEEE float format */ + is_float = (audio_is_wav (Fi) && Fi->audio_format == 3); + if (is_float && !user_set_bitno) + bitno = 32; + + /* Bytes per sample for the file format */ + bps = file_bitno / 8; /* ......... SOME INITIALIZATIONS ......... */ start_byte = --N1; - start_byte *= N * sizeof (short); + start_byte *= N * bps; /* Check if is to process the whole file */ if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); + long data_size = audio_get_data_size (Fi); + N2 = ceil ((data_size - start_byte) / (double) (N * bps)); } - /* Overflow (saturation) point */ - Overflow = pow ((double) 2.0, (double) (bitno - 1)); + /* Overflow (saturation) point: file_overflow for normalization, Overflow for algorithm */ + Overflow = is_float ? 1.0 : pow ((double) 2.0, (double) (file_bitno - 1)); /* reset variables for speech level measurements */ - init_speech_voltmeter (&state, sf); - - -/* - * ......... FILE PREPARATION ......... - */ - - /* Opening input file; abort if there's any problem */ -#ifdef VMS - sprintf (mrs, "mrs=%d", 2 * N); -#endif - if ((Fi = fopen (FileIn, RB)) == NULL) - KILL (FileIn, 2); + init_speech_voltmeter (&state, sf, (int)bitno); /* Creates output file */ - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, (long) sf, 1, file_bitno)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0) KILL (FileIn, 4); @@ -607,19 +633,27 @@ int main (int argc, char *argv[]) { /* Process selected blocks */ for (i = 0; i < N2; i++) { /* Read samples ... */ - if ((l = fread (buffer, sizeof (short), N, Fi)) > 0) { - /* ... Convert samples to float */ - sh2fl ((long) l, buffer, Buf, bitno, 1); - - /* ... Get the active level */ - ActiveLeveldB = speech_voltmeter (Buf, (long) l, &state); - - /* Print some preliminary information */ - if (!quiet) - printf ("%c\r", funny[i % 5]); + if (is_float) { + if ((l = audio_read (Fi, Buf, N)) <= 0) + KILL (FileIn, 5); + } else if (file_bitno <= 16) { + if ((l = audio_read (Fi, short_buf, N)) <= 0) + KILL (FileIn, 5); + for (k = 0; k < l; k++) + Buf[k] = (float) ((double) short_buf[k] / Overflow); } else { - KILL (FileIn, 5); + if ((l = audio_read (Fi, long_buf, N)) <= 0) + KILL (FileIn, 5); + for (k = 0; k < l; k++) + Buf[k] = (float) ((double) long_buf[k] / Overflow); } + + /* ... Get the active level */ + ActiveLeveldB = speech_voltmeter (Buf, (long) l, &state); + + /* Print some preliminary information */ + if (!quiet) + printf ("%c\r", funny[i % 5]); } /* Beautify screen ... */ @@ -645,26 +679,60 @@ int main (int argc, char *argv[]) { /* EQUALIZATION: hard clipping (with truncation) */ /* Move pointer to 1st desired block */ - if (fseek (Fi, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0) KILL (FileIn, 4); /* Get data of interest, equalize and de-normalize */ for (i = 0; i < N2; i++) { - if ((l = fread (buffer, sizeof (short), N, Fi)) > 0) { - /* convert samples to float */ - sh2fl ((long) l, buffer, Buf, bitno, 1); - - /* equalizes vector */ + if (is_float) { + if ((l = audio_read (Fi, Buf, N)) <= 0) + KILL (FileIn, 5); + /* equalizes vector and convert to 32-bit PCM */ + for (k = 0; k < l; k++) { + double val = (double) Buf[k] * factor; + if (val > 1.0 - (1.0 / 2147483648.0)) { val = 1.0 - (1.0 / 2147483648.0); NrSat++; } + else if (val < -1.0) { val = -1.0; NrSat++; } + write_buf32[k] = (int) (val * 2147483648.0); + } + if ((l = audio_write (Fo, write_buf32, l)) < 0) + KILL (FileOut, 6); + } else if (file_bitno <= 16) { + if ((l = audio_read (Fi, short_buf, N)) <= 0) + KILL (FileIn, 5); + /* Use float path for backward-compatible rounding */ + for (k = 0; k < l; k++) + Buf[k] = (float) ((double) short_buf[k] / Overflow); scale (Buf, (long) l, (double) factor); - - /* Convert from float to short with hard clip and truncation */ - NrSat += fl2sh ((long) l, Buf, buffer, (double) 0.0, mask[16 - bitno]); - - /* write equalized, de-normalized and hard-clipped samples to file */ - if ((l = fwrite (buffer, sizeof (short), l, Fo)) < 0) + for (k = 0; k < l; k++) { + double val = (double) Buf[k] * Overflow; + if (val > Overflow - 1.0) { val = Overflow - 1.0; NrSat++; } + else if (val < -Overflow) { val = -Overflow; NrSat++; } + short_buf[k] = (short) val; + } + if ((l = audio_write (Fo, short_buf, l)) < 0) + KILL (FileOut, 6); + } else if (file_bitno == 24) { + if ((l = audio_read (Fi, long_buf, N)) <= 0) + KILL (FileIn, 5); + for (k = 0; k < l; k++) { + double val = (double) long_buf[k] * factor; + if (val > Overflow - 1.0) { val = Overflow - 1.0; NrSat++; } + else if (val < -Overflow) { val = -Overflow; NrSat++; } + long_buf[k] = (long) val; + } + if ((l = audio_write (Fo, long_buf, l)) < 0) KILL (FileOut, 6); } else { - KILL (FileIn, 5); + if ((l = audio_read (Fi, long_buf, N)) <= 0) + KILL (FileIn, 5); + for (k = 0; k < l; k++) { + double val = (double) long_buf[k] * factor; + if (val > Overflow - 1.0) { val = Overflow - 1.0; NrSat++; } + else if (val < -Overflow) { val = -Overflow; NrSat++; } + write_buf32[k] = (int) val; + } + if ((l = audio_write (Fo, write_buf32, l)) < 0) + KILL (FileOut, 6); } } @@ -680,8 +748,8 @@ int main (int argc, char *argv[]) { printf ("---> DONE \n"); /* Close files ... */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); if (out != stdout) fclose (out); #if !defined(VMS) diff --git a/src/sv56/test_data/actlev_multi.log.ref b/src/sv56/test_data/actlev_multi.log.ref new file mode 100644 index 00000000..050558a9 --- /dev/null +++ b/src/sv56/test_data/actlev_multi.log.ref @@ -0,0 +1,2 @@ +Samples: 105472 Min: -5141930 Max: 8227312 DC: 2326.99 RMSLev[dB]: -25.478 ActLev[dB]: -25.023 %Active: 90.044 RMSPkF[dB]: 25.310 ActPkF[dB]: 24.854 test_data/speech_normal_24bit.wav +Samples: 105472 Min: -659712 Max: 1055232 DC: 298.53 RMSLev[dB]: -91.478 ActLev[dB]: -91.029 %Active: 90.181 RMSPkF[dB]: 25.306 ActPkF[dB]: 24.858 test_data/speech_vquiet_32bit.wav diff --git a/src/sv56/test_data/actlev_normal_24bit.log.ref b/src/sv56/test_data/actlev_normal_24bit.log.ref new file mode 100644 index 00000000..79982f46 --- /dev/null +++ b/src/sv56/test_data/actlev_normal_24bit.log.ref @@ -0,0 +1 @@ +Samples: 105472 Min: -5141930 Max: 8227312 DC: 2326.99 RMSLev[dB]: -25.478 ActLev[dB]: -25.023 %Active: 90.044 RMSPkF[dB]: 25.310 ActPkF[dB]: 24.854 test_data/speech_normal_24bit.wav diff --git a/src/sv56/test_data/actlev_vquiet_32bit.log.ref b/src/sv56/test_data/actlev_vquiet_32bit.log.ref new file mode 100644 index 00000000..9373737a --- /dev/null +++ b/src/sv56/test_data/actlev_vquiet_32bit.log.ref @@ -0,0 +1 @@ +Samples: 105472 Min: -659712 Max: 1055232 DC: 298.53 RMSLev[dB]: -91.478 ActLev[dB]: -91.029 %Active: 90.181 RMSPkF[dB]: 25.306 ActPkF[dB]: 24.858 test_data/speech_vquiet_32bit.wav diff --git a/src/sv56/test_data/actlev_vquiet_32bit_16bit.log.ref b/src/sv56/test_data/actlev_vquiet_32bit_16bit.log.ref new file mode 100644 index 00000000..5b2b193f --- /dev/null +++ b/src/sv56/test_data/actlev_vquiet_32bit_16bit.log.ref @@ -0,0 +1 @@ +Samples: 105472 Min: -659712 Max: 1055232 DC: 298.53 RMSLev[dB]: -91.478 ActLev[dB]: -100.000 %Active: 0.000 RMSPkF[dB]: 25.306 ActPkF[dB]: 33.828 test_data/speech_vquiet_32bit.wav diff --git a/src/sv56/test_data/speech_normal_16bit.wav b/src/sv56/test_data/speech_normal_16bit.wav new file mode 100644 index 00000000..a66436b6 Binary files /dev/null and b/src/sv56/test_data/speech_normal_16bit.wav differ diff --git a/src/sv56/test_data/speech_normal_24bit.log.ref b/src/sv56/test_data/speech_normal_24bit.log.ref new file mode 100644 index 00000000..fea652c8 --- /dev/null +++ b/src/sv56/test_data/speech_normal_24bit.log.ref @@ -0,0 +1,19 @@ + ------------------------------------------------------- + Input file: ................... test_data/speech_normal_24bit.wav, 24 bits, fs=16000 Hz + Block Length: ................. 256 [samples] + Starting Block: ............... 1 [] + Number of Blocks: ............. 412 [] + dBov desired for output: ...... -26.000 [dBov] + Norm factor desired is: ....... 0.894 [times] + Max norm WITHOUT saturation: .. -24.854 [dBov] + ------------------------------------------------------- + DC level: ..................... 2327 [PCM] + Maximum positive value: ....... 8227312 [PCM] + Maximum negative value: ....... -5141930 [PCM] + ------------------------------------------------------- + Long term energy (rms): ....... -25.478 [dBov] + Active speech level: .......... -25.023 [dBov] + RMS peak-factor found: ........ 25.310 [dB] + Active peak factor found: ..... 24.854 [dB] + Activity factor: .............. 90.044 [%] + ------------------------------------------------------- diff --git a/src/sv56/test_data/speech_normal_24bit.ref b/src/sv56/test_data/speech_normal_24bit.ref new file mode 100644 index 00000000..7d91f4a8 Binary files /dev/null and b/src/sv56/test_data/speech_normal_24bit.ref differ diff --git a/src/sv56/test_data/speech_normal_24bit.wav b/src/sv56/test_data/speech_normal_24bit.wav new file mode 100644 index 00000000..cdca0c79 Binary files /dev/null and b/src/sv56/test_data/speech_normal_24bit.wav differ diff --git a/src/sv56/test_data/speech_normal_32bit.log.ref b/src/sv56/test_data/speech_normal_32bit.log.ref new file mode 100644 index 00000000..0b7433fa --- /dev/null +++ b/src/sv56/test_data/speech_normal_32bit.log.ref @@ -0,0 +1,19 @@ + ------------------------------------------------------- + Input file: ................... test_data/speech_normal_32bit.wav, 32 bits, fs=16000 Hz + Block Length: ................. 256 [samples] + Starting Block: ............... 1 [] + Number of Blocks: ............. 412 [] + dBov desired for output: ...... -26.000 [dBov] + Norm factor desired is: ....... 0.894 [times] + Max norm WITHOUT saturation: .. -24.854 [dBov] + ------------------------------------------------------- + DC level: ..................... 595710 [PCM] + Maximum positive value: ....... 2106191744 [PCM] + Maximum negative value: ....... -1316334336 [PCM] + ------------------------------------------------------- + Long term energy (rms): ....... -25.478 [dBov] + Active speech level: .......... -25.023 [dBov] + RMS peak-factor found: ........ 25.310 [dB] + Active peak factor found: ..... 24.854 [dB] + Activity factor: .............. 90.044 [%] + ------------------------------------------------------- diff --git a/src/sv56/test_data/speech_normal_32bit.ref b/src/sv56/test_data/speech_normal_32bit.ref new file mode 100644 index 00000000..49c5ac17 Binary files /dev/null and b/src/sv56/test_data/speech_normal_32bit.ref differ diff --git a/src/sv56/test_data/speech_normal_32bit.wav b/src/sv56/test_data/speech_normal_32bit.wav new file mode 100644 index 00000000..7c203d03 Binary files /dev/null and b/src/sv56/test_data/speech_normal_32bit.wav differ diff --git a/src/sv56/test_data/speech_normal_32bit_float.wav b/src/sv56/test_data/speech_normal_32bit_float.wav new file mode 100644 index 00000000..a517054d Binary files /dev/null and b/src/sv56/test_data/speech_normal_32bit_float.wav differ diff --git a/src/sv56/test_data/speech_quiet_16bit.wav b/src/sv56/test_data/speech_quiet_16bit.wav new file mode 100644 index 00000000..419b344e Binary files /dev/null and b/src/sv56/test_data/speech_quiet_16bit.wav differ diff --git a/src/sv56/test_data/speech_quiet_24bit.log.ref b/src/sv56/test_data/speech_quiet_24bit.log.ref new file mode 100644 index 00000000..76aa133c --- /dev/null +++ b/src/sv56/test_data/speech_quiet_24bit.log.ref @@ -0,0 +1,19 @@ + ------------------------------------------------------- + Input file: ................... test_data/speech_quiet_24bit.wav, 24 bits, fs=16000 Hz + Block Length: ................. 256 [samples] + Starting Block: ............... 1 [] + Number of Blocks: ............. 412 [] + dBov desired for output: ...... -26.000 [dBov] + Norm factor desired is: ....... 44.876 [times] + Max norm WITHOUT saturation: .. -24.871 [dBov] + ------------------------------------------------------- + DC level: ..................... 46 [PCM] + Maximum positive value: ....... 164155 [PCM] + Maximum negative value: ....... -102591 [PCM] + ------------------------------------------------------- + Long term energy (rms): ....... -59.478 [dBov] + Active speech level: .......... -59.040 [dBov] + RMS peak-factor found: ........ 25.310 [dB] + Active peak factor found: ..... 24.871 [dB] + Activity factor: .............. 90.403 [%] + ------------------------------------------------------- diff --git a/src/sv56/test_data/speech_quiet_24bit.ref b/src/sv56/test_data/speech_quiet_24bit.ref new file mode 100644 index 00000000..19e05473 Binary files /dev/null and b/src/sv56/test_data/speech_quiet_24bit.ref differ diff --git a/src/sv56/test_data/speech_quiet_24bit.wav b/src/sv56/test_data/speech_quiet_24bit.wav new file mode 100644 index 00000000..ad1029ad Binary files /dev/null and b/src/sv56/test_data/speech_quiet_24bit.wav differ diff --git a/src/sv56/test_data/speech_quiet_32bit.wav b/src/sv56/test_data/speech_quiet_32bit.wav new file mode 100644 index 00000000..86573363 Binary files /dev/null and b/src/sv56/test_data/speech_quiet_32bit.wav differ diff --git a/src/sv56/test_data/speech_quiet_32bit_float.log.ref b/src/sv56/test_data/speech_quiet_32bit_float.log.ref new file mode 100644 index 00000000..00ee7154 --- /dev/null +++ b/src/sv56/test_data/speech_quiet_32bit_float.log.ref @@ -0,0 +1,19 @@ + ------------------------------------------------------- + Input file: ................... test_data/speech_quiet_32bit_float.wav, 32 bits, fs=16000 Hz + Block Length: ................. 256 [samples] + Starting Block: ............... 1 [] + Number of Blocks: ............. 412 [] + dBov desired for output: ...... -26.000 [dBov] + Norm factor desired is: ....... 44.876 [times] + Max norm WITHOUT saturation: .. -24.872 [dBov] + ------------------------------------------------------- + DC level: ..................... 0 [PCM] + Maximum positive value: ....... 0 [PCM] + Maximum negative value: ....... -0 [PCM] + ------------------------------------------------------- + Long term energy (rms): ....... -59.478 [dBov] + Active speech level: .......... -59.040 [dBov] + RMS peak-factor found: ........ 25.310 [dB] + Active peak factor found: ..... 24.872 [dB] + Activity factor: .............. 90.403 [%] + ------------------------------------------------------- diff --git a/src/sv56/test_data/speech_quiet_32bit_float.ref b/src/sv56/test_data/speech_quiet_32bit_float.ref new file mode 100644 index 00000000..27fcc092 Binary files /dev/null and b/src/sv56/test_data/speech_quiet_32bit_float.ref differ diff --git a/src/sv56/test_data/speech_quiet_32bit_float.wav b/src/sv56/test_data/speech_quiet_32bit_float.wav new file mode 100644 index 00000000..f3aac555 Binary files /dev/null and b/src/sv56/test_data/speech_quiet_32bit_float.wav differ diff --git a/src/sv56/test_data/speech_vquiet_32bit.log.ref b/src/sv56/test_data/speech_vquiet_32bit.log.ref new file mode 100644 index 00000000..e2284e77 --- /dev/null +++ b/src/sv56/test_data/speech_vquiet_32bit.log.ref @@ -0,0 +1,19 @@ + ------------------------------------------------------- + Input file: ................... test_data/speech_vquiet_32bit.wav, 32 bits, fs=16000 Hz + Block Length: ................. 256 [samples] + Starting Block: ............... 1 [] + Number of Blocks: ............. 412 [] + dBov desired for output: ...... -26.000 [dBov] + Norm factor desired is: ....... 1784.261 [times] + Max norm WITHOUT saturation: .. -24.858 [dBov] + ------------------------------------------------------- + DC level: ..................... 299 [PCM] + Maximum positive value: ....... 1055232 [PCM] + Maximum negative value: ....... -659712 [PCM] + ------------------------------------------------------- + Long term energy (rms): ....... -91.478 [dBov] + Active speech level: .......... -91.029 [dBov] + RMS peak-factor found: ........ 25.306 [dB] + Active peak factor found: ..... 24.858 [dB] + Activity factor: .............. 90.181 [%] + ------------------------------------------------------- diff --git a/src/sv56/test_data/speech_vquiet_32bit.ref b/src/sv56/test_data/speech_vquiet_32bit.ref new file mode 100644 index 00000000..757bd5c5 Binary files /dev/null and b/src/sv56/test_data/speech_vquiet_32bit.ref differ diff --git a/src/sv56/test_data/speech_vquiet_32bit.wav b/src/sv56/test_data/speech_vquiet_32bit.wav new file mode 100644 index 00000000..310fe13f Binary files /dev/null and b/src/sv56/test_data/speech_vquiet_32bit.wav differ diff --git a/src/sv56/test_data/speech_vquiet_32bit_16bit.log.ref b/src/sv56/test_data/speech_vquiet_32bit_16bit.log.ref new file mode 100644 index 00000000..1e4e978a --- /dev/null +++ b/src/sv56/test_data/speech_vquiet_32bit_16bit.log.ref @@ -0,0 +1,18 @@ + ------------------------------------------------------- + Input file: ................... test_data/speech_vquiet_32bit.wav, 16 bits, fs=16000 Hz + Block Length: ................. 256 [samples] + Starting Block: ............... 1 [] + Number of Blocks: ............. 412 [] + dBov desired for output: ...... -26.000 [dBov] + Activity factor is ZERO -- the file is silence or idle noise + ------------------------------------------------------- + DC level: ..................... 299 [PCM] + Maximum positive value: ....... 1055232 [PCM] + Maximum negative value: ....... -659712 [PCM] + ------------------------------------------------------- + Noise/silence energy (rms): ... -91.478 [dB] + ------------------------------------------------------- +%SV-W-SAT, the dB level chosen causes SATURATION: old max=1055232; new max=5288688069 +%SV-I-MAXLEVDB, the maximum norm factor to PREVENT clipping is -33.828dB; + ------------------------------------------------------- + Number of clippings: .......... 81 [] diff --git a/src/sv56/test_data/speech_vquiet_32bit_16bit.ref b/src/sv56/test_data/speech_vquiet_32bit_16bit.ref new file mode 100644 index 00000000..19994da3 Binary files /dev/null and b/src/sv56/test_data/speech_vquiet_32bit_16bit.ref differ diff --git a/src/sv56/test_data/voice_12bit.log.ref b/src/sv56/test_data/voice_12bit.log.ref new file mode 100644 index 00000000..74d3e0da --- /dev/null +++ b/src/sv56/test_data/voice_12bit.log.ref @@ -0,0 +1,19 @@ + ------------------------------------------------------- + Input file: ................... test_data/voice.src, 12 bits, fs=16000 Hz + Block Length: ................. 256 [samples] + Starting Block: ............... 1 [] + Number of Blocks: ............. 206 [] + dBov desired for output: ...... -30.000 [dBov] + Norm factor desired is: ....... 0.584 [times] + Max norm WITHOUT saturation: .. -24.408 [dBov] + ------------------------------------------------------- + DC level: ..................... 9 [PCM] + Maximum positive value: ....... 29472 [PCM] + Maximum negative value: ....... -19874 [PCM] + ------------------------------------------------------- + Long term energy (rms): ....... -25.478 [dBov] + Active speech level: .......... -25.329 [dBov] + RMS peak-factor found: ........ 24.557 [dB] + Active peak factor found: ..... 24.408 [dB] + Activity factor: .............. 96.625 [%] + ------------------------------------------------------- diff --git a/src/sv56/test_data/voice_12bit.nrm b/src/sv56/test_data/voice_12bit.nrm new file mode 100644 index 00000000..f4271d78 Binary files /dev/null and b/src/sv56/test_data/voice_12bit.nrm differ diff --git a/src/sv56/test_data/voice_16bit.ref b/src/sv56/test_data/voice_16bit.ref new file mode 100644 index 00000000..d6d8ba84 --- /dev/null +++ b/src/sv56/test_data/voice_16bit.ref @@ -0,0 +1 @@ +ActLev[dB]: -25.329 RMSLev[dB]: -25.478 Activity[%]: 96.625 diff --git a/src/sv56/test_data/voice_24.src b/src/sv56/test_data/voice_24.src new file mode 100644 index 00000000..550cb83d Binary files /dev/null and b/src/sv56/test_data/voice_24.src differ diff --git a/src/sv56/test_data/voice_24bit.ref b/src/sv56/test_data/voice_24bit.ref new file mode 100644 index 00000000..d6d8ba84 --- /dev/null +++ b/src/sv56/test_data/voice_24bit.ref @@ -0,0 +1 @@ +ActLev[dB]: -25.329 RMSLev[dB]: -25.478 Activity[%]: 96.625 diff --git a/src/sv56/test_data/voice_32.src b/src/sv56/test_data/voice_32.src new file mode 100644 index 00000000..b82a9840 Binary files /dev/null and b/src/sv56/test_data/voice_32.src differ diff --git a/src/sv56/test_data/voice_32bit.ref b/src/sv56/test_data/voice_32bit.ref new file mode 100644 index 00000000..d6d8ba84 --- /dev/null +++ b/src/sv56/test_data/voice_32bit.ref @@ -0,0 +1 @@ +ActLev[dB]: -25.329 RMSLev[dB]: -25.478 Activity[%]: 96.625 diff --git a/src/unsup/CMakeLists.txt b/src/unsup/CMakeLists.txt old mode 100644 new mode 100755 index 03944831..942cbeaf --- a/src/unsup/CMakeLists.txt +++ b/src/unsup/CMakeLists.txt @@ -3,7 +3,7 @@ include_directories(../utl) add_executable(asc2bin asc2bin.c) target_link_libraries(asc2bin ${M_LIBRARY}) -add_executable(astrip astrip.c) +add_executable(astrip astrip.c ../utl/wav_io.c) target_link_libraries(astrip ${M_LIBRARY}) add_executable(bin2asc bin2asc.c) @@ -19,18 +19,18 @@ target_link_libraries(df ${M_LIBRARY}) add_executable(endian endian.c) -add_executable(fdelay fdelay.c) +add_executable(fdelay fdelay.c ../utl/wav_io.c) target_link_libraries(fdelay ${M_LIBRARY}) -add_executable(measure measure.c) +add_executable(measure measure.c ../utl/wav_io.c) target_link_libraries(measure ${M_LIBRARY}) -add_executable(oper oper.c) +add_executable(oper oper.c ../utl/wav_io.c) target_link_libraries(oper ${M_LIBRARY}) add_executable(sb sb.c) -add_executable(sine sine.c) +add_executable(sine sine.c ../utl/wav_io.c) target_link_libraries(sine ${M_LIBRARY}) add_executable(chr2sh chr2sh.c) @@ -39,6 +39,9 @@ add_executable(sh2chr sh2chr.c) add_executable(crc getcrc32.c) +add_executable(random random.c) +target_link_libraries(random ${M_LIBRARY}) + add_test(astrip1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/astrip -q -smooth -wlen 145 -sample test_data/cftest1.dat test_data/astrip.smp) add_test(astrip1-verify ${CMAKE_COMMAND} -E compare_files test_data/astrip.smp test_data/astrip.ref) @@ -48,11 +51,23 @@ add_test(astrip2-verify ${CMAKE_COMMAND} -E compare_files test_data/astrip.blk t add_test(concat1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/concat -f -undo test_data/undo.txt test_data/concat1.txt test_data/concat2.txt test_data/concat3.tst) add_test(concat1-verify ${CMAKE_COMMAND} -E compare_files test_data/concat3.tst test_data/concat3.txt) -add_test(sb1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sb test_data/bigend.src test_data/bytswpd.tst) -add_test(sb1-verify ${CMAKE_COMMAND} -E compare_files test_data/bytswpd.tst test_data/litend.src) +set(UNSUP_TEST_DATA ${CMAKE_CURRENT_SOURCE_DIR}/test_data) +set(UNSUP_TEST_OUT ${CMAKE_CURRENT_BINARY_DIR}/test_out) +file(MAKE_DIRECTORY ${UNSUP_TEST_OUT}) + +add_test(sb1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sb ${UNSUP_TEST_DATA}/bigend.src ${UNSUP_TEST_OUT}/bytswpd.tst) +set_tests_properties(sb1 PROPERTIES FIXTURES_SETUP SB1_DONE RESOURCE_LOCK SB_FILE) +add_test(sb1-verify ${CMAKE_COMMAND} -E compare_files ${UNSUP_TEST_OUT}/bytswpd.tst ${UNSUP_TEST_DATA}/litend.src) +set_tests_properties(sb1-verify PROPERTIES FIXTURES_REQUIRED SB1_DONE FIXTURES_SETUP SB1_VERIFIED RESOURCE_LOCK SB_FILE) + +# Debug: check file exists before sb2 +add_test(NAME sb2-debug COMMAND ${CMAKE_COMMAND} -E sha256sum ${UNSUP_TEST_OUT}/bytswpd.tst) +set_tests_properties(sb2-debug PROPERTIES FIXTURES_REQUIRED SB1_VERIFIED FIXTURES_SETUP SB2_DEBUG_DONE RESOURCE_LOCK SB_FILE) -add_test(sb2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sb -over test_data/bytswpd.tst) -add_test(sb2-verify ${CMAKE_COMMAND} -E compare_files test_data/bytswpd.tst test_data/bigend.src) +add_test(sb2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sb -over ${UNSUP_TEST_OUT}/bytswpd.tst) +set_tests_properties(sb2 PROPERTIES FIXTURES_REQUIRED SB2_DEBUG_DONE FIXTURES_SETUP SB2_DONE RESOURCE_LOCK SB_FILE) +add_test(sb2-verify ${CMAKE_COMMAND} -E compare_files ${UNSUP_TEST_OUT}/bytswpd.tst ${UNSUP_TEST_DATA}/bigend.src) +set_tests_properties(sb2-verify PROPERTIES FIXTURES_REQUIRED SB2_DONE RESOURCE_LOCK SB_FILE) add_test(fdelay1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/fdelay test_data/bigend.src test_data/delaydft.tst) add_test(fdelay1-verify ${CMAKE_COMMAND} -E compare_files test_data/delaydft.tst test_data/delaydft.ref) @@ -71,3 +86,12 @@ add_test(fdelay5-verify ${CMAKE_COMMAND} -E compare_files test_data/delay-15.tst add_test(fdelay6 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/fdelay -hex 0xF test_data/litend.src test_data/delay-0f.tst) add_test(fdelay6-verify ${CMAKE_COMMAND} -E compare_files test_data/delay-0f.tst test_data/delay-15.ref) + +add_test(random1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/random -s 12345 -r 10 20 -n 5) +set_tests_properties(random1 PROPERTIES PASS_REGULAR_EXPRESSION "12 19 12 14 14") + +add_test(random2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/random -s 42 alpha bravo charlie delta echo) +set_tests_properties(random2 PROPERTIES PASS_REGULAR_EXPRESSION "^alpha ") + +add_test(random3 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/random -s 42 -d 3 -n 3 alpha bravo charlie delta echo) +set_tests_properties(random3 PROPERTIES PASS_REGULAR_EXPRESSION "bravo delta charlie") diff --git a/src/unsup/README.md b/src/unsup/README.md index 4a414471..5a58be27 100644 --- a/src/unsup/README.md +++ b/src/unsup/README.md @@ -56,6 +56,10 @@ oper.c: implement arithmetic operation on two files: add, subtract, multiply or divide two files applying scaling factors (linear or dB), and adding a DC level. +random.c: randomization tool for selecting items from a list or drawing + numbers from a range. Reuses the EID linear congruential + generator from eid.c. + sb.c swap bytes for word-oriented files. For VMS/Unix/MSDOS. sh2chr.c: convert short-oriented (16-bit words) files to char-oriented diff --git a/src/unsup/astrip.c b/src/unsup/astrip.c index 8e7dd52e..379bb8cb 100644 --- a/src/unsup/astrip.c +++ b/src/unsup/astrip.c @@ -61,6 +61,7 @@ ======================================================================== */ #include "ugstdemo.h" +#include "wav_io.h" /* OS definition */ #if defined(__MSDOS__) && !defined(MSDOS) @@ -180,7 +181,7 @@ int main (int argc, char *argv[]) { short *buf; /* file-related variables */ char File1[100], File2[100]; - FILE *fi, *fo; + AUDIO_FILE *fi, *fo; #ifdef VMS char mrs[15] = "mrs="; #endif @@ -311,16 +312,8 @@ int main (int argc, char *argv[]) { /* Define 1st sample to compare */ start_byte = samplesize * N1 * N; - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the size of the full file and discount the number */ - /* ... of samples to skip in the beginning of the file ... */ - stat (File1, &st); - to_process = (st.st_size - start_byte) / samplesize; - N2 = ceil ((st.st_size - start_byte) / (double) (N * samplesize)); - } else + /* N2 will be computed after opening file if processing the whole file */ + if (N2 != 0) to_process = N * N2; /* Opening test file; abort if there's any problem */ @@ -329,13 +322,20 @@ int main (int argc, char *argv[]) { #endif /* Open input files */ - if ((fi = fopen (File1, RB)) == NULL) + if ((fi = audio_open_read (File1, 0, 0, 16)) == NULL) KILL (File1, 3); - if ((fo = fopen (File2, WB)) == NULL) + + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) { + to_process = (audio_get_data_size (fi) - start_byte) / samplesize; + N2 = ceil ((audio_get_data_size (fi) - start_byte) / (double) (N * samplesize)); + } + + if ((fo = audio_open_write (File2, audio_get_sample_rate (fi), 1, 16)) == NULL) KILL (File2, 4); /* Move pointer to 1st block of interest */ - if (fseek (fi, start_byte, 0l) < 0l) + if (audio_seek (fi, start_byte) < 0l) KILL (File1, 3); /* Some preliminaries */ @@ -364,7 +364,7 @@ int main (int argc, char *argv[]) { fprintf (stderr, "%c\r", funny[count % 8]); /* Read samples from input buffer */ - if ((smpno = fread (buf, sizeof (short), N, fi)) == 0) + if ((smpno = audio_read (fi, buf, N)) == 0) break; else if (smpno < 0) KILL (File1, 2); @@ -424,13 +424,13 @@ int main (int argc, char *argv[]) { #endif } } - tot_samples += fwrite (buf, sizeof (short), smpno, fo); + tot_samples += audio_write (fo, buf, smpno); } /* ..... FINALIZATIONS ..... */ fprintf (stderr, "> Total %ld samples extracted\n", tot_samples); - fclose (fi); - fclose (fo); + audio_close (fi); + audio_close (fo); free (buf); #ifndef VMS return (0); diff --git a/src/unsup/compfile.c b/src/unsup/compfile.c index 25693a3f..422bcf4f 100644 --- a/src/unsup/compfile.c +++ b/src/unsup/compfile.c @@ -87,15 +87,12 @@ /* ... Includes for O.S. specific headers ... */ #if defined(MSDOS) #include -#include /* For read(), write(), lseek() */ #include #elif defined(VMS) #include #include #include -#include /* For read(), write(), lseek() */ #else /* Unix */ -#include /* For read(), write(), lseek() */ #include #endif @@ -107,10 +104,10 @@ /* Function prototypes */ void display_usage ARGS ((void)); -long compare_doubles ARGS ((char *File1, char *File2, int fh1, int fh2, long N, long N1, long N2, char quiet, double reltol, double abstol)); -long compare_floats ARGS ((char *File1, char *File2, int fh1, int fh2, long N, long N1, long N2, char quiet, double reltol, float abstol)); -long compare_longs ARGS ((char *File1, char *File2, int fh1, int fh2, long N, long N1, long N2, char KindOfDump, char quiet, double reltol, long abstol)); -long compare_shorts ARGS( (char *File1, char *File2, int fh1, int fh2, long N, long N1, long N2, char KindOfDump, char quiet, double reltol, short abstol) ); +long compare_doubles ARGS ((char *File1, char *File2, FILE *f1, FILE *f2, long N, long N1, long N2, char quiet, double reltol, double abstol)); +long compare_floats ARGS ((char *File1, char *File2, FILE *f1, FILE *f2, long N, long N1, long N2, char quiet, double reltol, float abstol)); +long compare_longs ARGS ((char *File1, char *File2, FILE *f1, FILE *f2, long N, long N1, long N2, char KindOfDump, char quiet, double reltol, long abstol)); +long compare_shorts ARGS( (char *File1, char *File2, FILE *f1, FILE *f2, long N, long N1, long N2, char KindOfDump, char quiet, double reltol, short abstol) ); /* @@ -160,7 +157,7 @@ void display_usage () { /* ------------------------------------------------------------------------- - long compare_floats(char *File1, char *File2, int fh1, int fh2, + long compare_floats(char *File1, char *File2, FILE *f1, FILE *f2, long N, long N1, long N2, char quiet); Compare float data from 2 files and print different samples indicating @@ -171,7 +168,7 @@ void display_usage () { 30.Dec.93 v1.0 Simao -------------------------------------------------------------------------- */ -long compare_floats (char *File1, char *File2, int fh1, int fh2, long N, long N1, long N2, char quiet, double reltol, float abstol) { +long compare_floats (char *File1, char *File2, FILE *f1, FILE *f2, long N, long N1, long N2, char quiet, double reltol, float abstol) { long i, j, l, k, NrDiffs; char c; float *a, *b; @@ -187,7 +184,7 @@ long compare_floats (char *File1, char *File2, int fh1, int fh2, long N, long N1 /* Start loop */ for (c = 0, NrDiffs = i = j = 0; i < N2; i++, j = 0) { if (!(c == 'Q' || c == 'X' || c == 27 || c == 'S')) { - if ((l = read (fh1, a, sizeof (float) * N) / sizeof (float)) > 0 && (k = read (fh2, b, sizeof (float) * N) / sizeof (float)) > 0) + if ((l = fread (a, sizeof (float), N, f1)) > 0 && (k = fread (b, sizeof (float), N, f2)) > 0) while (j < l && j < k) { if( fabs( a[j] - b[j] ) > abstol && RELATIVE_DIFF(a[j],b[j]) > reltol ) { if (!quiet) { @@ -232,7 +229,7 @@ long compare_floats (char *File1, char *File2, int fh1, int fh2, long N, long N1 /* ------------------------------------------------------------------------- - long compare_doubles(char *File1, char *File2, int fh1, int fh2, + long compare_doubles(char *File1, char *File2, FILE *f1, FILE *f2, long N, long N1, long N2, char quiet); Compare double data from 2 files and print different samples indicating @@ -243,7 +240,7 @@ long compare_floats (char *File1, char *File2, int fh1, int fh2, long N, long N1 30.Dec.93 v1.0 Simao -------------------------------------------------------------------------- */ -long compare_doubles (char *File1, char *File2, int fh1, int fh2, long N, long N1, long N2, char quiet, double reltol, double abstol ) { +long compare_doubles (char *File1, char *File2, FILE *f1, FILE *f2, long N, long N1, long N2, char quiet, double reltol, double abstol ) { long i, j, l, k, NrDiffs; char c; double *a, *b; @@ -259,7 +256,7 @@ long compare_doubles (char *File1, char *File2, int fh1, int fh2, long N, long N /* Start loop */ for (c = 0, NrDiffs = i = j = 0; i < N2; i++, j = 0) { if (!(c == 'Q' || c == 'X' || c == 27 || c == 'S')) { - if ((l = read (fh1, a, sizeof (double) * N) / sizeof (double)) > 0 && (k = read (fh2, b, sizeof (double) * N) / sizeof (double)) > 0) + if ((l = fread (a, sizeof (double), N, f1)) > 0 && (k = fread (b, sizeof (double), N, f2)) > 0) while (j < l && j < k) { if ( a[j] != 0 && b[j] != 0 ) if( fabs( a[j] - b[j] ) > abstol && RELATIVE_DIFF( a[j], b[j] ) > reltol ) { @@ -305,7 +302,7 @@ long compare_doubles (char *File1, char *File2, int fh1, int fh2, long N, long N /* ------------------------------------------------------------------------- - long compare_shorts(char *File1, char *File2, int fh1, int fh2, + long compare_shorts(char *File1, char *File2, FILE *f1, FILE *f2, long N, long N1, long N2, char KindOfDump, char quiet); Compare short data from 2 files and print in decimal or hex format the @@ -316,7 +313,7 @@ long compare_doubles (char *File1, char *File2, int fh1, int fh2, long N, long N 30.Dec.93 v1.0 Simao -------------------------------------------------------------------------- */ -long compare_shorts (char *File1, char *File2, int fh1, int fh2, long N, long N1, long N2, char KindOfDump, char quiet, double reltol, short abstol ) { +long compare_shorts (char *File1, char *File2, FILE *f1, FILE *f2, long N, long N1, long N2, char KindOfDump, char quiet, double reltol, short abstol ) { long i, j, l, k, NrDiffs; char c; short *a, *b; @@ -332,7 +329,7 @@ long compare_shorts (char *File1, char *File2, int fh1, int fh2, long N, long N1 /* Start loop */ for (c = 0, NrDiffs = i = j = 0; i < N2; i++, j = 0) { if (!(c == 'Q' || c == 'X' || c == 27 || c == 'S')) { - if ((l = read (fh1, a, sizeof (short) * N) / sizeof (short)) > 0 && (k = read (fh2, b, sizeof (short) * N) / sizeof (short)) > 0) + if ((l = fread (a, sizeof (short), N, f1)) > 0 && (k = fread (b, sizeof (short), N, f2)) > 0) while (j < l && j < k) { if( abs( a[j] - b[j] ) > abstol && RELATIVE_DIFF( a[j], b[j] ) > reltol ) { if (!quiet) { @@ -380,7 +377,7 @@ long compare_shorts (char *File1, char *File2, int fh1, int fh2, long N, long N1 /* ------------------------------------------------------------------------- - long compare_longs(char *File1, char *File2, int fh1, int fh2, + long compare_longs(char *File1, char *File2, FILE *f1, FILE *f2, long N, long N1, long N2, char KindOfDump, char quiet); Compare long data from 2 files and print in decimal or hex format the @@ -391,7 +388,7 @@ long compare_shorts (char *File1, char *File2, int fh1, int fh2, long N, long N1 30.Dec.93 v1.0 Simao -------------------------------------------------------------------------- */ -long compare_longs (char *File1, char *File2, int fh1, int fh2, long N, long N1, long N2, char KindOfDump, char quiet, double reltol, long abstol ) { +long compare_longs (char *File1, char *File2, FILE *f1, FILE *f2, long N, long N1, long N2, char KindOfDump, char quiet, double reltol, long abstol ) { long i, j, l, k, NrDiffs; char c; long *a, *b; @@ -407,7 +404,7 @@ long compare_longs (char *File1, char *File2, int fh1, int fh2, long N, long N1, /* Start loop */ for (c = 0, NrDiffs = i = j = 0; i < N2; i++, j = 0) { if (!(c == 'Q' || c == 'X' || c == 27 || c == 'S')) { - if ((l = read (fh1, a, sizeof (long) * N) / sizeof (long)) > 0 && (k = read (fh2, b, sizeof (long) * N) / sizeof (long)) > 0) + if ((l = fread (a, sizeof (long), N, f1)) > 0 && (k = fread (b, sizeof (long), N, f2)) > 0) while (j < l && j < k) { if( labs( a[j] - b[j] ) > abstol && RELATIVE_DIFF( a[j], b[j] ) > reltol ) { if (!quiet) { @@ -454,18 +451,17 @@ long compare_longs (char *File1, char *File2, int fh1, int fh2, long N, long N1, int main (int argc, char *argv[]) { char C[1]; - int fh1, fh2; + FILE *f1, *f2; long N, N1, N2, NrDiffs = 0, tot_smp; long delay = 0, start_byte1, start_byte2, samplesize; char File1[50], File2[50]; char KindOfDump = 'D', TypeOfData = 'I', quiet = 0; - FILE *f1, *f2; struct stat st; long k, l, s1, s2; char *abstol; - double reltol; + double reltol = 0.0; double abstol_double; float abstol_float; long abstol_long; @@ -659,14 +655,11 @@ int main (int argc, char *argv[]) { KILL (File1, 3); if ((f2 = fopen (File2, RB)) == NULL) KILL (File2, 4); - fh1 = fileno (f1); - fh2 = fileno (f2); - /* Move pointer to 1st block of interest */ - if (lseek (fh1, start_byte1, 0l) < 0l) + if (fseek (f1, start_byte1, SEEK_SET) != 0) KILL (File1, 3); - if (lseek (fh2, start_byte2, 0l) < 0l) + if (fseek (f2, start_byte2, SEEK_SET) != 0) KILL (File2, 4); /* Some preliminaries */ @@ -675,19 +668,19 @@ int main (int argc, char *argv[]) { /* Dumps the file to the screen */ switch (TypeOfData) { case 'I': /* short data */ - NrDiffs = compare_shorts (File1, File2, fh1, fh2, N, N1, N2, KindOfDump, quiet, reltol, abstol_short); + NrDiffs = compare_shorts (File1, File2, f1, f2, N, N1, N2, KindOfDump, quiet, reltol, abstol_short); break; case 'L': /* long data */ - NrDiffs = compare_longs (File1, File2, fh1, fh2, N, N1, N2, KindOfDump, quiet, reltol, abstol_long ); + NrDiffs = compare_longs (File1, File2, f1, f2, N, N1, N2, KindOfDump, quiet, reltol, abstol_long ); break; case 'R': /* float data */ - NrDiffs = compare_floats (File1, File2, fh1, fh2, N, N1, N2, quiet, reltol, abstol_float ); + NrDiffs = compare_floats (File1, File2, f1, f2, N, N1, N2, quiet, reltol, abstol_float ); break; case 'D': /* double data */ - NrDiffs = compare_doubles (File1, File2, fh1, fh2, N, N1, N2, quiet, reltol, abstol_double ); + NrDiffs = compare_doubles (File1, File2, f1, f2, N, N1, N2, quiet, reltol, abstol_double ); break; } diff --git a/src/unsup/endian.c b/src/unsup/endian.c index 97ea087a..70990fe9 100644 --- a/src/unsup/endian.c +++ b/src/unsup/endian.c @@ -9,7 +9,7 @@ --------------------------------------------------------------------------- */ -reverse_endian_short (unsigned short *a, unsigned short *b, long n) { +void reverse_endian_short (unsigned short *a, unsigned short *b, long n) { long i; unsigned short register tmp; for (i = 0; i < n; i++) { @@ -26,7 +26,7 @@ reverse_endian_short (unsigned short *a, unsigned short *b, long n) { 06.Oct.97 v1.0 Created --------------------------------------------------------------------------- */ -reverse_endian_long (unsigned long *a, unsigned long *b, long n) { +void reverse_endian_long (unsigned long *a, unsigned long *b, long n) { long i; union { unsigned long tmp; @@ -52,7 +52,7 @@ int is_little_endian () { } void test_s () { - short a, b; + unsigned short a, b; while (1) { fread (&a, 1, sizeof (short), stdin); if (feof (stdin)) @@ -63,7 +63,7 @@ void test_s () { } void test_l () { - long a, b; + unsigned long a, b; while (1) { fread (&a, 1, sizeof (long), stdin); if (feof (stdin)) diff --git a/src/unsup/fdelay.c b/src/unsup/fdelay.c index 57361b78..6b9d6796 100644 --- a/src/unsup/fdelay.c +++ b/src/unsup/fdelay.c @@ -65,6 +65,7 @@ #include /* for memset() */ #include #include "ugstdemo.h" +#include "wav_io.h" #if defined(VMS) #include @@ -93,13 +94,13 @@ ----------------------------------------------------------------------------- */ -long add_delay (short *smp_buf, short sample, short delay, FILE * Fdel, FILE * Fout, FILE * OutFile) { +long add_delay (short *smp_buf, short sample, short delay, AUDIO_FILE * Fdel, AUDIO_FILE * Fout, char * OutFile) { long saved = 0, smpno, i; if (Fdel) { /* Delay comes from a file */ - while ((smpno = fread (smp_buf, sizeof (short), delay, Fdel)) > 0) { - if ((smpno = fwrite (smp_buf, sizeof (short), smpno, Fout)) < 0) + while ((smpno = audio_read (Fdel, smp_buf, delay)) > 0) { + if ((smpno = audio_write (Fout, smp_buf, smpno)) < 0) KILL (OutFile, 7); saved += smpno; } @@ -107,7 +108,7 @@ long add_delay (short *smp_buf, short sample, short delay, FILE * Fdel, FILE * F /* Delay created here */ for (i = 0; i < delay; i++) smp_buf[i] = sample; - if ((saved = fwrite (smp_buf, sizeof (short), delay, Fout)) < delay) + if ((saved = audio_write (Fout, smp_buf, delay)) < delay) KILL (OutFile, 7); } @@ -180,7 +181,7 @@ int main (int argc, char *argv[]) { char InpFile[150], OutFile[150], *delay_file = 0; char quiet = 0, append = 0; short sample = 0; - FILE *Finp, *Fout, *Fdel = 0; + AUDIO_FILE *Finp, *Fout, *Fdel = 0; #ifdef VMS char mrs[15] = "mrs="; #endif @@ -315,13 +316,13 @@ int main (int argc, char *argv[]) { fprintf (stderr, "# %s %ld samples of value %ld (0x%04X).\n", append ? "Appending" : "Delaying", delay, sample, sample); /* Open files; abort on error */ - if ((Finp = fopen (InpFile, RB)) == NULL) + if ((Finp = audio_open_read (InpFile, 0, 0, 16)) == NULL) KILL (InpFile, 3); - if ((Fout = fopen (OutFile, WB)) == NULL) + if ((Fout = audio_open_write (OutFile, audio_get_sample_rate (Finp), 1, 16)) == NULL) KILL (OutFile, 4); if (delay_file) { /* Delay comes from a file - open delay file */ - if ((Fdel = fopen (delay_file, RB)) == NULL) + if ((Fdel = audio_open_read (delay_file, 0, 0, 16)) == NULL) KILL (delay_file, 5); } @@ -334,15 +335,11 @@ int main (int argc, char *argv[]) { /* Check if is to process the whole file */ if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (InpFile, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); + N2 = ceil ((audio_get_data_size (Finp) - start_byte) / (double) (N * sizeof (short))); } /* Move pointer to 1st block of interest */ - if (fseek (Finp, start_byte, 0) < 0l) + if (audio_seek (Finp, start_byte) < 0l) KILL (InpFile, 4); /* Put delay samples in begining of file, if *not* appending */ @@ -352,14 +349,14 @@ int main (int argc, char *argv[]) { /* Copy input file to output file */ for (i = 0; i < N2; i++) { /* Read a block of samples */ - if ((smpno = fread (smp_buf, sizeof (short), N, Finp)) < 0) + if ((smpno = audio_read (Finp, smp_buf, N)) < 0) KILL (InpFile, 6); /* Frame counter */ frame++; /* Write output words */ - if ((smpno = fwrite (smp_buf, sizeof (short), smpno, Fout)) < 0) + if ((smpno = audio_write (Fout, smp_buf, smpno)) < 0) KILL (OutFile, 7); /* Update sample counter */ @@ -375,10 +372,10 @@ int main (int argc, char *argv[]) { /* Free memory, close files */ free (smp_buf); - fclose (Finp); - fclose (Fout); + audio_close (Finp); + audio_close (Fout); if (Fdel) - fclose (Fdel); + audio_close (Fdel); return (0); } diff --git a/src/unsup/measure.c b/src/unsup/measure.c index 68cdddec..3b66eddd 100644 --- a/src/unsup/measure.c +++ b/src/unsup/measure.c @@ -49,6 +49,7 @@ #include #include #include "ugstdemo.h" +#include "wav_io.h" /* Generic defines */ @@ -358,7 +359,7 @@ int main (int argc, char *argv[]) { double avg_x, rms_x, stddev_x, max_x, min_x; - FILE *Fi; + AUDIO_FILE *Fi; /* DEFAULT OPTIONS AND INITIAL VALUES */ @@ -418,13 +419,18 @@ int main (int argc, char *argv[]) { crc_x = init_crc_x; /* Open files */ - if (strcmp (inpfil, "-") == 0) - Fi = stdin; - else if ((Fi = fopen (inpfil, RB)) == NULL) + if (strcmp (inpfil, "-") == 0) { + /* stdin: wrap in a minimal AUDIO_FILE struct */ + static AUDIO_FILE stdin_af; + stdin_af.fp = stdin; + stdin_af.is_wav = 0; + stdin_af.write_mode = 0; + Fi = &stdin_af; + } else if ((Fi = audio_open_read (inpfil, 0, 0, 16)) == NULL) KILL (inpfil, 2); /* Move onto start */ - fseek (Fi, skip * blk * sizeof (short), 0); + audio_seek (Fi, skip * blk * sizeof (short)); /* Allocate memory */ samples = (short *) calloc (blk, sizeof (short)); @@ -432,7 +438,7 @@ int main (int argc, char *argv[]) { error_terminate ("Cannot allocate memory - aborted\n", 1); /* Find statistics */ - while ((count = fread (samples, sizeof (short), blk, Fi)) != 0) { + while ((count = audio_read (Fi, samples, blk)) != 0) { /* Update statistics */ avg_x += get_sum (samples, count); rms_x += get_square (samples, count); @@ -478,7 +484,8 @@ int main (int argc, char *argv[]) { printf ("\t%s\n", inpfil); /* Close file */ - fclose (Fi); + if (strcmp (inpfil, "-") != 0) + audio_close (Fi); } /* EXITING */ diff --git a/src/unsup/oper.c b/src/unsup/oper.c index 92c87872..7416e635 100644 --- a/src/unsup/oper.c +++ b/src/unsup/oper.c @@ -96,6 +96,7 @@ #include /* for memset() */ #include #include "ugstdemo.h" +#include "wav_io.h" /* ... Includes for O.S. specific headers ... */ #if defined(MSDOS) @@ -224,7 +225,7 @@ double divide (double x, double y) { Operate over short int files ------------------------------------------------------------------------- */ -long operate_shorts (char *File1, char *File2, char *File3, int fh1, int fh2, int fh3, long N, long N1, long N2, double A, double B, double C, double (*oper_f) (), char trim_by, double round) { +long operate_shorts (char *File1, char *File2, char *File3, AUDIO_FILE *af1, AUDIO_FILE *af2, AUDIO_FILE *afr, long N, long N1, long N2, double A, double B, double C, double (*oper_f) (), char trim_by, double round) { long i, j, l, k, saved = 0; short *a, *b; register double tmp; @@ -243,7 +244,7 @@ long operate_shorts (char *File1, char *File2, char *File3, int fh1, int fh2, in memset (a, 0, N * sizeof (short)); memset (b, 0, N * sizeof (short)); - if ((l = read (fh1, a, sizeof (short) * N) / sizeof (short)) >= 0 && (k = read (fh2, b, sizeof (short) * N) / sizeof (short)) >= 0) + if ((l = audio_read (af1, a, N)) >= 0 && (k = audio_read (af2, b, N)) >= 0) while (j < l && j < k) { tmp = oper_f (A * (double) a[j], B * (double) b[j]) + C + round; b[j] = (short) (tmp > 32767 ? 32767 : (tmp < -32768 ? -32768 : tmp)); @@ -267,7 +268,7 @@ long operate_shorts (char *File1, char *File2, char *File3, int fh1, int fh2, in b[j] = (short) (tmp > 32767 ? 32767 : (tmp < -32768 ? -32768 : tmp)); } - saved += write (fh3, b, sizeof (short) * j) / sizeof (short); + saved += audio_write (afr, b, j); } return (saved); } @@ -278,7 +279,6 @@ long operate_shorts (char *File1, char *File2, char *File3, int fh1, int fh2, in int main (int argc, char *argv[]) { char c[1], Oper; - int fh1, fh2, fhr; long N, N1, N2, Prcd = 0; long delay = 0, start_byte1, start_byte2, samplesize; @@ -287,7 +287,7 @@ int main (int argc, char *argv[]) { char better_seed = USE_IT, trim_by = 0; static char *trim_str[4] = { "shortest", "first", "second", "longest" }; double A = 0, B = 0, C = 0, (*oper_f) (), round = 0.5; - FILE *f1, *f2, *fr; + AUDIO_FILE *f1, *f2, *fr; #ifdef VMS char mrs[15] = "mrs="; #endif @@ -479,52 +479,40 @@ int main (int argc, char *argv[]) { start_byte2 *= (N1 * N - delay); } - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - long k, l; + /* N2 will be computed after opening files if processing the whole file */ - /* ... find the size of the 2 files and the number of blks from it */ - /* ... hey, need to skip the delayed samples! ... */ - stat (File1, &st); - k = (st.st_size - start_byte1) / (N * samplesize); - stat (File2, &st); - l = (st.st_size - start_byte2) / (N * samplesize); + /* Opening test file; abort if there's any problem */ +#ifdef VMS + sprintf (mrs, "mrs=%d", sizeof (short) * N); +#endif + /* Open input files */ + if ((f1 = audio_open_read (File1, 0, 0, 16)) == NULL) + KILL (File1, 3); + if ((f2 = audio_open_read (File2, 0, 0, 16)) == NULL) + KILL (File2, 4); + + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) { + long k, l; + k = (audio_get_data_size (f1) - start_byte1) / (N * samplesize); + l = (audio_get_data_size (f2) - start_byte2) / (N * samplesize); if (trim_by == 1) N2 = k; else if (trim_by == 2) N2 = l; else if (trim_by == 3) { - /* Trim by the size of the longest file */ N2 = k > l ? k : l; - - /* Convert the trim flag to the equivalent of trimming by the size of file 1 or file 2, the longest of them; this eases implementation */ trim_by = (k > l) ? 1 : 2; } else { - /* Trim by the size of the shortest file */ N2 = k < l ? k : l; } - if (k != l) fprintf (stderr, "WARNING: Files have different sizes!\n"); } - /* Opening test file; abort if there's any problem */ -#ifdef VMS - sprintf (mrs, "mrs=%d", sizeof (short) * N); -#endif - - /* Open input files */ - if ((f1 = fopen (File1, RB)) == NULL) - KILL (File1, 3); - if ((f2 = fopen (File2, RB)) == NULL) - KILL (File2, 4); - if ((fr = fopen (RFile, WB)) == NULL) + if ((fr = audio_open_write (RFile, audio_get_sample_rate (f1), 1, 16)) == NULL) KILL (RFile, 5); - fh1 = fileno (f1); - fh2 = fileno (f2); - fhr = fileno (fr); /* If samples of the primary files are to be skipped, dump them into the output file */ if (delay > 0) { @@ -532,23 +520,23 @@ int main (int argc, char *argv[]) { short *a = (short *) calloc (sizeof (short), delay); double register tmp; - if (lseek (fh1, dump * samplesize, 0l) < 0l) + if (audio_seek (f1, dump * samplesize) < 0l) KILL (File1, 3); - if (read (fh1, a, delay * samplesize) != samplesize * delay) + if (audio_read (f1, a, delay) != delay) KILL (File1, 6); for (i = 0; i < delay; i++) { tmp = (A * (double) a[i] + C + round); a[i] = (short) (tmp > 32767 ? 32767 : (tmp < -32768 ? -32768 : tmp)); } - write (fhr, a, delay * samplesize); + audio_write (fr, a, delay); free (a); } /* Move pointer to 1st block of interest */ - if (lseek (fh1, start_byte1, 0l) < 0l) + if (audio_seek (f1, start_byte1) < 0l) KILL (File1, 3); - if (lseek (fh2, start_byte2, 0l) < 0l) + if (audio_seek (f2, start_byte2) < 0l) KILL (File2, 4); /* Some preliminaries */ @@ -557,7 +545,7 @@ int main (int argc, char *argv[]) { /* Operates on the file to the screen */ switch (TypeOfData) { case 'I': /* short data */ - Prcd = operate_shorts (File1, File2, RFile, fh1, fh2, fhr, N, N1, N2, A, B, C, oper_f, trim_by, round); + Prcd = operate_shorts (File1, File2, RFile, f1, f2, fr, N, N1, N2, A, B, C, oper_f, trim_by, round); break; #ifdef DATA_TYPE_DEFINED @@ -577,8 +565,9 @@ int main (int argc, char *argv[]) { /* Finalizations */ - close (fh1); - close (fh2); + audio_close (f1); + audio_close (f2); + audio_close (fr); #ifndef VMS return (0); #endif diff --git a/src/unsup/random.c b/src/unsup/random.c new file mode 100644 index 00000000..d15e626a --- /dev/null +++ b/src/unsup/random.c @@ -0,0 +1,225 @@ +/*---------------------------------------------------------------------------* + * Randomization tool, V1.1 * + * ------------------------------------------ * + * (C) 2012 Fraunhofer IIS. All rights reserved. * + * * + * =============================================================== * + * COPYRIGHT NOTE: This source code, and all of its derivations, * + * is subject to the "ITU-T General Public License". Please have * + * it read in the distribution disk, or in the ITU-T Recommendation * + * G.191 on "SOFTWARE TOOLS FOR SPEECH AND AUDIO CODING STANDARDS". * + * See LICENSE.md in the top-level directory for terms. * + * =============================================================== * + * * + * The LCS generator is copied from ITU-T G.191, file STL/eid.c. * + * * + * Fraunhofer IIS makes no representation nor warranty in regard to * + * the accuracy, completeness or sufficiency of The Software, nor * + * shall Fraunhofer IIS be held liable for any damages whatsoever * + * relating to use of said Software. * + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include + +#define MAX_ITEMS 1000 +#define VERBOSE 0 +#define DEFAULT_SEED 3141592653U + +typedef enum { + SUBSET = 0, + FROM_RANGE = 1 +} MODE; + +/* +============================================================================ + double EID_random (unsigned long *seed); inherited from STL/eid.c, + ~~~~~~~~~~~~~~~~~ + + Description: + ~~~~~~~~~~~~ + Returns a new random number, generated a linear congruential + sequence (LCS) generator. See: Knuth, D.E. 1981: "Seminumerical + Algorithms" vol.2 of The Art of Computer Programming; Reading, + Mass.; Addison-Wesley. + + Parameters: + ~~~~~~~~~~~ + seed: ... long seed. + + Return value: + ~~~~~~~~~~~~~ + Returns a random number as double in the range 0..1. + + Author: + ~~~~~~~ + History: + ~~~~~~~~ + 28.Feb.92 v1.0 Release of 1st version + 20.Apr.92 v2.0 Change of polinomial generator to LCG + + 26.Jan.98 v3.0 Corrected bug for 64-bit operating systems (where + longs have 64, not 32 bits). Implemented by + , after bug reported + by + 12.Aug.12 v4.0 Changed unsigned long to unsigned int to have identical + behavior on at least Windows, Linux, OSX +============================================================================ */ + +static double EID_random(seed) +unsigned int *seed; +{ + /* Size in bits (=size in bytes * 8) for int variables*/ + static double bits_in_int = sizeof(unsigned int) * 8; + /* Update RNG */ + *seed = ((unsigned int)69069L * (*seed) +1L); + /* Return random number as a double */ +#ifdef WAS + return(pow((double)2.0, (double)-32.0) * (double)(*seed)); +#else + return(pow((double)2.0, -bits_in_int) * (double)(*seed)); +#endif +} + +static void usage() +{ + fprintf( stdout,"usage: random [OPTIONS] [ITEM_LIST]\n" ); + fprintf( stdout," OPTIONS:\n" ); + fprintf( stdout," -s SEED any number in between 0 and %u: as a seed for the RNG, default: %u\n", UINT_MAX, DEFAULT_SEED ); + fprintf( stdout," -d PRERUNS number of dummy pre-runs to alter the seed, default: 0\n" ); + fprintf( stdout," -r START STOP range mode, values define lowest and highest allowed value, not set by default\n" ); + fprintf( stdout," -n NUM_ITEMS select more than one item from the provided item list, default: 1\n" ); + exit(-1); +} + +int main( int argc, char** argv ) +{ + unsigned int seed = DEFAULT_SEED; + MODE mode = SUBSET; + unsigned int num_items = 1; + unsigned int num_dummyruns = 0; + unsigned int items_in_list = 0; + unsigned int selected_item = 0; + unsigned int verbose = 0; + unsigned int i = 0, j = 0; + unsigned int range_start = 0, range_stop = 1; + double rand_f = 0.0f; + char * item_list [MAX_ITEMS] = {0}; + + for(i=1; i= argc) usage(); + seed = atoi(argv[i]); + continue; + } + /* num items to select */ + if(!strcmp(argv[i],"-n")) { + if(++i >= argc) usage(); + num_items = atoi(argv[i]); + continue; + } + /* num dummy runs before the item selection is started - similar to different seed */ + if(!strcmp(argv[i],"-d")) { + if(++i >= argc) usage(); + num_dummyruns = atoi(argv[i]); + continue; + } + /* select item within given range instead of a subset */ + if(!strcmp(argv[i],"-r")) { + mode = FROM_RANGE; + if(++i >= argc) usage(); + range_start = atoi(argv[i]); + if(++i >= argc) usage(); + range_stop = atoi(argv[i]); + continue; + } + break; + } + + if(mode == SUBSET) { + /* list items are the last */ + if(i == (argc)) usage(); + items_in_list = argc - i; + if(items_in_list > MAX_ITEMS) + { + fprintf(stderr, "only up to %u items are supported by this tool\n", MAX_ITEMS); + exit(-2); + } + } + + for(i=0; i items_in_list) + { + fprintf(stderr, "requested %u items, but only %u in list\n", num_items, items_in_list); + exit (-1); + } + + for(i=0; iselected_item && i #include #include "ugstdemo.h" +#ifdef _WIN32 +#include +#endif +#ifndef _WIN32 +#include +#endif #ifdef VMS #include @@ -236,24 +242,23 @@ long decent_approach (FILE * i, FILE * o) { Get a temporary file name, handling ideosynchrasies from different compilers ----------------------------------------------------------------------------- */ -void get_tmp_name (char *fileout) { -#if defined (unix) || defined (__GNUC__) || defined(_MSC_VER) - char *ch; -#endif - - tmpnam (fileout); - -#if defined (unix) || defined (__GNUC__) - ch = strrchr (fileout, '/'); - ch++; - memmove(fileout, ch, strlen(ch)); - -#endif -#ifdef _MSC_VER - ch = strrchr (fileout, '\\'); - ch++; - memmove(fileout, ch, strlen(ch)); +void get_tmp_name (char *fileout, const char *input_file) { + /* Create temp file in same directory as input (rename requires same directory on some platforms) */ + const char *sep; + size_t dirlen; +#ifdef _WIN32 + sep = strrchr(input_file, '\\'); + if (!sep) sep = strrchr(input_file, '/'); +#else + sep = strrchr(input_file, '/'); #endif + if (sep) { + dirlen = (size_t)(sep - input_file + 1); + memcpy(fileout, input_file, dirlen); + sprintf(fileout + dirlen, "sb_tmp_%d.tmp", (int)getpid()); + } else { + sprintf(fileout, "sb_tmp_%d.tmp", (int)getpid()); + } #ifdef DEBUG printf ("Temporary file name: %s\n", fileout); @@ -284,7 +289,7 @@ int main (int argc, char *argv[]) { argc--; fprintf (stderr, "Aya, sir; it's and ILS file!\n"); } else if (!strcmp (argv[1], "-over")) { - get_tmp_name (fileout); + get_tmp_name (fileout, argv[2]); argv++; argc--; overwrite = 1; diff --git a/src/unsup/sine.c b/src/unsup/sine.c index cf4be20e..ad1608ac 100644 --- a/src/unsup/sine.c +++ b/src/unsup/sine.c @@ -75,6 +75,7 @@ #include #include #include +#include "wav_io.h" /* includes for OS specific directives */ #if defined(MSDOS) /* ... DOS ... */ @@ -182,7 +183,7 @@ int main (int argc, char *argv[]) { double refdB = 0; #endif - FILE *Fo; + AUDIO_FILE *Fo; static char FileOut[150]; int N = 256, blk_no = 0, DClevel = 0, AD_resolution = 16; #ifdef STATIC_ALLOCATION @@ -338,7 +339,7 @@ int main (int argc, char *argv[]) { #ifdef VMS sprintf (&mrs[4], "%d", 2 * N); #endif - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, (long) fs, 1, 16)) == NULL) KILL (FileOut, 1); /* Report of what is happening ... */ @@ -388,12 +389,12 @@ int main (int argc, char *argv[]) { } /* Saving the sine; aborts program on failure */ - if (fwrite (data, sizeof (short), N, Fo) != N) + if (audio_write (Fo, data, N) != N) KILL (FileOut, 2); } /* Finalizations */ - fclose (Fo); + audio_close (Fo); #ifndef VMS return (0); #endif diff --git a/src/utl/CMakeLists.txt b/src/utl/CMakeLists.txt index 98a00985..700aa7ab 100644 --- a/src/utl/CMakeLists.txt +++ b/src/utl/CMakeLists.txt @@ -1,10 +1,18 @@ add_executable(spdemo spdemo.c ugst-utl.c) target_link_libraries(spdemo ${M_LIBRARY}) -add_executable(scaldemo scaldemo.c ugst-utl.c) +add_executable(scaldemo scaldemo.c ugst-utl.c wav_io.c) target_link_libraries(scaldemo ${M_LIBRARY}) -add_executable(signal-diff signal-diff.c) +add_executable(signal-diff signal-diff.c wav_io.c) + +add_executable(test_wav_io test_wav_io.c wav_io.c) +add_test(wav_io ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_wav_io) + +add_executable(mkwav mkwav.c wav_io.c) +add_executable(test_wav_io_validate test_wav_io_validate.c wav_io.c) + +include(test_wav_integration.cmake) #TODO Input file is not _yet_ there. add_test(scaldemo1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/scaldemo -q -trunc ../is54/test_data/voice.src test_data/voice.tru 256 1 0 0.5941352) diff --git a/src/utl/mkwav.c b/src/utl/mkwav.c new file mode 100644 index 00000000..2f91ed47 --- /dev/null +++ b/src/utl/mkwav.c @@ -0,0 +1,48 @@ +/* mkwav.c - Create a WAV file from raw PCM data or silence. + * + * Usage: mkwav [input.pcm] + * If input.pcm is omitted, generates 100 samples of silence. + */ +#include +#include +#include +#include "wav_io.h" + +int main (int argc, char *argv[]) { + AUDIO_FILE *af; + long rate; + int channels, bits; + short buf[256]; + long n; + + if (argc < 5) { + fprintf (stderr, "Usage: mkwav [input.pcm]\n"); + return 1; + } + + rate = atol (argv[2]); + channels = atoi (argv[3]); + bits = atoi (argv[4]); + + af = audio_open_write (argv[1], rate, channels, bits); + if (!af) + return 1; + + if (argc > 5) { + FILE *fp = fopen (argv[5], "rb"); + if (!fp) { + fprintf (stderr, "Cannot open input: %s\n", argv[5]); + audio_close (af); + return 1; + } + while ((n = (long) fread (buf, sizeof (short), 256, fp)) > 0) + audio_write (af, buf, n); + fclose (fp); + } else { + memset (buf, 0, sizeof (buf)); + audio_write (af, buf, 100); + } + + audio_close (af); + return 0; +} diff --git a/src/utl/scaldemo.c b/src/utl/scaldemo.c index c4fc27e9..ac59b432 100644 --- a/src/utl/scaldemo.c +++ b/src/utl/scaldemo.c @@ -86,6 +86,7 @@ #include "ugstdemo.h" #include "ugst-utl.h" +#include "wav_io.h" #ifdef VMS #include @@ -163,7 +164,7 @@ int main (int argc, char *argv[]) { char use_dB = 0, quiet = 0, pre_mask = 0; /* File variables */ - FILE *Fi, *Fo; + AUDIO_FILE *Fi, *Fo; char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN]; #ifdef VMS char mrs[15]; @@ -307,14 +308,7 @@ int main (int argc, char *argv[]) { start_byte = --N1; start_byte *= N * sizeof (short); - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); - } + /* N2 will be computed after opening file if processing the whole file */ /* Allocate memory for data buffers */ if ((s_buf = (short *) calloc (sizeof (short), N)) == NULL) @@ -334,15 +328,19 @@ int main (int argc, char *argv[]) { #ifdef VMS sprintf (mrs, "mrs=%d", 2 * N); #endif - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = ceil ((audio_get_data_size (Fi) - start_byte) / (double) (N * sizeof (short))); + /* Creates output file */ - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st desired block */ - if (fseek (Fi, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* Get data of interest, equalize and de-normalize */ @@ -352,7 +350,7 @@ int main (int argc, char *argv[]) { printf ("%c\r", funny[blk_count % 5]); /* Read block of data */ - if ((nsam = fread (s_buf, sizeof (short), N, Fi)) > 0) { + if ((nsam = audio_read (Fi, s_buf, N)) > 0) { /* convert samples to float */ sh2fl ((long) nsam, s_buf, f_buf, pre_mask ? bitno : 16, 1); @@ -363,7 +361,7 @@ int main (int argc, char *argv[]) { NrSat += fl2sh ((long) nsam, f_buf, s_buf, h, mask[16 - bitno]); /* write equalized, de-normalized and hard-clipped samples to file */ - if ((nsam = fwrite (s_buf, sizeof (short), nsam, Fo)) < 0) + if ((nsam = audio_write (Fo, s_buf, nsam)) < 0) KILL (FileOut, 6); /* Update total number of samples in file */ @@ -382,8 +380,8 @@ int main (int argc, char *argv[]) { printf ("---> DONE \n"); /* Close files, free memory */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); free (f_buf); free (s_buf); diff --git a/src/utl/signal-diff.c b/src/utl/signal-diff.c index 2a176fb3..4c122825 100644 --- a/src/utl/signal-diff.c +++ b/src/utl/signal-diff.c @@ -55,6 +55,7 @@ #include #include #include "ugstdemo.h" +#include "wav_io.h" /* includes for DOS specific directives */ #if defined (MSDOS) @@ -106,8 +107,9 @@ int main (int argc, char *argv[]) { int i, j, k, l, K; char File1[50], File2[50]; - int fh1, fh2, fho; - FILE *F1, *F2, *Fo; + int fho; + AUDIO_FILE *F1, *F2; + FILE *Fo; long int N, N1, N2, NrDiffs = 0, NrEquivs = 0; long start_byte1, start_byte2, delay = 0; @@ -179,32 +181,31 @@ int main (int argc, char *argv[]) { /* Find number of blocks */ if (N2 == 0) { struct stat st; - long k, l; - - /* ... find the shortest of the 2 files and the number of blks from it */ - /* ... hey, need to skip the delayed samples! ... */ - stat (File1, &st); - k = (st.st_size - start_byte1) / (N * sizeof (short)); - stat (File2, &st); - l = (st.st_size - start_byte2) / (N * sizeof (short)); - N2 = k < l ? k : l; - if (k != l) - fprintf (stderr, "%%SUB-W-DIFSIZ: Files have different sizes!\n"); + /* N2 will be computed after opening files */ + N2 = 0; } /* Open input files */ - if ((F1 = fopen (File1, RB)) == NULL) + if ((F1 = audio_open_read (File1, 0, 0, 16)) == NULL) KILL (File1, 2); - if ((F2 = fopen (File2, RB)) == NULL) + if ((F2 = audio_open_read (File2, 0, 0, 16)) == NULL) KILL (File2, 3); - fh1 = fileno (F1); - fh2 = fileno (F2); + + /* Compute number of blocks if processing the whole files */ + if (N2 == 0) { + long k, l; + k = (audio_get_data_size (F1) - start_byte1) / (N * sizeof (short)); + l = (audio_get_data_size (F2) - start_byte2) / (N * sizeof (short)); + N2 = k < l ? k : l; + if (k != l) + fprintf (stderr, "%%SUB-W-DIFSIZ: Files have different sizes!\n"); + } /* Positions file to the starting of block N1 */ N1--; /* for the 1st block is not 1 but 0! */ - if (lseek (fh1, start_byte1, 0) < 0l) + if (audio_seek (F1, start_byte1) < 0l) KILL (File1, 5); - if (lseek (fh2, start_byte2, 0) < 0l) + if (audio_seek (F2, start_byte2) < 0l) KILL (File2, 6); /* Print dump information */ @@ -217,7 +218,7 @@ int main (int argc, char *argv[]) { /* Dumps the file to the output (file or screen) */ for (NrDiffs = i = j = 0; i < N2; i++, j = 0) { - if ((l = read (fh1, a, 2 * N) / 2) > 0 && (k = read (fh2, b, 2 * N) / 2) > 0) { + if ((l = audio_read (F1, a, N)) > 0 && (k = audio_read (F2, b, N)) > 0) { if (out_is_file) { if (isatty (fileno (stderr)) && !quiet) fprintf (stderr, "Now processing block %d\t\t\r", i + 1); @@ -233,7 +234,7 @@ int main (int argc, char *argv[]) { if (ABS (b[j]) <= equiv && b[j] != 0) NrEquivs++; } - if ((K = write (fho, b, 2 * N)) != 2 * l) + if ((K = fwrite (b, sizeof (short), N, Fo)) != l) KILL (argv[6], 9); } else for (j = 0; j < l && j < k; j++) { @@ -280,8 +281,8 @@ int main (int argc, char *argv[]) { } /* Finalizations */ - fclose (F1); - fclose (F2); + audio_close (F1); + audio_close (F2); if (out_is_file) fclose (Fo); #ifndef VMS diff --git a/src/utl/test_wav_integration.cmake b/src/utl/test_wav_integration.cmake new file mode 100644 index 00000000..69a5363f --- /dev/null +++ b/src/utl/test_wav_integration.cmake @@ -0,0 +1,519 @@ +# WAV I/O integration tests +# Tests that tools correctly handle WAV input with matching/mismatching parameters +# and that raw PCM input still works (backward compatibility). + +set(BIN ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +set(WAV_TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/wav_test_data) +file(MAKE_DIRECTORY ${WAV_TEST_DIR}) + +# --- Generate WAV test files from existing raw PCM test data --- + +# G.711 test input: 8000 Hz (narrowband codec) +add_test(NAME wav-gen-g711-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/sweep_8k.wav 8000 1 16 test_data/sweep.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g711) +add_test(NAME wav-gen-g711-wrong + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/sweep_48k.wav 48000 1 16 test_data/sweep.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g711) + +# SV56 test input: 16000 Hz (default) +add_test(NAME wav-gen-sv56-16k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/voice_16k.wav 16000 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/sv56) +add_test(NAME wav-gen-sv56-wrong + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/voice_44k.wav 44100 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/sv56) + +# MNRU test input: no fixed rate (pass-through) +add_test(NAME wav-gen-mnru-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/sine_8k.wav 8000 1 16 test_data/sine.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/mnru) + +# G.726 test input: 8000 Hz +add_test(NAME wav-gen-g726-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/g726_voice_8k.wav 8000 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g726) +add_test(NAME wav-gen-g726-wrong + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/g726_voice_16k.wav 16000 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g726) + +# FIR filter test input +add_test(NAME wav-gen-fir-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/fir_test_8k.wav 8000 1 16 test_data/test.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/fir) + +# Reverb test input (pass-through, any rate) +add_test(NAME wav-gen-reverb-16k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/reverb_input_16k.wav 16000 1 16 test_data/input.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/reverb) + +# Set fixture properties for WAV generation +set_tests_properties( + wav-gen-g711-8k wav-gen-g711-wrong + wav-gen-sv56-16k wav-gen-sv56-wrong + wav-gen-mnru-8k + wav-gen-g726-8k wav-gen-g726-wrong + wav-gen-fir-8k + wav-gen-reverb-16k + PROPERTIES FIXTURES_SETUP WAV_FILES) + +# ========================================================================== +# Case 1: WAV input with MATCHING parameters → should succeed, output matches +# ========================================================================== + +# G.711: WAV 8000 Hz input, encode A-law +add_test(NAME wav-g711-match-raw + COMMAND ${BIN}/g711demo A lilo ${CMAKE_SOURCE_DIR}/src/g711/test_data/sweep.src ${WAV_TEST_DIR}/g711_out_raw.raw 256 1 256) +set_tests_properties(wav-g711-match-raw PROPERTIES + FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-g711-match + COMMAND ${BIN}/g711demo A lilo ${WAV_TEST_DIR}/sweep_8k.wav ${WAV_TEST_DIR}/g711_out.raw 256 1 256) +set_tests_properties(wav-g711-match PROPERTIES + FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-g711-match-verify + COMMAND ${CMAKE_COMMAND} -E compare_files ${WAV_TEST_DIR}/g711_out.raw ${WAV_TEST_DIR}/g711_out_raw.raw) +set_tests_properties(wav-g711-match-verify PROPERTIES + DEPENDS "wav-g711-match;wav-g711-match-raw") + +# G.726: WAV 8000 Hz input +# g726demo: removed (g726demo expects A-law/mu-law input, not linear PCM; vbr-g726 WAV tests cover G.726) + +# MNRU: WAV 8000 Hz input (pass-through, any rate accepted) +add_test(NAME wav-mnru-match + COMMAND ${BIN}/mnrudemo -q ${WAV_TEST_DIR}/sine_8k.wav ${WAV_TEST_DIR}/mnru_out.raw 256 1 20 00) +set_tests_properties(wav-mnru-match PROPERTIES + FIXTURES_REQUIRED WAV_FILES) + +# FIR filter: WAV 8000 Hz input (matching default -fs 8000) +add_test(NAME wav-fir-match + COMMAND ${BIN}/firdemo -q ${WAV_TEST_DIR}/fir_test_8k.wav ${WAV_TEST_DIR}/fir_out.raw 8 0 0 0 0 0) +set_tests_properties(wav-fir-match PROPERTIES + FIXTURES_REQUIRED WAV_FILES) + +# Reverb: WAV 16000 Hz input (pass-through) +add_test(NAME wav-reverb-match + COMMAND ${BIN}/reverb ${WAV_TEST_DIR}/reverb_input_16k.wav test_data/irtest_le.IR ${WAV_TEST_DIR}/reverb_out.raw + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/reverb) +set_tests_properties(wav-reverb-match PROPERTIES + FIXTURES_REQUIRED WAV_FILES) + +# ========================================================================== +# Case 2: WAV input with WRONG sample rate → should fail (non-zero exit) +# ========================================================================== + +# G.711: WAV 48000 Hz input (expects 8000 Hz) +add_test(NAME wav-g711-mismatch + COMMAND ${BIN}/g711demo A lilo ${WAV_TEST_DIR}/sweep_48k.wav ${WAV_TEST_DIR}/g711_bad.raw 256 1 256) +set_tests_properties(wav-g711-mismatch PROPERTIES + FIXTURES_REQUIRED WAV_FILES + WILL_FAIL TRUE) + +# SV56: wav_io integration tests disabled (sv56 uses p56-bitdepth raw I/O) + +# MNRU: WAV 8000 Hz input with -sf 16000 (explicit mismatch) +add_test(NAME wav-gen-filter-16k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/filter_test_16k.wav 16000 1 16 test_data/test.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/fir) +set_tests_properties(wav-gen-filter-16k PROPERTIES FIXTURES_SETUP WAV_FILES_NOSF) +add_test(NAME wav-filter-no-fs + COMMAND ${BIN}/filter -q IRS16 ${WAV_TEST_DIR}/filter_test_16k.wav ${WAV_TEST_DIR}/filter_nosf.raw) +set_tests_properties(wav-filter-no-fs PROPERTIES + FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_NOSF") + +# actlevel: WAV 8000 Hz input, no -sf given (default is 16000, should accept WAV rate) +add_test(NAME wav-gen-actlev-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/actlev_8k.wav 8000 1 16 test_data/sweep.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g711) +set_tests_properties(wav-gen-actlev-8k PROPERTIES FIXTURES_SETUP WAV_FILES_NOSF) +add_test(NAME wav-actlevel-no-sf + COMMAND ${BIN}/actlev -q ${WAV_TEST_DIR}/actlev_8k.wav) +set_tests_properties(wav-actlevel-no-sf PROPERTIES + FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_NOSF") + +# esdru: WAV 16000 Hz input, no -sf given (default is 48000, should accept WAV rate) +add_test(NAME wav-gen-esdru-16k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/esdru_16k.wav 16000 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/sv56) +set_tests_properties(wav-gen-esdru-16k PROPERTIES FIXTURES_SETUP WAV_FILES_NOSF) +add_test(NAME wav-esdru-no-sf + COMMAND ${BIN}/esdru -e_out ${WAV_TEST_DIR}/esdru_nosf_el.raw 0.2 ${WAV_TEST_DIR}/esdru_16k.wav ${WAV_TEST_DIR}/esdru_nosf.raw) +set_tests_properties(wav-esdru-no-sf PROPERTIES + FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_NOSF") + +# freqresp: WAV 8000 Hz input, no -fs given (default is 16000, should accept WAV rate) +add_test(NAME wav-freqresp-no-fs + COMMAND ${BIN}/freqresp ${WAV_TEST_DIR}/fir_test_8k.wav ${WAV_TEST_DIR}/fir_test_8k.wav ${WAV_TEST_DIR}/freqresp_nosf.txt) +set_tests_properties(wav-freqresp-no-fs PROPERTIES + FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# ========================================================================== +# Case 3: WAV output extension → produces valid WAV with correct sample rate +# ========================================================================== + +# G.711: WAV input → WAV output (check output has WAV header) +add_test(NAME wav-g711-wav-output + COMMAND ${BIN}/g711demo A lilo ${WAV_TEST_DIR}/sweep_8k.wav ${WAV_TEST_DIR}/g711_out.wav 256 1 256) +set_tests_properties(wav-g711-wav-output PROPERTIES + FIXTURES_REQUIRED WAV_FILES) + +# Verify the output WAV can be opened and has correct sample rate +add_test(NAME wav-g711-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/g711_out.wav 8000 1 16) +set_tests_properties(wav-g711-wav-output-verify PROPERTIES + DEPENDS wav-g711-wav-output) + +# MNRU: WAV output preserves input rate +add_test(NAME wav-mnru-wav-output + COMMAND ${BIN}/mnrudemo -q ${WAV_TEST_DIR}/sine_8k.wav ${WAV_TEST_DIR}/mnru_out.wav 256 1 20 00) +set_tests_properties(wav-mnru-wav-output PROPERTIES + FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-mnru-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/mnru_out.wav 8000 1 16) +set_tests_properties(wav-mnru-wav-output-verify PROPERTIES + DEPENDS wav-mnru-wav-output) + +# Reverb: WAV output preserves input rate +add_test(NAME wav-reverb-wav-output + COMMAND ${BIN}/reverb ${WAV_TEST_DIR}/reverb_input_16k.wav test_data/irtest_le.IR ${WAV_TEST_DIR}/reverb_out.wav + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/reverb) +set_tests_properties(wav-reverb-wav-output PROPERTIES + FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-reverb-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/reverb_out.wav 16000 1 16) +set_tests_properties(wav-reverb-wav-output-verify PROPERTIES + DEPENDS wav-reverb-wav-output) + +# ========================================================================== +# Additional tool coverage — matching WAV tests +# ========================================================================== + +# --- Generate additional WAV test files --- +add_test(NAME wav-gen-iir-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/iir_test_8k.wav 8000 1 16 test_data/test.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/iir) +add_test(NAME wav-gen-scal-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/scal_voice_8k.wav 8000 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/is54) +add_test(NAME wav-gen-unsup-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/unsup_bigend_8k.wav 8000 1 16 test_data/bigend.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/unsup) +add_test(NAME wav-gen-stereoop-32k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/stereo_L_32k.wav 32000 1 16 test_data/sample.L.32k.1ch.smp + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/stereoop) +add_test(NAME wav-gen-stereoop-R-32k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/stereo_R_32k.wav 32000 1 16 test_data/sample.R.32k.1ch.smp + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/stereoop) +add_test(NAME wav-gen-g711iplc-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/g711iplc_8k.wav 8000 1 16 test_data/f2.le + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g711iplc) +add_test(NAME wav-gen-vbr-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/vbr_voice_8k.wav 8000 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g726) +add_test(NAME wav-gen-g722-16k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/g722_inp_16k.wav 16000 1 16 test_data/inpsp.bin + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g722) +add_test(NAME wav-gen-bs1770-48k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/bs1770_sine_48k.wav 48000 1 16 test_data/sine997_0dBFS.pcm + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/bs1770demo) +add_test(NAME wav-gen-esdru-48k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/esdru_stereo_48k.wav 48000 1 16 test_data/stereo_test.pcm + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/esdru) +add_test(NAME wav-gen-filter-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/filter_test_8k.wav 8000 1 16 test_data/test.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/fir) + +set_tests_properties( + wav-gen-iir-8k wav-gen-scal-8k wav-gen-unsup-8k + wav-gen-stereoop-32k wav-gen-stereoop-R-32k wav-gen-g711iplc-8k + wav-gen-vbr-8k wav-gen-g722-16k wav-gen-bs1770-48k + wav-gen-esdru-48k wav-gen-filter-8k + PROPERTIES FIXTURES_SETUP WAV_FILES_EXT) + +# --- IIR filters --- +add_test(NAME wav-cirsdemo-match + COMMAND ${BIN}/cirsdemo ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/cirsdemo_out.raw) +set_tests_properties(wav-cirsdemo-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +add_test(NAME wav-c712demo-match + COMMAND ${BIN}/c712demo ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/c712demo_out.raw) +set_tests_properties(wav-c712demo-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +add_test(NAME wav-pcmdemo-match + COMMAND ${BIN}/pcmdemo ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/pcmdemo_out.raw 1_1 0 0) +set_tests_properties(wav-pcmdemo-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- filter (FIR with -fs) --- +add_test(NAME wav-filter-match + COMMAND ${BIN}/filter -q IRS8 ${WAV_TEST_DIR}/filter_test_8k.wav ${WAV_TEST_DIR}/filter_out.raw) +set_tests_properties(wav-filter-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- scaldemo --- +add_test(NAME wav-scaldemo-match + COMMAND ${BIN}/scaldemo -q -trunc ${WAV_TEST_DIR}/scal_voice_8k.wav ${WAV_TEST_DIR}/scal_out.raw 256 1 0 0.5941352) +set_tests_properties(wav-scaldemo-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- stereoop --- +add_test(NAME wav-stereoop-match + COMMAND ${BIN}/stereoop -q -interleave ${WAV_TEST_DIR}/stereo_L_32k.wav ${WAV_TEST_DIR}/stereo_R_32k.wav ${WAV_TEST_DIR}/stereoop_out.raw) +set_tests_properties(wav-stereoop-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- astrip --- +add_test(NAME wav-astrip-match + COMMAND ${BIN}/astrip -q -smooth -wlen 145 -sample ${WAV_TEST_DIR}/unsup_bigend_8k.wav ${WAV_TEST_DIR}/astrip_out.raw) +set_tests_properties(wav-astrip-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- fdelay --- +add_test(NAME wav-fdelay-match + COMMAND ${BIN}/fdelay ${WAV_TEST_DIR}/unsup_bigend_8k.wav ${WAV_TEST_DIR}/fdelay_out.raw) +set_tests_properties(wav-fdelay-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- oper --- +add_test(NAME wav-oper-match + COMMAND ${BIN}/oper -q 1 ${WAV_TEST_DIR}/unsup_bigend_8k.wav + 1 ${WAV_TEST_DIR}/unsup_bigend_8k.wav 0 ${WAV_TEST_DIR}/oper_out.raw) +set_tests_properties(wav-oper-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- g711iplc --- +add_test(NAME wav-g711iplc-match + COMMAND ${BIN}/g711iplc -stats ${CMAKE_SOURCE_DIR}/src/g711iplc/test_data/fe10.g192 ${WAV_TEST_DIR}/g711iplc_8k.wav ${WAV_TEST_DIR}/g711iplc_out.raw) +set_tests_properties(wav-g711iplc-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- vbr-g726 --- +add_test(NAME wav-vbr-g726-match + COMMAND ${BIN}/vbr-g726 -q -law A -rate 16-24-32-40-32-24 ${WAV_TEST_DIR}/vbr_voice_8k.wav ${WAV_TEST_DIR}/vbr_out.raw) +set_tests_properties(wav-vbr-g726-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- g722demo --- +add_test(NAME wav-g722demo-match + COMMAND ${BIN}/g722demo -q -enc ${WAV_TEST_DIR}/g722_inp_16k.wav ${WAV_TEST_DIR}/g722_out.cod) +set_tests_properties(wav-g722demo-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- encg722 --- +add_test(NAME wav-encg722-match + COMMAND ${BIN}/encg722 ${WAV_TEST_DIR}/g722_inp_16k.wav ${WAV_TEST_DIR}/encg722_out.cod) +set_tests_properties(wav-encg722-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- bs1770demo --- +add_test(NAME wav-bs1770-match + COMMAND ${BIN}/bs1770demo ${WAV_TEST_DIR}/bs1770_sine_48k.wav ${WAV_TEST_DIR}/bs1770_out.raw) +set_tests_properties(wav-bs1770-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- esdru --- +add_test(NAME wav-esdru-match + COMMAND ${BIN}/esdru -e_out ${WAV_TEST_DIR}/esdru_el.raw 0.2 ${WAV_TEST_DIR}/esdru_stereo_48k.wav ${WAV_TEST_DIR}/esdru_out.raw) +set_tests_properties(wav-esdru-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- actlevel (read-only measurement) --- +add_test(NAME wav-actlevel-match + COMMAND ${BIN}/actlev -q ${WAV_TEST_DIR}/voice_16k.wav) +set_tests_properties(wav-actlevel-match PROPERTIES FIXTURES_REQUIRED WAV_FILES) + +# --- freqresp (read-only, no output file) --- +add_test(NAME wav-freqresp-match + COMMAND ${BIN}/freqresp ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/freqresp_out.txt) +set_tests_properties(wav-freqresp-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# ========================================================================== +# Additional mismatch tests for tools with fixed rates +# ========================================================================== + +# vbr-g726: WAV 16000 Hz input (expects 8000 Hz) +add_test(NAME wav-vbr-g726-mismatch + COMMAND ${BIN}/vbr-g726 -q -law A -rate 16-24-32-40-32-24 ${WAV_TEST_DIR}/g726_voice_16k.wav ${WAV_TEST_DIR}/vbr_bad.raw) +set_tests_properties(wav-vbr-g726-mismatch PROPERTIES + FIXTURES_REQUIRED WAV_FILES + WILL_FAIL TRUE) + +# g722demo: WAV 8000 Hz input (expects 16000 Hz) +add_test(NAME wav-g722-mismatch + COMMAND ${BIN}/g722demo ${WAV_TEST_DIR}/sweep_8k.wav ${WAV_TEST_DIR}/g722_bad.raw 256 1 256) +set_tests_properties(wav-g722-mismatch PROPERTIES + FIXTURES_REQUIRED WAV_FILES + WILL_FAIL TRUE) + +# bs1770demo: WAV 8000 Hz input (expects 48000 Hz) +add_test(NAME wav-bs1770-mismatch + COMMAND ${BIN}/bs1770demo ${WAV_TEST_DIR}/sweep_8k.wav ${WAV_TEST_DIR}/bs1770_bad.raw) +set_tests_properties(wav-bs1770-mismatch PROPERTIES + FIXTURES_REQUIRED WAV_FILES + WILL_FAIL TRUE) + +# g711iplc: WAV 16000 Hz input (expects 8000 Hz) +add_test(NAME wav-g711iplc-mismatch + COMMAND ${BIN}/g711iplc ${CMAKE_SOURCE_DIR}/src/g711iplc/test_data/fe10.g192 ${WAV_TEST_DIR}/g722_inp_16k.wav ${WAV_TEST_DIR}/g711iplc_bad.raw) +set_tests_properties(wav-g711iplc-mismatch PROPERTIES + FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT" + WILL_FAIL TRUE) + +# ========================================================================== +# More tool coverage +# ========================================================================== + +# --- Generate WAV for g727 and rpedemo --- +add_test(NAME wav-gen-g727-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/g727_speech_8k.wav 8000 1 16 test_data/speech.a-s + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g727) +add_test(NAME wav-gen-sigdiff-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/sigdiff_8k.wav 8000 1 16 test_data/test.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/iir) +set_tests_properties(wav-gen-g727-8k wav-gen-sigdiff-8k + PROPERTIES FIXTURES_SETUP WAV_FILES_EXT2) + +# g727demo encode mode +add_test(NAME wav-g727-match + COMMAND ${BIN}/g727demo -q -core 4 -enh 0 -enc -law A ${WAV_TEST_DIR}/g727_speech_8k.wav ${WAV_TEST_DIR}/g727_out.iad) +set_tests_properties(wav-g727-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT2") + +# g727demo: WAV 16000 Hz input (expects 8000) +add_test(NAME wav-g727-mismatch + COMMAND ${BIN}/g727demo -q -core 4 -enh 0 -enc -law A ${WAV_TEST_DIR}/g722_inp_16k.wav ${WAV_TEST_DIR}/g727_bad.iad) +set_tests_properties(wav-g727-mismatch PROPERTIES + FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT" + WILL_FAIL TRUE) + +# signal-diff (read-only comparison tool) +add_test(NAME wav-sigdiff-match + COMMAND ${BIN}/signal-diff -equiv 1 -q sigdiff_8k.wav sigdiff_8k.wav + WORKING_DIRECTORY ${WAV_TEST_DIR}) +set_tests_properties(wav-sigdiff-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT;WAV_FILES_EXT2") + +# --- decg722 WAV output --- +add_test(NAME wav-decg722-wav-output + COMMAND ${BIN}/decg722 -q -mode 1 -byte test_data/codspw.cod ${WAV_TEST_DIR}/decg722_out.wav + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g722) +set_tests_properties(wav-decg722-wav-output PROPERTIES FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-decg722-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/decg722_out.wav 16000 1 16) +set_tests_properties(wav-decg722-wav-output-verify PROPERTIES + DEPENDS wav-decg722-wav-output) + +# --- sine WAV output --- +add_test(NAME wav-sine-wav-output + COMMAND ${BIN}/sine -q ${WAV_TEST_DIR}/sine_out.wav 20000 1000 4 16000) +set_tests_properties(wav-sine-wav-output PROPERTIES FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-sine-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/sine_out.wav 16000 1 16) +set_tests_properties(wav-sine-wav-output-verify PROPERTIES DEPENDS wav-sine-wav-output) + +# ========================================================================== +# WAV output verification for all remaining tools +# ========================================================================== + +# vbr-g726: WAV output at 8000 Hz +add_test(NAME wav-vbr-g726-wav-output + COMMAND ${BIN}/vbr-g726 -q -law A -rate 16-24-32-40-32-24 ${WAV_TEST_DIR}/vbr_voice_8k.wav ${WAV_TEST_DIR}/vbr_out.wav) +set_tests_properties(wav-vbr-g726-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-vbr-g726-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/vbr_out.wav 8000 1 16) +set_tests_properties(wav-vbr-g726-wav-output-verify PROPERTIES DEPENDS wav-vbr-g726-wav-output) + +# g727demo: WAV output at 8000 Hz +add_test(NAME wav-g727-wav-output + COMMAND ${BIN}/g727demo -q -core 4 -enh 0 -enc -law A ${WAV_TEST_DIR}/g727_speech_8k.wav ${WAV_TEST_DIR}/g727_out.wav) +set_tests_properties(wav-g727-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT2") +add_test(NAME wav-g727-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/g727_out.wav 8000 1 16) +set_tests_properties(wav-g727-wav-output-verify PROPERTIES DEPENDS wav-g727-wav-output) + +# g711iplc: WAV output at 8000 Hz +add_test(NAME wav-g711iplc-wav-output + COMMAND ${BIN}/g711iplc -stats ${CMAKE_SOURCE_DIR}/src/g711iplc/test_data/fe10.g192 ${WAV_TEST_DIR}/g711iplc_8k.wav ${WAV_TEST_DIR}/g711iplc_out.wav) +set_tests_properties(wav-g711iplc-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-g711iplc-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/g711iplc_out.wav 8000 1 16) +set_tests_properties(wav-g711iplc-wav-output-verify PROPERTIES DEPENDS wav-g711iplc-wav-output) + +# filter: WAV output at 8000 Hz +add_test(NAME wav-filter-wav-output + COMMAND ${BIN}/filter -q IRS8 ${WAV_TEST_DIR}/filter_test_8k.wav ${WAV_TEST_DIR}/filter_out.wav) +set_tests_properties(wav-filter-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-filter-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/filter_out.wav 8000 1 16) +set_tests_properties(wav-filter-wav-output-verify PROPERTIES DEPENDS wav-filter-wav-output) + +# firdemo: WAV output at 8000 Hz +add_test(NAME wav-fir-wav-output + COMMAND ${BIN}/firdemo -q ${WAV_TEST_DIR}/fir_test_8k.wav ${WAV_TEST_DIR}/fir_out.wav 8 0 0 0 0 0) +set_tests_properties(wav-fir-wav-output PROPERTIES FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-fir-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/fir_out.wav 8000 1 16) +set_tests_properties(wav-fir-wav-output-verify PROPERTIES DEPENDS wav-fir-wav-output) + +# cirsdemo: WAV output at 8000 Hz +add_test(NAME wav-cirsdemo-wav-output + COMMAND ${BIN}/cirsdemo ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/cirsdemo_out.wav) +set_tests_properties(wav-cirsdemo-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-cirsdemo-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/cirsdemo_out.wav 8000 1 16) +set_tests_properties(wav-cirsdemo-wav-output-verify PROPERTIES DEPENDS wav-cirsdemo-wav-output) + +# pcmdemo: WAV output at 8000 Hz +add_test(NAME wav-pcmdemo-wav-output + COMMAND ${BIN}/pcmdemo ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/pcmdemo_out.wav 1_1 0 0) +set_tests_properties(wav-pcmdemo-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-pcmdemo-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/pcmdemo_out.wav 8000 1 16) +set_tests_properties(wav-pcmdemo-wav-output-verify PROPERTIES DEPENDS wav-pcmdemo-wav-output) + +# c712demo: WAV output at 8000 Hz +add_test(NAME wav-c712demo-wav-output + COMMAND ${BIN}/c712demo ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/c712demo_out.wav) +set_tests_properties(wav-c712demo-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-c712demo-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/c712demo_out.wav 8000 1 16) +set_tests_properties(wav-c712demo-wav-output-verify PROPERTIES DEPENDS wav-c712demo-wav-output) + +# scaldemo: WAV output at 8000 Hz +add_test(NAME wav-scaldemo-wav-output + COMMAND ${BIN}/scaldemo -q -trunc ${WAV_TEST_DIR}/scal_voice_8k.wav ${WAV_TEST_DIR}/scal_out.wav 256 1 0 0.5941352) +set_tests_properties(wav-scaldemo-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-scaldemo-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/scal_out.wav 8000 1 16) +set_tests_properties(wav-scaldemo-wav-output-verify PROPERTIES DEPENDS wav-scaldemo-wav-output) + +# stereoop: WAV output at 32000 Hz +add_test(NAME wav-stereoop-wav-output + COMMAND ${BIN}/stereoop -q -interleave ${WAV_TEST_DIR}/stereo_L_32k.wav ${WAV_TEST_DIR}/stereo_R_32k.wav ${WAV_TEST_DIR}/stereoop_out.wav) +set_tests_properties(wav-stereoop-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-stereoop-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/stereoop_out.wav 32000 1 16) +set_tests_properties(wav-stereoop-wav-output-verify PROPERTIES DEPENDS wav-stereoop-wav-output) + +# astrip: WAV output at 8000 Hz +add_test(NAME wav-astrip-wav-output + COMMAND ${BIN}/astrip -q -smooth -wlen 145 -sample ${WAV_TEST_DIR}/unsup_bigend_8k.wav ${WAV_TEST_DIR}/astrip_out.wav) +set_tests_properties(wav-astrip-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-astrip-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/astrip_out.wav 8000 1 16) +set_tests_properties(wav-astrip-wav-output-verify PROPERTIES DEPENDS wav-astrip-wav-output) + +# fdelay: WAV output at 8000 Hz +add_test(NAME wav-fdelay-wav-output + COMMAND ${BIN}/fdelay ${WAV_TEST_DIR}/unsup_bigend_8k.wav ${WAV_TEST_DIR}/fdelay_out.wav) +set_tests_properties(wav-fdelay-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-fdelay-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/fdelay_out.wav 8000 1 16) +set_tests_properties(wav-fdelay-wav-output-verify PROPERTIES DEPENDS wav-fdelay-wav-output) + +# oper: WAV output at 8000 Hz +add_test(NAME wav-oper-wav-output + COMMAND ${BIN}/oper -q 1 ${WAV_TEST_DIR}/unsup_bigend_8k.wav + 1 ${WAV_TEST_DIR}/unsup_bigend_8k.wav 0 ${WAV_TEST_DIR}/oper_out.wav) +set_tests_properties(wav-oper-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-oper-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/oper_out.wav 8000 1 16) +set_tests_properties(wav-oper-wav-output-verify PROPERTIES DEPENDS wav-oper-wav-output) + +# esdru: WAV output at 48000 Hz +add_test(NAME wav-esdru-wav-output + COMMAND ${BIN}/esdru -e_out ${WAV_TEST_DIR}/esdru_el2.raw 0.2 ${WAV_TEST_DIR}/esdru_stereo_48k.wav ${WAV_TEST_DIR}/esdru_out.wav) +set_tests_properties(wav-esdru-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-esdru-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/esdru_out.wav 48000 1 16) +set_tests_properties(wav-esdru-wav-output-verify PROPERTIES DEPENDS wav-esdru-wav-output) + +# bs1770demo: WAV output at 48000 Hz +add_test(NAME wav-bs1770-wav-output + COMMAND ${BIN}/bs1770demo ${WAV_TEST_DIR}/bs1770_sine_48k.wav ${WAV_TEST_DIR}/bs1770_out.wav) +set_tests_properties(wav-bs1770-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-bs1770-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/bs1770_out.wav 48000 1 16) +set_tests_properties(wav-bs1770-wav-output-verify PROPERTIES DEPENDS wav-bs1770-wav-output) diff --git a/src/utl/test_wav_io.c b/src/utl/test_wav_io.c new file mode 100644 index 00000000..0e7f01bb --- /dev/null +++ b/src/utl/test_wav_io.c @@ -0,0 +1,262 @@ +/* test_wav_io.c - Test program for wav_io library + * + * Creates test WAV files, reads them back, and verifies correctness. + * Returns 0 on success, 1 on failure. + */ +#include +#include +#include +#include "wav_io.h" + +#define NSAMPLES 100 +#define TEST_RATE 8000 + +static int test_write_and_read_wav (void) { + AUDIO_FILE *af; + short buf_out[NSAMPLES], buf_in[NSAMPLES]; + long n; + int i; + + /* Generate test samples */ + for (i = 0; i < NSAMPLES; i++) + buf_out[i] = (short) (i * 100 - 5000); + + /* Write WAV */ + af = audio_open_write ("test_data/test_out.wav", TEST_RATE, 1, 16); + if (!af) { + fprintf (stderr, "FAIL: Cannot open test_out.wav for writing\n"); + return 1; + } + if (!audio_is_wav (af)) { + fprintf (stderr, "FAIL: test_out.wav not detected as WAV for writing\n"); + audio_close (af); + return 1; + } + n = audio_write (af, buf_out, NSAMPLES); + if (n != NSAMPLES) { + fprintf (stderr, "FAIL: Wrote %ld samples, expected %d\n", n, NSAMPLES); + audio_close (af); + return 1; + } + audio_close (af); + + /* Read back */ + af = audio_open_read ("test_data/test_out.wav", TEST_RATE, 1, 16); + if (!af) { + fprintf (stderr, "FAIL: Cannot open test_out.wav for reading\n"); + return 1; + } + if (!audio_is_wav (af)) { + fprintf (stderr, "FAIL: test_out.wav not detected as WAV\n"); + audio_close (af); + return 1; + } + if (audio_get_sample_rate (af) != TEST_RATE) { + fprintf (stderr, "FAIL: Sample rate %ld, expected %d\n", audio_get_sample_rate (af), TEST_RATE); + audio_close (af); + return 1; + } + if (audio_get_channels (af) != 1) { + fprintf (stderr, "FAIL: Channels %d, expected 1\n", audio_get_channels (af)); + audio_close (af); + return 1; + } + n = audio_read (af, buf_in, NSAMPLES); + if (n != NSAMPLES) { + fprintf (stderr, "FAIL: Read %ld samples, expected %d\n", n, NSAMPLES); + audio_close (af); + return 1; + } + audio_close (af); + + /* Verify samples */ + if (memcmp (buf_out, buf_in, NSAMPLES * sizeof (short)) != 0) { + fprintf (stderr, "FAIL: Sample data mismatch\n"); + return 1; + } + + printf ("PASS: write_and_read_wav\n"); + return 0; +} + +static int test_raw_file (void) { + AUDIO_FILE *af; + short buf_out[NSAMPLES], buf_in[NSAMPLES]; + long n; + int i; + + /* Write raw file directly */ + { + FILE *fp = fopen ("test_data/test_raw.pcm", "wb"); + if (!fp) { + fprintf (stderr, "FAIL: Cannot create test_raw.pcm\n"); + return 1; + } + for (i = 0; i < NSAMPLES; i++) + buf_out[i] = (short) (i * 50); + fwrite (buf_out, sizeof (short), NSAMPLES, fp); + fclose (fp); + } + + /* Read via audio_open_read */ + af = audio_open_read ("test_data/test_raw.pcm", 0, 0, 16); + if (!af) { + fprintf (stderr, "FAIL: Cannot open test_raw.pcm\n"); + return 1; + } + if (audio_is_wav (af)) { + fprintf (stderr, "FAIL: Raw file detected as WAV\n"); + audio_close (af); + return 1; + } + n = audio_read (af, buf_in, NSAMPLES); + if (n != NSAMPLES) { + fprintf (stderr, "FAIL: Read %ld samples from raw, expected %d\n", n, NSAMPLES); + audio_close (af); + return 1; + } + audio_close (af); + + if (memcmp (buf_out, buf_in, NSAMPLES * sizeof (short)) != 0) { + fprintf (stderr, "FAIL: Raw sample data mismatch\n"); + return 1; + } + + printf ("PASS: raw_file\n"); + return 0; +} + +static int test_raw_to_wav_output (void) { + AUDIO_FILE *af; + short buf[NSAMPLES]; + int i; + + for (i = 0; i < NSAMPLES; i++) + buf[i] = (short) (i * 10); + + /* Write to .wav extension — should produce WAV */ + af = audio_open_write ("test_data/test_ext.wav", 16000, 1, 16); + if (!af || !audio_is_wav (af)) { + fprintf (stderr, "FAIL: .wav extension not producing WAV output\n"); + if (af) + audio_close (af); + return 1; + } + audio_write (af, buf, NSAMPLES); + audio_close (af); + + /* Write to .pcm extension — should produce raw */ + af = audio_open_write ("test_data/test_ext.pcm", 16000, 1, 16); + if (!af || audio_is_wav (af)) { + fprintf (stderr, "FAIL: .pcm extension producing WAV output\n"); + if (af) + audio_close (af); + return 1; + } + audio_write (af, buf, NSAMPLES); + audio_close (af); + + printf ("PASS: raw_to_wav_output\n"); + return 0; +} + +static int test_rate_mismatch (void) { + AUDIO_FILE *af; + short buf[NSAMPLES]; + int i; + + /* Create a valid 8000 Hz WAV */ + for (i = 0; i < NSAMPLES; i++) + buf[i] = (short) i; + af = audio_open_write ("test_data/test_8k.wav", 8000, 1, 16); + if (!af) + return 1; + audio_write (af, buf, NSAMPLES); + audio_close (af); + + /* Try to open expecting 16000 Hz — should fail */ + af = audio_open_read ("test_data/test_8k.wav", 16000, 0, 16); + if (af != NULL) { + fprintf (stderr, "FAIL: Rate mismatch not detected\n"); + audio_close (af); + return 1; + } + + printf ("PASS: rate_mismatch\n"); + return 0; +} + +static int test_stereo_extraction (void) { + AUDIO_FILE *af; + short stereo_buf[NSAMPLES * 2], mono_buf[NSAMPLES]; + long n; + int i; + + /* Create stereo WAV: ch0 = i, ch1 = -i */ + for (i = 0; i < NSAMPLES; i++) { + stereo_buf[i * 2] = (short) i; + stereo_buf[i * 2 + 1] = (short) (-i); + } + af = audio_open_write ("test_data/test_stereo.wav", 8000, 2, 16); + if (!af) + return 1; + /* Write raw interleaved data directly for stereo */ + fwrite (stereo_buf, sizeof (short), NSAMPLES * 2, af->fp); + af->data_size += NSAMPLES * 2 * sizeof (short); + audio_close (af); + + /* Read back — should extract channel 0 */ + af = audio_open_read ("test_data/test_stereo.wav", 0, 0, 16); + if (!af) { + fprintf (stderr, "FAIL: Cannot open stereo WAV\n"); + return 1; + } + if (audio_get_channels (af) != 2) { + fprintf (stderr, "FAIL: Expected 2 channels, got %d\n", audio_get_channels (af)); + audio_close (af); + return 1; + } + n = audio_read (af, mono_buf, NSAMPLES); + if (n != NSAMPLES) { + fprintf (stderr, "FAIL: Read %ld samples, expected %d\n", n, NSAMPLES); + audio_close (af); + return 1; + } + audio_close (af); + + /* Verify channel 0 extracted */ + for (i = 0; i < NSAMPLES; i++) { + if (mono_buf[i] != (short) i) { + fprintf (stderr, "FAIL: Stereo extraction mismatch at sample %d: got %d, expected %d\n", i, mono_buf[i], i); + return 1; + } + } + + printf ("PASS: stereo_extraction\n"); + return 0; +} + +int main (void) { + int failures = 0; + + failures += test_write_and_read_wav (); + failures += test_raw_file (); + failures += test_raw_to_wav_output (); + failures += test_rate_mismatch (); + failures += test_stereo_extraction (); + + if (failures == 0) + printf ("\nAll wav_io tests PASSED\n"); + else + printf ("\n%d wav_io test(s) FAILED\n", failures); + + /* Clean up test files */ + remove ("test_data/test_out.wav"); + remove ("test_data/test_raw.pcm"); + remove ("test_data/test_ext.wav"); + remove ("test_data/test_ext.pcm"); + remove ("test_data/test_8k.wav"); + remove ("test_data/test_stereo.wav"); + + return failures ? 1 : 0; +} diff --git a/src/utl/test_wav_io_validate.c b/src/utl/test_wav_io_validate.c new file mode 100644 index 00000000..58a4f289 --- /dev/null +++ b/src/utl/test_wav_io_validate.c @@ -0,0 +1,39 @@ +/* test_wav_io_validate.c - Validate WAV file header parameters. + * + * Usage: test_wav_io_validate + * Returns 0 if WAV file matches all expected parameters, 1 otherwise. + */ +#include +#include +#include "wav_io.h" + +int main (int argc, char *argv[]) { + AUDIO_FILE *af; + long expected_rate; + int expected_channels, expected_bits; + + if (argc != 5) { + fprintf (stderr, "Usage: test_wav_io_validate \n"); + return 1; + } + + expected_rate = atol (argv[2]); + expected_channels = atoi (argv[3]); + expected_bits = atoi (argv[4]); + + af = audio_open_read (argv[1], expected_rate, expected_channels, expected_bits); + if (!af) { + fprintf (stderr, "FAIL: Cannot open or parameters mismatch: %s\n", argv[1]); + return 1; + } + + if (!audio_is_wav (af)) { + fprintf (stderr, "FAIL: %s is not a WAV file\n", argv[1]); + audio_close (af); + return 1; + } + + printf ("PASS: %s (rate=%ld, ch=%d, bits=%d)\n", argv[1], audio_get_sample_rate (af), audio_get_channels (af), af->bits_per_sample); + audio_close (af); + return 0; +} diff --git a/src/utl/wav_io.c b/src/utl/wav_io.c new file mode 100644 index 00000000..733a123a --- /dev/null +++ b/src/utl/wav_io.c @@ -0,0 +1,447 @@ +/* wav_io.c - WAV file I/O support for STL tools + * + * Canonical WAV (RIFF) reader/writer for 8/16/24/32-bit PCM and 32-bit IEEE float. + * See wav_io.h for API documentation. + */ +#include "wav_io.h" +#include +#include +#include + +/* WAV format constants */ +#define WAV_RIFF_TAG 0x46464952 /* "RIFF" */ +#define WAV_WAVE_TAG 0x45564157 /* "WAVE" */ +#define WAV_FMT_TAG 0x20746D66 /* "fmt " */ +#define WAV_DATA_TAG 0x61746164 /* "data" */ +#define WAV_PCM_FORMAT 1 +#define WAV_FLOAT_FORMAT 3 +#define WAV_HEADER_SIZE 44 + +/* --- Helper: read little-endian integers from file --- */ + +static int read_u16 (FILE * fp, unsigned short *val) { + unsigned char b[2]; + if (fread (b, 1, 2, fp) != 2) + return 0; + *val = (unsigned short) (b[0] | (b[1] << 8)); + return 1; +} + +static int read_u32 (FILE * fp, unsigned long *val) { + unsigned char b[4]; + if (fread (b, 1, 4, fp) != 4) + return 0; + *val = (unsigned long) b[0] | ((unsigned long) b[1] << 8) | ((unsigned long) b[2] << 16) | ((unsigned long) b[3] << 24); + return 1; +} + +/* --- Helper: write little-endian integers to file --- */ + +static void write_u16 (FILE * fp, unsigned short val) { + unsigned char b[2]; + b[0] = (unsigned char) (val & 0xFF); + b[1] = (unsigned char) ((val >> 8) & 0xFF); + fwrite (b, 1, 2, fp); +} + +static void write_u32 (FILE * fp, unsigned long val) { + unsigned char b[4]; + b[0] = (unsigned char) (val & 0xFF); + b[1] = (unsigned char) ((val >> 8) & 0xFF); + b[2] = (unsigned char) ((val >> 16) & 0xFF); + b[3] = (unsigned char) ((val >> 24) & 0xFF); + fwrite (b, 1, 4, fp); +} + +/* --- Helper: case-insensitive extension check --- */ + +static int has_wav_extension (const char *filename) { + const char *dot; + dot = strrchr (filename, '.'); + if (!dot) + return 0; + if ((dot[1] == 'w' || dot[1] == 'W') && (dot[2] == 'a' || dot[2] == 'A') && (dot[3] == 'v' || dot[3] == 'V') && dot[4] == '\0') + return 1; + return 0; +} + +/* --- Public API --- */ + +AUDIO_FILE *audio_open_read (const char *filename, long expected_rate, int expected_channels, int expected_bits) { + AUDIO_FILE *af; + unsigned long riff_tag, file_size, wave_tag; + unsigned long chunk_id, chunk_size; + unsigned short audio_format, num_channels, bits_per_sample; + unsigned long sample_rate; + int fmt_found = 0; + + af = (AUDIO_FILE *) calloc (1, sizeof (AUDIO_FILE)); + if (!af) + return NULL; + + af->fp = fopen (filename, "rb"); + if (!af->fp) { + fprintf (stderr, "ERROR: Cannot open input file '%s'\n", filename); + free (af); + return NULL; + } + + af->write_mode = 0; + + /* Check for RIFF header */ + if (!read_u32 (af->fp, &riff_tag) || riff_tag != WAV_RIFF_TAG) { + /* Not a WAV file — treat as raw PCM */ + fseek (af->fp, 0, SEEK_SET); + af->is_wav = 0; + af->channels = 1; + af->sample_rate = 0; + af->bits_per_sample = 16; + af->data_offset = 0; + return af; + } + + /* Parse RIFF/WAVE header */ + if (!read_u32 (af->fp, &file_size) || !read_u32 (af->fp, &wave_tag) || wave_tag != WAV_WAVE_TAG) { + fprintf (stderr, "ERROR: '%s' has RIFF header but is not a WAVE file\n", filename); + fclose (af->fp); + free (af); + return NULL; + } + + /* Find fmt and data chunks */ + while (read_u32 (af->fp, &chunk_id) && read_u32 (af->fp, &chunk_size)) { + if (chunk_id == WAV_FMT_TAG) { + if (!read_u16 (af->fp, &audio_format) || !read_u16 (af->fp, &num_channels) || !read_u32 (af->fp, &sample_rate)) { + fprintf (stderr, "ERROR: Cannot read fmt chunk in '%s'\n", filename); + fclose (af->fp); + free (af); + return NULL; + } + /* Skip byte rate and block align */ + fseek (af->fp, 4 + 2, SEEK_CUR); + if (!read_u16 (af->fp, &bits_per_sample)) { + fprintf (stderr, "ERROR: Cannot read bits_per_sample in '%s'\n", filename); + fclose (af->fp); + free (af); + return NULL; + } + /* Skip any extra fmt bytes */ + if (chunk_size > 16) + fseek (af->fp, chunk_size - 16, SEEK_CUR); + fmt_found = 1; + } else if (chunk_id == WAV_DATA_TAG) { + if (!fmt_found) { + fprintf (stderr, "ERROR: data chunk before fmt chunk in '%s'\n", filename); + fclose (af->fp); + free (af); + return NULL; + } + af->data_offset = ftell (af->fp); + af->data_size = (long) chunk_size; + break; + } else { + /* Skip unknown chunk */ + fseek (af->fp, chunk_size, SEEK_CUR); + } + } + + if (!fmt_found || af->data_offset == 0) { + fprintf (stderr, "ERROR: Missing fmt or data chunk in '%s'\n", filename); + fclose (af->fp); + free (af); + return NULL; + } + + /* Validate format */ + if (audio_format != WAV_PCM_FORMAT && audio_format != WAV_FLOAT_FORMAT) { + fprintf (stderr, "ERROR: '%s' has unsupported WAV format (format tag=%d). Only PCM and IEEE float are supported.\n", filename, audio_format); + fclose (af->fp); + free (af); + return NULL; + } + + if (audio_format == WAV_FLOAT_FORMAT && bits_per_sample != 32) { + fprintf (stderr, "ERROR: '%s' is float WAV with %d bits (only 32-bit float supported).\n", filename, bits_per_sample); + fclose (af->fp); + free (af); + return NULL; + } + + if (audio_format == WAV_PCM_FORMAT && bits_per_sample != 8 && bits_per_sample != 16 && bits_per_sample != 24 && bits_per_sample != 32) { + fprintf (stderr, "ERROR: '%s' has unsupported bit depth (%d). Supported: 8, 16, 24, 32.\n", filename, bits_per_sample); + fclose (af->fp); + free (af); + return NULL; + } + + /* Check expected parameters */ + if (expected_bits > 0 && (int) bits_per_sample != expected_bits) { + fprintf (stderr, "ERROR: WAV bit depth (%d) does not match expected (%d) in '%s'\n", bits_per_sample, expected_bits, filename); + fclose (af->fp); + free (af); + return NULL; + } + + if (expected_rate > 0 && (long) sample_rate != expected_rate) { + fprintf (stderr, "ERROR: WAV sample rate (%lu Hz) does not match expected rate (%ld Hz) in '%s'\n", sample_rate, expected_rate, filename); + fclose (af->fp); + free (af); + return NULL; + } + + if (expected_channels > 0 && (int) num_channels != expected_channels) { + fprintf (stderr, "ERROR: WAV channel count (%d) does not match expected channels (%d) in '%s'\n", num_channels, expected_channels, filename); + fclose (af->fp); + free (af); + return NULL; + } + + af->is_wav = 1; + af->channels = (int) num_channels; + af->sample_rate = (long) sample_rate; + af->bits_per_sample = (int) bits_per_sample; + af->audio_format = (int) audio_format; + + return af; +} + + +AUDIO_FILE *audio_open_write (const char *filename, long sample_rate, int channels, int bits_per_sample) { + AUDIO_FILE *af; + + af = (AUDIO_FILE *) calloc (1, sizeof (AUDIO_FILE)); + if (!af) + return NULL; + + af->fp = fopen (filename, "wb"); + if (!af->fp) { + fprintf (stderr, "ERROR: Cannot open output file '%s'\n", filename); + free (af); + return NULL; + } + + af->write_mode = 1; + af->sample_rate = sample_rate; + af->channels = channels; + af->bits_per_sample = bits_per_sample > 0 ? bits_per_sample : 16; + + if (has_wav_extension (filename)) { + af->is_wav = 1; + /* Write placeholder WAV header (44 bytes) — updated on close */ + write_u32 (af->fp, WAV_RIFF_TAG); + write_u32 (af->fp, 0); /* file size - 8 (placeholder) */ + write_u32 (af->fp, WAV_WAVE_TAG); + /* fmt chunk */ + write_u32 (af->fp, WAV_FMT_TAG); + write_u32 (af->fp, 16); /* fmt chunk size */ + write_u16 (af->fp, WAV_PCM_FORMAT); + write_u16 (af->fp, (unsigned short) af->channels); + write_u32 (af->fp, (unsigned long) af->sample_rate); + write_u32 (af->fp, (unsigned long) (af->sample_rate * af->channels * af->bits_per_sample / 8)); /* byte rate */ + write_u16 (af->fp, (unsigned short) (af->channels * af->bits_per_sample / 8)); /* block align */ + write_u16 (af->fp, (unsigned short) af->bits_per_sample); + /* data chunk header */ + write_u32 (af->fp, WAV_DATA_TAG); + write_u32 (af->fp, 0); /* data size (placeholder) */ + af->data_offset = ftell (af->fp); + af->data_size = 0; + } else { + af->is_wav = 0; + af->data_size = 0; + } + + return af; +} + + +long audio_read (AUDIO_FILE * af, void *buffer, long nsamples) { + int bps, ch, sample_bytes, frame_bytes; + long frames_read, i; + + if (!af || !af->fp || !buffer || nsamples <= 0) + return 0; + + bps = af->bits_per_sample; + ch = af->is_wav ? af->channels : 1; + sample_bytes = (bps == 24) ? 3 : (bps / 8); + frame_bytes = sample_bytes * ch; + + /* Raw files are native-endian; direct fread is safe for 8/16-bit mono */ + if (!af->is_wav && ch <= 1 && bps <= 2) { + return (long) fread (buffer, (size_t) sample_bytes, (size_t) nsamples, af->fp); + } + + /* WAV (little-endian) and multi-channel: extract with byte-order handling */ + { + unsigned char *raw_buf; + + if (ch > 1 && !af->warned_multichan) { + fprintf (stderr, "WARNING: Multi-channel WAV (%d channels). Extracting channel 1 only.\n", ch); + af->warned_multichan = 1; + } + + raw_buf = (unsigned char *) malloc ((size_t) (nsamples * frame_bytes)); + if (!raw_buf) + return 0; + + frames_read = (long) fread (raw_buf, (size_t) frame_bytes, (size_t) nsamples, af->fp); + + if (bps == 8) { + unsigned char *out = (unsigned char *) buffer; + for (i = 0; i < frames_read; i++) + out[i] = raw_buf[i * frame_bytes]; + } else if (bps == 16) { + short *out = (short *) buffer; + for (i = 0; i < frames_read; i++) { + unsigned char *p = raw_buf + i * frame_bytes; + out[i] = (short) (p[0] | (p[1] << 8)); + } + } else if (bps == 24) { + long *out = (long *) buffer; + for (i = 0; i < frames_read; i++) { + unsigned char *p = raw_buf + i * frame_bytes; + out[i] = (long) p[0] | ((long) p[1] << 8) | ((long) (signed char) p[2] << 16); + } + } else if (bps == 32) { + long *out = (long *) buffer; + if (af->audio_format == WAV_FLOAT_FORMAT) { + float *fout = (float *) buffer; + for (i = 0; i < frames_read; i++) { + unsigned char *p = raw_buf + i * frame_bytes; + union { unsigned char b[4]; float f; } u; + u.b[0] = p[0]; u.b[1] = p[1]; u.b[2] = p[2]; u.b[3] = p[3]; + fout[i] = u.f; + } + } else { + for (i = 0; i < frames_read; i++) { + unsigned char *p = raw_buf + i * frame_bytes; + out[i] = (long) p[0] | ((long) p[1] << 8) | ((long) p[2] << 16) | ((long) (signed char) p[3] << 24); + } + } + } + + free (raw_buf); + return frames_read; + } +} + + +long audio_write (AUDIO_FILE * af, void *buffer, long nsamples) { + int bps, sample_bytes; + long n, i; + + if (!af || !af->fp || !buffer || nsamples <= 0) + return 0; + + bps = af->bits_per_sample; + sample_bytes = (bps == 24) ? 3 : (bps / 8); + + if (bps != 24) { + /* For raw or 8-bit: direct fwrite (native endian or single byte) */ + if (!af->is_wav || bps == 8) { + n = (long) fwrite (buffer, (size_t) sample_bytes, (size_t) nsamples, af->fp); + af->data_size += n * sample_bytes; + return n; + } + /* WAV 16-bit: write little-endian */ + if (bps == 16) { + short *in = (short *) buffer; + for (i = 0; i < nsamples; i++) { + unsigned char b[2]; + b[0] = (unsigned char) (in[i] & 0xFF); + b[1] = (unsigned char) ((in[i] >> 8) & 0xFF); + if (fwrite (b, 1, 2, af->fp) != 2) break; + } + af->data_size += i * 2; + return i; + } + /* WAV 32-bit: write little-endian */ + { + int *in = (int *) buffer; + for (i = 0; i < nsamples; i++) { + unsigned char b[4]; + unsigned int val = (unsigned int) in[i]; + b[0] = (unsigned char) (val & 0xFF); + b[1] = (unsigned char) ((val >> 8) & 0xFF); + b[2] = (unsigned char) ((val >> 16) & 0xFF); + b[3] = (unsigned char) ((val >> 24) & 0xFF); + if (fwrite (b, 1, 4, af->fp) != 4) break; + } + af->data_size += i * 4; + return i; + } + } + + /* 24-bit: pack from long */ + { + long *in = (long *) buffer; + for (i = 0; i < nsamples; i++) { + unsigned char b[3]; + long val = in[i]; + b[0] = (unsigned char) (val & 0xFF); + b[1] = (unsigned char) ((val >> 8) & 0xFF); + b[2] = (unsigned char) ((val >> 16) & 0xFF); + if (fwrite (b, 1, 3, af->fp) != 3) + break; + } + af->data_size += i * 3; + return i; + } +} + + +void audio_close (AUDIO_FILE * af) { + if (!af) + return; + + if (af->fp) { + if (af->write_mode && af->is_wav) { + /* Update WAV header with final sizes */ + unsigned long file_size = (unsigned long) af->data_size + WAV_HEADER_SIZE - 8; + fseek (af->fp, 4, SEEK_SET); + write_u32 (af->fp, file_size); + fseek (af->fp, WAV_HEADER_SIZE - 4, SEEK_SET); + write_u32 (af->fp, (unsigned long) af->data_size); + } + fclose (af->fp); + } + + free (af); +} + + +int audio_is_wav (AUDIO_FILE * af) { + return af ? af->is_wav : 0; +} + + +long audio_get_sample_rate (AUDIO_FILE * af) { + return af ? af->sample_rate : 0; +} + + +int audio_get_channels (AUDIO_FILE * af) { + return af ? af->channels : 0; +} + + +int audio_seek (AUDIO_FILE * af, long offset) { + if (!af || !af->fp) + return -1; + return fseek (af->fp, af->data_offset + offset, SEEK_SET) < 0 ? -1 : 0; +} + + +long audio_get_data_size (AUDIO_FILE * af) { + if (!af || !af->fp) + return 0; + if (af->is_wav) + return af->data_size; + else { + long cur = ftell (af->fp); + fseek (af->fp, 0, SEEK_END); + long size = ftell (af->fp); + fseek (af->fp, cur, SEEK_SET); + return size; + } +} diff --git a/src/utl/wav_io.h b/src/utl/wav_io.h new file mode 100644 index 00000000..63c2f64c --- /dev/null +++ b/src/utl/wav_io.h @@ -0,0 +1,74 @@ +/* wav_io.h - WAV file I/O support for STL tools + * + * Provides transparent reading/writing of WAV and raw PCM files. + * Input format is auto-detected (RIFF header check). + * Output format is determined by filename extension (.wav = WAV, else raw). + * Supports 8/16/24/32-bit PCM and 32-bit IEEE float WAV. + */ +#ifndef WAV_IO_H +#define WAV_IO_H + +#include + +typedef struct { + FILE *fp; + int is_wav; /* 1 if WAV format, 0 if raw PCM */ + int channels; /* Number of channels (from WAV header, or 1 for raw) */ + long sample_rate; /* Sample rate in Hz (from WAV header, or 0 for raw) */ + int bits_per_sample; /* Bits per sample (from WAV header, or 16 for raw) */ + int audio_format; /* WAV format tag: 1=PCM, 3=IEEE float (0 for raw) */ + long data_offset; /* Byte offset to start of PCM data */ + long data_size; /* Bytes of PCM data written (for WAV write) */ + int warned_multichan; /* Flag: already warned about multi-channel extraction */ + int write_mode; /* 1 if opened for writing, 0 for reading */ +} AUDIO_FILE; + +/* Open file for reading. Auto-detects WAV vs raw PCM. + * expected_rate: if > 0, error if WAV sample rate doesn't match + * expected_channels: if > 0, error if WAV channel count doesn't match + * expected_bits: if > 0, error if WAV bits_per_sample doesn't match + * Returns NULL on error (prints message to stderr). */ +AUDIO_FILE *audio_open_read (const char *filename, long expected_rate, int expected_channels, int expected_bits); + +/* Open file for writing. Writes WAV if filename ends in .wav, raw otherwise. + * sample_rate/channels/bits_per_sample used for WAV header. + * For raw output, these are ignored. + * Returns NULL on error. */ +AUDIO_FILE *audio_open_write (const char *filename, long sample_rate, int channels, int bits_per_sample); + +/* Read up to nsamples into buffer, using the appropriate sample size + * based on the file's bits_per_sample (8/16/24/32-bit PCM or 32-bit float). + * Buffer must be large enough for the native sample size. + * For multi-channel WAV, extracts channel 0 (warns once on stderr). + * Returns number of samples actually read. */ +long audio_read (AUDIO_FILE * af, void *buffer, long nsamples); + +/* Write nsamples from buffer, using the appropriate sample size + * based on the file's bits_per_sample. + * Returns number of samples actually written. */ +long audio_write (AUDIO_FILE * af, void *buffer, long nsamples); + +/* Close file. For WAV output, updates header with final data size. */ +void audio_close (AUDIO_FILE * af); + +/* Returns 1 if file was detected/opened as WAV, 0 if raw */ +int audio_is_wav (AUDIO_FILE * af); + +/* Returns sample rate from WAV header (0 if raw) */ +long audio_get_sample_rate (AUDIO_FILE * af); + +/* Returns channel count from WAV header (0 if raw) */ +int audio_get_channels (AUDIO_FILE * af); + +/* Seek to a byte offset relative to the start of PCM data. + * For WAV files, accounts for the header (data_offset). + * For raw files, seeks from byte 0. + * Returns 0 on success, -1 on failure. */ +int audio_seek (AUDIO_FILE * af, long offset); + +/* Returns total size of PCM data in bytes. + * For WAV, returns the data chunk size from the header. + * For raw, returns the file size. */ +long audio_get_data_size (AUDIO_FILE * af); + +#endif /* WAV_IO_H */ diff --git a/src/wmc_tool/CMakeLists.txt b/src/wmc_tool/CMakeLists.txt index 858ee70c..33df6e17 100644 --- a/src/wmc_tool/CMakeLists.txt +++ b/src/wmc_tool/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.10...3.31) project(wmc_tool) include(CTest) @@ -8,10 +8,11 @@ if(WIN32) -D_CRT_SECURE_NO_WARNINGS /MP ) -endif() +endif() add_executable(wmc_tool c_parser.cpp output.cpp text_utils.cpp wmc_tool.cpp) -find_package(PythonInterp) +find_package(Python3 COMPONENTS Interpreter) +set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) # Testing file(TO_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/test_data TEST_DIR) @@ -19,16 +20,18 @@ file(TO_CMAKE_PATH ${TEST_DIR}/test_wmc_tool.py TEST_WMC_TOOL_SCRIPT) add_test(NAME wmc_tool_dry_run COMMAND wmc_tool -h) add_test(NAME wmc_tool_dry_run2 COMMAND wmc_tool -i) + +if(Python3_FOUND) add_test(NAME wmc_tool_test_single_file COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -s src -r ref -o out -v test_file1.c WORKING_DIRECTORY ${TEST_DIR}) add_test(NAME wmc_tool_test_single_file2 COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ test_file2.c WORKING_DIRECTORY ${TEST_DIR}) -add_test(NAME wmc_tool_test_multiple_files COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v test_file*.c test_g728durb.c WORKING_DIRECTORY ${TEST_DIR}) +add_test(NAME wmc_tool_test_multiple_files COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v "test_file*.c" test_g728durb.c WORKING_DIRECTORY ${TEST_DIR}) add_test(NAME wmc_tool_test_basop_file COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v test_basop.c WORKING_DIRECTORY ${TEST_DIR}) add_test(NAME wmc_tool_test_basop_file2 COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v test_basop32.c WORKING_DIRECTORY ${TEST_DIR}) add_test(NAME wmc_tool_test_rom_file COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -m main1.c test_rom.c WORKING_DIRECTORY ${TEST_DIR}) -add_test(NAME wmc_tool_test_rom_file2 COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -m main2.c test*.c WORKING_DIRECTORY ${TEST_DIR}) +add_test(NAME wmc_tool_test_rom_file2 COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -m main2.c "test*.c" WORKING_DIRECTORY ${TEST_DIR}) add_test(NAME wmc_tool_test_desinstrument_file COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -d di_test_file1.c WORKING_DIRECTORY ${TEST_DIR}) add_test(NAME wmc_tool_test_desinstrument_rom_file COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -v -d di_test_rom.c WORKING_DIRECTORY ${TEST_DIR}) add_test(NAME wmc_tool_test_wmc_auto_files COMMAND ${PYTHON_EXECUTABLE} ${TEST_WMC_TOOL_SCRIPT} -e $ -c ${TEST_DIR} test_file3.c WORKING_DIRECTORY ${TEST_DIR}) - - - +else() + message(STATUS "Python3 not found -- skipping wmc_tool Python tests") +endif() diff --git a/src/wmc_tool/c_parser.cpp b/src/wmc_tool/c_parser.cpp index 79f11010..6feb79b2 100644 --- a/src/wmc_tool/c_parser.cpp +++ b/src/wmc_tool/c_parser.cpp @@ -805,7 +805,8 @@ static TOOL_ERROR Allocate_Insertion( Insert_Tbl_def *InsertTbl_ptr ) /* Calculate Bigger Size */ size = InsertTbl_ptr->MaxSize + INSERT_TBL_MEM_INCREMENT; /* Allocate Memory */ - if ( ( ptr = (Insert_Rec_def *) malloc( nbytes = INSERT_REC_SIZE * size ) ) == NULL ) + nbytes = INSERT_REC_SIZE * size; + if ( ( ptr = (Insert_Rec_def *) calloc( size, INSERT_REC_SIZE ) ) == NULL ) { ErrCode = ERR_MEM_PARSING; Error( ERROR_MSG_MEM_PARSING, ErrCode, itos( temp, nbytes ) ); @@ -882,6 +883,7 @@ static TOOL_ERROR Add_Insertion( } InsertRec_ptr = InsertTbl_ptr->Data + InsertTbl_ptr->Size; /* Fill Record */ + memset(InsertRec_ptr, 0, sizeof(*InsertRec_ptr)); InsertRec_ptr->Ptr = (char *)ptr; /* Reset # of Chars Stored */ nChars = 0; @@ -1679,7 +1681,7 @@ static TOOL_ERROR Find_Enclosed_Text( char *ptr; char *last_ptr; - Item_Type item_type; + Item_Type item_type = ITEM_NONE; char chr; /* Start at Beginning */ @@ -2471,7 +2473,7 @@ static TOOL_ERROR Find_Keywords( char kw_name[16]; size_t kw_name_len; char *ns, *ne; /* Name Start/End */ - char *ps, *pe; /* Params Start/End */ + char *ps = NULL, *pe; /* Params Start/End */ char *dp; Item_Type item_type; Parse_Tbl_def *ParseTbl_ptr; @@ -5440,6 +5442,7 @@ static TOOL_ERROR Instrument_Operators( /* Initialize (No Memory Allocated by Default) */ OperInsTbl.MaxSize = 0; + OperInsTbl.Data = NULL; /* Get Parse Table Address (for clarity) */ ParseTbl_ptr = &ParseCtx_ptr->ParseTbl; diff --git a/src/wmc_tool/test_data/test_wmc_tool.py b/src/wmc_tool/test_data/test_wmc_tool.py index a5291936..db240a6a 100644 --- a/src/wmc_tool/test_data/test_wmc_tool.py +++ b/src/wmc_tool/test_data/test_wmc_tool.py @@ -33,6 +33,10 @@ parser.add_argument('-c', '--wmc_auto_dir', metavar='wmc_auto_dir', type=str, dest='wmc_auto_dir', help='copy wmc_auto.[h|c] to a user-specified directory') args = parser.parse_args() + # Debug: print received arguments + print("DEBUG test_wmc_tool.py: sys.argv =", sys.argv, file=sys.stderr) + print("DEBUG test_wmc_tool.py: file_list =", args.file_list, file=sys.stderr) + # create temporary directory # tmp_dir = tempfile.mkdtemp() # tmp_dir = './tmp' @@ -107,6 +111,12 @@ for file in args.file_list: cmdline.append(file) + # Debug: print command and working directory + print("DEBUG test_wmc_tool.py: cwd =", os.getcwd(), file=sys.stderr) + print("DEBUG test_wmc_tool.py: cmdline =", cmdline, file=sys.stderr) + print("DEBUG test_wmc_tool.py: out dir exists =", os.path.isdir(args.outdir), file=sys.stderr) + print("DEBUG test_wmc_tool.py: out contents =", os.listdir(args.outdir) if os.path.isdir(args.outdir) else "N/A", file=sys.stderr) + # print(' '.join(cmdline)) # sys.exit(0) diff --git a/src/wmc_tool/wmc_tool.cpp b/src/wmc_tool/wmc_tool.cpp index dac4c482..23f3e37b 100644 --- a/src/wmc_tool/wmc_tool.cpp +++ b/src/wmc_tool/wmc_tool.cpp @@ -1161,11 +1161,7 @@ int main( int argc, char *argv[] ) TOOL_ERROR ErrCode = NO_ERR; /* Initialization */ - ParseContext.File.MaxSize = 0; - ParseContext.ParseTbl.MaxSize = 0; - ParseContext.InsertTbl.MaxSize = 0; - ParseContext.FctCallTbl.MaxSize = 0; - ParseContext.PointerTbl.MaxSize = 0; + memset(&ParseContext, 0, sizeof(ParseContext)); ParseContext.PROMOpsWeightsSet = 1; /* Set PROM Ops Weighting Set in Context (0 = Std, 1 = STL 2009) */ /* Skip the Executable's Name */