Skip to content

Commit

Permalink
First commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
tangshaozhu committed Feb 9, 2022
1 parent dedf097 commit 438dd13
Show file tree
Hide file tree
Showing 21 changed files with 1,458 additions and 32 deletions.
39 changes: 7 additions & 32 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,32 +1,7 @@
# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app
*.user
*.swp
*.vcxproj
*.filters
/Debug/
/Release/
.gitignore
50 changes: 50 additions & 0 deletions Crossover.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "stdafx.h"
#include "Crossover.h"


// y = (exp(x*a)-1)/(exp(th * a) - 1)
// y' = a * (exp(x*a)) / (exp(th * a) - 1)


Crossover::Crossover(float _a, float _th)
{
a = fabs(_a);
th = fabs(_th);

// y' = 1
// a * (exp(x*a)) / (exp(th * a) - 1) = 1
// a * (exp(x*a)) = (exp(th * a) - 1)
// exp(x*a) = (exp(th * a) - 1) / a
// x * a = ln ((exp(th * a) - 1) / a)
// x = ln ((exp(th * a) - 1) / a) / a
double temp = log((exp(th * a) - 1) / a) / a; // logº¯Êýµ×Ϊe
if (temp < 0.f) {
theta_b = theta = 0.0f;
}
else {
theta = temp;
theta_b = (exp((double)temp * a) - 1) / (exp((double)th * a) - 1) - (double)temp;
}
}


Crossover::~Crossover()
{
}

float Crossover::GetSample(float input)
{
float ret;
uint32 sign = *((uint32*)(&input)) & 0x80000000;
float absinput = abs(input);
if (absinput < theta) {
ret = (exp(absinput * a) - 1) / (exp(th * a) - 1);
*((uint32*)(&ret)) |= sign;
return ret;
}
else {
ret = absinput + theta_b;
*((uint32*)(&ret)) |= sign;
return ret;
}
}
19 changes: 19 additions & 0 deletions Crossover.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once
#include "Disorter.h"

// 交越失真,继承失真器
class Crossover :
public Disorter
{
public:
Crossover(float _a, float _th);
~Crossover();

private:
virtual float GetSample(float input); // 应该加上virtual使程序清晰
float a;
float th;
float theta;
float theta_b;
};

32 changes: 32 additions & 0 deletions Disorter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "stdafx.h"
#include "Disorter.h"


Disorter::Disorter()
{
}


Disorter::~Disorter()
{
}

void Disorter::ProcessWav(WaveFile& _wav, uint32 _start, int _len)
{
DWORD datalen = _wav.dataSize / sizeof(float32);

if (_wav.pData == nullptr || datalen <= _start * _wav.channels || _len == 0) {
printf("wav object No data!\n");
return;
}
DWORD leftlen = datalen - _start * _wav.channels;
DWORD lentotal = ((DWORD)_len) * _wav.channels;
lentotal = lentotal < leftlen ? lentotal : leftlen;
float32* pDataOffset = _wav.pData + _start * _wav.channels; // Êý¾ÝÔ´µØÖ·

for (DWORD i = 0; i < lentotal; i++)
{
pDataOffset[i] = GetSample(pDataOffset[i]);
}

}
17 changes: 17 additions & 0 deletions Disorter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#define _USE_MATH_DEFINES
#include <cmath>
#include "WaveFile.h"

class Disorter
{
public:
Disorter();
virtual ~Disorter();
void ProcessWav(WaveFile& _wav, uint32 _start = 0, int _len = 0x7fffffff);

protected:
virtual float GetSample(float input) = 0; // ´¿Ð麯Êý
};

76 changes: 76 additions & 0 deletions FirFilter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "stdafx.h"
#include "FirFilter.h"

#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif

FirFilter::FirFilter(const float32* coef, uint32 coeflen)
{
if (coef == nullptr || coeflen == 0) {
throw "Filter ctor failed";
}
len = coeflen * 2 - 1;
h = new float32[len]; // 滤波器长度
flt = h + coeflen - 1;
for (int32 i = 0; i < (int32)coeflen; i++)
{
fderef(i) = coef[i];
fderef(-i) = fderef(i);
}
}


FirFilter::~FirFilter()
{
if (h != nullptr) {
delete[] h;
h = nullptr;
}
}

// 滤波处理。滤波器从中心点开始计算
void FirFilter::ProcessWav(WaveFile& _wav, uint32 _start, int _len)
{
DWORD datalen = _wav.dataSize / sizeof(float32);

if (_wav.pData == nullptr || datalen <= _start * _wav.channels || _len == 0) {
printf("wav object No data!\n");
return;
}
DWORD leftlen = datalen - _start * _wav.channels;
DWORD lentotal = ((DWORD)_len) * _wav.channels;// 待处理采样总个数
lentotal = lentotal < leftlen ? lentotal : leftlen;
float32* pDataOffset = _wav.pData + _start * _wav.channels; // 数据源地址
float32* pProc = new float32[lentotal](); // 初始化0

int start, end;
int i,j;
if (_wav.GetChannels() == 1) {
for (i = 0; i < lentotal; ++i) {
start = - min(len / 2, i);
end = min(lentotal - i - 1, len / 2);
for (j = start; j <= end; ++j){ // 系数的下标
pProc[i] += fderef(j) * pDataOffset[i + j];
}
}
}
else {
stereo_f32_t pDualData = (stereo_f32_t)pDataOffset;
stereo_f32_t pDualProc = (stereo_f32_t)pProc;
int singlelen = lentotal / 2;
for (i = 0; i < singlelen; ++i) {
start = -min(len / 2, i);
end = min(singlelen - i - 1, len / 2);
for (j = start; j <= end; ++j){ // 系数的下标
pDualProc[i][0] += fderef(j) * pDualData[i + j][0];
pDualProc[i][1] += fderef(j) * pDualData[i + j][1];
}
}
}

memcpy_s(pDataOffset, lentotal * sizeof(float32), pProc, lentotal * sizeof(float32));
delete[] pProc;
pProc = nullptr;

}
19 changes: 19 additions & 0 deletions FirFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include "WaveFile.h"

#define fderef(index) (*((this->flt) + (index))) // 解引用,为了支持负数下标

class FirFilter
{
public:
FirFilter(const float32* coef, uint32 coeflen);
virtual ~FirFilter();
virtual void ProcessWav(WaveFile& _wav, uint32 _start = 0, int _len = 0x7fffffff);

protected:
float32* h; // 申请内存
float32* flt; // 指向滤波器中心
uint32 len;
};

74 changes: 74 additions & 0 deletions IirFilter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "stdafx.h"
#include "IirFilter.h"


IirFilter::IirFilter(mult_biquad_state& _sec1, mult_biquad_state& _sec2)
{
sec1L = _sec1;
sec1R = _sec1;
sec2L = _sec2;
sec2R = _sec2;
}


IirFilter::~IirFilter()
{
}


void IirFilter::ProcessWav(WaveFile& _wav, uint32 _start, int _len)
{
DWORD datalen = _wav.dataSize / sizeof(float32);

if (_wav.pData == nullptr || datalen <= _start * _wav.channels || _len == 0) {
printf("wav object No data!\n");
return;
}
DWORD leftlen = datalen - _start * _wav.channels;
DWORD lentotal = ((DWORD)_len) * _wav.channels;// 待处理采样总个数
lentotal = lentotal < leftlen ? lentotal : leftlen;
float32* pDataOffset = _wav.pData + _start * _wav.channels; // 数据源地址
float32* pProc = new float32[lentotal](); // 初始化0

int i;

sec1L.x1 = 0.f;
sec1L.x2 = 0.f;
sec1L.y1 = 0.f;
sec1L.y2 = 0.f;
sec1R.x1 = 0.f;
sec1R.x2 = 0.f;
sec1R.y1 = 0.f;
sec1R.y2 = 0.f;
sec2L.x1 = 0.f;
sec2L.x2 = 0.f;
sec2L.y1 = 0.f;
sec2L.y2 = 0.f;
sec2R.x1 = 0.f;
sec2R.x2 = 0.f;
sec2R.y1 = 0.f;
sec2R.y2 = 0.f;

if (_wav.GetChannels() == 1) {
for (i = 0; i < (int)lentotal; ++i) {
pProc[i] = mult_biquad(&sec1L, pDataOffset[i]);
pProc[i] = mult_biquad(&sec2L, pProc[i]);
}
}
else {
stereo_f32_t pDualData = (stereo_f32_t)pDataOffset;
stereo_f32_t pDualProc = (stereo_f32_t)pProc;
int singlelen = lentotal / 2;
for (i = 0; i < singlelen; ++i) {
pDualProc[i][0] = mult_biquad(&sec1L, pDualData[i][0]);
pDualProc[i][0] = mult_biquad(&sec2L, pDualProc[i][0]);

pDualProc[i][1] = mult_biquad(&sec1R, pDualData[i][1]);
pDualProc[i][1] = mult_biquad(&sec2R, pDualProc[i][1]);
}
}

memcpy_s(pDataOffset, lentotal * sizeof(float32), pProc, lentotal * sizeof(float32));
delete[] pProc;
pProc = nullptr;
}
14 changes: 14 additions & 0 deletions IirFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once
#include "WaveFile.h"
#include "iir.h"

class IirFilter
{
public:
IirFilter(mult_biquad_state& _sec1, mult_biquad_state& _sec2);
virtual ~IirFilter();
virtual void ProcessWav(WaveFile& _wav, uint32 _start = 0, int _len = 0x7fffffff);

protected:
mult_biquad_state sec1L, sec2L, sec1R, sec2R;
};
30 changes: 30 additions & 0 deletions ReadMe.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
========================================================================
控制台应用程序:WaveFileDemo 项目概述
========================================================================

应用程序向导已为您创建了此 WaveFileDemo 应用程序。

本文件概要介绍组成 WaveFileDemo 应用程序的每个文件的内容。


WaveFileDemo.vcxproj
这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。

WaveFileDemo.vcxproj.filters
这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。

WaveFileDemo.cpp
这是主应用程序源文件。

/////////////////////////////////////////////////////////////////////////////
其他标准文件:

StdAfx.h, StdAfx.cpp
这些文件用于生成名为 WaveFileDemo.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。

/////////////////////////////////////////////////////////////////////////////
其他注释:

应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。

/////////////////////////////////////////////////////////////////////////////
Loading

0 comments on commit 438dd13

Please sign in to comment.