summaryrefslogtreecommitdiff
path: root/src/audio/chunk.cpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2022-11-22 23:10:42 +1100
committerjacqueline <me@jacqueline.id.au>2022-11-22 23:10:42 +1100
commitdfa9ab6e04689b99267092e016a91d9254f94cd8 (patch)
tree6f33f8d0d099fb85efa746e041e836f4505371ee /src/audio/chunk.cpp
parent9176ef187227ffb56c249c5f321cd1bf50d4cfcc (diff)
downloadtangara-fw-dfa9ab6e04689b99267092e016a91d9254f94cd8.tar.gz
template-ify the cbor stuff
Diffstat (limited to 'src/audio/chunk.cpp')
-rw-r--r--src/audio/chunk.cpp43
1 files changed, 26 insertions, 17 deletions
diff --git a/src/audio/chunk.cpp b/src/audio/chunk.cpp
index a8864930..40564069 100644
--- a/src/audio/chunk.cpp
+++ b/src/audio/chunk.cpp
@@ -10,18 +10,22 @@
namespace audio {
/*
- * The maximum size that we expect a header to take up.
+ * The amount of space to allocate for the first chunk's header. After the first
+ * chunk, we have a more concrete idea of the header's size and can allocate
+ * space for future headers more compactly.
*/
-// TODO: tune this.
-static const size_t kMaxHeaderSize = 64;
+// TODO: measure how big headers tend to be to pick a better value.
+static const size_t kInitialHeaderSize = 32;
auto WriteChunksToStream(MessageBufferHandle_t *stream, uint8_t *working_buffer, size_t working_buffer_length, std::function<size_t(uint8_t*,size_t)> callback, TickType_t max_wait) -> EncodeWriteResult {
+
+ size_t header_size = kInitialHeaderSize;
while (1) {
// First, ask the callback for some data to write.
size_t chunk_size =
callback(
- working_buffer + kMaxHeaderSize,
- working_buffer_length - kMaxHeaderSize);
+ working_buffer + header_size,
+ working_buffer_length - header_size);
if (chunk_size == 0) {
// They had nothing for us, so bail out.
@@ -31,22 +35,28 @@ auto WriteChunksToStream(MessageBufferHandle_t *stream, uint8_t *working_buffer,
// Put together a header.
cbor::Encoder encoder(cbor::CONTAINER_ARRAY, 3, working_buffer, working_buffer_length);
encoder.WriteUnsigned(TYPE_CHUNK_HEADER);
- // Note here that we need to write the offset of the chunk into the header.
- // We could be smarter here and write the actual header size, allowing us to
- // pack slightly more data into each message, but this is hard so I haven't
- // done it. Please make my code better for me.
- encoder.WriteUnsigned(kMaxHeaderSize);
+ encoder.WriteUnsigned(header_size);
encoder.WriteUnsigned(chunk_size);
- if (encoder.Finish().has_error()) {
+
+ size_t new_header_size = header_size;
+ cpp::result<size_t, CborError> encoder_res = encoder.Finish();
+ if (encoder_res.has_error()) {
return CHUNK_ENCODING_ERROR;
- };
+ } else {
+ // We can now tune the space to allocate for the header to be closer to
+ // its actual size. We pad this by 2 bytes to allow extra space for the
+ // chunk size and header size fields to each spill over into another byte
+ // each.
+ new_header_size = encoder_res.value() + 2;
+ }
// Try to write to the buffer. Note the return type here will be either 0 or
- // kMaxHeaderSize + chunk_size, as MessageBuffer doesn't allow partial
- // writes.
+ // header_size + chunk_size, as MessageBuffer doesn't allow partial writes.
size_t actual_write_size =
xMessageBufferSend(
- *stream, working_buffer, kMaxHeaderSize + chunk_size, max_wait);
+ *stream, working_buffer, header_size + chunk_size, max_wait);
+
+ header_size = new_header_size;
if (actual_write_size == 0) {
// We failed to write in time, so bail out. This is techinically data loss
@@ -84,8 +94,7 @@ auto ReadChunksFromStream(MessageBufferHandle_t *stream, uint8_t *working_buffer
return CHUNK_STREAM_ENDED;
}
- // Work the size and position of the chunk (don't assume it's at
- // kMaxHeaderSize offset for future-proofing).
+ // Work the size and position of the chunk.
header_length = decoder.ParseUnsigned().value_or(0);
chunk_length = decoder.ParseUnsigned().value_or(0);
if (decoder.Failed()) {