Skip to content

Commit

Permalink
Merge pull request #56 from sp-nitech/alaw
Browse files Browse the repository at this point in the history
Add alaw
  • Loading branch information
takenori-y committed Jan 18, 2024
2 parents a7ad25f + 70c45cd commit e77cf86
Show file tree
Hide file tree
Showing 19 changed files with 780 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ set(CC_SOURCES
${SOURCE_DIR}/check/line_spectral_pairs_stability_check.cc
${SOURCE_DIR}/check/linear_predictive_coefficients_stability_check.cc
${SOURCE_DIR}/check/mlsa_digital_filter_stability_check.cc
${SOURCE_DIR}/compression/a_law_compression.cc
${SOURCE_DIR}/compression/a_law_expansion.cc
${SOURCE_DIR}/compression/dynamic_range_compression.cc
${SOURCE_DIR}/compression/huffman_coding.cc
${SOURCE_DIR}/compression/huffman_decoding.cc
Expand Down Expand Up @@ -262,6 +264,7 @@ set(MAIN_SOURCES
${SOURCE_DIR}/main/acorr.cc
${SOURCE_DIR}/main/acr2csm.cc
${SOURCE_DIR}/main/aeq.cc
${SOURCE_DIR}/main/alaw.cc
${SOURCE_DIR}/main/amgcep.cc
${SOURCE_DIR}/main/ap.cc
${SOURCE_DIR}/main/average.cc
Expand Down Expand Up @@ -305,6 +308,7 @@ set(MAIN_SOURCES
${SOURCE_DIR}/main/huffman.cc
${SOURCE_DIR}/main/huffman_decode.cc
${SOURCE_DIR}/main/huffman_encode.cc
${SOURCE_DIR}/main/ialaw.cc
${SOURCE_DIR}/main/idct.cc
${SOURCE_DIR}/main/ifft.cc
${SOURCE_DIR}/main/ifft2.cc
Expand Down
11 changes: 11 additions & 0 deletions doc/main/alaw.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.. _alaw:

alaw
====

.. doxygenfile:: alaw.cc

.. seealso:: :ref:`ialaw` :ref:`ulaw`

.. doxygenclass:: sptk::ALawCompression
:members:
11 changes: 11 additions & 0 deletions doc/main/ialaw.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.. _ialaw:

ialaw
=====

.. doxygenfile:: ialaw.cc

.. seealso:: :ref:`alaw` :ref:`iulaw`

.. doxygenclass:: sptk::ALawExpansion
:members:
2 changes: 1 addition & 1 deletion doc/main/iulaw.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ iulaw

.. doxygenfile:: iulaw.cc

.. seealso:: :ref:`ulaw`
.. seealso:: :ref:`ulaw` :ref:`ialaw`

.. doxygenclass:: sptk::MuLawExpansion
:members:
2 changes: 1 addition & 1 deletion doc/main/ulaw.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ulaw

.. doxygenfile:: ulaw.cc

.. seealso:: :ref:`iulaw`
.. seealso:: :ref:`iulaw` :ref:`alaw`

.. doxygenclass:: sptk::MuLawCompression
:members:
96 changes: 96 additions & 0 deletions include/SPTK/compression/a_law_compression.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// ------------------------------------------------------------------------ //
// Copyright 2021 SPTK Working Group //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
// You may obtain a copy of the License at //
// //
// http://www.apache.org/licenses/LICENSE-2.0 //
// //
// Unless required by applicable law or agreed to in writing, software //
// distributed under the License is distributed on an "AS IS" BASIS, //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and //
// limitations under the License. //
// ------------------------------------------------------------------------ //

#ifndef SPTK_COMPRESSION_A_LAW_COMPRESSION_H_
#define SPTK_COMPRESSION_A_LAW_COMPRESSION_H_

#include "SPTK/utils/sptk_utils.h"

namespace sptk {

/**
* Nonlinearly compress data based on A-law algorithm.
*
* Given the input data @f$x(n)@f$, the compression is performed as follows:
* @f[
* y(n) = V \, \mathrm{sgn}(x(n)) \left\{ \begin{array}{ll}
* \frac{A \frac{|x(n)|}{V}}{1 + \log A}, &
* \frac{|x(n)|}{V} < \frac{1}{A} \\
* \frac{1 + \log(A \frac{|x(n)|}{V})}{1 + \log A}, &
* \frac{|x(n)|}{V} \ge \frac{1}{A}
* \end{array} \right.
* @f]
* where @f$V@f$ is the absolute maximum value of the input data and @f$A@f$
* is the compression factor, which is typically set to 87.6.
*/
class ALawCompression {
public:
/**
* @param[in] abs_max_value Absolute maximum value.
* @param[in] compression_factor Compression factor, @f$A@f$.
*/
ALawCompression(double abs_max_value, double compression_factor);

virtual ~ALawCompression() {
}

/**
* @return Absolute maximum value.
*/
double GetAbsMaxValue() const {
return abs_max_value_;
}

/**
* @return Compression factor.
*/
double GetCompressionFactor() const {
return compression_factor_;
}

/**
* @return True if this object is valid.
*/
bool IsValid() const {
return is_valid_;
}

/**
* @param[in] input Input data.
* @param[out] output Output data.
* @return True on success, false on failure.
*/
bool Run(double input, double* output) const;

/**
* @param[in,out] input_and_output Input/output data.
* @return True on success, false on failure.
*/
bool Run(double* input_and_output) const;

private:
const double abs_max_value_;
const double compression_factor_;
const double constant_;

bool is_valid_;

DISALLOW_COPY_AND_ASSIGN(ALawCompression);
};

} // namespace sptk

#endif // SPTK_COMPRESSION_A_LAW_COMPRESSION_H_
96 changes: 96 additions & 0 deletions include/SPTK/compression/a_law_expansion.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// ------------------------------------------------------------------------ //
// Copyright 2021 SPTK Working Group //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
// You may obtain a copy of the License at //
// //
// http://www.apache.org/licenses/LICENSE-2.0 //
// //
// Unless required by applicable law or agreed to in writing, software //
// distributed under the License is distributed on an "AS IS" BASIS, //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and //
// limitations under the License. //
// ------------------------------------------------------------------------ //

#ifndef SPTK_COMPRESSION_A_LAW_EXPANSION_H_
#define SPTK_COMPRESSION_A_LAW_EXPANSION_H_

#include "SPTK/utils/sptk_utils.h"

namespace sptk {

/**
* Nonlinearly decompress data based on A-law algorithm.
*
* Given the input data @f$y(n)@f$, the expansion is performed as follows:
* @f[
* x(n) = V \, \mathrm{sgn}(y(n)) \left\{ \begin{array}{ll}
* \frac{\frac{|y(n)|}{V}(1 + \log A)}{A}, &
* \frac{|y(n)|}{V} < \frac{1}{1 + \log A} \\
* \frac{\exp(-1 + \frac{|y(n)|}{V}(1 + \log A))}{A}, &
* \frac{|y(n)|}{V} \ge \frac{1}{1 + \log A} \\
* \end{array} \right.
* @f]
* where @f$V@f$ is the absolute maximum value of the input data and @f$A@f$
* is the compression factor, which is typically set to 87.6.
*/
class ALawExpansion {
public:
/**
* @param[in] abs_max_value Absolute maximum value.
* @param[in] compression_factor Compression factor, @f$A@f$.
*/
ALawExpansion(double abs_max_value, double compression_factor);

virtual ~ALawExpansion() {
}

/**
* @return Absolute maximum value.
*/
double GetAbsMaxValue() const {
return abs_max_value_;
}

/**
* @return Compression factor.
*/
double GetCompressionFactor() const {
return compression_factor_;
}

/**
* @return True if this object is valid.
*/
bool IsValid() const {
return is_valid_;
}

/**
* @param[in] input Input data.
* @param[out] output Output data.
* @return True on success, false on failure.
*/
bool Run(double input, double* output) const;

/**
* @param[in,out] input_and_output Input/output data.
* @return True on success, false on failure.
*/
bool Run(double* input_and_output) const;

private:
const double abs_max_value_;
const double compression_factor_;
const double constant_;

bool is_valid_;

DISALLOW_COPY_AND_ASSIGN(ALawExpansion);
};

} // namespace sptk

#endif // SPTK_COMPRESSION_A_LAW_EXPANSION_H_
55 changes: 55 additions & 0 deletions src/compression/a_law_compression.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// ------------------------------------------------------------------------ //
// Copyright 2021 SPTK Working Group //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
// You may obtain a copy of the License at //
// //
// http://www.apache.org/licenses/LICENSE-2.0 //
// //
// Unless required by applicable law or agreed to in writing, software //
// distributed under the License is distributed on an "AS IS" BASIS, //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and //
// limitations under the License. //
// ------------------------------------------------------------------------ //

#include "SPTK/compression/a_law_compression.h"

#include <cmath> // std::fabs, std::log

namespace sptk {

ALawCompression::ALawCompression(double abs_max_value,
double compression_factor)
: abs_max_value_(abs_max_value),
compression_factor_(compression_factor),
constant_(abs_max_value_ / (1.0 + std::log(compression_factor_))),
is_valid_(true) {
if (abs_max_value_ <= 0.0 || compression_factor_ < 1.0) {
is_valid_ = false;
return;
}
}

bool ALawCompression::Run(double input, double* output) const {
if (!is_valid_ || NULL == output) {
return false;
}

const double x(std::fabs(input) / abs_max_value_);
double y(compression_factor_ * x);
if (1.0 / compression_factor_ <= x) {
y = 1.0 + std::log(y);
}
*output = constant_ * sptk::ExtractSign(input) * y;

return true;
}

bool ALawCompression::Run(double* input_and_output) const {
if (NULL == input_and_output) return false;
return Run(*input_and_output, input_and_output);
}

} // namespace sptk
55 changes: 55 additions & 0 deletions src/compression/a_law_expansion.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// ------------------------------------------------------------------------ //
// Copyright 2021 SPTK Working Group //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
// You may obtain a copy of the License at //
// //
// http://www.apache.org/licenses/LICENSE-2.0 //
// //
// Unless required by applicable law or agreed to in writing, software //
// distributed under the License is distributed on an "AS IS" BASIS, //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and //
// limitations under the License. //
// ------------------------------------------------------------------------ //

#include "SPTK/compression/a_law_expansion.h"

#include <cmath> // std::exp, std::fabs, std::pow

namespace sptk {

ALawExpansion::ALawExpansion(double abs_max_value, double compression_factor)
: abs_max_value_(abs_max_value),
compression_factor_(compression_factor),
constant_(abs_max_value_ / compression_factor_),
is_valid_(true) {
if (abs_max_value_ <= 0.0 || compression_factor_ < 1.0) {
is_valid_ = false;
return;
}
}

bool ALawExpansion::Run(double input, double* output) const {
if (!is_valid_ || NULL == output) {
return false;
}

const double x(std::fabs(input) / abs_max_value_);
const double z(1 + std::log(compression_factor_));
double y(z * x);
if (1.0 / z <= x) {
y = std::exp(y - 1.0);
}
*output = constant_ * sptk::ExtractSign(input) * y;

return true;
}

bool ALawExpansion::Run(double* input_and_output) const {
if (NULL == input_and_output) return false;
return Run(*input_and_output, input_and_output);
}

} // namespace sptk
4 changes: 2 additions & 2 deletions src/compression/mu_law_compression.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ MuLawCompression::MuLawCompression(double abs_max_value,
double compression_factor)
: abs_max_value_(abs_max_value),
compression_factor_(compression_factor),
constant_(1.0 / std::log(1.0 + compression_factor_)),
constant_(abs_max_value_ / std::log(1.0 + compression_factor_)),
is_valid_(true) {
if (abs_max_value_ <= 0.0 || compression_factor_ <= 0.0) {
is_valid_ = false;
Expand All @@ -38,7 +38,7 @@ bool MuLawCompression::Run(double input, double* output) const {
}

const double x(std::fabs(input) / abs_max_value_);
*output = (constant_ * abs_max_value_ * sptk::ExtractSign(input) *
*output = (constant_ * sptk::ExtractSign(input) *
std::log(1.0 + compression_factor_ * x));

return true;
Expand Down
Loading

0 comments on commit e77cf86

Please sign in to comment.