Skip to content

Commit 03310d7

Browse files
authored
Merge pull request #2 from scheffle/develop
develop->main
2 parents 2e9fef3 + 4191bbb commit 03310d7

27 files changed

+2409
-30
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build
2+
.cache

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "gcem"]
22
path = gcem
33
url = https://github.com/kthohr/gcem.git
4+
[submodule "tests/googletest"]
5+
path = tests/googletest
6+
url = https://github.com/google/googletest.git

CMakeLists.txt

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1-
cmake_minimum_required(VERSION 3.14.0)
1+
cmake_minimum_required(VERSION 3.19.0)
22

3-
project(vst3utils VERSION 1.0.0)
3+
project(vst3utils VERSION 1.2.0)
44

55
add_library(vst3utils INTERFACE
6+
"include/vst3utils/buffer.h"
7+
"include/vst3utils/byteorder_stream.h"
68
"include/vst3utils/enum_array.h"
79
"include/vst3utils/event_iterator.h"
10+
"include/vst3utils/events.h"
811
"include/vst3utils/message.h"
912
"include/vst3utils/norm_plain_conversion.h"
13+
"include/vst3utils/observable.h"
1014
"include/vst3utils/parameter_changes_iterator.h"
1115
"include/vst3utils/parameter_description.h"
1216
"include/vst3utils/parameter_updater.h"
1317
"include/vst3utils/parameter.h"
1418
"include/vst3utils/smooth_value.h"
1519
"include/vst3utils/string_conversion.h"
20+
"include/vst3utils/transport_state_observer.h"
1621
"ReadMe.md"
1722
)
1823

@@ -23,3 +28,79 @@ target_compile_features(vst3utils
2328
cxx_std_17
2429
)
2530

31+
option(VST3UTILS_TESTS "Enable unit test target" OFF)
32+
set(VST3UTILS_TESTS_SDK_PATH "" CACHE PATH "Path to the VST SDK for unit testing")
33+
if(VST3UTILS_TESTS)
34+
35+
enable_testing()
36+
37+
set(BUILD_GMOCK 0)
38+
set(INSTALL_GTEST 0)
39+
add_subdirectory(tests/googletest)
40+
41+
add_executable(vst3utils_test
42+
"tests/buffer_test.cpp"
43+
"tests/norm_plain_conversion_test.cpp"
44+
"tests/observable_test.cpp"
45+
"tests/string_conversion_test.cpp"
46+
"tests/transport_state_observer_test.cpp"
47+
)
48+
49+
target_link_libraries(vst3utils_test
50+
PRIVATE
51+
vst3utils
52+
gtest_main
53+
)
54+
55+
target_compile_features(vst3utils_test
56+
INTERFACE
57+
cxx_std_17
58+
)
59+
60+
if(CMAKE_XCODE_BUILD_SYSTEM EQUAL 12)
61+
add_custom_command(
62+
TARGET vst3utils_test
63+
POST_BUILD
64+
COMMAND
65+
codesign --force -s - $<TARGET_FILE:vst3utils_test>
66+
)
67+
endif()
68+
69+
if(SMTG_WIN)
70+
target_compile_options(vst3utils_test PRIVATE "/utf-8" "/Zc:__cplusplus")
71+
endif()
72+
73+
if(VST3UTILS_TESTS_SDK_PATH)
74+
set(SMTG_ENABLE_VSTGUI_SUPPORT 0)
75+
set(SMTG_ENABLE_VST3_HOSTING_EXAMPLES 0)
76+
set(SMTG_ENABLE_VST3_PLUGIN_EXAMPLES 0)
77+
set(SMTG_ADD_VST3_UTILITIES 0)
78+
set(SMTG_RUN_VST_VALIDATOR 0)
79+
set(SMTG_COREAUDIO_SDK_PATH "")
80+
add_subdirectory("${VST3UTILS_TESTS_SDK_PATH}" "${PROJECT_BINARY_DIR}/vst3sdk")
81+
smtg_enable_vst3_sdk()
82+
83+
target_sources(vst3utils_test PRIVATE
84+
"tests/attribute_list_test.cpp"
85+
"tests/events_test.cpp"
86+
"tests/message_test.cpp"
87+
)
88+
89+
target_link_libraries(vst3utils_test
90+
PRIVATE
91+
sdk_hosting
92+
)
93+
94+
if(SMTG_MAC)
95+
target_link_libraries(vst3utils_test
96+
PRIVATE
97+
"-framework CoreFoundation"
98+
)
99+
endif()
100+
101+
endif()
102+
103+
include(GoogleTest)
104+
gtest_discover_tests(vst3utils_test)
105+
106+
endif(VST3UTILS_TESTS)

ReadMe.md

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# vst3utils
22

3-
a c++ header only library with little helper classes for writing vst3 plug-ins.
3+
A C++ header-only library providing little helper classes for developing vst3 plug-ins.
44

55
## Requirements
66

@@ -9,9 +9,9 @@ a c++ header only library with little helper classes for writing vst3 plug-ins.
99

1010
## Usage
1111

12-
Eiher add a header include directory pointing to the 'include' repository path or
13-
if you use cmake then just add this directoy in cmake with `add_subdirectory` and add a
14-
target dependency to your own target:
12+
You can either add a header include directory pointing to the 'include' repository path or,
13+
if you use CMake, simply add this directory to CMake with `add_subdirectory` and add a target
14+
dependency to your own target.
1515

1616
```cmake
1717
add_subdirectory("path/to/vst3utils" ${PROJECT_BINARY_DIR}/vst3utils)
@@ -24,6 +24,14 @@ add_target_dependency(myTarget
2424

2525
## History
2626

27+
- **Version 1.2.0** [03/22/2025]
28+
- added unit tests
29+
- added transport_state_observer
30+
- added event dispatcher helper
31+
- added observable template
32+
- added RAII memory buffer object
33+
- added byte_order_stream.h
34+
- added dB to gain functions
2735
- **Version 1.1.0** [08/03/2023]
2836
- added messages.h and parameter_changes_iterator.h
2937
- a few additions else where, see git commit history
@@ -32,6 +40,16 @@ add_target_dependency(myTarget
3240

3341
## Headers
3442

43+
### `#include "vst3utils/buffer.h`
44+
45+
- `vst3utils::buffer`
46+
- RAII memory buffer object with support for aligned memory
47+
48+
### `#include "vst3utils/byte_order_stream.h`
49+
50+
- `vst3utils::byte_order_ibstream`
51+
- an adapter to read/write byte ordered data to an IBStream
52+
3553
### `#include "vst3utils/enum_array.h`
3654

3755
- `vst3utils::enum_array`
@@ -42,6 +60,11 @@ add_target_dependency(myTarget
4260
- `vst3utils::event_iterator`
4361
- a c++ compatible forward iterator for `Steinberg::Vst::Event`
4462

63+
### `#include "vst3utils/events.h"`
64+
65+
- `vst3utils::dispatch_event`
66+
- function to dispatch a `Steinberg::Vst::Event`
67+
4568
### `#include "vst3utils/message.h"`
4669

4770
- `vst3utils::message`
@@ -59,6 +82,13 @@ contains functions to convert from normalized to plain and back
5982
- `vst3utils::plain_to_normalized`
6083
- `vst3utils::steps_to_normalized`
6184
- `vst3utils::exp_to_normalized`
85+
- `vst3utils::db_to_gain`
86+
- `vst3utils::gain_to_db`
87+
88+
### `#include "vst3utils/observable.h"`
89+
90+
- `vst3utils::observable`
91+
- template to observe an object by multiple listeners without direct dependency
6292

6393
### `#include "vst3utils/parameter_changes_iterator.h`
6494

@@ -102,6 +132,11 @@ static constexpr std::array<description, 4> param_desc = {{
102132
- `vst3utils::create_utf16_from_ascii`
103133
- `vst3utils::copy_ascii_to_utf16`
104134

135+
### `#include "vst3utils/transport_state_observer.h`
136+
137+
- `vst3utils::transport_state_observer`
138+
- helper for handling transport state changes
139+
105140
## License
106141

107142
```

include/vst3utils/buffer.h

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
//------------------------------------------------------------------------
2+
/* This source code is free software. It comes without any warranty, to
3+
* the extent permitted by applicable law. You can redistribute it
4+
* and/or modify it under the terms of the Do What The Fuck You Want
5+
* To Public License, Version 2, as published by Sam Hocevar. See
6+
* http://sam.zoy.org/wtfpl/COPYING for more details. */
7+
//------------------------------------------------------------------------
8+
9+
#pragma once
10+
11+
#include <cstdlib>
12+
#include <algorithm>
13+
#include <cassert>
14+
15+
#ifdef _MSC_VER
16+
#include <malloc.h>
17+
#endif
18+
19+
#if __APPLE__
20+
#include <AvailabilityMacros.h>
21+
#endif
22+
23+
//------------------------------------------------------------------------
24+
namespace vst3utils {
25+
26+
//------------------------------------------------------------------------
27+
/** standard allocator using malloc and free */
28+
struct standard_allocator
29+
{
30+
static void* allocate (size_t numBytes) { return std::malloc (numBytes); }
31+
static void deallocate (void* ptr, size_t numButes) { std::free (ptr); }
32+
};
33+
34+
//------------------------------------------------------------------------
35+
/** simple RAII buffer implementation */
36+
template<typename T, typename allocatorT = standard_allocator>
37+
struct buffer final
38+
{
39+
buffer (size_t num_elements = 0) { allocate (num_elements); }
40+
~buffer () noexcept { deallocate (); }
41+
42+
/** allocate */
43+
void allocate (size_t num_elements)
44+
{
45+
deallocate ();
46+
if (num_elements == 0u)
47+
return;
48+
buffer_ptr = reinterpret_cast<T*> (allocatorT::allocate (num_elements * element_size ()));
49+
if (buffer_ptr)
50+
num_buffer_elements = num_elements;
51+
}
52+
53+
/** fill all elements in the buffer with the same value */
54+
void fill (T value)
55+
{
56+
assert (buffer_ptr);
57+
std::fill_n (buffer_ptr, num_buffer_elements, value);
58+
}
59+
60+
/** access specified element */
61+
T& operator[] (size_t index)
62+
{
63+
assert (index < num_buffer_elements);
64+
return buffer_ptr[index];
65+
}
66+
67+
/** access specified element */
68+
const T& operator[] (size_t index) const
69+
{
70+
assert (index < num_buffer_elements);
71+
return buffer_ptr[index];
72+
}
73+
74+
/** returns a pointer to the first element */
75+
T* data () { return buffer_ptr; }
76+
/** returns a pointer to the first element */
77+
const T* data () const { return buffer_ptr; }
78+
79+
/** returns the number of elements */
80+
size_t size () const { return num_buffer_elements; }
81+
/** returns the byte size of one element */
82+
constexpr size_t element_size () const { return sizeof (T); }
83+
84+
/** returns an iterator to the beginning */
85+
T* begin () { return &buffer_ptr[0]; }
86+
/** returns an iterator to the end */
87+
T* end () { return &buffer_ptr[size ()]; }
88+
89+
/** returns an iterator to the beginning */
90+
const T* begin () const { return &buffer_ptr[0]; }
91+
/** returns an iterator to the end */
92+
const T* end () const { return &buffer_ptr[size ()]; }
93+
94+
private:
95+
void deallocate ()
96+
{
97+
if (!buffer_ptr)
98+
return;
99+
allocatorT::deallocate (buffer_ptr, num_buffer_elements * element_size ());
100+
buffer_ptr = nullptr;
101+
num_buffer_elements = 0u;
102+
}
103+
104+
T* buffer_ptr {nullptr};
105+
size_t num_buffer_elements {0u};
106+
};
107+
108+
//------------------------------------------------------------------------
109+
/** allocator that uses memory aligned allocations */
110+
template<size_t alignment>
111+
struct alignment_allocator
112+
{
113+
static void* allocate (size_t numBytes)
114+
{
115+
if (alignment == 0)
116+
return malloc (numBytes);
117+
void* data {nullptr};
118+
#if __APPLE__ && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_15
119+
posix_memalign (&data, alignment, numBytes);
120+
#elif defined(_MSC_VER)
121+
data = _aligned_malloc (numBytes, alignment);
122+
#else
123+
size_t d = numBytes % alignment;
124+
if (d != 0u)
125+
numBytes += (alignment - d);
126+
data = std::aligned_alloc (alignment, numBytes);
127+
#endif
128+
return data;
129+
}
130+
static void deallocate (void* ptr, size_t numButes)
131+
{
132+
if (alignment == 0)
133+
std::free (ptr);
134+
else
135+
{
136+
#if defined(_MSC_VER)
137+
_aligned_free (ptr);
138+
#else
139+
std::free (ptr);
140+
#endif
141+
}
142+
}
143+
};
144+
145+
//------------------------------------------------------------------------
146+
template<typename T, size_t alignment>
147+
using aligned_buffer = buffer<T, alignment_allocator<alignment>>;
148+
149+
//------------------------------------------------------------------------
150+
} // vst3utils

0 commit comments

Comments
 (0)