Skip to content

Commit 5c593cf

Browse files
committed
Resources API
1 parent c4f3d43 commit 5c593cf

4 files changed

Lines changed: 290 additions & 0 deletions

File tree

LibSource/Resource.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#include <cstddef>
2+
#include "Resource.h"
3+
4+
bool Resource::setData(void* src, uint32_t length, bool copy){
5+
if (hasData()){
6+
// Buffer is allocated, we don't allow doing it more than once
7+
return false;
8+
}
9+
else if (copy) {
10+
// Allocate a new buffer and copy there
11+
size = length;
12+
data = new uint8_t[size];
13+
memcpy((void*)data, src, length);
14+
allocated = true;
15+
}
16+
else {
17+
// Set pointer to source data, but don't allocate a new buffer
18+
data = (uint8_t*)src;
19+
size = length;
20+
}
21+
return true;
22+
}
23+
24+
template<typename Array, typename Element>
25+
const Array Resource::asArray() const {
26+
// Data is expected to be aligned
27+
return Array((Element*)getData(), size / sizeof(Element));
28+
}
29+
30+
template const FloatArray Resource::asArray<FloatArray, float>() const;
31+
32+
template<typename Array, typename Element>
33+
Array Resource::asArray() {
34+
// Data is expected to be aligned
35+
return Array((Element*)getData(), size / sizeof(Element));
36+
}
37+
38+
template FloatArray Resource::asArray<FloatArray, float>();
39+
40+
void Resource::destroy(Resource resource) {
41+
if (resource.isAllocated()){
42+
delete [] resource.getData();
43+
}
44+
}
45+
46+
const Resource* Resource::get(const char* name, uint32_t offset, uint32_t max_size) {
47+
uint8_t* buffer = NULL;
48+
// Load resource with a pointer to empty buffer
49+
void* args[] = {
50+
(void*)name, (void*)&buffer, (void*)&offset, (void*)&max_size
51+
};
52+
if (getProgramVector()->serviceCall(OWL_SERVICE_LOAD_RESOURCE, args, 4) == OWL_SERVICE_OK && buffer != NULL) {
53+
Resource* resource = new Resource(name);
54+
resource->setData(buffer, max_size, false);
55+
return resource;
56+
}
57+
else {
58+
return NULL;
59+
}
60+
}
61+
62+
Resource Resource::load(const char* name, uint32_t offset, uint32_t max_size) {
63+
uint8_t* buffer = NULL;
64+
// Load resource header separately to know full resource size in advance
65+
void* args[] = {
66+
(void*)name, (void*)&buffer, (void*)&offset, (void*)&max_size
67+
};
68+
if (getProgramVector()->serviceCall(OWL_SERVICE_LOAD_RESOURCE, args, 4) == OWL_SERVICE_OK){
69+
// Reset data pointer to force allocation on memory mapped resources.
70+
Resource allocated_resource = Resource::create(max_size);
71+
args[1] = &allocated_resource.data;
72+
if (getProgramVector()->serviceCall(OWL_SERVICE_LOAD_RESOURCE, args, 4) == OWL_SERVICE_OK){
73+
return allocated_resource;
74+
}
75+
else {
76+
Resource::destroy(allocated_resource);
77+
}
78+
}
79+
// An empty resource is returned if we've failed to load one
80+
Resource resource(name);
81+
return resource;
82+
}
83+
84+
Resource Resource::create(uint32_t size) {
85+
Resource resource;
86+
resource.setData(new uint8_t[size], size, false);
87+
resource.allocated = true;
88+
return resource;
89+
}

LibSource/Resource.h

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
#ifndef __RESOURCE_STORAGE_H__
2+
#define __RESOURCE_STORAGE_H__
3+
4+
#include <stdint.h>
5+
#include <cstring>
6+
#include "OpenWareMidiControl.h"
7+
#include "ServiceCall.h"
8+
#include "ProgramVector.h"
9+
#include "FloatArray.h"
10+
11+
12+
/*
13+
* This class should not be instantiated directly, but it can be returned by untyped
14+
* getResource() calls to storage.
15+
*/
16+
17+
class Resource {
18+
public:
19+
/**
20+
* Default constructor
21+
*/
22+
Resource() = default;
23+
24+
/**
25+
* Construct a resource with known name
26+
*/
27+
Resource(const char* name) {
28+
setName(name);
29+
}
30+
31+
/**
32+
* Resource destructor
33+
*/
34+
~Resource() {
35+
}
36+
37+
/**
38+
* Check if data is available
39+
*/
40+
bool hasData() const {
41+
return data != NULL;
42+
}
43+
44+
/**
45+
* Get pointer to data. This may be NULL if no buffer is assigned yet.
46+
*/
47+
uint8_t* getData() {
48+
return data;
49+
}
50+
51+
/**
52+
* Get pointer to data. This may be NULL if no buffer is assigned yet.
53+
* This is the **const** version
54+
*/
55+
const uint8_t* getData() const {
56+
return const_cast<const uint8_t*>(data);
57+
}
58+
59+
/**
60+
* Template method for converting data to an object of particular class
61+
*/
62+
template<typename Payload>
63+
const Payload& getData() const {
64+
return *(reinterpret_cast<const Payload*>(data));
65+
}
66+
67+
/**
68+
* Template method for converting data to an object. This is the **const** version
69+
*/
70+
template<typename Payload>
71+
Payload& getData() {
72+
return *(reinterpret_cast<Payload*>(data));
73+
}
74+
75+
/**
76+
* Set data
77+
*
78+
* @param src source buffer address
79+
* @param length number of bytes to use
80+
* @param copy flag to copy data to a new buffer instead of changing current buffer address
81+
*/
82+
bool setData(void* src, uint32_t length, bool copy);
83+
84+
/**
85+
* Template method for setting data from an object
86+
*
87+
* @param src source object
88+
* @param copy flag to copy data to a new buffer instead of changing current buffer address
89+
*/
90+
template<typename Payload>
91+
bool setData(const Payload& src, bool copy){
92+
return setData((void*)&src, sizeof(Payload), copy);
93+
}
94+
95+
/**
96+
* Get buffer size in bytes
97+
*/
98+
uint32_t getSize() const {
99+
return size;
100+
}
101+
102+
/**
103+
* Set buffer size
104+
*
105+
* @param new_size new size in bytes
106+
*/
107+
void setSize(uint32_t new_size) {
108+
size = new_size;
109+
}
110+
111+
/**
112+
* Get resource name
113+
*/
114+
const char* getName() const {
115+
return name;
116+
}
117+
118+
/**
119+
* Set resource neam
120+
*
121+
* @param new_name new name
122+
*/
123+
void setName(const char* new_name) {
124+
strncpy(name, new_name, 24);
125+
}
126+
127+
/**
128+
* Check if resource is set to a valid buffer with some data
129+
*/
130+
bool isValid() const {
131+
return size > 0 && hasData();
132+
}
133+
134+
/**
135+
* Check if buffer is allocated on the heap
136+
*/
137+
bool isAllocated() const {
138+
return allocated;
139+
}
140+
141+
/**
142+
* Array conversion
143+
*/
144+
template<typename Array, typename Element>
145+
const Array asArray() const;
146+
147+
/**
148+
* Array conversion. This is the **const** version
149+
*/
150+
template<typename Array, typename Element>
151+
Array asArray();
152+
153+
/**
154+
* Create a new resource with allocated buffer
155+
*
156+
* @param size buffer size in bytes
157+
*/
158+
static Resource create(uint32_t size);
159+
160+
/**
161+
* Destroy allocated buffer for a resource
162+
*/
163+
static void destroy(Resource resource);
164+
165+
/**
166+
* Get resource from storage
167+
*
168+
* This method will never allocate a new buffer, only using data stored on flash
169+
* directly. For this reason it returns a pointer **const** resource object. This
170+
* object should be deleted after using, but resource shouldn't be destroyed.
171+
*
172+
* @param name resource name
173+
* @param offest offset in bytes
174+
* @param max_size maximum size, actual size can be smaller depending on object size
175+
*/
176+
static const Resource* get(
177+
const char* name, uint32_t offset = 0, uint32_t max_size = 0xFFFFFFFF);
178+
179+
/**
180+
* Load resource to a new buffer in memory
181+
*
182+
* This will always allocate a buffer in memory and copy object into it. This
183+
* buffer is mutable. This object should be destroyed after it's used to deallocated
184+
* stored buffer.
185+
*
186+
* @param name resource name
187+
* @param offest offset in bytes
188+
* @param max_size maximum size, actual size can be smaller depending on object size
189+
*/
190+
static Resource load(
191+
const char* name, uint32_t offset = 0, uint32_t max_size = 0xFFFFFFFF);
192+
193+
protected:
194+
char name[24];
195+
uint32_t size;
196+
uint8_t* data = NULL;
197+
bool allocated;
198+
};
199+
#endif

Source/ServiceCall.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define OWL_SERVICE_ARM_RFFT_FAST_INIT_F32 0x0100
33
#define OWL_SERVICE_ARM_CFFT_INIT_F32 0x0110
44
#define OWL_SERVICE_GET_PARAMETERS 0x1000
5+
#define OWL_SERVICE_LOAD_RESOURCE 0x1001
56
#define OWL_SERVICE_GET_ARRAY 0x1010
67
#define OWL_SERVICE_REGISTER_CALLBACK 0x1100
78
#define OWL_SERVICE_REQUEST_CALLBACK 0x1101

compile.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CPP_SRC += Envelope.cpp VoltsPerOctave.cpp Window.cpp
99
CPP_SRC += WavetableOscillator.cpp PolyBlepOscillator.cpp
1010
CPP_SRC += SmoothValue.cpp PatchParameter.cpp
1111
CPP_SRC += MonochromeScreenPatch.cpp ColourScreenPatch.cpp
12+
CPP_SRC += Resource.cpp
1213
C_SRC += font.c
1314

1415
SOURCE = $(BUILDROOT)/Source

0 commit comments

Comments
 (0)