Why my window function isn't removing harmonics? - c++

I have been working on creating a mixed wave signal. My code is in c++ :
Server signal:
void server_sineWave(BitDepth buffer[], double sin_freq, double beep_freq) {
BitDepth amplitude = std::numeric_limits<BitDepth>::max() * 0.5;
QWORD c = 0;
double d = (samplerate / sin_freq);
int initial = NUM_SAMPLES / 25;
for (QWORD i = 0; i < NUM_SAMPLES; i += channels) {
buffer[i] = amplitude * sin((2 * pi * sin_freq * i) / samplerate); // sin wave generated at "freq"
if (i == initial) {
for (QWORD j = 0; j < 480; j++) {
double stream = amplitude * sin((2 * pi * sin_freq * i / samplerate));
double beep = amplitude * sin((2 * pi * beep_freq * j / samplerate));
double multiplier = .4 * (1 - cos(2 * pi * j / 480));
buffer[i] = stream + (beep * multiplier);
i++;
}
initial = i + 19200.0;
}
}
}
Client signal:
void client_sineWave(BitDepth buffer[], double sin_freq, double beep_freq) {
BitDepth amplitude = std::numeric_limits<BitDepth>::max() * 0.5;
QWORD c = 0;
double d = (samplerate / sin_freq);
int initial = NUM_SAMPLES / 25;
for (QWORD i = 0; i < NUM_SAMPLES; i += channels) {
buffer[i] = amplitude * sin(2 * pi * sin_freq * i / samplerate); // sin wave generated at "freq"
if (i == initial) {
for (QWORD j = 0; j < 480; j++) {
double stream = amplitude * sin((2 * pi * sin_freq * i / samplerate));
double beep = amplitude * sin((2 * pi * beep_freq * j / samplerate));
double multiplier = .4 * (1 - cos(2 * pi * j / 480));
buffer[i] = stream + (beep * multiplier);
// buffer[i] += (beep * multiplier);
i++;
}
initial = i + 19200.0;
//(1000 + rand() % 10000)
//double deg = 360.0 / d;
//buffer[i] = buffer[i + (1 * (channels - 1))] = sin((c++ * deg) * pi / 180) * amplitude;
}
}
}
Mixing of server and client signals:
void mix(BitDepth buffer[], BitDepth server[], BitDepth client[], double duration_milliseconds) {
QWORD num_samples = duration_milliseconds * (NUM_SAMPLES / 10000.0);
double tmp = 0;
QWORD size = NUM_SAMPLES + num_samples;
BitDepth *server_delay = new BitDepth[size];
BitDepth *client_delay = new BitDepth[size];
for (QWORD i = 0; i < size; i++) {
if (i < num_samples) {
server_delay[i] = 0;
client_delay[i + NUM_SAMPLES] = 0;
}
if (i > num_samples) {
server_delay[i] = server[i - num_samples];
client_delay[i - num_samples] = client[i - num_samples];
}
}
for (QWORD i = 0; i < NUM_SAMPLES; i += channels) {
// double multiplier = .5 * (1 - cos(2 * pi * i / NUM_SAMPLES-1));
// double multiplier = (0.54 - 0.46 * cos(2.0 * M_PI * (double) i / (double) (NUM_SAMPLES - 1)));
// server_delay[i] = multiplier * (server_delay[i]);
// client_delay[i] = multiplier * (client_delay[i]);
tmp = server_delay[i] + client_delay[i];
if (tmp > 32767) {
tmp = 32767;
} else if (tmp < -32768) {
tmp = -32768;
}
buffer[i] = tmp;
}
}
My Result in spectrogram from the above code:
Now, when I change the amplitude by increasing value from 0.5 to 0.8, in the following line:
BitDepth amplitude = std::numeric_limits<BitDepth>::max() * 0.5;
to
BitDepth amplitude = std::numeric_limits<BitDepth>::max() * 0.8;
I get following result:
I am new in DSP c++ programming and I really don't know what is this issue and how to resolve this issue?
Please help me in solving this issue.
thanks.

As Suggested by #PaulR, clipping was causing a lot of harmonics.
Your waveform is clipping (because 0.8 + 0.8 > 1.0), which will generate a lot of harmonics - look at the data in your debugger and you’ll see lots of flat peaks at +/- 32k.
So, after taking care of this limit. My issue is resolved.
Thanks alot.

Related

How to add random term in different steps of numerical integration

For the function below, I would not add the noise (Inoise in the code below) in every time step but, for example, only in every second time step. So while dt=0.0025 serves as the time step for the numerical integration, I would, for example, add Inoise only in every second time step (i.e. in 0.005 steps).
What is the best way to insert this into my existing function?
runs = 1000;
t_end = 5;
dt = 0.0025;
t_steps = t_end/dt;
for(int j=0; j<runs; j++){
double vT = v0;
double mT = m0;
double hT = h0;
double nT = n0;
for(int i=0; i<t_steps; i++){
double IStim = 0.0;
if ((delay / dt <= (double)i) && ((double)i <= (delay + duration) / dt))
IStim = I;
mT = (mT + dt * alphaM(vT)) / (1.0 + dt * (alphaM(vT) + betaM(vT)));
hT = (hT + dt * alphaH(vT)) / (1.0 + dt * (alphaH(vT) + betaH(vT)));
nT = (nT + dt * alphaN(vT)) / (1.0 + dt * (alphaN(vT) + betaN(vT)));
const double iNa = gNa * pow(mT, 3.0) * hT * (vT - vNa);
const double iK = gK * pow(nT, 4.0) * (vT - vK);
const double iL = gL * (vT-vL);
const double Inoise = (doubleRand() * knoise * sqrt(gNa * A));
const double IIon = ((iNa + iK + iL) * A) + Inoise;
vT += ((-IIon + IStim) / C) * dt;
voltage[i] = vT;
if(vT > 60.0) {
count++;
break;
}
}
}
return count;
}
You could accumulate the elapsed time and only add the noise once enough steps have passed:
double elapsedTime = 0;
double INoiseThreshold = 0.005;
for(int j=0; j<runs; j++){
//...
for(int i=0; i<t_steps; i++){
//...
double Inoise = 0;
elapsedTime += dt;
if(elapsedTime >= INoiseThreshold){
Inoise = (doubleRand() * knoise * sqrt(gNa * A));
elapsedTime = 0;
}
const double IIon = ((iNa + iK + iL) * A) + Inoise;
//...
}
}
return count;
Instead of comparing the floating point numbers directly, you could check if their differences are within an small epsilon to allow for rounding errors.
Instead of making the value of Inoise dependent on the condition, you could make the presence in the IIon formula dependent e.g.:
const double IIon = ((iNa + iK + iL) * A) + (elapsedTime >= INoiseThreshold) ? Inoise : 0;
just remember to reset elapsedTime once it surpassed the threshold.

Bandlimited synthesis - get number of harmonics

I'm doing a simple brute force bandlimited synthesis by summing up harmonics. I copied the formulas from Wikipedia but there was no information how to get the highest harmonic number. Can someone give me a formula?
Here's what I've come up with intuition:
Pulse wave:
numharmonics = samplerate / 2.0 / frequency;
float sample = dutycycle;
// Precomputing 2 * Pi * (phase - duty / 2).
// It is used inside cos() a lot.
float precompute1 = (phase - dutycycle / 2.0) * 2.0 * M_PI;
for (std::size_t i = 1; i <= numharmonics; ++i)
{
float harmonic = 2.0 / (i * M_PI) *
std::sin(M_PI * i * dutycycle) *
std::cos(i * precompute1);
sample += harmonic;
}
sample = sample * 2.0 - 1.0;
phase += phasedelta;
return sample;
Triangle wave:
numharmonics = (samplerate / 2.0 / frequency - 1.0) / 2.0;
float sample = 0.0;
// Precomputing 2 * Pi * phase. It is used inside sin() a lot.
float precompute1 = 2.0 * M_PI * phase;
for (std::size_t i = 0; i <= numharmonics; ++i)
{
float harmonic = std::sin((2 * i + 1) * precompute1) /
std::pow((2 * i + 1), 2);
if ((i % 2) == 0)
{
sample += harmonic;
}
else
{
sample -= harmonic;
}
}
sample = sample * 8.0 / std::pow(M_PI, 2);
phase += phasedelta;
return sample;
Sawtooth wave:
numharmonics = samplerate / 2.0 / frequency;
float sample = 0.0;
// Precomputing 2 * Pi * phase. It is used inside sin() a lot.
float precompute1 = 2.0 * M_PI * phase;
for (std::size_t i = 1; i <= numharmonics; ++i)
{
float harmonic = std::sin(precompute1 * i) / i;
if ((i % 2) == 1)
{
sample += harmonic;
}
else
{
sample -= harmonic;
}
}
sample = -1.0 / M_PI * sample;
phase += phasedelta;
return sample;

Unexpected convergence of calculated values, can you help me figure out why? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am writing a molecular dynamics program to create an lattice and populate it with atoms/molecules. These then are given random velocities and the system is initialized. Then throughout time the molecules interact with each other and exert forces on each other.
I've tried to make my program as readable as possible.
My issue is when the code is run, the values of everything I'm interested in, mainly the vectors _tempreture, _pressure, _totalEnergy, _interactionEnergy, _kineticEnergy all seem to converge (after 5 runs) to certain values. These values then do not change throughout the rest of the runs and sometimes will randomly spike, then drop back down.
I can't figure out the unexpected behavior of my code, and I've been looking at it hours upon hours. I hoping one of you bright guys will be able to help me.
//in MD.h
#ifndef MD_H
#define MD_H
#include <iostream>
#include <random>
#include <time.h>
#include <vector>
#include <string>
#include <fstream>
class MD{
public:
MD();
~MD();
void initLatice();
void simulate(int _runs);
void wrtieToFile(std::string fileName);
double randomValue(double upper, double lower);
private:
double _nMolecules;
double _estKineticEnergy;
double _dt;
double _density;
bool _tempscale;
double _energyCorrection;
double _pressureCorrection;
double _nFCC = 4;
double _truncationSeperation;
double _sidelength;
double _pi = 3.142;
std::vector<double> x_data, y_data, z_data;
std::vector<double> _vX, _vY, _vZ;
std::vector<double> _xPos, _yPos, _zPos;
std::vector<double> _totalEnergy, _kineticEnergy, _interactionEnergy, _pressure, _tempreture;
std::vector<double> _radialDist, _radialDistCoord;
};
#endif
in case anyone is wondering the next file doesn't contain the definition for writeToFile, I decided not to paste it on here to save space.
//in MD.cpp
#include "MD.h"
MD::MD() : _radialDist(201, 0.0), _radialDistCoord(201, 0.0) {
_dt = 0.005;
_density = 1.0;
_tempscale = true;
_nMolecules = pow(_nFCC, 3) * 4;
x_data = { 0.25, 0.75, 0.75, 0.25 };
y_data = { 0.25, 0.75, 0.25, 0.75 };
z_data = { 0.25, 0.25, 0.75, 0.75 };
_sidelength = pow((_nFCC / _density), 1. / 3.);
_truncationSeperation = 2.5;
if (_truncationSeperation > _sidelength / 2.0)
_truncationSeperation = _sidelength / 2.0;
_energyCorrection = (8.0 * _pi * _density)*(1.0 / (9.0 * pow(_truncationSeperation, 9)) - 1 / (3.0 * pow(_truncationSeperation, 3)));
_pressureCorrection = (16.0 * _pi * pow(_density, 2))*(2.0 / (9.0 * pow(_truncationSeperation, 9)) - 1 / (3.0 * pow(_truncationSeperation, 3)));
}
MD::~MD(){}
double MD::randomValue(double upper, double lower)
{
double returnValue;
do{
returnValue = upper + (rand() / (RAND_MAX / (lower - upper)));
} while (returnValue > upper || returnValue < lower);
return returnValue;
}
void MD::initLatice(){
int count = 0;
double x_init = 0, y_init = 0, z_init = 0;
double _tempreture = 1.0;
_estKineticEnergy = 0.5 * (3.0 * _nMolecules - 4.0) * _tempreture;
srand(time(NULL));
for (int i = 0; i < 4; i++){
for (int a = 1; a <= _nFCC; a++){
for (int b = 1; b <= _nFCC; b++){
for (int c = 1; c <= _nFCC; c++){
_xPos.push_back(_sidelength*(a - 1 + x_data[i]) / _nFCC);
_vX.push_back(randomValue(0.5, -0.5));
x_init += _vX[count] / _nMolecules;
_yPos.push_back(_sidelength*(b - 1 + y_data[i]) / _nFCC);
_vY.push_back(randomValue(0.5, -0.5));
y_init += _vY[count] / _nMolecules;
_zPos.push_back(_sidelength*(c - 1 + z_data[i]) / _nFCC);
_vZ.push_back(randomValue(0.5, -0.5));
z_init += _vZ[count] / _nMolecules;
count++;
}
}
}
}
double velocityScale = 0, kineticEnergy = 0;
for (int i = 0; i < _nMolecules; i++){
_vX[i] -= x_init;
_vY[i] -= y_init;
_vZ[i] -= z_init;
kineticEnergy += 0.5 * (pow(_vX[i], 2) + pow(_vY[i], 2) + pow(_vZ[i], 2));
}
velocityScale = sqrt(_estKineticEnergy / kineticEnergy);
for (int i = 0; i < _nMolecules; i++){
_vX[i] = _vX[i] * velocityScale;
_vY[i] = _vY[i] * velocityScale;
_vZ[i] = _vZ[i] * velocityScale;
}
}
void MD::simulate(int _runs){
double force = 0;
double seperationSquared = 0;
double interactionEnergy = 0;
double kineticEnergy = 0;
double pressure = 0;
for (int run = 0; run <= _runs; run++){
interactionEnergy = 0;
pressure = 0;
std::vector<double> force_x(256, 0.0);
std::vector<double> force_y(256, 0.0);
std::vector<double> force_z(256, 0.0);
for (int i = 0; i < _nMolecules - 1; i++){
double xI = _xPos[i], yI = _yPos[i], zI = _zPos[i];
for (int j = i + 1; j < _nMolecules; j++){
double x = xI - _xPos[j];
double y = yI - _yPos[j];
double z = zI - _zPos[j];
if (x > _sidelength / 2.0)
x -= _sidelength;
if (y > _sidelength / 2.0)
y -= _sidelength;
if (z > _sidelength / 2.0)
z -= _sidelength;
if (x < -_sidelength / 2.0)
x += _sidelength;
if (y < -_sidelength / 2.0)
y += _sidelength;
if (z < -_sidelength / 2.0)
z += _sidelength;
seperationSquared = pow(x, 2) + pow(y, 2) + pow(z, 2);
if (seperationSquared <= (pow(_truncationSeperation, 2))){
interactionEnergy += 4. * ((1. / pow(seperationSquared, 6)) - (1. / pow(seperationSquared, 3)));
force = 24. * ((2. / pow(seperationSquared, 7)) - (1. / pow(seperationSquared, 4)));
force_x[i] += x * force;
force_y[i] += y * force;
force_z[i] += z * force;
force_x[j] -= x * force;
force_y[j] -= y * force;
force_z[j] -= z * force;
pressure += force * seperationSquared;
int histCounter = ceil(sqrt(seperationSquared) * (200.0/_truncationSeperation));
_radialDist[histCounter] += 1.0;
}
}
}
//thermostating
double velocityScale = 0;
if (_tempscale == true){
kineticEnergy = 0;
for (int i = 0; i < _nMolecules; i++)
kineticEnergy += 0.5 * (pow(_vX[i], 2) + pow(_vY[i], 2) + pow(_vZ[i], 2));
velocityScale = sqrt(_estKineticEnergy / kineticEnergy);
}
else { velocityScale = 1.0; }
kineticEnergy = 0;
//applying verlets leapfrog algorithm
for (int i = 0; i < _nMolecules; i++){
_vX[i] = _vX[i] * velocityScale + force_x[i] * _dt;
_xPos[i] += _vX[i] * _dt;
_vY[i] = _vY[i] * velocityScale + force_y[i] * _dt;
_yPos[i] += _vY[i] * _dt;
_vZ[i] = _vZ[i] * velocityScale + force_z[i] * _dt;
_zPos[i] += _vZ[i] * _dt;
kineticEnergy += 0.5 * (pow(_vX[i], 2) + pow(_vY[i], 2) + pow(_vZ[i], 2));
//check if the particle is still within the box
if (_xPos[i] > _sidelength)
_xPos[i] -= _sidelength;
if (_yPos[i] > _sidelength)
_yPos[i] -= _sidelength;
if (_zPos[i] > _sidelength)
_zPos[i] -= _sidelength;
if (_xPos[i] < 0.0)
_xPos[i] += _sidelength;
if (_yPos[i] < 0.0)
_yPos[i] += _sidelength;
if (_zPos[i] < 0.0)
_zPos[i] += _sidelength;
}
_kineticEnergy.push_back(kineticEnergy / _nMolecules);
_interactionEnergy.push_back((interactionEnergy / _nMolecules) + _energyCorrection);
_totalEnergy.push_back(_kineticEnergy[run] + _interactionEnergy[run]);
if (_tempscale == true)
_tempreture.push_back(_nMolecules * 2. * _kineticEnergy[run] / (3.0 * _nMolecules - 4.0));
else
_tempreture.push_back(_nMolecules * 2. * _kineticEnergy[run] / (3.0 * _nMolecules - 3.0));
_pressure.push_back((2.0 * _kineticEnergy[run] * _nMolecules + pressure) / (3.0*(pow(_sidelength, 3) + _pressureCorrection)));
}
for (int i = 1; i <= 200; i++){
double r = i * _truncationSeperation / 200.0;
_radialDistCoord[i] = _radialDistCoord[i - 1] + 2.0 * _radialDist[i] * 10 / _runs / _nMolecules;
_radialDist[i] = _radialDist[i] / (2.0*_pi*r*r*(_truncationSeperation/200.0)*_density*_runs*_nMolecules);
}
}
and finally...
//in main.cpp
#include "MD.h"
int main(){
MD myMD;
myMD.initLatice();
myMD.simulate(400);
std::string fileName = "myFile.txt";
myMD.wrtieToFile(fileName);
return 0;
}
Many thanks!

How to implement overlap add method?

I implemented my filter, where overlap add method to prevent circular convultion is used.
input - file with noise, output should be filtered file.
My result: out is slightly modified, frequencies aren`t cut
My guess is that I wrongly multiply in the frequency domain input signal on the filter kernel
(My intention is to cut off frequencies that aren't in range [300,3700]). How multiplication should be done?
I construct kernel using blackmanwindow - is my understanding correct? ( I compute amount of frequency per one sample of filter, then go through samples and see if it is in range I want to cut off I calculate frequency using formula for Blackman window.)
I just started learning DSP.
Here is my implementation (what is wrong with it???):
void DeleteFrequencies(char* fileWithNoise, char* resultFile, const int bufferSize, int lowestFrequency, int highestFrequency, int sampleRate )
{
// |1|. files
std::fstream in;
std::fstream out;
in.open (fileWithNoise, std::ios::in | std::ios::binary);
out.open(resultFile, std::ios::out | std::ios::binary);
// |2|. Filter kernel design. I shall use blackman window
// fundamental params
const int filterKernelLength = 200; // 512
const int filterMaxFrequency = sampleRate / 2; // 8000 / 2
const int frequencyPerSamle = filterMaxFrequency / filterKernelLength;
double *RealFilterResp = new double [bufferSize / 2];
double *ImmFilterResp = new double [bufferSize / 2];
// coefficients for Blackman window
const double a0 = 0.42659;
const double a1 = 0.49656;
const double a2 = 0.076849;
// construct filter kernel
for (int i = 0 ; i < bufferSize / 2; ++i)
{
if ( i >= filterKernelLength ) // padd filter kernel with zeroes
{
RealFilterResp[i] = 0;
ImmFilterResp[i] = 0;
}
else if (i * frequencyPerSamle < lowestFrequency || i * frequencyPerSamle > highestFrequency)
{
// apply blackman window (to eleminate frequencies < 300 hz and > 3700 hz)
RealFilterResp[i] = a0 - a1 * cos (2 * M_PI * i / (bufferSize / 2 - 1)) + a2 * cos (4 * M_PI / (bufferSize / 2 - 1));
ImmFilterResp[i] = a0 - a1 * cos (2 * M_PI * i / (bufferSize / 2 - 1)) + a2 * cos (4 * M_PI / (bufferSize / 2 - 1));
}
else
{
RealFilterResp[i] = 1;
ImmFilterResp[i] = 1;
}
}
// |3|. overlap add method
// calculate parameters for overlap add method (we use it to prevent circular convultion)
const int FFT_length = pow (2.0 ,(int)(log(bufferSize + filterKernelLength - 1.0)/log(2.0)) + 1.0);
double *OLAP = new double[bufferSize / 2 ]; // holds the overlapping samples from segment to segment
memset(OLAP,0, bufferSize / 2 * sizeof (double));
double *RealX = new double[bufferSize];
memset(RealX, 0, bufferSize * sizeof(double));
double *ImmX = new double[bufferSize];
memset(ImmX, 0, bufferSize * sizeof(double));
short* audioDataBuffer = new short[bufferSize];
memset(audioDataBuffer, 0 , sizeof(short) * bufferSize);
// start reading from file by chunks of bufferSize
while (in.good())
{
// get proper chunk of data
FillBufferFromFile(audioDataBuffer, bufferSize, in); // read chunk from file
ShortArrayToDoubleArray(audioDataBuffer, RealX, bufferSize); // fill RealPart
ForwardRealFFT(RealX, ImmX, bufferSize); // go to frequency domain
// perform convultion as multiplication in frequency domain
for (int j = 0; j < bufferSize / 2; ++j)
{
double tmp = RealX[j] * RealFilterResp[j] - ImmX[j] * ImmFilterResp[j];
ImmX[j] = RealX[j] * ImmFilterResp[j] + ImmX[j] * RealFilterResp[j];
RealX[j] = tmp;
}
// Inverse FFT
ReverseRealFFT(RealX, ImmX, bufferSize); // go to time domain
// add last segment overlap to this segment
for (int j = 0; j < filterKernelLength - 2; ++j )
{
RealX[j] += OLAP[j];
}
// save samples that will overlap the next segment
for (int j = bufferSize/2 + 1; j < bufferSize; ++j )
{
OLAP[j - bufferSize/2 - 1] = audioDataBuffer[j];
}
// write results
DoubleArrayToShortArray(RealX, audioDataBuffer, bufferSize);
FillFileFromBuffer(audioDataBuffer, bufferSize, out);
}
/*ReverseRealFFT(RealX, ImmX, bufferSize
);
DoubleArrayToShortArray(RealX, audioDataBuffer, bufferSize);*/
delete [] audioDataBuffer;
delete [] RealFilterResp;
delete [] ImmFilterResp;
delete [] OLAP;
delete [] RealX;
delete [] ImmX;
in.close();
out.close();
}
If your intention is to use the window method to implement the filter, the window should multiply the time-domain sequence corresponding to the infinite impulse response of the ideal bandpass filter.
Specifically, for a bandpass filter of bandwidth w0=2*pi*(3700-300)/8000 centered at wc=2*pi*(300+3700)/8000, the ideal impulse response would be (for -infinity < n < infinity):
w0*sinc(0.5*w0*n/pi) * cos(wc*n) / pi
Which you would shift to the interval [0,N-1], and then apply the window that you computed:
double sinc(double x) {
if (fabs(x)<1e-6) return 1.0;
return sin(M_PI * x)/(M_PI * x);
}
void bandpassDesign(int N, double* filterImpulseResponse) {
double w0 = 2*(3700-300)*M_PI/8000;
double wc = 2*(300+3700)*M_PI/8000;
double shift = 0.5*N;
for (int i = 0; i < bufferSize; ++i) {
double truncatedIdealResponse = w0*sinc(0.5*w0*(i-shift)/M_PI) * cos(wc*i) / M_PI;
double window = a0 - a1 * cos (2 * M_PI * i / (N- 1)) + a2 * cos (4 * M_PI * i / (N- 1));
filterImpulseResponse[i] = truncatedIdealResponse * window;
}
}
You can then take the FFT to obtain the frequency-domain coefficients. Remember that if you intend on filtering data using this filter, the time sequence has to be zero padded.
For example, if you wish to use a 1024-point FFT with the overlap-add method, and assuming a 128-point filter kernel meets your filter design specifications, you would call bandpassDesign with N=128, pad with 1024-128=896 zeros, then take the FFT.
Your window coefficients are wrong - the window function is purely real, and you are going to multiply your (complex) frequency domain data with these real coeffs. So your filter coef initialisation:
double *RealFilterResp = new double [bufferSize / 2];
double *ImmFilterResp = new double [bufferSize / 2];
if ( i >= filterKernelLength ) // padd filter kernel with zeroes
{
RealFilterResp[i] = 0;
ImmFilterResp[i] = 0;
}
else if (i * frequencyPerSamle < lowestFrequency || i * frequencyPerSamle > highestFrequency)
{
// apply blackman window (to eleminate frequencies < 300 hz and > 3700 hz)
RealFilterResp[i] = a0 - a1 * cos (2 * M_PI * i / (bufferSize / 2 - 1)) + a2 * cos (4 * M_PI / (bufferSize / 2 - 1));
ImmFilterResp[i] = a0 - a1 * cos (2 * M_PI * i / (bufferSize / 2 - 1)) + a2 * cos (4 * M_PI / (bufferSize / 2 - 1));
}
else
{
RealFilterResp[i] = 1;
ImmFilterResp[i] = 1;
}
should just be:
double *FilterResp = new double [bufferSize / 2];
if ( i >= filterKernelLength ) // padd filter kernel with zeroes
{
FilterResp[i] = 0;
}
else if (i * frequencyPerSamle < lowestFrequency || i * frequencyPerSamle > highestFrequency)
{
FilterResp[i] = a0 - a1 * cos (2 * M_PI * i / (bufferSize / 2 - 1)) + a2 * cos (4 * M_PI / (bufferSize / 2 - 1));
}
else
{
FilterResp[i] = 1;
}
and the frequency domain multiplication:
for (int j = 0; j < bufferSize / 2; ++j)
{
double tmp = RealX[j] * RealFilterResp[j] - ImmX[j] * ImmFilterResp[j];
ImmX[j] = RealX[j] * ImmFilterResp[j] + ImmX[j] * RealFilterResp[j];
RealX[j] = tmp;
}
should just be:
for (int j = 0; j < bufferSize / 2; ++j)
{
RealX[j] *= FilterResp[j];
ImmX[j] *= FilterResp[j];
}

Pointers in C/C++ compiles but gives segfault error

Here's a code snipped that I have for a larger program
double *pos_x_h[224];
double *pos_y_h[224];
const double A = 1;
const int N = 224;
double d_0;
double alpha;
void initialize(double nu, int rows = 16, int columns = 14) {
double d = 1 / double(columns);
d_0 = d * (1 - pow(2.0, nu - 8));
alpha = d - d_0;
double dx = d;
double dy = d * sqrt(3.0) / 2;
for (int j = 0; j < rows; j++) {
for (int i = 0; i < columns; i++) {
int n = i + j * columns;
*pos_x_h[n] = i * dx + (j % 2) * dx / 2.0;
*pos_y_h[n] = j * dy;
}
}
}
int main(int argc, char *argv[]) {
double nu=7.5;
int rows=16;
int columns=14;
initialize(nu);
return 0;
}
The code compiles but it is gives a seg fault error. Can't see why that's the case. Am I going over array_size?
There doesn't seem to be any point in utilizing pos_x_h and pos_y_h as pointer arrays.
Change this:
double *pos_x_h[224];
double *pos_y_h[224];
To this:
double pos_x_h[224];
double pos_y_h[224];
And this:
*pos_x_h[n] = i * dx + (j % 2) * dx / 2.0;
*pos_y_h[n] = j * dy;
To this:
pos_x_h[n] = i * dx + (j % 2) * dx / 2.0;
pos_y_h[n] = j * dy;
If you really insist on utilizing pointer arrays, then you can use this (in addition to the above):
double *pos_x_h_ptr[224];
double *pos_y_h_ptr[224];
for (int n=0; n<224; n++)
{
pos_x_h_ptr[n] = pos_x_h+n;
pos_y_h_ptr[n] = pos_y_h+n;
}
double *pos_x_h[224];
double *pos_y_h[224];
are arrays of pointers, but you use them wihtout allocating memory
*pos_x_h[n] = i * dx + (j % 2) * dx / 2.0;
*pos_y_h[n] = j * dy;
probably something like that
pos_x_h[n] = malloc(sizeof(double));
*pos_x_h[n] = i * dx + (j % 2) * dx / 2.0;
pos_y_h[n] = malloc(sizeof(double));
*pos_y_h[n] = j * dy;
if you need to alocate memory outside the initialize function (why would you? it is init function) you can do it in main
int i = 0;
for(;i< 224;++i)
{
pos_x_h[i] = malloc(sizeof(double));
pos_y_h[i] = malloc(sizeof(double));
}