Skip to content

Commit 5a17117

Browse files
committed
DynamicMemoryStream correction
1 parent 7f2bd4a commit 5a17117

File tree

2 files changed

+98
-17
lines changed

2 files changed

+98
-17
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* @file streams-audiokit-sd-audiokit.ino
3+
* @author Phil Schatzmann
4+
* @brief We record the input from the microphone to a file and constantly repeat to play the file
5+
* The input is triggered by pressing key 1. Recording stops when key 1 is released!
6+
* @version 0.1
7+
* @date 2022-09-01
8+
*
9+
* @copyright Copyright (c) 2022
10+
*
11+
*/
12+
#include "AudioTools.h"
13+
#include "AudioLibs/AudioKit.h"
14+
#include "AudioLibs/MemoryManager.h"
15+
16+
uint16_t sample_rate = 16000;
17+
uint8_t channels = 1; // The stream will have 2 channels
18+
AudioKitStream kit;
19+
MemoryManager memory(500); // Activate PSRAM for objects > 500 bytes
20+
DynamicMemoryStream recording(true); // Audio Stored on heap (PSRAM)
21+
StreamCopy copier; // copies data
22+
bool is_recording = false; // flag to make sure that close is only executed one
23+
uint64_t end_time; // trigger to call endRecord
24+
25+
26+
void record_start(bool pinStatus, int pin, void* ref){
27+
Serial.println("Recording...");
28+
recording.begin();
29+
copier.begin(recording, kit);
30+
is_recording = true;
31+
}
32+
33+
void record_end(bool pinStatus, int pin, void* ref){
34+
if (recording == true){
35+
Serial.println("Playing...");
36+
is_recording = false;
37+
copier.begin(kit, recording); // start playback
38+
}
39+
}
40+
41+
void setup(){
42+
Serial.begin(115200);
43+
while(!Serial); // wait for serial to be ready
44+
AudioLogger::instance().begin(Serial, AudioLogger::Info);
45+
46+
// setup input and output
47+
auto cfg = kit.defaultConfig(RXTX_MODE);
48+
cfg.sd_active = true;
49+
cfg.sample_rate = sample_rate;
50+
cfg.channels = channels;
51+
cfg.input_device = AUDIO_HAL_ADC_INPUT_LINE2;
52+
kit.begin(cfg);
53+
kit.setVolume(1.0);
54+
55+
// record when key 1 is pressed
56+
kit.audioActions().add(PIN_KEY1, record_start, record_end);
57+
Serial.println("Press Key 1 to record");
58+
59+
}
60+
61+
void loop(){
62+
63+
// record or play recording
64+
copier.copy();
65+
66+
// Process keys
67+
kit.processActions();
68+
69+
}

src/AudioTools/AudioStreams.h

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -319,17 +319,21 @@ class DynamicMemoryStream : public AudioStreamX {
319319
struct DataNode {
320320
int len=0;
321321
uint8_t* data=nullptr;
322+
322323
DataNode() = default;
323324
/// Constructor
324-
DataNode(void*data, int len){
325+
DataNode(void*inData, int len){
325326
this->len = len;
326-
this->data = new uint8_t[len];
327+
this->data = (uint8_t*) malloc(len);
327328
assert(this->data!=nullptr);
328-
memcpy(this->data, data, len);
329+
memcpy(this->data, inData, len);
329330
}
330331

331332
~DataNode(){
332-
if (data!=nullptr) delete[]data;
333+
if (data!=nullptr) {
334+
free(data);
335+
data = nullptr;
336+
}
333337
}
334338
};
335339

@@ -365,7 +369,15 @@ class DynamicMemoryStream : public AudioStreamX {
365369
}
366370

367371
void clear() {
368-
audio_list.clear();
372+
DataNode *p_node;
373+
bool ok;
374+
do{
375+
ok = audio_list.pop_front(p_node);
376+
if (ok){
377+
delete p_node;
378+
}
379+
} while (ok);
380+
369381
temp_audio.reset();
370382
total_available = 0;
371383
alloc_failed = false;
@@ -382,11 +394,11 @@ class DynamicMemoryStream : public AudioStreamX {
382394
}
383395

384396
virtual size_t write(const uint8_t *buffer, size_t size) override {
385-
DataNode node((void*)buffer, size);
386-
if (node.data!=nullptr){
397+
DataNode *p_node = new DataNode((void*)buffer, size);
398+
if (p_node->data!=nullptr){
387399
alloc_failed = false;
388400
total_available += size;
389-
audio_list.push_back(node);
401+
audio_list.push_back(p_node);
390402

391403
// setup interator to point to first record
392404
if (it == audio_list.end()){
@@ -404,7 +416,7 @@ class DynamicMemoryStream : public AudioStreamX {
404416
}
405417

406418
virtual int available() override {
407-
return it == audio_list.end() ? 0 : (*it).len;
419+
return it == audio_list.end() ? 0 : (*it)->len;
408420
}
409421

410422
virtual size_t readBytes(uint8_t *buffer, size_t length) override {
@@ -424,13 +436,13 @@ class DynamicMemoryStream : public AudioStreamX {
424436
}
425437

426438
// provide data from next node
427-
DataNode node = *it;
428-
int result_len = min(length, (size_t) node.len);
429-
memcpy(buffer, node.data, result_len);
439+
DataNode *p_node = *it;
440+
int result_len = min(length, (size_t) p_node->len);
441+
memcpy(buffer, p_node->data, result_len);
430442
// save unprocessed data to temp buffer
431-
if (node.len>length){
432-
uint8_t *start = node.data+result_len;
433-
int uprocessed_len = node.len - length;
443+
if (p_node->len>length){
444+
uint8_t *start = p_node->data+result_len;
445+
int uprocessed_len = p_node->len - length;
434446
temp_audio.writeArray(start, uprocessed_len);
435447
}
436448
//move to next pos
@@ -439,8 +451,8 @@ class DynamicMemoryStream : public AudioStreamX {
439451
}
440452

441453
protected:
442-
List<DataNode> audio_list;
443-
List<DataNode>::Iterator it = audio_list.end();
454+
List<DataNode*> audio_list;
455+
List<DataNode*>::Iterator it = audio_list.end();
444456
size_t total_available=0;
445457
int default_buffer_size=DEFAULT_BUFFER_SIZE;
446458
bool alloc_failed = false;

0 commit comments

Comments
 (0)