Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9af15ed7a4 | |||
| 289d73c07e | |||
| 1be102a51c | |||
| 4446c24e07 | |||
| b56fd19a20 | |||
| 58e843f8aa | |||
| 005f102253 | |||
| 484e81e834 | |||
| e8778a51aa | |||
| 180b94ab7c |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,3 +1,8 @@
|
|||||||
|
__pycache__
|
||||||
|
.bck
|
||||||
|
out
|
||||||
|
target
|
||||||
|
build
|
||||||
*~
|
*~
|
||||||
*.swp
|
*.swp
|
||||||
*.old
|
*.old
|
||||||
|
|||||||
24
GLD_audio-algo-chunkware-test.json
Normal file
24
GLD_audio-algo-chunkware-test.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"type":"BINARY",
|
||||||
|
"sub-type":"TEST",
|
||||||
|
"group-id":"com.atria-soft",
|
||||||
|
"description":"Chunkware test unit",
|
||||||
|
"license":"MPL-2",
|
||||||
|
"license-file":"file://LICENSE",
|
||||||
|
"maintainer":"file://authors.txt",
|
||||||
|
"author":"file://authors.txt",
|
||||||
|
"version":"file://version.txt",
|
||||||
|
"code-quality":"MEDIUM",
|
||||||
|
|
||||||
|
"source": [
|
||||||
|
"test/main.cpp"
|
||||||
|
],
|
||||||
|
"compilation-version": {
|
||||||
|
"c++": 2017
|
||||||
|
},
|
||||||
|
"dependency": [
|
||||||
|
"audio-algo-chunkware",
|
||||||
|
"etk",
|
||||||
|
"test-debug"
|
||||||
|
]
|
||||||
|
}
|
||||||
42
GLD_audio-algo-chunkware.json
Normal file
42
GLD_audio-algo-chunkware.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"type":"LIBRARY",
|
||||||
|
"group-id":"com.atria-soft",
|
||||||
|
"description":"Chunkware algo",
|
||||||
|
"license":"MPL-2",
|
||||||
|
"license-file":"file://LICENSE",
|
||||||
|
"maintainer":"file://authors.txt",
|
||||||
|
"author":"file://authors.txt",
|
||||||
|
"version":"file://version.txt",
|
||||||
|
"code-quality":"MEDIUM",
|
||||||
|
|
||||||
|
"source": [
|
||||||
|
"audio/algo/chunkware/debug.cpp",
|
||||||
|
"audio/algo/chunkware/Compressor.cpp",
|
||||||
|
"audio/algo/chunkware/debug.cpp",
|
||||||
|
"audio/algo/chunkware/EnvelopeDetector.cpp",
|
||||||
|
"audio/algo/chunkware/AttRelEnvelope.cpp",
|
||||||
|
"audio/algo/chunkware/Gate.cpp",
|
||||||
|
"audio/algo/chunkware/GateRms.cpp",
|
||||||
|
"audio/algo/chunkware/Limiter.cpp"
|
||||||
|
],
|
||||||
|
"header": [
|
||||||
|
"audio/algo/chunkware/Compressor.hpp",
|
||||||
|
"audio/algo/chunkware/debug.hpp",
|
||||||
|
"audio/algo/chunkware/EnvelopeDetector.hpp",
|
||||||
|
"audio/algo/chunkware/AttRelEnvelope.hpp",
|
||||||
|
"audio/algo/chunkware/Gate.hpp",
|
||||||
|
"audio/algo/chunkware/GateRms.hpp",
|
||||||
|
"audio/algo/chunkware/Gain.hpp",
|
||||||
|
"audio/algo/chunkware/Limiter.hpp"
|
||||||
|
],
|
||||||
|
"path":[
|
||||||
|
"."
|
||||||
|
],
|
||||||
|
"compilation-version": {
|
||||||
|
"c++": 2017
|
||||||
|
},
|
||||||
|
"dependency": [
|
||||||
|
"etk",
|
||||||
|
"audio"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -49,15 +49,15 @@ void audio::algo::chunkware::Compressor::init() {
|
|||||||
m_isConfigured = true;
|
m_isConfigured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<enum audio::format> audio::algo::chunkware::Compressor::getSupportedFormat() {
|
etk::Vector<enum audio::format> audio::algo::chunkware::Compressor::getSupportedFormat() {
|
||||||
std::vector<enum audio::format> out = getNativeSupportedFormat();
|
etk::Vector<enum audio::format> out = getNativeSupportedFormat();
|
||||||
out.push_back(audio::format_int16);
|
out.pushBack(audio::format_int16);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<enum audio::format> audio::algo::chunkware::Compressor::getNativeSupportedFormat() {
|
etk::Vector<enum audio::format> audio::algo::chunkware::Compressor::getNativeSupportedFormat() {
|
||||||
std::vector<enum audio::format> out;
|
etk::Vector<enum audio::format> out;
|
||||||
out.push_back(audio::format_double);
|
out.pushBack(audio::format_double);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ void audio::algo::chunkware::Compressor::process(void* _output, const void* _inp
|
|||||||
processDouble(vals, vals, _nbChannel);
|
processDouble(vals, vals, _nbChannel);
|
||||||
for (int8_t kkk=0; kkk<_nbChannel ; ++kkk) {
|
for (int8_t kkk=0; kkk<_nbChannel ; ++kkk) {
|
||||||
vals[kkk] *= 32768.0;
|
vals[kkk] *= 32768.0;
|
||||||
output[iii*_nbChannel+kkk] = int16_t(std::avg(-32768.0, vals[kkk], 32767.0));
|
output[iii*_nbChannel+kkk] = int16_t(etk::avg(-32768.0, vals[kkk], 32767.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,8 +108,8 @@ void audio::algo::chunkware::Compressor::processDouble(double* _out, const doubl
|
|||||||
double keyLink = 0;
|
double keyLink = 0;
|
||||||
// get greater value;
|
// get greater value;
|
||||||
for (int8_t iii=0; iii<_nbChannel; ++iii) {
|
for (int8_t iii=0; iii<_nbChannel; ++iii) {
|
||||||
double absValue = std::abs(_in[iii]);
|
double absValue = etk::abs(_in[iii]);
|
||||||
keyLink = std::max(keyLink, absValue);
|
keyLink = etk::max(keyLink, absValue);
|
||||||
}
|
}
|
||||||
processDouble(_out, _in, _nbChannel, keyLink);
|
processDouble(_out, _in, _nbChannel, keyLink);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,12 +47,12 @@ namespace audio {
|
|||||||
* @brief Get list of format suported in input.
|
* @brief Get list of format suported in input.
|
||||||
* @return list of supported format
|
* @return list of supported format
|
||||||
*/
|
*/
|
||||||
virtual std::vector<enum audio::format> getSupportedFormat();
|
virtual etk::Vector<enum audio::format> getSupportedFormat();
|
||||||
/**
|
/**
|
||||||
* @brief Get list of algorithm format suported. No format convertion.
|
* @brief Get list of algorithm format suported. No format convertion.
|
||||||
* @return list of supported format
|
* @return list of supported format
|
||||||
*/
|
*/
|
||||||
virtual std::vector<enum audio::format> getNativeSupportedFormat();
|
virtual etk::Vector<enum audio::format> getNativeSupportedFormat();
|
||||||
/**
|
/**
|
||||||
* @brief Main input algo process.
|
* @brief Main input algo process.
|
||||||
* @param[in,out] _output Output data.
|
* @param[in,out] _output Output data.
|
||||||
|
|||||||
@@ -47,15 +47,15 @@ void audio::algo::chunkware::Gate::init() {
|
|||||||
m_isConfigured = true;
|
m_isConfigured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<enum audio::format> audio::algo::chunkware::Gate::getSupportedFormat() {
|
etk::Vector<enum audio::format> audio::algo::chunkware::Gate::getSupportedFormat() {
|
||||||
std::vector<enum audio::format> out = getNativeSupportedFormat();
|
etk::Vector<enum audio::format> out = getNativeSupportedFormat();
|
||||||
out.push_back(audio::format_int16);
|
out.pushBack(audio::format_int16);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<enum audio::format> audio::algo::chunkware::Gate::getNativeSupportedFormat() {
|
etk::Vector<enum audio::format> audio::algo::chunkware::Gate::getNativeSupportedFormat() {
|
||||||
std::vector<enum audio::format> out;
|
etk::Vector<enum audio::format> out;
|
||||||
out.push_back(audio::format_double);
|
out.pushBack(audio::format_double);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ void audio::algo::chunkware::Gate::process(void* _output, const void* _input, si
|
|||||||
processDouble(vals, vals, _nbChannel);
|
processDouble(vals, vals, _nbChannel);
|
||||||
for (int8_t kkk=0; kkk<_nbChannel ; ++kkk) {
|
for (int8_t kkk=0; kkk<_nbChannel ; ++kkk) {
|
||||||
vals[kkk] *= 32768.0;
|
vals[kkk] *= 32768.0;
|
||||||
output[iii*_nbChannel+kkk] = int16_t(std::avg(-32768.0, vals[kkk], 32767.0));
|
output[iii*_nbChannel+kkk] = int16_t(etk::avg(-32768.0, vals[kkk], 32767.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,8 +103,8 @@ void audio::algo::chunkware::Gate::processDouble(double* _out, const double* _in
|
|||||||
double keyLink = 0;
|
double keyLink = 0;
|
||||||
// get greater value;
|
// get greater value;
|
||||||
for (int8_t iii=0; iii<_nbChannel; ++iii) {
|
for (int8_t iii=0; iii<_nbChannel; ++iii) {
|
||||||
double absValue = std::abs(_in[iii]);
|
double absValue = etk::abs(_in[iii]);
|
||||||
keyLink = std::max(keyLink, absValue);
|
keyLink = etk::max(keyLink, absValue);
|
||||||
}
|
}
|
||||||
processDouble(_out, _in, _nbChannel, keyLink);
|
processDouble(_out, _in, _nbChannel, keyLink);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,12 +47,12 @@ namespace audio {
|
|||||||
* @brief Get list of format suported in input.
|
* @brief Get list of format suported in input.
|
||||||
* @return list of supported format
|
* @return list of supported format
|
||||||
*/
|
*/
|
||||||
virtual std::vector<enum audio::format> getSupportedFormat();
|
virtual etk::Vector<enum audio::format> getSupportedFormat();
|
||||||
/**
|
/**
|
||||||
* @brief Get list of algorithm format suported. No format convertion.
|
* @brief Get list of algorithm format suported. No format convertion.
|
||||||
* @return list of supported format
|
* @return list of supported format
|
||||||
*/
|
*/
|
||||||
virtual std::vector<enum audio::format> getNativeSupportedFormat();
|
virtual etk::Vector<enum audio::format> getNativeSupportedFormat();
|
||||||
/**
|
/**
|
||||||
* @brief Main input algo process.
|
* @brief Main input algo process.
|
||||||
* @param[in,out] _output Output data.
|
* @param[in,out] _output Output data.
|
||||||
|
|||||||
@@ -74,25 +74,24 @@ void audio::algo::chunkware::Limiter::init(int8_t _nbChannel) {
|
|||||||
m_outputBuffer.resize(_nbChannel);
|
m_outputBuffer.resize(_nbChannel);
|
||||||
for (int8_t iii=0; iii<_nbChannel; ++iii) {
|
for (int8_t iii=0; iii<_nbChannel; ++iii) {
|
||||||
m_outputBuffer[iii].resize(BUFFER_SIZE, 0.0);
|
m_outputBuffer[iii].resize(BUFFER_SIZE, 0.0);
|
||||||
m_outputBuffer[iii].assign(BUFFER_SIZE, 0.0);
|
|
||||||
}
|
}
|
||||||
m_isConfigured = true;
|
m_isConfigured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio::algo::chunkware::FastEnvelope::setCoef() {
|
void audio::algo::chunkware::FastEnvelope::setCoef() {
|
||||||
// rises to 99% of in value over duration of time constant
|
// rises to 99% of in value over duration of time constant
|
||||||
m_coefficient = std::pow(0.01, (1000.0 / (m_timeMs * m_sampleRate)));
|
m_coefficient = etk::pow(0.01, (1000.0 / (m_timeMs * m_sampleRate)));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<enum audio::format> audio::algo::chunkware::Limiter::getSupportedFormat() {
|
etk::Vector<enum audio::format> audio::algo::chunkware::Limiter::getSupportedFormat() {
|
||||||
std::vector<enum audio::format> out = getNativeSupportedFormat();
|
etk::Vector<enum audio::format> out = getNativeSupportedFormat();
|
||||||
out.push_back(audio::format_int16);
|
out.pushBack(audio::format_int16);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<enum audio::format> audio::algo::chunkware::Limiter::getNativeSupportedFormat() {
|
etk::Vector<enum audio::format> audio::algo::chunkware::Limiter::getNativeSupportedFormat() {
|
||||||
std::vector<enum audio::format> out;
|
etk::Vector<enum audio::format> out;
|
||||||
out.push_back(audio::format_double);
|
out.pushBack(audio::format_double);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +116,7 @@ void audio::algo::chunkware::Limiter::process(void* _output, const void* _input,
|
|||||||
processDouble(vals, vals, _nbChannel);
|
processDouble(vals, vals, _nbChannel);
|
||||||
for (int8_t kkk=0; kkk<_nbChannel ; ++kkk) {
|
for (int8_t kkk=0; kkk<_nbChannel ; ++kkk) {
|
||||||
vals[kkk] *= 32768.0;
|
vals[kkk] *= 32768.0;
|
||||||
output[iii*_nbChannel+kkk] = int16_t(std::avg(-32768.0, vals[kkk], 32767.0));
|
output[iii*_nbChannel+kkk] = int16_t(etk::avg(-32768.0, vals[kkk], 32767.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,8 +141,8 @@ void audio::algo::chunkware::Limiter::processDouble(double* _out, const double*
|
|||||||
double keyLink = 0;
|
double keyLink = 0;
|
||||||
// get greater value;
|
// get greater value;
|
||||||
for (int8_t iii=0; iii<_nbChannel; ++iii) {
|
for (int8_t iii=0; iii<_nbChannel; ++iii) {
|
||||||
double absValue = std::abs(_in[iii]);
|
double absValue = etk::abs(_in[iii]);
|
||||||
keyLink = std::max(keyLink, absValue);
|
keyLink = etk::max(keyLink, absValue);
|
||||||
}
|
}
|
||||||
// we always want to feed the sidechain AT LEATS the threshold value
|
// we always want to feed the sidechain AT LEATS the threshold value
|
||||||
if (keyLink < m_threshold) {
|
if (keyLink < m_threshold) {
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
#include <audio/format.hpp>
|
#include <audio/format.hpp>
|
||||||
#include <audio/algo/chunkware/AttRelEnvelope.hpp>
|
#include <audio/algo/chunkware/AttRelEnvelope.hpp>
|
||||||
#include <audio/algo/chunkware/Gain.hpp>
|
#include <audio/algo/chunkware/Gain.hpp>
|
||||||
#include <chrono>
|
#include <echrono/Steady.hpp>
|
||||||
#include <vector>
|
#include <etk/Vector.hpp>
|
||||||
|
|
||||||
namespace audio {
|
namespace audio {
|
||||||
namespace algo {
|
namespace algo {
|
||||||
@@ -63,12 +63,12 @@ namespace audio {
|
|||||||
* @brief Get list of format suported in input.
|
* @brief Get list of format suported in input.
|
||||||
* @return list of supported format
|
* @return list of supported format
|
||||||
*/
|
*/
|
||||||
virtual std::vector<enum audio::format> getSupportedFormat();
|
virtual etk::Vector<enum audio::format> getSupportedFormat();
|
||||||
/**
|
/**
|
||||||
* @brief Get list of algorithm format suported. No format convertion.
|
* @brief Get list of algorithm format suported. No format convertion.
|
||||||
* @return list of supported format
|
* @return list of supported format
|
||||||
*/
|
*/
|
||||||
virtual std::vector<enum audio::format> getNativeSupportedFormat();
|
virtual etk::Vector<enum audio::format> getNativeSupportedFormat();
|
||||||
/**
|
/**
|
||||||
* @brief Main input algo process.
|
* @brief Main input algo process.
|
||||||
* @param[in,out] _output Output data.
|
* @param[in,out] _output Output data.
|
||||||
@@ -97,7 +97,7 @@ namespace audio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::chrono::microseconds m_attackTime; //!< attaque time in ms.
|
echrono::microseconds m_attackTime; //!< attaque time in ms.
|
||||||
public:
|
public:
|
||||||
virtual void setAttack(double _ms);
|
virtual void setAttack(double _ms);
|
||||||
virtual double getAttack() const {
|
virtual double getAttack() const {
|
||||||
@@ -105,7 +105,7 @@ namespace audio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::chrono::microseconds m_releaseTime; //!< attaque time in ms.
|
echrono::microseconds m_releaseTime; //!< attaque time in ms.
|
||||||
public:
|
public:
|
||||||
virtual void setRelease(double _ms);
|
virtual void setRelease(double _ms);
|
||||||
virtual double getRelease() const {
|
virtual double getRelease() const {
|
||||||
@@ -150,7 +150,7 @@ namespace audio {
|
|||||||
static const int BUFFER_SIZE = 1024; //!< buffer size (always a power of 2!)
|
static const int BUFFER_SIZE = 1024; //!< buffer size (always a power of 2!)
|
||||||
uint32_t m_bufferMask; //!< buffer mask
|
uint32_t m_bufferMask; //!< buffer mask
|
||||||
uint32_t m_cursor; //!< cursor
|
uint32_t m_cursor; //!< cursor
|
||||||
std::vector<std::vector<double> > m_outputBuffer; //!< output buffer
|
etk::Vector<etk::Vector<double> > m_outputBuffer; //!< output buffer
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
import lutin.debug as debug
|
|
||||||
import lutin.tools as tools
|
|
||||||
|
|
||||||
|
|
||||||
def get_type():
|
|
||||||
return "BINARY"
|
|
||||||
|
|
||||||
def get_sub_type():
|
|
||||||
return "TEST"
|
|
||||||
|
|
||||||
def get_desc():
|
|
||||||
return "test chunkware"
|
|
||||||
|
|
||||||
def get_licence():
|
|
||||||
return "APACHE-2"
|
|
||||||
|
|
||||||
def get_compagny_type():
|
|
||||||
return "com"
|
|
||||||
|
|
||||||
def get_compagny_name():
|
|
||||||
return "atria-soft"
|
|
||||||
|
|
||||||
def get_maintainer():
|
|
||||||
return "authors.txt"
|
|
||||||
|
|
||||||
def configure(target, my_module):
|
|
||||||
my_module.add_src_file([
|
|
||||||
'test/main.cpp'
|
|
||||||
])
|
|
||||||
my_module.add_depend(['audio-algo-chunkware', 'test-debug'])
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
import lutin.debug as debug
|
|
||||||
import lutin.tools as tools
|
|
||||||
|
|
||||||
|
|
||||||
def get_type():
|
|
||||||
return "LIBRARY"
|
|
||||||
|
|
||||||
def get_desc():
|
|
||||||
return "chunkware algo"
|
|
||||||
|
|
||||||
def get_licence():
|
|
||||||
return "BSD-2"
|
|
||||||
|
|
||||||
def get_compagny_type():
|
|
||||||
return "com"
|
|
||||||
|
|
||||||
def get_compagny_name():
|
|
||||||
return "atria-soft"
|
|
||||||
|
|
||||||
def get_maintainer():
|
|
||||||
return "authors.txt"
|
|
||||||
|
|
||||||
def get_version():
|
|
||||||
return "version.txt"
|
|
||||||
|
|
||||||
def configure(target, my_module):
|
|
||||||
my_module.add_src_file([
|
|
||||||
'audio/algo/chunkware/debug.cpp',
|
|
||||||
'audio/algo/chunkware/Compressor.cpp',
|
|
||||||
'audio/algo/chunkware/debug.cpp',
|
|
||||||
'audio/algo/chunkware/EnvelopeDetector.cpp',
|
|
||||||
'audio/algo/chunkware/AttRelEnvelope.cpp',
|
|
||||||
'audio/algo/chunkware/Gate.cpp',
|
|
||||||
'audio/algo/chunkware/GateRms.cpp',
|
|
||||||
'audio/algo/chunkware/Limiter.cpp'
|
|
||||||
])
|
|
||||||
my_module.add_header_file([
|
|
||||||
'audio/algo/chunkware/Compressor.hpp',
|
|
||||||
'audio/algo/chunkware/debug.hpp',
|
|
||||||
'audio/algo/chunkware/EnvelopeDetector.hpp',
|
|
||||||
'audio/algo/chunkware/AttRelEnvelope.hpp',
|
|
||||||
'audio/algo/chunkware/Gate.hpp',
|
|
||||||
'audio/algo/chunkware/GateRms.hpp',
|
|
||||||
'audio/algo/chunkware/Gain.hpp',
|
|
||||||
'audio/algo/chunkware/Limiter.hpp'
|
|
||||||
])
|
|
||||||
my_module.add_depend(['etk', 'audio'])
|
|
||||||
my_module.add_path(".")
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
154
test/main.cpp
154
test/main.cpp
@@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
* @author Edouard DUPIN
|
* @author Edouard DUPIN
|
||||||
* @copyright 2015, Edouard DUPIN, all right reserved
|
* @copyright 2015, Edouard DUPIN, all right reserved
|
||||||
* @license APACHE v2.0 (see license file)
|
* @license MPL v2.0 (see license file)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <test-debug/debug.hpp>
|
#include <test-debug/debug.hpp>
|
||||||
@@ -9,14 +9,18 @@
|
|||||||
#include <audio/algo/chunkware/Compressor.hpp>
|
#include <audio/algo/chunkware/Compressor.hpp>
|
||||||
#include <audio/algo/chunkware/Limiter.hpp>
|
#include <audio/algo/chunkware/Limiter.hpp>
|
||||||
#include <audio/algo/chunkware/Gate.hpp>
|
#include <audio/algo/chunkware/Gate.hpp>
|
||||||
#include <etk/os/FSNode.hpp>
|
#include <ememory/SharedPtr.hpp>
|
||||||
#include <chrono>
|
#include <etk/io/Interface.hpp>
|
||||||
#include <thread>
|
#include <etk/path/Path.hpp>
|
||||||
|
#include <etk/uri/uri.hpp>
|
||||||
|
#include <echrono/Steady.hpp>
|
||||||
|
#include <ethread/Thread.hpp>
|
||||||
|
#include <ethread/tools.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static std::vector<double> convert(const std::vector<int16_t>& _data) {
|
static etk::Vector<double> convert(const etk::Vector<int16_t>& _data) {
|
||||||
std::vector<double> out;
|
etk::Vector<double> out;
|
||||||
out.resize(_data.size(), 0.0);
|
out.resize(_data.size(), 0.0);
|
||||||
for (size_t iii=0; iii<_data.size(); ++iii) {
|
for (size_t iii=0; iii<_data.size(); ++iii) {
|
||||||
out[iii] = _data[iii];
|
out[iii] = _data[iii];
|
||||||
@@ -27,11 +31,11 @@ static std::vector<double> convert(const std::vector<int16_t>& _data) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<int16_t> convert(const std::vector<double>& _data) {
|
static etk::Vector<int16_t> convert(const etk::Vector<double>& _data) {
|
||||||
std::vector<int16_t> out;
|
etk::Vector<int16_t> out;
|
||||||
out.resize(_data.size(), 0.0);
|
out.resize(_data.size(), 0.0);
|
||||||
for (size_t iii=0; iii<_data.size(); ++iii) {
|
for (size_t iii=0; iii<_data.size(); ++iii) {
|
||||||
out[iii] = int16_t(std::avg(-32768.0, _data[iii]*32768.0, 32767.0));
|
out[iii] = int16_t(etk::avg(-32768.0, _data[iii]*32768.0, 32767.0));
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@@ -39,40 +43,40 @@ static std::vector<int16_t> convert(const std::vector<double>& _data) {
|
|||||||
|
|
||||||
class Performance {
|
class Performance {
|
||||||
private:
|
private:
|
||||||
std::chrono::steady_clock::time_point m_timeStart;
|
echrono::Steady m_timeStart;
|
||||||
std::chrono::steady_clock::time_point m_timeStop;
|
echrono::Steady m_timeStop;
|
||||||
std::chrono::nanoseconds m_totalTimeProcessing;
|
echrono::Duration m_totalTimeProcessing;
|
||||||
std::chrono::nanoseconds m_minProcessing;
|
echrono::Duration m_minProcessing;
|
||||||
std::chrono::nanoseconds m_maxProcessing;
|
echrono::Duration m_maxProcessing;
|
||||||
int32_t m_totalIteration;
|
int32_t m_totalIteration;
|
||||||
public:
|
public:
|
||||||
Performance() :
|
Performance() :
|
||||||
m_totalTimeProcessing(0),
|
m_totalTimeProcessing(0),
|
||||||
m_minProcessing(99999999999999LL),
|
m_minProcessing(int64_t(99999999999999LL)),
|
||||||
m_maxProcessing(0),
|
m_maxProcessing(0),
|
||||||
m_totalIteration(0) {
|
m_totalIteration(0) {
|
||||||
|
|
||||||
}
|
}
|
||||||
void tic() {
|
void tic() {
|
||||||
m_timeStart = std::chrono::steady_clock::now();
|
m_timeStart = echrono::Steady::now();
|
||||||
}
|
}
|
||||||
void toc() {
|
void toc() {
|
||||||
m_timeStop = std::chrono::steady_clock::now();
|
m_timeStop = echrono::Steady::now();
|
||||||
std::chrono::nanoseconds time = m_timeStop - m_timeStart;
|
echrono::Duration time = m_timeStop - m_timeStart;
|
||||||
m_minProcessing = std::min(m_minProcessing, time);
|
m_minProcessing = etk::min(m_minProcessing, time);
|
||||||
m_maxProcessing = std::max(m_maxProcessing, time);
|
m_maxProcessing = etk::max(m_maxProcessing, time);
|
||||||
m_totalTimeProcessing += time;
|
m_totalTimeProcessing += time;
|
||||||
m_totalIteration++;
|
m_totalIteration++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::nanoseconds getTotalTimeProcessing() {
|
echrono::Duration getTotalTimeProcessing() {
|
||||||
return m_totalTimeProcessing;
|
return m_totalTimeProcessing;
|
||||||
}
|
}
|
||||||
std::chrono::nanoseconds getMinProcessing() {
|
echrono::Duration getMinProcessing() {
|
||||||
return m_minProcessing;
|
return m_minProcessing;
|
||||||
}
|
}
|
||||||
std::chrono::nanoseconds getMaxProcessing() {
|
echrono::Duration getMaxProcessing() {
|
||||||
return m_maxProcessing;
|
return m_maxProcessing;
|
||||||
}
|
}
|
||||||
int32_t getTotalIteration() {
|
int32_t getTotalIteration() {
|
||||||
@@ -82,15 +86,15 @@ class Performance {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void performanceCompressor() {
|
void performanceCompressor() {
|
||||||
std::vector<double> input;
|
etk::Vector<double> input;
|
||||||
input.resize(8192, 0);
|
input.resize(8192, 0);
|
||||||
std::vector<double> output;
|
etk::Vector<double> output;
|
||||||
output.resize(8192, 0);
|
output.resize(8192, 0);
|
||||||
double sampleRate = 48000.0;
|
double sampleRate = 48000.0;
|
||||||
{
|
{
|
||||||
double phase = 0;
|
double phase = 0;
|
||||||
double baseCycle = 2.0*M_PI/sampleRate * 1280.0;
|
double baseCycle = 2.0*M_PI/sampleRate * 1280.0;
|
||||||
for (int32_t iii=0; iii<input.size(); iii++) {
|
for (size_t iii=0; iii<input.size(); iii++) {
|
||||||
input[iii] = cos(phase) * 5.0;
|
input[iii] = cos(phase) * 5.0;
|
||||||
phase += baseCycle;
|
phase += baseCycle;
|
||||||
if (phase >= 2*M_PI) {
|
if (phase >= 2*M_PI) {
|
||||||
@@ -108,28 +112,28 @@ void performanceCompressor() {
|
|||||||
perfo.tic();
|
perfo.tic();
|
||||||
algo.process(&output[0], &input[0], input.size(), 1, audio::format_double);
|
algo.process(&output[0], &input[0], input.size(), 1, audio::format_double);
|
||||||
perfo.toc();
|
perfo.toc();
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
ethread::sleepMilliSeconds((1));
|
||||||
}
|
}
|
||||||
TEST_PRINT("Performance Compressor (double): ");
|
TEST_PRINT("Performance Compressor (double): ");
|
||||||
TEST_PRINT(" blockSize=" << input.size() << " sample");
|
TEST_PRINT(" blockSize=" << input.size() << " sample");
|
||||||
TEST_PRINT(" min < avg < max =" << perfo.getMinProcessing().count() << "ns < "
|
TEST_PRINT(" min < avg < max =" << perfo.getMinProcessing() << " < "
|
||||||
<< perfo.getTotalTimeProcessing().count()/perfo.getTotalIteration() << "ns < "
|
<< perfo.getTotalTimeProcessing().get()/perfo.getTotalIteration() << "ns < "
|
||||||
<< perfo.getMaxProcessing().count() << "ns ");
|
<< perfo.getMaxProcessing());
|
||||||
TEST_PRINT(" min < avg < max= " << (float((perfo.getMinProcessing().count()*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "% < "
|
TEST_PRINT(" min < avg < max= " << (float((perfo.getMinProcessing().get()*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "% < "
|
||||||
<< (float(((perfo.getTotalTimeProcessing().count()/perfo.getTotalIteration())*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "% < "
|
<< (float(((perfo.getTotalTimeProcessing().get()/perfo.getTotalIteration())*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "% < "
|
||||||
<< (float((perfo.getMaxProcessing().count()*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "%");
|
<< (float((perfo.getMaxProcessing().get()*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
void performanceLimiter() {
|
void performanceLimiter() {
|
||||||
std::vector<double> input;
|
etk::Vector<double> input;
|
||||||
input.resize(8192, 0);
|
input.resize(8192, 0);
|
||||||
std::vector<double> output;
|
etk::Vector<double> output;
|
||||||
output.resize(8192, 0);
|
output.resize(8192, 0);
|
||||||
double sampleRate = 48000.0;
|
double sampleRate = 48000.0;
|
||||||
{
|
{
|
||||||
double phase = 0;
|
double phase = 0;
|
||||||
double baseCycle = 2.0*M_PI/sampleRate * 1280.0;
|
double baseCycle = 2.0*M_PI/sampleRate * 1280.0;
|
||||||
for (int32_t iii=0; iii<input.size(); iii++) {
|
for (size_t iii=0; iii<input.size(); iii++) {
|
||||||
input[iii] = cos(phase) * 5.0;
|
input[iii] = cos(phase) * 5.0;
|
||||||
phase += baseCycle;
|
phase += baseCycle;
|
||||||
if (phase >= 2*M_PI) {
|
if (phase >= 2*M_PI) {
|
||||||
@@ -149,28 +153,28 @@ void performanceLimiter() {
|
|||||||
perfo.tic();
|
perfo.tic();
|
||||||
algo.process(&output[0], &input[0], input.size(), 1, audio::format_double);
|
algo.process(&output[0], &input[0], input.size(), 1, audio::format_double);
|
||||||
perfo.toc();
|
perfo.toc();
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
ethread::sleepMilliSeconds((1));
|
||||||
}
|
}
|
||||||
TEST_PRINT("Performance Limiter (double): ");
|
TEST_PRINT("Performance Limiter (double): ");
|
||||||
TEST_PRINT(" blockSize=" << input.size() << " sample");
|
TEST_PRINT(" blockSize=" << input.size() << " sample");
|
||||||
TEST_PRINT(" min < avg < max =" << perfo.getMinProcessing().count() << "ns < "
|
TEST_PRINT(" min < avg < max =" << perfo.getMinProcessing() << " < "
|
||||||
<< perfo.getTotalTimeProcessing().count()/perfo.getTotalIteration() << "ns < "
|
<< perfo.getTotalTimeProcessing().get()/perfo.getTotalIteration() << "ns < "
|
||||||
<< perfo.getMaxProcessing().count() << "ns ");
|
<< perfo.getMaxProcessing());
|
||||||
TEST_PRINT(" min < avg < max = " << (float((perfo.getMinProcessing().count()*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "% < "
|
TEST_PRINT(" min < avg < max = " << (float((perfo.getMinProcessing().get()*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "% < "
|
||||||
<< (float(((perfo.getTotalTimeProcessing().count()/perfo.getTotalIteration())*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "% < "
|
<< (float(((perfo.getTotalTimeProcessing().get()/perfo.getTotalIteration())*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "% < "
|
||||||
<< (float((perfo.getMaxProcessing().count()*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "%");
|
<< (float((perfo.getMaxProcessing().get()*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
void performanceGate() {
|
void performanceGate() {
|
||||||
std::vector<double> input;
|
etk::Vector<double> input;
|
||||||
input.resize(8192, 0);
|
input.resize(8192, 0);
|
||||||
std::vector<double> output;
|
etk::Vector<double> output;
|
||||||
output.resize(8192, 0);
|
output.resize(8192, 0);
|
||||||
double sampleRate = 48000.0;
|
double sampleRate = 48000.0;
|
||||||
{
|
{
|
||||||
double phase = 0;
|
double phase = 0;
|
||||||
double baseCycle = 2.0*M_PI/sampleRate * 1280.0;
|
double baseCycle = 2.0*M_PI/sampleRate * 1280.0;
|
||||||
for (int32_t iii=0; iii<input.size(); iii++) {
|
for (size_t iii=0; iii<input.size(); iii++) {
|
||||||
input[iii] = cos(phase) * 5.0;
|
input[iii] = cos(phase) * 5.0;
|
||||||
phase += baseCycle;
|
phase += baseCycle;
|
||||||
if (phase >= 2*M_PI) {
|
if (phase >= 2*M_PI) {
|
||||||
@@ -190,16 +194,16 @@ void performanceGate() {
|
|||||||
perfo.tic();
|
perfo.tic();
|
||||||
algo.process(&output[0], &input[0], input.size(), 1, audio::format_double);
|
algo.process(&output[0], &input[0], input.size(), 1, audio::format_double);
|
||||||
perfo.toc();
|
perfo.toc();
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
ethread::sleepMilliSeconds((1));
|
||||||
}
|
}
|
||||||
TEST_PRINT("Performance Gate (double): ");
|
TEST_PRINT("Performance Gate (double): ");
|
||||||
TEST_PRINT(" blockSize=" << input.size() << " sample");
|
TEST_PRINT(" blockSize=" << input.size() << " sample");
|
||||||
TEST_PRINT(" min < avg < max =" << perfo.getMinProcessing().count() << "ns < "
|
TEST_PRINT(" min < avg < max =" << perfo.getMinProcessing() << " < "
|
||||||
<< perfo.getTotalTimeProcessing().count()/perfo.getTotalIteration() << "ns < "
|
<< perfo.getTotalTimeProcessing().get()/perfo.getTotalIteration() << "ns < "
|
||||||
<< perfo.getMaxProcessing().count() << "ns ");
|
<< perfo.getMaxProcessing());
|
||||||
TEST_PRINT(" min < avg < max = " << (float((perfo.getMinProcessing().count()*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "% < "
|
TEST_PRINT(" min < avg < max = " << (float((perfo.getMinProcessing().get()*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "% < "
|
||||||
<< (float(((perfo.getTotalTimeProcessing().count()/perfo.getTotalIteration())*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "% < "
|
<< (float(((perfo.getTotalTimeProcessing().get()/perfo.getTotalIteration())*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "% < "
|
||||||
<< (float((perfo.getMaxProcessing().count()*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "%");
|
<< (float((perfo.getMaxProcessing().get()*sampleRate)/double(input.size()))/1000000000.0)*100.0 << "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -208,12 +212,12 @@ void performanceGate() {
|
|||||||
int main(int _argc, const char** _argv) {
|
int main(int _argc, const char** _argv) {
|
||||||
// the only one init for etk:
|
// the only one init for etk:
|
||||||
etk::init(_argc, _argv);
|
etk::init(_argc, _argv);
|
||||||
std::string inputName = "";
|
etk::Path inputName = "";
|
||||||
bool performance = false;
|
bool performance = false;
|
||||||
bool perf = false;
|
bool perf = false;
|
||||||
int64_t sampleRate = 48000;
|
int64_t sampleRate = 48000;
|
||||||
for (int32_t iii=0; iii<_argc ; ++iii) {
|
for (int32_t iii=0; iii<_argc ; ++iii) {
|
||||||
std::string data = _argv[iii];
|
etk::String data = _argv[iii];
|
||||||
if (etk::start_with(data,"--in=")) {
|
if (etk::start_with(data,"--in=")) {
|
||||||
inputName = &data[5];
|
inputName = &data[5];
|
||||||
} else if (data == "--performance") {
|
} else if (data == "--performance") {
|
||||||
@@ -241,15 +245,23 @@ int main(int _argc, const char** _argv) {
|
|||||||
performanceGate();
|
performanceGate();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (inputName == "") {
|
if (inputName.isEmpty() == true) {
|
||||||
TEST_ERROR("Can not Process missing parameters...");
|
TEST_ERROR("Can not Process missing parameters...");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
TEST_INFO("Read input:");
|
TEST_INFO("Read input:");
|
||||||
std::vector<double> inputData = convert(etk::FSNodeReadAllDataType<int16_t>(inputName));
|
etk::Vector<int16_t> tmpData;
|
||||||
|
{
|
||||||
|
ememory::SharedPtr<etk::io::Interface> fileIO = etk::uri::get(inputName);
|
||||||
|
fileIO->open(etk::io::OpenMode::Read);
|
||||||
|
tmpData = fileIO->readAll<int16_t>();
|
||||||
|
fileIO->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
etk::Vector<double> inputData = convert(tmpData);
|
||||||
TEST_INFO(" " << inputData.size() << " samples");
|
TEST_INFO(" " << inputData.size() << " samples");
|
||||||
// resize output :
|
// resize output :
|
||||||
std::vector<double> output;
|
etk::Vector<double> output;
|
||||||
output.resize(inputData.size(), 0);
|
output.resize(inputData.size(), 0);
|
||||||
// process in chunk of 256 samples
|
// process in chunk of 256 samples
|
||||||
int32_t blockSize = 256;
|
int32_t blockSize = 256;
|
||||||
@@ -271,7 +283,7 @@ int main(int _argc, const char** _argv) {
|
|||||||
algo.process(audio::format_double, &output[iii*blockSize], &inputData[iii*blockSize], blockSize, 1);
|
algo.process(audio::format_double, &output[iii*blockSize], &inputData[iii*blockSize], blockSize, 1);
|
||||||
if (perf == true) {
|
if (perf == true) {
|
||||||
perfo.toc();
|
perfo.toc();
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
ethread::sleepMilliSeconds((1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@@ -293,7 +305,7 @@ int main(int _argc, const char** _argv) {
|
|||||||
algo.process(&output[iii*blockSize], &inputData[iii*blockSize], blockSize, 1, audio::format_double);
|
algo.process(&output[iii*blockSize], &inputData[iii*blockSize], blockSize, 1, audio::format_double);
|
||||||
if (perf == true) {
|
if (perf == true) {
|
||||||
perfo.toc();
|
perfo.toc();
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
ethread::sleepMilliSeconds((1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,15 +313,23 @@ int main(int _argc, const char** _argv) {
|
|||||||
if (perf == true) {
|
if (perf == true) {
|
||||||
TEST_INFO("Performance Result: ");
|
TEST_INFO("Performance Result: ");
|
||||||
TEST_INFO(" blockSize=" << blockSize << " sample");
|
TEST_INFO(" blockSize=" << blockSize << " sample");
|
||||||
TEST_INFO(" min=" << perfo.getMinProcessing().count() << " ns");
|
TEST_INFO(" min=" << perfo.getMinProcessing());
|
||||||
TEST_INFO(" max=" << perfo.getMaxProcessing().count() << " ns");
|
TEST_INFO(" max=" << perfo.getMaxProcessing());
|
||||||
TEST_INFO(" avg=" << perfo.getTotalTimeProcessing().count()/perfo.getTotalIteration() << " ns");
|
TEST_INFO(" avg=" << perfo.getTotalTimeProcessing().get()/perfo.getTotalIteration() << " ns");
|
||||||
|
|
||||||
TEST_INFO(" min=" << (float((perfo.getMinProcessing().count()*sampleRate)/blockSize)/1000000000.0)*100.0 << " %");
|
TEST_INFO(" min=" << (float((perfo.getMinProcessing().get()*sampleRate)/blockSize)/1000000000.0)*100.0 << " %");
|
||||||
TEST_INFO(" max=" << (float((perfo.getMaxProcessing().count()*sampleRate)/blockSize)/1000000000.0)*100.0 << " %");
|
TEST_INFO(" max=" << (float((perfo.getMaxProcessing().get()*sampleRate)/blockSize)/1000000000.0)*100.0 << " %");
|
||||||
TEST_INFO(" avg=" << (float(((perfo.getTotalTimeProcessing().count()/perfo.getTotalIteration())*sampleRate)/blockSize)/1000000000.0)*100.0 << " %");
|
TEST_INFO(" avg=" << (float(((perfo.getTotalTimeProcessing().get()/perfo.getTotalIteration())*sampleRate)/blockSize)/1000000000.0)*100.0 << " %");
|
||||||
}
|
}
|
||||||
etk::FSNodeWriteAllDataType<int16_t>("output.raw", convert(output));
|
{
|
||||||
|
ememory::SharedPtr<etk::io::Interface> fileIO = etk::uri::get(etk::Path("output.raw"));
|
||||||
|
if (fileIO->open(etk::io::OpenMode::Write) == false) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fileIO->writeAll<double>(output);
|
||||||
|
fileIO->close();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
0.2.0
|
1.0.0-dev
|
||||||
Reference in New Issue
Block a user