#include "cppmain.h" #include "init.h" #include "utils.h" #include #include #include "limits" #include #include #define SAMPLE_FREQ 42000 #define SAMPLE_MAX 4096 #define BUFFER_SIZE 256 #define BLOCK_SIZE 128 const double pi{ std::acos(-1) }; // Buffer and block static u32 audio_buffer[BUFFER_SIZE]; static u32 *block = &audio_buffer[0]; static volatile bool process_block{ true }; static volatile bool process_block2{ true }; // time static u64 inf_phasor{ 0 }; namespace ut = Heck::Utils; namespace Heck { // LED // --- void led_green_toggle() { HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12); } void led_green_on() { HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET); } void led_green_off() { HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET); } // CALLBACKS void irq1_cb() { ut::debug_suspend_continue(); } void timer3_cb() { led_green_toggle(); } void bytebeat() { long t{ 0 }; while (true) { unsigned char res = t * ((t >> 12 | t >> 8) & 63 & t >> 4); dac1_set((res % 256) * 100); for (int g = 0; g < 60000; g++) {} t++; t %= (std::numeric_limits::max() - 1); } } void buffer_init_noise() { ut::log("buffer_init_noise()"); for (int i = 0; i < BUFFER_SIZE; i++) { u32 val = ut::random(SAMPLE_MAX); audio_buffer[i] = val; } } void block_fill_saw() { u32 *b = block; u32 step = (SAMPLE_MAX - (SAMPLE_MAX / 4)) / BLOCK_SIZE; for (int i = 0; i < BLOCK_SIZE; i++) { u32 val = i * step; b[i] = val; } } void buffer_init_sin() { ut::log("buffer_init_sin()"); for (int i = 0; i < BUFFER_SIZE; i++) { float p = float(i) / (float)BUFFER_SIZE - 0.5; u32 val = sin(p) * SAMPLE_MAX; audio_buffer[i] = val; } } void buffer_div(int div) { ut::log("init_scale()"); for (int i = 0; i < BUFFER_SIZE; i++) { u32 val = audio_buffer[i] / div; audio_buffer[i] = val; } } void buffer_randomize(int max) { ut::log("buffer_randomize()"); u32 buf_index = ut::random(BUFFER_SIZE); u32 buf_val = ut::random(max); audio_buffer[buf_index] = buf_val; } u32 hz_to_samps(float hz) { return (u32)floor((float)SAMPLE_FREQ / (float)hz); } u32 saw(u64 t, float freq_hz) { u32 ret{ 0 }; u32 samps = hz_to_samps(freq_hz); u32 normalizing_factor = SAMPLE_MAX / samps; ret = t % samps; ret *= normalizing_factor; return ret; } void calculate_audio() { // log("calculate_audio time: "); u32 *b = block; u64 t = inf_phasor; for (int i = 0; i < BLOCK_SIZE; i++) { b[i] = saw(t, 80); // b[i] *= saw(t, 20); t++; } } std::string block_to_string() { u32 *b = block; std::stringstream ss{}; for (int i = 0; i < BLOCK_SIZE; i++) { ss << std::setw(4) << b[i] << " "; } return ss.str(); } void main() { heck_debug_suspend(); ut::log("Starting..."); HAL_TIM_Base_Start_IT(&htim_blinky_led); HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, audio_buffer, BUFFER_SIZE, DAC_ALIGN_12B_R); HAL_TIM_Base_Start_IT(&htim_dac1); ut::log("Entering MainLoop..."); while (true) { if (process_block) { process_block = false; calculate_audio(); inf_phasor += BLOCK_SIZE; } } } } // namespace Heck // ---------------------------------------------------------------------------------------------- // C Linkage (Bridging) // ---------------------------------------------------------------------------------------------- extern "C" void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin == GPIO_PIN_0) { Heck::irq1_cb(); } } extern "C" void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM2) { // Heck::log( // "TIM2 timer: instance: " + std::to_string(reinterpret_cast(htim->Instance)) + // " channel: " + std::to_string(htim->Channel)); } else if (htim->Instance == TIM3) { ut::log( "TIM3 timer: instance: " + std::to_string(reinterpret_cast(htim->Instance)) + " channel: " + std::to_string(htim->Channel)); Heck::timer3_cb(); } else { ut::log( "UNKNOWN timer: instance: " + std::to_string(reinterpret_cast(htim->Instance)) + " channel: " + std::to_string(htim->Channel)); } } extern "C" void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef *hdac) { // Heck::log("HAL_DAC_ConvHalfCpltCallbackCh1"); block = &audio_buffer[0]; process_block = true; } extern "C" void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac) { // Heck::log("HAL_DAC_ConvCpltCallbackCh1"); block = &audio_buffer[BLOCK_SIZE]; process_block = true; } extern "C" void heck_cppmain(void) { Heck::main(); }