summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorozpv <39195175+ozpv@users.noreply.github.com>2026-08-22 19:53:06 -0500
committerozpv <39195175+ozpv@users.noreply.github.com>2026-08-22 19:53:06 -0500
commitd000890eafbc6cc715fa6e7da2db61db05a6f3e4 (patch)
tree2688c10beee0a7c5eaca3d0f254f6cc274e1d6bb
parent0cb345ed5ccbe786d0a7e7e2de740c0a07b82770 (diff)
update ring mod
-rwxr-xr-xCore/Inc/Effects/ringmod.h11
-rwxr-xr-xCore/Src/Effects/ringmod.c30
-rwxr-xr-xCore/Src/cs4272.c26
-rwxr-xr-xCore/Src/main.c2
4 files changed, 44 insertions, 25 deletions
diff --git a/Core/Inc/Effects/ringmod.h b/Core/Inc/Effects/ringmod.h
index 42cb229..516ca6c 100755
--- a/Core/Inc/Effects/ringmod.h
+++ b/Core/Inc/Effects/ringmod.h
@@ -10,7 +10,16 @@
#include <stdint.h>
#include <stddef.h>
+#include <stdbool.h>
-void ringmod(float *samples, size_t range_min, size_t range_max);
+typedef struct RingModParams {
+ float mix;
+ float frequency;
+ float lfo_amount;
+ float lfo_rate;
+ bool square_lfo;
+} RingModParams;
+
+void ringmod(float *samples, const size_t range_min, const size_t range_max, const struct RingModParams *params);
#endif /* INC_EFFECTS_RINGMOD_H_ */
diff --git a/Core/Src/Effects/ringmod.c b/Core/Src/Effects/ringmod.c
index 732f68e..1b411dc 100755
--- a/Core/Src/Effects/ringmod.c
+++ b/Core/Src/Effects/ringmod.c
@@ -8,30 +8,34 @@
#include "cs4272.h"
#include "ringmod.h"
#include <math.h>
+#include <float.h>
-/* ring modulator */
-void ringmod(float *samples, size_t range_min, size_t range_max) {
+/* MF-102S ring modulator */
+void ringmod(float *samples, const size_t range_min, const size_t range_max, const struct RingModParams *params) {
static float lfo_phase = 0.0f;
static float carrier_phase = 0.0f;
- const float frequency = 156.0f;
- const float amount = 0.67f;
const float sample_rate = (float)SAMPLE_RATE;
+ const float inverse_sample_rate = 1.0f / sample_rate;
- float lfo_increment = M_TWOPI * (0.18f / sample_rate);
-
- /* plus two because of */
+ /* samples are interleaved */
for (size_t i = range_min; i < range_max; i += 2) {
- lfo_phase = fmodf(lfo_phase + lfo_increment, M_TWOPI);
+ float frequency_lfo = 0.0f;
- float lfo = sinf(lfo_phase);
+ if (params->square_lfo) {
+ frequency_lfo = (lfo_phase < 0.5f) ? params->lfo_amount : -params->lfo_amount;
+ } else {
+ frequency_lfo = params->lfo_amount * sinf(M_TWOPI * lfo_phase);
+ }
- float carrier_increment = M_TWOPI * ((frequency + lfo * (frequency * 3.0f * amount)) / sample_rate);
+ float carrier = sinf(M_TWOPI * carrier_phase);
- carrier_phase = fmodf(carrier_phase + carrier_increment, M_TWOPI);
+ samples[i] = (samples[i] * (1.0f - params->mix)) + (samples[i] * carrier * params->mix);
- float carrier = sinf(carrier_phase);
+ lfo_phase += params->lfo_rate * inverse_sample_rate;
+ lfo_phase = fmod(lfo_phase, 1.0f);
- samples[i] = (samples[i] * 0.50f) + (samples[i] * carrier * 0.50f);
+ carrier_phase += (params->frequency + frequency_lfo) * inverse_sample_rate;
+ carrier_phase = fmod(carrier_phase, 1.0f);
}
}
diff --git a/Core/Src/cs4272.c b/Core/Src/cs4272.c
index 81179c7..9a7f0d1 100755
--- a/Core/Src/cs4272.c
+++ b/Core/Src/cs4272.c
@@ -9,6 +9,14 @@
#include "cs4272.h"
#include "ringmod.h"
+const struct RingModParams params = {
+ 0.40f,
+ 156.0f,
+ 6.90f,
+ 0.18f,
+ true,
+};
+
volatile int32_t rx_buffer[BUFFER_SIZE] __attribute__((section(".audio_buffers")));
volatile int32_t tx_buffer[BUFFER_SIZE] __attribute__((section(".audio_buffers")));
volatile float samples[BUFFER_SIZE] __attribute__((section(".sdram")));
@@ -50,13 +58,13 @@ const uint8_t CS4272_CONFIG[7] = {
0b00000010,
};
-void int32_t_to_float(int32_t *in, float *out, size_t range_min, size_t range_max) {
+inline void int32_t_to_float(int32_t *in, float *out, const size_t range_min, const size_t range_max) {
for (size_t i = range_min; i < range_max; ++i) {
out[i] = ((float)(in[i] << 8)) / ((float)INT32_MAX);
}
}
-void float_to_int32_t(float *in, int32_t *out, size_t range_min, size_t range_max) {
+inline void float_to_int32_t(float *in, int32_t *out, const size_t range_min, const size_t range_max) {
for (size_t i = range_min; i < range_max; ++i) {
out[i] = ((int32_t)(in[i] * ((float)INT32_MAX))) >> 8;
}
@@ -65,7 +73,7 @@ void float_to_int32_t(float *in, int32_t *out, size_t range_min, size_t range_ma
void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai) {
int32_t_to_float((int32_t *)rx_buffer, (float *)samples, 0, BUFFER_SIZE / 2);
- ringmod((float *)samples, 0, BUFFER_SIZE / 2);
+ ringmod((float *)samples, 0, BUFFER_SIZE / 2, &params);
float_to_int32_t((float *)samples, (int32_t *)tx_buffer, 0, BUFFER_SIZE / 2);
}
@@ -73,20 +81,18 @@ void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai) {
void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai) {
int32_t_to_float((int32_t *)rx_buffer, (float *)samples, BUFFER_SIZE / 2, BUFFER_SIZE);
- ringmod((float *)samples, BUFFER_SIZE / 2, BUFFER_SIZE);
+ ringmod((float *)samples, BUFFER_SIZE / 2, BUFFER_SIZE, &params);
float_to_int32_t((float *)samples, (int32_t *)tx_buffer, BUFFER_SIZE / 2, BUFFER_SIZE);
}
-HAL_StatusTypeDef CS4272_ReadRegister(uint8_t addr, uint8_t *data) {
- return HAL_I2C_Mem_Read(&hi2c4, CS4272_I2C_ADDR, addr, I2C_MEMADD_SIZE_8BIT,
- data, 1, HAL_MAX_DELAY);
+HAL_StatusTypeDef CS4272_ReadRegister(const uint8_t addr, uint8_t *data) {
+ return HAL_I2C_Mem_Read(&hi2c4, CS4272_I2C_ADDR, addr, I2C_MEMADD_SIZE_8BIT, data, 1, HAL_MAX_DELAY);
}
-HAL_StatusTypeDef CS4272_WriteRegister(uint8_t addr, uint8_t data) {
- return HAL_I2C_Mem_Write(&hi2c4, CS4272_I2C_ADDR, addr,
- I2C_MEMADD_SIZE_8BIT, &data, 1, HAL_MAX_DELAY);
+HAL_StatusTypeDef CS4272_WriteRegister(const uint8_t addr, uint8_t data) {
+ return HAL_I2C_Mem_Write(&hi2c4, CS4272_I2C_ADDR, addr, I2C_MEMADD_SIZE_8BIT, &data, 1, HAL_MAX_DELAY);
}
void CS4272_Reset(void) {
diff --git a/Core/Src/main.c b/Core/Src/main.c
index 9c58861..f7fdeac 100755
--- a/Core/Src/main.c
+++ b/Core/Src/main.c
@@ -121,7 +121,7 @@ int main(void)
/* USER CODE BEGIN 2 */
FMC_Init();
- SDRAM_Test();
+ //SDRAM_Test();
__HAL_RCC_SAI1_CLK_ENABLE();
__HAL_SAI_ENABLE(&hsai_BlockA1);