pax_global_header 0000666 0000000 0000000 00000000064 14424151631 0014513 g ustar 00root root 0000000 0000000 52 comment=7cc4cdbf575571d3b8581b183bea4591861e99fb
libad9361-iio-0.3/ 0000775 0000000 0000000 00000000000 14424151631 0013531 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/.github/ 0000775 0000000 0000000 00000000000 14424151631 0015071 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/.github/workflows/ 0000775 0000000 0000000 00000000000 14424151631 0017126 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/.github/workflows/doc.yml 0000664 0000000 0000000 00000003414 14424151631 0020420 0 ustar 00root root 0000000 0000000 name: Documentation Build and Deploy
on: [push, pull_request]
jobs:
BuildDocs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.7
uses: actions/setup-python@v2
with:
python-version: 3.7
- name: Install dependencies
run: |
wget https://raw.githubusercontent.com/analogdevicesinc/pyadi-iio/master/.github/scripts/install_libiio.sh
bash install_libiio.sh
sudo apt-get install -y python3-pip python3-setuptools doxygen graphviz
sudo pip install -r bindings/python/requirements.txt
sudo pip install -r bindings/python/requirements_dev.txt
sudo pip install -r bindings/python/requirements_doc.txt
- name: Build all components
run: |
mkdir build
cd build
cmake .. -DPYTHON_BINDINGS=OFF
make -j$(nproc)
sudo make install
cmake .. -DPYTHON_BINDINGS=ON
make -j$(nproc)
make
mkdir all_doc
mkdir all_doc/python
mv bindings/python/html/* all_doc/python
mv html/* all_doc/
cd ..
# If on master deploy to gh-pages within dev folder
- name: Deploy development build to GitHub Pages
if: github.ref == 'refs/heads/master'
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: .build/all_doc
destination_dir: dev
# If on a release deploy to gh-pages top-level
- name: Deploy release to GitHub Pages
if: startsWith(github.ref, 'refs/tags/')
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: .build/all_doc
libad9361-iio-0.3/.gitignore 0000664 0000000 0000000 00000000236 14424151631 0015522 0 ustar 00root root 0000000 0000000 *.swp
CPackConfig.cmake
CPackSourceConfig.cmake
CMakeCache.txt
CMakeFiles
Makefile
cmake_install.cmake
install_manifest.txt
libad9361.pc
libad9361.so*
build/
libad9361-iio-0.3/.travis.yml 0000664 0000000 0000000 00000015646 14424151631 0015656 0 ustar 00root root 0000000 0000000 language: c
sudo: required
env:
global:
- EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss
# SSHHOST
- secure: "Izx3rvvdDSlv26z0OLsyHj6uN5YoOz/Deg0bLx8IHRqPcRULJlQLqXOaeX41DmsltFq1X8AbVW2TmqzaLHnsGfM76IyqIWVLANC0TcevKyonDujkiuWoFDrYciKJyLS2aN4SgnG4jyp9977Z0Vc5EL9D61QDlh3LUU+x3+CYxQIWWpMoOsfyZUw8FU/b/KmjqE7zvtgN/RMAeuDIn7jLP9Yg9pFB8KnOFyWHSfT5cXux4WSYqwQasYf68+3JyuJSebS3kK/FgCJOODMs+xed9BjeP8QinhmXFdy+epIFXLARUKZrLzj9+94PZ8n0m0TV39yqFfk96qRjM4bJNwCqfUU6iaSsuLNlSU2HbQeqSDW//BsXFL3EicM+7xgYnx/luboLQZgqJYQAPk3ihaH456Gl9PNF6h4zv8vXsHE+nHDZvubwsgNdTk25YP+3GglQZdRHBhsdBSASGYc0CxYwPHsBi4/QD0RQ2k0W4D1dwJXXRXxTqoSfveP8QIsQVfDwfAhWLG9QMjVwp1dMl+5wIp25E4v1C2I2rQJVuc7pjPb/av34ltWBlQwcXkxUl3/E3qDrO4b5gS/UD47bRCCqYf9GLniXVBm7z+ebA7tW4G/q/RJvb3G7q59nAJXSwJOvB5Kt3pnfeCmfgv6wGeeNizQer+AjHkQy1uNQBBSI8Jw="
# SSHUSER
- secure: "qNOraig2HbEH9MfIzwiXTZ9+DIKN1RpXaIEurkGFr96UNeeNPqsyPBtzHqXJvXRtq0Wta5S5VI3t8dWe4kqfkYhctYqFJ0lHWRanYd+NXBSHqFWndU3Q+wy5p7NZ4st/jFaHyiVPkpTGv5T8IPsCahgaCt3wYVLloSrTytBXc9iSn3T71JhFBj47zqEa+E8MSNZlNaqh7BnxI6lVhpMrgft7dOIaByFkieeqFFsOKU4D79/XwCcpo66pmIo5OenfRHCtmp2xYMHXbUrKGDaZMhnoc9VBDsaHsMFiyEKWukHwxmFjt2k60AqkqT8BuBf2uyT/20/JQw4W9iDwedPmhz3mHmHh6cc2EMwrBrD3sIpnMuxabrUwfuwfTFgWHd7IkEw9WGwM1DMsWlxxi5u8fF2xMA+4KYcuZIkHPjl5nQ+RQhd0Y9N/+HrVrf88z0cw9lIlobf0MuZvPfxLv2hJbHaNZsOet5d1W9DsZWS0+V6BxNRjEpJci5xKZpgPaEyY+p+kKz/Q11PW+A1VGSVs+aRUHJb0tPm/MrySF8D3uClHKiadFy1mwvvOHUyHuOtiTbb0LGbnEoyySTjLDwsSJ2ybhbqPCbnFNclDWX7Jv20dpY9ZuWVdt/Z4PCmk7/vKw6eyfI0xsGBQQJcizKICQei+Zh8UeHCdU1GOMFiy26Y="
# DEPLOY_TO directory
- secure: "KejjF6Zyhd37TCFfn08Htco7LYkKc+yEwMzgSEUF6kjeoMe0VYlNCDqlAvQRdGXONZg7cz83h298gJfbvDkKdMm32e73NPfXcCdQBWTuWYx8xzM63WuKrYjM+oFyAxJ2hgOOaK14ctSQtAcnpaZRm12aIpbeRgwpe2oZEBOwwYi4TdwMvrG7WyxhZniqfFQYYjT/8xAgzkmREAJRxp/PBp1+Xe2vkTHZUMHxOM3JAiganSfvgnPA7imY/wu5si9qcwNw0bo+0ISDNXk3mV9p5dlB5Cudjfme8kMjYjqUrBcQ9p0heODZXRCfwC+kdsg4oLAYdDB5nOvPX3b18liWl6ZZ/qaiaq6eLro9IgJgrALFBpElr6oVlMaAil8yKIokM9Pfga1MhdZLLZEuziK2B1T34IS7/5PEy/l9+9cFezpCj0e2Mdpa6FbcrjyX1uPK/U2Hy9tKdVzuLPBS4bQgrKah+Xc2ml3EU+SEhz3UGSi2d+9GZQ0G2n1sVcawVOyzcdqHO6Y53WQ2/UVwJ9TsnLPTWUHLplGgRmAXbTtEhQDDYeffwVd7nZfTQlEug00DlrSoJoSHra6s7oEYLC2lrJoyH82/nkjvCupqxZM9D1V82sUsYAgC4KVzZNg0VROycbBefpgIrvw01eSakay1vOVNsrxptcNXjK9/wiuFbOI="
services:
- docker
matrix:
include:
- stage: "Build & Deploy"
compiler: "clang"
os: linux
env: LDIST=DO_NOT_DEPLOY
- compiler: "gcc"
os: linux
dist: xenial
- os: linux
env:
- OS_TYPE=centos_docker
- OS_VERSION=6
- os: linux
env:
- OS_TYPE=centos_docker
- OS_VERSION=7
- os: linux
env:
- OS_TYPE=centos_docker
- OS_VERSION=8
- os: linux
dist: bionic
- os: linux
dist: focal
- compiler: "gcc"
os: osx
osx_image: xcode10.1
- compiler: "gcc"
os: osx
osx_image: xcode11
- stage: "Trigger Next In Pipeline"
env:
- TRIGGER_NEXT_BUILD=true
addons:
artifacts: true
ssh_known_hosts:
secure: "HzU57pX/0iwRgPCnrP7QQ92XkrySsx/jjCLEqNAyWuQBYTMl2vVXnys7dclUp841CWRHv3TQXT0Jem9mZ9oZbzMR8Nxo2mjJyiH06BMcBYmTiaGxzSOh0XjiYTm3ZZvH+SQYdiXNBbPIY7B1ekC6Vw/ZQ8N4U1SiMh5W38+jXgqTYefB2h8GjmYB8f3DP0WE97ITaLG0/dUF+vLkuyJaLHND2j0e+cjjir8ah8eioK67+iX1dnDnN4U6su7tdVcqHGdgS3sSjvFl8+q9R9IFuT2RuQLd05Fu5gehV5ruJP0GzjJ8eU1fhkFSiWPenBGgkDRsv7ORmtL9ZmZKjtXIxhIlgVBdH8Rb9qtDCbKf6tSSrOU14TkN1FR8uPw68xhlnptS31AwB+OisWw1ULRJBEWRTABw+avUloDhgFMgUtFnSukjMlst16Qwq5bGKn5yQ6KBJU8BP/uX6ptGQemTokEe92TWJq6TS6kNpb8rA537gaMp8VQ2zk8Nhw6LovA5LbuKB73rcjuQsOto2/DF2GhJkBQ0peVzu1vsAFD5WmMTPzQziTLiTyI+gQktYJSoV8ERAvxqeDptqUYMrRMg7VtuV5fNEQ2Q5fVMrcqB9NGkeUjfIo7GHP0tBEzLCNjaRNYrMxEqKYW8OQSfINA3b3gLZuwLepHW71j2xqnFlpQ="
before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./CI/travis/before_install_darwin ; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./CI/travis/before_install_linux "$OS_TYPE" "$OS_VERSION" ; fi
- mkdir -p $TRAVIS_BUILD_DIR/build
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mkdir -p $TRAVIS_BUILD_DIR/build_tar ; fi
script:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ${TRAVIS_BUILD_DIR}/CI/travis/make_linux libad9361-iio "$OS_TYPE" "$OS_VERSION" ; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ${TRAVIS_BUILD_DIR}/CI/travis/make_darwin; fi
- if [[ "$TRIGGER_NEXT_BUILD" == "true" ]]; then ${TRAVIS_BUILD_DIR}/CI/travis/after_deploy; fi
notifications:
email:
on_success: change
on_failure: always
before_deploy:
- . ${TRAVIS_BUILD_DIR}/CI/travis/before_deploy
- openssl aes-256-cbc -K $encrypted_ca7c55addc40_key -iv $encrypted_ca7c55addc40_iv -in ${TRAVIS_BUILD_DIR}/CI/travis/deploy.rsa.enc -out /tmp/deploy.rsa -d
- eval "$(ssh-agent -s)"
- chmod 600 /tmp/deploy.rsa
- ssh-add /tmp/deploy.rsa
deploy:
- provider: releases
api_key:
secure: "ocDkFUpRYim0o3kEzO5It8mTjg4FnVYT+KaXoUtZA6r9x6VZteSFvimELIV/WePGnNLOavlXPgRb+cXmJiYSkVkFqrrwRkHgYvTapjPn/LBh0xDQZi9SrvTj/ICW3tMu7Esxqa7P2snhLf7P4XkLMySxeooKe4BoV5Uy8WUy+IE0HCkCxaiokUFEg7UVVDLy5ahTyVcdV4su44E+URCBDTk+UvgKJ3VDjNVDZp8uea7RBRHVfSucb/12AeJr+PkaxrbsqtI+GHMohvmLVBmALkP+WtLLMklxPofEnBW/UV6iU+hvEd6dROqG9T52hDQpcBqdJlqx4C3mHkPpt7lxSFTcyyTKEqRKZA0sBexadMZ3fnS2gNXizstuDAxIuCowc+nOjk1WNAN8z4ADxk5t4ct8U1I7CTA0TgkTzkRizeelTTZCbt8kHwh4oTalBt/5rIg3Tk8+YgrwvuEIAmRwPIORob+xbYGK9GCKwmdfpSuVhcLsgb43eh96ZXQ2bBn30I3pebCMm9xa+1c8pStBlMYmJPJv0Y6m5uNUJAvOImWNoZlyA967Df8b3pbODqhFkUN3OgDyR3uYRxBCohZgmguOvHsqtkM66/QgIMy2vQxhcnzc78dMT/BfLJ13RuN6+9DiGUMuGCzsVgQ7MNQu8MAkUV+fiEdGz6yxskiwpAQ="
file:
- "${RELEASE_PKG_FILE_DEB}"
- "${RELEASE_PKG_FILE_RPM}"
- "${RELEASE_PKG_FILE_TGZ}"
skip_cleanup: true
on:
repo: analogdevicesinc/libad9361-iio
tags: true
condition: "($CC = gcc) && ($TRAVIS_OS_NAME = linux)"
- provider: releases
api_key:
secure: "ocDkFUpRYim0o3kEzO5It8mTjg4FnVYT+KaXoUtZA6r9x6VZteSFvimELIV/WePGnNLOavlXPgRb+cXmJiYSkVkFqrrwRkHgYvTapjPn/LBh0xDQZi9SrvTj/ICW3tMu7Esxqa7P2snhLf7P4XkLMySxeooKe4BoV5Uy8WUy+IE0HCkCxaiokUFEg7UVVDLy5ahTyVcdV4su44E+URCBDTk+UvgKJ3VDjNVDZp8uea7RBRHVfSucb/12AeJr+PkaxrbsqtI+GHMohvmLVBmALkP+WtLLMklxPofEnBW/UV6iU+hvEd6dROqG9T52hDQpcBqdJlqx4C3mHkPpt7lxSFTcyyTKEqRKZA0sBexadMZ3fnS2gNXizstuDAxIuCowc+nOjk1WNAN8z4ADxk5t4ct8U1I7CTA0TgkTzkRizeelTTZCbt8kHwh4oTalBt/5rIg3Tk8+YgrwvuEIAmRwPIORob+xbYGK9GCKwmdfpSuVhcLsgb43eh96ZXQ2bBn30I3pebCMm9xa+1c8pStBlMYmJPJv0Y6m5uNUJAvOImWNoZlyA967Df8b3pbODqhFkUN3OgDyR3uYRxBCohZgmguOvHsqtkM66/QgIMy2vQxhcnzc78dMT/BfLJ13RuN6+9DiGUMuGCzsVgQ7MNQu8MAkUV+fiEdGz6yxskiwpAQ="
file:
- "${RELEASE_PKG_FILE_PKG}"
- "${RELEASE_PKG_FILE_TGZ}"
skip_cleanup: true
on:
repo: analogdevicesinc/libad9361-iio
tags: true
condition: "$TRAVIS_OS_NAME = osx"
- provider: script
skip_cleanup: true
script:
- ${TRAVIS_BUILD_DIR}/CI/travis/deploy
on:
condition: "($CC = gcc) && ($TRAVIS_OS_NAME = linux)"
all_branches: true
- provider: script
skip_cleanup: true
script:
- ${TRAVIS_BUILD_DIR}/CI/travis/deploy
on:
condition: "$TRAVIS_OS_NAME = osx"
all_branches: true
libad9361-iio-0.3/CI/ 0000775 0000000 0000000 00000000000 14424151631 0014024 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/CI/build_win.ps1 0000664 0000000 0000000 00000000500 14424151631 0016420 0 ustar 00root root 0000000 0000000
$COMPILER=$Env:COMPILER
$ARCH=$Env:ARCH
$src_dir=$pwd
if (!(Test-Path build)) {
mkdir build
}
cd build
cmake -G "$COMPILER" -A "$ARCH" `
-DLIBIIO_LIBRARIES:FILEPATH=$pwd\libiio.lib `
-DLIBIIO_INCLUDEDIR:PATH=$pwd `
-DCMAKE_CONFIGURATION_TYPES=Release `
..
cmake --build . --config Release
libad9361-iio-0.3/CI/install_deps_win.ps1 0000664 0000000 0000000 00000000357 14424151631 0020014 0 ustar 00root root 0000000 0000000
# Note: InnoSetup is already installed on Azure images; so don't run this step
# Running choco seems a bit slow; seems to save about 40-60 seconds here
#choco install InnoSetup
set PATH=%PATH%;"C:\Program Files (x86)\Inno Setup 6"
libad9361-iio-0.3/CI/travis/ 0000775 0000000 0000000 00000000000 14424151631 0015334 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/CI/travis/before_install_darwin 0000775 0000000 0000000 00000000671 14424151631 0021622 0 ustar 00root root 0000000 0000000 #!/bin/sh -e
. CI/travis/lib.sh
brew_install_if_not_exists cmake doxygen libusb libxml2
if [ -n "$PACKAGE_TO_INSTALL" ] ; then
for file in $PACKAGE_TO_INSTALL ; do
sudo installer -pkg "${file}" -target /
done
elif [ "$INSTALL_FROM_SW_DOWNLOADS" = "1" ] ; then
wget http://swdownloads.analog.com/cse/travis_builds/${LIBIIO_BRANCH}_latest_libiio${LDIST}.pkg
sudo installer -pkg ${LIBIIO_BRANCH}_latest_libiio${LDIST}.pkg -target /
fi
libad9361-iio-0.3/CI/travis/before_install_linux 0000775 0000000 0000000 00000004542 14424151631 0021476 0 ustar 00root root 0000000 0000000 #!/bin/sh -e
. CI/travis/lib.sh
install_sphinx() {
$PYTHON --version
if ! is_python_at_least_ver "$PYTHON" "3.6" ; then
echo_red "Python version is too old no python interpreter installed"
return 1
fi
command -v $PYTHON
sudo $PYTHON -m pip install sphinx
sudo $PYTHON -m pip install sphinx-rtd-theme furo
}
handle_centos() {
# FIXME: see about adding `libserialport-dev` from EPEL ; maybe libusb-1.0.0-devel...
yum -y groupinstall 'Development Tools'
if is_centos_at_least_ver "8" ; then
# On CentOS 8, avahi-devel & doxygen are in this repo; enable it
yum -y install yum-utils
yum config-manager --set-enabled powertools
yum -y install python3
install_sphinx
else
yum -y install python3
install_sphinx
fi
# CMake has a bug when installed from repos. Must grab from kitware
yum -y install wget
wget https://github.com/Kitware/CMake/releases/download/v3.15.2/cmake-3.15.2.tar.gz
tar -zxvf cmake-3.15.2.tar.gz
cd cmake-3.15.2
./bootstrap
make
make install
cd ..
# Need libzstd from EPEL
yum -y install epel-release
yum -y install libzstd
yum -y install libxml2-devel libusb1-devel doxygen libaio-devel \
avahi-devel bzip2 gzip rpm rpm-build
if [ -n "$PACKAGE_TO_INSTALL" ] ; then
sudo yum localinstall -y $PACKAGE_TO_INSTALL
elif [ "$INSTALL_FROM_SW_DOWNLOADS" = "1" ] ; then
wget http://swdownloads.analog.com/cse/travis_builds/${LIBIIO_BRANCH}_latest_libiio${LDIST}.rpm
sudo yum localinstall -y ./${LIBIIO_BRANCH}_latest_libiio${LDIST}.rpm
fi
$PYTHON -m pip install pylibiio --no-binary :all:
}
handle_generic_docker() {
prepare_docker_image
}
handle_default() {
sudo apt-get -qq update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y cmake doxygen graphviz \
libaio-dev libavahi-client-dev libavahi-common-dev libusb-1.0-0-dev \
libxml2-dev rpm tar bzip2 gzip flex bison libserialport-dev \
python3 python3-pip python3-setuptools
if [ -n "$PACKAGE_TO_INSTALL" ] ; then
sudo dpkg -i $PACKAGE_TO_INSTALL
elif [ "$INSTALL_FROM_SW_DOWNLOADS" = "1" ] ; then
wget http://swdownloads.analog.com/cse/travis_builds/${LIBIIO_BRANCH}_latest_libiio${LDIST}.deb
sudo dpkg -i ./${LIBIIO_BRANCH}_latest_libiio${LDIST}.deb
fi
sudo $PYTHON -m pip install pylibiio --no-binary :all:
install_sphinx
}
handle_ubuntu() {
handle_default
}
handle_debian() {
handle_default
}
setup_build_type_env_vars
handle_${BUILD_TYPE}
libad9361-iio-0.3/CI/travis/ci-ubuntu.sh 0000664 0000000 0000000 00000001204 14424151631 0017600 0 ustar 00root root 0000000 0000000 #!/bin/bash
set -x
uname -a
DEBIAN_FRONTEND=noninteractive apt install -y make graphviz libaio-dev \
libavahi-client-dev libavahi-common-dev libusb-1.0-0-dev \
rpm tar bzip2 gzip libserialport-dev python3-pip
dpkg -i /ci/build/*.deb
python3 -m pip install pylibiio --no-binary :all:
python3 -m pip install sphinx
python3 -m pip install sphinx-rtd-theme furo
echo "$PWD"
mkdir -p build
cd build
cmake -DPYTHON_BINDINGS=ON -DENABLE_PACKAGING=ON -DDEB_DETECT_DEPENDENCIES=ON -DWITH_DOC=OFF ..
make && make package && make test
make install
ldconfig
cd ../bindings/python
pip3 install -r requirements_dev.txt
python3 -m pytest -vs --skip-scan
libad9361-iio-0.3/CI/travis/inside_docker.sh 0000664 0000000 0000000 00000001307 14424151631 0020473 0 ustar 00root root 0000000 0000000 #!/bin/sh -e
export INSIDE_DOCKER="1"
INSIDE_DOCKER_BUILD_DIR=/docker_build_dir
export TRAVIS_BUILD_DIR="$INSIDE_DOCKER_BUILD_DIR"
cd "$INSIDE_DOCKER_BUILD_DIR"
if [ -d "/$INSIDE_DOCKER_BUILD_DIR/CI" ] ; then
CI="/$INSIDE_DOCKER_BUILD_DIR/CI"
elif [ -d "/$INSIDE_DOCKER_BUILD_DIR/ci" ] ; then
CI="/$INSIDE_DOCKER_BUILD_DIR/ci"
else
echo "No CI/ci directory present"
exit 1
fi
if [ -f "$INSIDE_DOCKER_BUILD_DIR/inside-travis-ci-docker-env" ] ; then
. "$INSIDE_DOCKER_BUILD_DIR/inside-travis-ci-docker-env"
fi
"$CI/travis/before_install_linux"
"$CI/travis/make_linux"
# need to find this out inside the container
. "$CI/travis/lib.sh"
echo "$(get_ldist)" > "${INSIDE_DOCKER_BUILD_DIR}/build/.LDIST"
libad9361-iio-0.3/CI/travis/lib.sh 0000664 0000000 0000000 00000014134 14424151631 0016441 0 ustar 00root root 0000000 0000000 #!/bin/sh -e
export TRAVIS_API_URL="https://api.travis-ci.com"
LOCAL_BUILD_DIR=${LOCAL_BUILD_DIR:-build}
HOMEBREW_NO_INSTALL_CLEANUP=1
export HOMEBREW_NO_INSTALL_CLEANUP
LIBIIO_BRANCH=master
PYTHON=python3
export PYTHON
# This needs to be duplicated inside 'inside_docker.sh'
# It's the common convention between host & container
INSIDE_DOCKER_BUILD_DIR=/docker_build_dir
# Add here all the common env-vars that should be propagated
# to the docker image, simply by referencing the env-var name.
# The values will be evaluated.
#
# Make sure to not pass certain stuff that are specific to the host
# and not specific to inside-the-docker (like TRAVIS_BUILD_DIR)
#
# If these nothing should be passed, then clear or
#'unset INSIDE_DOCKER_TRAVIS_CI_ENV' after this script is included
INSIDE_DOCKER_TRAVIS_CI_ENV="TRAVIS TRAVIS_COMMIT TRAVIS_PULL_REQUEST OS_TYPE OS_VERSION ARTIFACTNAME PACKAGE_TO_INSTALL"
echo_red() { printf "\033[1;31m$*\033[m\n"; }
echo_green() { printf "\033[1;32m$*\033[m\n"; }
echo_blue() { printf "\033[1;34m$*\033[m\n"; }
get_script_path() {
local script="$1"
[ -n "$script" ] || return 1
if [ -f "CI/travis/$script" ] ; then
echo "CI/travis/$script"
elif [ -f "ci/travis/$script" ] ; then
echo "ci/travis/$script"
elif [ -f "${LOCAL_BUILD_DIR}/$script" ] ; then
echo "${LOCAL_BUILD_DIR}/$script"
else
return 1
fi
}
get_ldist() {
case "$(uname)" in
Linux*)
. /etc/os-release
if ! command_exists dpkg ; then
echo $ID-$VERSION_ID-$(uname -m)
else
echo $ID-$VERSION_ID-$(dpkg --print-architecture)
fi
;;
Darwin*)
echo "darwin-$(sw_vers -productVersion)"
;;
*)
echo "$(uname)-unknown"
;;
esac
return 0
}
__brew_install_if_not_exists() {
brew ls --versions "$1" || \
brew install "$1"
}
brew_install_if_not_exists() {
while [ -n "$1" ] ; do
__brew_install_if_not_exists "$1" || return 1
shift
done
}
prepare_docker_image() {
local DOCKER_IMAGE="${OS_TYPE}:${OS_VERSION}"
# If arch is specified, setup multiarch support
if [ -n "$OS_ARCH" ] ; then
sudo apt-get -qq update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y qemu \
qemu binfmt-support qemu-user-static
sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
DOCKER_IMAGE="${OS_ARCH}/${DOCKER_IMAGE}"
fi
echo 'DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock -s devicemapper"' | sudo tee /etc/default/docker > /dev/null
sudo service docker restart
sudo docker pull "$DOCKER_IMAGE"
}
__save_env_for_docker() {
local env_file="$1/inside-travis-ci-docker-env"
for env in $INSIDE_DOCKER_TRAVIS_CI_ENV ; do
val="$(eval echo "\$${env}")"
if [ -n "$val" ] ; then
echo "export ${env}=\"${val}\"" >> "${env_file}"
fi
done
}
run_docker_script() {
local DOCKER_SCRIPT="$(get_script_path "$1")"
local MOUNTPOINT="${INSIDE_DOCKER_BUILD_DIR}"
local DOCKER_IMAGE="${OS_TYPE}:${OS_VERSION}"
if [ -n "$OS_ARCH" ] ; then
DOCKER_IMAGE="${OS_ARCH}/${DOCKER_IMAGE}"
fi
__save_env_for_docker "$(pwd)"
sudo docker run --rm=true \
-v "$(pwd):/${MOUNTPOINT}:rw" \
"$DOCKER_IMAGE" \
/bin/bash -e "/${MOUNTPOINT}/${DOCKER_SCRIPT}" "${MOUNTPOINT}" "${OS_TYPE}"
}
command_exists() {
local cmd=$1
[ -n "$cmd" ] || return 1
type "$cmd" >/dev/null 2>&1
}
ensure_command_exists() {
local cmd="$1"
local package="$2"
local yes_confirm
[ -n "$cmd" ] || return 1
[ -n "$package" ] || package="$cmd"
! command_exists "$cmd" || return 0
# go through known package managers
for pacman in apt-get brew yum ; do
command_exists $pacman || continue
if [ "$pacman" = "brew" ] ; then
yes_confirm=
else
yes_confirm="-y"
fi
"$pacman" install $yes_confirm "$package" || {
# Try an update if install doesn't work the first time
"$pacman" $yes_confirm update && \
"$pacman" install $yes_confirm "$package"
}
return $?
done
return 1
}
version_gt() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"; }
version_le() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" = "$1"; }
version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; }
version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" = "$1"; }
get_codename() {
local VERSION_CODENAME
eval $(grep -w VERSION_CODENAME /etc/os-release)
echo "$VERSION_CODENAME"
}
get_dist_id() {
local ID
eval $(grep -w ID /etc/os-release)
echo "$ID"
}
get_version() {
local VERSION_ID
eval $(grep -w VERSION_ID /etc/os-release)
echo "$VERSION_ID"
}
is_ubuntu_at_least_ver() {
[ "$(get_dist_id)" = "ubuntu" ] || return 1
version_ge "$(get_version)" "$1"
}
is_centos_at_least_ver() {
[ "$(get_dist_id)" = "centos" ] || return 1
version_ge "$(get_version)" "$1"
}
is_python_at_least_ver() {
local out python_exec
python_exec="$1"
command_exists "$python_exec" || return 1
out=$($python_exec --version)
version_ge "${out#* }" "$2"
}
is_arm() {
[ "$(dpkg --print-architecture)" = "armhf" ] || return 1
}
is_arm64() {
[ "$(dpkg --print-architecture)" = "arm64" ] || return 1
}
print_github_api_rate_limits() {
# See https://developer.github.com/v3/rate_limit/
# Note: Accessing this endpoint does not count against your REST API rate limit.
echo_green '-----------------------------------------'
echo_green 'Github API Rate limits'
echo_green '-----------------------------------------'
wget -q -O- https://api.github.com/rate_limit
echo_green '-----------------------------------------'
}
setup_build_type_env_vars() {
OS_TYPE=${OS_TYPE:-default}
# For a 'arm32_v7/debian_docker' string, OS TYPE becomes 'debian'
# This also works for just 'debian_docker'
# And we're extracting OS_ARCH if present
if [ "${OS_TYPE#*_}" = "docker" ] ; then
BUILD_TYPE=generic_docker
OS_TYPE=${OS_TYPE%_*}
OS_ARCH=${OS_TYPE%/*}
OS_TYPE=${OS_TYPE#*/}
if [ "$OS_ARCH" = "$OS_TYPE" ] ; then
OS_ARCH=
fi
else
BUILD_TYPE="$OS_TYPE"
fi
export OS_TYPE
export OS_ARCH
export BUILD_TYPE
}
ensure_command_exists wget
ensure_command_exists sudo
if [ -z "${LDIST}" -a -f "build/.LDIST" ] ; then
export LDIST="-$(cat build/.LDIST)"
echo $LDIST
fi
if [ -z "${LDIST}" ] || [ "$LDIST" = "DO_NOT_DEPLOY" ] ; then
export LDIST="-$(get_ldist)"
echo $LDIST
fi
libad9361-iio-0.3/CI/travis/make_darwin 0000775 0000000 0000000 00000000416 14424151631 0017544 0 ustar 00root root 0000000 0000000 #!/bin/sh -e
if [ "x${COVERITY_SCAN_PROJECT_NAME}" != "x" ] ; then exit 0; fi
mkdir -p build
cd build
cmake -DOSX_PACKAGE=ON ..
make
ls
make test
cd ..
mkdir -p build_tar
cd build_tar
cmake -DOSX_PACKAGE=OFF -DENABLE_PACKAGING=ON ..
make
ls
make package
make test
libad9361-iio-0.3/CI/travis/make_linux 0000775 0000000 0000000 00000001635 14424151631 0017423 0 ustar 00root root 0000000 0000000 #!/bin/sh -e
if [ "x${COVERITY_SCAN_PROJECT_NAME}" != "x" ] ; then exit 0; fi
. CI/travis/lib.sh
handle_default() {
mkdir -p build
cd build
sudo cmake -DPYTHON_BINDINGS=ON -DENABLE_PACKAGING=ON -DDEB_DETECT_DEPENDENCIES=ON ..
sudo make && make package && make test
sudo make install
ldconfig
cd ..
cd bindings/python
sudo pip3 install -r requirements_dev.txt
sudo python3 -m pytest -vs --skip-scan
}
handle_centos() {
mkdir -p build
cd build
sudo cmake -DPYTHON_BINDINGS=ON -DENABLE_PACKAGING=ON ..
sudo make && make package && make test
sudo make install
ldconfig
cd ..
cd bindings/python
sudo pip3 install -r requirements_dev.txt
export LD_LIBRARY_PATH=/usr/local/lib/
sudo python3 -m pytest -vs --skip-scan
}
handle_ubuntu() {
handle_default
}
handle_debian() {
handle_default
}
handle_generic_docker() {
run_docker_script inside_docker.sh
}
setup_build_type_env_vars
handle_${BUILD_TYPE}
libad9361-iio-0.3/CMakeLists.txt 0000664 0000000 0000000 00000016515 14424151631 0016301 0 ustar 00root root 0000000 0000000 # Copyright (C) 2015 Analog Devices, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
cmake_minimum_required(VERSION 2.8.12)
project(ad9361 C)
set(LIBAD9361_VERSION_MAJOR 0)
set(LIBAD9361_VERSION_MINOR 2)
set(VERSION ${LIBAD9361_VERSION_MAJOR}.${LIBAD9361_VERSION_MINOR})
if (WIN32)
string(TIMESTAMP BUILD_YEAR "%Y")
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
option(OSX_PACKAGE "Create a OSX package" ON)
set(CMAKE_MACOSX_RPATH ON)
set(SKIP_INSTALL_ALL ${OSX_PACKAGE})
endif()
include(FindGit OPTIONAL)
if (GIT_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --show-toplevel
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE LIBAD9361_GIT_REPO
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if ("${LIBAD9361_GIT_REPO}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE LIBAD9361_VERSION_GIT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
endif()
if (NOT LIBAD9361_VERSION_GIT)
set(LIBAD9361_VERSION_GIT v${VERSION})
endif()
set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries")
if (NOT WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
endif()
# based on host, set these on macos
if(APPLE)
#full Single Unix Standard v3 (SUSv3) conformance (the Unix API)
add_definitions(-D_DARWIN_C_SOURCE)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE=1")
add_definitions(-D_GNU_SOURCE=1)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD|DragonFly|OpenBSD|NetBSD")
set(CMAKE_REQUIRED_DEFINITIONS "-D__BSD_VISIBLE")
add_definitions(-D__BSD_VISIBLE=1)
endif()
add_definitions(-D_POSIX_C_SOURCE=200809L -D__XSI_VISIBLE=500 -DLIBAD9361_EXPORTS=1)
set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib"
CACHE PATH "Installation directory for libraries")
mark_as_advanced(INSTALL_LIB_DIR)
find_library(LIBIIO_LIBRARIES iio)
find_path(LIBIIO_INCLUDEDIR iio.h)
set(LIBAD9361_HEADERS ad9361.h)
file(GLOB_RECURSE FD_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/filterdesigner/*.c)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${LIBIIO_INCLUDEDIR})
add_library(ad9361 ad9361_multichip_sync.c
ad9361_baseband_auto_rate.c
ad9361_design_taps.c
ad9361_calculate_rf_clock_chain.c
ad9361_fmcomms5_phase_sync.c
${FD_SRC_FILES}
${LIBAD9361_HEADERS})
enable_testing()
add_subdirectory(test)
set_target_properties(ad9361 PROPERTIES
VERSION ${VERSION}
SOVERSION ${LIBAD9361_VERSION_MAJOR}
FRAMEWORK TRUE
PUBLIC_HEADER ${LIBAD9361_HEADERS}
C_STANDARD 99
C_STANDARD_REQUIRED ON
C_EXTENSIONS OFF
)
target_link_libraries(ad9361 LINK_PRIVATE ${LIBIIO_LIBRARIES})
if (MSVC)
set_target_properties(ad9361 PROPERTIES OUTPUT_NAME libad9361)
endif()
configure_file(libad9361-iio.iss.cmakein ${CMAKE_CURRENT_BINARY_DIR}/libad9361-iio.iss @ONLY)
set(LIBAD9361_PC ${CMAKE_CURRENT_BINARY_DIR}/libad9361.pc)
configure_file(libad9361.pc.cmakein ${LIBAD9361_PC} @ONLY)
install(FILES ${LIBAD9361_PC} DESTINATION ${INSTALL_LIB_DIR}/pkgconfig)
if(NOT SKIP_INSTALL_ALL)
install(TARGETS ad9361
ARCHIVE DESTINATION lib
LIBRARY DESTINATION "${INSTALL_LIB_DIR}"
RUNTIME DESTINATION bin
FRAMEWORK DESTINATION lib
PUBLIC_HEADER DESTINATION include)
endif()
set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/${PROJECT_NAME}${LIBAD9361_VERSION_MAJOR}-doc)")
include(GNUInstallDirs)
set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}${LIBAD9361_VERSION_MAJOR}-doc")
find_package(Doxygen)
if(DOXYGEN_FOUND)
option(WITH_DOC "Generate documentation with Doxygen" ON)
if (WITH_DOC)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
set(HTML_DEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/html)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/doc DESTINATION ${HTML_DEST_DIR})
add_custom_command(TARGET ad9361 POST_BUILD
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen" VERBATIM
)
if(NOT SKIP_INSTALL_ALL)
install(DIRECTORY ${HTML_DEST_DIR} DESTINATION ${CMAKE_INSTALL_DOCDIR})
endif()
endif()
else()
message(STATUS "Doxygen not found, API documentation won't be generated")
endif()
option(PYTHON_BINDINGS "Install Python bindings" OFF)
option(MATLAB_BINDINGS "Install MATLAB bindings" OFF)
option(LIB_CHECK_PYINSTALL "Check for library during python install" OFF)
add_subdirectory(bindings)
# Create an installer if compiling for OSX
if(OSX_PACKAGE)
set(LIBAD9361_PKG ${CMAKE_CURRENT_BINARY_DIR}/libad9361-${VERSION}.pkg)
set(LIBAD9361_TEMP_PKG ${CMAKE_CURRENT_BINARY_DIR}/libad9361-${VERSION}-temp.pkg)
set(LIBAD9361_DISTRIBUTION_XML ${CMAKE_CURRENT_BINARY_DIR}/Distribution.xml)
set(LIBAD9361_FRAMEWORK_DIR ${CMAKE_CURRENT_BINARY_DIR}/ad9361.framework)
configure_file(Distribution.xml.cmakein ${LIBAD9361_DISTRIBUTION_XML} @ONLY)
find_program(PKGBUILD_EXECUTABLE
NAMES pkgbuild
DOC "OSX Package builder (pkgbuild)")
mark_as_advanced(PKGBUILD_EXECUTABLE)
find_program(PRODUCTBUILD_EXECUTABLE
NAMES productbuild
DOC "OSX Package builder (productbuild)")
mark_as_advanced(PRODUCTBUILD_EXECUTABLE)
add_custom_command(OUTPUT ${LIBAD9361_PKG}
COMMAND ${PKGBUILD_EXECUTABLE}
--component ${LIBAD9361_FRAMEWORK_DIR}
--identifier com.adi.ad9361 --version ${VERSION}
--install-location /Library/Frameworks ${LIBAD9361_TEMP_PKG}
COMMAND ${PRODUCTBUILD_EXECUTABLE}
--distribution ${LIBAD9361_DISTRIBUTION_XML} ${LIBAD9361_PKG}
COMMAND ${CMAKE_COMMAND} -E remove ${LIBAD9361_TEMP_PKG}
DEPENDS ad9361 ${LIBAD9361_DISTRIBUTION_XML}
)
if (PKGBUILD_EXECUTABLE AND PRODUCTBUILD_EXECUTABLE)
add_custom_target(libad9361-pkg ALL DEPENDS ${LIBAD9361_PKG})
install(CODE "execute_process(COMMAND /usr/sbin/installer -pkg ${LIBAD9361_PKG} -target /)")
else()
message(WARNING "Missing pkgbuild or productbuild: OSX installer won't be created.")
endif()
else()
# Support creating some basic binpkgs via `make package`.
# Disabled if OSX_PACKAGE is enabled, as tarballs would
# end up empty otherwise.
option(ENABLE_PACKAGING "Create .deb/.rpm or .tar.gz packages via 'make package'" ON)
if(ENABLE_PACKAGING)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
include(cmake/DarwinPackaging.cmake)
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
include(cmake/LinuxPackaging.cmake)
endif()
endif()
endif()
########################################################################
# uninstall target
########################################################################
add_custom_target(uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
libad9361-iio-0.3/Distribution.xml.cmakein 0000664 0000000 0000000 00000001321 14424151631 0020335 0 ustar 00root root 0000000 0000000
Libad9361
@LIBAD9361_TEMP_PKG@
libad9361-iio-0.3/Doxyfile.in 0000664 0000000 0000000 00000340041 14424151631 0015646 0 ustar 00root root 0000000 0000000 # Doxyfile 1.9.1
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
#
# All text after a double hash (##) is considered a comment and is placed in
# front of the TAG it is preceding.
#
# All text after a single hash (#) is considered a comment and will be ignored.
# The format is:
# TAG = value [value, ...]
# For lists, items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (\" \").
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the configuration
# file that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
# The default value is: UTF-8.
DOXYFILE_ENCODING = UTF-8
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
# double-quotes, unless you are using Doxywizard) that should identify the
# project for which the documentation is generated. This name is used in the
# title of most generated pages and in a few other places.
# The default value is: My Project.
PROJECT_NAME = libad9361
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = @LIBAD9361_VERSION_MAJOR@.@LIBAD9361_VERSION_MINOR@
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF = "Device specific library for AD936X transceivers"
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
PROJECT_LOGO =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY = .
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
# will distribute the generated files over these directories. Enabling this
# option can be useful when feeding doxygen a huge amount of source files, where
# putting all generated files in the same directory would otherwise causes
# performance problems for the file system.
# The default value is: NO.
CREATE_SUBDIRS = NO
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
# characters to appear in the names of generated files. If set to NO, non-ASCII
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
# U+3044.
# The default value is: NO.
ALLOW_UNICODE_NAMES = NO
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
# Ukrainian and Vietnamese.
# The default value is: English.
OUTPUT_LANGUAGE = English
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all generated output in the proper direction.
# Possible values are: None, LTR, RTL and Context.
# The default value is: None.
OUTPUT_TEXT_DIRECTION = None
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
# The default value is: YES.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
# description of a member or function before the detailed description
#
# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
# The default value is: YES.
REPEAT_BRIEF = YES
# This tag implements a quasi-intelligent brief description abbreviator that is
# used to form the text in various listings. Each string in this list, if found
# as the leading text of the brief description, will be stripped from the text
# and the result, after processing the whole list, is used as the annotated
# text. Otherwise, the brief description is used as-is. If left blank, the
# following values are used ($name is automatically replaced with the name of
# the entity):The $name class, The $name widget, The $name file, is, provides,
# specifies, contains, represents, a, an and the.
ABBREVIATE_BRIEF =
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# doxygen will generate a detailed section even if there is only a brief
# description.
# The default value is: NO.
ALWAYS_DETAILED_SEC = NO
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
# inherited members of a class in the documentation of that class as if those
# members were ordinary class members. Constructors, destructors and assignment
# operators of the base classes will not be shown.
# The default value is: NO.
INLINE_INHERITED_MEMB = NO
# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
# before files name in the file list and in the header files. If set to NO the
# shortest path that makes the file name unique will be used
# The default value is: YES.
FULL_PATH_NAMES = YES
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
# Stripping is only done if one of the specified strings matches the left-hand
# part of the path. The tag can be used to show relative paths in the file list.
# If left blank the directory from which doxygen is run is used as the path to
# strip.
#
# Note that you can specify absolute paths here, but also relative paths, which
# will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
STRIP_FROM_PATH =
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which
# header file to include in order to use a class. If left blank only the name of
# the header file containing the class definition is used. Otherwise one should
# specify the list of include paths that are normally passed to the compiler
# using the -I flag.
STRIP_FROM_INC_PATH =
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
# less readable) file names. This can be useful is your file systems doesn't
# support long names like on DOS, Mac, or CD-ROM.
# The default value is: NO.
SHORT_NAMES = NO
# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
# first line (until the first dot) of a Javadoc-style comment as the brief
# description. If set to NO, the Javadoc-style will behave just like regular Qt-
# style comments (thus requiring an explicit @brief command for a brief
# description.)
# The default value is: NO.
JAVADOC_AUTOBRIEF = NO
# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
# such as
# /***************
# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
# Javadoc-style will behave just like regular comments and it will not be
# interpreted by doxygen.
# The default value is: NO.
JAVADOC_BANNER = NO
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
# requiring an explicit \brief command for a brief description.)
# The default value is: NO.
QT_AUTOBRIEF = NO
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
# a brief description. This used to be the default behavior. The new default is
# to treat a multi-line C++ comment block as a detailed description. Set this
# tag to YES if you prefer the old behavior instead.
#
# Note that setting this tag to YES also means that rational rose comments are
# not recognized any more.
# The default value is: NO.
MULTILINE_CPP_IS_BRIEF = NO
# By default Python docstrings are displayed as preformatted text and doxygen's
# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the
# doxygen's special commands can be used and the contents of the docstring
# documentation blocks is shown as doxygen documentation.
# The default value is: YES.
PYTHON_DOCSTRING = YES
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
# documentation from any documented member that it re-implements.
# The default value is: YES.
INHERIT_DOCS = YES
# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
# page for each member. If set to NO, the documentation of a member will be part
# of the file/class/namespace that contains it.
# The default value is: NO.
SEPARATE_MEMBER_PAGES = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
# uses this value to replace tabs by spaces in code fragments.
# Minimum value: 1, maximum value: 16, default value: 4.
TAB_SIZE = 4
# This tag can be used to specify a number of aliases that act as commands in
# the documentation. An alias has the form:
# name=value
# For example adding
# "sideeffect=@par Side Effects:\n"
# will allow you to put the command \sideeffect (or @sideeffect) in the
# documentation, which will result in a user-defined paragraph with heading
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines (in the resulting output). You can put ^^ in the value part of an
# alias to insert a newline as if a physical newline was in the original file.
# When you need a literal { or } or , in the value part of an alias you have to
# escape them by means of a backslash (\), this can lead to conflicts with the
# commands \{ and \} for these it is advised to use the version @{ and @} or use
# a double escape (\\{ and \\})
ALIASES =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
# instance, some of the names that are used will be different. The list of all
# members will be omitted, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_FOR_C = YES
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
# Python sources only. Doxygen will then generate output that is more tailored
# for that language. For instance, namespaces will be presented as packages,
# qualified scopes will look different, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_JAVA = NO
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
# sources. Doxygen will then generate output that is tailored for Fortran.
# The default value is: NO.
OPTIMIZE_FOR_FORTRAN = NO
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
# sources. Doxygen will then generate output that is tailored for VHDL.
# The default value is: NO.
OPTIMIZE_OUTPUT_VHDL = NO
# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
# sources only. Doxygen will then generate output that is more tailored for that
# language. For instance, namespaces will be presented as modules, types will be
# separated into more groups, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_SLICE = NO
# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
# tries to guess whether the code is fixed or free formatted code, this is the
# default for Fortran type files). For instance to make doxygen treat .inc files
# as Fortran files (default is PHP), and .f files as C (default is Fortran),
# use: inc=Fortran f=C.
#
# Note: For files without extension you can use no_extension as a placeholder.
#
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
# the files are not read by doxygen. When specifying no_extension you should add
# * to the FILE_PATTERNS.
#
# Note see also the list of default file extension mappings.
EXTENSION_MAPPING =
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
# documentation. See https://daringfireball.net/projects/markdown/ for details.
# The output of markdown processing is further processed by doxygen, so you can
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
# case of backward compatibilities issues.
# The default value is: YES.
MARKDOWN_SUPPORT = YES
# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
# to that level are automatically included in the table of contents, even if
# they do not have an id attribute.
# Note: This feature currently applies only to Markdown headings.
# Minimum value: 0, maximum value: 99, default value: 5.
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
TOC_INCLUDE_HEADINGS = 5
# When enabled doxygen tries to link words that correspond to documented
# classes, or namespaces to their corresponding documentation. Such a link can
# be prevented in individual cases by putting a % sign in front of the word or
# globally by setting AUTOLINK_SUPPORT to NO.
# The default value is: YES.
AUTOLINK_SUPPORT = YES
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
# to include (a tag file for) the STL sources as input, then you should set this
# tag to YES in order to let doxygen match functions declarations and
# definitions whose arguments contain STL classes (e.g. func(std::string);
# versus func(std::string) {}). This also make the inheritance and collaboration
# diagrams that involve STL classes more complete and accurate.
# The default value is: NO.
BUILTIN_STL_SUPPORT = NO
# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.
# The default value is: NO.
CPP_CLI_SUPPORT = NO
# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
# will parse them like normal C++ but will assume all classes use public instead
# of private inheritance when no explicit protection keyword is present.
# The default value is: NO.
SIP_SUPPORT = NO
# For Microsoft's IDL there are propget and propput attributes to indicate
# getter and setter methods for a property. Setting this option to YES will make
# doxygen to replace the get and set methods by a property in the documentation.
# This will only work if the methods are indeed getting or setting a simple
# type. If this is not the case, or you want to show the methods anyway, you
# should set this option to NO.
# The default value is: YES.
IDL_PROPERTY_SUPPORT = YES
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
# The default value is: NO.
DISTRIBUTE_GROUP_DOC = NO
# If one adds a struct or class to a group and this option is enabled, then also
# any nested class or struct is added to the same group. By default this option
# is disabled and one has to add nested compounds explicitly via \ingroup.
# The default value is: NO.
GROUP_NESTED_COMPOUNDS = NO
# Set the SUBGROUPING tag to YES to allow class member groups of the same type
# (for instance a group of public functions) to be put as a subgroup of that
# type (e.g. under the Public Functions section). Set it to NO to prevent
# subgrouping. Alternatively, this can be done per class using the
# \nosubgrouping command.
# The default value is: YES.
SUBGROUPING = YES
# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
# are shown inside the group in which they are included (e.g. using \ingroup)
# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
# and RTF).
#
# Note that this feature does not work in combination with
# SEPARATE_MEMBER_PAGES.
# The default value is: NO.
INLINE_GROUPED_CLASSES = NO
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
# with only public data fields or simple typedef fields will be shown inline in
# the documentation of the scope in which they are defined (i.e. file,
# namespace, or group documentation), provided this scope is documented. If set
# to NO, structs, classes, and unions are shown on a separate page (for HTML and
# Man pages) or section (for LaTeX and RTF).
# The default value is: NO.
INLINE_SIMPLE_STRUCTS = NO
# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
# enum is documented as struct, union, or enum with the name of the typedef. So
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
# with name TypeT. When disabled the typedef will appear as a member of a file,
# namespace, or class. And the struct will be named TypeS. This can typically be
# useful for C code in case the coding convention dictates that all compound
# types are typedef'ed and only the typedef is referenced, never the tag name.
# The default value is: NO.
TYPEDEF_HIDES_STRUCT = NO
# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
# cache is used to resolve symbols given their name and scope. Since this can be
# an expensive process and often the same symbol appears multiple times in the
# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
# doxygen will become slower. If the cache is too large, memory is wasted. The
# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
# symbols. At the end of a run doxygen will report the cache usage and suggest
# the optimal cache size from a speed point of view.
# Minimum value: 0, maximum value: 9, default value: 0.
LOOKUP_CACHE_SIZE = 0
# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
# during processing. When set to 0 doxygen will based this on the number of
# cores available in the system. You can set it explicitly to a value larger
# than 0 to get more control over the balance between CPU load and processing
# speed. At this moment only the input processing can be done using multiple
# threads. Since this is still an experimental feature the default is set to 1,
# which efficively disables parallel processing. Please report any issues you
# encounter. Generating dot graphs in parallel is controlled by the
# DOT_NUM_THREADS setting.
# Minimum value: 0, maximum value: 32, default value: 1.
NUM_PROC_THREADS = 1
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
# documentation are documented, even if no documentation was available. Private
# class members and static file members will be hidden unless the
# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
# Note: This will also disable the warnings about undocumented members that are
# normally produced when WARNINGS is set to YES.
# The default value is: NO.
EXTRACT_ALL = NO
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
# be included in the documentation.
# The default value is: NO.
EXTRACT_PRIVATE = NO
# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
# methods of a class will be included in the documentation.
# The default value is: NO.
EXTRACT_PRIV_VIRTUAL = NO
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
# scope will be included in the documentation.
# The default value is: NO.
EXTRACT_PACKAGE = NO
# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
# included in the documentation.
# The default value is: NO.
EXTRACT_STATIC = NO
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
# locally in source files will be included in the documentation. If set to NO,
# only classes defined in header files are included. Does not have any effect
# for Java sources.
# The default value is: YES.
EXTRACT_LOCAL_CLASSES = NO
# This flag is only useful for Objective-C code. If set to YES, local methods,
# which are defined in the implementation section but not in the interface are
# included in the documentation. If set to NO, only methods in the interface are
# included.
# The default value is: NO.
EXTRACT_LOCAL_METHODS = NO
# If this flag is set to YES, the members of anonymous namespaces will be
# extracted and appear in the documentation as a namespace called
# 'anonymous_namespace{file}', where file will be replaced with the base name of
# the file that contains the anonymous namespace. By default anonymous namespace
# are hidden.
# The default value is: NO.
EXTRACT_ANON_NSPACES = NO
# If this flag is set to YES, the name of an unnamed parameter in a declaration
# will be determined by the corresponding definition. By default unnamed
# parameters remain unnamed in the output.
# The default value is: YES.
RESOLVE_UNNAMED_PARAMS = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
# undocumented members inside documented classes or files. If set to NO these
# members will be included in the various overviews, but no documentation
# section is generated. This option has no effect if EXTRACT_ALL is enabled.
# The default value is: NO.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy. If set
# to NO, these classes will be included in the various overviews. This option
# has no effect if EXTRACT_ALL is enabled.
# The default value is: NO.
HIDE_UNDOC_CLASSES = YES
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
# declarations. If set to NO, these declarations will be included in the
# documentation.
# The default value is: NO.
HIDE_FRIEND_COMPOUNDS = NO
# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
# documentation blocks found inside the body of a function. If set to NO, these
# blocks will be appended to the function's detailed documentation block.
# The default value is: NO.
HIDE_IN_BODY_DOCS = NO
# The INTERNAL_DOCS tag determines if documentation that is typed after a
# \internal command is included. If the tag is set to NO then the documentation
# will be excluded. Set it to YES to include the internal documentation.
# The default value is: NO.
INTERNAL_DOCS = NO
# With the correct setting of option CASE_SENSE_NAMES doxygen will better be
# able to match the capabilities of the underlying filesystem. In case the
# filesystem is case sensitive (i.e. it supports files in the same directory
# whose names only differ in casing), the option must be set to YES to properly
# deal with such files in case they appear in the input. For filesystems that
# are not case sensitive the option should be be set to NO to properly deal with
# output files written for symbols that only differ in casing, such as for two
# classes, one named CLASS and the other named Class, and to also support
# references to files without having to specify the exact matching casing. On
# Windows (including Cygwin) and MacOS, users should typically set this option
# to NO, whereas on Linux or other Unix flavors it should typically be set to
# YES.
# The default value is: system dependent.
CASE_SENSE_NAMES = YES
# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
# their full class and namespace scopes in the documentation. If set to YES, the
# scope will be hidden.
# The default value is: NO.
HIDE_SCOPE_NAMES = NO
# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
# append additional text to a page's title, such as Class Reference. If set to
# YES the compound reference will be hidden.
# The default value is: NO.
HIDE_COMPOUND_REFERENCE= NO
# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
# the files that are included by a file in the documentation of that file.
# The default value is: YES.
SHOW_INCLUDE_FILES = YES
# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
# grouped member an include statement to the documentation, telling the reader
# which file to include in order to use the member.
# The default value is: NO.
SHOW_GROUPED_MEMB_INC = NO
# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
# files with double quotes in the documentation rather than with sharp brackets.
# The default value is: NO.
FORCE_LOCAL_INCLUDES = NO
# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
# documentation for inline members.
# The default value is: YES.
INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
# (detailed) documentation of file and class members alphabetically by member
# name. If set to NO, the members will appear in declaration order.
# The default value is: YES.
SORT_MEMBER_DOCS = YES
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
# descriptions of file, namespace and class members alphabetically by member
# name. If set to NO, the members will appear in declaration order. Note that
# this will also influence the order of the classes in the class list.
# The default value is: NO.
SORT_BRIEF_DOCS = NO
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
# (brief and detailed) documentation of class members so that constructors and
# destructors are listed first. If set to NO the constructors will appear in the
# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
# member documentation.
# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
# detailed member documentation.
# The default value is: NO.
SORT_MEMBERS_CTORS_1ST = NO
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
# of group names into alphabetical order. If set to NO the group names will
# appear in their defined order.
# The default value is: NO.
SORT_GROUP_NAMES = NO
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
# fully-qualified names, including namespaces. If set to NO, the class list will
# be sorted only by class name, not including the namespace part.
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
# Note: This option applies only to the class list, not to the alphabetical
# list.
# The default value is: NO.
SORT_BY_SCOPE_NAME = NO
# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
# type resolution of all parameters of a function it will reject a match between
# the prototype and the implementation of a member function even if there is
# only one candidate or it is obvious which candidate to choose by doing a
# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
# accept a match between prototype and implementation in such cases.
# The default value is: NO.
STRICT_PROTO_MATCHING = NO
# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
# list. This list is created by putting \todo commands in the documentation.
# The default value is: YES.
GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
# list. This list is created by putting \test commands in the documentation.
# The default value is: YES.
GENERATE_TESTLIST = YES
# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
# list. This list is created by putting \bug commands in the documentation.
# The default value is: YES.
GENERATE_BUGLIST = YES
# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
# the deprecated list. This list is created by putting \deprecated commands in
# the documentation.
# The default value is: YES.
GENERATE_DEPRECATEDLIST= YES
# The ENABLED_SECTIONS tag can be used to enable conditional documentation
# sections, marked by \if ... \endif and \cond
# ... \endcond blocks.
ENABLED_SECTIONS =
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
# initial value of a variable or macro / define can have for it to appear in the
# documentation. If the initializer consists of more lines than specified here
# it will be hidden. Use a value of 0 to hide initializers completely. The
# appearance of the value of individual variables and macros / defines can be
# controlled using \showinitializer or \hideinitializer command in the
# documentation regardless of this setting.
# Minimum value: 0, maximum value: 10000, default value: 30.
MAX_INITIALIZER_LINES = 30
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
# the bottom of the documentation of classes and structs. If set to YES, the
# list will mention the files that were used to generate the documentation.
# The default value is: YES.
SHOW_USED_FILES = YES
# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
# will remove the Files entry from the Quick Index and from the Folder Tree View
# (if specified).
# The default value is: YES.
SHOW_FILES = YES
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
# page. This will remove the Namespaces entry from the Quick Index and from the
# Folder Tree View (if specified).
# The default value is: YES.
SHOW_NAMESPACES = YES
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from
# the version control system). Doxygen will invoke the program by executing (via
# popen()) the command command input-file, where command is the value of the
# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
# by doxygen. Whatever the program writes to standard output is used as the file
# version. For an example see the documentation.
FILE_VERSION_FILTER =
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
# by doxygen. The layout file controls the global structure of the generated
# output files in an output format independent way. To create the layout file
# that represents doxygen's defaults, run doxygen with the -l option. You can
# optionally specify a file name after the option, if omitted DoxygenLayout.xml
# will be used as the name of the layout file.
#
# Note that if you run doxygen from a directory containing a file called
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
# tag is left empty.
LAYOUT_FILE =
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
# extension is automatically appended if omitted. This requires the bibtex tool
# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
# For LaTeX the style of the bibliography can be controlled using
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
# search path. See also \cite for info how to create references.
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated to
# standard output by doxygen. If QUIET is set to YES this implies that the
# messages are off.
# The default value is: NO.
QUIET = YES
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
# this implies that the warnings are on.
#
# Tip: Turn warnings on while writing the documentation.
# The default value is: YES.
WARNINGS = YES
# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
# will automatically be disabled.
# The default value is: YES.
WARN_IF_UNDOCUMENTED = YES
# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
# potential errors in the documentation, such as not documenting some parameters
# in a documented function, or documenting parameters that don't exist or using
# markup commands wrongly.
# The default value is: YES.
WARN_IF_DOC_ERROR = YES
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return
# value. If set to NO, doxygen will only warn about wrong or incomplete
# parameter documentation, but not about the absence of documentation. If
# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
# The default value is: NO.
WARN_NO_PARAMDOC = NO
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
# at the end of the doxygen process doxygen will return with a non-zero status.
# Possible values are: NO, YES and FAIL_ON_WARNINGS.
# The default value is: NO.
WARN_AS_ERROR = NO
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which
# will be replaced by the file and line number from which the warning originated
# and the warning text. Optionally the format may contain $version, which will
# be replaced by the version of the file (if it could be obtained via
# FILE_VERSION_FILTER)
# The default value is: $file:$line: $text.
WARN_FORMAT = "$file:$line: $text"
# The WARN_LOGFILE tag can be used to specify a file to which warning and error
# messages should be written. If left blank the output is written to standard
# error (stderr).
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag is used to specify the files and/or directories that contain
# documented source files. You may enter file names like myfile.cpp or
# directories like /usr/src/myproject. Separate the files or directories with
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = @CMAKE_SOURCE_DIR@
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
# documentation (see:
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
# The default value is: UTF-8.
INPUT_ENCODING = UTF-8
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
# *.h) to filter out the source-files in the directories.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# read by doxygen.
#
# Note the list of default checked file patterns might differ from the list of
# default file extension mappings.
#
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl,
# *.ucf, *.qsf and *.ice.
FILE_PATTERNS = *.c \
*.h \
*.dox
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
# The default value is: NO.
RECURSIVE = NO
# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
#
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
# from the input.
# The default value is: NO.
EXCLUDE_SYMLINKS = NO
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories.
#
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*
EXCLUDE_PATTERNS =
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test
#
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories use the pattern */test/*
EXCLUDE_SYMBOLS = __api
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
# that contain example code fragments that are included (see the \include
# command).
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
# *.h) to filter out the source-files in the directories. If left blank all
# files are included.
EXAMPLE_PATTERNS =
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude commands
# irrespective of the value of the RECURSIVE tag.
# The default value is: NO.
EXAMPLE_RECURSIVE = NO
# The IMAGE_PATH tag can be used to specify one or more files or directories
# that contain images that are to be included in the documentation (see the
# \image command).
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command:
#
#
#
# where is the value of the INPUT_FILTER tag, and is the
# name of an input file. Doxygen will then use the output that the filter
# program writes to standard output. If FILTER_PATTERNS is specified, this tag
# will be ignored.
#
# Note that the filter must not add or remove lines; it is applied before the
# code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
INPUT_FILTER =
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
# basis. Doxygen will compare the file name with each pattern and apply the
# filter if there is a match. The filters are a list of the form: pattern=filter
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
# patterns match the file name, INPUT_FILTER is applied.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
FILTER_PATTERNS =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will also be used to filter the input files that are used for
# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
# The default value is: NO.
FILTER_SOURCE_FILES = NO
# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
# it is also possible to disable source filtering for a specific pattern using
# *.ext= (so without naming a filter).
# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
FILTER_SOURCE_PATTERNS =
# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
# is part of the input, its contents will be placed on the main page
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.
USE_MDFILE_AS_MAINPAGE =
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
# generated. Documented entities will be cross-referenced with these sources.
#
# Note: To get rid of all source code in the generated output, make sure that
# also VERBATIM_HEADERS is set to NO.
# The default value is: NO.
SOURCE_BROWSER = NO
# Setting the INLINE_SOURCES tag to YES will include the body of functions,
# classes and enums directly into the documentation.
# The default value is: NO.
INLINE_SOURCES = NO
# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
# special comment blocks from generated source code fragments. Normal C, C++ and
# Fortran comments will always remain visible.
# The default value is: YES.
STRIP_CODE_COMMENTS = YES
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
# entity all documented functions referencing it will be listed.
# The default value is: NO.
REFERENCED_BY_RELATION = NO
# If the REFERENCES_RELATION tag is set to YES then for each documented function
# all documented entities called/used by that function will be listed.
# The default value is: NO.
REFERENCES_RELATION = NO
# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
# to YES then the hyperlinks from functions in REFERENCES_RELATION and
# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
# link to the documentation.
# The default value is: YES.
REFERENCES_LINK_SOURCE = YES
# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
# source code will show a tooltip with additional information such as prototype,
# brief description and links to the definition and documentation. Since this
# will make the HTML file larger and loading of large files a bit slower, you
# can opt to disable this feature.
# The default value is: YES.
# This tag requires that the tag SOURCE_BROWSER is set to YES.
SOURCE_TOOLTIPS = YES
# If the USE_HTAGS tag is set to YES then the references to source code will
# point to the HTML generated by the htags(1) tool instead of doxygen built-in
# source browser. The htags tool is part of GNU's global source tagging system
# (see https://www.gnu.org/software/global/global.html). You will need version
# 4.8.6 or higher.
#
# To use it do the following:
# - Install the latest version of global
# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
# - Make sure the INPUT points to the root of the source tree
# - Run doxygen as normal
#
# Doxygen will invoke htags (and that will in turn invoke gtags), so these
# tools must be available from the command line (i.e. in the search path).
#
# The result: instead of the source browser generated by doxygen, the links to
# source code will now point to the output of htags.
# The default value is: NO.
# This tag requires that the tag SOURCE_BROWSER is set to YES.
USE_HTAGS = NO
# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
# verbatim copy of the header file for each class for which an include is
# specified. Set to NO to disable this.
# See also: Section \class.
# The default value is: YES.
VERBATIM_HEADERS = YES
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
# clang parser (see:
# http://clang.llvm.org/) for more accurate parsing at the cost of reduced
# performance. This can be particularly helpful with template rich C++ code for
# which doxygen's built-in parser lacks the necessary type information.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
# The default value is: NO.
CLANG_ASSISTED_PARSING = NO
# If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to
# YES then doxygen will add the directory of each input to the include path.
# The default value is: YES.
CLANG_ADD_INC_PATHS = YES
# If clang assisted parsing is enabled you can provide the compiler with command
# line options that you would normally use when invoking the compiler. Note that
# the include paths will already be set by doxygen for the files and directories
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_OPTIONS =
# If clang assisted parsing is enabled you can provide the clang parser with the
# path to the directory containing a file called compile_commands.json. This
# file is the compilation database (see:
# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the
# options used when the source files were built. This is equivalent to
# specifying the -p option to a clang tool, such as clang-check. These options
# will then be passed to the parser. Any options specified with CLANG_OPTIONS
# will be added as well.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
CLANG_DATABASE_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
# compounds will be generated. Enable this if the project contains a lot of
# classes, structs, unions or interfaces.
# The default value is: YES.
ALPHABETICAL_INDEX = YES
# In case all classes in a project start with a common prefix, all classes will
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
# can be used to specify a prefix (or a list of prefixes) that should be ignored
# while generating the index headers.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
# The default value is: YES.
GENERATE_HTML = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
# it.
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_OUTPUT = html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp).
# The default value is: .html.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FILE_EXTENSION = .html
# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
# each generated HTML page. If the tag is left blank doxygen will generate a
# standard header.
#
# To get valid HTML the header file that includes any scripts and style sheets
# that doxygen needs, which is dependent on the configuration options used (e.g.
# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
# default header using
# doxygen -w html new_header.html new_footer.html new_stylesheet.css
# YourConfigFile
# and then modify the file new_header.html. See also section "Doxygen usage"
# for information on how to generate the default header that doxygen normally
# uses.
# Note: The header is subject to change so you typically have to regenerate the
# default header when upgrading to a newer version of doxygen. For a description
# of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard
# footer. See HTML_HEADER for more information on how to generate a default
# footer and what special commands can be used inside the footer. See also
# section "Doxygen usage" for information on how to generate the default footer
# that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of
# the HTML output. If left blank doxygen will generate a default style sheet.
# See also section "Doxygen usage" for information on how to generate the style
# sheet that doxygen normally uses.
# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
# it is more robust and this tag (HTML_STYLESHEET) will in the future become
# obsolete.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_STYLESHEET =
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# cascading style sheets that are included after the standard style sheets
# created by doxygen. Using this option one can overrule certain style aspects.
# This is preferred over using HTML_STYLESHEET since it does not replace the
# standard style sheet and is therefore more robust against future updates.
# Doxygen will copy the style sheet files to the output directory.
# Note: The order of the extra style sheet files is of importance (e.g. the last
# style sheet in the list overrules the setting of the previous ones in the
# list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET =
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
# that these files will be copied to the base HTML output directory. Use the
# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
# files will be copied as-is; there are no commands or markers available.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
# this color. Hue is specified as an angle on a colorwheel, see
# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
# purple, and 360 is red again.
# Minimum value: 0, maximum value: 359, default value: 220.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE_HUE = 220
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
# in the HTML output. For a value of 0 the output will use grayscales only. A
# value of 255 will produce the most vivid colors.
# Minimum value: 0, maximum value: 255, default value: 100.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE_SAT = 100
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
# luminance component of the colors in the HTML output. Values below 100
# gradually make the output lighter, whereas values above 100 make the output
# darker. The value divided by 100 is the actual gamma applied, so 80 represents
# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
# change the gamma.
# Minimum value: 40, maximum value: 240, default value: 80.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE_GAMMA = 80
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting this
# to YES can help to show when doxygen was last run and thus if the
# documentation is up to date.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = YES
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
# documentation will contain a main index with vertical navigation menus that
# are dynamically created via JavaScript. If disabled, the navigation index will
# consists of multiple levels of tabs that are statically embedded in every HTML
# page. Disable this option to support browsers that do not have JavaScript,
# like the Qt help browser.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_DYNAMIC_MENUS = YES
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_DYNAMIC_SECTIONS = NO
# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
# shown in the various tree structured indices initially; the user can expand
# and collapse entries dynamically later on. Doxygen will expand the tree to
# such a level that at most the specified number of entries are visible (unless
# a fully collapsed tree already exceeds this amount). So setting the number of
# entries 1 will produce a full collapsed tree by default. 0 is a special value
# representing an infinite number of entries and will result in a full expanded
# tree by default.
# Minimum value: 0, maximum value: 9999, default value: 100.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_INDEX_NUM_ENTRIES = 100
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
# generated that can be used as input for Apple's Xcode 3 integrated development
# environment (see:
# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To
# create a documentation set, doxygen will generate a Makefile in the HTML
# output directory. Running make will produce the docset in that directory and
# running make install will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
# genXcode/_index.html for more information.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_DOCSET = NO
# This tag determines the name of the docset feed. A documentation feed provides
# an umbrella under which multiple documentation sets from a single provider
# (such as a company or product suite) can be grouped.
# The default value is: Doxygen generated docs.
# This tag requires that the tag GENERATE_DOCSET is set to YES.
DOCSET_FEEDNAME = "Doxygen generated docs"
# This tag specifies a string that should uniquely identify the documentation
# set bundle. This should be a reverse domain-name style string, e.g.
# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_DOCSET is set to YES.
DOCSET_BUNDLE_ID = org.doxygen.Project
# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
# the documentation publisher. This should be a reverse domain-name style
# string, e.g. com.mycompany.MyDocSet.documentation.
# The default value is: org.doxygen.Publisher.
# This tag requires that the tag GENERATE_DOCSET is set to YES.
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
# The default value is: Publisher.
# This tag requires that the tag GENERATE_DOCSET is set to YES.
DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
# (see:
# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows.
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
# files are now used as the Windows 98 help format, and will replace the old
# Windows help format (.hlp) on all Windows platforms in the future. Compressed
# HTML files also contain an index, a table of contents, and you can search for
# words in the documentation. The HTML workshop also contains a viewer for
# compressed HTML files.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_HTMLHELP = NO
# The CHM_FILE tag can be used to specify the file name of the resulting .chm
# file. You can add a path in front of the file if the result should not be
# written to the html output directory.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
CHM_FILE =
# The HHC_LOCATION tag can be used to specify the location (absolute path
# including file name) of the HTML help compiler (hhc.exe). If non-empty,
# doxygen will try to run the HTML help compiler on the generated index.hhp.
# The file has to be specified with full path.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
HHC_LOCATION =
# The GENERATE_CHI flag controls if a separate .chi index file is generated
# (YES) or that it should be included in the main .chm file (NO).
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
GENERATE_CHI = NO
# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
# and project file content.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
CHM_INDEX_ENCODING =
# The BINARY_TOC flag controls whether a binary table of contents is generated
# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
# enables the Previous and Next buttons.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
BINARY_TOC = NO
# The TOC_EXPAND flag can be set to YES to add extra items for group members to
# the table of contents of the HTML help documentation and to the tree view.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
TOC_EXPAND = NO
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
# (.qch) of the generated HTML documentation.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_QHP = NO
# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
# the file name of the resulting .qch file. The path specified is relative to
# the HTML output folder.
# This tag requires that the tag GENERATE_QHP is set to YES.
QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
# (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_NAMESPACE = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
# Folders (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_VIRTUAL_FOLDER = doc
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
# Filters (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
# Filters (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS =
# The QHG_LOCATION tag can be used to specify the location (absolute path
# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to
# run qhelpgenerator on the generated .qhp file.
# This tag requires that the tag GENERATE_QHP is set to YES.
QHG_LOCATION =
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
# generated, together with the HTML files, they form an Eclipse help plugin. To
# install this plugin and make it available under the help contents menu in
# Eclipse, the contents of the directory containing the HTML and XML files needs
# to be copied into the plugins directory of eclipse. The name of the directory
# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
# After copying Eclipse needs to be restarted before the help appears.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_ECLIPSEHELP = NO
# A unique identifier for the Eclipse help plugin. When installing the plugin
# the directory name containing the HTML and XML files should also have this
# name. Each documentation set should have its own identifier.
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
ECLIPSE_DOC_ID = org.doxygen.Project
# If you want full control over the layout of the generated HTML pages it might
# be necessary to disable the index and replace it with your own. The
# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
# of each HTML page. A value of NO enables the index and the value YES disables
# it. Since the tabs in the index contain the same information as the navigation
# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
DISABLE_INDEX = NO
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information. If the tag
# value is set to YES, a side panel will be generated containing a tree-like
# index structure (just like the one that is generated for HTML Help). For this
# to work a browser that supports JavaScript, DHTML, CSS and frames is required
# (i.e. any modern browser). Windows users are probably better off using the
# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
# further fine-tune the look of the index. As an example, the default style
# sheet generated by doxygen has an example that shows how to put an image at
# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
# the same information as the tab index, you could consider setting
# DISABLE_INDEX to YES when enabling this option.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_TREEVIEW = NO
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation.
#
# Note that a value of 0 will completely suppress the enum values from appearing
# in the overview section.
# Minimum value: 0, maximum value: 20, default value: 4.
# This tag requires that the tag GENERATE_HTML is set to YES.
ENUM_VALUES_PER_LINE = 4
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
# to set the initial width (in pixels) of the frame in which the tree is shown.
# Minimum value: 0, maximum value: 1500, default value: 250.
# This tag requires that the tag GENERATE_HTML is set to YES.
TREEVIEW_WIDTH = 250
# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
# external symbols imported via tag files in a separate window.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
EXT_LINKS_IN_WINDOW = NO
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
# the HTML output. These images will generally look nicer at scaled resolutions.
# Possible values are: png (the default) and svg (looks nicer but requires the
# pdf2svg or inkscape tool).
# The default value is: png.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FORMULA_FORMAT = png
# Use this tag to change the font size of LaTeX formulas included as images in
# the HTML documentation. When you change the font size after a successful
# doxygen run you need to manually remove any form_*.png images from the HTML
# output directory to force them to be regenerated.
# Minimum value: 8, maximum value: 50, default value: 10.
# This tag requires that the tag GENERATE_HTML is set to YES.
FORMULA_FONTSIZE = 10
# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are not
# supported properly for IE 6.0, but are supported on all modern browsers.
#
# Note that when changing this option you need to delete any form_*.png files in
# the HTML output directory before the changes have effect.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
FORMULA_TRANSPARENT = YES
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
# to create new LaTeX commands to be used in formulas as building blocks. See
# the section "Including formulas" for details.
FORMULA_MACROFILE =
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# https://www.mathjax.org) which uses client side JavaScript for the rendering
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path
# to it using the MATHJAX_RELPATH option.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
USE_MATHJAX = NO
# When MathJax is enabled you can set the default output format to be used for
# the MathJax output. See the MathJax site (see:
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details.
# Possible values are: HTML-CSS (which is slower, but has the best
# compatibility), NativeMML (i.e. MathML) and SVG.
# The default value is: HTML-CSS.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_FORMAT = HTML-CSS
# When MathJax is enabled you need to specify the location relative to the HTML
# output directory using the MATHJAX_RELPATH option. The destination directory
# should contain the MathJax.js script. For instance, if the mathjax directory
# is located at the same level as the HTML output directory, then
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
# MathJax from https://www.mathjax.org before deployment.
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
# extension names that should be enabled during MathJax rendering. For example
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_EXTENSIONS =
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
# of code that will be used on startup of the MathJax code. See the MathJax site
# (see:
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an
# example see the documentation.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_CODEFILE =
# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
# the HTML output. The underlying search engine uses javascript and DHTML and
# should work on any modern browser. Note that when using HTML help
# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
# there is already a search function so this one should typically be disabled.
# For large projects the javascript based search engine can be slow, then
# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
# search using the keyboard; to jump to the search box use + S
# (what the is depends on the OS and browser, but it is typically
# , /, or both). Inside the search box use the to jump into the search results window, the results can be navigated
# using the . Press to select an item or to cancel
# the search. The filter options can be selected when the cursor is inside the
# search box by pressing +. Also here use the
# to select a filter and or to activate or cancel the filter
# option.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using JavaScript. There
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
# setting. When disabled, doxygen will generate a PHP script for searching and
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
# and searching needs to be provided by external tools. See the section
# "External Indexing and Searching" for details.
# The default value is: NO.
# This tag requires that the tag SEARCHENGINE is set to YES.
SERVER_BASED_SEARCH = NO
# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
# script for searching. Instead the search results are written to an XML file
# which needs to be processed by an external indexer. Doxygen will invoke an
# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
# search results.
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see:
# https://xapian.org/).
#
# See the section "External Indexing and Searching" for details.
# The default value is: NO.
# This tag requires that the tag SEARCHENGINE is set to YES.
EXTERNAL_SEARCH = NO
# The SEARCHENGINE_URL should point to a search engine hosted by a web server
# which will return the search results when EXTERNAL_SEARCH is enabled.
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see:
# https://xapian.org/). See the section "External Indexing and Searching" for
# details.
# This tag requires that the tag SEARCHENGINE is set to YES.
SEARCHENGINE_URL =
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
# search data is written to a file for indexing by an external tool. With the
# SEARCHDATA_FILE tag the name of this file can be specified.
# The default file is: searchdata.xml.
# This tag requires that the tag SEARCHENGINE is set to YES.
SEARCHDATA_FILE = searchdata.xml
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
# projects and redirect the results back to the right project.
# This tag requires that the tag SEARCHENGINE is set to YES.
EXTERNAL_SEARCH_ID =
# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
# projects other than the one defined by this configuration file, but that are
# all added to the same external search index. Each project needs to have a
# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
# to a relative location where the documentation can be found. The format is:
# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
# This tag requires that the tag SEARCHENGINE is set to YES.
EXTRA_SEARCH_MAPPINGS =
#---------------------------------------------------------------------------
# Configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
# The default value is: YES.
GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
# it.
# The default directory is: latex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked.
#
# Note that when not enabling USE_PDFLATEX the default is latex when enabling
# USE_PDFLATEX the default is pdflatex and when in the later case latex is
# chosen this is overwritten by pdflatex. For specific output languages the
# default can have been set differently, this depends on the implementation of
# the output language.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_CMD_NAME =
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
# index for LaTeX.
# Note: This tag is used in the Makefile / make.bat.
# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
# (.tex).
# The default file is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
MAKEINDEX_CMD_NAME = makeindex
# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
# generate index for LaTeX. In case there is no backslash (\) as first character
# it will be automatically added in the LaTeX code.
# Note: This tag is used in the generated output file (.tex).
# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
# The default value is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_MAKEINDEX_CMD = makeindex
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
# documents. This may be useful for small projects and may help to save some
# trees in general.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
COMPACT_LATEX = NO
# The PAPER_TYPE tag can be used to set the paper type that is used by the
# printer.
# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
# 14 inches) and executive (7.25 x 10.5 inches).
# The default value is: a4.
# This tag requires that the tag GENERATE_LATEX is set to YES.
PAPER_TYPE = a4
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
# that should be included in the LaTeX output. The package can be specified just
# by its name or with the correct syntax as to be used with the LaTeX
# \usepackage command. To get the times font for instance you can specify :
# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
# To use the option intlimits with the amsmath package you can specify:
# EXTRA_PACKAGES=[intlimits]{amsmath}
# If left blank no extra packages will be included.
# This tag requires that the tag GENERATE_LATEX is set to YES.
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
# generated LaTeX document. The header should contain everything until the first
# chapter. If it is left blank doxygen will generate a standard header. See
# section "Doxygen usage" for information on how to let doxygen write the
# default header to a separate file.
#
# Note: Only use a user-defined header if you know what you are doing! The
# following commands have a special meaning inside the header: $title,
# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
# string, for the replacement values of the other commands the user is referred
# to HTML_HEADER.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HEADER =
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
# generated LaTeX document. The footer should contain everything after the last
# chapter. If it is left blank doxygen will generate a standard footer. See
# LATEX_HEADER for more information on how to generate a default footer and what
# special commands can be used inside the footer.
#
# Note: Only use a user-defined footer if you know what you are doing!
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_FOOTER =
# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# LaTeX style sheets that are included after the standard style sheets created
# by doxygen. Using this option one can overrule certain style aspects. Doxygen
# will copy the style sheet files to the output directory.
# Note: The order of the extra style sheet files is of importance (e.g. the last
# style sheet in the list overrules the setting of the previous ones in the
# list).
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EXTRA_STYLESHEET =
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the LATEX_OUTPUT output
# directory. Note that the files will be copied as-is; there are no commands or
# markers available.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EXTRA_FILES =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
# contain links (just like the HTML output) instead of page references. This
# makes the output suitable for online browsing using a PDF viewer.
# The default value is: YES.
# This tag requires that the tag GENERATE_LATEX is set to YES.
PDF_HYPERLINKS = YES
# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as
# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX
# files. Set this option to YES, to get a higher quality PDF documentation.
#
# See also section LATEX_CMD_NAME for selecting the engine.
# The default value is: YES.
# This tag requires that the tag GENERATE_LATEX is set to YES.
USE_PDFLATEX = YES
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
# command to the generated LaTeX files. This will instruct LaTeX to keep running
# if errors occur, instead of asking the user for help. This option is also used
# when generating formulas in HTML.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_BATCHMODE = NO
# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
# index chapters (such as File Index, Compound Index, etc.) in the output.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HIDE_INDICES = NO
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
# code with syntax highlighting in the LaTeX output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_SOURCE_CODE = NO
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
# The default value is: plain.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_BIB_STYLE = plain
# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
# page will contain the date and time when the page was generated. Setting this
# to NO can help when comparing the output of multiple runs.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_TIMESTAMP = NO
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
# path from which the emoji images will be read. If a relative path is entered,
# it will be relative to the LATEX_OUTPUT directory. If left blank the
# LATEX_OUTPUT directory will be used.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
# RTF output is optimized for Word 97 and may not look too pretty with other RTF
# readers/editors.
# The default value is: NO.
GENERATE_RTF = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
# it.
# The default directory is: rtf.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_OUTPUT = rtf
# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
# documents. This may be useful for small projects and may help to save some
# trees in general.
# The default value is: NO.
# This tag requires that the tag GENERATE_RTF is set to YES.
COMPACT_RTF = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
# contain hyperlink fields. The RTF file will contain links (just like the HTML
# output) instead of page references. This makes the output suitable for online
# browsing using Word or some other Word compatible readers that support those
# fields.
#
# Note: WordPad (write) and others do not support links.
# The default value is: NO.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# configuration file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
#
# See also section "Doxygen usage" for information on how to generate the
# default style sheet that doxygen normally uses.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an RTF document. Syntax is
# similar to doxygen's configuration file. A template extensions file can be
# generated using doxygen -e rtf extensionFile.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_EXTENSIONS_FILE =
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
# with syntax highlighting in the RTF output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
# classes and files.
# The default value is: NO.
GENERATE_MAN = NO
# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
# it. A directory man3 will be created inside the directory specified by
# MAN_OUTPUT.
# The default directory is: man.
# This tag requires that the tag GENERATE_MAN is set to YES.
MAN_OUTPUT = man
# The MAN_EXTENSION tag determines the extension that is added to the generated
# man pages. In case the manual section does not start with a number, the number
# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
# optional.
# The default value is: .3.
# This tag requires that the tag GENERATE_MAN is set to YES.
MAN_EXTENSION = .3
# The MAN_SUBDIR tag determines the name of the directory created within
# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
# MAN_EXTENSION with the initial . removed.
# This tag requires that the tag GENERATE_MAN is set to YES.
MAN_SUBDIR =
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
# will generate one additional man file for each entity documented in the real
# man page(s). These additional files only source the real man page, but without
# them the man command would be unable to find the correct page.
# The default value is: NO.
# This tag requires that the tag GENERATE_MAN is set to YES.
MAN_LINKS = NO
#---------------------------------------------------------------------------
# Configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
# captures the structure of the code including all documentation.
# The default value is: NO.
GENERATE_XML = NO
# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
# it.
# The default directory is: xml.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_OUTPUT = xml
# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
# listings (including syntax highlighting and cross-referencing information) to
# the XML output. Note that enabling this will significantly increase the size
# of the XML output.
# The default value is: YES.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_PROGRAMLISTING = YES
# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
# namespace members in file scope as well, matching the HTML output.
# The default value is: NO.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
# that can be used to generate PDF.
# The default value is: NO.
GENERATE_DOCBOOK = NO
# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
# front of it.
# The default directory is: docbook.
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
DOCBOOK_OUTPUT = docbook
# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
# program listings (including syntax highlighting and cross-referencing
# information) to the DOCBOOK output. Note that enabling this will significantly
# increase the size of the DOCBOOK output.
# The default value is: NO.
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
# the structure of the code including all documentation. Note that this feature
# is still experimental and incomplete at the moment.
# The default value is: NO.
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
# file that captures the structure of the code including all documentation.
#
# Note that this feature is still experimental and incomplete at the moment.
# The default value is: NO.
GENERATE_PERLMOD = NO
# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
# output from the Perl module output.
# The default value is: NO.
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
PERLMOD_LATEX = NO
# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
# formatted so it can be parsed by a human reader. This is useful if you want to
# understand what is going on. On the other hand, if this tag is set to NO, the
# size of the Perl module output will be much smaller and Perl will parse it
# just the same.
# The default value is: YES.
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
PERLMOD_PRETTY = YES
# The names of the make variables in the generated doxyrules.make file are
# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
# so different doxyrules.make files included by the same Makefile don't
# overwrite each other's variables.
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
# C-preprocessor directives found in the sources and include files.
# The default value is: YES.
ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
# in the source code. If set to NO, only conditional compilation will be
# performed. Macro expansion can be done in a controlled way by setting
# EXPAND_ONLY_PREDEF to YES.
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and
# EXPAND_AS_DEFINED tags.
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found.
# The default value is: YES.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by the
# preprocessor.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will be
# used.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that are
# defined before the preprocessor is started (similar to the -D option of e.g.
# gcc). The argument of the tag is a list of macros of the form: name or
# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
# is assumed. To prevent a macro definition from being undefined via #undef or
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
# macro definition that is found in the sources will be used. Use the PREDEFINED
# tag if you want to use a different macro definition that overrules the
# definition found in the source code.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have
# an all uppercase name, and do not end with a semicolon. Such function macros
# are typically used for boiler-plate code, and will confuse the parser if not
# removed.
# The default value is: YES.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration options related to external references
#---------------------------------------------------------------------------
# The TAGFILES tag can be used to specify one or more tag files. For each tag
# file the location of the external documentation should be added. The format of
# a tag file without this location is as follows:
# TAGFILES = file1 file2 ...
# Adding location for the tag files is done as follows:
# TAGFILES = file1=loc1 "file2 = loc2" ...
# where loc1 and loc2 can be relative or absolute paths or URLs. See the
# section "Linking to external documentation" for more information about the use
# of tag files.
# Note: Each tag file must have a unique name (where the name does NOT include
# the path). If a tag file is not located in the directory in which doxygen is
# run, you must also specify the path to the tagfile here.
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
# tag file that is based on the input files it reads. See section "Linking to
# external documentation" for more information about the usage of tag files.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
# the class index. If set to NO, only the inherited external classes will be
# listed.
# The default value is: NO.
ALLEXTERNALS = NO
# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
# in the modules index. If set to NO, only the current project's groups will be
# listed.
# The default value is: YES.
EXTERNAL_GROUPS = YES
# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
# the related pages index. If set to NO, only the current project's pages will
# be listed.
# The default value is: YES.
EXTERNAL_PAGES = YES
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
# disabled, but it is recommended to install and use dot, since it yields more
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = YES
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
# If left empty dia is assumed to be found in the default search path.
DIA_PATH =
# If set to YES the inheritance and collaboration graphs will hide inheritance
# and usage relations if the target is undocumented or is not a class.
# The default value is: YES.
HIDE_UNDOC_RELATIONS = YES
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz (see:
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# Bell Labs. The other options in this section have no effect if this option is
# set to NO
# The default value is: YES.
HAVE_DOT = NO
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
# to run in parallel. When set to 0 doxygen will base this on the number of
# processors available in the system. You can set it explicitly to a value
# larger than 0 to get control over the balance between CPU load and processing
# speed.
# Minimum value: 0, maximum value: 32, default value: 0.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_NUM_THREADS = 0
# When you want a differently looking font in the dot files that doxygen
# generates you can specify the font name using DOT_FONTNAME. You need to make
# sure dot is able to find the font, which can be done by putting it in a
# standard location or by setting the DOTFONTPATH environment variable or by
# setting DOT_FONTPATH to the directory containing the font.
# The default value is: Helvetica.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTNAME = Helvetica
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
# dot graphs.
# Minimum value: 4, maximum value: 24, default value: 10.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTSIZE = 10
# By default doxygen will tell dot to use the default font as specified with
# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
# the path where dot can find it using this tag.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTPATH =
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
# each documented class showing the direct and indirect inheritance relations.
# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
# graph for each documented class showing the direct and indirect implementation
# dependencies (inheritance, containment, and class references variables) of the
# class with other documented classes.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
COLLABORATION_GRAPH = YES
# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
# groups, showing the direct groups dependencies.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
GROUP_GRAPHS = YES
# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
# collaboration diagrams in a style similar to the OMG's Unified Modeling
# Language.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
UML_LOOK = NO
# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
# class node. If there are many fields or methods and many nodes the graph may
# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
# number of items for each type to make the size more manageable. Set this to 0
# for no limit. Note that the threshold may be exceeded by 50% before the limit
# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
# but if the number exceeds 15, the total amount of fields shown is limited to
# 10.
# Minimum value: 0, maximum value: 100, default value: 10.
# This tag requires that the tag UML_LOOK is set to YES.
UML_LIMIT_NUM_FIELDS = 10
# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and
# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS
# tag is set to YES, doxygen will add type and arguments for attributes and
# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen
# will not generate fields with class member information in the UML graphs. The
# class diagrams will look similar to the default class diagrams but using UML
# notation for the relationships.
# Possible values are: NO, YES and NONE.
# The default value is: NO.
# This tag requires that the tag UML_LOOK is set to YES.
DOT_UML_DETAILS = NO
# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters
# to display on a single line. If the actual line length exceeds this threshold
# significantly it will wrapped across multiple lines. Some heuristics are apply
# to avoid ugly line breaks.
# Minimum value: 0, maximum value: 1000, default value: 17.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_WRAP_THRESHOLD = 17
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
# collaboration graphs will show the relations between templates and their
# instances.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
TEMPLATE_RELATIONS = NO
# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
# YES then doxygen will generate a graph for each documented file showing the
# direct and indirect include dependencies of the file with other documented
# files.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
INCLUDE_GRAPH = YES
# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
# set to YES then doxygen will generate a graph for each documented file showing
# the direct and indirect include dependencies of the file with other documented
# files.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
INCLUDED_BY_GRAPH = YES
# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
# dependency graph for every global function or class method.
#
# Note that enabling this option will significantly increase the time of a run.
# So in most cases it will be better to enable call graphs for selected
# functions only using the \callgraph command. Disabling a call graph can be
# accomplished by means of the command \hidecallgraph.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
CALL_GRAPH = NO
# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
# dependency graph for every global function or class method.
#
# Note that enabling this option will significantly increase the time of a run.
# So in most cases it will be better to enable caller graphs for selected
# functions only using the \callergraph command. Disabling a caller graph can be
# accomplished by means of the command \hidecallergraph.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
CALLER_GRAPH = NO
# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
# hierarchy of all classes instead of a textual one.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
GRAPHICAL_HIERARCHY = YES
# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
# dependencies a directory has on other directories in a graphical way. The
# dependency relations are determined by the #include relations between the
# files in the directories.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
DIRECTORY_GRAPH = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. For an explanation of the image formats see the section
# output formats in the documentation of the dot tool (Graphviz (see:
# http://www.graphviz.org/)).
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
# to make the SVG files visible in IE 9+ (other browsers do not have this
# requirement).
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
# png:gdiplus:gdiplus.
# The default value is: png.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_IMAGE_FORMAT = png
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
# enable generation of interactive SVG images that allow zooming and panning.
#
# Note that this requires a modern browser other than Internet Explorer. Tested
# and working are Firefox, Chrome, Safari, and Opera.
# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
# the SVG files visible. Older versions of IE do not have SVG support.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
INTERACTIVE_SVG = NO
# The DOT_PATH tag can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found in the path.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_PATH =
# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the \dotfile
# command).
# This tag requires that the tag HAVE_DOT is set to YES.
DOTFILE_DIRS =
# The MSCFILE_DIRS tag can be used to specify one or more directories that
# contain msc files that are included in the documentation (see the \mscfile
# command).
MSCFILE_DIRS =
# The DIAFILE_DIRS tag can be used to specify one or more directories that
# contain dia files that are included in the documentation (see the \diafile
# command).
DIAFILE_DIRS =
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
# path where java can find the plantuml.jar file. If left blank, it is assumed
# PlantUML is not used or called during a preprocessing step. Doxygen will
# generate a warning when it encounters a \startuml command in this case and
# will not generate output for the diagram.
PLANTUML_JAR_PATH =
# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
# configuration file for plantuml.
PLANTUML_CFG_FILE =
# When using plantuml, the specified paths are searched for files specified by
# the !include statement in a plantuml block.
PLANTUML_INCLUDE_PATH =
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
# that will be shown in the graph. If the number of nodes in a graph becomes
# larger than this value, doxygen will truncate the graph, which is visualized
# by representing a node as a red box. Note that doxygen if the number of direct
# children of the root node in a graph is already larger than
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
# Minimum value: 0, maximum value: 10000, default value: 50.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_GRAPH_MAX_NODES = 50
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
# generated by dot. A depth value of 3 means that only nodes reachable from the
# root by following a path via at most 3 edges will be shown. Nodes that lay
# further from the root node will be omitted. Note that setting this option to 1
# or 2 may greatly reduce the computation time needed for large code bases. Also
# note that the size of a graph can be further restricted by
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
# Minimum value: 0, maximum value: 1000, default value: 0.
# This tag requires that the tag HAVE_DOT is set to YES.
MAX_DOT_GRAPH_DEPTH = 0
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
# background. This is disabled by default, because dot on Windows does not seem
# to support this out of the box.
#
# Warning: Depending on the platform used, enabling this option may lead to
# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
# read).
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_TRANSPARENT = NO
# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
# files in one run (i.e. multiple -o and -T options on the command line). This
# makes dot run faster, but since only newer versions of dot (>1.8.10) support
# this, this feature is disabled by default.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_MULTI_TARGETS = YES
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
# explaining the meaning of the various boxes and arrows in the dot generated
# graphs.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
# files that are used to generate the various graphs.
#
# Note: This setting is not only used for dot files but also for msc and
# plantuml temporary files.
# The default value is: YES.
DOT_CLEANUP = YES
libad9361-iio-0.3/LICENSE 0000664 0000000 0000000 00000063536 14424151631 0014553 0 ustar 00root root 0000000 0000000 GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
(This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.)
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random
Hacker.
{signature of Ty Coon}, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
libad9361-iio-0.3/README.md 0000664 0000000 0000000 00000020211 14424151631 0015004 0 ustar 00root root 0000000 0000000 # libad9361-iio
This is a simple library used for userspace,
- which manages multi-chip sync (on platforms (FMCOMMS5) where multiple AD9361 devices are use)
- can create AD9361 specific FIR filters on the fly,
**Docs**
Doxygen-based documentation is available at: http://analogdevicesinc.github.io/libad9361-iio/
License : [](https://github.com/analogdevicesinc/libad9361-iio/blob/master/COPYING.txt)
Latest Release : [](https://github.com/analogdevicesinc/libad9361-iio/releases/latest)
Downloads : [](https://github.com/analogdevicesinc/libad9361-iio/releases/latest)
As with many open source packages, we use [GitHub](https://github.com/analogdevicesinc/libad9361-iio) to do develop and maintain the source, and [Travis CI](https://travis-ci.com/) and [Appveyor](https://www.appveyor.com/) for continuous integration.
- If you want to just use libad9361-iio, we suggest using the [latest release](https://github.com/analogdevicesinc/libad9361-iio/releases/latest).
- If you think you have found a bug in the release, or need a feature which isn't in the release, try the latest **untested** binaries from the master branch. We provide builds for a few operating systems. If you need something else, we can most likely add that -- just ask.
| Operating System | GitHub master status | Version | Installer Package | tarball or zip |
|:-----------------------:|:---------------------:|:-------:|:-------------------:|:--------------:|
| Windows | [](https://ci.appveyor.com/project/analogdevicesinc/libad9361-iio/branch/master) | Windows 10 Windows 8.1 Windows 8 Windows 7 | [](https://ci.appveyor.com/api/projects/analogdevicesinc/libad9361-iio/artifacts/libad9361-setup.exe?branch=master) | Win32 : [](https://ci.appveyor.com/api/projects/analogdevicesinc/libad9361-iio/artifacts/libad9361-win32.zip?branch=master) Win64: [](https://ci.appveyor.com/api/projects/analogdevicesinc/libad9361-iio/artifacts/libad9361-win64.zip?branch=master) |
| OS X | [](https://travis-ci.org/analogdevicesinc/libad9361-iio) | OS X Mojave (v 10.14) | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-darwin-10.14.4.pkg) | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-darwin-10.14.4.tar.gz) |
| | | OS X High Sierra (v 10.13) | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-darwin-10.13.6.pkg) | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-darwin-10.13.6.tar.gz) |
| | | macOS Sierra (v 10.12) | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-darwin-10.12.6.pkg) | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-darwin-10.12.6.tar.gz) |
| Linux | [](https://travis-ci.org/analogdevicesinc/libad9361-iio) | Ubuntu Bionic Beaver (v 18.04)1 | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-ubuntu-18.04-amd64.deb) | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-ubuntu-18.04-amd64.rpm) [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-ubuntu-18.04-amd64.tar.gz) |
| | | Ubuntu Xenial Xerus (v 16.04)1 | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-ubuntu-16.04-amd64.deb) | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-ubuntu-16.04-amd64.rpm) [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-ubuntu-16.04-amd64.tar.gz) |
| | | CentOS 7 | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-centos-7-x86_64.rpm) | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-centos-7-x86_64.deb) [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-centos-7-x86_64.tar.gz) |
| | | CentOS 6 | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-centos-6.10-x86_64.rpm) | [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-centos-6.10-x86_64.deb) [](http://swdownloads.analog.com/cse/travis_builds/master_latest_libad9361-iio-centos-6.10-x86_64.tar.gz) |
If you use it, and like it - please let us know. If you use it, and hate it - please let us know that too. The goal of the project is to try to make Linux IIO devices easier to use on a variety of platforms. If we aren't doing that - we will try to make it better.
## Building & Installing
should be a quick matter of `cmake`, then `make`, then `make install`:
```
rgetz@pinky:~/libad9361-iio$ cmake ./CMakeLists.txt
-- The C compiler identification is GNU 4.7.2
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/rgetz/libad9361-iio
rgetz@pinky:~/libad9361-iio$ make
Scanning dependencies of target ad9361
[100%] Building C object CMakeFiles/ad9361.dir/ad9361_multichip_sync.c.o
Linking C shared library libad9361.so
Copying OS X content Headers/ad9361.h
[100%] Built target ad9361
rgetz@pinky:~/libad9361-iio$ sudo make install
[sudo] password for rgetz:
[100%] Built target ad9361
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/pkgconfig/libad9361.pc
-- Installing: /usr/local/lib/libad9361.so.0.1
-- Installing: /usr/local/lib/libad9361.so.0
-- Installing: /usr/local/lib/libad9361.so
-- Installing: /usr/local/include/ad9361.h
```
libad9361-iio-0.3/ad9361.h 0000664 0000000 0000000 00000024707 14424151631 0014623 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2015 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
/** @file ad9361.h
* @brief Public interface */
#ifndef __AD9361_H__
#define __AD9361_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup FLAGS MCS Flags
*
* @{
*/
/** Flag for ad9361_multichip_sync which verifies interface timing between
master and all slaves is identical
*/
#define FIXUP_INTERFACE_TIMING 1
/** Flag for ad9361_multichip_sync which checks if master and associated slaves
have the same sample rate
*/
#define CHECK_SAMPLE_RATES 2
/** @} */
#ifdef _WIN32
# ifdef LIBAD9361_EXPORTS
# define __api __declspec(dllexport)
# else
# define __api __declspec(dllimport)
# endif
#elif __GNUC__ >= 4 && !defined(MATLAB_MEX_FILE) && !defined(MATLAB_LOADLIBRARY)
# define __api __attribute__((visibility ("default")))
#else
# define __api
#endif
struct iio_context;
struct iio_device;
/**
* @struct filter_design_parameters
* @brief Custom Filter Design Parameters
*
* A structure for custom filter designs for the AD936X programmable FIR
* in both TX and RX paths.
*/
struct filter_design_parameters {
double Rdata; /**< Data rate of digital interface */
double Fpass; /**< Stop edge frequency in hertz of passband */
double Fstop; /**< Start edge frequency in hertz of stopband */
double caldiv; /**< Baseband analog filter calibration divider setting [1-511] */
double FIR; /**< Decimation/Interpolation setting of FIR [1,2,4] */
double HB1; /**< Decimation/Interpolation setting of HB1 [1,2] */
double DAC_div; /**< Divider enable setting of DAC clock [0,1] */
const char *Type; /**< Designer mode (only Lowpass supported) */
const char *RxTx; /**< Filter path [Tx,Rx] */
double RFbw; /**< 3dB corner of analog filter in hertz */
double converter_rate; /**< Rate of ADC in hertz */
double PLL_rate; /**< Rate of PLL in hertz */
double Fcenter; /**< Center frequency in hertz of bandpass (Unused) */
double wnom; /**< RF bandwidth of analog filter in hertz */
double FIRdBmin; /**< Minimum stop band attentuation of the FIR in dB */
double int_FIR; /**< Enable use of internal FIR filter [0,1] */
double PLL_mult; /**< Ratio of converter to PLL rate */
double Apass; /**< Desired passband ripple in dB */
double Astop; /**< Desired stopband attenuation in dB */
double phEQ; /**< Enable phase equalization [0,1] */
double HB2; /**< Decimation/Interpolation setting of HB2 [1,2] */
double HB3; /**< Decimation/Interpolation setting of HB3 [1,2,3] */
double maxTaps; /**< Maximum allowed FIR taps */
};
/* ---------------------------------------------------------------------------*/
/* ------------------------- Top-level functions -----------------------------*/
/** @defgroup TopLevel Top-level functions
* @{ */
/** @brief Multi-chip synchronization (MCS) management
* @param master A pointer to an iio_device structure
* @param slaves A double pointer to an iio_device structure
* @param num_slaves Number of slave devices associated with the master
* @param flags Control flags for MCS configuration
* @return On success, 0 is returned
* @return On error, a negative errno code is returned */
__api int ad9361_multichip_sync(struct iio_device *master,
struct iio_device **slaves, unsigned int num_slaves,
unsigned int flags);
/** @brief FMComms5 specific MCS management
* @param ctx A pointer to an iio_context structure
* @param flags Control flags for MCS configuration
* @return On success, 0 is returned
* @return On error, a negative errno code is returned */
__api int ad9361_fmcomms5_multichip_sync(
struct iio_context *ctx, unsigned int flags);
/** @brief Baseband rate configuration with generic filter support
* @param dev A pointer to an iio_device structure
* @param rate Rate in samples per second of desired baseband rate
* @return On success, 0 is returned
* @return On error, a negative errno code is returned
*
* NOTE: Three possible filters are loaded based on required rate and
* associated decimation/interpolation. These filters are generally very wide
* band and not waveform specific. */
__api int ad9361_set_bb_rate(struct iio_device *dev, unsigned long rate);
/** @brief Enable or disable transmit and receiver FIRs simultaneously
* @param dev A pointer to an iio_device structure
* @param enable Integer to enable FIRs when 1 or disable when 0
* @return On success, 0 is returned
* @return On error, a negative errno code is returned */
__api int ad9361_set_trx_fir_enable(struct iio_device *dev, int enable);
/** @brief Get current enable value of transmit and receiver FIRs
* @param dev A pointer to an iio_device structure
* @param enable Returned integer value of FIR enabled
* @return On success, 0 is returned
* @return On error, a negative errno code is returned */
__api int ad9361_get_trx_fir_enable(struct iio_device *dev, int *enable);
/** @brief Design custom FIR filter from specific design criteria
* @param parameters A pointer filter designer structure
* @param taps A pointer to taps of designed filter
* @param num_taps A pointer to integer number of taps designed in taps
* @param gain Integer gain for designed filter
* @return On success, 0 is returned
* @return On error, a negative errno code is returned */
__api int ad9361_generate_fir_taps(struct filter_design_parameters *parameters,
short *taps, int *num_taps, int *gain);
/** @brief Calculate the clock path rates for both transmit and receiver paths
* @param tx_sample_rate Sample rate in samples per second of desired baseband rate
* @param rate_gov Rate governor enable setting forcing HB3=3 when enabled
* @param rx_path_clks A pointer to a unsigned long variable where the 6 RX path rates should be stored
* @param tx_path_clks A pointer to a unsigned long variable where the 6 TX path rates should be stored
* @return On success, 0 is returned
* @return On error, a negative errno code is returned */
__api int ad9361_calculate_rf_clock_chain(unsigned long tx_sample_rate,
unsigned long rate_gov,
unsigned long *rx_path_clks,
unsigned long *tx_path_clks);
/** @brief Calculate the clock path rates and default filter settings for both transmit and receiver for a desired baseband rate
* @param fdpTX Filter design parameters structure where TX filter design parameters will be stored
* @param fdpRX Filter design parameters structure where RX filter design parameters will be stored
* @param sample_rate Desired basedband sample rate in samples per second for both RX and TX filter configurations
* @return On success, 0 is returned
* @return On error, a negative errno code is returned */
__api int ad9361_calculate_rf_clock_chain_fdp(struct filter_design_parameters *fdpTX,
struct filter_design_parameters *fdpRX,
unsigned long sample_rate);
/** @brief Baseband rate configuration with custom filter support based on desired baseband sample rate
* @param dev A pointer to an iio_device structure
* @param rate Rate in samples per second of desired baseband rate
* @return On success, 0 is returned
* @return On error, a negative errno code is returned
*
* NOTE: Designed filter will have the following configuration:
* Fpass = rate / 3
* Fstop = Fpass * 1.25
* wnomTX = 1.6 * Fstop
* wnomRX = 1.4 * Fstop */
__api int ad9361_set_bb_rate_custom_filter_auto(struct iio_device *dev,
unsigned long rate);
/** @brief Baseband rate configuration with custom filter support based on desired baseband sample rate and simplified filter configuration
* @param dev A pointer to an iio_device structure
* @param rate Rate in samples per second of desired baseband rate
* @param Fpass Stop edge frequency in hertz of passband
* @param Fstop Start edge frequency in hertz of stopband
* @param wnom_tx TX RF bandwidth of analog filter in hertz
* @param wnom_rx RX RF bandwidth of analog filter in hertz
* @return On success, 0 is returned
* @return On error, a negative errno code is returned */
__api int ad9361_set_bb_rate_custom_filter_manual(struct iio_device *dev,
unsigned long rate, unsigned long Fpass,
unsigned long Fstop, unsigned long wnom_tx,
unsigned long wnom_rx);
/** @brief FMComms5 phase synchronize all TX and RX channels together
* @param ctx A pointer to an iio_context structure
* @param lo Frequency in hertz of LO for TX and RX
* @return On success, 0 is returned
* @return On error, a negative errno code is returned. If -2 is returned calibration failed
*
* NOTES: To perform calibration the following side effects occur:
* - RF bandwidths of both TX and RX are expanded to the current sample rate. It can be changed after calibration without effecting phase synchronization.
* - DDSs are enabled and left on after synchronization. Changing these DDSs or switching to DMA sources will not effect phase synchronization.
* - TX and RX LOs are set to the same frequency based on the input provided. LO changes can invalidate phase synchronization.
* - AGCs are set to manual mode at predetermined hardware gains for TX and RX. Gain changes can invalidate phase synchronization.
*
* Phase synchronization is valid until the LOs are retuned or sample rates change or gains are modified.
*
* External Links:
* - Detailed information on synchronization process
* - Phase synchronization performance can depend on revision of hardware */
__api int ad9361_fmcomms5_phase_sync(struct iio_context *ctx, long long lo);
/** @} */
#ifdef __cplusplus
}
#endif
#undef __api
#endif /* __AD9361_H__ */
libad9361-iio-0.3/ad9361_baseband_auto_rate.c 0000664 0000000 0000000 00000012601 14424151631 0020466 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2016 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#include "ad9361.h"
#include
#include
#include
#ifdef _WIN32
#include
#else
#include
#endif
#ifdef _MSC_BUILD
#define snprintf sprintf_s
#endif
static int16_t fir_128_4[] = {
-15,-27,-23,-6,17,33,31,9,-23,-47,-45,-13,34,69,67,21,-49,-102,-99,-32,69,146,143,48,-96,-204,-200,-69,129,278,275,97,-170,
-372,-371,-135,222,494,497,187,-288,-654,-665,-258,376,875,902,363,-500,-1201,-1265,-530,699,1748,1906,845,-1089,-2922,-3424,
-1697,2326,7714,12821,15921,15921,12821,7714,2326,-1697,-3424,-2922,-1089,845,1906,1748,699,-530,-1265,-1201,-500,363,902,875,
376,-258,-665,-654,-288,187,497,494,222,-135,-371,-372,-170,97,275,278,129,-69,-200,-204,-96,48,143,146,69,-32,-99,-102,-49,21,
67,69,34,-13,-45,-47,-23,9,31,33,17,-6,-23,-27,-15};
static int16_t fir_128_2[] = {
-0,0,1,-0,-2,0,3,-0,-5,0,8,-0,-11,0,17,-0,-24,0,33,-0,-45,0,61,-0,-80,0,104,-0,-134,0,169,-0,
-213,0,264,-0,-327,0,401,-0,-489,0,595,-0,-724,0,880,-0,-1075,0,1323,-0,-1652,0,2114,-0,-2819,0,4056,-0,-6883,0,20837,32767,
20837,0,-6883,-0,4056,0,-2819,-0,2114,0,-1652,-0,1323,0,-1075,-0,880,0,-724,-0,595,0,-489,-0,401,0,-327,-0,264,0,-213,-0,
169,0,-134,-0,104,0,-80,-0,61,0,-45,-0,33,0,-24,-0,17,0,-11,-0,8,0,-5,-0,3,0,-2,-0,1,0,-0, 0 };
static int16_t fir_96_2[] = {
-4,0,8,-0,-14,0,23,-0,-36,0,52,-0,-75,0,104,-0,-140,0,186,-0,-243,0,314,-0,-400,0,505,-0,-634,0,793,-0,
-993,0,1247,-0,-1585,0,2056,-0,-2773,0,4022,-0,-6862,0,20830,32767,20830,0,-6862,-0,4022,0,-2773,-0,2056,0,-1585,-0,1247,0,-993,-0,
793,0,-634,-0,505,0,-400,-0,314,0,-243,-0,186,0,-140,-0,104,0,-75,-0,52,0,-36,-0,23,0,-14,-0,8,0,-4,0};
static int16_t fir_64_2[] = {
-58,0,83,-0,-127,0,185,-0,-262,0,361,-0,-488,0,648,-0,-853,0,1117,-0,-1466,0,1954,-0,-2689,0,3960,-0,-6825,0,20818,32767,
20818,0,-6825,-0,3960,0,-2689,-0,1954,0,-1466,-0,1117,0,-853,-0,648,0,-488,-0,361,0,-262,-0,185,0,-127,-0,83,0,-58,0};
#define FIR_BUF_SIZE 8192
int ad9361_set_trx_fir_enable(struct iio_device *dev, int enable)
{
int ret = iio_device_attr_write_bool(dev,
"in_out_voltage_filter_fir_en", !!enable);
if (ret < 0)
ret = iio_channel_attr_write_bool(iio_device_find_channel(dev, "out", false),
"voltage_filter_fir_en", !!enable);
return ret;
}
int ad9361_get_trx_fir_enable(struct iio_device *dev, int *enable)
{
bool value;
int ret = iio_device_attr_read_bool(dev, "in_out_voltage_filter_fir_en", &value);
if (ret < 0)
ret = iio_channel_attr_read_bool(iio_device_find_channel(dev, "out", false),
"voltage_filter_fir_en", &value);
if (!ret)
*enable = value;
return ret;
}
int ad9361_set_bb_rate(struct iio_device *dev, unsigned long rate)
{
struct iio_channel *chan;
long long current_rate;
int dec, taps, ret, i, enable, len = 0;
int16_t *fir;
char *buf;
if (rate <= 20000000UL) {
dec = 4;
taps = 128;
fir = fir_128_4;
} else if (rate <= 40000000UL) {
dec = 2;
fir = fir_128_2;
taps = 128;
} else if (rate <= 53333333UL) {
dec = 2;
fir = fir_96_2;
taps = 96;
} else {
dec = 2;
fir = fir_64_2;
taps = 64;
}
chan = iio_device_find_channel(dev, "voltage0", true);
if (chan == NULL)
return -ENODEV;
ret = iio_channel_attr_read_longlong(chan, "sampling_frequency", ¤t_rate);
if (ret < 0)
return ret;
ret = ad9361_get_trx_fir_enable(dev, &enable);
if (ret < 0)
return ret;
if (enable) {
if (current_rate <= (25000000 / 12))
iio_channel_attr_write_longlong(chan, "sampling_frequency", 3000000);
ret = ad9361_set_trx_fir_enable(dev, false);
if (ret < 0)
return ret;
}
buf = malloc(FIR_BUF_SIZE);
if (!buf)
return -ENOMEM;
len += snprintf(buf + len, FIR_BUF_SIZE - len, "RX 3 GAIN -6 DEC %d\n", dec);
len += snprintf(buf + len, FIR_BUF_SIZE - len, "TX 3 GAIN 0 INT %d\n", dec);
for (i = 0; i < taps; i++)
len += snprintf(buf + len, FIR_BUF_SIZE - len, "%d,%d\n", fir[i], fir[i]);
len += snprintf(buf + len, FIR_BUF_SIZE - len, "\n");
ret = iio_device_attr_write_raw(dev, "filter_fir_config", buf, len);
free (buf);
if (ret < 0)
return ret;
if (rate <= (25000000 / 12)) {
int dacrate, txrate, max;
char readbuf[100];
ret = iio_device_attr_read(dev, "tx_path_rates", readbuf, sizeof(readbuf));
if (ret < 0)
return ret;
ret = sscanf(readbuf, "BBPLL:%*d DAC:%d T2:%*d T1:%*d TF:%*d TXSAMP:%d", &dacrate, &txrate);
if (ret != 2)
return -EFAULT;
if (txrate == 0)
return -EINVAL;
max = (dacrate / txrate) * 16;
if (max < taps)
iio_channel_attr_write_longlong(chan, "sampling_frequency", 3000000);
ret = ad9361_set_trx_fir_enable(dev, true);
if (ret < 0)
return ret;
ret = iio_channel_attr_write_longlong(chan, "sampling_frequency", rate);
if (ret < 0)
return ret;
} else {
ret = iio_channel_attr_write_longlong(chan, "sampling_frequency", rate);
if (ret < 0)
return ret;
ret = ad9361_set_trx_fir_enable(dev, true);
if (ret < 0)
return ret;
}
return 0;
}
libad9361-iio-0.3/ad9361_calculate_rf_clock_chain.c 0000664 0000000 0000000 00000014061 14424151631 0021627 0 ustar 00root root 0000000 0000000
#include "ad9361.h"
#include
#include
#include
#include
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define MIN_ADC_CLK 25000000UL /* 25 MHz */
#define MAX_ADC_CLK 640000000UL /* 640 MHz */
#define MIN_DAC_CLK 25000000UL /* 25 MHz */
#define MAX_DAC_CLK (MAX_ADC_CLK / 2)
#define MAX_BBPLL_FREF 70007000UL /* 70 MHz + 100ppm */
#define MIN_BBPLL_FREQ 714928500UL /* 715 MHz - 100ppm */
#define MAX_BBPLL_FREQ 1430143000UL /* 1430 MHz + 100ppm */
#define MAX_BBPLL_DIV 64
#define MIN_BBPLL_DIV 2
#define MAX_DATA_RATE 61440000UL // Output of FIR (RX)
#define MIN_DATA_RATE MIN_ADC_CLK / 48
// Output of FIR on RX
#define MAX_FIR MAX_DATA_RATE * 2
// Associated with outputs of stage
#define MAX_RX_HB1 122880000UL
#define MAX_RX_HB2 245760000UL
#define MAX_RX_HB3 320000000UL
// Associated with inputs of stage
#define MAX_TX_HB1 122880000UL
#define MAX_TX_HB2 245760000UL
#define MAX_TX_HB3 320000000UL
const unsigned long RX_MAX_PATH_RATES[] = {MAX_ADC_CLK, MAX_RX_HB3, MAX_RX_HB2, MAX_RX_HB1, MAX_FIR};
const unsigned long TX_MAX_PATH_RATES[] = {MAX_DAC_CLK, MAX_TX_HB3, MAX_TX_HB2, MAX_TX_HB1, MAX_FIR};
const unsigned long RX_MIN_PATH_RATES[] = {MIN_ADC_CLK, 0, 0, 0, 0};
const unsigned long TX_MIN_PATH_RATES[] = {MIN_DAC_CLK, 0, 0, 0, 0};
#define check(val,min,max) ( (val)<=(max) ? (val)>=(min) : false )
unsigned long max_rate_found;
bool check_rates(int FIR, const int *HB_configs, unsigned long samp_rate,
unsigned long *rates)
{
int j;
bool c = true;
rates[5] = samp_rate;
for (j=4; j>0; j--) {
rates[j] = rates[j+1]*HB_configs[j-1];
if (j>1) {
c &= check(rates[j],TX_MIN_PATH_RATES[j-1],TX_MAX_PATH_RATES[j-1]);
c &= check(rates[j],RX_MIN_PATH_RATES[j-1],RX_MAX_PATH_RATES[j-1]);
}
}
return c;
}
int determine_pll_div(unsigned long *rates)
{
// Determine necessary PLL multiplier
unsigned long long tmp;
int PLL_mult = MAX_BBPLL_DIV;
while (PLL_mult>1) {
tmp = (unsigned long long) rates[1]*PLL_mult;
if (check(tmp, MIN_BBPLL_FREQ, MAX_BBPLL_FREQ)) {
rates[0] = (unsigned long) rates[1]*PLL_mult;
return PLL_mult;
}
PLL_mult >>= 1;
}
return -1;
}
int check_dac_adc_config(unsigned long pll_bb, int PLL_mult,
int dec_table_index)
{
// Need to determine if DAC divider is required and if ADC and DAC rates
// can be satisfied
unsigned long with_dd, without_dd;
bool a, b, c;
with_dd = pll_bb/PLL_mult/2;
without_dd = pll_bb/PLL_mult/1;
a = check(with_dd, MIN_DAC_CLK, MAX_DAC_CLK);
b = check(without_dd, MIN_ADC_CLK, MAX_ADC_CLK);
c = check(without_dd, MIN_DAC_CLK, MAX_DAC_CLK);
if (c && b)
return 1; // Run without dac div
else if (a && b && (dec_table_index<5))
return 2; // Run with dac div
else
return -1;
}
void set_rates(unsigned long *rx_path_clks,
unsigned long *tx_path_clks, int DAC_div, unsigned long *rates,
int dec_table_index)
{
int k;
// Check if ADC will run faster in config
if (rates[1]>max_rate_found)
max_rate_found = rates[1];
else
return;
for (k=0; k<6; k++) {
rx_path_clks[k] = rates[k];
tx_path_clks[k] = rates[k];
if (k>0) { // Adjust HB's for DAC divider setting
if ((dec_table_index<2) && (k<4))
tx_path_clks[k] = rates[k]/DAC_div;
else if ((dec_table_index<4) && (k<3))
tx_path_clks[k] = rates[k]/DAC_div;
}
}
}
int determine_path_rates_with_fir(unsigned long sample_rate,
unsigned long rate_gov,
unsigned long *rx_path_clks,
unsigned long *tx_path_clks,
int FIR)
{
unsigned long rates[6];
int PLL_mult, k;
max_rate_found = 0UL;
const int HB_configs[][4] = {
{3,2,2,FIR}, //12
{2,2,2,FIR}, //8
{3,2,1,FIR}, //6
{2,2,1,FIR}, //4
{2,1,1,FIR}, //2
{3,1,1,FIR}, //3
{1,1,1,FIR}, //1
};
// RX Path:
// BBPLL -> /PLL_div -> /HB3 -> /HB2 -> /HB1 -> /FIR
// TX Path:
// BBPLL -> /(PLL_div*DAC_div) -> /HB3 -> /HB2 -> /HB1 -> /FIR
// Cycle through possible decimations from highest to lowest
for (k=0; k<7; k++) {
// HB3 cannot be 3 if rate_gov enabled
if ((rate_gov>0) && HB_configs[k][0]==3)
continue;
// Check if HB and FIR rates are valid
if ( check_rates(FIR, HB_configs[k], sample_rate, rates) ) {
// Calculate PLL divider for configuration
PLL_mult = determine_pll_div(rates);
if (PLL_mult>0) {
// Determine DAC divider setting and check ADC/DAC settings
int dac_div = check_dac_adc_config(rates[0], PLL_mult, k);
// printf("dac_div: %d\n",dac_div);
if (dac_div>0)
set_rates(rx_path_clks, tx_path_clks, dac_div, rates, k);
}
}
}
if (max_rate_found==0UL)
return -EINVAL;
else
return 0;
}
int ad9361_calculate_rf_clock_chain(unsigned long sample_rate,
unsigned long rate_gov,
unsigned long *rx_path_clks,
unsigned long *tx_path_clks)
{
int ret, k;
int FIR[] = {4,2,1};
// Check desired rate within bounds
if (!check(sample_rate, MIN_DATA_RATE, MAX_DATA_RATE))
return -EINVAL;
// Rate selection will try to:
// 1. Utilize the maximum decimation in the FIR
// 2. Run the ADC/DAC as fast as possible
// 3. Use the most decimation possible starting with HB3(closest to ADC)->HB1
// Cycle through available FIR settings
for (k=0; k<3; k++) {
ret = determine_path_rates_with_fir(sample_rate, rate_gov, rx_path_clks,
tx_path_clks, FIR[k]);
if (ret==0)
break;
}
return ret;
}
libad9361-iio-0.3/ad9361_design_taps.c 0000664 0000000 0000000 00000030271 14424151631 0017167 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#include "ad9361.h"
#include "filterdesigner/internal_design_filter_cg.h"
#include
#include
#include
#include
#include
#ifdef _WIN32
#include
#else
#include
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define FIR_BUF_SIZE 8192
#ifdef _MSC_BUILD
#define snprintf sprintf_s
#endif
int ad9361_generate_fir_taps(struct filter_design_parameters *parameters,
short *taps, int *num_taps, int *gain)
{
double dnum_taps = 0;
double dgain = 0;
// Call filter designer
internal_design_filter_cg_initialize();
// Designer will alway return a filter, but it may not meet specifications
internal_design_filter_cg(
parameters->Rdata, parameters->Fpass, parameters->Fstop,
parameters->caldiv, parameters->FIR, parameters->HB1,
parameters->PLL_mult, parameters->Apass, parameters->Astop,
parameters->phEQ, parameters->HB2, parameters->HB3, parameters->Type,
parameters->RxTx, parameters->RFbw, parameters->DAC_div,
parameters->converter_rate, parameters->PLL_rate, parameters->Fcenter,
parameters->wnom, parameters->FIRdBmin, parameters->int_FIR,
parameters->maxTaps, taps, &dnum_taps, &dgain);
internal_design_filter_cg_terminate();
*num_taps = (int)dnum_taps;
*gain = (int)dgain;
// Filter with less than 32 taps is an error
if (*num_taps < 32)
return -EDOM;
else
return 0;
}
double calculate_rfbw(double pll_rate, double caldiv, bool TX,
double *rcaldiv)
{
double rfbw, min_rfbw, max_rfbw, scale;
if (TX) {
scale = 1.6;
min_rfbw = 1250000;
max_rfbw = 40000000;
} else {
scale = 1.4;
min_rfbw = 400000;
max_rfbw = 56000000;
}
rfbw =
(double)round((pll_rate / caldiv) * (2 / (scale * (2 * M_PI) / log(2))));
// If the RF bandwidth is outside the range of acceptable values we modify
// the divider value until it falls into an acceptable range.
while ((rfbw < min_rfbw) || (rfbw > max_rfbw)) {
if (rfbw < min_rfbw)
caldiv = caldiv - 1;
else
caldiv = caldiv + 1;
if ((caldiv < 1) || (caldiv > 511)) {
fprintf(stderr,"Calibration divider out of bounds (1 - 511): %f\n", caldiv);
return -EINVAL;
}
rfbw = calculate_rfbw(pll_rate, caldiv, TX, rcaldiv);
}
*rcaldiv = caldiv;
return rfbw;
}
void set_max_taps(struct filter_design_parameters *fdpTX,
struct filter_design_parameters *fdpRX)
{
// RX side
int N,M,K;
if (fdpRX->HB3 == 3)
N = 16*floor(fdpRX->converter_rate/(fdpRX->Rdata));
else
N = 16*floor(fdpRX->converter_rate/(2*fdpRX->Rdata));
if (N>128)
N = 128;
// TX side
if (fdpTX->FIR==1)
M = 64;
else
M = 128;
K = 16*floor(fdpTX->converter_rate*fdpTX->DAC_div/(2*fdpTX->Rdata));
if (KN) {
fdpTX->maxTaps = N;
fdpRX->maxTaps = N;
} else {
fdpTX->maxTaps = M;
fdpRX->maxTaps = M;
}
}
int build_configuration(struct filter_design_parameters *fdpTX,
struct filter_design_parameters *fdpRX,
unsigned long sample_rate,
unsigned long Fpass,
unsigned long Fstop,
unsigned long wnomTX,
unsigned long wnomRX)
{
double div, max;
unsigned long rx_path_clk[6];
unsigned long tx_path_clk[6];
unsigned long *path_clk;
struct filter_design_parameters *fdp;
int ret,k;
unsigned long rate_gov = 0;
ret = ad9361_calculate_rf_clock_chain((unsigned long) sample_rate,
rate_gov, rx_path_clk, tx_path_clk);
if (ret < 0)
return -EINVAL;
for (k=0; k<2; k++) {
if (k > 0) {
path_clk = tx_path_clk;
fdp = fdpTX;
fdp->RxTx = "Tx";
fdp->DAC_div = (double) rx_path_clk[1]/tx_path_clk[1];
} else {
path_clk = rx_path_clk;
fdp = fdpRX;
fdp->RxTx = "Rx";
fdp->DAC_div = 1.0;
}
// Map rates and dividers
fdp->PLL_rate = (double) path_clk[0];
fdp->converter_rate = (double) path_clk[1];
fdp->PLL_mult = (double) path_clk[0]/path_clk[1];
fdp->HB3 = (double) path_clk[1]/path_clk[2];
fdp->HB2 = (double) path_clk[2]/path_clk[3];
fdp->HB1 = (double) path_clk[3]/path_clk[4];
fdp->FIR = (double) path_clk[4]/path_clk[5];
// Set default parameters
fdp->Rdata = (double)path_clk[5];
fdp->Type = "Lowpass";
fdp->int_FIR = 1;
fdp->Apass = 0.5;
fdp->Astop = 80;
fdp->phEQ = -1;
fdp->FIRdBmin = 0;
// Define filter design specifications
fdp->Fpass = (double) Fpass;
fdp->Fstop = (double) Fstop;
fdp->Fcenter = 0.0;
if (k>0)
fdp->wnom = (double) wnomTX;
else
fdp->wnom = (double) wnomRX;
// Determine default analog bandwidth
div = ceil((fdp->PLL_rate / fdp->wnom) * (log(2) / (2 * M_PI)));
max = (div > 1) ? div : 1.0;
fdp->caldiv = (max > 511) ? 511.0 : max;
fdp->RFbw = calculate_rfbw(fdp->PLL_rate,fdp->caldiv, k>0, &(fdp->caldiv));
if (fdp->RFbw < 0)
return -EINVAL;
}
set_max_taps(fdpTX,fdpRX);
return 0;
}
int apply_custom_filter(struct iio_device *dev, unsigned dec_tx,
unsigned dec_rx, short *tapsTx,
short *tapsRx, unsigned taps,
unsigned long rate,
int gain_tx, int gain_rx,
unsigned long wnom_tx, unsigned long wnom_rx)
{
struct iio_channel *chanTX, *chanRX;
long long current_rate;
int ret, i, enable, len = 0;
char *buf;
chanTX = iio_device_find_channel(dev, "voltage0", true);
if (chanTX == NULL)
return -ENODEV;
ret = iio_channel_attr_read_longlong(chanTX, "sampling_frequency", ¤t_rate);
if (ret < 0)
return ret;
ret = ad9361_get_trx_fir_enable(dev, &enable);
if (ret < 0)
return ret;
if (enable) {
if (current_rate <= (25000000 / 12))
iio_channel_attr_write_longlong(chanTX, "sampling_frequency", 3000000);
ret = ad9361_set_trx_fir_enable(dev, false);
if (ret < 0)
return ret;
}
buf = (char*) malloc(FIR_BUF_SIZE);
if (!buf)
return -ENOMEM;
len += snprintf(buf + len, FIR_BUF_SIZE - len, "RX 3 GAIN %d DEC %d\n", gain_rx,
dec_rx);
len += snprintf(buf + len, FIR_BUF_SIZE - len, "TX 3 GAIN %d INT %d\n", gain_tx,
dec_tx);
for (i = 0; i < (int)taps; i++)
len += snprintf(buf + len, FIR_BUF_SIZE - len, "%d,%d\n", tapsRx[i], tapsTx[i]);
len += snprintf(buf + len, FIR_BUF_SIZE - len, "\n");
ret = iio_device_attr_write_raw(dev, "filter_fir_config", buf, len);
free (buf);
if (ret < 0)
return ret;
if (rate <= (25000000 / 12)) {
int dacrate, txrate, max;
char readbuf[100];
ret = iio_device_attr_read(dev, "tx_path_rates", readbuf, sizeof(readbuf));
if (ret < 0)
return ret;
ret = sscanf(readbuf, "BBPLL:%*d DAC:%d T2:%*d T1:%*d TF:%*d TXSAMP:%d",
&dacrate, &txrate);
if (ret != 2)
return -EFAULT;
if (txrate == 0)
return -EINVAL;
max = (dacrate / txrate) * 16;
if (max < taps)
iio_channel_attr_write_longlong(chanTX, "sampling_frequency", 3000000);
ret = ad9361_set_trx_fir_enable(dev, true);
if (ret < 0)
return ret;
ret = iio_channel_attr_write_longlong(chanTX, "sampling_frequency", rate);
if (ret < 0)
return ret;
} else {
ret = iio_channel_attr_write_longlong(chanTX, "sampling_frequency", rate);
if (ret < 0)
return ret;
ret = ad9361_set_trx_fir_enable(dev, true);
if (ret < 0)
return ret;
}
chanRX = iio_device_find_channel(dev, "voltage0", false);
if (chanRX == NULL)
return -ENODEV;
ret = iio_channel_attr_write_longlong(chanTX, "rf_bandwidth", wnom_tx);
if (ret < 0)
return ret;
ret = iio_channel_attr_write_longlong(chanRX, "rf_bandwidth", wnom_rx);
if (ret < 0)
return ret;
return 0;
}
int ad9361_calculate_rf_clock_chain_fdp(struct filter_design_parameters *fdpTX,
struct filter_design_parameters *fdpRX,
unsigned long sample_rate)
{
int ret;
// Set default configuration
unsigned long Fpass = sample_rate / 3.0;
unsigned long Fstop = Fpass * 1.25;
unsigned long wnomTX = 1.6 * Fstop;
unsigned long wnomRX = 1.4 * Fstop;
ret = build_configuration(fdpTX, fdpRX, sample_rate, Fpass, Fstop, wnomTX,
wnomRX);
if (ret<0)
return ret;
return 0;
}
int ad9361_set_bb_rate_custom_filter_auto(struct iio_device *dev,
unsigned long rate)
{
struct filter_design_parameters fdpTX;
struct filter_design_parameters fdpRX;
short taps_tx[128];
short taps_rx[128];
int ret, num_taps_tx, num_taps_rx, gain_tx, gain_rx;
unsigned dec_tx, dec_rx, num_taps;
ret = ad9361_calculate_rf_clock_chain_fdp(&fdpTX, &fdpRX, rate);
if (ret < 0)
return ret;
ret = ad9361_generate_fir_taps(&fdpRX, taps_rx, &num_taps_rx, &gain_rx);
if (ret < 0)
return ret;
ret = ad9361_generate_fir_taps(&fdpTX, taps_tx, &num_taps_tx, &gain_tx);
if (ret < 0)
return ret;
dec_tx = (unsigned) fdpTX.FIR;
dec_rx = (unsigned) fdpRX.FIR;
num_taps = (unsigned) fdpTX.maxTaps;
ret = apply_custom_filter(dev, dec_tx, dec_rx, taps_tx, taps_rx, num_taps,
rate, gain_tx, gain_rx, fdpTX.wnom, fdpRX.wnom);
if (ret < 0)
return ret;
return 0;
}
int ad9361_set_bb_rate_custom_filter_manual(struct iio_device *dev,
unsigned long rate, unsigned long Fpass,
unsigned long Fstop, unsigned long wnom_tx, unsigned long wnom_rx)
{
struct filter_design_parameters fdpTX;
struct filter_design_parameters fdpRX;
short taps_tx[128];
short taps_rx[128];
int ret, num_taps_tx, num_taps_rx, gain_tx, gain_rx;
unsigned dec_tx, dec_rx, num_taps;
if (Fpass >= Fstop)
return -EINVAL;
ret = build_configuration(&fdpTX, &fdpRX, rate, Fpass, Fstop, wnom_tx,
wnom_rx);
if (ret<0)
return ret;
ret = ad9361_generate_fir_taps(&fdpRX, taps_rx, &num_taps_rx, &gain_rx);
if (ret < 0)
return ret;
ret = ad9361_generate_fir_taps(&fdpTX, taps_tx, &num_taps_tx, &gain_tx);
if (ret < 0)
return ret;
dec_tx = (unsigned) fdpTX.FIR;
dec_rx = (unsigned) fdpRX.FIR;
num_taps = (unsigned) fdpTX.maxTaps;
ret = apply_custom_filter(dev, dec_tx, dec_rx, taps_tx, taps_rx, num_taps,
rate, gain_tx, gain_rx, wnom_tx, wnom_rx);
if (ret < 0)
return ret;
return 0;
}
libad9361-iio-0.3/ad9361_fmcomms5_phase_sync.c 0000664 0000000 0000000 00000042267 14424151631 0020641 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#include "ad9361.h"
#include
#include
#include
#ifdef _WIN32
#include
#else
#include
#include
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#include
#include
#include
#include
#ifdef _MSC_BUILD
#define snprintf sprintf_s
#endif
// Device names
#define DEV_RX_NAME "cf-ad9361-A"
#define DEV_RX_SLAVE_NAME "cf-ad9361-B"
#define DEV_TX_NAME "cf-ad9361-dds-core-lpc"
#define DEV_TX_SLAVE_NAME "cf-ad9361-dds-core-B"
#define DEV_PHY_NAME "ad9361-phy"
#define DEV_PHY_SLAVE_NAME "ad9361-phy-B"
#define DDS_SCALE 0.2
#define SAMPLES 8192
#define TOLERANCE 0.01 // Degrees
#define CALIBRATE_TRIES 30
#define STEP_SIZE 0.5
#define M_2PI 2 * M_PI
#define STALE_BUFFERS 20
// DEBUG = 0 Off
// DEBUG = 1 Verbose
// DEBUG = 2 More verbose
#define DEBUG 0
// Set to 1 if external splitter is connected to all receive chains,
// this does not calibrate the transmitters. This is useful if you want to
// calibrate from a the SMA connectors
#define EXTERNAL_REFERENCE_TONE 0
#define CHECK(expr) \
if (expr < 0) { \
return expr; \
}
static struct iio_device *dev_phy, *dev_phy_slave;
static struct iio_device *dev_rx, *dev_rx_slave;
static struct iio_device *dev_tx, *dev_tx_slave;
static struct iio_channel *dds_out[2][8];
static struct iio_buffer *rxbuf;
static struct iio_channel *rxa_chan_real, *rxa_chan_imag;
static struct iio_channel *rxb_chan_real, *rxb_chan_imag;
static void ad9361_sleep_ms(void)
{
#ifdef _WIN32
Sleep(1); /* milliseconds */
#else
struct timespec time;
time.tv_sec = 0;
time.tv_nsec = 1000 * 1000;
nanosleep(&time, NULL);
#endif
}
double scale_phase_0_360(double val)
{
if (val >= 360.0)
val -= 360.0;
if (val < 0)
val += 360.0;
return val;
}
void dds_tx_phase_rotation(struct iio_device *dev, double val)
{
long long i, q;
int d, j;
if (dev == dev_tx_slave)
d = 1;
else
d = 0;
i = scale_phase_0_360(val + 90.0) * 1000;
q = scale_phase_0_360(val) * 1000;
for (j = 0; j < 8; j++) {
switch (j) {
case 0:
case 1:
case 4:
case 5:
iio_channel_attr_write_longlong(dds_out[d][j], "phase", i);
break;
default:
iio_channel_attr_write_longlong(dds_out[d][j], "phase", q);
}
}
}
double calculate_phase(int16_t *a, int16_t *b, int16_t *c, int16_t *d,
int samples)
{
// Fast phase estimation with complex signals handling wrapped phase
int k = 0;
double real = 0, imag = 0;
for (; k < samples; k++) {
real += ((double)a[k] * (double)c[k] + (double)b[k] * (double)d[k]);
imag += ((double)a[k] * (double)d[k] - (double)b[k] * (double)c[k]);
}
return atan2(imag, real);
}
void near_end_loopback_ctrl(unsigned channel, bool enable)
{
unsigned tmp;
struct iio_device *dev = (channel > 3) ? dev_rx : dev_rx_slave;
if (!dev)
return;
if (channel > 3)
channel -= 4;
if (iio_device_reg_read(dev, 0x80000418 + channel * 0x40, &tmp))
return;
if (enable)
tmp |= 0x1;
else
tmp &= ~0xF;
iio_device_reg_write(dev, 0x80000418 + channel * 0x40, tmp);
}
void configure_ports(unsigned val)
{
unsigned lp_slave, lp_master, sw;
char *rx_port, *tx_port;
// https://wiki.analog.com/resources/eval/user-guides/ad-fmcomms5-ebz/multi-chip-sync#rf_phase_difference
/*
* 0 DISABLE: Use RF ports
* 1 TX1B_B (HPC) -> RX1C_B (HPC) : BIST_LOOPBACK on A
* 2 TX1B_A (LPC) -> RX1C_B (HPC) : BIST_LOOPBACK on A
* 3 TX1B_B (HPC) -> RX1C_A (LPC) : BIST_LOOPBACK on B
* 4 TX1B_A (LPC) -> RX1C_A (LPC) : BIST_LOOPBACK on B
*
*/
switch (val) {
default:
case 0:
lp_slave = 0;
lp_master = 0;
sw = 0;
tx_port = "A";
rx_port = "A_BALANCED";
break;
case 1:
case 2: //
lp_slave = 0;
lp_master = 1;
sw = val - 1;
tx_port = "B";
#if EXTERNAL_REFERENCE_TONE
rx_port = "A_BALANCED";
#else
rx_port = "C_BALANCED";
#endif
break;
case 3:
case 4:
lp_slave = 1;
lp_master = 0;
sw = val - 1;
tx_port = "B";
#if EXTERNAL_REFERENCE_TONE
rx_port = "A_BALANCED";
#else
rx_port = "C_BALANCED";
#endif
break;
}
// Set up ports for FPGA BIST Loopback
near_end_loopback_ctrl(0, lp_slave); /* HPC */
near_end_loopback_ctrl(1, lp_slave); /* HPC */
near_end_loopback_ctrl(4, lp_master); /* LPC */
near_end_loopback_ctrl(5, lp_master); /* LPC */
// Configure ADG918 switches
#if !EXTERNAL_REFERENCE_TONE
iio_device_debug_attr_write_longlong(dev_phy, "calibration_switch_control",
sw);
#endif
// Map ports to switch orientation
iio_channel_attr_write(iio_device_find_channel(dev_phy, "voltage0", false),
"rf_port_select", rx_port);
iio_channel_attr_write(iio_device_find_channel(dev_phy, "voltage0", true),
"rf_port_select", tx_port);
iio_channel_attr_write(
iio_device_find_channel(dev_phy_slave, "voltage0", false),
"rf_port_select", rx_port);
iio_channel_attr_write(
iio_device_find_channel(dev_phy_slave, "voltage0", true),
"rf_port_select", tx_port);
}
int trx_phase_rotation(struct iio_device *dev, double val)
{
struct iio_channel *out0, *out1;
double phase, vcos, vsin;
unsigned offset;
int ret;
bool output = (dev == dev_tx_slave) || (dev == dev_tx);
phase = val * 2 * M_PI / 360.0;
vcos = cos(phase);
vsin = sin(phase);
if (output) {
double corr;
corr = 1.0 /
fmax(fabs(sin(phase) + cos(phase)), fabs(cos(phase) - sin(phase)));
vcos *= corr;
vsin *= corr;
}
/* Set both RX1 and RX2 */
for (offset = 0; offset <= 2; offset += 2) {
if (offset == 2) {
out0 = iio_device_find_channel(dev, "voltage2", output);
out1 = iio_device_find_channel(dev, "voltage3", output);
} else {
out0 = iio_device_find_channel(dev, "voltage0", output);
out1 = iio_device_find_channel(dev, "voltage1", output);
}
if ((out0 == NULL) || (out0 == NULL))
return -ENODEV;
if (out1 && out0) {
ret = iio_channel_attr_write_double(out0, "calibscale", (double)vcos);
CHECK(ret);
ret = iio_channel_attr_write_double(out0, "calibphase", (double)(-1.0 * vsin));
CHECK(ret);
ret = iio_channel_attr_write_double(out1, "calibscale", (double)vcos);
CHECK(ret);
ret = iio_channel_attr_write_double(out1, "calibphase", (double)vsin);
CHECK(ret);
}
}
return 0;
}
int streaming_interfaces(bool enable)
{
if (enable) {
rxa_chan_real = iio_device_find_channel(dev_rx, "voltage0", false);
rxa_chan_imag = iio_device_find_channel(dev_rx, "voltage1", false);
rxb_chan_real = iio_device_find_channel(dev_rx, "voltage4", false);
rxb_chan_imag = iio_device_find_channel(dev_rx, "voltage5", false);
if (!(rxa_chan_real && rxa_chan_imag && rxb_chan_real && rxb_chan_imag))
streaming_interfaces(false);
iio_channel_enable(rxa_chan_real);
iio_channel_enable(rxa_chan_imag);
iio_channel_enable(rxb_chan_real);
iio_channel_enable(rxb_chan_imag);
rxbuf = iio_device_create_buffer(dev_rx, SAMPLES, false);
if (!rxbuf)
streaming_interfaces(false);
} else {
if (rxbuf) {
iio_buffer_destroy(rxbuf);
}
if (rxa_chan_real) {
iio_channel_disable(rxa_chan_real);
}
if (rxa_chan_imag) {
iio_channel_disable(rxa_chan_imag);
}
if (rxb_chan_real) {
iio_channel_disable(rxb_chan_real);
}
if (rxb_chan_imag) {
iio_channel_disable(rxb_chan_imag);
}
return -1;
}
return 0;
}
void read_buffer_data(struct iio_channel *chn, struct iio_buffer *buf,
void *dst, size_t len)
{
uintptr_t src_ptr, dst_ptr = (uintptr_t)dst, end = dst_ptr + len;
unsigned int bytes = iio_channel_get_data_format(chn)->length / 8;
uintptr_t buf_end = (uintptr_t)iio_buffer_end(buf);
ptrdiff_t buf_step = iio_buffer_step(buf);
for (src_ptr = (uintptr_t)iio_buffer_first(buf, chn);
src_ptr < buf_end && dst_ptr + bytes <= end;
src_ptr += buf_step, dst_ptr += bytes)
iio_channel_convert(chn, (void *)dst_ptr, (const void *)src_ptr);
}
double estimate_phase_diff(double *estimate)
{
ssize_t nbytes_rx = iio_buffer_refill(rxbuf);
if (!nbytes_rx)
return nbytes_rx;
int16_t myData0_i[SAMPLES], myData0_q[SAMPLES];
int16_t myData2_i[SAMPLES], myData2_q[SAMPLES];
// Read data from all channels
read_buffer_data(rxa_chan_real, rxbuf, myData0_i, SAMPLES * sizeof(int16_t));
read_buffer_data(rxa_chan_imag, rxbuf, myData0_q, SAMPLES * sizeof(int16_t));
read_buffer_data(rxb_chan_real, rxbuf, myData2_i, SAMPLES * sizeof(int16_t));
read_buffer_data(rxb_chan_imag, rxbuf, myData2_q, SAMPLES * sizeof(int16_t));
ad9361_sleep_ms();
*estimate =
calculate_phase(myData0_i, myData0_q, myData2_i, myData2_q, SAMPLES) *
180 / M_PI;
return 0;
}
int calibrate_chain(struct iio_device *dev, double scale, double *phase)
{
double est = 0, tmp;
int k = 0, ret = -2, g;
if (streaming_interfaces(true) < 0)
return -ENODEV;
*phase = 0;
for (; k < CALIBRATE_TRIES; k++) {
*phase = STEP_SIZE * est + (*phase);
ret = trx_phase_rotation(dev, *phase);
CHECK(ret);
for (g=0; g 1)
printf("Phase error: %f | Phase Setting: %f\n", est, *phase);
#endif
if (fabs(est) < TOLERANCE) {
ret = 0;
break;
}
est *= scale;
}
streaming_interfaces(false);
#if (DEBUG > 0)
printf("Remaining Phase error: %f\n", est);
printf("Rotation: %f\n", *phase);
#endif
return 0;
}
int quad_tracking(bool enable)
{
struct iio_channel *chn =
iio_device_find_channel(dev_phy, "voltage0", enable);
if (chn == NULL)
return -ENODEV;
iio_channel_attr_write(chn, "quadrature_tracking_en", "0");
chn = iio_device_find_channel(dev_phy_slave, "voltage0", enable);
if (chn == NULL)
return -ENODEV;
iio_channel_attr_write(chn, "quadrature_tracking_en", "0");
return 0;
}
int configure_transceiver(struct iio_device *dev, long long bw_hz,
long long fs_hz, long long lo_hz)
{
int ret = 0;
// Set up channels
struct iio_channel *chnRX1;
struct iio_channel *chnTX1;
struct iio_channel *chnRX2;
struct iio_channel *chnTX2;
// Configure LO channel
chnRX1 = iio_device_find_channel(dev, "altvoltage0", true);
chnTX1 = iio_device_find_channel(dev, "altvoltage1", true);
if (!(chnRX1 && chnTX1))
return -ENODEV;
ret = iio_channel_attr_write_longlong(chnRX1, "frequency", lo_hz);
CHECK(ret);
ret = iio_channel_attr_write_longlong(chnTX1, "frequency", lo_hz);
CHECK(ret);
// Set up gains to know good values
chnRX1 = iio_device_find_channel(dev, "voltage0", false);
chnTX1 = iio_device_find_channel(dev, "voltage0", true);
chnRX2 = iio_device_find_channel(dev, "voltage1", false);
chnTX2 = iio_device_find_channel(dev, "voltage1", true);
if (!(chnRX1 && chnTX1 && chnRX2 && chnTX2))
return -ENODEV;
ret = iio_channel_attr_write(chnRX1, "gain_control_mode", "manual");
CHECK(ret);
ret = iio_channel_attr_write(chnRX2, "gain_control_mode", "manual");
CHECK(ret);
ret = iio_channel_attr_write_double(chnRX1, "hardwaregain", 32.0);
CHECK(ret);
ret = iio_channel_attr_write_double(chnRX2, "hardwaregain", 32.0);
CHECK(ret);
ret = iio_channel_attr_write_double(chnTX1, "hardwaregain", -20);
CHECK(ret);
ret = iio_channel_attr_write_double(chnTX2, "hardwaregain", -20);
CHECK(ret);
return 0;
}
int configure_dds(double fs, double scale)
{
long long freq = (long long)fs * 0.01;
int i, j, ret = 0;
for (i = 0; i < 2; i++) {
for (j = 0; j < 8; j++) {
ret |= iio_channel_attr_write_longlong(dds_out[i][j], "frequency", freq);
ret |= iio_channel_attr_write_double(dds_out[i][j], "scale", scale);
}
dds_tx_phase_rotation(i ? dev_tx_slave : dev_tx, 0.0);
trx_phase_rotation(i ? dev_tx_slave : dev_tx, 0.0);
}
return ret;
}
int get_dds_channels()
{
struct iio_device *dev;
int i, j;
char name[16];
for (i = 0; i < 2; i++) {
dev = i ? dev_tx : dev_tx_slave;
for (j = 0; j < 8; j++) {
snprintf(name, sizeof(name), "altvoltage%d", j);
dds_out[i][j] = iio_device_find_channel(dev, name, true);
if (!dds_out[i][j])
return -errno;
}
}
return 0;
}
int setup_iio_devices(struct iio_context *ctx)
{
dev_rx = iio_context_find_device(ctx, DEV_RX_NAME);
dev_rx_slave = iio_context_find_device(ctx, DEV_RX_SLAVE_NAME);
dev_phy = iio_context_find_device(ctx, DEV_PHY_NAME);
dev_phy_slave = iio_context_find_device(ctx, DEV_PHY_SLAVE_NAME);
dev_tx = iio_context_find_device(ctx, DEV_TX_NAME);
dev_tx_slave = iio_context_find_device(ctx, DEV_TX_SLAVE_NAME);
return (dev_rx && dev_rx_slave && dev_phy && dev_phy_slave && dev_tx &&
dev_tx_slave);
}
/* Synchronize all transmit and receive channels for FMComms5*/
int phase_sync(struct iio_context *ctx, long long sample_rate, long long lo)
{
// Set analog bandwidth same as sample rate
long long bw = sample_rate;
// Set up devices
if (!setup_iio_devices(ctx))
return -ENODEV;
// Set up DDSs
int ret = get_dds_channels();
CHECK(ret);
// Sync chips together
ret = ad9361_multichip_sync(dev_phy, &dev_phy_slave, 1,
FIXUP_INTERFACE_TIMING | CHECK_SAMPLE_RATES);
CHECK(ret);
// Set up DDS at given frequency
ret = configure_dds(sample_rate, DDS_SCALE);
CHECK(ret);
// Set LO, bandwidth, and gain of transceivers
ret = configure_transceiver(dev_phy, bw, sample_rate, lo);
CHECK(ret);
ret = configure_transceiver(dev_phy_slave, bw, sample_rate, lo);
CHECK(ret);
// Turn off quad tracking
quad_tracking(false);
// Reset all phase shifts to zero
ret = trx_phase_rotation(dev_rx, 0.0);
CHECK(ret);
ret = trx_phase_rotation(dev_rx_slave, 0.0);
CHECK(ret);
ret = trx_phase_rotation(dev_tx, 0.0);
CHECK(ret);
ret = trx_phase_rotation(dev_tx_slave, 0.0);
CHECK(ret);
// Align receiver on Chip A (TX from chip A) with BIST loopback
configure_ports(1); // Chip A -> Chip A | FPGA Loopback on B
double phase_est_rx_slave = 0, phase_est = 0;
ret = calibrate_chain(dev_rx_slave, -1, &phase_est_rx_slave);
CHECK(ret);
// Align receiver on Chip B (TX from chip A) with BIST loopback
ret = trx_phase_rotation(dev_rx_slave, 0.0); // Reset reference channel
CHECK(ret);
configure_ports(3); // Chip A -> Chip B | FPGA Loopback on A
ret = calibrate_chain(dev_rx, 1, &phase_est);
CHECK(ret);
// At this point both receivers are aligned with Chip A TX
// Align Chip B TX with a receiver
ret = trx_phase_rotation(dev_rx_slave, 0);
CHECK(ret);
configure_ports(4); // Chip B -> Chip B | FPGA Loopback on A
ret = calibrate_chain(dev_tx_slave, -1, &phase_est);
CHECK(ret);
// Set rotation of chip B receiver to originally measured
ret = trx_phase_rotation(dev_rx_slave, phase_est_rx_slave);
CHECK(ret);
return 0;
}
/* Synchronize all transmit and receive channels for FMComms5*/
int ad9361_fmcomms5_phase_sync(struct iio_context *ctx, long long lo)
{
struct iio_channel *chan;
struct iio_device *dev;
long long sample_rate;
int ret;
// Get current sample rate
dev = iio_context_find_device(ctx, DEV_PHY_NAME);
if (dev == NULL)
return -ENODEV;
chan = iio_device_find_channel(dev, "voltage0", true);
if (chan == NULL)
return -ENODEV;
ret = iio_channel_attr_read_longlong(chan, "sampling_frequency", &sample_rate);
CHECK(ret);
ret = phase_sync(ctx, sample_rate, lo);
// Reset ports out to RF
configure_ports(0);
return ret;
}
libad9361-iio-0.3/ad9361_multichip_sync.c 0000664 0000000 0000000 00000007322 14424151631 0017722 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2015 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#include "ad9361.h"
#include
#include
#include
#ifdef _WIN32
#include
#else
#include
#include
#endif
#define MAX_AD9361_SYNC_DEVS 4
static void ad9361_sleep_ms(void)
{
#ifdef _WIN32
Sleep(1); /* milliseconds */
#else
struct timespec time;
time.tv_sec = 0;
time.tv_nsec = 1000 * 1000;
nanosleep(&time, NULL);
#endif
}
int ad9361_multichip_sync(struct iio_device *master, struct iio_device **slaves,
unsigned int num_slaves, unsigned int flags)
{
char ensm_mode[MAX_AD9361_SYNC_DEVS][20];
unsigned int i, step;
bool mcs_is_debug_attr = !iio_device_find_attr(master, "multichip_sync");
if (num_slaves >= MAX_AD9361_SYNC_DEVS || num_slaves < 1)
return -EINVAL;
if (flags & CHECK_SAMPLE_RATES) {
struct iio_channel *tx_sample_master, *tx_sample_slave;
long long tx_sample_master_freq, tx_sample_slave_freq;
tx_sample_master = iio_device_find_channel(master, "voltage0", true);
iio_channel_attr_read_longlong(tx_sample_master, "sampling_frequency", &tx_sample_master_freq);
for (i = 0; i < num_slaves; i++) {
tx_sample_slave = iio_device_find_channel(slaves[i], "voltage0", true);
if (tx_sample_slave == NULL)
return -ENODEV;
iio_channel_attr_read_longlong(tx_sample_slave, "sampling_frequency", &tx_sample_slave_freq);
if (tx_sample_master_freq != tx_sample_slave_freq) {
fprintf(stderr, "tx_sample_master_freq != tx_sample_slave_freq\nUpdating...\n");
iio_channel_attr_write_longlong(tx_sample_slave, "sampling_frequency", tx_sample_master_freq);
}
}
}
if (flags & FIXUP_INTERFACE_TIMING) {
unsigned tmp, tmp2;
iio_device_reg_read(master, 0x6, &tmp);
iio_device_reg_read(master, 0x7, &tmp2);
for (i = 0; i < num_slaves; i++) {
iio_device_reg_write(slaves[i], 0x6, tmp);
iio_device_reg_write(slaves[i], 0x7, tmp2);
}
}
/* Move the parts int ALERT for MCS */
iio_device_attr_read(master, "ensm_mode", ensm_mode[0], sizeof(ensm_mode));
iio_device_attr_write(master, "ensm_mode", "alert");
for (i = 0; i < num_slaves; i++) {
iio_device_attr_read(slaves[i], "ensm_mode", ensm_mode[i + 1], sizeof(ensm_mode));
iio_device_attr_write(slaves[i], "ensm_mode", "alert");
}
for (step = 0; step <= 5; step++) {
for (i = 0; i < num_slaves; i++) {
if (mcs_is_debug_attr)
iio_device_debug_attr_write_longlong(slaves[i], "multichip_sync", step);
else
iio_device_attr_write_longlong(slaves[i], "multichip_sync", step);
}
/* The master controls the SYNC GPIO */
if (mcs_is_debug_attr)
iio_device_debug_attr_write_longlong(master, "multichip_sync", step);
else
iio_device_attr_write_longlong(master, "multichip_sync", step);
ad9361_sleep_ms();
}
iio_device_attr_write(master, "ensm_mode", ensm_mode[0]);
for (i = 0; i < num_slaves; i++)
iio_device_attr_write(slaves[i], "ensm_mode", ensm_mode[i + 1]);
return 0;
}
int ad9361_fmcomms5_multichip_sync(struct iio_context *ctx, unsigned int flags)
{
struct iio_device *master, *slave;
master = iio_context_find_device(ctx, "ad9361-phy");
slave = iio_context_find_device(ctx, "ad9361-phy-B");
if (!master || !slave)
return -ENODEV;
return ad9361_multichip_sync(master, &slave, 1, flags);
}
libad9361-iio-0.3/appveyor.yml 0000664 0000000 0000000 00000013214 14424151631 0016122 0 ustar 00root root 0000000 0000000 version: '{branch}.{build}'
clone_depth: 1
environment:
# Tell msys2 to add mingw64 to the path
MSYSTEM: MINGW64
# Tell msys2 to inherit the current directory when starting the shell
CHERE_INVOKING: 1
install:
# Download libiio
- cd c:\
- appveyor DownloadFile https://ci.appveyor.com/api/projects/analogdevicesinc/libiio/artifacts/libiio.zip?branch=master
- 7z x libiio*.zip > nul
- mkdir libiio-win64
- mkdir libiio-win32
- mkdir libiio-mingw-win64
- mkdir libiio-mingw-win32
- mv libiio-*/MS64/* libiio-win64/
- cp libiio-*/include/* libiio-win64/
- mv libiio-*/MS32/* libiio-win32/
- cp libiio-*/include/* libiio-win32/
- mv libiio-*/MinGW32/* libiio-mingw-win32/
- cp libiio-*/include/* libiio-mingw-win32/
- mv libiio-*/MinGW64/* libiio-mingw-win64/
- cp libiio-*/include/* libiio-mingw-win64/
#Install Inno Setup
- choco install InnoSetup
- set PATH=%PATH%;"C:\Program Files (x86)\Inno Setup 5"
build_script:
# 32-bit build - MinGW
- set OLD_PATH=%PATH%
- set OPT_PATH=C:\msys64\mingw32\bin;C:\msys64\mingw64\bin;
- set PATH=%OPT_PATH%%PATH%
- mkdir c:\projects\libad9361-iio\build-mingw-win32
- cd c:\projects\libad9361-iio\build-mingw-win32
# - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy mingw-w64-i686-gcc "
- cmake -G "Unix Makefiles" \
-DLIBIIO_LIBRARIES:FILEPATH=c:/libiio-mingw-win32/libiio.dll.a \
-DLIBIIO_INCLUDEDIR:PATH=c:/libiio-mingw-win32 \
-DCMAKE_CONFIGURATION_TYPES=Release \
-DCMAKE_C_COMPILER:FILEPATH=c:/msys64/mingw32/bin/i686-w64-mingw32-gcc.exe \
-DCMAKE_MAKE_PROGRAM=c:/msys64/mingw32/bin/mingw32-make.exe \
..
- cmake --build . --config Release
- copy c:\libiio-mingw-win32\*.dll c:\projects\libad9361-iio\build-mingw-win32\test\
- copy c:\projects\libad9361-iio\build-mingw-win32\*.dll c:\projects\libad9361-iio\build-mingw-win32\test\
- ctest -V -R
# 64-bit build - MinGW
- mkdir c:\projects\libad9361-iio\build-mingw-win64
- cd c:\projects\libad9361-iio\build-mingw-win64
# - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy mingw-w64-x86_64-gcc"
- cmake -G "Unix Makefiles" \
-DLIBIIO_LIBRARIES:FILEPATH=c:/libiio-mingw-win64/libiio.dll.a \
-DLIBIIO_INCLUDEDIR:PATH=c:/libiio-mingw-win64 \
-DCMAKE_CONFIGURATION_TYPES=Release \
-DCMAKE_C_COMPILER:FILEPATH=c:/msys64/mingw64/bin/x86_64-w64-mingw32-gcc.exe \
-DCMAKE_MAKE_PROGRAM=c:/msys64/mingw64/bin/mingw32-make.exe \
..
- cmake --build . --config Release
- copy c:\libiio-mingw-win64\*.dll c:\projects\libad9361-iio\build-mingw-win64\test\
- copy c:\projects\libad9361-iio\build-mingw-win64\*.dll c:\projects\libad9361-iio\build-mingw-win64\test\
- ctest -V -R
# 32-bit build - VS
- mkdir c:\projects\libad9361-iio\build-win32
- cd c:\projects\libad9361-iio\build-win32
- cmake -G "Visual Studio 12" \
-DLIBIIO_LIBRARIES:FILEPATH=c:/libiio-win32/libiio.lib \
-DLIBIIO_INCLUDEDIR:PATH=c:/libiio-win32 \
-DCMAKE_CONFIGURATION_TYPES=Release \
..
- cmake --build . --config Release
- copy c:\libiio-win32\*.dll c:\projects\libad9361-iio\build-win32\test\Release
- copy c:\projects\libad9361-iio\build-win32\Release\*.dll c:\projects\libad9361-iio\build-win32\test\Release
- ctest -V -C Release
# 64-bit build - VS
- mkdir c:\projects\libad9361-iio\build-win64
- cd c:\projects\libad9361-iio\build-win64
- cmake -G "Visual Studio 12 Win64" \
-DLIBIIO_LIBRARIES:FILEPATH=c:/libiio-win64/libiio.lib \
-DLIBIIO_INCLUDEDIR:PATH=c:/libiio-win64 \
-DCMAKE_CONFIGURATION_TYPES=Release \
..
- cmake --build . --config Release
- copy c:\libiio-win64\*.dll c:\projects\libad9361-iio\build-win64\test\Release
- copy c:\projects\libad9361-iio\build-win64\Release\*.dll c:\projects\libad9361-iio\build-win64\test\Release
- ctest -V -C Release
#Create the installer
- ISCC c:\projects\libad9361-iio\build-win64\libad9361-iio.iss
- appveyor PushArtifact C:\libad9361-setup.exe
# Create ZIPs
- cd c:\projects\libad9361-iio
- mkdir c:\libad9361-win32
- copy ad9361.h c:\libad9361-win32\
- copy bindings\matlab\ad9361-wrapper.h c:\libad9361-win32\
- copy build-win32\Release\libad9361.* c:\libad9361-win32\
- copy c:\libiio-win32\*.dll c:\libad9361-win32\
- 7z a "c:\libad9361-win32.zip" c:\libad9361-win32
- appveyor PushArtifact c:\libad9361-win32.zip
- mkdir c:\libad9361-win64
- copy ad9361.h c:\libad9361-win64\
- copy bindings\matlab\ad9361-wrapper.h c:\libad9361-win64\
- copy build-win64\Release\libad9361.* c:\libad9361-win64\
- copy c:\libiio-win64\*.dll c:\libad9361-win64\
- 7z a "c:\libad9361-win64.zip" c:\libad9361-win64
- appveyor PushArtifact c:\libad9361-win64.zip
- mkdir c:\libad9361-mingw-win32
- copy ad9361.h c:\libad9361-mingw-win32\
- copy bindings\matlab\ad9361-wrapper.h c:\libad9361-mingw-win32\
- copy build-mingw-win32\libad9361.* c:\libad9361-mingw-win32\
- copy c:\libiio-mingw-win32\*.dll c:\libad9361-mingw-win32\
- 7z a "c:\libad9361-mingw-win32.zip" c:\libad9361-mingw-win32
- appveyor PushArtifact c:\libad9361-mingw-win32.zip
- mkdir c:\libad9361-mingw-win64
- copy ad9361.h c:\libad9361-mingw-win64\
- copy bindings\matlab\ad9361-wrapper.h c:\libad9361-mingw-win64\
- copy build-mingw-win64\libad9361.* c:\libad9361-mingw-win64\
- copy c:\libiio-mingw-win64\*.dll c:\libad9361-mingw-win64\
- 7z a "c:\libad9361-mingw-win64.zip" c:\libad9361-mingw-win64
- appveyor PushArtifact c:\libad9361-mingw-win64.zip
libad9361-iio-0.3/azure-pipelines.yml 0000664 0000000 0000000 00000021555 14424151631 0017400 0 ustar 00root root 0000000 0000000 variables:
libiioPipelineId: 9
trigger:
branches:
include:
- main
- master
- staging/*
- 20*
tags:
include:
- v*
pr:
branches:
include:
- main
- master
- 20*
jobs:
- job: LinuxBuilds
strategy:
matrix:
ubuntu_20_04_x86_64:
imageName: 'ubuntu-20.04'
OS_TYPE: 'ubuntu_docker'
OS_VERSION: focal
artifactName: 'Linux-Ubuntu-20.04'
PACKAGE_TO_INSTALL: 'build/*.deb'
ubuntu_22_04_x86_64:
imageName: 'ubuntu-22.04'
OS_TYPE: 'ubuntu_docker'
OS_VERSION: jammy
artifactName: 'Linux-Ubuntu-22.04'
PACKAGE_TO_INSTALL: 'build/*.deb'
pool:
vmImage: $(imageName)
steps:
- checkout: self
fetchDepth: 1
clean: true
- task: DownloadPipelineArtifact@2
inputs:
source: 'specific'
project: '$(System.TeamProjectId)'
pipeline: $(libiioPipelineId)
artifact: '$(artifactName)'
runVersion: 'latestFromBranch'
runBranch: 'refs/heads/master'
path: '$(Agent.BuildDirectory)/s/build/'
- script: ./CI/travis/before_install_linux
displayName: "Install Dependencies"
- script: ./CI/travis/make_linux
displayName: "Build"
- task: CopyFiles@2
inputs:
sourceFolder: '$(Agent.BuildDirectory)/s/build/'
contents: '$(Agent.BuildDirectory)/s/build/?(*.deb|*.rpm)'
targetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishPipelineArtifact@1
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)'
artifactName: '$(artifactName)'
- script: |
sudo pip install setuptools wheel twine build
cd /home/vsts/work/1/s/build/bindings/python
sudo python setup.py bdist_wheel
condition: eq(variables['artifactName'], 'Linux-Ubuntu-20.04')
displayName: "Install wheel and twine"
- task: TwineAuthenticate@1
condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v'), eq(variables['artifactName'], 'Linux-Ubuntu-20.04'))
displayName: Twine Authenticate
inputs:
artifactFeed: libad9361-iio
pythonUploadServiceConnection: PyPi
- task: TwineAuthenticate@1
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq(variables['artifactName'], 'Linux-Ubuntu-20.04'))
displayName: Twine Authenticate
inputs:
artifactFeed: test-libad9361-iio
pythonUploadServiceConnection: PyPi_Test
- script: |
cd /home/vsts/work/1/s/build/bindings/python
python -m twine upload -u $(USERNAME) -p $(PASSWORD) --config-file $(PYPIRC_PATH) dist/*.whl
condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v'), eq(variables['artifactName'], 'Linux-Ubuntu-20.04'))
displayName: "Deploy python package"
- script: |
cd /home/vsts/work/1/s/build/bindings/python
sudo rm ./dist/*.whl
sudo pip3 install --upgrade requests
sudo pip install invoke
sudo invoke bumpversion-test
sudo python -m build
ls -al
cd dist
ls -al
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq(variables['artifactName'], 'Linux-Ubuntu-20.04'))
displayName: "Update to dev version"
- script: |
cd /home/vsts/work/1/s/build/bindings/python
sudo python -m twine upload --repository-url https://test.pypi.org/legacy/ -u $(USERNAME) -p $(PASSWORD) --skip-existing --config-file $(PYPIRC_PATH) dist/*.whl
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq(variables['artifactName'], 'Linux-Ubuntu-20.04'))
displayName: "Deploy python test package"
- job: ARMBuilds
# Host Box
pool:
vmImage: "ubuntu-latest"
# Docker Images
strategy:
matrix:
ubuntu-ppc64le:
image: tfcollins/libiio_ubuntu_18_04-ci-arm-ppc:latest
arch: ppc64le
build_script: ci-ubuntu.sh
artifactName: 'Ubuntu-ppc64le'
ubuntu-x390x:
image: tfcollins/libiio_ubuntu_18_04-ci-arm-ppc:latest
arch: s390x
build_script: ci-ubuntu.sh
artifactName: 'Ubuntu-x390x'
debian_buster_arm32v7:
image: tfcollins/libiio_ubuntu_18_04-ci-arm-ppc:latest
arch: arm
build_script: ci-ubuntu.sh
artifactName: 'Ubuntu-arm32v7'
debian_buster_arm64v8:
image: tfcollins/libiio_ubuntu_18_04-ci-arm-ppc:latest
arch: aarch64
build_script: ci-ubuntu.sh
artifactName: 'Ubuntu-arm64v8'
steps:
- checkout: self
fetchDepth: 1
clean: true
- task: DownloadPipelineArtifact@2
inputs:
source: 'specific'
project: '$(System.TeamProjectId)'
pipeline: $(libiioPipelineId)
artifact: '$(artifactName)'
runVersion: 'latestFromBranch'
runBranch: 'refs/heads/master'
path: '$(Agent.BuildDirectory)/s/build/'
- script: |
set -e
sudo apt-get update
sudo apt-get install -y gcc-arm-linux-gnueabihf libc6-dev-armhf-cross
sudo apt-get install -y g++-arm-linux-gnueabihf
sudo apt-get install -y g++-aarch64-linux-gnu
sudo apt-get install -y qemu-system-ppc64
sudo apt-get install qemu binfmt-support qemu-user-static
sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
displayName: "Setup"
- script: |
set -e
sudo docker run --platform "linux/$(arch)" --rm -t --privileged -e ARTIFACTNAME=$(artifactName) -v "$(Agent.BuildDirectory)/s":"/ci" -v "/usr/bin/qemu-$(arch)-static":"/usr/bin/qemu-$(arch)-static" "$(image)" /bin/bash -c "cd /ci/ && chmod +x ./CI/travis/$(build_script) && ./CI/travis/$(build_script)"
displayName: "Build"
- task: CopyFiles@2
inputs:
sourceFolder: '$(Agent.BuildDirectory)/s/build/'
contents: '$(Agent.BuildDirectory)/s/build/?(*.deb|*.rpm)'
targetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishPipelineArtifact@1
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)'
artifactName: '$(artifactName)'
- job: macOSBuilds
strategy:
matrix:
macOS_11:
imageName: 'macOS-11'
artifactName: 'macOS-11'
macOS_12:
imageName: 'macOS-12'
artifactName: 'macOS-12'
pool:
vmImage: $(imageName)
variables:
PACKAGE_TO_INSTALL: 'build/*.pkg'
steps:
- checkout: self
fetchDepth: 1
clean: true
- task: DownloadPipelineArtifact@2
inputs:
source: 'specific'
project: '$(System.TeamProjectId)'
pipeline: $(libiioPipelineId)
artifact: '$(artifactName)'
runVersion: 'latestFromBranch'
runBranch: 'refs/heads/master'
path: '$(Agent.BuildDirectory)/s/build/'
- script: ./CI/travis/before_install_darwin
displayName: "Install Dependencies"
- script: ./CI/travis/make_darwin
displayName: "Build"
- task: CopyFiles@2
inputs:
sourceFolder: '$(Agent.BuildDirectory)/s/build/'
contents: '$(Agent.BuildDirectory)/s/build/?(*.pkg)'
targetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishPipelineArtifact@1
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)'
artifactName: '$(artifactName)'
- job: WindowsBuilds
strategy:
matrix:
VS2022:
imageName: 'windows-2022'
COMPILER: 'Visual Studio 17 2022'
ARCH: 'x64'
artifactName: 'Windows-VS-2022-x64'
VS2019_Win64:
imageName: 'windows-2019'
COMPILER: 'Visual Studio 16 2019'
ARCH: 'x64'
artifactName: 'Windows-VS-2019-x64'
pool:
vmImage: $[ variables['imageName'] ]
steps:
- checkout: self
fetchDepth: 1
clean: true
- task: DownloadPipelineArtifact@2
inputs:
source: 'specific'
project: '$(System.TeamProjectId)'
pipeline: $(libiioPipelineId)
artifact: '$(artifactName)'
runVersion: 'latestFromBranch'
runBranch: 'refs/heads/master'
path: '$(Agent.BuildDirectory)/s/build/'
- task: PowerShell@2
inputs:
targetType: 'filePath'
filePath: .\CI\install_deps_win.ps1
displayName: Dependencies
- task: PowerShell@2
inputs:
targetType: 'filePath'
filePath: .\CI\build_win.ps1
displayName: Build
- task: CopyFiles@2
displayName: 'Copy libraries'
inputs:
sourceFolder: '$(Agent.BuildDirectory)/s/build/Release'
targetFolder: '$(Build.ArtifactStagingDirectory)'
- task: CopyFiles@2
displayName: 'Copy ad9361.h header'
inputs:
sourceFolder: '$(Agent.BuildDirectory)/s/'
contents: 'ad9361.h'
targetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishPipelineArtifact@1
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)'
artifactName: '$(artifactName)'
libad9361-iio-0.3/bindings/ 0000775 0000000 0000000 00000000000 14424151631 0015326 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/bindings/CMakeLists.txt 0000664 0000000 0000000 00000000156 14424151631 0020070 0 ustar 00root root 0000000 0000000 if (MATLAB_BINDINGS)
add_subdirectory(matlab)
endif()
if (PYTHON_BINDINGS)
add_subdirectory(python)
endif() libad9361-iio-0.3/bindings/matlab/ 0000775 0000000 0000000 00000000000 14424151631 0016566 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/bindings/matlab/CMakeLists.txt 0000664 0000000 0000000 00000000065 14424151631 0021327 0 ustar 00root root 0000000 0000000 install (FILES ad9361-wrapper.h DESTINATION include)
libad9361-iio-0.3/bindings/matlab/ad9361-wrapper.h 0000664 0000000 0000000 00000000121 14424151631 0021316 0 ustar 00root root 0000000 0000000 #ifndef MATLAB_LOADLIBRARY
#define MATLAB_LOADLIBRARY
#include
#endif
libad9361-iio-0.3/bindings/python/ 0000775 0000000 0000000 00000000000 14424151631 0016647 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/bindings/python/CMakeLists.txt 0000664 0000000 0000000 00000004270 14424151631 0021412 0 ustar 00root root 0000000 0000000 cmake_minimum_required(VERSION 2.87)
project(libad9361-py NONE)
if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
if(Python3_EXECUTABLE)
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
endif()
find_package(PythonInterp 3.6 REQUIRED)
set(Python3_FOUND ${PYTHONINTERP_FOUND})
set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
else()
find_package(Python3 3.6 REQUIRED COMPONENTS Interpreter)
endif()
if (Python3_FOUND)
message(STATUS "Found Python: Building bindings")
set(SETUP_PY_IN ${CMAKE_CURRENT_SOURCE_DIR}/setup.py.cmakein)
set(SETUP_PY ${CMAKE_CURRENT_BINARY_DIR}/setup.py)
configure_file(${SETUP_PY_IN} ${SETUP_PY})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ad9361.py ${CMAKE_CURRENT_BINARY_DIR}/ad9361.py COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tasks.py ${CMAKE_CURRENT_BINARY_DIR}/tasks.py COPYONLY)
add_custom_target(libad9361-py-py ALL DEPENDS ${SETUP_PY} COMMAND ${Python3_EXECUTABLE} ${SETUP_PY} --quiet build)
if(NOT SKIP_INSTALL_ALL)
install(CODE "execute_process(WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${Python3_EXECUTABLE} ${SETUP_PY} install --root=\$ENV{DESTDIR}/ --prefix=${CMAKE_INSTALL_PREFIX})")
endif()
else()
message(FATAL_ERROR "Python search failed : Can not build Python bindings")
endif()
if(WITH_DOC)
find_program(SPHINX_EXECUTABLE
NAMES sphinx-build
DOC "Sphinx Documentation Builder (sphinx-doc.org)"
)
if (NOT SPHINX_EXECUTABLE)
message(FATAL_ERROR "Can not build python doc without sphinx-build")
endif()
message (STATUS "Building with Python Doc (Sphinx)")
set(CMAKE_HTML_DEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/html/v${LIBAD9361_VERSION_MAJOR}.${LIBAD9361_VERSION_MINOR}")
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/doc/conf.py.in
${CMAKE_CURRENT_SOURCE_DIR}/doc/conf.py)
add_custom_command(TARGET libad9361-py-py POST_BUILD
COMMAND ${CMAKE_COMMAND} -E env "LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH}:${CMAKE_BINARY_DIR}"
${SPHINX_EXECUTABLE}
-b html
-n
-c ${CMAKE_CURRENT_SOURCE_DIR}/doc
-d ${CMAKE_CURRENT_BINARY_DIR}/doctrees
-w ${CMAKE_BINARY_DIR}/Spx_output_python
${CMAKE_CURRENT_SOURCE_DIR}/doc
${CMAKE_HTML_DEST_DIR}/python
COMMENT "Generating Python binding documentation with Sphinx" VERBATIM
)
endif()
libad9361-iio-0.3/bindings/python/README.md 0000664 0000000 0000000 00000006212 14424151631 0020127 0 ustar 00root root 0000000 0000000 # libad9361-iio: Python Bindings
This package contains the python bindings for libad9361-iio, a library for managing different AD9361 transceiver features. Such as multi-chip sync and filter generation.
License : [](https://github.com/analogdevicesinc/libad9361-iio/blob/master/COPYING.txt)
Latest Release : [](https://github.com/analogdevicesinc/libad9361-iio/releases/latest)
Downloads : [](https://github.com/analogdevicesinc/libad9361-iio/releases/latest)
Support:
If you have a question about libad9361-iio or the AD9361 transceiver please ask on : [](https://ez.analog.com/linux-device-drivers/linux-software-drivers).
## Requirements
To use these bindings naturally you need the core library they depend upon, libad9361-iio. This is not packaged with the pypi release but there are a number of options:
- If you want to just use libad9361-iio, we suggest using the [latest release](https://github.com/analogdevicesinc/libad9361-iio/releases/latest).
- If you think you have found a bug in the release, or need a feature which isn't in the release, try the latest **untested** binaries from the master branch and check out the [documentation](https://codedocs.xyz/analogdevicesinc/libad9361-iio/) based on the master branch. We provide builds for a few operating systems. If you need something else, we can most likely add that -- just ask.
### Installing the bindings
To install these bindings there are a few methods. If you already have the library itself and just need the bindings, pip is the most convenient method:
```shell
(sudo) pip install pylibad9361-iio
```
If you do not want to use pip, then installation is dependent on your operating system.
#### Linux / macOS
For Linux and macOS the python bindings need to be installed through source if not using pip.
#### Windows
Only pip installation is supported.
### Support
If you have a question about libad9361-iio or the python bindings please ask on: [](https://ez.analog.com/linux-device-drivers/linux-software-drivers).
If you use it, and like it - please let us know. If you use it, and hate it - please let us know that too. The goal of the project is to try to make the AD9361 transceiver easier to use on a variety of platforms. If we aren't doing that - we will try to make it better.
Feedback is appreciated (in order of preference):
* [Github trackers](https://github.com/analogdevicesinc/libad9361-iio/issues) for bugs, improvements, or feature requests
* [Analog Devices web forums](https://ez.analog.com/community/linux-device-drivers/linux-software-drivers) for general help on libiio and/or ADI Linux IIO drivers
## Useful resources
* [API Documentation](http://analogdevicesinc.github.io/libad9361-iio/)
* [Libiio](http://wiki.analog.com/resources/tools-software/linux-software/libiio)
libad9361-iio-0.3/bindings/python/ad9361.py 0000664 0000000 0000000 00000027371 14424151631 0020142 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
# SPDX-License-Identifier: LGPL-2.1-or-later
# Copyright (C) 2021 Analog Devices, Inc.
# Author: Travis F. Collins
from typing import List
import math
import iio
from iio import _ContextPtr, _DevicePtr
# Imports from package ctypes are not grouped
# pylint: disable=ungrouped-imports
#
# The way the methods and classes are used, violate this, but there
# isn't a good way to do things otherwise
# pylint: disable=protected-access
from ctypes import (
byref,
c_ubyte,
c_double,
c_int,
c_longlong,
c_short,
c_uint,
c_ulong,
CDLL as _cdll,
POINTER as _POINTER,
Structure,
)
from ctypes.util import find_library
from os import strerror as _strerror
from platform import system as _system
if "Windows" in _system():
from ctypes import get_last_error
else:
from ctypes import get_errno
# pylint: enable=ungrouped-imports
# ctypes requires the errcheck to take three arguments, but we don't use them
# pylint: disable=unused-argument
def _check_negative(result, func, arguments):
if result >= 0:
return result
raise OSError(-result, _strerror(-result))
if "Windows" in _system():
_libad9361 = "libad9361.dll"
else:
# Non-windows, possibly Posix system
_libad9361 = "ad9361"
_lib = _cdll(find_library(_libad9361), use_errno=True, use_last_error=True)
class FilterDesignParameters(Structure):
_fields_ = [
("Rdata", c_double),
("Fpass", c_double),
("Fstop", c_double),
("caldiv", c_double),
("FIR", c_double),
("HB1", c_double),
("DAC_div", c_double),
("RFbw", c_double),
("converter_rate", c_double),
("PLL_rate", c_double),
("Fcenter", c_double),
("wnom", c_double),
("FIRdBmin", c_double),
("int_FIR", c_double),
("PLL_mult", c_double),
("Apass", c_double),
("Astop", c_double),
("phEQ", c_double),
("HB2", c_double),
("HB3", c_double),
("maxTaps", c_double),
("Type", _POINTER(c_ubyte)),
("RxTx", _POINTER(c_ubyte)),
]
_ad9361_multichip_sync = _lib.ad9361_multichip_sync
_ad9361_multichip_sync.restype = c_int
_ad9361_multichip_sync.argtypes = (_DevicePtr, _POINTER(_DevicePtr), c_uint, c_uint)
_ad9361_multichip_sync.errcheck = _check_negative
_ad9361_fmcomms5_multichip_sync = _lib.ad9361_fmcomms5_multichip_sync
_ad9361_fmcomms5_multichip_sync.restype = c_int
_ad9361_fmcomms5_multichip_sync.argtypes = (_ContextPtr, c_uint)
_ad9361_fmcomms5_multichip_sync.errcheck = _check_negative
_ad9361_set_bb_rate = _lib.ad9361_set_bb_rate
_ad9361_set_bb_rate.restype = c_int
_ad9361_set_bb_rate.argtypes = (_DevicePtr, c_ulong)
_ad9361_set_bb_rate.errcheck = _check_negative
_ad9361_set_trx_fir_enable = _lib.ad9361_set_trx_fir_enable
_ad9361_set_trx_fir_enable.restype = c_int
_ad9361_set_trx_fir_enable.argtypes = (_DevicePtr, c_int)
_ad9361_set_trx_fir_enable.errcheck = _check_negative
_ad9361_get_trx_fir_enable = _lib.ad9361_get_trx_fir_enable
_ad9361_get_trx_fir_enable.restype = c_int
_ad9361_get_trx_fir_enable.argtypes = (_DevicePtr, _POINTER(c_int))
_ad9361_get_trx_fir_enable.errcheck = _check_negative
_ad9361_generate_fir_taps = _lib.ad9361_generate_fir_taps
_ad9361_generate_fir_taps.restype = c_int
_ad9361_generate_fir_taps.argtypes = (
_POINTER(FilterDesignParameters),
_POINTER(c_short),
_POINTER(c_int),
_POINTER(c_int),
)
_ad9361_generate_fir_taps.errcheck = _check_negative
_ad9361_calculate_rf_clock_chain = _lib.ad9361_calculate_rf_clock_chain
_ad9361_calculate_rf_clock_chain.restype = c_int
_ad9361_calculate_rf_clock_chain.argtypes = (
c_ulong,
c_ulong,
_POINTER(c_ulong),
_POINTER(c_ulong),
)
_ad9361_calculate_rf_clock_chain.errcheck = _check_negative
_ad9361_calculate_rf_clock_chain_fdp = _lib.ad9361_calculate_rf_clock_chain_fdp
_ad9361_calculate_rf_clock_chain_fdp.restype = c_int
_ad9361_calculate_rf_clock_chain_fdp.argtypes = (
_POINTER(FilterDesignParameters),
_POINTER(FilterDesignParameters),
c_ulong,
)
_ad9361_calculate_rf_clock_chain_fdp.errcheck = _check_negative
_ad9361_set_bb_rate_custom_filter_auto = _lib.ad9361_set_bb_rate_custom_filter_auto
_ad9361_set_bb_rate_custom_filter_auto.restype = c_int
_ad9361_set_bb_rate_custom_filter_auto.argtypes = (_DevicePtr, c_ulong)
_ad9361_set_bb_rate_custom_filter_auto.errcheck = _check_negative
_ad9361_set_bb_rate_custom_filter_manual = _lib.ad9361_set_bb_rate_custom_filter_manual
_ad9361_set_bb_rate_custom_filter_manual.restype = c_int
_ad9361_set_bb_rate_custom_filter_manual.argtypes = (
_DevicePtr,
c_ulong,
c_ulong,
c_ulong,
c_ulong,
c_ulong,
)
_ad9361_set_bb_rate_custom_filter_manual.errcheck = _check_negative
_ad9361_fmcomms5_phase_sync = _lib.ad9361_fmcomms5_phase_sync
_ad9361_fmcomms5_phase_sync.restype = c_int
_ad9361_fmcomms5_phase_sync.argtypes = (_ContextPtr, c_longlong)
_ad9361_fmcomms5_phase_sync.errcheck = _check_negative
def multichip_sync(main: iio.Device, secondaries: List[iio.Device], flags: int) -> None:
"""Multi-chip synchronization (MCS) management.
:param: iio.Device master: IIO Device object of master AD9361 transceiver
:param: List[iio.Device] slaves: A list of IIO Device objects to child AD9361 transceivers
:param int flags: Control flags for MCS configuration
"""
if math.trunc(flags) != flags:
raise Exception("flags must be an integer")
psecondaries = [d._device for d in secondaries]
csecondaries = (_DevicePtr * len(secondaries))(*psecondaries)
cnum_secondaries = c_uint(len(secondaries))
cflags = c_uint(flags)
ret = _ad9361_multichip_sync(main._device, csecondaries, cnum_secondaries, cflags)
if ret != 0:
raise Exception(f"Setting MCS failed. ERROR: {ret}")
return ret
def fmcomms5_multichip_sync(ctx: iio.Context, flags: int):
"""FMComms5 Multi-chip synchronization (MCS).
:param iio.Context ctx: IIO Context object of FMComms5
:param int flags: Control flags for MCS configuration
"""
if math.trunc(flags) != flags:
raise Exception("flags must be an integer")
cflags = c_uint(flags)
ret = _ad9361_fmcomms5_multichip_sync(ctx._context, cflags)
if ret != 0:
raise Exception(f"Setting MCS failed. ERROR: {ret}")
return ret
def set_bb_rate(dev: iio.Device, rate: int):
"""Baseband rate configuration with generic filter support.
:param: iio.Device dev: IIO Device object of AD9361 transceiver phy driver
:param int rate: Desired sample rate between 61.44 MSPS and 520833 SPS
"""
if math.trunc(rate) != rate:
raise Exception("rate must be an integer")
ret = _ad9361_set_bb_rate(dev._device, c_ulong(int(rate)))
if ret != 0:
raise Exception(f"Setting rate failed. ERROR: {ret}")
return ret
def set_trx_fir_enable(dev: iio.Device, enable: int):
"""Enable or disable transmit and receiver FIRs simultaneously.
:param: iio.Device dev: IIO Device object of AD9361 transceiver phy driver
:param int enable: Enable FIRs when 1 or disable when 0
"""
if math.trunc(enable) != enable:
raise Exception("enable must be an integer")
ret = _ad9361_set_trx_fir_enable(dev._device, c_int(int(enable)))
if ret != 0:
raise Exception(f"Failed setting filters state. ERROR: {ret}")
return ret
def get_trx_fir_enable(dev: iio.Device):
"""Get current enable value of transmit and receiver FIRs.
:param: iio.Device dev: IIO Device object of AD9361 transceiver phy driver
"""
enable = c_int(0)
ret = _ad9361_get_trx_fir_enable(dev._device, enable)
if ret != 0:
raise Exception(f"Failed to get filters state. ERROR: {ret}")
return int(enable.value)
def set_bb_rate_custom_filter_auto(dev: iio.Device, rate: int):
"""Baseband rate configuration with custom filter support based on desired
baseband sample rate.
:param: iio.Device dev: IIO Device object of AD9361 transceiver phy driver
:param int rate: Desired sample rate between 61.44 MSPS and 520833 SPS
"""
if math.trunc(rate) != rate:
raise Exception("rate must be an integer")
ret = _ad9361_set_bb_rate_custom_filter_auto(dev._device, c_ulong(int(rate)))
if ret != 0:
raise Exception(f"Failed to set custom filter. ERROR: {ret}")
return ret
def fmcomms5_phase_sync(ctx: iio.Context, lo: int):
"""FMComms5 phase synchronize all TX and RX channels together.
:param iio.Context ctx: IIO Context object of FMComms5
:param int lo: Frequency in hertz of LO for TX and RX
"""
if math.trunc(lo) != lo:
raise Exception("lo must be an integer")
ret = _ad9361_fmcomms5_phase_sync(ctx._context, c_longlong(int(lo)))
if ret != 0:
raise Exception(f"Failed to sync FMComms5. ERROR: {ret}")
return ret
def generate_fir_taps(fdp: FilterDesignParameters):
"""Design custom FIR filter from specific design criteria.
:param FilterDesignParameters fdp: Design structure for filter wizard
"""
taps = (c_short * 128)()
num_taps = c_int(0)
gain = c_int(0)
ret = _ad9361_generate_fir_taps(byref(fdp), taps, byref(num_taps), byref(gain))
if ret != 0:
raise Exception(f"Failed to generate taps. ERROR: {ret}")
return taps[0 : num_taps.value], gain.value
def calculate_rf_clock_chain(rate: int, rate_gov: bool):
"""Calculate the clock path rates for both transmit and receiver paths.
:param int rate: Desired interface rate of transmit and receive
:param bool rate_gov: Force HB3 dec == 3
"""
if math.trunc(rate) != rate or rate < 0:
raise Exception("rate must be an integer > 0")
rx_path_clks = (c_ulong * 6)()
tx_path_clks = (c_ulong * 6)()
ret = _ad9361_calculate_rf_clock_chain(
c_ulong(int(rate)),
c_ulong(int(rate_gov > 0)),
rx_path_clks,
tx_path_clks,
)
if ret != 0:
raise Exception(f"Failed to generate clock chain. ERROR: {ret}")
return list(rx_path_clks), list(tx_path_clks)
def calculate_rf_clock_chain_fdp(rate: int):
"""Calculate the clock path rates and default filter settings for both
transmit and receiver for a desired baseband rate.
:param int rate: Desired interface rate of transmit and receive
"""
if math.trunc(rate) != rate or rate < 0:
raise Exception("rate must be an integer > 0")
rxfdp = FilterDesignParameters()
txfdp = FilterDesignParameters()
ret = _ad9361_calculate_rf_clock_chain_fdp(
byref(txfdp), byref(rxfdp), c_ulong(int(rate))
)
if ret != 0:
raise Exception(f"Failed to generate taps. ERROR: {ret}")
return rxfdp, txfdp
def set_bb_rate_custom_filter_manual(
dev: iio.Device, rate: int, Fpass: int, Fstop: int, wnom_tx: int, wnom_rx: int
):
"""Baseband rate configuration with custom filter support based on desired
baseband sample rate and simplified filter configuration.
:param: iio.Device dev: IIO Device object of AD9361 transceiver phy driver
:param int rate: Desired interface rate of transmit and receive
:param int Fpass: Start edge frequency in hertz of stopband
:param int Fstop: Stop edge frequency in hertz of passband
:param int wnom_tx: TX RF bandwidth of analog filter in hertz
:param int wnom_rx: RX RF bandwidth of analog filter in hertz
"""
for v in ["rate", "Fpass", "Fstop", "wnom_tx", "wnom_rx"]:
x = eval(f"{v}")
if math.trunc(x) != x or x < 0:
raise Exception(f"{v} must be an integer > 0")
ret = _ad9361_set_bb_rate_custom_filter_manual(
dev._device,
c_ulong(int(rate)),
c_ulong(int(Fpass)),
c_ulong(int(Fstop)),
c_ulong(int(wnom_tx)),
c_ulong(int(wnom_rx)),
)
if ret != 0:
raise Exception(f"Failed to generate clock chain. ERROR: {ret}")
return ret
libad9361-iio-0.3/bindings/python/doc/ 0000775 0000000 0000000 00000000000 14424151631 0017414 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/bindings/python/doc/conf.py.in 0000664 0000000 0000000 00000004123 14424151631 0021320 0 ustar 00root root 0000000 0000000 # Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('../.'))
#sys.path.insert(0, os.path.abspath('../examples'))
import iio
# -- Project information -----------------------------------------------------
project = '@PROJECT_NAME@'
copyright = '2021, Analog Devices, Inc.'
author = 'Paul Cercueil '
# The full version, including alpha/beta/rc tags
release = '@LIBAD9361_VERSION@'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ["sphinx.ext.githubpages", 'sphinx.ext.viewcode', 'sphinx.ext.autodoc']
#]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "furo"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static']
master_doc = 'index'
libad9361-iio-0.3/bindings/python/doc/functions.rst 0000664 0000000 0000000 00000000147 14424151631 0022160 0 ustar 00root root 0000000 0000000 Library Functions
==================
API Functions
--------------
.. automodule:: ad9361
:members:
libad9361-iio-0.3/bindings/python/doc/index.rst 0000664 0000000 0000000 00000001666 14424151631 0021266 0 ustar 00root root 0000000 0000000 libad9361-iio Python Bindings
==================================
Python bindings for the `libad9361-iio`. A device-specific library for AD936X transceivers.
Installation
==================
The libad9361-iio python bindings can be installed from pip
.. code-block:: bash
(sudo) pip install pylibad9361
or by grabbing the source directly
.. code-block:: bash
git clone https://github.com/analogdevicesinc/libad9361-iio.git
cd bindings/python
(sudo) python3 setup.py install
.. note::
On Linux the libad9361-iio python bindings are sometimes installed in locations not on path. On Ubuntu this is a common fix
.. code-block:: bash
export PYTHONPATH=$PYTHONPATH:/usr/lib/python{python-version}/site-packages
.. toctree::
:maxdepth: 1
:caption: Contents:
Components
==================
.. toctree::
:maxdepth: 1
functions
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
libad9361-iio-0.3/bindings/python/requirements.txt 0000664 0000000 0000000 00000000011 14424151631 0022123 0 ustar 00root root 0000000 0000000 pylibiio
libad9361-iio-0.3/bindings/python/requirements_dev.txt 0000664 0000000 0000000 00000000034 14424151631 0022766 0 ustar 00root root 0000000 0000000 pytest
pytest-libiio==0.0.13 libad9361-iio-0.3/bindings/python/requirements_doc.txt 0000664 0000000 0000000 00000000014 14424151631 0022753 0 ustar 00root root 0000000 0000000 sphinx
furo
libad9361-iio-0.3/bindings/python/setup.py.cmakein 0000664 0000000 0000000 00000006266 14424151631 0022001 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# Copyright (C) 2021 Analog Devices, Inc.
# Author: Travis Collins
from setuptools import setup, find_packages
from setuptools.command.install import install
config = dict(long_description_content_type="text/markdown")
description = "Device specific library for AD936X transceivers"
try:
with open("${CMAKE_CURRENT_SOURCE_DIR}/README.md", "r") as fh:
long_description = fh.read()
except:
long_description = description
def find_recursive(folder, filename):
import os
for root, dirs, files in os.walk(folder):
for file in files:
if file == filename:
return os.path.join(root, file)
class InstallWrapper(install):
"""Before installing we check if the
libad9361 library is actually installed"""
def run(self):
self._check_libad9361_installed()
# Run the standard PyPi copy
install.run(self)
def _check_libad9361_installed(self):
lib_check = ("${LIB_CHECK_PYINSTALL}" == "OFF")
if lib_check:
# When cross-compiling or installing from git, we generally cannot
# dlopen the libad9361 shared lib from the build platform.
# Simply skip this check in that case.
return
from platform import system as _system
from ctypes import CDLL as _cdll
from ctypes.util import find_library
if "Windows" in _system():
_ad9361lib = "libad9361.dll"
else:
# Non-windows, possibly Posix system
_ad9361lib = "ad9361"
try:
import os
destdir = os.getenv("DESTDIR", "")
if destdir:
destdir = os.path.join("${CMAKE_BINARY_DIR}", destdir)
fulllibpath = find_recursive(destdir, "libad9361.so")
_lib = _cdll(fulllibpath, use_errno=True, use_last_error=True)
else:
_lib = _cdll(find_library(_ad9361lib), use_errno=True, use_last_error=True)
if not _lib._name:
raise OSError
except OSError:
msg = "The libad9361 library could not be found.\n\
libad9361 needs to be installed first before the python bindings.\n\
The latest release can be found on GitHub:\n\
https://github.com/analogdevicesinc/libad9361-iio/releases"
raise Exception(msg)
config.update(
dict(
name="pylibad9361",
version="${VERSION}",
maintainer="Analog Devices, Inc",
maintainer_email="travis.collins@analog.com",
description=description,
long_description=long_description,
url="https://github.com/analogdevicesinc/libad9361",
install_requires=["pylibiio==0.23.1"],
py_modules=["ad9361"],
packages=find_packages(exclude=["test*"]),
python_requires=">=3.6",
cmdclass={"install": InstallWrapper},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)",
"Operating System :: OS Independent",
],
)
)
setup(**config)
libad9361-iio-0.3/bindings/python/tasks.py 0000664 0000000 0000000 00000001337 14424151631 0020352 0 ustar 00root root 0000000 0000000 from invoke import task
@task
def bumpversion_test(c):
"""Bump version to {current-version}.dev.{date}
Used for marking development releases for test-pypi
"""
import fileinput
import time
for line in fileinput.input("setup.py", inplace=True):
if line.find("version") > -1:
l = line[len("version="):].strip()[:-1].strip("\"=version")[:].split(".")
major = (l[0])
minor = (l[1])
seconds = int(time.time())
line = ' version="{}.{}.{}",\n'.format(
major, minor, seconds
)
ver_string = "v{}.{}".format(major, minor, seconds)
print(line, end="")
print(f"Version bumped to {ver_string}")
libad9361-iio-0.3/bindings/python/test/ 0000775 0000000 0000000 00000000000 14424151631 0017626 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/bindings/python/test/LTE15_MHz.ftr 0000664 0000000 0000000 00000003037 14424151631 0021716 0 ustar 00root root 0000000 0000000 # Generated with the MATLAB AD9361 Filter Design Wizard
# Generated 05-Feb-2015 17:27:51
# Inputs:
# Data Sample Frequency = 23040000.000000 Hz
TX 3 GAIN 0 INT 2
RX 3 GAIN -6 DEC 2
RTX 737280000 184320000 184320000 92160000 46080000 23040000
RRX 737280000 368640000 184320000 92160000 46080000 23040000
BWTX 14524078
BWRX 14524135
-5,-9
0,-23
4,-20
23,-22
36,12
39,20
18,29
-13,-5
-36,-30
-26,-43
11,-6
48,40
46,64
-2,24
-60,-47
-72,-90
-16,-49
69,49
104,122
43,85
-74,-44
-142,-158
-82,-134
71,29
184,196
136,196
-57,-1
-228,-234
-205,-274
26,-46
272,270
291,368
25,114
-311,-298
-395,-481
-101,-212
342,315
519,612
210,344
-357,-312
-663,-762
-361,-522
349,282
829,935
564,757
-307,-212
-1022,-1133
-841,-1074
216,80
1251,1365
1225,1510
-44,149
-1536,-1646
-1793,-2146
-268,-551
1930,2016
2728,3173
873,1310
-2622,-2634
-4718,-5298
-2416,-3194
4788,4431
13982,14435
20380,21470
20380,21470
13982,14435
4788,4431
-2416,-3194
-4718,-5298
-2622,-2634
873,1310
2728,3173
1930,2016
-268,-551
-1793,-2146
-1536,-1646
-44,149
1225,1510
1251,1365
216,80
-841,-1074
-1022,-1133
-307,-212
564,757
829,935
349,282
-361,-522
-663,-762
-357,-312
210,344
519,612
342,315
-101,-212
-395,-481
-311,-298
25,114
291,368
272,270
26,-46
-205,-274
-228,-234
-57,-1
136,196
184,196
71,29
-82,-134
-142,-158
-74,-44
43,85
104,122
69,49
-16,-49
-72,-90
-60,-47
-2,24
46,64
48,40
11,-6
-26,-43
-36,-30
-13,-5
18,29
39,20
36,12
23,-22
4,-20
0,-23
-5,-9
libad9361-iio-0.3/bindings/python/test/test_ad9361.py 0000664 0000000 0000000 00000010173 14424151631 0022150 0 ustar 00root root 0000000 0000000 import pytest
import iio
import ad9361
import os
import pathlib
ad9361_all = ["fmcomms2", "fmcomms5", "ad9361", "ad9364"]
path = pathlib.Path(__file__).parent.absolute()
filterfile_name = os.path.join(path, "LTE15_MHz.ftr")
@pytest.mark.iio_hardware(ad9361_all)
@pytest.mark.parametrize("rate_msps", [*(range(1, 30))])
def test_bb_rate(iio_uri, rate_msps):
rate = rate_msps * 1e6
ctx = iio.Context(iio_uri)
dev = ctx.find_device("ad9361-phy")
ad9361.set_bb_rate(dev, int(rate))
hw = float(dev.find_channel("voltage0").attrs["sampling_frequency"].value)
assert abs(rate - hw) < 3
@pytest.mark.iio_hardware(ad9361_all)
@pytest.mark.parametrize("rate_msps", [*(range(1, 30))])
def test_bb_rate_custom_filter_manual(iio_uri, rate_msps):
rate = rate_msps * 1e6
ctx = iio.Context(iio_uri)
dev = ctx.find_device("ad9361-phy")
Fstop = rate * 0.6
Fpass = rate * 0.4
wnom = Fpass
ad9361.set_bb_rate_custom_filter_manual(
dev, int(rate), int(Fpass), int(Fstop), int(wnom), int(wnom)
)
hw = float(dev.find_channel("voltage0").attrs["sampling_frequency"].value)
assert abs(rate - hw) < 3
@pytest.mark.iio_hardware(ad9361_all)
@pytest.mark.parametrize("rate_msps", [*(range(1, 30))])
def test_bb_rate_custom_filter(iio_uri, rate_msps):
rate = rate_msps * 1e6
ctx = iio.Context(iio_uri)
dev = ctx.find_device("ad9361-phy")
ad9361.set_bb_rate_custom_filter_auto(dev, int(rate))
hw = float(dev.find_channel("voltage0").attrs["sampling_frequency"].value)
assert abs(rate - hw) < 3
@pytest.mark.iio_hardware("fmcomms5")
def test_mcs(iio_uri):
ctx = iio.Context(iio_uri)
main = ctx.find_device("ad9361-phy")
assert main
secondary = ctx.find_device("ad9361-phy-B")
assert secondary
ret = ad9361.multichip_sync(main, [secondary], 3)
assert ret == 0
@pytest.mark.iio_hardware("fmcomms5")
def test_fmc5_mcs(iio_uri):
ctx = iio.Context(iio_uri)
ret = ad9361.fmcomms5_multichip_sync(ctx, 3)
assert ret == 0
@pytest.mark.iio_hardware(ad9361_all)
def test_trx_fir_enable(iio_uri):
ctx = iio.Context(iio_uri)
dev = ctx.find_device("ad9361-phy")
assert dev
# Set sample rate so filter isn't needed
dev.find_channel("voltage0").attrs["sampling_frequency"].value = "3000000"
# disable filter and check
ad9361.set_trx_fir_enable(dev, 0)
assert dev.find_channel("voltage0").attrs["filter_fir_en"].value == "0"
assert dev.find_channel("voltage0", True).attrs["filter_fir_en"].value == "0"
# Load filter
with open(filterfile_name, "r") as file:
data = file.read()
dev.attrs["filter_fir_config"].value = data
# Enable filter and check
ad9361.set_trx_fir_enable(dev, 1)
assert ad9361.get_trx_fir_enable(dev) == 1
assert dev.find_channel("voltage0").attrs["filter_fir_en"].value == "1"
assert dev.find_channel("voltage0", True).attrs["filter_fir_en"].value == "1"
# Disable filter and check
ad9361.set_trx_fir_enable(dev, 0)
assert dev.find_channel("voltage0").attrs["filter_fir_en"].value == "0"
assert dev.find_channel("voltage0", True).attrs["filter_fir_en"].value == "0"
@pytest.mark.iio_hardware("fmcomms5")
def test_fmc5_phase_sync(iio_uri):
ctx = iio.Context(iio_uri)
ret = ad9361.fmcomms5_phase_sync(ctx, 1e9)
assert ret == 0
def test_generate_fir_taps():
rate = 10e6
[rxfdp, txfdp] = ad9361.calculate_rf_clock_chain_fdp(rate)
assert rxfdp.Rdata == rate
assert txfdp.Rdata == rate
[tapsRX, gain] = ad9361.generate_fir_taps(rxfdp)
[tapsTX, gainTX] = ad9361.generate_fir_taps(txfdp)
def compare(taps):
rtaps = taps[int(len(taps) / 2) :]
rtaps = rtaps[::-1]
for k in range(64):
assert taps[k] == rtaps[k]
compare(tapsRX)
compare(tapsTX)
def test_generate_clock_chain():
rate = 10e6
rate_gov = 0
[rx_path_clks, tx_path_clks] = ad9361.calculate_rf_clock_chain(rate, rate_gov)
rx_ref = [960000000, 480000000, 160000000, 80000000, 40000000, 10000000]
tx_ref = [960000000, 240000000, 80000000, 40000000, 40000000, 10000000]
assert rx_path_clks == rx_ref
assert tx_path_clks == tx_ref
libad9361-iio-0.3/cmake/ 0000775 0000000 0000000 00000000000 14424151631 0014611 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/cmake/DarwinPackaging.cmake 0000664 0000000 0000000 00000000570 14424151631 0020646 0 ustar 00root root 0000000 0000000 # support creating some basic binpkgs via `make package`
set(CPACK_SET_DESTDIR ON)
set(CPACK_GENERATOR TGZ)
set(CPACK_PACKAGE_VERSION_MAJOR ${LIBAD9361_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${LIBAD9361_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH g${LIBAD9361_VERSION_GIT})
set(CPACK_BUNDLE_NAME libad9361)
set(CPACK_PACKAGE_VERSION ${VERSION})
include(CPack)
libad9361-iio-0.3/cmake/LinuxPackaging.cmake 0000664 0000000 0000000 00000007343 14424151631 0020526 0 ustar 00root root 0000000 0000000 # support creating some basic binpkgs via `make package`
set(CPACK_SET_DESTDIR ON)
set(CPACK_GENERATOR TGZ;DEB)
FIND_PROGRAM(RPMBUILD_CMD rpmbuild)
if (RPMBUILD_CMD)
set(CPACK_PACKAGE_RELOCATABLE OFF)
set(CPACK_GENERATOR ${CPACK_GENERATOR};RPM)
endif()
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
set(CPACK_PACKAGE_VERSION_MAJOR ${LIBAD9361_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${LIBAD9361_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH g${LIBAD9361_VERSION_GIT})
set(CPACK_BUNDLE_NAME libad9361)
set(CPACK_PACKAGE_VERSION ${VERSION})
# debian specific package settings
set(CPACK_PACKAGE_CONTACT "Engineerzone ")
option(DEB_DETECT_DEPENDENCIES "Detect dependencies for .deb packages" OFF)
# if we are going to be looking for things, make sure we have the utilities
if(DEB_DETECT_DEPENDENCIES)
FIND_PROGRAM(DPKG_CMD dpkg)
FIND_PROGRAM(DPKGQ_CMD dpkg-query)
endif()
# if we want to, and have the capabilities find what is needed,
# based on what backends are turned on and what libraries are installed
if(DEB_DETECT_DEPENDENCIES AND DPKG_CMD AND DPKGQ_CMD)
message(STATUS "querying installed packages on system for dependancies")
execute_process(COMMAND "${DPKG_CMD}" --print-architecture
OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
OUTPUT_STRIP_TRAILING_WHITESPACE)
# don't add a package dependancy if it is not installed locally
# these should be the debian package names
set(PACKAGES "libc6 libiio")
# find the version of the installed package, which is hard to do in
# cmake first, turn the list into an list (seperated by semicolons)
string(REGEX REPLACE " " ";" PACKAGES ${PACKAGES})
# then iterate over each
foreach(package ${PACKAGES})
# List packages matching given pattern ${package},
# key is the glob (*) at the end of the ${package} name,
# so we don't need to be so specific
execute_process(COMMAND "${DPKG_CMD}" -l ${package}*
OUTPUT_VARIABLE DPKG_PACKAGES)
# returns a string, in a format:
# ii libxml2:amd64 2.9.4+dfsg1- amd64 GNOME XML library
# 'ii' means installed - which is what we are looking for
STRING(REGEX MATCHALL "ii ${package}[a-z0-9A-Z.-]*"
DPKG_INSTALLED_PACKAGES ${DPKG_PACKAGES})
# get rid of the 'ii', and split things up, so we can look
# at the name
STRING(REGEX REPLACE "ii " ";" NAME_INSTALLED_PACKAGES
${DPKG_INSTALLED_PACKAGES})
foreach(match ${NAME_INSTALLED_PACKAGES})
# ignore packages marked as dev, debug,
# documentations, or utils
STRING(REGEX MATCHALL "dev|dbg|doc|utils" TEMP_TEST
${match})
if("${TEMP_TEST}" STREQUAL "")
# find the actual version, executes:
# dpkg-query --showformat='\${Version}'
# --show libusb-1.0-0
execute_process(COMMAND "${DPKGQ_CMD}"
--showformat='\${Version}'
--show "${match}"
OUTPUT_VARIABLE DPKGQ_VER)
# debian standard is package_ver-debian_ver,
# "'2.9.4+dfsg1-2.1'"
# ignore patches and debian suffix version, and
# remove single quote
string(REGEX REPLACE "[+-][a-z0-9A-Z.]*" ""
DPKGQ_VER ${DPKGQ_VER})
string(REGEX REPLACE "'" "" DPKGQ_VER
${DPKGQ_VER})
# build the string for the Debian dependancy
set(CPACK_DEBIAN_PACKAGE_DEPENDS
"${CPACK_DEBIAN_PACKAGE_DEPENDS}"
"${match} (>= ${DPKGQ_VER}), ")
endif()
endforeach(match)
endforeach(package)
# remove the dangling end comma
string(REGEX REPLACE ", $" "" CPACK_DEBIAN_PACKAGE_DEPENDS
${CPACK_DEBIAN_PACKAGE_DEPENDS})
else()
# assume everything is turned on, and running on a modern OS
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6-dev (>= 2.19)")
message(STATUS "Using default dependencies for packaging")
endif()
message(STATUS "Package dependencies: " ${CPACK_DEBIAN_PACKAGE_DEPENDS})
include(CPack)
libad9361-iio-0.3/cmake/cmake_uninstall.cmake.in 0000664 0000000 0000000 00000002532 14424151631 0021373 0 ustar 00root root 0000000 0000000 # http://www.vtk.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
STRING(REGEX REPLACE "\n" ";" files "${files}")
FOREACH(file ${files})
MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
IF(EXISTS "$ENV{DESTDIR}${file}")
EXEC_PROGRAM(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
IF(NOT "${rm_retval}" STREQUAL 0)
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
ENDIF(NOT "${rm_retval}" STREQUAL 0)
ELSEIF(IS_SYMLINK "$ENV{DESTDIR}${file}")
EXEC_PROGRAM(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
IF(NOT "${rm_retval}" STREQUAL 0)
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
ENDIF(NOT "${rm_retval}" STREQUAL 0)
ELSE(EXISTS "$ENV{DESTDIR}${file}")
MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
ENDIF(EXISTS "$ENV{DESTDIR}${file}")
ENDFOREACH(file)
libad9361-iio-0.3/debian/ 0000775 0000000 0000000 00000000000 14424151631 0014753 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/debian/.gitignore 0000664 0000000 0000000 00000000114 14424151631 0016737 0 ustar 00root root 0000000 0000000 *.substvars
*.debhelper
*.log
files
libad9361-0
libad9361-dev
tmp
substvars
libad9361-iio-0.3/debian/changelog 0000664 0000000 0000000 00000000213 14424151631 0016621 0 ustar 00root root 0000000 0000000 libad9361 (0.1) unstable; urgency=low
* Initial release.
-- Paul Cercueil Wed, 29 Jul 2015 14:46:52 +0200
libad9361-iio-0.3/debian/compat 0000664 0000000 0000000 00000000002 14424151631 0016151 0 ustar 00root root 0000000 0000000 9
libad9361-iio-0.3/debian/control 0000664 0000000 0000000 00000001664 14424151631 0016365 0 ustar 00root root 0000000 0000000 Source: libad9361
Section: libs
Priority: optional
Maintainer: Paul Cercueil
Build-Depends: cmake (>= 2.8), debhelper (>= 9)
Standards-Version: 3.9.6
Homepage: http://github.com/analogdevicesinc/libad9361-iio
Vcs-Git: git://github.com/analogdevicesinc/libad9361-iio
Package: libad9361-0
Architecture: any
Multi-Arch: same
Pre-Depends: ${misc:Pre-Depends}
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: Library of functions specific to the Analog Devices AD9361
This library contains a few functions useful to configure and use the
Analog Devices AD9361 Agile Transceiver.
Package: libad9361-dev
Architecture: any
Depends: libad9361-0 (= ${binary:Version}), ${misc:Depends}
Description: Library of functions specific to the Analog Devices AD9361
This library contains a few functions useful to configure and use the
Analog Devices AD9361 Agile Transceiver.
.
This package contains the development files.
libad9361-iio-0.3/debian/copyright 0000664 0000000 0000000 00000002206 14424151631 0016706 0 ustar 00root root 0000000 0000000 Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: libad9361
Upstream-Contact: Paul Cercueil
Source: https://github.com/analogdevicesinc/libad9361-iio/
Files: *
Copyright: 2015, Analog Devices Inc.
License: LGPL-2.1+
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at
your option) any later version.
.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
General Public License for more details.
.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
.
On Debian systems, the full text of the GNU Lesser General Public
License version 2.1 can be found in the file
`/usr/share/common-licenses/LGPL-2.1'.
libad9361-iio-0.3/debian/libad9361-0.install 0000664 0000000 0000000 00000000032 14424151631 0020071 0 ustar 00root root 0000000 0000000 usr/lib/*/libad9361.so.0*
libad9361-iio-0.3/debian/libad9361-dev.install 0000664 0000000 0000000 00000000067 14424151631 0020520 0 ustar 00root root 0000000 0000000 usr/include
usr/lib/*/libad9361.so
usr/lib/*/pkgconfig
libad9361-iio-0.3/debian/rules 0000775 0000000 0000000 00000000464 14424151631 0016037 0 ustar 00root root 0000000 0000000 #!/usr/bin/make -f
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
%:
dh $@ --parallel
override_dh_auto_configure:
dh_auto_configure -- -DINSTALL_LIB_DIR=/usr/lib/$(DEB_HOST_MULTIARCH)
override_dh_compress:
dh_compress -X.c -X.C
override_dh_clistrip:
dh_clistrip --exclude=mdb
libad9361-iio-0.3/doc/ 0000775 0000000 0000000 00000000000 14424151631 0014276 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/doc/AD9361.svg 0000664 0000000 0000000 00001006023 14424151631 0015630 0 ustar 00root root 0000000 0000000
image/svg+xml
RxA
RxB
RxC
Baseband
GPO
Rx Channel 1
Rx Channel 2
12-bit
Tx Channel 1
Tx Channel 2
SPI
Reset
CTRL
DIV
Tx Mon
Sheet.256
Calibration and Correction
70MHz - 6GHz
Tx
Rx
Ch1 I/Q
Ch2 I/Q
Ch1 I/Q
Ch2 I/Q
Temperature Sensor
Sheet.256
Sheet.256
70MHz - 6GHz
Rx
Tx
DIV
DIV
Rx 61.44 MSPS
Enable State Machine (ENSM)
TxA
TxB
AD9361
DIV
GND
Dual 10-bit
Automatic Gain Control
â–¡ Manual â–¡ Slow â–¡ Fast
25 - 640 MSPS
FIR
HB2
HB1
GAIN
HB3
I
ADC
RF Channel Bandwidth
200kHz - 56MHz (I/Q)
÷1 ÷2 ÷3
÷1 ÷2
÷1 ÷2
÷1 ÷2 ÷4
FIR
HB2
HB1
GAIN
HB3
Q
ADC
Phase Splitter
Sheet.256
Rx
Tx
Rx Decimation Digital Filtering and Equalization
RF Channel Bandwidth
Tx Interpolation Digital Filtering and Equalization
200kHz - 56MHz (I/Q)
1x 2x 3x
1x 2x
1x 2x
1x 2x 4 x
I
Q
FIR
HB1
HB2
HB3
DAC
Phase Splitter
320 MSPS
FIR
HB1
HB2
HB3
DAC
Sheet.256
Input Mux
AUX DAC
AUX ADC
LNA
TIA
TIA
ATTN
Sheet.256
Output Mux
Sheet.256
CMOS / LVDS INTERFACE
Tx 61.44 MSPS
LOOP BACK
PN & BIST
Sheet.256
715 MHz - 1430 MHz
DCXO
VDD_GPO
VDD_INTERFACE
VDD_MAIN
RX2A_P, RX2A_N RX1A_P, RX1A_N
RX2B_P, RX2B_N RX1B_P, RX1B_N
RX2C_P, RX2C_N RX1C_P, RX1C_N
TXMON2
TXMON1
RXLO
TXLO
SPI
CTRL
AUXDAC1 AUXDAC2
TX2A_P, TX2A_N TX1A_P, TX1A_N
TX2B_P, TX2B_N TX1B_P, TX1B_N
AUXADC
XTALP
XTALN
RADIO SWITCHING
RESETB
P0_[D11:D0]/ TX_[D5:D0] P1_[D11:D0]/ RX_[D5:D0]
GND
1.8 - 3.3V
1.2V - 2.5V
1.3 V
libad9361-iio-0.3/filterdesigner/ 0000775 0000000 0000000 00000000000 14424151631 0016537 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/filterdesigner/internal_design_filter_cg.c 0000664 0000000 0000000 00002103274 14424151631 0024077 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
/* Include Files */
#include "rt_nonfinite.h"
#include "internal_design_filter_cg.h"
#include "internal_design_filter_cg_emxutil.h"
#include
/* Type Definitions */
#ifndef typedef_struct_T
#define typedef_struct_T
typedef struct {
double nfft[2048];
double Fs;
double w[2048];
double fvflag;
char range[8];
double centerdc;
char configlevel[7];
} struct_T;
#endif /*typedef_struct_T*/
/* Function Declarations */
static void analogresp(const char type[2], const double f[2048], double
Fconverter, const double b1_data[], const int b1_size[2], const
emxArray_creal_T *a1, const double b2_data[], const int b2_size[2], const
emxArray_creal_T *a2, creal_T abc[2048]);
static boolean_T anyNonFinite(const emxArray_creal_T *x);
static void b_abs(const emxArray_creal_T *x, emxArray_real_T *y);
static void b_acos(double *x);
static void b_analogresp(const char type[2], const emxArray_real_T *f, double
Fconverter, const double b1_data[], const int b1_size[2], const
emxArray_creal_T *a1, const double b2_data[], const int b2_size[2], const
emxArray_creal_T *a2, emxArray_creal_T *abc);
static void b_butter_cg(double Wn, double num[4], emxArray_creal_T *den);
static void b_cos(emxArray_real_T *x);
static void b_determineBestFractionLength(const double tap_store[128], double
taps[128]);
static void b_exp(creal_T x[2048]);
static void b_firfreqz(const double b[15], const struct_T *options, creal_T h
[2048], double w[2048]);
static void b_firpm_cg(double order, const double ff[4], const emxArray_real_T
*amplitudes, const emxArray_real_T *frequencies, const emxArray_real_T
*weights, emxArray_real_T *h, boolean_T *valid, double *err);
static void b_fix(double *x);
static void b_freqs_cg(const double b_data[], const int b_size[2], const
emxArray_creal_T *a, const emxArray_real_T *w, emxArray_creal_T *h);
static void b_freqz_cg(const double b[15], const double w[2048], double Fs,
creal_T hh[2048]);
static void b_generateCascadedResponseRx(const char enables[4], const
emxArray_real_T *w, double Fs, const double hb1_coeff[15], const double
hb2_coeff[7], const double hb3_coeff_data[], const int hb3_coeff_size[2],
const double dec_int3_coeff_data[], const int dec_int3_coeff_size[2],
emxArray_creal_T *combinedResponse);
static double b_log2(double x);
static void b_polyval(const double p[7], const creal_T x[2048],
creal_T y[2048]);
static void b_power(const double a[2048], double y[2048]);
static void b_rdivide(const emxArray_creal_T *x, const emxArray_creal_T *y,
emxArray_creal_T *z);
static void b_sinc(emxArray_real_T *x);
static void b_sqrt(double *x);
static boolean_T b_strcmp(const char a[2]);
static double b_sum(const emxArray_real_T *x);
static void b_us(const double o[7], double u[7]);
static void b_xscal(int n, const creal_T a, emxArray_creal_T *x, int ix0, int
incx);
static void b_xzlartg(const creal_T f, const creal_T g, double *cs,
creal_T *sn);
static void butter_cg(double Wn, double num[2], creal_T den_data[], int
den_size[2]);
static void c_abs(const emxArray_real_T *x, emxArray_real_T *y);
static void c_analogresp(const emxArray_real_T *f, double Fconverter, const
double b1_data[], const int b1_size[2], const emxArray_creal_T *a1, const
double b2_data[], const int b2_size[2], const emxArray_creal_T *a2,
emxArray_creal_T *abc);
static void c_exp(emxArray_creal_T *x);
static void c_firfreqz(const double b[7], const struct_T *options, creal_T h
[2048], double w[2048]);
static void c_fix(emxArray_real_T *x);
static void c_freqz_cg(const double b[7], const double w[2048], double Fs,
creal_T hh[2048]);
static void c_generateCascadedResponseRx(const char enables[4], const
emxArray_real_T *w, double Fs, const double hb1_coeff[15], const double
hb2_coeff[7], const double hb3_coeff_data[], const int hb3_coeff_size[2],
const double dec_int3_coeff_data[], const int dec_int3_coeff_size[2], const
emxArray_real_T *extraTaps, emxArray_creal_T *combinedResponse);
static void c_polyval(const double p_data[], const int p_size[2], const creal_T
x[2048], creal_T y[2048]);
static void c_power(const emxArray_real_T *a, emxArray_real_T *y);
static void c_rdivide(const emxArray_real_T *x, const emxArray_real_T *y,
emxArray_real_T *z);
static void c_sqrt(creal_T *x);
static boolean_T c_strcmp(const char a[2]);
static double c_sum(const double x[128]);
static void c_us(const double o_data[], const int o_size[2], double u_data[],
int u_size[2]);
static double dBinv(double dBinput);
static void d_abs(const double x[128], double y[128]);
static void d_analogresp(const emxArray_real_T *f, double Fconverter, const
double b1_data[], const int b1_size[2], const emxArray_creal_T *a1, const
double b2_data[], const int b2_size[2], const emxArray_creal_T *a2,
emxArray_creal_T *abc);
static void d_firfreqz(double b_data[], int b_size[2], const struct_T *options,
creal_T h[2048], double w[2048]);
static void d_freqz_cg(const double b_data[], const int b_size[2], const double
w[2048], double Fs, creal_T hh[2048]);
static void d_polyval(const double p[29], const creal_T x[2048],
creal_T y[2048]);
static void d_us(const double o[15], double u[29]);
static double db2mag(double ydb);
static void determineBestFractionLength(const emxArray_real_T *tap_store, double
i, double M, emxArray_real_T *taps);
static int div_s32_floor(int numerator, int denominator);
static void e_firfreqz(const double b[29], const struct_T *options, creal_T h
[2048], double w[2048]);
static void e_freqz_cg(const double b[29], const double w[2048], double Fs,
creal_T hh[2048]);
static void e_polyval(const double p[13], const creal_T x[2048],
creal_T y[2048]);
static void e_us(const double o[7], double u[13]);
static void eig(const emxArray_creal_T *A, emxArray_creal_T *V);
static int eml_zlahqr(emxArray_creal_T *h);
static void f_firfreqz(const double b[13], const struct_T *options, creal_T h
[2048], double w[2048]);
static void f_freqz_cg(const double b[13], const double w[2048], double Fs,
creal_T hh[2048]);
static void f_polyval(const double p[57], const creal_T x[2048],
creal_T y[2048]);
static void f_us(const double o[15], double u[57]);
static void firfreqz(const struct_T *options, creal_T h[2048], double w[2048]);
static void firpm_cg(double order, const double ff[4], const emxArray_real_T
*amplitudes, const emxArray_real_T *frequencies, const
emxArray_real_T *weights, emxArray_real_T *h);
static void firpmgrid_cg(double nfilt, const double ff[4], emxArray_real_T
*gridactual);
static void freqs_cg(const double b_data[], const int b_size[2], const
emxArray_creal_T *a, const double w[2048], creal_T h[2048]);
static void freqz_cg(const double w[2048], double Fs, creal_T hh[2048]);
static void g_firfreqz(const double b[57], const struct_T *options, creal_T h
[2048], double w[2048]);
static void g_freqz_cg(const double b[57], const double w[2048], double Fs,
creal_T hh[2048]);
static void g_polyval(const double p[43], const creal_T x[2048],
creal_T y[2048]);
static void g_us(const double o[15], double u[43]);
static void generateCascadedResponseRx(const char enables[4], const double w
[2048], double Fs, const double hb1_coeff[15], const double hb2_coeff[7],
const double hb3_coeff_data[], const int hb3_coeff_size[2], const double
dec_int3_coeff_data[], const int dec_int3_coeff_size[2], creal_T
combinedResponse[2048]);
static void h_firfreqz(const double b[43], const struct_T *options, creal_T h
[2048], double w[2048]);
static void h_freqz_cg(const double b[43], const double w[2048], double Fs,
creal_T hh[2048]);
static void h_polyval(const double p[19], const creal_T x[2048],
creal_T y[2048]);
static void h_us(const double o[7], double u[19]);
static void i_firfreqz(const double b[19], const struct_T *options, creal_T h
[2048], double w[2048]);
static void i_freqz_cg(const double b[19], const double w[2048], double Fs,
creal_T hh[2048]);
static void i_polyval(const double p[85], const creal_T x[2048],
creal_T y[2048]);
static void i_us(const double o[15], double u[85]);
static void interp1(const emxArray_real_T *varargin_1, const emxArray_real_T
*varargin_2, const emxArray_real_T *varargin_3,
emxArray_real_T *Vq);
static void j_firfreqz(const double b[85], const struct_T *options, creal_T h
[2048], double w[2048]);
static void j_freqz_cg(const double b[85], const double w[2048], double Fs,
creal_T hh[2048]);
static void j_polyval(const emxArray_real_T *p, const emxArray_creal_T *x,
emxArray_creal_T *y);
static void k_freqz_cg(const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh);
static void l_freqz_cg(const double b[15], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh);
static void lp2lp_cg(const emxArray_creal_T *a, const emxArray_real_T *b, double
wo, emxArray_creal_T *at, emxArray_real_T *bt, double *dt);
static void m_freqz_cg(const double b[7], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh);
static double mag2db(double y);
static double mpower(double a, double b);
static void n_freqz_cg(const emxArray_real_T *b, const emxArray_real_T *w,
double Fs, emxArray_creal_T *hh);
static void o_freqz_cg(const double b[29], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh);
static void p_freqz_cg(const double b[13], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh);
static void poly(const emxArray_creal_T *x, emxArray_creal_T *c);
static void polyval(const double p[15], const creal_T x[2048], creal_T y[2048]);
static void power(const double a[2048], double y[2048]);
static void q_freqz_cg(const double b[57], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh);
static void r_freqz_cg(const double b[43], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh);
static void rdivide(const emxArray_real_T *x, double y, emxArray_real_T *z);
static creal_T recip(const creal_T y);
static double remezdd(double k, double n, double m, const emxArray_real_T *x);
static void remezm(double nfilt, const double edge[4], const emxArray_real_T
*grid, emxArray_real_T *des, emxArray_real_T *wt,
emxArray_real_T *h, double *dev, boolean_T *valid);
static void removeTrailingZero(const double b_data[], const int b_size[2], const
emxArray_creal_T *a, double bR_data[], int bR_size[2], emxArray_creal_T *aR);
static double rt_atan2d_snf(double u0, double u1);
static double rt_hypotd_snf(double u0, double u1);
static double rt_powd_snf(double u0, double u1);
static double rt_remd_snf(double u0, double u1);
static double rt_roundd_snf(double u);
static void s_freqz_cg(const double b[19], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh);
static void sinc(double x[2048]);
static double sum(const double x[2048]);
static void t_freqz_cg(const double b[85], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh);
static void us(const double o[15], double u[15]);
static void vector_poly(const emxArray_creal_T *x, emxArray_creal_T *c);
static double xdlapy3(double x1, double x2, double x3);
static void xgehrd(emxArray_creal_T *a);
static double xnrm2(int n, const emxArray_creal_T *x, int ix0);
static void xscal(int n, const creal_T a, emxArray_creal_T *x, int ix0);
static void xzgeev(const emxArray_creal_T *A, int *info, emxArray_creal_T
*alpha1, emxArray_creal_T *beta1);
static void xzhgeqz(const emxArray_creal_T *A, int ilo, int ihi, int *info,
emxArray_creal_T *alpha1, emxArray_creal_T *beta1);
static creal_T xzlarfg(creal_T *alpha1, creal_T *x);
static void xzlartg(const creal_T f, const creal_T g, double *cs, creal_T *sn,
creal_T *r);
static void zp2ss_cg(emxArray_creal_T *a, emxArray_real_T *b,
emxArray_real_T *c,
double *d);
/* Function Definitions */
/*
* UNTITLED Summary of this function goes here
* Detailed explanation goes here
* Arguments : const char type[2]
* const double f[2048]
* double Fconverter
* const double b1_data[]
* const int b1_size[2]
* const emxArray_creal_T *a1
* const double b2_data[]
* const int b2_size[2]
* const emxArray_creal_T *a2
* creal_T abc[2048]
* Return Type : void
*/
static void analogresp(const char type[2], const double f[2048], double
Fconverter, const double b1_data[], const int b1_size[2], const
emxArray_creal_T *a1, const double b2_data[], const int b2_size[2], const
emxArray_creal_T *a2, creal_T abc[2048])
{
boolean_T b_bool;
int kstr;
int exitg1;
static const char cv33[2] = { 'T', 'x' };
static const char cv34[2] = { 'R', 'x' };
double dv14[2048];
double dv15[2048];
static creal_T dcv1[2048];
double abc_im;
double im;
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 3) {
if (type[kstr] != cv33[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 0;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 3) {
if (type[kstr] != cv34[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 1;
} else {
kstr = -1;
}
}
switch (kstr) {
case 0:
for (kstr = 0; kstr < 2048; kstr++) {
dv14[kstr] = f[kstr] / Fconverter;
}
sinc(dv14);
for (kstr = 0; kstr < 2048; kstr++) {
dv15[kstr] = 6.2831853071795862 * f[kstr];
}
freqs_cg(b1_data, b1_size, a1, dv15, abc);
for (kstr = 0; kstr < 2048; kstr++) {
dv15[kstr] = 6.2831853071795862 * f[kstr];
}
freqs_cg(b2_data, b2_size, a2, dv15, dcv1);
for (kstr = 0; kstr < 2048; kstr++) {
abc_im = dv14[kstr] * abc[kstr].re;
im = dv14[kstr] * abc[kstr].im;
abc[kstr].re = abc_im * dcv1[kstr].re - im * dcv1[kstr].im;
abc[kstr].im = abc_im * dcv1[kstr].im + im * dcv1[kstr].re;
}
break;
case 1:
for (kstr = 0; kstr < 2048; kstr++) {
dv14[kstr] = 6.2831853071795862 * f[kstr];
}
freqs_cg(b1_data, b1_size, a1, dv14, abc);
for (kstr = 0; kstr < 2048; kstr++) {
dv14[kstr] = 6.2831853071795862 * f[kstr];
}
freqs_cg(b2_data, b2_size, a2, dv14, dcv1);
for (kstr = 0; kstr < 2048; kstr++) {
dv14[kstr] = f[kstr] / Fconverter;
}
sinc(dv14);
power(dv14, dv15);
for (kstr = 0; kstr < 2048; kstr++) {
abc_im = abc[kstr].re * dcv1[kstr].im + abc[kstr].im * dcv1[kstr].re;
abc[kstr].re = dv15[kstr] * (abc[kstr].re * dcv1[kstr].re - abc[kstr].im *
dcv1[kstr].im);
abc[kstr].im = dv15[kstr] * abc_im;
}
break;
default:
/* Default to Rx */
for (kstr = 0; kstr < 2048; kstr++) {
dv14[kstr] = 6.2831853071795862 * f[kstr];
}
freqs_cg(b1_data, b1_size, a1, dv14, abc);
for (kstr = 0; kstr < 2048; kstr++) {
dv14[kstr] = 6.2831853071795862 * f[kstr];
}
freqs_cg(b2_data, b2_size, a2, dv14, dcv1);
for (kstr = 0; kstr < 2048; kstr++) {
dv14[kstr] = f[kstr] / Fconverter;
}
sinc(dv14);
power(dv14, dv15);
for (kstr = 0; kstr < 2048; kstr++) {
abc_im = abc[kstr].re * dcv1[kstr].im + abc[kstr].im * dcv1[kstr].re;
abc[kstr].re = dv15[kstr] * (abc[kstr].re * dcv1[kstr].re - abc[kstr].im *
dcv1[kstr].im);
abc[kstr].im = dv15[kstr] * abc_im;
}
break;
}
}
/*
* Arguments : const emxArray_creal_T *x
* Return Type : boolean_T
*/
static boolean_T anyNonFinite(const emxArray_creal_T *x)
{
boolean_T p;
int nx;
int k;
nx = x->size[0] * x->size[1];
p = true;
for (k = 0; k + 1 <= nx; k++) {
if (p && ((!(rtIsInf(x->data[k].re) || rtIsInf(x->data[k].im))) &&
(!(rtIsNaN(x->data[k].re) || rtIsNaN(x->data[k].im))))) {
p = true;
} else {
p = false;
}
}
return !p;
}
/*
* Arguments : const emxArray_creal_T *x
* emxArray_real_T *y
* Return Type : void
*/
static void b_abs(const emxArray_creal_T *x, emxArray_real_T *y)
{
int k;
k = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = x->size[1];
emxEnsureCapacity_real_T(y, k);
for (k = 0; k + 1 <= x->size[1]; k++) {
y->data[k] = rt_hypotd_snf(x->data[k].re, x->data[k].im);
}
}
/*
* Arguments : double *x
* Return Type : void
*/
static void b_acos(double *x)
{
*x = acos(*x);
}
/*
* UNTITLED Summary of this function goes here
* Detailed explanation goes here
* Arguments : const char type[2]
* const emxArray_real_T *f
* double Fconverter
* const double b1_data[]
* const int b1_size[2]
* const emxArray_creal_T *a1
* const double b2_data[]
* const int b2_size[2]
* const emxArray_creal_T *a2
* emxArray_creal_T *abc
* Return Type : void
*/
static void b_analogresp(const char type[2], const emxArray_real_T *f, double
Fconverter, const double b1_data[], const int b1_size[2], const
emxArray_creal_T *a1, const double b2_data[], const int b2_size[2], const
emxArray_creal_T *a2, emxArray_creal_T *abc)
{
boolean_T b_bool;
int kstr;
int exitg1;
static const char cv46[2] = { 'T', 'x' };
emxArray_creal_T *r17;
emxArray_real_T *r18;
emxArray_real_T *r19;
static const char cv47[2] = { 'R', 'x' };
int loop_ub;
double abc_re;
double abc_im;
double re;
double im;
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 3) {
if (type[kstr] != cv46[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 0;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 3) {
if (type[kstr] != cv47[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 1;
} else {
kstr = -1;
}
}
emxInit_creal_T(&r17, 2);
emxInit_real_T(&r18, 2);
emxInit_real_T(&r19, 2);
switch (kstr) {
case 0:
rdivide(f, Fconverter, r19);
b_sinc(r19);
kstr = r18->size[0] * r18->size[1];
r18->size[0] = 1;
r18->size[1] = f->size[1];
emxEnsureCapacity_real_T(r18, kstr);
loop_ub = f->size[0] * f->size[1];
for (kstr = 0; kstr < loop_ub; kstr++) {
r18->data[kstr] = 6.2831853071795862 * f->data[kstr];
}
b_freqs_cg(b1_data, b1_size, a1, r18, abc);
kstr = r18->size[0] * r18->size[1];
r18->size[0] = 1;
r18->size[1] = f->size[1];
emxEnsureCapacity_real_T(r18, kstr);
loop_ub = f->size[0] * f->size[1];
for (kstr = 0; kstr < loop_ub; kstr++) {
r18->data[kstr] = 6.2831853071795862 * f->data[kstr];
}
b_freqs_cg(b2_data, b2_size, a2, r18, r17);
kstr = abc->size[0] * abc->size[1];
abc->size[0] = 1;
abc->size[1] = r19->size[1];
emxEnsureCapacity_creal_T(abc, kstr);
loop_ub = r19->size[0] * r19->size[1];
for (kstr = 0; kstr < loop_ub; kstr++) {
abc_re = r19->data[kstr] * abc->data[kstr].re;
abc_im = r19->data[kstr] * abc->data[kstr].im;
re = r17->data[kstr].re;
im = r17->data[kstr].im;
abc->data[kstr].re = abc_re * re - abc_im * im;
abc->data[kstr].im = abc_re * im + abc_im * re;
}
break;
case 1:
kstr = r19->size[0] * r19->size[1];
r19->size[0] = 1;
r19->size[1] = f->size[1];
emxEnsureCapacity_real_T(r19, kstr);
loop_ub = f->size[0] * f->size[1];
for (kstr = 0; kstr < loop_ub; kstr++) {
r19->data[kstr] = 6.2831853071795862 * f->data[kstr];
}
b_freqs_cg(b1_data, b1_size, a1, r19, abc);
kstr = r19->size[0] * r19->size[1];
r19->size[0] = 1;
r19->size[1] = f->size[1];
emxEnsureCapacity_real_T(r19, kstr);
loop_ub = f->size[0] * f->size[1];
for (kstr = 0; kstr < loop_ub; kstr++) {
r19->data[kstr] = 6.2831853071795862 * f->data[kstr];
}
b_freqs_cg(b2_data, b2_size, a2, r19, r17);
rdivide(f, Fconverter, r19);
b_sinc(r19);
c_power(r19, r18);
kstr = abc->size[0] * abc->size[1];
abc->size[0] = 1;
emxEnsureCapacity_creal_T(abc, kstr);
kstr = abc->size[0];
loop_ub = abc->size[1];
loop_ub *= kstr;
for (kstr = 0; kstr < loop_ub; kstr++) {
abc_re = abc->data[kstr].re * r17->data[kstr].re - abc->data[kstr].im *
r17->data[kstr].im;
abc_im = abc->data[kstr].re * r17->data[kstr].im + abc->data[kstr].im *
r17->data[kstr].re;
abc->data[kstr].re = r18->data[kstr] * abc_re;
abc->data[kstr].im = r18->data[kstr] * abc_im;
}
break;
default:
/* Default to Rx */
kstr = r19->size[0] * r19->size[1];
r19->size[0] = 1;
r19->size[1] = f->size[1];
emxEnsureCapacity_real_T(r19, kstr);
loop_ub = f->size[0] * f->size[1];
for (kstr = 0; kstr < loop_ub; kstr++) {
r19->data[kstr] = 6.2831853071795862 * f->data[kstr];
}
b_freqs_cg(b1_data, b1_size, a1, r19, abc);
kstr = r19->size[0] * r19->size[1];
r19->size[0] = 1;
r19->size[1] = f->size[1];
emxEnsureCapacity_real_T(r19, kstr);
loop_ub = f->size[0] * f->size[1];
for (kstr = 0; kstr < loop_ub; kstr++) {
r19->data[kstr] = 6.2831853071795862 * f->data[kstr];
}
b_freqs_cg(b2_data, b2_size, a2, r19, r17);
rdivide(f, Fconverter, r19);
b_sinc(r19);
c_power(r19, r18);
kstr = abc->size[0] * abc->size[1];
abc->size[0] = 1;
emxEnsureCapacity_creal_T(abc, kstr);
kstr = abc->size[0];
loop_ub = abc->size[1];
loop_ub *= kstr;
for (kstr = 0; kstr < loop_ub; kstr++) {
abc_re = abc->data[kstr].re * r17->data[kstr].re - abc->data[kstr].im *
r17->data[kstr].im;
abc_im = abc->data[kstr].re * r17->data[kstr].im + abc->data[kstr].im *
r17->data[kstr].re;
abc->data[kstr].re = r18->data[kstr] * abc_re;
abc->data[kstr].im = r18->data[kstr] * abc_im;
}
break;
}
emxFree_real_T(&r19);
emxFree_real_T(&r18);
emxFree_creal_T(&r17);
}
/*
* BUTTER_CG Butterworth digital and analog filter design. Codegen support
*
* This function is based on 'butter' by The MathWorks Inc.
* Arguments : double Wn
* double num[4]
* emxArray_creal_T *den
* Return Type : void
*/
static void b_butter_cg(double Wn, double num[4], emxArray_creal_T *den)
{
emxArray_creal_T *a;
emxArray_real_T *b;
emxArray_real_T *c;
emxArray_creal_T *b_a;
emxArray_real_T *b_b;
double d;
double y_re;
double y_im;
int k;
static const double c_a[4] = { 0.0, 0.0, 0.0, 0.037037037037037035 };
double ai;
emxInit_creal_T(&a, 2);
emxInit_real_T1(&b, 1);
emxInit_real_T(&c, 2);
emxInit_creal_T(&b_a, 2);
emxInit_real_T1(&b_b, 1);
/* Set types we will only use */
/* Cast to enforce precision rules */
/* step 1: get analog, pre-warped frequencies */
/* step 2: convert to low-pass prototype estimate */
/* lowpass */
/* Cast to enforce precision rules */
/* step 3: Get N-th order Butterworth analog lowpass prototype */
/* Transform to state-space */
zp2ss_cg(a, b, c, &d);
/* step 4: Transform to lowpass, bandpass, highpass, or bandstop of desired Wn */
/* Lowpass */
lp2lp_cg(a, b, Wn, b_a, b_b, &d);
/* step 5: Use Bilinear transformation to find discrete equivalent: */
/* nargout <= 3 */
/* Transform to zero-pole-gain and polynomial forms: */
/* nargout <= 2 */
poly(b_a, den);
/* This internal function returns more exact numerator vectors */
/* for the num/den case. */
/* Wn input is two element band edge vector */
/* --------------------------------- */
/* lowpass */
y_re = den->data[0].re;
y_im = den->data[0].im;
k = 0;
emxFree_real_T(&b_b);
emxFree_creal_T(&b_a);
emxFree_real_T(&c);
emxFree_real_T(&b);
emxFree_creal_T(&a);
while (k <= den->size[1] - 2) {
d = 0.0 * y_im + 0.0 * y_re;
y_re = (0.0 * y_re - 0.0 * y_im) + den->data[k + 1].re;
y_im = d + den->data[k + 1].im;
k++;
}
for (k = 0; k < 4; k++) {
d = c_a[k] * y_re;
ai = c_a[k] * y_im;
if (ai == 0.0) {
d /= 0.037037037037037035;
} else if (d == 0.0) {
d = 0.0;
} else {
d /= 0.037037037037037035;
}
num[k] = d;
}
/* num = poly(a-b*c)+(d-1)*den; */
}
/*
* Arguments : emxArray_real_T *x
* Return Type : void
*/
static void b_cos(emxArray_real_T *x)
{
int nx;
int k;
nx = x->size[1];
for (k = 0; k + 1 <= nx; k++) {
x->data[k] = cos(x->data[k]);
}
}
/*
* Codegen workaround for fixed fi call requirements
* Arguments : const double tap_store[128]
* double taps[128]
* Return Type : void
*/
static void b_determineBestFractionLength(const double tap_store[128], double
taps[128])
{
double r[2048];
int ixstart;
double b_r[128];
double dv16[128];
double u;
double e[16];
double v;
double dv17[128];
short i57;
double dv18[128];
double dv19[128];
double dv20[128];
double dv21[128];
double dv22[128];
double dv23[128];
double dv24[128];
double dv25[128];
double dv26[128];
double dv27[128];
double dv28[128];
double dv29[128];
double dv30[128];
double dv31[128];
int itmp;
int ix;
boolean_T exitg1;
memset(&r[0], 0, sizeof(double) << 11);
for (ixstart = 0; ixstart < 128; ixstart++) {
u = tap_store[ixstart] * 2.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[ixstart << 4] = (double)i57 * 0.5;
b_r[ixstart] = r[ixstart << 4] - tap_store[ixstart];
u = tap_store[ixstart] * 4.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[1 + (ixstart << 4)] = (double)i57 * 0.25;
}
d_abs(b_r, dv16);
e[0] = c_sum(dv16);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[1 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 8.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[2 + (ixstart << 4)] = (double)i57 * 0.125;
}
d_abs(b_r, dv17);
e[1] = c_sum(dv17);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[2 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 16.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[3 + (ixstart << 4)] = (double)i57 * 0.0625;
}
d_abs(b_r, dv18);
e[2] = c_sum(dv18);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[3 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 32.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[4 + (ixstart << 4)] = (double)i57 * 0.03125;
}
d_abs(b_r, dv19);
e[3] = c_sum(dv19);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[4 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 64.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[5 + (ixstart << 4)] = (double)i57 * 0.015625;
}
d_abs(b_r, dv20);
e[4] = c_sum(dv20);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[5 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 128.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[6 + (ixstart << 4)] = (double)i57 * 0.0078125;
}
d_abs(b_r, dv21);
e[5] = c_sum(dv21);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[6 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 256.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[7 + (ixstart << 4)] = (double)i57 * 0.00390625;
}
d_abs(b_r, dv22);
e[6] = c_sum(dv22);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[7 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 512.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[8 + (ixstart << 4)] = (double)i57 * 0.001953125;
}
d_abs(b_r, dv23);
e[7] = c_sum(dv23);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[8 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 1024.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[9 + (ixstart << 4)] = (double)i57 * 0.0009765625;
}
d_abs(b_r, dv24);
e[8] = c_sum(dv24);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[9 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 2048.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[10 + (ixstart << 4)] = (double)i57 * 0.00048828125;
}
d_abs(b_r, dv25);
e[9] = c_sum(dv25);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[10 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 4096.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[11 + (ixstart << 4)] = (double)i57 * 0.000244140625;
}
d_abs(b_r, dv26);
e[10] = c_sum(dv26);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[11 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 8192.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[12 + (ixstart << 4)] = (double)i57 * 0.0001220703125;
}
d_abs(b_r, dv27);
e[11] = c_sum(dv27);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[12 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 16384.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[13 + (ixstart << 4)] = (double)i57 * 6.103515625E-5;
}
d_abs(b_r, dv28);
e[12] = c_sum(dv28);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[13 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 32768.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[14 + (ixstart << 4)] = (double)i57 * 3.0517578125E-5;
}
d_abs(b_r, dv29);
e[13] = c_sum(dv29);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[14 + (ixstart << 4)] - tap_store[ixstart];
u = tap_store[ixstart] * 65536.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i57 = (short)u;
} else {
i57 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i57 = MAX_int16_T;
} else {
i57 = 0;
}
r[15 + (ixstart << 4)] = (double)i57 * 1.52587890625E-5;
}
d_abs(b_r, dv30);
e[14] = c_sum(dv30);
for (ixstart = 0; ixstart < 128; ixstart++) {
b_r[ixstart] = r[15 + (ixstart << 4)] - tap_store[ixstart];
}
d_abs(b_r, dv31);
e[15] = c_sum(dv31);
ixstart = 1;
u = e[0];
itmp = 0;
if (rtIsNaN(e[0])) {
ix = 2;
exitg1 = false;
while ((!exitg1) && (ix < 17)) {
ixstart = ix;
if (!rtIsNaN(e[ix - 1])) {
u = e[ix - 1];
itmp = ix - 1;
exitg1 = true;
} else {
ix++;
}
}
}
if (ixstart < 16) {
while (ixstart + 1 < 17) {
if (e[ixstart] < u) {
u = e[ixstart];
itmp = ixstart;
}
ixstart++;
}
}
for (ixstart = 0; ixstart < 128; ixstart++) {
taps[ixstart] = r[itmp + (ixstart << 4)];
}
}
/*
* Arguments : creal_T x[2048]
* Return Type : void
*/
static void b_exp(creal_T x[2048])
{
int k;
double x_re;
double r;
for (k = 0; k < 2048; k++) {
if (x[k].im == 0.0) {
x_re = exp(x[k].re);
r = 0.0;
} else if (rtIsInf(x[k].im) && rtIsInf(x[k].re) && (x[k].re < 0.0)) {
x_re = 0.0;
r = 0.0;
} else {
r = exp(x[k].re / 2.0);
x_re = r * (r * cos(x[k].im));
r *= r * sin(x[k].im);
}
x[k].re = x_re;
x[k].im = r;
}
}
/*
* Make b a row
* Arguments : const double b[15]
* const struct_T *options
* creal_T h[2048]
* double w[2048]
* Return Type : void
*/
static void b_firfreqz(const double b[15], const struct_T *options, creal_T h
[2048], double w[2048])
{
int i64;
creal_T dcv2[2048];
double digw;
double b_digw[2048];
double h_re;
double brm;
double d;
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
/* Convert from Hz to rad/sample for computational purposes */
/* Digital frequency must be used for this calculation */
for (i64 = 0; i64 < 2048; i64++) {
w[i64] = options->w[i64];
digw = 6.2831853071795862 * options->w[i64] / options->Fs;
dcv2[i64].re = digw * 0.0;
dcv2[i64].im = digw;
b_digw[i64] = digw;
}
b_exp(dcv2);
polyval(b, dcv2, h);
for (i64 = 0; i64 < 2048; i64++) {
dcv2[i64].re = 14.0 * (b_digw[i64] * 0.0);
dcv2[i64].im = 14.0 * b_digw[i64];
}
b_exp(dcv2);
for (i64 = 0; i64 < 2048; i64++) {
h_re = h[i64].re;
if (dcv2[i64].im == 0.0) {
if (h[i64].im == 0.0) {
h[i64].re /= dcv2[i64].re;
h[i64].im = 0.0;
} else if (h[i64].re == 0.0) {
h[i64].re = 0.0;
h[i64].im /= dcv2[i64].re;
} else {
h[i64].re /= dcv2[i64].re;
h[i64].im /= dcv2[i64].re;
}
} else if (dcv2[i64].re == 0.0) {
if (h[i64].re == 0.0) {
h[i64].re = h[i64].im / dcv2[i64].im;
h[i64].im = 0.0;
} else if (h[i64].im == 0.0) {
h[i64].re = 0.0;
h[i64].im = -(h_re / dcv2[i64].im);
} else {
h[i64].re = h[i64].im / dcv2[i64].im;
h[i64].im = -(h_re / dcv2[i64].im);
}
} else {
brm = fabs(dcv2[i64].re);
digw = fabs(dcv2[i64].im);
if (brm > digw) {
digw = dcv2[i64].im / dcv2[i64].re;
d = dcv2[i64].re + digw * dcv2[i64].im;
h[i64].re = (h[i64].re + digw * h[i64].im) / d;
h[i64].im = (h[i64].im - digw * h_re) / d;
} else if (digw == brm) {
if (dcv2[i64].re > 0.0) {
digw = 0.5;
} else {
digw = -0.5;
}
if (dcv2[i64].im > 0.0) {
d = 0.5;
} else {
d = -0.5;
}
h[i64].re = (h[i64].re * digw + h[i64].im * d) / brm;
h[i64].im = (h[i64].im * digw - h_re * d) / brm;
} else {
digw = dcv2[i64].re / dcv2[i64].im;
d = dcv2[i64].im + digw * dcv2[i64].re;
h[i64].re = (digw * h[i64].re + h[i64].im) / d;
h[i64].im = (digw * h[i64].im - h_re) / d;
}
}
}
}
/*
* FIRPM Parks-McClellan optimal equiripple FIR filter design.
*
* This function is based on 'firpm' by The MathWorks Inc.
* Arguments : double order
* const double ff[4]
* const emxArray_real_T *amplitudes
* const emxArray_real_T *frequencies
* const emxArray_real_T *weights
* emxArray_real_T *h
* boolean_T *valid
* double *err
* Return Type : void
*/
static void b_firpm_cg(double order, const double ff[4], const emxArray_real_T
*amplitudes, const emxArray_real_T *frequencies, const emxArray_real_T
*weights, emxArray_real_T *h, boolean_T *valid, double *err)
{
emxArray_real_T *grid;
emxArray_real_T *des;
emxArray_real_T *wt;
emxArray_real_T *b_h;
int i52;
emxArray_real_T *c_h;
double b_ff[4];
double x;
boolean_T b_valid;
int h_idx_0;
double d2;
int i53;
int i54;
int loop_ub;
emxInit_real_T(&grid, 2);
emxInit_real_T(&des, 2);
emxInit_real_T(&wt, 2);
emxInit_real_T(&b_h, 2);
/* */
firpmgrid_cg(order + 1.0, ff, grid);
/* orgFreqIndx = frequencies; */
/* */
/* positionsOfNewFreqIndx = zeros(size(grid)); */
/* for ind = 1:length(positionsOfNewFreqIndx) */
/* */
/* [~,indx] = min( abs(orgFreqIndx-grid(ind)) ); */
/* */
/* positionsOfNewFreqIndx(ind) = indx; */
/* end */
/* */
/* wt = weights(positionsOfNewFreqIndx); */
/* des = amplitudes(positionsOfNewFreqIndx); */
interp1(frequencies, amplitudes, grid, des);
interp1(frequencies, weights, grid, wt);
/* Workaround */
/* ftype = 2; */
/* sign_val = 1; */
/* Always bandpass designs */
/* cast to enforce precision rules */
/* Call actual design algorithm */
rdivide(grid, 2.0, b_h);
emxFree_real_T(&grid);
for (i52 = 0; i52 < 4; i52++) {
b_ff[i52] = ff[i52] / 2.0;
}
emxInit_real_T(&c_h, 2);
remezm(order + 1.0, b_ff, b_h, des, wt, c_h, &x, &b_valid);
h_idx_0 = c_h->size[0] * c_h->size[1];
i52 = h->size[0] * h->size[1];
h->size[0] = 1;
h->size[1] = h_idx_0;
emxEnsureCapacity_real_T(h, i52);
emxFree_real_T(&wt);
emxFree_real_T(&des);
for (i52 = 0; i52 < h_idx_0; i52++) {
h->data[h->size[0] * i52] = c_h->data[i52];
}
emxFree_real_T(&c_h);
/* make it a row */
d2 = (double)h->size[1] - rt_remd_snf(order + 1.0, 2.0);
if (1.0 > d2) {
i52 = 1;
h_idx_0 = 1;
i53 = 0;
} else {
i52 = (int)d2;
h_idx_0 = -1;
i53 = 1;
}
i54 = b_h->size[0] * b_h->size[1];
b_h->size[0] = 1;
b_h->size[1] = (h->size[1] + div_s32_floor(i53 - i52, h_idx_0)) + 1;
emxEnsureCapacity_real_T(b_h, i54);
loop_ub = h->size[1];
for (i54 = 0; i54 < loop_ub; i54++) {
b_h->data[b_h->size[0] * i54] = h->data[h->size[0] * i54];
}
loop_ub = div_s32_floor(i53 - i52, h_idx_0);
for (i53 = 0; i53 <= loop_ub; i53++) {
b_h->data[b_h->size[0] * (i53 + h->size[1])] = h->data[(i52 + h_idx_0 * i53)
- 1];
}
i52 = h->size[0] * h->size[1];
h->size[0] = 1;
h->size[1] = b_h->size[1];
emxEnsureCapacity_real_T(h, i52);
loop_ub = b_h->size[1];
for (i52 = 0; i52 < loop_ub; i52++) {
h->data[h->size[0] * i52] = b_h->data[b_h->size[0] * i52];
}
if (1 > h->size[1]) {
i52 = 1;
h_idx_0 = 1;
i53 = 0;
} else {
i52 = h->size[1];
h_idx_0 = -1;
i53 = 1;
}
i54 = b_h->size[0] * b_h->size[1];
b_h->size[0] = 1;
b_h->size[1] = div_s32_floor(i53 - i52, h_idx_0) + 1;
emxEnsureCapacity_real_T(b_h, i54);
loop_ub = div_s32_floor(i53 - i52, h_idx_0);
for (i53 = 0; i53 <= loop_ub; i53++) {
b_h->data[b_h->size[0] * i53] = h->data[(i52 + h_idx_0 * i53) - 1];
}
i52 = h->size[0] * h->size[1];
h->size[0] = 1;
h->size[1] = b_h->size[1];
emxEnsureCapacity_real_T(h, i52);
loop_ub = b_h->size[1];
for (i52 = 0; i52 < loop_ub; i52++) {
h->data[h->size[0] * i52] = b_h->data[b_h->size[0] * i52];
}
emxFree_real_T(&b_h);
*valid = b_valid;
*err = fabs(x);
}
/*
* Arguments : double *x
* Return Type : void
*/
static void b_fix(double *x)
{
if (*x < 0.0) {
*x = ceil(*x);
} else {
*x = floor(*x);
}
}
/*
* FREQS Laplace-transform (s-domain) frequency response with codegen support
*
* This function is based on 'freqs' by The MathWorks Inc.
* Arguments : const double b_data[]
* const int b_size[2]
* const emxArray_creal_T *a
* const emxArray_real_T *w
* emxArray_creal_T *h
* Return Type : void
*/
static void b_freqs_cg(const double b_data[], const int b_size[2], const
emxArray_creal_T *a, const emxArray_real_T *w, emxArray_creal_T *h)
{
emxArray_creal_T *s;
emxArray_creal_T *b_a;
double b_b_data[4];
int b_b_size[2];
int i40;
int loop_ub;
emxArray_creal_T *y;
boolean_T b11;
emxArray_real_T c_b_data;
int k;
double a_re;
double a_im;
double s_re;
double s_im;
emxInit_creal_T(&s, 2);
emxInit_creal_T(&b_a, 2);
removeTrailingZero(b_data, b_size, a, b_b_data, b_b_size, b_a);
i40 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = w->size[1];
emxEnsureCapacity_creal_T(s, i40);
loop_ub = w->size[0] * w->size[1];
for (i40 = 0; i40 < loop_ub; i40++) {
s->data[i40].re = w->data[i40] * 0.0;
s->data[i40].im = w->data[i40];
}
emxInit_creal_T(&y, 2);
i40 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i40);
if ((y->size[1] == 0) || (b_a->size[1] == 0)) {
b11 = true;
} else {
b11 = false;
}
if (!b11) {
i40 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_creal_T(y, i40);
loop_ub = y->size[1];
for (i40 = 0; i40 < loop_ub; i40++) {
y->data[y->size[0] * i40] = b_a->data[0];
}
for (k = 0; k <= b_a->size[1] - 2; k++) {
i40 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i40);
a_re = b_a->data[k + 1].re;
a_im = b_a->data[k + 1].im;
loop_ub = s->size[0] * s->size[1];
for (i40 = 0; i40 < loop_ub; i40++) {
s_re = s->data[i40].re * y->data[i40].re - s->data[i40].im * y->data[i40]
.im;
s_im = s->data[i40].re * y->data[i40].im + s->data[i40].im * y->data[i40]
.re;
y->data[i40].re = s_re + a_re;
y->data[i40].im = s_im + a_im;
}
}
}
c_b_data.data = (double *)&b_b_data;
c_b_data.size = (int *)&b_b_size;
c_b_data.allocatedSize = 4;
c_b_data.numDimensions = 2;
c_b_data.canFreeData = false;
j_polyval(&c_b_data, s, b_a);
b_rdivide(b_a, y, h);
emxFree_creal_T(&y);
emxFree_creal_T(&b_a);
emxFree_creal_T(&s);
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[15]
* const double w[2048]
* double Fs
* creal_T hh[2048]
* Return Type : void
*/
static void b_freqz_cg(const double b[15], const double w[2048], double Fs,
creal_T hh[2048])
{
static struct_T options;
int i10;
static const char cv14[8] = { 'o', 'n', 'e', 's', 'i', 'd', 'e', 'd' };
double b_w[2048];
static const char cv15[7] = { 'o', 'm', 'i', 't', 't', 'e', 'd' };
/* Cast to enforce precision rules */
options.Fs = Fs;
memcpy(&options.nfft[0], &w[0], sizeof(double) << 11);
memcpy(&options.w[0], &w[0], sizeof(double) << 11);
/* Remaining are default or for advanced use */
options.fvflag = 1.0;
for (i10 = 0; i10 < 8; i10++) {
options.range[i10] = cv14[i10];
}
options.centerdc = 0.0;
for (i10 = 0; i10 < 7; i10++) {
options.configlevel[i10] = cv15[i10];
}
b_firfreqz(b, &options, hh, b_w);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
}
/*
* Arguments : const char enables[4]
* const emxArray_real_T *w
* double Fs
* const double hb1_coeff[15]
* const double hb2_coeff[7]
* const double hb3_coeff_data[]
* const int hb3_coeff_size[2]
* const double dec_int3_coeff_data[]
* const int dec_int3_coeff_size[2]
* emxArray_creal_T *combinedResponse
* Return Type : void
*/
static void b_generateCascadedResponseRx(const char enables[4], const
emxArray_real_T *w, double Fs, const double hb1_coeff[15], const double
hb2_coeff[7], const double hb3_coeff_data[], const int hb3_coeff_size[2],
const double dec_int3_coeff_data[], const int dec_int3_coeff_size[2],
emxArray_creal_T *combinedResponse)
{
boolean_T b_bool;
int ix;
int exitg1;
emxArray_creal_T *d2;
emxArray_creal_T *d3;
static const char cv35[4] = { '2', '1', '1', '1' };
double u[15];
double tmp_data[29];
int tmp_size[2];
double b_u[30];
double c_u[14];
double d_u[60];
double e_u[45];
double f_u[21];
double g_u[90];
emxArray_real_T b_tmp_data;
int iy;
double h_u[7];
int k;
static const char cv36[4] = { '1', '2', '1', '1' };
static const char cv37[4] = { '1', '1', '2', '1' };
double combinedResponse_re;
double combinedResponse_im;
double d2_re;
double d2_im;
static const char cv38[4] = { '2', '2', '1', '1' };
static const char cv39[4] = { '2', '1', '2', '1' };
static const char cv40[4] = { '1', '2', '2', '1' };
static const char cv41[4] = { '2', '2', '2', '1' };
static const char cv42[4] = { '1', '1', '1', '3' };
static const char cv43[4] = { '2', '1', '1', '3' };
static const char cv44[4] = { '1', '2', '1', '3' };
static const char cv45[4] = { '2', '2', '1', '3' };
/* Cast */
b_bool = false;
ix = 1;
do {
exitg1 = 0;
if (ix < 5) {
if (enables[ix - 1] != '1') {
exitg1 = 1;
} else {
ix++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
ix = 0;
} else {
b_bool = false;
ix = 0;
do {
exitg1 = 0;
if (ix + 1 < 5) {
if (enables[ix] != cv35[ix]) {
exitg1 = 1;
} else {
ix++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
ix = 1;
} else {
b_bool = false;
ix = 0;
do {
exitg1 = 0;
if (ix + 1 < 5) {
if (enables[ix] != cv36[ix]) {
exitg1 = 1;
} else {
ix++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
ix = 2;
} else {
b_bool = false;
ix = 0;
do {
exitg1 = 0;
if (ix + 1 < 5) {
if (enables[ix] != cv37[ix]) {
exitg1 = 1;
} else {
ix++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
ix = 3;
} else {
b_bool = false;
ix = 0;
do {
exitg1 = 0;
if (ix + 1 < 5) {
if (enables[ix] != cv38[ix]) {
exitg1 = 1;
} else {
ix++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
ix = 4;
} else {
b_bool = false;
ix = 0;
do {
exitg1 = 0;
if (ix + 1 < 5) {
if (enables[ix] != cv39[ix]) {
exitg1 = 1;
} else {
ix++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
ix = 5;
} else {
b_bool = false;
ix = 0;
do {
exitg1 = 0;
if (ix + 1 < 5) {
if (enables[ix] != cv40[ix]) {
exitg1 = 1;
} else {
ix++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
ix = 6;
} else {
b_bool = false;
ix = 0;
do {
exitg1 = 0;
if (ix + 1 < 5) {
if (enables[ix] != cv41[ix]) {
exitg1 = 1;
} else {
ix++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
ix = 7;
} else {
b_bool = false;
ix = 0;
do {
exitg1 = 0;
if (ix + 1 < 5) {
if (enables[ix] != cv42[ix]) {
exitg1 = 1;
} else {
ix++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
ix = 8;
} else {
b_bool = false;
ix = 0;
do {
exitg1 = 0;
if (ix + 1 < 5) {
if (enables[ix] != cv43[ix]) {
exitg1 = 1;
} else {
ix++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
ix = 9;
} else {
b_bool = false;
ix = 0;
do {
exitg1 = 0;
if (ix + 1 < 5) {
if (enables[ix] != cv44[ix]) {
exitg1 = 1;
} else {
ix++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
ix = 10;
} else {
b_bool = false;
ix = 0;
do {
exitg1 = 0;
if (ix + 1 < 5) {
if (enables[ix] != cv45[ix]) {
exitg1 = 1;
} else {
ix++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
ix = 11;
} else {
ix = -1;
}
}
}
}
}
}
}
}
}
}
}
}
emxInit_creal_T(&d2, 2);
emxInit_creal_T(&d3, 2);
switch (ix) {
case 0:
/* only FIR */
k_freqz_cg(w, Fs, combinedResponse);
break;
case 1:
/* Hb1 */
memset(&u[0], 0, 15U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 15; k++) {
u[iy] = hb1_coeff[ix];
ix++;
iy++;
}
l_freqz_cg(u, w, Fs, combinedResponse);
break;
case 2:
/* Hb2 */
for (ix = 0; ix < 7; ix++) {
h_u[ix] = 0.0;
}
ix = 0;
iy = 0;
for (k = 0; k < 7; k++) {
h_u[iy] = hb2_coeff[ix];
ix++;
iy++;
}
m_freqz_cg(h_u, w, Fs, combinedResponse);
break;
case 3:
/* Hb3 */
c_us(hb3_coeff_data, hb3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, combinedResponse);
break;
case 4:
/* Hb2,Hb1 */
memset(&b_u[0], 0, 30U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 15; k++) {
b_u[iy] = hb1_coeff[ix];
ix++;
iy += 2;
}
o_freqz_cg(*(double (*)[29])&b_u[0], w, Fs, combinedResponse);
for (ix = 0; ix < 7; ix++) {
h_u[ix] = 0.0;
}
ix = 0;
iy = 0;
for (k = 0; k < 7; k++) {
h_u[iy] = hb2_coeff[ix];
ix++;
iy++;
}
m_freqz_cg(h_u, w, Fs, d2);
ix = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, ix);
ix = combinedResponse->size[0];
iy = combinedResponse->size[1];
iy *= ix;
for (ix = 0; ix < iy; ix++) {
combinedResponse_re = combinedResponse->data[ix].re;
combinedResponse_im = combinedResponse->data[ix].im;
d2_re = d2->data[ix].re;
d2_im = d2->data[ix].im;
combinedResponse->data[ix].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[ix].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
break;
case 5:
/* Hb3,Hb1 */
memset(&b_u[0], 0, 30U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 15; k++) {
b_u[iy] = hb1_coeff[ix];
ix++;
iy += 2;
}
o_freqz_cg(*(double (*)[29])&b_u[0], w, Fs, combinedResponse);
c_us(hb3_coeff_data, hb3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, d2);
ix = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, ix);
ix = combinedResponse->size[0];
iy = combinedResponse->size[1];
iy *= ix;
for (ix = 0; ix < iy; ix++) {
combinedResponse_re = combinedResponse->data[ix].re;
combinedResponse_im = combinedResponse->data[ix].im;
d2_re = d2->data[ix].re;
d2_im = d2->data[ix].im;
combinedResponse->data[ix].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[ix].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
break;
case 6:
/* Hb3,Hb2 */
memset(&c_u[0], 0, 14U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 7; k++) {
c_u[iy] = hb2_coeff[ix];
ix++;
iy += 2;
}
p_freqz_cg(*(double (*)[13])&c_u[0], w, Fs, combinedResponse);
c_us(hb3_coeff_data, hb3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, d2);
ix = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, ix);
ix = combinedResponse->size[0];
iy = combinedResponse->size[1];
iy *= ix;
for (ix = 0; ix < iy; ix++) {
combinedResponse_re = combinedResponse->data[ix].re;
combinedResponse_im = combinedResponse->data[ix].im;
d2_re = d2->data[ix].re;
d2_im = d2->data[ix].im;
combinedResponse->data[ix].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[ix].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
break;
case 7:
/* Hb3,Hb2,Hb1 */
memset(&d_u[0], 0, 60U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 15; k++) {
d_u[iy] = hb1_coeff[ix];
ix++;
iy += 4;
}
q_freqz_cg(*(double (*)[57])&d_u[0], w, Fs, combinedResponse);
memset(&c_u[0], 0, 14U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 7; k++) {
c_u[iy] = hb2_coeff[ix];
ix++;
iy += 2;
}
p_freqz_cg(*(double (*)[13])&c_u[0], w, Fs, d2);
c_us(hb3_coeff_data, hb3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, d3);
ix = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, ix);
ix = combinedResponse->size[0];
iy = combinedResponse->size[1];
iy *= ix;
for (ix = 0; ix < iy; ix++) {
combinedResponse_re = combinedResponse->data[ix].re * d2->data[ix].re -
combinedResponse->data[ix].im * d2->data[ix].im;
combinedResponse_im = combinedResponse->data[ix].re * d2->data[ix].im +
combinedResponse->data[ix].im * d2->data[ix].re;
d2_re = d3->data[ix].re;
d2_im = d3->data[ix].im;
combinedResponse->data[ix].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[ix].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
break;
case 8:
/* Dec/Int3 */
c_us(dec_int3_coeff_data, dec_int3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, combinedResponse);
/* RECHECK ALL DEC BY 3 */
break;
case 9:
/* Dec/Int3,Hb1 */
memset(&e_u[0], 0, 45U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 15; k++) {
e_u[iy] = hb1_coeff[ix];
ix++;
iy += 3;
}
r_freqz_cg(*(double (*)[43])&e_u[0], w, Fs, combinedResponse);
c_us(dec_int3_coeff_data, dec_int3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, d2);
ix = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, ix);
ix = combinedResponse->size[0];
iy = combinedResponse->size[1];
iy *= ix;
for (ix = 0; ix < iy; ix++) {
combinedResponse_re = combinedResponse->data[ix].re;
combinedResponse_im = combinedResponse->data[ix].im;
d2_re = d2->data[ix].re;
d2_im = d2->data[ix].im;
combinedResponse->data[ix].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[ix].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
break;
case 10:
/* Dec/Int3,Hb2 */
memset(&f_u[0], 0, 21U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 7; k++) {
f_u[iy] = hb2_coeff[ix];
ix++;
iy += 3;
}
s_freqz_cg(*(double (*)[19])&f_u[0], w, Fs, combinedResponse);
c_us(dec_int3_coeff_data, dec_int3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, d2);
ix = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, ix);
ix = combinedResponse->size[0];
iy = combinedResponse->size[1];
iy *= ix;
for (ix = 0; ix < iy; ix++) {
combinedResponse_re = combinedResponse->data[ix].re;
combinedResponse_im = combinedResponse->data[ix].im;
d2_re = d2->data[ix].re;
d2_im = d2->data[ix].im;
combinedResponse->data[ix].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[ix].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
break;
case 11:
/* Dec/Int3,Hb2,Hb1 {Hm4,Hm2c34,Hm1} */
memset(&g_u[0], 0, 90U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 15; k++) {
g_u[iy] = hb1_coeff[ix];
ix++;
iy += 6;
}
t_freqz_cg(*(double (*)[85])&g_u[0], w, Fs, combinedResponse);
memset(&f_u[0], 0, 21U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 7; k++) {
f_u[iy] = hb2_coeff[ix];
ix++;
iy += 3;
}
s_freqz_cg(*(double (*)[19])&f_u[0], w, Fs, d2);
c_us(dec_int3_coeff_data, dec_int3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, d3);
ix = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, ix);
ix = combinedResponse->size[0];
iy = combinedResponse->size[1];
iy *= ix;
for (ix = 0; ix < iy; ix++) {
combinedResponse_re = combinedResponse->data[ix].re * d2->data[ix].re -
combinedResponse->data[ix].im * d2->data[ix].im;
combinedResponse_im = combinedResponse->data[ix].re * d2->data[ix].im +
combinedResponse->data[ix].im * d2->data[ix].re;
d2_re = d3->data[ix].re;
d2_im = d3->data[ix].im;
combinedResponse->data[ix].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[ix].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
break;
}
emxFree_creal_T(&d3);
emxFree_creal_T(&d2);
/* Add filter extra filter to end of cascade */
}
/*
* Arguments : double x
* Return Type : double
*/
static double b_log2(double x)
{
double f;
double t;
int eint;
if (x == 0.0) {
f = rtMinusInf;
} else if (x < 0.0) {
f = rtNaN;
} else if ((!rtIsInf(x)) && (!rtIsNaN(x))) {
t = frexp(x, &eint);
if (t == 0.5) {
f = (double)eint - 1.0;
} else if ((eint == 1) && (t < 0.75)) {
f = log(2.0 * t) / 0.69314718055994529;
} else {
f = log(t) / 0.69314718055994529 + (double)eint;
}
} else {
f = x;
}
return f;
}
/*
* Arguments : const double p[7]
* const creal_T x[2048]
* creal_T y[2048]
* Return Type : void
*/
static void b_polyval(const double p[7], const creal_T x[2048], creal_T y[2048])
{
int i11;
int k;
double x_im;
for (i11 = 0; i11 < 2048; i11++) {
y[i11].re = p[0];
y[i11].im = 0.0;
}
for (k = 0; k < 6; k++) {
for (i11 = 0; i11 < 2048; i11++) {
x_im = x[i11].re * y[i11].im + x[i11].im * y[i11].re;
y[i11].re = (x[i11].re * y[i11].re - x[i11].im * y[i11].im) + p[k + 1];
y[i11].im = x_im;
}
}
}
/*
* Arguments : const double a[2048]
* double y[2048]
* Return Type : void
*/
static void b_power(const double a[2048], double y[2048])
{
int k;
for (k = 0; k < 2048; k++) {
y[k] = a[k] * a[k];
}
}
/*
* Arguments : const emxArray_creal_T *x
* const emxArray_creal_T *y
* emxArray_creal_T *z
* Return Type : void
*/
static void b_rdivide(const emxArray_creal_T *x, const emxArray_creal_T *y,
emxArray_creal_T *z)
{
int i29;
int loop_ub;
double x_re;
double x_im;
double y_re;
double y_im;
double brm;
double bim;
double s;
i29 = z->size[0] * z->size[1];
z->size[0] = 1;
z->size[1] = x->size[1];
emxEnsureCapacity_creal_T(z, i29);
loop_ub = x->size[0] * x->size[1];
for (i29 = 0; i29 < loop_ub; i29++) {
x_re = x->data[i29].re;
x_im = x->data[i29].im;
y_re = y->data[i29].re;
y_im = y->data[i29].im;
if (y_im == 0.0) {
if (x_im == 0.0) {
z->data[i29].re = x_re / y_re;
z->data[i29].im = 0.0;
} else if (x_re == 0.0) {
z->data[i29].re = 0.0;
z->data[i29].im = x_im / y_re;
} else {
z->data[i29].re = x_re / y_re;
z->data[i29].im = x_im / y_re;
}
} else if (y_re == 0.0) {
if (x_re == 0.0) {
z->data[i29].re = x_im / y_im;
z->data[i29].im = 0.0;
} else if (x_im == 0.0) {
z->data[i29].re = 0.0;
z->data[i29].im = -(x_re / y_im);
} else {
z->data[i29].re = x_im / y_im;
z->data[i29].im = -(x_re / y_im);
}
} else {
brm = fabs(y_re);
bim = fabs(y_im);
if (brm > bim) {
s = y_im / y_re;
bim = y_re + s * y_im;
z->data[i29].re = (x_re + s * x_im) / bim;
z->data[i29].im = (x_im - s * x_re) / bim;
} else if (bim == brm) {
if (y_re > 0.0) {
s = 0.5;
} else {
s = -0.5;
}
if (y_im > 0.0) {
bim = 0.5;
} else {
bim = -0.5;
}
z->data[i29].re = (x_re * s + x_im * bim) / brm;
z->data[i29].im = (x_im * s - x_re * bim) / brm;
} else {
s = y_re / y_im;
bim = y_im + s * y_re;
z->data[i29].re = (s * x_re + x_im) / bim;
z->data[i29].im = (s * x_im - x_re) / bim;
}
}
}
}
/*
* Arguments : emxArray_real_T *x
* Return Type : void
*/
static void b_sinc(emxArray_real_T *x)
{
int i72;
int k;
i72 = x->size[1];
for (k = 0; k < i72; k++) {
if (fabs(x->data[k]) < 1.0020841800044864E-292) {
x->data[k] = 1.0;
} else {
x->data[k] *= 3.1415926535897931;
x->data[k] = sin(x->data[k]) / x->data[k];
}
}
}
/*
* Arguments : double *x
* Return Type : void
*/
static void b_sqrt(double *x)
{
*x = sqrt(*x);
}
/*
* Arguments : const char a[2]
* Return Type : boolean_T
*/
static boolean_T b_strcmp(const char a[2])
{
boolean_T b_bool;
int kstr;
int exitg1;
static const char cv0[2] = { 'R', 'x' };
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 3) {
if (a[kstr] != cv0[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
return b_bool;
}
/*
* Arguments : const emxArray_real_T *x
* Return Type : double
*/
static double b_sum(const emxArray_real_T *x)
{
double y;
int k;
if (x->size[1] == 0) {
y = 0.0;
} else {
y = x->data[0];
for (k = 2; k <= x->size[1]; k++) {
y += x->data[k - 1];
}
}
return y;
}
/*
* Arguments : const double o[7]
* double u[7]
* Return Type : void
*/
static void b_us(const double o[7], double u[7])
{
int ix;
int iy;
int k;
for (ix = 0; ix < 7; ix++) {
u[ix] = 0.0;
}
ix = 0;
iy = 0;
for (k = 0; k < 7; k++) {
u[iy] = o[ix];
ix++;
iy++;
}
}
/*
* Arguments : int n
* const creal_T a
* emxArray_creal_T *x
* int ix0
* int incx
* Return Type : void
*/
static void b_xscal(int n, const creal_T a, emxArray_creal_T *x, int ix0, int
incx)
{
int i62;
int k;
double x_re;
double x_im;
if (!(incx < 1)) {
i62 = ix0 + incx * (n - 1);
for (k = ix0; k <= i62; k += incx) {
x_re = x->data[k - 1].re;
x_im = x->data[k - 1].im;
x->data[k - 1].re = a.re * x_re - a.im * x_im;
x->data[k - 1].im = a.re * x_im + a.im * x_re;
}
}
}
/*
* Arguments : const creal_T f
* const creal_T g
* double *cs
* creal_T *sn
* Return Type : void
*/
static void b_xzlartg(const creal_T f, const creal_T g, double *cs, creal_T *sn)
{
double scale;
double f2s;
double x;
double fs_re;
double fs_im;
double gs_re;
double gs_im;
boolean_T guard1 = false;
double g2;
double g2s;
scale = fabs(f.re);
f2s = fabs(f.im);
if (f2s > scale) {
scale = f2s;
}
x = fabs(g.re);
f2s = fabs(g.im);
if (f2s > x) {
x = f2s;
}
if (x > scale) {
scale = x;
}
fs_re = f.re;
fs_im = f.im;
gs_re = g.re;
gs_im = g.im;
guard1 = false;
if (scale >= 7.4428285367870146E+137) {
do {
fs_re *= 1.3435752215134178E-138;
fs_im *= 1.3435752215134178E-138;
gs_re *= 1.3435752215134178E-138;
gs_im *= 1.3435752215134178E-138;
scale *= 1.3435752215134178E-138;
} while (!(scale < 7.4428285367870146E+137));
guard1 = true;
} else if (scale <= 1.3435752215134178E-138) {
if ((g.re == 0.0) && (g.im == 0.0)) {
*cs = 1.0;
sn->re = 0.0;
sn->im = 0.0;
} else {
do {
fs_re *= 7.4428285367870146E+137;
fs_im *= 7.4428285367870146E+137;
gs_re *= 7.4428285367870146E+137;
gs_im *= 7.4428285367870146E+137;
scale *= 7.4428285367870146E+137;
} while (!(scale > 1.3435752215134178E-138));
guard1 = true;
}
} else {
guard1 = true;
}
if (guard1) {
scale = fs_re * fs_re + fs_im * fs_im;
g2 = gs_re * gs_re + gs_im * gs_im;
x = g2;
if (1.0 > g2) {
x = 1.0;
}
if (scale <= x * 2.0041683600089728E-292) {
if ((f.re == 0.0) && (f.im == 0.0)) {
*cs = 0.0;
g2 = rt_hypotd_snf(gs_re, gs_im);
sn->re = gs_re / g2;
sn->im = -gs_im / g2;
} else {
g2s = sqrt(g2);
*cs = rt_hypotd_snf(fs_re, fs_im) / g2s;
x = fabs(f.re);
f2s = fabs(f.im);
if (f2s > x) {
x = f2s;
}
if (x > 1.0) {
g2 = rt_hypotd_snf(f.re, f.im);
fs_re = f.re / g2;
fs_im = f.im / g2;
} else {
scale = 7.4428285367870146E+137 * f.re;
f2s = 7.4428285367870146E+137 * f.im;
g2 = rt_hypotd_snf(scale, f2s);
fs_re = scale / g2;
fs_im = f2s / g2;
}
gs_re /= g2s;
gs_im = -gs_im / g2s;
sn->re = fs_re * gs_re - fs_im * gs_im;
sn->im = fs_re * gs_im + fs_im * gs_re;
}
} else {
f2s = sqrt(1.0 + g2 / scale);
fs_re *= f2s;
fs_im *= f2s;
*cs = 1.0 / f2s;
g2 += scale;
fs_re /= g2;
fs_im /= g2;
sn->re = fs_re * gs_re - fs_im * -gs_im;
sn->im = fs_re * -gs_im + fs_im * gs_re;
}
}
}
/*
* BUTTER_CG Butterworth digital and analog filter design. Codegen support
*
* This function is based on 'butter' by The MathWorks Inc.
* Arguments : double Wn
* double num[2]
* creal_T den_data[]
* int den_size[2]
* Return Type : void
*/
static void butter_cg(double Wn, double num[2], creal_T den_data[], int
den_size[2])
{
emxArray_real_T *c;
int i5;
int tmp_size[2];
creal_T tmp_data[1];
int b_tmp_size[1];
double b_tmp_data[1];
emxArray_creal_T *a;
emxArray_real_T *b;
emxArray_creal_T *r1;
emxArray_creal_T c_tmp_data;
emxArray_real_T d_tmp_data;
double d;
int loop_ub;
double y_im;
double ar;
double ai;
emxInit_real_T(&c, 2);
/* Set types we will only use */
/* Cast to enforce precision rules */
/* step 1: get analog, pre-warped frequencies */
/* step 2: convert to low-pass prototype estimate */
/* lowpass */
/* Cast to enforce precision rules */
/* step 3: Get N-th order Butterworth analog lowpass prototype */
/* Transform to state-space */
/* ZP2SS Zero-pole to state-space conversion. Codegen support */
/* */
/* This function is based on 'zp2ss' by The MathWorks Inc. */
/* Strip infinities and throw away. */
/* Group into complex pairs */
/* try */
/* % z and p should have real elements and exact complex conjugate pair. */
/* z = cplxpair(zF,0); */
/* p = cplxpair(pF,0); */
/* catch */
/* % If fail, revert to use the old default tolerance. */
/* % The use of tolerance in checking for real entries and conjugate pairs */
/* % may result in misinterpretation for edge cases. Please review the */
/* % process of how z and p are generated. */
/* z = cplxpair(zF,1e6*nz*norm(zF)*eps + eps); */
/* p = cplxpair(pF,1e6*np*norm(pF)*eps + eps); */
/* end */
/* Initialize state-space matrices for running series */
/* If odd number of poles AND zeros, convert the pole and zero */
/* at the end into state-space. */
/* H(s) = (s-z1)/(s-p1) = (s + num(2)) / (s + den(2)) */
/* If odd number of poles only, convert the pole at the */
/* end into state-space. */
/* H(s) = 1/(s-p1) = 1/(s + den(2)) */
/* If odd number of zeros only, convert the zero at the */
/* end, along with a pole-pair into state-space. */
/* H(s) = (s+num(2))/(s^2+den(2)s+den(3)) */
/* Now we have an even number of poles and zeros, although not */
/* necessarily the same number - there may be more poles. */
/* H(s) = (s^2+num(2)s+num(3))/(s^2+den(2)s+den(3)) */
/* Loop through rest of pairs, connecting in series to build the model. */
/* Take care of any left over unmatched pole pairs. */
/* H(s) = 1/(s^2+den(2)s+den(3)) */
/* Apply gain k: */
/* step 4: Transform to lowpass, bandpass, highpass, or bandstop of desired Wn */
/* Lowpass */
i5 = c->size[0] * c->size[1];
c->size[0] = 1;
c->size[1] = 1;
emxEnsureCapacity_real_T(c, i5);
c->data[0] = 1.0;
tmp_size[0] = 1;
tmp_size[1] = 1;
tmp_data[0].re = -1.0;
tmp_data[0].im = 0.0;
b_tmp_size[0] = 1;
b_tmp_data[0] = 1.0;
emxInit_creal_T(&a, 2);
emxInit_real_T1(&b, 1);
emxInit_creal_T(&r1, 2);
c_tmp_data.data = (creal_T *)&tmp_data;
c_tmp_data.size = (int *)&tmp_size;
c_tmp_data.allocatedSize = 1;
c_tmp_data.numDimensions = 2;
c_tmp_data.canFreeData = false;
d_tmp_data.data = (double *)&b_tmp_data;
d_tmp_data.size = (int *)&b_tmp_size;
d_tmp_data.allocatedSize = 1;
d_tmp_data.numDimensions = 1;
d_tmp_data.canFreeData = false;
lp2lp_cg(&c_tmp_data, &d_tmp_data, Wn, a, b, &d);
/* step 5: Use Bilinear transformation to find discrete equivalent: */
/* nargout <= 3 */
/* Transform to zero-pole-gain and polynomial forms: */
/* nargout <= 2 */
poly(a, r1);
den_size[0] = 1;
den_size[1] = r1->size[1];
loop_ub = r1->size[0] * r1->size[1];
emxFree_real_T(&c);
emxFree_real_T(&b);
emxFree_creal_T(&a);
for (i5 = 0; i5 < loop_ub; i5++) {
den_data[i5] = r1->data[i5];
}
emxFree_creal_T(&r1);
/* This internal function returns more exact numerator vectors */
/* for the num/den case. */
/* Wn input is two element band edge vector */
/* --------------------------------- */
/* lowpass */
d = (0.0 * den_data[0].re - 0.0 * den_data[0].im) + den_data[1].re;
y_im = (0.0 * den_data[0].im + 0.0 * den_data[0].re) + den_data[1].im;
for (i5 = 0; i5 < 2; i5++) {
ar = (double)i5 * d;
ai = (double)i5 * y_im;
if ((!(ai == 0.0)) && (ar == 0.0)) {
ar = 0.0;
}
num[i5] = ar;
}
/* num = poly(a-b*c)+(d-1)*den; */
}
/*
* Arguments : const emxArray_real_T *x
* emxArray_real_T *y
* Return Type : void
*/
static void c_abs(const emxArray_real_T *x, emxArray_real_T *y)
{
int k;
k = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = x->size[1];
emxEnsureCapacity_real_T(y, k);
for (k = 0; k + 1 <= x->size[1]; k++) {
y->data[k] = fabs(x->data[k]);
}
}
/*
* UNTITLED Summary of this function goes here
* Detailed explanation goes here
* Arguments : const emxArray_real_T *f
* double Fconverter
* const double b1_data[]
* const int b1_size[2]
* const emxArray_creal_T *a1
* const double b2_data[]
* const int b2_size[2]
* const emxArray_creal_T *a2
* emxArray_creal_T *abc
* Return Type : void
*/
static void c_analogresp(const emxArray_real_T *f, double Fconverter, const
double b1_data[], const int b1_size[2], const emxArray_creal_T *a1, const
double b2_data[], const int b2_size[2], const emxArray_creal_T *a2,
emxArray_creal_T *abc)
{
emxArray_real_T *r25;
int b_abc;
int loop_ub;
emxArray_creal_T *r26;
emxArray_real_T *r27;
double abc_re;
double abc_im;
emxInit_real_T(&r25, 2);
b_abc = r25->size[0] * r25->size[1];
r25->size[0] = 1;
r25->size[1] = f->size[1];
emxEnsureCapacity_real_T(r25, b_abc);
loop_ub = f->size[0] * f->size[1];
for (b_abc = 0; b_abc < loop_ub; b_abc++) {
r25->data[b_abc] = 6.2831853071795862 * f->data[b_abc];
}
b_freqs_cg(b1_data, b1_size, a1, r25, abc);
b_abc = r25->size[0] * r25->size[1];
r25->size[0] = 1;
r25->size[1] = f->size[1];
emxEnsureCapacity_real_T(r25, b_abc);
loop_ub = f->size[0] * f->size[1];
for (b_abc = 0; b_abc < loop_ub; b_abc++) {
r25->data[b_abc] = 6.2831853071795862 * f->data[b_abc];
}
emxInit_creal_T(&r26, 2);
emxInit_real_T(&r27, 2);
b_freqs_cg(b2_data, b2_size, a2, r25, r26);
rdivide(f, Fconverter, r25);
b_sinc(r25);
c_power(r25, r27);
b_abc = abc->size[0] * abc->size[1];
abc->size[0] = 1;
emxEnsureCapacity_creal_T(abc, b_abc);
b_abc = abc->size[0];
loop_ub = abc->size[1];
loop_ub *= b_abc;
emxFree_real_T(&r25);
for (b_abc = 0; b_abc < loop_ub; b_abc++) {
abc_re = abc->data[b_abc].re * r26->data[b_abc].re - abc->data[b_abc].im *
r26->data[b_abc].im;
abc_im = abc->data[b_abc].re * r26->data[b_abc].im + abc->data[b_abc].im *
r26->data[b_abc].re;
abc->data[b_abc].re = r27->data[b_abc] * abc_re;
abc->data[b_abc].im = r27->data[b_abc] * abc_im;
}
emxFree_real_T(&r27);
emxFree_creal_T(&r26);
}
/*
* Arguments : emxArray_creal_T *x
* Return Type : void
*/
static void c_exp(emxArray_creal_T *x)
{
int nx;
int k;
double x_re;
double r;
nx = x->size[1];
for (k = 0; k + 1 <= nx; k++) {
if (x->data[k].im == 0.0) {
x_re = exp(x->data[k].re);
r = 0.0;
} else if (rtIsInf(x->data[k].im) && rtIsInf(x->data[k].re) && (x->data[k].
re < 0.0)) {
x_re = 0.0;
r = 0.0;
} else {
r = exp(x->data[k].re / 2.0);
x_re = r * (r * cos(x->data[k].im));
r *= r * sin(x->data[k].im);
}
x->data[k].re = x_re;
x->data[k].im = r;
}
}
/*
* Make b a row
* Arguments : const double b[7]
* const struct_T *options
* creal_T h[2048]
* double w[2048]
* Return Type : void
*/
static void c_firfreqz(const double b[7], const struct_T *options, creal_T h
[2048], double w[2048])
{
int i65;
creal_T dcv3[2048];
double digw;
double b_digw[2048];
double h_re;
double brm;
double d;
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
/* Convert from Hz to rad/sample for computational purposes */
/* Digital frequency must be used for this calculation */
for (i65 = 0; i65 < 2048; i65++) {
w[i65] = options->w[i65];
digw = 6.2831853071795862 * options->w[i65] / options->Fs;
dcv3[i65].re = digw * 0.0;
dcv3[i65].im = digw;
b_digw[i65] = digw;
}
b_exp(dcv3);
b_polyval(b, dcv3, h);
for (i65 = 0; i65 < 2048; i65++) {
dcv3[i65].re = 6.0 * (b_digw[i65] * 0.0);
dcv3[i65].im = 6.0 * b_digw[i65];
}
b_exp(dcv3);
for (i65 = 0; i65 < 2048; i65++) {
h_re = h[i65].re;
if (dcv3[i65].im == 0.0) {
if (h[i65].im == 0.0) {
h[i65].re /= dcv3[i65].re;
h[i65].im = 0.0;
} else if (h[i65].re == 0.0) {
h[i65].re = 0.0;
h[i65].im /= dcv3[i65].re;
} else {
h[i65].re /= dcv3[i65].re;
h[i65].im /= dcv3[i65].re;
}
} else if (dcv3[i65].re == 0.0) {
if (h[i65].re == 0.0) {
h[i65].re = h[i65].im / dcv3[i65].im;
h[i65].im = 0.0;
} else if (h[i65].im == 0.0) {
h[i65].re = 0.0;
h[i65].im = -(h_re / dcv3[i65].im);
} else {
h[i65].re = h[i65].im / dcv3[i65].im;
h[i65].im = -(h_re / dcv3[i65].im);
}
} else {
brm = fabs(dcv3[i65].re);
digw = fabs(dcv3[i65].im);
if (brm > digw) {
digw = dcv3[i65].im / dcv3[i65].re;
d = dcv3[i65].re + digw * dcv3[i65].im;
h[i65].re = (h[i65].re + digw * h[i65].im) / d;
h[i65].im = (h[i65].im - digw * h_re) / d;
} else if (digw == brm) {
if (dcv3[i65].re > 0.0) {
digw = 0.5;
} else {
digw = -0.5;
}
if (dcv3[i65].im > 0.0) {
d = 0.5;
} else {
d = -0.5;
}
h[i65].re = (h[i65].re * digw + h[i65].im * d) / brm;
h[i65].im = (h[i65].im * digw - h_re * d) / brm;
} else {
digw = dcv3[i65].re / dcv3[i65].im;
d = dcv3[i65].im + digw * dcv3[i65].re;
h[i65].re = (digw * h[i65].re + h[i65].im) / d;
h[i65].im = (digw * h[i65].im - h_re) / d;
}
}
}
}
/*
* Arguments : emxArray_real_T *x
* Return Type : void
*/
static void c_fix(emxArray_real_T *x)
{
int nx;
int k;
double b_x;
nx = x->size[1];
for (k = 0; k + 1 <= nx; k++) {
if (x->data[k] < 0.0) {
b_x = ceil(x->data[k]);
} else {
b_x = floor(x->data[k]);
}
x->data[k] = b_x;
}
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[7]
* const double w[2048]
* double Fs
* creal_T hh[2048]
* Return Type : void
*/
static void c_freqz_cg(const double b[7], const double w[2048], double Fs,
creal_T hh[2048])
{
static struct_T options;
int i12;
static const char cv16[8] = { 'o', 'n', 'e', 's', 'i', 'd', 'e', 'd' };
double b_w[2048];
static const char cv17[7] = { 'o', 'm', 'i', 't', 't', 'e', 'd' };
/* Cast to enforce precision rules */
options.Fs = Fs;
memcpy(&options.nfft[0], &w[0], sizeof(double) << 11);
memcpy(&options.w[0], &w[0], sizeof(double) << 11);
/* Remaining are default or for advanced use */
options.fvflag = 1.0;
for (i12 = 0; i12 < 8; i12++) {
options.range[i12] = cv16[i12];
}
options.centerdc = 0.0;
for (i12 = 0; i12 < 7; i12++) {
options.configlevel[i12] = cv17[i12];
}
c_firfreqz(b, &options, hh, b_w);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
}
/*
* Arguments : const char enables[4]
* const emxArray_real_T *w
* double Fs
* const double hb1_coeff[15]
* const double hb2_coeff[7]
* const double hb3_coeff_data[]
* const int hb3_coeff_size[2]
* const double dec_int3_coeff_data[]
* const int dec_int3_coeff_size[2]
* const emxArray_real_T *extraTaps
* emxArray_creal_T *combinedResponse
* Return Type : void
*/
static void c_generateCascadedResponseRx(const char enables[4], const
emxArray_real_T *w, double Fs, const double hb1_coeff[15], const double
hb2_coeff[7], const double hb3_coeff_data[], const int hb3_coeff_size[2],
const double dec_int3_coeff_data[], const int dec_int3_coeff_size[2], const
emxArray_real_T *extraTaps, emxArray_creal_T *combinedResponse)
{
boolean_T b_bool;
int iy;
int exitg1;
emxArray_creal_T *d2;
emxArray_creal_T *d3;
static const char cv48[4] = { '2', '1', '1', '1' };
double u[15];
int stages;
double tmp_data[29];
int tmp_size[2];
double b_u[30];
double c_u[14];
double d_u[60];
double e_u[45];
double f_u[21];
double g_u[90];
emxArray_real_T b_tmp_data;
double h_u[7];
emxArray_real_T *i_u;
int k;
int c;
static const char cv49[4] = { '1', '2', '1', '1' };
static const char cv50[4] = { '1', '1', '2', '1' };
double combinedResponse_re;
double combinedResponse_im;
double d2_re;
double d2_im;
static const char cv51[4] = { '2', '2', '1', '1' };
static const char cv52[4] = { '2', '1', '2', '1' };
static const char cv53[4] = { '1', '2', '2', '1' };
static const char cv54[4] = { '2', '2', '2', '1' };
static const char cv55[4] = { '1', '1', '1', '3' };
static const char cv56[4] = { '2', '1', '1', '3' };
static const char cv57[4] = { '1', '2', '1', '3' };
static const char cv58[4] = { '2', '2', '1', '3' };
/* Cast */
b_bool = false;
iy = 1;
do {
exitg1 = 0;
if (iy < 5) {
if (enables[iy - 1] != '1') {
exitg1 = 1;
} else {
iy++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
iy = 0;
} else {
b_bool = false;
iy = 0;
do {
exitg1 = 0;
if (iy + 1 < 5) {
if (enables[iy] != cv48[iy]) {
exitg1 = 1;
} else {
iy++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
iy = 1;
} else {
b_bool = false;
iy = 0;
do {
exitg1 = 0;
if (iy + 1 < 5) {
if (enables[iy] != cv49[iy]) {
exitg1 = 1;
} else {
iy++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
iy = 2;
} else {
b_bool = false;
iy = 0;
do {
exitg1 = 0;
if (iy + 1 < 5) {
if (enables[iy] != cv50[iy]) {
exitg1 = 1;
} else {
iy++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
iy = 3;
} else {
b_bool = false;
iy = 0;
do {
exitg1 = 0;
if (iy + 1 < 5) {
if (enables[iy] != cv51[iy]) {
exitg1 = 1;
} else {
iy++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
iy = 4;
} else {
b_bool = false;
iy = 0;
do {
exitg1 = 0;
if (iy + 1 < 5) {
if (enables[iy] != cv52[iy]) {
exitg1 = 1;
} else {
iy++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
iy = 5;
} else {
b_bool = false;
iy = 0;
do {
exitg1 = 0;
if (iy + 1 < 5) {
if (enables[iy] != cv53[iy]) {
exitg1 = 1;
} else {
iy++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
iy = 6;
} else {
b_bool = false;
iy = 0;
do {
exitg1 = 0;
if (iy + 1 < 5) {
if (enables[iy] != cv54[iy]) {
exitg1 = 1;
} else {
iy++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
iy = 7;
} else {
b_bool = false;
iy = 0;
do {
exitg1 = 0;
if (iy + 1 < 5) {
if (enables[iy] != cv55[iy]) {
exitg1 = 1;
} else {
iy++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
iy = 8;
} else {
b_bool = false;
iy = 0;
do {
exitg1 = 0;
if (iy + 1 < 5) {
if (enables[iy] != cv56[iy]) {
exitg1 = 1;
} else {
iy++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
iy = 9;
} else {
b_bool = false;
iy = 0;
do {
exitg1 = 0;
if (iy + 1 < 5) {
if (enables[iy] != cv57[iy]) {
exitg1 = 1;
} else {
iy++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
iy = 10;
} else {
b_bool = false;
iy = 0;
do {
exitg1 = 0;
if (iy + 1 < 5) {
if (enables[iy] != cv58[iy]) {
exitg1 = 1;
} else {
iy++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
iy = 11;
} else {
iy = -1;
}
}
}
}
}
}
}
}
}
}
}
}
emxInit_creal_T(&d2, 2);
emxInit_creal_T(&d3, 2);
switch (iy) {
case 0:
/* only FIR */
k_freqz_cg(w, Fs, combinedResponse);
stages = 1;
break;
case 1:
/* Hb1 */
memset(&u[0], 0, 15U * sizeof(double));
stages = 0;
iy = 0;
for (k = 0; k < 15; k++) {
u[iy] = hb1_coeff[stages];
stages++;
iy++;
}
l_freqz_cg(u, w, Fs, combinedResponse);
stages = 1;
break;
case 2:
/* Hb2 */
for (stages = 0; stages < 7; stages++) {
h_u[stages] = 0.0;
}
stages = 0;
iy = 0;
for (k = 0; k < 7; k++) {
h_u[iy] = hb2_coeff[stages];
stages++;
iy++;
}
m_freqz_cg(h_u, w, Fs, combinedResponse);
stages = 1;
break;
case 3:
/* Hb3 */
c_us(hb3_coeff_data, hb3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, combinedResponse);
stages = 1;
break;
case 4:
/* Hb2,Hb1 */
memset(&b_u[0], 0, 30U * sizeof(double));
stages = 0;
iy = 0;
for (k = 0; k < 15; k++) {
b_u[iy] = hb1_coeff[stages];
stages++;
iy += 2;
}
o_freqz_cg(*(double (*)[29])&b_u[0], w, Fs, combinedResponse);
for (stages = 0; stages < 7; stages++) {
h_u[stages] = 0.0;
}
stages = 0;
iy = 0;
for (k = 0; k < 7; k++) {
h_u[iy] = hb2_coeff[stages];
stages++;
iy++;
}
m_freqz_cg(h_u, w, Fs, d2);
stages = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, stages);
iy = combinedResponse->size[0];
stages = combinedResponse->size[1];
iy *= stages;
for (stages = 0; stages < iy; stages++) {
combinedResponse_re = combinedResponse->data[stages].re;
combinedResponse_im = combinedResponse->data[stages].im;
d2_re = d2->data[stages].re;
d2_im = d2->data[stages].im;
combinedResponse->data[stages].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[stages].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
stages = 2;
break;
case 5:
/* Hb3,Hb1 */
memset(&b_u[0], 0, 30U * sizeof(double));
stages = 0;
iy = 0;
for (k = 0; k < 15; k++) {
b_u[iy] = hb1_coeff[stages];
stages++;
iy += 2;
}
o_freqz_cg(*(double (*)[29])&b_u[0], w, Fs, combinedResponse);
c_us(hb3_coeff_data, hb3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, d2);
stages = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, stages);
iy = combinedResponse->size[0];
stages = combinedResponse->size[1];
iy *= stages;
for (stages = 0; stages < iy; stages++) {
combinedResponse_re = combinedResponse->data[stages].re;
combinedResponse_im = combinedResponse->data[stages].im;
d2_re = d2->data[stages].re;
d2_im = d2->data[stages].im;
combinedResponse->data[stages].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[stages].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
stages = 2;
break;
case 6:
/* Hb3,Hb2 */
memset(&c_u[0], 0, 14U * sizeof(double));
stages = 0;
iy = 0;
for (k = 0; k < 7; k++) {
c_u[iy] = hb2_coeff[stages];
stages++;
iy += 2;
}
p_freqz_cg(*(double (*)[13])&c_u[0], w, Fs, combinedResponse);
c_us(hb3_coeff_data, hb3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, d2);
stages = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, stages);
iy = combinedResponse->size[0];
stages = combinedResponse->size[1];
iy *= stages;
for (stages = 0; stages < iy; stages++) {
combinedResponse_re = combinedResponse->data[stages].re;
combinedResponse_im = combinedResponse->data[stages].im;
d2_re = d2->data[stages].re;
d2_im = d2->data[stages].im;
combinedResponse->data[stages].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[stages].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
stages = 2;
break;
case 7:
/* Hb3,Hb2,Hb1 */
memset(&d_u[0], 0, 60U * sizeof(double));
stages = 0;
iy = 0;
for (k = 0; k < 15; k++) {
d_u[iy] = hb1_coeff[stages];
stages++;
iy += 4;
}
q_freqz_cg(*(double (*)[57])&d_u[0], w, Fs, combinedResponse);
memset(&c_u[0], 0, 14U * sizeof(double));
stages = 0;
iy = 0;
for (k = 0; k < 7; k++) {
c_u[iy] = hb2_coeff[stages];
stages++;
iy += 2;
}
p_freqz_cg(*(double (*)[13])&c_u[0], w, Fs, d2);
c_us(hb3_coeff_data, hb3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, d3);
stages = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, stages);
iy = combinedResponse->size[0];
stages = combinedResponse->size[1];
iy *= stages;
for (stages = 0; stages < iy; stages++) {
combinedResponse_re = combinedResponse->data[stages].re * d2->data[stages]
.re - combinedResponse->data[stages].im * d2->data[stages].im;
combinedResponse_im = combinedResponse->data[stages].re * d2->data[stages]
.im + combinedResponse->data[stages].im * d2->data[stages].re;
d2_re = d3->data[stages].re;
d2_im = d3->data[stages].im;
combinedResponse->data[stages].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[stages].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
stages = 3;
break;
case 8:
/* Dec/Int3 */
c_us(dec_int3_coeff_data, dec_int3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, combinedResponse);
stages = 1;
/* RECHECK ALL DEC BY 3 */
break;
case 9:
/* Dec/Int3,Hb1 */
memset(&e_u[0], 0, 45U * sizeof(double));
stages = 0;
iy = 0;
for (k = 0; k < 15; k++) {
e_u[iy] = hb1_coeff[stages];
stages++;
iy += 3;
}
r_freqz_cg(*(double (*)[43])&e_u[0], w, Fs, combinedResponse);
c_us(dec_int3_coeff_data, dec_int3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, d2);
stages = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, stages);
iy = combinedResponse->size[0];
stages = combinedResponse->size[1];
iy *= stages;
for (stages = 0; stages < iy; stages++) {
combinedResponse_re = combinedResponse->data[stages].re;
combinedResponse_im = combinedResponse->data[stages].im;
d2_re = d2->data[stages].re;
d2_im = d2->data[stages].im;
combinedResponse->data[stages].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[stages].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
stages = 2;
break;
case 10:
/* Dec/Int3,Hb2 */
memset(&f_u[0], 0, 21U * sizeof(double));
stages = 0;
iy = 0;
for (k = 0; k < 7; k++) {
f_u[iy] = hb2_coeff[stages];
stages++;
iy += 3;
}
s_freqz_cg(*(double (*)[19])&f_u[0], w, Fs, combinedResponse);
c_us(dec_int3_coeff_data, dec_int3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, d2);
stages = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, stages);
iy = combinedResponse->size[0];
stages = combinedResponse->size[1];
iy *= stages;
for (stages = 0; stages < iy; stages++) {
combinedResponse_re = combinedResponse->data[stages].re;
combinedResponse_im = combinedResponse->data[stages].im;
d2_re = d2->data[stages].re;
d2_im = d2->data[stages].im;
combinedResponse->data[stages].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[stages].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
stages = 2;
break;
case 11:
/* Dec/Int3,Hb2,Hb1 {Hm4,Hm2c34,Hm1} */
memset(&g_u[0], 0, 90U * sizeof(double));
stages = 0;
iy = 0;
for (k = 0; k < 15; k++) {
g_u[iy] = hb1_coeff[stages];
stages++;
iy += 6;
}
t_freqz_cg(*(double (*)[85])&g_u[0], w, Fs, combinedResponse);
memset(&f_u[0], 0, 21U * sizeof(double));
stages = 0;
iy = 0;
for (k = 0; k < 7; k++) {
f_u[iy] = hb2_coeff[stages];
stages++;
iy += 3;
}
s_freqz_cg(*(double (*)[19])&f_u[0], w, Fs, d2);
c_us(dec_int3_coeff_data, dec_int3_coeff_size, tmp_data, tmp_size);
b_tmp_data.data = (double *)&tmp_data;
b_tmp_data.size = (int *)&tmp_size;
b_tmp_data.allocatedSize = 29;
b_tmp_data.numDimensions = 2;
b_tmp_data.canFreeData = false;
n_freqz_cg(&b_tmp_data, w, Fs, d3);
stages = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, stages);
iy = combinedResponse->size[0];
stages = combinedResponse->size[1];
iy *= stages;
for (stages = 0; stages < iy; stages++) {
combinedResponse_re = combinedResponse->data[stages].re * d2->data[stages]
.re - combinedResponse->data[stages].im * d2->data[stages].im;
combinedResponse_im = combinedResponse->data[stages].re * d2->data[stages]
.im + combinedResponse->data[stages].im * d2->data[stages].re;
d2_re = d3->data[stages].re;
d2_im = d3->data[stages].im;
combinedResponse->data[stages].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[stages].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
stages = 3;
break;
}
emxFree_creal_T(&d3);
/* Add filter extra filter to end of cascade */
if (!(extraTaps->size[1] == 0)) {
emxInit_real_T(&i_u, 2);
c = (int)rt_powd_snf(2.0, stages);
iy = c * extraTaps->size[1];
stages = i_u->size[0] * i_u->size[1];
i_u->size[0] = 1;
i_u->size[1] = iy;
emxEnsureCapacity_real_T(i_u, stages);
for (stages = 0; stages < iy; stages++) {
i_u->data[stages] = 0.0;
}
stages = 0;
iy = 0;
for (k = 1; k <= extraTaps->size[1]; k++) {
i_u->data[iy] = extraTaps->data[stages];
stages++;
iy += c;
}
stages = (i_u->size[1] - c) + 1;
iy = i_u->size[0] * i_u->size[1];
if (1 > stages) {
i_u->size[1] = 0;
} else {
i_u->size[1] = stages;
}
emxEnsureCapacity_real_T(i_u, iy);
n_freqz_cg(i_u, w, Fs, d2);
stages = combinedResponse->size[0] * combinedResponse->size[1];
combinedResponse->size[0] = 1;
emxEnsureCapacity_creal_T(combinedResponse, stages);
iy = combinedResponse->size[0];
stages = combinedResponse->size[1];
iy *= stages;
emxFree_real_T(&i_u);
for (stages = 0; stages < iy; stages++) {
combinedResponse_re = combinedResponse->data[stages].re;
combinedResponse_im = combinedResponse->data[stages].im;
d2_re = d2->data[stages].re;
d2_im = d2->data[stages].im;
combinedResponse->data[stages].re = combinedResponse_re * d2_re -
combinedResponse_im * d2_im;
combinedResponse->data[stages].im = combinedResponse_re * d2_im +
combinedResponse_im * d2_re;
}
}
emxFree_creal_T(&d2);
}
/*
* Arguments : const double p_data[]
* const int p_size[2]
* const creal_T x[2048]
* creal_T y[2048]
* Return Type : void
*/
static void c_polyval(const double p_data[], const int p_size[2], const creal_T
x[2048], creal_T y[2048])
{
int i13;
int k;
double x_im;
if (!(p_size[1] == 0)) {
for (i13 = 0; i13 < 2048; i13++) {
y[i13].re = p_data[0];
y[i13].im = 0.0;
}
for (k = 0; k <= p_size[1] - 2; k++) {
for (i13 = 0; i13 < 2048; i13++) {
x_im = x[i13].re * y[i13].im + x[i13].im * y[i13].re;
y[i13].re = (x[i13].re * y[i13].re - x[i13].im * y[i13].im) + p_data[k +
1];
y[i13].im = x_im;
}
}
}
}
/*
* Arguments : const emxArray_real_T *a
* emxArray_real_T *y
* Return Type : void
*/
static void c_power(const emxArray_real_T *a, emxArray_real_T *y)
{
int unnamed_idx_1;
int k;
unnamed_idx_1 = a->size[1];
k = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = a->size[1];
emxEnsureCapacity_real_T(y, k);
for (k = 0; k + 1 <= unnamed_idx_1; k++) {
y->data[k] = rt_powd_snf(a->data[k], 3.0);
}
}
/*
* Arguments : const emxArray_real_T *x
* const emxArray_real_T *y
* emxArray_real_T *z
* Return Type : void
*/
static void c_rdivide(const emxArray_real_T *x, const emxArray_real_T *y,
emxArray_real_T *z)
{
int i50;
int loop_ub;
i50 = z->size[0] * z->size[1];
z->size[0] = 1;
z->size[1] = x->size[1];
emxEnsureCapacity_real_T(z, i50);
loop_ub = x->size[0] * x->size[1];
for (i50 = 0; i50 < loop_ub; i50++) {
z->data[i50] = x->data[i50] / y->data[i50];
}
}
/*
* Arguments : creal_T *x
* Return Type : void
*/
static void c_sqrt(creal_T *x)
{
double xr;
double xi;
double absxi;
double absxr;
xr = x->re;
xi = x->im;
if (xi == 0.0) {
if (xr < 0.0) {
absxi = 0.0;
xr = sqrt(-xr);
} else {
absxi = sqrt(xr);
xr = 0.0;
}
} else if (xr == 0.0) {
if (xi < 0.0) {
absxi = sqrt(-xi / 2.0);
xr = -absxi;
} else {
absxi = sqrt(xi / 2.0);
xr = absxi;
}
} else if (rtIsNaN(xr)) {
absxi = xr;
} else if (rtIsNaN(xi)) {
absxi = xi;
xr = xi;
} else if (rtIsInf(xi)) {
absxi = fabs(xi);
xr = xi;
} else if (rtIsInf(xr)) {
if (xr < 0.0) {
absxi = 0.0;
xr = xi * -xr;
} else {
absxi = xr;
xr = 0.0;
}
} else {
absxr = fabs(xr);
absxi = fabs(xi);
if ((absxr > 4.4942328371557893E+307) || (absxi > 4.4942328371557893E+307)) {
absxr *= 0.5;
absxi *= 0.5;
absxi = rt_hypotd_snf(absxr, absxi);
if (absxi > absxr) {
absxi = sqrt(absxi) * sqrt(1.0 + absxr / absxi);
} else {
absxi = sqrt(absxi) * 1.4142135623730951;
}
} else {
absxi = sqrt((rt_hypotd_snf(absxr, absxi) + absxr) * 0.5);
}
if (xr > 0.0) {
xr = 0.5 * (xi / absxi);
} else {
if (xi < 0.0) {
xr = -absxi;
} else {
xr = absxi;
}
absxi = 0.5 * (xi / xr);
}
}
x->re = absxi;
x->im = xr;
}
/*
* Arguments : const char a[2]
* Return Type : boolean_T
*/
static boolean_T c_strcmp(const char a[2])
{
boolean_T b_bool;
int kstr;
int exitg1;
static const char cv32[2] = { 'T', 'x' };
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 3) {
if (a[kstr] != cv32[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
return b_bool;
}
/*
* Arguments : const double x[128]
* Return Type : double
*/
static double c_sum(const double x[128])
{
double y;
int k;
y = x[0];
for (k = 0; k < 127; k++) {
y += x[k + 1];
}
return y;
}
/*
* Arguments : const double o_data[]
* const int o_size[2]
* double u_data[]
* int u_size[2]
* Return Type : void
*/
static void c_us(const double o_data[], const int o_size[2], double u_data[],
int u_size[2])
{
int ix;
int iy;
int k;
u_size[0] = 1;
u_size[1] = (signed char)o_size[1];
ix = (signed char)o_size[1];
if (0 <= ix - 1) {
memset(&u_data[0], 0, (unsigned int)(ix * (int)sizeof(double)));
}
ix = 0;
iy = 0;
for (k = 1; k <= o_size[1]; k++) {
u_data[iy] = o_data[ix];
ix++;
iy++;
}
}
/*
* Arguments : double dBinput
* Return Type : double
*/
static double dBinv(double dBinput)
{
double dBoutput;
if (dBinput > -150.0) {
dBoutput = rt_powd_snf(10.0, dBinput / 20.0);
} else {
dBoutput = 0.0;
}
return dBoutput;
}
/*
* Arguments : const double x[128]
* double y[128]
* Return Type : void
*/
static void d_abs(const double x[128], double y[128])
{
int k;
for (k = 0; k < 128; k++) {
y[k] = fabs(x[k]);
}
}
/*
* UNTITLED Summary of this function goes here
* Detailed explanation goes here
* Arguments : const emxArray_real_T *f
* double Fconverter
* const double b1_data[]
* const int b1_size[2]
* const emxArray_creal_T *a1
* const double b2_data[]
* const int b2_size[2]
* const emxArray_creal_T *a2
* emxArray_creal_T *abc
* Return Type : void
*/
static void d_analogresp(const emxArray_real_T *f, double Fconverter, const
double b1_data[], const int b1_size[2], const emxArray_creal_T *a1, const
double b2_data[], const int b2_size[2], const emxArray_creal_T *a2,
emxArray_creal_T *abc)
{
emxArray_real_T *r28;
emxArray_real_T *r29;
int i56;
int loop_ub;
emxArray_creal_T *r30;
double re;
double im;
double b_re;
double b_im;
emxInit_real_T(&r28, 2);
emxInit_real_T(&r29, 2);
rdivide(f, Fconverter, r28);
b_sinc(r28);
i56 = r29->size[0] * r29->size[1];
r29->size[0] = 1;
r29->size[1] = f->size[1];
emxEnsureCapacity_real_T(r29, i56);
loop_ub = f->size[0] * f->size[1];
for (i56 = 0; i56 < loop_ub; i56++) {
r29->data[i56] = 6.2831853071795862 * f->data[i56];
}
b_freqs_cg(b1_data, b1_size, a1, r29, abc);
i56 = r29->size[0] * r29->size[1];
r29->size[0] = 1;
r29->size[1] = f->size[1];
emxEnsureCapacity_real_T(r29, i56);
loop_ub = f->size[0] * f->size[1];
for (i56 = 0; i56 < loop_ub; i56++) {
r29->data[i56] = 6.2831853071795862 * f->data[i56];
}
emxInit_creal_T(&r30, 2);
b_freqs_cg(b2_data, b2_size, a2, r29, r30);
i56 = abc->size[0] * abc->size[1];
abc->size[0] = 1;
abc->size[1] = r28->size[1];
emxEnsureCapacity_creal_T(abc, i56);
loop_ub = r28->size[0] * r28->size[1];
emxFree_real_T(&r29);
for (i56 = 0; i56 < loop_ub; i56++) {
re = r28->data[i56] * abc->data[i56].re;
im = r28->data[i56] * abc->data[i56].im;
b_re = r30->data[i56].re;
b_im = r30->data[i56].im;
abc->data[i56].re = re * b_re - im * b_im;
abc->data[i56].im = re * b_im + im * b_re;
}
emxFree_real_T(&r28);
emxFree_creal_T(&r30);
}
/*
* Make b a row
* Arguments : double b_data[]
* int b_size[2]
* const struct_T *options
* creal_T h[2048]
* double w[2048]
* Return Type : void
*/
static void d_firfreqz(double b_data[], int b_size[2], const struct_T *options,
creal_T h[2048], double w[2048])
{
int b_idx_0;
int loop_ub;
double b_b_data[29];
creal_T dcv4[2048];
double digw;
double b_digw[2048];
double h_re;
double brm;
double d;
/* -------------------------------------------------------------------------- */
b_idx_0 = b_size[1];
loop_ub = b_size[1];
if (0 <= loop_ub - 1) {
memcpy(&b_b_data[0], &b_data[0], (unsigned int)(loop_ub * (int)sizeof(double)));
}
b_size[0] = 1;
if (0 <= b_idx_0 - 1) {
memcpy(&b_data[0], &b_b_data[0], (unsigned int)(b_idx_0 * (int)sizeof(double)));
}
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
/* Convert from Hz to rad/sample for computational purposes */
/* Digital frequency must be used for this calculation */
for (b_idx_0 = 0; b_idx_0 < 2048; b_idx_0++) {
w[b_idx_0] = options->w[b_idx_0];
digw = 6.2831853071795862 * options->w[b_idx_0] / options->Fs;
dcv4[b_idx_0].re = digw * 0.0;
dcv4[b_idx_0].im = digw;
b_digw[b_idx_0] = digw;
}
b_exp(dcv4);
c_polyval(b_data, b_size, dcv4, h);
for (b_idx_0 = 0; b_idx_0 < 2048; b_idx_0++) {
dcv4[b_idx_0].re = ((double)b_size[1] - 1.0) * (b_digw[b_idx_0] * 0.0);
dcv4[b_idx_0].im = ((double)b_size[1] - 1.0) * b_digw[b_idx_0];
}
b_exp(dcv4);
for (b_idx_0 = 0; b_idx_0 < 2048; b_idx_0++) {
h_re = h[b_idx_0].re;
if (dcv4[b_idx_0].im == 0.0) {
if (h[b_idx_0].im == 0.0) {
h[b_idx_0].re /= dcv4[b_idx_0].re;
h[b_idx_0].im = 0.0;
} else if (h[b_idx_0].re == 0.0) {
h[b_idx_0].re = 0.0;
h[b_idx_0].im /= dcv4[b_idx_0].re;
} else {
h[b_idx_0].re /= dcv4[b_idx_0].re;
h[b_idx_0].im /= dcv4[b_idx_0].re;
}
} else if (dcv4[b_idx_0].re == 0.0) {
if (h[b_idx_0].re == 0.0) {
h[b_idx_0].re = h[b_idx_0].im / dcv4[b_idx_0].im;
h[b_idx_0].im = 0.0;
} else if (h[b_idx_0].im == 0.0) {
h[b_idx_0].re = 0.0;
h[b_idx_0].im = -(h_re / dcv4[b_idx_0].im);
} else {
h[b_idx_0].re = h[b_idx_0].im / dcv4[b_idx_0].im;
h[b_idx_0].im = -(h_re / dcv4[b_idx_0].im);
}
} else {
brm = fabs(dcv4[b_idx_0].re);
digw = fabs(dcv4[b_idx_0].im);
if (brm > digw) {
digw = dcv4[b_idx_0].im / dcv4[b_idx_0].re;
d = dcv4[b_idx_0].re + digw * dcv4[b_idx_0].im;
h[b_idx_0].re = (h[b_idx_0].re + digw * h[b_idx_0].im) / d;
h[b_idx_0].im = (h[b_idx_0].im - digw * h_re) / d;
} else if (digw == brm) {
if (dcv4[b_idx_0].re > 0.0) {
digw = 0.5;
} else {
digw = -0.5;
}
if (dcv4[b_idx_0].im > 0.0) {
d = 0.5;
} else {
d = -0.5;
}
h[b_idx_0].re = (h[b_idx_0].re * digw + h[b_idx_0].im * d) / brm;
h[b_idx_0].im = (h[b_idx_0].im * digw - h_re * d) / brm;
} else {
digw = dcv4[b_idx_0].re / dcv4[b_idx_0].im;
d = dcv4[b_idx_0].im + digw * dcv4[b_idx_0].re;
h[b_idx_0].re = (digw * h[b_idx_0].re + h[b_idx_0].im) / d;
h[b_idx_0].im = (digw * h[b_idx_0].im - h_re) / d;
}
}
}
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b_data[]
* const int b_size[2]
* const double w[2048]
* double Fs
* creal_T hh[2048]
* Return Type : void
*/
static void d_freqz_cg(const double b_data[], const int b_size[2], const double
w[2048], double Fs, creal_T hh[2048])
{
static struct_T options;
int loop_ub;
static const char cv18[8] = { 'o', 'n', 'e', 's', 'i', 'd', 'e', 'd' };
int b_b_size[2];
static const char cv19[7] = { 'o', 'm', 'i', 't', 't', 'e', 'd' };
double b_b_data[29];
double b_w[2048];
/* Cast to enforce precision rules */
options.Fs = Fs;
memcpy(&options.nfft[0], &w[0], sizeof(double) << 11);
memcpy(&options.w[0], &w[0], sizeof(double) << 11);
/* Remaining are default or for advanced use */
options.fvflag = 1.0;
for (loop_ub = 0; loop_ub < 8; loop_ub++) {
options.range[loop_ub] = cv18[loop_ub];
}
options.centerdc = 0.0;
for (loop_ub = 0; loop_ub < 7; loop_ub++) {
options.configlevel[loop_ub] = cv19[loop_ub];
}
b_b_size[0] = 1;
b_b_size[1] = b_size[1];
loop_ub = b_size[0] * b_size[1];
if (0 <= loop_ub - 1) {
memcpy(&b_b_data[0], &b_data[0], (unsigned int)(loop_ub * (int)sizeof(double)));
}
d_firfreqz(b_b_data, b_b_size, &options, hh, b_w);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
}
/*
* Arguments : const double p[29]
* const creal_T x[2048]
* creal_T y[2048]
* Return Type : void
*/
static void d_polyval(const double p[29], const creal_T x[2048],
creal_T y[2048])
{
int i14;
int k;
double x_im;
for (i14 = 0; i14 < 2048; i14++) {
y[i14].re = p[0];
y[i14].im = 0.0;
}
for (k = 0; k < 28; k++) {
for (i14 = 0; i14 < 2048; i14++) {
x_im = x[i14].re * y[i14].im + x[i14].im * y[i14].re;
y[i14].re = (x[i14].re * y[i14].re - x[i14].im * y[i14].im) + p[k + 1];
y[i14].im = x_im;
}
}
}
/*
* Arguments : const double o[15]
* double u[29]
* Return Type : void
*/
static void d_us(const double o[15], double u[29])
{
double b_u[30];
int ix;
int iy;
int k;
memset(&b_u[0], 0, 30U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 15; k++) {
b_u[iy] = o[ix];
ix++;
iy += 2;
}
memcpy(&u[0], &b_u[0], 29U * sizeof(double));
}
/*
* Arguments : double ydb
* Return Type : double
*/
static double db2mag(double ydb)
{
return rt_powd_snf(10.0, ydb / 20.0);
}
/*
* Codegen workaround for fixed fi call requirements
* Arguments : const emxArray_real_T *tap_store
* double i
* double M
* emxArray_real_T *taps
* Return Type : void
*/
static void determineBestFractionLength(const emxArray_real_T *tap_store, double
i, double M, emxArray_real_T *taps)
{
int ixstart;
emxArray_real_T *org;
int ix;
emxArray_real_T *r;
double u;
double v;
emxArray_real_T *b_r;
short i55;
emxArray_real_T *r24;
double e[16];
int itmp;
boolean_T exitg1;
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
emxInit_real_T(&org, 2);
ix = org->size[0] * org->size[1];
org->size[0] = 1;
org->size[1] = ixstart;
emxEnsureCapacity_real_T(org, ix);
for (ix = 0; ix < ixstart; ix++) {
org->data[org->size[0] * ix] = tap_store->data[((int)i + tap_store->size[0] *
ix) - 1];
}
emxInit_real_T(&r, 2);
ix = r->size[0] * r->size[1];
r->size[0] = 16;
r->size[1] = (int)M;
emxEnsureCapacity_real_T(r, ix);
ixstart = (int)M << 4;
for (ix = 0; ix < ixstart; ix++) {
r->data[ix] = 0.0;
}
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 2.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[r->size[0] * ix] = (double)i55 * 0.5;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
emxInit_real_T(&b_r, 2);
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[r->size[0] * ix] - org->data
[org->size[0] * ix];
}
emxInit_real_T(&r24, 2);
c_abs(b_r, r24);
e[0] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 4.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[1 + r->size[0] * ix] = (double)i55 * 0.25;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[1 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[1] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 8.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[2 + r->size[0] * ix] = (double)i55 * 0.125;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[2 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[2] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 16.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[3 + r->size[0] * ix] = (double)i55 * 0.0625;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[3 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[3] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 32.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[4 + r->size[0] * ix] = (double)i55 * 0.03125;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[4 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[4] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 64.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[5 + r->size[0] * ix] = (double)i55 * 0.015625;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[5 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[5] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 128.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[6 + r->size[0] * ix] = (double)i55 * 0.0078125;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[6 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[6] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 256.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[7 + r->size[0] * ix] = (double)i55 * 0.00390625;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[7 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[7] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 512.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[8 + r->size[0] * ix] = (double)i55 * 0.001953125;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[8 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[8] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 1024.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[9 + r->size[0] * ix] = (double)i55 * 0.0009765625;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[9 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[9] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 2048.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[10 + r->size[0] * ix] = (double)i55 * 0.00048828125;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[10 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[10] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 4096.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[11 + r->size[0] * ix] = (double)i55 * 0.000244140625;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[11 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[11] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 8192.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[12 + r->size[0] * ix] = (double)i55 * 0.0001220703125;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[12 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[12] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 16384.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[13 + r->size[0] * ix] = (double)i55 * 6.103515625E-5;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[13 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[13] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 32768.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[14 + r->size[0] * ix] = (double)i55 * 3.0517578125E-5;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[14 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
c_abs(b_r, r24);
e[14] = b_sum(r24);
if (1.0 > M) {
ixstart = -1;
} else {
ixstart = (int)M - 1;
}
for (ix = 0; ix <= ixstart; ix++) {
u = tap_store->data[((int)i + tap_store->size[0] * ix) - 1] * 65536.0;
v = fabs(u);
if (v < 4.503599627370496E+15) {
if (v >= 0.5) {
u = floor(u + 0.5);
} else {
u *= 0.0;
}
}
if (u < 32768.0) {
if (u >= -32768.0) {
i55 = (short)u;
} else {
i55 = MIN_int16_T;
}
} else if (u >= 32768.0) {
i55 = MAX_int16_T;
} else {
i55 = 0;
}
r->data[15 + r->size[0] * ix] = (double)i55 * 1.52587890625E-5;
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = b_r->size[0] * b_r->size[1];
b_r->size[0] = 1;
b_r->size[1] = ixstart;
emxEnsureCapacity_real_T(b_r, ix);
for (ix = 0; ix < ixstart; ix++) {
b_r->data[b_r->size[0] * ix] = r->data[15 + r->size[0] * ix] - org->data
[org->size[0] * ix];
}
emxFree_real_T(&org);
c_abs(b_r, r24);
e[15] = b_sum(r24);
ixstart = 1;
u = e[0];
itmp = 0;
emxFree_real_T(&b_r);
emxFree_real_T(&r24);
if (rtIsNaN(e[0])) {
ix = 2;
exitg1 = false;
while ((!exitg1) && (ix < 17)) {
ixstart = ix;
if (!rtIsNaN(e[ix - 1])) {
u = e[ix - 1];
itmp = ix - 1;
exitg1 = true;
} else {
ix++;
}
}
}
if (ixstart < 16) {
while (ixstart + 1 < 17) {
if (e[ixstart] < u) {
u = e[ixstart];
itmp = ixstart;
}
ixstart++;
}
}
if (1.0 > M) {
ixstart = 0;
} else {
ixstart = (int)M;
}
ix = taps->size[0] * taps->size[1];
taps->size[0] = 1;
taps->size[1] = ixstart;
emxEnsureCapacity_real_T(taps, ix);
for (ix = 0; ix < ixstart; ix++) {
taps->data[taps->size[0] * ix] = r->data[itmp + r->size[0] * ix];
}
emxFree_real_T(&r);
}
/*
* Arguments : int numerator
* int denominator
* Return Type : int
*/
static int div_s32_floor(int numerator, int denominator)
{
int quotient;
unsigned int absNumerator;
unsigned int absDenominator;
boolean_T quotientNeedsNegation;
unsigned int tempAbsQuotient;
if (denominator == 0) {
if (numerator >= 0) {
quotient = MAX_int32_T;
} else {
quotient = MIN_int32_T;
}
} else {
if (numerator < 0) {
absNumerator = ~(unsigned int)numerator + 1U;
} else {
absNumerator = (unsigned int)numerator;
}
if (denominator < 0) {
absDenominator = ~(unsigned int)denominator + 1U;
} else {
absDenominator = (unsigned int)denominator;
}
quotientNeedsNegation = ((numerator < 0) != (denominator < 0));
tempAbsQuotient = absNumerator / absDenominator;
if (quotientNeedsNegation) {
absNumerator %= absDenominator;
if (absNumerator > 0U) {
tempAbsQuotient++;
}
quotient = -(int)tempAbsQuotient;
} else {
quotient = (int)tempAbsQuotient;
}
}
return quotient;
}
/*
* Make b a row
* Arguments : const double b[29]
* const struct_T *options
* creal_T h[2048]
* double w[2048]
* Return Type : void
*/
static void e_firfreqz(const double b[29], const struct_T *options, creal_T h
[2048], double w[2048])
{
int i66;
creal_T dcv5[2048];
double digw;
double b_digw[2048];
double h_re;
double brm;
double d;
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
/* Convert from Hz to rad/sample for computational purposes */
/* Digital frequency must be used for this calculation */
for (i66 = 0; i66 < 2048; i66++) {
w[i66] = options->w[i66];
digw = 6.2831853071795862 * options->w[i66] / options->Fs;
dcv5[i66].re = digw * 0.0;
dcv5[i66].im = digw;
b_digw[i66] = digw;
}
b_exp(dcv5);
d_polyval(b, dcv5, h);
for (i66 = 0; i66 < 2048; i66++) {
dcv5[i66].re = 28.0 * (b_digw[i66] * 0.0);
dcv5[i66].im = 28.0 * b_digw[i66];
}
b_exp(dcv5);
for (i66 = 0; i66 < 2048; i66++) {
h_re = h[i66].re;
if (dcv5[i66].im == 0.0) {
if (h[i66].im == 0.0) {
h[i66].re /= dcv5[i66].re;
h[i66].im = 0.0;
} else if (h[i66].re == 0.0) {
h[i66].re = 0.0;
h[i66].im /= dcv5[i66].re;
} else {
h[i66].re /= dcv5[i66].re;
h[i66].im /= dcv5[i66].re;
}
} else if (dcv5[i66].re == 0.0) {
if (h[i66].re == 0.0) {
h[i66].re = h[i66].im / dcv5[i66].im;
h[i66].im = 0.0;
} else if (h[i66].im == 0.0) {
h[i66].re = 0.0;
h[i66].im = -(h_re / dcv5[i66].im);
} else {
h[i66].re = h[i66].im / dcv5[i66].im;
h[i66].im = -(h_re / dcv5[i66].im);
}
} else {
brm = fabs(dcv5[i66].re);
digw = fabs(dcv5[i66].im);
if (brm > digw) {
digw = dcv5[i66].im / dcv5[i66].re;
d = dcv5[i66].re + digw * dcv5[i66].im;
h[i66].re = (h[i66].re + digw * h[i66].im) / d;
h[i66].im = (h[i66].im - digw * h_re) / d;
} else if (digw == brm) {
if (dcv5[i66].re > 0.0) {
digw = 0.5;
} else {
digw = -0.5;
}
if (dcv5[i66].im > 0.0) {
d = 0.5;
} else {
d = -0.5;
}
h[i66].re = (h[i66].re * digw + h[i66].im * d) / brm;
h[i66].im = (h[i66].im * digw - h_re * d) / brm;
} else {
digw = dcv5[i66].re / dcv5[i66].im;
d = dcv5[i66].im + digw * dcv5[i66].re;
h[i66].re = (digw * h[i66].re + h[i66].im) / d;
h[i66].im = (digw * h[i66].im - h_re) / d;
}
}
}
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[29]
* const double w[2048]
* double Fs
* creal_T hh[2048]
* Return Type : void
*/
static void e_freqz_cg(const double b[29], const double w[2048], double Fs,
creal_T hh[2048])
{
static struct_T options;
int i15;
static const char cv20[8] = { 'o', 'n', 'e', 's', 'i', 'd', 'e', 'd' };
double b_w[2048];
static const char cv21[7] = { 'o', 'm', 'i', 't', 't', 'e', 'd' };
/* Cast to enforce precision rules */
options.Fs = Fs;
memcpy(&options.nfft[0], &w[0], sizeof(double) << 11);
memcpy(&options.w[0], &w[0], sizeof(double) << 11);
/* Remaining are default or for advanced use */
options.fvflag = 1.0;
for (i15 = 0; i15 < 8; i15++) {
options.range[i15] = cv20[i15];
}
options.centerdc = 0.0;
for (i15 = 0; i15 < 7; i15++) {
options.configlevel[i15] = cv21[i15];
}
e_firfreqz(b, &options, hh, b_w);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
}
/*
* Arguments : const double p[13]
* const creal_T x[2048]
* creal_T y[2048]
* Return Type : void
*/
static void e_polyval(const double p[13], const creal_T x[2048],
creal_T y[2048])
{
int i16;
int k;
double x_im;
for (i16 = 0; i16 < 2048; i16++) {
y[i16].re = p[0];
y[i16].im = 0.0;
}
for (k = 0; k < 12; k++) {
for (i16 = 0; i16 < 2048; i16++) {
x_im = x[i16].re * y[i16].im + x[i16].im * y[i16].re;
y[i16].re = (x[i16].re * y[i16].re - x[i16].im * y[i16].im) + p[k + 1];
y[i16].im = x_im;
}
}
}
/*
* Arguments : const double o[7]
* double u[13]
* Return Type : void
*/
static void e_us(const double o[7], double u[13])
{
double b_u[14];
int ix;
int iy;
int k;
memset(&b_u[0], 0, 14U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 7; k++) {
b_u[iy] = o[ix];
ix++;
iy += 2;
}
memcpy(&u[0], &b_u[0], 13U * sizeof(double));
}
/*
* Arguments : const emxArray_creal_T *A
* emxArray_creal_T *V
* Return Type : void
*/
static void eig(const emxArray_creal_T *A, emxArray_creal_T *V)
{
int info;
boolean_T p;
int i;
boolean_T exitg2;
emxArray_creal_T *T;
unsigned int uv0[2];
int exitg1;
double A_re;
double V_re;
double A_im;
double V_im;
boolean_T b_A;
double beta1_re;
double beta1_im;
int m;
double brm;
int istart;
int jend;
if ((A->size[0] == 0) || (A->size[1] == 0)) {
info = V->size[0];
V->size[0] = A->size[0];
emxEnsureCapacity_creal_T1(V, info);
i = A->size[0];
for (info = 0; info < i; info++) {
V->data[info].re = 0.0;
V->data[info].im = 0.0;
}
} else if (anyNonFinite(A)) {
if ((A->size[0] == 1) && (A->size[1] == 1)) {
info = V->size[0];
V->size[0] = 1;
emxEnsureCapacity_creal_T1(V, info);
V->data[0].re = rtNaN;
V->data[0].im = 0.0;
} else {
info = V->size[0];
V->size[0] = A->size[0];
emxEnsureCapacity_creal_T1(V, info);
i = A->size[0];
for (info = 0; info < i; info++) {
V->data[info].re = rtNaN;
V->data[info].im = 0.0;
}
}
} else if ((A->size[0] == 1) && (A->size[1] == 1)) {
info = V->size[0];
V->size[0] = 1;
emxEnsureCapacity_creal_T1(V, info);
V->data[0] = A->data[0];
} else {
p = (A->size[0] == A->size[1]);
if (p) {
info = 0;
exitg2 = false;
while ((!exitg2) && (info <= A->size[1] - 1)) {
i = 0;
do {
exitg1 = 0;
if (i <= info) {
A_re = A->data[info + A->size[0] * i].re;
A_im = -A->data[info + A->size[0] * i].im;
b_A = ((A->data[i + A->size[0] * info].re == A_re) && (A->data[i +
A->size[0] * info].im == A_im));
if (!b_A) {
p = false;
exitg1 = 1;
} else {
i++;
}
} else {
info++;
exitg1 = 2;
}
} while (exitg1 == 0);
if (exitg1 == 1) {
exitg2 = true;
}
}
}
if (p) {
emxInit_creal_T(&T, 2);
if (anyNonFinite(A)) {
for (info = 0; info < 2; info++) {
uv0[info] = (unsigned int)A->size[info];
}
info = T->size[0] * T->size[1];
T->size[0] = (int)uv0[0];
T->size[1] = (int)uv0[1];
emxEnsureCapacity_creal_T(T, info);
i = (int)uv0[0] * (int)uv0[1];
for (info = 0; info < i; info++) {
T->data[info].re = rtNaN;
T->data[info].im = 0.0;
}
m = T->size[0];
if (!(1 >= T->size[0])) {
istart = 2;
if (T->size[0] - 2 < T->size[1] - 1) {
jend = T->size[0] - 1;
} else {
jend = T->size[1];
}
for (info = 1; info <= jend; info++) {
for (i = istart; i <= m; i++) {
T->data[(i + T->size[0] * (info - 1)) - 1].re = 0.0;
T->data[(i + T->size[0] * (info - 1)) - 1].im = 0.0;
}
istart++;
}
}
} else {
info = T->size[0] * T->size[1];
T->size[0] = A->size[0];
T->size[1] = A->size[1];
emxEnsureCapacity_creal_T(T, info);
i = A->size[0] * A->size[1];
for (info = 0; info < i; info++) {
T->data[info] = A->data[info];
}
xgehrd(T);
eml_zlahqr(T);
m = T->size[0];
if ((T->size[0] == 0) || (T->size[1] == 0) || (3 >= T->size[0])) {
} else {
istart = 4;
if (T->size[0] - 4 < T->size[1] - 1) {
jend = T->size[0] - 3;
} else {
jend = T->size[1];
}
for (info = 1; info <= jend; info++) {
for (i = istart; i <= m; i++) {
T->data[(i + T->size[0] * (info - 1)) - 1].re = 0.0;
T->data[(i + T->size[0] * (info - 1)) - 1].im = 0.0;
}
istart++;
}
}
}
info = V->size[0];
V->size[0] = T->size[0];
emxEnsureCapacity_creal_T1(V, info);
for (info = 0; info + 1 <= T->size[0]; info++) {
V->data[info] = T->data[info + T->size[0] * info];
}
emxFree_creal_T(&T);
} else {
emxInit_creal_T1(&T, 1);
xzgeev(A, &info, V, T);
info = V->size[0];
emxEnsureCapacity_creal_T1(V, info);
i = V->size[0];
for (info = 0; info < i; info++) {
V_re = V->data[info].re;
V_im = V->data[info].im;
beta1_re = T->data[info].re;
beta1_im = T->data[info].im;
if (beta1_im == 0.0) {
if (V_im == 0.0) {
V->data[info].re = V_re / beta1_re;
V->data[info].im = 0.0;
} else if (V_re == 0.0) {
V->data[info].re = 0.0;
V->data[info].im = V_im / beta1_re;
} else {
V->data[info].re = V_re / beta1_re;
V->data[info].im = V_im / beta1_re;
}
} else if (beta1_re == 0.0) {
if (V_re == 0.0) {
V->data[info].re = V_im / beta1_im;
V->data[info].im = 0.0;
} else if (V_im == 0.0) {
V->data[info].re = 0.0;
V->data[info].im = -(V_re / beta1_im);
} else {
V->data[info].re = V_im / beta1_im;
V->data[info].im = -(V_re / beta1_im);
}
} else {
brm = fabs(beta1_re);
A_re = fabs(beta1_im);
if (brm > A_re) {
A_im = beta1_im / beta1_re;
A_re = beta1_re + A_im * beta1_im;
V->data[info].re = (V_re + A_im * V_im) / A_re;
V->data[info].im = (V_im - A_im * V_re) / A_re;
} else if (A_re == brm) {
if (beta1_re > 0.0) {
A_im = 0.5;
} else {
A_im = -0.5;
}
if (beta1_im > 0.0) {
A_re = 0.5;
} else {
A_re = -0.5;
}
V->data[info].re = (V_re * A_im + V_im * A_re) / brm;
V->data[info].im = (V_im * A_im - V_re * A_re) / brm;
} else {
A_im = beta1_re / beta1_im;
A_re = beta1_im + A_im * beta1_re;
V->data[info].re = (A_im * V_re + V_im) / A_re;
V->data[info].im = (A_im * V_im - V_re) / A_re;
}
}
}
emxFree_creal_T(&T);
}
}
}
/*
* Arguments : emxArray_creal_T *h
* Return Type : int
*/
static int eml_zlahqr(emxArray_creal_T *h)
{
int info;
int n;
int maxval;
int itmax;
int ldh;
int i;
double SMLNUM;
double tst;
boolean_T exitg1;
double aa;
double ba;
int L;
creal_T u2;
boolean_T goto140;
int its;
boolean_T exitg2;
int k;
boolean_T exitg3;
double htmp1;
creal_T y;
double ab;
boolean_T goto70;
int m;
double x_re;
double u_re;
double x_im;
double u_im;
double s;
int b_k;
creal_T v[2];
double b_SMLNUM;
int i61;
n = h->size[0];
if (h->size[0] < 10) {
maxval = 10;
} else {
maxval = h->size[0];
}
itmax = 30 * maxval;
ldh = h->size[0];
info = 0;
if ((h->size[0] != 0) && (1 != h->size[0])) {
for (maxval = 0; maxval + 1 <= n - 3; maxval++) {
h->data[(maxval + h->size[0] * maxval) + 2].re = 0.0;
h->data[(maxval + h->size[0] * maxval) + 2].im = 0.0;
h->data[(maxval + h->size[0] * maxval) + 3].re = 0.0;
h->data[(maxval + h->size[0] * maxval) + 3].im = 0.0;
}
if (1 <= n - 2) {
h->data[(n + h->size[0] * (n - 3)) - 1].re = 0.0;
h->data[(n + h->size[0] * (n - 3)) - 1].im = 0.0;
}
for (i = 1; i + 1 <= n; i++) {
if (h->data[i + h->size[0] * (i - 1)].im != 0.0) {
tst = h->data[i + h->size[0] * (i - 1)].re;
aa = h->data[i + h->size[0] * (i - 1)].im;
ba = fabs(h->data[i + h->size[0] * (i - 1)].re) + fabs(h->data[i +
h->size[0] * (i - 1)].im);
if (aa == 0.0) {
u2.re = tst / ba;
u2.im = 0.0;
} else if (tst == 0.0) {
u2.re = 0.0;
u2.im = aa / ba;
} else {
u2.re = tst / ba;
u2.im = aa / ba;
}
ba = rt_hypotd_snf(u2.re, u2.im);
if (-u2.im == 0.0) {
u2.re /= ba;
u2.im = 0.0;
} else if (u2.re == 0.0) {
u2.re = 0.0;
u2.im = -u2.im / ba;
} else {
u2.re /= ba;
u2.im = -u2.im / ba;
}
tst = h->data[i + h->size[0] * (i - 1)].re;
htmp1 = h->data[i + h->size[0] * (i - 1)].im;
h->data[i + h->size[0] * (i - 1)].re = rt_hypotd_snf(tst, htmp1);
h->data[i + h->size[0] * (i - 1)].im = 0.0;
b_xscal(n - i, u2, h, (i + i * ldh) + 1, ldh);
y.re = u2.re;
y.im = -u2.im;
maxval = i + 2;
if (n < maxval) {
maxval = n;
}
xscal(maxval, y, h, 1 + i * ldh);
}
}
SMLNUM = 2.2250738585072014E-308 * ((double)n / 2.2204460492503131E-16);
i = n - 1;
exitg1 = false;
while ((!exitg1) && (i + 1 >= 1)) {
L = -1;
goto140 = false;
its = 0;
exitg2 = false;
while ((!exitg2) && (its <= itmax)) {
k = i;
exitg3 = false;
while ((!exitg3) && ((k + 1 > L + 2) && (!(fabs(h->data[k + h->size[0] *
(k - 1)].re) + fabs(h->data[k + h->size[0] * (k - 1)].im) <=
SMLNUM)))) {
tst = (fabs(h->data[(k + h->size[0] * (k - 1)) - 1].re) + fabs(h->
data[(k + h->size[0] * (k - 1)) - 1].im)) + (fabs(h->data[k +
h->size[0] * k].re) + fabs(h->data[k + h->size[0] * k].im));
if (tst == 0.0) {
if (k - 1 >= 1) {
tst = fabs(h->data[(k + h->size[0] * (k - 2)) - 1].re);
}
if (k + 2 <= n) {
tst += fabs(h->data[(k + h->size[0] * k) + 1].re);
}
}
if (fabs(h->data[k + h->size[0] * (k - 1)].re) <=
2.2204460492503131E-16 * tst) {
htmp1 = fabs(h->data[k + h->size[0] * (k - 1)].re) + fabs(h->data[k
+ h->size[0] * (k - 1)].im);
tst = fabs(h->data[(k + h->size[0] * k) - 1].re) + fabs(h->data[(k +
h->size[0] * k) - 1].im);
if (htmp1 > tst) {
ab = htmp1;
ba = tst;
} else {
ab = tst;
ba = htmp1;
}
htmp1 = fabs(h->data[k + h->size[0] * k].re) + fabs(h->data[k +
h->size[0] * k].im);
x_re = h->data[(k + h->size[0] * (k - 1)) - 1].re - h->data[k +
h->size[0] * k].re;
x_im = h->data[(k + h->size[0] * (k - 1)) - 1].im - h->data[k +
h->size[0] * k].im;
tst = fabs(x_re) + fabs(x_im);
if (htmp1 > tst) {
aa = htmp1;
htmp1 = tst;
} else {
aa = tst;
}
s = aa + ab;
tst = 2.2204460492503131E-16 * (htmp1 * (aa / s));
if ((SMLNUM > tst) || rtIsNaN(tst)) {
b_SMLNUM = SMLNUM;
} else {
b_SMLNUM = tst;
}
if (ba * (ab / s) <= b_SMLNUM) {
exitg3 = true;
} else {
k--;
}
} else {
k--;
}
}
L = k - 1;
if (k + 1 > 1) {
h->data[k + h->size[0] * (k - 1)].re = 0.0;
h->data[k + h->size[0] * (k - 1)].im = 0.0;
}
if (k + 1 >= i + 1) {
goto140 = true;
exitg2 = true;
} else {
if (its == 10) {
ba = 0.75 * fabs(h->data[(k + h->size[0] * k) + 1].re) + h->data[k +
h->size[0] * k].re;
ab = h->data[k + h->size[0] * k].im;
} else if (its == 20) {
ba = 0.75 * fabs(h->data[i + h->size[0] * (i - 1)].re) + h->data[i +
h->size[0] * i].re;
ab = h->data[i + h->size[0] * i].im;
} else {
ba = h->data[i + h->size[0] * i].re;
ab = h->data[i + h->size[0] * i].im;
y = h->data[(i + h->size[0] * i) - 1];
c_sqrt(&y);
u2 = h->data[i + h->size[0] * (i - 1)];
c_sqrt(&u2);
u_re = y.re * u2.re - y.im * u2.im;
u_im = y.re * u2.im + y.im * u2.re;
s = fabs(u_re) + fabs(u_im);
if (s != 0.0) {
tst = h->data[(i + h->size[0] * (i - 1)) - 1].re - h->data[i +
h->size[0] * i].re;
htmp1 = h->data[(i + h->size[0] * (i - 1)) - 1].im - h->data[i +
h->size[0] * i].im;
x_re = 0.5 * tst;
x_im = 0.5 * htmp1;
aa = fabs(x_re) + fabs(x_im);
tst = fabs(x_re) + fabs(x_im);
if (!((s > tst) || rtIsNaN(tst))) {
s = tst;
}
if (x_im == 0.0) {
ba = x_re / s;
ab = 0.0;
} else if (x_re == 0.0) {
ba = 0.0;
ab = x_im / s;
} else {
ba = x_re / s;
ab = x_im / s;
}
tst = ba;
ba = ba * ba - ab * ab;
ab = tst * ab + ab * tst;
if (u_im == 0.0) {
u2.re = u_re / s;
u2.im = 0.0;
} else if (u_re == 0.0) {
u2.re = 0.0;
u2.im = u_im / s;
} else {
u2.re = u_re / s;
u2.im = u_im / s;
}
y.re = ba + (u2.re * u2.re - u2.im * u2.im);
y.im = ab + (u2.re * u2.im + u2.im * u2.re);
c_sqrt(&y);
y.re *= s;
y.im *= s;
if (aa > 0.0) {
if (x_im == 0.0) {
ba = x_re / aa;
ab = 0.0;
} else if (x_re == 0.0) {
ba = 0.0;
ab = x_im / aa;
} else {
ba = x_re / aa;
ab = x_im / aa;
}
if (ba * y.re + ab * y.im < 0.0) {
y.re = -y.re;
y.im = -y.im;
}
}
ba = x_re + y.re;
htmp1 = x_im + y.im;
if (htmp1 == 0.0) {
if (u_im == 0.0) {
x_re = u_re / ba;
tst = 0.0;
} else if (u_re == 0.0) {
x_re = 0.0;
tst = u_im / ba;
} else {
x_re = u_re / ba;
tst = u_im / ba;
}
} else if (ba == 0.0) {
if (u_re == 0.0) {
x_re = u_im / htmp1;
tst = 0.0;
} else if (u_im == 0.0) {
x_re = 0.0;
tst = -(u_re / htmp1);
} else {
x_re = u_im / htmp1;
tst = -(u_re / htmp1);
}
} else {
ab = fabs(ba);
tst = fabs(htmp1);
if (ab > tst) {
s = htmp1 / ba;
tst = ba + s * htmp1;
x_re = (u_re + s * u_im) / tst;
tst = (u_im - s * u_re) / tst;
} else if (tst == ab) {
if (ba > 0.0) {
aa = 0.5;
} else {
aa = -0.5;
}
if (htmp1 > 0.0) {
tst = 0.5;
} else {
tst = -0.5;
}
x_re = (u_re * aa + u_im * tst) / ab;
tst = (u_im * aa - u_re * tst) / ab;
} else {
s = ba / htmp1;
tst = htmp1 + s * ba;
x_re = (s * u_re + u_im) / tst;
tst = (s * u_im - u_re) / tst;
}
}
ba = h->data[i + h->size[0] * i].re - (u_re * x_re - u_im * tst);
ab = h->data[i + h->size[0] * i].im - (u_re * tst + u_im * x_re);
}
}
goto70 = false;
m = i;
exitg3 = false;
while ((!exitg3) && (m > k + 1)) {
u2.re = h->data[(m + h->size[0] * (m - 1)) - 1].re - ba;
u2.im = h->data[(m + h->size[0] * (m - 1)) - 1].im - ab;
tst = h->data[m + h->size[0] * (m - 1)].re;
s = (fabs(u2.re) + fabs(u2.im)) + fabs(tst);
if (u2.im == 0.0) {
u2.re /= s;
u2.im = 0.0;
} else if (u2.re == 0.0) {
u2.re = 0.0;
u2.im /= s;
} else {
u2.re /= s;
u2.im /= s;
}
tst /= s;
v[0] = u2;
v[1].re = tst;
v[1].im = 0.0;
if (fabs(h->data[(m + h->size[0] * (m - 2)) - 1].re) * fabs(tst) <=
2.2204460492503131E-16 * ((fabs(u2.re) + fabs(u2.im)) * ((fabs
(h->data[(m + h->size[0] * (m - 1)) - 1].re) + fabs(h->data
[(m + h->size[0] * (m - 1)) - 1].im)) + (fabs(h->data[m +
h->size[0] * m].re) + fabs(h->data[m + h->size[0] * m].im))))) {
goto70 = true;
exitg3 = true;
} else {
m--;
}
}
if (!goto70) {
u2.re = h->data[k + h->size[0] * k].re - ba;
u2.im = h->data[k + h->size[0] * k].im - ab;
tst = h->data[(k + h->size[0] * k) + 1].re;
s = (fabs(u2.re) + fabs(u2.im)) + fabs(tst);
if (u2.im == 0.0) {
u2.re /= s;
u2.im = 0.0;
} else if (u2.re == 0.0) {
u2.re = 0.0;
u2.im /= s;
} else {
u2.re /= s;
u2.im /= s;
}
tst /= s;
v[0] = u2;
v[1].re = tst;
v[1].im = 0.0;
}
for (b_k = m; b_k <= i; b_k++) {
if (b_k > m) {
v[0] = h->data[(b_k + h->size[0] * (b_k - 2)) - 1];
v[1] = h->data[b_k + h->size[0] * (b_k - 2)];
}
u2 = xzlarfg(&v[0], &v[1]);
if (b_k > m) {
h->data[(b_k + h->size[0] * (b_k - 2)) - 1] = v[0];
h->data[b_k + h->size[0] * (b_k - 2)].re = 0.0;
h->data[b_k + h->size[0] * (b_k - 2)].im = 0.0;
}
htmp1 = u2.re * v[1].re - u2.im * v[1].im;
for (maxval = b_k - 1; maxval + 1 <= n; maxval++) {
tst = u2.re * h->data[(b_k + h->size[0] * maxval) - 1].re - -u2.im
* h->data[(b_k + h->size[0] * maxval) - 1].im;
aa = u2.re * h->data[(b_k + h->size[0] * maxval) - 1].im + -u2.im *
h->data[(b_k + h->size[0] * maxval) - 1].re;
ba = tst + htmp1 * h->data[b_k + h->size[0] * maxval].re;
ab = aa + htmp1 * h->data[b_k + h->size[0] * maxval].im;
h->data[(b_k + h->size[0] * maxval) - 1].re -= ba;
h->data[(b_k + h->size[0] * maxval) - 1].im -= ab;
h->data[b_k + h->size[0] * maxval].re -= ba * v[1].re - ab * v[1].
im;
h->data[b_k + h->size[0] * maxval].im -= ba * v[1].im + ab * v[1].
re;
}
if (b_k + 2 < i + 1) {
i61 = b_k;
} else {
i61 = i - 1;
}
for (maxval = 0; maxval + 1 <= i61 + 2; maxval++) {
tst = u2.re * h->data[maxval + h->size[0] * (b_k - 1)].re - u2.im *
h->data[maxval + h->size[0] * (b_k - 1)].im;
aa = u2.re * h->data[maxval + h->size[0] * (b_k - 1)].im + u2.im *
h->data[maxval + h->size[0] * (b_k - 1)].re;
ba = tst + htmp1 * h->data[maxval + h->size[0] * b_k].re;
ab = aa + htmp1 * h->data[maxval + h->size[0] * b_k].im;
h->data[maxval + h->size[0] * (b_k - 1)].re -= ba;
h->data[maxval + h->size[0] * (b_k - 1)].im -= ab;
h->data[maxval + h->size[0] * b_k].re -= ba * v[1].re - ab * -v[1]
.im;
h->data[maxval + h->size[0] * b_k].im -= ba * -v[1].im + ab * v[1]
.re;
}
if ((b_k == m) && (m > k + 1)) {
u2.re = 1.0 - u2.re;
u2.im = 0.0 - u2.im;
ba = rt_hypotd_snf(u2.re, u2.im);
if (u2.im == 0.0) {
u2.re /= ba;
u2.im = 0.0;
} else if (u2.re == 0.0) {
u2.re = 0.0;
u2.im /= ba;
} else {
u2.re /= ba;
u2.im /= ba;
}
tst = h->data[m + h->size[0] * (m - 1)].re;
htmp1 = h->data[m + h->size[0] * (m - 1)].im;
h->data[m + h->size[0] * (m - 1)].re = tst * u2.re - htmp1 *
-u2.im;
h->data[m + h->size[0] * (m - 1)].im = tst * -u2.im + htmp1 *
u2.re;
if (m + 2 <= i + 1) {
tst = h->data[(m + h->size[0] * m) + 1].re;
htmp1 = h->data[(m + h->size[0] * m) + 1].im;
h->data[(m + h->size[0] * m) + 1].re = tst * u2.re - htmp1 *
u2.im;
h->data[(m + h->size[0] * m) + 1].im = tst * u2.im + htmp1 *
u2.re;
}
for (maxval = m; maxval <= i + 1; maxval++) {
if (maxval != m + 1) {
if (n > maxval) {
b_xscal(n - maxval, u2, h, maxval + maxval * ldh, ldh);
}
y.re = u2.re;
y.im = -u2.im;
xscal(maxval - 1, y, h, 1 + (maxval - 1) * ldh);
}
}
}
}
u2 = h->data[i + h->size[0] * (i - 1)];
if (h->data[i + h->size[0] * (i - 1)].im != 0.0) {
tst = rt_hypotd_snf(h->data[i + h->size[0] * (i - 1)].re, h->data[i
+ h->size[0] * (i - 1)].im);
h->data[i + h->size[0] * (i - 1)].re = tst;
h->data[i + h->size[0] * (i - 1)].im = 0.0;
if (u2.im == 0.0) {
u2.re /= tst;
u2.im = 0.0;
} else if (u2.re == 0.0) {
u2.re = 0.0;
u2.im /= tst;
} else {
u2.re /= tst;
u2.im /= tst;
}
if (n > i + 1) {
y.re = u2.re;
y.im = -u2.im;
b_xscal((n - i) - 1, y, h, (i + (i + 1) * ldh) + 1, ldh);
}
xscal(i, u2, h, 1 + i * ldh);
}
its++;
}
}
if (!goto140) {
info = i + 1;
exitg1 = true;
} else {
i = L;
}
}
}
return info;
}
/*
* Make b a row
* Arguments : const double b[13]
* const struct_T *options
* creal_T h[2048]
* double w[2048]
* Return Type : void
*/
static void f_firfreqz(const double b[13], const struct_T *options, creal_T h
[2048], double w[2048])
{
int i67;
creal_T dcv6[2048];
double digw;
double b_digw[2048];
double h_re;
double brm;
double d;
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
/* Convert from Hz to rad/sample for computational purposes */
/* Digital frequency must be used for this calculation */
for (i67 = 0; i67 < 2048; i67++) {
w[i67] = options->w[i67];
digw = 6.2831853071795862 * options->w[i67] / options->Fs;
dcv6[i67].re = digw * 0.0;
dcv6[i67].im = digw;
b_digw[i67] = digw;
}
b_exp(dcv6);
e_polyval(b, dcv6, h);
for (i67 = 0; i67 < 2048; i67++) {
dcv6[i67].re = 12.0 * (b_digw[i67] * 0.0);
dcv6[i67].im = 12.0 * b_digw[i67];
}
b_exp(dcv6);
for (i67 = 0; i67 < 2048; i67++) {
h_re = h[i67].re;
if (dcv6[i67].im == 0.0) {
if (h[i67].im == 0.0) {
h[i67].re /= dcv6[i67].re;
h[i67].im = 0.0;
} else if (h[i67].re == 0.0) {
h[i67].re = 0.0;
h[i67].im /= dcv6[i67].re;
} else {
h[i67].re /= dcv6[i67].re;
h[i67].im /= dcv6[i67].re;
}
} else if (dcv6[i67].re == 0.0) {
if (h[i67].re == 0.0) {
h[i67].re = h[i67].im / dcv6[i67].im;
h[i67].im = 0.0;
} else if (h[i67].im == 0.0) {
h[i67].re = 0.0;
h[i67].im = -(h_re / dcv6[i67].im);
} else {
h[i67].re = h[i67].im / dcv6[i67].im;
h[i67].im = -(h_re / dcv6[i67].im);
}
} else {
brm = fabs(dcv6[i67].re);
digw = fabs(dcv6[i67].im);
if (brm > digw) {
digw = dcv6[i67].im / dcv6[i67].re;
d = dcv6[i67].re + digw * dcv6[i67].im;
h[i67].re = (h[i67].re + digw * h[i67].im) / d;
h[i67].im = (h[i67].im - digw * h_re) / d;
} else if (digw == brm) {
if (dcv6[i67].re > 0.0) {
digw = 0.5;
} else {
digw = -0.5;
}
if (dcv6[i67].im > 0.0) {
d = 0.5;
} else {
d = -0.5;
}
h[i67].re = (h[i67].re * digw + h[i67].im * d) / brm;
h[i67].im = (h[i67].im * digw - h_re * d) / brm;
} else {
digw = dcv6[i67].re / dcv6[i67].im;
d = dcv6[i67].im + digw * dcv6[i67].re;
h[i67].re = (digw * h[i67].re + h[i67].im) / d;
h[i67].im = (digw * h[i67].im - h_re) / d;
}
}
}
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[13]
* const double w[2048]
* double Fs
* creal_T hh[2048]
* Return Type : void
*/
static void f_freqz_cg(const double b[13], const double w[2048], double Fs,
creal_T hh[2048])
{
static struct_T options;
int i17;
static const char cv22[8] = { 'o', 'n', 'e', 's', 'i', 'd', 'e', 'd' };
double b_w[2048];
static const char cv23[7] = { 'o', 'm', 'i', 't', 't', 'e', 'd' };
/* Cast to enforce precision rules */
options.Fs = Fs;
memcpy(&options.nfft[0], &w[0], sizeof(double) << 11);
memcpy(&options.w[0], &w[0], sizeof(double) << 11);
/* Remaining are default or for advanced use */
options.fvflag = 1.0;
for (i17 = 0; i17 < 8; i17++) {
options.range[i17] = cv22[i17];
}
options.centerdc = 0.0;
for (i17 = 0; i17 < 7; i17++) {
options.configlevel[i17] = cv23[i17];
}
f_firfreqz(b, &options, hh, b_w);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
}
/*
* Arguments : const double p[57]
* const creal_T x[2048]
* creal_T y[2048]
* Return Type : void
*/
static void f_polyval(const double p[57], const creal_T x[2048],
creal_T y[2048])
{
int i18;
int k;
double x_im;
for (i18 = 0; i18 < 2048; i18++) {
y[i18].re = p[0];
y[i18].im = 0.0;
}
for (k = 0; k < 56; k++) {
for (i18 = 0; i18 < 2048; i18++) {
x_im = x[i18].re * y[i18].im + x[i18].im * y[i18].re;
y[i18].re = (x[i18].re * y[i18].re - x[i18].im * y[i18].im) + p[k + 1];
y[i18].im = x_im;
}
}
}
/*
* Arguments : const double o[15]
* double u[57]
* Return Type : void
*/
static void f_us(const double o[15], double u[57])
{
double b_u[60];
int ix;
int iy;
int k;
memset(&b_u[0], 0, 60U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 15; k++) {
b_u[iy] = o[ix];
ix++;
iy += 4;
}
memcpy(&u[0], &b_u[0], 57U * sizeof(double));
}
/*
* Make b a row
* Arguments : const struct_T *options
* creal_T h[2048]
* double w[2048]
* Return Type : void
*/
static void firfreqz(const struct_T *options, creal_T h[2048], double w[2048])
{
int i63;
double brm;
double bim;
double d;
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
/* Convert from Hz to rad/sample for computational purposes */
/* Digital frequency must be used for this calculation */
for (i63 = 0; i63 < 2048; i63++) {
w[i63] = options->w[i63];
h[i63].re = 0.0 * (6.2831853071795862 * options->w[i63] / options->Fs * 0.0);
h[i63].im = 0.0 * (6.2831853071795862 * options->w[i63] / options->Fs);
}
b_exp(h);
for (i63 = 0; i63 < 2048; i63++) {
if (h[i63].im == 0.0) {
h[i63].re = 1.0 / h[i63].re;
h[i63].im = 0.0;
} else if (h[i63].re == 0.0) {
h[i63].re = 0.0;
h[i63].im = -(1.0 / h[i63].im);
} else {
brm = fabs(h[i63].re);
bim = fabs(h[i63].im);
if (brm > bim) {
bim = h[i63].im / h[i63].re;
d = h[i63].re + bim * h[i63].im;
h[i63].re = (1.0 + bim * 0.0) / d;
h[i63].im = (0.0 - bim) / d;
} else if (bim == brm) {
if (h[i63].re > 0.0) {
bim = 0.5;
} else {
bim = -0.5;
}
if (h[i63].im > 0.0) {
d = 0.5;
} else {
d = -0.5;
}
h[i63].re = (bim + 0.0 * d) / brm;
h[i63].im = (0.0 * bim - d) / brm;
} else {
bim = h[i63].re / h[i63].im;
d = h[i63].im + bim * h[i63].re;
h[i63].re = bim / d;
h[i63].im = (bim * 0.0 - 1.0) / d;
}
}
}
}
/*
* FIRPM Parks-McClellan optimal equiripple FIR filter design.
*
* This function is based on 'firpm' by The MathWorks Inc.
* Arguments : double order
* const double ff[4]
* const emxArray_real_T *amplitudes
* const emxArray_real_T *frequencies
* const emxArray_real_T *weights
* emxArray_real_T *h
* Return Type : void
*/
static void firpm_cg(double order, const double ff[4], const emxArray_real_T
*amplitudes, const emxArray_real_T *frequencies, const
emxArray_real_T *weights, emxArray_real_T *h)
{
emxArray_real_T *grid;
emxArray_real_T *des;
emxArray_real_T *wt;
emxArray_real_T *b_h;
int i41;
emxArray_real_T *c_h;
double b_ff[4];
double err;
boolean_T valid;
int h_idx_0;
int i42;
int i43;
int loop_ub;
emxInit_real_T(&grid, 2);
emxInit_real_T(&des, 2);
emxInit_real_T(&wt, 2);
emxInit_real_T(&b_h, 2);
/* */
firpmgrid_cg(order + 1.0, ff, grid);
/* orgFreqIndx = frequencies; */
/* */
/* positionsOfNewFreqIndx = zeros(size(grid)); */
/* for ind = 1:length(positionsOfNewFreqIndx) */
/* */
/* [~,indx] = min( abs(orgFreqIndx-grid(ind)) ); */
/* */
/* positionsOfNewFreqIndx(ind) = indx; */
/* end */
/* */
/* wt = weights(positionsOfNewFreqIndx); */
/* des = amplitudes(positionsOfNewFreqIndx); */
interp1(frequencies, amplitudes, grid, des);
interp1(frequencies, weights, grid, wt);
/* Workaround */
/* ftype = 2; */
/* sign_val = 1; */
/* Always bandpass designs */
/* cast to enforce precision rules */
/* Call actual design algorithm */
rdivide(grid, 2.0, b_h);
emxFree_real_T(&grid);
for (i41 = 0; i41 < 4; i41++) {
b_ff[i41] = ff[i41] / 2.0;
}
emxInit_real_T(&c_h, 2);
remezm(order + 1.0, b_ff, b_h, des, wt, c_h, &err, &valid);
h_idx_0 = c_h->size[0] * c_h->size[1];
i41 = h->size[0] * h->size[1];
h->size[0] = 1;
h->size[1] = h_idx_0;
emxEnsureCapacity_real_T(h, i41);
emxFree_real_T(&wt);
emxFree_real_T(&des);
for (i41 = 0; i41 < h_idx_0; i41++) {
h->data[h->size[0] * i41] = c_h->data[i41];
}
emxFree_real_T(&c_h);
/* make it a row */
err = (double)h->size[1] - rt_remd_snf(order + 1.0, 2.0);
if (1.0 > err) {
i41 = 1;
h_idx_0 = 1;
i42 = 0;
} else {
i41 = (int)err;
h_idx_0 = -1;
i42 = 1;
}
i43 = b_h->size[0] * b_h->size[1];
b_h->size[0] = 1;
b_h->size[1] = (h->size[1] + div_s32_floor(i42 - i41, h_idx_0)) + 1;
emxEnsureCapacity_real_T(b_h, i43);
loop_ub = h->size[1];
for (i43 = 0; i43 < loop_ub; i43++) {
b_h->data[b_h->size[0] * i43] = h->data[h->size[0] * i43];
}
loop_ub = div_s32_floor(i42 - i41, h_idx_0);
for (i42 = 0; i42 <= loop_ub; i42++) {
b_h->data[b_h->size[0] * (i42 + h->size[1])] = h->data[(i41 + h_idx_0 * i42)
- 1];
}
i41 = h->size[0] * h->size[1];
h->size[0] = 1;
h->size[1] = b_h->size[1];
emxEnsureCapacity_real_T(h, i41);
loop_ub = b_h->size[1];
for (i41 = 0; i41 < loop_ub; i41++) {
h->data[h->size[0] * i41] = b_h->data[b_h->size[0] * i41];
}
if (1 > h->size[1]) {
i41 = 1;
h_idx_0 = 1;
i42 = 0;
} else {
i41 = h->size[1];
h_idx_0 = -1;
i42 = 1;
}
i43 = b_h->size[0] * b_h->size[1];
b_h->size[0] = 1;
b_h->size[1] = div_s32_floor(i42 - i41, h_idx_0) + 1;
emxEnsureCapacity_real_T(b_h, i43);
loop_ub = div_s32_floor(i42 - i41, h_idx_0);
for (i42 = 0; i42 <= loop_ub; i42++) {
b_h->data[b_h->size[0] * i42] = h->data[(i41 + h_idx_0 * i42) - 1];
}
i41 = h->size[0] * h->size[1];
h->size[0] = 1;
h->size[1] = b_h->size[1];
emxEnsureCapacity_real_T(h, i41);
loop_ub = b_h->size[1];
for (i41 = 0; i41 < loop_ub; i41++) {
h->data[h->size[0] * i41] = b_h->data[b_h->size[0] * i41];
}
emxFree_real_T(&b_h);
}
/*
* firpmgrid
* Arguments : double nfilt
* const double ff[4]
* emxArray_real_T *gridactual
* Return Type : void
*/
static void firpmgrid_cg(double nfilt, const double ff[4], emxArray_real_T
*gridactual)
{
static double grid[100000];
double ngrid;
double b_ngrid;
double delf;
double j;
double l;
double gridSize;
emxArray_real_T *newgrid;
emxArray_int32_T *r20;
double a;
int k;
int nm1d2;
double ndbl;
double apnd;
double cdiff;
double delf1;
double absa;
double absb;
int n;
/* -------------------------------------------------------------------------- */
memset(&grid[0], 0, 100000U * sizeof(double));
/* Make large initial memory */
/* Generate frequency grid */
ngrid = nfilt / 2.0;
grid[0] = ff[0];
if (ngrid < 0.0) {
b_ngrid = ceil(ngrid);
} else {
b_ngrid = floor(ngrid);
}
delf = 1.0 / (16.0 * b_ngrid);
/* If value at frequency 0 is constrained, make sure first grid point */
/* is not too small: */
j = 1.0;
l = 1.0;
gridSize = 1.0;
emxInit_real_T(&newgrid, 2);
emxInit_int32_T(&r20, 2);
while (l + 1.0 <= 4.0) {
a = grid[(int)j - 1] + delf;
ngrid = ff[(int)(l + 1.0) - 1] + delf;
if (rtIsNaN(a) || rtIsNaN(delf) || rtIsNaN(ngrid)) {
k = newgrid->size[0] * newgrid->size[1];
newgrid->size[0] = 1;
newgrid->size[1] = 1;
emxEnsureCapacity_real_T(newgrid, k);
newgrid->data[0] = rtNaN;
} else if ((delf == 0.0) || ((a < ngrid) && (delf < 0.0)) || ((ngrid < a) &&
(delf > 0.0))) {
k = newgrid->size[0] * newgrid->size[1];
newgrid->size[0] = 1;
newgrid->size[1] = 0;
emxEnsureCapacity_real_T(newgrid, k);
} else if ((rtIsInf(a) || rtIsInf(ngrid)) && (rtIsInf(delf) || (a == ngrid))) {
k = newgrid->size[0] * newgrid->size[1];
newgrid->size[0] = 1;
newgrid->size[1] = 1;
emxEnsureCapacity_real_T(newgrid, k);
newgrid->data[0] = rtNaN;
} else if (rtIsInf(delf)) {
k = newgrid->size[0] * newgrid->size[1];
newgrid->size[0] = 1;
newgrid->size[1] = 1;
emxEnsureCapacity_real_T(newgrid, k);
newgrid->data[0] = a;
} else if ((floor(a) == a) && (floor(delf) == delf)) {
k = newgrid->size[0] * newgrid->size[1];
newgrid->size[0] = 1;
newgrid->size[1] = (int)floor((ngrid - a) / delf) + 1;
emxEnsureCapacity_real_T(newgrid, k);
nm1d2 = (int)floor((ngrid - a) / delf);
for (k = 0; k <= nm1d2; k++) {
newgrid->data[newgrid->size[0] * k] = a + delf * (double)k;
}
} else {
ndbl = floor((ngrid - a) / delf + 0.5);
apnd = a + ndbl * delf;
if (delf > 0.0) {
cdiff = apnd - ngrid;
} else {
cdiff = ngrid - apnd;
}
absa = fabs(a);
absb = fabs(ngrid);
if ((absa > absb) || rtIsNaN(absb)) {
absb = absa;
}
if (fabs(cdiff) < 4.4408920985006262E-16 * absb) {
ndbl++;
apnd = ngrid;
} else if (cdiff > 0.0) {
apnd = a + (ndbl - 1.0) * delf;
} else {
ndbl++;
}
if (ndbl >= 0.0) {
n = (int)ndbl;
} else {
n = 0;
}
k = newgrid->size[0] * newgrid->size[1];
newgrid->size[0] = 1;
newgrid->size[1] = n;
emxEnsureCapacity_real_T(newgrid, k);
if (n > 0) {
newgrid->data[0] = a;
if (n > 1) {
newgrid->data[n - 1] = apnd;
nm1d2 = (n - 1) / 2;
for (k = 1; k < nm1d2; k++) {
ngrid = (double)k * delf;
newgrid->data[k] = a + ngrid;
newgrid->data[(n - k) - 1] = apnd - ngrid;
}
if (nm1d2 << 1 == n - 1) {
newgrid->data[nm1d2] = (a + apnd) / 2.0;
} else {
ngrid = (double)nm1d2 * delf;
newgrid->data[nm1d2] = a + ngrid;
newgrid->data[nm1d2 + 1] = apnd - ngrid;
}
}
}
}
if (newgrid->size[1] < 11) {
delf1 = ((ff[(int)(l + 1.0) - 1] + delf) - (grid[(int)j - 1] + delf)) /
10.0;
a = grid[(int)j - 1] + delf1;
ngrid = ff[(int)(l + 1.0) - 1] + delf1;
if (rtIsNaN(a) || rtIsNaN(delf1) || rtIsNaN(ngrid)) {
k = newgrid->size[0] * newgrid->size[1];
newgrid->size[0] = 1;
newgrid->size[1] = 1;
emxEnsureCapacity_real_T(newgrid, k);
newgrid->data[0] = rtNaN;
} else if ((delf1 == 0.0) || ((a < ngrid) && (delf1 < 0.0)) || ((ngrid < a)
&& (delf1 > 0.0))) {
k = newgrid->size[0] * newgrid->size[1];
newgrid->size[0] = 1;
newgrid->size[1] = 0;
emxEnsureCapacity_real_T(newgrid, k);
} else if ((rtIsInf(a) || rtIsInf(ngrid)) && (rtIsInf(delf1) || (a ==
ngrid))) {
k = newgrid->size[0] * newgrid->size[1];
newgrid->size[0] = 1;
newgrid->size[1] = 1;
emxEnsureCapacity_real_T(newgrid, k);
newgrid->data[0] = rtNaN;
} else if (rtIsInf(delf1)) {
k = newgrid->size[0] * newgrid->size[1];
newgrid->size[0] = 1;
newgrid->size[1] = 1;
emxEnsureCapacity_real_T(newgrid, k);
newgrid->data[0] = a;
} else if ((floor(a) == a) && (floor(delf1) == delf1)) {
k = newgrid->size[0] * newgrid->size[1];
newgrid->size[0] = 1;
newgrid->size[1] = (int)floor((ngrid - a) / delf1) + 1;
emxEnsureCapacity_real_T(newgrid, k);
nm1d2 = (int)floor((ngrid - a) / delf1);
for (k = 0; k <= nm1d2; k++) {
newgrid->data[newgrid->size[0] * k] = a + delf1 * (double)k;
}
} else {
ndbl = floor((ngrid - a) / delf1 + 0.5);
apnd = a + ndbl * delf1;
if (delf1 > 0.0) {
cdiff = apnd - ngrid;
} else {
cdiff = ngrid - apnd;
}
absa = fabs(a);
absb = fabs(ngrid);
if ((absa > absb) || rtIsNaN(absb)) {
absb = absa;
}
if (fabs(cdiff) < 4.4408920985006262E-16 * absb) {
ndbl++;
apnd = ngrid;
} else if (cdiff > 0.0) {
apnd = a + (ndbl - 1.0) * delf1;
} else {
ndbl++;
}
if (ndbl >= 0.0) {
n = (int)ndbl;
} else {
n = 0;
}
k = newgrid->size[0] * newgrid->size[1];
newgrid->size[0] = 1;
newgrid->size[1] = n;
emxEnsureCapacity_real_T(newgrid, k);
if (n > 0) {
newgrid->data[0] = a;
if (n > 1) {
newgrid->data[n - 1] = apnd;
nm1d2 = (n - 1) / 2;
for (k = 1; k < nm1d2; k++) {
ngrid = (double)k * delf1;
newgrid->data[k] = a + ngrid;
newgrid->data[(n - k) - 1] = apnd - ngrid;
}
if (nm1d2 << 1 == n - 1) {
newgrid->data[nm1d2] = (a + apnd) / 2.0;
} else {
ngrid = (double)nm1d2 * delf1;
newgrid->data[nm1d2] = a + ngrid;
newgrid->data[nm1d2 + 1] = apnd - ngrid;
}
}
}
}
}
/* grid = [grid newgrid]; */
k = newgrid->size[1];
nm1d2 = r20->size[0] * r20->size[1];
r20->size[0] = 1;
r20->size[1] = (int)((double)k - 1.0) + 1;
emxEnsureCapacity_int32_T(r20, nm1d2);
nm1d2 = (int)((double)k - 1.0);
for (k = 0; k <= nm1d2; k++) {
r20->data[r20->size[0] * k] = (int)(gridSize + (1.0 + (double)k));
}
nm1d2 = newgrid->size[0] * newgrid->size[1];
for (k = 0; k < nm1d2; k++) {
grid[r20->data[k] - 1] = newgrid->data[k];
}
gridSize += (double)newgrid->size[1];
/* jend = length(grid); */
/* length(grid); */
if (gridSize > 1.0) {
grid[(int)(gridSize - 1.0) - 1] = ff[(int)(l + 1.0) - 1];
j = gridSize;
} else {
j = 2.0;
}
l += 2.0;
if (l + 1.0 <= 4.0) {
grid[(int)j - 1] = ff[(int)l - 1];
}
}
emxFree_int32_T(&r20);
emxFree_real_T(&newgrid);
ngrid = j - 1.0;
/* If value at frequency 1 is constrained, remove that grid point: */
if (grid[(int)(j - 1.0) - 1] > 1.0 - delf) {
if (ff[2] < 1.0 - delf) {
ngrid = (j - 1.0) - 1.0;
} else {
grid[(int)(j - 1.0) - 1] = ff[2];
}
}
if (1.0 > ngrid) {
nm1d2 = 0;
} else {
nm1d2 = (int)ngrid;
}
k = gridactual->size[0] * gridactual->size[1];
gridactual->size[0] = 1;
gridactual->size[1] = nm1d2;
emxEnsureCapacity_real_T(gridactual, k);
for (k = 0; k < nm1d2; k++) {
gridactual->data[gridactual->size[0] * k] = grid[k];
}
}
/*
* FREQS Laplace-transform (s-domain) frequency response with codegen support
*
* This function is based on 'freqs' by The MathWorks Inc.
* Arguments : const double b_data[]
* const int b_size[2]
* const emxArray_creal_T *a
* const double w[2048]
* creal_T h[2048]
* Return Type : void
*/
static void freqs_cg(const double b_data[], const int b_size[2], const
emxArray_creal_T *a, const double w[2048], creal_T h[2048])
{
emxArray_creal_T *b_a;
double b_b_data[4];
int b_b_size[2];
int i26;
boolean_T b0;
static creal_T s[2048];
int k;
creal_T y[2048];
double h_re;
double bim;
double d;
double brm;
emxInit_creal_T(&b_a, 2);
removeTrailingZero(b_data, b_size, a, b_b_data, b_b_size, b_a);
for (i26 = 0; i26 < 2048; i26++) {
s[i26].re = w[i26] * 0.0;
s[i26].im = w[i26];
}
b0 = (b_a->size[1] == 0);
if (!b0) {
for (i26 = 0; i26 < 2048; i26++) {
y[i26] = b_a->data[0];
}
for (k = 0; k <= b_a->size[1] - 2; k++) {
bim = b_a->data[k + 1].re;
d = b_a->data[k + 1].im;
for (i26 = 0; i26 < 2048; i26++) {
brm = s[i26].re * y[i26].im + s[i26].im * y[i26].re;
y[i26].re = (s[i26].re * y[i26].re - s[i26].im * y[i26].im) + bim;
y[i26].im = brm + d;
}
}
}
emxFree_creal_T(&b_a);
c_polyval(b_b_data, b_b_size, s, h);
for (i26 = 0; i26 < 2048; i26++) {
h_re = h[i26].re;
if (y[i26].im == 0.0) {
if (h[i26].im == 0.0) {
h[i26].re /= y[i26].re;
h[i26].im = 0.0;
} else if (h[i26].re == 0.0) {
h[i26].re = 0.0;
h[i26].im /= y[i26].re;
} else {
h[i26].re /= y[i26].re;
h[i26].im /= y[i26].re;
}
} else if (y[i26].re == 0.0) {
if (h[i26].re == 0.0) {
h[i26].re = h[i26].im / y[i26].im;
h[i26].im = 0.0;
} else if (h[i26].im == 0.0) {
h[i26].re = 0.0;
h[i26].im = -(h_re / y[i26].im);
} else {
h[i26].re = h[i26].im / y[i26].im;
h[i26].im = -(h_re / y[i26].im);
}
} else {
brm = fabs(y[i26].re);
bim = fabs(y[i26].im);
if (brm > bim) {
bim = y[i26].im / y[i26].re;
d = y[i26].re + bim * y[i26].im;
h[i26].re = (h[i26].re + bim * h[i26].im) / d;
h[i26].im = (h[i26].im - bim * h_re) / d;
} else if (bim == brm) {
if (y[i26].re > 0.0) {
bim = 0.5;
} else {
bim = -0.5;
}
if (y[i26].im > 0.0) {
d = 0.5;
} else {
d = -0.5;
}
h[i26].re = (h[i26].re * bim + h[i26].im * d) / brm;
h[i26].im = (h[i26].im * bim - h_re * d) / brm;
} else {
bim = y[i26].re / y[i26].im;
d = y[i26].im + bim * y[i26].re;
h[i26].re = (bim * h[i26].re + h[i26].im) / d;
h[i26].im = (bim * h[i26].im - h_re) / d;
}
}
}
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double w[2048]
* double Fs
* creal_T hh[2048]
* Return Type : void
*/
static void freqz_cg(const double w[2048], double Fs, creal_T hh[2048])
{
struct_T options;
int i8;
static const char cv12[8] = { 'o', 'n', 'e', 's', 'i', 'd', 'e', 'd' };
double b_w[2048];
static const char cv13[7] = { 'o', 'm', 'i', 't', 't', 'e', 'd' };
/* Cast to enforce precision rules */
options.Fs = Fs;
memcpy(&options.nfft[0], &w[0], sizeof(double) << 11);
memcpy(&options.w[0], &w[0], sizeof(double) << 11);
/* Remaining are default or for advanced use */
options.fvflag = 1.0;
for (i8 = 0; i8 < 8; i8++) {
options.range[i8] = cv12[i8];
}
options.centerdc = 0.0;
for (i8 = 0; i8 < 7; i8++) {
options.configlevel[i8] = cv13[i8];
}
firfreqz(&options, hh, b_w);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
}
/*
* Make b a row
* Arguments : const double b[57]
* const struct_T *options
* creal_T h[2048]
* double w[2048]
* Return Type : void
*/
static void g_firfreqz(const double b[57], const struct_T *options, creal_T h
[2048], double w[2048])
{
int i68;
creal_T dcv7[2048];
double digw;
double b_digw[2048];
double h_re;
double brm;
double d;
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
/* Convert from Hz to rad/sample for computational purposes */
/* Digital frequency must be used for this calculation */
for (i68 = 0; i68 < 2048; i68++) {
w[i68] = options->w[i68];
digw = 6.2831853071795862 * options->w[i68] / options->Fs;
dcv7[i68].re = digw * 0.0;
dcv7[i68].im = digw;
b_digw[i68] = digw;
}
b_exp(dcv7);
f_polyval(b, dcv7, h);
for (i68 = 0; i68 < 2048; i68++) {
dcv7[i68].re = 56.0 * (b_digw[i68] * 0.0);
dcv7[i68].im = 56.0 * b_digw[i68];
}
b_exp(dcv7);
for (i68 = 0; i68 < 2048; i68++) {
h_re = h[i68].re;
if (dcv7[i68].im == 0.0) {
if (h[i68].im == 0.0) {
h[i68].re /= dcv7[i68].re;
h[i68].im = 0.0;
} else if (h[i68].re == 0.0) {
h[i68].re = 0.0;
h[i68].im /= dcv7[i68].re;
} else {
h[i68].re /= dcv7[i68].re;
h[i68].im /= dcv7[i68].re;
}
} else if (dcv7[i68].re == 0.0) {
if (h[i68].re == 0.0) {
h[i68].re = h[i68].im / dcv7[i68].im;
h[i68].im = 0.0;
} else if (h[i68].im == 0.0) {
h[i68].re = 0.0;
h[i68].im = -(h_re / dcv7[i68].im);
} else {
h[i68].re = h[i68].im / dcv7[i68].im;
h[i68].im = -(h_re / dcv7[i68].im);
}
} else {
brm = fabs(dcv7[i68].re);
digw = fabs(dcv7[i68].im);
if (brm > digw) {
digw = dcv7[i68].im / dcv7[i68].re;
d = dcv7[i68].re + digw * dcv7[i68].im;
h[i68].re = (h[i68].re + digw * h[i68].im) / d;
h[i68].im = (h[i68].im - digw * h_re) / d;
} else if (digw == brm) {
if (dcv7[i68].re > 0.0) {
digw = 0.5;
} else {
digw = -0.5;
}
if (dcv7[i68].im > 0.0) {
d = 0.5;
} else {
d = -0.5;
}
h[i68].re = (h[i68].re * digw + h[i68].im * d) / brm;
h[i68].im = (h[i68].im * digw - h_re * d) / brm;
} else {
digw = dcv7[i68].re / dcv7[i68].im;
d = dcv7[i68].im + digw * dcv7[i68].re;
h[i68].re = (digw * h[i68].re + h[i68].im) / d;
h[i68].im = (digw * h[i68].im - h_re) / d;
}
}
}
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[57]
* const double w[2048]
* double Fs
* creal_T hh[2048]
* Return Type : void
*/
static void g_freqz_cg(const double b[57], const double w[2048], double Fs,
creal_T hh[2048])
{
static struct_T options;
int i19;
static const char cv24[8] = { 'o', 'n', 'e', 's', 'i', 'd', 'e', 'd' };
double b_w[2048];
static const char cv25[7] = { 'o', 'm', 'i', 't', 't', 'e', 'd' };
/* Cast to enforce precision rules */
options.Fs = Fs;
memcpy(&options.nfft[0], &w[0], sizeof(double) << 11);
memcpy(&options.w[0], &w[0], sizeof(double) << 11);
/* Remaining are default or for advanced use */
options.fvflag = 1.0;
for (i19 = 0; i19 < 8; i19++) {
options.range[i19] = cv24[i19];
}
options.centerdc = 0.0;
for (i19 = 0; i19 < 7; i19++) {
options.configlevel[i19] = cv25[i19];
}
g_firfreqz(b, &options, hh, b_w);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
}
/*
* Arguments : const double p[43]
* const creal_T x[2048]
* creal_T y[2048]
* Return Type : void
*/
static void g_polyval(const double p[43], const creal_T x[2048],
creal_T y[2048])
{
int i20;
int k;
double x_im;
for (i20 = 0; i20 < 2048; i20++) {
y[i20].re = p[0];
y[i20].im = 0.0;
}
for (k = 0; k < 42; k++) {
for (i20 = 0; i20 < 2048; i20++) {
x_im = x[i20].re * y[i20].im + x[i20].im * y[i20].re;
y[i20].re = (x[i20].re * y[i20].re - x[i20].im * y[i20].im) + p[k + 1];
y[i20].im = x_im;
}
}
}
/*
* Arguments : const double o[15]
* double u[43]
* Return Type : void
*/
static void g_us(const double o[15], double u[43])
{
double b_u[45];
int ix;
int iy;
int k;
memset(&b_u[0], 0, 45U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 15; k++) {
b_u[iy] = o[ix];
ix++;
iy += 3;
}
memcpy(&u[0], &b_u[0], 43U * sizeof(double));
}
/*
* Arguments : const char enables[4]
* const double w[2048]
* double Fs
* const double hb1_coeff[15]
* const double hb2_coeff[7]
* const double hb3_coeff_data[]
* const int hb3_coeff_size[2]
* const double dec_int3_coeff_data[]
* const int dec_int3_coeff_size[2]
* creal_T combinedResponse[2048]
* Return Type : void
*/
static void generateCascadedResponseRx(const char enables[4], const double w
[2048], double Fs, const double hb1_coeff[15], const double hb2_coeff[7],
const double hb3_coeff_data[], const int hb3_coeff_size[2], const double
dec_int3_coeff_data[], const int dec_int3_coeff_size[2], creal_T
combinedResponse[2048])
{
boolean_T b_bool;
int kstr;
int exitg1;
double dv2[15];
double dv3[7];
double tmp_data[29];
int tmp_size[2];
double dv4[29];
double dv5[29];
double dv6[13];
double dv7[57];
double dv8[43];
double dv9[19];
double dv10[85];
static const char cv1[4] = { '2', '1', '1', '1' };
double dv11[7];
double dv12[13];
double dv13[19];
static creal_T d2[2048];
static creal_T d3[2048];
double combinedResponse_re;
double combinedResponse_im;
static const char cv2[4] = { '1', '2', '1', '1' };
static const char cv3[4] = { '1', '1', '2', '1' };
static const char cv4[4] = { '2', '2', '1', '1' };
static const char cv5[4] = { '2', '1', '2', '1' };
static const char cv6[4] = { '1', '2', '2', '1' };
static const char cv7[4] = { '2', '2', '2', '1' };
static const char cv8[4] = { '1', '1', '1', '3' };
static const char cv9[4] = { '2', '1', '1', '3' };
static const char cv10[4] = { '1', '2', '1', '3' };
static const char cv11[4] = { '2', '2', '1', '3' };
/* Cast */
b_bool = false;
kstr = 1;
do {
exitg1 = 0;
if (kstr < 5) {
if (enables[kstr - 1] != '1') {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 0;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 5) {
if (enables[kstr] != cv1[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 1;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 5) {
if (enables[kstr] != cv2[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 2;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 5) {
if (enables[kstr] != cv3[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 3;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 5) {
if (enables[kstr] != cv4[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 4;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 5) {
if (enables[kstr] != cv5[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 5;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 5) {
if (enables[kstr] != cv6[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 6;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 5) {
if (enables[kstr] != cv7[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 7;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 5) {
if (enables[kstr] != cv8[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 8;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 5) {
if (enables[kstr] != cv9[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 9;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 5) {
if (enables[kstr] != cv10[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 10;
} else {
b_bool = false;
kstr = 0;
do {
exitg1 = 0;
if (kstr + 1 < 5) {
if (enables[kstr] != cv11[kstr]) {
exitg1 = 1;
} else {
kstr++;
}
} else {
b_bool = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (b_bool) {
kstr = 11;
} else {
kstr = -1;
}
}
}
}
}
}
}
}
}
}
}
}
switch (kstr) {
case 0:
/* only FIR */
freqz_cg(w, Fs, combinedResponse);
break;
case 1:
/* Hb1 */
us(hb1_coeff, dv2);
b_freqz_cg(dv2, w, Fs, combinedResponse);
break;
case 2:
/* Hb2 */
b_us(hb2_coeff, dv3);
c_freqz_cg(dv3, w, Fs, combinedResponse);
break;
case 3:
/* Hb3 */
c_us(hb3_coeff_data, hb3_coeff_size, tmp_data, tmp_size);
d_freqz_cg(tmp_data, tmp_size, w, Fs, combinedResponse);
break;
case 4:
/* Hb2,Hb1 */
d_us(hb1_coeff, dv4);
e_freqz_cg(dv4, w, Fs, combinedResponse);
b_us(hb2_coeff, dv11);
c_freqz_cg(dv11, w, Fs, d2);
for (kstr = 0; kstr < 2048; kstr++) {
combinedResponse_re = combinedResponse[kstr].re;
combinedResponse[kstr].re = combinedResponse[kstr].re * d2[kstr].re -
combinedResponse[kstr].im * d2[kstr].im;
combinedResponse[kstr].im = combinedResponse_re * d2[kstr].im +
combinedResponse[kstr].im * d2[kstr].re;
}
break;
case 5:
/* Hb3,Hb1 */
d_us(hb1_coeff, dv5);
e_freqz_cg(dv5, w, Fs, combinedResponse);
c_us(hb3_coeff_data, hb3_coeff_size, tmp_data, tmp_size);
d_freqz_cg(tmp_data, tmp_size, w, Fs, d2);
for (kstr = 0; kstr < 2048; kstr++) {
combinedResponse_re = combinedResponse[kstr].re;
combinedResponse[kstr].re = combinedResponse[kstr].re * d2[kstr].re -
combinedResponse[kstr].im * d2[kstr].im;
combinedResponse[kstr].im = combinedResponse_re * d2[kstr].im +
combinedResponse[kstr].im * d2[kstr].re;
}
break;
case 6:
/* Hb3,Hb2 */
e_us(hb2_coeff, dv6);
f_freqz_cg(dv6, w, Fs, combinedResponse);
c_us(hb3_coeff_data, hb3_coeff_size, tmp_data, tmp_size);
d_freqz_cg(tmp_data, tmp_size, w, Fs, d2);
for (kstr = 0; kstr < 2048; kstr++) {
combinedResponse_re = combinedResponse[kstr].re;
combinedResponse[kstr].re = combinedResponse[kstr].re * d2[kstr].re -
combinedResponse[kstr].im * d2[kstr].im;
combinedResponse[kstr].im = combinedResponse_re * d2[kstr].im +
combinedResponse[kstr].im * d2[kstr].re;
}
break;
case 7:
/* Hb3,Hb2,Hb1 */
f_us(hb1_coeff, dv7);
g_freqz_cg(dv7, w, Fs, combinedResponse);
e_us(hb2_coeff, dv12);
f_freqz_cg(dv12, w, Fs, d2);
c_us(hb3_coeff_data, hb3_coeff_size, tmp_data, tmp_size);
d_freqz_cg(tmp_data, tmp_size, w, Fs, d3);
for (kstr = 0; kstr < 2048; kstr++) {
combinedResponse_re = combinedResponse[kstr].re * d2[kstr].re -
combinedResponse[kstr].im * d2[kstr].im;
combinedResponse_im = combinedResponse[kstr].re * d2[kstr].im +
combinedResponse[kstr].im * d2[kstr].re;
combinedResponse[kstr].re = combinedResponse_re * d3[kstr].re -
combinedResponse_im * d3[kstr].im;
combinedResponse[kstr].im = combinedResponse_re * d3[kstr].im +
combinedResponse_im * d3[kstr].re;
}
break;
case 8:
/* Dec/Int3 */
c_us(dec_int3_coeff_data, dec_int3_coeff_size, tmp_data, tmp_size);
d_freqz_cg(tmp_data, tmp_size, w, Fs, combinedResponse);
/* RECHECK ALL DEC BY 3 */
break;
case 9:
/* Dec/Int3,Hb1 */
g_us(hb1_coeff, dv8);
h_freqz_cg(dv8, w, Fs, combinedResponse);
c_us(dec_int3_coeff_data, dec_int3_coeff_size, tmp_data, tmp_size);
d_freqz_cg(tmp_data, tmp_size, w, Fs, d2);
for (kstr = 0; kstr < 2048; kstr++) {
combinedResponse_re = combinedResponse[kstr].re;
combinedResponse[kstr].re = combinedResponse[kstr].re * d2[kstr].re -
combinedResponse[kstr].im * d2[kstr].im;
combinedResponse[kstr].im = combinedResponse_re * d2[kstr].im +
combinedResponse[kstr].im * d2[kstr].re;
}
break;
case 10:
/* Dec/Int3,Hb2 */
h_us(hb2_coeff, dv9);
i_freqz_cg(dv9, w, Fs, combinedResponse);
c_us(dec_int3_coeff_data, dec_int3_coeff_size, tmp_data, tmp_size);
d_freqz_cg(tmp_data, tmp_size, w, Fs, d2);
for (kstr = 0; kstr < 2048; kstr++) {
combinedResponse_re = combinedResponse[kstr].re;
combinedResponse[kstr].re = combinedResponse[kstr].re * d2[kstr].re -
combinedResponse[kstr].im * d2[kstr].im;
combinedResponse[kstr].im = combinedResponse_re * d2[kstr].im +
combinedResponse[kstr].im * d2[kstr].re;
}
break;
case 11:
/* Dec/Int3,Hb2,Hb1 {Hm4,Hm2c34,Hm1} */
i_us(hb1_coeff, dv10);
j_freqz_cg(dv10, w, Fs, combinedResponse);
h_us(hb2_coeff, dv13);
i_freqz_cg(dv13, w, Fs, d2);
c_us(dec_int3_coeff_data, dec_int3_coeff_size, tmp_data, tmp_size);
d_freqz_cg(tmp_data, tmp_size, w, Fs, d3);
for (kstr = 0; kstr < 2048; kstr++) {
combinedResponse_re = combinedResponse[kstr].re * d2[kstr].re -
combinedResponse[kstr].im * d2[kstr].im;
combinedResponse_im = combinedResponse[kstr].re * d2[kstr].im +
combinedResponse[kstr].im * d2[kstr].re;
combinedResponse[kstr].re = combinedResponse_re * d3[kstr].re -
combinedResponse_im * d3[kstr].im;
combinedResponse[kstr].im = combinedResponse_re * d3[kstr].im +
combinedResponse_im * d3[kstr].re;
}
break;
}
/* Add filter extra filter to end of cascade */
}
/*
* Make b a row
* Arguments : const double b[43]
* const struct_T *options
* creal_T h[2048]
* double w[2048]
* Return Type : void
*/
static void h_firfreqz(const double b[43], const struct_T *options, creal_T h
[2048], double w[2048])
{
int i69;
creal_T dcv8[2048];
double digw;
double b_digw[2048];
double h_re;
double brm;
double d;
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
/* Convert from Hz to rad/sample for computational purposes */
/* Digital frequency must be used for this calculation */
for (i69 = 0; i69 < 2048; i69++) {
w[i69] = options->w[i69];
digw = 6.2831853071795862 * options->w[i69] / options->Fs;
dcv8[i69].re = digw * 0.0;
dcv8[i69].im = digw;
b_digw[i69] = digw;
}
b_exp(dcv8);
g_polyval(b, dcv8, h);
for (i69 = 0; i69 < 2048; i69++) {
dcv8[i69].re = 42.0 * (b_digw[i69] * 0.0);
dcv8[i69].im = 42.0 * b_digw[i69];
}
b_exp(dcv8);
for (i69 = 0; i69 < 2048; i69++) {
h_re = h[i69].re;
if (dcv8[i69].im == 0.0) {
if (h[i69].im == 0.0) {
h[i69].re /= dcv8[i69].re;
h[i69].im = 0.0;
} else if (h[i69].re == 0.0) {
h[i69].re = 0.0;
h[i69].im /= dcv8[i69].re;
} else {
h[i69].re /= dcv8[i69].re;
h[i69].im /= dcv8[i69].re;
}
} else if (dcv8[i69].re == 0.0) {
if (h[i69].re == 0.0) {
h[i69].re = h[i69].im / dcv8[i69].im;
h[i69].im = 0.0;
} else if (h[i69].im == 0.0) {
h[i69].re = 0.0;
h[i69].im = -(h_re / dcv8[i69].im);
} else {
h[i69].re = h[i69].im / dcv8[i69].im;
h[i69].im = -(h_re / dcv8[i69].im);
}
} else {
brm = fabs(dcv8[i69].re);
digw = fabs(dcv8[i69].im);
if (brm > digw) {
digw = dcv8[i69].im / dcv8[i69].re;
d = dcv8[i69].re + digw * dcv8[i69].im;
h[i69].re = (h[i69].re + digw * h[i69].im) / d;
h[i69].im = (h[i69].im - digw * h_re) / d;
} else if (digw == brm) {
if (dcv8[i69].re > 0.0) {
digw = 0.5;
} else {
digw = -0.5;
}
if (dcv8[i69].im > 0.0) {
d = 0.5;
} else {
d = -0.5;
}
h[i69].re = (h[i69].re * digw + h[i69].im * d) / brm;
h[i69].im = (h[i69].im * digw - h_re * d) / brm;
} else {
digw = dcv8[i69].re / dcv8[i69].im;
d = dcv8[i69].im + digw * dcv8[i69].re;
h[i69].re = (digw * h[i69].re + h[i69].im) / d;
h[i69].im = (digw * h[i69].im - h_re) / d;
}
}
}
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[43]
* const double w[2048]
* double Fs
* creal_T hh[2048]
* Return Type : void
*/
static void h_freqz_cg(const double b[43], const double w[2048], double Fs,
creal_T hh[2048])
{
static struct_T options;
int i21;
static const char cv26[8] = { 'o', 'n', 'e', 's', 'i', 'd', 'e', 'd' };
double b_w[2048];
static const char cv27[7] = { 'o', 'm', 'i', 't', 't', 'e', 'd' };
/* Cast to enforce precision rules */
options.Fs = Fs;
memcpy(&options.nfft[0], &w[0], sizeof(double) << 11);
memcpy(&options.w[0], &w[0], sizeof(double) << 11);
/* Remaining are default or for advanced use */
options.fvflag = 1.0;
for (i21 = 0; i21 < 8; i21++) {
options.range[i21] = cv26[i21];
}
options.centerdc = 0.0;
for (i21 = 0; i21 < 7; i21++) {
options.configlevel[i21] = cv27[i21];
}
h_firfreqz(b, &options, hh, b_w);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
}
/*
* Arguments : const double p[19]
* const creal_T x[2048]
* creal_T y[2048]
* Return Type : void
*/
static void h_polyval(const double p[19], const creal_T x[2048],
creal_T y[2048])
{
int i22;
int k;
double x_im;
for (i22 = 0; i22 < 2048; i22++) {
y[i22].re = p[0];
y[i22].im = 0.0;
}
for (k = 0; k < 18; k++) {
for (i22 = 0; i22 < 2048; i22++) {
x_im = x[i22].re * y[i22].im + x[i22].im * y[i22].re;
y[i22].re = (x[i22].re * y[i22].re - x[i22].im * y[i22].im) + p[k + 1];
y[i22].im = x_im;
}
}
}
/*
* Arguments : const double o[7]
* double u[19]
* Return Type : void
*/
static void h_us(const double o[7], double u[19])
{
double b_u[21];
int ix;
int iy;
int k;
memset(&b_u[0], 0, 21U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 7; k++) {
b_u[iy] = o[ix];
ix++;
iy += 3;
}
memcpy(&u[0], &b_u[0], 19U * sizeof(double));
}
/*
* Make b a row
* Arguments : const double b[19]
* const struct_T *options
* creal_T h[2048]
* double w[2048]
* Return Type : void
*/
static void i_firfreqz(const double b[19], const struct_T *options, creal_T h
[2048], double w[2048])
{
int i70;
creal_T dcv9[2048];
double digw;
double b_digw[2048];
double h_re;
double brm;
double d;
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
/* Convert from Hz to rad/sample for computational purposes */
/* Digital frequency must be used for this calculation */
for (i70 = 0; i70 < 2048; i70++) {
w[i70] = options->w[i70];
digw = 6.2831853071795862 * options->w[i70] / options->Fs;
dcv9[i70].re = digw * 0.0;
dcv9[i70].im = digw;
b_digw[i70] = digw;
}
b_exp(dcv9);
h_polyval(b, dcv9, h);
for (i70 = 0; i70 < 2048; i70++) {
dcv9[i70].re = 18.0 * (b_digw[i70] * 0.0);
dcv9[i70].im = 18.0 * b_digw[i70];
}
b_exp(dcv9);
for (i70 = 0; i70 < 2048; i70++) {
h_re = h[i70].re;
if (dcv9[i70].im == 0.0) {
if (h[i70].im == 0.0) {
h[i70].re /= dcv9[i70].re;
h[i70].im = 0.0;
} else if (h[i70].re == 0.0) {
h[i70].re = 0.0;
h[i70].im /= dcv9[i70].re;
} else {
h[i70].re /= dcv9[i70].re;
h[i70].im /= dcv9[i70].re;
}
} else if (dcv9[i70].re == 0.0) {
if (h[i70].re == 0.0) {
h[i70].re = h[i70].im / dcv9[i70].im;
h[i70].im = 0.0;
} else if (h[i70].im == 0.0) {
h[i70].re = 0.0;
h[i70].im = -(h_re / dcv9[i70].im);
} else {
h[i70].re = h[i70].im / dcv9[i70].im;
h[i70].im = -(h_re / dcv9[i70].im);
}
} else {
brm = fabs(dcv9[i70].re);
digw = fabs(dcv9[i70].im);
if (brm > digw) {
digw = dcv9[i70].im / dcv9[i70].re;
d = dcv9[i70].re + digw * dcv9[i70].im;
h[i70].re = (h[i70].re + digw * h[i70].im) / d;
h[i70].im = (h[i70].im - digw * h_re) / d;
} else if (digw == brm) {
if (dcv9[i70].re > 0.0) {
digw = 0.5;
} else {
digw = -0.5;
}
if (dcv9[i70].im > 0.0) {
d = 0.5;
} else {
d = -0.5;
}
h[i70].re = (h[i70].re * digw + h[i70].im * d) / brm;
h[i70].im = (h[i70].im * digw - h_re * d) / brm;
} else {
digw = dcv9[i70].re / dcv9[i70].im;
d = dcv9[i70].im + digw * dcv9[i70].re;
h[i70].re = (digw * h[i70].re + h[i70].im) / d;
h[i70].im = (digw * h[i70].im - h_re) / d;
}
}
}
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[19]
* const double w[2048]
* double Fs
* creal_T hh[2048]
* Return Type : void
*/
static void i_freqz_cg(const double b[19], const double w[2048], double Fs,
creal_T hh[2048])
{
static struct_T options;
int i23;
static const char cv28[8] = { 'o', 'n', 'e', 's', 'i', 'd', 'e', 'd' };
double b_w[2048];
static const char cv29[7] = { 'o', 'm', 'i', 't', 't', 'e', 'd' };
/* Cast to enforce precision rules */
options.Fs = Fs;
memcpy(&options.nfft[0], &w[0], sizeof(double) << 11);
memcpy(&options.w[0], &w[0], sizeof(double) << 11);
/* Remaining are default or for advanced use */
options.fvflag = 1.0;
for (i23 = 0; i23 < 8; i23++) {
options.range[i23] = cv28[i23];
}
options.centerdc = 0.0;
for (i23 = 0; i23 < 7; i23++) {
options.configlevel[i23] = cv29[i23];
}
i_firfreqz(b, &options, hh, b_w);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
}
/*
* Arguments : const double p[85]
* const creal_T x[2048]
* creal_T y[2048]
* Return Type : void
*/
static void i_polyval(const double p[85], const creal_T x[2048],
creal_T y[2048])
{
int i24;
int k;
double x_im;
for (i24 = 0; i24 < 2048; i24++) {
y[i24].re = p[0];
y[i24].im = 0.0;
}
for (k = 0; k < 84; k++) {
for (i24 = 0; i24 < 2048; i24++) {
x_im = x[i24].re * y[i24].im + x[i24].im * y[i24].re;
y[i24].re = (x[i24].re * y[i24].re - x[i24].im * y[i24].im) + p[k + 1];
y[i24].im = x_im;
}
}
}
/*
* Arguments : const double o[15]
* double u[85]
* Return Type : void
*/
static void i_us(const double o[15], double u[85])
{
double b_u[90];
int ix;
int iy;
int k;
memset(&b_u[0], 0, 90U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 15; k++) {
b_u[iy] = o[ix];
ix++;
iy += 6;
}
memcpy(&u[0], &b_u[0], 85U * sizeof(double));
}
/*
* Arguments : const emxArray_real_T *varargin_1
* const emxArray_real_T *varargin_2
* const emxArray_real_T *varargin_3
* emxArray_real_T *Vq
* Return Type : void
*/
static void interp1(const emxArray_real_T *varargin_1, const emxArray_real_T
*varargin_2, const emxArray_real_T *varargin_3,
emxArray_real_T *Vq)
{
emxArray_real_T *y;
int low_ip1;
int nd2;
emxArray_real_T *x;
int nx;
int outsize[2];
int k;
int exitg1;
int mid_i;
double r;
emxInit_real_T(&y, 2);
low_ip1 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = varargin_2->size[1];
emxEnsureCapacity_real_T(y, low_ip1);
nd2 = varargin_2->size[0] * varargin_2->size[1];
for (low_ip1 = 0; low_ip1 < nd2; low_ip1++) {
y->data[low_ip1] = varargin_2->data[low_ip1];
}
emxInit_real_T(&x, 2);
low_ip1 = x->size[0] * x->size[1];
x->size[0] = 1;
x->size[1] = varargin_1->size[1];
emxEnsureCapacity_real_T(x, low_ip1);
nd2 = varargin_1->size[0] * varargin_1->size[1];
for (low_ip1 = 0; low_ip1 < nd2; low_ip1++) {
x->data[low_ip1] = varargin_1->data[low_ip1];
}
nx = varargin_1->size[1];
for (low_ip1 = 0; low_ip1 < 2; low_ip1++) {
outsize[low_ip1] = varargin_3->size[low_ip1];
}
low_ip1 = Vq->size[0] * Vq->size[1];
Vq->size[0] = 1;
Vq->size[1] = outsize[1];
emxEnsureCapacity_real_T(Vq, low_ip1);
nd2 = outsize[1];
for (low_ip1 = 0; low_ip1 < nd2; low_ip1++) {
Vq->data[low_ip1] = rtNaN;
}
if (varargin_3->size[1] != 0) {
k = 1;
do {
exitg1 = 0;
if (k <= nx) {
if (rtIsNaN(varargin_1->data[k - 1])) {
exitg1 = 1;
} else {
k++;
}
} else {
if (varargin_1->data[1] < varargin_1->data[0]) {
low_ip1 = nx >> 1;
for (mid_i = 1; mid_i <= low_ip1; mid_i++) {
r = x->data[mid_i - 1];
x->data[mid_i - 1] = x->data[nx - mid_i];
x->data[nx - mid_i] = r;
}
nd2 = varargin_2->size[1] >> 1;
for (mid_i = 1; mid_i <= nd2; mid_i++) {
low_ip1 = varargin_2->size[1] - mid_i;
r = y->data[mid_i - 1];
y->data[mid_i - 1] = y->data[low_ip1];
y->data[low_ip1] = r;
}
}
for (k = 0; k + 1 <= varargin_3->size[1]; k++) {
if (rtIsNaN(varargin_3->data[k])) {
Vq->data[k] = rtNaN;
} else {
if ((!(varargin_3->data[k] > x->data[x->size[1] - 1])) &&
(!(varargin_3->data[k] < x->data[0]))) {
nd2 = 1;
low_ip1 = 2;
nx = x->size[1];
while (nx > low_ip1) {
mid_i = (nd2 >> 1) + (nx >> 1);
if (((nd2 & 1) == 1) && ((nx & 1) == 1)) {
mid_i++;
}
if (varargin_3->data[k] >= x->data[mid_i - 1]) {
nd2 = mid_i;
low_ip1 = mid_i + 1;
} else {
nx = mid_i;
}
}
r = (varargin_3->data[k] - x->data[nd2 - 1]) / (x->data[nd2] -
x->data[nd2 - 1]);
if (r == 0.0) {
Vq->data[k] = y->data[nd2 - 1];
} else if (r == 1.0) {
Vq->data[k] = y->data[nd2];
} else if (y->data[nd2 - 1] == y->data[nd2]) {
Vq->data[k] = y->data[nd2 - 1];
} else {
Vq->data[k] = (1.0 - r) * y->data[nd2 - 1] + r * y->data[nd2];
}
}
}
}
exitg1 = 1;
}
} while (exitg1 == 0);
}
emxFree_real_T(&x);
emxFree_real_T(&y);
}
/*
* Make b a row
* Arguments : const double b[85]
* const struct_T *options
* creal_T h[2048]
* double w[2048]
* Return Type : void
*/
static void j_firfreqz(const double b[85], const struct_T *options, creal_T h
[2048], double w[2048])
{
int i71;
creal_T dcv10[2048];
double digw;
double b_digw[2048];
double h_re;
double brm;
double d;
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
/* Convert from Hz to rad/sample for computational purposes */
/* Digital frequency must be used for this calculation */
for (i71 = 0; i71 < 2048; i71++) {
w[i71] = options->w[i71];
digw = 6.2831853071795862 * options->w[i71] / options->Fs;
dcv10[i71].re = digw * 0.0;
dcv10[i71].im = digw;
b_digw[i71] = digw;
}
b_exp(dcv10);
i_polyval(b, dcv10, h);
for (i71 = 0; i71 < 2048; i71++) {
dcv10[i71].re = 84.0 * (b_digw[i71] * 0.0);
dcv10[i71].im = 84.0 * b_digw[i71];
}
b_exp(dcv10);
for (i71 = 0; i71 < 2048; i71++) {
h_re = h[i71].re;
if (dcv10[i71].im == 0.0) {
if (h[i71].im == 0.0) {
h[i71].re /= dcv10[i71].re;
h[i71].im = 0.0;
} else if (h[i71].re == 0.0) {
h[i71].re = 0.0;
h[i71].im /= dcv10[i71].re;
} else {
h[i71].re /= dcv10[i71].re;
h[i71].im /= dcv10[i71].re;
}
} else if (dcv10[i71].re == 0.0) {
if (h[i71].re == 0.0) {
h[i71].re = h[i71].im / dcv10[i71].im;
h[i71].im = 0.0;
} else if (h[i71].im == 0.0) {
h[i71].re = 0.0;
h[i71].im = -(h_re / dcv10[i71].im);
} else {
h[i71].re = h[i71].im / dcv10[i71].im;
h[i71].im = -(h_re / dcv10[i71].im);
}
} else {
brm = fabs(dcv10[i71].re);
digw = fabs(dcv10[i71].im);
if (brm > digw) {
digw = dcv10[i71].im / dcv10[i71].re;
d = dcv10[i71].re + digw * dcv10[i71].im;
h[i71].re = (h[i71].re + digw * h[i71].im) / d;
h[i71].im = (h[i71].im - digw * h_re) / d;
} else if (digw == brm) {
if (dcv10[i71].re > 0.0) {
digw = 0.5;
} else {
digw = -0.5;
}
if (dcv10[i71].im > 0.0) {
d = 0.5;
} else {
d = -0.5;
}
h[i71].re = (h[i71].re * digw + h[i71].im * d) / brm;
h[i71].im = (h[i71].im * digw - h_re * d) / brm;
} else {
digw = dcv10[i71].re / dcv10[i71].im;
d = dcv10[i71].im + digw * dcv10[i71].re;
h[i71].re = (digw * h[i71].re + h[i71].im) / d;
h[i71].im = (digw * h[i71].im - h_re) / d;
}
}
}
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[85]
* const double w[2048]
* double Fs
* creal_T hh[2048]
* Return Type : void
*/
static void j_freqz_cg(const double b[85], const double w[2048], double Fs,
creal_T hh[2048])
{
static struct_T options;
int i25;
static const char cv30[8] = { 'o', 'n', 'e', 's', 'i', 'd', 'e', 'd' };
double b_w[2048];
static const char cv31[7] = { 'o', 'm', 'i', 't', 't', 'e', 'd' };
/* Cast to enforce precision rules */
options.Fs = Fs;
memcpy(&options.nfft[0], &w[0], sizeof(double) << 11);
memcpy(&options.w[0], &w[0], sizeof(double) << 11);
/* Remaining are default or for advanced use */
options.fvflag = 1.0;
for (i25 = 0; i25 < 8; i25++) {
options.range[i25] = cv30[i25];
}
options.centerdc = 0.0;
for (i25 = 0; i25 < 7; i25++) {
options.configlevel[i25] = cv31[i25];
}
j_firfreqz(b, &options, hh, b_w);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
}
/*
* Arguments : const emxArray_real_T *p
* const emxArray_creal_T *x
* emxArray_creal_T *y
* Return Type : void
*/
static void j_polyval(const emxArray_real_T *p, const emxArray_creal_T *x,
emxArray_creal_T *y)
{
int i33;
boolean_T b4;
int loop_ub;
int k;
double p_re;
double x_re;
double x_im;
i33 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = x->size[1];
emxEnsureCapacity_creal_T(y, i33);
if ((y->size[1] == 0) || (p->size[1] == 0)) {
b4 = true;
} else {
b4 = false;
}
if (!b4) {
i33 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_creal_T(y, i33);
loop_ub = y->size[1];
for (i33 = 0; i33 < loop_ub; i33++) {
y->data[y->size[0] * i33].re = p->data[0];
y->data[y->size[0] * i33].im = 0.0;
}
for (k = 0; k <= p->size[1] - 2; k++) {
i33 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = x->size[1];
emxEnsureCapacity_creal_T(y, i33);
p_re = p->data[k + 1];
loop_ub = x->size[0] * x->size[1];
for (i33 = 0; i33 < loop_ub; i33++) {
x_re = x->data[i33].re * y->data[i33].re - x->data[i33].im * y->data[i33]
.im;
x_im = x->data[i33].re * y->data[i33].im + x->data[i33].im * y->data[i33]
.re;
y->data[i33].re = x_re + p_re;
y->data[i33].im = x_im;
}
}
}
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const emxArray_real_T *w
* double Fs
* emxArray_creal_T *hh
* Return Type : void
*/
static void k_freqz_cg(const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh)
{
emxArray_real_T *r4;
int i28;
int loop_ub;
emxArray_real_T *digw;
emxArray_creal_T *y;
emxArray_creal_T *r5;
boolean_T b1;
double re;
double im;
emxInit_real_T(&r4, 2);
/* Cast to enforce precision rules */
/* Remaining are default or for advanced use */
/* Make b a row */
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
i28 = r4->size[0] * r4->size[1];
r4->size[0] = 1;
r4->size[1] = w->size[1];
emxEnsureCapacity_real_T(r4, i28);
loop_ub = w->size[0] * w->size[1];
for (i28 = 0; i28 < loop_ub; i28++) {
r4->data[i28] = 6.2831853071795862 * w->data[i28];
}
emxInit_real_T(&digw, 2);
emxInit_creal_T(&y, 2);
emxInit_creal_T(&r5, 2);
rdivide(r4, Fs, digw);
/* Convert from Hz to rad/sample for computational purposes */
/* Digital frequency must be used for this calculation */
i28 = r5->size[0] * r5->size[1];
r5->size[0] = 1;
r5->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(r5, i28);
loop_ub = digw->size[0] * digw->size[1];
emxFree_real_T(&r4);
for (i28 = 0; i28 < loop_ub; i28++) {
r5->data[i28].re = digw->data[i28] * 0.0;
r5->data[i28].im = digw->data[i28];
}
c_exp(r5);
i28 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = r5->size[1];
emxEnsureCapacity_creal_T(y, i28);
b1 = (y->size[1] == 0);
if (!b1) {
i28 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_creal_T(y, i28);
loop_ub = y->size[1];
for (i28 = 0; i28 < loop_ub; i28++) {
y->data[y->size[0] * i28].re = 1.0;
y->data[y->size[0] * i28].im = 0.0;
}
}
i28 = r5->size[0] * r5->size[1];
r5->size[0] = 1;
r5->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(r5, i28);
loop_ub = digw->size[0] * digw->size[1];
for (i28 = 0; i28 < loop_ub; i28++) {
re = digw->data[i28] * 0.0;
im = digw->data[i28];
r5->data[i28].re = 0.0 * re;
r5->data[i28].im = 0.0 * im;
}
emxFree_real_T(&digw);
c_exp(r5);
b_rdivide(y, r5, hh);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
emxFree_creal_T(&r5);
emxFree_creal_T(&y);
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[15]
* const emxArray_real_T *w
* double Fs
* emxArray_creal_T *hh
* Return Type : void
*/
static void l_freqz_cg(const double b[15], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh)
{
emxArray_real_T *r6;
int i30;
int loop_ub;
emxArray_real_T *digw;
emxArray_creal_T *s;
emxArray_creal_T *y;
boolean_T b2;
int k;
double s_re;
double s_im;
emxInit_real_T(&r6, 2);
/* Cast to enforce precision rules */
/* Remaining are default or for advanced use */
/* Make b a row */
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
i30 = r6->size[0] * r6->size[1];
r6->size[0] = 1;
r6->size[1] = w->size[1];
emxEnsureCapacity_real_T(r6, i30);
loop_ub = w->size[0] * w->size[1];
for (i30 = 0; i30 < loop_ub; i30++) {
r6->data[i30] = 6.2831853071795862 * w->data[i30];
}
emxInit_real_T(&digw, 2);
emxInit_creal_T(&s, 2);
rdivide(r6, Fs, digw);
/* Convert from Hz to rad/sample for computational purposes */
i30 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i30);
loop_ub = digw->size[0] * digw->size[1];
emxFree_real_T(&r6);
for (i30 = 0; i30 < loop_ub; i30++) {
s->data[i30].re = digw->data[i30] * 0.0;
s->data[i30].im = digw->data[i30];
}
emxInit_creal_T(&y, 2);
c_exp(s);
/* Digital frequency must be used for this calculation */
i30 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i30);
b2 = (y->size[1] == 0);
if (!b2) {
i30 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_creal_T(y, i30);
loop_ub = y->size[1];
for (i30 = 0; i30 < loop_ub; i30++) {
y->data[y->size[0] * i30].re = b[0];
y->data[y->size[0] * i30].im = 0.0;
}
for (k = 0; k < 14; k++) {
i30 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i30);
loop_ub = s->size[0] * s->size[1];
for (i30 = 0; i30 < loop_ub; i30++) {
s_re = s->data[i30].re * y->data[i30].re - s->data[i30].im * y->data[i30]
.im;
s_im = s->data[i30].re * y->data[i30].im + s->data[i30].im * y->data[i30]
.re;
y->data[i30].re = s_re + b[k + 1];
y->data[i30].im = s_im;
}
}
}
i30 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i30);
loop_ub = digw->size[0] * digw->size[1];
for (i30 = 0; i30 < loop_ub; i30++) {
s_re = digw->data[i30] * 0.0;
s_im = digw->data[i30];
s->data[i30].re = 14.0 * s_re;
s->data[i30].im = 14.0 * s_im;
}
emxFree_real_T(&digw);
c_exp(s);
b_rdivide(y, s, hh);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
emxFree_creal_T(&y);
emxFree_creal_T(&s);
}
/*
* LP2LP Lowpass to lowpass analog filter transformation. Codegen support
*
* This function is based on 'lp2lp' by The MathWorks Inc.
* Arguments : const emxArray_creal_T *a
* const emxArray_real_T *b
* double wo
* emxArray_creal_T *at
* emxArray_real_T *bt
* double *dt
* Return Type : void
*/
static void lp2lp_cg(const emxArray_creal_T *a, const emxArray_real_T *b, double
wo, emxArray_creal_T *at, emxArray_real_T *bt, double *dt)
{
int i58;
int loop_ub;
/* Transform lowpass to lowpass */
i58 = at->size[0] * at->size[1];
at->size[0] = a->size[0];
at->size[1] = a->size[1];
emxEnsureCapacity_creal_T(at, i58);
loop_ub = a->size[0] * a->size[1];
for (i58 = 0; i58 < loop_ub; i58++) {
at->data[i58].re = wo * a->data[i58].re;
at->data[i58].im = wo * a->data[i58].im;
}
i58 = bt->size[0];
bt->size[0] = b->size[0];
emxEnsureCapacity_real_T1(bt, i58);
loop_ub = b->size[0];
for (i58 = 0; i58 < loop_ub; i58++) {
bt->data[i58] = wo * b->data[i58];
}
*dt = 0.0;
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[7]
* const emxArray_real_T *w
* double Fs
* emxArray_creal_T *hh
* Return Type : void
*/
static void m_freqz_cg(const double b[7], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh)
{
emxArray_real_T *r7;
int i31;
int loop_ub;
emxArray_real_T *digw;
emxArray_creal_T *s;
emxArray_creal_T *y;
boolean_T b3;
int k;
double s_re;
double s_im;
emxInit_real_T(&r7, 2);
/* Cast to enforce precision rules */
/* Remaining are default or for advanced use */
/* Make b a row */
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
i31 = r7->size[0] * r7->size[1];
r7->size[0] = 1;
r7->size[1] = w->size[1];
emxEnsureCapacity_real_T(r7, i31);
loop_ub = w->size[0] * w->size[1];
for (i31 = 0; i31 < loop_ub; i31++) {
r7->data[i31] = 6.2831853071795862 * w->data[i31];
}
emxInit_real_T(&digw, 2);
emxInit_creal_T(&s, 2);
rdivide(r7, Fs, digw);
/* Convert from Hz to rad/sample for computational purposes */
i31 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i31);
loop_ub = digw->size[0] * digw->size[1];
emxFree_real_T(&r7);
for (i31 = 0; i31 < loop_ub; i31++) {
s->data[i31].re = digw->data[i31] * 0.0;
s->data[i31].im = digw->data[i31];
}
emxInit_creal_T(&y, 2);
c_exp(s);
/* Digital frequency must be used for this calculation */
i31 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i31);
b3 = (y->size[1] == 0);
if (!b3) {
i31 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_creal_T(y, i31);
loop_ub = y->size[1];
for (i31 = 0; i31 < loop_ub; i31++) {
y->data[y->size[0] * i31].re = b[0];
y->data[y->size[0] * i31].im = 0.0;
}
for (k = 0; k < 6; k++) {
i31 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i31);
loop_ub = s->size[0] * s->size[1];
for (i31 = 0; i31 < loop_ub; i31++) {
s_re = s->data[i31].re * y->data[i31].re - s->data[i31].im * y->data[i31]
.im;
s_im = s->data[i31].re * y->data[i31].im + s->data[i31].im * y->data[i31]
.re;
y->data[i31].re = s_re + b[k + 1];
y->data[i31].im = s_im;
}
}
}
i31 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i31);
loop_ub = digw->size[0] * digw->size[1];
for (i31 = 0; i31 < loop_ub; i31++) {
s_re = digw->data[i31] * 0.0;
s_im = digw->data[i31];
s->data[i31].re = 6.0 * s_re;
s->data[i31].im = 6.0 * s_im;
}
emxFree_real_T(&digw);
c_exp(s);
b_rdivide(y, s, hh);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
emxFree_creal_T(&y);
emxFree_creal_T(&s);
}
/*
* Arguments : double y
* Return Type : double
*/
static double mag2db(double y)
{
return 20.0 * log10(y);
}
/*
* Arguments : double a
* double b
* Return Type : double
*/
static double mpower(double a, double b)
{
return rt_powd_snf(a, b);
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const emxArray_real_T *b
* const emxArray_real_T *w
* double Fs
* emxArray_creal_T *hh
* Return Type : void
*/
static void n_freqz_cg(const emxArray_real_T *b, const emxArray_real_T *w,
double Fs, emxArray_creal_T *hh)
{
emxArray_real_T *y;
int b_idx_0;
int i32;
emxArray_real_T *r8;
emxArray_real_T *digw;
emxArray_creal_T *r9;
emxArray_creal_T *r10;
double b_y;
double re;
double im;
emxInit_real_T(&y, 2);
/* Cast to enforce precision rules */
/* Remaining are default or for advanced use */
/* Make b a row */
/* -------------------------------------------------------------------------- */
b_idx_0 = b->size[1];
i32 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = b_idx_0;
emxEnsureCapacity_real_T(y, i32);
for (i32 = 0; i32 < b_idx_0; i32++) {
y->data[y->size[0] * i32] = b->data[i32];
}
emxInit_real_T(&r8, 2);
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
i32 = r8->size[0] * r8->size[1];
r8->size[0] = 1;
r8->size[1] = w->size[1];
emxEnsureCapacity_real_T(r8, i32);
b_idx_0 = w->size[0] * w->size[1];
for (i32 = 0; i32 < b_idx_0; i32++) {
r8->data[i32] = 6.2831853071795862 * w->data[i32];
}
emxInit_real_T(&digw, 2);
emxInit_creal_T(&r9, 2);
rdivide(r8, Fs, digw);
/* Convert from Hz to rad/sample for computational purposes */
/* Digital frequency must be used for this calculation */
i32 = r9->size[0] * r9->size[1];
r9->size[0] = 1;
r9->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(r9, i32);
b_idx_0 = digw->size[0] * digw->size[1];
emxFree_real_T(&r8);
for (i32 = 0; i32 < b_idx_0; i32++) {
r9->data[i32].re = digw->data[i32] * 0.0;
r9->data[i32].im = digw->data[i32];
}
emxInit_creal_T(&r10, 2);
c_exp(r9);
j_polyval(y, r9, r10);
i32 = r9->size[0] * r9->size[1];
r9->size[0] = 1;
r9->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(r9, i32);
b_y = (double)y->size[1] - 1.0;
b_idx_0 = digw->size[0] * digw->size[1];
emxFree_real_T(&y);
for (i32 = 0; i32 < b_idx_0; i32++) {
re = digw->data[i32] * 0.0;
im = digw->data[i32];
r9->data[i32].re = b_y * re;
r9->data[i32].im = b_y * im;
}
emxFree_real_T(&digw);
c_exp(r9);
b_rdivide(r10, r9, hh);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
emxFree_creal_T(&r10);
emxFree_creal_T(&r9);
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[29]
* const emxArray_real_T *w
* double Fs
* emxArray_creal_T *hh
* Return Type : void
*/
static void o_freqz_cg(const double b[29], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh)
{
emxArray_real_T *r11;
int i34;
int loop_ub;
emxArray_real_T *digw;
emxArray_creal_T *s;
emxArray_creal_T *y;
boolean_T b5;
int k;
double s_re;
double s_im;
emxInit_real_T(&r11, 2);
/* Cast to enforce precision rules */
/* Remaining are default or for advanced use */
/* Make b a row */
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
i34 = r11->size[0] * r11->size[1];
r11->size[0] = 1;
r11->size[1] = w->size[1];
emxEnsureCapacity_real_T(r11, i34);
loop_ub = w->size[0] * w->size[1];
for (i34 = 0; i34 < loop_ub; i34++) {
r11->data[i34] = 6.2831853071795862 * w->data[i34];
}
emxInit_real_T(&digw, 2);
emxInit_creal_T(&s, 2);
rdivide(r11, Fs, digw);
/* Convert from Hz to rad/sample for computational purposes */
i34 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i34);
loop_ub = digw->size[0] * digw->size[1];
emxFree_real_T(&r11);
for (i34 = 0; i34 < loop_ub; i34++) {
s->data[i34].re = digw->data[i34] * 0.0;
s->data[i34].im = digw->data[i34];
}
emxInit_creal_T(&y, 2);
c_exp(s);
/* Digital frequency must be used for this calculation */
i34 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i34);
b5 = (y->size[1] == 0);
if (!b5) {
i34 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_creal_T(y, i34);
loop_ub = y->size[1];
for (i34 = 0; i34 < loop_ub; i34++) {
y->data[y->size[0] * i34].re = b[0];
y->data[y->size[0] * i34].im = 0.0;
}
for (k = 0; k < 28; k++) {
i34 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i34);
loop_ub = s->size[0] * s->size[1];
for (i34 = 0; i34 < loop_ub; i34++) {
s_re = s->data[i34].re * y->data[i34].re - s->data[i34].im * y->data[i34]
.im;
s_im = s->data[i34].re * y->data[i34].im + s->data[i34].im * y->data[i34]
.re;
y->data[i34].re = s_re + b[k + 1];
y->data[i34].im = s_im;
}
}
}
i34 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i34);
loop_ub = digw->size[0] * digw->size[1];
for (i34 = 0; i34 < loop_ub; i34++) {
s_re = digw->data[i34] * 0.0;
s_im = digw->data[i34];
s->data[i34].re = 28.0 * s_re;
s->data[i34].im = 28.0 * s_im;
}
emxFree_real_T(&digw);
c_exp(s);
b_rdivide(y, s, hh);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
emxFree_creal_T(&y);
emxFree_creal_T(&s);
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[13]
* const emxArray_real_T *w
* double Fs
* emxArray_creal_T *hh
* Return Type : void
*/
static void p_freqz_cg(const double b[13], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh)
{
emxArray_real_T *r12;
int i35;
int loop_ub;
emxArray_real_T *digw;
emxArray_creal_T *s;
emxArray_creal_T *y;
boolean_T b6;
int k;
double s_re;
double s_im;
emxInit_real_T(&r12, 2);
/* Cast to enforce precision rules */
/* Remaining are default or for advanced use */
/* Make b a row */
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
i35 = r12->size[0] * r12->size[1];
r12->size[0] = 1;
r12->size[1] = w->size[1];
emxEnsureCapacity_real_T(r12, i35);
loop_ub = w->size[0] * w->size[1];
for (i35 = 0; i35 < loop_ub; i35++) {
r12->data[i35] = 6.2831853071795862 * w->data[i35];
}
emxInit_real_T(&digw, 2);
emxInit_creal_T(&s, 2);
rdivide(r12, Fs, digw);
/* Convert from Hz to rad/sample for computational purposes */
i35 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i35);
loop_ub = digw->size[0] * digw->size[1];
emxFree_real_T(&r12);
for (i35 = 0; i35 < loop_ub; i35++) {
s->data[i35].re = digw->data[i35] * 0.0;
s->data[i35].im = digw->data[i35];
}
emxInit_creal_T(&y, 2);
c_exp(s);
/* Digital frequency must be used for this calculation */
i35 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i35);
b6 = (y->size[1] == 0);
if (!b6) {
i35 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_creal_T(y, i35);
loop_ub = y->size[1];
for (i35 = 0; i35 < loop_ub; i35++) {
y->data[y->size[0] * i35].re = b[0];
y->data[y->size[0] * i35].im = 0.0;
}
for (k = 0; k < 12; k++) {
i35 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i35);
loop_ub = s->size[0] * s->size[1];
for (i35 = 0; i35 < loop_ub; i35++) {
s_re = s->data[i35].re * y->data[i35].re - s->data[i35].im * y->data[i35]
.im;
s_im = s->data[i35].re * y->data[i35].im + s->data[i35].im * y->data[i35]
.re;
y->data[i35].re = s_re + b[k + 1];
y->data[i35].im = s_im;
}
}
}
i35 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i35);
loop_ub = digw->size[0] * digw->size[1];
for (i35 = 0; i35 < loop_ub; i35++) {
s_re = digw->data[i35] * 0.0;
s_im = digw->data[i35];
s->data[i35].re = 12.0 * s_re;
s->data[i35].im = 12.0 * s_im;
}
emxFree_real_T(&digw);
c_exp(s);
b_rdivide(y, s, hh);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
emxFree_creal_T(&y);
emxFree_creal_T(&s);
}
/*
* Arguments : const emxArray_creal_T *x
* emxArray_creal_T *c
* Return Type : void
*/
static void poly(const emxArray_creal_T *x, emxArray_creal_T *c)
{
emxArray_creal_T *r2;
emxInit_creal_T1(&r2, 1);
eig(x, r2);
vector_poly(r2, c);
emxFree_creal_T(&r2);
}
/*
* Arguments : const double p[15]
* const creal_T x[2048]
* creal_T y[2048]
* Return Type : void
*/
static void polyval(const double p[15], const creal_T x[2048], creal_T y[2048])
{
int i9;
int k;
double x_im;
for (i9 = 0; i9 < 2048; i9++) {
y[i9].re = p[0];
y[i9].im = 0.0;
}
for (k = 0; k < 14; k++) {
for (i9 = 0; i9 < 2048; i9++) {
x_im = x[i9].re * y[i9].im + x[i9].im * y[i9].re;
y[i9].re = (x[i9].re * y[i9].re - x[i9].im * y[i9].im) + p[k + 1];
y[i9].im = x_im;
}
}
}
/*
* Arguments : const double a[2048]
* double y[2048]
* Return Type : void
*/
static void power(const double a[2048], double y[2048])
{
int k;
for (k = 0; k < 2048; k++) {
y[k] = rt_powd_snf(a[k], 3.0);
}
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[57]
* const emxArray_real_T *w
* double Fs
* emxArray_creal_T *hh
* Return Type : void
*/
static void q_freqz_cg(const double b[57], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh)
{
emxArray_real_T *r13;
int i36;
int loop_ub;
emxArray_real_T *digw;
emxArray_creal_T *s;
emxArray_creal_T *y;
boolean_T b7;
int k;
double s_re;
double s_im;
emxInit_real_T(&r13, 2);
/* Cast to enforce precision rules */
/* Remaining are default or for advanced use */
/* Make b a row */
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
i36 = r13->size[0] * r13->size[1];
r13->size[0] = 1;
r13->size[1] = w->size[1];
emxEnsureCapacity_real_T(r13, i36);
loop_ub = w->size[0] * w->size[1];
for (i36 = 0; i36 < loop_ub; i36++) {
r13->data[i36] = 6.2831853071795862 * w->data[i36];
}
emxInit_real_T(&digw, 2);
emxInit_creal_T(&s, 2);
rdivide(r13, Fs, digw);
/* Convert from Hz to rad/sample for computational purposes */
i36 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i36);
loop_ub = digw->size[0] * digw->size[1];
emxFree_real_T(&r13);
for (i36 = 0; i36 < loop_ub; i36++) {
s->data[i36].re = digw->data[i36] * 0.0;
s->data[i36].im = digw->data[i36];
}
emxInit_creal_T(&y, 2);
c_exp(s);
/* Digital frequency must be used for this calculation */
i36 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i36);
b7 = (y->size[1] == 0);
if (!b7) {
i36 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_creal_T(y, i36);
loop_ub = y->size[1];
for (i36 = 0; i36 < loop_ub; i36++) {
y->data[y->size[0] * i36].re = b[0];
y->data[y->size[0] * i36].im = 0.0;
}
for (k = 0; k < 56; k++) {
i36 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i36);
loop_ub = s->size[0] * s->size[1];
for (i36 = 0; i36 < loop_ub; i36++) {
s_re = s->data[i36].re * y->data[i36].re - s->data[i36].im * y->data[i36]
.im;
s_im = s->data[i36].re * y->data[i36].im + s->data[i36].im * y->data[i36]
.re;
y->data[i36].re = s_re + b[k + 1];
y->data[i36].im = s_im;
}
}
}
i36 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i36);
loop_ub = digw->size[0] * digw->size[1];
for (i36 = 0; i36 < loop_ub; i36++) {
s_re = digw->data[i36] * 0.0;
s_im = digw->data[i36];
s->data[i36].re = 56.0 * s_re;
s->data[i36].im = 56.0 * s_im;
}
emxFree_real_T(&digw);
c_exp(s);
b_rdivide(y, s, hh);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
emxFree_creal_T(&y);
emxFree_creal_T(&s);
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[43]
* const emxArray_real_T *w
* double Fs
* emxArray_creal_T *hh
* Return Type : void
*/
static void r_freqz_cg(const double b[43], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh)
{
emxArray_real_T *r14;
int i37;
int loop_ub;
emxArray_real_T *digw;
emxArray_creal_T *s;
emxArray_creal_T *y;
boolean_T b8;
int k;
double s_re;
double s_im;
emxInit_real_T(&r14, 2);
/* Cast to enforce precision rules */
/* Remaining are default or for advanced use */
/* Make b a row */
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
i37 = r14->size[0] * r14->size[1];
r14->size[0] = 1;
r14->size[1] = w->size[1];
emxEnsureCapacity_real_T(r14, i37);
loop_ub = w->size[0] * w->size[1];
for (i37 = 0; i37 < loop_ub; i37++) {
r14->data[i37] = 6.2831853071795862 * w->data[i37];
}
emxInit_real_T(&digw, 2);
emxInit_creal_T(&s, 2);
rdivide(r14, Fs, digw);
/* Convert from Hz to rad/sample for computational purposes */
i37 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i37);
loop_ub = digw->size[0] * digw->size[1];
emxFree_real_T(&r14);
for (i37 = 0; i37 < loop_ub; i37++) {
s->data[i37].re = digw->data[i37] * 0.0;
s->data[i37].im = digw->data[i37];
}
emxInit_creal_T(&y, 2);
c_exp(s);
/* Digital frequency must be used for this calculation */
i37 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i37);
b8 = (y->size[1] == 0);
if (!b8) {
i37 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_creal_T(y, i37);
loop_ub = y->size[1];
for (i37 = 0; i37 < loop_ub; i37++) {
y->data[y->size[0] * i37].re = b[0];
y->data[y->size[0] * i37].im = 0.0;
}
for (k = 0; k < 42; k++) {
i37 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i37);
loop_ub = s->size[0] * s->size[1];
for (i37 = 0; i37 < loop_ub; i37++) {
s_re = s->data[i37].re * y->data[i37].re - s->data[i37].im * y->data[i37]
.im;
s_im = s->data[i37].re * y->data[i37].im + s->data[i37].im * y->data[i37]
.re;
y->data[i37].re = s_re + b[k + 1];
y->data[i37].im = s_im;
}
}
}
i37 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i37);
loop_ub = digw->size[0] * digw->size[1];
for (i37 = 0; i37 < loop_ub; i37++) {
s_re = digw->data[i37] * 0.0;
s_im = digw->data[i37];
s->data[i37].re = 42.0 * s_re;
s->data[i37].im = 42.0 * s_im;
}
emxFree_real_T(&digw);
c_exp(s);
b_rdivide(y, s, hh);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
emxFree_creal_T(&y);
emxFree_creal_T(&s);
}
/*
* Arguments : const emxArray_real_T *x
* double y
* emxArray_real_T *z
* Return Type : void
*/
static void rdivide(const emxArray_real_T *x, double y, emxArray_real_T *z)
{
int i27;
int loop_ub;
i27 = z->size[0] * z->size[1];
z->size[0] = 1;
z->size[1] = x->size[1];
emxEnsureCapacity_real_T(z, i27);
loop_ub = x->size[0] * x->size[1];
for (i27 = 0; i27 < loop_ub; i27++) {
z->data[i27] = x->data[i27] / y;
}
}
/*
* Arguments : const creal_T y
* Return Type : creal_T
*/
static creal_T recip(const creal_T y)
{
creal_T z;
double brm;
double bim;
double d;
brm = fabs(y.re);
bim = fabs(y.im);
if (y.im == 0.0) {
z.re = 1.0 / y.re;
z.im = 0.0;
} else if (y.re == 0.0) {
z.re = 0.0;
z.im = -1.0 / y.im;
} else if (brm > bim) {
bim = y.im / y.re;
d = y.re + bim * y.im;
z.re = 1.0 / d;
z.im = -bim / d;
} else if (brm == bim) {
bim = 0.5;
if (y.re < 0.0) {
bim = -0.5;
}
d = 0.5;
if (y.im < 0.0) {
d = -0.5;
}
z.re = bim / brm;
z.im = -d / brm;
} else {
bim = y.re / y.im;
d = y.im + bim * y.re;
z.re = bim / d;
z.im = -1.0 / d;
}
return z;
}
/*
* REMEZDD Lagrange interpolation coefficients.
* Arguments : double k
* double n
* double m
* const emxArray_real_T *x
* Return Type : double
*/
static double remezdd(double k, double n, double m, const emxArray_real_T *x)
{
double y;
int l;
emxArray_real_T *xx;
emxArray_int32_T *r23;
int i51;
int i;
int end;
double b_x;
int vlen;
/* */
/* Author: T. Krauss 1993 */
/* Was Revision: 1.4, Date: 1994/01/25 17:59:44 */
y = 1.0;
l = 0;
emxInit_real_T(&xx, 2);
emxInit_int32_T(&r23, 2);
while (l <= (int)m - 1) {
if ((m == 0.0) || (((m > 0.0) && (1.0 + (double)l > n)) || ((0.0 > m) && (n >
1.0 + (double)l)))) {
i51 = 1;
i = 1;
end = 0;
} else {
i51 = l + 1;
i = (int)m;
end = (int)n;
}
b_x = x->data[(int)k - 1];
vlen = xx->size[0] * xx->size[1];
xx->size[0] = 1;
xx->size[1] = div_s32_floor(end - i51, i) + 1;
emxEnsureCapacity_real_T(xx, vlen);
vlen = div_s32_floor(end - i51, i);
for (end = 0; end <= vlen; end++) {
xx->data[xx->size[0] * end] = 2.0 * (b_x - x->data[(i51 + i * end) - 1]);
}
end = xx->size[1] - 1;
vlen = 0;
for (i = 0; i <= end; i++) {
if (xx->data[i] != 0.0) {
vlen++;
}
}
i51 = r23->size[0] * r23->size[1];
r23->size[0] = 1;
r23->size[1] = vlen;
emxEnsureCapacity_int32_T(r23, i51);
vlen = 0;
for (i = 0; i <= end; i++) {
if (xx->data[i] != 0.0) {
r23->data[vlen] = i + 1;
vlen++;
}
}
vlen = r23->size[1];
if (r23->size[1] == 0) {
b_x = 1.0;
} else {
b_x = xx->data[r23->data[0] - 1];
for (i = 2; i <= vlen; i++) {
b_x *= xx->data[r23->data[r23->size[0] * (i - 1)] - 1];
}
}
y *= b_x;
l++;
}
emxFree_int32_T(&r23);
emxFree_real_T(&xx);
y = 1.0 / y;
/* EOF */
return y;
}
/*
* remezm function
* Inputs
* nfilt - filter length
* edge - vector of band edges (between 0 and .5)
* grid - frequency grid (between 0 and .5)
* des - desired function on frequency grid
* wt - weight function on frequency grid
* neg == 1 ==> antisymmetric imp resp,
* == 0 ==> symmetric imp resp
* Outputs
* h - coefficients of basis functions
* dev - computed error
* iext - indices of extremal frequencies
* Arguments : double nfilt
* const double edge[4]
* const emxArray_real_T *grid
* emxArray_real_T *des
* emxArray_real_T *wt
* emxArray_real_T *h
* double *dev
* boolean_T *valid
* Return Type : void
*/
static void remezm(double nfilt, const double edge[4], const emxArray_real_T
*grid, emxArray_real_T *des, emxArray_real_T *wt,
emxArray_real_T *h, double *dev, boolean_T *valid)
{
boolean_T b_valid;
double nodd;
double nfcns;
int varargin_2;
int ngrid;
emxArray_real_T *j;
emxArray_real_T *x2;
int i44;
double temp;
int loop_ub;
emxArray_real_T *iext;
emxArray_real_T *y;
emxArray_real_T *x;
int ixstart;
int flag;
double comp;
double dtemp;
double b_y1;
int luck;
int nut1;
double err;
double b_dev;
double devl;
emxArray_real_T *ad;
int niter;
double jchnge;
double d1;
emxArray_real_T *l;
emxArray_int32_T *r21;
emxArray_real_T *b;
emxArray_real_T *a;
emxArray_real_T *b_wt;
emxArray_int8_T *r22;
emxArray_int32_T *b_iext;
emxArray_real_T *mtmp;
boolean_T guard1 = false;
int exitg1;
double k1;
int nut;
double b_j;
double b_l;
int nu;
double varargin_1[2];
double dnum;
double kup;
int i45;
int i46;
int i47;
int i48;
int i49;
boolean_T guard2 = false;
double b_y;
int flag34;
int exitg3;
boolean_T exitg2;
boolean_T exitg4;
/* */
b_valid = true;
nodd = rt_remd_snf(nfilt, 2.0);
/* nodd == 1 ==> filter length is odd */
/* nodd == 0 ==> filter length is even */
nfcns = nfilt / 2.0;
b_fix(&nfcns);
if (nodd == 1.0) {
nfcns++;
}
varargin_2 = grid->size[1];
ngrid = grid->size[1];
emxInit_real_T(&j, 2);
emxInit_real_T(&x2, 2);
if (nodd != 1.0) {
i44 = x2->size[0] * x2->size[1];
x2->size[0] = 1;
x2->size[1] = grid->size[1];
emxEnsureCapacity_real_T(x2, i44);
loop_ub = grid->size[0] * grid->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
x2->data[i44] = 3.1415926535897931 * grid->data[i44];
}
b_cos(x2);
c_rdivide(des, x2, j);
i44 = des->size[0] * des->size[1];
des->size[0] = 1;
des->size[1] = j->size[1];
emxEnsureCapacity_real_T(des, i44);
loop_ub = j->size[0] * j->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
des->data[i44] = j->data[i44];
}
i44 = x2->size[0] * x2->size[1];
x2->size[0] = 1;
x2->size[1] = grid->size[1];
emxEnsureCapacity_real_T(x2, i44);
loop_ub = grid->size[0] * grid->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
x2->data[i44] = 3.1415926535897931 * grid->data[i44];
}
b_cos(x2);
i44 = wt->size[0] * wt->size[1];
wt->size[0] = 1;
emxEnsureCapacity_real_T(wt, i44);
ixstart = wt->size[0];
flag = wt->size[1];
loop_ub = ixstart * flag;
for (i44 = 0; i44 < loop_ub; i44++) {
wt->data[i44] *= x2->data[i44];
}
}
temp = ((double)grid->size[1] - 1.0) / nfcns;
if (rtIsNaN(nfcns)) {
i44 = j->size[0] * j->size[1];
j->size[0] = 1;
j->size[1] = 1;
emxEnsureCapacity_real_T(j, i44);
j->data[0] = rtNaN;
} else if (nfcns < 1.0) {
i44 = j->size[0] * j->size[1];
j->size[0] = 1;
j->size[1] = 0;
emxEnsureCapacity_real_T(j, i44);
} else if (rtIsInf(nfcns) && (1.0 == nfcns)) {
i44 = j->size[0] * j->size[1];
j->size[0] = 1;
j->size[1] = 1;
emxEnsureCapacity_real_T(j, i44);
j->data[0] = rtNaN;
} else {
i44 = j->size[0] * j->size[1];
j->size[0] = 1;
j->size[1] = (int)floor(nfcns - 1.0) + 1;
emxEnsureCapacity_real_T(j, i44);
loop_ub = (int)floor(nfcns - 1.0);
for (i44 = 0; i44 <= loop_ub; i44++) {
j->data[j->size[0] * i44] = 1.0 + (double)i44;
}
}
i44 = x2->size[0] * x2->size[1];
x2->size[0] = 1;
x2->size[1] = j->size[1] + 1;
emxEnsureCapacity_real_T(x2, i44);
loop_ub = j->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
x2->data[x2->size[0] * i44] = temp * (j->data[j->size[0] * i44] - 1.0) + 1.0;
}
emxInit_real_T1(&iext, 1);
x2->data[x2->size[0] * j->size[1]] = grid->size[1];
c_fix(x2);
i44 = iext->size[0];
iext->size[0] = x2->size[1] + 1;
emxEnsureCapacity_real_T1(iext, i44);
loop_ub = x2->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
iext->data[i44] = x2->data[x2->size[0] * i44];
}
emxInit_real_T(&y, 2);
emxInit_real_T(&x, 2);
iext->data[x2->size[1]] = 0.0;
/* Remez exchange loop */
comp = -1.0;
dtemp = -1.0;
b_y1 = -1.0;
luck = -1;
nut1 = -1;
err = -1.0;
i44 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = 1;
emxEnsureCapacity_real_T(y, i44);
y->data[0] = -1.0;
b_dev = -1.0;
devl = -1.0;
i44 = x->size[0] * x->size[1];
x->size[0] = 1;
x->size[1] = (int)(nfcns + 1.0);
emxEnsureCapacity_real_T(x, i44);
loop_ub = (int)(nfcns + 1.0);
for (i44 = 0; i44 < loop_ub; i44++) {
x->data[i44] = 0.0;
}
emxInit_real_T(&ad, 2);
niter = 0;
jchnge = 1.0;
d1 = (nfcns - 1.0) / 15.0;
b_fix(&d1);
i44 = ad->size[0] * ad->size[1];
ad->size[0] = 1;
ad->size[1] = (int)(nfcns + 1.0);
emxEnsureCapacity_real_T(ad, i44);
loop_ub = (int)(nfcns + 1.0);
for (i44 = 0; i44 < loop_ub; i44++) {
ad->data[i44] = 0.0;
}
/* index manager(s) */
emxInit_real_T(&l, 2);
emxInit_int32_T(&r21, 2);
emxInit_real_T1(&b, 1);
emxInit_real_T(&a, 2);
emxInit_real_T(&b_wt, 2);
emxInit_int8_T(&r22, 2);
emxInit_int32_T1(&b_iext, 1);
emxInit_real_T1(&mtmp, 1);
guard1 = false;
do {
exitg1 = 0;
if (jchnge > 0.0) {
iext->data[(int)((nfcns + 1.0) + 1.0) - 1] = (double)varargin_2 + 1.0;
niter++;
if (niter > 250) {
guard1 = true;
exitg1 = 1;
} else {
if (1.0 > nfcns + 1.0) {
loop_ub = 0;
} else {
loop_ub = (int)(nfcns + 1.0);
}
i44 = l->size[0] * l->size[1];
l->size[0] = 1;
l->size[1] = loop_ub;
emxEnsureCapacity_real_T(l, i44);
for (i44 = 0; i44 < loop_ub; i44++) {
l->data[l->size[0] * i44] = iext->data[i44];
}
i44 = x->size[0] * x->size[1];
x->size[0] = 1;
x->size[1] = l->size[1];
emxEnsureCapacity_real_T(x, i44);
nut = l->size[0] * l->size[1];
for (i44 = 0; i44 < nut; i44++) {
x->data[i44] = 6.2831853071795862 * grid->data[(int)l->data[i44] - 1];
}
b_cos(x);
for (ixstart = 0; ixstart < (int)(nfcns + 1.0); ixstart++) {
ad->data[ixstart] = remezdd(1.0 + (double)ixstart, nfcns + 1.0, d1 +
1.0, x);
}
for (i44 = 0; i44 < 2; i44++) {
varargin_1[i44] = ad->size[i44];
}
i44 = j->size[0] * j->size[1];
j->size[0] = 1;
j->size[1] = (int)varargin_1[1];
emxEnsureCapacity_real_T(j, i44);
nut = (int)varargin_1[1];
for (i44 = 0; i44 < nut; i44++) {
j->data[i44] = 1.0;
}
if (2.0 > nfcns + 1.0) {
i44 = 0;
i45 = 1;
i46 = 0;
i47 = 0;
i48 = 1;
} else {
i44 = 1;
i45 = 2;
i46 = (int)(nfcns + 1.0);
i47 = 1;
i48 = 2;
}
i49 = r22->size[0] * r22->size[1];
r22->size[0] = 1;
r22->size[1] = (int)varargin_1[1];
emxEnsureCapacity_int8_T(r22, i49);
nut = (int)varargin_1[1];
for (i49 = 0; i49 < nut; i49++) {
r22->data[r22->size[0] * i49] = 1;
}
nut = div_s32_floor((i46 - i44) - 1, i45);
for (i46 = 0; i46 <= nut; i46++) {
j->data[i47 + i48 * i46] = -(double)r22->data[i44 + i45 * i46];
}
i44 = b->size[0];
b->size[0] = l->size[1];
emxEnsureCapacity_real_T1(b, i44);
nut = l->size[1];
for (i44 = 0; i44 < nut; i44++) {
b->data[i44] = des->data[(int)l->data[l->size[0] * i44] - 1];
}
guard2 = false;
if (ad->size[1] == 1) {
guard2 = true;
} else {
i44 = b_iext->size[0];
b_iext->size[0] = loop_ub;
emxEnsureCapacity_int32_T1(b_iext, i44);
for (i44 = 0; i44 < loop_ub; i44++) {
b_iext->data[i44] = (int)iext->data[i44];
}
if (b_iext->size[0] == 1) {
guard2 = true;
} else {
dnum = 0.0;
for (i44 = 0; i44 < ad->size[1]; i44++) {
dnum += ad->data[ad->size[0] * i44] * b->data[i44];
}
}
}
if (guard2) {
dnum = 0.0;
for (i44 = 0; i44 < ad->size[1]; i44++) {
dnum += ad->data[ad->size[0] * i44] * b->data[i44];
}
}
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = l->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = l->size[0] * l->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = wt->data[(int)l->data[i44] - 1];
}
c_rdivide(ad, b_wt, x2);
i44 = b->size[0];
b->size[0] = x2->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = x2->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = x2->data[x2->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
temp = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
temp += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
temp = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
temp += j->data[j->size[0] * i44] * b->data[i44];
}
}
b_dev = dnum / temp;
nu = 1;
if (b_dev > 0.0) {
nu = -1;
}
b_dev *= -(double)nu;
temp = (double)nu * b_dev;
i44 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = j->size[1];
emxEnsureCapacity_real_T(a, i44);
loop_ub = j->size[0] * j->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
a->data[i44] = temp * j->data[i44];
}
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = l->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = l->size[0] * l->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = wt->data[(int)l->data[i44] - 1];
}
c_rdivide(a, b_wt, x2);
i44 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = l->size[1];
emxEnsureCapacity_real_T(y, i44);
loop_ub = l->size[0] * l->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
y->data[i44] = des->data[(int)l->data[i44] - 1] + x2->data[i44];
}
if (b_dev <= devl) {
/* warning(message('signal:firpm:DidNotConverge',niter)) */
printf("%s\n", "DidNotConverge");
fflush(stdout);
i44 = h->size[0] * h->size[1];
h->size[0] = (int)nfilt;
h->size[1] = 1;
emxEnsureCapacity_real_T(h, i44);
loop_ub = (int)nfilt;
for (i44 = 0; i44 < loop_ub; i44++) {
h->data[i44] = 0.0;
}
b_dev = -1.0;
/* iext */
b_valid = false;
exitg1 = 1;
} else {
devl = b_dev;
jchnge = 0.0;
k1 = iext->data[0];
dnum = iext->data[(int)(nfcns + 1.0) - 1];
temp = 0.0;
nut = -nu;
b_j = 1.0;
flag34 = 1;
while (b_j < (nfcns + 1.0) + 1.0) {
kup = iext->data[(int)(unsigned int)b_j];
b_l = iext->data[(int)b_j - 1] + 1.0;
nut = -nut;
if (b_j == 2.0) {
b_y1 = comp;
}
comp = b_dev;
flag = 1;
if (iext->data[(int)b_j - 1] + 1.0 < iext->data[(int)(b_j + 1.0) - 1]) {
/* gee */
dtemp = cos(6.2831853071795862 * grid->data[(int)(iext->data[(int)
b_j - 1] + 1.0) - 1]);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = x->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = x->size[0] * x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = dtemp - x->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
err = (b_y / dtemp - des->data[(int)(iext->data[(int)b_j - 1] +
1.0) - 1]) * wt->data[(int)(iext->data[(int)b_j - 1] + 1.0)
- 1];
dtemp = (double)nut * err - b_dev;
if (dtemp > 0.0) {
comp = (double)nut * err;
b_l = (iext->data[(int)b_j - 1] + 1.0) + 1.0;
exitg2 = false;
while ((!exitg2) && (b_l < kup)) {
/* gee */
dtemp = cos(6.2831853071795862 * grid->data[(int)b_l - 1]);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = x->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = x->size[0] * x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = dtemp - x->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
err = (b_y / dtemp - des->data[(int)b_l - 1]) * wt->data[(int)
b_l - 1];
dtemp = (double)nut * err - comp;
if (dtemp > 0.0) {
comp = (double)nut * err;
b_l++;
} else {
exitg2 = true;
}
}
iext->data[(int)b_j - 1] = b_l - 1.0;
b_j++;
temp = b_l - 1.0;
jchnge++;
flag = 0;
}
}
if (flag != 0) {
b_l -= 2.0;
exitg2 = false;
while ((!exitg2) && (b_l > temp)) {
/* gee */
dtemp = cos(6.2831853071795862 * grid->data[(int)b_l - 1]);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = x->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = x->size[0] * x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = dtemp - x->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
err = (b_y / dtemp - des->data[(int)b_l - 1]) * wt->data[(int)
b_l - 1];
dtemp = (double)nut * err - comp;
if ((dtemp > 0.0) || (jchnge > 0.0)) {
exitg2 = true;
} else {
b_l--;
}
}
if (b_l <= temp) {
b_l = iext->data[(int)b_j - 1] + 1.0;
if (jchnge > 0.0) {
iext->data[(int)b_j - 1] = (iext->data[(int)b_j - 1] + 1.0) -
1.0;
b_j++;
temp = b_l - 1.0;
jchnge++;
} else {
b_l = (iext->data[(int)b_j - 1] + 1.0) + 1.0;
exitg2 = false;
while ((!exitg2) && (b_l < kup)) {
/* gee */
dtemp = cos(6.2831853071795862 * grid->data[(int)b_l - 1]);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = x->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = x->size[0] * x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = dtemp - x->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
err = (b_y / dtemp - des->data[(int)b_l - 1]) * wt->data
[(int)b_l - 1];
dtemp = (double)nut * err - comp;
if (dtemp > 0.0) {
exitg2 = true;
} else {
b_l++;
}
}
if ((b_l < kup) && (dtemp > 0.0)) {
comp = (double)nut * err;
b_l++;
exitg2 = false;
while ((!exitg2) && (b_l < kup)) {
/* gee */
dtemp = cos(6.2831853071795862 * grid->data[(int)b_l - 1]);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = x->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = x->size[0] * x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = dtemp - x->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
err = (b_y / dtemp - des->data[(int)b_l - 1]) * wt->data
[(int)b_l - 1];
dtemp = (double)nut * err - comp;
if (dtemp > 0.0) {
comp = (double)nut * err;
b_l++;
} else {
exitg2 = true;
}
}
iext->data[(int)b_j - 1] = b_l - 1.0;
b_j++;
temp = b_l - 1.0;
jchnge = 1.0;
} else {
temp = iext->data[(int)b_j - 1];
b_j++;
}
}
} else if (dtemp > 0.0) {
comp = (double)nut * err;
b_l--;
exitg2 = false;
while ((!exitg2) && (b_l > temp)) {
/* gee */
dtemp = cos(6.2831853071795862 * grid->data[(int)b_l - 1]);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = x->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = x->size[0] * x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = dtemp - x->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
err = (b_y / dtemp - des->data[(int)b_l - 1]) * wt->data[(int)
b_l - 1];
dtemp = (double)nut * err - comp;
if (dtemp > 0.0) {
comp = (double)nut * err;
b_l--;
} else {
exitg2 = true;
}
}
temp = iext->data[(int)b_j - 1];
iext->data[(int)b_j - 1] = b_l + 1.0;
b_j++;
jchnge++;
} else {
temp = iext->data[(int)b_j - 1];
b_j++;
}
}
}
do {
exitg3 = 0;
if (b_j == (nfcns + 1.0) + 1.0) {
varargin_1[1] = iext->data[0];
ixstart = 1;
if (rtIsNaN(k1)) {
flag = 2;
exitg2 = false;
while ((!exitg2) && (flag < 3)) {
ixstart = 2;
if (!rtIsNaN(varargin_1[1])) {
k1 = varargin_1[1];
exitg2 = true;
} else {
flag = 3;
}
}
}
if ((ixstart < 2) && (varargin_1[1] < k1)) {
k1 = varargin_1[1];
}
varargin_1[1] = iext->data[(int)(nfcns + 1.0) - 1];
ixstart = 1;
if (rtIsNaN(dnum)) {
flag = 2;
exitg2 = false;
while ((!exitg2) && (flag < 3)) {
ixstart = 2;
if (!rtIsNaN(varargin_1[1])) {
dnum = varargin_1[1];
exitg2 = true;
} else {
flag = 3;
}
}
}
if ((ixstart < 2) && (varargin_1[1] > dnum)) {
dnum = varargin_1[1];
}
nut1 = nut;
nut = -nu;
comp *= 1.00001;
luck = 1;
flag = 1;
b_l = 1.0;
exitg2 = false;
while ((!exitg2) && (b_l < k1)) {
/* gee */
dtemp = cos(6.2831853071795862 * grid->data[(int)b_l - 1]);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = x->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = x->size[0] * x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = dtemp - x->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
err = (b_y / dtemp - des->data[(int)b_l - 1]) * wt->data[(int)
b_l - 1];
dtemp = err * -(double)nu - comp;
if (dtemp > 0.0) {
comp = -(double)nu * err;
b_l++;
exitg4 = false;
while ((!exitg4) && (b_l < k1)) {
/* gee */
dtemp = cos(6.2831853071795862 * grid->data[(int)b_l - 1]);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = x->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = x->size[0] * x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = dtemp - x->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
err = (b_y / dtemp - des->data[(int)b_l - 1]) * wt->data
[(int)b_l - 1];
dtemp = -(double)nu * err - comp;
if (dtemp > 0.0) {
comp = -(double)nu * err;
b_l++;
} else {
exitg4 = true;
}
}
iext->data[(int)((nfcns + 1.0) + 1.0) - 1] = b_l - 1.0;
b_j = ((nfcns + 1.0) + 1.0) + 1.0;
jchnge++;
flag = 0;
exitg2 = true;
} else {
b_l++;
}
}
if (flag != 0) {
luck = 6;
nut = -nut1;
comp = b_y1 * 1.00001;
b_l = ((double)ngrid + 1.0) - 1.0;
exitg2 = false;
while ((!exitg2) && (b_l > dnum)) {
/* gee */
dtemp = cos(6.2831853071795862 * grid->data[(int)b_l - 1]);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = x->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = x->size[0] * x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = dtemp - x->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
err = (b_y / dtemp - des->data[(int)b_l - 1]) * wt->data[(int)
b_l - 1];
dtemp = err * -(double)nut1 - comp;
if (dtemp > 0.0) {
comp = -(double)nut1 * err;
luck = 16;
b_l--;
exitg4 = false;
while ((!exitg4) && (b_l > dnum)) {
/* gee */
dtemp = cos(6.2831853071795862 * grid->data[(int)b_l - 1]);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = x->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = x->size[0] * x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = dtemp - x->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
err = (b_y / dtemp - des->data[(int)b_l - 1]) * wt->data
[(int)b_l - 1];
dtemp = -(double)nut1 * err - comp;
if (dtemp > 0.0) {
comp = -(double)nut1 * err;
b_l--;
} else {
exitg4 = true;
}
}
iext->data[(int)((nfcns + 1.0) + 1.0) - 1] = b_l + 1.0;
b_j = ((nfcns + 1.0) + 1.0) + 1.0;
jchnge++;
flag = 0;
exitg2 = true;
} else {
b_l--;
}
}
if (flag != 0) {
flag34 = 0;
if (luck != 6) {
temp = (nfcns + 1.0) - nfcns;
if (2.0 > temp) {
i44 = -2;
i45 = 0;
} else {
i44 = -1;
i45 = (int)temp;
}
temp = (nfcns + 1.0) - nfcns;
if (temp > (nfcns + 1.0) - 1.0) {
i46 = 1;
i47 = 0;
} else {
i46 = (int)temp;
i47 = (int)((nfcns + 1.0) - 1.0);
}
/* Update index */
temp = (nfcns + 1.0) - nfcns;
if (2.0 > temp) {
i48 = -2;
i49 = 0;
} else {
i48 = -1;
i49 = (int)temp;
}
temp = (nfcns + 1.0) - nfcns;
if (temp > (nfcns + 1.0) - 1.0) {
ixstart = 1;
flag = 0;
} else {
ixstart = (int)temp;
flag = (int)((nfcns + 1.0) - 1.0);
}
nu = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = ((i45 - i44) + i47) - i46;
emxEnsureCapacity_real_T(b_wt, nu);
loop_ub = i45 - i44;
for (nu = 0; nu <= loop_ub - 3; nu++) {
b_wt->data[b_wt->size[0] * (nu + 1)] = iext->data[(i44 +
nu) + 2];
}
loop_ub = i47 - i46;
for (i47 = 0; i47 <= loop_ub; i47++) {
b_wt->data[b_wt->size[0] * (((i47 + i45) - i44) - 1)] =
iext->data[(i46 + i47) - 1];
}
loop_ub = b_wt->size[1];
i44 = r21->size[0] * r21->size[1];
r21->size[0] = 1;
r21->size[1] = loop_ub;
emxEnsureCapacity_int32_T(r21, i44);
for (i44 = 0; i44 < loop_ub; i44++) {
r21->data[r21->size[0] * i44] = i44;
}
i44 = mtmp->size[0];
mtmp->size[0] = ((i49 - i48) + flag) - ixstart;
emxEnsureCapacity_real_T1(mtmp, i44);
mtmp->data[0] = k1;
loop_ub = i49 - i48;
for (i44 = 0; i44 <= loop_ub - 3; i44++) {
mtmp->data[i44 + 1] = iext->data[(i48 + i44) + 2];
}
loop_ub = flag - ixstart;
for (i44 = 0; i44 <= loop_ub; i44++) {
mtmp->data[((i44 + i49) - i48) - 1] = iext->data[(ixstart
+ i44) - 1];
}
loop_ub = r21->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
iext->data[r21->data[r21->size[0] * i44]] = mtmp->data
[(*(int (*)[2])r21->size)[0] * i44];
}
jchnge++;
}
exitg3 = 1;
}
}
} else {
exitg3 = 1;
}
} while (exitg3 == 0);
if ((flag34 != 0) && (b_j > (nfcns + 1.0) + 1.0)) {
if (luck > 9) {
if (2.0 > nfcns + 1.0) {
i44 = 0;
i45 = 0;
} else {
i44 = 1;
i45 = (int)(nfcns + 1.0);
}
if (nfcns + 1.0 > (nfcns + 1.0) - 1.0) {
i46 = 0;
i47 = 0;
} else {
i46 = (int)(nfcns + 1.0) - 1;
i47 = (int)((nfcns + 1.0) - 1.0);
}
/* Update index */
if (2.0 > nfcns + 1.0) {
i48 = 0;
i49 = 0;
} else {
i48 = 1;
i49 = (int)(nfcns + 1.0);
}
if (nfcns + 1.0 > (nfcns + 1.0) - 1.0) {
ixstart = 0;
flag = 0;
} else {
ixstart = (int)(nfcns + 1.0) - 1;
flag = (int)((nfcns + 1.0) - 1.0);
}
nu = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = (((i45 - i44) + i47) - i46) + 2;
emxEnsureCapacity_real_T(b_wt, nu);
loop_ub = i45 - i44;
for (nu = 0; nu < loop_ub; nu++) {
b_wt->data[b_wt->size[0] * nu] = iext->data[i44 + nu];
}
loop_ub = i47 - i46;
for (nu = 0; nu < loop_ub; nu++) {
b_wt->data[b_wt->size[0] * ((nu + i45) - i44)] = iext->data[i46
+ nu];
}
b_wt->data[b_wt->size[0] * (((i45 - i44) + i47) - i46)] =
iext->data[(int)((nfcns + 1.0) + 1.0) - 1];
b_wt->data[b_wt->size[0] * ((((i45 - i44) + i47) - i46) + 1)] =
iext->data[(int)((nfcns + 1.0) + 1.0) - 1];
loop_ub = b_wt->size[1];
i44 = r21->size[0] * r21->size[1];
r21->size[0] = 1;
r21->size[1] = loop_ub;
emxEnsureCapacity_int32_T(r21, i44);
for (i44 = 0; i44 < loop_ub; i44++) {
r21->data[r21->size[0] * i44] = i44;
}
temp = iext->data[(int)((nfcns + 1.0) + 1.0) - 1];
dnum = iext->data[(int)((nfcns + 1.0) + 1.0) - 1];
i44 = mtmp->size[0];
mtmp->size[0] = (((i49 - i48) + flag) - ixstart) + 2;
emxEnsureCapacity_real_T1(mtmp, i44);
loop_ub = i49 - i48;
for (i44 = 0; i44 < loop_ub; i44++) {
mtmp->data[i44] = iext->data[i48 + i44];
}
loop_ub = flag - ixstart;
for (i44 = 0; i44 < loop_ub; i44++) {
mtmp->data[(i44 + i49) - i48] = iext->data[ixstart + i44];
}
mtmp->data[((i49 - i48) + flag) - ixstart] = temp;
mtmp->data[(((i49 - i48) + flag) - ixstart) + 1] = dnum;
loop_ub = r21->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
iext->data[r21->data[r21->size[0] * i44]] = mtmp->data[(*(int (*)
[2])r21->size)[0] * i44];
}
jchnge++;
} else {
ixstart = 1;
if (rtIsNaN(b_y1)) {
flag = 2;
exitg2 = false;
while ((!exitg2) && (flag < 3)) {
ixstart = 2;
if (!rtIsNaN(comp)) {
b_y1 = comp;
exitg2 = true;
} else {
flag = 3;
}
}
}
if ((ixstart < 2) && (comp > b_y1)) {
b_y1 = comp;
}
k1 = iext->data[(int)((nfcns + 1.0) + 1.0) - 1];
comp = b_y1 * 1.00001;
b_l = ((double)ngrid + 1.0) - 1.0;
exitg2 = false;
while ((!exitg2) && (b_l > dnum)) {
/* gee */
dtemp = cos(6.2831853071795862 * grid->data[(int)b_l - 1]);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = x->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = x->size[0] * x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = dtemp - x->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
err = (b_y / dtemp - des->data[(int)b_l - 1]) * wt->data[(int)
b_l - 1];
dtemp = err * -(double)nut1 - comp;
if (dtemp > 0.0) {
comp = -(double)nut1 * err;
luck += 10;
b_l--;
exitg4 = false;
while ((!exitg4) && (b_l > dnum)) {
/* gee */
dtemp = cos(6.2831853071795862 * grid->data[(int)b_l - 1]);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = x->size[1];
emxEnsureCapacity_real_T(b_wt, i44);
loop_ub = x->size[0] * x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[i44] = dtemp - x->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
err = (b_y / dtemp - des->data[(int)b_l - 1]) * wt->data
[(int)b_l - 1];
dtemp = -(double)nut1 * err - comp;
if (dtemp > 0.0) {
comp = -(double)nut1 * err;
b_l--;
} else {
exitg4 = true;
}
}
iext->data[(int)((nfcns + 1.0) + 1.0) - 1] = b_l + 1.0;
jchnge++;
if (2.0 > nfcns + 1.0) {
i44 = 0;
i45 = 0;
} else {
i44 = 1;
i45 = (int)(nfcns + 1.0);
}
if (nfcns + 1.0 > (nfcns + 1.0) - 1.0) {
i46 = 0;
i47 = 0;
} else {
i46 = (int)(nfcns + 1.0) - 1;
i47 = (int)((nfcns + 1.0) - 1.0);
}
/* Update index */
if (2.0 > nfcns + 1.0) {
i48 = 0;
i49 = 0;
} else {
i48 = 1;
i49 = (int)(nfcns + 1.0);
}
if (nfcns + 1.0 > (nfcns + 1.0) - 1.0) {
ixstart = 0;
flag = 0;
} else {
ixstart = (int)(nfcns + 1.0) - 1;
flag = (int)((nfcns + 1.0) - 1.0);
}
nu = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = (((i45 - i44) + i47) - i46) + 2;
emxEnsureCapacity_real_T(b_wt, nu);
loop_ub = i45 - i44;
for (nu = 0; nu < loop_ub; nu++) {
b_wt->data[b_wt->size[0] * nu] = iext->data[i44 + nu];
}
loop_ub = i47 - i46;
for (nu = 0; nu < loop_ub; nu++) {
b_wt->data[b_wt->size[0] * ((nu + i45) - i44)] = iext->
data[i46 + nu];
}
b_wt->data[b_wt->size[0] * (((i45 - i44) + i47) - i46)] =
iext->data[(int)((nfcns + 1.0) + 1.0) - 1];
b_wt->data[b_wt->size[0] * ((((i45 - i44) + i47) - i46) + 1)] =
iext->data[(int)((nfcns + 1.0) + 1.0) - 1];
loop_ub = b_wt->size[1];
i44 = r21->size[0] * r21->size[1];
r21->size[0] = 1;
r21->size[1] = loop_ub;
emxEnsureCapacity_int32_T(r21, i44);
for (i44 = 0; i44 < loop_ub; i44++) {
r21->data[r21->size[0] * i44] = i44;
}
temp = iext->data[(int)((nfcns + 1.0) + 1.0) - 1];
dnum = iext->data[(int)((nfcns + 1.0) + 1.0) - 1];
i44 = mtmp->size[0];
mtmp->size[0] = (((i49 - i48) + flag) - ixstart) + 2;
emxEnsureCapacity_real_T1(mtmp, i44);
loop_ub = i49 - i48;
for (i44 = 0; i44 < loop_ub; i44++) {
mtmp->data[i44] = iext->data[i48 + i44];
}
loop_ub = flag - ixstart;
for (i44 = 0; i44 < loop_ub; i44++) {
mtmp->data[(i44 + i49) - i48] = iext->data[ixstart + i44];
}
mtmp->data[((i49 - i48) + flag) - ixstart] = temp;
mtmp->data[(((i49 - i48) + flag) - ixstart) + 1] = dnum;
loop_ub = r21->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
iext->data[r21->data[r21->size[0] * i44]] = mtmp->data
[(*(int (*)[2])r21->size)[0] * i44];
}
exitg2 = true;
} else {
b_l--;
}
}
if (luck != 6) {
temp = (nfcns + 1.0) - nfcns;
if (2.0 > temp) {
i44 = -2;
i45 = 0;
} else {
i44 = -1;
i45 = (int)temp;
}
temp = (nfcns + 1.0) - nfcns;
if (temp > (nfcns + 1.0) - 1.0) {
i46 = 1;
i47 = 0;
} else {
i46 = (int)temp;
i47 = (int)((nfcns + 1.0) - 1.0);
}
/* Update index */
temp = (nfcns + 1.0) - nfcns;
if (2.0 > temp) {
i48 = -2;
i49 = 0;
} else {
i48 = -1;
i49 = (int)temp;
}
temp = (nfcns + 1.0) - nfcns;
if (temp > (nfcns + 1.0) - 1.0) {
ixstart = 1;
flag = 0;
} else {
ixstart = (int)temp;
flag = (int)((nfcns + 1.0) - 1.0);
}
nu = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = ((i45 - i44) + i47) - i46;
emxEnsureCapacity_real_T(b_wt, nu);
loop_ub = i45 - i44;
for (nu = 0; nu <= loop_ub - 3; nu++) {
b_wt->data[b_wt->size[0] * (nu + 1)] = iext->data[(i44 + nu) +
2];
}
loop_ub = i47 - i46;
for (i47 = 0; i47 <= loop_ub; i47++) {
b_wt->data[b_wt->size[0] * (((i47 + i45) - i44) - 1)] =
iext->data[(i46 + i47) - 1];
}
loop_ub = b_wt->size[1];
i44 = r21->size[0] * r21->size[1];
r21->size[0] = 1;
r21->size[1] = loop_ub;
emxEnsureCapacity_int32_T(r21, i44);
for (i44 = 0; i44 < loop_ub; i44++) {
r21->data[r21->size[0] * i44] = i44;
}
i44 = mtmp->size[0];
mtmp->size[0] = ((i49 - i48) + flag) - ixstart;
emxEnsureCapacity_real_T1(mtmp, i44);
mtmp->data[0] = k1;
loop_ub = i49 - i48;
for (i44 = 0; i44 <= loop_ub - 3; i44++) {
mtmp->data[i44 + 1] = iext->data[(i48 + i44) + 2];
}
loop_ub = flag - ixstart;
for (i44 = 0; i44 <= loop_ub; i44++) {
mtmp->data[((i44 + i49) - i48) - 1] = iext->data[(ixstart +
i44) - 1];
}
loop_ub = r21->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
iext->data[r21->data[r21->size[0] * i44]] = mtmp->data[(*(int
(*)[2])r21->size)[0] * i44];
}
jchnge++;
}
}
}
guard1 = false;
}
}
} else {
guard1 = true;
exitg1 = 1;
}
} while (exitg1 == 0);
if (guard1) {
/* Inverse Fourier transformation */
err = -1.0;
k1 = -1.0;
/* initialize memory */
/* x(nzz) = -2; */
i44 = x2->size[0] * x2->size[1];
x2->size[0] = 1;
x2->size[1] = x->size[1] + 1;
emxEnsureCapacity_real_T(x2, i44);
loop_ub = x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
x2->data[x2->size[0] * i44] = x->data[x->size[0] * i44];
}
x2->data[x2->size[0] * x->size[1]] = -2.0;
jchnge = 2.0 * nfcns - 1.0;
b_j = 1.0 / jchnge;
b_l = 1.0;
nu = 0;
if (((edge[0] == 0.0) && (edge[3] == 0.5)) || (nfcns <= 3.0)) {
nu = 1;
}
if (nu != 1) {
dtemp = cos(6.2831853071795862 * grid->data[0]);
dnum = cos(6.2831853071795862 * grid->data[varargin_2 - 1]);
k1 = 2.0 / (dtemp - dnum);
err = -(dtemp + dnum) / (dtemp - dnum);
}
i44 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = (int)nfcns;
emxEnsureCapacity_real_T(a, i44);
for (nut = 0; nut < (int)nfcns; nut++) {
temp = ((1.0 + (double)nut) - 1.0) * b_j;
kup = cos(6.2831853071795862 * temp);
if (nu != 1) {
kup = (kup - err) / k1;
dtemp = kup;
b_acos(&dtemp);
temp = dtemp / 6.2831853071795862;
}
dnum = x2->data[(int)b_l - 1];
while ((kup <= dnum) && (dnum - kup >= 1.0E-6)) {
b_l++;
dnum = x2->data[(int)b_l - 1];
}
if (fabs(kup - dnum) < 1.0E-6) {
a->data[nut] = y->data[(int)b_l - 1];
} else {
/* gee */
loop_ub = (int)(nfcns + 1.0);
dtemp = cos(6.2831853071795862 * temp);
i44 = b_wt->size[0] * b_wt->size[1];
b_wt->size[0] = 1;
b_wt->size[1] = (int)(nfcns + 1.0);
emxEnsureCapacity_real_T(b_wt, i44);
for (i44 = 0; i44 < loop_ub; i44++) {
b_wt->data[b_wt->size[0] * i44] = dtemp - x2->data[i44];
}
c_rdivide(ad, b_wt, j);
i44 = b->size[0];
b->size[0] = y->size[1];
emxEnsureCapacity_real_T1(b, i44);
loop_ub = y->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
b->data[i44] = y->data[y->size[0] * i44];
}
if ((j->size[1] == 1) || (b->size[0] == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < j->size[1]; i44++) {
b_y += j->data[j->size[0] * i44] * b->data[i44];
}
}
dtemp = b_sum(j);
a->data[nut] = b_y / dtemp;
}
ixstart = 1;
if ((int)(b_l - 1.0) > 1) {
ixstart = (int)(b_l - 1.0);
}
b_l = ixstart;
}
temp = 6.2831853071795862 / jchnge;
i44 = j->size[0] * j->size[1];
j->size[0] = 1;
j->size[1] = (int)nfcns;
emxEnsureCapacity_real_T(j, i44);
for (nut = 0; nut < (int)nfcns; nut++) {
dnum = ((1.0 + (double)nut) - 1.0) * temp;
if (nfcns - 1.0 < 1.0) {
j->data[nut] = a->data[0];
} else {
if (2.0 > nfcns) {
i44 = 1;
i45 = 1;
} else {
i44 = 2;
i45 = (int)nfcns + 1;
}
if (nfcns - 1.0 < 1.0) {
i46 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = 0;
emxEnsureCapacity_real_T(y, i46);
} else {
i46 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = (int)floor((nfcns - 1.0) - 1.0) + 1;
emxEnsureCapacity_real_T(y, i46);
loop_ub = (int)floor((nfcns - 1.0) - 1.0);
for (i46 = 0; i46 <= loop_ub; i46++) {
y->data[y->size[0] * i46] = 1.0 + (double)i46;
}
}
i46 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_real_T(y, i46);
ixstart = y->size[0];
flag = y->size[1];
loop_ub = ixstart * flag;
for (i46 = 0; i46 < loop_ub; i46++) {
y->data[i46] *= dnum;
}
b_cos(y);
i46 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_real_T(y, i46);
ixstart = y->size[0];
flag = y->size[1];
loop_ub = ixstart * flag;
for (i46 = 0; i46 < loop_ub; i46++) {
y->data[i46] *= 2.0;
}
i46 = b->size[0];
b->size[0] = i45 - i44;
emxEnsureCapacity_real_T1(b, i46);
loop_ub = i45 - i44;
for (i46 = 0; i46 < loop_ub; i46++) {
b->data[i46] = a->data[(i44 + i46) - 1];
}
if ((y->size[1] == 1) || (i45 - i44 == 1)) {
b_y = 0.0;
for (i44 = 0; i44 < y->size[1]; i44++) {
b_y += y->data[y->size[0] * i44] * b->data[i44];
}
} else {
b_y = 0.0;
for (i44 = 0; i44 < y->size[1]; i44++) {
b_y += y->data[y->size[0] * i44] * b->data[i44];
}
}
j->data[nut] = a->data[0] + b_y;
}
}
if (2.0 > nfcns) {
i44 = -1;
i45 = 0;
} else {
i44 = 0;
i45 = (int)nfcns;
}
i46 = iext->size[0];
iext->size[0] = i45 - i44;
emxEnsureCapacity_real_T1(iext, i46);
iext->data[0] = j->data[0] / jchnge;
loop_ub = i45 - i44;
for (i45 = 0; i45 <= loop_ub - 2; i45++) {
iext->data[i45 + 1] = 2.0 * j->data[(i44 + i45) + 1] / jchnge;
}
i44 = j->size[0] * j->size[1];
j->size[0] = 1;
j->size[1] = (int)nfcns;
emxEnsureCapacity_real_T(j, i44);
loop_ub = (int)nfcns;
for (i44 = 0; i44 < loop_ub; i44++) {
j->data[i44] = 0.0;
}
i44 = l->size[0] * l->size[1];
l->size[0] = 1;
l->size[1] = (int)nfcns - 1;
emxEnsureCapacity_real_T(l, i44);
loop_ub = (int)nfcns - 1;
for (i44 = 0; i44 < loop_ub; i44++) {
l->data[i44] = 0.0;
}
if (nu != 1) {
j->data[0] = 2.0 * iext->data[(int)nfcns - 1] * err + iext->data[(int)
nfcns - 2];
j->data[1] = 2.0 * k1 * iext->data[(int)nfcns - 1];
l->data[0] = iext->data[(int)nfcns - 3] - iext->data[(int)nfcns - 1];
for (nut = 0; nut <= (int)nfcns - 3; nut++) {
if (2 + nut == (int)nfcns - 1) {
k1 /= 2.0;
err /= 2.0;
}
j->data[nut + 2] = 0.0;
i44 = x2->size[0] * x2->size[1];
x2->size[0] = 1;
x2->size[1] = (int)((2.0 + (double)nut) - 1.0) + 1;
emxEnsureCapacity_real_T(x2, i44);
loop_ub = (int)((2.0 + (double)nut) - 1.0);
for (i44 = 0; i44 <= loop_ub; i44++) {
x2->data[x2->size[0] * i44] = 1.0 + (double)i44;
}
loop_ub = x2->size[0] * x2->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
a->data[(int)x2->data[i44] - 1] = j->data[(int)x2->data[i44] - 1];
}
temp = 2.0 * err;
loop_ub = x2->size[0] * x2->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
j->data[(int)x2->data[i44] - 1] = temp * a->data[(int)x2->data[i44] -
1];
}
j->data[1] += 2.0 * a->data[0] * k1;
i44 = x2->size[0] * x2->size[1];
x2->size[0] = 1;
x2->size[1] = (int)(((2.0 + (double)nut) - 1.0) - 1.0) + 1;
emxEnsureCapacity_real_T(x2, i44);
loop_ub = (int)(((2.0 + (double)nut) - 1.0) - 1.0);
for (i44 = 0; i44 <= loop_ub; i44++) {
x2->data[x2->size[0] * i44] = 1.0 + (double)i44;
}
i44 = x->size[0] * x->size[1];
x->size[0] = 1;
x->size[1] = x2->size[1];
emxEnsureCapacity_real_T(x, i44);
loop_ub = x2->size[0] * x2->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
x->data[i44] = a->data[(int)x2->data[i44]];
}
i44 = mtmp->size[0];
mtmp->size[0] = x2->size[0] * x2->size[1];
emxEnsureCapacity_real_T1(mtmp, i44);
loop_ub = x2->size[0] * x2->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
mtmp->data[i44] = (j->data[(int)x2->data[i44] - 1] + l->data[(int)
x2->data[i44] - 1]) + k1 * x->data[i44];
}
loop_ub = mtmp->size[0];
for (i44 = 0; i44 < loop_ub; i44++) {
j->data[(int)x2->data[i44] - 1] = mtmp->data[i44];
}
i44 = x2->size[0] * x2->size[1];
x2->size[0] = 1;
x2->size[1] = (int)(((2.0 + (double)nut) + 1.0) - 3.0) + 1;
emxEnsureCapacity_real_T(x2, i44);
loop_ub = (int)(((2.0 + (double)nut) + 1.0) - 3.0);
for (i44 = 0; i44 <= loop_ub; i44++) {
x2->data[x2->size[0] * i44] = 3.0 + (double)i44;
}
i44 = x->size[0] * x->size[1];
x->size[0] = 1;
x->size[1] = x2->size[1];
emxEnsureCapacity_real_T(x, i44);
loop_ub = x2->size[0] * x2->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
x->data[i44] = a->data[(int)x2->data[i44] - 2];
}
i44 = mtmp->size[0];
mtmp->size[0] = x2->size[0] * x2->size[1];
emxEnsureCapacity_real_T1(mtmp, i44);
loop_ub = x2->size[0] * x2->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
mtmp->data[i44] = j->data[(int)x2->data[i44] - 1] + k1 * x->data[i44];
}
loop_ub = mtmp->size[0];
for (i44 = 0; i44 < loop_ub; i44++) {
j->data[(int)x2->data[i44] - 1] = mtmp->data[i44];
}
if (2 + nut != (int)nfcns - 1) {
i44 = x2->size[0] * x2->size[1];
x2->size[0] = 1;
x2->size[1] = (int)((2.0 + (double)nut) - 1.0) + 1;
emxEnsureCapacity_real_T(x2, i44);
loop_ub = (int)((2.0 + (double)nut) - 1.0);
for (i44 = 0; i44 <= loop_ub; i44++) {
x2->data[x2->size[0] * i44] = 1.0 + (double)i44;
}
loop_ub = x2->size[0] * x2->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
l->data[(int)x2->data[i44] - 1] = -a->data[(int)x2->data[i44] - 1];
}
l->data[0] += iext->data[((int)nfcns - nut) - 4];
}
}
loop_ub = (int)nfcns;
for (i44 = 0; i44 < loop_ub; i44++) {
iext->data[i44] = j->data[i44];
}
}
/* alpha must be at lease >=3 */
if (nfcns <= 3.0) {
/* alpha(nfcns + 1) = 0; */
/* alpha(nfcns + 2) = 0; */
i44 = j->size[0] * j->size[1];
j->size[0] = 1;
j->size[1] = iext->size[0] + 2;
emxEnsureCapacity_real_T(j, i44);
loop_ub = iext->size[0];
for (i44 = 0; i44 < loop_ub; i44++) {
j->data[j->size[0] * i44] = iext->data[i44];
}
j->data[j->size[0] * iext->size[0]] = 0.0;
j->data[j->size[0] * (iext->size[0] + 1)] = 0.0;
} else {
i44 = j->size[0] * j->size[1];
j->size[0] = 1;
j->size[1] = iext->size[0];
emxEnsureCapacity_real_T(j, i44);
loop_ub = iext->size[0];
for (i44 = 0; i44 < loop_ub; i44++) {
j->data[j->size[0] * i44] = iext->data[i44];
}
}
/* alpha=alpha'; */
/* now that's done! */
if (nodd != 0.0) {
i44 = x->size[0] * x->size[1];
x->size[0] = 1;
x->size[1] = (int)floor(-((0.0 - (nfcns - 1.0)) - -1.0)) + 1;
emxEnsureCapacity_real_T(x, i44);
loop_ub = (int)floor(-((0.0 - (nfcns - 1.0)) - -1.0));
for (i44 = 0; i44 <= loop_ub; i44++) {
x->data[x->size[0] * i44] = j->data[(int)((nfcns + 1.0) + (-1.0 -
(double)i44)) - 1];
}
i44 = h->size[0] * h->size[1];
h->size[0] = 1;
h->size[1] = x->size[1] + 1;
emxEnsureCapacity_real_T(h, i44);
loop_ub = x->size[1];
for (i44 = 0; i44 < loop_ub; i44++) {
h->data[h->size[0] * i44] = 0.5 * x->data[x->size[0] * i44];
}
h->data[h->size[0] * x->size[1]] = j->data[0];
} else {
if ((nfcns - (nfcns - 1.0)) + 2.0 > nfcns) {
i44 = 0;
i45 = 1;
} else {
i44 = (int)nfcns - 1;
i45 = -1;
}
i46 = x2->size[0] * x2->size[1];
x2->size[0] = 1;
x2->size[1] = (int)floor(-((0.0 - (nfcns - 1.0)) - -2.0)) + 1;
emxEnsureCapacity_real_T(x2, i46);
loop_ub = (int)floor(-((0.0 - (nfcns - 1.0)) - -2.0));
for (i46 = 0; i46 <= loop_ub; i46++) {
x2->data[x2->size[0] * i46] = j->data[(int)((nfcns + 1.0) + (double)(int)
(-2.0 - (double)i46)) - 1];
}
i46 = h->size[0] * h->size[1];
h->size[0] = 1;
h->size[1] = 2 + x2->size[1];
emxEnsureCapacity_real_T(h, i46);
h->data[0] = 0.25 * j->data[(int)nfcns - 1];
loop_ub = x2->size[1];
for (i46 = 0; i46 < loop_ub; i46++) {
h->data[h->size[0] * (i46 + 1)] = 0.25 * (x2->data[x2->size[0] * i46] +
j->data[i44 + i45 * i46]);
}
h->data[h->size[0] * (1 + x2->size[1])] = 0.25 * (2.0 * j->data[0] +
j->data[1]);
}
}
emxFree_real_T(&mtmp);
emxFree_int32_T(&b_iext);
emxFree_int8_T(&r22);
emxFree_real_T(&b_wt);
emxFree_real_T(&a);
emxFree_real_T(&b);
emxFree_int32_T(&r21);
emxFree_real_T(&x2);
emxFree_real_T(&l);
emxFree_real_T(&ad);
emxFree_real_T(&x);
emxFree_real_T(&y);
emxFree_real_T(&iext);
emxFree_real_T(&j);
*dev = b_dev;
*valid = b_valid;
}
/*
* Arguments : const double b_data[]
* const int b_size[2]
* const emxArray_creal_T *a
* double bR_data[]
* int bR_size[2]
* emxArray_creal_T *aR
* Return Type : void
*/
static void removeTrailingZero(const double b_data[], const int b_size[2], const
emxArray_creal_T *a, double bR_data[], int bR_size[2], emxArray_creal_T *aR)
{
int idx;
int ii_size_idx_1;
int ii;
boolean_T exitg1;
int ii_data[1];
int b_ii_size_idx_1;
boolean_T b_a;
int b_ii_data[1];
signed char varargin_1_data[1];
int varargin_2_data[1];
int c_ii_size_idx_1;
int trz_len_data_idx_0;
double d0;
/* end freqs */
idx = 0;
ii_size_idx_1 = 1;
ii = b_size[1];
exitg1 = false;
while ((!exitg1) && (ii > 0)) {
if (b_data[ii - 1] != 0.0) {
idx = 1;
ii_data[0] = ii;
exitg1 = true;
} else {
ii--;
}
}
if (idx == 0) {
ii_size_idx_1 = 0;
}
idx = 0;
b_ii_size_idx_1 = 1;
ii = a->size[1];
exitg1 = false;
while ((!exitg1) && (ii > 0)) {
b_a = ((a->data[ii - 1].re != 0.0) || (a->data[ii - 1].im != 0.0));
if (b_a) {
idx = 1;
b_ii_data[0] = ii;
exitg1 = true;
} else {
ii--;
}
}
if (idx == 0) {
b_ii_size_idx_1 = 0;
}
for (ii = 0; ii < ii_size_idx_1; ii++) {
varargin_1_data[ii] = (signed char)((signed char)b_size[1] - (signed char)
ii_data[ii]);
}
idx = a->size[1];
for (ii = 0; ii < b_ii_size_idx_1; ii++) {
varargin_2_data[ii] = idx - b_ii_data[ii];
}
if (ii_size_idx_1 <= b_ii_size_idx_1) {
c_ii_size_idx_1 = ii_size_idx_1;
} else {
c_ii_size_idx_1 = 0;
}
if (1 <= c_ii_size_idx_1) {
idx = varargin_1_data[0];
trz_len_data_idx_0 = varargin_2_data[0];
if (idx < trz_len_data_idx_0) {
trz_len_data_idx_0 = idx;
}
}
if (trz_len_data_idx_0 > 0) {
d0 = (double)b_size[1] - (double)trz_len_data_idx_0;
if (1.0 > d0) {
idx = 0;
} else {
idx = (int)d0;
}
bR_size[0] = 1;
bR_size[1] = idx;
for (ii = 0; ii < idx; ii++) {
bR_data[bR_size[0] * ii] = b_data[ii];
}
d0 = (double)a->size[1] - (double)trz_len_data_idx_0;
if (1.0 > d0) {
idx = 0;
} else {
idx = (int)d0;
}
ii = aR->size[0] * aR->size[1];
aR->size[0] = 1;
aR->size[1] = idx;
emxEnsureCapacity_creal_T(aR, ii);
for (ii = 0; ii < idx; ii++) {
aR->data[aR->size[0] * ii] = a->data[ii];
}
} else {
bR_size[0] = 1;
bR_size[1] = b_size[1];
idx = b_size[0] * b_size[1];
for (ii = 0; ii < idx; ii++) {
bR_data[ii] = b_data[ii];
}
ii = aR->size[0] * aR->size[1];
aR->size[0] = 1;
aR->size[1] = a->size[1];
emxEnsureCapacity_creal_T(aR, ii);
idx = a->size[0] * a->size[1];
for (ii = 0; ii < idx; ii++) {
aR->data[ii] = a->data[ii];
}
}
/* end removeTrailingZero */
}
/*
* Arguments : double u0
* double u1
* Return Type : double
*/
static double rt_atan2d_snf(double u0, double u1)
{
double y;
int b_u0;
int b_u1;
if (rtIsNaN(u0) || rtIsNaN(u1)) {
y = rtNaN;
} else if (rtIsInf(u0) && rtIsInf(u1)) {
if (u0 > 0.0) {
b_u0 = 1;
} else {
b_u0 = -1;
}
if (u1 > 0.0) {
b_u1 = 1;
} else {
b_u1 = -1;
}
y = atan2(b_u0, b_u1);
} else if (u1 == 0.0) {
if (u0 > 0.0) {
y = RT_PI / 2.0;
} else if (u0 < 0.0) {
y = -(RT_PI / 2.0);
} else {
y = 0.0;
}
} else {
y = atan2(u0, u1);
}
return y;
}
/*
* Arguments : double u0
* double u1
* Return Type : double
*/
static double rt_hypotd_snf(double u0, double u1)
{
double y;
double a;
double b;
a = fabs(u0);
b = fabs(u1);
if (a < b) {
a /= b;
y = b * sqrt(a * a + 1.0);
} else if (a > b) {
b /= a;
y = a * sqrt(b * b + 1.0);
} else if (rtIsNaN(b)) {
y = b;
} else {
y = a * 1.4142135623730951;
}
return y;
}
/*
* Arguments : double u0
* double u1
* Return Type : double
*/
static double rt_powd_snf(double u0, double u1)
{
double y;
double d3;
double d4;
if (rtIsNaN(u0) || rtIsNaN(u1)) {
y = rtNaN;
} else {
d3 = fabs(u0);
d4 = fabs(u1);
if (rtIsInf(u1)) {
if (d3 == 1.0) {
y = 1.0;
} else if (d3 > 1.0) {
if (u1 > 0.0) {
y = rtInf;
} else {
y = 0.0;
}
} else if (u1 > 0.0) {
y = 0.0;
} else {
y = rtInf;
}
} else if (d4 == 0.0) {
y = 1.0;
} else if (d4 == 1.0) {
if (u1 > 0.0) {
y = u0;
} else {
y = 1.0 / u0;
}
} else if (u1 == 2.0) {
y = u0 * u0;
} else if ((u1 == 0.5) && (u0 >= 0.0)) {
y = sqrt(u0);
} else if ((u0 < 0.0) && (u1 > floor(u1))) {
y = rtNaN;
} else {
y = pow(u0, u1);
}
}
return y;
}
/*
* Arguments : double u0
* double u1
* Return Type : double
*/
static double rt_remd_snf(double u0, double u1)
{
double y;
double b_u1;
double q;
if (!((!rtIsNaN(u0)) && (!rtIsInf(u0)) && ((!rtIsNaN(u1)) && (!rtIsInf(u1))))) {
y = rtNaN;
} else {
if (u1 < 0.0) {
b_u1 = ceil(u1);
} else {
b_u1 = floor(u1);
}
if ((u1 != 0.0) && (u1 != b_u1)) {
q = fabs(u0 / u1);
if (fabs(q - floor(q + 0.5)) <= DBL_EPSILON * q) {
y = 0.0 * u0;
} else {
y = fmod(u0, u1);
}
} else {
y = fmod(u0, u1);
}
}
return y;
}
/*
* Arguments : double u
* Return Type : double
*/
static double rt_roundd_snf(double u)
{
double y;
if (fabs(u) < 4.503599627370496E+15) {
if (u >= 0.5) {
y = floor(u + 0.5);
} else if (u > -0.5) {
y = u * 0.0;
} else {
y = ceil(u - 0.5);
}
} else {
y = u;
}
return y;
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[19]
* const emxArray_real_T *w
* double Fs
* emxArray_creal_T *hh
* Return Type : void
*/
static void s_freqz_cg(const double b[19], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh)
{
emxArray_real_T *r15;
int i38;
int loop_ub;
emxArray_real_T *digw;
emxArray_creal_T *s;
emxArray_creal_T *y;
boolean_T b9;
int k;
double s_re;
double s_im;
emxInit_real_T(&r15, 2);
/* Cast to enforce precision rules */
/* Remaining are default or for advanced use */
/* Make b a row */
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
i38 = r15->size[0] * r15->size[1];
r15->size[0] = 1;
r15->size[1] = w->size[1];
emxEnsureCapacity_real_T(r15, i38);
loop_ub = w->size[0] * w->size[1];
for (i38 = 0; i38 < loop_ub; i38++) {
r15->data[i38] = 6.2831853071795862 * w->data[i38];
}
emxInit_real_T(&digw, 2);
emxInit_creal_T(&s, 2);
rdivide(r15, Fs, digw);
/* Convert from Hz to rad/sample for computational purposes */
i38 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i38);
loop_ub = digw->size[0] * digw->size[1];
emxFree_real_T(&r15);
for (i38 = 0; i38 < loop_ub; i38++) {
s->data[i38].re = digw->data[i38] * 0.0;
s->data[i38].im = digw->data[i38];
}
emxInit_creal_T(&y, 2);
c_exp(s);
/* Digital frequency must be used for this calculation */
i38 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i38);
b9 = (y->size[1] == 0);
if (!b9) {
i38 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_creal_T(y, i38);
loop_ub = y->size[1];
for (i38 = 0; i38 < loop_ub; i38++) {
y->data[y->size[0] * i38].re = b[0];
y->data[y->size[0] * i38].im = 0.0;
}
for (k = 0; k < 18; k++) {
i38 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i38);
loop_ub = s->size[0] * s->size[1];
for (i38 = 0; i38 < loop_ub; i38++) {
s_re = s->data[i38].re * y->data[i38].re - s->data[i38].im * y->data[i38]
.im;
s_im = s->data[i38].re * y->data[i38].im + s->data[i38].im * y->data[i38]
.re;
y->data[i38].re = s_re + b[k + 1];
y->data[i38].im = s_im;
}
}
}
i38 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i38);
loop_ub = digw->size[0] * digw->size[1];
for (i38 = 0; i38 < loop_ub; i38++) {
s_re = digw->data[i38] * 0.0;
s_im = digw->data[i38];
s->data[i38].re = 18.0 * s_re;
s->data[i38].im = 18.0 * s_im;
}
emxFree_real_T(&digw);
c_exp(s);
b_rdivide(y, s, hh);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
emxFree_creal_T(&y);
emxFree_creal_T(&s);
}
/*
* Arguments : double x[2048]
* Return Type : void
*/
static void sinc(double x[2048])
{
int k;
for (k = 0; k < 2048; k++) {
if (fabs(x[k]) < 1.0020841800044864E-292) {
x[k] = 1.0;
} else {
x[k] *= 3.1415926535897931;
x[k] = sin(x[k]) / x[k];
}
}
}
/*
* Arguments : const double x[2048]
* Return Type : double
*/
static double sum(const double x[2048])
{
double y;
int k;
y = x[0];
for (k = 0; k < 2047; k++) {
y += x[k + 1];
}
return y;
}
/*
* FREQZ_CG Frequency response of digital filter with codegen support
*
* This function is based on 'freqz' by The MathWorks Inc.
* Arguments : const double b[85]
* const emxArray_real_T *w
* double Fs
* emxArray_creal_T *hh
* Return Type : void
*/
static void t_freqz_cg(const double b[85], const emxArray_real_T *w, double Fs,
emxArray_creal_T *hh)
{
emxArray_real_T *r16;
int i39;
int loop_ub;
emxArray_real_T *digw;
emxArray_creal_T *s;
emxArray_creal_T *y;
boolean_T b10;
int k;
double s_re;
double s_im;
emxInit_real_T(&r16, 2);
/* Cast to enforce precision rules */
/* Remaining are default or for advanced use */
/* Make b a row */
/* -------------------------------------------------------------------------- */
/* Actual Frequency Response Computation */
/* if fvflag, */
/* Frequency vector specified. Use Horner's method of polynomial */
/* evaluation at the frequency points and divide the numerator */
/* by the denominator. */
/* */
/* Note: we use positive i here because of the relationship */
/* polyval(a,exp(1i*w)) = fft(a).*exp(1i*w*(length(a)-1)) */
/* ( assuming w = 2*pi*(0:length(a)-1)/length(a) ) */
/* */
/* Fs was specified, freq. vector is in Hz */
i39 = r16->size[0] * r16->size[1];
r16->size[0] = 1;
r16->size[1] = w->size[1];
emxEnsureCapacity_real_T(r16, i39);
loop_ub = w->size[0] * w->size[1];
for (i39 = 0; i39 < loop_ub; i39++) {
r16->data[i39] = 6.2831853071795862 * w->data[i39];
}
emxInit_real_T(&digw, 2);
emxInit_creal_T(&s, 2);
rdivide(r16, Fs, digw);
/* Convert from Hz to rad/sample for computational purposes */
i39 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i39);
loop_ub = digw->size[0] * digw->size[1];
emxFree_real_T(&r16);
for (i39 = 0; i39 < loop_ub; i39++) {
s->data[i39].re = digw->data[i39] * 0.0;
s->data[i39].im = digw->data[i39];
}
emxInit_creal_T(&y, 2);
c_exp(s);
/* Digital frequency must be used for this calculation */
i39 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i39);
b10 = (y->size[1] == 0);
if (!b10) {
i39 = y->size[0] * y->size[1];
y->size[0] = 1;
emxEnsureCapacity_creal_T(y, i39);
loop_ub = y->size[1];
for (i39 = 0; i39 < loop_ub; i39++) {
y->data[y->size[0] * i39].re = b[0];
y->data[y->size[0] * i39].im = 0.0;
}
for (k = 0; k < 84; k++) {
i39 = y->size[0] * y->size[1];
y->size[0] = 1;
y->size[1] = s->size[1];
emxEnsureCapacity_creal_T(y, i39);
loop_ub = s->size[0] * s->size[1];
for (i39 = 0; i39 < loop_ub; i39++) {
s_re = s->data[i39].re * y->data[i39].re - s->data[i39].im * y->data[i39]
.im;
s_im = s->data[i39].re * y->data[i39].im + s->data[i39].im * y->data[i39]
.re;
y->data[i39].re = s_re + b[k + 1];
y->data[i39].im = s_im;
}
}
}
i39 = s->size[0] * s->size[1];
s->size[0] = 1;
s->size[1] = digw->size[1];
emxEnsureCapacity_creal_T(s, i39);
loop_ub = digw->size[0] * digw->size[1];
for (i39 = 0; i39 < loop_ub; i39++) {
s_re = digw->data[i39] * 0.0;
s_im = digw->data[i39];
s->data[i39].re = 84.0 * s_re;
s->data[i39].im = 84.0 * s_im;
}
emxFree_real_T(&digw);
c_exp(s);
b_rdivide(y, s, hh);
/* Generate the default structure to pass to freqzplot */
/* If rad/sample, Fs is empty */
emxFree_creal_T(&y);
emxFree_creal_T(&s);
}
/*
* Arguments : const double o[15]
* double u[15]
* Return Type : void
*/
static void us(const double o[15], double u[15])
{
int ix;
int iy;
int k;
memset(&u[0], 0, 15U * sizeof(double));
ix = 0;
iy = 0;
for (k = 0; k < 15; k++) {
u[iy] = o[ix];
ix++;
iy++;
}
}
/*
* Arguments : const emxArray_creal_T *x
* emxArray_creal_T *c
* Return Type : void
*/
static void vector_poly(const emxArray_creal_T *x, emxArray_creal_T *c)
{
int n;
int unnamed_idx_1;
int k;
double x_re;
double x_im;
double c_re;
double c_im;
n = x->size[0];
unnamed_idx_1 = x->size[0] + 1;
k = c->size[0] * c->size[1];
c->size[0] = 1;
c->size[1] = unnamed_idx_1;
emxEnsureCapacity_creal_T(c, k);
c->data[0].re = 1.0;
c->data[0].im = 0.0;
for (unnamed_idx_1 = 0; unnamed_idx_1 + 1 <= n; unnamed_idx_1++) {
x_re = -x->data[unnamed_idx_1].re;
x_im = -x->data[unnamed_idx_1].im;
c_re = c->data[unnamed_idx_1].re;
c_im = c->data[unnamed_idx_1].im;
c->data[unnamed_idx_1 + 1].re = x_re * c_re - x_im * c_im;
c->data[unnamed_idx_1 + 1].im = x_re * c_im + x_im * c_re;
for (k = unnamed_idx_1; k + 1 > 1; k--) {
x_re = x->data[unnamed_idx_1].re * c->data[k - 1].re - x->
data[unnamed_idx_1].im * c->data[k - 1].im;
x_im = x->data[unnamed_idx_1].re * c->data[k - 1].im + x->
data[unnamed_idx_1].im * c->data[k - 1].re;
c->data[k].re -= x_re;
c->data[k].im -= x_im;
}
}
}
/*
* Arguments : double x1
* double x2
* double x3
* Return Type : double
*/
static double xdlapy3(double x1, double x2, double x3)
{
double y;
double a;
double b;
double c;
a = fabs(x1);
b = fabs(x2);
c = fabs(x3);
if ((a > b) || rtIsNaN(b)) {
y = a;
} else {
y = b;
}
if (c > y) {
y = c;
}
if ((y > 0.0) && (!rtIsInf(y))) {
a /= y;
b /= y;
c /= y;
y *= sqrt((a * a + c * c) + b * b);
} else {
y = (a + b) + c;
}
return y;
}
/*
* Arguments : emxArray_creal_T *a
* Return Type : void
*/
static void xgehrd(emxArray_creal_T *a)
{
int n;
int ntau;
emxArray_creal_T *tau;
emxArray_creal_T *work;
int i59;
int i;
int im1n;
int in;
creal_T alpha1;
int c;
double alpha1_re;
double alpha1_im;
double xnorm;
double beta1;
int jy;
int knt;
boolean_T b_tau;
double ai;
int lastv;
int lastc;
int k;
boolean_T exitg1;
creal_T b_c;
int ix;
int exitg2;
n = a->size[0];
if (a->size[0] < 1) {
ntau = 0;
} else {
ntau = a->size[0] - 1;
}
emxInit_creal_T1(&tau, 1);
emxInit_creal_T1(&work, 1);
i59 = tau->size[0];
tau->size[0] = ntau;
emxEnsureCapacity_creal_T1(tau, i59);
ntau = a->size[0];
i59 = work->size[0];
work->size[0] = ntau;
emxEnsureCapacity_creal_T1(work, i59);
for (i59 = 0; i59 < ntau; i59++) {
work->data[i59].re = 0.0;
work->data[i59].im = 0.0;
}
for (i = 0; i + 1 < n; i++) {
im1n = i * n + 2;
in = (i + 1) * n;
alpha1 = a->data[(i + a->size[0] * i) + 1];
ntau = i + 3;
if (!(ntau < n)) {
ntau = n;
}
ntau += i * n;
c = (n - i) - 2;
alpha1_re = 0.0;
alpha1_im = 0.0;
if (!(c + 1 <= 0)) {
xnorm = xnrm2(c, a, ntau);
if ((xnorm != 0.0) || (a->data[(i + a->size[0] * i) + 1].im != 0.0)) {
beta1 = xdlapy3(a->data[(i + a->size[0] * i) + 1].re, a->data[(i +
a->size[0] * i) + 1].im, xnorm);
if (a->data[(i + a->size[0] * i) + 1].re >= 0.0) {
beta1 = -beta1;
}
if (fabs(beta1) < 1.0020841800044864E-292) {
knt = 0;
i59 = (ntau + c) - 1;
do {
knt++;
for (k = ntau; k <= i59; k++) {
xnorm = a->data[k - 1].re;
ai = a->data[k - 1].im;
a->data[k - 1].re = 9.9792015476736E+291 * xnorm - 0.0 * ai;
a->data[k - 1].im = 9.9792015476736E+291 * ai + 0.0 * xnorm;
}
beta1 *= 9.9792015476736E+291;
alpha1.re *= 9.9792015476736E+291;
alpha1.im *= 9.9792015476736E+291;
} while (!(fabs(beta1) >= 1.0020841800044864E-292));
beta1 = xdlapy3(alpha1.re, alpha1.im, xnrm2(c, a, ntau));
if (alpha1.re >= 0.0) {
beta1 = -beta1;
}
xnorm = beta1 - alpha1.re;
if (0.0 - alpha1.im == 0.0) {
alpha1_re = xnorm / beta1;
alpha1_im = 0.0;
} else if (xnorm == 0.0) {
alpha1_re = 0.0;
alpha1_im = (0.0 - alpha1.im) / beta1;
} else {
alpha1_re = xnorm / beta1;
alpha1_im = (0.0 - alpha1.im) / beta1;
}
b_c.re = alpha1.re - beta1;
b_c.im = alpha1.im;
xscal(c, recip(b_c), a, ntau);
for (k = 1; k <= knt; k++) {
beta1 *= 1.0020841800044864E-292;
}
alpha1.re = beta1;
alpha1.im = 0.0;
} else {
xnorm = beta1 - a->data[(i + a->size[0] * i) + 1].re;
ai = 0.0 - a->data[(i + a->size[0] * i) + 1].im;
if (ai == 0.0) {
alpha1_re = xnorm / beta1;
alpha1_im = 0.0;
} else if (xnorm == 0.0) {
alpha1_re = 0.0;
alpha1_im = ai / beta1;
} else {
alpha1_re = xnorm / beta1;
alpha1_im = ai / beta1;
}
b_c.re = a->data[(i + a->size[0] * i) + 1].re - beta1;
b_c.im = a->data[(i + a->size[0] * i) + 1].im;
xscal(c, recip(b_c), a, ntau);
alpha1.re = beta1;
alpha1.im = 0.0;
}
}
}
tau->data[i].re = alpha1_re;
tau->data[i].im = alpha1_im;
a->data[(i + a->size[0] * i) + 1].re = 1.0;
a->data[(i + a->size[0] * i) + 1].im = 0.0;
c = (n - i) - 3;
jy = (i + im1n) - 1;
b_tau = ((tau->data[i].re != 0.0) || (tau->data[i].im != 0.0));
if (b_tau) {
lastv = c + 2;
ntau = jy + c;
exitg1 = false;
while ((!exitg1) && (lastv > 0)) {
b_tau = ((a->data[ntau + 1].re == 0.0) && (a->data[ntau + 1].im == 0.0));
if (b_tau) {
lastv--;
ntau--;
} else {
exitg1 = true;
}
}
lastc = n;
exitg1 = false;
while ((!exitg1) && (lastc > 0)) {
ntau = in + lastc;
c = ntau;
do {
exitg2 = 0;
if ((n > 0) && (c <= ntau + (lastv - 1) * n)) {
b_tau = ((a->data[c - 1].re != 0.0) || (a->data[c - 1].im != 0.0));
if (b_tau) {
exitg2 = 1;
} else {
c += n;
}
} else {
lastc--;
exitg2 = 2;
}
} while (exitg2 == 0);
if (exitg2 == 1) {
exitg1 = true;
}
}
} else {
lastv = 0;
lastc = 0;
}
if (lastv > 0) {
if (lastc != 0) {
for (ntau = 1; ntau <= lastc; ntau++) {
work->data[ntau - 1].re = 0.0;
work->data[ntau - 1].im = 0.0;
}
ix = jy;
i59 = (in + n * (lastv - 1)) + 1;
knt = in + 1;
while ((n > 0) && (knt <= i59)) {
b_c.re = a->data[ix].re - 0.0 * a->data[ix].im;
b_c.im = a->data[ix].im + 0.0 * a->data[ix].re;
ntau = 0;
k = (knt + lastc) - 1;
for (c = knt; c <= k; c++) {
xnorm = a->data[c - 1].re * b_c.re - a->data[c - 1].im * b_c.im;
ai = a->data[c - 1].re * b_c.im + a->data[c - 1].im * b_c.re;
work->data[ntau].re += xnorm;
work->data[ntau].im += ai;
ntau++;
}
ix++;
knt += n;
}
}
alpha1_re = -tau->data[i].re;
alpha1_im = -tau->data[i].im;
if (!((alpha1_re == 0.0) && (alpha1_im == 0.0))) {
ntau = in;
for (knt = 1; knt <= lastv; knt++) {
b_tau = ((a->data[jy].re != 0.0) || (a->data[jy].im != 0.0));
if (b_tau) {
b_c.re = a->data[jy].re * alpha1_re + a->data[jy].im * alpha1_im;
b_c.im = a->data[jy].re * alpha1_im - a->data[jy].im * alpha1_re;
ix = 0;
i59 = lastc + ntau;
for (k = ntau; k + 1 <= i59; k++) {
xnorm = work->data[ix].re * b_c.re - work->data[ix].im * b_c.im;
ai = work->data[ix].re * b_c.im + work->data[ix].im * b_c.re;
a->data[k].re += xnorm;
a->data[k].im += ai;
ix++;
}
}
jy++;
ntau += n;
}
}
}
c = (n - i) - 3;
im1n = (i + im1n) - 1;
jy = (i + in) + 2;
alpha1_re = tau->data[i].re;
alpha1_im = -tau->data[i].im;
if ((alpha1_re != 0.0) || (alpha1_im != 0.0)) {
lastv = c + 2;
ntau = im1n + c;
exitg1 = false;
while ((!exitg1) && (lastv > 0)) {
b_tau = ((a->data[ntau + 1].re == 0.0) && (a->data[ntau + 1].im == 0.0));
if (b_tau) {
lastv--;
ntau--;
} else {
exitg1 = true;
}
}
lastc = (n - i) - 1;
exitg1 = false;
while ((!exitg1) && (lastc > 0)) {
ntau = jy + (lastc - 1) * n;
c = ntau;
do {
exitg2 = 0;
if (c <= (ntau + lastv) - 1) {
b_tau = ((a->data[c - 1].re != 0.0) || (a->data[c - 1].im != 0.0));
if (b_tau) {
exitg2 = 1;
} else {
c++;
}
} else {
lastc--;
exitg2 = 2;
}
} while (exitg2 == 0);
if (exitg2 == 1) {
exitg1 = true;
}
}
} else {
lastv = 0;
lastc = 0;
}
if (lastv > 0) {
if (lastc != 0) {
for (ntau = 1; ntau <= lastc; ntau++) {
work->data[ntau - 1].re = 0.0;
work->data[ntau - 1].im = 0.0;
}
ntau = 0;
i59 = jy + n * (lastc - 1);
knt = jy;
while ((n > 0) && (knt <= i59)) {
ix = im1n;
b_c.re = 0.0;
b_c.im = 0.0;
k = (knt + lastv) - 1;
for (c = knt - 1; c + 1 <= k; c++) {
b_c.re += a->data[c].re * a->data[ix].re + a->data[c].im * a->
data[ix].im;
b_c.im += a->data[c].re * a->data[ix].im - a->data[c].im * a->
data[ix].re;
ix++;
}
work->data[ntau].re += b_c.re - 0.0 * b_c.im;
work->data[ntau].im += b_c.im + 0.0 * b_c.re;
ntau++;
knt += n;
}
}
alpha1_re = -alpha1_re;
alpha1_im = -alpha1_im;
if (!((alpha1_re == 0.0) && (alpha1_im == 0.0))) {
ntau = jy - 1;
jy = 0;
for (knt = 1; knt <= lastc; knt++) {
b_tau = ((work->data[jy].re != 0.0) || (work->data[jy].im != 0.0));
if (b_tau) {
b_c.re = work->data[jy].re * alpha1_re + work->data[jy].im *
alpha1_im;
b_c.im = work->data[jy].re * alpha1_im - work->data[jy].im *
alpha1_re;
ix = im1n;
i59 = lastv + ntau;
for (k = ntau; k + 1 <= i59; k++) {
xnorm = a->data[ix].re * b_c.re - a->data[ix].im * b_c.im;
ai = a->data[ix].re * b_c.im + a->data[ix].im * b_c.re;
a->data[k].re += xnorm;
a->data[k].im += ai;
ix++;
}
}
jy++;
ntau += n;
}
}
}
a->data[(i + a->size[0] * i) + 1] = alpha1;
}
emxFree_creal_T(&work);
emxFree_creal_T(&tau);
}
/*
* Arguments : int n
* const emxArray_creal_T *x
* int ix0
* Return Type : double
*/
static double xnrm2(int n, const emxArray_creal_T *x, int ix0)
{
double y;
double scale;
int kend;
int k;
double absxk;
double t;
y = 0.0;
if (!(n < 1)) {
if (n == 1) {
y = rt_hypotd_snf(x->data[ix0 - 1].re, x->data[ix0 - 1].im);
} else {
scale = 3.3121686421112381E-170;
kend = (ix0 + n) - 1;
for (k = ix0; k <= kend; k++) {
absxk = fabs(x->data[k - 1].re);
if (absxk > scale) {
t = scale / absxk;
y = 1.0 + y * t * t;
scale = absxk;
} else {
t = absxk / scale;
y += t * t;
}
absxk = fabs(x->data[k - 1].im);
if (absxk > scale) {
t = scale / absxk;
y = 1.0 + y * t * t;
scale = absxk;
} else {
t = absxk / scale;
y += t * t;
}
}
y = scale * sqrt(y);
}
}
return y;
}
/*
* Arguments : int n
* const creal_T a
* emxArray_creal_T *x
* int ix0
* Return Type : void
*/
static void xscal(int n, const creal_T a, emxArray_creal_T *x, int ix0)
{
int i60;
int k;
double x_re;
double x_im;
i60 = (ix0 + n) - 1;
for (k = ix0; k <= i60; k++) {
x_re = x->data[k - 1].re;
x_im = x->data[k - 1].im;
x->data[k - 1].re = a.re * x_re - a.im * x_im;
x->data[k - 1].im = a.re * x_im + a.im * x_re;
}
}
/*
* Arguments : const emxArray_creal_T *A
* int *info
* emxArray_creal_T *alpha1
* emxArray_creal_T *beta1
* Return Type : void
*/
static void xzgeev(const emxArray_creal_T *A, int *info, emxArray_creal_T
*alpha1, emxArray_creal_T *beta1)
{
emxArray_creal_T *At;
int jcol;
int ii;
int nzcount;
double anrm;
boolean_T exitg1;
double absxk;
boolean_T ilascl;
double anrmto;
int ilo;
double ctoc;
int ihi;
boolean_T notdone;
int exitg3;
double cfrom1;
int i;
double cto1;
int j;
double mul;
creal_T b_At;
creal_T c_At;
double c;
creal_T atmp;
boolean_T exitg4;
int exitg2;
boolean_T d_At;
double stemp_re;
emxInit_creal_T(&At, 2);
jcol = At->size[0] * At->size[1];
At->size[0] = A->size[0];
At->size[1] = A->size[1];
emxEnsureCapacity_creal_T(At, jcol);
ii = A->size[0] * A->size[1];
for (jcol = 0; jcol < ii; jcol++) {
At->data[jcol] = A->data[jcol];
}
nzcount = 0;
jcol = alpha1->size[0];
alpha1->size[0] = At->size[0];
emxEnsureCapacity_creal_T1(alpha1, jcol);
ii = At->size[0];
for (jcol = 0; jcol < ii; jcol++) {
alpha1->data[jcol].re = 0.0;
alpha1->data[jcol].im = 0.0;
}
jcol = beta1->size[0];
beta1->size[0] = At->size[0];
emxEnsureCapacity_creal_T1(beta1, jcol);
ii = At->size[0];
for (jcol = 0; jcol < ii; jcol++) {
beta1->data[jcol].re = 0.0;
beta1->data[jcol].im = 0.0;
}
if (!((At->size[0] == 0) || (At->size[1] == 0))) {
anrm = 0.0;
jcol = 0;
exitg1 = false;
while ((!exitg1) && (jcol <= At->size[0] * At->size[1] - 1)) {
absxk = rt_hypotd_snf(At->data[jcol].re, At->data[jcol].im);
if (rtIsNaN(absxk)) {
anrm = rtNaN;
exitg1 = true;
} else {
if (absxk > anrm) {
anrm = absxk;
}
jcol++;
}
}
if (!((!rtIsInf(anrm)) && (!rtIsNaN(anrm)))) {
jcol = alpha1->size[0];
alpha1->size[0] = At->size[0];
emxEnsureCapacity_creal_T1(alpha1, jcol);
ii = At->size[0];
for (jcol = 0; jcol < ii; jcol++) {
alpha1->data[jcol].re = rtNaN;
alpha1->data[jcol].im = 0.0;
}
jcol = beta1->size[0];
beta1->size[0] = At->size[0];
emxEnsureCapacity_creal_T1(beta1, jcol);
ii = At->size[0];
for (jcol = 0; jcol < ii; jcol++) {
beta1->data[jcol].re = rtNaN;
beta1->data[jcol].im = 0.0;
}
} else {
ilascl = false;
anrmto = anrm;
if ((anrm > 0.0) && (anrm < 6.7178761075670888E-139)) {
anrmto = 6.7178761075670888E-139;
ilascl = true;
} else {
if (anrm > 1.4885657073574029E+138) {
anrmto = 1.4885657073574029E+138;
ilascl = true;
}
}
if (ilascl) {
absxk = anrm;
ctoc = anrmto;
notdone = true;
while (notdone) {
cfrom1 = absxk * 2.0041683600089728E-292;
cto1 = ctoc / 4.9896007738368E+291;
if ((cfrom1 > ctoc) && (ctoc != 0.0)) {
mul = 2.0041683600089728E-292;
absxk = cfrom1;
} else if (cto1 > absxk) {
mul = 4.9896007738368E+291;
ctoc = cto1;
} else {
mul = ctoc / absxk;
notdone = false;
}
jcol = At->size[0] * At->size[1];
emxEnsureCapacity_creal_T(At, jcol);
jcol = At->size[0];
ii = At->size[1];
ii *= jcol;
for (jcol = 0; jcol < ii; jcol++) {
At->data[jcol].re *= mul;
At->data[jcol].im *= mul;
}
}
}
ilo = 0;
ihi = At->size[0];
if (At->size[0] <= 1) {
ihi = 1;
} else {
do {
exitg3 = 0;
i = 0;
j = 0;
notdone = false;
ii = ihi;
exitg1 = false;
while ((!exitg1) && (ii > 0)) {
nzcount = 0;
i = ii;
j = ihi;
jcol = 1;
exitg4 = false;
while ((!exitg4) && (jcol <= ihi)) {
d_At = ((At->data[(ii + At->size[0] * (jcol - 1)) - 1].re != 0.0) ||
(At->data[(ii + At->size[0] * (jcol - 1)) - 1].im != 0.0));
if (d_At || (ii == jcol)) {
if (nzcount == 0) {
j = jcol;
nzcount = 1;
jcol++;
} else {
nzcount = 2;
exitg4 = true;
}
} else {
jcol++;
}
}
if (nzcount < 2) {
notdone = true;
exitg1 = true;
} else {
ii--;
}
}
if (!notdone) {
exitg3 = 2;
} else {
nzcount = At->size[0];
if (i != ihi) {
for (jcol = 0; jcol + 1 <= nzcount; jcol++) {
atmp = At->data[(i + At->size[0] * jcol) - 1];
At->data[(i + At->size[0] * jcol) - 1] = At->data[(ihi +
At->size[0] * jcol) - 1];
At->data[(ihi + At->size[0] * jcol) - 1] = atmp;
}
}
if (j != ihi) {
for (jcol = 0; jcol + 1 <= ihi; jcol++) {
atmp = At->data[jcol + At->size[0] * (j - 1)];
At->data[jcol + At->size[0] * (j - 1)] = At->data[jcol +
At->size[0] * (ihi - 1)];
At->data[jcol + At->size[0] * (ihi - 1)] = atmp;
}
}
ihi--;
if (ihi == 1) {
exitg3 = 1;
}
}
} while (exitg3 == 0);
if (exitg3 == 1) {
} else {
do {
exitg2 = 0;
i = 0;
j = 0;
notdone = false;
jcol = ilo + 1;
exitg1 = false;
while ((!exitg1) && (jcol <= ihi)) {
nzcount = 0;
i = ihi;
j = jcol;
ii = ilo + 1;
exitg4 = false;
while ((!exitg4) && (ii <= ihi)) {
d_At = ((At->data[(ii + At->size[0] * (jcol - 1)) - 1].re != 0.0)
|| (At->data[(ii + At->size[0] * (jcol - 1)) - 1].im !=
0.0));
if (d_At || (ii == jcol)) {
if (nzcount == 0) {
i = ii;
nzcount = 1;
ii++;
} else {
nzcount = 2;
exitg4 = true;
}
} else {
ii++;
}
}
if (nzcount < 2) {
notdone = true;
exitg1 = true;
} else {
jcol++;
}
}
if (!notdone) {
exitg2 = 1;
} else {
nzcount = At->size[0];
if (i != ilo + 1) {
for (jcol = ilo; jcol + 1 <= nzcount; jcol++) {
atmp = At->data[(i + At->size[0] * jcol) - 1];
At->data[(i + At->size[0] * jcol) - 1] = At->data[ilo +
At->size[0] * jcol];
At->data[ilo + At->size[0] * jcol] = atmp;
}
}
if (j != ilo + 1) {
for (jcol = 0; jcol + 1 <= ihi; jcol++) {
atmp = At->data[jcol + At->size[0] * (j - 1)];
At->data[jcol + At->size[0] * (j - 1)] = At->data[jcol +
At->size[0] * ilo];
At->data[jcol + At->size[0] * ilo] = atmp;
}
}
ilo++;
if (ilo + 1 == ihi) {
exitg2 = 1;
}
}
} while (exitg2 == 0);
}
}
nzcount = At->size[0];
if ((!(At->size[0] <= 1)) && (!(ihi < ilo + 3))) {
for (jcol = ilo; jcol + 1 < ihi - 1; jcol++) {
for (ii = ihi - 1; ii + 1 > jcol + 2; ii--) {
b_At = At->data[(ii + At->size[0] * jcol) - 1];
c_At = At->data[ii + At->size[0] * jcol];
xzlartg(b_At, c_At, &c, &atmp, &At->data[(ii + At->size[0] * jcol) -
1]);
At->data[ii + At->size[0] * jcol].re = 0.0;
At->data[ii + At->size[0] * jcol].im = 0.0;
for (j = jcol + 1; j + 1 <= nzcount; j++) {
absxk = atmp.re * At->data[ii + At->size[0] * j].re - atmp.im *
At->data[ii + At->size[0] * j].im;
ctoc = atmp.re * At->data[ii + At->size[0] * j].im + atmp.im *
At->data[ii + At->size[0] * j].re;
stemp_re = c * At->data[(ii + At->size[0] * j) - 1].re + absxk;
absxk = c * At->data[(ii + At->size[0] * j) - 1].im + ctoc;
ctoc = At->data[(ii + At->size[0] * j) - 1].re;
cfrom1 = At->data[(ii + At->size[0] * j) - 1].im;
cto1 = At->data[(ii + At->size[0] * j) - 1].im;
mul = At->data[(ii + At->size[0] * j) - 1].re;
At->data[ii + At->size[0] * j].re = c * At->data[ii + At->size[0] *
j].re - (atmp.re * ctoc + atmp.im * cfrom1);
At->data[ii + At->size[0] * j].im = c * At->data[ii + At->size[0] *
j].im - (atmp.re * cto1 - atmp.im * mul);
At->data[(ii + At->size[0] * j) - 1].re = stemp_re;
At->data[(ii + At->size[0] * j) - 1].im = absxk;
}
atmp.re = -atmp.re;
atmp.im = -atmp.im;
for (i = 0; i + 1 <= ihi; i++) {
absxk = atmp.re * At->data[i + At->size[0] * (ii - 1)].re -
atmp.im * At->data[i + At->size[0] * (ii - 1)].im;
ctoc = atmp.re * At->data[i + At->size[0] * (ii - 1)].im + atmp.im
* At->data[i + At->size[0] * (ii - 1)].re;
stemp_re = c * At->data[i + At->size[0] * ii].re + absxk;
absxk = c * At->data[i + At->size[0] * ii].im + ctoc;
ctoc = At->data[i + At->size[0] * ii].re;
cfrom1 = At->data[i + At->size[0] * ii].im;
cto1 = At->data[i + At->size[0] * ii].im;
mul = At->data[i + At->size[0] * ii].re;
At->data[i + At->size[0] * (ii - 1)].re = c * At->data[i +
At->size[0] * (ii - 1)].re - (atmp.re * ctoc + atmp.im * cfrom1);
At->data[i + At->size[0] * (ii - 1)].im = c * At->data[i +
At->size[0] * (ii - 1)].im - (atmp.re * cto1 - atmp.im * mul);
At->data[i + At->size[0] * ii].re = stemp_re;
At->data[i + At->size[0] * ii].im = absxk;
}
}
}
}
xzhgeqz(At, ilo + 1, ihi, &nzcount, alpha1, beta1);
if ((nzcount == 0) && ilascl) {
notdone = true;
while (notdone) {
cfrom1 = anrmto * 2.0041683600089728E-292;
cto1 = anrm / 4.9896007738368E+291;
if ((cfrom1 > anrm) && (anrm != 0.0)) {
mul = 2.0041683600089728E-292;
anrmto = cfrom1;
} else if (cto1 > anrmto) {
mul = 4.9896007738368E+291;
anrm = cto1;
} else {
mul = anrm / anrmto;
notdone = false;
}
jcol = alpha1->size[0];
emxEnsureCapacity_creal_T1(alpha1, jcol);
ii = alpha1->size[0];
for (jcol = 0; jcol < ii; jcol++) {
alpha1->data[jcol].re *= mul;
alpha1->data[jcol].im *= mul;
}
}
}
}
}
emxFree_creal_T(&At);
*info = nzcount;
}
/*
* Arguments : const emxArray_creal_T *A
* int ilo
* int ihi
* int *info
* emxArray_creal_T *alpha1
* emxArray_creal_T *beta1
* Return Type : void
*/
static void xzhgeqz(const emxArray_creal_T *A, int ilo, int ihi, int *info,
emxArray_creal_T *alpha1, emxArray_creal_T *beta1)
{
emxArray_creal_T *b_A;
int jm1;
int jp1;
int b_info;
double eshift_re;
double eshift_im;
creal_T ctemp;
double anorm;
double scale;
double reAij;
double sumsq;
double b_atol;
boolean_T firstNonZero;
int j;
double ascale;
double bscale;
int i;
boolean_T failed;
double imAij;
boolean_T guard1 = false;
boolean_T guard2 = false;
int ifirst;
int istart;
double temp2;
int ilast;
int ilastm1;
int ifrstm;
int ilastm;
int iiter;
boolean_T goto60;
boolean_T goto70;
boolean_T goto90;
int jiter;
int exitg1;
boolean_T exitg2;
creal_T b_ascale;
creal_T shift;
creal_T c_A;
double ad22_re;
double ad22_im;
double t1_im;
emxInit_creal_T(&b_A, 2);
jm1 = b_A->size[0] * b_A->size[1];
b_A->size[0] = A->size[0];
b_A->size[1] = A->size[1];
emxEnsureCapacity_creal_T(b_A, jm1);
jp1 = A->size[0] * A->size[1];
for (jm1 = 0; jm1 < jp1; jm1++) {
b_A->data[jm1] = A->data[jm1];
}
b_info = -1;
if ((A->size[0] == 1) && (A->size[1] == 1)) {
ihi = 1;
}
jm1 = alpha1->size[0];
alpha1->size[0] = A->size[0];
emxEnsureCapacity_creal_T1(alpha1, jm1);
jp1 = A->size[0];
for (jm1 = 0; jm1 < jp1; jm1++) {
alpha1->data[jm1].re = 0.0;
alpha1->data[jm1].im = 0.0;
}
jm1 = beta1->size[0];
beta1->size[0] = A->size[0];
emxEnsureCapacity_creal_T1(beta1, jm1);
jp1 = A->size[0];
for (jm1 = 0; jm1 < jp1; jm1++) {
beta1->data[jm1].re = 1.0;
beta1->data[jm1].im = 0.0;
}
eshift_re = 0.0;
eshift_im = 0.0;
ctemp.re = 0.0;
ctemp.im = 0.0;
anorm = 0.0;
if (!(ilo > ihi)) {
scale = 0.0;
sumsq = 0.0;
firstNonZero = true;
for (j = ilo; j <= ihi; j++) {
jm1 = j + 1;
if (ihi < j + 1) {
jm1 = ihi;
}
for (i = ilo; i <= jm1; i++) {
reAij = A->data[(i + A->size[0] * (j - 1)) - 1].re;
imAij = A->data[(i + A->size[0] * (j - 1)) - 1].im;
if (reAij != 0.0) {
anorm = fabs(reAij);
if (firstNonZero) {
sumsq = 1.0;
scale = anorm;
firstNonZero = false;
} else if (scale < anorm) {
temp2 = scale / anorm;
sumsq = 1.0 + sumsq * temp2 * temp2;
scale = anorm;
} else {
temp2 = anorm / scale;
sumsq += temp2 * temp2;
}
}
if (imAij != 0.0) {
anorm = fabs(imAij);
if (firstNonZero) {
sumsq = 1.0;
scale = anorm;
firstNonZero = false;
} else if (scale < anorm) {
temp2 = scale / anorm;
sumsq = 1.0 + sumsq * temp2 * temp2;
scale = anorm;
} else {
temp2 = anorm / scale;
sumsq += temp2 * temp2;
}
}
}
}
anorm = scale * sqrt(sumsq);
}
reAij = 2.2204460492503131E-16 * anorm;
b_atol = 2.2250738585072014E-308;
if (reAij > 2.2250738585072014E-308) {
b_atol = reAij;
}
reAij = 2.2250738585072014E-308;
if (anorm > 2.2250738585072014E-308) {
reAij = anorm;
}
ascale = 1.0 / reAij;
bscale = 1.0 / sqrt(A->size[0]);
failed = true;
for (j = ihi; j + 1 <= A->size[0]; j++) {
alpha1->data[j] = A->data[j + A->size[0] * j];
}
guard1 = false;
guard2 = false;
if (ihi >= ilo) {
ifirst = ilo;
istart = ilo;
ilast = ihi - 1;
ilastm1 = ihi - 2;
ifrstm = ilo;
ilastm = ihi;
iiter = 0;
goto60 = false;
goto70 = false;
goto90 = false;
jiter = 1;
do {
exitg1 = 0;
if (jiter <= 30 * ((ihi - ilo) + 1)) {
if (ilast + 1 == ilo) {
goto60 = true;
} else if (fabs(b_A->data[ilast + b_A->size[0] * ilastm1].re) + fabs
(b_A->data[ilast + b_A->size[0] * ilastm1].im) <= b_atol) {
b_A->data[ilast + b_A->size[0] * ilastm1].re = 0.0;
b_A->data[ilast + b_A->size[0] * ilastm1].im = 0.0;
goto60 = true;
} else {
j = ilastm1;
exitg2 = false;
while ((!exitg2) && (j + 1 >= ilo)) {
if (j + 1 == ilo) {
firstNonZero = true;
} else if (fabs(b_A->data[j + b_A->size[0] * (j - 1)].re) + fabs
(b_A->data[j + b_A->size[0] * (j - 1)].im) <= b_atol) {
b_A->data[j + b_A->size[0] * (j - 1)].re = 0.0;
b_A->data[j + b_A->size[0] * (j - 1)].im = 0.0;
firstNonZero = true;
} else {
firstNonZero = false;
}
if (firstNonZero) {
ifirst = j + 1;
goto70 = true;
exitg2 = true;
} else {
j--;
}
}
}
if (goto60 || goto70) {
firstNonZero = true;
} else {
firstNonZero = false;
}
if (!firstNonZero) {
jp1 = alpha1->size[0];
jm1 = alpha1->size[0];
alpha1->size[0] = jp1;
emxEnsureCapacity_creal_T1(alpha1, jm1);
for (jm1 = 0; jm1 < jp1; jm1++) {
alpha1->data[jm1].re = rtNaN;
alpha1->data[jm1].im = 0.0;
}
jp1 = beta1->size[0];
jm1 = beta1->size[0];
beta1->size[0] = jp1;
emxEnsureCapacity_creal_T1(beta1, jm1);
for (jm1 = 0; jm1 < jp1; jm1++) {
beta1->data[jm1].re = rtNaN;
beta1->data[jm1].im = 0.0;
}
b_info = 0;
exitg1 = 1;
} else if (goto60) {
goto60 = false;
alpha1->data[ilast] = b_A->data[ilast + b_A->size[0] * ilast];
ilast = ilastm1;
ilastm1--;
if (ilast + 1 < ilo) {
failed = false;
guard2 = true;
exitg1 = 1;
} else {
iiter = 0;
eshift_re = 0.0;
eshift_im = 0.0;
ilastm = ilast + 1;
if (ifrstm > ilast + 1) {
ifrstm = ilo;
}
jiter++;
}
} else {
if (goto70) {
goto70 = false;
iiter++;
ifrstm = ifirst;
if (iiter - iiter / 10 * 10 != 0) {
anorm = ascale * b_A->data[ilastm1 + b_A->size[0] * ilastm1].re;
reAij = ascale * b_A->data[ilastm1 + b_A->size[0] * ilastm1].im;
if (reAij == 0.0) {
shift.re = anorm / bscale;
shift.im = 0.0;
} else if (anorm == 0.0) {
shift.re = 0.0;
shift.im = reAij / bscale;
} else {
shift.re = anorm / bscale;
shift.im = reAij / bscale;
}
anorm = ascale * b_A->data[ilast + b_A->size[0] * ilast].re;
reAij = ascale * b_A->data[ilast + b_A->size[0] * ilast].im;
if (reAij == 0.0) {
ad22_re = anorm / bscale;
ad22_im = 0.0;
} else if (anorm == 0.0) {
ad22_re = 0.0;
ad22_im = reAij / bscale;
} else {
ad22_re = anorm / bscale;
ad22_im = reAij / bscale;
}
temp2 = 0.5 * (shift.re + ad22_re);
t1_im = 0.5 * (shift.im + ad22_im);
anorm = ascale * b_A->data[ilastm1 + b_A->size[0] * ilast].re;
reAij = ascale * b_A->data[ilastm1 + b_A->size[0] * ilast].im;
if (reAij == 0.0) {
sumsq = anorm / bscale;
imAij = 0.0;
} else if (anorm == 0.0) {
sumsq = 0.0;
imAij = reAij / bscale;
} else {
sumsq = anorm / bscale;
imAij = reAij / bscale;
}
anorm = ascale * b_A->data[ilast + b_A->size[0] * ilastm1].re;
reAij = ascale * b_A->data[ilast + b_A->size[0] * ilastm1].im;
if (reAij == 0.0) {
scale = anorm / bscale;
anorm = 0.0;
} else if (anorm == 0.0) {
scale = 0.0;
anorm = reAij / bscale;
} else {
scale = anorm / bscale;
anorm = reAij / bscale;
}
reAij = shift.re * ad22_im + shift.im * ad22_re;
shift.re = ((temp2 * temp2 - t1_im * t1_im) + (sumsq * scale -
imAij * anorm)) - (shift.re * ad22_re - shift.im * ad22_im);
shift.im = ((temp2 * t1_im + t1_im * temp2) + (sumsq * anorm +
imAij * scale)) - reAij;
c_sqrt(&shift);
if ((temp2 - ad22_re) * shift.re + (t1_im - ad22_im) * shift.im <=
0.0) {
shift.re += temp2;
shift.im += t1_im;
} else {
shift.re = temp2 - shift.re;
shift.im = t1_im - shift.im;
}
} else {
anorm = ascale * b_A->data[ilast + b_A->size[0] * ilastm1].re;
reAij = ascale * b_A->data[ilast + b_A->size[0] * ilastm1].im;
if (reAij == 0.0) {
sumsq = anorm / bscale;
imAij = 0.0;
} else if (anorm == 0.0) {
sumsq = 0.0;
imAij = reAij / bscale;
} else {
sumsq = anorm / bscale;
imAij = reAij / bscale;
}
eshift_re += sumsq;
eshift_im += imAij;
shift.re = eshift_re;
shift.im = eshift_im;
}
j = ilastm1;
jp1 = ilastm1 + 1;
exitg2 = false;
while ((!exitg2) && (j + 1 > ifirst)) {
istart = j + 1;
ctemp.re = ascale * b_A->data[j + b_A->size[0] * j].re - shift.re *
bscale;
ctemp.im = ascale * b_A->data[j + b_A->size[0] * j].im - shift.im *
bscale;
anorm = fabs(ctemp.re) + fabs(ctemp.im);
temp2 = ascale * (fabs(b_A->data[jp1 + b_A->size[0] * j].re) +
fabs(b_A->data[jp1 + b_A->size[0] * j].im));
reAij = anorm;
if (temp2 > anorm) {
reAij = temp2;
}
if ((reAij < 1.0) && (reAij != 0.0)) {
anorm /= reAij;
temp2 /= reAij;
}
if ((fabs(b_A->data[j + b_A->size[0] * (j - 1)].re) + fabs
(b_A->data[j + b_A->size[0] * (j - 1)].im)) * temp2 <= anorm *
b_atol) {
goto90 = true;
exitg2 = true;
} else {
jp1 = j;
j--;
}
}
if (!goto90) {
istart = ifirst;
ctemp.re = ascale * b_A->data[(ifirst + b_A->size[0] * (ifirst - 1))
- 1].re - shift.re * bscale;
ctemp.im = ascale * b_A->data[(ifirst + b_A->size[0] * (ifirst - 1))
- 1].im - shift.im * bscale;
goto90 = true;
}
}
if (goto90) {
goto90 = false;
b_ascale.re = ascale * b_A->data[istart + b_A->size[0] * (istart - 1)]
.re;
b_ascale.im = ascale * b_A->data[istart + b_A->size[0] * (istart - 1)]
.im;
b_xzlartg(ctemp, b_ascale, &imAij, &shift);
j = istart;
jm1 = istart - 2;
while (j < ilast + 1) {
if (j > istart) {
b_ascale = b_A->data[(j + b_A->size[0] * jm1) - 1];
c_A = b_A->data[j + b_A->size[0] * jm1];
xzlartg(b_ascale, c_A, &imAij, &shift, &b_A->data[(j + b_A->
size[0] * jm1) - 1]);
b_A->data[j + b_A->size[0] * jm1].re = 0.0;
b_A->data[j + b_A->size[0] * jm1].im = 0.0;
}
for (jp1 = j - 1; jp1 + 1 <= ilastm; jp1++) {
anorm = shift.re * b_A->data[j + b_A->size[0] * jp1].re -
shift.im * b_A->data[j + b_A->size[0] * jp1].im;
reAij = shift.re * b_A->data[j + b_A->size[0] * jp1].im +
shift.im * b_A->data[j + b_A->size[0] * jp1].re;
ad22_re = imAij * b_A->data[(j + b_A->size[0] * jp1) - 1].re +
anorm;
ad22_im = imAij * b_A->data[(j + b_A->size[0] * jp1) - 1].im +
reAij;
anorm = b_A->data[(j + b_A->size[0] * jp1) - 1].re;
reAij = b_A->data[(j + b_A->size[0] * jp1) - 1].im;
scale = b_A->data[(j + b_A->size[0] * jp1) - 1].im;
sumsq = b_A->data[(j + b_A->size[0] * jp1) - 1].re;
b_A->data[j + b_A->size[0] * jp1].re = imAij * b_A->data[j +
b_A->size[0] * jp1].re - (shift.re * anorm + shift.im * reAij);
b_A->data[j + b_A->size[0] * jp1].im = imAij * b_A->data[j +
b_A->size[0] * jp1].im - (shift.re * scale - shift.im * sumsq);
b_A->data[(j + b_A->size[0] * jp1) - 1].re = ad22_re;
b_A->data[(j + b_A->size[0] * jp1) - 1].im = ad22_im;
}
shift.re = -shift.re;
shift.im = -shift.im;
jp1 = j;
if (ilast + 1 < j + 2) {
jp1 = ilast - 1;
}
for (i = ifrstm - 1; i + 1 <= jp1 + 2; i++) {
anorm = shift.re * b_A->data[i + b_A->size[0] * (j - 1)].re -
shift.im * b_A->data[i + b_A->size[0] * (j - 1)].im;
reAij = shift.re * b_A->data[i + b_A->size[0] * (j - 1)].im +
shift.im * b_A->data[i + b_A->size[0] * (j - 1)].re;
ad22_re = imAij * b_A->data[i + b_A->size[0] * j].re + anorm;
ad22_im = imAij * b_A->data[i + b_A->size[0] * j].im + reAij;
anorm = b_A->data[i + b_A->size[0] * j].re;
reAij = b_A->data[i + b_A->size[0] * j].im;
scale = b_A->data[i + b_A->size[0] * j].im;
sumsq = b_A->data[i + b_A->size[0] * j].re;
b_A->data[i + b_A->size[0] * (j - 1)].re = imAij * b_A->data[i +
b_A->size[0] * (j - 1)].re - (shift.re * anorm + shift.im *
reAij);
b_A->data[i + b_A->size[0] * (j - 1)].im = imAij * b_A->data[i +
b_A->size[0] * (j - 1)].im - (shift.re * scale - shift.im *
sumsq);
b_A->data[i + b_A->size[0] * j].re = ad22_re;
b_A->data[i + b_A->size[0] * j].im = ad22_im;
}
jm1 = j - 1;
j++;
}
}
jiter++;
}
} else {
guard2 = true;
exitg1 = 1;
}
} while (exitg1 == 0);
} else {
guard1 = true;
}
if (guard2) {
if (failed) {
b_info = ilast;
for (jp1 = 0; jp1 + 1 <= ilast + 1; jp1++) {
alpha1->data[jp1].re = rtNaN;
alpha1->data[jp1].im = 0.0;
beta1->data[jp1].re = rtNaN;
beta1->data[jp1].im = 0.0;
}
} else {
guard1 = true;
}
}
if (guard1) {
for (j = 0; j + 1 < ilo; j++) {
alpha1->data[j] = b_A->data[j + b_A->size[0] * j];
}
}
emxFree_creal_T(&b_A);
*info = b_info + 1;
}
/*
* Arguments : creal_T *alpha1
* creal_T *x
* Return Type : creal_T
*/
static creal_T xzlarfg(creal_T *alpha1, creal_T *x)
{
creal_T tau;
double xnorm;
double beta1;
int knt;
double ai;
creal_T b_alpha1;
double x_re;
double x_im;
int k;
tau.re = 0.0;
tau.im = 0.0;
xnorm = rt_hypotd_snf(x->re, x->im);
if ((xnorm != 0.0) || (alpha1->im != 0.0)) {
beta1 = xdlapy3(alpha1->re, alpha1->im, xnorm);
if (alpha1->re >= 0.0) {
beta1 = -beta1;
}
if (fabs(beta1) < 1.0020841800044864E-292) {
knt = 0;
do {
knt++;
x->re *= 9.9792015476736E+291;
x->im *= 9.9792015476736E+291;
beta1 *= 9.9792015476736E+291;
alpha1->re *= 9.9792015476736E+291;
alpha1->im *= 9.9792015476736E+291;
} while (!(fabs(beta1) >= 1.0020841800044864E-292));
beta1 = xdlapy3(alpha1->re, alpha1->im, rt_hypotd_snf(x->re, x->im));
if (alpha1->re >= 0.0) {
beta1 = -beta1;
}
xnorm = beta1 - alpha1->re;
ai = 0.0 - alpha1->im;
if (ai == 0.0) {
tau.re = xnorm / beta1;
tau.im = 0.0;
} else if (xnorm == 0.0) {
tau.re = 0.0;
tau.im = ai / beta1;
} else {
tau.re = xnorm / beta1;
tau.im = ai / beta1;
}
b_alpha1.re = alpha1->re - beta1;
b_alpha1.im = alpha1->im;
*alpha1 = recip(b_alpha1);
xnorm = alpha1->re;
ai = alpha1->im;
x_re = x->re;
x_im = x->im;
x->re = xnorm * x_re - ai * x_im;
x->im = xnorm * x_im + ai * x_re;
for (k = 1; k <= knt; k++) {
beta1 *= 1.0020841800044864E-292;
}
alpha1->re = beta1;
alpha1->im = 0.0;
} else {
xnorm = beta1 - alpha1->re;
ai = 0.0 - alpha1->im;
if (ai == 0.0) {
tau.re = xnorm / beta1;
tau.im = 0.0;
} else if (xnorm == 0.0) {
tau.re = 0.0;
tau.im = ai / beta1;
} else {
tau.re = xnorm / beta1;
tau.im = ai / beta1;
}
b_alpha1.re = alpha1->re - beta1;
b_alpha1.im = alpha1->im;
*alpha1 = recip(b_alpha1);
xnorm = alpha1->re;
ai = alpha1->im;
x_re = x->re;
x_im = x->im;
x->re = xnorm * x_re - ai * x_im;
x->im = xnorm * x_im + ai * x_re;
alpha1->re = beta1;
alpha1->im = 0.0;
}
}
return tau;
}
/*
* Arguments : const creal_T f
* const creal_T g
* double *cs
* creal_T *sn
* creal_T *r
* Return Type : void
*/
static void xzlartg(const creal_T f, const creal_T g, double *cs, creal_T *sn,
creal_T *r)
{
double scale;
double f2s;
double x;
double fs_re;
double fs_im;
double gs_re;
double gs_im;
int count;
int rescaledir;
boolean_T guard1 = false;
double g2;
double g2s;
scale = fabs(f.re);
f2s = fabs(f.im);
if (f2s > scale) {
scale = f2s;
}
x = fabs(g.re);
f2s = fabs(g.im);
if (f2s > x) {
x = f2s;
}
if (x > scale) {
scale = x;
}
fs_re = f.re;
fs_im = f.im;
gs_re = g.re;
gs_im = g.im;
count = 0;
rescaledir = 0;
guard1 = false;
if (scale >= 7.4428285367870146E+137) {
do {
count++;
fs_re *= 1.3435752215134178E-138;
fs_im *= 1.3435752215134178E-138;
gs_re *= 1.3435752215134178E-138;
gs_im *= 1.3435752215134178E-138;
scale *= 1.3435752215134178E-138;
} while (!(scale < 7.4428285367870146E+137));
rescaledir = 1;
guard1 = true;
} else if (scale <= 1.3435752215134178E-138) {
if ((g.re == 0.0) && (g.im == 0.0)) {
*cs = 1.0;
sn->re = 0.0;
sn->im = 0.0;
*r = f;
} else {
do {
count++;
fs_re *= 7.4428285367870146E+137;
fs_im *= 7.4428285367870146E+137;
gs_re *= 7.4428285367870146E+137;
gs_im *= 7.4428285367870146E+137;
scale *= 7.4428285367870146E+137;
} while (!(scale > 1.3435752215134178E-138));
rescaledir = -1;
guard1 = true;
}
} else {
guard1 = true;
}
if (guard1) {
scale = fs_re * fs_re + fs_im * fs_im;
g2 = gs_re * gs_re + gs_im * gs_im;
x = g2;
if (1.0 > g2) {
x = 1.0;
}
if (scale <= x * 2.0041683600089728E-292) {
if ((f.re == 0.0) && (f.im == 0.0)) {
*cs = 0.0;
r->re = rt_hypotd_snf(g.re, g.im);
r->im = 0.0;
g2 = rt_hypotd_snf(gs_re, gs_im);
sn->re = gs_re / g2;
sn->im = -gs_im / g2;
} else {
g2s = sqrt(g2);
*cs = rt_hypotd_snf(fs_re, fs_im) / g2s;
x = fabs(f.re);
f2s = fabs(f.im);
if (f2s > x) {
x = f2s;
}
if (x > 1.0) {
g2 = rt_hypotd_snf(f.re, f.im);
fs_re = f.re / g2;
fs_im = f.im / g2;
} else {
scale = 7.4428285367870146E+137 * f.re;
f2s = 7.4428285367870146E+137 * f.im;
g2 = rt_hypotd_snf(scale, f2s);
fs_re = scale / g2;
fs_im = f2s / g2;
}
gs_re /= g2s;
gs_im = -gs_im / g2s;
sn->re = fs_re * gs_re - fs_im * gs_im;
sn->im = fs_re * gs_im + fs_im * gs_re;
r->re = *cs * f.re + (sn->re * g.re - sn->im * g.im);
r->im = *cs * f.im + (sn->re * g.im + sn->im * g.re);
}
} else {
f2s = sqrt(1.0 + g2 / scale);
r->re = f2s * fs_re;
r->im = f2s * fs_im;
*cs = 1.0 / f2s;
g2 += scale;
scale = r->re / g2;
f2s = r->im / g2;
sn->re = scale * gs_re - f2s * -gs_im;
sn->im = scale * -gs_im + f2s * gs_re;
if (rescaledir > 0) {
for (rescaledir = 1; rescaledir <= count; rescaledir++) {
r->re *= 7.4428285367870146E+137;
r->im *= 7.4428285367870146E+137;
}
} else {
if (rescaledir < 0) {
for (rescaledir = 1; rescaledir <= count; rescaledir++) {
r->re *= 1.3435752215134178E-138;
r->im *= 1.3435752215134178E-138;
}
}
}
}
}
}
/*
* ZP2SS Zero-pole to state-space conversion. Codegen support
*
* This function is based on 'zp2ss' by The MathWorks Inc.
* Arguments : emxArray_creal_T *a
* emxArray_real_T *b
* emxArray_real_T *c
* double *d
* Return Type : void
*/
static void zp2ss_cg(emxArray_creal_T *a, emxArray_real_T *b,
emxArray_real_T *c,
double *d)
{
int i6;
creal_T b_c[3];
int r1;
double wn;
double a22;
int k;
double den[3];
double b1[2];
double t[4];
double B[4];
int r2;
double Y[4];
emxArray_int8_T *reshapes_f2;
emxArray_cint8_T *b_a;
emxArray_cint8_T *result;
int i7;
signed char a_re;
signed char a_im;
emxArray_real_T *b_b1;
emxArray_real_T *varargin_2;
int result_im;
emxArray_real_T *r3;
/* Strip infinities and throw away. */
/* Group into complex pairs */
/* try */
/* % z and p should have real elements and exact complex conjugate pair. */
/* z = cplxpair(zF,0); */
/* p = cplxpair(pF,0); */
/* catch */
/* % If fail, revert to use the old default tolerance. */
/* % The use of tolerance in checking for real entries and conjugate pairs */
/* % may result in misinterpretation for edge cases. Please review the */
/* % process of how z and p are generated. */
/* z = cplxpair(zF,1e6*nz*norm(zF)*eps + eps); */
/* p = cplxpair(pF,1e6*np*norm(pF)*eps + eps); */
/* end */
/* Initialize state-space matrices for running series */
/* If odd number of poles AND zeros, convert the pole and zero */
/* at the end into state-space. */
/* H(s) = (s-z1)/(s-p1) = (s + num(2)) / (s + den(2)) */
/* If odd number of poles only, convert the pole at the */
/* end into state-space. */
/* H(s) = 1/(s-p1) = 1/(s + den(2)) */
i6 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = 1;
emxEnsureCapacity_creal_T(a, i6);
a->data[0].re = -1.0;
a->data[0].im = 0.0;
i6 = b->size[0];
b->size[0] = 1;
emxEnsureCapacity_real_T1(b, i6);
b->data[0] = 1.0;
i6 = c->size[0] * c->size[1];
c->size[0] = 1;
c->size[1] = 1;
emxEnsureCapacity_real_T(c, i6);
c->data[0] = 1.0;
/* If odd number of zeros only, convert the zero at the */
/* end, along with a pole-pair into state-space. */
/* H(s) = (s+num(2))/(s^2+den(2)s+den(3)) */
/* Now we have an even number of poles and zeros, although not */
/* necessarily the same number - there may be more poles. */
/* H(s) = (s^2+num(2)s+num(3))/(s^2+den(2)s+den(3)) */
/* Loop through rest of pairs, connecting in series to build the model. */
/* Take care of any left over unmatched pole pairs. */
/* H(s) = 1/(s^2+den(2)s+den(3)) */
b_c[0].re = 1.0;
b_c[0].im = 0.0;
for (r1 = 0; r1 < 2; r1++) {
wn = -(0.86602540378443871 + -1.7320508075688774 * (double)r1);
a22 = b_c[r1].re;
b_c[r1 + 1].re = 0.49999999999999978 * b_c[r1].re - wn * b_c[r1].im;
b_c[r1 + 1].im = 0.49999999999999978 * b_c[r1].im + wn * a22;
k = r1;
while (k + 1 > 1) {
wn = 0.86602540378443871 + -1.7320508075688774 * (double)r1;
b_c[1].re -= -0.49999999999999978 * b_c[0].re - wn * b_c[0].im;
b_c[1].im -= -0.49999999999999978 * b_c[0].im + wn * b_c[0].re;
k = 0;
}
}
for (i6 = 0; i6 < 3; i6++) {
den[i6] = b_c[i6].re;
}
for (k = 0; k < 2; k++) {
b1[k] = rt_hypotd_snf(-0.49999999999999978, 0.86602540378443871 +
-1.7320508075688774 * (double)k);
}
wn = sqrt(b1[0] * b1[1]);
b1[0] = 1.0;
b1[1] = 1.0 / wn;
for (i6 = 0; i6 < 4; i6++) {
t[i6] = 0.0;
}
/* Balancing transformation */
B[0] = -den[1];
B[2] = -den[2];
for (r1 = 0; r1 < 2; r1++) {
t[r1 + (r1 << 1)] = b1[r1];
B[1 + (r1 << 1)] = 1.0 - (double)r1;
}
if (t[1] > t[0]) {
r1 = 1;
r2 = 0;
} else {
r1 = 0;
r2 = 1;
}
wn = t[r2] / t[r1];
a22 = t[2 + r2] - wn * t[2 + r1];
for (k = 0; k < 2; k++) {
Y[1 + (k << 1)] = (B[r2 + (k << 1)] - B[r1 + (k << 1)] * wn) / a22;
Y[k << 1] = (B[r1 + (k << 1)] - Y[1 + (k << 1)] * t[2 + r1]) / t[r1];
}
if (t[1] > t[0]) {
r1 = 1;
r2 = 0;
} else {
r1 = 0;
r2 = 1;
}
emxInit_int8_T(&reshapes_f2, 2);
wn = t[r2] / t[r1];
b1[1] = ((1.0 - (double)r2) - (1.0 - (double)r1) * wn) / (t[2 + r2] - wn * t[2
+ r1]);
b1[0] = ((1.0 - (double)r1) - b1[1] * t[2 + r1]) / t[r1];
/* [a,b,c,d] = series(a,b,c,d,a1,b1,c1,d1); */
/* Next lines perform series connection */
i6 = reshapes_f2->size[0] * reshapes_f2->size[1];
reshapes_f2->size[0] = 1;
reshapes_f2->size[1] = 2;
emxEnsureCapacity_int8_T(reshapes_f2, i6);
for (i6 = 0; i6 < 2; i6++) {
reshapes_f2->data[i6] = 0;
}
emxInit_cint8_T(&b_a, 2);
i6 = b_a->size[0] * b_a->size[1];
b_a->size[0] = a->size[0];
b_a->size[1] = a->size[1];
emxEnsureCapacity_cint8_T(b_a, i6);
r1 = a->size[1];
for (i6 = 0; i6 < r1; i6++) {
r2 = a->size[0];
for (i7 = 0; i7 < r2; i7++) {
a_re = (signed char)a->data[i7 + a->size[0] * i6].re;
a_im = (signed char)a->data[i7 + a->size[0] * i6].im;
b_a->data[i7 + b_a->size[0] * i6].re = a_re;
b_a->data[i7 + b_a->size[0] * i6].im = a_im;
}
}
emxInit_cint8_T(&result, 2);
i6 = result->size[0] * result->size[1];
result->size[0] = 1;
result->size[1] = 1 + reshapes_f2->size[1];
emxEnsureCapacity_cint8_T(result, i6);
for (i6 = 0; i6 < 1; i6++) {
for (i7 = 0; i7 < 1; i7++) {
result->data[0] = b_a->data[0];
}
}
emxFree_cint8_T(&b_a);
r1 = reshapes_f2->size[1];
for (i6 = 0; i6 < r1; i6++) {
r2 = reshapes_f2->size[0];
for (i7 = 0; i7 < r2; i7++) {
result->data[i7 + result->size[0] * (i6 + 1)].re = reshapes_f2->data[i7 +
reshapes_f2->size[0] * i6];
result->data[i7 + result->size[0] * (i6 + 1)].im = 0;
}
}
emxFree_int8_T(&reshapes_f2);
emxInit_real_T(&b_b1, 2);
i6 = b_b1->size[0] * b_b1->size[1];
b_b1->size[0] = 2;
b_b1->size[1] = c->size[1];
emxEnsureCapacity_real_T(b_b1, i6);
for (i6 = 0; i6 < 2; i6++) {
r1 = c->size[1];
for (i7 = 0; i7 < r1; i7++) {
b_b1->data[i6 + b_b1->size[0] * i7] = b1[i6] * c->data[c->size[0] * i7];
}
}
for (i6 = 0; i6 < 2; i6++) {
for (i7 = 0; i7 < 2; i7++) {
B[i6 + (i7 << 1)] = 0.0;
for (r1 = 0; r1 < 2; r1++) {
B[i6 + (i7 << 1)] += Y[i6 + (r1 << 1)] * t[r1 + (i7 << 1)];
}
}
}
emxInit_real_T(&varargin_2, 2);
i6 = varargin_2->size[0] * varargin_2->size[1];
varargin_2->size[0] = 2;
varargin_2->size[1] = b_b1->size[1] + 2;
emxEnsureCapacity_real_T(varargin_2, i6);
r1 = b_b1->size[1];
for (i6 = 0; i6 < r1; i6++) {
for (i7 = 0; i7 < 2; i7++) {
varargin_2->data[i7 + varargin_2->size[0] * i6] = b_b1->data[i7 +
b_b1->size[0] * i6];
}
}
for (i6 = 0; i6 < 2; i6++) {
for (i7 = 0; i7 < 2; i7++) {
varargin_2->data[i7 + varargin_2->size[0] * (i6 + b_b1->size[1])] = B[i7 +
(i6 << 1)];
}
}
emxFree_real_T(&b_b1);
if (!(result->size[1] == 0)) {
r1 = result->size[1];
} else {
r1 = 3;
}
r2 = !(result->size[1] == 0);
i6 = a->size[0] * a->size[1];
a->size[0] = r2 + 2;
a->size[1] = r1;
emxEnsureCapacity_creal_T(a, i6);
for (i6 = 0; i6 < r1; i6++) {
for (i7 = 0; i7 < r2; i7++) {
k = result->data[i7 + r2 * i6].re;
result_im = result->data[i7 + r2 * i6].im;
a->data[i7 + a->size[0] * i6].re = k;
a->data[i7 + a->size[0] * i6].im = result_im;
}
}
emxFree_cint8_T(&result);
for (i6 = 0; i6 < r1; i6++) {
for (i7 = 0; i7 < 2; i7++) {
a->data[(i7 + r2) + a->size[0] * i6].re = varargin_2->data[i7 + (i6 << 1)];
a->data[(i7 + r2) + a->size[0] * i6].im = 0.0;
}
}
emxFree_real_T(&varargin_2);
r1 = b->size[0];
i6 = b->size[0];
b->size[0] = r1 + 2;
emxEnsureCapacity_real_T1(b, i6);
for (i6 = 0; i6 < 2; i6++) {
b->data[r1 + i6] = b1[i6] * 0.0;
}
for (i6 = 0; i6 < 2; i6++) {
b1[i6] = 0.0;
for (i7 = 0; i7 < 2; i7++) {
b1[i6] += (double)i7 * t[i7 + (i6 << 1)];
}
}
emxInit_real_T(&r3, 2);
i6 = r3->size[0] * r3->size[1];
r3->size[0] = 1;
r3->size[1] = c->size[1] + 2;
emxEnsureCapacity_real_T(r3, i6);
r1 = c->size[1];
for (i6 = 0; i6 < r1; i6++) {
r3->data[r3->size[0] * i6] = 0.0 * c->data[c->size[0] * i6];
}
for (i6 = 0; i6 < 2; i6++) {
r3->data[r3->size[0] * (i6 + c->size[1])] = b1[i6];
}
i6 = c->size[0] * c->size[1];
c->size[0] = 1;
c->size[1] = r3->size[1];
emxEnsureCapacity_real_T(c, i6);
r1 = r3->size[1];
for (i6 = 0; i6 < r1; i6++) {
c->data[c->size[0] * i6] = r3->data[r3->size[0] * i6];
}
emxFree_real_T(&r3);
/* Apply gain k: */
i6 = c->size[0] * c->size[1];
c->size[0] = 1;
emxEnsureCapacity_real_T(c, i6);
r1 = c->size[0];
r2 = c->size[1];
r1 *= r2;
for (i6 = 0; i6 < r1; i6++) {
c->data[i6] *= 0.99999999999999989;
}
*d = 0.0;
}
/*
* %%%%%%%%%%%%%%%%%%% Perform Input Checks
* Arguments : double Rdata
* double Fpass
* double Fstop
* double caldiv
* double FIR
* double HB1
* double PLL_mult
* double Apass
* double Astop
* double phEQ
* double HB2
* double HB3
* const char Type[7]
* const char RxTx[2]
* double RFbw
* double DAC_div
* double converter_rate
* double PLL_rate
* double Fcenter
* double wnom
* double FIRdBmin
* double int_FIR
* double maxTaps
* short outputTaps[128]
* double *numOutputTaps
* double *filterGain
* Return Type : void
*/
void internal_design_filter_cg(double Rdata, double Fpass, double Fstop, double
caldiv, double FIR, double HB1, double PLL_mult, double Apass, double Astop,
double phEQ, double HB2, double HB3, const char Type[7], const char RxTx[2],
double RFbw, double DAC_div, double converter_rate, double PLL_rate, double
Fcenter, double wnom, double FIRdBmin, double int_FIR, double maxTaps, short
outputTaps[128], double *numOutputTaps, double *filterGain)
{
emxArray_creal_T *a1;
emxArray_creal_T *a2;
double b1[4];
double b2[2];
creal_T a2_data[2];
int a2_size[2];
int b1_size[2];
int i0;
double b1_data[4];
int b2_size[2];
double b2_data[4];
double hb1_coeff[15];
static const double dv0[15] = { -0.00323486328125, 0.0, 0.01910400390625, 0.0,
-0.07049560546875, 0.0, 0.30450439453125, 0.5, 0.30450439453125, 0.0,
-0.07049560546875, 0.0, 0.01910400390625, 0.0, -0.00323486328125
};
static const double dv1[15] = { -0.00390625, 0.0, 0.0205078125, 0.0,
-0.07177734375, 0.0, 0.30224609375, 0.49462890625, 0.30224609375, 0.0,
-0.07177734375, 0.0, 0.0205078125, 0.0, -0.00390625
};
int hb3_coeff_size[2];
int dec_int3_coeff_size[2];
double hb3_coeff_data[5];
static const double y[3] = { 0.25, 0.5, 0.25 };
static const double b_y[5] = { 0.0625, 0.25, 0.375, 0.25, 0.0625 };
double dec_int3_coeff_data[29];
static const double c_y[29] = { 0.00146484375, -0.00077311197916666663, 0.0,
-0.00634765625, -0.00048828125, 0.0, 0.019490559895833332,
0.0090738932291666661, 0.0, -0.0494384765625, -0.0404052734375, 0.0,
0.14522298177083331, 0.25541178385416663, 0.33333333333333331,
0.25541178385416663, 0.14522298177083331, 0.0, -0.0404052734375,
-0.0494384765625, 0.0, 0.0090738932291666661, 0.019490559895833332, 0.0,
-0.00048828125, -0.00634765625, 0.0, -0.00077311197916666663, 0.00146484375
};
static const double d_y[17] = { 0.00335693359375, 0.00506591796875, 0.0,
-0.02398681640625, -0.035400390625, 0.0, 0.1168212890625, 0.24664306640625,
0.3125, 0.24664306640625, 0.1168212890625, 0.0, -0.035400390625,
-0.02398681640625, 0.0, 0.00506591796875, 0.00335693359375
};
int hb3;
int dec_int3;
double sigma;
signed char i1;
char enables[4];
double w[2048];
double phi[2048];
static const double hb2_coeff[7] = { -0.03515625, 0.0, 0.28515625, 0.5,
0.28515625, 0.0, -0.03515625
};
static creal_T combinedResponse[2048];
static creal_T dcv0[2048];
double b_combinedResponse[2048];
double invariance[2048];
double sigmax;
double b_phi[2048];
double b_w[2048];
double clkFIR;
double Gpass;
double Gstop;
emxArray_real_T *fg;
int loop_ub;
emxArray_real_T *omega;
emxArray_creal_T *rg1;
emxArray_creal_T *c_combinedResponse;
emxArray_creal_T *r0;
double apnd;
double absa;
double rg1_im;
double re;
double im;
emxArray_real_T *sw;
emxArray_real_T *fg2;
int n;
emxArray_real_T *omega2;
emxArray_creal_T *rgN;
emxArray_real_T *b_omega2;
emxArray_creal_T *d_combinedResponse;
emxArray_real_T *a;
emxArray_real_T *wg;
emxArray_real_T *weight;
boolean_T exitg1;
emxArray_real_T *F1;
emxArray_real_T *F2;
emxArray_real_T *A1;
emxArray_real_T *A2;
emxArray_real_T *W1;
emxArray_real_T *W2;
emxArray_real_T *tap_store;
emxArray_real_T *Apass_actual_vector;
emxArray_real_T *Astop_actual_vector;
unsigned int i;
emxArray_real_T *ccoef;
emxArray_real_T *F4;
emxArray_real_T *b_W1;
int exitg2;
int i2;
int b_loop_ub;
boolean_T valid;
int i3;
double firTapsPreScale[128];
double b_firTapsPreScale[128];
short i4;
(void)caldiv;
(void)PLL_mult;
(void)Type;
(void)RFbw;
(void)DAC_div;
(void)PLL_rate;
(void)Fcenter;
/* internal_design_filter_cg */
/* */
/* This implementation of the ADI ad936x-filter-wizard supports */
/* code generation from MATLAB Coder */
/* */
/* Edits by: Travis F. Collins */
/* */
/* When calling this function utilize the function "process_input" to make */
/* sure all the necessary fields exist */
/* */
/* Todo: */
/* - Set fractionalLength based on FSR of inputs (ML has no doc on this) */
/* */
/* Inputs */
/* ============================================ */
/* Rdata = Input/output sample data rate (in Hz) */
/* Fpass = Passband frequency (in Hz) */
/* Fstop = Stopband frequency (in Hz) */
/* caldiv = The actual discrete register value that describes the */
/* rolloff for the analog filters */
/* FIR = FIR interpolation/decimation factor */
/* HB1 = HB1 interpolation/decimation rates */
/* PLL_mult = PLL multiplication */
/* Apass = Max ripple allowed in passband (in dB) */
/* Astop = Min attenuation in stopband (in dB) */
/* phEQ = Phase equalization on (not -1)/off (-1) */
/* HB2 = HB2 interpolation/decimation rates */
/* HB3 = HB3 interpolation/decimation rates */
/* Type = The type of filter required. one of: */
/* 'Lowpass' (default,and only support) */
/* 'Bandpass' (Not implemented) */
/* 'Equalize' (Not implemented) */
/* 'Root Raised Cosine' (Not implemented) */
/* RxTx = Is this 'Rx' or 'Tx'?. */
/* RFbw */
/* DAC_div = The ADC/DAC ratio, for Rx channels, this is */
/* always '1', for Tx, it is either '1' or '2' */
/* converter_rate = Rate of converter */
/* PLL_rate = the PLL rate in Hz */
/* Fcenter = Center Frequency in Hz (only used for Bandpass), */
/* otherwise 0 */
/* wnom = analog cutoff frequency (in Hz) */
/* FIRdBmin = min rejection that FIR is required to have (in dB) */
/* int_FIR = use AD9361 FIR on (1)/off (0) */
/* */
/* Outputs */
/* =============================================== */
/* firtaps = fixed point FIR coefficients */
/* Scalar checks */
/* String checks */
/* This is unused */
/* %%%%%%%%%%%%%%%%%%% Build processing struct */
/* Not used */
/* Design analog filters */
emxInit_creal_T(&a1, 2);
emxInit_creal_T(&a2, 2);
if (b_strcmp(RxTx)) {
/* Define the analog filters (for design purpose) */
butter_cg(6.2831853071795862 * (wnom * 1.7857142857142858), b2, a2_data,
a2_size);
b1_size[0] = 1;
b1_size[1] = 2;
for (i0 = 0; i0 < 2; i0++) {
b1_data[i0] = b2[i0];
}
i0 = a1->size[0] * a1->size[1];
a1->size[0] = 1;
a1->size[1] = 2;
emxEnsureCapacity_creal_T(a1, i0);
for (i0 = 0; i0 < 2; i0++) {
a1->data[i0] = a2_data[i0];
}
/* 1st order */
b_butter_cg(6.2831853071795862 * wnom, b1, a2);
b2_size[0] = 1;
b2_size[1] = 4;
for (i0 = 0; i0 < 4; i0++) {
b2_data[i0] = b1[i0];
}
/* 3rd order */
/* Define the digital filters with fixed coefficients */
memcpy(&hb1_coeff[0], &dv1[0], 15U * sizeof(double));
hb3_coeff_size[0] = 1;
hb3_coeff_size[1] = 5;
for (i0 = 0; i0 < 5; i0++) {
hb3_coeff_data[i0] = b_y[i0];
}
dec_int3_coeff_size[0] = 1;
dec_int3_coeff_size[1] = 17;
memcpy(&dec_int3_coeff_data[0], &d_y[0], 17U * sizeof(double));
} else {
/* Define the analog filters (for design purpose) */
b_butter_cg(6.2831853071795862 * wnom, b1, a1);
b1_size[0] = 1;
b1_size[1] = 4;
for (i0 = 0; i0 < 4; i0++) {
b1_data[i0] = b1[i0];
}
/* 3rd order */
butter_cg(6.2831853071795862 * (wnom * 3.125), b2, a2_data, a2_size);
b2_size[0] = 1;
b2_size[1] = 2;
for (i0 = 0; i0 < 2; i0++) {
b2_data[i0] = b2[i0];
}
i0 = a2->size[0] * a2->size[1];
a2->size[0] = 1;
a2->size[1] = 2;
emxEnsureCapacity_creal_T(a2, i0);
for (i0 = 0; i0 < 2; i0++) {
a2->data[i0] = a2_data[i0];
}
/* 1st order */
/* Define the digital filters with fixed coefficients */
memcpy(&hb1_coeff[0], &dv0[0], 15U * sizeof(double));
hb3_coeff_size[0] = 1;
hb3_coeff_size[1] = 3;
for (i0 = 0; i0 < 3; i0++) {
hb3_coeff_data[i0] = y[i0];
}
dec_int3_coeff_size[0] = 1;
dec_int3_coeff_size[1] = 29;
memcpy(&dec_int3_coeff_data[0], &c_y[0], 29U * sizeof(double));
}
/* Configure staging of filters */
if (HB3 == 2.0) {
hb3 = 50;
dec_int3 = 49;
} else if (HB3 == 3.0) {
hb3 = 49;
dec_int3 = 51;
} else {
hb3 = 49;
dec_int3 = 49;
}
/* convert the enables into a string */
sigma = rt_roundd_snf(HB1);
if (sigma < 128.0) {
if (sigma >= -128.0) {
i1 = (signed char)sigma;
} else {
i1 = MIN_int8_T;
}
} else if (sigma >= 128.0) {
i1 = MAX_int8_T;
} else {
i1 = 0;
}
i0 = 48 + i1;
if (i0 > 127) {
i0 = 127;
}
enables[0] = (signed char)i0;
sigma = rt_roundd_snf(HB2);
if (sigma < 128.0) {
if (sigma >= -128.0) {
i1 = (signed char)sigma;
} else {
i1 = MIN_int8_T;
}
} else if (sigma >= 128.0) {
i1 = MAX_int8_T;
} else {
i1 = 0;
}
i0 = 48 + i1;
if (i0 > 127) {
i0 = 127;
}
enables[1] = (signed char)i0;
enables[2] = (signed char)hb3;
enables[3] = (signed char)dec_int3;
/* Find out the best fit delay on passband */
memset(&w[0], 0, sizeof(double) << 11);
memset(&phi[0], 0, sizeof(double) << 11);
w[0] = -Fpass;
for (hb3 = 0; hb3 < 2047; hb3++) {
w[hb3 + 1] = w[0] - 2.0 * w[0] * (2.0 + (double)hb3) / 2048.0;
}
/* Generate target responses used in filter design phase */
/* Generate responses then convolve */
generateCascadedResponseRx(enables, w, converter_rate, hb1_coeff, hb2_coeff,
hb3_coeff_data, hb3_coeff_size, dec_int3_coeff_data, dec_int3_coeff_size,
combinedResponse);
/* Determine overall response with analog filters inline */
analogresp(RxTx, w, converter_rate, b1_data, b1_size, a1, b2_data, b2_size, a2,
dcv0);
for (i0 = 0; i0 < 2048; i0++) {
sigmax = combinedResponse[i0].re;
combinedResponse[i0].re = combinedResponse[i0].re * dcv0[i0].re -
combinedResponse[i0].im * dcv0[i0].im;
combinedResponse[i0].im = sigmax * dcv0[i0].im + combinedResponse[i0].im *
dcv0[i0].re;
b_combinedResponse[i0] = combinedResponse[i0].re;
}
b_power(b_combinedResponse, invariance);
for (i0 = 0; i0 < 2048; i0++) {
b_combinedResponse[i0] = combinedResponse[i0].im;
}
b_power(b_combinedResponse, b_phi);
for (i0 = 0; i0 < 2048; i0++) {
invariance[i0] += b_phi[i0];
}
phi[0] = rt_atan2d_snf(combinedResponse[0].im, combinedResponse[0].re);
for (hb3 = 0; hb3 < 2047; hb3++) {
sigma = rt_atan2d_snf(combinedResponse[hb3 + 1].im, combinedResponse[hb3 + 1]
.re) - phi[hb3];
phi[hb3 + 1] = phi[hb3] + (sigma - 6.2831853071795862 * floor(sigma /
6.2831853071795862 + 0.5));
}
sigma = sum(invariance);
for (i0 = 0; i0 < 2048; i0++) {
b_combinedResponse[i0] = w[i0] * invariance[i0];
}
sigmax = sum(b_combinedResponse);
if ((phEQ == 0.0) || (phEQ == -1.0)) {
for (i0 = 0; i0 < 2048; i0++) {
b_combinedResponse[i0] = w[i0] * phi[i0] * invariance[i0];
b_phi[i0] = phi[i0] * invariance[i0];
b_w[i0] = w[i0] * w[i0] * invariance[i0];
}
sigma = -((sigma * sum(b_combinedResponse) - sigmax * sum(b_phi)) / (sigma *
sum(b_w) - sigmax * sigmax)) / 6.2831853071795862;
} else {
sigma = phEQ * 1.0E-9;
}
/* Design the FIR */
clkFIR = Rdata * FIR;
Gpass = floor(16384.0 * Fpass / clkFIR);
Gstop = ceil(16384.0 * Fstop / clkFIR);
if (!((Gpass < Gstop - 1.0) || rtIsNaN(Gstop - 1.0))) {
Gpass = Gstop - 1.0;
}
emxInit_real_T(&fg, 2);
i0 = fg->size[0] * fg->size[1];
fg->size[0] = 1;
fg->size[1] = (int)(Gpass + 1.0);
emxEnsureCapacity_real_T(fg, i0);
loop_ub = (int)(Gpass + 1.0);
for (i0 = 0; i0 < loop_ub; i0++) {
fg->data[i0] = 0.0;
}
emxInit_real_T(&omega, 2);
i0 = omega->size[0] * omega->size[1];
omega->size[0] = 1;
omega->size[1] = (int)(Gpass + 1.0);
emxEnsureCapacity_real_T(omega, i0);
loop_ub = (int)(Gpass + 1.0);
for (i0 = 0; i0 < loop_ub; i0++) {
omega->data[i0] = 0.0;
}
/* passband */
for (hb3 = 0; hb3 < (int)(Gpass + 1.0); hb3++) {
fg->data[hb3] = ((1.0 + (double)hb3) - 1.0) / 16384.0;
omega->data[hb3] = fg->data[hb3] * clkFIR;
}
emxInit_creal_T(&rg1, 2);
emxInit_creal_T(&c_combinedResponse, 2);
/* Generate responses then convolve */
b_generateCascadedResponseRx(enables, omega, converter_rate, hb1_coeff,
hb2_coeff, hb3_coeff_data, hb3_coeff_size, dec_int3_coeff_data,
dec_int3_coeff_size, c_combinedResponse);
/* Determine overall response with analog filters inline */
b_analogresp(RxTx, omega, converter_rate, b1_data, b1_size, a1, b2_data,
b2_size, a2, rg1);
i0 = rg1->size[0] * rg1->size[1];
rg1->size[0] = 1;
rg1->size[1] = c_combinedResponse->size[1];
emxEnsureCapacity_creal_T(rg1, i0);
loop_ub = c_combinedResponse->size[0] * c_combinedResponse->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
sigmax = c_combinedResponse->data[i0].re;
apnd = c_combinedResponse->data[i0].im;
absa = rg1->data[i0].re;
rg1_im = rg1->data[i0].im;
rg1->data[i0].re = sigmax * absa - apnd * rg1_im;
rg1->data[i0].im = sigmax * rg1_im + apnd * absa;
}
emxInit_creal_T(&r0, 2);
i0 = r0->size[0] * r0->size[1];
r0->size[0] = 1;
r0->size[1] = omega->size[1];
emxEnsureCapacity_creal_T(r0, i0);
loop_ub = omega->size[0] * omega->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
re = omega->data[i0] * -0.0;
im = omega->data[i0] * -6.2831853071795862;
r0->data[i0].re = sigma * re;
r0->data[i0].im = sigma * im;
}
c_exp(r0);
b_rdivide(r0, rg1, c_combinedResponse);
sigma = Gpass + 1.0;
/* Expand memory correctly */
emxInit_real_T(&sw, 2);
if (rtIsNaN(Gstop)) {
i0 = sw->size[0] * sw->size[1];
sw->size[1] = 1;
emxEnsureCapacity_real_T(sw, i0);
} else if (8192.0 < Gstop) {
i0 = sw->size[0] * sw->size[1];
sw->size[1] = 0;
emxEnsureCapacity_real_T(sw, i0);
} else if (rtIsInf(Gstop) && (Gstop == 8192.0)) {
i0 = sw->size[0] * sw->size[1];
sw->size[1] = 1;
emxEnsureCapacity_real_T(sw, i0);
} else if (Gstop == Gstop) {
i0 = sw->size[0] * sw->size[1];
sw->size[0] = 1;
sw->size[1] = (int)(8192.0 - Gstop) + 1;
emxEnsureCapacity_real_T(sw, i0);
loop_ub = (int)(8192.0 - Gstop);
for (i0 = 0; i0 <= loop_ub; i0++) {
sw->data[sw->size[0] * i0] = Gstop + (double)i0;
}
} else {
sigmax = floor((8192.0 - Gstop) + 0.5);
apnd = Gstop + sigmax;
absa = fabs(Gstop);
if (!(absa > 8192.0)) {
absa = 8192.0;
}
if (fabs(apnd - 8192.0) < 4.4408920985006262E-16 * absa) {
sigmax++;
apnd = 8192.0;
} else if (apnd - 8192.0 > 0.0) {
apnd = Gstop + (sigmax - 1.0);
} else {
sigmax++;
}
if (sigmax >= 0.0) {
n = (int)sigmax;
} else {
n = 0;
}
i0 = sw->size[0] * sw->size[1];
sw->size[0] = 1;
sw->size[1] = n;
emxEnsureCapacity_real_T(sw, i0);
if (n > 0) {
sw->data[0] = Gstop;
if (n > 1) {
sw->data[n - 1] = apnd;
hb3 = (n - 1) / 2;
for (dec_int3 = 1; dec_int3 < hb3; dec_int3++) {
sw->data[dec_int3] = Gstop + (double)dec_int3;
sw->data[(n - dec_int3) - 1] = apnd - (double)dec_int3;
}
if (hb3 << 1 == n - 1) {
sw->data[hb3] = (Gstop + apnd) / 2.0;
} else {
sw->data[hb3] = Gstop + (double)hb3;
sw->data[hb3 + 1] = apnd - (double)hb3;
}
}
}
}
emxInit_real_T(&fg2, 2);
i0 = fg2->size[0] * fg2->size[1];
fg2->size[0] = 1;
fg2->size[1] = (int)((unsigned int)sw->size[1] + fg->size[1]);
emxEnsureCapacity_real_T(fg2, i0);
loop_ub = (int)((unsigned int)sw->size[1] + fg->size[1]);
for (i0 = 0; i0 < loop_ub; i0++) {
fg2->data[i0] = 0.0;
}
loop_ub = fg->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
fg2->data[i0] = fg->data[fg->size[0] * i0];
}
if (rtIsNaN(Gstop)) {
i0 = sw->size[0] * sw->size[1];
sw->size[1] = 1;
emxEnsureCapacity_real_T(sw, i0);
} else if (8192.0 < Gstop) {
i0 = sw->size[0] * sw->size[1];
sw->size[1] = 0;
emxEnsureCapacity_real_T(sw, i0);
} else if (rtIsInf(Gstop) && (Gstop == 8192.0)) {
i0 = sw->size[0] * sw->size[1];
sw->size[1] = 1;
emxEnsureCapacity_real_T(sw, i0);
} else if (Gstop == Gstop) {
i0 = sw->size[0] * sw->size[1];
sw->size[0] = 1;
sw->size[1] = (int)(8192.0 - Gstop) + 1;
emxEnsureCapacity_real_T(sw, i0);
loop_ub = (int)(8192.0 - Gstop);
for (i0 = 0; i0 <= loop_ub; i0++) {
sw->data[sw->size[0] * i0] = Gstop + (double)i0;
}
} else {
sigmax = floor((8192.0 - Gstop) + 0.5);
apnd = Gstop + sigmax;
absa = fabs(Gstop);
if (!(absa > 8192.0)) {
absa = 8192.0;
}
if (fabs(apnd - 8192.0) < 4.4408920985006262E-16 * absa) {
sigmax++;
apnd = 8192.0;
} else if (apnd - 8192.0 > 0.0) {
apnd = Gstop + (sigmax - 1.0);
} else {
sigmax++;
}
if (sigmax >= 0.0) {
n = (int)sigmax;
} else {
n = 0;
}
i0 = sw->size[0] * sw->size[1];
sw->size[0] = 1;
sw->size[1] = n;
emxEnsureCapacity_real_T(sw, i0);
if (n > 0) {
sw->data[0] = Gstop;
if (n > 1) {
sw->data[n - 1] = apnd;
hb3 = (n - 1) / 2;
for (dec_int3 = 1; dec_int3 < hb3; dec_int3++) {
sw->data[dec_int3] = Gstop + (double)dec_int3;
sw->data[(n - dec_int3) - 1] = apnd - (double)dec_int3;
}
if (hb3 << 1 == n - 1) {
sw->data[hb3] = (Gstop + apnd) / 2.0;
} else {
sw->data[hb3] = Gstop + (double)hb3;
sw->data[hb3 + 1] = apnd - (double)hb3;
}
}
}
}
emxInit_real_T(&omega2, 2);
i0 = omega2->size[0] * omega2->size[1];
omega2->size[0] = 1;
omega2->size[1] = (int)((unsigned int)sw->size[1] + omega->size[1]);
emxEnsureCapacity_real_T(omega2, i0);
loop_ub = (int)((unsigned int)sw->size[1] + omega->size[1]);
for (i0 = 0; i0 < loop_ub; i0++) {
omega2->data[i0] = 0.0;
}
loop_ub = omega->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
omega2->data[i0] = omega->data[omega->size[0] * i0];
}
if (rtIsNaN(Gstop)) {
i0 = sw->size[0] * sw->size[1];
sw->size[1] = 1;
emxEnsureCapacity_real_T(sw, i0);
} else if (8192.0 < Gstop) {
i0 = sw->size[0] * sw->size[1];
sw->size[1] = 0;
emxEnsureCapacity_real_T(sw, i0);
} else if (rtIsInf(Gstop) && (Gstop == 8192.0)) {
i0 = sw->size[0] * sw->size[1];
sw->size[1] = 1;
emxEnsureCapacity_real_T(sw, i0);
} else if (Gstop == Gstop) {
i0 = sw->size[0] * sw->size[1];
sw->size[0] = 1;
sw->size[1] = (int)(8192.0 - Gstop) + 1;
emxEnsureCapacity_real_T(sw, i0);
loop_ub = (int)(8192.0 - Gstop);
for (i0 = 0; i0 <= loop_ub; i0++) {
sw->data[sw->size[0] * i0] = Gstop + (double)i0;
}
} else {
sigmax = floor((8192.0 - Gstop) + 0.5);
apnd = Gstop + sigmax;
absa = fabs(Gstop);
if (!(absa > 8192.0)) {
absa = 8192.0;
}
if (fabs(apnd - 8192.0) < 4.4408920985006262E-16 * absa) {
sigmax++;
apnd = 8192.0;
} else if (apnd - 8192.0 > 0.0) {
apnd = Gstop + (sigmax - 1.0);
} else {
sigmax++;
}
if (sigmax >= 0.0) {
n = (int)sigmax;
} else {
n = 0;
}
i0 = sw->size[0] * sw->size[1];
sw->size[0] = 1;
sw->size[1] = n;
emxEnsureCapacity_real_T(sw, i0);
if (n > 0) {
sw->data[0] = Gstop;
if (n > 1) {
sw->data[n - 1] = apnd;
hb3 = (n - 1) / 2;
for (dec_int3 = 1; dec_int3 < hb3; dec_int3++) {
sw->data[dec_int3] = Gstop + (double)dec_int3;
sw->data[(n - dec_int3) - 1] = apnd - (double)dec_int3;
}
if (hb3 << 1 == n - 1) {
sw->data[hb3] = (Gstop + apnd) / 2.0;
} else {
sw->data[hb3] = Gstop + (double)hb3;
sw->data[hb3 + 1] = apnd - (double)hb3;
}
}
}
}
emxInit_creal_T(&rgN, 2);
i0 = rgN->size[0] * rgN->size[1];
rgN->size[0] = 1;
rgN->size[1] = (int)((unsigned int)sw->size[1] + c_combinedResponse->size[1]);
emxEnsureCapacity_creal_T(rgN, i0);
loop_ub = (int)((unsigned int)sw->size[1] + c_combinedResponse->size[1]);
for (i0 = 0; i0 < loop_ub; i0++) {
rgN->data[i0].re = 0.0;
rgN->data[i0].im = 0.0;
}
loop_ub = c_combinedResponse->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
rgN->data[i0] = c_combinedResponse->data[c_combinedResponse->size[0] * i0];
}
/* stop band */
for (hb3 = 0; hb3 < (int)(8192.0 + (1.0 - Gstop)); hb3++) {
sigma++;
fg2->data[(int)sigma - 1] = (Gstop + (double)hb3) / 16384.0;
omega2->data[(int)sigma - 1] = fg2->data[(int)sigma - 1] * clkFIR;
rgN->data[(int)sigma - 1].re = 0.0;
rgN->data[(int)sigma - 1].im = 0.0;
}
/* Generate responses then convolve */
if (Gpass + 2.0 > omega2->size[1]) {
i0 = 0;
n = 0;
} else {
i0 = (int)(Gpass + 2.0) - 1;
n = omega2->size[1];
}
emxInit_real_T(&b_omega2, 2);
hb3 = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = n - i0;
emxEnsureCapacity_real_T(b_omega2, hb3);
loop_ub = n - i0;
for (n = 0; n < loop_ub; n++) {
b_omega2->data[b_omega2->size[0] * n] = omega2->data[i0 + n];
}
b_generateCascadedResponseRx(enables, b_omega2, converter_rate, hb1_coeff,
hb2_coeff, hb3_coeff_data, hb3_coeff_size, dec_int3_coeff_data,
dec_int3_coeff_size, c_combinedResponse);
if (Gpass + 2.0 > omega2->size[1]) {
i0 = 0;
n = 0;
} else {
i0 = (int)(Gpass + 2.0) - 1;
n = omega2->size[1];
}
hb3 = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = n - i0;
emxEnsureCapacity_real_T(b_omega2, hb3);
loop_ub = n - i0;
for (n = 0; n < loop_ub; n++) {
b_omega2->data[b_omega2->size[0] * n] = omega2->data[i0 + n];
}
emxInit_creal_T(&d_combinedResponse, 2);
b_analogresp(RxTx, b_omega2, converter_rate, b1_data, b1_size, a1, b2_data,
b2_size, a2, r0);
i0 = d_combinedResponse->size[0] * d_combinedResponse->size[1];
d_combinedResponse->size[0] = 1;
d_combinedResponse->size[1] = c_combinedResponse->size[1];
emxEnsureCapacity_creal_T(d_combinedResponse, i0);
loop_ub = c_combinedResponse->size[0] * c_combinedResponse->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
sigmax = c_combinedResponse->data[i0].re;
apnd = c_combinedResponse->data[i0].im;
re = r0->data[i0].re;
im = r0->data[i0].im;
d_combinedResponse->data[i0].re = sigmax * re - apnd * im;
d_combinedResponse->data[i0].im = sigmax * im + apnd * re;
}
b_abs(d_combinedResponse, fg);
emxInit_real_T(&a, 2);
if (b_strcmp(RxTx)) {
rdivide(fg, dBinv(-Astop), omega);
} else {
sigma = FIR;
b_sqrt(&sigma);
i0 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = fg->size[1];
emxEnsureCapacity_real_T(a, i0);
loop_ub = fg->size[0] * fg->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
a->data[i0] = sigma * fg->data[i0];
}
rdivide(a, dBinv(-Astop), omega);
}
emxInit_real_T(&wg, 2);
sigma = dBinv(FIRdBmin);
hb3 = omega->size[1];
i0 = wg->size[0] * wg->size[1];
wg->size[0] = 1;
wg->size[1] = omega->size[1];
emxEnsureCapacity_real_T(wg, i0);
for (dec_int3 = 0; dec_int3 + 1 <= hb3; dec_int3++) {
if ((omega->data[dec_int3] > sigma) || rtIsNaN(sigma)) {
sigmax = omega->data[dec_int3];
} else {
sigmax = sigma;
}
wg->data[dec_int3] = sigmax;
}
if (phEQ == -1.0) {
b_abs(rgN, sw);
i0 = rgN->size[0] * rgN->size[1];
rgN->size[0] = 1;
rgN->size[1] = sw->size[1];
emxEnsureCapacity_creal_T(rgN, i0);
loop_ub = sw->size[0] * sw->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
rgN->data[i0].re = sw->data[i0];
rgN->data[i0].im = 0.0;
}
}
emxInit_real_T(&weight, 2);
b_abs(rg1, sw);
rdivide(sw, dBinv(Apass / 2.0) - 1.0, fg);
i0 = weight->size[0] * weight->size[1];
weight->size[0] = 1;
weight->size[1] = fg->size[1] + wg->size[1];
emxEnsureCapacity_real_T(weight, i0);
loop_ub = fg->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
weight->data[weight->size[0] * i0] = fg->data[fg->size[0] * i0];
}
loop_ub = wg->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
weight->data[weight->size[0] * (i0 + fg->size[1])] = wg->data[wg->size[0] *
i0];
}
hb3 = 1;
n = weight->size[1];
sigma = weight->data[0];
if (weight->size[1] > 1) {
if (rtIsNaN(weight->data[0])) {
dec_int3 = 2;
exitg1 = false;
while ((!exitg1) && (dec_int3 <= n)) {
hb3 = dec_int3;
if (!rtIsNaN(weight->data[dec_int3 - 1])) {
sigma = weight->data[dec_int3 - 1];
exitg1 = true;
} else {
dec_int3++;
}
}
}
if (hb3 < weight->size[1]) {
while (hb3 + 1 <= n) {
if (weight->data[hb3] > sigma) {
sigma = weight->data[hb3];
}
hb3++;
}
}
}
i0 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = weight->size[1];
emxEnsureCapacity_real_T(a, i0);
loop_ub = weight->size[0] * weight->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
a->data[i0] = weight->data[i0];
}
rdivide(a, sigma, weight);
/* Set up design for FIR filter */
i0 = fg->size[0] * fg->size[1];
fg->size[0] = 1;
fg->size[1] = rgN->size[1];
emxEnsureCapacity_real_T(fg, i0);
loop_ub = rgN->size[0] * rgN->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
fg->data[i0] = rgN->data[i0].re;
}
if (1.0 > Gpass + 1.0) {
loop_ub = 0;
} else {
loop_ub = (int)(Gpass + 1.0);
}
emxInit_real_T(&F1, 2);
i0 = F1->size[0] * F1->size[1];
F1->size[0] = 1;
F1->size[1] = loop_ub;
emxEnsureCapacity_real_T(F1, i0);
for (i0 = 0; i0 < loop_ub; i0++) {
F1->data[F1->size[0] * i0] = fg2->data[i0] * 2.0;
}
if (Gpass + 2.0 > fg2->size[1]) {
i0 = 0;
n = 0;
} else {
i0 = (int)(Gpass + 2.0) - 1;
n = fg2->size[1];
}
emxInit_real_T(&F2, 2);
hb3 = F2->size[0] * F2->size[1];
F2->size[0] = 1;
F2->size[1] = n - i0;
emxEnsureCapacity_real_T(F2, hb3);
loop_ub = n - i0;
for (n = 0; n < loop_ub; n++) {
F2->data[F2->size[0] * n] = fg2->data[i0 + n] * 2.0;
}
if (1.0 > Gpass + 1.0) {
loop_ub = 0;
} else {
loop_ub = (int)(Gpass + 1.0);
}
emxInit_real_T(&A1, 2);
i0 = A1->size[0] * A1->size[1];
A1->size[0] = 1;
A1->size[1] = loop_ub;
emxEnsureCapacity_real_T(A1, i0);
for (i0 = 0; i0 < loop_ub; i0++) {
A1->data[A1->size[0] * i0] = fg->data[i0];
}
if (Gpass + 2.0 > fg->size[1]) {
i0 = 0;
n = 0;
} else {
i0 = (int)(Gpass + 2.0) - 1;
n = fg->size[1];
}
emxInit_real_T(&A2, 2);
hb3 = A2->size[0] * A2->size[1];
A2->size[0] = 1;
A2->size[1] = n - i0;
emxEnsureCapacity_real_T(A2, hb3);
loop_ub = n - i0;
for (n = 0; n < loop_ub; n++) {
A2->data[A2->size[0] * n] = fg->data[i0 + n];
}
if (1.0 > Gpass + 1.0) {
loop_ub = 0;
} else {
loop_ub = (int)(Gpass + 1.0);
}
emxInit_real_T(&W1, 2);
i0 = W1->size[0] * W1->size[1];
W1->size[0] = 1;
W1->size[1] = loop_ub;
emxEnsureCapacity_real_T(W1, i0);
for (i0 = 0; i0 < loop_ub; i0++) {
W1->data[W1->size[0] * i0] = weight->data[i0];
}
if (Gpass + 2.0 > weight->size[1]) {
i0 = 0;
n = 0;
} else {
i0 = (int)(Gpass + 2.0) - 1;
n = weight->size[1];
}
emxInit_real_T(&W2, 2);
hb3 = W2->size[0] * W2->size[1];
W2->size[0] = 1;
W2->size[1] = n - i0;
emxEnsureCapacity_real_T(W2, hb3);
loop_ub = n - i0;
for (n = 0; n < loop_ub; n++) {
W2->data[W2->size[0] * n] = weight->data[i0 + n];
}
emxInit_real_T(&tap_store, 2);
/* % Determine the number of taps for FIR */
/* if strcmp(input.RxTx, 'Rx') */
/* if hb3 == 1 */
/* N = min(16*floor(input.converter_rate/(input.Rdata)),128); */
/* else */
/* N = min(16*floor(input.converter_rate/(2*input.Rdata)),128); */
/* end */
/* else */
/* switch input.FIR */
/* case 1 */
/* Nmax = 64; */
/* case 2 */
/* Nmax = 128; */
/* case 4 */
/* Nmax = 128; */
/* otherwise */
/* error('Wrong FIR Type'); */
/* end */
/* N = min(16*floor(input.converter_rate*input.DAC_div/(2*input.Rdata)),Nmax); */
/* end */
clkFIR = maxTaps;
sigma = maxTaps / 16.0;
i0 = tap_store->size[0] * tap_store->size[1];
tap_store->size[0] = (int)sigma;
tap_store->size[1] = (int)maxTaps;
emxEnsureCapacity_real_T(tap_store, i0);
loop_ub = (int)sigma * (int)maxTaps;
for (i0 = 0; i0 < loop_ub; i0++) {
tap_store->data[i0] = 0.0;
}
emxInit_real_T1(&Apass_actual_vector, 1);
sigma = maxTaps / 16.0;
i0 = Apass_actual_vector->size[0];
Apass_actual_vector->size[0] = (int)sigma;
emxEnsureCapacity_real_T1(Apass_actual_vector, i0);
loop_ub = (int)sigma;
for (i0 = 0; i0 < loop_ub; i0++) {
Apass_actual_vector->data[i0] = 0.0;
}
emxInit_real_T1(&Astop_actual_vector, 1);
sigma = maxTaps / 16.0;
i0 = Astop_actual_vector->size[0];
Astop_actual_vector->size[0] = (int)sigma;
emxEnsureCapacity_real_T1(Astop_actual_vector, i0);
loop_ub = (int)sigma;
for (i0 = 0; i0 < loop_ub; i0++) {
Astop_actual_vector->data[i0] = 0.0;
}
i = 1U;
/* Design filter */
emxInit_real_T(&ccoef, 2);
emxInit_real_T(&F4, 2);
emxInit_real_T(&b_W1, 2);
do {
exitg2 = 0;
if (int_FIR != 0.0) {
b1[0] = F1->data[0];
b1[1] = F1->data[F1->size[1] - 1];
b1[2] = F2->data[0];
b1[3] = F2->data[F2->size[1] - 1];
i0 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = A1->size[1] + A2->size[1];
emxEnsureCapacity_real_T(a, i0);
loop_ub = A1->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
a->data[a->size[0] * i0] = A1->data[A1->size[0] * i0];
}
loop_ub = A2->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
a->data[a->size[0] * (i0 + A1->size[1])] = A2->data[A2->size[0] * i0];
}
i0 = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = F1->size[1] + F2->size[1];
emxEnsureCapacity_real_T(b_omega2, i0);
loop_ub = F1->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
b_omega2->data[b_omega2->size[0] * i0] = F1->data[F1->size[0] * i0];
}
loop_ub = F2->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
b_omega2->data[b_omega2->size[0] * (i0 + F1->size[1])] = F2->data
[F2->size[0] * i0];
}
i0 = b_W1->size[0] * b_W1->size[1];
b_W1->size[0] = 1;
b_W1->size[1] = W1->size[1] + W2->size[1];
emxEnsureCapacity_real_T(b_W1, i0);
loop_ub = W1->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
b_W1->data[b_W1->size[0] * i0] = W1->data[W1->size[0] * i0];
}
loop_ub = W2->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
b_W1->data[b_W1->size[0] * (i0 + W1->size[1])] = W2->data[W2->size[0] *
i0];
}
firpm_cg(clkFIR - 1.0, b1, a, b_omega2, b_W1, ccoef);
} else {
/* Check different designs until we reach required ripple condition */
sigma = db2mag(-Astop);
/* Peak Ripple */
i0 = ccoef->size[0] * ccoef->size[1];
ccoef->size[0] = 1;
ccoef->size[1] = 1;
emxEnsureCapacity_real_T(ccoef, i0);
ccoef->data[0] = 0.0;
/* Predef type */
dec_int3 = 0;
exitg1 = false;
while ((!exitg1) && (dec_int3 < 126)) {
b1[0] = F1->data[0];
b1[1] = F1->data[F1->size[1] - 1];
b1[2] = F2->data[0];
b1[3] = F2->data[F2->size[1] - 1];
i0 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = A1->size[1] + A2->size[1];
emxEnsureCapacity_real_T(a, i0);
loop_ub = A1->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
a->data[a->size[0] * i0] = A1->data[A1->size[0] * i0];
}
loop_ub = A2->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
a->data[a->size[0] * (i0 + A1->size[1])] = A2->data[A2->size[0] * i0];
}
i0 = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = F1->size[1] + F2->size[1];
emxEnsureCapacity_real_T(b_omega2, i0);
loop_ub = F1->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
b_omega2->data[b_omega2->size[0] * i0] = F1->data[F1->size[0] * i0];
}
loop_ub = F2->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
b_omega2->data[b_omega2->size[0] * (i0 + F1->size[1])] = F2->data
[F2->size[0] * i0];
}
i0 = b_W1->size[0] * b_W1->size[1];
b_W1->size[0] = 1;
b_W1->size[1] = W1->size[1] + W2->size[1];
emxEnsureCapacity_real_T(b_W1, i0);
loop_ub = W1->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
b_W1->data[b_W1->size[0] * i0] = W1->data[W1->size[0] * i0];
}
loop_ub = W2->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
b_W1->data[b_W1->size[0] * (i0 + W1->size[1])] = W2->data[W2->size[0] *
i0];
}
b_firpm_cg(3.0 + (double)dec_int3, b1, a, b_omega2, b_W1, ccoef, &valid,
&sigmax);
/* Check if design meets specs */
if ((sigmax < sigma) && valid) {
exitg1 = true;
} else {
dec_int3++;
}
}
}
/* Enable phase equalization and apply update to taps */
if (phEQ != -1.0) {
if (1 > fg2->size[1]) {
i0 = 1;
n = 1;
hb3 = 0;
} else {
i0 = fg2->size[1];
n = -1;
hb3 = 1;
}
i2 = fg->size[0] * fg->size[1];
fg->size[0] = 1;
fg->size[1] = div_s32_floor(hb3 - i0, n) + 1;
emxEnsureCapacity_real_T(fg, i2);
loop_ub = div_s32_floor(hb3 - i0, n);
for (hb3 = 0; hb3 <= loop_ub; hb3++) {
fg->data[fg->size[0] * hb3] = 0.5 - fg2->data[(i0 + n * hb3) - 1];
}
if (1 > rgN->size[1]) {
i0 = 1;
n = 1;
hb3 = 0;
} else {
i0 = rgN->size[1];
n = -1;
hb3 = 1;
}
i2 = omega->size[0] * omega->size[1];
omega->size[0] = 1;
omega->size[1] = div_s32_floor(hb3 - i0, n) + 1;
emxEnsureCapacity_real_T(omega, i2);
loop_ub = div_s32_floor(hb3 - i0, n);
for (hb3 = 0; hb3 <= loop_ub; hb3++) {
omega->data[omega->size[0] * hb3] = rgN->data[(i0 + n * hb3) - 1].im;
}
if (1 > weight->size[1]) {
i0 = 1;
n = 1;
hb3 = 0;
} else {
i0 = weight->size[1];
n = -1;
hb3 = 1;
}
i2 = sw->size[0] * sw->size[1];
sw->size[0] = 1;
sw->size[1] = div_s32_floor(hb3 - i0, n) + 1;
emxEnsureCapacity_real_T(sw, i2);
loop_ub = div_s32_floor(hb3 - i0, n);
for (i2 = 0; i2 <= loop_ub; i2++) {
sw->data[sw->size[0] * i2] = weight->data[(i0 + n * i2) - 1];
}
if (1.0 > (8192.0 - Gstop) + 1.0) {
loop_ub = 0;
} else {
loop_ub = (int)((8192.0 - Gstop) + 1.0);
}
i2 = wg->size[0] * wg->size[1];
wg->size[0] = 1;
wg->size[1] = loop_ub;
emxEnsureCapacity_real_T(wg, i2);
for (i2 = 0; i2 < loop_ub; i2++) {
wg->data[wg->size[0] * i2] = fg->data[i2] * 2.0;
}
if ((8192.0 - Gstop) + 2.0 > fg->size[1]) {
i2 = 0;
dec_int3 = 0;
} else {
i2 = (int)((8192.0 - Gstop) + 2.0) - 1;
dec_int3 = fg->size[1];
}
i3 = F4->size[0] * F4->size[1];
F4->size[0] = 1;
F4->size[1] = dec_int3 - i2;
emxEnsureCapacity_real_T(F4, i3);
loop_ub = dec_int3 - i2;
for (dec_int3 = 0; dec_int3 < loop_ub; dec_int3++) {
F4->data[F4->size[0] * dec_int3] = fg->data[i2 + dec_int3] * 2.0;
}
if (1.0 > (8192.0 - Gstop) + 1.0) {
loop_ub = 0;
} else {
loop_ub = (int)((8192.0 - Gstop) + 1.0);
}
if ((8192.0 - Gstop) + 2.0 > omega->size[1]) {
i2 = 0;
dec_int3 = 0;
} else {
i2 = (int)((8192.0 - Gstop) + 2.0) - 1;
dec_int3 = omega->size[1];
}
if (1.0 > (8192.0 - Gstop) + 1.0) {
b_loop_ub = 0;
} else {
b_loop_ub = (int)((8192.0 - Gstop) + 1.0);
}
if ((8192.0 - Gstop) + 2.0 > div_s32_floor(hb3 - i0, n) + 1) {
i3 = 0;
i0 = -1;
} else {
i3 = (int)((8192.0 - Gstop) + 2.0) - 1;
i0 = div_s32_floor(hb3 - i0, n);
}
if (int_FIR != 0.0) {
sigma = clkFIR - 1.0;
} else {
sigma = (double)ccoef->size[1] - 1.0;
}
b1[0] = wg->data[0];
b1[1] = wg->data[wg->size[1] - 1];
b1[2] = F4->data[0];
b1[3] = F4->data[F4->size[1] - 1];
n = b_W1->size[0] * b_W1->size[1];
b_W1->size[0] = 1;
b_W1->size[1] = (loop_ub + dec_int3) - i2;
emxEnsureCapacity_real_T(b_W1, n);
for (n = 0; n < loop_ub; n++) {
b_W1->data[b_W1->size[0] * n] = omega->data[n];
}
hb3 = dec_int3 - i2;
for (n = 0; n < hb3; n++) {
b_W1->data[b_W1->size[0] * (n + loop_ub)] = omega->data[i2 + n];
}
n = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = wg->size[1] + F4->size[1];
emxEnsureCapacity_real_T(a, n);
loop_ub = wg->size[1];
for (n = 0; n < loop_ub; n++) {
a->data[a->size[0] * n] = wg->data[wg->size[0] * n];
}
loop_ub = F4->size[1];
for (n = 0; n < loop_ub; n++) {
a->data[a->size[0] * (n + wg->size[1])] = F4->data[F4->size[0] * n];
}
n = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = ((b_loop_ub + i0) - i3) + 1;
emxEnsureCapacity_real_T(b_omega2, n);
for (n = 0; n < b_loop_ub; n++) {
b_omega2->data[b_omega2->size[0] * n] = sw->data[n];
}
loop_ub = i0 - i3;
for (i0 = 0; i0 <= loop_ub; i0++) {
b_omega2->data[b_omega2->size[0] * (i0 + b_loop_ub)] = sw->data[i3 + i0];
}
firpm_cg(sigma, b1, b_W1, a, b_omega2, fg);
i0 = fg->size[1];
for (dec_int3 = 0; dec_int3 < i0; dec_int3++) {
fg->data[dec_int3] = -fg->data[dec_int3] * mpower(-1.0, (1.0 + (double)
dec_int3) - 1.0);
}
} else {
for (i0 = 0; i0 < 2; i0++) {
b2[i0] = ccoef->size[i0];
}
i0 = fg->size[0] * fg->size[1];
fg->size[0] = 1;
fg->size[1] = (int)b2[1];
emxEnsureCapacity_real_T(fg, i0);
loop_ub = (int)b2[1];
for (i0 = 0; i0 < loop_ub; i0++) {
fg->data[i0] = 0.0;
}
}
loop_ub = ccoef->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
tap_store->data[((int)i + tap_store->size[0] * i0) - 1] = ccoef->
data[ccoef->size[0] * i0] + fg->data[fg->size[0] * i0];
}
/* scoef ==0 when no EQ */
determineBestFractionLength(tap_store, i, ccoef->size[1], a);
loop_ub = a->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
tap_store->data[((int)i + tap_store->size[0] * i0) - 1] = a->data[a->size
[0] * i0];
}
if (b_strcmp(RxTx)) {
if (1.0 > Gpass + 1.0) {
loop_ub = 0;
} else {
loop_ub = (int)(Gpass + 1.0);
}
if (1 > ccoef->size[1]) {
b_loop_ub = 0;
} else {
b_loop_ub = ccoef->size[1];
}
i0 = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = loop_ub;
emxEnsureCapacity_real_T(b_omega2, i0);
for (i0 = 0; i0 < loop_ub; i0++) {
b_omega2->data[b_omega2->size[0] * i0] = omega2->data[i0];
}
i0 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = b_loop_ub;
emxEnsureCapacity_real_T(a, i0);
for (i0 = 0; i0 < b_loop_ub; i0++) {
a->data[a->size[0] * i0] = tap_store->data[((int)i + tap_store->size[0] *
i0) - 1];
}
c_generateCascadedResponseRx(enables, b_omega2, converter_rate, hb1_coeff,
hb2_coeff, hb3_coeff_data, hb3_coeff_size, dec_int3_coeff_data,
dec_int3_coeff_size, a, c_combinedResponse);
if (Gpass + 2.0 > omega2->size[1]) {
i0 = 0;
n = 0;
} else {
i0 = (int)(Gpass + 2.0) - 1;
n = omega2->size[1];
}
if (1 > ccoef->size[1]) {
loop_ub = 0;
} else {
loop_ub = ccoef->size[1];
}
hb3 = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = n - i0;
emxEnsureCapacity_real_T(b_omega2, hb3);
b_loop_ub = n - i0;
for (n = 0; n < b_loop_ub; n++) {
b_omega2->data[b_omega2->size[0] * n] = omega2->data[i0 + n];
}
i0 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = loop_ub;
emxEnsureCapacity_real_T(a, i0);
for (i0 = 0; i0 < loop_ub; i0++) {
a->data[a->size[0] * i0] = tap_store->data[((int)i + tap_store->size[0] *
i0) - 1];
}
c_generateCascadedResponseRx(enables, b_omega2, converter_rate, hb1_coeff,
hb2_coeff, hb3_coeff_data, hb3_coeff_size, dec_int3_coeff_data,
dec_int3_coeff_size, a, rg1);
if (1.0 > Gpass + 1.0) {
loop_ub = 0;
} else {
loop_ub = (int)(Gpass + 1.0);
}
i0 = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = loop_ub;
emxEnsureCapacity_real_T(b_omega2, i0);
for (i0 = 0; i0 < loop_ub; i0++) {
b_omega2->data[b_omega2->size[0] * i0] = omega2->data[i0];
}
c_analogresp(b_omega2, converter_rate, b1_data, b1_size, a1, b2_data,
b2_size, a2, r0);
i0 = d_combinedResponse->size[0] * d_combinedResponse->size[1];
d_combinedResponse->size[0] = 1;
d_combinedResponse->size[1] = r0->size[1];
emxEnsureCapacity_creal_T(d_combinedResponse, i0);
loop_ub = r0->size[0] * r0->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
re = r0->data[i0].re;
im = r0->data[i0].im;
sigmax = c_combinedResponse->data[i0].re;
apnd = c_combinedResponse->data[i0].im;
d_combinedResponse->data[i0].re = re * sigmax - im * apnd;
d_combinedResponse->data[i0].im = re * apnd + im * sigmax;
}
b_abs(d_combinedResponse, fg);
if (Gpass + 2.0 > omega2->size[1]) {
i0 = 0;
n = 0;
} else {
i0 = (int)(Gpass + 2.0) - 1;
n = omega2->size[1];
}
hb3 = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = n - i0;
emxEnsureCapacity_real_T(b_omega2, hb3);
loop_ub = n - i0;
for (n = 0; n < loop_ub; n++) {
b_omega2->data[b_omega2->size[0] * n] = omega2->data[i0 + n];
}
c_analogresp(b_omega2, converter_rate, b1_data, b1_size, a1, b2_data,
b2_size, a2, r0);
i0 = d_combinedResponse->size[0] * d_combinedResponse->size[1];
d_combinedResponse->size[0] = 1;
d_combinedResponse->size[1] = r0->size[1];
emxEnsureCapacity_creal_T(d_combinedResponse, i0);
loop_ub = r0->size[0] * r0->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
re = r0->data[i0].re;
im = r0->data[i0].im;
absa = rg1->data[i0].re;
rg1_im = rg1->data[i0].im;
d_combinedResponse->data[i0].re = re * absa - im * rg1_im;
d_combinedResponse->data[i0].im = re * rg1_im + im * absa;
}
b_abs(d_combinedResponse, omega);
} else {
/* TX */
if (1.0 > Gpass + 1.0) {
loop_ub = 0;
} else {
loop_ub = (int)(Gpass + 1.0);
}
if (1 > ccoef->size[1]) {
b_loop_ub = 0;
} else {
b_loop_ub = ccoef->size[1];
}
i0 = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = loop_ub;
emxEnsureCapacity_real_T(b_omega2, i0);
for (i0 = 0; i0 < loop_ub; i0++) {
b_omega2->data[b_omega2->size[0] * i0] = omega2->data[i0];
}
i0 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = b_loop_ub;
emxEnsureCapacity_real_T(a, i0);
for (i0 = 0; i0 < b_loop_ub; i0++) {
a->data[a->size[0] * i0] = tap_store->data[((int)i + tap_store->size[0] *
i0) - 1];
}
c_generateCascadedResponseRx(enables, b_omega2, converter_rate, hb1_coeff,
hb2_coeff, hb3_coeff_data, hb3_coeff_size, dec_int3_coeff_data,
dec_int3_coeff_size, a, c_combinedResponse);
if (Gpass + 2.0 > omega2->size[1]) {
i0 = 0;
n = 0;
} else {
i0 = (int)(Gpass + 2.0) - 1;
n = omega2->size[1];
}
if (1 > ccoef->size[1]) {
loop_ub = 0;
} else {
loop_ub = ccoef->size[1];
}
hb3 = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = n - i0;
emxEnsureCapacity_real_T(b_omega2, hb3);
b_loop_ub = n - i0;
for (n = 0; n < b_loop_ub; n++) {
b_omega2->data[b_omega2->size[0] * n] = omega2->data[i0 + n];
}
i0 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = loop_ub;
emxEnsureCapacity_real_T(a, i0);
for (i0 = 0; i0 < loop_ub; i0++) {
a->data[a->size[0] * i0] = tap_store->data[((int)i + tap_store->size[0] *
i0) - 1];
}
c_generateCascadedResponseRx(enables, b_omega2, converter_rate, hb1_coeff,
hb2_coeff, hb3_coeff_data, hb3_coeff_size, dec_int3_coeff_data,
dec_int3_coeff_size, a, rg1);
if (1.0 > Gpass + 1.0) {
loop_ub = 0;
} else {
loop_ub = (int)(Gpass + 1.0);
}
i0 = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = loop_ub;
emxEnsureCapacity_real_T(b_omega2, i0);
for (i0 = 0; i0 < loop_ub; i0++) {
b_omega2->data[b_omega2->size[0] * i0] = omega2->data[i0];
}
d_analogresp(b_omega2, converter_rate, b1_data, b1_size, a1, b2_data,
b2_size, a2, r0);
i0 = d_combinedResponse->size[0] * d_combinedResponse->size[1];
d_combinedResponse->size[0] = 1;
d_combinedResponse->size[1] = c_combinedResponse->size[1];
emxEnsureCapacity_creal_T(d_combinedResponse, i0);
loop_ub = c_combinedResponse->size[0] * c_combinedResponse->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
sigmax = c_combinedResponse->data[i0].re;
apnd = c_combinedResponse->data[i0].im;
re = r0->data[i0].re;
im = r0->data[i0].im;
d_combinedResponse->data[i0].re = sigmax * re - apnd * im;
d_combinedResponse->data[i0].im = sigmax * im + apnd * re;
}
b_abs(d_combinedResponse, fg);
if (Gpass + 2.0 > omega2->size[1]) {
i0 = 0;
n = 0;
} else {
i0 = (int)(Gpass + 2.0) - 1;
n = omega2->size[1];
}
hb3 = b_omega2->size[0] * b_omega2->size[1];
b_omega2->size[0] = 1;
b_omega2->size[1] = n - i0;
emxEnsureCapacity_real_T(b_omega2, hb3);
loop_ub = n - i0;
for (n = 0; n < loop_ub; n++) {
b_omega2->data[b_omega2->size[0] * n] = omega2->data[i0 + n];
}
d_analogresp(b_omega2, converter_rate, b1_data, b1_size, a1, b2_data,
b2_size, a2, r0);
i0 = d_combinedResponse->size[0] * d_combinedResponse->size[1];
d_combinedResponse->size[0] = 1;
d_combinedResponse->size[1] = rg1->size[1];
emxEnsureCapacity_creal_T(d_combinedResponse, i0);
loop_ub = rg1->size[0] * rg1->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
absa = rg1->data[i0].re;
rg1_im = rg1->data[i0].im;
re = r0->data[i0].re;
im = r0->data[i0].im;
d_combinedResponse->data[i0].re = absa * re - rg1_im * im;
d_combinedResponse->data[i0].im = absa * im + rg1_im * re;
}
b_abs(d_combinedResponse, omega);
}
/* quantitative values about actual passband and stopband */
hb3 = 1;
n = fg->size[1];
sigma = fg->data[0];
if (fg->size[1] > 1) {
if (rtIsNaN(fg->data[0])) {
dec_int3 = 2;
exitg1 = false;
while ((!exitg1) && (dec_int3 <= n)) {
hb3 = dec_int3;
if (!rtIsNaN(fg->data[dec_int3 - 1])) {
sigma = fg->data[dec_int3 - 1];
exitg1 = true;
} else {
dec_int3++;
}
}
}
if (hb3 < fg->size[1]) {
while (hb3 + 1 <= n) {
if (fg->data[hb3] > sigma) {
sigma = fg->data[hb3];
}
hb3++;
}
}
}
hb3 = 1;
n = fg->size[1];
sigmax = fg->data[0];
if (fg->size[1] > 1) {
if (rtIsNaN(fg->data[0])) {
dec_int3 = 2;
exitg1 = false;
while ((!exitg1) && (dec_int3 <= n)) {
hb3 = dec_int3;
if (!rtIsNaN(fg->data[dec_int3 - 1])) {
sigmax = fg->data[dec_int3 - 1];
exitg1 = true;
} else {
dec_int3++;
}
}
}
if (hb3 < fg->size[1]) {
while (hb3 + 1 <= n) {
if (fg->data[hb3] < sigmax) {
sigmax = fg->data[hb3];
}
hb3++;
}
}
}
Apass_actual_vector->data[(int)i - 1] = mag2db(sigma) - mag2db(sigmax);
hb3 = 1;
n = omega->size[1];
sigma = omega->data[0];
if (omega->size[1] > 1) {
if (rtIsNaN(omega->data[0])) {
dec_int3 = 2;
exitg1 = false;
while ((!exitg1) && (dec_int3 <= n)) {
hb3 = dec_int3;
if (!rtIsNaN(omega->data[dec_int3 - 1])) {
sigma = omega->data[dec_int3 - 1];
exitg1 = true;
} else {
dec_int3++;
}
}
}
if (hb3 < omega->size[1]) {
while (hb3 + 1 <= n) {
if (omega->data[hb3] > sigma) {
sigma = omega->data[hb3];
}
hb3++;
}
}
}
Astop_actual_vector->data[(int)i - 1] = -mag2db(sigma);
if (int_FIR == 0.0) {
if (1 > ccoef->size[1]) {
loop_ub = 0;
} else {
loop_ub = ccoef->size[1];
}
i0 = fg->size[0] * fg->size[1];
fg->size[0] = 1;
fg->size[1] = loop_ub;
emxEnsureCapacity_real_T(fg, i0);
for (i0 = 0; i0 < loop_ub; i0++) {
fg->data[fg->size[0] * i0] = tap_store->data[tap_store->size[0] * i0];
}
/* Apass_actual = Apass_actual_vector(1); */
/* Astop_actual = Astop_actual_vector(1); */
exitg2 = 1;
} else if ((Apass_actual_vector->data[0] > Apass) ||
(Astop_actual_vector->data[0] < Astop)) {
if (1.0 > clkFIR) {
loop_ub = 0;
} else {
loop_ub = (int)clkFIR;
}
i0 = fg->size[0] * fg->size[1];
fg->size[0] = 1;
fg->size[1] = loop_ub;
emxEnsureCapacity_real_T(fg, i0);
for (i0 = 0; i0 < loop_ub; i0++) {
fg->data[fg->size[0] * i0] = tap_store->data[tap_store->size[0] * i0];
}
/* Apass_actual = Apass_actual_vector(1); */
/* Astop_actual = Astop_actual_vector(1); */
exitg2 = 1;
} else if ((Apass_actual_vector->data[(int)i - 1] > Apass) ||
(Astop_actual_vector->data[(int)i - 1] < Astop)) {
if (1.0 > clkFIR + 16.0) {
loop_ub = 0;
} else {
loop_ub = (int)(clkFIR + 16.0);
}
i0 = fg->size[0] * fg->size[1];
fg->size[0] = 1;
fg->size[1] = loop_ub;
emxEnsureCapacity_real_T(fg, i0);
for (i0 = 0; i0 < loop_ub; i0++) {
fg->data[fg->size[0] * i0] = tap_store->data[((int)i + tap_store->size[0]
* i0) - 2];
}
/* Apass_actual = Apass_actual_vector(i-1); */
/* Astop_actual = Astop_actual_vector(i-1); */
exitg2 = 1;
} else {
clkFIR -= 16.0;
i++;
}
} while (exitg2 == 0);
emxFree_real_T(&b_omega2);
emxFree_creal_T(&d_combinedResponse);
emxFree_real_T(&b_W1);
emxFree_creal_T(&r0);
emxFree_creal_T(&c_combinedResponse);
emxFree_real_T(&F4);
emxFree_real_T(&sw);
emxFree_real_T(&ccoef);
emxFree_real_T(&Astop_actual_vector);
emxFree_real_T(&Apass_actual_vector);
emxFree_real_T(&tap_store);
emxFree_real_T(&W2);
emxFree_real_T(&W1);
emxFree_real_T(&A2);
emxFree_real_T(&A1);
emxFree_real_T(&F2);
emxFree_real_T(&F1);
emxFree_real_T(&weight);
emxFree_real_T(&wg);
emxFree_creal_T(&rgN);
emxFree_real_T(&omega2);
emxFree_real_T(&fg2);
emxFree_creal_T(&rg1);
emxFree_real_T(&omega);
emxFree_creal_T(&a2);
emxFree_creal_T(&a1);
if (c_strcmp(RxTx)) {
if ((int_FIR == 1.0) && (FIR == 2.0)) {
if (rt_remd_snf(fg->size[1], 32.0) != 0.0) {
i0 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = 16 + fg->size[1];
emxEnsureCapacity_real_T(a, i0);
for (i0 = 0; i0 < 8; i0++) {
a->data[a->size[0] * i0] = 0.0;
}
loop_ub = fg->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
a->data[a->size[0] * (i0 + 8)] = fg->data[fg->size[0] * i0];
}
for (i0 = 0; i0 < 8; i0++) {
a->data[a->size[0] * ((i0 + fg->size[1]) + 8)] = 0.0;
}
i0 = fg->size[0] * fg->size[1];
fg->size[0] = 1;
fg->size[1] = a->size[1];
emxEnsureCapacity_real_T(fg, i0);
loop_ub = a->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
fg->data[fg->size[0] * i0] = a->data[a->size[0] * i0];
}
}
} else {
if ((int_FIR == 1.0) && (FIR == 4.0) && (rt_remd_snf(fg->size[1], 64.0) !=
0.0)) {
sigma = (ceil((double)fg->size[1] / 64.0) * 64.0 - (double)fg->size[1]) /
2.0;
i0 = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = ((int)sigma + fg->size[1]) + (int)sigma;
emxEnsureCapacity_real_T(a, i0);
loop_ub = (int)sigma;
for (i0 = 0; i0 < loop_ub; i0++) {
a->data[a->size[0] * i0] = 0.0;
}
loop_ub = fg->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
a->data[a->size[0] * (i0 + (int)sigma)] = fg->data[fg->size[0] * i0];
}
loop_ub = (int)sigma;
for (i0 = 0; i0 < loop_ub; i0++) {
a->data[a->size[0] * ((i0 + (int)sigma) + fg->size[1])] = 0.0;
}
i0 = fg->size[0] * fg->size[1];
fg->size[0] = 1;
fg->size[1] = a->size[1];
emxEnsureCapacity_real_T(fg, i0);
loop_ub = a->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
fg->data[fg->size[0] * i0] = a->data[a->size[0] * i0];
}
}
}
}
emxFree_real_T(&a);
/* There will always be 128 taps output */
memset(&firTapsPreScale[0], 0, sizeof(double) << 7);
loop_ub = fg->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
firTapsPreScale[i0] = fg->data[fg->size[0] * i0];
}
/* Calculate group delay */
/* Hmd = dec_int_func(input.FIR,h(1:128)); */
/* */
/* if ~isempty(ver('fixedpoint')) && license('test','fixed_point_toolbox') && license('checkout','fixed_point_toolbox') */
/* Hmd.Numerator = double(fi(Hmd.Numerator,true,16)); */
/* end */
/* if strcmp(input.RxTx, 'Rx') */
/* addStage(dfilter, Hmd); */
/* else */
/* addStage(dfilter, Hmd, 1); */
/* end */
/* gd2c = grpdelay(Hmd,omega1,clkFIR).*(1/clkFIR); */
/* gd2 = grpdelay_cg(firTapsPreScale,1,omega1,clkFIR).'.*(1/clkFIR); */
/* */
/* if input.phEQ == -1 */
/* groupdelay = gd1 + gd2; */
/* else */
/* groupdelay = gd1 + gd2; */
/* end */
/* grpdelayvar = max(groupdelay)-min(groupdelay); */
/* Determine Gains */
hb3 = 1;
sigma = firTapsPreScale[0];
if (rtIsNaN(firTapsPreScale[0])) {
dec_int3 = 2;
exitg1 = false;
while ((!exitg1) && (dec_int3 < 129)) {
hb3 = dec_int3;
if (!rtIsNaN(firTapsPreScale[dec_int3 - 1])) {
sigma = firTapsPreScale[dec_int3 - 1];
exitg1 = true;
} else {
dec_int3++;
}
}
}
if (hb3 < 128) {
while (hb3 + 1 < 129) {
if (firTapsPreScale[hb3] > sigma) {
sigma = firTapsPreScale[hb3];
}
hb3++;
}
}
sigma = b_log2(sigma);
sigma = ceil(sigma);
switch ((int)(1.0 + sigma)) {
case 2:
hb3 = 6;
break;
case 1:
hb3 = 0;
break;
case 0:
hb3 = -6;
break;
default:
hb3 = -12;
break;
}
if (b_strcmp(RxTx)) {
if (1.0 + sigma > 2.0) {
hb3 = 6;
}
} else {
if (FIR == 2.0) {
hb3 += 6;
} else {
if (FIR == 4.0) {
hb3 += 12;
}
}
if (hb3 > 0) {
hb3 = 0;
} else {
if (hb3 < -6) {
hb3 = -6;
}
}
}
/* Scale taps */
memcpy(&b_firTapsPreScale[0], &firTapsPreScale[0], sizeof(double) << 7);
b_determineBestFractionLength(b_firTapsPreScale, firTapsPreScale);
sigma = mpower(2.0, 16.0 - (1.0 + sigma));
for (i0 = 0; i0 < 128; i0++) {
sigmax = rt_roundd_snf(firTapsPreScale[i0] * sigma);
if (sigmax < 32768.0) {
if (sigmax >= -32768.0) {
i4 = (short)sigmax;
} else {
i4 = MIN_int16_T;
}
} else if (sigmax >= 32768.0) {
i4 = MAX_int16_T;
} else {
i4 = 0;
}
outputTaps[i0] = i4;
}
/* output = input; */
/* %% Non-codegen outputs */
/* % externally accessible fields */
/* output.firtaps = firtaps; */
/* output.nfirtaps = length(h); */
/* %output.filter = dfilter; */
/* output.gain = gain; */
/* %output.Hm1 = Hm1; */
/* %output.Hm2 = Hm2; */
/* %output.Hm3 = Hm3; */
/* %output.Hm4 = Hm4; */
/* %output.Hmd = Hmd; */
/* output.enables = enables; */
/* */
/* % internal fields used by the GUI */
/* %output.Hanalog = Hanalog; */
/* output.Apass_actual = Apass_actual; */
/* output.Astop_actual = Astop_actual; */
/* %output.delay = delay; */
/* %output.grpdelayvar = grpdelayvar; */
/* %output.Hd1 = Hd1; */
/* %output.Hd2 = Hd2; */
/* %output.Hmiddle = Hmiddle; */
/* output.a1 = a1; */
/* output.b1 = b1; */
/* output.a2 = a2; */
/* output.b2 = b2; */
/* For codegen only output taps */
*numOutputTaps = fg->size[1];
*filterGain = hb3;
emxFree_real_T(&fg);
}
/*
* Arguments : void
* Return Type : void
*/
void internal_design_filter_cg_initialize(void)
{
rt_InitInfAndNaN(8U);
}
/*
* Arguments : void
* Return Type : void
*/
void internal_design_filter_cg_terminate(void)
{
/* (no terminate code required) */
}
/*
* File trailer for internal_design_filter_cg.c
*
* [EOF]
*/
libad9361-iio-0.3/filterdesigner/internal_design_filter_cg.def 0000664 0000000 0000000 00000001230 14424151631 0024376 0 ustar 00root root 0000000 0000000 DLL {
global:
internal_design_filter_cg;
emxEnsureCapacity_cint8_T;
emxEnsureCapacity_creal_T;
emxEnsureCapacity_creal_T1;
emxEnsureCapacity_int32_T;
emxEnsureCapacity_int32_T1;
emxEnsureCapacity_int8_T;
emxEnsureCapacity_real_T;
emxEnsureCapacity_real_T1;
emxFree_cint8_T;
emxFree_creal_T;
emxFree_int32_T;
emxFree_int8_T;
emxFree_real_T;
emxInit_cint8_T;
emxInit_creal_T;
emxInit_creal_T1;
emxInit_int32_T;
emxInit_int32_T1;
emxInit_int8_T;
emxInit_real_T;
emxInit_real_T1;
internal_design_filter_cg_initialize;
internal_design_filter_cg_terminate;
local:
*;
};
libad9361-iio-0.3/filterdesigner/internal_design_filter_cg.h 0000664 0000000 0000000 00000003422 14424151631 0024074 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef INTERNAL_DESIGN_FILTER_CG_H
#define INTERNAL_DESIGN_FILTER_CG_H
/* Include Files */
#include
#include
#include
#include
#include
#include "rt_defines.h"
#include "rt_nonfinite.h"
#include "rtwtypes.h"
#include "internal_design_filter_cg_types.h"
/* Function Declarations */
#ifdef __cplusplus
extern "C" {
#endif
extern void internal_design_filter_cg(double Rdata, double Fpass, double Fstop,
double caldiv, double FIR, double HB1, double PLL_mult, double Apass, double
Astop, double phEQ, double HB2, double HB3, const char Type[7], const char
RxTx[2], double RFbw, double DAC_div, double converter_rate, double PLL_rate,
double Fcenter, double wnom, double FIRdBmin, double int_FIR, double maxTaps,
short outputTaps[128], double *numOutputTaps, double *filterGain);
extern void internal_design_filter_cg_initialize(void);
extern void internal_design_filter_cg_terminate(void);
#ifdef __cplusplus
}
#endif
#endif
/*
* File trailer for internal_design_filter_cg.h
*
* [EOF]
*/
libad9361-iio-0.3/filterdesigner/internal_design_filter_cg_emxutil.c 0000664 0000000 0000000 00000041330 14424151631 0025636 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
/* Include Files */
#include "rt_nonfinite.h"
#include "internal_design_filter_cg.h"
#include "internal_design_filter_cg_emxutil.h"
/* Function Definitions */
/*
* Arguments : emxArray_cint8_T *emxArray
* int oldNumel
* Return Type : void
*/
void emxEnsureCapacity_cint8_T(emxArray_cint8_T *emxArray, int oldNumel)
{
int newNumel;
int i;
void *newData;
if (oldNumel < 0) {
oldNumel = 0;
}
newNumel = 1;
for (i = 0; i < emxArray->numDimensions; i++) {
newNumel *= emxArray->size[i];
}
if (newNumel > emxArray->allocatedSize) {
i = emxArray->allocatedSize;
if (i < 16) {
i = 16;
}
while (i < newNumel) {
if (i > 1073741823) {
i = MAX_int32_T;
} else {
i <<= 1;
}
}
newData = calloc((unsigned int)i, sizeof(cint8_T));
if (emxArray->data != NULL) {
memcpy(newData, (void *)emxArray->data, sizeof(cint8_T) * oldNumel);
if (emxArray->canFreeData) {
free((void *)emxArray->data);
}
}
emxArray->data = (cint8_T *)newData;
emxArray->allocatedSize = i;
emxArray->canFreeData = true;
}
}
/*
* Arguments : emxArray_creal_T *emxArray
* int oldNumel
* Return Type : void
*/
void emxEnsureCapacity_creal_T(emxArray_creal_T *emxArray, int oldNumel)
{
int newNumel;
int i;
void *newData;
if (oldNumel < 0) {
oldNumel = 0;
}
newNumel = 1;
for (i = 0; i < emxArray->numDimensions; i++) {
newNumel *= emxArray->size[i];
}
if (newNumel > emxArray->allocatedSize) {
i = emxArray->allocatedSize;
if (i < 16) {
i = 16;
}
while (i < newNumel) {
if (i > 1073741823) {
i = MAX_int32_T;
} else {
i <<= 1;
}
}
newData = calloc((unsigned int)i, sizeof(creal_T));
if (emxArray->data != NULL) {
memcpy(newData, (void *)emxArray->data, sizeof(creal_T) * oldNumel);
if (emxArray->canFreeData) {
free((void *)emxArray->data);
}
}
emxArray->data = (creal_T *)newData;
emxArray->allocatedSize = i;
emxArray->canFreeData = true;
}
}
/*
* Arguments : emxArray_creal_T *emxArray
* int oldNumel
* Return Type : void
*/
void emxEnsureCapacity_creal_T1(emxArray_creal_T *emxArray, int oldNumel)
{
int newNumel;
int i;
void *newData;
if (oldNumel < 0) {
oldNumel = 0;
}
newNumel = 1;
for (i = 0; i < emxArray->numDimensions; i++) {
newNumel *= emxArray->size[i];
}
if (newNumel > emxArray->allocatedSize) {
i = emxArray->allocatedSize;
if (i < 16) {
i = 16;
}
while (i < newNumel) {
if (i > 1073741823) {
i = MAX_int32_T;
} else {
i <<= 1;
}
}
newData = calloc((unsigned int)i, sizeof(creal_T));
if (emxArray->data != NULL) {
memcpy(newData, (void *)emxArray->data, sizeof(creal_T) * oldNumel);
if (emxArray->canFreeData) {
free((void *)emxArray->data);
}
}
emxArray->data = (creal_T *)newData;
emxArray->allocatedSize = i;
emxArray->canFreeData = true;
}
}
/*
* Arguments : emxArray_int32_T *emxArray
* int oldNumel
* Return Type : void
*/
void emxEnsureCapacity_int32_T(emxArray_int32_T *emxArray, int oldNumel)
{
int newNumel;
int i;
void *newData;
if (oldNumel < 0) {
oldNumel = 0;
}
newNumel = 1;
for (i = 0; i < emxArray->numDimensions; i++) {
newNumel *= emxArray->size[i];
}
if (newNumel > emxArray->allocatedSize) {
i = emxArray->allocatedSize;
if (i < 16) {
i = 16;
}
while (i < newNumel) {
if (i > 1073741823) {
i = MAX_int32_T;
} else {
i <<= 1;
}
}
newData = calloc((unsigned int)i, sizeof(int));
if (emxArray->data != NULL) {
memcpy(newData, (void *)emxArray->data, sizeof(int) * oldNumel);
if (emxArray->canFreeData) {
free((void *)emxArray->data);
}
}
emxArray->data = (int *)newData;
emxArray->allocatedSize = i;
emxArray->canFreeData = true;
}
}
/*
* Arguments : emxArray_int32_T *emxArray
* int oldNumel
* Return Type : void
*/
void emxEnsureCapacity_int32_T1(emxArray_int32_T *emxArray, int oldNumel)
{
int newNumel;
int i;
void *newData;
if (oldNumel < 0) {
oldNumel = 0;
}
newNumel = 1;
for (i = 0; i < emxArray->numDimensions; i++) {
newNumel *= emxArray->size[i];
}
if (newNumel > emxArray->allocatedSize) {
i = emxArray->allocatedSize;
if (i < 16) {
i = 16;
}
while (i < newNumel) {
if (i > 1073741823) {
i = MAX_int32_T;
} else {
i <<= 1;
}
}
newData = calloc((unsigned int)i, sizeof(int));
if (emxArray->data != NULL) {
memcpy(newData, (void *)emxArray->data, sizeof(int) * oldNumel);
if (emxArray->canFreeData) {
free((void *)emxArray->data);
}
}
emxArray->data = (int *)newData;
emxArray->allocatedSize = i;
emxArray->canFreeData = true;
}
}
/*
* Arguments : emxArray_int8_T *emxArray
* int oldNumel
* Return Type : void
*/
void emxEnsureCapacity_int8_T(emxArray_int8_T *emxArray, int oldNumel)
{
int newNumel;
int i;
void *newData;
if (oldNumel < 0) {
oldNumel = 0;
}
newNumel = 1;
for (i = 0; i < emxArray->numDimensions; i++) {
newNumel *= emxArray->size[i];
}
if (newNumel > emxArray->allocatedSize) {
i = emxArray->allocatedSize;
if (i < 16) {
i = 16;
}
while (i < newNumel) {
if (i > 1073741823) {
i = MAX_int32_T;
} else {
i <<= 1;
}
}
newData = calloc((unsigned int)i, sizeof(signed char));
if (emxArray->data != NULL) {
memcpy(newData, (void *)emxArray->data, sizeof(signed char) * oldNumel);
if (emxArray->canFreeData) {
free((void *)emxArray->data);
}
}
emxArray->data = (signed char *)newData;
emxArray->allocatedSize = i;
emxArray->canFreeData = true;
}
}
/*
* Arguments : emxArray_real_T *emxArray
* int oldNumel
* Return Type : void
*/
void emxEnsureCapacity_real_T(emxArray_real_T *emxArray, int oldNumel)
{
int newNumel;
int i;
void *newData;
if (oldNumel < 0) {
oldNumel = 0;
}
newNumel = 1;
for (i = 0; i < emxArray->numDimensions; i++) {
newNumel *= emxArray->size[i];
}
if (newNumel > emxArray->allocatedSize) {
i = emxArray->allocatedSize;
if (i < 16) {
i = 16;
}
while (i < newNumel) {
if (i > 1073741823) {
i = MAX_int32_T;
} else {
i <<= 1;
}
}
newData = calloc((unsigned int)i, sizeof(double));
if (emxArray->data != NULL) {
memcpy(newData, (void *)emxArray->data, sizeof(double) * oldNumel);
if (emxArray->canFreeData) {
free((void *)emxArray->data);
}
}
emxArray->data = (double *)newData;
emxArray->allocatedSize = i;
emxArray->canFreeData = true;
}
}
/*
* Arguments : emxArray_real_T *emxArray
* int oldNumel
* Return Type : void
*/
void emxEnsureCapacity_real_T1(emxArray_real_T *emxArray, int oldNumel)
{
int newNumel;
int i;
void *newData;
if (oldNumel < 0) {
oldNumel = 0;
}
newNumel = 1;
for (i = 0; i < emxArray->numDimensions; i++) {
newNumel *= emxArray->size[i];
}
if (newNumel > emxArray->allocatedSize) {
i = emxArray->allocatedSize;
if (i < 16) {
i = 16;
}
while (i < newNumel) {
if (i > 1073741823) {
i = MAX_int32_T;
} else {
i <<= 1;
}
}
newData = calloc((unsigned int)i, sizeof(double));
if (emxArray->data != NULL) {
memcpy(newData, (void *)emxArray->data, sizeof(double) * oldNumel);
if (emxArray->canFreeData) {
free((void *)emxArray->data);
}
}
emxArray->data = (double *)newData;
emxArray->allocatedSize = i;
emxArray->canFreeData = true;
}
}
/*
* Arguments : emxArray_cint8_T **pEmxArray
* Return Type : void
*/
void emxFree_cint8_T(emxArray_cint8_T **pEmxArray)
{
if (*pEmxArray != (emxArray_cint8_T *)NULL) {
if (((*pEmxArray)->data != (cint8_T *)NULL) && (*pEmxArray)->canFreeData) {
free((void *)(*pEmxArray)->data);
}
free((void *)(*pEmxArray)->size);
free((void *)*pEmxArray);
*pEmxArray = (emxArray_cint8_T *)NULL;
}
}
/*
* Arguments : emxArray_creal_T **pEmxArray
* Return Type : void
*/
void emxFree_creal_T(emxArray_creal_T **pEmxArray)
{
if (*pEmxArray != (emxArray_creal_T *)NULL) {
if (((*pEmxArray)->data != (creal_T *)NULL) && (*pEmxArray)->canFreeData) {
free((void *)(*pEmxArray)->data);
}
free((void *)(*pEmxArray)->size);
free((void *)*pEmxArray);
*pEmxArray = (emxArray_creal_T *)NULL;
}
}
/*
* Arguments : emxArray_int32_T **pEmxArray
* Return Type : void
*/
void emxFree_int32_T(emxArray_int32_T **pEmxArray)
{
if (*pEmxArray != (emxArray_int32_T *)NULL) {
if (((*pEmxArray)->data != (int *)NULL) && (*pEmxArray)->canFreeData) {
free((void *)(*pEmxArray)->data);
}
free((void *)(*pEmxArray)->size);
free((void *)*pEmxArray);
*pEmxArray = (emxArray_int32_T *)NULL;
}
}
/*
* Arguments : emxArray_int8_T **pEmxArray
* Return Type : void
*/
void emxFree_int8_T(emxArray_int8_T **pEmxArray)
{
if (*pEmxArray != (emxArray_int8_T *)NULL) {
if (((*pEmxArray)->data != (signed char *)NULL) && (*pEmxArray)->canFreeData) {
free((void *)(*pEmxArray)->data);
}
free((void *)(*pEmxArray)->size);
free((void *)*pEmxArray);
*pEmxArray = (emxArray_int8_T *)NULL;
}
}
/*
* Arguments : emxArray_real_T **pEmxArray
* Return Type : void
*/
void emxFree_real_T(emxArray_real_T **pEmxArray)
{
if (*pEmxArray != (emxArray_real_T *)NULL) {
if (((*pEmxArray)->data != (double *)NULL) && (*pEmxArray)->canFreeData) {
free((void *)(*pEmxArray)->data);
}
free((void *)(*pEmxArray)->size);
free((void *)*pEmxArray);
*pEmxArray = (emxArray_real_T *)NULL;
}
}
/*
* Arguments : emxArray_cint8_T **pEmxArray
* int numDimensions
* Return Type : void
*/
void emxInit_cint8_T(emxArray_cint8_T **pEmxArray, int numDimensions)
{
emxArray_cint8_T *emxArray;
int i;
*pEmxArray = (emxArray_cint8_T *)malloc(sizeof(emxArray_cint8_T));
emxArray = *pEmxArray;
emxArray->data = (cint8_T *)NULL;
emxArray->numDimensions = numDimensions;
emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions));
emxArray->allocatedSize = 0;
emxArray->canFreeData = true;
for (i = 0; i < numDimensions; i++) {
emxArray->size[i] = 0;
}
}
/*
* Arguments : emxArray_creal_T **pEmxArray
* int numDimensions
* Return Type : void
*/
void emxInit_creal_T(emxArray_creal_T **pEmxArray, int numDimensions)
{
emxArray_creal_T *emxArray;
int i;
*pEmxArray = (emxArray_creal_T *)malloc(sizeof(emxArray_creal_T));
emxArray = *pEmxArray;
emxArray->data = (creal_T *)NULL;
emxArray->numDimensions = numDimensions;
emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions));
emxArray->allocatedSize = 0;
emxArray->canFreeData = true;
for (i = 0; i < numDimensions; i++) {
emxArray->size[i] = 0;
}
}
/*
* Arguments : emxArray_creal_T **pEmxArray
* int numDimensions
* Return Type : void
*/
void emxInit_creal_T1(emxArray_creal_T **pEmxArray, int numDimensions)
{
emxArray_creal_T *emxArray;
int i;
*pEmxArray = (emxArray_creal_T *)malloc(sizeof(emxArray_creal_T));
emxArray = *pEmxArray;
emxArray->data = (creal_T *)NULL;
emxArray->numDimensions = numDimensions;
emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions));
emxArray->allocatedSize = 0;
emxArray->canFreeData = true;
for (i = 0; i < numDimensions; i++) {
emxArray->size[i] = 0;
}
}
/*
* Arguments : emxArray_int32_T **pEmxArray
* int numDimensions
* Return Type : void
*/
void emxInit_int32_T(emxArray_int32_T **pEmxArray, int numDimensions)
{
emxArray_int32_T *emxArray;
int i;
*pEmxArray = (emxArray_int32_T *)malloc(sizeof(emxArray_int32_T));
emxArray = *pEmxArray;
emxArray->data = (int *)NULL;
emxArray->numDimensions = numDimensions;
emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions));
emxArray->allocatedSize = 0;
emxArray->canFreeData = true;
for (i = 0; i < numDimensions; i++) {
emxArray->size[i] = 0;
}
}
/*
* Arguments : emxArray_int32_T **pEmxArray
* int numDimensions
* Return Type : void
*/
void emxInit_int32_T1(emxArray_int32_T **pEmxArray, int numDimensions)
{
emxArray_int32_T *emxArray;
int i;
*pEmxArray = (emxArray_int32_T *)malloc(sizeof(emxArray_int32_T));
emxArray = *pEmxArray;
emxArray->data = (int *)NULL;
emxArray->numDimensions = numDimensions;
emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions));
emxArray->allocatedSize = 0;
emxArray->canFreeData = true;
for (i = 0; i < numDimensions; i++) {
emxArray->size[i] = 0;
}
}
/*
* Arguments : emxArray_int8_T **pEmxArray
* int numDimensions
* Return Type : void
*/
void emxInit_int8_T(emxArray_int8_T **pEmxArray, int numDimensions)
{
emxArray_int8_T *emxArray;
int i;
*pEmxArray = (emxArray_int8_T *)malloc(sizeof(emxArray_int8_T));
emxArray = *pEmxArray;
emxArray->data = (signed char *)NULL;
emxArray->numDimensions = numDimensions;
emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions));
emxArray->allocatedSize = 0;
emxArray->canFreeData = true;
for (i = 0; i < numDimensions; i++) {
emxArray->size[i] = 0;
}
}
/*
* Arguments : emxArray_real_T **pEmxArray
* int numDimensions
* Return Type : void
*/
void emxInit_real_T(emxArray_real_T **pEmxArray, int numDimensions)
{
emxArray_real_T *emxArray;
int i;
*pEmxArray = (emxArray_real_T *)malloc(sizeof(emxArray_real_T));
emxArray = *pEmxArray;
emxArray->data = (double *)NULL;
emxArray->numDimensions = numDimensions;
emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions));
emxArray->allocatedSize = 0;
emxArray->canFreeData = true;
for (i = 0; i < numDimensions; i++) {
emxArray->size[i] = 0;
}
}
/*
* Arguments : emxArray_real_T **pEmxArray
* int numDimensions
* Return Type : void
*/
void emxInit_real_T1(emxArray_real_T **pEmxArray, int numDimensions)
{
emxArray_real_T *emxArray;
int i;
*pEmxArray = (emxArray_real_T *)malloc(sizeof(emxArray_real_T));
emxArray = *pEmxArray;
emxArray->data = (double *)NULL;
emxArray->numDimensions = numDimensions;
emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions));
emxArray->allocatedSize = 0;
emxArray->canFreeData = true;
for (i = 0; i < numDimensions; i++) {
emxArray->size[i] = 0;
}
}
/*
* File trailer for internal_design_filter_cg_emxutil.c
*
* [EOF]
*/
libad9361-iio-0.3/filterdesigner/internal_design_filter_cg_emxutil.h 0000664 0000000 0000000 00000005231 14424151631 0025643 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef INTERNAL_DESIGN_FILTER_CG_EMXUTIL_H
#define INTERNAL_DESIGN_FILTER_CG_EMXUTIL_H
/* Include Files */
#include
#include
#include
#include
#include
#include "rt_defines.h"
#include "rt_nonfinite.h"
#include "rtwtypes.h"
#include "internal_design_filter_cg_types.h"
/* Function Declarations */
#ifdef __cplusplus
extern "C" {
#endif
extern void emxEnsureCapacity_cint8_T(emxArray_cint8_T *emxArray, int oldNumel);
extern void emxEnsureCapacity_creal_T(emxArray_creal_T *emxArray, int oldNumel);
extern void emxEnsureCapacity_creal_T1(emxArray_creal_T *emxArray, int
oldNumel);
extern void emxEnsureCapacity_int32_T(emxArray_int32_T *emxArray, int oldNumel);
extern void emxEnsureCapacity_int32_T1(emxArray_int32_T *emxArray, int
oldNumel);
extern void emxEnsureCapacity_int8_T(emxArray_int8_T *emxArray, int oldNumel);
extern void emxEnsureCapacity_real_T(emxArray_real_T *emxArray, int oldNumel);
extern void emxEnsureCapacity_real_T1(emxArray_real_T *emxArray, int oldNumel);
extern void emxFree_cint8_T(emxArray_cint8_T **pEmxArray);
extern void emxFree_creal_T(emxArray_creal_T **pEmxArray);
extern void emxFree_int32_T(emxArray_int32_T **pEmxArray);
extern void emxFree_int8_T(emxArray_int8_T **pEmxArray);
extern void emxFree_real_T(emxArray_real_T **pEmxArray);
extern void emxInit_cint8_T(emxArray_cint8_T **pEmxArray, int numDimensions);
extern void emxInit_creal_T(emxArray_creal_T **pEmxArray, int numDimensions);
extern void emxInit_creal_T1(emxArray_creal_T **pEmxArray, int numDimensions);
extern void emxInit_int32_T(emxArray_int32_T **pEmxArray, int numDimensions);
extern void emxInit_int32_T1(emxArray_int32_T **pEmxArray, int numDimensions);
extern void emxInit_int8_T(emxArray_int8_T **pEmxArray, int numDimensions);
extern void emxInit_real_T(emxArray_real_T **pEmxArray, int numDimensions);
extern void emxInit_real_T1(emxArray_real_T **pEmxArray, int numDimensions);
#ifdef __cplusplus
}
#endif
#endif
/*
* File trailer for internal_design_filter_cg_emxutil.h
*
* [EOF]
*/
libad9361-iio-0.3/filterdesigner/internal_design_filter_cg_types.h 0000664 0000000 0000000 00000005774 14424151631 0025334 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef INTERNAL_DESIGN_FILTER_CG_TYPES_H
#define INTERNAL_DESIGN_FILTER_CG_TYPES_H
/* Include Files */
#include "rtwtypes.h"
/* Type Definitions */
#ifndef struct_emxArray_cint8_T
#define struct_emxArray_cint8_T
struct emxArray_cint8_T {
cint8_T *data;
int *size;
int allocatedSize;
int numDimensions;
boolean_T canFreeData;
};
#endif /*struct_emxArray_cint8_T*/
#ifndef typedef_emxArray_cint8_T
#define typedef_emxArray_cint8_T
typedef struct emxArray_cint8_T emxArray_cint8_T;
#endif /*typedef_emxArray_cint8_T*/
#ifndef struct_emxArray_creal_T
#define struct_emxArray_creal_T
struct emxArray_creal_T {
creal_T *data;
int *size;
int allocatedSize;
int numDimensions;
boolean_T canFreeData;
};
#endif /*struct_emxArray_creal_T*/
#ifndef typedef_emxArray_creal_T
#define typedef_emxArray_creal_T
typedef struct emxArray_creal_T emxArray_creal_T;
#endif /*typedef_emxArray_creal_T*/
#ifndef struct_emxArray_int32_T
#define struct_emxArray_int32_T
struct emxArray_int32_T {
int *data;
int *size;
int allocatedSize;
int numDimensions;
boolean_T canFreeData;
};
#endif /*struct_emxArray_int32_T*/
#ifndef typedef_emxArray_int32_T
#define typedef_emxArray_int32_T
typedef struct emxArray_int32_T emxArray_int32_T;
#endif /*typedef_emxArray_int32_T*/
#ifndef struct_emxArray_int8_T
#define struct_emxArray_int8_T
struct emxArray_int8_T {
signed char *data;
int *size;
int allocatedSize;
int numDimensions;
boolean_T canFreeData;
};
#endif /*struct_emxArray_int8_T*/
#ifndef typedef_emxArray_int8_T
#define typedef_emxArray_int8_T
typedef struct emxArray_int8_T emxArray_int8_T;
#endif /*typedef_emxArray_int8_T*/
#ifndef struct_emxArray_real_T
#define struct_emxArray_real_T
struct emxArray_real_T {
double *data;
int *size;
int allocatedSize;
int numDimensions;
boolean_T canFreeData;
};
#endif /*struct_emxArray_real_T*/
#ifndef typedef_emxArray_real_T
#define typedef_emxArray_real_T
typedef struct emxArray_real_T emxArray_real_T;
#endif /*typedef_emxArray_real_T*/
#endif
/*
* File trailer for internal_design_filter_cg_types.h
*
* [EOF]
*/
libad9361-iio-0.3/filterdesigner/rtGetInf.c 0000664 0000000 0000000 00000006613 14424151631 0020433 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
/*
* Abstract:
* MATLAB for code generation function to initialize non-finite, Inf and MinusInf
*/
#include "rtGetInf.h"
#define NumBitsPerChar 8U
/* Function: rtGetInf ==================================================
* Abstract:
* Initialize rtInf needed by the generated code.
* Inf is initialized as non-signaling. Assumes IEEE.
*/
real_T rtGetInf(void)
{
real_T inf = 0.0;
uint16_T one = 1U;
enum {
LittleEndian,
BigEndian
} machByteOrder = (*((uint8_T *) &one) == 1U) ? LittleEndian : BigEndian;
switch (machByteOrder) {
case LittleEndian: {
union {
LittleEndianIEEEDouble bitVal;
real_T fltVal;
} tmpVal;
tmpVal.bitVal.words.wordH = 0x7FF00000U;
tmpVal.bitVal.words.wordL = 0x00000000U;
inf = tmpVal.fltVal;
break;
}
case BigEndian: {
union {
BigEndianIEEEDouble bitVal;
real_T fltVal;
} tmpVal;
tmpVal.bitVal.words.wordH = 0x7FF00000U;
tmpVal.bitVal.words.wordL = 0x00000000U;
inf = tmpVal.fltVal;
break;
}
}
return inf;
}
/* Function: rtGetInfF ==================================================
* Abstract:
* Initialize rtInfF needed by the generated code.
* Inf is initialized as non-signaling. Assumes IEEE.
*/
real32_T rtGetInfF(void)
{
IEEESingle infF;
infF.wordL.wordLuint = 0x7F800000U;
return infF.wordL.wordLreal;
}
/* Function: rtGetMinusInf ==================================================
* Abstract:
* Initialize rtMinusInf needed by the generated code.
* Inf is initialized as non-signaling. Assumes IEEE.
*/
real_T rtGetMinusInf(void)
{
real_T minf = 0.0;
uint16_T one = 1U;
enum {
LittleEndian,
BigEndian
} machByteOrder = (*((uint8_T *) &one) == 1U) ? LittleEndian : BigEndian;
switch (machByteOrder) {
case LittleEndian: {
union {
LittleEndianIEEEDouble bitVal;
real_T fltVal;
} tmpVal;
tmpVal.bitVal.words.wordH = 0xFFF00000U;
tmpVal.bitVal.words.wordL = 0x00000000U;
minf = tmpVal.fltVal;
break;
}
case BigEndian: {
union {
BigEndianIEEEDouble bitVal;
real_T fltVal;
} tmpVal;
tmpVal.bitVal.words.wordH = 0xFFF00000U;
tmpVal.bitVal.words.wordL = 0x00000000U;
minf = tmpVal.fltVal;
break;
}
}
return minf;
}
/* Function: rtGetMinusInfF ==================================================
* Abstract:
* Initialize rtMinusInfF needed by the generated code.
* Inf is initialized as non-signaling. Assumes IEEE.
*/
real32_T rtGetMinusInfF(void)
{
IEEESingle minfF;
minfF.wordL.wordLuint = 0xFF800000U;
return minfF.wordL.wordLreal;
}
/*
* File trailer for rtGetInf.c
*
* [EOF]
*/
libad9361-iio-0.3/filterdesigner/rtGetInf.h 0000664 0000000 0000000 00000001551 14424151631 0020434 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef RTGETINF_H
#define RTGETINF_H
#include
#include "rtwtypes.h"
#include "rt_nonfinite.h"
extern real_T rtGetInf(void);
extern real32_T rtGetInfF(void);
extern real_T rtGetMinusInf(void);
extern real32_T rtGetMinusInfF(void);
#endif
/*
* File trailer for rtGetInf.h
*
* [EOF]
*/
libad9361-iio-0.3/filterdesigner/rtGetNaN.c 0000664 0000000 0000000 00000004606 14424151631 0020373 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
/*
* Abstract:
* MATLAB for code generation function to initialize non-finite, NaN
*/
#include "rtGetNaN.h"
#define NumBitsPerChar 8U
/* Function: rtGetNaN ==================================================
* Abstract:
* Initialize rtNaN needed by the generated code.
* NaN is initialized as non-signaling. Assumes IEEE.
*/
real_T rtGetNaN(void)
{
real_T nan = 0.0;
uint16_T one = 1U;
enum {
LittleEndian,
BigEndian
} machByteOrder = (*((uint8_T *) &one) == 1U) ? LittleEndian : BigEndian;
switch (machByteOrder) {
case LittleEndian: {
union {
LittleEndianIEEEDouble bitVal;
real_T fltVal;
} tmpVal;
tmpVal.bitVal.words.wordH = 0xFFF80000U;
tmpVal.bitVal.words.wordL = 0x00000000U;
nan = tmpVal.fltVal;
break;
}
case BigEndian: {
union {
BigEndianIEEEDouble bitVal;
real_T fltVal;
} tmpVal;
tmpVal.bitVal.words.wordH = 0x7FFFFFFFU;
tmpVal.bitVal.words.wordL = 0xFFFFFFFFU;
nan = tmpVal.fltVal;
break;
}
}
return nan;
}
/* Function: rtGetNaNF ==================================================
* Abstract:
* Initialize rtNaNF needed by the generated code.
* NaN is initialized as non-signaling. Assumes IEEE.
*/
real32_T rtGetNaNF(void)
{
IEEESingle nanF = { { 0 } };
uint16_T one = 1U;
enum {
LittleEndian,
BigEndian
} machByteOrder = (*((uint8_T *) &one) == 1U) ? LittleEndian : BigEndian;
switch (machByteOrder) {
case LittleEndian: {
nanF.wordL.wordLuint = 0xFFC00000U;
break;
}
case BigEndian: {
nanF.wordL.wordLuint = 0x7FFFFFFFU;
break;
}
}
return nanF.wordL.wordLreal;
}
/*
* File trailer for rtGetNaN.c
*
* [EOF]
*/
libad9361-iio-0.3/filterdesigner/rtGetNaN.h 0000664 0000000 0000000 00000001440 14424151631 0020371 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef RTGETNAN_H
#define RTGETNAN_H
#include
#include "rtwtypes.h"
#include "rt_nonfinite.h"
extern real_T rtGetNaN(void);
extern real32_T rtGetNaNF(void);
#endif
/*
* File trailer for rtGetNaN.h
*
* [EOF]
*/
libad9361-iio-0.3/filterdesigner/rt_defines.h 0000664 0000000 0000000 00000002164 14424151631 0021035 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef RT_DEFINES_H
#define RT_DEFINES_H
#include
#define RT_PI 3.14159265358979323846
#define RT_PIF 3.1415927F
#define RT_LN_10 2.30258509299404568402
#define RT_LN_10F 2.3025851F
#define RT_LOG10E 0.43429448190325182765
#define RT_LOG10EF 0.43429449F
#define RT_E 2.7182818284590452354
#define RT_EF 2.7182817F
#endif
/*
* File trailer for rt_defines.h
*
* [EOF]
*/
libad9361-iio-0.3/filterdesigner/rt_nonfinite.c 0000664 0000000 0000000 00000004631 14424151631 0021405 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
/*
* Abstract:
* MATLAB for code generation function to initialize non-finites,
* (Inf, NaN and -Inf).
*/
#include "rt_nonfinite.h"
#include "rtGetNaN.h"
#include "rtGetInf.h"
real_T rtInf;
real_T rtMinusInf;
real_T rtNaN;
real32_T rtInfF;
real32_T rtMinusInfF;
real32_T rtNaNF;
/* Function: rt_InitInfAndNaN ==================================================
* Abstract:
* Initialize the rtInf, rtMinusInf, and rtNaN needed by the
* generated code. NaN is initialized as non-signaling. Assumes IEEE.
*/
void rt_InitInfAndNaN(size_t realSize)
{
(void) (realSize);
rtNaN = rtGetNaN();
rtNaNF = rtGetNaNF();
rtInf = rtGetInf();
rtInfF = rtGetInfF();
rtMinusInf = rtGetMinusInf();
rtMinusInfF = rtGetMinusInfF();
}
/* Function: rtIsInf ==================================================
* Abstract:
* Test if value is infinite
*/
boolean_T rtIsInf(real_T value)
{
return ((value==rtInf || value==rtMinusInf) ? 1U : 0U);
}
/* Function: rtIsInfF =================================================
* Abstract:
* Test if single-precision value is infinite
*/
boolean_T rtIsInfF(real32_T value)
{
return(((value)==rtInfF || (value)==rtMinusInfF) ? 1U : 0U);
}
/* Function: rtIsNaN ==================================================
* Abstract:
* Test if value is not a number
*/
boolean_T rtIsNaN(real_T value)
{
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
return _isnan(value)? TRUE:FALSE;
#else
return (value!=value)? 1U:0U;
#endif
}
/* Function: rtIsNaNF =================================================
* Abstract:
* Test if single-precision value is not a number
*/
boolean_T rtIsNaNF(real32_T value)
{
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
return _isnan((real_T)value)? true:false;
#else
return (value!=value)? 1U:0U;
#endif
}
/*
* File trailer for rt_nonfinite.c
*
* [EOF]
*/
libad9361-iio-0.3/filterdesigner/rt_nonfinite.h 0000664 0000000 0000000 00000002731 14424151631 0021411 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef RT_NONFINITE_H
#define RT_NONFINITE_H
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
#include
#endif
#include
#include "rtwtypes.h"
extern real_T rtInf;
extern real_T rtMinusInf;
extern real_T rtNaN;
extern real32_T rtInfF;
extern real32_T rtMinusInfF;
extern real32_T rtNaNF;
extern void rt_InitInfAndNaN(size_t realSize);
extern boolean_T rtIsInf(real_T value);
extern boolean_T rtIsInfF(real32_T value);
extern boolean_T rtIsNaN(real_T value);
extern boolean_T rtIsNaNF(real32_T value);
typedef struct {
struct {
uint32_T wordH;
uint32_T wordL;
} words;
} BigEndianIEEEDouble;
typedef struct {
struct {
uint32_T wordL;
uint32_T wordH;
} words;
} LittleEndianIEEEDouble;
typedef struct {
union {
real32_T wordLreal;
uint32_T wordLuint;
} wordL;
} IEEESingle;
#endif
/*
* File trailer for rt_nonfinite.h
*
* [EOF]
*/
libad9361-iio-0.3/filterdesigner/rtwtypes.h 0000664 0000000 0000000 00000012237 14424151631 0020616 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2017 Analog Devices, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef RTWTYPES_H
#define RTWTYPES_H
#ifndef __TMWTYPES__
#define __TMWTYPES__
/*=======================================================================*
* Target hardware information
* Device type: Generic->MATLAB Host Computer
* Number of bits: char: 8 short: 16 int: 32
* long: 64 long long: 64
* native word size: 64
* Byte ordering: LittleEndian
* Signed integer division rounds to: Zero
* Shift right on a signed integer as arithmetic shift: on
*=======================================================================*/
/*=======================================================================*
* Fixed width word size data types: *
* int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers *
* uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers *
* real32_T, real64_T - 32 and 64 bit floating point numbers *
*=======================================================================*/
typedef signed char int8_T;
typedef unsigned char uint8_T;
typedef short int16_T;
typedef unsigned short uint16_T;
typedef int int32_T;
typedef unsigned int uint32_T;
typedef long int64_T;
typedef unsigned long uint64_T;
typedef float real32_T;
typedef double real64_T;
/*===========================================================================*
* Generic type definitions: real_T, time_T, boolean_T, int_T, uint_T, *
* ulong_T, ulonglong_T, char_T and byte_T. *
*===========================================================================*/
typedef double real_T;
typedef double time_T;
typedef unsigned char boolean_T;
typedef int int_T;
typedef unsigned int uint_T;
typedef unsigned long ulong_T;
typedef unsigned long long ulonglong_T;
typedef char char_T;
typedef char_T byte_T;
/*===========================================================================*
* Complex number type definitions *
*===========================================================================*/
#define CREAL_T
typedef struct {
real32_T re;
real32_T im;
} creal32_T;
typedef struct {
real64_T re;
real64_T im;
} creal64_T;
typedef struct {
real_T re;
real_T im;
} creal_T;
typedef struct {
int8_T re;
int8_T im;
} cint8_T;
typedef struct {
uint8_T re;
uint8_T im;
} cuint8_T;
typedef struct {
int16_T re;
int16_T im;
} cint16_T;
typedef struct {
uint16_T re;
uint16_T im;
} cuint16_T;
typedef struct {
int32_T re;
int32_T im;
} cint32_T;
typedef struct {
uint32_T re;
uint32_T im;
} cuint32_T;
typedef struct {
int64_T re;
int64_T im;
} cint64_T;
typedef struct {
uint64_T re;
uint64_T im;
} cuint64_T;
/*=======================================================================*
* Min and Max: *
* int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers *
* uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers *
*=======================================================================*/
#define MAX_int8_T ((int8_T)(127))
#define MIN_int8_T ((int8_T)(-128))
#define MAX_uint8_T ((uint8_T)(255))
#define MIN_uint8_T ((uint8_T)(0))
#define MAX_int16_T ((int16_T)(32767))
#define MIN_int16_T ((int16_T)(-32768))
#define MAX_uint16_T ((uint16_T)(65535))
#define MIN_uint16_T ((uint16_T)(0))
#define MAX_int32_T ((int32_T)(2147483647))
#define MIN_int32_T ((int32_T)(-2147483647-1))
#define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU))
#define MIN_uint32_T ((uint32_T)(0))
#define MAX_int64_T ((int64_T)(9223372036854775807L))
#define MIN_int64_T ((int64_T)(-9223372036854775807L-1L))
#define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFUL))
#define MIN_uint64_T ((uint64_T)(0UL))
/* Logical type definitions */
#if !defined(__cplusplus) && !defined(__true_false_are_keywords)
# ifndef false
# define false (0U)
# endif
# ifndef true
# define true (1U)
# endif
#endif
/*
* Maximum length of a MATLAB identifier (function/variable)
* including the null-termination character. Referenced by
* rt_logging.c and rt_matrx.c.
*/
#define TMW_NAME_LENGTH_MAX 64
#endif
#endif
/*
* File trailer for rtwtypes.h
*
* [EOF]
*/
libad9361-iio-0.3/libad9361-iio.iss.cmakein 0000664 0000000 0000000 00000010454 14424151631 0020037 0 ustar 00root root 0000000 0000000 [Setup]
AppId={{96BC5CC7-C522-4883-BCCD-0F5B6CF1131D}
AppName="libad9361"
AppVersion="@VERSION@"
AppPublisher="Analog Devices, Inc."
AppPublisherURL="http://www.analog.com"
AppSupportURL="http://www.analog.com"
AppUpdatesURL="http://www.analog.com"
AppCopyright="Copyright 2015-@BUILD_YEAR@ ADI and other contributors"
CreateAppDir=no
LicenseFile="C:\projects\libad9361-iio\LICENSE"
OutputBaseFilename=libad9361-setup
OutputDir="C:\"
Compression=lzma
SolidCompression=yes
ArchitecturesInstallIn64BitMode=x64
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "brazilianportuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl"
Name: "catalan"; MessagesFile: "compiler:Languages\Catalan.isl"
Name: "corsican"; MessagesFile: "compiler:Languages\Corsican.isl"
Name: "czech"; MessagesFile: "compiler:Languages\Czech.isl"
Name: "danish"; MessagesFile: "compiler:Languages\Danish.isl"
Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl"
Name: "finnish"; MessagesFile: "compiler:Languages\Finnish.isl"
Name: "french"; MessagesFile: "compiler:Languages\French.isl"
Name: "german"; MessagesFile: "compiler:Languages\German.isl"
Name: "greek"; MessagesFile: "compiler:Languages\Greek.isl"
Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl"
Name: "hungarian"; MessagesFile: "compiler:Languages\Hungarian.isl"
Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl"
Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl"
Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl"
Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl"
Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl"
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"
Name: "scottishgaelic"; MessagesFile: "compiler:Languages\ScottishGaelic.isl"
Name: "serbiancyrillic"; MessagesFile: "compiler:Languages\SerbianCyrillic.isl"
Name: "serbianlatin"; MessagesFile: "compiler:Languages\SerbianLatin.isl"
Name: "slovenian"; MessagesFile: "compiler:Languages\Slovenian.isl"
Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl"
Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl"
Name: "ukrainian"; MessagesFile: "compiler:Languages\Ukrainian.isl"
[Files]
Source: "C:\projects\libad9361-iio\build-win32\Release\libad9361.dll"; DestDir: "{sys}"; Flags: 32bit
Source: "C:\projects\libad9361-iio\build-win64\Release\libad9361.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode
Source: "C:\projects\libad9361-iio\build-win32\test\Release\*.exe"; DestDir: "{sys}"; Check: not Is64BitInstallMode
Source: "C:\projects\libad9361-iio\build-win64\test\Release\*.exe"; DestDir: "{sys}"; Check: Is64BitInstallMode
Source: "C:\projects\libad9361-iio\build-win32\Release\libad9361.lib"; DestDir: "{pf32}\Microsoft Visual Studio 12.0\VC\lib"; Check: not Is64BitInstallMode
Source: "C:\projects\libad9361-iio\build-win64\Release\libad9361.lib"; DestDir: "{pf32}\Microsoft Visual Studio 12.0\VC\lib\amd64"; Check: Is64BitInstallMode
Source: "C:\projects\libad9361-iio\ad9361.h"; DestDir: "{pf32}\Microsoft Visual Studio 12.0\VC\include"
Source: "C:\projects\libad9361-iio\bindings\matlab\ad9361-wrapper.h"; DestDir: "{pf32}\Microsoft Visual Studio 12.0\VC\include"
Source: "C:\libiio-win32\libiio.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit
Source: "C:\libiio-win64\libiio.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist
Source: "C:\libiio-win32\libxml2.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit
Source: "C:\libiio-win64\libxml2.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist
Source: "C:\libiio-win32\libusb-1.0.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit
Source: "C:\libiio-win64\libusb-1.0.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist
Source: "C:\libiio-win32\libserialport-0.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit
Source: "C:\libiio-win64\libserialport-0.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist
Source: "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\x86\Microsoft.VC120.CRT\msvcr120.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit
Source: "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\x64\Microsoft.VC120.CRT\msvcr120.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist libad9361-iio-0.3/libad9361.pc.cmakein 0000664 0000000 0000000 00000000546 14424151631 0017066 0 ustar 00root root 0000000 0000000 prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@CMAKE_INSTALL_PREFIX@/lib
sharedlibdir=@CMAKE_INSTALL_PREFIX@/lib
includedir=@CMAKE_INSTALL_PREFIX@/include
Name: libad9361
Description: Device specific library for AD936X transceivers
Version: @VERSION@
Requires:
Libs: -L${libdir} -L${sharedlibdir} -lad9361
Cflags: -I${includedir}
libad9361-iio-0.3/mainpage.dox 0000664 0000000 0000000 00000001710 14424151631 0016025 0 ustar 00root root 0000000 0000000 /**
@mainpage
@tableofcontents
@section license License
Libad9361 has been developed and is released under the terms of the GNU Lesser General Public
License, version 2. This open-source license allows anyone to use the library for proprietary or
open-source, commercial or non-commercial applications. This choice was motivated by the fact
that Analog Devices is a company that principally sells hardware, and this library provides the
clients with a better and easier way of using this hardware.
The full terms of the license can be found here: http://opensource.org/licenses/LGPL-2.1
@section overview Overview
This is a simple library used for userspace management control and configuration of AD936X transceivers,
- which manages multi-chip sync (on platforms (FMCOMMS5) where multiple AD9361 devices are use)
- can create AD9361 specific FIR filters on the fly
@section ad9361_hardware AD9361 Transceiver Internals

*/
libad9361-iio-0.3/test/ 0000775 0000000 0000000 00000000000 14424151631 0014510 5 ustar 00root root 0000000 0000000 libad9361-iio-0.3/test/CMakeLists.txt 0000664 0000000 0000000 00000002617 14424151631 0017256 0 ustar 00root root 0000000 0000000 add_executable(FilterDesignerTest filter_designer_test.c)
target_link_libraries(FilterDesignerTest LINK_PRIVATE ${LIBIIO_LIBRARIES} ad9361)
add_test(NAME FilterDesignerTest
COMMAND FilterDesignerTest
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_executable(GenerateRatesTest gen_rates_test.c)
target_link_libraries(GenerateRatesTest LINK_PRIVATE ${LIBIIO_LIBRARIES} ad9361)
add_test(NAME GenerateRatesTest
COMMAND GenerateRatesTest
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_executable(FilterDesignerHardwareTest filter_designer_hw.c)
target_link_libraries(FilterDesignerHardwareTest LINK_PRIVATE ${LIBIIO_LIBRARIES} ad9361)
add_test(NAME FilterDesignerHardwareTest
COMMAND FilterDesignerHardwareTest
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_executable(FMComms5SyncTest fmcomms5_sync_test.c)
if(WIN32)
target_link_libraries(FMComms5SyncTest LINK_PRIVATE ${LIBIIO_LIBRARIES} ad9361)
else()
target_link_libraries(FMComms5SyncTest LINK_PRIVATE ${LIBIIO_LIBRARIES} ad9361 m)
endif()
add_test(NAME FMComms5SyncTest
COMMAND FMComms5SyncTest
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_executable(AutoRateTest auto_rate_test_hw.c)
target_link_libraries(AutoRateTest LINK_PRIVATE ${LIBIIO_LIBRARIES} ad9361)
add_test(NAME AutoRateTest
COMMAND AutoRateTest
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
libad9361-iio-0.3/test/auto_rate_test_hw.c 0000664 0000000 0000000 00000004322 14424151631 0020375 0 ustar 00root root 0000000 0000000
#include "ad9361.h"
#include
#include
#include
#include
#include
#include
#ifdef __APPLE__
#include
#else
#include
#endif
#define RATE_TOLERANCE_HZ 2
int run_test(unsigned long rate, struct iio_device *dev)
{
struct iio_channel *chan;
long long current_rate;
int ret;
printf("Testing rate: %lu\n",rate);
ret = ad9361_set_bb_rate(dev, rate);
if (ret<0) {
printf("ad9361_set_bb_rate Failed: %d\n",ret);
return ret;
}
// Checks
chan = iio_device_find_channel(dev, "voltage0", true);
if (chan == NULL)
return -ENODEV;
ret = iio_channel_attr_read_longlong(chan, "sampling_frequency", ¤t_rate);
if (ret < 0)
return ret;
if (abs(current_rate != (long long) rate)> RATE_TOLERANCE_HZ)
return -1;
printf("FIR rate check passed\n");
return 0;
}
int main(void)
{
int ret, k, g;
struct iio_context *ctx;
struct iio_device *dev;
unsigned long rates[] = {520888, 600000, 1000000, 10000000, 20000000, 40000000, 60000000};
const char* uri = getenv("URI_AD9361");
if (uri == NULL)
exit(0);// Cant find anything don't run tests
ctx = iio_create_context_from_uri(uri);
if (ctx == NULL) {
printf("No device found... skipping test");
exit(0);// Cant find anything don't run tests
}
dev = iio_context_find_device(ctx, "ad9361-phy");
for (g = 0; g < 2; g++) {
printf("########################\n");
printf("Loop %d\n",g);
printf("########################\n");
for (k = 6; k >= 0; k--) {
ret = run_test(rates[k], dev);
if (ret < 0)
return ret;
}
}
printf("########################\n");
printf("Running tests backwards\n");
printf("########################\n");
for (g = 0; g < 2; g++) {
printf("########################\n");
printf("Loop %d\n",g);
printf("########################\n");
for (k = 0; k < 7; k++) {
ret = run_test(rates[k], dev);
if (ret < 0)
return ret;
}
}
printf("Overall Passed\n");
return 0;
}
libad9361-iio-0.3/test/filter_designer_hw.c 0000664 0000000 0000000 00000002247 14424151631 0020524 0 ustar 00root root 0000000 0000000
#include "ad9361.h"
#include
#include
#include
#include
#include
#ifdef __APPLE__
#include
#else
#include
#endif
int main(void)
{
int ret, k;
unsigned long Fpass, Fstop, wnomTX, wnomRX;
struct iio_context *ctx;
struct iio_device *dev;
unsigned long rates[] = {1000000, 10000000, 20000000, 60000000};
const char* uri = getenv("URI_AD9361");
if (uri == NULL)
exit(0);// Cant find anything don't run tests
ctx = iio_create_context_from_uri(uri);
if (ctx == NULL)
exit(0);// Cant find anything don't run tests
dev = iio_context_find_device(ctx, "ad9361-phy");
for (k = 0; k < 4; k++) {
printf("Testing rate: %lu\n",rates[k]);
ret = ad9361_set_bb_rate_custom_filter_auto(dev, rates[k]);
if (ret<0)
return ret;
Fpass = rates[k] / 3.0;
Fstop = Fpass * 1.25;
wnomTX = 1.6 * Fstop;
wnomRX = 1.4 * Fstop;
ret = ad9361_set_bb_rate_custom_filter_manual(dev, rates[k], Fpass, Fstop,
wnomTX, wnomRX);
if (ret<0)
return ret;
}
return 0;
}
libad9361-iio-0.3/test/filter_designer_test.c 0000664 0000000 0000000 00000003371 14424151631 0021064 0 ustar 00root root 0000000 0000000
#include "ad9361.h"
#include
#include
#include
#include
#include
int check_result(short *taps, char tap_filename[100])
{
FILE *fp;
char buffer[255];
printf("FN: %s\n",tap_filename);
fp = fopen(tap_filename, "r");
uint8_t k = 0;
while (fgets(buffer, 255, (FILE *)fp)) {
int tap = atoi(buffer);
// printf("|%i|%i|\n", tap, taps[k]);
// Taps need to be within 2 samples (remez had randomness in it)
if (abs(tap - taps[k])>2) {
fclose(fp);
printf("Error: Tap missmatch\n");
return -2;
}
k++;
}
fclose(fp);
return 0;
}
int main(void)
{
struct filter_design_parameters fdpTX;
struct filter_design_parameters fdpRX;
short outputTaps[128];
int num_taps, ret, gain, k;
char filename[100];
unsigned long rates[] = {1000000, 10000000, 20000000, 60000000};
for (k = 0; k < 4; k++) {
// Generate rates in filter struct
ret = ad9361_calculate_rf_clock_chain_fdp(&fdpTX, &fdpRX, rates[k]);
// Test RX side
ret = ad9361_generate_fir_taps(&fdpRX, outputTaps, &num_taps, &gain);
if (ret < 0)
return ret;
sprintf(filename,"rateRX_%lu.taps",rates[k]);
ret = check_result(outputTaps,filename);
if (ret < 0)
return ret;
// Test TX side
ret = ad9361_generate_fir_taps(&fdpTX, outputTaps, &num_taps, &gain);
if (ret < 0)
return ret;
sprintf(filename,"rateTX_%lu.taps",rates[k]);
ret = check_result(outputTaps,filename);
if (ret < 0)
return ret;
}
return 0;
}
libad9361-iio-0.3/test/fmcomms5_sync_test.c 0000664 0000000 0000000 00000020300 14424151631 0020470 0 ustar 00root root 0000000 0000000
#include "ad9361.h"
#include
#include
#include
#ifdef __APPLE__
#include
#else
#include
#endif
#include
#include
#include
#include
#ifdef _WIN32
#include
#else
#include
#include
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define MHZ(x) ((long long)(x*1000000.0 + .5))
#define GHZ(x) ((long long)(x*1000000000.0 + .5))
#define DEV_RX_NAME "cf-ad9361-A"
#define DEV_RX_SLAVE_NAME "cf-ad9361-B"
#define DEV_TX_NAME "cf-ad9361-dds-core-lpc"
#define DEV_TX_SLAVE_NAME "cf-ad9361-dds-core-B"
#define DEV_PHY_NAME "ad9361-phy"
#define DEV_PHY_SLAVE_NAME "ad9361-phy-B"
#define SAMPLES 32768
#define M_2PI 2 * M_PI
#define STALE_BUFFERS 20
#define ENABLE_PERFORMANCE_TESTS 0
bool same_chip = 0;
#define CHECK(expr) \
if (expr < 0) { \
return expr; \
}
static struct iio_device *dev_phy, *dev_phy_slave;
static struct iio_device *dev_rx, *dev_rx_slave;
static struct iio_device *dev_tx, *dev_tx_slave;
static struct iio_buffer *rxbuf;
static struct iio_channel *rxa_chan_real, *rxa_chan_imag;
static struct iio_channel *rxb_chan_real, *rxb_chan_imag;
static void ad9361_sleep_ms(void)
{
#ifdef _WIN32
Sleep(1); /* milliseconds */
#else
struct timespec time;
time.tv_sec = 0;
time.tv_nsec = 1000 * 1000;
nanosleep(&time, NULL);
#endif
}
int check_fmcomms5_connected(struct iio_context *ctx)
{
dev_rx = iio_context_find_device(ctx, DEV_RX_NAME);
dev_rx_slave = iio_context_find_device(ctx, DEV_RX_SLAVE_NAME);
return (dev_rx && dev_rx_slave);
}
double calculate_phase(int16_t *a, int16_t *b, int16_t *c, int16_t *d,
int samples)
{
int k = 0;
double real = 0, imag = 0;
for (; k < samples; k++) {
real += ((double)a[k] * (double)c[k] + (double)b[k] * (double)d[k]);
imag += ((double)a[k] * (double)d[k] - (double)b[k] * (double)c[k]);
}
return atan2(imag, real);
}
int streaming_interfaces(bool enable)
{
if (enable) {
rxa_chan_real = iio_device_find_channel(dev_rx, "voltage0", false);
rxa_chan_imag = iio_device_find_channel(dev_rx, "voltage1", false);
if (same_chip) {
rxb_chan_real = iio_device_find_channel(dev_rx, "voltage2", false);
rxb_chan_imag = iio_device_find_channel(dev_rx, "voltage3", false);
} else {
rxb_chan_real = iio_device_find_channel(dev_rx, "voltage4", false);
rxb_chan_imag = iio_device_find_channel(dev_rx, "voltage5", false);
}
if (!(rxa_chan_real && rxa_chan_imag && rxb_chan_real && rxb_chan_imag))
streaming_interfaces(false);
iio_channel_enable(rxa_chan_real);
iio_channel_enable(rxa_chan_imag);
iio_channel_enable(rxb_chan_real);
iio_channel_enable(rxb_chan_imag);
rxbuf = iio_device_create_buffer(dev_rx, SAMPLES, false);
if (!rxbuf)
streaming_interfaces(false);
} else {
if (rxbuf) {
iio_buffer_destroy(rxbuf);
}
if (rxa_chan_real) {
iio_channel_disable(rxa_chan_real);
}
if (rxa_chan_imag) {
iio_channel_disable(rxa_chan_imag);
}
if (rxb_chan_real) {
iio_channel_disable(rxb_chan_real);
}
if (rxb_chan_imag) {
iio_channel_disable(rxb_chan_imag);
}
return -1;
}
return 0;
}
void read_buffer_data(struct iio_channel *chn, struct iio_buffer *buf,
void *dst, size_t len)
{
uintptr_t src_ptr, dst_ptr = (uintptr_t)dst, end = dst_ptr + len;
unsigned int bytes = iio_channel_get_data_format(chn)->length / 8;
uintptr_t buf_end = (uintptr_t)iio_buffer_end(buf);
ptrdiff_t buf_step = iio_buffer_step(buf);
for (src_ptr = (uintptr_t)iio_buffer_first(buf, chn);
src_ptr < buf_end && dst_ptr + bytes <= end;
src_ptr += buf_step, dst_ptr += bytes)
iio_channel_convert(chn, (void *)dst_ptr, (const void *)src_ptr);
}
double estimate_phase_diff(double *estimate)
{
ssize_t nbytes_rx = iio_buffer_refill(rxbuf);
if (!nbytes_rx)
return nbytes_rx;
int16_t myData0_i[SAMPLES], myData0_q[SAMPLES];
int16_t myData2_i[SAMPLES], myData2_q[SAMPLES];
// Read data from all channels
read_buffer_data(rxa_chan_real, rxbuf, myData0_i, SAMPLES * sizeof(int16_t));
read_buffer_data(rxa_chan_imag, rxbuf, myData0_q, SAMPLES * sizeof(int16_t));
read_buffer_data(rxb_chan_real, rxbuf, myData2_i, SAMPLES * sizeof(int16_t));
read_buffer_data(rxb_chan_imag, rxbuf, myData2_q, SAMPLES * sizeof(int16_t));
ad9361_sleep_ms();
*estimate =
calculate_phase(myData0_i, myData0_q, myData2_i, myData2_q, SAMPLES) *
180 / M_PI;
return 0;
}
int setup_iio_devices(struct iio_context *ctx)
{
dev_rx = iio_context_find_device(ctx, DEV_RX_NAME);
dev_rx_slave = iio_context_find_device(ctx, DEV_RX_SLAVE_NAME);
dev_phy = iio_context_find_device(ctx, DEV_PHY_NAME);
dev_phy_slave = iio_context_find_device(ctx, DEV_PHY_SLAVE_NAME);
dev_tx = iio_context_find_device(ctx, DEV_TX_NAME);
dev_tx_slave = iio_context_find_device(ctx, DEV_TX_SLAVE_NAME);
return (dev_rx && dev_rx_slave && dev_phy && dev_phy_slave && dev_tx &&
dev_tx_slave);
}
int check_phase_sma(struct iio_context *ctx, double *est)
{
int ret, g;
// Set up devices
if (!setup_iio_devices(ctx))
return -ENODEV;
// Enable channels
if (streaming_interfaces(true) < 0)
return -ENODEV;
for (g=0; g 0)
// Test sync performance
double phase_tolerance = 3; // Degrees
// These tests assume you have a signal splitter from TX1A_A to
// RX1A_A, RX2A_A, RX1A_B, and RX2A_B using matched length cables
double est = 0, est2 = 0;
for (freqGHZ = 1; freqGHZ<9; freqGHZ++) {
printf("#### Calibrating FMComms5 at LO %f GHz ####\n",(double)freqGHZ/10);
freq = 100000000*freqGHZ;
ret = ad9361_fmcomms5_phase_sync(ctx, freq);
if (ret<0) {
printf("FS Error: %d\n",ret);
break;
}
// Check results
same_chip = 1;
ret = check_phase_sma(ctx, &est);
if (ret<0) {
printf("CP1 Error: %d\n",ret);
break;
}
same_chip = 0;
est2 = 0;
ret = check_phase_sma(ctx, &est2);
if (ret<0) {
printf("CP2 Error: %d\n",ret);
break;
}
printf("Same Chips Phase: %f | ",est);
printf("Accross Chips Phase: %f\n",est2);
if ((fabs(est)>phase_tolerance) || (fabs(est2)>phase_tolerance)) {
printf("Phase calibration not within tolerance\n");
ret = -2;
break;
}
}
#endif
// Cleanup
if (ctx) {
iio_context_destroy(ctx);
}
exit(ret);
}
libad9361-iio-0.3/test/gen_rates_test.c 0000664 0000000 0000000 00000020601 14424151631 0017661 0 ustar 00root root 0000000 0000000
#include "ad9361.h"
#include
#include
#include
#include
#include
#include
/******************************Linux Reference*********************************/
struct PHY {
bool bypass_rx_fir;
int rx_fir_dec;
bool bypass_tx_fir;
int tx_fir_int;
//int tx_intdec;
bool rx_eq_2tx;
};
#define MIN_ADC_CLK 25000000UL /* 25 MHz */
//#define MIN_ADC_CLK (MIN_BBPLL_FREQ / MAX_BBPLL_DIV) /* 11.17MHz */
#define MAX_ADC_CLK 640000000UL /* 640 MHz */
#define MAX_DAC_CLK (MAX_ADC_CLK / 2)
#define MIN_DAC_CLK 25000000UL /* 25 MHz */
#define MAX_BBPLL_FREF 70007000UL /* 70 MHz + 100ppm */
#define MIN_BBPLL_FREQ 714928500UL /* 715 MHz - 100ppm */
#define MAX_BBPLL_FREQ 1430143000UL /* 1430 MHz + 100ppm */
#define MAX_BBPLL_DIV 64
#define MIN_BBPLL_DIV 2
// Output of FIR (RX)
#define MAX_DATA_RATE 61440000UL
#define MIN_DATA_RATE MIN_ADC_CLK / 48
// Output of FIR on RX
#define MAX_FIR MAX_DATA_RATE * 2
// Associated with outputs of stage
#define MAX_RX_HB1 122880000UL
#define MAX_RX_HB2 245760000UL
#define MAX_RX_HB3 320000000UL
// Associated with inputs of stage
#define MAX_TX_HB1 122880000UL
#define MAX_TX_HB2 245760000UL
#define MAX_TX_HB3 320000000UL
#define check(val,min,max) ( (val)<=(max) ? (val)>=(min) : false )
const unsigned long RX_MAX_PATH_RATES[] = {MAX_BBPLL_FREQ,MAX_ADC_CLK, MAX_RX_HB3, MAX_RX_HB2, MAX_RX_HB1, MAX_FIR};
const unsigned long TX_MAX_PATH_RATES[] = {MAX_BBPLL_FREQ,MAX_DAC_CLK, MAX_TX_HB3, MAX_TX_HB2, MAX_TX_HB1, MAX_FIR};
const unsigned long RX_MIN_PATH_RATES[] = {MIN_BBPLL_FREQ,MIN_ADC_CLK, 0, 0, 0, 0};
const unsigned long TX_MIN_PATH_RATES[] = {MIN_BBPLL_FREQ,MIN_DAC_CLK, 0, 0, 0, 0};
enum ad9361_pdata_rx_freq {
BBPLL_FREQ,
ADC_FREQ,
R2_FREQ,
R1_FREQ,
CLKRF_FREQ,
RX_SAMPL_FREQ,
NUM_RX_CLOCKS,
};
enum ad9361_pdata_tx_freq {
IGNORE,
DAC_FREQ,
T2_FREQ,
T1_FREQ,
CLKTF_FREQ,
TX_SAMPL_FREQ,
NUM_TX_CLOCKS,
};
int FIR = 0;
int linux_calculate_rf_clock_chain(
unsigned long tx_sample_rate,
uint32_t rate_gov,
unsigned long *rx_path_clks,
unsigned long *tx_path_clks)
{
// PHY SETTINGS
struct PHY phy;
phy.bypass_rx_fir = false;
phy.bypass_tx_fir = false;
phy.rx_fir_dec = FIR;
phy.tx_fir_int = FIR;
//phy.tx_intdec = 4;
phy.rx_eq_2tx = false;
unsigned long clktf, clkrf, adc_rate = 0, dac_rate = 0;
uint64_t bbpll_rate;
int i, index_rx = -1, index_tx = -1, tmp;
uint32_t div, tx_intdec, rx_intdec, recursion = 1;
const char clk_dividers[][4] = {
{12,3,2,2},
{8,2,2,2},
{6,3,2,1},//Updated to give correct orientation
{4,2,2,1},
{3,3,1,1},
{2,2,1,1},
{1,1,1,1},
};
if (phy.bypass_rx_fir)
rx_intdec = 1;
else
rx_intdec = phy.rx_fir_dec;
if (phy.bypass_tx_fir)
tx_intdec = 1;
else
tx_intdec = phy.tx_fir_int;
if ((rate_gov == 1) && ((rx_intdec * tx_sample_rate * 8) < MIN_ADC_CLK)) {
recursion = 0;
rate_gov = 0;
}
// dev_dbg(&phy.spi.dev, "%s: requested rate %lu TXFIR int %d RXFIR dec %d mode %s",
// __func__, tx_sample_rate, tx_intdec, rx_intdec,
// rate_gov ? "Nominal" : "Highest OSR");
if (tx_sample_rate > 61440000UL)
return -EINVAL;
clktf = tx_sample_rate * tx_intdec;
clkrf = tx_sample_rate * rx_intdec * (phy.rx_eq_2tx ? 2 : 1);
for (i = rate_gov; i < 7; i++) {
adc_rate = clkrf * clk_dividers[i][0];
dac_rate = clktf * clk_dividers[i][0];
if ((adc_rate <= MAX_ADC_CLK) && (adc_rate >= MIN_ADC_CLK)) {
if (dac_rate > adc_rate)
tmp = (dac_rate / adc_rate) * -1;
else
tmp = adc_rate / dac_rate;
if (adc_rate <= MAX_DAC_CLK) {
index_rx = i;
index_tx = i - ((tmp == 1) ? 0 : tmp);
dac_rate = adc_rate; /* ADC_CLK */
break;
} else {
dac_rate = adc_rate / 2; /* ADC_CLK/2 */
index_rx = i;
if (i == 4 && tmp >= 0)
index_tx = 7; /* STOP: 3/2 != 1 */
else
index_tx = i + ((i == 5 && tmp >= 0) ? 1 : 2) -
((tmp == 1) ? 0 : tmp);
break;
}
}
}
if ((index_tx < 0 || index_tx > 6 || index_rx < 0 || index_rx > 6)
&& rate_gov < 7 && recursion) {
return linux_calculate_rf_clock_chain(tx_sample_rate,
++rate_gov, rx_path_clks, tx_path_clks);
} else if ((index_tx < 0 || index_tx > 6 || index_rx < 0 || index_rx > 6)) {
// dev_err(&phy.spi.dev, "%s: Failed to find suitable dividers: %s",
// __func__, (adc_rate < MIN_ADC_CLK) ? "ADC clock below limit" : "BBPLL rate above limit");
printf("Failed to find clock rate\n");
return -EINVAL;
}
/* Calculate target BBPLL rate */
div = MAX_BBPLL_DIV;
do {
bbpll_rate = (uint64_t)adc_rate * div;
div >>= 1;
} while ((bbpll_rate > MAX_BBPLL_FREQ) && (div >= MIN_BBPLL_DIV));
// printf("div: %d\n",div<<=1);
rx_path_clks[BBPLL_FREQ] = bbpll_rate;
rx_path_clks[ADC_FREQ] = adc_rate;
rx_path_clks[R2_FREQ] = rx_path_clks[ADC_FREQ] / clk_dividers[index_rx][1];
rx_path_clks[R1_FREQ] = rx_path_clks[R2_FREQ] / clk_dividers[index_rx][2];
rx_path_clks[CLKRF_FREQ] = rx_path_clks[R1_FREQ] / clk_dividers[index_rx][3];
rx_path_clks[RX_SAMPL_FREQ] = rx_path_clks[CLKRF_FREQ] / rx_intdec;
tx_path_clks[BBPLL_FREQ] = bbpll_rate;
tx_path_clks[DAC_FREQ] = dac_rate;
tx_path_clks[T2_FREQ] = tx_path_clks[DAC_FREQ] / clk_dividers[index_tx][1];
tx_path_clks[T1_FREQ] =tx_path_clks[T2_FREQ] / clk_dividers[index_tx][2];
tx_path_clks[CLKTF_FREQ] = tx_path_clks[T1_FREQ] / clk_dividers[index_tx][3];
tx_path_clks[TX_SAMPL_FREQ] = tx_path_clks[CLKTF_FREQ] / tx_intdec;
return 0;
}
void set_fir_decint(unsigned long rate)
{
if (rate <= 30720000)
FIR = 4;
else
FIR = 2;
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
bool check_result(unsigned long *rx1, unsigned long *rx2, unsigned long *tx1,
unsigned long *tx2)
{
bool r = false;
int o=0;
for (o=0; o<6; o++)
r |= ( (rx1[o] != rx2[o]) || (tx1[o] != tx2[o]) ) ;
if (r) {
printf("LINUX\n");
printf("BBPLL | RX %lu | TX %lu | MAX: %lu\n",rx1[o],tx1[o],RX_MAX_PATH_RATES[0]);
for (o=1; o<6; o++)
printf("RX %lu (%lu MAX %lu)| TX %lu (%lu MAX %lu) \n",
rx1[o],rx1[o-1]/rx1[o], RX_MAX_PATH_RATES[o],
tx1[o], tx1[o-1]/tx1[o], TX_MAX_PATH_RATES[o]);
printf("----------\n");
printf("LIBAD9361\n");
printf("BBPLL | RX %lu | TX %lu | MAX: %lu\n",rx2[0],tx2[0],RX_MAX_PATH_RATES[0]);
for (o=1; o<6; o++)
printf("RX %lu (%lu MAX %lu)| TX %lu (%lu MAX %lu)\n",
rx2[o],rx2[o-1]/rx2[o],RX_MAX_PATH_RATES[o],
tx2[o],tx2[o-1]/tx2[o],TX_MAX_PATH_RATES[o]);
}
// Check rates themselves
for (o=0; o<6; o++)
{
r |= !check(rx1[o],RX_MIN_PATH_RATES[o],RX_MAX_PATH_RATES[o]);
r |= !check(rx2[o],RX_MIN_PATH_RATES[o],RX_MAX_PATH_RATES[o]);
r |= !check(tx1[o],TX_MIN_PATH_RATES[o],TX_MAX_PATH_RATES[o]);
r |= !check(tx2[o],TX_MIN_PATH_RATES[o],TX_MAX_PATH_RATES[o]);
if (r)
printf("Rate validation failed\n");
}
return r;
}
int main(void)
{
int ret, k;
unsigned long rx1[6], tx1[6];
unsigned long rx2[6], tx2[6];
unsigned long sample_rate = 5208334;
unsigned long max = 61440000;
uint32_t rate_governor = 0; //phy->rate_governor ? 1500000U : 1000000U;
while (sample_rate <= max) {
// Baseline from linux driver
set_fir_decint(sample_rate);
ret = linux_calculate_rf_clock_chain(sample_rate, rate_governor, rx1, tx1);
if (ret<0)
return ret;
ret = ad9361_calculate_rf_clock_chain(sample_rate, rate_governor, rx2, tx2);
if (ret<0)
return ret;
if (check_result(rx1,rx2,tx1,tx2))
return -1;
sample_rate++;
}
return 0;
}
libad9361-iio-0.3/test/rateRX_1000000.taps 0000664 0000000 0000000 00000001156 14424151631 0017471 0 ustar 00root root 0000000 0000000 197
-86
334
-32
238
-99
-39
-369
-411
-648
-616
-639
-423
-239
70
259
419
375
241
-46
-319
-566
-631
-536
-234
148
545
785
813
560
108
-447
-907
-1137
-1007
-543
166
896
1427
1543
1169
353
-680
-1629
-2157
-2044
-1223
125
1644
2850
3295
2695
1057
-1286
-3705
-5422
-5683
-3981
-197
5305
11735
18010
22998
25758
25758
22998
18010
11735
5305
-197
-3981
-5683
-5422
-3705
-1286
1057
2695
3295
2850
1644
125
-1223
-2044
-2157
-1629
-680
353
1169
1543
1427
896
166
-543
-1007
-1137
-907
-447
108
560
813
785
545
148
-234
-536
-631
-566
-319
-46
241
375
419
259
70
-239
-423
-639
-616
-648
-411
-369
-39
-99
238
-32
334
-86
197
libad9361-iio-0.3/test/rateRX_10000000.taps 0000664 0000000 0000000 00000001156 14424151631 0017551 0 ustar 00root root 0000000 0000000 197
-86
334
-32
238
-99
-39
-369
-411
-648
-616
-639
-423
-239
70
259
419
375
241
-46
-319
-566
-631
-536
-234
148
545
785
813
560
108
-447
-907
-1137
-1007
-543
166
896
1427
1543
1169
353
-680
-1629
-2157
-2044
-1223
125
1644
2850
3295
2695
1057
-1286
-3705
-5422
-5683
-3981
-197
5305
11735
18010
22998
25758
25758
22998
18010
11735
5305
-197
-3981
-5683
-5422
-3705
-1286
1057
2695
3295
2850
1644
125
-1223
-2044
-2157
-1629
-680
353
1169
1543
1427
896
166
-543
-1007
-1137
-907
-447
108
560
813
785
545
148
-234
-536
-631
-566
-319
-46
241
375
419
259
70
-239
-423
-639
-616
-648
-411
-369
-39
-99
238
-32
334
-86
197
libad9361-iio-0.3/test/rateRX_20000000.taps 0000664 0000000 0000000 00000001152 14424151631 0017546 0 ustar 00root root 0000000 0000000 190
-88
329
-40
239
-99
-24
-349
-377
-611
-573
-604
-395
-229
66
239
394
350
227
-46
-300
-534
-593
-506
-221
137
512
737
765
526
103
-420
-852
-1069
-947
-512
156
841
1341
1450
1100
333
-638
-1531
-2028
-1922
-1152
115
1544
2677
3099
2535
997
-1205
-3479
-5095
-5345
-3750
-199
4965
11002
16895
21580
24172
24172
21580
16895
11002
4965
-199
-3750
-5345
-5095
-3479
-1205
997
2535
3099
2677
1544
115
-1152
-1922
-2028
-1531
-638
333
1100
1450
1341
841
156
-512
-947
-1069
-852
-420
103
526
765
737
512
137
-221
-506
-593
-534
-300
-46
227
350
394
239
66
-229
-395
-604
-573
-611
-377
-349
-24
-99
239
-40
329
-88
190
libad9361-iio-0.3/test/rateRX_60000000.taps 0000664 0000000 0000000 00000000656 14424151631 0017562 0 ustar 00root root 0000000 0000000 68
76
11
-259
-539
-615
-288
212
447
128
-430
-589
-45
677
713
-156
-1037
-808
520
1515
809
-1145
-2155
-624
2238
3098
36
-4522
-5064
1970
13975
23302
23302
13975
1970
-5064
-4522
36
3098
2238
-624
-2155
-1145
809
1515
520
-808
-1037
-156
713
677
-45
-589
-430
128
447
212
-288
-615
-539
-259
11
76
68
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
libad9361-iio-0.3/test/rateTX_1000000.taps 0000664 0000000 0000000 00000001144 14424151631 0017470 0 ustar 00root root 0000000 0000000 54
-53
39
-124
-126
-316
-401
-580
-647
-710
-634
-506
-263
-9
255
424
491
401
201
-84
-351
-540
-565
-423
-125
234
562
737
700
429
-6
-490
-865
-1006
-833
-372
266
890
1300
1332
934
177
-733
-1523
-1915
-1729
-942
275
1589
2583
2878
2251
738
-1344
-3433
-4845
-4936
-3278
204
5174
10925
16507
20929
23370
23370
20929
16507
10925
5174
204
-3278
-4936
-4845
-3433
-1344
738
2251
2878
2583
1589
275
-942
-1729
-1915
-1523
-733
177
934
1332
1300
890
266
-372
-833
-1006
-865
-490
-6
429
700
737
562
234
-125
-423
-565
-540
-351
-84
201
401
491
424
255
-9
-263
-506
-634
-710
-647
-580
-401
-316
-126
-124
39
-53
54
libad9361-iio-0.3/test/rateTX_10000000.taps 0000664 0000000 0000000 00000001146 14424151631 0017552 0 ustar 00root root 0000000 0000000 58
-57
47
-125
-123
-312
-401
-576
-647
-707
-637
-505
-266
-10
252
423
489
401
200
-83
-351
-538
-565
-422
-126
234
561
737
699
429
-6
-489
-865
-1005
-833
-372
266
890
1299
1332
934
178
-732
-1521
-1914
-1729
-942
274
1588
2581
2877
2251
739
-1342
-3431
-4842
-4933
-3276
204
5173
10922
16502
20921
23362
23362
20921
16502
10922
5173
204
-3276
-4933
-4842
-3431
-1342
739
2251
2877
2581
1588
274
-942
-1729
-1914
-1521
-732
178
934
1332
1299
890
266
-372
-833
-1005
-865
-489
-6
429
699
737
561
234
-126
-422
-565
-538
-351
-83
200
401
489
423
252
-10
-266
-505
-637
-707
-647
-576
-401
-312
-123
-125
47
-57
58
libad9361-iio-0.3/test/rateTX_20000000.taps 0000664 0000000 0000000 00000001146 14424151631 0017553 0 ustar 00root root 0000000 0000000 63
-62
58
-132
-111
-316
-393
-579
-644
-711
-636
-510
-267
-13
252
423
491
402
202
-83
-352
-541
-568
-425
-128
234
563
740
703
432
-4
-490
-869
-1011
-838
-375
265
893
1306
1340
941
182
-733
-1528
-1924
-1740
-950
271
1592
2593
2893
2267
750
-1341
-3441
-4864
-4963
-3308
177
5157
10921
16518
20952
23400
23400
20952
16518
10921
5157
177
-3308
-4963
-4864
-3441
-1341
750
2267
2893
2593
1592
271
-950
-1740
-1924
-1528
-733
182
941
1340
1306
893
265
-375
-838
-1011
-869
-490
-4
432
703
740
563
234
-128
-425
-568
-541
-352
-83
202
402
491
423
252
-13
-267
-510
-636
-711
-644
-579
-393
-316
-111
-132
58
-62
63
libad9361-iio-0.3/test/rateTX_60000000.taps 0000664 0000000 0000000 00000000666 14424151631 0017565 0 ustar 00root root 0000000 0000000 26
-13
-154
-428
-652
-600
-179
334
493
101
-467
-570
12
706
670
-220
-1044
-739
585
1496
719
-1201
-2101
-511
2279
3005
-101
-4553
-4948
2112
13990
23175
23175
13990
2112
-4948
-4553
-101
3005
2279
-511
-2101
-1201
719
1496
585
-739
-1044
-220
670
706
12
-570
-467
101
493
334
-179
-600
-652
-428
-154
-13
26
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
libad9361-iio-0.3/test/testLoadLibrary.m 0000664 0000000 0000000 00000003141 14424151631 0017771 0 ustar 00root root 0000000 0000000 libName = 'libad9361';
hfile = '/usr/local/include/ad9361-wrapper.h';
loadlibraryArgs = {hfile,'includepath','/usr/local/include','addheader','ad9361.h'};
[a1, b1] = loadlibrary(libName, loadlibraryArgs{:});
libfunctions('libad9361')
hfile = '/usr/share/libiio/matlab/iio-wrapper.h';
loadlibraryArgs = {hfile,'includepath','/usr/local/include','addheader','iio.h'};
[a2, b2] = loadlibrary('libiio', loadlibraryArgs{:});
libfunctions('libiio')
% Create the network context
ip_address = '192.168.2.1';
iio_ctx = calllib('libiio', 'iio_create_network_context', ip_address);
% Check if the network context is valid
if (isNull(iio_ctx))
iio_ctx = {}; %#ok
unloadlibrary('libad9361')
unloadlibrary('libiio')
error('Could not connect to the IIO server!');
end
% Increase the object's instance count
fprintf('Connected to IP %s\n', ip_address);
nb_devices = calllib('libiio', 'iio_context_get_devices_count', iio_ctx);
% If no devices are present return with error
if(nb_devices == 0)
unloadlibrary('libad9361')
unloadlibrary('libiio')
error('No devices were detected in the system!');
end
fprintf('Found %d devices in the system\n', nb_devices);
% Detect if the targeted device is installed
dev_found = 0;
for i = 0 : nb_devices - 1
dev = calllib('libiio', 'iio_context_get_device', iio_ctx, i);
name = calllib('libiio', 'iio_device_get_name', dev);
fprintf('%s\n',name);
if strcmp(name,'ad9361-phy')
ret = calllib(libName,'ad9361_set_bb_rate',dev,int32(2e6));
disp(ret);
end
clear dev;
end
iio_ctx = {};
unloadlibrary('libad9361')
unloadlibrary('libiio')