Skip to content

Commit

Permalink
Add huffman command
Browse files Browse the repository at this point in the history
  • Loading branch information
takenori-y committed Nov 26, 2018
1 parent 33fc96d commit c57f0ba
Show file tree
Hide file tree
Showing 13 changed files with 493 additions and 15 deletions.
91 changes: 91 additions & 0 deletions include/SPTK/compressor/huffman_coding.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// ----------------------------------------------------------------- //
// The Speech Signal Processing Toolkit (SPTK) //
// developed by SPTK Working Group //
// http://sp-tk.sourceforge.net/ //
// ----------------------------------------------------------------- //
// //
// Copyright (c) 1984-2007 Tokyo Institute of Technology //
// Interdisciplinary Graduate School of //
// Science and Engineering //
// //
// 1996-2018 Nagoya Institute of Technology //
// Department of Computer Science //
// //
// 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. //
// - Neither the name of the SPTK working group nor the names of its //
// contributors may be used to endorse or promote products derived //
// from this software without specific prior written permission. //
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND //
// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, //
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF //
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE //
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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 SPTK_COMPRESSOR_HUFFMAN_CODING_H_
#define SPTK_COMPRESSOR_HUFFMAN_CODING_H_

#include <string> // std::string
#include <vector> // std::vector

#include "SPTK/utils/sptk_utils.h"

namespace sptk {

class HuffmanCoding {
public:
//
explicit HuffmanCoding(int num_element);

//
virtual ~HuffmanCoding() {
}

//
int GetNumElement() const {
return num_element_;
}

//
bool IsValid() const {
return is_valid_;
}

//
bool Run(const std::vector<double>& probability,
std::vector<std::string>* codeword) const;

private:
//
const int num_element_;

//
bool is_valid_;

//
DISALLOW_COPY_AND_ASSIGN(HuffmanCoding);
};

} // namespace sptk

#endif // SPTK_COMPRESSOR_HUFFMAN_CODING_H_
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
// POSSIBILITY OF SUCH DAMAGE. //
// ----------------------------------------------------------------- //

#ifndef SPTK_QUANTIZER_INVERSE_MU_LAW_COMPRESSION_H_
#define SPTK_QUANTIZER_INVERSE_MU_LAW_COMPRESSION_H_
#ifndef SPTK_COMPRESSOR_INVERSE_MU_LAW_COMPRESSION_H_
#define SPTK_COMPRESSOR_INVERSE_MU_LAW_COMPRESSION_H_

#include "SPTK/utils/sptk_utils.h"

Expand Down Expand Up @@ -93,4 +93,4 @@ class InverseMuLawCompression {

} // namespace sptk

#endif // SPTK_QUANTIZER_INVERSE_MU_LAW_COMPRESSION_H_
#endif // SPTK_COMPRESSOR_INVERSE_MU_LAW_COMPRESSION_H_
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
// POSSIBILITY OF SUCH DAMAGE. //
// ----------------------------------------------------------------- //

#ifndef SPTK_QUANTIZER_LINDE_BUZO_GRAY_ALGORITHM_H_
#define SPTK_QUANTIZER_LINDE_BUZO_GRAY_ALGORITHM_H_
#ifndef SPTK_COMPRESSOR_LINDE_BUZO_GRAY_ALGORITHM_H_
#define SPTK_COMPRESSOR_LINDE_BUZO_GRAY_ALGORITHM_H_

#include <vector> // std::vector

Expand Down Expand Up @@ -159,4 +159,4 @@ class LindeBuzoGrayAlgorithm {

} // namespace sptk

#endif // SPTK_QUANTIZER_LINDE_BUZO_GRAY_ALGORITHM_H_
#endif // SPTK_COMPRESSOR_LINDE_BUZO_GRAY_ALGORITHM_H_
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
// POSSIBILITY OF SUCH DAMAGE. //
// ----------------------------------------------------------------- //

#ifndef SPTK_QUANTIZER_MU_LAW_COMPRESSION_H_
#define SPTK_QUANTIZER_MU_LAW_COMPRESSION_H_
#ifndef SPTK_COMPRESSOR_MU_LAW_COMPRESSION_H_
#define SPTK_COMPRESSOR_MU_LAW_COMPRESSION_H_

#include "SPTK/utils/sptk_utils.h"

Expand Down Expand Up @@ -92,4 +92,4 @@ class MuLawCompression {

} // namespace sptk

#endif // SPTK_QUANTIZER_MU_LAW_COMPRESSION_H_
#endif // SPTK_COMPRESSOR_MU_LAW_COMPRESSION_H_
186 changes: 186 additions & 0 deletions src/compressor/huffman_coding.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
// ----------------------------------------------------------------- //
// The Speech Signal Processing Toolkit (SPTK) //
// developed by SPTK Working Group //
// http://sp-tk.sourceforge.net/ //
// ----------------------------------------------------------------- //
// //
// Copyright (c) 1984-2007 Tokyo Institute of Technology //
// Interdisciplinary Graduate School of //
// Science and Engineering //
// //
// 1996-2018 Nagoya Institute of Technology //
// Department of Computer Science //
// //
// 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. //
// - Neither the name of the SPTK working group nor the names of its //
// contributors may be used to endorse or promote products derived //
// from this software without specific prior written permission. //
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND //
// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, //
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF //
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE //
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. //
// ----------------------------------------------------------------- //

#include "SPTK/compressor/huffman_coding.h"

#include <cstddef> // std::size_t
#include <queue> // std::priority_queue

namespace {

class Node {
public:
// Leaf node
Node(int symbol, double probability)
: symbol_(symbol), probability_(probability), left_(NULL), right_(NULL) {
}

// Internal node
Node(const Node* left, const Node* right)
: symbol_(-1),
probability_((NULL == left || NULL == right)
? 0.0
: left->GetProbability() + right->GetProbability()),
left_(left),
right_(right) {
}

virtual ~Node() {
}

int GetSymbol() const {
return symbol_;
}

double GetProbability() const {
return probability_;
}

const Node* GetLeft() const {
return left_;
}

const Node* GetRight() const {
return right_;
}

private:
const int symbol_;
const double probability_;
const Node* left_;
const Node* right_;

DISALLOW_COPY_AND_ASSIGN(Node);
};

struct Compare {
bool operator()(const Node* a, const Node* b) const {
return b->GetProbability() < a->GetProbability();
}
};

void Encode(const Node* node, std::string code,
std::vector<std::string>* codeword) {
if (NULL == node) return;

const int symbol(node->GetSymbol());
if (0 <= symbol) {
(*codeword)[symbol] = code;
} else {
Encode(node->GetLeft(), code + "0", codeword);
Encode(node->GetRight(), code + "1", codeword);
}
}

void Free(const Node* node) {
if (NULL == node) return;
Free(node->GetLeft());
Free(node->GetRight());
delete node;
}

} // namespace

namespace sptk {

HuffmanCoding::HuffmanCoding(int num_element)
: num_element_(num_element), is_valid_(true) {
if (num_element_ <= 0) {
is_valid_ = false;
}
}

bool HuffmanCoding::Run(const std::vector<double>& probability,
std::vector<std::string>* codeword) const {
// check inputs
if (!is_valid_ ||
probability.size() != static_cast<std::size_t>(num_element_) ||
NULL == codeword) {
return false;
}

// prepare memory
if (codeword->size() != static_cast<std::size_t>(num_element_)) {
codeword->resize(num_element_);
}

if (1 == num_element_) {
(*codeword)[0] = "0";
return true;
}

std::priority_queue<Node*, std::vector<Node*>, Compare> tree;

try {
for (int i(0); i < num_element_; ++i) {
tree.push(new Node(i, probability[i]));
}
while (1 < tree.size()) {
const Node* left(tree.top());
tree.pop();
const Node* right(tree.top());
tree.pop();

try {
tree.push(new Node(left, right));
} catch (...) {
delete left;
delete right;
throw;
}
}
Encode(tree.top(), "", codeword);
Free(tree.top());
} catch (...) {
while (!tree.empty()) {
Free(tree.top());
tree.pop();
}
return false;
}

return true;
}

} // namespace sptk
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
// POSSIBILITY OF SUCH DAMAGE. //
// ----------------------------------------------------------------- //

#include "SPTK/quantizer/inverse_mu_law_compression.h"
#include "SPTK/compressor/inverse_mu_law_compression.h"

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
// POSSIBILITY OF SUCH DAMAGE. //
// ----------------------------------------------------------------- //

#include "SPTK/quantizer/linde_buzo_gray_algorithm.h"
#include "SPTK/compressor/linde_buzo_gray_algorithm.h"

#include <cfloat> // DBL_MAX
#include <cmath> // std::fabs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
// POSSIBILITY OF SUCH DAMAGE. //
// ----------------------------------------------------------------- //

#include "SPTK/quantizer/mu_law_compression.h"
#include "SPTK/compressor/mu_law_compression.h"

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

Expand Down
Loading

0 comments on commit c57f0ba

Please sign in to comment.