Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dave/server/languages/c_cpp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
from .std_2D import *
from .juce import *
from .choc import *
from .hart import *
49 changes: 49 additions & 0 deletions dave/server/languages/c_cpp/hart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from __future__ import annotations

import re
from typing import Tuple

from ...container import SampleType, Container2D
from ...debuggers.value import AbstractValue
from dave.server.languages import c_cpp

class HartAudioBuffer(Container2D):
__REGEX = rf"^(?:const\s+)?hart::AudioBuffer<{SampleType.regex()}>\s*$"

def __init__(self, dbg_value: AbstractValue, name: str, _):
typename = dbg_value.typename()
sample_type, *_ = self._parse_typename(typename)
super().__init__(dbg_value, name, sample_type)

@property
def __inner(self) -> c_cpp.StdVector1D:
return c_cpp.StdVector1D(self._value.attr("m_frames"), self.name + ".m_frames")

@classmethod
def typename_matcher(cls) -> re.Pattern:
return re.compile(cls.__REGEX)

@classmethod
def _parse_typename(cls, typename: str, **_) -> Tuple[SampleType, None, None]:
re_match = cls.typename_matcher().match(typename)
if re_match is None:
raise TypeError(
f"HartAudioBuffer could not parse {typename} as a valid type"
)

return (SampleType.parse(re_match.group(1)), None, None)

def shape(self) -> Tuple[int, int]:
assert isinstance(self._value, AbstractValue)
try:
return (
int(self._value.attr("m_numChannels")),
int(self._value.attr("m_numFrames"))
)
except:
raise RuntimeError(f"Failed to retrieve shape of {self._value.typename()}")

def read_from_debugger(self) -> bytearray:
return self.__inner.read_from_debugger()

HartAudioBuffer.register()
21 changes: 21 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ FetchContent_Declare(
FetchContent_MakeAvailable(GSL)


set(HART_BUILD_TESTS OFF)
FetchContent_Declare(
HART
GIT_REPOSITORY "https://github.com/daleonov/HART.git"
GIT_TAG 0.1.0
GIT_SHALLOW ON
)

FetchContent_MakeAvailable(HART)

################################################################################
### stdlib
################################################################################
Expand Down Expand Up @@ -89,6 +99,17 @@ add_executable(
)
set_target_properties(choc PROPERTIES CXX_STANDARD 17)

################################################################################
### HART
################################################################################

add_executable(
hart
${CMAKE_CURRENT_SOURCE_DIR}/hart.cpp
)
set_target_properties(hart PROPERTIES CXX_STANDARD 11)
target_link_libraries(hart PRIVATE HART::HART)

################################################################################
### Custom containers example
################################################################################
Expand Down
52 changes: 52 additions & 0 deletions examples/hart.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#define HART_IMPLEMENTATION
#include "hart.hpp"

HART_DECLARE_ALIASES_FOR_FLOAT;
using AudioBuffer = hart::AudioBuffer<float>;
using hart::roundToSizeT;

int main()
{
constexpr double sampleRateHz = 44100.0;

// Sine sweep
const size_t sineSweepDurationFrames = roundToSizeT (sampleRateHz * 1.0_s);
AudioBuffer bufferA (1, sineSweepDurationFrames);
auto sineSweepSignalA = SineSweep();
sineSweepSignalA.prepare (
sampleRateHz,
1, // numOutputChannels
sineSweepDurationFrames // maxBlockSizeFrames
);
sineSweepSignalA.renderNextBlock (bufferA);

// A different sweep, overwrites the same buffer
auto sineSweepSignalB = SineSweep()
.withType (SineSweep::SweepType::linear)
.withStartFrequency (100_Hz)
.withEndFrequency (1_Hz)
.withDuration (500_ms)
.withLoop (SineSweep::Loop::yes);
sineSweepSignalB.prepare (
sampleRateHz,
1, // numOutputChannels
sineSweepDurationFrames // maxBlockSizeFrames
);
sineSweepSignalB.renderNextBlock (bufferA);

// Multi-channel noise
constexpr size_t multiChannelNoiseNumChannels = 5;
const size_t multiChannelNoiseDurationFrames = hart::roundToSizeT (sampleRateHz * 10_ms);
AudioBuffer bufferB (multiChannelNoiseNumChannels, multiChannelNoiseDurationFrames);
auto multiChannelNoiseSignal = WhiteNoise();
multiChannelNoiseSignal.prepare (
sampleRateHz,
multiChannelNoiseNumChannels, // numOutputChannels
multiChannelNoiseDurationFrames // maxBlockSizeFrames
);
multiChannelNoiseSignal.renderNextBlock (bufferB);
multiChannelNoiseSignal.renderNextBlock (bufferB); // Some more noise...
multiChannelNoiseSignal.renderNextBlock (bufferB); // ...and more noise

return 0;
}