#include <stdio.h>
#include <math.h>
#include "pico/stdlib.h"
#include "pico/float.h"
#include "hardware/gpio.h"
#include "hardware/irq.h"
#include "hardware/pwm.h"

#define PI      ((float) M_PI)    // float型の円周率
#define FCLKSYS (120000000) // システムクロック周波数（Hz）
#define FS      (48000)     // サンプリング周波数（Hz）
//////// オシレータ //////////////////////////////
static float Osc_freq_table[8] = {      // 周波数テーブル
  261.6F / FS, 293.7F / FS,
  329.6F / FS, 349.2F / FS,
  392.0F / FS, 440.0F / FS,
  493.9F / FS, 523.3F / FS };
static float Osc_wave_tables[8][512];   // 波形テーブル群
static volatile uint32_t Osc_pitch = 0; // ピッチ設定値

static void Osc_init() {
  for (uint32_t pitch = 0; pitch < 8; ++pitch) {
    uint32_t harm_max = // 最大倍音次数
      (23000.0F / FS) / Osc_freq_table[pitch];
    if (harm_max > 127) { harm_max = 127; }

    for (uint32_t i = 0; i < 512; ++i) {
      float sum = 0.0F;
      for (uint32_t k = 1; k <= harm_max; ++k) {
        sum += (2 / PI)
               * (sinf(2 * PI * k * i / 512) / k);
      }
      sum *= 0.25F;
      Osc_wave_tables[pitch][i] = sum;
    }
  }
}
static inline float Osc_process() {
  static float phase = 0; // 位相
  phase += Osc_freq_table[Osc_pitch];
  phase = phase - floorf(phase); // 小数部のみを残す

  float* wave_table = Osc_wave_tables[Osc_pitch];
  float phase_512 = phase * 512;
  uint32_t curr_index = float2int(phase_512);
  uint32_t next_index = (curr_index + 1) &
                                       0x000001FF;
  float curr_sample = wave_table[curr_index];
  float next_sample = wave_table[next_index];
  float next_weight =
                  phase_512 - floorf(phase_512);
  float curr_weight = 1.0F - next_weight;
  return (curr_sample * curr_weight) +
         (next_sample * next_weight);
}
