diff --git a/libs/getLoudness/macx/.gitignore b/libs/getLoudness/macx/.gitignore new file mode 100644 index 0000000..9c66351 --- /dev/null +++ b/libs/getLoudness/macx/.gitignore @@ -0,0 +1,22 @@ +*.asv +*.m~ +*.mex* +*.o +*.obj +*.dll +*.so +*.dylib +*.a +*.lib +*.exe +*.map +*.rsp +*.tmw +*.mat +sil/ +interface/_coder_*_info.* +coderassumptions/ +target/ +build/ +debug/ +*.slxc diff --git a/libs/getLoudness/macx/coder_array.h b/libs/getLoudness/macx/coder_array.h new file mode 100644 index 0000000..bedaa74 --- /dev/null +++ b/libs/getLoudness/macx/coder_array.h @@ -0,0 +1,783 @@ +/* Copyright 2019 The Mathworks, Inc. */ +/* Copied from + * fullfile(matlabroot,'extern','include','coder','coder_array','coder_array_rtw_cpp11.h') */ + +#ifndef _mw_coder_array_cpp11_h +#define _mw_coder_array_cpp11_h + +// Usage: +// +// coder::array: T base type of data, N number of dimensions +// +// coder::array() +// : default constructor +// coder::array(coder::array const &) +// : copy constructor (always make a deep copy of other array) +// coder::array(T const *data, SizeType const *sz) +// : Set data with sizes of this array. +// : (Data is not copied, data is not deleted) +// coder::array::operator = (coder coder::array &) +// : Assign into this array; +// : delete its previous contents (if owning the data.) +// set(T const *data, SizeType sz1, SizeType sz2, ...) +// : Set data with dimensions. +// : (Data is not copied, data is not deleted) +// set_size(SizeType sz1, SizeType sz2, ...) +// : Set sizes of array. Reallocate memory of data if needed. +// bool is_owner() : Return true if the data is owned by the class. +// void set_owner(b) : Set if the data is owned by the class. +// SizeType capacity() : How many entries are reserved by memory allocation. +// reshape( SizeType sz1, SizeType sz2, ...) +// : Reshape array to a different ND shape. Do not copy the data. +// : The number of elements must not be changed (numel()==sz1*sz2*...) +// : Return the array with possibly new number of dimensions. +// clear() : Reset array to be empty. +// SizeType numel() : Return the number of elements. +// operator [] (SizeType index) : Extract element at linear index (0 based.) +// size(SizeType dimension) : Size of array of the provided dimension. +// SizeType * size() : Return the pointer to all the sizes of this array. +// SizeType index(SizeType i1, SizeType i2, ...) +// : Compute the linear index from ND index (i1,i2,...) +// at(SizeType i1, SizeType i2, ...) : The element at index (i1,i2,...) + +#include +#include +#include +#include +#include + +#ifndef INT32_T +#include "rtwtypes.h" +#endif + +namespace coder { + +#ifndef CODER_ARRAY_NEW_DELETE +#define CODER_ARRAY_NEW_DELETE +#define CODER_NEW(T, N) new T[N] +#define CODER_DELETE(P) delete[](P) +#endif + +using SizeType = int32_T; +namespace std = ::std; + +namespace detail { + +#ifndef CODER_ARRAY_DATA_PTR_DEFINED +template +class data_ptr { + public: + using value_type = T; + using size_type = SZ; + + data_ptr() + : data_(nullptr) + , size_(0) + , capacity_(0) + , owner_(false) { + } + data_ptr(T* _data, SZ _sz) + : data_(_data) + , size_(_sz) + , capacity_(_sz) + , owner_(false) { + } + + data_ptr(data_ptr const& _other) + : data_(_other.owner_ ? nullptr : _other.data_) + , size_(_other.owner_ ? 0 : _other.size_) + , capacity_(_other.owner_ ? 0 : _other.capacity_) + , owner_(_other.owner_) { + if (owner_) { + resize(_other.size_); + (void)std::copy(_other.data_, _other.data_ + size_, data_); + } + } + + ~data_ptr() { + if (owner_) { + CODER_DELETE(data_); + } + } + SZ capacity() const { + return capacity_; + } + void reserve(SZ _n) { + if (_n > capacity_) { + T* const new_data{CODER_NEW(T, _n)}; + (void)std::copy(data_, data_ + size_, new_data); + if (owner_) { + CODER_DELETE(data_); + } + data_ = new_data; + capacity_ = _n; + owner_ = true; + } + } + void resize(SZ _n) { + reserve(_n); + size_ = _n; + } + + private: + // Prohibit use of assignment operator to prevent subtle bugs + void operator=(data_ptr const& _other); + + public: + void set(T* _data, SZ _sz) { + if (owner_) { + CODER_DELETE(data_); + } + data_ = _data; + size_ = _sz; + owner_ = false; + capacity_ = size_; + } + + void copy(T const* const _data, SZ _size) { + if (data_ == _data) { + size_ = _size; + return; + } + if (owner_) { + CODER_DELETE(data_); + } + data_ = CODER_NEW(T, _size); + owner_ = true; + size_ = _size; + capacity_ = size_; + (void)std::copy(_data, _data + _size, data_); + } + + void copy(data_ptr const& _other) { + copy(_other.data_, _other.size_); + } + + operator T*() { + return &data_[0]; + } + + operator T const *() const { + return &data_[0]; + } + + T& operator[](SZ _index) { + return data_[_index]; + } + T const& operator[](SZ _index) const { + return data_[_index]; + } + + T* operator->() { + return data_; + } + + T const* operator->() const { + return data_; + } + + bool is_null() const { + return data_ == nullptr; + } + + void clear() { + if (owner_) { + CODER_DELETE(data_); + } + data_ = nullptr; + size_ = 0; + capacity_ = 0; + owner_ = false; + } + + bool is_owner() const { + return owner_; + } + + void set_owner(bool _b) { + owner_ = _b; + } + + private: + T* data_; + SZ size_; + SZ capacity_; + bool owner_; +}; +#endif + +} // namespace detail + +// Implementing the random access iterator class so coder::array can be +// used in STL iterators. +template +class array_iterator : public std::iterator { + public: + array_iterator() + : arr_(nullptr) + , i_(0) { + } + array_iterator(array_iterator const& other) + : arr_(other.arr_) + , i_(other.i_) { + } + ~array_iterator() { + } + typename T::value_type& operator*() const { + return (*arr_)[i_]; + } + typename T::value_type* operator->() const { + return &(*arr_)[i_]; + } + typename T::value_type& operator[](typename T::size_type _di) const { + return (*arr_)[i_ + _di]; + } + array_iterator& operator++() { + ++i_; + return *this; + } + array_iterator& operator--() { + --i_; + return *this; + } + array_iterator operator++(int) { + array_iterator cp{*this}; + ++i_; + return cp; + } + array_iterator operator--(int) { + array_iterator cp{*this}; + --i_; + return cp; + } + array_iterator& operator=(array_iterator const& _other) { + this->i_ = _other.i_; + return *this; + } + bool operator==(array_iterator const& _other) const { + return i_ == _other.i_; + } + bool operator!=(array_iterator const& _other) const { + return i_ != _other.i_; + } + bool operator<(array_iterator const& _other) const { + return i_ < _other.i_; + } + bool operator>(array_iterator const& _other) const { + return i_ > _other.i_; + } + bool operator<=(array_iterator const& _other) const { + return i_ <= _other.i_; + } + bool operator>=(array_iterator const& _other) const { + return i_ >= _other.i_; + } + array_iterator operator+(typename T::size_type _add) const { + array_iterator cp{*this}; + cp.i_ += _add; + return cp; + } + array_iterator& operator+=(typename T::size_type _add) { + this->i_ += _add; + return *this; + } + array_iterator operator-(typename T::size_type _subtract) const { + array_iterator cp{*this}; + cp.i_ -= _subtract; + return cp; + } + array_iterator& operator-=(typename T::size_type _subtract) { + this->i_ -= _subtract; + return *this; + } + typename T::size_type operator-(array_iterator const& _other) const { + return static_cast(this->i_ - _other.i_); + } + + array_iterator(T* _arr, typename T::size_type _i) + : arr_(_arr) + , i_(_i) { + } + + private: + T* arr_; + typename T::size_type i_; +}; + +// Const version of the array iterator. +template +class const_array_iterator : public std::iterator { + public: + const_array_iterator() + : arr_(nullptr) + , i_(0) { + } + const_array_iterator(const_array_iterator const& other) + : arr_(other.arr_) + , i_(other.i_) { + } + ~const_array_iterator() { + } + typename T::value_type const& operator*() const { + return (*arr_)[i_]; + } + typename T::value_type const* operator->() const { + return &(*arr_)[i_]; + } + typename T::value_type const& operator[](typename T::size_type _di) const { + return (*arr_)[i_ + _di]; + } + const_array_iterator& operator++() { + ++i_; + return *this; + } + const_array_iterator& operator--() { + --i_; + return *this; + } + const_array_iterator operator++(int) { + const_array_iterator copy{*this}; + ++i_; + return copy; + } + const_array_iterator operator--(int) { + const_array_iterator copy{*this}; + --i_; + return copy; + } + const_array_iterator& operator=(const_array_iterator const& _other) { + this->i_ = _other.i_; + return *this; + } + bool operator==(const_array_iterator const& _other) const { + return i_ == _other.i_; + } + bool operator!=(const_array_iterator const& _other) const { + return i_ != _other.i_; + } + bool operator<(const_array_iterator const& _other) const { + return i_ < _other.i_; + } + bool operator>(const_array_iterator const& _other) const { + return i_ > _other.i_; + } + bool operator<=(const_array_iterator const& _other) const { + return i_ <= _other.i_; + } + bool operator>=(const_array_iterator const& _other) const { + return i_ >= _other.i_; + } + const_array_iterator operator+(typename T::size_type _add) const { + const_array_iterator cp{*this}; + cp.i_ += _add; + return cp; + } + const_array_iterator& operator+=(typename T::size_type _add) { + this->i_ += _add; + return *this; + } + const_array_iterator operator-(typename T::size_type _subtract) const { + const_array_iterator cp{*this}; + cp.i_ -= _subtract; + return cp; + } + + const_array_iterator& operator-=(typename T::size_type _subtract) { + this->i_ -= _subtract; + return *this; + } + + typename T::size_type operator-(const_array_iterator const& _other) const { + return static_cast(this->i_ - _other.i_); + } + + const_array_iterator(T const* _arr, typename T::size_type _i) + : arr_(_arr) + , i_(_i) { + } + + private: + T const* arr_; + typename T::size_type i_; + typename T::size_type n_; +}; + +namespace detail { + +// detail::numel: Compile-time product of the given size vector of length N. +template +class numel { + public: + template + static SZ compute(SZ _size[]) { + return _size[N - 1] * numel::compute(_size); + } +}; +template <> +class numel<0> { + public: + template + static SZ compute(SZ[]) { + return 1; + } +}; + +// Compute the product for a set of numeric arguments: product(10, 20, 30, ...) => +// 10*20*30*... +template +struct product_i { + static SZ compute(First _f, Rest... _rest) { + return _f * product_i::compute(_rest...); + } +}; +template +struct product_i { + static SZ compute(Last _l) { + return _l; + } +}; + +template +SZ product(Args... args) { + return product_i::compute(args...); +} + +// Compute flat index from (column-major) ND size vector and a list of indices. +template +class index_nd { + public: + template + static SZ compute(SZ const _size[], SZ const _indices[]) { + SZ const weight{numel::compute(_size)}; + return weight * _indices[I - 1] + index_nd::compute(_size, _indices); + } +}; + +template <> +class index_nd<0> { + public: + template + static SZ compute(SZ[], SZ[]) { + return 0; + } +}; + +template +struct match_dimensions {}; + +template <> +struct match_dimensions { + static void check() { + } +}; + +} // namespace detail + +// Base class for code::array. SZ is the type used for sizes (currently int32_t.) +// Overloading up to 10 dimensions (not using variadic templates to +// stay compatible with C++98.) +template +class array_base { + public: + using value_type = T; + using size_type = SZ; + + array_base() { + (void)::memset(size_, 0, sizeof(SZ) * N); + } + + array_base(T* _data, SZ const* _sz) + : data_(_data, coder::detail::numel::compute(_sz)) { + (void)std::copy(_sz, _sz + N, size_); + } + + array_base& operator=(array_base const& _other) { + data_.copy(_other.data_); + (void)std::copy(_other.size_, _other.size_ + N, size_); + return *this; + } + + template + void set(T* _data, Dims... dims) { + coder::detail::match_dimensions::check(); + data_.set(_data, coder::detail::product(dims...)); + set_size_i<0>(dims...); + } + + bool is_owner() const { + return data_.is_owner(); + } + + void set_owner(bool b) { + data_.set_owner(b); + } + + SZ capacity() const { + return data_.capacity(); + } + + private: + template + void set_size_i(First f, Rest... rest) { + size_[_i] = f; + set_size_i<_i + 1, Rest...>(rest...); + } + template + void set_size_i(Last l) { + size_[_i] = l; + } + + public: + template + void set_size(Dims... dims) { + coder::detail::match_dimensions::check(); + set_size_i<0>(dims...); + ensureCapacity(numel()); + } + + template + array_base reshape_n(SZ const (&_ns)[N1]) const { + array_base reshaped{const_cast(&data_[0]), _ns}; + return reshaped; + } + + template + array_base(sizeof...(Dims))> reshape(Dims... dims) const { + SZ const ns[]{static_cast(dims)...}; + return reshape_n(ns); + } + + T& operator[](SZ _index) { + return data_[_index]; + } + + T const& operator[](SZ _index) const { + return data_[_index]; + } + + void clear() { + data_.clear(); + } + + T* data() { + return data_; + } + + T const* data() const { + return data_; + } + + SZ const* size() const { + return &size_[0]; + } + + SZ size(SZ _index) const { + return size_[_index]; + } + + SZ numel() const { + return coder::detail::numel::compute(size_); + } + + template + SZ index(Dims... _dims) const { + coder::detail::match_dimensions::check(); + SZ const indices[]{static_cast(_dims)...}; + return coder::detail::index_nd(sizeof...(_dims))>::compute(size_, indices); + } + + template + T& at(Dims... _i) { + coder::detail::match_dimensions::check(); + return data_[index(_i...)]; + } + + template + T const& at(Dims... _i) const { + coder::detail::match_dimensions::check(); + return data_[index(_i...)]; + } + + array_iterator> begin() { + return array_iterator>(this, 0); + } + array_iterator> end() { + return array_iterator>(this, this->numel()); + } + const_array_iterator> begin() const { + return const_array_iterator>(this, 0); + } + const_array_iterator> end() const { + return const_array_iterator>(this, this->numel()); + } + + protected: + coder::detail::data_ptr data_; + SZ size_[N]; + + private: + void ensureCapacity(SZ _newNumel) { + if (_newNumel > data_.capacity()) { + SZ i{data_.capacity()}; + if (i < 16) { + i = 16; + } + + while (i < _newNumel) { + if (i > 1073741823) { + i = MAX_int32_T; + } else { + i *= 2; + } + } + data_.reserve(i); + } + data_.resize(_newNumel); + } +}; + +// The standard coder::array class with base type and number of dimensions. +template +class array : public array_base { + private: + using Base = array_base; + + public: + array() + : Base() { + } + array(array const& _other) + : Base(_other) { + } + array(Base const& _other) + : Base(_other) { + } + array(T* _data, SizeType const* _sz) + : Base(_data, _sz) { + } +}; + +// Specialize on char_T (row vector) for better support on strings. +template <> +class array : public array_base { + private: + using Base = array_base; + + public: + array() + : array_base() { + } + array(array const& _other) + : Base(_other) { + } + array(Base const& _other) + : Base(_other) { + } + + array(std::string const& _str) { + operator=(_str); + } + + array(char_T const* const _str) { + operator=(_str); + } + + array(std::vector const& _vec) { + SizeType const n{static_cast(_vec.size())}; + set_size(1, n); + data_.copy(&_vec[0], n); + } + + array& operator=(std::string const& _str) { + SizeType const n{static_cast(_str.size())}; + set_size(1, n); + data_.copy(_str.c_str(), n); + return *this; + } + + array& operator=(char_T const* const _str) { + SizeType const n{static_cast(strlen(_str))}; + set_size(1, n); + data_.copy(_str, n); + return *this; + } + + operator std::string() const { + return std::string(static_cast(&(*this)[0]), static_cast(size(1))); + } +}; + +// Specialize on 2 dimensions for better support interactions with +// std::vector and row vectors. +template +class array : public array_base { + private: + using Base = array_base; + + public: + array() + : Base() { + } + array(array const& _other) + : Base(_other) { + } + array(Base const& _other) + : Base(_other) { + } + array(std::vector const& _vec) { + operator=(_vec); + } + + array& operator=(std::vector const& _vec) { + SizeType n{static_cast(_vec.size())}; + Base::set_size(1, n); + Base::data_.copy(&_vec[0], n); + return *this; + } + + operator std::vector() const { + T const* p{&Base::data_[0]}; + return std::vector(p, p + Base::numel()); + } +}; + +// Specialize on 1 dimension for better support with std::vector and +// column vectors. +template +class array : public array_base { + private: + using Base = array_base; + + public: + array() + : Base() { + } + array(array const& _other) + : Base(_other) { + } + array(Base const& _other) + : Base(_other) { + } + array(std::vector const& _vec) { + operator=(_vec); + } + + array& operator=(std::vector const& _vec) { + SizeType n{static_cast(_vec.size())}; + Base::set_size(n); + Base::data_.copy(&_vec[0], n); + return *this; + } + + operator std::vector() const { + T const* p{&Base::data_[0]}; + return std::vector(p, p + Base::numel()); + } +}; +} // namespace coder + +#endif diff --git a/libs/getLoudness/macx/coder_bounded_array.h b/libs/getLoudness/macx/coder_bounded_array.h new file mode 100644 index 0000000..946a05b --- /dev/null +++ b/libs/getLoudness/macx/coder_bounded_array.h @@ -0,0 +1,34 @@ +/* Copyright 2020 The Mathworks, Inc. */ +/* Copied from fullfile(matlabroot,'extern','include','coder','coder_array','coder_bounded_array.h') */ + +#ifndef _mw_coder_bounded_array_h +#define _mw_coder_bounded_array_h + +#ifdef MATLAB_MEX_FILE +#include "tmwtypes.h" +#else +#include "rtwtypes.h" +#endif + +namespace coder { + +#if __cplusplus >= 201103L +using SizeType = int32_T; +#else +typedef int32_T SizeType; +#endif + +// Bounded array +template +struct bounded_array { + T data[UpperBoundSize]; + SizeType size[NumDims]; +}; + +template +struct empty_bounded_array { + SizeType size[NumDims]; +}; +} // namespace coder + +#endif diff --git a/libs/getLoudness/macx/designKWeightingFilter.h b/libs/getLoudness/macx/designKWeightingFilter.h new file mode 100644 index 0000000..a5af77c --- /dev/null +++ b/libs/getLoudness/macx/designKWeightingFilter.h @@ -0,0 +1,34 @@ +// +// Academic License - for use in teaching, academic research, and meeting +// course requirements at degree granting institutions only. Not for +// government, commercial, or other organizational use. +// File: designKWeightingFilter.h +// +// MATLAB Coder version : 5.2 +// C/C++ source code generated on : 05-Feb-2022 12:14:13 +// + +#ifndef DESIGNKWEIGHTINGFILTER_H +#define DESIGNKWEIGHTINGFILTER_H + +// Include Files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace coder { +namespace audio { +namespace internal { +void convertToFs(float sos_48kHz[6], float Fs); + +} +} // namespace audio +} // namespace coder + +#endif +// +// File trailer for designKWeightingFilter.h +// +// [EOF] +// diff --git a/libs/getLoudness/macx/getLoudness.h b/libs/getLoudness/macx/getLoudness.h new file mode 100644 index 0000000..b5e38f6 --- /dev/null +++ b/libs/getLoudness/macx/getLoudness.h @@ -0,0 +1,29 @@ +// +// Academic License - for use in teaching, academic research, and meeting +// course requirements at degree granting institutions only. Not for +// government, commercial, or other organizational use. +// File: getLoudness.h +// +// MATLAB Coder version : 5.2 +// C/C++ source code generated on : 05-Feb-2022 12:14:13 +// + +#ifndef GETLOUDNESS_H +#define GETLOUDNESS_H + +// Include Files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +extern void getLoudness(const coder::array &data, float fs, + coder::array &loudness); + +#endif +// +// File trailer for getLoudness.h +// +// [EOF] +// diff --git a/libs/getLoudness/macx/getLoudness_data.h b/libs/getLoudness/macx/getLoudness_data.h new file mode 100644 index 0000000..e3a461e --- /dev/null +++ b/libs/getLoudness/macx/getLoudness_data.h @@ -0,0 +1,24 @@ +// +// Academic License - for use in teaching, academic research, and meeting +// course requirements at degree granting institutions only. Not for +// government, commercial, or other organizational use. +// File: getLoudness_data.h +// +// MATLAB Coder version : 5.2 +// C/C++ source code generated on : 05-Feb-2022 12:14:13 +// + +#ifndef GETLOUDNESS_DATA_H +#define GETLOUDNESS_DATA_H + +// Include Files +#include "rtwtypes.h" +#include +#include + +#endif +// +// File trailer for getLoudness_data.h +// +// [EOF] +// diff --git a/libs/getLoudness/macx/getLoudness_initialize.h b/libs/getLoudness/macx/getLoudness_initialize.h new file mode 100644 index 0000000..ae08787 --- /dev/null +++ b/libs/getLoudness/macx/getLoudness_initialize.h @@ -0,0 +1,27 @@ +// +// Academic License - for use in teaching, academic research, and meeting +// course requirements at degree granting institutions only. Not for +// government, commercial, or other organizational use. +// File: getLoudness_initialize.h +// +// MATLAB Coder version : 5.2 +// C/C++ source code generated on : 05-Feb-2022 12:14:13 +// + +#ifndef GETLOUDNESS_INITIALIZE_H +#define GETLOUDNESS_INITIALIZE_H + +// Include Files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +extern void getLoudness_initialize(); + +#endif +// +// File trailer for getLoudness_initialize.h +// +// [EOF] +// diff --git a/libs/getLoudness/macx/getLoudness_terminate.h b/libs/getLoudness/macx/getLoudness_terminate.h new file mode 100644 index 0000000..8c9bd9f --- /dev/null +++ b/libs/getLoudness/macx/getLoudness_terminate.h @@ -0,0 +1,27 @@ +// +// Academic License - for use in teaching, academic research, and meeting +// course requirements at degree granting institutions only. Not for +// government, commercial, or other organizational use. +// File: getLoudness_terminate.h +// +// MATLAB Coder version : 5.2 +// C/C++ source code generated on : 05-Feb-2022 12:14:13 +// + +#ifndef GETLOUDNESS_TERMINATE_H +#define GETLOUDNESS_TERMINATE_H + +// Include Files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +extern void getLoudness_terminate(); + +#endif +// +// File trailer for getLoudness_terminate.h +// +// [EOF] +// diff --git a/libs/getLoudness/macx/getLoudness_types.h b/libs/getLoudness/macx/getLoudness_types.h new file mode 100644 index 0000000..83382c3 --- /dev/null +++ b/libs/getLoudness/macx/getLoudness_types.h @@ -0,0 +1,22 @@ +// +// Academic License - for use in teaching, academic research, and meeting +// course requirements at degree granting institutions only. Not for +// government, commercial, or other organizational use. +// File: getLoudness_types.h +// +// MATLAB Coder version : 5.2 +// C/C++ source code generated on : 05-Feb-2022 12:14:13 +// + +#ifndef GETLOUDNESS_TYPES_H +#define GETLOUDNESS_TYPES_H + +// Include Files +#include "rtwtypes.h" + +#endif +// +// File trailer for getLoudness_types.h +// +// [EOF] +// diff --git a/libs/getLoudness/macx/rtGetInf.h b/libs/getLoudness/macx/rtGetInf.h new file mode 100644 index 0000000..bcca372 --- /dev/null +++ b/libs/getLoudness/macx/rtGetInf.h @@ -0,0 +1,34 @@ +// +// Academic License - for use in teaching, academic research, and meeting +// course requirements at degree granting institutions only. Not for +// government, commercial, or other organizational use. +// File: rtGetInf.h +// +// MATLAB Coder version : 5.2 +// C/C++ source code generated on : 05-Feb-2022 12:14:13 +// + +#ifndef RTGETINF_H +#define RTGETINF_H + +// Include Files +#include "rtwtypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern real_T rtGetInf(void); +extern real32_T rtGetInfF(void); +extern real_T rtGetMinusInf(void); +extern real32_T rtGetMinusInfF(void); + +#ifdef __cplusplus +} +#endif +#endif +// +// File trailer for rtGetInf.h +// +// [EOF] +// diff --git a/libs/getLoudness/macx/rtGetNaN.h b/libs/getLoudness/macx/rtGetNaN.h new file mode 100644 index 0000000..2c0608c --- /dev/null +++ b/libs/getLoudness/macx/rtGetNaN.h @@ -0,0 +1,32 @@ +// +// Academic License - for use in teaching, academic research, and meeting +// course requirements at degree granting institutions only. Not for +// government, commercial, or other organizational use. +// File: rtGetNaN.h +// +// MATLAB Coder version : 5.2 +// C/C++ source code generated on : 05-Feb-2022 12:14:13 +// + +#ifndef RTGETNAN_H +#define RTGETNAN_H + +// Include Files +#include "rtwtypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern real_T rtGetNaN(void); +extern real32_T rtGetNaNF(void); + +#ifdef __cplusplus +} +#endif +#endif +// +// File trailer for rtGetNaN.h +// +// [EOF] +// diff --git a/libs/getLoudness/macx/rt_nonfinite.h b/libs/getLoudness/macx/rt_nonfinite.h new file mode 100644 index 0000000..ba2731d --- /dev/null +++ b/libs/getLoudness/macx/rt_nonfinite.h @@ -0,0 +1,36 @@ +// +// Academic License - for use in teaching, academic research, and meeting +// course requirements at degree granting institutions only. Not for +// government, commercial, or other organizational use. +// File: rt_nonfinite.h +// +// MATLAB Coder version : 5.2 +// C/C++ source code generated on : 05-Feb-2022 12:14:13 +// + +#ifndef RT_NONFINITE_H +#define RT_NONFINITE_H + +// Include Files +#include "rtwtypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern real_T rtInf; +extern real_T rtMinusInf; +extern real_T rtNaN; +extern real32_T rtInfF; +extern real32_T rtMinusInfF; +extern real32_T rtNaNF; + +#ifdef __cplusplus +} +#endif +#endif +// +// File trailer for rt_nonfinite.h +// +// [EOF] +// diff --git a/libs/getLoudness/macx/rtwtypes.h b/libs/getLoudness/macx/rtwtypes.h new file mode 100644 index 0000000..8f59789 --- /dev/null +++ b/libs/getLoudness/macx/rtwtypes.h @@ -0,0 +1,48 @@ +// +// Academic License - for use in teaching, academic research, and meeting +// course requirements at degree granting institutions only. Not for +// government, commercial, or other organizational use. +// File: rtwtypes.h +// +// MATLAB Coder version : 5.2 +// C/C++ source code generated on : 05-Feb-2022 12:14:13 +// + +#ifndef RTWTYPES_H +#define RTWTYPES_H + +/*=======================================================================* + * Fixed width word size data types: * + * int64_T - signed 64 bit integers * + * uint64_T - unsigned 64 bit integers * + *=======================================================================*/ + +#if defined(__APPLE__) +#ifndef INT64_T +#define INT64_T long +#define FMT64 "l" +#if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG) +#define INT_TYPE_64_IS_LONG +#endif +#endif +#endif + +#if defined(__APPLE__) +#ifndef UINT64_T +#define UINT64_T unsigned long +#define FMT64 "l" +#if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG) +#define INT_TYPE_64_IS_LONG +#endif +#endif +#endif + +// Include Files +#include "tmwtypes.h" + +#endif +// +// File trailer for rtwtypes.h +// +// [EOF] +// diff --git a/libs/getLoudness/macx/sum.h b/libs/getLoudness/macx/sum.h new file mode 100644 index 0000000..6c0581f --- /dev/null +++ b/libs/getLoudness/macx/sum.h @@ -0,0 +1,31 @@ +// +// Academic License - for use in teaching, academic research, and meeting +// course requirements at degree granting institutions only. Not for +// government, commercial, or other organizational use. +// File: sum.h +// +// MATLAB Coder version : 5.2 +// C/C++ source code generated on : 05-Feb-2022 12:14:13 +// + +#ifndef SUM_H +#define SUM_H + +// Include Files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace coder { +void sum(const ::coder::array &x, float y_data[], int y_size[2]); + +} + +#endif +// +// File trailer for sum.h +// +// [EOF] +// diff --git a/libs/getLoudness/macx/tmwtypes.h b/libs/getLoudness/macx/tmwtypes.h new file mode 100644 index 0000000..1e637b0 --- /dev/null +++ b/libs/getLoudness/macx/tmwtypes.h @@ -0,0 +1,838 @@ +/* + * @(#)tmwtypes.h generated by: makeheader 5.1.5 Fri Dec 27 18:07:22 2013 + * + * built from: ../../src/include/copyright.h + * ../../src/include/tmwtypes.h + */ + +#if defined(_MSC_VER) +# pragma once +#endif +#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)) +# pragma once +#endif + +#ifndef tmwtypes_h +#define tmwtypes_h + + +/* + * Copyright 1984-2003 The MathWorks, Inc. + * All Rights Reserved. + */ + + + +/* Copyright 1995-2013 The MathWorks, Inc. */ + +#ifndef __TMWTYPES__ +#define __TMWTYPES__ +/* + * File : tmwtypes.h + * Abstract: + * Data types for use with MATLAB/SIMULINK and the Real-Time Workshop. + * + * When compiling stand-alone model code, data types can be overridden + * via compiler switches. + * + * Define NO_FLOATS to eliminate reference to real_T, etc. + */ + +#include + +#ifdef __APPLE_CC__ +#include +#endif + +#define LOGICAL_IS_A_TYPE +#define SPARSE_GENERALIZATION + +#ifdef NO_FLOATS +# define double double_not_allowed +# define float float_not_allowed +#endif /*NO_FLOATS*/ + +#ifndef NO_FLOATS + +#ifndef __MWERKS__ +# ifdef __STDC__ +# include +# else +# define FLT_MANT_DIG 24 +# define DBL_MANT_DIG 53 +# endif +#endif + +#endif /*NO_FLOATS*/ + +/* + * The following data types cannot be overridden when building MEX files. + */ +#ifdef MATLAB_MEX_FILE +# undef CHARACTER_T +# undef INTEGER_T +# undef BOOLEAN_T +# undef REAL_T +# undef TIME_T +#endif + +/* + * The uchar_T, ushort_T and ulong_T types are needed for compilers which do + * not allow defines to be specified, at the command line, with spaces in them. + */ + +typedef unsigned char uchar_T; +typedef unsigned short ushort_T; +typedef unsigned long ulong_T; + +#if (defined(_MSC_VER) && _MSC_VER >= 1500) \ + || defined(__x86_64__) || defined(__LP64__) \ + || defined(__LCC64__) + +typedef unsigned long long ulonglong_T; +#endif + + + +/*=======================================================================* + * 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 * + *=======================================================================*/ + +/* When used with Real Time Workshop generated code, this + * header file can be used with a variety of compilers. + * + * The compiler could be for an 8 bit embedded processor that + * only had 8 bits per integer and 16 bits per long. + * In that example, a 32 bit integer size is not even available. + * This header file should be robust to that. + * + * For the case of an 8 bit processor, the preprocessor + * may be limited to 16 bit math like its target. That limitation + * would mean that 32 bit comparisons can't be done accurately. + * To increase robustness to this, comparisons are done against + * smaller values first. An inaccurate 32 bit comparison isn't + * attempted if the 16 bit comparison has already succeeded. + * + * Limitations on preprocessor math can also be stricter than + * for the target. There are known cases where a compiler + * targeting processors with 64 bit longs can't do accurate + * preprocessor comparisons on more than 32 bits. + */ + +/* Determine the number of bits for int, long, short, and char. + * If one fails to be determined, set the number of bits to -1 + */ + +#ifndef TMW_BITS_PER_INT +# if INT_MAX == 0x7FL +# define TMW_BITS_PER_INT 8 +# elif INT_MAX == 0x7FFFL +# define TMW_BITS_PER_INT 16 +# elif INT_MAX == 0x7FFFFFFFL +# define TMW_BITS_PER_INT 32 +# else +# define TMW_BITS_PER_INT -1 +# endif +#endif + +#ifndef TMW_BITS_PER_LONG +# if LONG_MAX == 0x7FL +# define TMW_BITS_PER_LONG 8 +# elif LONG_MAX == 0x7FFFL +# define TMW_BITS_PER_LONG 16 +# elif LONG_MAX == 0x7FFFFFFFL +# define TMW_BITS_PER_LONG 32 +# else +# define TMW_BITS_PER_LONG -1 +# endif +#endif + +#ifndef TMW_BITS_PER_SHRT +# if SHRT_MAX == 0x7FL +# define TMW_BITS_PER_SHRT 8 +# elif SHRT_MAX == 0x7FFFL +# define TMW_BITS_PER_SHRT 16 +# elif SHRT_MAX == 0x7FFFFFFFL +# define TMW_BITS_PER_SHRT 32 +# else +# define TMW_BITS_PER_SHRT -1 +# endif +#endif + +#ifndef TMW_BITS_PER_SCHAR +# if SCHAR_MAX == 0x7FL +# define TMW_BITS_PER_SCHAR 8 +# elif SCHAR_MAX == 0x7FFFL +# define TMW_BITS_PER_SCHAR 16 +# elif SCHAR_MAX == 0x7FFFFFFFL +# define TMW_BITS_PER_SCHAR 32 +# else +# define TMW_BITS_PER_SCHAR -1 +# endif +#endif + +#ifndef TMW_CHAR_SIGNED +# if SCHAR_MAX == CHAR_MAX +# define TMW_CHAR_SIGNED 1 +# else +# define TMW_CHAR_SIGNED 0 +# endif +#endif + +/* It is common for one or more of the integer types + * to be the same size. For example, on many embedded + * processors, both shorts and ints are 16 bits. On + * processors used for workstations, it is quite common + * for both int and long to be 32 bits. + * When there is more than one choice for typdef'ing + * a portable type like int16_T or uint32_T, in + * concept, it should not matter which choice is made. + * However, some style guides and some code checking + * tools do identify and complain about seemingly + * irrelevant differences. For example, a code + * checking tool may complain about an implicit + * conversion from int to short even though both + * are 16 bits. To reduce these types of + * complaints, it is best to make int the + * preferred choice when more than one is available. + */ + +#ifndef INT8_T +# if TMW_BITS_PER_INT == 8 +# define INT8_T int +# elif TMW_BITS_PER_LONG == 8 +# define INT8_T long +# elif TMW_BITS_PER_SCHAR == 8 +# define INT8_T signed char +# elif TMW_BITS_PER_SHRT == 8 +# define INT8_T short +# endif +#endif +#ifdef INT8_T + typedef INT8_T int8_T; +#endif + +#ifndef UINT8_T +# if TMW_BITS_PER_INT == 8 +# define UINT8_T unsigned int +# elif TMW_BITS_PER_LONG == 8 +# define UINT8_T unsigned long +# elif TMW_BITS_PER_SCHAR == 8 +# define UINT8_T unsigned char +# elif TMW_BITS_PER_SHRT == 8 +# define UINT8_T unsigned short +# endif +#endif +#ifdef UINT8_T + typedef UINT8_T uint8_T; +#endif + + +#ifndef INT16_T +# if TMW_BITS_PER_INT == 16 +# define INT16_T int +# elif TMW_BITS_PER_LONG == 16 +# define INT16_T long +# elif TMW_BITS_PER_SCHAR == 16 +# define INT16_T signed char +# elif TMW_BITS_PER_SHRT == 16 +# define INT16_T short +# endif +#endif +#ifdef INT16_T + typedef INT16_T int16_T; +#endif + + +#ifndef UINT16_T +# if TMW_BITS_PER_INT == 16 +# define UINT16_T unsigned int +# elif TMW_BITS_PER_LONG == 16 +# define UINT16_T unsigned long +# elif TMW_BITS_PER_SCHAR == 16 +# define UINT16_T unsigned char +# elif TMW_BITS_PER_SHRT == 16 +# define UINT16_T unsigned short +# endif +#endif +#ifdef UINT16_T + typedef UINT16_T uint16_T; +#endif + + +#ifndef INT32_T +# if TMW_BITS_PER_INT == 32 +# define INT32_T int +# elif TMW_BITS_PER_LONG == 32 +# define INT32_T long +# elif TMW_BITS_PER_SCHAR == 32 +# define INT32_T signed char +# elif TMW_BITS_PER_SHRT == 32 +# define INT32_T short +# endif +#endif +#ifdef INT32_T + typedef INT32_T int32_T; +#endif + + +#ifndef UINT32_T +# if TMW_BITS_PER_INT == 32 +# define UINT32_T unsigned int +# elif TMW_BITS_PER_LONG == 32 +# define UINT32_T unsigned long +# elif TMW_BITS_PER_SCHAR == 32 +# define UINT32_T unsigned char +# elif TMW_BITS_PER_SHRT == 32 +# define UINT32_T unsigned short +# endif +#endif +#ifdef UINT32_T + typedef UINT32_T uint32_T; +#endif + +/* The following is used to emulate smaller integer types when only + * larger types are available. For example, compilers for TI C3x/C4x DSPs + * define char and short to be 32 bits, so 8 and 16 bits are not directly + * available. This target is commonly used with RTW rapid prototyping. + * Other DSPs define char to be 16 bits, so 8 bits is not directly + * available. + */ +#ifndef INT8_T +# ifdef INT16_T +# define INT8_T INT16_T + typedef INT8_T int8_T; +# else +# ifdef INT32_T +# define INT8_T INT32_T + typedef INT8_T int8_T; +# endif +# endif +#endif + +#ifndef UINT8_T +# ifdef UINT16_T +# define UINT8_T UINT16_T + typedef UINT8_T uint8_T; +# else +# ifdef UINT32_T +# define UINT8_T UINT32_T + typedef UINT8_T uint8_T; +# endif +# endif +#endif + +#ifndef INT16_T +# ifdef INT32_T +# define INT16_T INT32_T + typedef INT16_T int16_T; +# endif +#endif + +#ifndef UINT16_T +# ifdef UINT32_T +# define UINT16_T UINT32_T + typedef UINT16_T uint16_T; +# endif +#endif + + +#ifndef NO_FLOATS + +#ifndef REAL32_T +# ifndef __MWERKS__ +# if FLT_MANT_DIG >= 23 +# define REAL32_T float +# endif +# else +# define REAL32_T float +# endif +#endif +#ifdef REAL32_T + typedef REAL32_T real32_T; +#endif + + +#ifndef REAL64_T +# ifndef __MWERKS__ +# if DBL_MANT_DIG >= 52 +# define REAL64_T double +# endif +# else +# define REAL64_T double +# endif +#endif +#ifdef REAL64_T + typedef REAL64_T real64_T; +#endif + +#endif /* NO_FLOATS*/ + +/*=======================================================================* + * Fixed width word size data types: * + * int64_T - signed 64 bit integers * + * uint64_T - unsigned 64 bit integers * + *=======================================================================*/ + + + +#ifndef INT64_T +# if defined(__APPLE__) +# define INT64_T long long +# define FMT64 "ll" +# if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG) +# define INT_TYPE_64_IS_LONG +# endif +# elif defined(__x86_64__) || defined(__LP64__) +# define INT64_T long +# define FMT64 "l" +# if !defined(INT_TYPE_64_IS_LONG) +# define INT_TYPE_64_IS_LONG +# endif +# elif defined(_MSC_VER) || (defined(__BORLANDC__) && __BORLANDC__ >= 0x530) \ + || (defined(__WATCOMC__) && __WATCOMC__ >= 1100) +# define INT64_T __int64 +# define FMT64 "I64" +# elif defined(__GNUC__) || defined(TMW_ENABLE_INT64) \ + || defined(__LCC64__) +# define INT64_T long long +# define FMT64 "ll" +# endif +#endif + + + +#if defined(INT64_T) +# if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >=9))) + __extension__ +# endif + typedef INT64_T int64_T; +#endif + + + +#ifndef UINT64_T +# if defined(__APPLE__) +# define UINT64_T unsigned long long +# define FMT64 "ll" +# if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG) +# define INT_TYPE_64_IS_LONG +# endif +# elif defined(__x86_64__) || defined(__LP64__) +# define UINT64_T unsigned long +# define FMT64 "l" +# if !defined(INT_TYPE_64_IS_LONG) +# define INT_TYPE_64_IS_LONG +# endif +# elif defined(_MSC_VER) || (defined(__BORLANDC__) && __BORLANDC__ >= 0x530) \ + || (defined(__WATCOMC__) && __WATCOMC__ >= 1100) +# define UINT64_T unsigned __int64 +# define FMT64 "I64" +# elif defined(__GNUC__) || defined(TMW_ENABLE_INT64) \ + || defined(__LCC64__) +# define UINT64_T unsigned long long +# define FMT64 "ll" +# endif +#endif + +#if defined(_WIN64) || (defined(__APPLE__) && defined(__LP64__)) \ + || defined(__x86_64__) \ + || defined(__LP64__) +# define INT_TYPE_64_IS_SUPPORTED +#endif + +#if defined(UINT64_T) +# if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >=9))) + __extension__ +# endif + typedef UINT64_T uint64_T; +#endif + +/*===========================================================================* + * Format string modifiers for using size_t variables in printf statements. * + *===========================================================================*/ + +#ifndef FMT_SIZE_T +# if defined( __GNUC__ ) || defined(_STDC_C99) +# define FMT_SIZE_T "z" +# elif defined (__WATCOMC__) +# define FMT_SIZE_T "l" +# elif defined (_WIN32 ) +# define FMT_SIZE_T "I" +# else +# define FMT_SIZE_T "l" +# endif +#endif + +#ifndef FMT_PTRDIFF_T +# if defined(__APPLE__) +# define FMT_PTRDIFF_T "l" +# elif defined( __GNUC__ ) || defined(_STDC_C99) +# define FMT_PTRDIFF_T "t" +# elif defined (__WATCOMC__) +# define FMT_PTRDIFF_T "l" +# elif defined (_WIN32 ) +# define FMT_PTRDIFF_T "I" +# else +# define FMT_PTRDIFF_T "l" +# endif +#endif + +/*===========================================================================* + * General or logical data types where the word size is not guaranteed. * + * real_T - possible settings include real32_T or real64_T * + * time_T - possible settings include real64_T or uint32_T * + * boolean_T * + * char_T * + * int_T * + * uint_T * + * byte_T * + *===========================================================================*/ + +#ifndef NO_FLOATS + +#ifndef REAL_T +# ifdef REAL64_T +# define REAL_T real64_T +# else +# ifdef REAL32_T +# define REAL_T real32_T +# endif +# endif +#endif +#ifdef REAL_T + typedef REAL_T real_T; +#endif + +#ifndef TIME_T +# ifdef REAL_T +# define TIME_T real_T +# endif +#endif +#ifdef TIME_T + typedef TIME_T time_T; +#endif + +#endif /* NO_FLOATS */ + +#ifndef BOOLEAN_T +# if defined(UINT8_T) +# define BOOLEAN_T UINT8_T +# else +# define BOOLEAN_T unsigned int +# endif +#endif +typedef BOOLEAN_T boolean_T; + + +#ifndef CHARACTER_T +# define CHARACTER_T char +#endif +typedef CHARACTER_T char_T; + + +#ifndef INTEGER_T +# define INTEGER_T int +#endif +typedef INTEGER_T int_T; + + +#ifndef UINTEGER_T +# define UINTEGER_T unsigned +#endif +typedef UINTEGER_T uint_T; + + +#ifndef BYTE_T +# define BYTE_T unsigned char +#endif +typedef BYTE_T byte_T; + + +/*===========================================================================* + * Define Complex Structures * + *===========================================================================*/ +#ifndef NO_FLOATS + +#ifndef CREAL32_T +# ifdef REAL32_T + typedef struct { + real32_T re, im; + } creal32_T; +# define CREAL32_T creal32_T +# endif +#endif + +#ifndef CREAL64_T +# ifdef REAL64_T + typedef struct { + real64_T re, im; + } creal64_T; +# define CREAL64_T creal64_T +# endif +#endif + +#ifndef CREAL_T +# ifdef REAL_T + typedef struct { + real_T re, im; + } creal_T; +# define CREAL_T creal_T +# endif +#endif + +#endif /* NO_FLOATS */ + +#ifndef CINT8_T +# ifdef INT8_T + typedef struct { + int8_T re, im; + } cint8_T; +# define CINT8_T cint8_T +# endif +#endif + +#ifndef CUINT8_T +# ifdef UINT8_T + typedef struct { + uint8_T re, im; + } cuint8_T; +# define CUINT8_T cuint8_T +# endif +#endif + +#ifndef CINT16_T +# ifdef INT16_T + typedef struct { + int16_T re, im; + } cint16_T; +# define CINT16_T cint16_T +# endif +#endif + +#ifndef CUINT16_T +# ifdef UINT16_T + typedef struct { + uint16_T re, im; + } cuint16_T; +# define CUINT16_T cuint16_T +# endif +#endif + +#ifndef CINT32_T +# ifdef INT32_T + typedef struct { + int32_T re, im; + } cint32_T; +# define CINT32_T cint32_T +# endif +#endif + +#ifndef CUINT32_T +# ifdef UINT32_T + typedef struct { + uint32_T re, im; + } cuint32_T; +# define CUINT32_T cuint32_T +# endif +#endif + +#ifndef CINT64_T +# ifdef INT64_T + typedef struct { + int64_T re, im; + } cint64_T; +# define CINT64_T cint64_T +# endif +#endif + +#ifndef CUINT64_T +# ifdef UINT64_T + typedef struct { + uint64_T re, im; + } cuint64_T; +# define CUINT64_T cuint64_T +# endif +#endif + +/*=======================================================================* + * 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)) /* 127 */ +#define MIN_int8_T ((int8_T)(-128)) /* -128 */ +#define MAX_uint8_T ((uint8_T)(255)) /* 255 */ +#define MIN_uint8_T ((uint8_T)(0)) + +#define MAX_int16_T ((int16_T)(32767)) /* 32767 */ +#define MIN_int16_T ((int16_T)(-32768)) /* -32768 */ +#define MAX_uint16_T ((uint16_T)(65535)) /* 65535 */ +#define MIN_uint16_T ((uint16_T)(0)) + +#define MAX_int32_T ((int32_T)(2147483647)) /* 2147483647 */ +#define MIN_int32_T ((int32_T)(-2147483647-1)) /* -2147483648 */ +#define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU)) /* 4294967295 */ +#define MIN_uint32_T ((uint32_T)(0)) + +#if defined(_MSC_VER) || (defined(__BORLANDC__) && __BORLANDC__ >= 0x530) \ + || (defined(__WATCOMC__) && __WATCOMC__ >= 1100) \ + || defined(__LCC64__) +# ifdef INT64_T +# define MAX_int64_T ((int64_T)(9223372036854775807LL)) +# define MIN_int64_T ((int64_T)(-9223372036854775807LL-1LL)) +# endif +# ifdef UINT64_T +# define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFULL)) +# define MIN_uint64_T ((uint64_T)(0)) +# endif +#else +# ifdef INT64_T +# ifdef INT_TYPE_64_IS_LONG +# define MAX_int64_T ((int64_T)(9223372036854775807L)) +# define MIN_int64_T ((int64_T)(-9223372036854775807L-1L)) +# else +# define MAX_int64_T ((int64_T)(9223372036854775807LL)) +# define MIN_int64_T ((int64_T)(-9223372036854775807LL-1LL)) +# endif +# endif +# ifdef UINT64_T +# ifdef INT_TYPE_64_IS_LONG +# define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFUL)) +# define MIN_uint64_T ((uint64_T)(0)) +# else +# define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFULL)) +# define MIN_uint64_T ((uint64_T)(0)) +# endif +# endif +#endif + +#ifdef _MSC_VER +/* Conversion from unsigned __int64 to double is not implemented in windows + * and results in a compile error, thus the value must first be cast to + * signed __int64, and then to double. + * + * If the 64 bit int value is greater than 2^63-1, which is the signed int64 max, + * the macro below provides a workaround for casting a uint64 value to a double + * in windows. + */ +# define uint64_to_double(u) ( ((u) > _I64_MAX) ? \ + (double)(__int64)((u) - _I64_MAX - 1) + (double)_I64_MAX + 1: \ + (double)(__int64)(u) ) + +/* The following inline function should only be used in the macro double_to_uint64, + * as it only handles the specfic range of double between 2^63 and 2^64-1 */ +__forceinline +uint64_T double_to_uint64_helper(double d) { + union double_to_uint64_union_type { + double dd; + uint64_T i64; + } di; + di.dd = d; + return (((di.i64 & 0x000fffffffffffff) | 0x0010000000000000) << 11); +} + +/* The largest double value that can be cast to uint64 in windows is the + * signed int64 max, which is 2^63-1. The macro below provides + * a workaround for casting large double values to uint64 in windows. + */ +/* The magic number 18446744073709551616.0 is 2^64 */ +/* The magic number 9223372036854775808.0 is 2^63 */ +# define double_to_uint64(d) ( ((d) >= 18446744073709551616.0) ? \ + 0xffffffffffffffffULL : \ + ((d) < 0.0) ? 0ULL : \ + ((d) >= 9223372036854775808.0) ? \ + double_to_uint64_helper(d) : \ + (unsigned __int64)(d) ) +#else +# define uint64_to_double(u) ((double)(u)) +# if defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__TICCSC__) +/* double_to_uint64 defined only for MSVC and UNIX */ +# else +# define double_to_uint64(d) ( ((d) > 0xffffffffffffffffULL) ? \ + (unsigned long long) 0xffffffffffffffffULL : \ + ((d) < 0) ? (unsigned long long) 0 : (unsigned long long)(d) ) +# endif +#endif + +#if !defined(__cplusplus) && !defined(__bool_true_false_are_defined) + +#ifndef _bool_T +#define _bool_T + +typedef boolean_T bool; + +#ifndef false +#define false (0) +#endif +#ifndef true +#define true (1) +#endif + +#endif /* _bool_T */ + +#endif /* !__cplusplus */ + +/* + * This software assumes that the code is being compiled on a target using a + * 2's complement representation for signed integer values. + */ +#if ((SCHAR_MIN + 1) != -SCHAR_MAX) +#error "This code must be compiled using a 2's complement representation for signed integer values" +#endif + +/* + * Maximum length of a MATLAB identifier (function/variable/model) + * including the null-termination character. + */ +#define TMW_NAME_LENGTH_MAX 64 + +/* + * Maximum values for indices and dimensions + */ +#include + +#ifdef MX_COMPAT_32 +typedef int mwSize; +typedef int mwIndex; +typedef int mwSignedIndex; +#else +typedef size_t mwSize; /* unsigned pointer-width integer */ +typedef size_t mwIndex; /* unsigned pointer-width integer */ +typedef ptrdiff_t mwSignedIndex; /* a signed pointer-width integer */ +#endif + +#if (defined(_LP64) || defined(_WIN64)) && !defined(MX_COMPAT_32) +/* Currently 2^48 based on hardware limitations */ +# define MWSIZE_MAX 281474976710655UL +# define MWINDEX_MAX 281474976710655UL +# define MWSINDEX_MAX 281474976710655L +# define MWSINDEX_MIN -281474976710655L +#else +# define MWSIZE_MAX 2147483647UL +# define MWINDEX_MAX 2147483647UL +# define MWSINDEX_MAX 2147483647L +# define MWSINDEX_MIN -2147483647L +#endif +#define MWSIZE_MIN 0UL +#define MWINDEX_MIN 0UL + +/** UTF-16 character type */ + +#if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) && _HAS_CHAR16_T_LANGUAGE_SUPPORT) +typedef char16_t CHAR16_T; +#elif defined(_MSC_VER) +typedef wchar_t CHAR16_T; +#else +typedef UINT16_T CHAR16_T; +#endif + +#endif /* __TMWTYPES__ */ + +#endif /* tmwtypes_h */ diff --git a/libs/libnyquist/include/libnyquist/Common.h b/libs/libnyquist/include/libnyquist/Common.h new file mode 100644 index 0000000..050f146 --- /dev/null +++ b/libs/libnyquist/include/libnyquist/Common.h @@ -0,0 +1,694 @@ +/* +Copyright (c) 2019, Dimitri Diakopoulos All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef LIBNYQUIST_COMMON_H +#define LIBNYQUIST_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nqr +{ + +///////////////// +// Util Macros // +///////////////// + +#define F_ROUND(x) ((x) > 0 ? (x) + 0.5f : (x) - 0.5f) +#define D_ROUND(x) ((x) > 0 ? (x) + 0.5 : (x) - 0.5) + +#define NO_COPY(C) C(const C &) = delete; C & operator = (const C &) = delete +#define NO_MOVE(C) NO_COPY(C); C(C &&) = delete; C & operator = (const C &&) = delete + +/////////////////////// +// Endian Operations // +/////////////////////// + +#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) + #define CPU_X86 1 +#endif + +#if defined(__arm__) || defined(_M_ARM) + #define CPU_ARM 1 +#endif + +#if defined(CPU_X86) && defined(CPU_ARM) + #error CPU_X86 and CPU_ARM both defined. +#endif + +#if !defined(ARCH_CPU_BIG_ENDIAN) && !defined(ARCH_CPU_LITTLE_ENDIAN) + #if CPU_X86 || CPU_ARM || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + #define ARCH_CPU_LITTLE_ENDIAN + #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + #define ARCH_CPU_BIG_ENDIAN + #else + #error ARCH_CPU_BIG_ENDIAN or ARCH_CPU_LITTLE_ENDIAN should be defined. + #endif +#endif + +#if defined(ARCH_CPU_BIG_ENDIAN) && defined(ARCH_CPU_LITTLE_ENDIAN) + #error ARCH_CPU_BIG_ENDIAN and ARCH_CPU_LITTLE_ENDIAN both defined. +#endif + +static inline uint16_t Swap16(uint16_t value) +{ + return (uint16_t)((value >> 8) | (value << 8)); +} + +static inline uint32_t Swap24(uint32_t value) +{ + return (((value & 0x00ff0000) >> 16) | + ((value & 0x0000ff00)) | + ((value & 0x000000ff) << 16)) & 0x00FFFFFF; +} + +static inline uint32_t Swap32(uint32_t value) +{ + return (((value & 0x000000ff) << 24) | + ((value & 0x0000ff00) << 8) | + ((value & 0x00ff0000) >> 8) | + ((value & 0xff000000) >> 24)); +} + +static inline uint64_t Swap64(uint64_t value) +{ + return (((value & 0x00000000000000ffLL) << 56) | + ((value & 0x000000000000ff00LL) << 40) | + ((value & 0x0000000000ff0000LL) << 24) | + ((value & 0x00000000ff000000LL) << 8) | + ((value & 0x000000ff00000000LL) >> 8) | + ((value & 0x0000ff0000000000LL) >> 24) | + ((value & 0x00ff000000000000LL) >> 40) | + ((value & 0xff00000000000000LL) >> 56)); +} + +template +inline bool isOdd(const T x) +{ + return (x & 0x1); +} + +#ifdef ARCH_CPU_LITTLE_ENDIAN + #define Read16(n) (n) + #define Read24(n) (n) + #define Read32(n) (n) + #define Read64(n) (n) + #define Write16(n) (n) + #define Write24(n) (n) + #define Write32(n) (n) + #define Write64(n) (n) +#else + #define Read16(n) Swap16(n) + #define Read24(n) Swap24(n) + #define Read32(n) Swap32(n) + #define Read64(n) Swap64(n) + #define Write16(n) Swap16(n) + #define Write24(n) Swap24(n) + #define Write32(n) Swap32(n) + #define Write64(n) Swap64(n) +#endif + +inline uint64_t Pack(uint32_t a, uint32_t b) +{ + uint64_t tmp = (uint64_t) b << 32 | (uint64_t) a; +#ifdef ARCH_CPU_LITTLE_ENDIAN + return tmp; +#else + return Swap64(tmp); +#endif +} + +inline uint32_t Pack(uint16_t a, uint16_t b) +{ + uint32_t tmp = (uint32_t) b << 16 | (uint32_t) a; +#ifdef ARCH_CPU_LITTLE_ENDIAN + return tmp; +#else + return Swap32(tmp); +#endif +} + +inline uint16_t Pack(uint8_t a, uint8_t b) +{ + uint16_t tmp = (uint16_t) b << 8 | (uint16_t) a; +#ifdef ARCH_CPU_LITTLE_ENDIAN + return tmp; +#else + return Swap16(tmp); +#endif +} + +// http://www.dsprelated.com/showthread/comp.dsp/136689-1.php +inline int32_t Pack(uint8_t a, uint8_t b, uint8_t c) +{ + // uint32_t tmp = ((c & 0x80) ? (0xFF << 24) : 0x00 << 24) | (c << 16) | (b << 8) | (a << 0); // alternate method + int32_t x = (c << 16) | (b << 8) | (a << 0); + auto sign_extended = (x) | (!!((x) & 0x800000) * 0xff000000); + #ifdef ARCH_CPU_LITTLE_ENDIAN + return sign_extended; + #else + Swap32(sign_extended); + #endif +} + +inline std::array Unpack(uint32_t a) +{ + static std::array output; + + #ifdef ARCH_CPU_LITTLE_ENDIAN + output[0] = a >> 0; + output[1] = a >> 8; + output[2] = a >> 16; + #else + output[0] = a >> 16; + output[1] = a >> 8; + output[2] = a >> 0; + #endif + return output; +} + +////////////////////////// +// Resampling Utilities // +////////////////////////// + +// This is a naieve implementation of a resampling filter where a lerp is used as a bad low-pass. +// It very far from the ideal case and should be used with caution (or not at all) on signals that matter. +// It is included here to upsample 44.1k to 48k for the purposes of microphone input => Opus, where the the +// nominal frequencies of speech are particularly far from Nyquist. +inline void linear_resample(const double rate, const std::vector & input, std::vector & output, const uint32_t samplesToProcess) +{ + double virtualReadIndex = 0; + double a, b, i, sample; + uint32_t n = samplesToProcess - 1; + while (n--) + { + uint32_t readIndex = static_cast(virtualReadIndex); + i = virtualReadIndex - readIndex; + a = input[readIndex + 0]; + b = input[readIndex + 1]; + sample = (1.0 - i) * a + i * b; // linear interpolate + output.push_back(static_cast(sample)); + virtualReadIndex += rate; + } +} + +inline double sample_hermite_4p_3o(double x, double * y) +{ + static double c0, c1, c2, c3; + c0 = y[1]; + c1 = (1.0 / 2.0)*(y[2] - y[0]); + c2 = (y[0] - (5.0 / 2.0)*y[1]) + (2.0*y[2] - (1.0 / 2.0)*y[3]); + c3 = (1.0 / 2.0)*(y[3] - y[0]) + (3.0 / 2.0)*(y[1] - y[2]); + return ((c3*x + c2)*x + c1)*x + c0; +} + +inline void hermite_resample(const double rate, const std::vector & input, std::vector & output, const uint32_t samplesToProcess) +{ + double virtualReadIndex = 1; + double i, sample; + uint32_t n = samplesToProcess - 1; + while (n--) + { + uint32_t readIndex = static_cast(virtualReadIndex); + i = virtualReadIndex - readIndex; + double samps[4] = { input[readIndex - 1], input[readIndex], input[readIndex + 1], input[readIndex + 2] }; + sample = sample_hermite_4p_3o(i, samps); // cubic hermite interpolate over 4 samples + output.push_back(static_cast(sample)); + virtualReadIndex += rate; + } +} + +////////////////////////// +// Conversion Utilities // +////////////////////////// + +enum DitherType +{ + DITHER_NONE, + DITHER_TRIANGLE +}; + +class Dither +{ + std::uniform_real_distribution distribution; + std::mt19937 gen; + float previous; + DitherType d; +public: + + Dither(DitherType d) : distribution(-0.5f, +0.5f), previous(0.f), d(d) {} + + float operator()(float s) + { + if (d == DITHER_TRIANGLE) + { + const float value = distribution(gen); + s = s + value - previous; + previous = value; + return s; + } + else return s; + } +}; + +// Signed maxes, defined for readabilty/convenience +#define NQR_INT16_MAX 32767.f +#define NQR_INT24_MAX 8388608.f +#define NQR_INT32_MAX 2147483648.f + +static const float NQR_BYTE_2_FLT = 1.0f / 127.0f; + +#define int8_to_float32(s) ((float) (s) * NQR_BYTE_2_FLT) +#define uint8_to_float32(s)(((float) (s) - 128) * NQR_BYTE_2_FLT) +#define int16_to_float32(s) ((float) (s) / NQR_INT16_MAX) +#define int24_to_float32(s) ((float) (s) / NQR_INT24_MAX) +#define int32_to_float32(s) ((float) (s) / NQR_INT32_MAX) + +#define float32_to_int8(s) (float) (s * 127.f) +#define float32_to_uint8(s) (float) ((s * 127.f) + 128) +#define float32_to_int16(s) (float) (s * NQR_INT16_MAX) +#define float32_to_int24(s) (float) (s * NQR_INT24_MAX) +#define float32_to_int32(s) (float) (s * NQR_INT32_MAX) + +//@todo add 12, 20 for flac +enum PCMFormat +{ + PCM_U8, + PCM_S8, + PCM_16, + PCM_24, + PCM_32, + PCM_64, + PCM_FLT, + PCM_DBL, + PCM_END +}; + +template T clamp(T a, T mn, T mx) { return std::max(std::min(a, mx), mn); } + +// Src data is aligned to PCMFormat +// @todo normalize? +void ConvertToFloat32(float * dst, const uint8_t * src, const size_t N, PCMFormat f); + +// Src data is always aligned to 4 bytes (WavPack, primarily) +void ConvertToFloat32(float * dst, const int32_t * src, const size_t N, PCMFormat f); + +// Src data is always aligned to 2 bytes (IMA ADPCM, primarily) +void ConvertToFloat32(float * dst, const int16_t * src, const size_t N, PCMFormat f); + +void ConvertFromFloat32(uint8_t * dst, const float * src, const size_t N, PCMFormat f, DitherType t = DITHER_NONE); + +int GetFormatBitsPerSample(PCMFormat f); +PCMFormat MakeFormatForBits(int bits, bool floatingPt, bool isSigned); + +////////////////////////// +// User Data + File Ops // +////////////////////////// + +struct AudioData +{ + int channelCount; + int sampleRate; + double lengthSeconds; + size_t frameSize; // channels * bits per sample + std::vector samples; + PCMFormat sourceFormat; + + //@todo: add field: channel layout + //@todo: add field: lossy / lossless + //@todo: audio data loaded (for metadata only) + //@todo: bitrate (if applicable) + //@todo: original sample rate (if applicable) +}; + +struct StreamableAudioData : public AudioData +{ + //@todo: add field: is this format streamable? + //@todo: hold file handle +}; + +struct NyquistFileBuffer +{ + std::vector buffer; + size_t size; +}; + +NyquistFileBuffer ReadFile(const std::string & pathToFile); + +//////////////////// +// Encoding Utils // +//////////////////// + +struct EncoderParams +{ + int channelCount; + PCMFormat targetFormat; + DitherType dither; +}; + +enum EncoderError +{ + NoError, + InsufficientSampleData, + FileIOError, + UnsupportedSamplerate, + UnsupportedChannelConfiguration, + UnsupportedBitdepth, + UnsupportedChannelMix, + BufferTooBig, +}; + +////////////////////// +// Wav Format Utils // +////////////////////// + +enum WaveFormatCode +{ + FORMAT_UNKNOWN = 0x0, // Unknown Wave Format + FORMAT_PCM = 0x1, // PCM Format + FORMAT_ADPCM = 0x2, // Microsoft ADPCM Format + FORMAT_IEEE = 0x3, // IEEE float/double + FORMAT_ALAW = 0x6, // 8-bit ITU-T G.711 A-law + FORMAT_MULAW = 0x7, // 8-bit ITU-T G.711 µ-law + FORMAT_IMA_ADPCM = 0x11, // IMA ADPCM Format + FORMAT_EXT = 0xFFFE // Set via subformat +}; + +struct RiffChunkHeader +{ + uint32_t id_riff; // Chunk ID: 'RIFF' + uint32_t file_size; // Entire file in bytes + uint32_t id_wave; // Chunk ID: 'WAVE' +}; + +struct WaveChunkHeader +{ + uint32_t fmt_id; // Chunk ID: 'fmt ' + uint32_t chunk_size; // Size in bytes + uint16_t format; // Format code + uint16_t channel_count; // Num interleaved channels + uint32_t sample_rate; // SR + uint32_t data_rate; // Data rate + uint16_t frame_size; // 1 frame = channels * bits per sample (also known as block align) + uint16_t bit_depth; // Bits per sample +}; + +struct BextChunk +{ + uint32_t fmt_id; // Chunk ID: 'bext' + uint32_t chunk_size; // Size in bytes + uint8_t description[256]; // Description of the sound (ascii) + uint8_t origin[32]; // Name of the originator (ascii) + uint8_t origin_ref[32]; // Reference of the originator (ascii) + uint8_t orgin_date[10]; // yyyy-mm-dd (ascii) + uint8_t origin_time[8]; // hh-mm-ss (ascii) + uint64_t time_ref; // First sample count since midnight + uint32_t version; // Version of the BWF + uint8_t uimd[64]; // Byte 0 of SMPTE UMID + uint8_t reserved[188]; // 190 bytes, reserved for future use & set to NULL +}; + +struct FactChunk +{ + uint32_t fact_id; // Chunk ID: 'fact' + uint32_t chunk_size; // Size in bytes + uint32_t sample_length; // number of samples per channel +}; + +struct ExtensibleData +{ + uint16_t size; + uint16_t valid_bits_per_sample; + uint32_t channel_mask; + struct GUID + { + uint32_t data0; + uint16_t data1; + uint16_t data2; + uint16_t data3; + uint8_t data4[6]; + }; +}; + +template +std::basic_ostream & operator << (std::basic_ostream & a, const WaveChunkHeader & b) +{ + return a << + "Format ID:\t\t" << b.fmt_id << + "\nChunk Size:\t\t" << b.chunk_size << + "\nFormat Code:\t\t" << b.format << + "\nChannels:\t\t" << b.channel_count << + "\nSample Rate:\t\t" << b.sample_rate << + "\nData Rate:\t\t" << b.data_rate << + "\nFrame Size:\t\t" << b.frame_size << + "\nBit Depth:\t\t" << b.bit_depth << std::endl; +} + +//@todo expose speaker/channel/layout masks in the API: + +enum SpeakerChannelMask +{ + SPEAKER_FRONT_LEFT = 0x00000001, + SPEAKER_FRONT_RIGHT = 0x00000002, + SPEAKER_FRONT_CENTER = 0x00000004, + SPEAKER_LOW_FREQUENCY = 0x00000008, + SPEAKER_BACK_LEFT = 0x00000010, + SPEAKER_BACK_RIGHT = 0x00000020, + SPEAKER_FRONT_LEFT_OF_CENTER = 0x00000040, + SPEAKER_FRONT_RIGHT_OF_CENTER = 0x00000080, + SPEAKER_BACK_CENTER = 0x00000100, + SPEAKER_SIDE_LEFT = 0x00000200, + SPEAKER_SIDE_RIGHT = 0x00000400, + SPEAKER_TOP_CENTER = 0x00000800, + SPEAKER_TOP_FRONT_LEFT = 0x00001000, + SPEAKER_TOP_FRONT_CENTER = 0x00002000, + SPEAKER_TOP_FRONT_RIGHT = 0x00004000, + SPEAKER_TOP_BACK_LEFT = 0x00008000, + SPEAKER_TOP_BACK_CENTER = 0x00010000, + SPEAKER_TOP_BACK_RIGHT = 0x00020000, + SPEAKER_RESERVED = 0x7FFC0000, + SPEAKER_ALL = 0x80000000 +}; + +enum SpeakerLayoutMask +{ + SPEAKER_MONO = (SPEAKER_FRONT_CENTER), + SPEAKER_STEREO = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT), + SPEAKER_2POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY), + SPEAKER_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER), + SPEAKER_QUAD = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT), + SPEAKER_4POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT), + SPEAKER_5POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT), + SPEAKER_7POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER), + SPEAKER_5POINT1_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT), + SPEAKER_7POINT1_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT), +}; + +//@todo verify mask values +inline int ComputeChannelMask(const size_t channels) +{ + switch (channels) + { + case 1: return SPEAKER_MONO; + case 2: return SPEAKER_STEREO; + case 3: return SPEAKER_2POINT1; + case 4: return SPEAKER_QUAD; + case 5: return SPEAKER_4POINT1; + case 6: return SPEAKER_5POINT1; + default: return -1; + } +} + +///////////////////// +// Chunk utilities // +///////////////////// + +struct ChunkHeaderInfo +{ + uint32_t offset; // Byte offset into chunk + uint32_t size; // Size of the chunk in bytes +}; + +inline uint32_t GenerateChunkCode(uint8_t a, uint8_t b, uint8_t c, uint8_t d) +{ +#ifdef ARCH_CPU_LITTLE_ENDIAN + return ((uint32_t)((a) | ((b) << 8) | ((c) << 16) | (((uint32_t)(d)) << 24))); +#else + return ((uint32_t)((((uint32_t)(a)) << 24) | ((b) << 16) | ((c) << 8) | (d))); +#endif +} + +inline char * GenerateChunkCodeChar(uint8_t a, uint8_t b, uint8_t c, uint8_t d) +{ + auto chunk = GenerateChunkCode(a, b, c, d); + + char * outArr = new char[4]; + + uint32_t t = 0x000000FF; + + for (size_t i = 0; i < 4; i++) + { + outArr[i] = chunk & t; + chunk >>= 8; + } + return outArr; +} + +inline ChunkHeaderInfo ScanForChunk(const std::vector & fileData, uint32_t chunkMarker) +{ + // D[n] aligned to 16 bytes now + const uint16_t * d = reinterpret_cast(fileData.data()); + + for (size_t i = 0; i < fileData.size() / sizeof(uint16_t); i++) + { + // This will be in machine endianess + uint32_t m = Pack(Read16(d[i]), Read16(d[i + 1])); + + if (m == chunkMarker) + { + uint32_t cSz = Pack(Read16(d[i + 2]), Read16(d[i + 3])); + return { (uint32_t(i * sizeof(uint16_t))), cSz }; // return i in bytes to the start of the data + } + else continue; + } + return { 0, 0 }; +}; + +inline WaveChunkHeader MakeWaveHeader(const EncoderParams param, const int sampleRate) +{ + WaveChunkHeader header; + + int bitdepth = GetFormatBitsPerSample(param.targetFormat); + + header.fmt_id = GenerateChunkCode('f', 'm', 't', ' '); + header.chunk_size = 16; + header.format = (param.targetFormat <= PCMFormat::PCM_32) ? WaveFormatCode::FORMAT_PCM : WaveFormatCode::FORMAT_IEEE; + header.channel_count = param.channelCount; + header.sample_rate = sampleRate; + header.data_rate = sampleRate * param.channelCount * (bitdepth / 8); + header.frame_size = param.channelCount * (bitdepth / 8); + header.bit_depth = bitdepth; + + return header; +} + +// @todo expose this in the FLAC API +inline std::map GetFlacQualityTable() +{ + return { + { 0, "0 (Fastest)" }, + { 1, "1" }, + { 2, "2" }, + { 3, "3" }, + { 4, "4" }, + { 5, "5 (Default)" }, + { 6, "6" }, + { 7, "7" }, + { 8, "8 (Highest)" }, + }; +} + +template +inline void DeinterleaveStereo(T * c1, T * c2, T const * src, size_t count) +{ + auto src_end = src + count; + while (src != src_end) + { + *c1 = src[0]; + *c2 = src[1]; + c1++; + c2++; + src += 2; + } +} + +template +void InterleaveChannels(const T * src, T * dest, size_t numFramesPerChannel, size_t numChannels, size_t N) +{ + for (size_t ch = 0; ch < numChannels; ch++) + { + size_t x = ch; + const T * srcChannel = &src[ch * numFramesPerChannel]; + for (size_t i = 0; i < N; i++) + { + dest[x] = srcChannel[i]; + x += numChannels; + } + } +} + +template +void DeinterleaveChannels(const T * src, T * dest, size_t numFramesPerChannel, size_t numChannels, size_t N) +{ + for (size_t ch = 0; ch < numChannels; ch++) + { + size_t x = ch; + T *destChannel = &dest[ch * numFramesPerChannel]; + for (size_t i = 0; i < N; i++) + { + destChannel[i] = (T)src[x]; + x += numChannels; + } + } +} + +template +void StereoToMono(const T * src, T * dest, size_t N) +{ + for (size_t i = 0, j = 0; i < N; i += 2, ++j) + { + dest[j] = (src[i] + src[i + 1]) / 2.0f; + } +} + +template +void MonoToStereo(const T * src, T * dest, size_t N) +{ + for (size_t i = 0, j = 0; i < N; ++i, j += 2) + { + dest[j] = src[i]; + dest[j + 1] = src[i]; + } +} + +inline void TrimSilenceInterleaved(std::vector & buffer, float v, bool fromFront, bool fromEnd) +{ + //@todo implement me! +} + +} // end namespace nqr + +#endif diff --git a/libs/libnyquist/include/libnyquist/Decoders.h b/libs/libnyquist/include/libnyquist/Decoders.h new file mode 100644 index 0000000..7998869 --- /dev/null +++ b/libs/libnyquist/include/libnyquist/Decoders.h @@ -0,0 +1,136 @@ +/* +Copyright (c) 2019, Dimitri Diakopoulos All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef AUDIO_DECODER_H +#define AUDIO_DECODER_H + +#include "Common.h" +#include +#include +#include +#include + +namespace nqr +{ + struct BaseDecoder + { + virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) = 0; + virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector & memory) = 0; + virtual std::vector GetSupportedFileExtensions() = 0; + virtual ~BaseDecoder() {} + }; + + typedef std::pair< std::string, std::shared_ptr > DecoderPair; + + class NyquistIO + { + std::string ParsePathForExtension(const std::string & path) const; + std::shared_ptr GetDecoderForExtension(const std::string & ext); + void BuildDecoderTable(); + void AddDecoderToTable(std::shared_ptr decoder); + std::map< std::string, std::shared_ptr > decoderTable; + + NO_MOVE(NyquistIO); + + public: + + NyquistIO(); + ~NyquistIO(); + void Load(AudioData * data, const std::string & path); + void Load(AudioData * data, const std::vector & buffer); + void Load(AudioData * data, const std::string & extension, const std::vector & buffer); + bool IsFileSupported(const std::string & path) const; + }; + + struct UnsupportedExtensionEx : public std::runtime_error { UnsupportedExtensionEx() : std::runtime_error("Unsupported file extension") {} }; + struct LoadPathNotImplEx : public std::runtime_error { LoadPathNotImplEx() : std::runtime_error("Loading from path not implemented") {} }; + struct LoadBufferNotImplEx : public std::runtime_error { LoadBufferNotImplEx() : std::runtime_error("Loading from buffer not implemented") {} }; + + struct WavDecoder final : public nqr::BaseDecoder + { + WavDecoder() = default; + virtual ~WavDecoder() {} + virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final; + virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector & memory) override final; + virtual std::vector GetSupportedFileExtensions() override final; + }; + + struct WavPackDecoder final : public nqr::BaseDecoder + { + WavPackDecoder() = default; + virtual ~WavPackDecoder() override {}; + virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final; + virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector & memory) override final; + virtual std::vector GetSupportedFileExtensions() override final; + }; + + struct VorbisDecoder final : public nqr::BaseDecoder + { + VorbisDecoder() = default; + virtual ~VorbisDecoder() override {} + virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final; + virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector & memory) override final; + virtual std::vector GetSupportedFileExtensions() override final; + }; + + struct OpusDecoder final : public nqr::BaseDecoder + { + OpusDecoder() = default; + virtual ~OpusDecoder() override {} + virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final; + virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector & memory) override final; + virtual std::vector GetSupportedFileExtensions() override final; + }; + + struct MusepackDecoder final : public nqr::BaseDecoder + { + MusepackDecoder() = default; + virtual ~MusepackDecoder() override {}; + virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final; + virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector & memory) override final; + virtual std::vector GetSupportedFileExtensions() override final; + }; + + struct Mp3Decoder final : public nqr::BaseDecoder + { + Mp3Decoder() = default; + virtual ~Mp3Decoder() override {}; + virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final; + virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector & memory) override final; + virtual std::vector GetSupportedFileExtensions() override final; + }; + + struct FlacDecoder final : public nqr::BaseDecoder + { + FlacDecoder() = default; + virtual ~FlacDecoder() override {} + virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final; + virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector & memory) override final; + virtual std::vector GetSupportedFileExtensions() override final; + }; + +} // end namespace nqr + +#endif diff --git a/libs/libnyquist/include/libnyquist/Encoders.h b/libs/libnyquist/include/libnyquist/Encoders.h new file mode 100644 index 0000000..f9fb9ff --- /dev/null +++ b/libs/libnyquist/include/libnyquist/Encoders.h @@ -0,0 +1,44 @@ +/* +Copyright (c) 2019, Dimitri Diakopoulos All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef NYQUIST_ENCODERS_H +#define NYQUIST_ENCODERS_H + +#include "Common.h" + +namespace nqr +{ + // A simplistic encoder that takes a buffer of audio, conforms it to the user's + // EncoderParams preference, and writes to disk. Be warned, does not support resampling! + // @todo support dithering, samplerate conversion, etc. + int encode_wav_to_disk(const EncoderParams p, const AudioData * d, const std::string & path); + + // Assume data adheres to EncoderParams, except for bit depth and fmt which are re-formatted + // to satisfy the Ogg/Opus spec. + int encode_opus_to_disk(const EncoderParams p, const AudioData * d, const std::string & path); + +} // end namespace nqr + +#endif // end NYQUIST_ENCODERS_H diff --git a/libs/libnyquist/lib-macx/liblibnyquist.a b/libs/libnyquist/lib-macx/liblibnyquist.a new file mode 100644 index 0000000..8e68fb6 Binary files /dev/null and b/libs/libnyquist/lib-macx/liblibnyquist.a differ diff --git a/libs/libnyquist/lib-macx/liblibwavpack.a b/libs/libnyquist/lib-macx/liblibwavpack.a new file mode 100644 index 0000000..08fba41 Binary files /dev/null and b/libs/libnyquist/lib-macx/liblibwavpack.a differ diff --git a/source/PA_Calculator.pro b/source/PA_Calculator.pro index d253dbc..ea4aac2 100644 --- a/source/PA_Calculator.pro +++ b/source/PA_Calculator.pro @@ -14,7 +14,9 @@ SOURCES += \ camp.cpp \ campmode.cpp \ cdac.cpp \ + csong.cpp \ cspeaker.cpp \ + delegatepathitem.cpp \ library.cpp \ main.cpp \ mainwindow.cpp @@ -25,7 +27,9 @@ HEADERS += \ camp.h \ campmode.h \ cdac.h \ + csong.h \ cspeaker.h \ + delegatepathitem.h \ library.h \ mainwindow.h @@ -56,7 +60,7 @@ RESOURCES += \ VERSION=1.1.0 QMAKE_TARGET_PRODUCT = "PA-Calculator" QMAKE_TARGET_COMPANY = "Alexander Diamadis" -QMAKE_TARGET_COPYRIGHT = "Copyright (c) 2021 by Alexander Diamadis (alex@dkm-tech.de)" +QMAKE_TARGET_COPYRIGHT = "Copyright (c) 2022 by Alexander Diamadis" win32 { commit = $$system("FOR /F \"tokens=*\" %H IN ('git rev-parse --short HEAD') DO @SET /A DECIMAL=0x%H") @@ -71,4 +75,30 @@ DEFINES += APP_VERSION=\"\\\"$${VERSION}\\\"\" \ APP_COMMIT=\"\\\"$${commit}\\\"\" \ APP_COPYRIGHT=\"\\\"$${QMAKE_TARGET_COPYRIGHT}\\\"\" +# Library Libnyquist + +macx: LIBS += -L$$PWD/../libs/libnyquist/lib-macx/ -llibnyquist + +INCLUDEPATH += $$PWD/../libs/libnyquist/include +DEPENDPATH += $$PWD/../libs/libnyquist/include + +macx: PRE_TARGETDEPS += $$PWD/../libs/libnyquist/lib-macx/liblibnyquist.a + + +macx: LIBS += -L$$PWD/../libs/libnyquist/lib-macx/ -llibwavpack + +INCLUDEPATH += $$PWD/../libs/libnyquist/include +DEPENDPATH += $$PWD/../libs/libnyquist/include + +macx: PRE_TARGETDEPS += $$PWD/../libs/libnyquist/lib-macx/liblibwavpack.a + +# Library getLoudness + + +macx: LIBS += -L$$PWD/../libs/getLoudness/macx/ -lgetLoudness + +macx: INCLUDEPATH += $$PWD/../libs/getLoudness/macx +macx: DEPENDPATH += $$PWD/../libs/getLoudness/macx + +macx: PRE_TARGETDEPS += $$PWD/../libs/getLoudness/macx/libgetLoudness.a diff --git a/source/about.ui b/source/about.ui index 58ce7d6..8491d32 100644 --- a/source/about.ui +++ b/source/about.ui @@ -136,7 +136,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'.AppleSystemUIFont'; font-size:7pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#ffffff;"><a name="license-text"></a><span style=" font-family:'Consolas','Monaco','Courier','monospace'; font-size:8pt; color:#5c5855; background-color:#ffffff;">T</span><span style=" font-family:'Consolas','Monaco','Courier','monospace'; font-size:8pt; color:#5c5855; background-color:#ffffff;">his program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Consolas','Monaco','Courier','monospace'; font-size:8pt; color:#5c5855; background-color:#ffffff;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#ffffff;"><span style=" font-family:'Consolas','Monaco','Courier','monospace'; font-size:8pt; color:#5c5855; background-color:#ffffff;">This program 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 General Public License for more details.</span></p> diff --git a/source/analyzer.cpp b/source/analyzer.cpp index c22bed7..73149ec 100644 --- a/source/analyzer.cpp +++ b/source/analyzer.cpp @@ -5,17 +5,29 @@ #include #include #include +#include +#include +#include "delegatepathitem.h" analyzer::analyzer(QWidget *parent) : QDialog(parent), ui(new Ui::analyzer) { ui->setupUi(this); + countSongs=0; + firstAnalysisDone=false; + + ui->tableWidget->setHorizontalHeaderLabels(QStringList() << "Filename"<<"Loudness in dBFS"<<"Peaklevel in dBFS"<<"corrected peak in dBFS"<<"required Correction"); + ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + ui->tableWidget->horizontalHeader()->setSectionResizeMode(0,QHeaderView::Stretch); } analyzer::~analyzer() { delete ui; + if (countSongs>0){ + delete [] songList; + } } void analyzer::on_pushButton_clicked() @@ -27,13 +39,56 @@ void analyzer::on_pushButton_clicked() void analyzer::on_pushButton_calculate_clicked() { - QDirIterator it(ui->lineEdit_path->text(), QStringList() << "*.mp3", QDir::NoFilter, QDirIterator::Subdirectories); - //while (it.hasNext()) { - QFileInfo f(it.next()); - CAudioSource src; - - src.decode(f.absoluteFilePath()); + ui->pushButton_calculate->setDisabled(true); + ui->doubleSpinBox_preferredLoudness->setDisabled(true); + if (countSongs>0){ + delete [] songList; + } + countSongs=0; + QDirIterator it_counter(ui->lineEdit_path->text(), {"*.mp3", "*.wav", "*.flac", "*.ogg"}, QDir::NoFilter, QDirIterator::Subdirectories); + while (it_counter.next()!="") { + countSongs+=1; + } + QDirIterator it(ui->lineEdit_path->text(), {"*.mp3", "*.wav"}, QDir::NoFilter, QDirIterator::Subdirectories); + unsigned int k=0; + songList=new csong[countSongs]; + float preferedLoudness=ui->doubleSpinBox_preferredLoudness->value(); + ui->label_progress->setText(QString("0 of ")+QString::number(countSongs)+QString(" songs analyzed")); + ui->progressBar->setMaximum(countSongs); + while (it.hasNext()) { + QFileInfo f(it.next()); + songList[k].setPath(f.absoluteFilePath()); + songList[k].analyze(preferedLoudness); + k++; + ui->progressBar->setValue(k); + ui->label_progress->setText(QString::number(k)+QString(" of ")+QString::number(countSongs)+QString(" songs analyzed")); + QApplication::processEvents(); + } + ui->label_progress->setText(QString("done")); + ui->tableWidget->setSortingEnabled(false); + ui->tableWidget->setRowCount(countSongs); + for (unsigned int i=0;itableWidget->setItem(i,k,&songList[i].m_widgetItem[k]); + } + } + ui->tableWidget->setItemDelegateForColumn(0, new DelegatePathItem); + ui->pushButton_calculate->setDisabled(false); + ui->doubleSpinBox_preferredLoudness->setDisabled(false); + ui->tableWidget->setSortingEnabled(true); + ui->tableWidget->sortItems(0); + firstAnalysisDone=true; } + +void analyzer::on_doubleSpinBox_preferredLoudness_valueChanged(double arg1) +{ + if (firstAnalysisDone){ + for (unsigned int i=0; i -#include +#include +#include "csong.h" namespace Ui { class analyzer; @@ -22,8 +23,15 @@ private slots: void on_pushButton_calculate_clicked(); + + + void on_doubleSpinBox_preferredLoudness_valueChanged(double arg1); + private: Ui::analyzer *ui; + csong * songList; + unsigned int countSongs; + bool firstAnalysisDone; }; #endif // ANALYZER_H diff --git a/source/analyzer.ui b/source/analyzer.ui index af81e8f..d1ab8e2 100644 --- a/source/analyzer.ui +++ b/source/analyzer.ui @@ -6,16 +6,25 @@ 0 0 - 432 - 141 + 836 + 658 - Dialog + Loudness Analyzer - + + + QLayout::SetDefaultConstraint + + + QFormLayout::ExpandingFieldsGrow + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + @@ -24,45 +33,36 @@ - - - - 0 - 0 - - - - C:/Users/fsx12/Downloads/Zeugnisverleihung - - + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + Browse + + + + - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 0 - 0 - - - - Browse - - - - Qt::LeftToRight @@ -72,34 +72,94 @@ - - - - dBFS - - - 1 - - - -100.000000000000000 - - - 0.000000000000000 - - - -18.000000000000000 - - - - + Calculate + + + + + + + 0 + 0 + + + + 0 + + + + + + + + 0 + 0 + + + + ready + + + + + + + + + + + dBFS + + + 1 + + + -100.000000000000000 + + + 0.000000000000000 + + + -18.000000000000000 + + + + + + + + + + + + + + + + Qt::ElideLeft + + + 1 + + + 5 + + + + + + + + + diff --git a/source/csong.cpp b/source/csong.cpp new file mode 100644 index 0000000..c76c1b5 --- /dev/null +++ b/source/csong.cpp @@ -0,0 +1,138 @@ +#include "csong.h" +#include + +#include "getLoudness.h" +#include "getLoudness_terminate.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include +csong::csong() +{ + m_path=""; + m_loudness=0; + m_peakLevel=0; + m_widgetItem=new QTableWidgetItem[5]; + setWidgetProperties(); +} + +csong::csong(QString path) +{ + m_path=path; + m_widgetItem=new QTableWidgetItem[5]; + setWidgetProperties(); +} + +csong::~csong() +{ + delete [] m_widgetItem; +} + +void csong::analyze(float preferedLoudness) +{ + using namespace nqr; + + NyquistIO loader; + + std::shared_ptr fileData = std::make_shared(); + auto memory= ReadFile(m_path.toStdString()); + QFileInfo fi(m_path); + loader.Load(fileData.get(),fi.suffix().toStdString(),memory.buffer); + + + coder::array loudness; + loudness.set_size(1,1); + coder::array data; + data.set_size(fileData->samples.size()/2,fileData->channelCount); + for (int idx0{0}; idx0 < data.size(0); idx0++) { + for (int idx1{0}; idx1 < data.size(1); idx1++) { + data[idx0 + data.size(0) * idx1] = fileData->samples[idx1+data.size(1)*idx0]; + } + } + getLoudness(data,fileData->sampleRate,loudness); + getLoudness_terminate(); + m_loudness=loudness[0]; + m_widgetItem[1].setText(QString::number(m_loudness)); + + + m_peakLevel=0; + for (unsigned int i=0;isamples.size();i++){ + if (abs(fileData->samples[i])>m_peakLevel){ + m_peakLevel=abs(fileData->samples[i]); + } + } + m_peakLevel=linToDb(m_peakLevel); + if (m_peakLevel>0){ + m_peakLevel=0; + } + m_widgetItem[2].setText(QString::number(m_peakLevel)); + + m_correction=preferedLoudness-m_loudness; + m_widgetItem[4].setText(QString::number(m_correction)); + + m_correctedPeakLevel=m_peakLevel+m_correction; + m_widgetItem[3].setText(QString::number(m_correctedPeakLevel)); + if (m_correctedPeakLevel>0){ + m_widgetItem[3].setBackground(Qt::red); + }else { + m_widgetItem[3].setBackground(Qt::white); + } +} + +void csong::setNewPreferedLoudness(float preferedLoudness) +{ + m_correction=preferedLoudness-m_loudness; + m_widgetItem[4].setText(QString::number(m_correction)); + + m_correctedPeakLevel=m_peakLevel+m_correction; + m_widgetItem[3].setText(QString::number(m_correctedPeakLevel)); + if (m_correctedPeakLevel>0){ + m_widgetItem[3].setBackground(Qt::red); + }else { + m_widgetItem[3].setBackground(Qt::white); + } +} + +void csong::setPath(QString path) +{ + m_path=path; + m_widgetItem[0].setText(m_path); +} + +float csong::get_PeakLevel() const +{ + return m_peakLevel; +} + +float csong::get_Loudness() const +{ + return m_loudness; +} + +float csong::get_correctedPeakLevel() const +{ + return m_correctedPeakLevel; +} + +float csong::get_correction() const +{ + return m_correction; +} + + +float csong::linToDb(float linValue) +{ + return 20*std::log10f(linValue); +} + +void csong::setWidgetProperties() +{ + for (int i=0;i<5;i++){ + m_widgetItem[i].setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + m_widgetItem[i].setTextAlignment(Qt::AlignCenter); + } + m_widgetItem[0].setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); +} + +QString csong::get_path() const{ + return m_path; +} diff --git a/source/csong.h b/source/csong.h new file mode 100644 index 0000000..eff6af0 --- /dev/null +++ b/source/csong.h @@ -0,0 +1,40 @@ +#ifndef CSONG_H +#define CSONG_H + +#include +#include + +#include "libnyquist/Decoders.h" + +#include "rtwtypes.h" +#include +#include + + +class csong +{ +public: + csong(); + csong(QString path); + ~csong(); + void analyze(float preferedLoudness); + void setNewPreferedLoudness(float preferedLoudness); + void setPath(QString path); + QString get_path() const; + float get_PeakLevel() const; + float get_Loudness() const; + float get_correctedPeakLevel() const; + float get_correction() const; + float requiredCorrection; + float linToDb(float linValue); + QTableWidgetItem* m_widgetItem; +private: + float m_peakLevel; + float m_loudness; + float m_correctedPeakLevel; + float m_correction; + QString m_path; + void setWidgetProperties(); +}; + +#endif // CSONG_H diff --git a/source/delegatepathitem.cpp b/source/delegatepathitem.cpp new file mode 100644 index 0000000..16ea18e --- /dev/null +++ b/source/delegatepathitem.cpp @@ -0,0 +1,28 @@ +#include "delegatepathitem.h" +#include +#include + +void DelegatePathItem::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const + { + if (!index.isValid()) + return; + + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + int padding = 3; + + painter->save(); + painter->setClipRect(opt.rect); + opt.rect = opt.rect.adjusted(padding, padding, -padding, -padding); + painter->drawText(opt.rect, Qt::AlignLeft | Qt::AlignVCenter, + opt.fontMetrics.elidedText(opt.text, Qt::ElideLeft, + opt.rect.width())); + painter->restore(); + + opt.rect = option.rect; + opt.textElideMode = Qt::ElideLeft; + opt.text = ""; + + QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter); + } diff --git a/source/delegatepathitem.h b/source/delegatepathitem.h new file mode 100644 index 0000000..d8486bc --- /dev/null +++ b/source/delegatepathitem.h @@ -0,0 +1,13 @@ +#ifndef DELEGATEPATHITEM_H +#define DELEGATEPATHITEM_H + +#include + +class DelegatePathItem : public QStyledItemDelegate +{ +public: + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; +}; + +#endif // DELEGATEPATHITEM_H diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index ce28665..7cb8f2d 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -30,9 +30,6 @@ MainWindow::MainWindow(QWidget *parent) refreshLibraryAmpModes(); refreshLibrarySpeaker(); refreshLibraryDacs(); - - analyzer analyzerWindow; - analyzerWindow.exec(); } MainWindow::~MainWindow()