diff -Nru libmysofa-0.6~dfsg0/.appveyor.yml libmysofa-0.7~dfsg0/.appveyor.yml --- libmysofa-0.6~dfsg0/.appveyor.yml 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/.appveyor.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -version: 1.0.{build} -configuration: Release -platform: x64 -install: -- cmd: >- - cp "%APPVEYOR_BUILD_FOLDER%\src\hrtf\mysofa_export.h.in" "%APPVEYOR_BUILD_FOLDER%\src\hrtf\mysofa_export.h" - - cp "%APPVEYOR_BUILD_FOLDER%\windows/config.h.sln" "%APPVEYOR_BUILD_FOLDER%\src\config.h" -nuget: - account_feed: true - project_feed: true -build: - project: windows/libmysofa.sln - verbosity: normal -artifacts: -- path: windows\bin diff -Nru libmysofa-0.6~dfsg0/CMakeLists.txt libmysofa-0.7~dfsg0/CMakeLists.txt --- libmysofa-0.6~dfsg0/CMakeLists.txt 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/CMakeLists.txt 2019-03-31 15:16:24.000000000 +0000 @@ -3,6 +3,7 @@ INCLUDE(CheckCCompilerFlag) include(GenerateExportHeader) +include(GNUInstallDirs) option(BUILD_TESTS "Build test programs" ON) option(BUILD_SHARED_LIBS "Build shared library" ON) @@ -18,15 +19,19 @@ SET(CPACK_PACKAGE_VERSION_PATCH "1") SET(CPACK_DEBIAN_PACKAGE_DEPENDS "zlib1g") +SET(PKG_CONFIG_PRIVATELIBS "") + +SET(PROJECT_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}") + CHECK_C_COMPILER_FLAG(-Wall C_HAS_WALL) IF(C_HAS_WALL) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") ENDIF(C_HAS_WALL) -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG") +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG -DVDEBUG") -install(FILES share/default.sofa DESTINATION share/libmysofa) -install(FILES share/MIT_KEMAR_normal_pinna.sofa DESTINATION share/libmysofa) +install(FILES share/default.sofa DESTINATION ${CMAKE_INSTALL_DATADIR}/libmysofa) +install(FILES share/MIT_KEMAR_normal_pinna.sofa DESTINATION ${CMAKE_INSTALL_DATADIR}/libmysofa) if(BUILD_TESTS) @@ -38,6 +43,9 @@ enable_testing() + # add_test(security_1 ./src/mysofa2json ../tests/security/1.sofa) + # add_test(security_2 /bin/sh -c "./src/mysofa2json ../tests/security/2.sofa || test \$? = 22") + add_test(CIPIC_subject_003_hrir_final ../tests/compare.sh ../tests/CIPIC_subject_003_hrir_final) add_test(FHK_HRIR_L2354.sofa ../tests/compare.sh ../tests/FHK_HRIR_L2354) add_test(LISTEN_1002_IRC_1002_C_HRIR.sofa ../tests/compare.sh ../tests/LISTEN_1002_IRC_1002_C_HRIR) @@ -51,3 +59,13 @@ add_subdirectory(src) INCLUDE(CPack) + +CONFIGURE_FILE( + "${CMAKE_CURRENT_SOURCE_DIR}/libmysofa.pc.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + @ONLY +) +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + DESTINATION "lib/pkgconfig" +) diff -Nru libmysofa-0.6~dfsg0/CONTRIBUTING.md libmysofa-0.7~dfsg0/CONTRIBUTING.md --- libmysofa-0.6~dfsg0/CONTRIBUTING.md 1970-01-01 00:00:00.000000000 +0000 +++ libmysofa-0.7~dfsg0/CONTRIBUTING.md 2019-03-31 15:16:24.000000000 +0000 @@ -0,0 +1,92 @@ +# Contributing + +When contributing to this repository, please first discuss the change you wish to make via issue, +email, or any other method with the owners of this repository before making a change. + +Please note we have a code of conduct, please follow it in all your interactions with the project. + +## Pull Request Process + +1. Ensure any install or build dependencies are removed before the end of the layer when doing a + build. +2. Update the README.md with details of changes to the interface, this includes new environment + variables, exposed ports, useful file locations and container parameters. +3. Increase the version numbers in any examples files and the README.md to the new version that this + Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). +4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you + do not have permission to do that, you may request the second reviewer to merge it for you. + +## Code of Conduct + +### Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, intergalactic origin, gender identity and expression, +level of experience, nationality, personal appearance, race, religion, or sexual identity and +orientation. + +### Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +### Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +### Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +### Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at mysofa@symonics.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +### Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff -Nru libmysofa-0.6~dfsg0/debian/changelog libmysofa-0.7~dfsg0/debian/changelog --- libmysofa-0.6~dfsg0/debian/changelog 2019-04-01 21:25:15.000000000 +0000 +++ libmysofa-0.7~dfsg0/debian/changelog 2019-08-20 13:47:39.000000000 +0000 @@ -1,3 +1,21 @@ +libmysofa (0.7~dfsg0-1) unstable; urgency=medium + + * New upstream version 0.7~dfsg0 + + [ Ondřej Nový ] + * Use debhelper-compat instead of debian/compat + + [ IOhannes m zmölnig ] + * Drop patches applied upstream + * Install library files from ${DEB_HOST_MULTIARCH} + * Add new libmysofa0 symbols + * State that building this package does not require root powers + * Drop obsolete d/source/local-options + * Bump dh compat to 12 + * Bumped standards to 4.4.0 + + -- IOhannes m zmölnig (Debian/GNU) Tue, 20 Aug 2019 15:47:39 +0200 + libmysofa (0.6~dfsg0-3) unstable; urgency=medium [ IOhannes m zmölnig ] diff -Nru libmysofa-0.6~dfsg0/debian/compat libmysofa-0.7~dfsg0/debian/compat --- libmysofa-0.6~dfsg0/debian/compat 2019-04-01 21:25:15.000000000 +0000 +++ libmysofa-0.7~dfsg0/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -10 diff -Nru libmysofa-0.6~dfsg0/debian/control libmysofa-0.7~dfsg0/debian/control --- libmysofa-0.6~dfsg0/debian/control 2019-04-01 21:25:15.000000000 +0000 +++ libmysofa-0.7~dfsg0/debian/control 2019-08-20 13:47:39.000000000 +0000 @@ -4,12 +4,13 @@ Uploaders: IOhannes m zmölnig (Debian/GNU) , Build-Depends: - debhelper (>= 10~), + debhelper-compat (= 12), dh-exec, cmake, zlib1g-dev | libz-dev, libcunit1-dev, -Standards-Version: 4.1.1 +Standards-Version: 4.4.0 +Rules-Requires-Root: no Section: devel Homepage: https://github.com/hoene/libmysofa Vcs-Git: https://salsa.debian.org/multimedia-team/libmysofa.git diff -Nru libmysofa-0.6~dfsg0/debian/libmysofa0.install libmysofa-0.7~dfsg0/debian/libmysofa0.install --- libmysofa-0.6~dfsg0/debian/libmysofa0.install 2019-04-01 21:25:15.000000000 +0000 +++ libmysofa-0.7~dfsg0/debian/libmysofa0.install 2019-08-20 13:47:39.000000000 +0000 @@ -1,2 +1,2 @@ #! /usr/bin/dh-exec -usr/lib/lib*.so.* usr/lib/${DEB_HOST_MULTIARCH}/ +usr/lib/${DEB_HOST_MULTIARCH}/lib*.so.* usr/lib/${DEB_HOST_MULTIARCH}/ diff -Nru libmysofa-0.6~dfsg0/debian/libmysofa0.symbols libmysofa-0.7~dfsg0/debian/libmysofa0.symbols --- libmysofa-0.6~dfsg0/debian/libmysofa0.symbols 2019-04-01 21:25:15.000000000 +0000 +++ libmysofa-0.7~dfsg0/debian/libmysofa0.symbols 2019-08-20 13:47:39.000000000 +0000 @@ -22,8 +22,11 @@ mysofa_neighborhood@Base 0.6~ mysofa_neighborhood_free@Base 0.6~ mysofa_neighborhood_init@Base 0.6~ + mysofa_neighborhood_init_withstepdefine@Base 0.7~ mysofa_open@Base 0.6~ + mysofa_open_advanced@Base 0.7~ mysofa_open_cached@Base 0.6~ + mysofa_open_no_norm@Base 0.7~ mysofa_resample@Base 0.6~ mysofa_s2c@Base 0.6~ mysofa_tocartesian@Base 0.6~ diff -Nru libmysofa-0.6~dfsg0/debian/libmysofa-dev.install libmysofa-0.7~dfsg0/debian/libmysofa-dev.install --- libmysofa-0.6~dfsg0/debian/libmysofa-dev.install 2019-04-01 21:25:15.000000000 +0000 +++ libmysofa-0.7~dfsg0/debian/libmysofa-dev.install 2019-08-20 13:47:39.000000000 +0000 @@ -1,4 +1,4 @@ #! /usr/bin/dh-exec usr/include/* -usr/lib/lib*.so usr/lib/${DEB_HOST_MULTIARCH}/ -usr/lib/lib*.a usr/lib/${DEB_HOST_MULTIARCH}/ +usr/lib/${DEB_HOST_MULTIARCH}/lib*.so usr/lib/${DEB_HOST_MULTIARCH}/ +usr/lib/${DEB_HOST_MULTIARCH}/lib*.a usr/lib/${DEB_HOST_MULTIARCH}/ diff -Nru libmysofa-0.6~dfsg0/debian/patches/CVE-2019-10672.patch libmysofa-0.7~dfsg0/debian/patches/CVE-2019-10672.patch --- libmysofa-0.6~dfsg0/debian/patches/CVE-2019-10672.patch 2019-04-01 21:25:15.000000000 +0000 +++ libmysofa-0.7~dfsg0/debian/patches/CVE-2019-10672.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -Description: backported fixes for CVE-2019-10672 -Author: Christian Höne/IOhannes m zmölnig -Origin: upstream -Applied-Upstream: d39a171e9c6a1c44dbdf43f9db6c3fbd887e38c1, 83d21e38f4ed65c2e3d76fc792bdf4abde6ec148, 05ff8a6903c8a357c6d6fd921276732767741670, 2ed84bbcf261629adf16c56a5b4532670084842e -Last-Update: 2019-04-01 ---- -This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ ---- libmysofa.orig/src/hdf/btree.c -+++ libmysofa/src/hdf/btree.c -@@ -308,8 +308,11 @@ - b = i / elements; - x = i % elements + start[0]; - if (x < sx) { -+ - j = x * size + b; -- ((char*)data->data)[j] = output[i]; -+ if (j >= 0 && j < data->data_len) { -+ ((char*) data->data)[j] = output[i]; -+ } - } - } - break; -@@ -321,7 +324,9 @@ - x = x / dy + start[0]; - if (y < sy && x < sx) { - j = ((x * sy + y) * size) + b; -- ((char*)data->data)[j] = output[i]; -+ if (j >= 0 && j < data->data_len) { -+ ((char*) data->data)[j] = output[i]; -+ } - } - } - break; -@@ -334,7 +339,9 @@ - x = (x / dzy) + start[0]; - if (z < sz && y < sy && x < sx) { - j = (x * szy + y * sz + z) * size + b; -- ((char*)data->data)[j] = output[i]; -+ if (j >= 0 && j < data->data_len) { -+ ((char*) data->data)[j] = output[i]; -+ } - } - } - break; ---- libmysofa.orig/src/hdf/dataobject.c -+++ libmysofa/src/hdf/dataobject.c -@@ -665,13 +665,14 @@ - - if(name_size>0x1000) - return MYSOFA_NO_MEMORY; -- name = malloc(name_size); -+ name = malloc(name_size + 1); - if(!name) - return MYSOFA_NO_MEMORY; - if(fread(name, 1, name_size, reader->fhd)!=name_size) { - free(name); - return errno; - } -+ name[name_size] = 0; - log(" attribute name %s\n", name); - - if (flags & 3) { ---- libmysofa.orig/src/hdf/fractalhead.c -+++ libmysofa/src/hdf/fractalhead.c -@@ -180,6 +180,12 @@ - log("\nfractal head type 1 length %4lX name %s address %lX\n", length, name, heap_header_address); - - dir = malloc(sizeof(struct DIR)); -+ if(!dir) { -+ free(name); -+ return MYSOFA_NO_MEMORY; -+ } -+ memset(dir,0,sizeof(*dir)); -+ - dir->next = dataobject->directory; - dataobject->directory = dir; - diff -Nru libmysofa-0.6~dfsg0/debian/patches/fix_export_symbols.patch libmysofa-0.7~dfsg0/debian/patches/fix_export_symbols.patch --- libmysofa-0.6~dfsg0/debian/patches/fix_export_symbols.patch 2019-04-01 21:25:15.000000000 +0000 +++ libmysofa-0.7~dfsg0/debian/patches/fix_export_symbols.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -Description: sync mysofa.h-declaration with exported symbols - symbols declared (but not defined) in the public header must be exported. -Author: IOhannes m zmölnig -Applied-Upstream: 00c6e62aecaac89e965348c85de5b7d71bd5f873 -Last-Update: 2017-07-20 ---- -This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ ---- libmysofa.orig/src/hrtf/tools.c -+++ libmysofa/src/hrtf/tools.c -@@ -45,6 +45,7 @@ - return 0; - } - -+MYSOFA_EXPORT - char* mysofa_getAttribute(struct MYSOFA_ATTRIBUTE *attr, char *name) { - while (attr) { - if (!strcmp(name, attr->name)) { diff -Nru libmysofa-0.6~dfsg0/debian/patches/series libmysofa-0.7~dfsg0/debian/patches/series --- libmysofa-0.6~dfsg0/debian/patches/series 2019-04-01 21:25:15.000000000 +0000 +++ libmysofa-0.7~dfsg0/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -fix_export_symbols.patch -CVE-2019-10672.patch diff -Nru libmysofa-0.6~dfsg0/.gitignore libmysofa-0.7~dfsg0/.gitignore --- libmysofa-0.6~dfsg0/.gitignore 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,146 +0,0 @@ -### Eclipse - -#.project -#.cproject -bin/ -.settings/ - -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion - -*.iml - -## Directory-based project format: -.idea/ -# if you remove the above rule, at least ignore the following: - -# User-specific stuff: -# .idea/workspace.xml -# .idea/tasks.xml -# .idea/dictionaries - -# Sensitive or high-churn files: -# .idea/dataSources.ids -# .idea/dataSources.xml -# .idea/sqlDataSources.xml -# .idea/dynamic.xml -# .idea/uiDesigner.xml - -# Gradle: -# .idea/gradle.xml -# .idea/libraries - -# Mongo Explorer plugin: -# .idea/mongoSettings.xml - -## File-based project format: -*.ipr -*.iws - -## Plugin-specific files: - -# IntelliJ -/out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties - - -### Linux template -*~ - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* - - -### C template -# Object files -*.o -*.ko -*.obj -*.elf - -# Precompiled Headers -*.gch -*.pch - -# Libraries -# *.lib -*.a -*.la -*.lo - -# Shared objects (inc. Windows DLLs) -# *.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Debug files -*.dSYM/ - - -### C++ template -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -# *.dll - -# Fortran module files -*.mod - -# Compiled Static libraries -*.lai -*.la -*.a -# *.lib - -# Executables -*.exe -*.out -*.app - - -### Vim template -[._]*.s[a-w][a-z] -[._]s[a-w][a-z] -*.un~ -Session.vim -.netrwhist -*~ - -# Build -build/ - -src/hrtf/mysofa_export.h -src/config.h - diff -Nru libmysofa-0.6~dfsg0/libmysofa.pc.cmake libmysofa-0.7~dfsg0/libmysofa.pc.cmake --- libmysofa-0.6~dfsg0/libmysofa.pc.cmake 1970-01-01 00:00:00.000000000 +0000 +++ libmysofa-0.7~dfsg0/libmysofa.pc.cmake 2019-03-31 15:16:24.000000000 +0000 @@ -0,0 +1,12 @@ +Name: @PROJECT_NAME@ +Description: @CPACK_PACKAGE_DESCRIPTION@ +Version: @PROJECT_VERSION@ +Requires: @PKG_CONFIG_REQUIRES@ +prefix=@CMAKE_INSTALL_PREFIX@ +includedir=${prefix}/include +libdir=${prefix}/lib +Libs: -L${libdir} -lmysofa +Cflags: -I${includedir} + +Libs.private: @PKG_CONFIG_PRIVATELIBS@ +#Requires.private: diff -Nru libmysofa-0.6~dfsg0/README.md libmysofa-0.7~dfsg0/README.md --- libmysofa-0.6~dfsg0/README.md 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/README.md 2019-03-31 15:16:24.000000000 +0000 @@ -1,28 +1,41 @@ +
+ + Symonics MySofa + +
- Travis CI Status +Travis CI Status - - Coverity Scan Build Status +Coverity Scan Build Status - - + AppVeyor Status + +Donate + + ## Compile -Enter following commands +On Ubuntu, to install the required components, enter + +> sudo apt install zlib1g-dev libcunit1-dev libcunit1-dev + +Then, to compile enter following commands > cd build @@ -34,24 +47,41 @@ > cd build && cpack -## Usage +## Usage -Libmysofa has a few main function calls. +Libmysofa has a few main function calls. -To read a SOFA file call +To read a SOFA file call ``` #include int filter_length; int err; -struct MYSOFA_EASY *hrtf; +struct MYSOFA_EASY *hrtf = NULL; hrtf = mysofa_open("file.sofa", 48000, &filter_length, &err); -if(hrtf==NULL) +if(hrtf==NULL) return err; ``` +This call will normalize your hrtf data upon opening. For non-normalized data, replace the call to mysofa_open by: + +``` +hrtf = mysofa_open_no_norm("file.sofa", 48000, &filter_length, &err); +``` + +Or for a complete control over neighbors search algorithm parameters: + +``` +bool norm = true; // bool, apply normalization upon import +float neighbor_angle_step = 5; // in degree, neighbor search angle step (common to azimuth and elevation) +float neighbor_radius_step = 0.01; // in meters, neighbor search radius step +hrtf = mysofa_open_advanced("file.sofa", 48000, &filter_length, &err, norm, neighbor_angle_step, neighbor_radius_step); +``` + +(The greater the neighbor_*_step, the faster the neighbors search. The algorithm will end up skipping true nearest neighbors if these values are set too high. To be define based on the will-be-imported sofa files grid step. Default mysofa_open method is usually fast enough for classical hrtf grids not to bother with the advanced one.) + To free the HRTF structure, call: ``` mysofa_close(hrtf); @@ -80,11 +110,11 @@ ``` void mysofa_s2c(float values[3]) ``` -which phi (azimuth measure counterwise from the X axis), theta (elevation measured up from the x-y plane), and r (distance between listener and source) as parameters in the float array and x,y,z as response in the same array. Similar, call +with phi (azimuth in degree, measured counterclockwise from the X axis), theta (elevation in degree, measured up from the X-Y plane), and r (distance between listener and source) as parameters in the float array and x,y,z as response in the same array. Similar, call ``` void mysofa_c2s(float values[3]) ``` -The coordinate system is defined in the SOFA specification and is the same as in the SOFA file. Typically, the x axis vector (1 0 0) is the listening direction. The y axis (0 1 0) is the left side of the listener and z (0 0 1) is upwards. +The coordinate system is defined in the SOFA specification and is the same as in the SOFA file. Typically, the X axis vector (1 0 0) is the listening direction. The Y axis (0 1 0) is the left side of the listener and Z (0 0 1) is upwards. Sometimes, you want to use multiple SOFA filters or if you have to open a SOFA file multiple times, you may use @@ -100,13 +130,13 @@ ... mysofa_cache_release_all(); ``` -Then, all HRTFs having the same filename and sampling rate are stored only once in memory. +Then, all HRTFs having the same filename and sampling rate are stored only once in memory. If your program is using several threads, you must use appropriate synchronisation mechanisms so only a single thread can access the library at a given time. ## OS support -Libmysofa compiles for Linux operating systems, OSX and Windows. By default, each commit is compiled with Travis CI under Ubuntu 14.04 and OSX 7.3 and with AppVeyor for Windows Visual Studio 2015 on a x64 system. In addition, FFmpeg is compiling libmysofa with MinGW under Windows using their own build system. +Libmysofa compiles for Linux operating systems, OSX and Windows. By default, each commit is compiled with Travis CI under Ubuntu 14.04 and OSX 7.3 and with AppVeyor for Windows Visual Studio 2015 on a x64 system. In addition, FFmpeg is compiling libmysofa with MinGW under Windows using their own build system. ## References @@ -114,9 +144,7 @@ * Christian Hoene and Piotr Majdak, "HDF5 under the SOFA – A 3D audio case in HDF5 on embedded and mobile devices", HDF Blog, https://www.hdfgroup.org/2017/04/hdf5-under-the-sofa-hdf5-on-embedded-and-mobile-devices/, April 26, 2017. * Christian Hoene, Isabel C. Patiño Mejía, Alexandru Cacerovschi, "MySofa: Design Your Personal HRTF", Audio Engineering Society Convention Paper 9764, Presented at the 142nd Convention, May 2017, Berlin, Germany, http://www.aes.org/e-lib/browse.cfm?elib=18640 - -## Disclaimer - -The SOFA files are from https://www.sofaconventions.org/, Piotr Majdak . The K-D tree algorithm is by John Tsiombikas . The resampler is by Jean-Marc Valin. The remaining source code is by Christian Hoene , Symonics GmbH, and available under BSD-3-Clause license. This work has been funded by German Federal Ministry of Education and Research, funding code 01IS14027A. +## Disclaimer +The SOFA files are from https://www.sofaconventions.org/, Piotr Majdak . The K-D tree algorithm is by John Tsiombikas . The resampler is by Jean-Marc Valin. The remaining source code is by Christian Hoene , Symonics GmbH, and available under BSD-3-Clause license. This work has been funded by German Federal Ministry of Education and Research, funding code 01IS14027A. diff -Nru libmysofa-0.6~dfsg0/src/CMakeLists.txt libmysofa-0.7~dfsg0/src/CMakeLists.txt --- libmysofa-0.6~dfsg0/src/CMakeLists.txt 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/CMakeLists.txt 2019-03-31 15:16:24.000000000 +0000 @@ -10,10 +10,14 @@ use_c99() -configure_file (config.h.in ${CMAKE_SOURCE_DIR}/src/config.h) +configure_file (config.h.in ${PROJECT_SOURCE_DIR}/src/config.h) -if(NOT WIN32) - find_library(MATH m) +if(NOT MSVC) + if(NOT WIN32) + find_library(MATH m) + else() + set(MATH "") + endif() include(FindZLIB) else() set(MATH "") @@ -21,16 +25,23 @@ if (NUGET) execute_process(COMMAND ${NUGET} install zlib) endif() - include_directories(${CMAKE_SOURCE_DIR}/windows/third-party/zlib-1.2.11/include/) + include_directories(${PROJECT_SOURCE_DIR}/windows/third-party/zlib-1.2.11/include/) endif() # include(FindZLIB) # include_directories(${ZLIB_INCLUDE_DIRS}) # MESSAGE(STATUS "ZLIB libs" ${ZLIB_LIBRARIES}) -if(NOT WIN32) +if(NOT MSVC) + if(NOT WIN32) find_library(MATH m) - include(FindZLIB) + else() + set(MATH "") + endif() + include(FindZLIB) + include_directories(${ZLIB_INCLUDE_DIRS}) + SET(PKG_CONFIG_PRIVATELIBS "-lm ${PKG_CONFIG_PRIVATELIBS}") + SET(PKG_CONFIG_PRIVATELIBS "-lz ${PKG_CONFIG_PRIVATELIBS}") else() set(MATH "") find_program(NUGET nuget) @@ -39,7 +50,7 @@ else() execute_process(COMMAND ${NUGET} install zlib) endif() - include_directories(${CMAKE_SOURCE_DIR}/windows/third-party/zlib-1.2.11/include/) + include_directories(${PROJECT_SOURCE_DIR}/windows/third-party/zlib-1.2.11/include/) endif() @@ -50,7 +61,7 @@ target_link_libraries (mysofa-static ${MATH} ${ZLIB_LIBRARIES}) SET_TARGET_PROPERTIES(mysofa-static PROPERTIES OUTPUT_NAME mysofa CLEAN_DIRECT_OUTPUT 1 POSITION_INDEPENDENT_CODE ON) install(TARGETS mysofa-static - ARCHIVE DESTINATION lib) + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) if(BUILD_SHARED_LIBS) add_library(mysofa-shared SHARED ${libsrc}) @@ -59,15 +70,15 @@ set_property(TARGET mysofa-shared PROPERTY VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") set_property(TARGET mysofa-shared PROPERTY SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR} ) set_property(TARGET mysofa-shared PROPERTY C_VISIBILITY_PRESET hidden) - GENERATE_EXPORT_HEADER(mysofa-shared BASE_NAME mysofa EXPORT_FILE_NAME ${CMAKE_SOURCE_DIR}/src/hrtf/mysofa_export.h) + GENERATE_EXPORT_HEADER(mysofa-shared BASE_NAME mysofa EXPORT_FILE_NAME ${PROJECT_SOURCE_DIR}/src/hrtf/mysofa_export.h) install(TARGETS mysofa-shared - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib) + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) else() - GENERATE_EXPORT_HEADER(mysofa-static BASE_NAME mysofa EXPORT_FILE_NAME ${CMAKE_SOURCE_DIR}/src/hrtf/mysofa_export.h) + GENERATE_EXPORT_HEADER(mysofa-static BASE_NAME mysofa EXPORT_FILE_NAME ${PROJECT_SOURCE_DIR}/src/hrtf/mysofa_export.h) endif() -install(FILES hrtf/mysofa.h DESTINATION include) +install(FILES hrtf/mysofa.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) if(BUILD_TESTS) add_executable(mysofa2json tests/sofa2json.c tests/json.c) @@ -84,8 +95,10 @@ install(TARGETS mysofa2json - RUNTIME DESTINATION bin - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif(BUILD_TESTS) +SET(PKG_CONFIG_PRIVATELIBS "${PKG_CONFIG_PRIVATELIBS}" PARENT_SCOPE) + diff -Nru libmysofa-0.6~dfsg0/src/hdf/btree.c libmysofa-0.7~dfsg0/src/hdf/btree.c --- libmysofa-0.6~dfsg0/src/hdf/btree.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hdf/btree.c 2019-03-31 15:16:24.000000000 +0000 @@ -1,8 +1,8 @@ /* - Copyright 2016 Christian Hoene, Symonics GmbH + Copyright 2016 Christian Hoene, Symonics GmbH -*/ + */ #include #include @@ -59,10 +59,10 @@ 00000690 15 00 00 00 d3 c7 19 a0 00 00 00 00 00 00 00 00 |................| 000006a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -*/ + */ static int readBTLF(struct READER *reader, struct BTREE *btree, - int number_of_records, union RECORD *records) { + int number_of_records, union RECORD *records) { int i; @@ -81,42 +81,51 @@ if (fread(buf, 1, 4, reader->fhd) != 4 || strncmp(buf, "BTLF", 4)) { log("cannot read signature of BTLF\n"); return MYSOFA_INVALID_FORMAT; - } log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); + }log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); if (fgetc(reader->fhd) != 0) { log("object BTLF must have version 0\n"); return MYSOFA_INVALID_FORMAT; } - type = (uint8_t)fgetc(reader->fhd); + type = (uint8_t) fgetc(reader->fhd); for (i = 0; i < number_of_records; i++) { switch (type) { case 5: - records->type5.hash_of_name = (uint32_t)readValue(reader, 4); + records->type5.hash_of_name = (uint32_t) readValue(reader, 4); records->type5.heap_id = readValue(reader, 7); log(" type5 %08X %14lX\n", records->type5.hash_of_name, - records->type5.heap_id); + records->type5.heap_id); records++; break; case 6: - /*creation_order = */readValue(reader, 8); - /*heap_id = */readValue(reader, 7); + /*creation_order = */ + readValue(reader, 8); + /*heap_id = */ + readValue(reader, 7); break; case 8: - /*heap_id = */readValue(reader, 8); - /*message_flags = */fgetc(reader->fhd); - /*creation_order = */readValue(reader, 4); - /*hash_of_name = */readValue(reader, 4); + /*heap_id = */ + readValue(reader, 8); + /*message_flags = */ + fgetc(reader->fhd); + /*creation_order = */ + readValue(reader, 4); + /*hash_of_name = */ + readValue(reader, 4); break; case 9: - /*heap_id = */readValue(reader, 8); - /*message_flags = */fgetc(reader->fhd); - /*creation_order = */readValue(reader, 4); + /*heap_id = */ + readValue(reader, 8); + /*message_flags = */ + fgetc(reader->fhd); + /*creation_order = */ + readValue(reader, 4); break; default: @@ -125,20 +134,20 @@ } } -/* fseeko(reader->fhd, bthd->root_node_address + bthd->node_size, SEEK_SET); skip checksum */ + /* fseeko(reader->fhd, bthd->root_node_address + bthd->node_size, SEEK_SET); skip checksum */ return MYSOFA_OK; } /* III.A.2. Disk Format: Level 1A2 - Version 2 B-trees - 000002d0 32 1d 42 54 48 44 00 08 00 02 00 00 11 00 00 00 |2.BTHD..........| - 000002e0 64 28 70 03 00 00 00 00 00 00 16 00 16 00 00 00 |d(p.............| - 000002f0 00 00 00 00 30 12 d9 6e 42 54 48 44 00 09 00 02 |....0..nBTHD....| - 00000300 00 00 0d 00 00 00 64 28 70 05 00 00 00 00 00 00 |......d(p.......| - 00000310 16 00 16 00 00 00 00 00 00 00 e2 0d 76 5c 46 53 |............v\FS| + 000002d0 32 1d 42 54 48 44 00 08 00 02 00 00 11 00 00 00 |2.BTHD..........| + 000002e0 64 28 70 03 00 00 00 00 00 00 16 00 16 00 00 00 |d(p.............| + 000002f0 00 00 00 00 30 12 d9 6e 42 54 48 44 00 09 00 02 |....0..nBTHD....| + 00000300 00 00 0d 00 00 00 64 28 70 05 00 00 00 00 00 00 |......d(p.......| + 00000310 16 00 16 00 00 00 00 00 00 00 e2 0d 76 5c 46 53 |............v\FS| -*/ + */ int btreeRead(struct READER *reader, struct BTREE *btree) { char buf[4]; @@ -147,30 +156,31 @@ if (fread(buf, 1, 4, reader->fhd) != 4 || strncmp(buf, "BTHD", 4)) { log("cannot read signature of BTHD\n"); return MYSOFA_INVALID_FORMAT; - } log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); + }log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); if (fgetc(reader->fhd) != 0) { log("object BTHD must have version 0\n"); return MYSOFA_INVALID_FORMAT; } - btree->type = (uint8_t)fgetc(reader->fhd); - btree->node_size = (uint32_t)readValue(reader, 4); - btree->record_size = (uint16_t)readValue(reader, 2); - btree->depth = (uint16_t)readValue(reader, 2); - - btree->split_percent = (uint8_t)fgetc(reader->fhd); - btree->merge_percent = (uint8_t)fgetc(reader->fhd); - btree->root_node_address = (uint64_t)readValue(reader, - reader->superblock.size_of_offsets); - btree->number_of_records = (uint16_t)readValue(reader, 2); - if(btree->number_of_records>0x1000) - return MYSOFA_UNSUPPORTED_FORMAT; - btree->total_number = (uint64_t)readValue(reader, reader->superblock.size_of_lengths); + btree->type = (uint8_t) fgetc(reader->fhd); + btree->node_size = (uint32_t) readValue(reader, 4); + btree->record_size = (uint16_t) readValue(reader, 2); + btree->depth = (uint16_t) readValue(reader, 2); + + btree->split_percent = (uint8_t) fgetc(reader->fhd); + btree->merge_percent = (uint8_t) fgetc(reader->fhd); + btree->root_node_address = (uint64_t) readValue(reader, + reader->superblock.size_of_offsets); + btree->number_of_records = (uint16_t) readValue(reader, 2); + if (btree->number_of_records > 0x1000) + return MYSOFA_UNSUPPORTED_FORMAT; + btree->total_number = (uint64_t) readValue(reader, + reader->superblock.size_of_lengths); /* fseek(reader->fhd, 4, SEEK_CUR); skip checksum */ - if(btree->total_number > 0x10000000) + if (btree->total_number > 0x10000000) return MYSOFA_NO_MEMORY; btree->records = malloc(sizeof(btree->records[0]) * btree->total_number); if (!btree->records) @@ -178,7 +188,7 @@ memset(btree->records, 0, sizeof(btree->records[0]) * btree->total_number); /* read records */ - if(fseek(reader->fhd, btree->root_node_address, SEEK_SET)<0) + if (fseek(reader->fhd, btree->root_node_address, SEEK_SET) < 0) return errno; return readBTLF(reader, btree, btree->number_of_records, btree->records); } @@ -194,7 +204,7 @@ int treeRead(struct READER *reader, struct DATAOBJECT *data) { int i, j, err, olen, elements, size, x, y, z, b, e, dy, dz, sx, sy, sz, dzy, - szy; + szy; char *input, *output; uint8_t node_type, node_level; @@ -202,7 +212,7 @@ uint32_t size_of_chunk; uint32_t filter_mask; uint64_t address_of_left_sibling, address_of_right_sibling, start[4], - child_pointer, key, store; + child_pointer, key, store; char buf[4]; @@ -220,17 +230,17 @@ if (fread(buf, 1, 4, reader->fhd) != 4 || strncmp(buf, "TREE", 4)) { log("cannot read signature of TREE\n"); return MYSOFA_INVALID_FORMAT; - } log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); + }log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); - node_type = (uint8_t)fgetc(reader->fhd); - node_level = (uint8_t)fgetc(reader->fhd); - entries_used = (uint16_t)readValue(reader, 2); - if(entries_used>0x1000) + node_type = (uint8_t) fgetc(reader->fhd); + node_level = (uint8_t) fgetc(reader->fhd); + entries_used = (uint16_t) readValue(reader, 2); + if (entries_used > 0x1000) return MYSOFA_UNSUPPORTED_FORMAT; address_of_left_sibling = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); address_of_right_sibling = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); elements = 1; for (j = 0; j < data->ds.dimensionality; j++) @@ -254,8 +264,8 @@ if (node_type == 0) { key = readValue(reader, reader->superblock.size_of_lengths); } else { - size_of_chunk = (uint32_t)readValue(reader, 4); - filter_mask = (uint32_t)readValue(reader, 4); + size_of_chunk = (uint32_t) readValue(reader, 4); + filter_mask = (uint32_t) readValue(reader, 4); if (filter_mask) { log("TREE all filters must be enabled\n"); free(output); @@ -272,12 +282,12 @@ } child_pointer = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); log(" data at %lX len %u\n", child_pointer, size_of_chunk); /* read data */ store = ftell(reader->fhd); - if (fseek(reader->fhd, child_pointer, SEEK_SET)<0) { + if (fseek(reader->fhd, child_pointer, SEEK_SET) < 0) { free(output); return errno; } @@ -308,8 +318,11 @@ b = i / elements; x = i % elements + start[0]; if (x < sx) { + j = x * size + b; - ((char*)data->data)[j] = output[i]; + if (j >= 0 && j < data->data_len) { + ((char*) data->data)[j] = output[i]; + } } } break; @@ -321,7 +334,9 @@ x = x / dy + start[0]; if (y < sy && x < sx) { j = ((x * sy + y) * size) + b; - ((char*)data->data)[j] = output[i]; + if (j >= 0 && j < data->data_len) { + ((char*) data->data)[j] = output[i]; + } } } break; @@ -334,7 +349,9 @@ x = (x / dzy) + start[0]; if (z < sz && y < sy && x < sx) { j = (x * szy + y * sz + z) * size + b; - ((char*)data->data)[j] = output[i]; + if (j >= 0 && j < data->data_len) { + ((char*) data->data)[j] = output[i]; + } } } break; @@ -343,7 +360,7 @@ return MYSOFA_INTERNAL_ERROR; } - if(fseek(reader->fhd, store, SEEK_SET)<0) { + if (fseek(reader->fhd, store, SEEK_SET) < 0) { free(output); return errno; } @@ -351,7 +368,7 @@ } free(output); - if(fseek(reader->fhd, 4, SEEK_CUR)<0) /* skip checksum */ + if (fseek(reader->fhd, 4, SEEK_CUR) < 0) /* skip checksum */ return errno; return MYSOFA_OK; diff -Nru libmysofa-0.6~dfsg0/src/hdf/dataobject.c libmysofa-0.7~dfsg0/src/hdf/dataobject.c --- libmysofa-0.6~dfsg0/src/hdf/dataobject.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hdf/dataobject.c 2019-03-31 15:16:24.000000000 +0000 @@ -1,16 +1,16 @@ /* - Copyright 2016 Christian Hoene, Symonics GmbH + Copyright 2016 Christian Hoene, Symonics GmbH -*/ + */ /* IV.A.1.b. Version 2 Data Object Header Prefix - 00000030 4f 48 44 52 02 2d d3 18 2b 53 d3 18 2b 53 d3 18 |OHDR.-..+S..+S..| - 00000040 2b 53 d3 18 2b 53 f4 01 02 22 00 00 00 00 |+S..+S..."......| - .... - 00000230 00 00 00 00 00 00 00 00 00 00 00 00 f9 ba 5d c9 |..............].| -*/ + 00000030 4f 48 44 52 02 2d d3 18 2b 53 d3 18 2b 53 d3 18 |OHDR.-..+S..+S..| + 00000040 2b 53 d3 18 2b 53 f4 01 02 22 00 00 00 00 |+S..+S..."......| + .... + 00000230 00 00 00 00 00 00 00 00 00 00 00 00 f9 ba 5d c9 |..............].| + */ #include #include @@ -21,10 +21,10 @@ #include "reader.h" static int readOCHK(struct READER *reader, struct DATAOBJECT *dataobject, - uint64_t end); + uint64_t end); static struct DATAOBJECT *findDataobject(struct READER *reader, - uint64_t address) { + uint64_t address) { struct DATAOBJECT *p = reader->all; while (p && p->address != address) p = p->all; @@ -40,11 +40,11 @@ * 00000230 00 00 00 00 00 00 00 00 00 00 00 00 f9 ba 5d c9 |..............].| -*/ + */ static int readOHDRHeaderMessageNIL(struct READER *reader, int length) { - if (fseek(reader->fhd, length, SEEK_CUR)<0) + if (fseek(reader->fhd, length, SEEK_CUR) < 0) return errno; return MYSOFA_OK; @@ -56,7 +56,7 @@ */ static int readOHDRHeaderMessageDataspace(struct READER *reader, - struct DATASPACE *ds) { + struct DATASPACE *ds) { int i; @@ -65,19 +65,19 @@ return MYSOFA_INVALID_FORMAT; } - ds->dimensionality = (uint8_t)fgetc(reader->fhd); + ds->dimensionality = (uint8_t) fgetc(reader->fhd); if (ds->dimensionality > 4) { log("dimensionality must be low 5\n"); return MYSOFA_INVALID_FORMAT; } - ds->flags = (uint8_t)fgetc(reader->fhd); - ds->type = (uint8_t)fgetc(reader->fhd); + ds->flags = (uint8_t) fgetc(reader->fhd); + ds->type = (uint8_t) fgetc(reader->fhd); for (i = 0; i < ds->dimensionality; i++) { if (i < 4) { ds->dimension_size[i] = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); log(" dimension %d %lu\n", i, ds->dimension_size[i]); } else readValue(reader, reader->superblock.size_of_lengths); @@ -87,7 +87,7 @@ for (i = 0; i < ds->dimensionality; i++) { if (i < 4) ds->dimension_max_size[i] = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); else readValue(reader, reader->superblock.size_of_lengths); @@ -103,29 +103,29 @@ 00 03 |+S..+S..."......| 00000050 0f 00 00 00 00 00 00 00 c9 11 00 00 00 00 00 00 |................| 00000060 5b 12 00 00 00 00 00 00 81 12 00 00 00 00 00 00 |[...............| -*/ + */ static int readOHDRHeaderMessageLinkInfo(struct READER *reader, - struct LINKINFO *li) { + struct LINKINFO *li) { if (fgetc(reader->fhd) != 0) { log("object OHDR link info message must have version 0\n"); return MYSOFA_UNSUPPORTED_FORMAT; } - li->flags = (uint8_t)fgetc(reader->fhd); + li->flags = (uint8_t) fgetc(reader->fhd); if (li->flags & 1) li->maximum_creation_index = readValue(reader, 8); li->fractal_heap_address = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); li->address_btree_index = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); if (li->flags & 2) li->address_btree_order = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); return MYSOFA_OK; } @@ -138,29 +138,28 @@ 000007e0 00|05 02 00 01 00 00 03 0a 10 10 00 00 07 00 6d |...............m| 000007f0 36 00 00 00 00 00 00 ea 00 00 00 00 00 00 00 15 |6...............| -*/ + */ static int readOHDRHeaderMessageDatatype(struct READER *reader, - struct DATATYPE *dt) { + struct DATATYPE *dt) { int i, j, c, err; - char *buffer, *p; + char *buffer; struct DATATYPE dt2; - dt->class_and_version = (uint8_t)fgetc(reader->fhd); + dt->class_and_version = (uint8_t) fgetc(reader->fhd); if ((dt->class_and_version & 0xf0) != 0x10 - && (dt->class_and_version & 0xf0) != 0x30) { + && (dt->class_and_version & 0xf0) != 0x30) { log("object OHDR datatype message must have version 1 not %d\n", - dt->class_and_version >> 4); + dt->class_and_version >> 4); return MYSOFA_UNSUPPORTED_FORMAT; } - dt->class_bit_field = (uint32_t)readValue(reader, 3); - dt->size = (uint32_t)readValue(reader, 4); - if(dt->size>64) + dt->class_bit_field = (uint32_t) readValue(reader, 3); + dt->size = (uint32_t) readValue(reader, 4); + if (dt->size > 64) return MYSOFA_UNSUPPORTED_FORMAT; - switch (dt->class_and_version & 0xf) { case 0: /* int */ dt->u.i.bit_offset = readValue(reader, 2); @@ -169,34 +168,34 @@ break; case 1: /* float */ - dt->u.f.bit_offset = (uint16_t)readValue(reader, 2); - dt->u.f.bit_precision = (uint16_t)readValue(reader, 2); - dt->u.f.exponent_location = (uint8_t)fgetc(reader->fhd); - dt->u.f.exponent_size = (uint8_t)fgetc(reader->fhd); - dt->u.f.mantissa_location = (uint8_t)fgetc(reader->fhd); - dt->u.f.mantissa_size = (uint8_t)fgetc(reader->fhd); - dt->u.f.exponent_bias = (uint32_t)readValue(reader, 4); + dt->u.f.bit_offset = (uint16_t) readValue(reader, 2); + dt->u.f.bit_precision = (uint16_t) readValue(reader, 2); + dt->u.f.exponent_location = (uint8_t) fgetc(reader->fhd); + dt->u.f.exponent_size = (uint8_t) fgetc(reader->fhd); + dt->u.f.mantissa_location = (uint8_t) fgetc(reader->fhd); + dt->u.f.mantissa_size = (uint8_t) fgetc(reader->fhd); + dt->u.f.exponent_bias = (uint32_t) readValue(reader, 4); log(" FLOAT bit %d %d exponent %d %d MANTISSA %d %d OFFSET %d\n", - dt->u.f.bit_offset, dt->u.f.bit_precision, dt->u.f.exponent_location, - dt->u.f.exponent_size, dt->u.f.mantissa_location, - dt->u.f.mantissa_size, dt->u.f.exponent_bias); + dt->u.f.bit_offset, dt->u.f.bit_precision, dt->u.f.exponent_location, + dt->u.f.exponent_size, dt->u.f.mantissa_location, + dt->u.f.mantissa_size, dt->u.f.exponent_bias); /* FLOAT bit 0 32 exponent 23 8 MANTISSA 0 23 OFFSET 127 - FLOAT bit 0 64 exponent 52 11 MANTISSA 0 52 OFFSET 1023 */ + FLOAT bit 0 64 exponent 52 11 MANTISSA 0 52 OFFSET 1023 */ if (dt->u.f.bit_offset != 0 || dt->u.f.mantissa_location != 0 - || (dt->u.f.bit_precision != 32 && dt->u.f.bit_precision != 64) - || (dt->u.f.bit_precision == 32 - && (dt->u.f.exponent_location != 23 - || dt->u.f.exponent_size != 8 - || dt->u.f.mantissa_size != 23 - || dt->u.f.exponent_bias != 127)) - || (dt->u.f.bit_precision == 64 - && (dt->u.f.exponent_location != 52 - || dt->u.f.exponent_size != 11 - || dt->u.f.mantissa_size != 52 - || dt->u.f.exponent_bias != 1023))) + || (dt->u.f.bit_precision != 32 && dt->u.f.bit_precision != 64) + || (dt->u.f.bit_precision == 32 + && (dt->u.f.exponent_location != 23 + || dt->u.f.exponent_size != 8 + || dt->u.f.mantissa_size != 23 + || dt->u.f.exponent_bias != 127)) + || (dt->u.f.bit_precision == 64 + && (dt->u.f.exponent_location != 52 + || dt->u.f.exponent_size != 11 + || dt->u.f.mantissa_size != 52 + || dt->u.f.exponent_bias != 1023))) return MYSOFA_UNSUPPORTED_FORMAT; break; @@ -208,36 +207,42 @@ log(" COMPONENT %d %02X\n", dt->size, dt->class_bit_field); if ((dt->class_and_version & 0xf0) != 0x30) { log("object OHDR datatype message must have version 1 not %d\n", - dt->class_and_version >> 4); + dt->class_and_version >> 4); return MYSOFA_INVALID_FORMAT; } for (i = 0; i < (dt->class_bit_field & 0xffff); i++) { int maxsize = 0x1000; buffer = malloc(maxsize); - if(!buffer) + if (!buffer) return MYSOFA_NO_MEMORY; - for(j=0;jfhd); - if(c<0) { + if (c < 0) { free(buffer); return MYSOFA_READ_ERROR; } buffer[j] = c; - if(c==0) + if (c == 0) break; } - buffer[j]=0; - p = realloc(buffer, j); - if (!p) { - free(buffer); - return errno; - } - buffer = p; + buffer[j] = 0; for (j = 0, c = 0; (dt->size >> (8 * j)) > 0; j++) { c |= fgetc(reader->fhd) << (8 * j); - } log(" COMPONENT %s offset %d\n", buffer, c); + } + + log(" COMPONENT %s offset %d\n", buffer, c); + + /* not needed until the data is stored somewhere permanently + p = realloc(buffer, j); + if (!p) { + free(buffer); + return errno; + } + buffer = p; + */ free(buffer); + err = readOHDRHeaderMessageDatatype(reader, &dt2); if (err) return err; @@ -258,7 +263,7 @@ default: log("object OHDR datatype message has unknown variable type %d\n", - dt->class_and_version & 0xf); + dt->class_and_version & 0xf); return MYSOFA_UNSUPPORTED_FORMAT; } @@ -270,7 +275,7 @@ 000007e0 |05 02 00 01 00 00|03 0a -*/ + */ static int readOHDRHeaderMessageDataFill(struct READER *reader) { @@ -278,19 +283,19 @@ uint8_t flags; uint32_t size; - version = (uint8_t)fgetc(reader->fhd); + version = (uint8_t) fgetc(reader->fhd); if (version != 3) { log( - "object OHDR data storage fill value message must have version 3 not %d\n", - version); + "object OHDR data storage fill value message must have version 3 not %d\n", + version); return MYSOFA_INVALID_FORMAT; } - flags = (uint8_t)fgetc(reader->fhd); + flags = (uint8_t) fgetc(reader->fhd); if (flags & (1 << 5)) { - size = (uint32_t)readValue(reader, 4); - if (fseek(reader->fhd, size, SEEK_CUR)<0) + size = (uint32_t) readValue(reader, 4); + if (fseek(reader->fhd, size, SEEK_CUR) < 0) return errno; } @@ -314,10 +319,10 @@ 00000f30 00 00 00 00 03 00 05 00 08 00 04 00 00 54 79 70 |.............Typ| -*/ + */ static int readOHDRHeaderMessageDataLayout(struct READER *reader, - struct DATAOBJECT *data) { + struct DATAOBJECT *data) { int i, err; unsigned size; @@ -334,15 +339,15 @@ return MYSOFA_INVALID_FORMAT; } - layout_class = (uint8_t)fgetc(reader->fhd); + layout_class = (uint8_t) fgetc(reader->fhd); switch (layout_class) { #if 0 case 0: - data_size = readValue(reader, 2); - fseek(reader->fhd, data_size, SEEK_CUR); - log("TODO 0 SIZE %u\n", data_size); - break; + data_size = readValue(reader, 2); + fseek(reader->fhd, data_size, SEEK_CUR); + log("TODO 0 SIZE %u\n", data_size); + break; #endif case 1: data_address = readValue(reader, reader->superblock.size_of_offsets); @@ -351,7 +356,7 @@ break; case 2: - dimensionality = (uint8_t)fgetc(reader->fhd); + dimensionality = (uint8_t) fgetc(reader->fhd); data_address = readValue(reader, reader->superblock.size_of_offsets); log(" CHUNK %lX\n", data_address); for (i = 0; i < dimensionality; i++) { @@ -366,7 +371,7 @@ if (validAddress(reader, data_address)) { store = ftell(reader->fhd); - if (fseek(reader->fhd, data_address, SEEK_SET)<0) + if (fseek(reader->fhd, data_address, SEEK_SET) < 0) return errno; if (!data->data) { data->data_len = size; @@ -377,15 +382,15 @@ err = treeRead(reader, data); if (err) return err; - if (fseek(reader->fhd, store, SEEK_SET)<0) + if (fseek(reader->fhd, store, SEEK_SET) < 0) return errno; } break; default: log( - "object OHDR message data layout message has unknown layout class %d\n", - layout_class); + "object OHDR message data layout message has unknown layout class %d\n", + layout_class); return MYSOFA_INVALID_FORMAT; } @@ -401,23 +406,23 @@ */ static int readOHDRHeaderMessageGroupInfo(struct READER *reader, - struct GROUPINFO *gi) { + struct GROUPINFO *gi) { if (fgetc(reader->fhd) != 0) { log("object OHDR group info message must have version 0\n"); return MYSOFA_UNSUPPORTED_FORMAT; } - gi->flags = (uint8_t)fgetc(reader->fhd); + gi->flags = (uint8_t) fgetc(reader->fhd); if (gi->flags & 1) { - gi->maximum_compact_value = (uint16_t)readValue(reader, 2); - gi->minimum_dense_value = (uint16_t)readValue(reader, 2); + gi->maximum_compact_value = (uint16_t) readValue(reader, 2); + gi->minimum_dense_value = (uint16_t) readValue(reader, 2); } if (gi->flags & 2) { - gi->number_of_entries = (uint16_t)readValue(reader, 2); - gi->length_of_entries = (uint16_t)readValue(reader, 2); + gi->number_of_entries = (uint16_t) readValue(reader, 2); + gi->length_of_entries = (uint16_t) readValue(reader, 2); } return MYSOFA_OK; } @@ -435,7 +440,7 @@ uint16_t filter_identification_value, flags, number_client_data_values; uint32_t client_data; uint64_t maximum_compact_value, minimum_dense_value, number_of_entries, - length_of_entries; + length_of_entries; UNUSED(flags); UNUSED(client_data); @@ -449,28 +454,28 @@ return MYSOFA_INVALID_FORMAT; } - filters = (uint8_t)fgetc(reader->fhd); + filters = (uint8_t) fgetc(reader->fhd); if (filters > 32) { log("object OHDR filter pipeline message has too many filters: %d\n", - filters); + filters); return MYSOFA_INVALID_FORMAT; } for (i = 0; i < filters; i++) { - filter_identification_value = (uint16_t)readValue(reader, 2); + filter_identification_value = (uint16_t) readValue(reader, 2); switch (filter_identification_value) { case 1: case 2: break; default: log( - "object OHDR filter pipeline message contains unsupported filter: %d\n", - filter_identification_value); + "object OHDR filter pipeline message contains unsupported filter: %d\n", + filter_identification_value); return MYSOFA_INVALID_FORMAT; - } log(" filter %d\n", filter_identification_value); - flags = (uint16_t)readValue(reader, 2); - number_client_data_values = (uint16_t)readValue(reader, 2); - if(number_client_data_values > 0x1000) + }log(" filter %d\n", filter_identification_value); + flags = (uint16_t) readValue(reader, 2); + number_client_data_values = (uint16_t) readValue(reader, 2); + if (number_client_data_values > 0x1000) return MYSOFA_UNSUPPORTED_FORMAT; /* no name here */ for (j = 0; j < number_client_data_values; j++) { @@ -486,19 +491,18 @@ struct DATATYPE *dt, struct DATASPACE *ds) { char *buffer, number[16]; - uint64_t reference, gcol=0, dataobject; + uint64_t reference, gcol = 0, dataobject; int err; struct DATAOBJECT *referenceData; if (dt->list) { if (dt->list - dt->size == 8) { - readValue(reader, 4); /* TODO unknown? */ + readValue(reader, 4); /* TODO unknown? */ gcol = readValue(reader, 4); } else { gcol = readValue(reader, dt->list - dt->size); - } - log(" GCOL %d %8lX %8lX\n",dt->list - dt->size,gcol,ftell(reader->fhd)); -/* fseek(reader->fhd, dt->list - dt->size, SEEK_CUR); TODO: missing part in specification */ + } log(" GCOL %d %8lX %8lX\n",dt->list - dt->size,gcol,ftell(reader->fhd)); + /* fseek(reader->fhd, dt->list - dt->size, SEEK_CUR); TODO: missing part in specification */ } switch (dt->class_and_version & 0xf) { @@ -521,7 +525,7 @@ /* * 000036e3 67 0e 00 00 00 00 00 00 00 00 00 00 00 |...g............| 000036f0 00 00 00 - */ + */ case 6: /* TODO unclear spec */ log("COMPONENT todo %lX %d\n", ftell(reader->fhd),dt->size); @@ -530,27 +534,27 @@ break; case 7: - readValue(reader, 4); /* TODO unclear reference */ + readValue(reader, 4); /* TODO unclear reference */ reference = readValue(reader, dt->size - 4); log(" REFERENCE size %d %lX\n",dt->size, reference); if (!!(err = gcolRead(reader, gcol, reference, &dataobject))) { - return MYSOFA_OK; /* ignore error - return err; */ + return MYSOFA_OK; /* ignore error + return err; */ } referenceData = findDataobject(reader, dataobject); if (referenceData) buffer = referenceData->name; else { - sprintf(number, "REF%08lX", (long unsigned int)reference); + sprintf(number, "REF%08lX", (long unsigned int) reference); buffer = number; } log(" REFERENCE %lu %lX %s\n", reference, dataobject, buffer); -/* if(!referenceData) { - return MYSOFA_UNSUPPORTED_FORMAT; - } */ + /* if(!referenceData) { + return MYSOFA_UNSUPPORTED_FORMAT; + } */ if (data->string) { data->string = realloc(data->string, - strlen(data->string) + strlen(buffer) + 2); + strlen(data->string) + strlen(buffer) + 2); strcat(data->string, ","); strcat(data->string, buffer); } else { @@ -584,7 +588,7 @@ } int readData(struct READER *reader, struct DATAOBJECT *da, struct DATATYPE *dt, - struct DATASPACE *ds) { + struct DATASPACE *ds) { if (ds->dimensionality == 0) { ds->dimension_size[0] = 1; } @@ -592,14 +596,14 @@ } /* - IV.A.2.q. The Object Header Continuation Message + IV.A.2.q. The Object Header Continuation Message - 10 10 00 00 07 00 6d |...............m| - 000007f0 36 00 00 00 00 00 00 ea 00 00 00 00 00 00 00 15 |6...............| -*/ + 10 10 00 00 07 00 6d |...............m| + 000007f0 36 00 00 00 00 00 00 ea 00 00 00 00 00 00 00 15 |6...............| + */ static int readOHDRHeaderMessageContinue(struct READER *reader, - struct DATAOBJECT *dataobject) { + struct DATAOBJECT *dataobject) { int err; uint64_t offset, length; @@ -607,23 +611,23 @@ offset = readValue(reader, reader->superblock.size_of_offsets); length = readValue(reader, reader->superblock.size_of_lengths); - if(offset > 0x1000000 || length > 0x10000000) + if (offset > 0x1000000 || length > 0x10000000) return MYSOFA_UNSUPPORTED_FORMAT; log(" continue %08lX %08lX\n", offset, length); store = ftell(reader->fhd); - if(fseek(reader->fhd, offset, SEEK_SET)<0) + if (fseek(reader->fhd, offset, SEEK_SET) < 0) return errno; err = readOCHK(reader, dataobject, offset + length); if (err) return err; - if(store<0) + if (store < 0) return MYSOFA_READ_ERROR; - if(fseek(reader->fhd, store, SEEK_SET)<0) + if (fseek(reader->fhd, store, SEEK_SET) < 0) return errno; log(" continue back\n"); @@ -631,12 +635,12 @@ } /* - IV.A.2.m. The Attribute Message + IV.A.2.m. The Attribute Message -*/ + */ static int readOHDRHeaderMessageAttribute(struct READER *reader, - struct DATAOBJECT *dataobject) { + struct DATAOBJECT *dataobject) { int err; uint8_t flags, encoding; @@ -656,22 +660,23 @@ return MYSOFA_INVALID_FORMAT; } - flags = (uint8_t)fgetc(reader->fhd); + flags = (uint8_t) fgetc(reader->fhd); - name_size = (uint16_t)readValue(reader, 2); - datatype_size = (uint16_t)readValue(reader, 2); - dataspace_size = (uint16_t)readValue(reader, 2); - encoding = (uint8_t)fgetc(reader->fhd); + name_size = (uint16_t) readValue(reader, 2); + datatype_size = (uint16_t) readValue(reader, 2); + dataspace_size = (uint16_t) readValue(reader, 2); + encoding = (uint8_t) fgetc(reader->fhd); - if(name_size>0x1000) + if (name_size > 0x1000) return MYSOFA_NO_MEMORY; - name = malloc(name_size); - if(!name) + name = malloc(name_size + 1); + if (!name) return MYSOFA_NO_MEMORY; - if(fread(name, 1, name_size, reader->fhd)!=name_size) { + if (fread(name, 1, name_size, reader->fhd) != name_size) { free(name); return errno; } + name[name_size] = 0; log(" attribute name %s\n", name); if (flags & 3) { @@ -716,29 +721,29 @@ 00000080 16 00 40 02 00 00 00 00 00 00 d2 02 00 00 00 00 |..@.............| 00000090 00 00 f8 02 00 00 00 00 00 00 -*/ + */ static int readOHDRHeaderMessageAttributeInfo(struct READER *reader, - struct ATTRIBUTEINFO *ai) { + struct ATTRIBUTEINFO *ai) { if (fgetc(reader->fhd) != 0) { log("object OHDR attribute info message must have version 0\n"); return MYSOFA_UNSUPPORTED_FORMAT; } - ai->flags = (uint8_t)fgetc(reader->fhd); + ai->flags = (uint8_t) fgetc(reader->fhd); if (ai->flags & 1) ai->maximum_creation_index = readValue(reader, 2); ai->fractal_heap_address = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); ai->attribute_name_btree = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); if (ai->flags & 2) ai->attribute_creation_order_btree = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); return MYSOFA_OK; } @@ -747,29 +752,29 @@ * read all OHDR messages */ static int readOHDRmessages(struct READER *reader, - struct DATAOBJECT *dataobject, uint64_t end_of_messages) { + struct DATAOBJECT *dataobject, uint64_t end_of_messages) { FILE *fhd = reader->fhd; int err; long end; while (ftell(fhd) < end_of_messages - 4) { /* final gap may has a size of up to 3 */ - uint8_t header_message_type = (uint8_t)fgetc(fhd); - uint16_t header_message_size = (uint16_t)readValue(reader, 2); - uint8_t header_message_flags = (uint8_t)fgetc(fhd); + uint8_t header_message_type = (uint8_t) fgetc(fhd); + uint16_t header_message_size = (uint16_t) readValue(reader, 2); + uint8_t header_message_flags = (uint8_t) fgetc(fhd); if ((header_message_flags & ~5) != 0) { log("OHDR unsupported OHDR message flag %02X\n", - header_message_flags); + header_message_flags); return MYSOFA_UNSUPPORTED_FORMAT; } if ((dataobject->flags & (1 << 2)) != 0) /* ignore header_creation_order */ - if(fseek(reader->fhd, 2, SEEK_CUR)<0) + if (fseek(reader->fhd, 2, SEEK_CUR) < 0) return errno; log(" OHDR message type %2d offset %6lX len %4X\n", header_message_type, - ftell(fhd), header_message_size); + ftell(fhd), header_message_size); end = ftell(fhd) + header_message_size; @@ -816,12 +821,12 @@ break; case 21: /* Attribute Info Message */ if (!!(err = readOHDRHeaderMessageAttributeInfo(reader, - &dataobject->ai))) + &dataobject->ai))) return err; break; default: log("OHDR unknown header message of type %d\n", - header_message_type); + header_message_type); return MYSOFA_UNSUPPORTED_FORMAT; } @@ -832,14 +837,14 @@ } } - if(fseek(fhd, end_of_messages + 4, SEEK_SET)<0) /* skip checksum */ + if (fseek(fhd, end_of_messages + 4, SEEK_SET) < 0) /* skip checksum */ return errno; return MYSOFA_OK; } static int readOCHK(struct READER *reader, struct DATAOBJECT *dataobject, - uint64_t end) { + uint64_t end) { int err; char buf[4]; @@ -847,9 +852,9 @@ if (fread(buf, 1, 4, reader->fhd) != 4 || strncmp(buf, "OCHK", 4)) { log("cannot read signature of OCHK\n"); return MYSOFA_INVALID_FORMAT; - } log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); + }log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); - err = readOHDRmessages(reader, dataobject, end - 4); /* substract checksum */ + err = readOHDRmessages(reader, dataobject, end - 4); /* subtract checksum */ if (err) { return err; } @@ -858,7 +863,7 @@ } int dataobjectRead(struct READER *reader, struct DATAOBJECT *dataobject, - char *name) { + char *name) { uint64_t size_of_chunk, end_of_messages; int err; char buf[4]; @@ -878,10 +883,10 @@ return MYSOFA_UNSUPPORTED_FORMAT; } - dataobject->flags = (uint8_t)fgetc(reader->fhd); + dataobject->flags = (uint8_t) fgetc(reader->fhd); if (dataobject->flags & (1 << 5)) { /* bit 5 indicated time stamps */ - if(fseek(reader->fhd, 16, SEEK_CUR)<0) /* skip them */ + if (fseek(reader->fhd, 16, SEEK_CUR) < 0) /* skip them */ return errno; } @@ -900,15 +905,16 @@ } /* not needed - if (validAddress(reader, dataobject->ai.attribute_name_btree)) { - fseek(reader->fhd, dataobject->ai.attribute_name_btree, SEEK_SET); - btreeRead(reader, &dataobject->attributes); - } - */ + if (validAddress(reader, dataobject->ai.attribute_name_btree)) { + fseek(reader->fhd, dataobject->ai.attribute_name_btree, SEEK_SET); + btreeRead(reader, &dataobject->attributes); + } + */ /* parse message attribute info */ if (validAddress(reader, dataobject->ai.fractal_heap_address)) { - if(fseek(reader->fhd, dataobject->ai.fractal_heap_address, SEEK_SET)<0) + if (fseek(reader->fhd, dataobject->ai.fractal_heap_address, SEEK_SET) + < 0) return errno; fractalheapRead(reader, dataobject, &dataobject->attributes_heap); } @@ -921,12 +927,12 @@ return err; } - /* no needed - if (validAddress(reader, dataobject->li.address_btree_index)) { - fseek(reader->fhd, dataobject->li.address_btree_index, SEEK_SET); - btreeRead(reader, &dataobject->objects); - } - */ + /* not needed + if (validAddress(reader, dataobject->li.address_btree_index)) { + fseek(reader->fhd, dataobject->li.address_btree_index, SEEK_SET); + btreeRead(reader, &dataobject->objects); + } + */ dataobject->all = reader->all; reader->all = dataobject; @@ -936,7 +942,7 @@ void dataobjectFree(struct READER *reader, struct DATAOBJECT *dataobject) { struct DATAOBJECT **p; - + btreeFree(&dataobject->attributes_btree); fractalheapFree(&dataobject->attributes_heap); btreeFree(&dataobject->objects_btree); diff -Nru libmysofa-0.6~dfsg0/src/hdf/fractalhead.c libmysofa-0.7~dfsg0/src/hdf/fractalhead.c --- libmysofa-0.6~dfsg0/src/hdf/fractalhead.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hdf/fractalhead.c 2019-03-31 15:16:24.000000000 +0000 @@ -1,8 +1,8 @@ /* - Copyright 2016 Christian Hoene, Symonics GmbH + Copyright 2016 Christian Hoene, Symonics GmbH -*/ + */ #include #include @@ -17,13 +17,13 @@ } static int directblockRead(struct READER *reader, struct DATAOBJECT *dataobject, - struct FRACTALHEAP *fractalheap) { + struct FRACTALHEAP *fractalheap) { char buf[4], *name, *value; int size, offset_size, length_size, err, len; uint8_t typeandversion; uint64_t unknown, heap_header_address, block_offset, block_size, offset, - length; + length; long store; struct DIR *dir; struct MYSOFA_ATTRIBUTE *attr; @@ -36,7 +36,7 @@ if (fread(buf, 1, 4, reader->fhd) != 4 || strncmp(buf, "FHDB", 4)) { log("cannot read signature of fractal heap indirect block\n"); return MYSOFA_INVALID_FORMAT; - } log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); + }log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); if (fgetc(reader->fhd) != 0) { log("object FHDB must have version 0\n"); @@ -44,7 +44,7 @@ } /* ignore heap_header_address */ - if(fseek(reader->fhd, reader->superblock.size_of_offsets, SEEK_CUR)<0) + if (fseek(reader->fhd, reader->superblock.size_of_offsets, SEEK_CUR) < 0) return errno; size = (fractalheap->maximum_heap_size + 7) / 8; @@ -78,10 +78,10 @@ * */ do { - typeandversion = (uint8_t)fgetc(reader->fhd); + typeandversion = (uint8_t) fgetc(reader->fhd); offset = readValue(reader, offset_size); length = readValue(reader, length_size); - if(offset>0x10000000 || length>0x10000000) + if (offset > 0x10000000 || length > 0x10000000) return MYSOFA_UNSUPPORTED_FORMAT; log(" %d %4lX %ld %8lX\n",typeandversion,offset,length,ftell(reader->fhd)); @@ -99,7 +99,7 @@ if (!(name = malloc(length))) return MYSOFA_NO_MEMORY; - if(fread(name, 1, length, reader->fhd)!=length) { + if (fread(name, 1, length, reader->fhd) != length) { free(name); return MYSOFA_READ_ERROR; } @@ -110,8 +110,8 @@ return MYSOFA_UNSUPPORTED_FORMAT; } - len = (int)readValue(reader, 2); - if(len > 0x1000 || len<0) { + len = (int) readValue(reader, 2); + if (len > 0x1000 || len < 0) { free(name); return MYSOFA_UNSUPPORTED_FORMAT; } @@ -125,7 +125,7 @@ free(name); return MYSOFA_NO_MEMORY; } - if(fread(value, 1, len, reader->fhd)!=len) { + if (fread(value, 1, len, reader->fhd) != len) { free(value); free(name); return MYSOFA_READ_ERROR; @@ -140,10 +140,9 @@ } else { log("FHDB type 3 unsupported values: %12lX\n",unknown); free(name); -/* TODO: return MYSOFA_UNSUPPORTED_FORMAT; */ + /* TODO: return MYSOFA_UNSUPPORTED_FORMAT; */ return MYSOFA_OK; - } - log(" %s = %s\n", name, value); + } log(" %s = %s\n", name, value); attr = malloc(sizeof(struct MYSOFA_ATTRIBUTE)); attr->name = name; @@ -162,24 +161,30 @@ } len = fgetc(reader->fhd); - if(len < 0) + if (len < 0) return MYSOFA_READ_ERROR; assert(len < 0x100); if (!(name = malloc(len + 1))) return MYSOFA_NO_MEMORY; - if(fread(name, 1, len, reader->fhd) != len) { + if (fread(name, 1, len, reader->fhd) != len) { free(name); return MYSOFA_READ_ERROR; } name[len] = 0; heap_header_address = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); log("\nfractal head type 1 length %4lX name %s address %lX\n", length, name, heap_header_address); dir = malloc(sizeof(struct DIR)); + if (!dir) { + free(name); + return MYSOFA_NO_MEMORY; + } + memset(dir, 0, sizeof(*dir)); + dir->next = dataobject->directory; dataobject->directory = dir; @@ -194,16 +199,16 @@ return err; } - if(store < 0) { + if (store < 0) { return errno; } - if(fseek(reader->fhd, store, SEEK_SET)<0) + if (fseek(reader->fhd, store, SEEK_SET) < 0) return errno; } else if (typeandversion != 0) { /* TODO is must be avoided somehow */ log("fractal head unknown type %d\n", typeandversion); -/* return MYSOFA_UNSUPPORTED_FORMAT; */ + /* return MYSOFA_UNSUPPORTED_FORMAT; */ return MYSOFA_OK; } @@ -217,12 +222,12 @@ */ static int indirectblockRead(struct READER *reader, - struct DATAOBJECT *dataobject, struct FRACTALHEAP *fractalheap, - uint64_t iblock_size) { + struct DATAOBJECT *dataobject, struct FRACTALHEAP *fractalheap, + uint64_t iblock_size) { int size, nrows, max_dblock_rows, k, n, err; uint32_t filter_mask; - uint64_t heap_header_address, block_offset, child_direct_block=0, - size_filtered, child_indirect_block; + uint64_t heap_header_address, block_offset, child_direct_block = 0, + size_filtered, child_indirect_block; long store; char buf[4]; @@ -235,7 +240,7 @@ if (fread(buf, 1, 4, reader->fhd) != 4 || strncmp(buf, "FHIB", 4)) { log("cannot read signature of fractal heap indirect block\n"); return MYSOFA_INVALID_FORMAT; - } log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); + }log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); if (fgetc(reader->fhd) != 0) { log("object FHIB must have version 0\n"); @@ -258,7 +263,7 @@ /* The maximum number of rows of direct blocks, max_dblock_rows, in any indirect block of a fractal heap is given by the following expression: */ max_dblock_rows = (log2i(fractalheap->maximum_direct_block_size) - - log2i(fractalheap->starting_block_size)) + 2; + - log2i(fractalheap->starting_block_size)) + 2; /* Using the computed values for nrows and max_dblock_rows, along with the Width of the doubling table, the number of direct and indirect block entries (K and N in the indirect block description, below) in an indirect block can be computed: */ if (nrows < max_dblock_rows) @@ -271,22 +276,22 @@ while (k > 0) { child_direct_block = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); if (fractalheap->encoded_length > 0) { size_filtered = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); filter_mask = readValue(reader, 4); - } log(">> %d %lX %d\n",k,child_direct_block,size); + }log(">> %d %lX %d\n",k,child_direct_block,size); if (validAddress(reader, child_direct_block)) { store = ftell(reader->fhd); - if(fseek(reader->fhd, child_direct_block, SEEK_SET)<0) + if (fseek(reader->fhd, child_direct_block, SEEK_SET) < 0) return errno; err = directblockRead(reader, dataobject, fractalheap); if (err) return err; - if(store<0) + if (store < 0) return MYSOFA_READ_ERROR; - if(fseek(reader->fhd, store, SEEK_SET)<0) + if (fseek(reader->fhd, store, SEEK_SET) < 0) return errno; } @@ -295,19 +300,19 @@ while (n > 0) { child_indirect_block = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); if (validAddress(reader, child_direct_block)) { store = ftell(reader->fhd); - if(fseek(reader->fhd, child_indirect_block, SEEK_SET)<0) + if (fseek(reader->fhd, child_indirect_block, SEEK_SET) < 0) return errno; err = indirectblockRead(reader, dataobject, fractalheap, - iblock_size * 2); + iblock_size * 2); if (err) return err; - if(store < 0) + if (store < 0) return MYSOFA_READ_ERROR; - if(fseek(reader->fhd, store, SEEK_SET)<0) + if (fseek(reader->fhd, store, SEEK_SET) < 0) return errno; } @@ -319,21 +324,21 @@ /* III.G. Disk Format: Level 1G - Fractal Heap - 00000240 46 52 48 50 00 08 00 00 00 02 00 10 00 00 00 00 |FRHP............| - 00000250 00 00 00 00 00 00 ff ff ff ff ff ff ff ff a3 0b |................| - 00000260 00 00 00 00 00 00 1e 03 00 00 00 00 00 00 00 10 |................| - 00000270 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 08 |................| - 00000280 00 00 00 00 00 00 16 00 00 00 00 00 00 00 00 00 |................| - 00000290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - 000002a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 |................| - 000002b0 00 04 00 00 00 00 00 00 00 00 01 00 00 00 00 00 |................| - 000002c0 28 00 01 00 29 32 00 00 00 00 00 00 01 00 60 49 |(...)2........`I| - 000002d0 32 1d 42 54 48 44 00 08 00 02 00 00 11 00 00 00 |2.BTHD..........| + 00000240 46 52 48 50 00 08 00 00 00 02 00 10 00 00 00 00 |FRHP............| + 00000250 00 00 00 00 00 00 ff ff ff ff ff ff ff ff a3 0b |................| + 00000260 00 00 00 00 00 00 1e 03 00 00 00 00 00 00 00 10 |................| + 00000270 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 08 |................| + 00000280 00 00 00 00 00 00 16 00 00 00 00 00 00 00 00 00 |................| + 00000290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 000002a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 |................| + 000002b0 00 04 00 00 00 00 00 00 00 00 01 00 00 00 00 00 |................| + 000002c0 28 00 01 00 29 32 00 00 00 00 00 00 01 00 60 49 |(...)2........`I| + 000002d0 32 1d 42 54 48 44 00 08 00 02 00 00 11 00 00 00 |2.BTHD..........| -*/ + */ int fractalheapRead(struct READER *reader, struct DATAOBJECT *dataobject, - struct FRACTALHEAP *fractalheap) { + struct FRACTALHEAP *fractalheap) { int err; char buf[4]; @@ -341,78 +346,79 @@ if (fread(buf, 1, 4, reader->fhd) != 4 || strncmp(buf, "FRHP", 4)) { log("cannot read signature of fractal heap\n"); return MYSOFA_UNSUPPORTED_FORMAT; - } log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); + }log("%08lX %.4s\n", (uint64_t )ftell(reader->fhd) - 4, buf); if (fgetc(reader->fhd) != 0) { log("object fractal heap must have version 0\n"); return MYSOFA_UNSUPPORTED_FORMAT; } - fractalheap->heap_id_length = (uint16_t)readValue(reader, 2); - fractalheap->encoded_length = (uint16_t)readValue(reader, 2); - if(fractalheap->encoded_length>0x8000) + fractalheap->heap_id_length = (uint16_t) readValue(reader, 2); + fractalheap->encoded_length = (uint16_t) readValue(reader, 2); + if (fractalheap->encoded_length > 0x8000) return MYSOFA_UNSUPPORTED_FORMAT; - fractalheap->flags = (uint8_t)fgetc(reader->fhd); - fractalheap->maximum_size = (uint32_t)readValue(reader, 4); + fractalheap->flags = (uint8_t) fgetc(reader->fhd); + fractalheap->maximum_size = (uint32_t) readValue(reader, 4); fractalheap->next_huge_object_id = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); fractalheap->btree_address_of_huge_objects = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); fractalheap->free_space = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); fractalheap->address_free_space = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); fractalheap->amount_managed_space = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); fractalheap->amount_allocated_space = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); fractalheap->offset_managed_space = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); fractalheap->number_managed_objects = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); fractalheap->size_huge_objects = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); fractalheap->number_huge_objects = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); fractalheap->size_tiny_objects = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); fractalheap->number_tiny_objects = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); - fractalheap->table_width = (uint16_t)readValue(reader, 2); + fractalheap->table_width = (uint16_t) readValue(reader, 2); fractalheap->starting_block_size = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); fractalheap->maximum_direct_block_size = readValue(reader, - reader->superblock.size_of_lengths); + reader->superblock.size_of_lengths); - fractalheap->maximum_heap_size = (uint16_t)readValue(reader, 2); - fractalheap->starting_row = (uint16_t)readValue(reader, 2); + fractalheap->maximum_heap_size = (uint16_t) readValue(reader, 2); + fractalheap->starting_row = (uint16_t) readValue(reader, 2); fractalheap->address_of_root_block = readValue(reader, - reader->superblock.size_of_offsets); + reader->superblock.size_of_offsets); - fractalheap->current_row = (uint16_t)readValue(reader, 2); + fractalheap->current_row = (uint16_t) readValue(reader, 2); if (fractalheap->encoded_length > 0) { fractalheap->size_of_filtered_block = readValue(reader, - reader->superblock.size_of_lengths); - fractalheap->fitler_mask = (uint32_t)readValue(reader, 4); + reader->superblock.size_of_lengths); + fractalheap->fitler_mask = (uint32_t) readValue(reader, 4); fractalheap->filter_information = malloc(fractalheap->encoded_length); if (!fractalheap->filter_information) return MYSOFA_NO_MEMORY; - if(fread(fractalheap->filter_information, 1, fractalheap->encoded_length, - reader->fhd) != fractalheap->encoded_length) { + if (fread(fractalheap->filter_information, 1, + fractalheap->encoded_length, reader->fhd) + != fractalheap->encoded_length) { free(fractalheap->filter_information); return MYSOFA_READ_ERROR; } } - if(fseek(reader->fhd, 4, SEEK_CUR)<0) { /* skip checksum */ + if (fseek(reader->fhd, 4, SEEK_CUR) < 0) { /* skip checksum */ return MYSOFA_READ_ERROR; } @@ -428,11 +434,12 @@ if (validAddress(reader, fractalheap->address_of_root_block)) { - if(fseek(reader->fhd, fractalheap->address_of_root_block, SEEK_SET)<0) + if (fseek(reader->fhd, fractalheap->address_of_root_block, SEEK_SET) + < 0) return errno; if (fractalheap->current_row) err = indirectblockRead(reader, dataobject, fractalheap, - fractalheap->starting_block_size); + fractalheap->starting_block_size); else { err = directblockRead(reader, dataobject, fractalheap); diff -Nru libmysofa-0.6~dfsg0/src/hdf/gcol.c libmysofa-0.7~dfsg0/src/hdf/gcol.c --- libmysofa-0.6~dfsg0/src/hdf/gcol.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hdf/gcol.c 2019-03-31 15:16:24.000000000 +0000 @@ -1,8 +1,8 @@ /* - Copyright 2016 Christian Hoene, Symonics GmbH + Copyright 2016 Christian Hoene, Symonics GmbH -*/ + */ #include #include @@ -31,7 +31,8 @@ log("object GCOL must have version 1\n"); return MYSOFA_INVALID_FORMAT; } - if(fgetc(reader->fhd)<0 || fgetc(reader->fhd)<0 || fgetc(reader->fhd)<0) + if (fgetc(reader->fhd) < 0 || fgetc(reader->fhd) < 0 + || fgetc(reader->fhd) < 0) return MYSOFA_READ_ERROR; address = ftell(reader->fhd); @@ -48,32 +49,32 @@ break; } reference_count = readValue(reader, 2); - if(fseek(reader->fhd, 4, SEEK_CUR)<0) { + if (fseek(reader->fhd, 4, SEEK_CUR) < 0) { free(gcol); return errno; } gcol->object_size = readValue(reader, - reader->superblock.size_of_lengths); - if(gcol->object_size>8) { + reader->superblock.size_of_lengths); + if (gcol->object_size > 8) { free(gcol); return MYSOFA_UNSUPPORTED_FORMAT; } gcol->value = readValue(reader, gcol->object_size); gcol->address = address; log(" GCOL object %d size %ld value %08lX\n", gcol->heap_object_index, - gcol->object_size, gcol->value); + gcol->object_size, gcol->value); gcol->next = reader->gcol; reader->gcol = gcol; } log(" END %08lX vs. %08lX\n", ftell(reader->fhd), end); /* bug in the normal hdf5 specification */ -/* fseek(reader->fhd, end, SEEK_SET); */ + /* fseek(reader->fhd, end, SEEK_SET); */ return MYSOFA_OK; } int gcolRead(struct READER *reader, uint64_t gcol, int reference, - uint64_t *dataobject) { + uint64_t *dataobject) { long pos; struct GCOL *p = reader->gcol; @@ -82,12 +83,12 @@ } if (!p) { pos = ftell(reader->fhd); - if(fseek(reader->fhd, gcol, SEEK_SET)<0) + if (fseek(reader->fhd, gcol, SEEK_SET) < 0) return MYSOFA_READ_ERROR; readGCOL(reader); - if(pos<0) + if (pos < 0) return MYSOFA_READ_ERROR; - if(fseek(reader->fhd, pos, SEEK_SET)<0) + if (fseek(reader->fhd, pos, SEEK_SET) < 0) return MYSOFA_READ_ERROR; p = reader->gcol; @@ -126,10 +127,10 @@ gcol = gcol->next; #endif - void gcolFree(struct GCOL *gcol) { - if (gcol) { - gcolFree(gcol->next); - free(gcol); - } +void gcolFree(struct GCOL *gcol) { + if (gcol) { + gcolFree(gcol->next); + free(gcol); } +} diff -Nru libmysofa-0.6~dfsg0/src/hdf/gunzip.c libmysofa-0.7~dfsg0/src/hdf/gunzip.c --- libmysofa-0.6~dfsg0/src/hdf/gunzip.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hdf/gunzip.c 2019-03-31 15:16:24.000000000 +0000 @@ -1,8 +1,8 @@ /* - Copyright 2016 Christian Hoene, Symonics GmbH + Copyright 2016 Christian Hoene, Symonics GmbH -*/ + */ #include #include diff -Nru libmysofa-0.6~dfsg0/src/hdf/reader.h libmysofa-0.7~dfsg0/src/hdf/reader.h --- libmysofa-0.6~dfsg0/src/hdf/reader.h 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hdf/reader.h 2019-03-31 15:16:24.000000000 +0000 @@ -1,8 +1,8 @@ /* -Copyright 2016 Christian Hoene, Symonics GmbH + Copyright 2016 Christian Hoene, Symonics GmbH - */ + */ #ifndef READER_H_ #define READER_H_ @@ -56,37 +56,37 @@ struct FRACTALHEAP { uint8_t flags; uint16_t heap_id_length, encoded_length, table_width, maximum_heap_size, - starting_row, current_row; + starting_row, current_row; uint32_t maximum_size, fitler_mask; uint64_t next_huge_object_id, btree_address_of_huge_objects, free_space, - address_free_space, amount_managed_space, amount_allocated_space, - offset_managed_space, number_managed_objects, size_huge_objects, - number_huge_objects, size_tiny_objects, number_tiny_objects, - starting_block_size, maximum_direct_block_size, - address_of_root_block, size_of_filtered_block; + address_free_space, amount_managed_space, amount_allocated_space, + offset_managed_space, number_managed_objects, size_huge_objects, + number_huge_objects, size_tiny_objects, number_tiny_objects, + starting_block_size, maximum_direct_block_size, + address_of_root_block, size_of_filtered_block; uint8_t *filter_information; }; int fractalheapRead(struct READER *reader, struct DATAOBJECT *dataobject, - struct FRACTALHEAP *fractalheap); + struct FRACTALHEAP *fractalheap); void fractalheapFree(struct FRACTALHEAP *fractalheap); struct LINKINFO { uint8_t flags; uint64_t maximum_creation_index, fractal_heap_address, address_btree_index, - address_btree_order; + address_btree_order; }; struct GROUPINFO { uint8_t flags; uint64_t maximum_compact_value, minimum_dense_value, number_of_entries, - length_of_entries; + length_of_entries; }; struct ATTRIBUTEINFO { uint8_t flags; uint64_t maximum_creation_index, fractal_heap_address, attribute_name_btree, - attribute_creation_order_btree; + attribute_creation_order_btree; }; struct DATASPACE { @@ -105,7 +105,7 @@ struct { uint16_t bit_offset, bit_precision; uint8_t exponent_location, exponent_size, mantissa_location, - mantissa_size; + mantissa_size; uint32_t exponent_bias; } f; } u; @@ -146,7 +146,7 @@ }; int dataobjectRead(struct READER *reader, struct DATAOBJECT *dataobject, - char *name); + char *name); void dataobjectFree(struct READER *reader, struct DATAOBJECT *dataobject); struct DIR { @@ -160,7 +160,7 @@ uint8_t size_of_lengths; uint64_t base_address, superblock_extension_address, end_of_file_address, - root_group_object_header_address; + root_group_object_header_address; struct DATAOBJECT dataobject; }; @@ -169,7 +169,7 @@ void superblockFree(struct READER *reader, struct SUPERBLOCK *superblock); int gcolRead(struct READER *reader, uint64_t gcol, int reference, - uint64_t *dataobject); + uint64_t *dataobject); void gcolFree(struct GCOL *gcol); int treeRead(struct READER *reader, struct DATAOBJECT *data); @@ -191,5 +191,4 @@ char *mysofa_strdup(const char *s); - #endif /* READER_H_ */ diff -Nru libmysofa-0.6~dfsg0/src/hdf/superblock.c libmysofa-0.7~dfsg0/src/hdf/superblock.c --- libmysofa-0.6~dfsg0/src/hdf/superblock.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hdf/superblock.c 2019-03-31 15:16:24.000000000 +0000 @@ -1,8 +1,8 @@ /* - Copyright 2016 Christian Hoene, Symonics GmbH + Copyright 2016 Christian Hoene, Symonics GmbH -*/ + */ #include #include @@ -11,10 +11,10 @@ #include "reader.h" /* read superblock - 00000000 89 48 44 46 0d 0a 1a 0a 02 08 08 00 00 00 00 00 |.HDF............| - 00000010 00 00 00 00 ff ff ff ff ff ff ff ff bc 62 12 00 |.............b..| - 00000020 00 00 00 00 30 00 00 00 00 00 00 00 27 33 a3 16 |....0.......'3..| -*/ + 00000000 89 48 44 46 0d 0a 1a 0a 02 08 08 00 00 00 00 00 |.HDF............| + 00000010 00 00 00 00 ff ff ff ff ff ff ff ff bc 62 12 00 |.............b..| + 00000020 00 00 00 00 30 00 00 00 00 00 00 00 27 33 a3 16 |....0.......'3..| + */ int superblockRead(struct READER *reader, struct SUPERBLOCK *superblock) { char buf[8]; @@ -22,7 +22,7 @@ /* signature */ if (fread(buf, 1, 8, reader->fhd) != 8 - || strncmp("\211HDF\r\n\032\n", buf, 8)) { + || strncmp("\211HDF\r\n\032\n", buf, 8)) { log("file does not have correct signature"); return MYSOFA_INVALID_FORMAT; } @@ -33,26 +33,26 @@ return MYSOFA_UNSUPPORTED_FORMAT; } - superblock->size_of_offsets = (uint8_t)fgetc(reader->fhd); - superblock->size_of_lengths = (uint8_t)fgetc(reader->fhd); - if(fgetc(reader->fhd)<0) /* File Consistency Flags */ + superblock->size_of_offsets = (uint8_t) fgetc(reader->fhd); + superblock->size_of_lengths = (uint8_t) fgetc(reader->fhd); + if (fgetc(reader->fhd) < 0) /* File Consistency Flags */ return MYSOFA_READ_ERROR; if (superblock->size_of_offsets < 2 || superblock->size_of_offsets > 8 - || superblock->size_of_lengths < 2 - || superblock->size_of_lengths > 8) { + || superblock->size_of_lengths < 2 + || superblock->size_of_lengths > 8) { log("size of offsets and length is invalid: %d %d\n", - superblock->size_of_offsets, superblock->size_of_lengths); + superblock->size_of_offsets, superblock->size_of_lengths); return MYSOFA_UNSUPPORTED_FORMAT; } superblock->base_address = readValue(reader, superblock->size_of_offsets); superblock->superblock_extension_address = readValue(reader, - superblock->size_of_offsets); + superblock->size_of_offsets); superblock->end_of_file_address = readValue(reader, - superblock->size_of_offsets); + superblock->size_of_offsets); superblock->root_group_object_header_address = readValue(reader, - superblock->size_of_offsets); + superblock->size_of_offsets); if (superblock->base_address != 0) { log("base address is not null\n"); @@ -73,9 +73,9 @@ /* seek to first object */ if (fseek(reader->fhd, superblock->root_group_object_header_address, - SEEK_SET)) { + SEEK_SET)) { log("cannot seek to first object at %ld\n", - superblock->root_group_object_header_address); + superblock->root_group_object_header_address); return errno; } diff -Nru libmysofa-0.6~dfsg0/src/hrtf/cache.c libmysofa-0.7~dfsg0/src/hrtf/cache.c --- libmysofa-0.6~dfsg0/src/hrtf/cache.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/cache.c 2019-03-31 15:16:24.000000000 +0000 @@ -19,64 +19,65 @@ char *filename; float samplerate; int count; -} *cache; +}*cache; -static int compare_filenames(const char *a, const char *b) -{ - if(a == NULL && b == NULL) +static int compare_filenames(const char *a, const char *b) { + if (a == NULL && b == NULL) return 0; - if(a == NULL) + if (a == NULL) return -1; - else if(b == NULL) + else if (b == NULL) return 1; - return strcmp(a,b); + return strcmp(a, b); } -MYSOFA_EXPORT struct MYSOFA_EASY *mysofa_cache_lookup(const char *filename, float samplerate) -{ +MYSOFA_EXPORT struct MYSOFA_EASY *mysofa_cache_lookup(const char *filename, + float samplerate) { struct MYSOFA_CACHE_ENTRY *p; struct MYSOFA_EASY *res = NULL; p = cache; - while(p) { - if(samplerate == p->samplerate && !compare_filenames(filename, p->filename)) { + while (p) { + if (samplerate == p->samplerate + && !compare_filenames(filename, p->filename)) { res = p->easy; p->count++; break; } - p=p->next; + p = p->next; } return res; } -MYSOFA_EXPORT struct MYSOFA_EASY *mysofa_cache_store(struct MYSOFA_EASY *easy, const char *filename, float samplerate) -{ +MYSOFA_EXPORT struct MYSOFA_EASY *mysofa_cache_store(struct MYSOFA_EASY *easy, + const char *filename, float samplerate) { struct MYSOFA_CACHE_ENTRY *p; assert(easy); p = cache; - while(p) { - if(samplerate == p->samplerate && !compare_filenames(filename, p->filename)) { + while (p) { + if (samplerate == p->samplerate + && !compare_filenames(filename, p->filename)) { mysofa_close(easy); return p->easy; } - p=p->next; + p = p->next; } p = malloc(sizeof(struct MYSOFA_CACHE_ENTRY)); - if(p == NULL) { + if (p == NULL) { return NULL; } p->next = cache; p->samplerate = samplerate; p->filename = NULL; - if(filename != NULL) { + if (filename != NULL) { p->filename = mysofa_strdup(filename); - if(p->filename == NULL) { + if (p->filename == NULL) { free(p); return NULL; } @@ -87,8 +88,7 @@ return easy; } -MYSOFA_EXPORT void mysofa_cache_release(struct MYSOFA_EASY *easy) -{ +MYSOFA_EXPORT void mysofa_cache_release(struct MYSOFA_EASY *easy) { struct MYSOFA_CACHE_ENTRY **p; int count; @@ -97,33 +97,31 @@ p = &cache; - for(count=0;;count++) { - if((*p)->easy == easy) + for (count = 0;; count++) { + if ((*p)->easy == easy) break; p = &((*p)->next); assert(*p); } - if((*p)->count==1 && (count>0 || (*p)->next != NULL)) { + if ((*p)->count == 1 && (count > 0 || (*p)->next != NULL)) { struct MYSOFA_CACHE_ENTRY *gone = *p; free(gone->filename); mysofa_close(easy); *p = (*p)->next; free(gone); - } - else { + } else { (*p)->count--; } } -MYSOFA_EXPORT void mysofa_cache_release_all() -{ +MYSOFA_EXPORT void mysofa_cache_release_all() { struct MYSOFA_CACHE_ENTRY *p; p = cache; - while(p) { + while (p) { struct MYSOFA_CACHE_ENTRY *gone = p; - p=p->next; + p = p->next; free(gone->filename); free(gone->easy); free(gone); diff -Nru libmysofa-0.6~dfsg0/src/hrtf/check.c libmysofa-0.7~dfsg0/src/hrtf/check.c --- libmysofa-0.6~dfsg0/src/hrtf/check.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/check.c 2019-03-31 15:16:24.000000000 +0000 @@ -50,8 +50,7 @@ */ if (!verifyAttribute(hrtf->attributes, "Conventions", "SOFA") || !verifyAttribute(hrtf->attributes, "SOFAConventions", - "SimpleFreeFieldHRIR") - || + "SimpleFreeFieldHRIR") || /* TODO: Support FT too */ !verifyAttribute(hrtf->attributes, "DataType", "FIR") @@ -61,7 +60,7 @@ /*============================================================================== dimensions - ============================================================================== */ + ============================================================================== */ if (hrtf->C != 3 || hrtf->I != 1 || hrtf->E != 1 || hrtf->R != 2) return MYSOFA_INVALID_FORMAT; @@ -112,11 +111,11 @@ if (!compareValues(&hrtf->EmitterPosition, array000, 3)) return MYSOFA_INVALID_FORMAT; - /* TODO: Support data delays for each filter - However, so far, I have not seen any sofa files with an format other and I,R */ if (hrtf->DataDelay.values) { if (!verifyAttribute(hrtf->DataDelay.attributes, "DIMENSION_LIST", - "I,R")) + "I,R") + && !verifyAttribute(hrtf->DataDelay.attributes, + "DIMENSION_LIST", "M,R")) return MYSOFA_INVALID_FORMAT; } @@ -133,8 +132,8 @@ "cartesian")) return MYSOFA_INVALID_FORMAT; - if (!fequals(hrtf->ReceiverPosition.values[0], 0.) - || hrtf->ReceiverPosition.values[1] > 0 + if (!fequals(hrtf->ReceiverPosition.values[0], + 0.) || hrtf->ReceiverPosition.values[1] > 0 || !fequals(hrtf->ReceiverPosition.values[2], 0.) || !fequals(hrtf->ReceiverPosition.values[3], 0.) || !fequals(hrtf->ReceiverPosition.values[4], diff -Nru libmysofa-0.6~dfsg0/src/hrtf/easy.c libmysofa-0.7~dfsg0/src/hrtf/easy.c --- libmysofa-0.6~dfsg0/src/hrtf/easy.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/easy.c 2019-03-31 15:16:24.000000000 +0000 @@ -7,6 +7,7 @@ #include #include +#include #include #include "mysofa_export.h" #include "mysofa.h" @@ -15,10 +16,11 @@ * */ -MYSOFA_EXPORT struct MYSOFA_EASY* mysofa_open(const char *filename, float samplerate, int *filterlength, int *err) -{ +static struct MYSOFA_EASY* mysofa_open_default(const char *filename, + float samplerate, int *filterlength, int *err, bool applyNorm, + float neighbor_angle_step, float neighbor_radius_step) { struct MYSOFA_EASY *easy = malloc(sizeof(struct MYSOFA_EASY)); - if(!easy) { + if (!easy) { *err = MYSOFA_NO_MEMORY; return NULL; } @@ -44,11 +46,13 @@ return NULL; } - mysofa_loudness(easy->hrtf); + if (applyNorm) { + mysofa_loudness(easy->hrtf); + } -/* does not sound well: - mysofa_minphase(easy->hrtf,0.01); -*/ + /* does not sound well: + mysofa_minphase(easy->hrtf,0.01); + */ mysofa_tocartesian(easy->hrtf); @@ -59,34 +63,54 @@ return NULL; } - easy->neighborhood = mysofa_neighborhood_init(easy->hrtf, - easy->lookup); + easy->neighborhood = mysofa_neighborhood_init_withstepdefine(easy->hrtf, + easy->lookup, neighbor_angle_step, neighbor_radius_step); *filterlength = easy->hrtf->N; + easy->fir = malloc(easy->hrtf->N * easy->hrtf->R * sizeof(float)); + assert(easy->fir); + return easy; } -MYSOFA_EXPORT struct MYSOFA_EASY* mysofa_open_cached(const char *filename, float samplerate, int *filterlength, int *err) -{ +MYSOFA_EXPORT struct MYSOFA_EASY* mysofa_open(const char *filename, + float samplerate, int *filterlength, int *err) { + return mysofa_open_default(filename, samplerate, filterlength, err, true, + MYSOFA_DEFAULT_NEIGH_STEP_ANGLE, MYSOFA_DEFAULT_NEIGH_STEP_RADIUS); +} + +MYSOFA_EXPORT struct MYSOFA_EASY* mysofa_open_no_norm(const char *filename, + float samplerate, int *filterlength, int *err) { + return mysofa_open_default(filename, samplerate, filterlength, err, false, + MYSOFA_DEFAULT_NEIGH_STEP_ANGLE, MYSOFA_DEFAULT_NEIGH_STEP_RADIUS); +} + +MYSOFA_EXPORT struct MYSOFA_EASY* mysofa_open_advanced(const char *filename, + float samplerate, int *filterlength, int *err, bool norm, + float neighbor_angle_step, float neighbor_radius_step) { + return mysofa_open_default(filename, samplerate, filterlength, err, norm, + neighbor_angle_step, neighbor_radius_step); +} + +MYSOFA_EXPORT struct MYSOFA_EASY* mysofa_open_cached(const char *filename, + float samplerate, int *filterlength, int *err) { struct MYSOFA_EASY* res = mysofa_cache_lookup(filename, samplerate); - if(res) { + if (res) { *filterlength = res->hrtf->N; return res; } - res = mysofa_open(filename,samplerate,filterlength,err); - if(res) { - res = mysofa_cache_store(res,filename,samplerate); + res = mysofa_open(filename, samplerate, filterlength, err); + if (res) { + res = mysofa_cache_store(res, filename, samplerate); } return res; } -MYSOFA_EXPORT void mysofa_getfilter_short(struct MYSOFA_EASY* easy, float x, float y, float z, - short *IRleft, short *IRright, - int *delayLeft, int *delayRight) -{ +MYSOFA_EXPORT void mysofa_getfilter_short(struct MYSOFA_EASY* easy, float x, + float y, float z, short *IRleft, short *IRright, int *delayLeft, + int *delayRight) { float c[3]; - float *fir = malloc(easy->hrtf->N * easy->hrtf->R * sizeof(float)); float delays[2]; float *fl; float *fr; @@ -98,31 +122,26 @@ c[1] = y; c[2] = z; nearest = mysofa_lookup(easy->lookup, c); - assert(nearest>=0); + assert(nearest >= 0); neighbors = mysofa_neighborhood(easy->neighborhood, nearest); - - mysofa_interpolate(easy->hrtf, c, - nearest, neighbors, - fir, delays); - *delayLeft = delays[0] * easy->hrtf->DataSamplingRate.values[0]; + mysofa_interpolate(easy->hrtf, c, nearest, neighbors, easy->fir, delays); + + *delayLeft = delays[0] * easy->hrtf->DataSamplingRate.values[0]; *delayRight = delays[1] * easy->hrtf->DataSamplingRate.values[0]; - fl = fir; - fr = fir + easy->hrtf->N; - for(i=easy->hrtf->N;i>0;i--) { - *IRleft++ = *fl++ * 32767.; + fl = easy->fir; + fr = easy->fir + easy->hrtf->N; + for (i = easy->hrtf->N; i > 0; i--) { + *IRleft++ = *fl++ * 32767.; *IRright++ = *fr++ * 32767.; } - free(fir); } -MYSOFA_EXPORT void mysofa_getfilter_float(struct MYSOFA_EASY* easy, float x, float y, float z, - float *IRleft, float *IRright, - float *delayLeft, float *delayRight) -{ +MYSOFA_EXPORT void mysofa_getfilter_float(struct MYSOFA_EASY* easy, float x, + float y, float z, float *IRleft, float *IRright, float *delayLeft, + float *delayRight) { float c[3]; - float *fir = malloc(easy->hrtf->N * easy->hrtf->R * sizeof(float)); float delays[2]; float *fl; float *fr; @@ -134,39 +153,37 @@ c[1] = y; c[2] = z; nearest = mysofa_lookup(easy->lookup, c); - assert(nearest>=0); + assert(nearest >= 0); neighbors = mysofa_neighborhood(easy->neighborhood, nearest); - - mysofa_interpolate(easy->hrtf, c, - nearest, neighbors, - fir, delays); - *delayLeft = delays[0]; + float *res = mysofa_interpolate(easy->hrtf, c, nearest, neighbors, + easy->fir, delays); + + *delayLeft = delays[0]; *delayRight = delays[1]; - fl = fir; - fr = fir + easy->hrtf->N; - for(i=easy->hrtf->N;i>0;i--) { - *IRleft++ = *fl++; + fl = res; + fr = res + easy->hrtf->N; + for (i = easy->hrtf->N; i > 0; i--) { + *IRleft++ = *fl++; *IRright++ = *fr++; } - free(fir); } -MYSOFA_EXPORT void mysofa_close(struct MYSOFA_EASY* easy) -{ - if(easy) { - if(easy->neighborhood) +MYSOFA_EXPORT void mysofa_close(struct MYSOFA_EASY* easy) { + if (easy) { + if (easy->fir) + free(easy->fir); + if (easy->neighborhood) mysofa_neighborhood_free(easy->neighborhood); - if(easy->lookup) + if (easy->lookup) mysofa_lookup_free(easy->lookup); - if(easy->hrtf) + if (easy->hrtf) mysofa_free(easy->hrtf); free(easy); } } -MYSOFA_EXPORT void mysofa_close_cached(struct MYSOFA_EASY* easy) -{ +MYSOFA_EXPORT void mysofa_close_cached(struct MYSOFA_EASY* easy) { mysofa_cache_release(easy); } diff -Nru libmysofa-0.6~dfsg0/src/hrtf/interpolate.c libmysofa-0.7~dfsg0/src/hrtf/interpolate.c --- libmysofa-0.6~dfsg0/src/hrtf/interpolate.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/interpolate.c 2019-03-31 15:16:24.000000000 +0000 @@ -14,20 +14,20 @@ /* #define VDEBUG */ -MYSOFA_EXPORT float* mysofa_interpolate(struct MYSOFA_HRTF *hrtf, float *cordinate, - int nearest, int *neighborhood, float *fir, float *delays) { +MYSOFA_EXPORT float* mysofa_interpolate(struct MYSOFA_HRTF *hrtf, + float *cordinate, int nearest, int *neighborhood, float *fir, + float *delays) { int i, use[6]; float d, d6[6]; float weight; int size = hrtf->N * hrtf->R; - d = distance(cordinate, hrtf->SourcePosition.values + nearest); + d = distance(cordinate, hrtf->SourcePosition.values + nearest * hrtf->C); if (fequals(d, 0)) { if (hrtf->DataDelay.elements > hrtf->R) { delays[0] = hrtf->DataDelay.values[nearest * hrtf->R]; delays[1] = hrtf->DataDelay.values[nearest * hrtf->R + 1]; - } - else { + } else { delays[0] = hrtf->DataDelay.values[0]; delays[1] = hrtf->DataDelay.values[1]; } @@ -41,58 +41,58 @@ if (neighborhood[0] >= 0 && neighborhood[1] >= 0) { d6[0] = distance(cordinate, - hrtf->SourcePosition.values + neighborhood[0] * hrtf->C); + hrtf->SourcePosition.values + neighborhood[0] * hrtf->C); d6[1] = distance(cordinate, - hrtf->SourcePosition.values + neighborhood[1] * hrtf->C); + hrtf->SourcePosition.values + neighborhood[1] * hrtf->C); if (d6[0] < d6[1]) use[0] = 1; else use[1] = 1; } else if (neighborhood[0] >= 0) { d6[0] = distance(cordinate, - hrtf->SourcePosition.values + neighborhood[0] * hrtf->C); + hrtf->SourcePosition.values + neighborhood[0] * hrtf->C); use[0] = 1; } else if (neighborhood[1] >= 0) { d6[1] = distance(cordinate, - hrtf->SourcePosition.values + neighborhood[1] * hrtf->C); + hrtf->SourcePosition.values + neighborhood[1] * hrtf->C); use[1] = 1; } if (neighborhood[2] >= 0 && neighborhood[3] >= 0) { d6[2] = distance(cordinate, - hrtf->SourcePosition.values + neighborhood[2] * hrtf->C); + hrtf->SourcePosition.values + neighborhood[2] * hrtf->C); d6[3] = distance(cordinate, - hrtf->SourcePosition.values + neighborhood[3] * hrtf->C); + hrtf->SourcePosition.values + neighborhood[3] * hrtf->C); if (d6[2] < d6[3]) use[2] = 1; else use[3] = 1; } else if (neighborhood[2] >= 0) { d6[2] = distance(cordinate, - hrtf->SourcePosition.values + neighborhood[2] * hrtf->C); + hrtf->SourcePosition.values + neighborhood[2] * hrtf->C); use[2] = 1; } else if (neighborhood[3] >= 0) { d6[3] = distance(cordinate, - hrtf->SourcePosition.values + neighborhood[3] * hrtf->C); + hrtf->SourcePosition.values + neighborhood[3] * hrtf->C); use[3] = 1; } if (neighborhood[4] >= 0 && neighborhood[5] >= 0) { d6[4] = distance(cordinate, - hrtf->SourcePosition.values + neighborhood[4] * hrtf->C); + hrtf->SourcePosition.values + neighborhood[4] * hrtf->C); d6[5] = distance(cordinate, - hrtf->SourcePosition.values + neighborhood[5] * hrtf->C); + hrtf->SourcePosition.values + neighborhood[5] * hrtf->C); if (d6[4] < d6[5]) use[4] = 1; else use[5] = 1; } else if (neighborhood[4] >= 0) { d6[4] = distance(cordinate, - hrtf->SourcePosition.values + neighborhood[4] * hrtf->C); + hrtf->SourcePosition.values + neighborhood[4] * hrtf->C); use[4] = 1; } else if (neighborhood[5] >= 0) { d6[5] = distance(cordinate, - hrtf->SourcePosition.values + neighborhood[5] * hrtf->C); + hrtf->SourcePosition.values + neighborhood[5] * hrtf->C); use[5] = 1; } @@ -101,8 +101,7 @@ if (hrtf->DataDelay.elements > hrtf->R) { delays[0] = hrtf->DataDelay.values[nearest * hrtf->R] * weight; delays[1] = hrtf->DataDelay.values[nearest * hrtf->R + 1] * weight; - } - else { + } else { delays[0] = hrtf->DataDelay.values[0] * weight; delays[1] = hrtf->DataDelay.values[1] * weight; } @@ -115,13 +114,14 @@ #ifdef VDEBUG printf("%d - %f ",neighborhood[i], d6[i]); #endif - addArrayWeighted(fir, - hrtf->DataIR.values + neighborhood[i] * size, size, - w); + addArrayWeighted(fir, hrtf->DataIR.values + neighborhood[i] * size, + size, w); weight += w; if (hrtf->DataDelay.elements > hrtf->R) { - delays[0] += hrtf->DataDelay.values[neighborhood[i] * hrtf->R] * w; - delays[1] += hrtf->DataDelay.values[neighborhood[i] * hrtf->R + 1] * w; + delays[0] += hrtf->DataDelay.values[neighborhood[i] * hrtf->R] + * w; + delays[1] += hrtf->DataDelay.values[neighborhood[i] * hrtf->R + + 1] * w; } } } diff -Nru libmysofa-0.6~dfsg0/src/hrtf/kdtree.c libmysofa-0.7~dfsg0/src/hrtf/kdtree.c --- libmysofa-0.6~dfsg0/src/hrtf/kdtree.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/kdtree.c 2019-03-31 15:16:24.000000000 +0000 @@ -32,6 +32,12 @@ #include #include +/* avoid the use of malloc because we are in real-time critical processing routines: */ +#define USE_LIST_NODE_ALLOCATOR +/* libmysofa is by definition not thread safe */ +#define NO_PTHREADS +#define I_WANT_THREAD_BUGS + #if defined(WIN32) || defined(__WIN32__) #include #endif @@ -332,8 +338,7 @@ #endif static void kd_nearest_i(struct kdnode *node, const float *pos, - struct kdnode **result, float *result_dist_sq, - struct kdhyperrect* rect) { + struct kdnode **result, float *result_dist_sq, struct kdhyperrect* rect) { int dir = node->dir; int i; float dummy, dist_sq; @@ -522,8 +527,7 @@ return rset; }*/ -struct kdres *kd_nearest_range(struct kdtree *kd, const float *pos, - float range) { +struct kdres *kd_nearest_range(struct kdtree *kd, const float *pos, float range) { int ret; struct kdres *rset; @@ -581,8 +585,8 @@ return res; } -struct kdres *kd_nearest_range3(struct kdtree *tree, float x, float y, - float z, float range) { +struct kdres *kd_nearest_range3(struct kdtree *tree, float x, float y, float z, + float range) { float buf[3]; buf[0] = x; buf[1] = y; @@ -747,15 +751,14 @@ static pthread_mutex_t alloc_mutex = PTHREAD_MUTEX_INITIALIZER; #endif -static struct res_node *alloc_resnode(void) -{ +static struct res_node *alloc_resnode(void) { struct res_node *node; #ifndef NO_PTHREADS pthread_mutex_lock(&alloc_mutex); #endif - if(!free_nodes) { + if (!free_nodes) { node = malloc(sizeof *node); } else { node = free_nodes; @@ -770,8 +773,7 @@ return node; } -static void free_resnode(struct res_node *node) -{ +static void free_resnode(struct res_node *node) { #ifndef NO_PTHREADS pthread_mutex_lock(&alloc_mutex); #endif diff -Nru libmysofa-0.6~dfsg0/src/hrtf/kdtree.h libmysofa-0.7~dfsg0/src/hrtf/kdtree.h --- libmysofa-0.6~dfsg0/src/hrtf/kdtree.h 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/kdtree.h 2019-03-31 15:16:24.000000000 +0000 @@ -91,8 +91,8 @@ float range); struct kdres *kd_nearest_rangef(struct kdtree *tree, const float *pos, float range); -struct kdres *kd_nearest_range3(struct kdtree *tree, float x, float y, - float z, float range); +struct kdres *kd_nearest_range3(struct kdtree *tree, float x, float y, float z, + float range); struct kdres *kd_nearest_range3f(struct kdtree *tree, float x, float y, float z, float range); diff -Nru libmysofa-0.6~dfsg0/src/hrtf/lookup.c libmysofa-0.7~dfsg0/src/hrtf/lookup.c --- libmysofa-0.6~dfsg0/src/hrtf/lookup.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/lookup.c 2019-03-31 15:16:24.000000000 +0000 @@ -30,17 +30,40 @@ return NULL; /* - * find smallest and largest radius + * find smallest and largest phi, theta, and radius (to reduce neighbors table init) */ + float* origin; + origin = malloc(sizeof(float) * hrtf->C); + lookup->phi_min = FLT_MAX; + lookup->phi_max = FLT_MIN; + lookup->theta_min = FLT_MAX; + lookup->theta_max = FLT_MIN; lookup->radius_min = FLT_MAX; lookup->radius_max = FLT_MIN; - for (i = 0; i < hrtf->M; i ++) { - float r = radius(hrtf->SourcePosition.values + i * hrtf->C); - if (r < lookup->radius_min) - lookup->radius_min = r; - if (r > lookup->radius_max) - lookup->radius_max = r; + for (i = 0; i < hrtf->M; i++) { + memcpy(origin, hrtf->SourcePosition.values + i * hrtf->C, + sizeof(float) * hrtf->C); + convertCartesianToSpherical(origin, hrtf->C); + if (origin[0] < lookup->phi_min) { + lookup->phi_min = origin[0]; + } + if (origin[0] > lookup->phi_max) { + lookup->phi_max = origin[0]; + } + if (origin[1] < lookup->theta_min) { + lookup->theta_min = origin[1]; + } + if (origin[1] > lookup->theta_max) { + lookup->theta_max = origin[1]; + } + if (origin[2] < lookup->radius_min) { + lookup->radius_min = origin[2]; + } + if (origin[2] > lookup->radius_max) { + lookup->radius_max = origin[2]; + } } + free(origin); /* * Allocate kd tree @@ -56,7 +79,7 @@ */ for (i = 0; i < hrtf->M; i++) { float *f = hrtf->SourcePosition.values + i * hrtf->C; - kd_insert((struct kdtree *) lookup->kdtree, f, (void*)(intptr_t)i); + kd_insert((struct kdtree *) lookup->kdtree, f, (void*) (intptr_t) i); } return lookup; @@ -71,21 +94,19 @@ int index; struct kdres *res; float r = radius(coordinate); - if(r>lookup->radius_max) { + if (r > lookup->radius_max) { r = lookup->radius_max / r; coordinate[0] *= r; coordinate[1] *= r; coordinate[2] *= r; - } - else if(rradius_min) { + } else if (r < lookup->radius_min) { r = lookup->radius_min / r; coordinate[0] *= r; coordinate[1] *= r; coordinate[2] *= r; } - res = kd_nearest((struct kdtree *) lookup->kdtree, - coordinate); + res = kd_nearest((struct kdtree *) lookup->kdtree, coordinate); if (kd_res_size(res) != 1) { kd_res_free(res); return -1; @@ -96,7 +117,7 @@ } MYSOFA_EXPORT void mysofa_lookup_free(struct MYSOFA_LOOKUP *lookup) { - if(lookup) { + if (lookup) { kd_free((struct kdtree *) lookup->kdtree); free(lookup); } diff -Nru libmysofa-0.6~dfsg0/src/hrtf/loudness.c libmysofa-0.7~dfsg0/src/hrtf/loudness.c --- libmysofa-0.6~dfsg0/src/hrtf/loudness.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/loudness.c 2019-03-31 15:16:24.000000000 +0000 @@ -20,9 +20,9 @@ float c[3], factor; float min = FLT_MAX; int radius = 0; - int i, index=0; + int i, index = 0; int cartesian = verifyAttribute(hrtf->SourcePosition.attributes, "Type", - "cartesian"); + "cartesian"); /* * find frontal source position @@ -47,7 +47,7 @@ /* get loudness of frontal fir filter, for both channels*/ factor = loudness(hrtf->DataIR.values + (index / 3) * hrtf->N * hrtf->R, - hrtf->N * hrtf->R); + hrtf->N * hrtf->R); factor = sqrt(2 / factor); if (fequals(factor, 1.)) return 1.; diff -Nru libmysofa-0.6~dfsg0/src/hrtf/minphase.c libmysofa-0.7~dfsg0/src/hrtf/minphase.c --- libmysofa-0.6~dfsg0/src/hrtf/minphase.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/minphase.c 2019-03-31 15:16:24.000000000 +0000 @@ -66,7 +66,7 @@ */ for (i = 0; i < filters; i++) { trunk(hrtf->DataIR.values + i * hrtf->N, hrtf->N, start + i, end + i, - threshold); + threshold); if (end[i] - start[i] > max) max = end[i] - start[i]; } @@ -85,14 +85,14 @@ d[1] = hrtf->DataDelay.values[1]; hrtf->DataDelay.elements = filters; hrtf->DataDelay.values = realloc(hrtf->DataDelay.values, - sizeof(float) * filters); + sizeof(float) * filters); for (i = 0; i < filters; i++) { if (start[i] + max > hrtf->N) start[i] = hrtf->N - max; hrtf->DataDelay.values[i] = d[i % 1] + (start[i] / samplerate); memmove(hrtf->DataIR.values + i * max, - hrtf->DataIR.values + i * hrtf->N + start[i], - max * sizeof(float)); + hrtf->DataIR.values + i * hrtf->N + start[i], + max * sizeof(float)); } /* @@ -101,7 +101,7 @@ hrtf->N = max; hrtf->DataIR.elements = max * filters; hrtf->DataIR.values = realloc(hrtf->DataIR.values, - sizeof(float) * hrtf->DataIR.elements); + sizeof(float) * hrtf->DataIR.elements); free(start); free(end); diff -Nru libmysofa-0.6~dfsg0/src/hrtf/mysofa.h libmysofa-0.7~dfsg0/src/hrtf/mysofa.h --- libmysofa-0.6~dfsg0/src/hrtf/mysofa.h 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/mysofa.h 2019-03-31 15:16:24.000000000 +0000 @@ -1,8 +1,8 @@ /* - Copyright 2016 Christian Hoene, Symonics GmbH + Copyright 2016 Christian Hoene, Symonics GmbH -*/ + */ #ifndef MYSOFA_H_INCLUDED #define MYSOFA_H_INCLUDED @@ -11,131 +11,147 @@ #endif #include +#include + +#define MYSOFA_DEFAULT_NEIGH_STEP_ANGLE 0.5 +#define MYSOFA_DEFAULT_NEIGH_STEP_RADIUS 0.01 /** attributes */ - struct MYSOFA_ATTRIBUTE { - struct MYSOFA_ATTRIBUTE *next; - char *name; - char *value; - }; - - struct MYSOFA_ARRAY { - float *values; - unsigned int elements; - struct MYSOFA_ATTRIBUTE *attributes; - }; +struct MYSOFA_ATTRIBUTE { + struct MYSOFA_ATTRIBUTE *next; + char *name; + char *value; +}; + +struct MYSOFA_ARRAY { + float *values; + unsigned int elements; + struct MYSOFA_ATTRIBUTE *attributes; +}; /* * The HRTF structure data types */ - struct MYSOFA_HRTF { +struct MYSOFA_HRTF { - /* Dimensions defined in AES69 - M Number of measurements; must be integer greater than zero. - R Number of receivers; must be integer greater than zero. - E Number of emitters; must be integer greater than zero. - N Number of data samples describing one measurement; must be integer greater than zero. - S Number of characters in a string; must be integer greater than zero. - I 1 Singleton dimension, defines a scalar value. - C 3 Coordinate triplet, always three; the coordinate type defines the meaning of this dimension. - */ - unsigned I, C, R, E, N, M; + /* Dimensions defined in AES69 + M Number of measurements; must be integer greater than zero. + R Number of receivers; must be integer greater than zero. + E Number of emitters; must be integer greater than zero. + N Number of data samples describing one measurement; must be integer greater than zero. + S Number of characters in a string; must be integer greater than zero. + I 1 Singleton dimension, defines a scalar value. + C 3 Coordinate triplet, always three; the coordinate type defines the meaning of this dimension. + */ + unsigned I, C, R, E, N, M; - struct MYSOFA_ARRAY ListenerPosition; + struct MYSOFA_ARRAY ListenerPosition; - struct MYSOFA_ARRAY ReceiverPosition; + struct MYSOFA_ARRAY ReceiverPosition; - struct MYSOFA_ARRAY SourcePosition; + struct MYSOFA_ARRAY SourcePosition; - struct MYSOFA_ARRAY EmitterPosition; + struct MYSOFA_ARRAY EmitterPosition; - struct MYSOFA_ARRAY ListenerUp; + struct MYSOFA_ARRAY ListenerUp; - struct MYSOFA_ARRAY ListenerView; + struct MYSOFA_ARRAY ListenerView; - /** array of filter coefficients. Sizes are filters*filter_length. */ - struct MYSOFA_ARRAY DataIR; + /** array of filter coefficients. Sizes are filters*filter_length. */ + struct MYSOFA_ARRAY DataIR; - /** the sampling rate used in this structure */ - struct MYSOFA_ARRAY DataSamplingRate; + /** the sampling rate used in this structure */ + struct MYSOFA_ARRAY DataSamplingRate; - /** array of min-phase delays. Sizes are filters */ - struct MYSOFA_ARRAY DataDelay; + /** array of min-phase delays. Sizes are filters */ + struct MYSOFA_ARRAY DataDelay; - /** general file attributes */ - struct MYSOFA_ATTRIBUTE *attributes; - }; + /** general file attributes */ + struct MYSOFA_ATTRIBUTE *attributes; +}; /* structure for lookup HRTF filters */ - struct MYSOFA_LOOKUP { - void *kdtree; - float radius_min, radius_max; - }; - - struct MYSOFA_NEIGHBORHOOD { - int elements; - int *index; - }; - - enum { - MYSOFA_OK = 0, - MYSOFA_INVALID_FORMAT = 10000, - MYSOFA_UNSUPPORTED_FORMAT, - MYSOFA_INTERNAL_ERROR, - MYSOFA_NO_MEMORY, - MYSOFA_READ_ERROR - }; - - struct MYSOFA_HRTF* mysofa_load(const char *filename, int *err); - - int mysofa_check(struct MYSOFA_HRTF *hrtf); - char* mysofa_getAttribute(struct MYSOFA_ATTRIBUTE *attr, char *name); - void mysofa_tospherical(struct MYSOFA_HRTF *hrtf); - void mysofa_tocartesian(struct MYSOFA_HRTF *hrtf); - void mysofa_free(struct MYSOFA_HRTF *hrtf); - - struct MYSOFA_LOOKUP* mysofa_lookup_init(struct MYSOFA_HRTF *hrtf); - int mysofa_lookup(struct MYSOFA_LOOKUP *lookup, float *coordinate); - void mysofa_lookup_free(struct MYSOFA_LOOKUP *lookup); - - struct MYSOFA_NEIGHBORHOOD *mysofa_neighborhood_init(struct MYSOFA_HRTF *hrtf, - struct MYSOFA_LOOKUP *lookup); - int* mysofa_neighborhood(struct MYSOFA_NEIGHBORHOOD *neighborhood, int pos); - void mysofa_neighborhood_free(struct MYSOFA_NEIGHBORHOOD *neighborhood); - - float* mysofa_interpolate(struct MYSOFA_HRTF *hrtf, float *cordinate, - int nearest, int *neighborhood, float *fir, float *delays); - - int mysofa_resample(struct MYSOFA_HRTF *hrtf, float samplerate); - float mysofa_loudness(struct MYSOFA_HRTF *hrtf); - int mysofa_minphase(struct MYSOFA_HRTF *hrtf, float threshold); - - struct MYSOFA_EASY *mysofa_cache_lookup(const char *filename, float samplerate); - struct MYSOFA_EASY *mysofa_cache_store(struct MYSOFA_EASY *, const char *filename, float samplerate); - void mysofa_cache_release(struct MYSOFA_EASY *); - void mysofa_cache_release_all(void); - - void mysofa_c2s(float *values); - void mysofa_s2c(float *values); - - struct MYSOFA_EASY { - struct MYSOFA_HRTF *hrtf; - struct MYSOFA_LOOKUP *lookup; - struct MYSOFA_NEIGHBORHOOD *neighborhood; - }; - - struct MYSOFA_EASY* mysofa_open(const char *filename, float samplerate, int *filterlength, int *err); - struct MYSOFA_EASY* mysofa_open_cached(const char *filename, float samplerate, int *filterlength, int *err); - void mysofa_getfilter_short(struct MYSOFA_EASY* easy, float x, float y, float z, - short *IRleft, short *IRright, - int *delayLeft, int *delayRight); - void mysofa_getfilter_float(struct MYSOFA_EASY* easy, float x, float y, float z, - float *IRleft, float *IRright, - float *delayLeft, float *delayRight); - void mysofa_close(struct MYSOFA_EASY* easy); - void mysofa_close_cached(struct MYSOFA_EASY* easy); +struct MYSOFA_LOOKUP { + void *kdtree; + float radius_min, radius_max; + float theta_min, theta_max; + float phi_min, phi_max; +}; + +struct MYSOFA_NEIGHBORHOOD { + int elements; + int *index; +}; + +enum { + MYSOFA_OK = 0, + MYSOFA_INVALID_FORMAT = 10000, + MYSOFA_UNSUPPORTED_FORMAT, + MYSOFA_INTERNAL_ERROR, + MYSOFA_NO_MEMORY, + MYSOFA_READ_ERROR +}; + +struct MYSOFA_HRTF* mysofa_load(const char *filename, int *err); + +int mysofa_check(struct MYSOFA_HRTF *hrtf); +char* mysofa_getAttribute(struct MYSOFA_ATTRIBUTE *attr, char *name); +void mysofa_tospherical(struct MYSOFA_HRTF *hrtf); +void mysofa_tocartesian(struct MYSOFA_HRTF *hrtf); +void mysofa_free(struct MYSOFA_HRTF *hrtf); + +struct MYSOFA_LOOKUP* mysofa_lookup_init(struct MYSOFA_HRTF *hrtf); +int mysofa_lookup(struct MYSOFA_LOOKUP *lookup, float *coordinate); +void mysofa_lookup_free(struct MYSOFA_LOOKUP *lookup); + +struct MYSOFA_NEIGHBORHOOD *mysofa_neighborhood_init(struct MYSOFA_HRTF *hrtf, + struct MYSOFA_LOOKUP *lookup); +struct MYSOFA_NEIGHBORHOOD *mysofa_neighborhood_init_withstepdefine( + struct MYSOFA_HRTF *hrtf, struct MYSOFA_LOOKUP *lookup, + float neighbor_angle_step, float neighbor_radius_step); +int* mysofa_neighborhood(struct MYSOFA_NEIGHBORHOOD *neighborhood, int pos); +void mysofa_neighborhood_free(struct MYSOFA_NEIGHBORHOOD *neighborhood); + +float* mysofa_interpolate(struct MYSOFA_HRTF *hrtf, float *cordinate, + int nearest, int *neighborhood, float *fir, float *delays); + +int mysofa_resample(struct MYSOFA_HRTF *hrtf, float samplerate); +float mysofa_loudness(struct MYSOFA_HRTF *hrtf); +int mysofa_minphase(struct MYSOFA_HRTF *hrtf, float threshold); + +struct MYSOFA_EASY *mysofa_cache_lookup(const char *filename, float samplerate); +struct MYSOFA_EASY *mysofa_cache_store(struct MYSOFA_EASY *, + const char *filename, float samplerate); +void mysofa_cache_release(struct MYSOFA_EASY *); +void mysofa_cache_release_all(void); + +void mysofa_c2s(float *values); +void mysofa_s2c(float *values); + +struct MYSOFA_EASY { + struct MYSOFA_HRTF *hrtf; + struct MYSOFA_LOOKUP *lookup; + struct MYSOFA_NEIGHBORHOOD *neighborhood; + float *fir; +}; + +struct MYSOFA_EASY* mysofa_open(const char *filename, float samplerate, + int *filterlength, int *err); +struct MYSOFA_EASY* mysofa_open_no_norm(const char *filename, float samplerate, + int *filterlength, int *err); +struct MYSOFA_EASY* mysofa_open_advanced(const char *filename, float samplerate, + int *filterlength, int *err, bool norm, float neighbor_angle_step, + float neighbor_radius_step); +struct MYSOFA_EASY* mysofa_open_cached(const char *filename, float samplerate, + int *filterlength, int *err); +void mysofa_getfilter_short(struct MYSOFA_EASY* easy, float x, float y, float z, + short *IRleft, short *IRright, int *delayLeft, int *delayRight); +void mysofa_getfilter_float(struct MYSOFA_EASY* easy, float x, float y, float z, + float *IRleft, float *IRright, float *delayLeft, float *delayRight); +void mysofa_close(struct MYSOFA_EASY* easy); +void mysofa_close_cached(struct MYSOFA_EASY* easy); - void mysofa_getversion(int *major, int *minor, int *patch); +void mysofa_getversion(int *major, int *minor, int *patch); #ifdef __cplusplus } diff -Nru libmysofa-0.6~dfsg0/src/hrtf/neighbors.c libmysofa-0.7~dfsg0/src/hrtf/neighbors.c --- libmysofa-0.6~dfsg0/src/hrtf/neighbors.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/neighbors.c 2019-03-31 15:16:24.000000000 +0000 @@ -8,20 +8,28 @@ #include #include #include +#include #include "mysofa_export.h" #include "mysofa.h" #include "tools.h" -MYSOFA_EXPORT struct MYSOFA_NEIGHBORHOOD *mysofa_neighborhood_init(struct MYSOFA_HRTF *hrtf, - struct MYSOFA_LOOKUP *lookup) { +MYSOFA_EXPORT struct MYSOFA_NEIGHBORHOOD *mysofa_neighborhood_init( + struct MYSOFA_HRTF *hrtf, struct MYSOFA_LOOKUP *lookup) { + return mysofa_neighborhood_init_withstepdefine(hrtf, lookup, + MYSOFA_DEFAULT_NEIGH_STEP_ANGLE, MYSOFA_DEFAULT_NEIGH_STEP_RADIUS); +} + +MYSOFA_EXPORT struct MYSOFA_NEIGHBORHOOD *mysofa_neighborhood_init_withstepdefine( + struct MYSOFA_HRTF *hrtf, struct MYSOFA_LOOKUP *lookup, float angleStep, + float radiusStep) { int i, index; float *origin, *test; float radius, radius2; - float theta; - float phi; + float theta, theta2; + float phi, phi2; struct MYSOFA_NEIGHBORHOOD *neighbor = malloc( - sizeof(struct MYSOFA_NEIGHBORHOOD)); + sizeof(struct MYSOFA_NEIGHBORHOOD)); if (!neighbor) return NULL; @@ -34,110 +42,119 @@ for (i = 0; i < neighbor->elements * 6; i++) neighbor->index[i] = -1; - origin = malloc(sizeof(float)*hrtf->C); - test = malloc(sizeof(float)*hrtf->C); + origin = malloc(sizeof(float) * hrtf->C); + test = malloc(sizeof(float) * hrtf->C); - for (i = 0; i < hrtf->M; i ++) { - memcpy(origin, hrtf->SourcePosition.values + i * hrtf->C, sizeof(float) * hrtf->C); + for (i = 0; i < hrtf->M; i++) { + memcpy(origin, hrtf->SourcePosition.values + i * hrtf->C, + sizeof(float) * hrtf->C); convertCartesianToSpherical(origin, hrtf->C); - phi = 0.5; - do { - test[0] = origin[0] + phi; - test[1] = origin[1]; - test[2] = origin[2]; - convertSphericalToCartesian(test, 3); - index = mysofa_lookup(lookup, test); - if (index != i) { - neighbor->index[i * 6 + 0] = index; - break; - } - phi += 0.5; - } while (phi <= 45); - - phi = -0.5; - do { - test[0] = origin[0] + phi; - test[1] = origin[1]; - test[2] = origin[2]; - convertSphericalToCartesian(test,3); - index = mysofa_lookup(lookup, test); - if (index != i) { - neighbor->index[i * 6 + 1] = index; - break; - } - phi -= 0.5; - } while (phi >= -45); - - theta = 0.5; - do { - test[0] = origin[0]; - test[1] = origin[1] + theta; - test[2] = origin[2]; - convertSphericalToCartesian(test, 3); - index = mysofa_lookup(lookup, test); - if (index != i) { - neighbor->index[i * 6 + 2] = index; - break; - } - theta += 0.5; - } while (theta <= 45); - - theta = -0.5; - do { - test[0] = origin[0]; - test[1] = origin[1] + theta; - test[2] = origin[2]; - convertSphericalToCartesian(test, 3); - index = mysofa_lookup(lookup, test); - if (index != i) { - neighbor->index[i * 6 + 3] = index; - break; - } - theta -= 0.5; - } while (theta >= -45); - - radius = 0.1; - do { - test[0] = origin[0]; - test[1] = origin[1]; - radius2 = test[2] = origin[2] + radius; - convertSphericalToCartesian(test, 3); - index = mysofa_lookup(lookup, test); - if (index != i) { - neighbor->index[i * 6 + 4] = index; - break; - } - radius *= 1.5; - } while (radius2 <= lookup->radius_max); - - radius = 0.1; - do { - test[0] = origin[0]; - test[1] = origin[1]; - radius2 = test[2] = origin[2] - radius; - convertSphericalToCartesian(test, 3); - index = mysofa_lookup(lookup, test); - if (index != i) { - neighbor->index[i * 6 + 5] = index; - break; - } - radius *= 1.5; - } while (radius2 >= lookup->radius_min); + if ((lookup->phi_max - lookup->phi_min) > FLT_MIN) { + phi = angleStep; + do { + phi2 = test[0] = origin[0] + phi; + test[1] = origin[1]; + test[2] = origin[2]; + convertSphericalToCartesian(test, 3); + index = mysofa_lookup(lookup, test); + if (index != i) { + neighbor->index[i * 6 + 0] = index; + break; + } + phi += angleStep; + } while (phi2 <= lookup->phi_max + angleStep); + + phi = -angleStep; + do { + phi2 = test[0] = origin[0] + phi; + test[1] = origin[1]; + test[2] = origin[2]; + convertSphericalToCartesian(test, 3); + index = mysofa_lookup(lookup, test); + if (index != i) { + neighbor->index[i * 6 + 1] = index; + break; + } + phi -= angleStep; + } while (phi2 >= lookup->phi_min - angleStep); + } + + if ((lookup->theta_max - lookup->theta_min) > FLT_MIN) { + theta = angleStep; + do { + test[0] = origin[0]; + theta2 = test[1] = origin[1] + theta; + test[2] = origin[2]; + convertSphericalToCartesian(test, 3); + index = mysofa_lookup(lookup, test); + if (index != i) { + neighbor->index[i * 6 + 2] = index; + break; + } + theta += angleStep; + } while (theta2 <= lookup->theta_max + angleStep); + + theta = -angleStep; + do { + test[0] = origin[0]; + theta2 = test[1] = origin[1] + theta; + test[2] = origin[2]; + convertSphericalToCartesian(test, 3); + index = mysofa_lookup(lookup, test); + if (index != i) { + neighbor->index[i * 6 + 3] = index; + break; + } + theta -= angleStep; + } while (theta2 >= lookup->theta_min - angleStep); + } + + if ((lookup->radius_max - lookup->radius_min) > FLT_MIN) { + radius = radiusStep; + do { + test[0] = origin[0]; + test[1] = origin[1]; + radius2 = test[2] = origin[2] + radius; + convertSphericalToCartesian(test, 3); + index = mysofa_lookup(lookup, test); + if (index != i) { + neighbor->index[i * 6 + 4] = index; + break; + } + radius += radiusStep; + } while (radius2 <= lookup->radius_max + radiusStep); + + radius = -radiusStep; + do { + test[0] = origin[0]; + test[1] = origin[1]; + radius2 = test[2] = origin[2] + radius; + convertSphericalToCartesian(test, 3); + index = mysofa_lookup(lookup, test); + if (index != i) { + neighbor->index[i * 6 + 5] = index; + break; + } + radius -= radiusStep; + } while (radius2 >= lookup->radius_min - radiusStep); + } } free(test); free(origin); return neighbor; } -MYSOFA_EXPORT int* mysofa_neighborhood(struct MYSOFA_NEIGHBORHOOD *neighborhood, int index) { +MYSOFA_EXPORT int* mysofa_neighborhood(struct MYSOFA_NEIGHBORHOOD *neighborhood, + int index) { if (index < 0 || index >= neighborhood->elements) - return NULL ; + return NULL; return neighborhood->index + index * 6; } -MYSOFA_EXPORT void mysofa_neighborhood_free(struct MYSOFA_NEIGHBORHOOD *neighborhood) { - if(neighborhood) { +MYSOFA_EXPORT void mysofa_neighborhood_free( + struct MYSOFA_NEIGHBORHOOD *neighborhood) { + if (neighborhood) { free(neighborhood->index); free(neighborhood); } diff -Nru libmysofa-0.6~dfsg0/src/hrtf/reader.c libmysofa-0.7~dfsg0/src/hrtf/reader.c --- libmysofa-0.6~dfsg0/src/hrtf/reader.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/reader.c 2019-03-31 15:16:24.000000000 +0000 @@ -1,8 +1,8 @@ /* - Copyright 2016 Christian Hoene, Symonics GmbH + Copyright 2016 Christian Hoene, Symonics GmbH -*/ + */ #include #include @@ -25,17 +25,17 @@ /* little endian */ uint64_t readValue(struct READER *reader, int size) { - int i,c; + int i, c; uint64_t value; c = fgetc(reader->fhd); - if(c<0) + if (c < 0) return 0xffffffffffffffffLL; - value = (uint8_t)c; + value = (uint8_t) c; for (i = 1; i < size; i++) { c = fgetc(reader->fhd); - if(c<0) + if (c < 0) return 0xffffffffffffffffLL; - value |= ((uint64_t)c) << (i * 8); + value |= ((uint64_t) c) << (i * 8); } return value; } @@ -51,10 +51,10 @@ } static int checkAttribute(struct MYSOFA_ATTRIBUTE *attribute, char *name, - char *value) { + char *value) { while (attribute) { if (!mystrcmp(attribute->name, name) - && !mystrcmp(attribute->value, value)) + && !mystrcmp(attribute->value, value)) return MYSOFA_OK; attribute = attribute->next; } @@ -67,16 +67,16 @@ struct MYSOFA_ATTRIBUTE *attr = dataobject->attributes; if (!!(err = checkAttribute(dataobject->attributes, "CLASS", - "DIMENSION_SCALE"))) + "DIMENSION_SCALE"))) return err; while (attr) { log(" %s=%s\n",attr->name,attr->value); if (!strcmp(attr->name, "NAME") - && !strncmp(attr->value, - "This is a netCDF dimension but not a netCDF variable.", - 53)) { + && !strncmp(attr->value, + "This is a netCDF dimension but not a netCDF variable.", + 53)) { char *p = attr->value + strlen(attr->value) - 1; while (isdigit(*p)) { p--; @@ -112,9 +112,9 @@ p1 = dataobject->data; p2 = dataobject->data; - for(i=0;ielements;i++) - *p1++=*p2++; - array->values=realloc(dataobject->data,array->elements*sizeof(float)); + for (i = 0; i < array->elements; i++) + *p1++ = *p2++; + array->values = realloc(dataobject->data, array->elements * sizeof(float)); dataobject->data = NULL; @@ -143,7 +143,7 @@ /* read dimensions */ while (dir) { if (dir->dataobject.name && dir->dataobject.name[0] - && dir->dataobject.name[1] == 0) { + && dir->dataobject.name[1] == 0) { switch (dir->dataobject.name[0]) { case 'I': *err = getDimension(&hrtf->I, &dir->dataobject); @@ -170,7 +170,7 @@ dimensionflags |= 0x20; break; case 'S': - break; /* be graceful, some issues with API version 0.4.4 */ + break; /* be graceful, some issues with API version 0.4.4 */ default: log("UNKNOWN SOFA VARIABLE %s", dir->dataobject.name); goto error; @@ -216,7 +216,7 @@ return hrtf; - error: free(hrtf); + error: free(hrtf); if (!*err) *err = MYSOFA_INVALID_FORMAT; return NULL; @@ -226,10 +226,10 @@ struct READER reader; struct MYSOFA_HRTF *hrtf = NULL; - if(filename == NULL) + if (filename == NULL) filename = CMAKE_INSTALL_PREFIX "/share/libmysofa/default.sofa"; - if(strcmp(filename,"-")) + if (strcmp(filename, "-")) reader.fhd = fopen(filename, "rb"); else reader.fhd = stdin; @@ -250,7 +250,7 @@ superblockFree(&reader, &reader.superblock); gcolFree(reader.gcol); - if(strcmp(filename,"-")) + if (strcmp(filename, "-")) fclose(reader.fhd); return hrtf; @@ -291,8 +291,7 @@ free(hrtf); } -MYSOFA_EXPORT void mysofa_getversion(int *major, int *minor, int *patch) -{ +MYSOFA_EXPORT void mysofa_getversion(int *major, int *minor, int *patch) { *major = CPACK_PACKAGE_VERSION_MAJOR; *minor = CPACK_PACKAGE_VERSION_MINOR; *patch = CPACK_PACKAGE_VERSION_PATCH; diff -Nru libmysofa-0.6~dfsg0/src/hrtf/resample.c libmysofa-0.7~dfsg0/src/hrtf/resample.c --- libmysofa-0.6~dfsg0/src/hrtf/resample.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/resample.c 2019-03-31 15:16:24.000000000 +0000 @@ -22,8 +22,8 @@ float *values; SpeexResamplerState *resampler; float *out; - float zero[10] = { 0,0,0,0,0,0,0,0,0,0 }; - + float zero[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + if (hrtf->DataSamplingRate.elements != 1 || samplerate < 8000.) return MYSOFA_INVALID_FORMAT; @@ -40,27 +40,31 @@ if (values == NULL) return MYSOFA_NO_MEMORY; - resampler = speex_resampler_init(1, hrtf->DataSamplingRate.values[0], samplerate, 10, &err); - if(resampler == NULL) { + resampler = speex_resampler_init(1, hrtf->DataSamplingRate.values[0], + samplerate, 10, &err); + if (resampler == NULL) { free(values); return err; } - out = malloc(sizeof(float)*(newN+ speex_resampler_get_output_latency(resampler))); + out = malloc( + sizeof(float) + * (newN + speex_resampler_get_output_latency(resampler))); for (i = 0; i < hrtf->R * hrtf->M; i++) { unsigned inlen = hrtf->N; unsigned outlen = newN; speex_resampler_reset_mem(resampler); speex_resampler_skip_zeros(resampler); - speex_resampler_process_float(resampler, 0, hrtf->DataIR.values + i * hrtf->N, &inlen, - values + i * newN, &outlen); + speex_resampler_process_float(resampler, 0, + hrtf->DataIR.values + i * hrtf->N, &inlen, values + i * newN, + &outlen); assert(inlen == hrtf->N); while (outlen < newN) { unsigned difflen = newN - outlen; inlen = 10; speex_resampler_process_float(resampler, 0, zero, &inlen, - values + i * newN + outlen, &difflen); - outlen+=difflen; + values + i * newN + outlen, &difflen); + outlen += difflen; } } free(out); diff -Nru libmysofa-0.6~dfsg0/src/hrtf/tools.c libmysofa-0.7~dfsg0/src/hrtf/tools.c --- libmysofa-0.6~dfsg0/src/hrtf/tools.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/tools.c 2019-03-31 15:16:24.000000000 +0000 @@ -13,11 +13,10 @@ #include "mysofa_export.h" #include "mysofa.h" -char *mysofa_strdup(const char *str) -{ +char *mysofa_strdup(const char *str) { size_t size = strlen(str) + 1; char *copy = malloc(size); - if(copy) + if (copy) memcpy(copy, str, size); return copy; } @@ -32,10 +31,10 @@ } int changeAttribute(struct MYSOFA_ATTRIBUTE *attr, char *name, char *value, - char *newvalue) { + char *newvalue) { while (attr) { if (!strcmp(name, attr->name) - && (value == NULL || !strcmp(value, attr->value))) { + && (value == NULL || !strcmp(value, attr->value))) { free(attr->value); attr->value = mysofa_strdup(newvalue); return 1; @@ -45,6 +44,7 @@ return 0; } +MYSOFA_EXPORT char* mysofa_getAttribute(struct MYSOFA_ATTRIBUTE *attr, char *name) { while (attr) { if (!strcmp(name, attr->name)) { @@ -55,9 +55,8 @@ return NULL; } -MYSOFA_EXPORT void mysofa_c2s(float values[3]) -{ - float x,y,z,r,theta,phi; +MYSOFA_EXPORT void mysofa_c2s(float values[3]) { + float x, y, z, r, theta, phi; x = values[0]; y = values[1]; z = values[2]; @@ -71,8 +70,7 @@ values[2] = r; } -MYSOFA_EXPORT void mysofa_s2c(float values[3]) -{ +MYSOFA_EXPORT void mysofa_s2c(float values[3]) { float x, r, theta, phi; phi = values[0] * (M_PI / 180); theta = values[1] * (M_PI / 180); @@ -87,7 +85,7 @@ int i; for (i = 0; i < elements - 2; i += 3) { - mysofa_c2s(values+i); + mysofa_c2s(values + i); } } @@ -96,14 +94,14 @@ int i; for (i = 0; i < elements - 2; i += 3) { - mysofa_s2c(values+i); + mysofa_s2c(values + i); } } float radius(float *cartesian) { return sqrtf( - powf(cartesian[0], 2.f) + powf(cartesian[1], 2.f) - + powf(cartesian[2], 2.f)); + powf(cartesian[0], 2.f) + powf(cartesian[1], 2.f) + + powf(cartesian[2], 2.f)); } /* @@ -111,7 +109,7 @@ */ void nsearch(const void *key, const char *base, size_t num, size_t size, - int (*cmp)(const void *key, const void *elt), int *lower, int *higher) { + int (*cmp)(const void *key, const void *elt), int *lower, int *higher) { size_t start = 0, end = num; int result; @@ -186,4 +184,3 @@ return res; } - diff -Nru libmysofa-0.6~dfsg0/src/hrtf/tools.h libmysofa-0.7~dfsg0/src/hrtf/tools.h --- libmysofa-0.6~dfsg0/src/hrtf/tools.h 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/hrtf/tools.h 2019-03-31 15:16:24.000000000 +0000 @@ -13,7 +13,7 @@ #include "mysofa.h" int changeAttribute(struct MYSOFA_ATTRIBUTE *attr, char *name, char *value, - char *newvalue); + char *newvalue); int verifyAttribute(struct MYSOFA_ATTRIBUTE *attr, char *name, char *value); char* getAttribute(struct MYSOFA_ATTRIBUTE *attr, char *name); @@ -26,7 +26,7 @@ #define distance(cartesian1, cartesian2) (sqrtf(powf((cartesian1)[0] - (cartesian2)[0], 2.f) + powf((cartesian1)[1] - (cartesian2)[1], 2.f) + powf((cartesian1)[2] - (cartesian2)[2], 2.f))) -void copyToFloat(float *out, float *in, int size); +void copyToFloat(float *out, float *in, int size); void copyFromFloat(float *out, float *in, int size); void copyArrayWeighted(float *dst, float *src, int size, float w); @@ -35,6 +35,6 @@ float loudness(float *in, int size); void nsearch(const void *key, const char *base, size_t num, size_t size, - int (*cmp)(const void *key, const void *elt), int *lower, int *higher); + int (*cmp)(const void *key, const void *elt), int *lower, int *higher); #endif /* SRC_TOOLS_H_ */ diff -Nru libmysofa-0.6~dfsg0/src/resampler/arch.h libmysofa-0.7~dfsg0/src/resampler/arch.h --- libmysofa-0.6~dfsg0/src/resampler/arch.h 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/resampler/arch.h 2019-03-31 15:16:24.000000000 +0000 @@ -1,36 +1,36 @@ /* Copyright (C) 2003 Jean-Marc Valin */ /** - @file arch.h - @brief Various architecture definitions Speex -*/ + @file arch.h + @brief Various architecture definitions Speex + */ /* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef ARCH_H #define ARCH_H @@ -58,7 +58,6 @@ #define GAIN_SCALING 1.f #define GAIN_SCALING_1 1.f - #define VERY_SMALL 1e-15f #define VERY_LARGE32 1e15f #define VERY_LARGE16 1e15f @@ -137,11 +136,8 @@ #endif - - #ifdef FIXED_DEBUG extern long long spx_mips; #endif - #endif diff -Nru libmysofa-0.6~dfsg0/src/resampler/speex_resampler.c libmysofa-0.7~dfsg0/src/resampler/speex_resampler.c --- libmysofa-0.6~dfsg0/src/resampler/speex_resampler.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/resampler/speex_resampler.c 2019-03-31 15:16:24.000000000 +0000 @@ -1,67 +1,72 @@ /* Copyright (C) 2007-2008 Jean-Marc Valin - Copyright (C) 2008 Thorvald Natvig + Copyright (C) 2008 Thorvald Natvig - File: resample.c - Arbitrary resampling code + File: resample.c + Arbitrary resampling code - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ /* - The design goals of this code are: - - Very fast algorithm - - SIMD-friendly algorithm - - Low memory requirement - - Good *perceptual* quality (and not best SNR) - - Warning: This resampler is relatively new. Although I think I got rid of - all the major bugs and I don't expect the API to change anymore, there - may be something I've missed. So use with caution. - - This algorithm is based on this original resampling algorithm: - Smith, Julius O. Digital Audio Resampling Home Page - Center for Computer Research in Music and Acoustics (CCRMA), - Stanford University, 2007. - Web published at http://ccrma.stanford.edu/~jos/resample/. - - There is one main difference, though. This resampler uses cubic - interpolation instead of linear interpolation in the above paper. This - makes the table much smaller and makes it possible to compute that table - on a per-stream basis. In turn, being able to tweak the table for each - stream makes it possible to both reduce complexity on simple ratios - (e.g. 2/3), and get rid of the rounding operations in the inner loop. - The latter both reduces CPU time and makes the algorithm more SIMD-friendly. -*/ - + The design goals of this code are: + - Very fast algorithm + - SIMD-friendly algorithm + - Low memory requirement + - Good *perceptual* quality (and not best SNR) + + Warning: This resampler is relatively new. Although I think I got rid of + all the major bugs and I don't expect the API to change anymore, there + may be something I've missed. So use with caution. + + This algorithm is based on this original resampling algorithm: + Smith, Julius O. Digital Audio Resampling Home Page + Center for Computer Research in Music and Acoustics (CCRMA), + Stanford University, 2007. + Web published at http://ccrma.stanford.edu/~jos/resample/. + + There is one main difference, though. This resampler uses cubic + interpolation instead of linear interpolation in the above paper. This + makes the table much smaller and makes it possible to compute that table + on a per-stream basis. In turn, being able to tweak the table for each + stream makes it possible to both reduce complexity on simple ratios + (e.g. 2/3), and get rid of the rounding operations in the inner loop. + The latter both reduces CPU time and makes the algorithm more SIMD-friendly. + */ #include -static void *speex_alloc (int size) {return calloc(size,1);} -static void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);} -static void speex_free (void *ptr) {free(ptr);} +static void *speex_alloc(int size) { + return calloc(size, 1); +} +static void *speex_realloc(void *ptr, int size) { + return realloc(ptr, size); +} +static void speex_free(void *ptr) { + free(ptr); +} #include "speex_resampler.h" #include "arch.h" @@ -93,873 +98,889 @@ #define FIXED_STACK_ALLOC 1024 #endif -typedef int (*resampler_basic_func)(SpeexResamplerState *, spx_uint32_t , const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *); +typedef int (*resampler_basic_func)(SpeexResamplerState *, spx_uint32_t, + const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *); struct SpeexResamplerState_ { - spx_uint32_t in_rate; - spx_uint32_t out_rate; - spx_uint32_t num_rate; - spx_uint32_t den_rate; - - int quality; - spx_uint32_t nb_channels; - spx_uint32_t filt_len; - spx_uint32_t mem_alloc_size; - spx_uint32_t buffer_size; - int int_advance; - int frac_advance; - float cutoff; - spx_uint32_t oversample; - int initialised; - int started; - - /* These are per-channel */ - spx_int32_t *last_sample; - spx_uint32_t *samp_frac_num; - spx_uint32_t *magic_samples; - - spx_word16_t *mem; - spx_word16_t *sinc_table; - spx_uint32_t sinc_table_length; - resampler_basic_func resampler_ptr; - - int in_stride; - int out_stride; -} ; - -static const double kaiser12_table[68] = { - 0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076, - 0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014, - 0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601, - 0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014, - 0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490, - 0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546, - 0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178, - 0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947, - 0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058, - 0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438, - 0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734, - 0.00001000, 0.00000000}; + spx_uint32_t in_rate; + spx_uint32_t out_rate; + spx_uint32_t num_rate; + spx_uint32_t den_rate; + + int quality; + spx_uint32_t nb_channels; + spx_uint32_t filt_len; + spx_uint32_t mem_alloc_size; + spx_uint32_t buffer_size; + int int_advance; + int frac_advance; + float cutoff; + spx_uint32_t oversample; + int initialised; + int started; + + /* These are per-channel */ + spx_int32_t *last_sample; + spx_uint32_t *samp_frac_num; + spx_uint32_t *magic_samples; + + spx_word16_t *mem; + spx_word16_t *sinc_table; + spx_uint32_t sinc_table_length; + resampler_basic_func resampler_ptr; + + int in_stride; + int out_stride; +}; + +static const double kaiser12_table[68] = { 0.99859849, 1.00000000, 0.99859849, + 0.99440475, 0.98745105, 0.97779076, 0.96549770, 0.95066529, 0.93340547, + 0.91384741, 0.89213598, 0.86843014, 0.84290116, 0.81573067, 0.78710866, + 0.75723148, 0.72629970, 0.69451601, 0.66208321, 0.62920216, 0.59606986, + 0.56287762, 0.52980938, 0.49704014, 0.46473455, 0.43304576, 0.40211431, + 0.37206735, 0.34301800, 0.31506490, 0.28829195, 0.26276832, 0.23854851, + 0.21567274, 0.19416736, 0.17404546, 0.15530766, 0.13794294, 0.12192957, + 0.10723616, 0.09382272, 0.08164178, 0.07063950, 0.06075685, 0.05193064, + 0.04409466, 0.03718069, 0.03111947, 0.02584161, 0.02127838, 0.01736250, + 0.01402878, 0.01121463, 0.00886058, 0.00691064, 0.00531256, 0.00401805, + 0.00298291, 0.00216702, 0.00153438, 0.00105297, 0.00069463, 0.00043489, + 0.00025272, 0.00013031, 0.0000527734, 0.00001000, 0.00000000 }; struct FuncDef { - const double *table; - int oversample; + const double *table; + int oversample; }; -static const struct FuncDef _KAISER12 = {kaiser12_table, 64}; +static const struct FuncDef _KAISER12 = { kaiser12_table, 64 }; #define KAISER12 (&_KAISER12) struct QualityMapping { - int base_length; - int oversample; - float downsample_bandwidth; - float upsample_bandwidth; - const struct FuncDef *window_func; + int base_length; + int oversample; + float downsample_bandwidth; + float upsample_bandwidth; + const struct FuncDef *window_func; }; - /* This table maps conversion quality to internal parameters. There are two - reasons that explain why the up-sampling bandwidth is larger than the - down-sampling bandwidth: - 1) When up-sampling, we can assume that the spectrum is already attenuated - close to the Nyquist rate (from an A/D or a previous resampling filter) - 2) Any aliasing that occurs very close to the Nyquist rate will be masked - by the sinusoids/noise just below the Nyquist rate (guaranteed only for - up-sampling). -*/ -static const struct QualityMapping quality_map[1] = { - {256, 32, 0.975f, 0.975f, KAISER12}, /* Q10 */ /* 96.6% cutoff (~100 dB stop) 10 */ + reasons that explain why the up-sampling bandwidth is larger than the + down-sampling bandwidth: + 1) When up-sampling, we can assume that the spectrum is already attenuated + close to the Nyquist rate (from an A/D or a previous resampling filter) + 2) Any aliasing that occurs very close to the Nyquist rate will be masked + by the sinusoids/noise just below the Nyquist rate (guaranteed only for + up-sampling). + */ +static const struct QualityMapping quality_map[1] = { { 256, 32, 0.975f, 0.975f, + KAISER12 }, /* Q10 *//* 96.6% cutoff (~100 dB stop) 10 */ }; /*8,24,40,56,80,104,128,160,200,256,320*/ -static double compute_func(float x, const struct FuncDef *func) -{ - float y, frac; - double interp[4]; - int ind; - y = x*func->oversample; - ind = (int)floor(y); - frac = (y-ind); - /* CSE with handle the repeated powers */ - interp[3] = -0.1666666667*frac + 0.1666666667*(frac*frac*frac); - interp[2] = frac + 0.5*(frac*frac) - 0.5*(frac*frac*frac); - /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ - interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac); - /* Just to make sure we don't have rounding problems */ - interp[1] = 1.f-interp[3]-interp[2]-interp[0]; - - /*sum = frac*accum[1] + (1-frac)*accum[2];*/ - return interp[0]*func->table[ind] + interp[1]*func->table[ind+1] + interp[2]*func->table[ind+2] + interp[3]*func->table[ind+3]; +static double compute_func(float x, const struct FuncDef *func) { + float y, frac; + double interp[4]; + int ind; + y = x * func->oversample; + ind = (int) floor(y); + frac = (y - ind); + /* CSE with handle the repeated powers */ + interp[3] = -0.1666666667 * frac + 0.1666666667 * (frac * frac * frac); + interp[2] = frac + 0.5 * (frac * frac) - 0.5 * (frac * frac * frac); + /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ + interp[0] = -0.3333333333 * frac + 0.5 * (frac * frac) + - 0.1666666667 * (frac * frac * frac); + /* Just to make sure we don't have rounding problems */ + interp[1] = 1.f - interp[3] - interp[2] - interp[0]; + + /*sum = frac*accum[1] + (1-frac)*accum[2];*/ + return interp[0] * func->table[ind] + interp[1] * func->table[ind + 1] + + interp[2] * func->table[ind + 2] + + interp[3] * func->table[ind + 3]; } /* The slow way of computing a sinc for the table. Should improve that some day */ -static spx_word16_t sinc(float cutoff, float x, int N, const struct FuncDef *window_func) -{ - /*fprintf (stderr, "%f ", x);*/ - float xx = x * cutoff; - if (fabs(x)<1e-6) - return cutoff; - else if (fabs(x) > .5*N) - return 0; - /*FIXME: Can it really be any slower than this? */ - return cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func); -} - -static void cubic_coef(spx_word16_t frac, spx_word16_t interp[4]) -{ - /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation - but I know it's MMSE-optimal on a sinc */ - interp[0] = -0.16667f*frac + 0.16667f*frac*frac*frac; - interp[1] = frac + 0.5f*frac*frac - 0.5f*frac*frac*frac; - /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ - interp[3] = -0.33333f*frac + 0.5f*frac*frac - 0.16667f*frac*frac*frac; - /* Just to make sure we don't have rounding problems */ - interp[2] = 1.-interp[0]-interp[1]-interp[3]; -} - -static int resampler_basic_direct_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) -{ - const int N = st->filt_len; - int out_sample = 0; - int last_sample = st->last_sample[channel_index]; - spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; - const spx_word16_t *sinc_table = st->sinc_table; - const int out_stride = st->out_stride; - const int int_advance = st->int_advance; - const int frac_advance = st->frac_advance; - const spx_uint32_t den_rate = st->den_rate; - spx_word32_t sum; - - while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) - { - const spx_word16_t *sinct = & sinc_table[samp_frac_num*N]; - const spx_word16_t *iptr = & in[last_sample]; +static spx_word16_t sinc(float cutoff, float x, int N, + const struct FuncDef *window_func) { + /*fprintf (stderr, "%f ", x);*/ + float xx = x * cutoff; + if (fabs(x) < 1e-6) + return cutoff; + else if (fabs(x) > .5 * N) + return 0; + /*FIXME: Can it really be any slower than this? */ + return cutoff * sin(M_PI * xx) / (M_PI * xx) + * compute_func(fabs(2. * x / N), window_func); +} + +static void cubic_coef(spx_word16_t frac, spx_word16_t interp[4]) { + /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation + but I know it's MMSE-optimal on a sinc */ + interp[0] = -0.16667f * frac + 0.16667f * frac * frac * frac; + interp[1] = frac + 0.5f * frac * frac - 0.5f * frac * frac * frac; + /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ + interp[3] = -0.33333f * frac + 0.5f * frac * frac + - 0.16667f * frac * frac * frac; + /* Just to make sure we don't have rounding problems */ + interp[2] = 1. - interp[0] - interp[1] - interp[3]; +} + +static int resampler_basic_direct_single(SpeexResamplerState *st, + spx_uint32_t channel_index, const spx_word16_t *in, + spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) { + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const spx_word16_t *sinc_table = st->sinc_table; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + spx_word32_t sum; + + while (!(last_sample >= (spx_int32_t) *in_len + || out_sample >= (spx_int32_t) *out_len)) { + const spx_word16_t *sinct = &sinc_table[samp_frac_num * N]; + const spx_word16_t *iptr = &in[last_sample]; #ifndef OVERRIDE_INNER_PRODUCT_SINGLE - int j; - sum = 0; - for(j=0;j= den_rate) - { - samp_frac_num -= den_rate; - last_sample++; - } - } - - st->last_sample[channel_index] = last_sample; - st->samp_frac_num[channel_index] = samp_frac_num; - return out_sample; + out[out_stride * out_sample++] = sum; + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; } /* This is the same as the previous function, except with a double-precision accumulator */ -static int resampler_basic_direct_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) -{ - const int N = st->filt_len; - int out_sample = 0; - int last_sample = st->last_sample[channel_index]; - spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; - const spx_word16_t *sinc_table = st->sinc_table; - const int out_stride = st->out_stride; - const int int_advance = st->int_advance; - const int frac_advance = st->frac_advance; - const spx_uint32_t den_rate = st->den_rate; - double sum; - - while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) - { - const spx_word16_t *sinct = & sinc_table[samp_frac_num*N]; - const spx_word16_t *iptr = & in[last_sample]; +static int resampler_basic_direct_double(SpeexResamplerState *st, + spx_uint32_t channel_index, const spx_word16_t *in, + spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) { + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const spx_word16_t *sinc_table = st->sinc_table; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + double sum; + + while (!(last_sample >= (spx_int32_t) *in_len + || out_sample >= (spx_int32_t) *out_len)) { + const spx_word16_t *sinct = &sinc_table[samp_frac_num * N]; + const spx_word16_t *iptr = &in[last_sample]; #ifndef OVERRIDE_INNER_PRODUCT_DOUBLE - int j; - double accum[4] = {0,0,0,0}; + int j; + double accum[4] = { 0, 0, 0, 0 }; - for(j=0;j= den_rate) - { - samp_frac_num -= den_rate; - last_sample++; - } - } - - st->last_sample[channel_index] = last_sample; - st->samp_frac_num[channel_index] = samp_frac_num; - return out_sample; -} - -static int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) -{ - const int N = st->filt_len; - int out_sample = 0; - int last_sample = st->last_sample[channel_index]; - spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; - const int out_stride = st->out_stride; - const int int_advance = st->int_advance; - const int frac_advance = st->frac_advance; - const spx_uint32_t den_rate = st->den_rate; - spx_word32_t sum; - - while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) - { - const spx_word16_t *iptr = & in[last_sample]; - - const int offset = samp_frac_num*st->oversample/st->den_rate; - const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate; - spx_word16_t interp[4]; - + out[out_stride * out_sample++] = PSHR32(sum, 15); + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} + +static int resampler_basic_interpolate_single(SpeexResamplerState *st, + spx_uint32_t channel_index, const spx_word16_t *in, + spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) { + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + spx_word32_t sum; + + while (!(last_sample >= (spx_int32_t) *in_len + || out_sample >= (spx_int32_t) *out_len)) { + const spx_word16_t *iptr = &in[last_sample]; + + const int offset = samp_frac_num * st->oversample / st->den_rate; + const spx_word16_t frac = ((float) ((samp_frac_num * st->oversample) + % st->den_rate)) / st->den_rate; + spx_word16_t interp[4]; #ifndef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE - int j; - spx_word32_t accum[4] = {0,0,0,0}; + int j; + spx_word32_t accum[4] = { 0, 0, 0, 0 }; - for(j=0;jsinc_table[4+(j+1)*st->oversample-offset-2]); - accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); - accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); - accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); - } - - cubic_coef(frac, interp); - sum = MULT16_32_Q15(interp[0],SHR32(accum[0], 1)) + MULT16_32_Q15(interp[1],SHR32(accum[1], 1)) + MULT16_32_Q15(interp[2],SHR32(accum[2], 1)) + MULT16_32_Q15(interp[3],SHR32(accum[3], 1)); - sum = SATURATE32PSHR(sum, 15, 32767); + for (j = 0; j < N; j++) { + const spx_word16_t curr_in = iptr[j]; + accum[0] += MULT16_16(curr_in, + st->sinc_table[4 + (j + 1) * st->oversample - offset - 2]); + accum[1] += MULT16_16(curr_in, + st->sinc_table[4 + (j + 1) * st->oversample - offset - 1]); + accum[2] += MULT16_16(curr_in, + st->sinc_table[4 + (j + 1) * st->oversample - offset]); + accum[3] += MULT16_16(curr_in, + st->sinc_table[4 + (j + 1) * st->oversample - offset + 1]); + } + + cubic_coef(frac, interp); + sum = + MULT16_32_Q15(interp[0], + SHR32(accum[0], 1)) + MULT16_32_Q15(interp[1],SHR32(accum[1], 1)) + MULT16_32_Q15(interp[2],SHR32(accum[2], 1)) + MULT16_32_Q15(interp[3],SHR32(accum[3], 1)); + sum = SATURATE32PSHR(sum, 15, 32767); #else - cubic_coef(frac, interp); - sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); + cubic_coef(frac, interp); + sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); #endif - out[out_stride * out_sample++] = sum; - last_sample += int_advance; - samp_frac_num += frac_advance; - if (samp_frac_num >= den_rate) - { - samp_frac_num -= den_rate; - last_sample++; - } - } - - st->last_sample[channel_index] = last_sample; - st->samp_frac_num[channel_index] = samp_frac_num; - return out_sample; + out[out_stride * out_sample++] = sum; + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; } /* This is the same as the previous function, except with a double-precision accumulator */ -static int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) -{ - const int N = st->filt_len; - int out_sample = 0; - int last_sample = st->last_sample[channel_index]; - spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; - const int out_stride = st->out_stride; - const int int_advance = st->int_advance; - const int frac_advance = st->frac_advance; - const spx_uint32_t den_rate = st->den_rate; - spx_word32_t sum; - - while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) - { - const spx_word16_t *iptr = & in[last_sample]; - - const int offset = samp_frac_num*st->oversample/st->den_rate; - const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate; - spx_word16_t interp[4]; - +static int resampler_basic_interpolate_double(SpeexResamplerState *st, + spx_uint32_t channel_index, const spx_word16_t *in, + spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) { + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + spx_word32_t sum; + + while (!(last_sample >= (spx_int32_t) *in_len + || out_sample >= (spx_int32_t) *out_len)) { + const spx_word16_t *iptr = &in[last_sample]; + + const int offset = samp_frac_num * st->oversample / st->den_rate; + const spx_word16_t frac = ((float) ((samp_frac_num * st->oversample) + % st->den_rate)) / st->den_rate; + spx_word16_t interp[4]; #ifndef OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE - int j; - double accum[4] = {0,0,0,0}; - - for(j=0;jsinc_table[4+(j+1)*st->oversample-offset-2]); - accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); - accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); - accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); - } + int j; + double accum[4] = { 0, 0, 0, 0 }; - cubic_coef(frac, interp); - sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]); + for (j = 0; j < N; j++) { + const double curr_in = iptr[j]; + accum[0] += MULT16_16(curr_in, + st->sinc_table[4 + (j + 1) * st->oversample - offset - 2]); + accum[1] += MULT16_16(curr_in, + st->sinc_table[4 + (j + 1) * st->oversample - offset - 1]); + accum[2] += MULT16_16(curr_in, + st->sinc_table[4 + (j + 1) * st->oversample - offset]); + accum[3] += MULT16_16(curr_in, + st->sinc_table[4 + (j + 1) * st->oversample - offset + 1]); + } + + cubic_coef(frac, interp); + sum = + MULT16_32_Q15(interp[0], + accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]); #else - cubic_coef(frac, interp); - sum = interpolate_product_double(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); + cubic_coef(frac, interp); + sum = interpolate_product_double(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); #endif - out[out_stride * out_sample++] = PSHR32(sum,15); - last_sample += int_advance; - samp_frac_num += frac_advance; - if (samp_frac_num >= den_rate) - { - samp_frac_num -= den_rate; - last_sample++; - } - } - - st->last_sample[channel_index] = last_sample; - st->samp_frac_num[channel_index] = samp_frac_num; - return out_sample; + out[out_stride * out_sample++] = PSHR32(sum, 15); + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; } /* This resampler is used to produce zero output in situations where memory - for the filter could not be allocated. The expected numbers of input and - output samples are still processed so that callers failing to check error - codes are not surprised, possibly getting into infinite loops. */ -static int resampler_basic_zero(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) -{ - int out_sample = 0; - int last_sample = st->last_sample[channel_index]; - spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; - const int out_stride = st->out_stride; - const int int_advance = st->int_advance; - const int frac_advance = st->frac_advance; - const spx_uint32_t den_rate = st->den_rate; - - while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) - { - out[out_stride * out_sample++] = 0; - last_sample += int_advance; - samp_frac_num += frac_advance; - if (samp_frac_num >= den_rate) - { - samp_frac_num -= den_rate; - last_sample++; - } - } - - st->last_sample[channel_index] = last_sample; - st->samp_frac_num[channel_index] = samp_frac_num; - return out_sample; -} - -static int _muldiv(spx_uint32_t *result, spx_uint32_t value, spx_uint32_t mul, spx_uint32_t div) -{ - spx_uint32_t major = value / div; - spx_uint32_t remainder = value % div; - speex_assert(result); - /* TODO: Could use 64 bits operation to check for overflow. But only guaranteed in C99+ */ - if (remainder > UINT32_MAX / mul || major > UINT32_MAX / mul - || major * mul > UINT32_MAX - remainder * mul / div) - return RESAMPLER_ERR_OVERFLOW; - *result = remainder * mul / div + major * mul; - return RESAMPLER_ERR_SUCCESS; -} - -static int update_filter(SpeexResamplerState *st) -{ - spx_uint32_t old_length = st->filt_len; - spx_uint32_t old_alloc_size = st->mem_alloc_size; - int use_direct; - spx_uint32_t min_sinc_table_length; - spx_uint32_t min_alloc_size; - - st->int_advance = st->num_rate/st->den_rate; - st->frac_advance = st->num_rate%st->den_rate; - st->oversample = quality_map[0].oversample; - st->filt_len = quality_map[0].base_length; - - if (st->num_rate > st->den_rate) - { - /* down-sampling */ - st->cutoff = quality_map[0].downsample_bandwidth * st->den_rate / st->num_rate; - if (_muldiv(&st->filt_len,st->filt_len,st->num_rate,st->den_rate) != RESAMPLER_ERR_SUCCESS) - goto fail; - /* Round up to make sure we have a multiple of 8 for SSE */ - st->filt_len = ((st->filt_len-1)&(~0x7))+8; - if (2*st->den_rate < st->num_rate) - st->oversample >>= 1; - if (4*st->den_rate < st->num_rate) - st->oversample >>= 1; - if (8*st->den_rate < st->num_rate) - st->oversample >>= 1; - if (16*st->den_rate < st->num_rate) - st->oversample >>= 1; - if (st->oversample < 1) - st->oversample = 1; - } else { - /* up-sampling */ - st->cutoff = quality_map[0].upsample_bandwidth; - } + for the filter could not be allocated. The expected numbers of input and + output samples are still processed so that callers failing to check error + codes are not surprised, possibly getting into infinite loops. */ +static int resampler_basic_zero(SpeexResamplerState *st, + spx_uint32_t channel_index, const spx_word16_t *in, + spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) { + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + + while (!(last_sample >= (spx_int32_t) *in_len + || out_sample >= (spx_int32_t) *out_len)) { + out[out_stride * out_sample++] = 0; + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} + +static int _muldiv(spx_uint32_t *result, spx_uint32_t value, spx_uint32_t mul, + spx_uint32_t div) { + spx_uint32_t major = value / div; + spx_uint32_t remainder = value % div; + speex_assert(result); + /* TODO: Could use 64 bits operation to check for overflow. But only guaranteed in C99+ */ + if (remainder > UINT32_MAX / mul || major > UINT32_MAX / mul + || major * mul > UINT32_MAX - remainder * mul / div) + return RESAMPLER_ERR_OVERFLOW; + *result = remainder * mul / div + major * mul; + return RESAMPLER_ERR_SUCCESS; +} + +static int update_filter(SpeexResamplerState *st) { + spx_uint32_t old_length = st->filt_len; + spx_uint32_t old_alloc_size = st->mem_alloc_size; + int use_direct; + spx_uint32_t min_sinc_table_length; + spx_uint32_t min_alloc_size; + + st->int_advance = st->num_rate / st->den_rate; + st->frac_advance = st->num_rate % st->den_rate; + st->oversample = quality_map[0].oversample; + st->filt_len = quality_map[0].base_length; + + if (st->num_rate > st->den_rate) { + /* down-sampling */ + st->cutoff = quality_map[0].downsample_bandwidth * st->den_rate + / st->num_rate; + if (_muldiv(&st->filt_len, st->filt_len, st->num_rate, st->den_rate) + != RESAMPLER_ERR_SUCCESS) + goto fail; + /* Round up to make sure we have a multiple of 8 for SSE */ + st->filt_len = ((st->filt_len - 1) & (~0x7)) + 8; + if (2 * st->den_rate < st->num_rate) + st->oversample >>= 1; + if (4 * st->den_rate < st->num_rate) + st->oversample >>= 1; + if (8 * st->den_rate < st->num_rate) + st->oversample >>= 1; + if (16 * st->den_rate < st->num_rate) + st->oversample >>= 1; + if (st->oversample < 1) + st->oversample = 1; + } else { + /* up-sampling */ + st->cutoff = quality_map[0].upsample_bandwidth; + } - /* Choose the resampling type that requires the least amount of memory */ + /* Choose the resampling type that requires the least amount of memory */ #ifdef RESAMPLE_FULL_SINC_TABLE - use_direct = 1; - if (INT_MAX/sizeof(spx_word16_t)/st->den_rate < st->filt_len) - goto fail; + use_direct = 1; + if (INT_MAX/sizeof(spx_word16_t)/st->den_rate < st->filt_len) + goto fail; #else - use_direct = st->filt_len*st->den_rate <= st->filt_len*st->oversample+8 - && INT_MAX/sizeof(spx_word16_t)/st->den_rate >= st->filt_len; + use_direct = st->filt_len * st->den_rate + <= st->filt_len * st->oversample + 8 + && INT_MAX / sizeof(spx_word16_t) / st->den_rate >= st->filt_len; #endif - if (use_direct) - { - min_sinc_table_length = st->filt_len*st->den_rate; - } else { - if ((INT_MAX/sizeof(spx_word16_t)-8)/st->oversample < st->filt_len) - goto fail; - - min_sinc_table_length = st->filt_len*st->oversample+8; - } - if (st->sinc_table_length < min_sinc_table_length) - { - spx_word16_t *sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,min_sinc_table_length*sizeof(spx_word16_t)); - if (!sinc_table) - goto fail; - - st->sinc_table = sinc_table; - st->sinc_table_length = min_sinc_table_length; - } - if (use_direct) - { - spx_uint32_t i; - for (i=0;iden_rate;i++) - { - spx_int32_t j; - for (j=0;jfilt_len;j++) - { - st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-(spx_int32_t)st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[0].window_func); - } - } - if (st->quality>8) - st->resampler_ptr = resampler_basic_direct_double; - else - st->resampler_ptr = resampler_basic_direct_single; - /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/ - } else { - spx_int32_t i; - for (i=-4;i<(spx_int32_t)(st->oversample*st->filt_len+4);i++) - st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)st->oversample - st->filt_len/2), st->filt_len, quality_map[0].window_func); - if (st->quality>8) - st->resampler_ptr = resampler_basic_interpolate_double; - else - st->resampler_ptr = resampler_basic_interpolate_single; - /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/ - } - - /* Here's the place where we update the filter memory to take into account - the change in filter length. It's probably the messiest part of the code - due to handling of lots of corner cases. */ - - /* Adding buffer_size to filt_len won't overflow here because filt_len - could be multiplied by sizeof(spx_word16_t) above. */ - min_alloc_size = st->filt_len-1 + st->buffer_size; - if (min_alloc_size > st->mem_alloc_size) - { - spx_word16_t *mem; - if (INT_MAX/sizeof(spx_word16_t)/st->nb_channels < min_alloc_size) - goto fail; - else if (!(mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*min_alloc_size * sizeof(*mem)))) - goto fail; - - st->mem = mem; - st->mem_alloc_size = min_alloc_size; - } - if (!st->started) - { - spx_uint32_t i; - for (i=0;inb_channels*st->mem_alloc_size;i++) - st->mem[i] = 0; - /*speex_warning("reinit filter");*/ - } else if (st->filt_len > old_length) - { - spx_uint32_t i; - /* Increase the filter length */ - /*speex_warning("increase filter size");*/ - for (i=st->nb_channels;i--;) - { - spx_uint32_t j; - spx_uint32_t olen = old_length; - /*if (st->magic_samples[i])*/ - { - /* Try and remove the magic samples as if nothing had happened */ - - /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */ - olen = old_length + 2*st->magic_samples[i]; - for (j=old_length-1+st->magic_samples[i];j--;) - st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j]; - for (j=0;jmagic_samples[i];j++) - st->mem[i*st->mem_alloc_size+j] = 0; - st->magic_samples[i] = 0; - } - if (st->filt_len > olen) - { - /* If the new filter length is still bigger than the "augmented" length */ - /* Copy data going backward */ - for (j=0;jmem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)]; - /* Then put zeros for lack of anything better */ - for (;jfilt_len-1;j++) - st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0; - /* Adjust last_sample */ - st->last_sample[i] += (st->filt_len - olen)/2; - } else { - /* Put back some of the magic! */ - st->magic_samples[i] = (olen - st->filt_len)/2; - for (j=0;jfilt_len-1+st->magic_samples[i];j++) - st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; - } - } - } else if (st->filt_len < old_length) - { - spx_uint32_t i; - /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic" - samples so they can be used directly as input the next time(s) */ - for (i=0;inb_channels;i++) - { - spx_uint32_t j; - spx_uint32_t old_magic = st->magic_samples[i]; - st->magic_samples[i] = (old_length - st->filt_len)/2; - /* We must copy some of the memory that's no longer used */ - /* Copy data going backward */ - for (j=0;jfilt_len-1+st->magic_samples[i]+old_magic;j++) - st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; - st->magic_samples[i] += old_magic; - } - } - return RESAMPLER_ERR_SUCCESS; - -fail: - st->resampler_ptr = resampler_basic_zero; - /* st->mem may still contain consumed input samples for the filter. - Restore filt_len so that filt_len - 1 still points to the position after - the last of these samples. */ - st->filt_len = old_length; - return RESAMPLER_ERR_ALLOC_FAILED; -} - -EXPORT SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) -{ - return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err); -} - -EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) -{ - SpeexResamplerState *st; - int filter_err; - - if (nb_channels == 0 || ratio_num == 0 || ratio_den == 0 || quality > 10 || quality < 0) - { - if (err) - *err = RESAMPLER_ERR_INVALID_ARG; - return NULL; - } - st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState)); - if (!st) - { - if (err) - *err = RESAMPLER_ERR_ALLOC_FAILED; - return NULL; - } - st->initialised = 0; - st->started = 0; - st->in_rate = 0; - st->out_rate = 0; - st->num_rate = 0; - st->den_rate = 0; - st->quality = -1; - st->sinc_table_length = 0; - st->mem_alloc_size = 0; - st->filt_len = 0; - st->mem = 0; - st->resampler_ptr = 0; - - st->cutoff = 1.f; - st->nb_channels = nb_channels; - st->in_stride = 1; - st->out_stride = 1; - - st->buffer_size = 160; - - /* Per channel data */ - if (!(st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(spx_int32_t)))) - goto fail; - if (!(st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(spx_uint32_t)))) - goto fail; - if (!(st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(spx_uint32_t)))) - goto fail; - - speex_resampler_set_quality(st, quality); - speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate); - - filter_err = update_filter(st); - if (filter_err == RESAMPLER_ERR_SUCCESS) - { - st->initialised = 1; - } else { - speex_resampler_destroy(st); - st = NULL; - } - if (err) - *err = filter_err; - - return st; - -fail: - if (err) - *err = RESAMPLER_ERR_ALLOC_FAILED; - speex_resampler_destroy(st); - return NULL; -} - -EXPORT void speex_resampler_destroy(SpeexResamplerState *st) -{ - speex_free(st->mem); - speex_free(st->sinc_table); - speex_free(st->last_sample); - speex_free(st->magic_samples); - speex_free(st->samp_frac_num); - speex_free(st); -} - -static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t channel_index, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) -{ - int j=0; - const int N = st->filt_len; - int out_sample = 0; - spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size; - spx_uint32_t ilen; - - st->started = 1; - - /* Call the right resampler through the function ptr */ - out_sample = st->resampler_ptr(st, channel_index, mem, in_len, out, out_len); - - if (st->last_sample[channel_index] < (spx_int32_t)*in_len) - *in_len = st->last_sample[channel_index]; - *out_len = out_sample; - st->last_sample[channel_index] -= *in_len; - - ilen = *in_len; - - for(j=0;jmagic_samples[channel_index]; - spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size; - const int N = st->filt_len; - - speex_resampler_process_native(st, channel_index, &tmp_in_len, *out, &out_len); - - st->magic_samples[channel_index] -= tmp_in_len; - - /* If we couldn't process all "magic" input samples, save the rest for next time */ - if (st->magic_samples[channel_index]) - { - spx_uint32_t i; - for (i=0;imagic_samples[channel_index];i++) - mem[N-1+i]=mem[N-1+i+tmp_in_len]; - } - *out += out_len*st->out_stride; - return out_len; -} - -EXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) -{ - int j; - spx_uint32_t ilen = *in_len; - spx_uint32_t olen = *out_len; - spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size; - const int filt_offs = st->filt_len - 1; - const spx_uint32_t xlen = st->mem_alloc_size - filt_offs; - const int istride = st->in_stride; - - if (st->magic_samples[channel_index]) - olen -= speex_resampler_magic(st, channel_index, &out, olen); - if (! st->magic_samples[channel_index]) { - while (ilen && olen) { - spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen; - spx_uint32_t ochunk = olen; - - if (in) { - for(j=0;jout_stride; - if (in) - in += ichunk * istride; - } - } - *in_len -= ilen; - *out_len -= olen; - return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS; -} - - - -EXPORT int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate) -{ - return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate); -} - -EXPORT void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate) -{ - *in_rate = st->in_rate; - *out_rate = st->out_rate; -} - -static spx_uint32_t _gcd(spx_uint32_t a, spx_uint32_t b) -{ - while (b != 0) - { - spx_uint32_t temp = a; - - a = b; - b = temp % b; - } - return a; -} - -EXPORT int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate) -{ - spx_uint32_t fact; - spx_uint32_t old_den; - spx_uint32_t i; - - if (ratio_num == 0 || ratio_den == 0) - return RESAMPLER_ERR_INVALID_ARG; - - if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den) - return RESAMPLER_ERR_SUCCESS; - - old_den = st->den_rate; - st->in_rate = in_rate; - st->out_rate = out_rate; - st->num_rate = ratio_num; - st->den_rate = ratio_den; - - fact = _gcd (st->num_rate, st->den_rate); - - st->num_rate /= fact; - st->den_rate /= fact; - - if (old_den > 0) - { - for (i=0;inb_channels;i++) - { - if (_muldiv(&st->samp_frac_num[i],st->samp_frac_num[i],st->den_rate,old_den) != RESAMPLER_ERR_SUCCESS) - return RESAMPLER_ERR_OVERFLOW; - /* Safety net */ - if (st->samp_frac_num[i] >= st->den_rate) - st->samp_frac_num[i] = st->den_rate-1; - } - } - - if (st->initialised) - return update_filter(st); - return RESAMPLER_ERR_SUCCESS; -} - -EXPORT void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den) -{ - *ratio_num = st->num_rate; - *ratio_den = st->den_rate; -} - -EXPORT int speex_resampler_set_quality(SpeexResamplerState *st, int quality) -{ - if (quality > 10 || quality < 0) - return RESAMPLER_ERR_INVALID_ARG; - if (st->quality == quality) - return RESAMPLER_ERR_SUCCESS; - st->quality = quality; - if (st->initialised) - return update_filter(st); - return RESAMPLER_ERR_SUCCESS; -} - -EXPORT void speex_resampler_get_quality(SpeexResamplerState *st, int *quality) -{ - *quality = st->quality; -} - -EXPORT void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride) -{ - st->in_stride = stride; -} - -EXPORT void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride) -{ - *stride = st->in_stride; -} - -EXPORT void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride) -{ - st->out_stride = stride; -} - -EXPORT void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride) -{ - *stride = st->out_stride; -} - -EXPORT int speex_resampler_get_input_latency(SpeexResamplerState *st) -{ - return st->filt_len / 2; -} - -EXPORT int speex_resampler_get_output_latency(SpeexResamplerState *st) -{ - return ((st->filt_len / 2) * st->den_rate + (st->num_rate >> 1)) / st->num_rate; -} - -EXPORT int speex_resampler_skip_zeros(SpeexResamplerState *st) -{ - spx_uint32_t i; - for (i=0;inb_channels;i++) - st->last_sample[i] = st->filt_len/2; - return RESAMPLER_ERR_SUCCESS; -} - -EXPORT int speex_resampler_reset_mem(SpeexResamplerState *st) -{ - spx_uint32_t i; - for (i=0;inb_channels;i++) - { - st->last_sample[i] = 0; - st->magic_samples[i] = 0; - st->samp_frac_num[i] = 0; - } - for (i=0;inb_channels*(st->filt_len-1);i++) - st->mem[i] = 0; - return RESAMPLER_ERR_SUCCESS; + if (use_direct) { + min_sinc_table_length = st->filt_len * st->den_rate; + } else { + if ((INT_MAX / sizeof(spx_word16_t) - 8) / st->oversample + < st->filt_len) + goto fail; + + min_sinc_table_length = st->filt_len * st->oversample + 8; + } + if (st->sinc_table_length < min_sinc_table_length) { + spx_word16_t *sinc_table = (spx_word16_t *) speex_realloc( + st->sinc_table, min_sinc_table_length * sizeof(spx_word16_t)); + if (!sinc_table) + goto fail; + + st->sinc_table = sinc_table; + st->sinc_table_length = min_sinc_table_length; + } + if (use_direct) { + spx_uint32_t i; + for (i = 0; i < st->den_rate; i++) { + spx_int32_t j; + for (j = 0; j < st->filt_len; j++) { + st->sinc_table[i * st->filt_len + j] = sinc(st->cutoff, + ((j - (spx_int32_t) st->filt_len / 2 + 1) + - ((float) i) / st->den_rate), st->filt_len, + quality_map[0].window_func); + } + } + if (st->quality > 8) + st->resampler_ptr = resampler_basic_direct_double; + else + st->resampler_ptr = resampler_basic_direct_single; + /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/ + } else { + spx_int32_t i; + for (i = -4; i < (spx_int32_t) (st->oversample * st->filt_len + 4); i++) + st->sinc_table[i + 4] = sinc(st->cutoff, + (i / (float) st->oversample - st->filt_len / 2), + st->filt_len, quality_map[0].window_func); + if (st->quality > 8) + st->resampler_ptr = resampler_basic_interpolate_double; + else + st->resampler_ptr = resampler_basic_interpolate_single; + /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/ + } + + /* Here's the place where we update the filter memory to take into account + the change in filter length. It's probably the messiest part of the code + due to handling of lots of corner cases. */ + + /* Adding buffer_size to filt_len won't overflow here because filt_len + could be multiplied by sizeof(spx_word16_t) above. */ + min_alloc_size = st->filt_len - 1 + st->buffer_size; + if (min_alloc_size > st->mem_alloc_size) { + spx_word16_t *mem; + if (INT_MAX / sizeof(spx_word16_t) / st->nb_channels < min_alloc_size) + goto fail; + else if (!(mem = (spx_word16_t*) speex_realloc(st->mem, + st->nb_channels * min_alloc_size * sizeof(*mem)))) + goto fail; + + st->mem = mem; + st->mem_alloc_size = min_alloc_size; + } + if (!st->started) { + spx_uint32_t i; + for (i = 0; i < st->nb_channels * st->mem_alloc_size; i++) + st->mem[i] = 0; + /*speex_warning("reinit filter");*/ + } else if (st->filt_len > old_length) { + spx_uint32_t i; + /* Increase the filter length */ + /*speex_warning("increase filter size");*/ + for (i = st->nb_channels; i--;) { + spx_uint32_t j; + spx_uint32_t olen = old_length; + /*if (st->magic_samples[i])*/ + { + /* Try and remove the magic samples as if nothing had happened */ + + /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */ + olen = old_length + 2 * st->magic_samples[i]; + for (j = old_length - 1 + st->magic_samples[i]; j--;) + st->mem[i * st->mem_alloc_size + j + st->magic_samples[i]] = + st->mem[i * old_alloc_size + j]; + for (j = 0; j < st->magic_samples[i]; j++) + st->mem[i * st->mem_alloc_size + j] = 0; + st->magic_samples[i] = 0; + } + if (st->filt_len > olen) { + /* If the new filter length is still bigger than the "augmented" length */ + /* Copy data going backward */ + for (j = 0; j < olen - 1; j++) + st->mem[i * st->mem_alloc_size + (st->filt_len - 2 - j)] = + st->mem[i * st->mem_alloc_size + (olen - 2 - j)]; + /* Then put zeros for lack of anything better */ + for (; j < st->filt_len - 1; j++) + st->mem[i * st->mem_alloc_size + (st->filt_len - 2 - j)] = + 0; + /* Adjust last_sample */ + st->last_sample[i] += (st->filt_len - olen) / 2; + } else { + /* Put back some of the magic! */ + st->magic_samples[i] = (olen - st->filt_len) / 2; + for (j = 0; j < st->filt_len - 1 + st->magic_samples[i]; j++) + st->mem[i * st->mem_alloc_size + j] = st->mem[i + * st->mem_alloc_size + j + st->magic_samples[i]]; + } + } + } else if (st->filt_len < old_length) { + spx_uint32_t i; + /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic" + samples so they can be used directly as input the next time(s) */ + for (i = 0; i < st->nb_channels; i++) { + spx_uint32_t j; + spx_uint32_t old_magic = st->magic_samples[i]; + st->magic_samples[i] = (old_length - st->filt_len) / 2; + /* We must copy some of the memory that's no longer used */ + /* Copy data going backward */ + for (j = 0; j < st->filt_len - 1 + st->magic_samples[i] + old_magic; + j++) + st->mem[i * st->mem_alloc_size + j] = st->mem[i + * st->mem_alloc_size + j + st->magic_samples[i]]; + st->magic_samples[i] += old_magic; + } + } + return RESAMPLER_ERR_SUCCESS; + + fail: st->resampler_ptr = resampler_basic_zero; + /* st->mem may still contain consumed input samples for the filter. + Restore filt_len so that filt_len - 1 still points to the position after + the last of these samples. */ + st->filt_len = old_length; + return RESAMPLER_ERR_ALLOC_FAILED; +} + +EXPORT SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, + spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) { + return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, + out_rate, quality, err); +} + +EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, + spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, + spx_uint32_t out_rate, int quality, int *err) { + SpeexResamplerState *st; + int filter_err; + + if (nb_channels == 0 || ratio_num == 0 || ratio_den == 0 || quality > 10 + || quality < 0) { + if (err) + *err = RESAMPLER_ERR_INVALID_ARG; + return NULL; + } + st = (SpeexResamplerState *) speex_alloc(sizeof(SpeexResamplerState)); + if (!st) { + if (err) + *err = RESAMPLER_ERR_ALLOC_FAILED; + return NULL; + } + st->initialised = 0; + st->started = 0; + st->in_rate = 0; + st->out_rate = 0; + st->num_rate = 0; + st->den_rate = 0; + st->quality = -1; + st->sinc_table_length = 0; + st->mem_alloc_size = 0; + st->filt_len = 0; + st->mem = 0; + st->resampler_ptr = 0; + + st->cutoff = 1.f; + st->nb_channels = nb_channels; + st->in_stride = 1; + st->out_stride = 1; + + st->buffer_size = 160; + + /* Per channel data */ + if (!(st->last_sample = (spx_int32_t*) speex_alloc( + nb_channels * sizeof(spx_int32_t)))) + goto fail; + if (!(st->magic_samples = (spx_uint32_t*) speex_alloc( + nb_channels * sizeof(spx_uint32_t)))) + goto fail; + if (!(st->samp_frac_num = (spx_uint32_t*) speex_alloc( + nb_channels * sizeof(spx_uint32_t)))) + goto fail; + + speex_resampler_set_quality(st, quality); + speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate); + + filter_err = update_filter(st); + if (filter_err == RESAMPLER_ERR_SUCCESS) { + st->initialised = 1; + } else { + speex_resampler_destroy(st); + st = NULL; + } + if (err) + *err = filter_err; + + return st; + + fail: if (err) + *err = RESAMPLER_ERR_ALLOC_FAILED; + speex_resampler_destroy(st); + return NULL; +} + +EXPORT void speex_resampler_destroy(SpeexResamplerState *st) { + speex_free(st->mem); + speex_free(st->sinc_table); + speex_free(st->last_sample); + speex_free(st->magic_samples); + speex_free(st->samp_frac_num); + speex_free(st); +} + +static int speex_resampler_process_native(SpeexResamplerState *st, + spx_uint32_t channel_index, spx_uint32_t *in_len, spx_word16_t *out, + spx_uint32_t *out_len) { + int j = 0; + const int N = st->filt_len; + int out_sample = 0; + spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size; + spx_uint32_t ilen; + + st->started = 1; + + /* Call the right resampler through the function ptr */ + out_sample = st->resampler_ptr(st, channel_index, mem, in_len, out, + out_len); + + if (st->last_sample[channel_index] < (spx_int32_t) *in_len) + *in_len = st->last_sample[channel_index]; + *out_len = out_sample; + st->last_sample[channel_index] -= *in_len; + + ilen = *in_len; + + for (j = 0; j < N - 1; ++j) + mem[j] = mem[j + ilen]; + + return RESAMPLER_ERR_SUCCESS; +} + +static int speex_resampler_magic(SpeexResamplerState *st, + spx_uint32_t channel_index, spx_word16_t **out, spx_uint32_t out_len) { + spx_uint32_t tmp_in_len = st->magic_samples[channel_index]; + spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size; + const int N = st->filt_len; + + speex_resampler_process_native(st, channel_index, &tmp_in_len, *out, + &out_len); + + st->magic_samples[channel_index] -= tmp_in_len; + + /* If we couldn't process all "magic" input samples, save the rest for next time */ + if (st->magic_samples[channel_index]) { + spx_uint32_t i; + for (i = 0; i < st->magic_samples[channel_index]; i++) + mem[N - 1 + i] = mem[N - 1 + i + tmp_in_len]; + } + *out += out_len * st->out_stride; + return out_len; +} + +EXPORT int speex_resampler_process_float(SpeexResamplerState *st, + spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, + float *out, spx_uint32_t *out_len) { + int j; + spx_uint32_t ilen = *in_len; + spx_uint32_t olen = *out_len; + spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size; + const int filt_offs = st->filt_len - 1; + const spx_uint32_t xlen = st->mem_alloc_size - filt_offs; + const int istride = st->in_stride; + + if (st->magic_samples[channel_index]) + olen -= speex_resampler_magic(st, channel_index, &out, olen); + if (!st->magic_samples[channel_index]) { + while (ilen && olen) { + spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen; + spx_uint32_t ochunk = olen; + + if (in) { + for (j = 0; j < ichunk; ++j) + x[j + filt_offs] = in[j * istride]; + } else { + for (j = 0; j < ichunk; ++j) + x[j + filt_offs] = 0; + } + speex_resampler_process_native(st, channel_index, &ichunk, out, + &ochunk); + ilen -= ichunk; + olen -= ochunk; + out += ochunk * st->out_stride; + if (in) + in += ichunk * istride; + } + } + *in_len -= ilen; + *out_len -= olen; + return st->resampler_ptr == resampler_basic_zero ? + RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_set_rate(SpeexResamplerState *st, + spx_uint32_t in_rate, spx_uint32_t out_rate) { + return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, + out_rate); +} + +EXPORT void speex_resampler_get_rate(SpeexResamplerState *st, + spx_uint32_t *in_rate, spx_uint32_t *out_rate) { + *in_rate = st->in_rate; + *out_rate = st->out_rate; +} + +static spx_uint32_t _gcd(spx_uint32_t a, spx_uint32_t b) { + while (b != 0) { + spx_uint32_t temp = a; + + a = b; + b = temp % b; + } + return a; +} + +EXPORT int speex_resampler_set_rate_frac(SpeexResamplerState *st, + spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, + spx_uint32_t out_rate) { + spx_uint32_t fact; + spx_uint32_t old_den; + spx_uint32_t i; + + if (ratio_num == 0 || ratio_den == 0) + return RESAMPLER_ERR_INVALID_ARG; + + if (st->in_rate == in_rate && st->out_rate == out_rate + && st->num_rate == ratio_num && st->den_rate == ratio_den) + return RESAMPLER_ERR_SUCCESS; + + old_den = st->den_rate; + st->in_rate = in_rate; + st->out_rate = out_rate; + st->num_rate = ratio_num; + st->den_rate = ratio_den; + + fact = _gcd(st->num_rate, st->den_rate); + + st->num_rate /= fact; + st->den_rate /= fact; + + if (old_den > 0) { + for (i = 0; i < st->nb_channels; i++) { + if (_muldiv(&st->samp_frac_num[i], st->samp_frac_num[i], + st->den_rate, old_den) != RESAMPLER_ERR_SUCCESS) + return RESAMPLER_ERR_OVERFLOW; + /* Safety net */ + if (st->samp_frac_num[i] >= st->den_rate) + st->samp_frac_num[i] = st->den_rate - 1; + } + } + + if (st->initialised) + return update_filter(st); + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT void speex_resampler_get_ratio(SpeexResamplerState *st, + spx_uint32_t *ratio_num, spx_uint32_t *ratio_den) { + *ratio_num = st->num_rate; + *ratio_den = st->den_rate; +} + +EXPORT int speex_resampler_set_quality(SpeexResamplerState *st, int quality) { + if (quality > 10 || quality < 0) + return RESAMPLER_ERR_INVALID_ARG; + if (st->quality == quality) + return RESAMPLER_ERR_SUCCESS; + st->quality = quality; + if (st->initialised) + return update_filter(st); + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT void speex_resampler_get_quality(SpeexResamplerState *st, int *quality) { + *quality = st->quality; +} + +EXPORT void speex_resampler_set_input_stride(SpeexResamplerState *st, + spx_uint32_t stride) { + st->in_stride = stride; +} + +EXPORT void speex_resampler_get_input_stride(SpeexResamplerState *st, + spx_uint32_t *stride) { + *stride = st->in_stride; +} + +EXPORT void speex_resampler_set_output_stride(SpeexResamplerState *st, + spx_uint32_t stride) { + st->out_stride = stride; +} + +EXPORT void speex_resampler_get_output_stride(SpeexResamplerState *st, + spx_uint32_t *stride) { + *stride = st->out_stride; +} + +EXPORT int speex_resampler_get_input_latency(SpeexResamplerState *st) { + return st->filt_len / 2; +} + +EXPORT int speex_resampler_get_output_latency(SpeexResamplerState *st) { + return ((st->filt_len / 2) * st->den_rate + (st->num_rate >> 1)) + / st->num_rate; +} + +EXPORT int speex_resampler_skip_zeros(SpeexResamplerState *st) { + spx_uint32_t i; + for (i = 0; i < st->nb_channels; i++) + st->last_sample[i] = st->filt_len / 2; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_reset_mem(SpeexResamplerState *st) { + spx_uint32_t i; + for (i = 0; i < st->nb_channels; i++) { + st->last_sample[i] = 0; + st->magic_samples[i] = 0; + st->samp_frac_num[i] = 0; + } + for (i = 0; i < st->nb_channels * (st->filt_len - 1); i++) + st->mem[i] = 0; + return RESAMPLER_ERR_SUCCESS; } diff -Nru libmysofa-0.6~dfsg0/src/resampler/speex_resampler.h libmysofa-0.7~dfsg0/src/resampler/speex_resampler.h --- libmysofa-0.6~dfsg0/src/resampler/speex_resampler.h 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/resampler/speex_resampler.h 2019-03-31 15:16:24.000000000 +0000 @@ -1,40 +1,39 @@ /* Copyright (C) 2007 Jean-Marc Valin - File: speex_resampler.h - Resampling code - - The design goals of this code are: - - Very fast algorithm - - Low memory requirement - - Good *perceptual* quality (and not best SNR) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ + File: speex_resampler.h + Resampling code + The design goals of this code are: + - Very fast algorithm + - Low memory requirement + - Good *perceptual* quality (and not best SNR) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ #ifndef SPEEX_RESAMPLER_H #define SPEEX_RESAMPLER_H @@ -85,14 +84,14 @@ #define SPEEX_RESAMPLER_QUALITY_DESKTOP 5 enum { - RESAMPLER_ERR_SUCCESS = 0, - RESAMPLER_ERR_ALLOC_FAILED = 1, - RESAMPLER_ERR_BAD_STATE = 2, - RESAMPLER_ERR_INVALID_ARG = 3, - RESAMPLER_ERR_PTR_OVERLAP = 4, - RESAMPLER_ERR_OVERFLOW = 5, + RESAMPLER_ERR_SUCCESS = 0, + RESAMPLER_ERR_ALLOC_FAILED = 1, + RESAMPLER_ERR_BAD_STATE = 2, + RESAMPLER_ERR_INVALID_ARG = 3, + RESAMPLER_ERR_PTR_OVERLAP = 4, + RESAMPLER_ERR_OVERFLOW = 5, - RESAMPLER_ERR_MAX_ERROR + RESAMPLER_ERR_MAX_ERROR }; struct SpeexResamplerState_; @@ -108,10 +107,8 @@ * @retval NULL Error: not enough memory */ SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, - spx_uint32_t in_rate, - spx_uint32_t out_rate, - int quality, - int *err); +spx_uint32_t in_rate, +spx_uint32_t out_rate, int quality, int *err); /** Create a new resampler with fractional input/output rates. The sampling * rate ratio is an arbitrary rational number with both the numerator and @@ -127,12 +124,10 @@ * @retval NULL Error: not enough memory */ SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, - spx_uint32_t ratio_num, - spx_uint32_t ratio_den, - spx_uint32_t in_rate, - spx_uint32_t out_rate, - int quality, - int *err); +spx_uint32_t ratio_num, +spx_uint32_t ratio_den, +spx_uint32_t in_rate, +spx_uint32_t out_rate, int quality, int *err); /** Destroy a resampler state. * @param st Resampler state @@ -150,11 +145,9 @@ * @param out_len Size of the output buffer. Returns the number of samples written */ int speex_resampler_process_float(SpeexResamplerState *st, - spx_uint32_t channel_index, - const float *in, - spx_uint32_t *in_len, - float *out, - spx_uint32_t *out_len); +spx_uint32_t channel_index, const float *in, +spx_uint32_t *in_len, float *out, +spx_uint32_t *out_len); /** Resample an int array. The input and output buffers must *not* overlap. * @param st Resampler state @@ -167,11 +160,10 @@ * @param out_len Size of the output buffer. Returns the number of samples written */ int speex_resampler_process_int(SpeexResamplerState *st, - spx_uint32_t channel_index, - const spx_int16_t *in, - spx_uint32_t *in_len, - spx_int16_t *out, - spx_uint32_t *out_len); +spx_uint32_t channel_index, const spx_int16_t *in, +spx_uint32_t *in_len, +spx_int16_t *out, +spx_uint32_t *out_len); /** Resample an interleaved float array. The input and output buffers must *not* overlap. * @param st Resampler state @@ -183,10 +175,9 @@ * This is all per-channel. */ int speex_resampler_process_interleaved_float(SpeexResamplerState *st, - const float *in, - spx_uint32_t *in_len, - float *out, - spx_uint32_t *out_len); + const float *in, + spx_uint32_t *in_len, float *out, + spx_uint32_t *out_len); /** Resample an interleaved int array. The input and output buffers must *not* overlap. * @param st Resampler state @@ -198,10 +189,10 @@ * This is all per-channel. */ int speex_resampler_process_interleaved_int(SpeexResamplerState *st, - const spx_int16_t *in, - spx_uint32_t *in_len, - spx_int16_t *out, - spx_uint32_t *out_len); + const spx_int16_t *in, + spx_uint32_t *in_len, + spx_int16_t *out, + spx_uint32_t *out_len); /** Set (change) the input/output sampling rates (integer value). * @param st Resampler state @@ -209,8 +200,8 @@ * @param out_rate Output sampling rate (integer number of Hz). */ int speex_resampler_set_rate(SpeexResamplerState *st, - spx_uint32_t in_rate, - spx_uint32_t out_rate); +spx_uint32_t in_rate, +spx_uint32_t out_rate); /** Get the current input/output sampling rates (integer value). * @param st Resampler state @@ -218,8 +209,8 @@ * @param out_rate Output sampling rate (integer number of Hz) copied. */ void speex_resampler_get_rate(SpeexResamplerState *st, - spx_uint32_t *in_rate, - spx_uint32_t *out_rate); +spx_uint32_t *in_rate, +spx_uint32_t *out_rate); /** Set (change) the input/output sampling rates and resampling ratio * (fractional values in Hz supported). @@ -230,10 +221,10 @@ * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). */ int speex_resampler_set_rate_frac(SpeexResamplerState *st, - spx_uint32_t ratio_num, - spx_uint32_t ratio_den, - spx_uint32_t in_rate, - spx_uint32_t out_rate); +spx_uint32_t ratio_num, +spx_uint32_t ratio_den, +spx_uint32_t in_rate, +spx_uint32_t out_rate); /** Get the current resampling ratio. This will be reduced to the least * common denominator. @@ -242,52 +233,50 @@ * @param ratio_den Denominator of the sampling rate ratio copied */ void speex_resampler_get_ratio(SpeexResamplerState *st, - spx_uint32_t *ratio_num, - spx_uint32_t *ratio_den); +spx_uint32_t *ratio_num, +spx_uint32_t *ratio_den); /** Set (change) the conversion quality. * @param st Resampler state * @param quality Resampling quality between 0 and 10, where 0 has poor * quality and 10 has very high quality. */ -int speex_resampler_set_quality(SpeexResamplerState *st, - int quality); +int speex_resampler_set_quality(SpeexResamplerState *st, int quality); /** Get the conversion quality. * @param st Resampler state * @param quality Resampling quality between 0 and 10, where 0 has poor * quality and 10 has very high quality. */ -void speex_resampler_get_quality(SpeexResamplerState *st, - int *quality); +void speex_resampler_get_quality(SpeexResamplerState *st, int *quality); /** Set (change) the input stride. * @param st Resampler state * @param stride Input stride */ void speex_resampler_set_input_stride(SpeexResamplerState *st, - spx_uint32_t stride); +spx_uint32_t stride); /** Get the input stride. * @param st Resampler state * @param stride Input stride copied */ void speex_resampler_get_input_stride(SpeexResamplerState *st, - spx_uint32_t *stride); +spx_uint32_t *stride); /** Set (change) the output stride. * @param st Resampler state * @param stride Output stride */ void speex_resampler_set_output_stride(SpeexResamplerState *st, - spx_uint32_t stride); +spx_uint32_t stride); /** Get the output stride. * @param st Resampler state copied * @param stride Output stride */ void speex_resampler_get_output_stride(SpeexResamplerState *st, - spx_uint32_t *stride); +spx_uint32_t *stride); /** Get the latency introduced by the resampler measured in input samples. * @param st Resampler state diff -Nru libmysofa-0.6~dfsg0/src/resampler/stack_alloc.h libmysofa-0.7~dfsg0/src/resampler/stack_alloc.h --- libmysofa-0.6~dfsg0/src/resampler/stack_alloc.h 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/resampler/stack_alloc.h 2019-03-31 15:16:24.000000000 +0000 @@ -1,36 +1,36 @@ /* Copyright (C) 2002 Jean-Marc Valin */ /** - @file stack_alloc.h - @brief Temporary memory allocation on stack -*/ + @file stack_alloc.h + @brief Temporary memory allocation on stack + */ /* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef STACK_ALLOC_H #define STACK_ALLOC_H @@ -111,5 +111,4 @@ #define ALLOC(var, size, type) var = PUSH(stack, size, type) #endif - #endif diff -Nru libmysofa-0.6~dfsg0/src/tests/cache.c libmysofa-0.7~dfsg0/src/tests/cache.c --- libmysofa-0.6~dfsg0/src/tests/cache.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/cache.c 2019-03-31 15:16:24.000000000 +0000 @@ -15,54 +15,53 @@ struct MYSOFA_EASY *easy1 = malloc(sizeof(struct MYSOFA_EASY)); struct MYSOFA_EASY *easy2 = malloc(sizeof(struct MYSOFA_EASY)); - bzero(easy1,sizeof(struct MYSOFA_EASY)); - bzero(easy2,sizeof(struct MYSOFA_EASY)); + bzero(easy1, sizeof(struct MYSOFA_EASY)); + bzero(easy2, sizeof(struct MYSOFA_EASY)); - mysofa_close(easy2); /* must pass without segfail */ + mysofa_close(easy2); /* must pass without segfail */ - - CU_ASSERT(!mysofa_cache_lookup(filename1,sr1)); /* no entry so far */ - CU_ASSERT(mysofa_cache_store(easy1, filename1, sr1) == easy1); /* add */ - CU_ASSERT(mysofa_cache_lookup(filename1,sr1) == easy1); /* check whether easy1 has been cached. */ - - mysofa_cache_release_all(); /* remove all */ - CU_ASSERT(!mysofa_cache_lookup(filename1,sr1)); /* cache must be empty now */ - -/* - mysofa_cache_release(easy1); - free(easy1) - - must segfail -*/ + CU_ASSERT(!mysofa_cache_lookup(filename1, sr1)); /* no entry so far */ + CU_ASSERT(mysofa_cache_store(easy1, filename1, sr1) == easy1); /* add */ + CU_ASSERT(mysofa_cache_lookup(filename1, sr1) == easy1); /* check whether easy1 has been cached. */ + + mysofa_cache_release_all(); /* remove all */ + CU_ASSERT(!mysofa_cache_lookup(filename1, sr1)); /* cache must be empty now */ + + /* + mysofa_cache_release(easy1); + free(easy1) + + must segfail + */ easy1 = malloc(sizeof(struct MYSOFA_EASY)); - bzero(easy1,sizeof(struct MYSOFA_EASY)); + bzero(easy1, sizeof(struct MYSOFA_EASY)); - CU_ASSERT(mysofa_cache_store(easy1, filename1, sr1) == easy1); /* add again */ + CU_ASSERT(mysofa_cache_store(easy1, filename1, sr1) == easy1); /* add again */ - easy2 = malloc(sizeof(struct MYSOFA_EASY)); /* easy2 has been freed automatically */ - bzero(easy2,sizeof(struct MYSOFA_EASY)); + easy2 = malloc(sizeof(struct MYSOFA_EASY)); /* easy2 has been freed automatically */ + bzero(easy2, sizeof(struct MYSOFA_EASY)); - CU_ASSERT(mysofa_cache_store(easy2, filename1, sr1) == easy1); /* second add must be possible too, return cached */ + CU_ASSERT(mysofa_cache_store(easy2, filename1, sr1) == easy1); /* second add must be possible too, return cached */ - easy2 = malloc(sizeof(struct MYSOFA_EASY)); /* easy2 has been freed automatically */ - bzero(easy2,sizeof(struct MYSOFA_EASY)); + easy2 = malloc(sizeof(struct MYSOFA_EASY)); /* easy2 has been freed automatically */ + bzero(easy2, sizeof(struct MYSOFA_EASY)); - CU_ASSERT(mysofa_cache_store(easy2, filename1, sr2) == easy2); /* now third add with different sample rate */ + CU_ASSERT(mysofa_cache_store(easy2, filename1, sr2) == easy2); /* now third add with different sample rate */ - CU_ASSERT(mysofa_cache_lookup(filename1,sr2) == easy2); + CU_ASSERT(mysofa_cache_lookup(filename1, sr2) == easy2); mysofa_cache_release(easy2); mysofa_cache_release(easy2); - CU_ASSERT(!mysofa_cache_lookup(filename1,sr2)); + CU_ASSERT(!mysofa_cache_lookup(filename1, sr2)); easy2 = malloc(sizeof(struct MYSOFA_EASY)); - bzero(easy2,sizeof(struct MYSOFA_EASY)); + bzero(easy2, sizeof(struct MYSOFA_EASY)); - CU_ASSERT(mysofa_cache_store(easy2, filename2, sr2) == easy2); /* now third add with different file name */ - CU_ASSERT(mysofa_cache_lookup(filename2,sr2) == easy2); + CU_ASSERT(mysofa_cache_store(easy2, filename2, sr2) == easy2); /* now third add with different file name */ + CU_ASSERT(mysofa_cache_lookup(filename2, sr2) == easy2); mysofa_cache_release(easy2); mysofa_cache_release(easy2); - CU_ASSERT(!mysofa_cache_lookup(filename1,sr2)); - mysofa_cache_release_all(); /* remove all */ + CU_ASSERT(!mysofa_cache_lookup(filename1, sr2)); + mysofa_cache_release_all(); /* remove all */ } diff -Nru libmysofa-0.6~dfsg0/src/tests/check.c libmysofa-0.7~dfsg0/src/tests/check.c --- libmysofa-0.6~dfsg0/src/tests/check.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/check.c 2019-03-31 15:16:24.000000000 +0000 @@ -6,8 +6,7 @@ #include "../hrtf/tools.h" #include "tests.h" -static void check(char *filename) -{ +static void check(char *filename) { struct MYSOFA_HRTF *hrtf; int err; diff -Nru libmysofa-0.6~dfsg0/src/tests/easy.c libmysofa-0.7~dfsg0/src/tests/easy.c --- libmysofa-0.6~dfsg0/src/tests/easy.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/easy.c 2019-03-31 15:16:24.000000000 +0000 @@ -18,18 +18,19 @@ struct MYSOFA_EASY *easy; int err = 0; int filterlength; - int filters=0; - float theta,r; + int filters = 0; + float theta, r; float *coordinates; float *ir; float *delays; - int count=0; + int count = 0; FILE *file; float c[3]; - float l1,l2; + float l1, l2; float sdiff1, sdiff2, diff1, diff2; - easy = mysofa_open("share/MIT_KEMAR_normal_pinna.sofa", 8000., &filterlength, &err); + easy = mysofa_open("share/MIT_KEMAR_normal_pinna.sofa", 8000., + &filterlength, &err); if (!easy) { CU_FAIL_FATAL("Error reading file."); return; @@ -43,84 +44,86 @@ return; } mysofa_minphase(easy->hrtf, 0.01); - - for(filters=0;filtershrtf->M;filters++) { - c[0]=easy->hrtf->SourcePosition.values[filters*3]; - c[1]=easy->hrtf->SourcePosition.values[filters*3+1]; - c[2]=easy->hrtf->SourcePosition.values[filters*3+2]; + + for (filters = 0; filters < easy->hrtf->M; filters++) { + c[0] = easy->hrtf->SourcePosition.values[filters * 3]; + c[1] = easy->hrtf->SourcePosition.values[filters * 3 + 1]; + c[2] = easy->hrtf->SourcePosition.values[filters * 3 + 2]; mysofa_c2s(c); - + #ifdef VDEBUG - printf("in %d %f %f %f # %f %f %f\n",filters,c[0],c[1],c[2],easy->hrtf->SourcePosition.values[filters*3],easy->hrtf->SourcePosition.values[filters*3+1],easy->hrtf->SourcePosition.values[filters*3+2]); + printf("in %d %f %f %f # %f %f %f\n",filters,c[0],c[1],c[2],easy->hrtf->SourcePosition.values[filters*3],easy->hrtf->SourcePosition.values[filters*3+1],easy->hrtf->SourcePosition.values[filters*3+2]); #endif - c[0] = fmod(round(c[0]+360),360); - c[1] = fmod(round(c[1]+361),360); - l1 = round(easy->hrtf->DataDelay.values[filters*2]*48000*2); - l2 = round(easy->hrtf->DataDelay.values[filters*2+1]*48000*2); + c[0] = fmod(round(c[0] + 360), 360); + c[1] = fmod(round(c[1] + 361), 360); + l1 = round(easy->hrtf->DataDelay.values[filters * 2] * 48000 * 2); + l2 = round(easy->hrtf->DataDelay.values[filters * 2 + 1] * 48000 * 2); #ifdef VDEBUG -/* printf("compare %d %f %f %f %f %f\n",filters,c[0],c[1],c[2],l1,l2); */ + /* printf("compare %d %f %f %f %f %f\n",filters,c[0],c[1],c[2],l1,l2); */ #endif - CU_ASSERT(!((fabs(c[0]-l1)>2 || fabs(c[1]-l2)>2) && !fequals(l2,90))); + CU_ASSERT( + !((fabs(c[0] - l1) > 2 || fabs(c[1] - l2) > 2) + && !fequals(l2, 90))); } - - - filters=0; - for(theta=-90.;theta<=90.;theta+=5.) { - r = round(cos(theta*M_PI/180.) * 120.); - if(r==0.) r=1; - filters+=r; + + filters = 0; + for (theta = -90.; theta <= 90.; theta += 5.) { + r = round(cos(theta * M_PI / 180.) * 120.); + if (r == 0.) + r = 1; + filters += r; } #ifdef VDEBUG printf("Filters %d\n",filters); #endif - coordinates = malloc(filters*sizeof(float)*3); - ir = malloc(filters*easy->hrtf->N*sizeof(float)*2); - delays = malloc(filters*2*sizeof(float)); + coordinates = malloc(filters * sizeof(float) * 3); + ir = malloc(filters * easy->hrtf->N * sizeof(float) * 2); + delays = malloc(filters * 2 * sizeof(float)); sdiff1 = sdiff2 = 0; err = 0; - for(theta=-90.;theta<=90.;theta+=5.) { - int r = round(cos(theta*M_PI/180.) * 120.); + for (theta = -90.; theta <= 90.; theta += 5.) { + int r = round(cos(theta * M_PI / 180.) * 120.); int phi; - if(r==0) r=1; - for(phi=0;phihrtf->N, - ir + (2*count+1) * easy->hrtf->N, - &delays[2*count], &delays[2*count+1]); - diff1 = fabs(phi * (360. / r) - delays[2*count] * 48000 * 2); - diff2 = fabs(fmod(theta + 360,360) - delays[2*count+1] * 48000 * 2); - if(diff1 > 5 || diff2 > 5) + mysofa_getfilter_float(easy, coordinates[count * 3 + 0], + coordinates[count * 3 + 1], coordinates[count * 3 + 2], + ir + 2 * count * easy->hrtf->N, + ir + (2 * count + 1) * easy->hrtf->N, &delays[2 * count], + &delays[2 * count + 1]); + diff1 = fabs(phi * (360. / r) - delays[2 * count] * 48000 * 2); + diff2 = fabs( + fmod(theta + 360, 360) - delays[2 * count + 1] * 48000 * 2); + if (diff1 > 5 || diff2 > 5) err++; else { sdiff1 += diff1; sdiff2 += diff2; } - + #ifdef VDEBUG printf("diff %f %f\t", diff1, diff2); printf("delays %f %f %f %f\n", phi * (360. / r), fmod(theta + 360,360), delays[2*count] * 48000 * 2, delays[2*count+1] * 48000 * 2); #endif count++; - + } } - err = err*100./count; - sdiff1 = sdiff1 / (count-err); - sdiff2 = sdiff2 / (count-err); - + err = err * 100. / count; + sdiff1 = sdiff1 / (count - err); + sdiff2 = sdiff2 / (count - err); + #ifdef VDEBUG printf("errors %f%% diffs %f %f\n", err*100./count, sdiff1 / (count-err), sdiff2 / (count-err)); #endif @@ -131,20 +134,51 @@ free(easy->hrtf->DataDelay.values); free(easy->hrtf->DataIR.values); free(easy->hrtf->SourcePosition.values); - easy->hrtf->DataDelay.elements=filters*2; - easy->hrtf->DataDelay.values=delays; - easy->hrtf->DataIR.elements=filters*2*easy->hrtf->N; - easy->hrtf->DataIR.values=ir; - easy->hrtf->SourcePosition.elements=filters*3; - easy->hrtf->SourcePosition.values=coordinates; + easy->hrtf->DataDelay.elements = filters * 2; + easy->hrtf->DataDelay.values = delays; + easy->hrtf->DataIR.elements = filters * 2 * easy->hrtf->N; + easy->hrtf->DataIR.values = ir; + easy->hrtf->SourcePosition.elements = filters * 3; + easy->hrtf->SourcePosition.values = coordinates; easy->hrtf->M = filters; - file = fopen("/tmp/easy.tmp.json","w"); - CU_ASSERT(file!=NULL); - printJson(file,easy->hrtf); + file = fopen("/tmp/easy.tmp.json", "w"); + CU_ASSERT(file != NULL); + printJson(file, easy->hrtf); fclose(file); /* TODO verify correctness of the easy.json file */ mysofa_close(easy); + + /* Test raw opening (no norm) and MxR delay .sofa */ + easy = mysofa_open_no_norm("tests/tester2.sofa", 48000., &filterlength, + &err); + if (!easy) { + CU_FAIL_FATAL("Error reading file."); + return; + } + + ir = malloc(filters * easy->hrtf->N * sizeof(float) * 2); + delays = malloc(filters * 2 * sizeof(float)); + err = 0; + + for (filters = 0; filters < easy->hrtf->M; filters++) { + // see tester2.sofa file creation in tester2.m file + diff1 = filters - easy->hrtf->DataDelay.values[easy->hrtf->R * filters]; + diff2 = filters + + easy->hrtf->DataDelay.values[easy->hrtf->R * filters + 1]; + if (diff1 > 0.1 || diff2 > 0.1) + err++; +#ifdef VDEBUG + printf("delays: %f %f \t", easy->hrtf->DataDelay.values[easy->hrtf->R*filters], easy->hrtf->DataDelay.values[easy->hrtf->R*filters+1]); + printf("diff: %f %f %i\n", diff1, diff2, err); +#endif + } + CU_ASSERT(err < 1); + + free(delays); + + mysofa_close(easy); + } diff -Nru libmysofa-0.6~dfsg0/src/tests/external.c libmysofa-0.7~dfsg0/src/tests/external.c --- libmysofa-0.6~dfsg0/src/tests/external.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/external.c 2019-03-31 15:16:24.000000000 +0000 @@ -7,7 +7,7 @@ int main() { int err; - + CU_pSuite pSuite = NULL; /* initialize the CUnit test registry */ @@ -24,15 +24,25 @@ /* add the tests to the suite */ /* NOTE - ORDER IS IMPORTANT - MUST TEST fread() AFTER fprintf() */ if ((NULL == CU_add_test(pSuite, "test of mysofa_check", test_check)) - || (NULL == CU_add_test(pSuite, "test of mysofa_lookup", test_lookup)) - || (NULL == CU_add_test(pSuite, "test of mysofa_neighbors", test_neighbors)) - || (NULL == CU_add_test(pSuite, "test of mysofa_interpolate", test_interpolate)) - || (NULL == CU_add_test(pSuite, "test of mysofa_resample", test_resample)) - || (NULL == CU_add_test(pSuite, "test of mysofa_loudness", test_loudness)) - || (NULL == CU_add_test(pSuite, "test of mysofa_minphase", test_minphase)) - || (NULL == CU_add_test(pSuite, "test of mysofa_cache", test_cache)) - || (NULL == CU_add_test(pSuite, "test of mysofa_easy", test_easy)) - ) { + || (NULL + == CU_add_test(pSuite, "test of mysofa_lookup", test_lookup)) + || (NULL + == CU_add_test(pSuite, "test of mysofa_neighbors", + test_neighbors)) + || (NULL + == CU_add_test(pSuite, "test of mysofa_interpolate", + test_interpolate)) + || (NULL + == CU_add_test(pSuite, "test of mysofa_resample", + test_resample)) + || (NULL + == CU_add_test(pSuite, "test of mysofa_loudness", + test_loudness)) + || (NULL + == CU_add_test(pSuite, "test of mysofa_minphase", + test_minphase)) + || (NULL == CU_add_test(pSuite, "test of mysofa_cache", test_cache)) + || (NULL == CU_add_test(pSuite, "test of mysofa_easy", test_easy))) { CU_cleanup_registry(); return CU_get_error(); } diff -Nru libmysofa-0.6~dfsg0/src/tests/internal.c libmysofa-0.7~dfsg0/src/tests/internal.c --- libmysofa-0.6~dfsg0/src/tests/internal.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/internal.c 2019-03-31 15:16:24.000000000 +0000 @@ -7,7 +7,7 @@ int main() { int err; - + CU_pSuite pSuite = NULL; /* initialize the CUnit test registry */ @@ -24,8 +24,7 @@ /* add the tests to the suite */ /* NOTE - ORDER IS IMPORTANT - MUST TEST fread() AFTER fprintf() */ if ((NULL == CU_add_test(pSuite, "test of coordinates", test_coordinates)) - || (NULL == CU_add_test(pSuite, "test of nsearch", test_nsearch)) - ) { + || (NULL == CU_add_test(pSuite, "test of nsearch", test_nsearch))) { CU_cleanup_registry(); return CU_get_error(); } diff -Nru libmysofa-0.6~dfsg0/src/tests/interpolate.c libmysofa-0.7~dfsg0/src/tests/interpolate.c --- libmysofa-0.6~dfsg0/src/tests/interpolate.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/interpolate.c 2019-03-31 15:16:24.000000000 +0000 @@ -15,8 +15,7 @@ int neighborhood[6] = { -1, -1, -1, -1, -1, -1 }; float c[3]; - hrtf = mysofa_load("share/MIT_KEMAR_normal_pinna.sofa", - &err); + hrtf = mysofa_load("share/MIT_KEMAR_normal_pinna.sofa", &err); if (!hrtf) { CU_FAIL_FATAL("Error reading file."); @@ -28,17 +27,17 @@ fir = malloc(hrtf->N * hrtf->R * sizeof(float)); res = mysofa_interpolate(hrtf, hrtf->SourcePosition.values, 0, neighborhood, - fir, delays); + fir, delays); CU_ASSERT(res == hrtf->DataIR.values); CU_ASSERT(delays[0] == 0); CU_ASSERT(delays[1] == 0); c[0] = (hrtf->SourcePosition.values[0] + hrtf->SourcePosition.values[3]) - / 2; + / 2; c[1] = (hrtf->SourcePosition.values[1] + hrtf->SourcePosition.values[4]) - / 2; + / 2; c[2] = (hrtf->SourcePosition.values[2] + hrtf->SourcePosition.values[5]) - / 2; + / 2; neighborhood[0] = 1; res = mysofa_interpolate(hrtf, c, 0, neighborhood, fir, delays); @@ -49,9 +48,13 @@ for (i = 0; i < hrtf->N * hrtf->R; i++) { #ifdef VDEBUG printf("%f %f %f\n", res[i], hrtf->DataIR.values[i], - hrtf->DataIR.values[i + hrtf->N * hrtf->R]); + hrtf->DataIR.values[i + hrtf->N * hrtf->R]); #endif - CU_ASSERT(fequals(res[i],(hrtf->DataIR.values[i]+hrtf->DataIR.values[i+hrtf->N*hrtf->R])/2)); + CU_ASSERT( + fequals(res[i], + (hrtf->DataIR.values[i] + + hrtf->DataIR.values[i + hrtf->N * hrtf->R]) + / 2)); } /* TODO add some tests... */ diff -Nru libmysofa-0.6~dfsg0/src/tests/json.c libmysofa-0.7~dfsg0/src/tests/json.c --- libmysofa-0.6~dfsg0/src/tests/json.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/json.c 2019-03-31 15:16:24.000000000 +0000 @@ -50,7 +50,7 @@ } static void printAttributes(FILE *out, int spaces, - struct MYSOFA_ATTRIBUTE *attr) { + struct MYSOFA_ATTRIBUTE *attr) { int i; for (i = 0; i < spaces; i++) @@ -71,18 +71,18 @@ } /* - "Dimensions":[ - 1, - 2 - ], - "DimensionNames":[ - "I", - "R" - ], -*/ + "Dimensions":[ + 1, + 2 + ], + "DimensionNames":[ + "I", + "R" + ], + */ static void printDimensions(FILE *out, struct MYSOFA_HRTF *hrtf, - struct MYSOFA_ATTRIBUTE **p) { + struct MYSOFA_ATTRIBUTE **p) { struct MYSOFA_ATTRIBUTE *found = NULL; char *s; int dimensions[4]; @@ -147,7 +147,7 @@ } static int printArray(FILE *out, struct MYSOFA_HRTF *hrtf, - struct MYSOFA_ARRAY *array, char *name) { + struct MYSOFA_ARRAY *array, char *name) { int i = 0; if (!array->elements) @@ -169,7 +169,7 @@ fprintf(out, " \"Values\": ["); for (i = 0; i < array->elements; i++) { fprintf(out, "%c%s%.6f", i == 0 ? ' ' : ',', - i % 20 == 19 ? "\n " : "", array->values[i]); + i % 20 == 19 ? "\n " : "", array->values[i]); } fprintf(out, " ]\n }"); diff -Nru libmysofa-0.6~dfsg0/src/tests/json.h libmysofa-0.7~dfsg0/src/tests/json.h --- libmysofa-0.6~dfsg0/src/tests/json.h 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/json.h 2019-03-31 15:16:24.000000000 +0000 @@ -1,2 +1 @@ - void printJson(FILE *out, struct MYSOFA_HRTF *hrtf); diff -Nru libmysofa-0.6~dfsg0/src/tests/lookup.c libmysofa-0.7~dfsg0/src/tests/lookup.c --- libmysofa-0.6~dfsg0/src/tests/lookup.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/lookup.c 2019-03-31 15:16:24.000000000 +0000 @@ -20,7 +20,7 @@ #ifdef HAVE_GETTIMEOFDAY struct timeval r1, r2; #endif - float duration1=0.f, duration2=0.f; + float duration1 = 0.f, duration2 = 0.f; float find[3]; int j; struct MYSOFA_LOOKUP *lookup; @@ -48,7 +48,7 @@ for (j = 0; j < 10000; j++) { int index = -1; float dmin = FLT_MAX; - int i,lk; + int i, lk; find[0] = rand() * (4. / RAND_MAX) - 2; find[1] = rand() * (4. / RAND_MAX) - 2; @@ -61,11 +61,11 @@ #ifdef HAVE_GETTIMEOFDAY gettimeofday(&r2, NULL); duration1 = (r2.tv_sec - r1.tv_sec) * 1000000. - + (r2.tv_usec - r1.tv_usec); + + (r2.tv_usec - r1.tv_usec); gettimeofday(&r1, NULL); #endif - for (i = 0; i < hrtf->M; i ++) { + for (i = 0; i < hrtf->M; i++) { float r = distance(find, hrtf->SourcePosition.values + i * hrtf->C); if (r < dmin) { dmin = r; @@ -75,15 +75,16 @@ #ifdef HAVE_GETTIMEOFDAY gettimeofday(&r2, NULL); duration2 = (r2.tv_sec - r1.tv_sec) * 1000000. - + (r2.tv_usec - r1.tv_usec); + + (r2.tv_usec - r1.tv_usec); #endif - CU_ASSERT(lk==index); - if(lk!=index) { - printf("O(log n) %f %f %f -> %d %f \t\t", find[0], find[1], find[2], lk, - distance(find, hrtf->SourcePosition.values + lk * hrtf->C)); + CU_ASSERT(lk == index); + if (lk != index) { + printf("O(log n) %f %f %f -> %d %f \t\t", find[0], find[1], find[2], + lk, + distance(find, hrtf->SourcePosition.values + lk * hrtf->C)); printf("O(n): %f %f %f -> %d %f\t%f%%\n", find[0], find[1], find[2], - index, dmin, duration1 / duration2 * 100); + index, dmin, duration1 / duration2 * 100); } } diff -Nru libmysofa-0.6~dfsg0/src/tests/loudness.c libmysofa-0.7~dfsg0/src/tests/loudness.c --- libmysofa-0.6~dfsg0/src/tests/loudness.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/loudness.c 2019-03-31 15:16:24.000000000 +0000 @@ -22,13 +22,10 @@ #ifdef VDEBUG printf("loudness of Pulse.sofa %f\n", factor); #endif - CU_ASSERT(fequals(factor,1)); + CU_ASSERT(fequals(factor, 1)); mysofa_free(hrtf); - - - hrtf = mysofa_load("share/MIT_KEMAR_normal_pinna.sofa", - &err); + hrtf = mysofa_load("share/MIT_KEMAR_normal_pinna.sofa", &err); if (!hrtf) { CU_FAIL_FATAL("Error reading file."); } @@ -37,15 +34,15 @@ #ifdef VDEBUG printf("loudness of MIT_KEMAR_normal_pinna.sofa %f\n", factor); #endif - CU_ASSERT(fequals(factor,1.116589)); + CU_ASSERT(fequals(factor, 1.116589)); factor = mysofa_loudness(hrtf); #ifdef VDEBUG printf( - "loudness of MIT_KEMAR_normal_pinna.sofa after normalization %f\n", - factor); + "loudness of MIT_KEMAR_normal_pinna.sofa after normalization %f\n", + factor); #endif - CU_ASSERT(fequals(factor,1.)); + CU_ASSERT(fequals(factor, 1.)); mysofa_free(hrtf); } diff -Nru libmysofa-0.6~dfsg0/src/tests/minphase.c libmysofa-0.7~dfsg0/src/tests/minphase.c --- libmysofa-0.6~dfsg0/src/tests/minphase.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/minphase.c 2019-03-31 15:16:24.000000000 +0000 @@ -22,15 +22,12 @@ #ifdef VDEBUG printf("max length %d\n", len); #endif - CU_ASSERT(len==1); - for(i=0;iDataIR.elements;i++) - CU_ASSERT(fequals(hrtf->DataIR.values[i],1)); + CU_ASSERT(len == 1); + for (i = 0; i < hrtf->DataIR.elements; i++) + CU_ASSERT(fequals(hrtf->DataIR.values[i], 1)); mysofa_free(hrtf); - - - hrtf = mysofa_load("share/MIT_KEMAR_normal_pinna.sofa", - &err); + hrtf = mysofa_load("share/MIT_KEMAR_normal_pinna.sofa", &err); if (!hrtf) { CU_FAIL_FATAL("Error reading file."); } @@ -39,11 +36,10 @@ #ifdef VDEBUG printf("max length %d\n", len); #endif - CU_ASSERT(len==361); + CU_ASSERT(len == 361); mysofa_free(hrtf); - hrtf = mysofa_load("share/MIT_KEMAR_normal_pinna.sofa", - &err); + hrtf = mysofa_load("share/MIT_KEMAR_normal_pinna.sofa", &err); if (!hrtf) { CU_FAIL_FATAL("Error reading file."); } @@ -52,13 +48,10 @@ #ifdef VDEBUG printf("max length %d\n", len); #endif - CU_ASSERT(len==463); + CU_ASSERT(len == 463); mysofa_free(hrtf); - - - hrtf = mysofa_load("share/MIT_KEMAR_normal_pinna.sofa", - &err); + hrtf = mysofa_load("share/MIT_KEMAR_normal_pinna.sofa", &err); if (!hrtf) { CU_FAIL_FATAL("Error reading file."); } @@ -69,7 +62,7 @@ #ifdef VDEBUG printf("max length %d\n", len); #endif - CU_ASSERT(len==70 || len==71); + CU_ASSERT(len == 70 || len == 71); mysofa_free(hrtf); } diff -Nru libmysofa-0.6~dfsg0/src/tests/neighbors.c libmysofa-0.7~dfsg0/src/tests/neighbors.c --- libmysofa-0.6~dfsg0/src/tests/neighbors.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/neighbors.c 2019-03-31 15:16:24.000000000 +0000 @@ -12,13 +12,12 @@ struct MYSOFA_LOOKUP *lookup; struct MYSOFA_NEIGHBORHOOD *neighborhood; int i, j, *res; - float c[3],C[3]; + float c[3], C[3]; #ifdef VDEBUG const char *dir = "RLUDFB"; #endif - hrtf = mysofa_load("share/MIT_KEMAR_normal_pinna.sofa", - &err); + hrtf = mysofa_load("share/MIT_KEMAR_normal_pinna.sofa", &err); if (!hrtf) { CU_FAIL_FATAL("Error reading file."); return; @@ -33,8 +32,7 @@ return; } - neighborhood = mysofa_neighborhood_init(hrtf, - lookup); + neighborhood = mysofa_neighborhood_init(hrtf, lookup); if (neighborhood == NULL) { CU_FAIL("Error getting neighborhood."); @@ -43,33 +41,36 @@ return; } - for (i = 0; i < hrtf->M; i ++) { - memcpy(c, hrtf->SourcePosition.values + i * hrtf->C, sizeof(float) * hrtf->C); + for (i = 0; i < hrtf->M; i++) { + memcpy(c, hrtf->SourcePosition.values + i * hrtf->C, + sizeof(float) * hrtf->C); mysofa_c2s(c); #ifdef VDEBUG printf("%4.0f %4.0f %5.2f\t", c[0], c[1], c[2]); #endif res = mysofa_neighborhood(neighborhood, i); - CU_ASSERT(res!=NULL); + CU_ASSERT(res != NULL); for (j = 0; j < 6; j++) { if (res[j] >= 0) { memcpy(C, hrtf->SourcePosition.values + res[j] * hrtf->C, - sizeof(float) * hrtf->C); + sizeof(float) * hrtf->C); mysofa_c2s(C); #ifdef VDEBUG printf("\t%c %4.0f %4.0f %5.2f", dir[j], C[0], C[1], C[2]); #endif - switch(j) { + switch (j) { case 0: - if(C[0] C[0]); + if (C[0] < c[0]) + C[0] += 360; + CU_ASSERT_FATAL(c[0] < C[0] && c[0] + 45 > C[0]); break; case 1: - if(C[0]>c[0]) C[0]-=360; - CU_ASSERT_FATAL(c[0] > C[0] && c[0]-45 < C[0]); + if (C[0] > c[0]) + C[0] -= 360; + CU_ASSERT_FATAL(c[0] > C[0] && c[0] - 45 < C[0]); break; case 2: - CU_ASSERT_FATAL(c[1] < C[1] || fequals(c[1],90.f)); + CU_ASSERT_FATAL(c[1] < C[1] || fequals(c[1], 90.f)); break; case 3: CU_ASSERT_FATAL(c[1] > C[1]); diff -Nru libmysofa-0.6~dfsg0/src/tests/resample.c libmysofa-0.7~dfsg0/src/tests/resample.c --- libmysofa-0.6~dfsg0/src/tests/resample.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/resample.c 2019-03-31 15:16:24.000000000 +0000 @@ -18,15 +18,15 @@ return; } - backup = malloc(sizeof(float)*hrtf->N * 3); - if(!backup) { + backup = malloc(sizeof(float) * hrtf->N * 3); + if (!backup) { CU_FAIL_FATAL("No memory, N is too large."); mysofa_free(hrtf); return; } for (i = 0; i < hrtf->N * 3; i++) { - backup[i]=hrtf->DataIR.values[i]; + backup[i] = hrtf->DataIR.values[i]; } err = mysofa_resample(hrtf, 96000.); @@ -36,10 +36,11 @@ #ifdef VDEBUG printf("%6.3f~%6.3f ", hrtf->DataIR.values[i], backup[i/2]); if ((i % hrtf->N) == (hrtf->N - 1)) - printf("\n"); + printf("\n"); #endif - CU_ASSERT( !((hrtf->DataIR.values[i]>0.4 && backup[i/2]==0.) || - (hrtf->DataIR.values[i]<=0.3 && backup[i/2]==1.) ) ); + CU_ASSERT( + !((hrtf->DataIR.values[i] > 0.4 && backup[i / 2] == 0.) + || (hrtf->DataIR.values[i] <= 0.3 && backup[i / 2] == 1.))); } free(backup); diff -Nru libmysofa-0.6~dfsg0/src/tests/sofa2json.c libmysofa-0.7~dfsg0/src/tests/sofa2json.c --- libmysofa-0.6~dfsg0/src/tests/sofa2json.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/sofa2json.c 2019-03-31 15:16:24.000000000 +0000 @@ -1,8 +1,8 @@ /* - Copyright 2016 Christian Hoene, Symonics GmbH + Copyright 2016 Christian Hoene, Symonics GmbH -*/ + */ #include #include @@ -25,11 +25,11 @@ if (!hrtf) { fprintf(stderr, "Error reading file %s. Error code: %d\n", argv[1], - err); + err); return err; } - printJson(stdout,hrtf); + printJson(stdout, hrtf); mysofa_free(hrtf); diff -Nru libmysofa-0.6~dfsg0/src/tests/tools.c libmysofa-0.7~dfsg0/src/tests/tools.c --- libmysofa-0.6~dfsg0/src/tests/tools.c 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/src/tests/tools.c 2019-03-31 15:16:24.000000000 +0000 @@ -86,34 +86,34 @@ CU_ASSERT(cmp(array + 1, array) > 0); key = 10; - nsearch(&key, (char*)array, 5, sizeof(int), cmp, &l, &h); + nsearch(&key, (char*) array, 5, sizeof(int), cmp, &l, &h); CU_ASSERT(l == 0 && h == 0); key = 20; - nsearch(&key, (char*)array, 5, sizeof(int), cmp, &l, &h); + nsearch(&key, (char*) array, 5, sizeof(int), cmp, &l, &h); CU_ASSERT(l == 1 && h == 1); key = 50; - nsearch(&key, (char*)array, 5, sizeof(int), cmp, &l, &h); + nsearch(&key, (char*) array, 5, sizeof(int), cmp, &l, &h); CU_ASSERT(l == 4 && h == 4); key = 0; - nsearch(&key, (char*)array, 5, sizeof(int), cmp, &l, &h); + nsearch(&key, (char*) array, 5, sizeof(int), cmp, &l, &h); CU_ASSERT(l < 0 && h == 0); key = 60; - nsearch(&key, (char*)array, 5, sizeof(int), cmp, &l, &h); + nsearch(&key, (char*) array, 5, sizeof(int), cmp, &l, &h); CU_ASSERT(l == 4 && h < 0); key = 11; - nsearch(&key, (char*)array, 5, sizeof(int), cmp, &l, &h); + nsearch(&key, (char*) array, 5, sizeof(int), cmp, &l, &h); CU_ASSERT(l == 0 && h == 1); key = 41; - nsearch(&key, (char*)array, 5, sizeof(int), cmp, &l, &h); + nsearch(&key, (char*) array, 5, sizeof(int), cmp, &l, &h); CU_ASSERT(l == 3 && h == 4); key = 19; - nsearch(&key, (char*)array, 5, sizeof(int), cmp, &l, &h); + nsearch(&key, (char*) array, 5, sizeof(int), cmp, &l, &h); CU_ASSERT(l == 0 && h == 1); } Binary files /tmp/tmpXrcr1l/csdsovbMWU/libmysofa-0.6~dfsg0/symonics-mysofa.png and /tmp/tmpXrcr1l/Z7srENCQpt/libmysofa-0.7~dfsg0/symonics-mysofa.png differ diff -Nru libmysofa-0.6~dfsg0/tests/compare.sh libmysofa-0.7~dfsg0/tests/compare.sh --- libmysofa-0.6~dfsg0/tests/compare.sh 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/tests/compare.sh 2019-03-31 15:16:24.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh NODEJS=`which node || which nodejs || which false` ../build/src/mysofa2json "$1".sofa >tmp1.json 2>tmp1.txt diff -Nru libmysofa-0.6~dfsg0/tests/tester2.m libmysofa-0.7~dfsg0/tests/tester2.m --- libmysofa-0.6~dfsg0/tests/tester2.m 1970-01-01 00:00:00.000000000 +0000 +++ libmysofa-0.7~dfsg0/tests/tester2.m 2019-03-31 15:16:24.000000000 +0000 @@ -0,0 +1,14 @@ +hrtf.Data.Delay = zeros(size(hrtf.SourcePosition,1), 2); +hrtf = SOFAupdateDimensions(hrtf); + +L = size(hrtf.Data.IR,3); + +for n=1:size(hrtf.SourcePosition,1) + hrtf.Data.IR(n,1,:) = n + [1:L]; + hrtf.Data.IR(n,2,:) = n - [1:L]; + + hrtf.Data.Delay(n,1) = n-1; + hrtf.Data.Delay(n,2) = -(n-1); +end + + \ No newline at end of file Binary files /tmp/tmpXrcr1l/csdsovbMWU/libmysofa-0.6~dfsg0/tests/tester2.sofa and /tmp/tmpXrcr1l/Z7srENCQpt/libmysofa-0.7~dfsg0/tests/tester2.sofa differ diff -Nru libmysofa-0.6~dfsg0/tests/tester2.txt libmysofa-0.7~dfsg0/tests/tester2.txt --- libmysofa-0.6~dfsg0/tests/tester2.txt 1970-01-01 00:00:00.000000000 +0000 +++ libmysofa-0.7~dfsg0/tests/tester2.txt 2019-03-31 15:16:24.000000000 +0000 @@ -0,0 +1,9 @@ +To generate the tester2.sofa file, open Matlab and enter + +SOFAstart; +hrtf = SOFAload('/home/hoene/git/libmysofa/tests/sofa_api_mo_test/Pulse.sofa'); +tester2; +SOFAsave('/tmp/tester2.sofa',hrtf,9); + +You need API_MO for this. + diff -Nru libmysofa-0.6~dfsg0/.travis.yml libmysofa-0.7~dfsg0/.travis.yml --- libmysofa-0.6~dfsg0/.travis.yml 2017-07-11 11:36:33.000000000 +0000 +++ libmysofa-0.7~dfsg0/.travis.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -matrix: - include: - - os: linux - dist: trusty - sudo: required - - os: osx - osx_image: xcode7.3 - -language: c - -before_install: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y libcunit1-dev ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install cunit ; fi - -before_script: - - mkdir -p build - - cd build - - cmake -DCMAKE_BUILD_TYPE=Debug .. - -script: - - pwd - - make all test - -env: - global: - - secure: "4/u+9HdF0FZsQrZ50J+65MtmjdE3iNH1f0p4iY1zapihg03qVJ5S7hNDG1Suhvmk4YJ+WRxR1rimMlErL8Du72r4AfPoxmqnpuBSJJfLn3zYPTSx/jKSdRRKA9sWwaV+Fl+yIKvIn0eLmXBjY7KHtZufvNGEY7vV7rQoDPxiDhj5lDKz91wobMLA3Tw8YcpnvpyNgEkcIkBso6xKyTk/wJMhkZ9OmZFfv1FYHs373pluXH02NIpQqwIeLwG4hXzkkGHfuJvl/iVt72hBXQM02A9woNbst3pm0mg+CPJJpyhCd6Rk4zS/IW/1/Uh2JM/T0Lt/F0Nm0RhN8BCh6/YzETmYIak4lgR2DE/XvW7ban/5JGP7zgol0rFKIszEvieCTuHvqteY/h+xVMUDsmICFCDHBHVgJUgVAMN2aaRAthQ0/LWkYcuiRdZZvzzXpggPOHnPnB1TBPH0l1SNXnutv2TGP5z6P1WoZWv/YHD/CpQD4NB+jIw8vP5PDIrG5o9YMAwX1G5rVrxyowSFzx1PwNr+lDKPsysGKzlzpsev5wxd5lcwRGq9AtcBkAU2Lueq+9DMXRsSNLNkpzcblD6z8beuA81l64Qy/NNAUwNloauJXoeXm8pJmN3/KQB25RK2/7ej2SwCF0RwcWhPtso6rML1uEdB/aXJ4CvWjdc95hI=" - -addons: - coverity_scan: - project: - name: "hoene/libmysofa" - description: "Build submitted via Travis CI" - notification_email: christian.hoene@symonics.com - build_command: make all - branch_pattern: coverity -