Пн ноя 29, 2021 20:25:30
Частота, соответствующая i-му отсчету в массиве после Фурье, F(i) = i/(N * dt) = i * f/ N.Eddy_Em писал(а):А 20мс — это 50ГЦ!
Пн ноя 29, 2021 20:39:30
Пн ноя 29, 2021 20:40:36
Какое условие - такое решение.Eddy_Em писал(а): если мы будем оцифровывать данные с частотой в 6800Гц, то сможем измерить максимум 3400Гц. И то, хреново! Желательно хотя бы 13.6кГц. А еще лучше - больше.
Пн ноя 29, 2021 20:46:29
Пн ноя 29, 2021 21:00:42
Пн ноя 29, 2021 21:01:52
Пн ноя 29, 2021 21:24:22
Пн ноя 29, 2021 21:26:40
Пн ноя 29, 2021 21:37:47
Вт ноя 30, 2021 09:10:29
Вт ноя 30, 2021 15:53:52
Вт ноя 30, 2021 16:29:51
////////////////////////////////////////////////////////////////////////////////
// Biquad signal processing function
void DSP_Bq_Process(BiquadFilter* flt, int32_t* leftSample, int32_t* rightSample)
{
// Left input data shift
flt->leftInZ[2] = flt->leftInZ[1];
flt->leftInZ[1] = flt->leftInZ[0];
flt->leftInZ[0] = *leftSample;
// Right input data shift
flt->rightInZ[2] = flt->rightInZ[1];
flt->rightInZ[1] = flt->rightInZ[0];
flt->rightInZ[0] = *rightSample;
//-- Processing left
float tmpLch = flt->leftInZ[0] * flt->bqB[0]; // MAC Add
tmpLch += flt->leftInZ[1] * flt->bqB[1]; // MAC Add
tmpLch += flt->leftInZ[2] * flt->bqB[2]; // MAC Add
tmpLch -= flt->leftOutZ[0] * flt->bqA[1]; // MAC Substract
tmpLch -= flt->leftOutZ[1] * flt->bqA[2]; // MAC Substract
//-- Processing right
float tmpRch = flt->rightInZ[0] * flt->bqB[0]; // MAC Add
tmpRch += flt->rightInZ[1] * flt->bqB[1]; // MAC Add
tmpRch += flt->rightInZ[2] * flt->bqB[2]; // MAC Add
tmpRch -= flt->rightOutZ[0] * flt->bqA[1]; // MAC Substract
tmpRch -= flt->rightOutZ[1] * flt->bqA[2]; // MAC Substract
// Left out data shift
flt->leftOutZ[1] = flt->leftOutZ[0];
flt->leftOutZ[0] = tmpLch;
// Right out data shift
flt->rightOutZ[1] = flt->rightOutZ[0];
flt->rightOutZ[0] = tmpRch;
// Convert and store final result
*leftSample = (int32_t)tmpLch;
*rightSample = (int32_t)tmpRch;
}
// Biquad filter instanse
typedef struct _BiquadFilter
{
float frequency;
float param;
float gain;
uint8_t type;
float bqA[3];
float bqB[3];
float leftInZ[3];
float rightInZ[3];
float leftOutZ[2];
float rightOutZ[2];
}BiquadFilter;
////////////////////////////////////////////////////////////////////////////////
// Biquad filter coefficients calculate
void DSP_CalcBiquad(BiquadFilter* flt)
{
// Calculating reference values
float gainAbs = pow(10, (flt->gain / 40) );
float omega = 2 * PI * (flt->frequency / MAIN_SAMPLERATE);
float sinOmega = sin(omega);
float cosOmega = cos(omega);
// Patch need
float alpha = sinOmega / (2 * flt->param);
float beta = sqrt(gainAbs + gainAbs);
// Calculating coefficients
switch (flt->type)
{
default:
case LOWSHELF:
flt->bqB[0] = gainAbs * ((gainAbs + 1) - (gainAbs - 1) * cosOmega + beta * sinOmega);
flt->bqB[1] = 2 * gainAbs * ((gainAbs - 1) - (gainAbs + 1) * cosOmega);
flt->bqB[2] = gainAbs * ((gainAbs + 1) - (gainAbs - 1) * cosOmega - beta * sinOmega);
flt->bqA[0] = (gainAbs + 1) + (gainAbs - 1) * cosOmega + beta * sinOmega;
flt->bqA[1] = -2 * ((gainAbs - 1) + (gainAbs + 1) * cosOmega);
flt->bqA[2] = (gainAbs + 1) + (gainAbs - 1) * cosOmega - beta * sinOmega;
break;
case PEAK:
flt->bqB[0] = 1 + (alpha * gainAbs);
flt->bqB[1] = -2 * cosOmega;
flt->bqB[2] = 1 - (alpha * gainAbs);
flt->bqA[0] = 1 + (alpha / gainAbs);
flt->bqA[1] = -2 * cosOmega;
flt->bqA[2] = 1 - (alpha / gainAbs);
break;
case HIGHSHELF:
flt->bqB[0] = gainAbs * ((gainAbs + 1) + (gainAbs - 1) * cosOmega + beta * sinOmega);
flt->bqB[1] = -2 * gainAbs * ((gainAbs - 1) + (gainAbs + 1) * cosOmega);
flt->bqB[2] = gainAbs * ((gainAbs + 1) + (gainAbs - 1) * cosOmega - beta * sinOmega);
flt->bqA[0] = (gainAbs + 1) - (gainAbs - 1) * cosOmega + beta * sinOmega;
flt->bqA[1] = 2 * ((gainAbs - 1) - (gainAbs + 1) * cosOmega);
flt->bqA[2] = (gainAbs + 1) - (gainAbs - 1) * cosOmega - beta * sinOmega;
break;
case LOWPASS:
flt->bqB[0] = (1 - cosOmega) / 2;
flt->bqB[1] = 1 - cosOmega;
flt->bqB[2] = (1 - cosOmega) / 2;
flt->bqA[0] = 1 + alpha;
flt->bqA[1] = -2 * cosOmega;
flt->bqA[2] = 1 - alpha;
break;
case BANDPASS:
flt->bqB[0] = alpha;
flt->bqB[1] = 0;
flt->bqB[2] = -alpha;
flt->bqA[0] = 1 + alpha;
flt->bqA[1] = -2 * cosOmega;
flt->bqA[2] = 1 - alpha;
break;
case HIGHPASS:
flt->bqB[0] = (1 + cosOmega) / 2;
flt->bqB[1] = -(1 + cosOmega);
flt->bqB[2] = (1 + cosOmega) / 2;
flt->bqA[0] = 1 + alpha;
flt->bqA[1] = -2 * cosOmega;
flt->bqA[2] = 1 - alpha;
break;
case NOTCH:
flt->bqB[0] = 1;
flt->bqB[1] = -2 * cosOmega;
flt->bqB[2] = 1;
flt->bqA[0] = 1 + alpha;
flt->bqA[1] = -2 * cosOmega;
flt->bqA[2] = 1 - alpha;
break;
}
// Prescale flter constants
flt->bqB[0] /= flt->bqA[0];
flt->bqB[1] /= flt->bqA[0];
flt->bqB[2] /= flt->bqA[0];
flt->bqA[1] /= flt->bqA[0];
flt->bqA[2] /= flt->bqA[0];
}
////////////////////////////// BIQUAD filters //////////////////////////////////
// Filter parameters
uint8_t bqEn = 1;
BiquadFilter LowShelf =
{
.frequency = 75.0f,
.param = 1.5f,
.gain = 8.0f,
.type = LOWSHELF
};
BiquadFilter MidPeak =
{
.frequency = 5500.0f,
.param = 1.4f,
.gain = -3.0f,
.type = PEAK
};
BiquadFilter HighShelf =
{
.frequency = 10000.0f,
.param = 1.5f,
.gain = 6.0f,
.type = HIGHSHELF
};
// Calculate filters
DSP_CalcBiquad(&LowShelf);
DSP_CalcBiquad(&MidPeak);
DSP_CalcBiquad(&HighShelf);
////////////////////////////////////////////////////////////////////////////////
// DSP precess main function
int DSP_Process(pDspBufPoint buff, uint32_t samplNum)
{
for(int i = 0; i < samplNum; i++)
{
//---------- Volume control ----------//
buff->leftCh[i] *= (leftVol);
buff->rightCh[i] *= (rightVol);
//---------- Biquad filters ----------//
if(bqEn != 0)
{
DSP_Bq_Process(&LowShelf, &buff->leftCh[i], &buff->rightCh[i]);
DSP_Bq_Process(&MidPeak, &buff->leftCh[i], &buff->rightCh[i]);
DSP_Bq_Process(&HighShelf, &buff->leftCh[i], &buff->rightCh[i]);
}
// Signed saturation limit on 24 bit with SSAT instruction
buff->leftCh[i] = __SSAT(buff->leftCh[i], 24);
buff->rightCh[i] = __SSAT(buff->rightCh[i], 24);
}// DSP cycle
return 0;
}
Вт ноя 30, 2021 16:43:53