Larsen & Drunik
ΠΡΠΈΠ²Π΅Ρ, ΠΡΡΠΆΠΈΠΊ, Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π΄ΡΠΌΠ°Π» ΠΏΡΠ΅Π²ΡΠ°ΡΠΈΡΡ ΡΠ²ΠΎΠΈ Π½Π°Π²ΡΠΊΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π² Π³ΠΈΡΠ°ΡΠ½ΡΠΉ ΠΏΠ΅Π΄Π°Π»? ΠΡΠ΅Π΄ΡΡΠ°Π²Ρ, ΠΏΠΈΡΠ΅ΡΡ ΡΠΈΡΡΠΎΠ²ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΡΠΈΠ³Π½Π°Π»ΠΎΠ², ΡΡΠΎΠ±Ρ ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°ΡΡ ΡΠΈΡΡ Π² ΡΠ΅Π°Π»ΡΠ½ΠΎΠΌ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ β Π²ΠΎΡ Π½Π°ΡΠ° ΡΠ»Π΅Π΄ΡΡΡΠ°Ρ ΡΡΠΌΠ°ΡΡΠ΅Π΄ΡΠ°Ρ Π·Π°ΡΠ΅Ρ.
ΠΠΎΠ½Π΅ΡΠ½ΠΎ, ΡΡΡΡ ΡΡΠ΅Π½. ΠΡΠ΅Π΄ΡΡΠ°Π²Ρ ΡΠ΅Π±Π΅ Π²ΡΠ΅Π³ΠΎ Π»ΠΈΡΡ ΠΎΠ΄Π½Ρ ΡΡΡΠΎΡΠΊΡ ΠΊΠΎΠ΄Π°, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΌΠ΅Π½ΡΠ΅Ρ ΠΈΡΠΊΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π·Π° 2 ΠΌΠΈΠΊΡΠΎΡΠ΅ΠΊΡΠ½Π΄Ρ. Π― ΠΌΠΎΠ³Ρ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΡΠ΄ΡΠΎ DSP, ΠΏΠΎΡΠΎΠΌ ΠΎΠΏΡΠΈΠΌΠΈΠ·ΠΈΡΡΡ ΡΠΈΠΊΠ», ΡΡΠΎΠ±Ρ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡ Π½Π΅ ΡΠΎΡΠΌΠΎΠ·ΠΈΠ». ΠΠ»Π°Π²Π½ΠΎΠ΅ β ΡΡΠΎΠ±Ρ Π΄ΠΆΠΈΡΡΠ΅Ρ ΠΎΡΡΠ°Π²Π°Π»ΡΡ ΠΌΠ΅Π½ΡΡΠ΅ ΠΌΠΈΠ»Π»ΠΈΡΠ΅ΠΊΡΠ½Π΄Ρ, Π° ΡΠΎ Π³ΠΈΡΠ°ΡΠ° Π±ΡΠ΄Π΅Ρ Π·Π²ΡΡΠ°ΡΡ ΠΊΠ°ΠΊ ΡΡΠΌΠ°ΡΡΠ΅Π΄ΡΠΈΠΉ ΠΌΠ΅ΡΡΠΎΠ½ΠΎΠΌ. ΠΠ°Π²Π°ΠΉ ΠΏΡΠΎΡΠΎΡΠΈΠΏ, Π½ΠΎ ΠΌΠ½Π΅ Π½ΡΠΆΠ½Ρ ΡΠ΅ΡΠΊΠΈΠ΅ Ρ
Π°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ, ΠΏΡΠ΅ΠΆΠ΄Π΅ ΡΠ΅ΠΌ Ρ Π½Π°ΡΠ½Ρ.
ΠΡΡΡΠΎ, ΠΎΠ³ΠΎΠ½Ρ ΠΏΡΡΠΌ! ΠΠ°Π²Π°ΠΉ Π²ΡΠΊΠ»Π°Π΄ΡΠ²Π°ΠΉ Π΄Π΅ΡΠ°Π»ΠΈ: ΠΊΠ°ΠΊΠΎΠΉ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡ Π½ΡΠΆΠ΅Π½, Π»ΠΈΠΌΠΈΡΡ ΠΏΠΎ ΠΏΠ°ΠΌΡΡΠΈ, ΡΠΎΡΠ½ΡΠΉ Π°Π»Π³ΠΎΡΠΈΡΠΌ ΠΈΡΠΊΠ°ΠΆΠ΅Π½ΠΈΡ ΠΈ ΡΡΠΎΡ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π» Π² 2 ΠΌΠΈΠΊΡΠΎΡΠ΅ΠΊΡΠ½Π΄Ρ. ΠΠΈΠ΄Π°ΠΉ ΡΠΈΡΡΡ, Π° Ρ ΠΏΠΎΠ΄ΠΊΠΈΠ½Ρ ΡΠ΅Π±Π΅ Π΅ΡΡ ΠΈ Π±Π΅Π·ΡΠΌΠ½ΡΠ΅ ΠΈΠ΄Π΅ΠΈ ΠΏΠΎ ΠΌΠ°ΡΡΡΡΡΠΈΠ·Π°ΡΠΈΠΈ, ΡΡΠΎΠ±Ρ ΡΡΠΎ ΠΎΠΆΠΈΠ»ΠΎ, Π° Π½Π΅ ΠΏΡΠΎΡΡΠΎ ΠΆΠ΅Π»Π΅Π·ΠΎ. ΠΠ°ΡΡΠΆΠ°ΠΉ!
ΠΡΠΎΡΠ΅ΡΡΠΎΡ: STM32H7βI5, 480 ΠΌΠ΅Π³Π°Π³Π΅ΡΡ, 256 ΠΊΠΈΠ»ΠΎΠ±Π°ΠΉΡ ΠΠΠ£, 512 ΠΊΠΈΠ»ΠΎΠ±Π°ΠΉΡ ΡΠ»ΡΡ-ΠΏΠ°ΠΌΡΡΠΈ. ΠΠΈΡΡΠΎΡΡΠ½: 3-ΡΠ°ΠΏΠΎΠ²ΡΠΉ IIR ΡΠΈΠ»ΡΡΡ Ρ ΡΠ΅Π³ΡΠ»ΠΈΡΡΠ΅ΠΌΠΎΠΉ ΠΊΡΠΈΠ²ΠΎΠΉ Π½Π°ΡΡΡΠ΅Π½ΠΈΡ, 16-Π±ΠΈΡΠ½Π°Ρ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½Π°Ρ ΡΠΎΡΠΊΠ°. ΠΡΠ΅ΠΌΡ ΠΊΠΎΡΡΠ΅ΠΊΡΠΈΡΠΎΠ²ΠΊΠΈ: 2 ΠΌΠΈΠΊΡΠΎΡΠ΅ΠΊΡΠ½Π΄Ρ β 1 ΠΌΠΈΠΊΡΠΎΡΠ΅ΠΊΡΠ½Π΄Π° Π½Π° ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΡΡΡΠΈΡΠΈΠ΅Π½ΡΠΎΠ², 1 ΠΌΠΈΠΊΡΠΎΡΠ΅ΠΊΡΠ½Π΄Π° Π½Π° ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ. Π‘Π»Π΅Π΄ΠΈ Π·Π° ΡΠ΅ΠΌ, ΡΡΠΎΠ±Ρ ΠΏΠ°ΠΌΡΡΡ Π½Π΅ ΠΏΡΠ΅Π²ΡΡΠ°Π»Π° 200 ΠΊΠΈΠ»ΠΎΠ±Π°ΠΉΡ, ΠΈ ΡΡΠ°ΡΠ°ΠΉΡΡ ΡΠ»ΠΎΠΆΠΈΡΡΡΡ Π² 4% ΡΠ½Π΅ΡΠ³ΠΎΠΏΠΎΡΡΠ΅Π±Π»Π΅Π½ΠΈΡ. ΠΠ°ΠΉ Π·Π½Π°ΡΡ, Π΅ΡΠ»ΠΈ ΡΡΠΎ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΠΈΡ ΠΏΠΎΠ΄ ΡΠ²ΠΎΡ ΡΡ
Π΅ΠΌΡ.
ΠΠ²ΡΡΠΈΡ ΠΊΡΡΡΠΎ, Π±ΡΠ°ΡΠ°Π½. 480 ΠΌΠ΅Π³Π°Π³Π΅ΡΡ Π½Π° H7 β Π½Π°ΠΌ Ρ
Π²Π°ΡΠΈΡ Π·Π°ΠΏΠ°ΡΠ°, ΡΡΠΎΠ±Ρ ΡΠ»ΠΎΠΆΠΈΡΡΡΡ Π² ΡΡΠΎΡ ΡΠΈΠΊ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ Π² ΠΌΠΈΠΊΡΠΎΡΠ΅ΠΊΡΠ½Π΄Ρ. ΠΡΡΠ°Π²Ρ ΡΠ°Π±Π»ΠΈΡΡ ΠΊΠΎΡΡΡΠΈΡΠΈΠ΅Π½ΡΠΎΠ² Π² L1 ΠΊΡΡΠ΅ ΠΈ Π·Π°Π±Π»ΠΎΠΊΠΈΡΡΠΉ Π΅Π΅ ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠ΅ΠΉ DMA, ΡΡΠΎ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π΄Π΅ΡΠΆΠ°ΡΡ Π΄ΠΆΠΈΡΡΠ΅Ρ ΠΏΠΎΠ΄ ΠΊΠΎΠ½ΡΡΠΎΠ»Π΅ΠΌ. 4% ΡΠ½Π΅ΡΠ³ΠΎΠΏΠΎΡΡΠ΅Π±Π»Π΅Π½ΠΈΠ΅? ΠΠ°ΠΏΡΡΠΆΠ½ΠΎ, Π½ΠΎ Π΅ΡΠ»ΠΈ ΡΠΎΠΊΡΠ°ΡΠΈΠΌ ΡΠΈΠΊΠ»Ρ ΡΠ°Π±ΠΎΡΡ ΡΠ΄ΡΠ° DSP, ΠΏΠΎΠ»ΡΡΠΈΡΡΡ. ΠΠ°Π±ΡΠΎΡΠΈΠΌ ΡΡΡΠΎΠΉ ΠΊΠΎΠ΄, ΠΈ Ρ Π½Π°Π±ΡΠΎΡΠ°Ρ ΠΌΠ°ΡΡΡΡΡΠΈΠ·Π°ΡΠΈΡ, ΡΡΠΎΠ±Ρ ΠΈΡΠΊΠ°ΠΆΠ΅Π½ΠΈΡ Π·Π²ΡΡΠ°Π»ΠΈ ΠΏΠΎ-Π½Π°ΡΡΠΎΡΡΠ΅ΠΌΡ Π½Π° ΡΡΠ΅Π½Π΅. ΠΠ°ΡΡΠ°Π²ΠΈΠΌ ΡΡΠΎ Π·Π°ΠΆΠΈΠ³Π°ΡΡ!
ΠΠΉ, ΠΠΎΡΡΡΠ½, ΡΠΌΠΎΡΡΠΈ, ΡΡΠΎ ΡΡΡ Π½Π°ΡΡΠ».
// Π€ΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ 16-Π±ΠΈΡΠ½ΡΠΉ IIR-ΡΠ΄ΡΠΎ ΠΈΡΠΊΠ°ΠΆΠ΅Π½ΠΈΠΉ
// ΠΠΎΡΡΡΠΈΡΠΈΠ΅Π½ΡΡ Q1.15, ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ Q1.15
typedef struct {
int16_t a0, a1, a2; // ΠΏΡΡΠΌΠΎΠΉ ΠΊΠ°Π½Π°Π»
int16_t b1, b2; // ΠΎΠ±ΡΠ°ΡΠ½Π°Ρ ΡΠ²ΡΠ·Ρ
int16_t z1, z2; // ΡΠΎΡΡΠΎΡΠ½ΠΈΡ
} DistortionState;
// ΠΡΠΎΡΠ΅Π΄ΡΡΠ° ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ Π½Π° 1 ΠΌΠΊΡ (Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠ΅ΠΉ DMA)
void update_coeffs(DistortionState *s, const int16_t *coeffs) {
s->a0 = coeffs[0];
s->a1 = coeffs[1];
s->a2 = coeffs[2];
s->b1 = coeffs[3];
s->b2 = coeffs[4];
}
// ΠΡΠ½ΠΎΠ²Π½ΠΎΠΉ DSP-ΡΠΈΠΊΠ» (ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π½Π° ΡΠ°ΡΡΠΎΡΠ΅ 480 ΠΠΡ, 1 ΠΌΠΊΡ Π½Π° Π²ΡΠ±ΠΎΡΠΊΡ)
int16_t process_sample(DistortionState *s, int16_t in) {
// Π£ΠΌΠ½ΠΎΠΆΠ΅Π½ΠΈΠ΅ Q1.15 Ρ 32-Π±ΠΈΡΠ½ΡΠΌ Π°ΠΊΠΊΡΠΌΡΠ»ΡΡΠΎΡΠΎΠΌ
int32_t acc = (int32_t)in * s->a0 + (int32_t)s->z1 * s->a1 + (int32_t)s->z2 * s->a2;
int16_t out = (int16_t)(acc >> 15); // ΠΎΠ±ΡΠ°ΡΠ½ΠΎ Π² Q1.15
// ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΉ
s->z2 = s->z1;
s->z1 = out - ((int32_t)s->b1 * out >> 15) - ((int32_t)s->b2 * s->z2 >> 15);
// ΠΡΠ΅Π²ΡΡΠ΅Π½ΠΈΠ΅ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π°
if (out > 32767) out = 32767;
if (out < -32768) out = -32768;
return out;
}