Skip to content

Commit

Permalink
[kyma] Add basic oscillator
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiashienzsch committed May 18, 2023
1 parent 2a63b76 commit 1007fa9
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 6 deletions.
23 changes: 17 additions & 6 deletions src/kyma/main.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
#include "mc/dsp/oscillator.hpp"

#include "daisy_patch_sm.h"

daisy::patch_sm::DaisyPatchSM patch;
auto oscillator = mc::Oscillator<float>{};
auto patch = daisy::patch_sm::DaisyPatchSM{};

void AudioCallback(daisy::AudioHandle::InputBuffer in, daisy::AudioHandle::OutputBuffer out, size_t size)
static auto process(daisy::AudioHandle::InputBuffer /*in*/, daisy::AudioHandle::OutputBuffer out, size_t size) -> void
{
for (size_t i = 0; i < size; i++)
auto* leftOut = out[0];
auto* rightOut = out[0];

for (size_t i = 0; i < size; ++i)
{
out[0][i] = in[0][i];
out[1][i] = in[1][i];
auto const sample = oscillator();
leftOut[i] = sample;
rightOut[i] = sample;
}
}

int main(void)
{
oscillator.setShape(mc::OscillatorShape::Sine);
oscillator.setFrequency(440.0F);
oscillator.setSampleRate(patch.AudioSampleRate());

patch.Init();
patch.StartAudio(AudioCallback);
patch.StartAudio(process);
while (true) {}
}
12 changes: 12 additions & 0 deletions src/kyma/mc/dsp/constants.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

namespace mc::numbers
{

template<typename FloatType>
constexpr auto pi = static_cast<FloatType>(3.141592653589793);

template<typename FloatType>
constexpr auto twoPi = pi<FloatType> * static_cast<FloatType>(2);

} // namespace mc::numbers
119 changes: 119 additions & 0 deletions src/kyma/mc/dsp/oscillator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#pragma once

#include "constants.hpp"

namespace mc
{

enum struct OscillatorShape
{
Sine,
Triangle,
Saw,
Square,
};

template<typename SampleType>
struct Oscillator
{
Oscillator() = default;

auto setShape(OscillatorShape shape) noexcept -> void;
auto setPhase(SampleType phase) noexcept -> void;
auto setFrequency(SampleType frequency) noexcept -> void;
auto setSampleRate(SampleType sampleRate) noexcept -> void;

[[nodiscard]] auto operator()() noexcept -> SampleType;

private:
[[nodiscard]] auto sine() noexcept -> SampleType;
[[nodiscard]] auto triangle() noexcept -> SampleType;
[[nodiscard]] auto saw() noexcept -> SampleType;
[[nodiscard]] auto pulse(SampleType puslseWidth) noexcept -> SampleType;

OscillatorShape _shape{};
SampleType _phase{0};
SampleType _frequency{0};
SampleType _puslseWidth{0.5};
SampleType _sampleRate{0};
};

template<typename SampleType>
auto Oscillator<SampleType>::setShape(OscillatorShape shape) noexcept -> void
{
_shape = shape;
}

template<typename SampleType>
auto Oscillator<SampleType>::setPhase(SampleType phase) noexcept -> void
{
_phase = phase;
}

template<typename SampleType>
auto Oscillator<SampleType>::setFrequency(SampleType frequency) noexcept -> void
{
_frequency = frequency;
}

template<typename SampleType>
auto Oscillator<SampleType>::setSampleRate(SampleType sampleRate) noexcept -> void
{
_sampleRate = sampleRate;
}

template<typename SampleType>
auto Oscillator<SampleType>::operator()() noexcept -> SampleType
{
if (_shape == OscillatorShape::Sine) { return sine(); }
if (_shape == OscillatorShape::Triangle) { return triangle(); }
if (_shape == OscillatorShape::Saw) { return saw(); }
if (_shape == OscillatorShape::Square) { return pulse(_puslseWidth); }
return 0.0F;
}

template<typename SampleType>
auto Oscillator<SampleType>::sine() noexcept -> SampleType
{
auto output = std::sin(_phase * numbers::twoPi<SampleType>);

_phase += 1.0F / (_sampleRate / _frequency);
_phase -= std::floor(_phase);

return output;
}

template<typename SampleType>
auto Oscillator<SampleType>::pulse(SampleType puslseWidth) noexcept -> SampleType
{
if (puslseWidth < 0.0F) { puslseWidth = 0.0F; }
if (puslseWidth > 1.0F) { puslseWidth = 1; }

if (_phase >= 1.0F) { _phase -= 1.0F; }
_phase += (1.0F / (_sampleRate / (_frequency)));

if (_phase < puslseWidth) { return SampleType{-1}; }
return 1.0F;
}

template<typename SampleType>
auto Oscillator<SampleType>::saw() noexcept -> SampleType
{
auto output = _phase;

if (_phase >= 1.0F) { _phase -= SampleType{2}; }
_phase += (1.0F / (_sampleRate / (_frequency))) * SampleType{2};

return output;
}

template<typename SampleType>
auto Oscillator<SampleType>::triangle() noexcept -> SampleType
{
if (_phase >= 1.0F) { _phase -= 1.0F; }
_phase += (1.0F / (_sampleRate / (_frequency)));
if (_phase <= SampleType{0.5}) { return (_phase - SampleType{0.25}) * SampleType{4}; }
return ((1.0F - _phase) - SampleType{0.25}) * SampleType{4};
}

} // namespace mc

0 comments on commit 1007fa9

Please sign in to comment.