Skip to content

Commit 9ec67c5

Browse files
committed
MemoryStream: new method rewind()
1 parent 1da31e3 commit 9ec67c5

1 file changed

Lines changed: 54 additions & 9 deletions

File tree

src/AudioTools/CoreAudio/AudioStreams.h

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ class MemoryStream : public AudioStream {
134134
return begin();
135135
}
136136

137-
/// resets the read pointer
137+
/// resets the read pointer and write pointer if the memory is changeable
138138
bool begin() override {
139139
TRACED();
140140
write_pos = memoryCanChange() ? 0 : buffer_size;
@@ -146,6 +146,13 @@ class MemoryStream : public AudioStream {
146146
return is_active;
147147
}
148148

149+
/// Resets the read pointer
150+
void rewind() {
151+
if (buffer != nullptr && buffer_size > 0) {
152+
read_pos = 0;
153+
}
154+
}
155+
149156
virtual size_t write(uint8_t byte) override {
150157
if (!is_active) return 0;
151158
if (memory_type == FLASH_RAM) return 0;
@@ -181,7 +188,7 @@ class MemoryStream : public AudioStream {
181188
read_pos = rewind_pos;
182189
result = write_pos - read_pos;
183190
// call callback
184-
if (rewind != nullptr) rewind();
191+
if (rewind_cb != nullptr) rewind_cb();
185192
}
186193
return is_loop ? DEFAULT_BUFFER_SIZE : result;
187194
}
@@ -290,10 +297,17 @@ class MemoryStream : public AudioStream {
290297
virtual uint8_t *data() { return buffer; }
291298

292299
/// update the write_pos (e.g. when we used data() to update the array)
293-
virtual void setAvailable(size_t len) { this->write_pos = len; }
300+
virtual bool setAvailable(size_t len) {
301+
if (len <= buffer_size) {
302+
write_pos = len;
303+
if (read_pos > write_pos) read_pos = write_pos;
304+
return true;
305+
}
306+
return false;
307+
}
294308

295309
/// Callback which is executed when we rewind (in loop mode) to the beginning
296-
void setRewindCallback(void (*cb)()) { this->rewind = cb; }
310+
void setRewindCallback(void (*cb)()) { this->rewind_cb = cb; }
297311

298312
/// Update the values (buffer and size)
299313
void setValue(const uint8_t *buffer, int buffer_size,
@@ -313,21 +327,52 @@ class MemoryStream : public AudioStream {
313327
uint8_t *buffer = nullptr;
314328
MemoryType memory_type = RAM;
315329
bool is_loop = false;
316-
void (*rewind)() = nullptr;
330+
void (*rewind_cb)() = nullptr;
317331
bool is_active = false;
318332
bool owns_memory = true;
319333

320334
bool memoryCanChange() { return memory_type != FLASH_RAM; }
321335

322336
void copy(MemoryStream &source) {
323337
if (this == &source) return;
338+
339+
// Release currently owned mutable buffer.
340+
if (memoryCanChange() && owns_memory && buffer != nullptr) {
341+
free(buffer);
342+
buffer = nullptr;
343+
}
344+
345+
// Shallow copy for FLASH memory source.
324346
if (source.memory_type == FLASH_RAM) {
347+
owns_memory = false;
325348
setValue(source.buffer, source.buffer_size, source.memory_type);
326-
} else {
327-
setValue(nullptr, source.buffer_size, source.memory_type);
328-
resize(buffer_size);
329-
memcpy(buffer, source.buffer, buffer_size);
349+
is_active = source.is_active;
350+
is_loop = source.is_loop;
351+
rewind_pos = source.rewind_pos;
352+
return;
353+
}
354+
355+
// Deep copy for mutable source memory.
356+
owns_memory = true;
357+
setValue(nullptr, source.buffer_size, source.memory_type);
358+
if (!resize(source.buffer_size)) {
359+
setValue(nullptr, 0, source.memory_type);
360+
is_active = false;
361+
return;
362+
}
363+
364+
if (source.buffer != nullptr && source.buffer_size > 0) {
365+
memcpy(buffer, source.buffer, source.buffer_size);
330366
}
367+
368+
write_pos = source.write_pos;
369+
read_pos = source.read_pos;
370+
if (write_pos > buffer_size) write_pos = buffer_size;
371+
if (read_pos > write_pos) read_pos = write_pos;
372+
373+
is_active = source.is_active;
374+
is_loop = source.is_loop;
375+
rewind_pos = source.rewind_pos;
331376
}
332377
};
333378

0 commit comments

Comments
 (0)